Repository: imroc/ontts Branch: master Commit: af26ab273796 Files: 168 Total size: 952.7 KB Directory structure: gitextract_fcvvxwx4/ ├── .gitattributes ├── README.md ├── glide.yaml ├── main.go ├── server/ │ └── server.go ├── speed_test.go ├── vendor/ │ └── github.com/ │ ├── garyburd/ │ │ └── redigo/ │ │ ├── .travis.yml │ │ ├── LICENSE │ │ ├── README.markdown │ │ ├── internal/ │ │ │ ├── commandinfo.go │ │ │ ├── commandinfo_test.go │ │ │ └── redistest/ │ │ │ └── testdb.go │ │ ├── redis/ │ │ │ ├── conn.go │ │ │ ├── conn_test.go │ │ │ ├── doc.go │ │ │ ├── log.go │ │ │ ├── pool.go │ │ │ ├── pool_test.go │ │ │ ├── pubsub.go │ │ │ ├── pubsub_test.go │ │ │ ├── redis.go │ │ │ ├── reply.go │ │ │ ├── reply_test.go │ │ │ ├── scan.go │ │ │ ├── scan_test.go │ │ │ ├── script.go │ │ │ ├── script_test.go │ │ │ ├── test_test.go │ │ │ └── zpop_example_test.go │ │ └── redisx/ │ │ ├── connmux.go │ │ ├── connmux_test.go │ │ └── doc.go │ └── imroc/ │ └── log/ │ ├── LICENSE │ ├── README.md │ └── log.go └── xf/ ├── README.md ├── doc/ │ ├── iFlytek MSC Reference Manual/ │ │ ├── all__0_8js.html │ │ ├── all__1_8js.html │ │ ├── dir_25539194184bab781b1c7ecd67774cd8.html │ │ ├── dir_9a65024ac0a05d9abfc2bb6c7ff8f818.html │ │ ├── doxygen.css │ │ ├── dynsections.js │ │ ├── dynsections_8js.html │ │ ├── files.html │ │ ├── files__0_8js.html │ │ ├── files__1_8js.html │ │ ├── functions__0_8js.html │ │ ├── functions__1_8js.html │ │ ├── globals.html │ │ ├── globals_func.html │ │ ├── globals_vars.html │ │ ├── index.html │ │ ├── jquery.js │ │ ├── jquery_8js.html │ │ ├── msp__cmn_8h.html │ │ ├── msp__cmn_8h_source.html │ │ ├── qisr_8h.html │ │ ├── qisr_8h_source.html │ │ ├── qmfv_8h.html │ │ ├── qmfv_8h_source.html │ │ ├── qtts_8h.html │ │ ├── qtts_8h_source.html │ │ ├── search/ │ │ │ ├── all_0.html │ │ │ ├── all_0.js │ │ │ ├── all_1.html │ │ │ ├── all_1.js │ │ │ ├── all_10.html │ │ │ ├── all_10.js │ │ │ ├── all_11.html │ │ │ ├── all_11.js │ │ │ ├── all_2.html │ │ │ ├── all_2.js │ │ │ ├── all_3.html │ │ │ ├── all_3.js │ │ │ ├── all_4.html │ │ │ ├── all_4.js │ │ │ ├── all_5.html │ │ │ ├── all_5.js │ │ │ ├── all_6.html │ │ │ ├── all_6.js │ │ │ ├── all_7.html │ │ │ ├── all_7.js │ │ │ ├── all_8.html │ │ │ ├── all_8.js │ │ │ ├── all_9.html │ │ │ ├── all_9.js │ │ │ ├── all_a.html │ │ │ ├── all_a.js │ │ │ ├── all_b.html │ │ │ ├── all_b.js │ │ │ ├── all_c.html │ │ │ ├── all_c.js │ │ │ ├── all_d.html │ │ │ ├── all_d.js │ │ │ ├── all_e.html │ │ │ ├── all_e.js │ │ │ ├── all_f.html │ │ │ ├── all_f.js │ │ │ ├── files_0.html │ │ │ ├── files_0.js │ │ │ ├── files_1.html │ │ │ ├── files_1.js │ │ │ ├── files_2.html │ │ │ ├── files_2.js │ │ │ ├── files_3.html │ │ │ ├── files_3.js │ │ │ ├── files_4.html │ │ │ ├── files_4.js │ │ │ ├── files_5.html │ │ │ ├── files_5.js │ │ │ ├── files_6.html │ │ │ ├── files_6.js │ │ │ ├── functions_0.html │ │ │ ├── functions_0.js │ │ │ ├── functions_1.html │ │ │ ├── functions_1.js │ │ │ ├── functions_2.html │ │ │ ├── functions_2.js │ │ │ ├── functions_3.html │ │ │ ├── functions_3.js │ │ │ ├── functions_4.html │ │ │ ├── functions_4.js │ │ │ ├── functions_5.html │ │ │ ├── functions_5.js │ │ │ ├── functions_6.html │ │ │ ├── functions_6.js │ │ │ ├── functions_7.html │ │ │ ├── functions_7.js │ │ │ ├── functions_8.html │ │ │ ├── functions_8.js │ │ │ ├── functions_9.html │ │ │ ├── functions_9.js │ │ │ ├── functions_a.html │ │ │ ├── functions_a.js │ │ │ ├── nomatches.html │ │ │ ├── search.css │ │ │ ├── search.js │ │ │ ├── searchdata.js │ │ │ ├── variables_0.html │ │ │ ├── variables_0.js │ │ │ ├── variables_1.html │ │ │ ├── variables_1.js │ │ │ ├── variables_2.html │ │ │ ├── variables_2.js │ │ │ ├── variables_3.html │ │ │ ├── variables_3.js │ │ │ ├── variables_4.html │ │ │ ├── variables_4.js │ │ │ ├── variables_5.html │ │ │ ├── variables_5.js │ │ │ ├── variables_6.html │ │ │ ├── variables_6.js │ │ │ ├── variables_7.html │ │ │ └── variables_7.js │ │ ├── search_8js.html │ │ ├── searchdata_8js.html │ │ └── tabs.css │ └── tts_sample/ │ ├── 32bit_make.sh │ ├── 64bit_make.sh │ ├── Makefile │ └── tts_sample.c ├── include/ │ ├── .msp_cmn.h.swp │ ├── convert.h │ ├── msp_cmn.h │ ├── msp_errors.h │ ├── msp_types.h │ └── qtts.h └── xf.go ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitattributes ================================================ *.js linguist-language=Go *.css linguist-language=Go *.html linguist-language=Go *.c linguist-language=Go *.h linguist-language=Go ================================================ FILE: README.md ================================================ ontts ============== ontts 是语音在线合成服务 ## 编译 ##### GOPATH 项目源文件需要放在$GOPATH下 ##### glide 通过glide管理依赖,若没有安装glide,需先安装 Ubuntu下glide安装方法: ``` sh sudo add-apt-repository ppa:masterminds/glide && sudo apt-get update sudo apt-get install glide ``` 在源文件目录下执行以下命令下载依赖 ``` sh glide install ``` ##### 编译 ``` sh go build ``` ##### 运行 需要将libmsc.so加入环境变量 ``` sh mv xf/lib/libmsc.so /usr/local/lib/ vi ~/.bashrc ``` export LD_LIBRARY_PATH=/usr/local/lib ## 使用示例 ##### 单次合成: ``` sh ./ontts -t "云喇叭快递,快递小管家,您的快递到了,请于下午6点前到学校后门申通快递取件" -o test.wav ``` ##### 启动合成后台服务: ``` sh ./ontts -r ":6379" -d /tmp/out ``` ## 命令参数
讯飞语音参数选项:
    -tp                  TTS合成参数[有默认值]
    -lp                  登录参数[有默认值]

单次合成模式选项:
    -t                 	待合成的文本
    -o                	音频输出路径 

合成服务模式选项:
    -d                     音频保存的目录 
    -s                   合成速度级别(1-10),数值越小速度越快,越耗CPU[默认为1]
    -r                    redis连接地址

日志选项:
    -l                    日志输出路径[默认./ontts.log]
    -ll                  日志输出级别(debug,info,warn,error)

其他:
    -h                          查看帮助 
## 目录
── ontts
   ├── glide.yaml (glide依赖配置)
   ├── main.go (程序入口)
   ├── README.md
   ├── server (TTS合成主体逻辑的package)
   │   └── server.go
   ├── speed_test.go (速度测试)
   └── xf (讯飞SDK的Go封装)
       ├── doc (讯飞语音linux SDK相关参考)
       ├── include (cgo需要用到的头文件)
       ├── lib (动态链接库 SDK)
       │   └── libmsc.so
       ├── README.md
       └── xf.go
================================================ FILE: glide.yaml ================================================ package: ontts import: - package: github.com/imroc/log ================================================ FILE: main.go ================================================ package main import ( "flag" "fmt" "ontts/server" "os" "strings" "github.com/imroc/log" ) var usageStr = ` Usage: ontts [options] 讯飞语音参数选项: -tp TTS合成参数[有默认值] -lp 登录参数[有默认值] 单次合成模式选项: -t 待合成的文本 -o 音频输出路径 合成服务模式选项: -d 音频保存的目录 -b 音频备份的目录 -s 合成速度级别(1-10),数值越小速度越快,越耗CPU[默认为1] -r redis连接地址 -rp redis密码 日志选项: -l 日志输出路径[默认./ontts.log] -ll 日志输出级别(debug,info,warn,error) 其他: -h 查看帮助 ` func main() { opts := &server.Options{} var txt string var out string var help bool var logFile string var logLevel string flag.StringVar(&txt, "t", "", "单次合成的文本") flag.StringVar(&out, "o", "", "单次合成的输出路径") flag.StringVar(&logFile, "l", "ontts.log", "日志输出路径") flag.StringVar(&logLevel, "ll", "debug", "日志输出级别") flag.BoolVar(&help, "h", false, "Help") flag.StringVar(&opts.TTSParams, "tp", "voice_name = xiaoqi, text_encoding = UTF8, sample_rate = 8000, speed = 50, volume = 50, pitch = 50, rdn = 2", "TTS合成参数") flag.StringVar(&opts.LoginParams, "lp", "appid = 5718a335, work_dir = .", "登录参数") flag.StringVar(&opts.RedisAddr, "r", ":6379", "redis连接地址") flag.StringVar(&opts.RedisPass, "rp", "", "redis连接密码") flag.StringVar(&opts.OutDir, "d", "", "音频输出目录") flag.StringVar(&opts.BackupDir, "b", "", "音频保存目录") flag.IntVar(&opts.Speed, "s", 1, "合成速度") flag.Parse() if help { fmt.Printf("%s\n", usageStr) return } err := configureLog(logFile, logLevel) if err != nil { log.Error("日志配置失败:%v", err) return } s := server.New(opts) if txt != "" { // 单次合成 if out == "" { out = txt + ".wav" } log.Debug("合成文本:%q,输出:%s", txt, out) if err = s.Once(txt, out); err != nil { log.Error("%v", err) return } } s.Start() } func configureLog(logFile, logLevel string) error { level := log.DEBUG switch strings.ToLower(logLevel) { case "debug": level = log.DEBUG case "info": level = log.INFO case "warn": level = log.WARN case "error": level = log.ERROR } file, err := os.OpenFile(logFile, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666) if err != nil { return err } log.Set(level, file, log.Lshortfile|log.LstdFlags) return nil } ================================================ FILE: server/server.go ================================================ package server import ( "encoding/json" "fmt" "io" "ontts/xf" "os" "strings" "time" "github.com/garyburd/redigo/redis" "github.com/imroc/log" ) type Server struct { opts *Options } type Options struct { OutDir string //音频输出目录 BackupDir string // 备份目录,文件输出成功之后,再将文件复制到备份目录 Level int //音频生成速度级别,越快越耗CPU,级别1~10,数字越小速度越快 TTSParams string LoginParams string RedisAddr string RedisPass string Speed int } type Speech struct { Id string `json:"id"` Txt string `json:"txt"` } func New(opts *Options) *Server { return &Server{ opts: opts, } } func (s *Server) Start() { var c redis.Conn var err error if s.opts.RedisPass == "" { c, err = redis.Dial("tcp", s.opts.RedisAddr) } else { c, err = redis.Dial("tcp", s.opts.RedisAddr, redis.DialPassword(s.opts.RedisPass)) } if err != nil { log.Error("failed to connect redis:%v") return } defer c.Close() psc := redis.PubSubConn{Conn: c} err = psc.Subscribe("tts") if err != nil { log.Error("failed to subscribe:%v", err) return } sub, ok := psc.Receive().(redis.Subscription) if !ok { log.Error("first message is not subscription") return } if sub.Count == 0 { log.Error("redis subscription count is 0") return } err = setXF(s.opts.Speed, s.opts.TTSParams, s.opts.LoginParams) if err != nil { log.Error("failed to set xunfei params:%v", err) return } if s.opts.OutDir != "" && s.opts.OutDir[len(s.opts.OutDir)-1] != os.PathSeparator { s.opts.OutDir += string(os.PathSeparator) } if s.opts.BackupDir != "" && s.opts.BackupDir[len(s.opts.BackupDir)-1] != os.PathSeparator { s.opts.BackupDir += string(os.PathSeparator) } var speech Speech for { switch n := psc.Receive().(type) { case redis.Message: err := json.Unmarshal(n.Data, &speech) if err != nil { log.Error("error unmarshal:%v", err) continue } if len(strings.Fields(speech.Txt)) == 0 { // 忽略空白字符串,会导致语音合成参数错误 continue } tryN := 0 ttsFilename := s.opts.OutDir + speech.Id + ".wav" TTS: err = xf.TextToSpeech(speech.Txt, ttsFilename) if err != nil { tryN++ log.Error("error convert:%v,tts ID:%s,TXT:%s", err, speech.Id, speech.Txt) if tryN > 5 { // 多次重试失败,忽略此条语音的合成 continue } time.Sleep(5 * time.Second) goto TTS } log.Debug("合成ID:%s,TXT:%s", speech.Id, speech.Txt) if s.opts.BackupDir != "" { src, _err := os.Open(ttsFilename) if _err != nil { log.Error("failed to open file %s:%v", ttsFilename, _err) } filename := s.opts.BackupDir + speech.Id + ".wav" dst, _err := os.Create(filename) if _err != nil { log.Error("failed to create file %s:%v", filename, _err) } else { _, _err = io.Copy(dst, src) if _err != nil { log.Error("failed to copy file %s->%s:%v", ttsFilename, filename, _err) } } } case error: log.Error("error redis message:%v", n) time.Sleep(10 * time.Second) default: log.Warn("unknown message:%v", n) } } } func (s *Server) Once(txt string, desPath string) error { log.Debug("tts:%s,login:%s", s.opts.TTSParams, s.opts.LoginParams) xf.SetTTSParams(s.opts.TTSParams) err := xf.Login(s.opts.LoginParams) if err != nil { return err } //不SetSleep,默认为0,单次合成以高性能模式 log.Debug("txt:%s,des_path:%s", txt, desPath) err = xf.TextToSpeech(txt, desPath) if err != nil { return err } return nil } func setXF(speedLevel int, ttsParams, loginParams string) error { if speedLevel < 1 || speedLevel > 10 { return fmt.Errorf("wrong speed level:%d,it should between 1 and 10", speedLevel) } sleepTime := 15000 * (speedLevel - 1) xf.SetSleep(sleepTime) xf.SetTTSParams(ttsParams) err := xf.Login(loginParams) if err != nil { return err } return nil } ================================================ FILE: speed_test.go ================================================ package main import ( "fmt" "math/rand" "ontts/xf" "os" "testing" "time" "github.com/imroc/log" ) func TestSpeed(t *testing.T) { file, _ := os.OpenFile("test.log", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666) log.Set(log.DEBUG, file, log.LstdFlags) xf.SetTTSParams("voice_name = xiaoqi, text_encoding = UTF8, sample_rate = 8000, speed = 50, volume = 50, pitch = 50, rdn = 2") xf.SetSleep(0) err := xf.Login("appid = 5718a335, work_dir = .") if err != nil { log.Error("err:%v", err) return } now := time.Now() var txt string for i := 1; i < 1000; i++ { txt = getRandomString(r.Intn(21) + 40) err = xf.TextToSpeech(txt, fmt.Sprintf("/home/roc/wav/%d.wav", i)) if err != nil { log.Error("err:%v", err) return } log.Debug("已生成第%d个:%s,共用%f秒", i, txt, time.Since(now).Seconds()) } log.Info("执行完毕,总消耗:%f秒", time.Since(now).Seconds()) xf.Logout() } var start rune = 0x4e00 var stop rune = 0x9fa5 var n int32 = int32(stop - start) var r *rand.Rand = rand.New(rand.NewSource(time.Now().UnixNano())) func getRandomString(l int) string { s := make([]rune, l) for i := 0; i < l; i++ { s[i] = rune(r.Int31n(n) + start) } return string(s) } ================================================ FILE: vendor/github.com/garyburd/redigo/.travis.yml ================================================ language: go sudo: false services: - redis-server go: - 1.4 - 1.5 - 1.6 - 1.7 - tip script: - go get -t -v ./... - diff -u <(echo -n) <(gofmt -d .) - go vet $(go list ./... | grep -v /vendor/) - go test -v -race ./... ================================================ FILE: vendor/github.com/garyburd/redigo/LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. ================================================ FILE: vendor/github.com/garyburd/redigo/README.markdown ================================================ Redigo ====== [![Build Status](https://travis-ci.org/garyburd/redigo.svg?branch=master)](https://travis-ci.org/garyburd/redigo) [![GoDoc](https://godoc.org/github.com/garyburd/redigo/redis?status.svg)](https://godoc.org/github.com/garyburd/redigo/redis) Redigo is a [Go](http://golang.org/) client for the [Redis](http://redis.io/) database. Features ------- * A [Print-like](http://godoc.org/github.com/garyburd/redigo/redis#hdr-Executing_Commands) API with support for all Redis commands. * [Pipelining](http://godoc.org/github.com/garyburd/redigo/redis#hdr-Pipelining), including pipelined transactions. * [Publish/Subscribe](http://godoc.org/github.com/garyburd/redigo/redis#hdr-Publish_and_Subscribe). * [Connection pooling](http://godoc.org/github.com/garyburd/redigo/redis#Pool). * [Script helper type](http://godoc.org/github.com/garyburd/redigo/redis#Script) with optimistic use of EVALSHA. * [Helper functions](http://godoc.org/github.com/garyburd/redigo/redis#hdr-Reply_Helpers) for working with command replies. Documentation ------------- - [API Reference](http://godoc.org/github.com/garyburd/redigo/redis) - [FAQ](https://github.com/garyburd/redigo/wiki/FAQ) Installation ------------ Install Redigo using the "go get" command: go get github.com/garyburd/redigo/redis The Go distribution is Redigo's only dependency. Related Projects ---------------- - [rafaeljusto/redigomock](https://godoc.org/github.com/rafaeljusto/redigomock) - A mock library for Redigo. - [chasex/redis-go-cluster](https://github.com/chasex/redis-go-cluster) - A Redis cluster client implementation. - [FZambia/go-sentinel](https://github.com/FZambia/go-sentinel) - Redis Sentinel support for Redigo - [PuerkitoBio/redisc](https://github.com/PuerkitoBio/redisc) - Redis Cluster client built on top of Redigo Contributing ------------ Send email to Gary Burd (address in GitHub profile) before doing any work on Redigo. License ------- Redigo is available under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.html). ================================================ FILE: vendor/github.com/garyburd/redigo/internal/commandinfo.go ================================================ // Copyright 2014 Gary Burd // // Licensed under the Apache License, Version 2.0 (the "License"): you may // not use this file except in compliance with the License. You may obtain // a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. package internal // import "github.com/garyburd/redigo/internal" import ( "strings" ) const ( WatchState = 1 << iota MultiState SubscribeState MonitorState ) type CommandInfo struct { Set, Clear int } var commandInfos = map[string]CommandInfo{ "WATCH": {Set: WatchState}, "UNWATCH": {Clear: WatchState}, "MULTI": {Set: MultiState}, "EXEC": {Clear: WatchState | MultiState}, "DISCARD": {Clear: WatchState | MultiState}, "PSUBSCRIBE": {Set: SubscribeState}, "SUBSCRIBE": {Set: SubscribeState}, "MONITOR": {Set: MonitorState}, } func init() { for n, ci := range commandInfos { commandInfos[strings.ToLower(n)] = ci } } func LookupCommandInfo(commandName string) CommandInfo { if ci, ok := commandInfos[commandName]; ok { return ci } return commandInfos[strings.ToUpper(commandName)] } ================================================ FILE: vendor/github.com/garyburd/redigo/internal/commandinfo_test.go ================================================ package internal import "testing" func TestLookupCommandInfo(t *testing.T) { for _, n := range []string{"watch", "WATCH", "wAtch"} { if LookupCommandInfo(n) == (CommandInfo{}) { t.Errorf("LookupCommandInfo(%q) = CommandInfo{}, expected non-zero value", n) } } } func benchmarkLookupCommandInfo(b *testing.B, names ...string) { for i := 0; i < b.N; i++ { for _, c := range names { LookupCommandInfo(c) } } } func BenchmarkLookupCommandInfoCorrectCase(b *testing.B) { benchmarkLookupCommandInfo(b, "watch", "WATCH", "monitor", "MONITOR") } func BenchmarkLookupCommandInfoMixedCase(b *testing.B) { benchmarkLookupCommandInfo(b, "wAtch", "WeTCH", "monItor", "MONiTOR") } ================================================ FILE: vendor/github.com/garyburd/redigo/internal/redistest/testdb.go ================================================ // Copyright 2014 Gary Burd // // Licensed under the Apache License, Version 2.0 (the "License"): you may // not use this file except in compliance with the License. You may obtain // a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. // Package redistest contains utilities for writing Redigo tests. package redistest import ( "errors" "time" "github.com/garyburd/redigo/redis" ) type testConn struct { redis.Conn } func (t testConn) Close() error { _, err := t.Conn.Do("SELECT", "9") if err != nil { return nil } _, err = t.Conn.Do("FLUSHDB") if err != nil { return err } return t.Conn.Close() } // Dial dials the local Redis server and selects database 9. To prevent // stomping on real data, DialTestDB fails if database 9 contains data. The // returned connection flushes database 9 on close. func Dial() (redis.Conn, error) { c, err := redis.DialTimeout("tcp", ":6379", 0, 1*time.Second, 1*time.Second) if err != nil { return nil, err } _, err = c.Do("SELECT", "9") if err != nil { c.Close() return nil, err } n, err := redis.Int(c.Do("DBSIZE")) if err != nil { c.Close() return nil, err } if n != 0 { c.Close() return nil, errors.New("database #9 is not empty, test can not continue") } return testConn{c}, nil } ================================================ FILE: vendor/github.com/garyburd/redigo/redis/conn.go ================================================ // Copyright 2012 Gary Burd // // Licensed under the Apache License, Version 2.0 (the "License"): you may // not use this file except in compliance with the License. You may obtain // a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. package redis import ( "bufio" "bytes" "errors" "fmt" "io" "net" "net/url" "regexp" "strconv" "sync" "time" ) // conn is the low-level implementation of Conn type conn struct { // Shared mu sync.Mutex pending int err error conn net.Conn // Read readTimeout time.Duration br *bufio.Reader // Write writeTimeout time.Duration bw *bufio.Writer // Scratch space for formatting argument length. // '*' or '$', length, "\r\n" lenScratch [32]byte // Scratch space for formatting integers and floats. numScratch [40]byte } // DialTimeout acts like Dial but takes timeouts for establishing the // connection to the server, writing a command and reading a reply. // // Deprecated: Use Dial with options instead. func DialTimeout(network, address string, connectTimeout, readTimeout, writeTimeout time.Duration) (Conn, error) { return Dial(network, address, DialConnectTimeout(connectTimeout), DialReadTimeout(readTimeout), DialWriteTimeout(writeTimeout)) } // DialOption specifies an option for dialing a Redis server. type DialOption struct { f func(*dialOptions) } type dialOptions struct { readTimeout time.Duration writeTimeout time.Duration dial func(network, addr string) (net.Conn, error) db int password string } // DialReadTimeout specifies the timeout for reading a single command reply. func DialReadTimeout(d time.Duration) DialOption { return DialOption{func(do *dialOptions) { do.readTimeout = d }} } // DialWriteTimeout specifies the timeout for writing a single command. func DialWriteTimeout(d time.Duration) DialOption { return DialOption{func(do *dialOptions) { do.writeTimeout = d }} } // DialConnectTimeout specifies the timeout for connecting to the Redis server. func DialConnectTimeout(d time.Duration) DialOption { return DialOption{func(do *dialOptions) { dialer := net.Dialer{Timeout: d} do.dial = dialer.Dial }} } // DialNetDial specifies a custom dial function for creating TCP // connections. If this option is left out, then net.Dial is // used. DialNetDial overrides DialConnectTimeout. func DialNetDial(dial func(network, addr string) (net.Conn, error)) DialOption { return DialOption{func(do *dialOptions) { do.dial = dial }} } // DialDatabase specifies the database to select when dialing a connection. func DialDatabase(db int) DialOption { return DialOption{func(do *dialOptions) { do.db = db }} } // DialPassword specifies the password to use when connecting to // the Redis server. func DialPassword(password string) DialOption { return DialOption{func(do *dialOptions) { do.password = password }} } // Dial connects to the Redis server at the given network and // address using the specified options. func Dial(network, address string, options ...DialOption) (Conn, error) { do := dialOptions{ dial: net.Dial, } for _, option := range options { option.f(&do) } netConn, err := do.dial(network, address) if err != nil { return nil, err } c := &conn{ conn: netConn, bw: bufio.NewWriter(netConn), br: bufio.NewReader(netConn), readTimeout: do.readTimeout, writeTimeout: do.writeTimeout, } if do.password != "" { if _, err := c.Do("AUTH", do.password); err != nil { netConn.Close() return nil, err } } if do.db != 0 { if _, err := c.Do("SELECT", do.db); err != nil { netConn.Close() return nil, err } } return c, nil } var pathDBRegexp = regexp.MustCompile(`/(\d*)\z`) // DialURL connects to a Redis server at the given URL using the Redis // URI scheme. URLs should follow the draft IANA specification for the // scheme (https://www.iana.org/assignments/uri-schemes/prov/redis). func DialURL(rawurl string, options ...DialOption) (Conn, error) { u, err := url.Parse(rawurl) if err != nil { return nil, err } if u.Scheme != "redis" { return nil, fmt.Errorf("invalid redis URL scheme: %s", u.Scheme) } // As per the IANA draft spec, the host defaults to localhost and // the port defaults to 6379. host, port, err := net.SplitHostPort(u.Host) if err != nil { // assume port is missing host = u.Host port = "6379" } if host == "" { host = "localhost" } address := net.JoinHostPort(host, port) if u.User != nil { password, isSet := u.User.Password() if isSet { options = append(options, DialPassword(password)) } } match := pathDBRegexp.FindStringSubmatch(u.Path) if len(match) == 2 { db := 0 if len(match[1]) > 0 { db, err = strconv.Atoi(match[1]) if err != nil { return nil, fmt.Errorf("invalid database: %s", u.Path[1:]) } } if db != 0 { options = append(options, DialDatabase(db)) } } else if u.Path != "" { return nil, fmt.Errorf("invalid database: %s", u.Path[1:]) } return Dial("tcp", address, options...) } // NewConn returns a new Redigo connection for the given net connection. func NewConn(netConn net.Conn, readTimeout, writeTimeout time.Duration) Conn { return &conn{ conn: netConn, bw: bufio.NewWriter(netConn), br: bufio.NewReader(netConn), readTimeout: readTimeout, writeTimeout: writeTimeout, } } func (c *conn) Close() error { c.mu.Lock() err := c.err if c.err == nil { c.err = errors.New("redigo: closed") err = c.conn.Close() } c.mu.Unlock() return err } func (c *conn) fatal(err error) error { c.mu.Lock() if c.err == nil { c.err = err // Close connection to force errors on subsequent calls and to unblock // other reader or writer. c.conn.Close() } c.mu.Unlock() return err } func (c *conn) Err() error { c.mu.Lock() err := c.err c.mu.Unlock() return err } func (c *conn) writeLen(prefix byte, n int) error { c.lenScratch[len(c.lenScratch)-1] = '\n' c.lenScratch[len(c.lenScratch)-2] = '\r' i := len(c.lenScratch) - 3 for { c.lenScratch[i] = byte('0' + n%10) i -= 1 n = n / 10 if n == 0 { break } } c.lenScratch[i] = prefix _, err := c.bw.Write(c.lenScratch[i:]) return err } func (c *conn) writeString(s string) error { c.writeLen('$', len(s)) c.bw.WriteString(s) _, err := c.bw.WriteString("\r\n") return err } func (c *conn) writeBytes(p []byte) error { c.writeLen('$', len(p)) c.bw.Write(p) _, err := c.bw.WriteString("\r\n") return err } func (c *conn) writeInt64(n int64) error { return c.writeBytes(strconv.AppendInt(c.numScratch[:0], n, 10)) } func (c *conn) writeFloat64(n float64) error { return c.writeBytes(strconv.AppendFloat(c.numScratch[:0], n, 'g', -1, 64)) } func (c *conn) writeCommand(cmd string, args []interface{}) (err error) { c.writeLen('*', 1+len(args)) err = c.writeString(cmd) for _, arg := range args { if err != nil { break } switch arg := arg.(type) { case string: err = c.writeString(arg) case []byte: err = c.writeBytes(arg) case int: err = c.writeInt64(int64(arg)) case int64: err = c.writeInt64(arg) case float64: err = c.writeFloat64(arg) case bool: if arg { err = c.writeString("1") } else { err = c.writeString("0") } case nil: err = c.writeString("") default: var buf bytes.Buffer fmt.Fprint(&buf, arg) err = c.writeBytes(buf.Bytes()) } } return err } type protocolError string func (pe protocolError) Error() string { return fmt.Sprintf("redigo: %s (possible server error or unsupported concurrent read by application)", string(pe)) } func (c *conn) readLine() ([]byte, error) { p, err := c.br.ReadSlice('\n') if err == bufio.ErrBufferFull { return nil, protocolError("long response line") } if err != nil { return nil, err } i := len(p) - 2 if i < 0 || p[i] != '\r' { return nil, protocolError("bad response line terminator") } return p[:i], nil } // parseLen parses bulk string and array lengths. func parseLen(p []byte) (int, error) { if len(p) == 0 { return -1, protocolError("malformed length") } if p[0] == '-' && len(p) == 2 && p[1] == '1' { // handle $-1 and $-1 null replies. return -1, nil } var n int for _, b := range p { n *= 10 if b < '0' || b > '9' { return -1, protocolError("illegal bytes in length") } n += int(b - '0') } return n, nil } // parseInt parses an integer reply. func parseInt(p []byte) (interface{}, error) { if len(p) == 0 { return 0, protocolError("malformed integer") } var negate bool if p[0] == '-' { negate = true p = p[1:] if len(p) == 0 { return 0, protocolError("malformed integer") } } var n int64 for _, b := range p { n *= 10 if b < '0' || b > '9' { return 0, protocolError("illegal bytes in length") } n += int64(b - '0') } if negate { n = -n } return n, nil } var ( okReply interface{} = "OK" pongReply interface{} = "PONG" ) func (c *conn) readReply() (interface{}, error) { line, err := c.readLine() if err != nil { return nil, err } if len(line) == 0 { return nil, protocolError("short response line") } switch line[0] { case '+': switch { case len(line) == 3 && line[1] == 'O' && line[2] == 'K': // Avoid allocation for frequent "+OK" response. return okReply, nil case len(line) == 5 && line[1] == 'P' && line[2] == 'O' && line[3] == 'N' && line[4] == 'G': // Avoid allocation in PING command benchmarks :) return pongReply, nil default: return string(line[1:]), nil } case '-': return Error(string(line[1:])), nil case ':': return parseInt(line[1:]) case '$': n, err := parseLen(line[1:]) if n < 0 || err != nil { return nil, err } p := make([]byte, n) _, err = io.ReadFull(c.br, p) if err != nil { return nil, err } if line, err := c.readLine(); err != nil { return nil, err } else if len(line) != 0 { return nil, protocolError("bad bulk string format") } return p, nil case '*': n, err := parseLen(line[1:]) if n < 0 || err != nil { return nil, err } r := make([]interface{}, n) for i := range r { r[i], err = c.readReply() if err != nil { return nil, err } } return r, nil } return nil, protocolError("unexpected response line") } func (c *conn) Send(cmd string, args ...interface{}) error { c.mu.Lock() c.pending += 1 c.mu.Unlock() if c.writeTimeout != 0 { c.conn.SetWriteDeadline(time.Now().Add(c.writeTimeout)) } if err := c.writeCommand(cmd, args); err != nil { return c.fatal(err) } return nil } func (c *conn) Flush() error { if c.writeTimeout != 0 { c.conn.SetWriteDeadline(time.Now().Add(c.writeTimeout)) } if err := c.bw.Flush(); err != nil { return c.fatal(err) } return nil } func (c *conn) Receive() (reply interface{}, err error) { if c.readTimeout != 0 { c.conn.SetReadDeadline(time.Now().Add(c.readTimeout)) } if reply, err = c.readReply(); err != nil { return nil, c.fatal(err) } // When using pub/sub, the number of receives can be greater than the // number of sends. To enable normal use of the connection after // unsubscribing from all channels, we do not decrement pending to a // negative value. // // The pending field is decremented after the reply is read to handle the // case where Receive is called before Send. c.mu.Lock() if c.pending > 0 { c.pending -= 1 } c.mu.Unlock() if err, ok := reply.(Error); ok { return nil, err } return } func (c *conn) Do(cmd string, args ...interface{}) (interface{}, error) { c.mu.Lock() pending := c.pending c.pending = 0 c.mu.Unlock() if cmd == "" && pending == 0 { return nil, nil } if c.writeTimeout != 0 { c.conn.SetWriteDeadline(time.Now().Add(c.writeTimeout)) } if cmd != "" { if err := c.writeCommand(cmd, args); err != nil { return nil, c.fatal(err) } } if err := c.bw.Flush(); err != nil { return nil, c.fatal(err) } if c.readTimeout != 0 { c.conn.SetReadDeadline(time.Now().Add(c.readTimeout)) } if cmd == "" { reply := make([]interface{}, pending) for i := range reply { r, e := c.readReply() if e != nil { return nil, c.fatal(e) } reply[i] = r } return reply, nil } var err error var reply interface{} for i := 0; i <= pending; i++ { var e error if reply, e = c.readReply(); e != nil { return nil, c.fatal(e) } if e, ok := reply.(Error); ok && err == nil { err = e } } return reply, err } ================================================ FILE: vendor/github.com/garyburd/redigo/redis/conn_test.go ================================================ // Copyright 2012 Gary Burd // // Licensed under the Apache License, Version 2.0 (the "License"): you may // not use this file except in compliance with the License. You may obtain // a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. package redis_test import ( "bytes" "io" "math" "net" "os" "reflect" "strings" "testing" "time" "github.com/garyburd/redigo/redis" ) type testConn struct { io.Reader io.Writer } func (*testConn) Close() error { return nil } func (*testConn) LocalAddr() net.Addr { return nil } func (*testConn) RemoteAddr() net.Addr { return nil } func (*testConn) SetDeadline(t time.Time) error { return nil } func (*testConn) SetReadDeadline(t time.Time) error { return nil } func (*testConn) SetWriteDeadline(t time.Time) error { return nil } func dialTestConn(r io.Reader, w io.Writer) redis.DialOption { return redis.DialNetDial(func(net, addr string) (net.Conn, error) { return &testConn{Reader: r, Writer: w}, nil }) } var writeTests = []struct { args []interface{} expected string }{ { []interface{}{"SET", "key", "value"}, "*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$5\r\nvalue\r\n", }, { []interface{}{"SET", "key", "value"}, "*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$5\r\nvalue\r\n", }, { []interface{}{"SET", "key", byte(100)}, "*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$3\r\n100\r\n", }, { []interface{}{"SET", "key", 100}, "*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$3\r\n100\r\n", }, { []interface{}{"SET", "key", int64(math.MinInt64)}, "*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$20\r\n-9223372036854775808\r\n", }, { []interface{}{"SET", "key", float64(1349673917.939762)}, "*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$21\r\n1.349673917939762e+09\r\n", }, { []interface{}{"SET", "key", ""}, "*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$0\r\n\r\n", }, { []interface{}{"SET", "key", nil}, "*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$0\r\n\r\n", }, { []interface{}{"ECHO", true, false}, "*3\r\n$4\r\nECHO\r\n$1\r\n1\r\n$1\r\n0\r\n", }, } func TestWrite(t *testing.T) { for _, tt := range writeTests { var buf bytes.Buffer c, _ := redis.Dial("", "", dialTestConn(nil, &buf)) err := c.Send(tt.args[0].(string), tt.args[1:]...) if err != nil { t.Errorf("Send(%v) returned error %v", tt.args, err) continue } c.Flush() actual := buf.String() if actual != tt.expected { t.Errorf("Send(%v) = %q, want %q", tt.args, actual, tt.expected) } } } var errorSentinel = &struct{}{} var readTests = []struct { reply string expected interface{} }{ { "+OK\r\n", "OK", }, { "+PONG\r\n", "PONG", }, { "@OK\r\n", errorSentinel, }, { "$6\r\nfoobar\r\n", []byte("foobar"), }, { "$-1\r\n", nil, }, { ":1\r\n", int64(1), }, { ":-2\r\n", int64(-2), }, { "*0\r\n", []interface{}{}, }, { "*-1\r\n", nil, }, { "*4\r\n$3\r\nfoo\r\n$3\r\nbar\r\n$5\r\nHello\r\n$5\r\nWorld\r\n", []interface{}{[]byte("foo"), []byte("bar"), []byte("Hello"), []byte("World")}, }, { "*3\r\n$3\r\nfoo\r\n$-1\r\n$3\r\nbar\r\n", []interface{}{[]byte("foo"), nil, []byte("bar")}, }, { // "x" is not a valid length "$x\r\nfoobar\r\n", errorSentinel, }, { // -2 is not a valid length "$-2\r\n", errorSentinel, }, { // "x" is not a valid integer ":x\r\n", errorSentinel, }, { // missing \r\n following value "$6\r\nfoobar", errorSentinel, }, { // short value "$6\r\nxx", errorSentinel, }, { // long value "$6\r\nfoobarx\r\n", errorSentinel, }, } func TestRead(t *testing.T) { for _, tt := range readTests { c, _ := redis.Dial("", "", dialTestConn(strings.NewReader(tt.reply), nil)) actual, err := c.Receive() if tt.expected == errorSentinel { if err == nil { t.Errorf("Receive(%q) did not return expected error", tt.reply) } } else { if err != nil { t.Errorf("Receive(%q) returned error %v", tt.reply, err) continue } if !reflect.DeepEqual(actual, tt.expected) { t.Errorf("Receive(%q) = %v, want %v", tt.reply, actual, tt.expected) } } } } var testCommands = []struct { args []interface{} expected interface{} }{ { []interface{}{"PING"}, "PONG", }, { []interface{}{"SET", "foo", "bar"}, "OK", }, { []interface{}{"GET", "foo"}, []byte("bar"), }, { []interface{}{"GET", "nokey"}, nil, }, { []interface{}{"MGET", "nokey", "foo"}, []interface{}{nil, []byte("bar")}, }, { []interface{}{"INCR", "mycounter"}, int64(1), }, { []interface{}{"LPUSH", "mylist", "foo"}, int64(1), }, { []interface{}{"LPUSH", "mylist", "bar"}, int64(2), }, { []interface{}{"LRANGE", "mylist", 0, -1}, []interface{}{[]byte("bar"), []byte("foo")}, }, { []interface{}{"MULTI"}, "OK", }, { []interface{}{"LRANGE", "mylist", 0, -1}, "QUEUED", }, { []interface{}{"PING"}, "QUEUED", }, { []interface{}{"EXEC"}, []interface{}{ []interface{}{[]byte("bar"), []byte("foo")}, "PONG", }, }, } func TestDoCommands(t *testing.T) { c, err := redis.DialDefaultServer() if err != nil { t.Fatalf("error connection to database, %v", err) } defer c.Close() for _, cmd := range testCommands { actual, err := c.Do(cmd.args[0].(string), cmd.args[1:]...) if err != nil { t.Errorf("Do(%v) returned error %v", cmd.args, err) continue } if !reflect.DeepEqual(actual, cmd.expected) { t.Errorf("Do(%v) = %v, want %v", cmd.args, actual, cmd.expected) } } } func TestPipelineCommands(t *testing.T) { c, err := redis.DialDefaultServer() if err != nil { t.Fatalf("error connection to database, %v", err) } defer c.Close() for _, cmd := range testCommands { if err := c.Send(cmd.args[0].(string), cmd.args[1:]...); err != nil { t.Fatalf("Send(%v) returned error %v", cmd.args, err) } } if err := c.Flush(); err != nil { t.Errorf("Flush() returned error %v", err) } for _, cmd := range testCommands { actual, err := c.Receive() if err != nil { t.Fatalf("Receive(%v) returned error %v", cmd.args, err) } if !reflect.DeepEqual(actual, cmd.expected) { t.Errorf("Receive(%v) = %v, want %v", cmd.args, actual, cmd.expected) } } } func TestBlankCommmand(t *testing.T) { c, err := redis.DialDefaultServer() if err != nil { t.Fatalf("error connection to database, %v", err) } defer c.Close() for _, cmd := range testCommands { if err := c.Send(cmd.args[0].(string), cmd.args[1:]...); err != nil { t.Fatalf("Send(%v) returned error %v", cmd.args, err) } } reply, err := redis.Values(c.Do("")) if err != nil { t.Fatalf("Do() returned error %v", err) } if len(reply) != len(testCommands) { t.Fatalf("len(reply)=%d, want %d", len(reply), len(testCommands)) } for i, cmd := range testCommands { actual := reply[i] if !reflect.DeepEqual(actual, cmd.expected) { t.Errorf("Receive(%v) = %v, want %v", cmd.args, actual, cmd.expected) } } } func TestRecvBeforeSend(t *testing.T) { c, err := redis.DialDefaultServer() if err != nil { t.Fatalf("error connection to database, %v", err) } defer c.Close() done := make(chan struct{}) go func() { c.Receive() close(done) }() time.Sleep(time.Millisecond) c.Send("PING") c.Flush() <-done _, err = c.Do("") if err != nil { t.Fatalf("error=%v", err) } } func TestError(t *testing.T) { c, err := redis.DialDefaultServer() if err != nil { t.Fatalf("error connection to database, %v", err) } defer c.Close() c.Do("SET", "key", "val") _, err = c.Do("HSET", "key", "fld", "val") if err == nil { t.Errorf("Expected err for HSET on string key.") } if c.Err() != nil { t.Errorf("Conn has Err()=%v, expect nil", c.Err()) } _, err = c.Do("SET", "key", "val") if err != nil { t.Errorf("Do(SET, key, val) returned error %v, expected nil.", err) } } func TestReadTimeout(t *testing.T) { l, err := net.Listen("tcp", "127.0.0.1:0") if err != nil { t.Fatalf("net.Listen returned %v", err) } defer l.Close() go func() { for { c, err := l.Accept() if err != nil { return } go func() { time.Sleep(time.Second) c.Write([]byte("+OK\r\n")) c.Close() }() } }() // Do c1, err := redis.Dial(l.Addr().Network(), l.Addr().String(), redis.DialReadTimeout(time.Millisecond)) if err != nil { t.Fatalf("redis.Dial returned %v", err) } defer c1.Close() _, err = c1.Do("PING") if err == nil { t.Fatalf("c1.Do() returned nil, expect error") } if c1.Err() == nil { t.Fatalf("c1.Err() = nil, expect error") } // Send/Flush/Receive c2, err := redis.Dial(l.Addr().Network(), l.Addr().String(), redis.DialReadTimeout(time.Millisecond)) if err != nil { t.Fatalf("redis.Dial returned %v", err) } defer c2.Close() c2.Send("PING") c2.Flush() _, err = c2.Receive() if err == nil { t.Fatalf("c2.Receive() returned nil, expect error") } if c2.Err() == nil { t.Fatalf("c2.Err() = nil, expect error") } } var dialErrors = []struct { rawurl string expectedError string }{ { "localhost", "invalid redis URL scheme", }, // The error message for invalid hosts is diffferent in different // versions of Go, so just check that there is an error message. { "redis://weird url", "", }, { "redis://foo:bar:baz", "", }, { "http://www.google.com", "invalid redis URL scheme: http", }, { "redis://localhost:6379/abc123", "invalid database: abc123", }, } func TestDialURLErrors(t *testing.T) { for _, d := range dialErrors { _, err := redis.DialURL(d.rawurl) if err == nil || !strings.Contains(err.Error(), d.expectedError) { t.Errorf("DialURL did not return expected error (expected %v to contain %s)", err, d.expectedError) } } } func TestDialURLPort(t *testing.T) { checkPort := func(network, address string) (net.Conn, error) { if address != "localhost:6379" { t.Errorf("DialURL did not set port to 6379 by default (got %v)", address) } return nil, nil } _, err := redis.DialURL("redis://localhost", redis.DialNetDial(checkPort)) if err != nil { t.Error("dial error:", err) } } func TestDialURLHost(t *testing.T) { checkHost := func(network, address string) (net.Conn, error) { if address != "localhost:6379" { t.Errorf("DialURL did not set host to localhost by default (got %v)", address) } return nil, nil } _, err := redis.DialURL("redis://:6379", redis.DialNetDial(checkHost)) if err != nil { t.Error("dial error:", err) } } func TestDialURLPassword(t *testing.T) { var buf bytes.Buffer _, err := redis.DialURL("redis://x:abc123@localhost", dialTestConn(strings.NewReader("+OK\r\n"), &buf)) if err != nil { t.Error("dial error:", err) } expected := "*2\r\n$4\r\nAUTH\r\n$6\r\nabc123\r\n" actual := buf.String() if actual != expected { t.Errorf("commands = %q, want %q", actual, expected) } } func TestDialURLDatabase(t *testing.T) { var buf3 bytes.Buffer _, err3 := redis.DialURL("redis://localhost/3", dialTestConn(strings.NewReader("+OK\r\n"), &buf3)) if err3 != nil { t.Error("dial error:", err3) } expected3 := "*2\r\n$6\r\nSELECT\r\n$1\r\n3\r\n" actual3 := buf3.String() if actual3 != expected3 { t.Errorf("commands = %q, want %q", actual3, expected3) } // empty DB means 0 var buf0 bytes.Buffer _, err0 := redis.DialURL("redis://localhost/", dialTestConn(strings.NewReader("+OK\r\n"), &buf0)) if err0 != nil { t.Error("dial error:", err0) } expected0 := "" actual0 := buf0.String() if actual0 != expected0 { t.Errorf("commands = %q, want %q", actual0, expected0) } } // Connect to local instance of Redis running on the default port. func ExampleDial() { c, err := redis.Dial("tcp", ":6379") if err != nil { // handle error } defer c.Close() } // Connect to remote instance of Redis using a URL. func ExampleDialURL() { c, err := redis.DialURL(os.Getenv("REDIS_URL")) if err != nil { // handle connection error } defer c.Close() } // TextExecError tests handling of errors in a transaction. See // http://redis.io/topics/transactions for information on how Redis handles // errors in a transaction. func TestExecError(t *testing.T) { c, err := redis.DialDefaultServer() if err != nil { t.Fatalf("error connection to database, %v", err) } defer c.Close() // Execute commands that fail before EXEC is called. c.Do("DEL", "k0") c.Do("ZADD", "k0", 0, 0) c.Send("MULTI") c.Send("NOTACOMMAND", "k0", 0, 0) c.Send("ZINCRBY", "k0", 0, 0) v, err := c.Do("EXEC") if err == nil { t.Fatalf("EXEC returned values %v, expected error", v) } // Execute commands that fail after EXEC is called. The first command // returns an error. c.Do("DEL", "k1") c.Do("ZADD", "k1", 0, 0) c.Send("MULTI") c.Send("HSET", "k1", 0, 0) c.Send("ZINCRBY", "k1", 0, 0) v, err = c.Do("EXEC") if err != nil { t.Fatalf("EXEC returned error %v", err) } vs, err := redis.Values(v, nil) if err != nil { t.Fatalf("Values(v) returned error %v", err) } if len(vs) != 2 { t.Fatalf("len(vs) == %d, want 2", len(vs)) } if _, ok := vs[0].(error); !ok { t.Fatalf("first result is type %T, expected error", vs[0]) } if _, ok := vs[1].([]byte); !ok { t.Fatalf("second result is type %T, expected []byte", vs[1]) } // Execute commands that fail after EXEC is called. The second command // returns an error. c.Do("ZADD", "k2", 0, 0) c.Send("MULTI") c.Send("ZINCRBY", "k2", 0, 0) c.Send("HSET", "k2", 0, 0) v, err = c.Do("EXEC") if err != nil { t.Fatalf("EXEC returned error %v", err) } vs, err = redis.Values(v, nil) if err != nil { t.Fatalf("Values(v) returned error %v", err) } if len(vs) != 2 { t.Fatalf("len(vs) == %d, want 2", len(vs)) } if _, ok := vs[0].([]byte); !ok { t.Fatalf("first result is type %T, expected []byte", vs[0]) } if _, ok := vs[1].(error); !ok { t.Fatalf("second result is type %T, expected error", vs[2]) } } func BenchmarkDoEmpty(b *testing.B) { b.StopTimer() c, err := redis.DialDefaultServer() if err != nil { b.Fatal(err) } defer c.Close() b.StartTimer() for i := 0; i < b.N; i++ { if _, err := c.Do(""); err != nil { b.Fatal(err) } } } func BenchmarkDoPing(b *testing.B) { b.StopTimer() c, err := redis.DialDefaultServer() if err != nil { b.Fatal(err) } defer c.Close() b.StartTimer() for i := 0; i < b.N; i++ { if _, err := c.Do("PING"); err != nil { b.Fatal(err) } } } ================================================ FILE: vendor/github.com/garyburd/redigo/redis/doc.go ================================================ // Copyright 2012 Gary Burd // // Licensed under the Apache License, Version 2.0 (the "License"): you may // not use this file except in compliance with the License. You may obtain // a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. // Package redis is a client for the Redis database. // // The Redigo FAQ (https://github.com/garyburd/redigo/wiki/FAQ) contains more // documentation about this package. // // Connections // // The Conn interface is the primary interface for working with Redis. // Applications create connections by calling the Dial, DialWithTimeout or // NewConn functions. In the future, functions will be added for creating // sharded and other types of connections. // // The application must call the connection Close method when the application // is done with the connection. // // Executing Commands // // The Conn interface has a generic method for executing Redis commands: // // Do(commandName string, args ...interface{}) (reply interface{}, err error) // // The Redis command reference (http://redis.io/commands) lists the available // commands. An example of using the Redis APPEND command is: // // n, err := conn.Do("APPEND", "key", "value") // // The Do method converts command arguments to binary strings for transmission // to the server as follows: // // Go Type Conversion // []byte Sent as is // string Sent as is // int, int64 strconv.FormatInt(v) // float64 strconv.FormatFloat(v, 'g', -1, 64) // bool true -> "1", false -> "0" // nil "" // all other types fmt.Print(v) // // Redis command reply types are represented using the following Go types: // // Redis type Go type // error redis.Error // integer int64 // simple string string // bulk string []byte or nil if value not present. // array []interface{} or nil if value not present. // // Use type assertions or the reply helper functions to convert from // interface{} to the specific Go type for the command result. // // Pipelining // // Connections support pipelining using the Send, Flush and Receive methods. // // Send(commandName string, args ...interface{}) error // Flush() error // Receive() (reply interface{}, err error) // // Send writes the command to the connection's output buffer. Flush flushes the // connection's output buffer to the server. Receive reads a single reply from // the server. The following example shows a simple pipeline. // // c.Send("SET", "foo", "bar") // c.Send("GET", "foo") // c.Flush() // c.Receive() // reply from SET // v, err = c.Receive() // reply from GET // // The Do method combines the functionality of the Send, Flush and Receive // methods. The Do method starts by writing the command and flushing the output // buffer. Next, the Do method receives all pending replies including the reply // for the command just sent by Do. If any of the received replies is an error, // then Do returns the error. If there are no errors, then Do returns the last // reply. If the command argument to the Do method is "", then the Do method // will flush the output buffer and receive pending replies without sending a // command. // // Use the Send and Do methods to implement pipelined transactions. // // c.Send("MULTI") // c.Send("INCR", "foo") // c.Send("INCR", "bar") // r, err := c.Do("EXEC") // fmt.Println(r) // prints [1, 1] // // Concurrency // // Connections support one concurrent caller to the Receive method and one // concurrent caller to the Send and Flush methods. No other concurrency is // supported including concurrent calls to the Do method. // // For full concurrent access to Redis, use the thread-safe Pool to get, use // and release a connection from within a goroutine. Connections returned from // a Pool have the concurrency restrictions described in the previous // paragraph. // // Publish and Subscribe // // Use the Send, Flush and Receive methods to implement Pub/Sub subscribers. // // c.Send("SUBSCRIBE", "example") // c.Flush() // for { // reply, err := c.Receive() // if err != nil { // return err // } // // process pushed message // } // // The PubSubConn type wraps a Conn with convenience methods for implementing // subscribers. The Subscribe, PSubscribe, Unsubscribe and PUnsubscribe methods // send and flush a subscription management command. The receive method // converts a pushed message to convenient types for use in a type switch. // // psc := redis.PubSubConn{c} // psc.Subscribe("example") // for { // switch v := psc.Receive().(type) { // case redis.Message: // fmt.Printf("%s: message: %s\n", v.Channel, v.Data) // case redis.Subscription: // fmt.Printf("%s: %s %d\n", v.Channel, v.Kind, v.Count) // case error: // return v // } // } // // Reply Helpers // // The Bool, Int, Bytes, String, Strings and Values functions convert a reply // to a value of a specific type. To allow convenient wrapping of calls to the // connection Do and Receive methods, the functions take a second argument of // type error. If the error is non-nil, then the helper function returns the // error. If the error is nil, the function converts the reply to the specified // type: // // exists, err := redis.Bool(c.Do("EXISTS", "foo")) // if err != nil { // // handle error return from c.Do or type conversion error. // } // // The Scan function converts elements of a array reply to Go types: // // var value1 int // var value2 string // reply, err := redis.Values(c.Do("MGET", "key1", "key2")) // if err != nil { // // handle error // } // if _, err := redis.Scan(reply, &value1, &value2); err != nil { // // handle error // } package redis // import "github.com/garyburd/redigo/redis" ================================================ FILE: vendor/github.com/garyburd/redigo/redis/log.go ================================================ // Copyright 2012 Gary Burd // // Licensed under the Apache License, Version 2.0 (the "License"): you may // not use this file except in compliance with the License. You may obtain // a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. package redis import ( "bytes" "fmt" "log" ) // NewLoggingConn returns a logging wrapper around a connection. func NewLoggingConn(conn Conn, logger *log.Logger, prefix string) Conn { if prefix != "" { prefix = prefix + "." } return &loggingConn{conn, logger, prefix} } type loggingConn struct { Conn logger *log.Logger prefix string } func (c *loggingConn) Close() error { err := c.Conn.Close() var buf bytes.Buffer fmt.Fprintf(&buf, "%sClose() -> (%v)", c.prefix, err) c.logger.Output(2, buf.String()) return err } func (c *loggingConn) printValue(buf *bytes.Buffer, v interface{}) { const chop = 32 switch v := v.(type) { case []byte: if len(v) > chop { fmt.Fprintf(buf, "%q...", v[:chop]) } else { fmt.Fprintf(buf, "%q", v) } case string: if len(v) > chop { fmt.Fprintf(buf, "%q...", v[:chop]) } else { fmt.Fprintf(buf, "%q", v) } case []interface{}: if len(v) == 0 { buf.WriteString("[]") } else { sep := "[" fin := "]" if len(v) > chop { v = v[:chop] fin = "...]" } for _, vv := range v { buf.WriteString(sep) c.printValue(buf, vv) sep = ", " } buf.WriteString(fin) } default: fmt.Fprint(buf, v) } } func (c *loggingConn) print(method, commandName string, args []interface{}, reply interface{}, err error) { var buf bytes.Buffer fmt.Fprintf(&buf, "%s%s(", c.prefix, method) if method != "Receive" { buf.WriteString(commandName) for _, arg := range args { buf.WriteString(", ") c.printValue(&buf, arg) } } buf.WriteString(") -> (") if method != "Send" { c.printValue(&buf, reply) buf.WriteString(", ") } fmt.Fprintf(&buf, "%v)", err) c.logger.Output(3, buf.String()) } func (c *loggingConn) Do(commandName string, args ...interface{}) (interface{}, error) { reply, err := c.Conn.Do(commandName, args...) c.print("Do", commandName, args, reply, err) return reply, err } func (c *loggingConn) Send(commandName string, args ...interface{}) error { err := c.Conn.Send(commandName, args...) c.print("Send", commandName, args, nil, err) return err } func (c *loggingConn) Receive() (interface{}, error) { reply, err := c.Conn.Receive() c.print("Receive", "", nil, reply, err) return reply, err } ================================================ FILE: vendor/github.com/garyburd/redigo/redis/pool.go ================================================ // Copyright 2012 Gary Burd // // Licensed under the Apache License, Version 2.0 (the "License"): you may // not use this file except in compliance with the License. You may obtain // a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. package redis import ( "bytes" "container/list" "crypto/rand" "crypto/sha1" "errors" "io" "strconv" "sync" "time" "github.com/garyburd/redigo/internal" ) var nowFunc = time.Now // for testing // ErrPoolExhausted is returned from a pool connection method (Do, Send, // Receive, Flush, Err) when the maximum number of database connections in the // pool has been reached. var ErrPoolExhausted = errors.New("redigo: connection pool exhausted") var ( errPoolClosed = errors.New("redigo: connection pool closed") errConnClosed = errors.New("redigo: connection closed") ) // Pool maintains a pool of connections. The application calls the Get method // to get a connection from the pool and the connection's Close method to // return the connection's resources to the pool. // // The following example shows how to use a pool in a web application. The // application creates a pool at application startup and makes it available to // request handlers using a global variable. The pool configuration used here // is an example, not a recommendation. // // func newPool(server, password string) *redis.Pool { // return &redis.Pool{ // MaxIdle: 3, // IdleTimeout: 240 * time.Second, // Dial: func () (redis.Conn, error) { // c, err := redis.Dial("tcp", server) // if err != nil { // return nil, err // } // if _, err := c.Do("AUTH", password); err != nil { // c.Close() // return nil, err // } // return c, err // }, // TestOnBorrow: func(c redis.Conn, t time.Time) error { // if time.Since(t) < time.Minute { // return nil // } // _, err := c.Do("PING") // return err // }, // } // } // // var ( // pool *redis.Pool // redisServer = flag.String("redisServer", ":6379", "") // redisPassword = flag.String("redisPassword", "", "") // ) // // func main() { // flag.Parse() // pool = newPool(*redisServer, *redisPassword) // ... // } // // A request handler gets a connection from the pool and closes the connection // when the handler is done: // // func serveHome(w http.ResponseWriter, r *http.Request) { // conn := pool.Get() // defer conn.Close() // .... // } // type Pool struct { // Dial is an application supplied function for creating and configuring a // connection. // // The connection returned from Dial must not be in a special state // (subscribed to pubsub channel, transaction started, ...). Dial func() (Conn, error) // TestOnBorrow is an optional application supplied function for checking // the health of an idle connection before the connection is used again by // the application. Argument t is the time that the connection was returned // to the pool. If the function returns an error, then the connection is // closed. TestOnBorrow func(c Conn, t time.Time) error // Maximum number of idle connections in the pool. MaxIdle int // Maximum number of connections allocated by the pool at a given time. // When zero, there is no limit on the number of connections in the pool. MaxActive int // Close connections after remaining idle for this duration. If the value // is zero, then idle connections are not closed. Applications should set // the timeout to a value less than the server's timeout. IdleTimeout time.Duration // If Wait is true and the pool is at the MaxActive limit, then Get() waits // for a connection to be returned to the pool before returning. Wait bool // mu protects fields defined below. mu sync.Mutex cond *sync.Cond closed bool active int // Stack of idleConn with most recently used at the front. idle list.List } type idleConn struct { c Conn t time.Time } // NewPool creates a new pool. // // Deprecated: Initialize the Pool directory as shown in the example. func NewPool(newFn func() (Conn, error), maxIdle int) *Pool { return &Pool{Dial: newFn, MaxIdle: maxIdle} } // Get gets a connection. The application must close the returned connection. // This method always returns a valid connection so that applications can defer // error handling to the first use of the connection. If there is an error // getting an underlying connection, then the connection Err, Do, Send, Flush // and Receive methods return that error. func (p *Pool) Get() Conn { c, err := p.get() if err != nil { return errorConnection{err} } return &pooledConnection{p: p, c: c} } // ActiveCount returns the number of active connections in the pool. func (p *Pool) ActiveCount() int { p.mu.Lock() active := p.active p.mu.Unlock() return active } // Close releases the resources used by the pool. func (p *Pool) Close() error { p.mu.Lock() idle := p.idle p.idle.Init() p.closed = true p.active -= idle.Len() if p.cond != nil { p.cond.Broadcast() } p.mu.Unlock() for e := idle.Front(); e != nil; e = e.Next() { e.Value.(idleConn).c.Close() } return nil } // release decrements the active count and signals waiters. The caller must // hold p.mu during the call. func (p *Pool) release() { p.active -= 1 if p.cond != nil { p.cond.Signal() } } // get prunes stale connections and returns a connection from the idle list or // creates a new connection. func (p *Pool) get() (Conn, error) { p.mu.Lock() // Prune stale connections. if timeout := p.IdleTimeout; timeout > 0 { for i, n := 0, p.idle.Len(); i < n; i++ { e := p.idle.Back() if e == nil { break } ic := e.Value.(idleConn) if ic.t.Add(timeout).After(nowFunc()) { break } p.idle.Remove(e) p.release() p.mu.Unlock() ic.c.Close() p.mu.Lock() } } for { // Get idle connection. for i, n := 0, p.idle.Len(); i < n; i++ { e := p.idle.Front() if e == nil { break } ic := e.Value.(idleConn) p.idle.Remove(e) test := p.TestOnBorrow p.mu.Unlock() if test == nil || test(ic.c, ic.t) == nil { return ic.c, nil } ic.c.Close() p.mu.Lock() p.release() } // Check for pool closed before dialing a new connection. if p.closed { p.mu.Unlock() return nil, errors.New("redigo: get on closed pool") } // Dial new connection if under limit. if p.MaxActive == 0 || p.active < p.MaxActive { dial := p.Dial p.active += 1 p.mu.Unlock() c, err := dial() if err != nil { p.mu.Lock() p.release() p.mu.Unlock() c = nil } return c, err } if !p.Wait { p.mu.Unlock() return nil, ErrPoolExhausted } if p.cond == nil { p.cond = sync.NewCond(&p.mu) } p.cond.Wait() } } func (p *Pool) put(c Conn, forceClose bool) error { err := c.Err() p.mu.Lock() if !p.closed && err == nil && !forceClose { p.idle.PushFront(idleConn{t: nowFunc(), c: c}) if p.idle.Len() > p.MaxIdle { c = p.idle.Remove(p.idle.Back()).(idleConn).c } else { c = nil } } if c == nil { if p.cond != nil { p.cond.Signal() } p.mu.Unlock() return nil } p.release() p.mu.Unlock() return c.Close() } type pooledConnection struct { p *Pool c Conn state int } var ( sentinel []byte sentinelOnce sync.Once ) func initSentinel() { p := make([]byte, 64) if _, err := rand.Read(p); err == nil { sentinel = p } else { h := sha1.New() io.WriteString(h, "Oops, rand failed. Use time instead.") io.WriteString(h, strconv.FormatInt(time.Now().UnixNano(), 10)) sentinel = h.Sum(nil) } } func (pc *pooledConnection) Close() error { c := pc.c if _, ok := c.(errorConnection); ok { return nil } pc.c = errorConnection{errConnClosed} if pc.state&internal.MultiState != 0 { c.Send("DISCARD") pc.state &^= (internal.MultiState | internal.WatchState) } else if pc.state&internal.WatchState != 0 { c.Send("UNWATCH") pc.state &^= internal.WatchState } if pc.state&internal.SubscribeState != 0 { c.Send("UNSUBSCRIBE") c.Send("PUNSUBSCRIBE") // To detect the end of the message stream, ask the server to echo // a sentinel value and read until we see that value. sentinelOnce.Do(initSentinel) c.Send("ECHO", sentinel) c.Flush() for { p, err := c.Receive() if err != nil { break } if p, ok := p.([]byte); ok && bytes.Equal(p, sentinel) { pc.state &^= internal.SubscribeState break } } } c.Do("") pc.p.put(c, pc.state != 0) return nil } func (pc *pooledConnection) Err() error { return pc.c.Err() } func (pc *pooledConnection) Do(commandName string, args ...interface{}) (reply interface{}, err error) { ci := internal.LookupCommandInfo(commandName) pc.state = (pc.state | ci.Set) &^ ci.Clear return pc.c.Do(commandName, args...) } func (pc *pooledConnection) Send(commandName string, args ...interface{}) error { ci := internal.LookupCommandInfo(commandName) pc.state = (pc.state | ci.Set) &^ ci.Clear return pc.c.Send(commandName, args...) } func (pc *pooledConnection) Flush() error { return pc.c.Flush() } func (pc *pooledConnection) Receive() (reply interface{}, err error) { return pc.c.Receive() } type errorConnection struct{ err error } func (ec errorConnection) Do(string, ...interface{}) (interface{}, error) { return nil, ec.err } func (ec errorConnection) Send(string, ...interface{}) error { return ec.err } func (ec errorConnection) Err() error { return ec.err } func (ec errorConnection) Close() error { return ec.err } func (ec errorConnection) Flush() error { return ec.err } func (ec errorConnection) Receive() (interface{}, error) { return nil, ec.err } ================================================ FILE: vendor/github.com/garyburd/redigo/redis/pool_test.go ================================================ // Copyright 2011 Gary Burd // // Licensed under the Apache License, Version 2.0 (the "License"): you may // not use this file except in compliance with the License. You may obtain // a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. package redis_test import ( "errors" "io" "reflect" "sync" "testing" "time" "github.com/garyburd/redigo/redis" ) type poolTestConn struct { d *poolDialer err error redis.Conn } func (c *poolTestConn) Close() error { c.d.mu.Lock() c.d.open -= 1 c.d.mu.Unlock() return c.Conn.Close() } func (c *poolTestConn) Err() error { return c.err } func (c *poolTestConn) Do(commandName string, args ...interface{}) (interface{}, error) { if commandName == "ERR" { c.err = args[0].(error) commandName = "PING" } if commandName != "" { c.d.commands = append(c.d.commands, commandName) } return c.Conn.Do(commandName, args...) } func (c *poolTestConn) Send(commandName string, args ...interface{}) error { c.d.commands = append(c.d.commands, commandName) return c.Conn.Send(commandName, args...) } type poolDialer struct { mu sync.Mutex t *testing.T dialed int open int commands []string dialErr error } func (d *poolDialer) dial() (redis.Conn, error) { d.mu.Lock() d.dialed += 1 dialErr := d.dialErr d.mu.Unlock() if dialErr != nil { return nil, d.dialErr } c, err := redis.DialDefaultServer() if err != nil { return nil, err } d.mu.Lock() d.open += 1 d.mu.Unlock() return &poolTestConn{d: d, Conn: c}, nil } func (d *poolDialer) check(message string, p *redis.Pool, dialed, open int) { d.mu.Lock() if d.dialed != dialed { d.t.Errorf("%s: dialed=%d, want %d", message, d.dialed, dialed) } if d.open != open { d.t.Errorf("%s: open=%d, want %d", message, d.open, open) } if active := p.ActiveCount(); active != open { d.t.Errorf("%s: active=%d, want %d", message, active, open) } d.mu.Unlock() } func TestPoolReuse(t *testing.T) { d := poolDialer{t: t} p := &redis.Pool{ MaxIdle: 2, Dial: d.dial, } for i := 0; i < 10; i++ { c1 := p.Get() c1.Do("PING") c2 := p.Get() c2.Do("PING") c1.Close() c2.Close() } d.check("before close", p, 2, 2) p.Close() d.check("after close", p, 2, 0) } func TestPoolMaxIdle(t *testing.T) { d := poolDialer{t: t} p := &redis.Pool{ MaxIdle: 2, Dial: d.dial, } defer p.Close() for i := 0; i < 10; i++ { c1 := p.Get() c1.Do("PING") c2 := p.Get() c2.Do("PING") c3 := p.Get() c3.Do("PING") c1.Close() c2.Close() c3.Close() } d.check("before close", p, 12, 2) p.Close() d.check("after close", p, 12, 0) } func TestPoolError(t *testing.T) { d := poolDialer{t: t} p := &redis.Pool{ MaxIdle: 2, Dial: d.dial, } defer p.Close() c := p.Get() c.Do("ERR", io.EOF) if c.Err() == nil { t.Errorf("expected c.Err() != nil") } c.Close() c = p.Get() c.Do("ERR", io.EOF) c.Close() d.check(".", p, 2, 0) } func TestPoolClose(t *testing.T) { d := poolDialer{t: t} p := &redis.Pool{ MaxIdle: 2, Dial: d.dial, } defer p.Close() c1 := p.Get() c1.Do("PING") c2 := p.Get() c2.Do("PING") c3 := p.Get() c3.Do("PING") c1.Close() if _, err := c1.Do("PING"); err == nil { t.Errorf("expected error after connection closed") } c2.Close() c2.Close() p.Close() d.check("after pool close", p, 3, 1) if _, err := c1.Do("PING"); err == nil { t.Errorf("expected error after connection and pool closed") } c3.Close() d.check("after conn close", p, 3, 0) c1 = p.Get() if _, err := c1.Do("PING"); err == nil { t.Errorf("expected error after pool closed") } } func TestPoolTimeout(t *testing.T) { d := poolDialer{t: t} p := &redis.Pool{ MaxIdle: 2, IdleTimeout: 300 * time.Second, Dial: d.dial, } defer p.Close() now := time.Now() redis.SetNowFunc(func() time.Time { return now }) defer redis.SetNowFunc(time.Now) c := p.Get() c.Do("PING") c.Close() d.check("1", p, 1, 1) now = now.Add(p.IdleTimeout) c = p.Get() c.Do("PING") c.Close() d.check("2", p, 2, 1) } func TestPoolConcurrenSendReceive(t *testing.T) { p := &redis.Pool{ Dial: redis.DialDefaultServer, } defer p.Close() c := p.Get() done := make(chan error, 1) go func() { _, err := c.Receive() done <- err }() c.Send("PING") c.Flush() err := <-done if err != nil { t.Fatalf("Receive() returned error %v", err) } _, err = c.Do("") if err != nil { t.Fatalf("Do() returned error %v", err) } c.Close() } func TestPoolBorrowCheck(t *testing.T) { d := poolDialer{t: t} p := &redis.Pool{ MaxIdle: 2, Dial: d.dial, TestOnBorrow: func(redis.Conn, time.Time) error { return redis.Error("BLAH") }, } defer p.Close() for i := 0; i < 10; i++ { c := p.Get() c.Do("PING") c.Close() } d.check("1", p, 10, 1) } func TestPoolMaxActive(t *testing.T) { d := poolDialer{t: t} p := &redis.Pool{ MaxIdle: 2, MaxActive: 2, Dial: d.dial, } defer p.Close() c1 := p.Get() c1.Do("PING") c2 := p.Get() c2.Do("PING") d.check("1", p, 2, 2) c3 := p.Get() if _, err := c3.Do("PING"); err != redis.ErrPoolExhausted { t.Errorf("expected pool exhausted") } c3.Close() d.check("2", p, 2, 2) c2.Close() d.check("3", p, 2, 2) c3 = p.Get() if _, err := c3.Do("PING"); err != nil { t.Errorf("expected good channel, err=%v", err) } c3.Close() d.check("4", p, 2, 2) } func TestPoolMonitorCleanup(t *testing.T) { d := poolDialer{t: t} p := &redis.Pool{ MaxIdle: 2, MaxActive: 2, Dial: d.dial, } defer p.Close() c := p.Get() c.Send("MONITOR") c.Close() d.check("", p, 1, 0) } func TestPoolPubSubCleanup(t *testing.T) { d := poolDialer{t: t} p := &redis.Pool{ MaxIdle: 2, MaxActive: 2, Dial: d.dial, } defer p.Close() c := p.Get() c.Send("SUBSCRIBE", "x") c.Close() want := []string{"SUBSCRIBE", "UNSUBSCRIBE", "PUNSUBSCRIBE", "ECHO"} if !reflect.DeepEqual(d.commands, want) { t.Errorf("got commands %v, want %v", d.commands, want) } d.commands = nil c = p.Get() c.Send("PSUBSCRIBE", "x*") c.Close() want = []string{"PSUBSCRIBE", "UNSUBSCRIBE", "PUNSUBSCRIBE", "ECHO"} if !reflect.DeepEqual(d.commands, want) { t.Errorf("got commands %v, want %v", d.commands, want) } d.commands = nil } func TestPoolTransactionCleanup(t *testing.T) { d := poolDialer{t: t} p := &redis.Pool{ MaxIdle: 2, MaxActive: 2, Dial: d.dial, } defer p.Close() c := p.Get() c.Do("WATCH", "key") c.Do("PING") c.Close() want := []string{"WATCH", "PING", "UNWATCH"} if !reflect.DeepEqual(d.commands, want) { t.Errorf("got commands %v, want %v", d.commands, want) } d.commands = nil c = p.Get() c.Do("WATCH", "key") c.Do("UNWATCH") c.Do("PING") c.Close() want = []string{"WATCH", "UNWATCH", "PING"} if !reflect.DeepEqual(d.commands, want) { t.Errorf("got commands %v, want %v", d.commands, want) } d.commands = nil c = p.Get() c.Do("WATCH", "key") c.Do("MULTI") c.Do("PING") c.Close() want = []string{"WATCH", "MULTI", "PING", "DISCARD"} if !reflect.DeepEqual(d.commands, want) { t.Errorf("got commands %v, want %v", d.commands, want) } d.commands = nil c = p.Get() c.Do("WATCH", "key") c.Do("MULTI") c.Do("DISCARD") c.Do("PING") c.Close() want = []string{"WATCH", "MULTI", "DISCARD", "PING"} if !reflect.DeepEqual(d.commands, want) { t.Errorf("got commands %v, want %v", d.commands, want) } d.commands = nil c = p.Get() c.Do("WATCH", "key") c.Do("MULTI") c.Do("EXEC") c.Do("PING") c.Close() want = []string{"WATCH", "MULTI", "EXEC", "PING"} if !reflect.DeepEqual(d.commands, want) { t.Errorf("got commands %v, want %v", d.commands, want) } d.commands = nil } func startGoroutines(p *redis.Pool, cmd string, args ...interface{}) chan error { errs := make(chan error, 10) for i := 0; i < cap(errs); i++ { go func() { c := p.Get() _, err := c.Do(cmd, args...) errs <- err c.Close() }() } // Wait for goroutines to block. time.Sleep(time.Second / 4) return errs } func TestWaitPool(t *testing.T) { d := poolDialer{t: t} p := &redis.Pool{ MaxIdle: 1, MaxActive: 1, Dial: d.dial, Wait: true, } defer p.Close() c := p.Get() errs := startGoroutines(p, "PING") d.check("before close", p, 1, 1) c.Close() timeout := time.After(2 * time.Second) for i := 0; i < cap(errs); i++ { select { case err := <-errs: if err != nil { t.Fatal(err) } case <-timeout: t.Fatalf("timeout waiting for blocked goroutine %d", i) } } d.check("done", p, 1, 1) } func TestWaitPoolClose(t *testing.T) { d := poolDialer{t: t} p := &redis.Pool{ MaxIdle: 1, MaxActive: 1, Dial: d.dial, Wait: true, } defer p.Close() c := p.Get() if _, err := c.Do("PING"); err != nil { t.Fatal(err) } errs := startGoroutines(p, "PING") d.check("before close", p, 1, 1) p.Close() timeout := time.After(2 * time.Second) for i := 0; i < cap(errs); i++ { select { case err := <-errs: switch err { case nil: t.Fatal("blocked goroutine did not get error") case redis.ErrPoolExhausted: t.Fatal("blocked goroutine got pool exhausted error") } case <-timeout: t.Fatal("timeout waiting for blocked goroutine") } } c.Close() d.check("done", p, 1, 0) } func TestWaitPoolCommandError(t *testing.T) { testErr := errors.New("test") d := poolDialer{t: t} p := &redis.Pool{ MaxIdle: 1, MaxActive: 1, Dial: d.dial, Wait: true, } defer p.Close() c := p.Get() errs := startGoroutines(p, "ERR", testErr) d.check("before close", p, 1, 1) c.Close() timeout := time.After(2 * time.Second) for i := 0; i < cap(errs); i++ { select { case err := <-errs: if err != nil { t.Fatal(err) } case <-timeout: t.Fatalf("timeout waiting for blocked goroutine %d", i) } } d.check("done", p, cap(errs), 0) } func TestWaitPoolDialError(t *testing.T) { testErr := errors.New("test") d := poolDialer{t: t} p := &redis.Pool{ MaxIdle: 1, MaxActive: 1, Dial: d.dial, Wait: true, } defer p.Close() c := p.Get() errs := startGoroutines(p, "ERR", testErr) d.check("before close", p, 1, 1) d.dialErr = errors.New("dial") c.Close() nilCount := 0 errCount := 0 timeout := time.After(2 * time.Second) for i := 0; i < cap(errs); i++ { select { case err := <-errs: switch err { case nil: nilCount++ case d.dialErr: errCount++ default: t.Fatalf("expected dial error or nil, got %v", err) } case <-timeout: t.Fatalf("timeout waiting for blocked goroutine %d", i) } } if nilCount != 1 { t.Errorf("expected one nil error, got %d", nilCount) } if errCount != cap(errs)-1 { t.Errorf("expected %d dial errors, got %d", cap(errs)-1, errCount) } d.check("done", p, cap(errs), 0) } // Borrowing requires us to iterate over the idle connections, unlock the pool, // and perform a blocking operation to check the connection still works. If // TestOnBorrow fails, we must reacquire the lock and continue iteration. This // test ensures that iteration will work correctly if multiple threads are // iterating simultaneously. func TestLocking_TestOnBorrowFails_PoolDoesntCrash(t *testing.T) { const count = 100 // First we'll Create a pool where the pilfering of idle connections fails. d := poolDialer{t: t} p := &redis.Pool{ MaxIdle: count, MaxActive: count, Dial: d.dial, TestOnBorrow: func(c redis.Conn, t time.Time) error { return errors.New("No way back into the real world.") }, } defer p.Close() // Fill the pool with idle connections. conns := make([]redis.Conn, count) for i := range conns { conns[i] = p.Get() } for i := range conns { conns[i].Close() } // Spawn a bunch of goroutines to thrash the pool. var wg sync.WaitGroup wg.Add(count) for i := 0; i < count; i++ { go func() { c := p.Get() if c.Err() != nil { t.Errorf("pool get failed: %v", c.Err()) } c.Close() wg.Done() }() } wg.Wait() if d.dialed != count*2 { t.Errorf("Expected %d dials, got %d", count*2, d.dialed) } } func BenchmarkPoolGet(b *testing.B) { b.StopTimer() p := redis.Pool{Dial: redis.DialDefaultServer, MaxIdle: 2} c := p.Get() if err := c.Err(); err != nil { b.Fatal(err) } c.Close() defer p.Close() b.StartTimer() for i := 0; i < b.N; i++ { c = p.Get() c.Close() } } func BenchmarkPoolGetErr(b *testing.B) { b.StopTimer() p := redis.Pool{Dial: redis.DialDefaultServer, MaxIdle: 2} c := p.Get() if err := c.Err(); err != nil { b.Fatal(err) } c.Close() defer p.Close() b.StartTimer() for i := 0; i < b.N; i++ { c = p.Get() if err := c.Err(); err != nil { b.Fatal(err) } c.Close() } } func BenchmarkPoolGetPing(b *testing.B) { b.StopTimer() p := redis.Pool{Dial: redis.DialDefaultServer, MaxIdle: 2} c := p.Get() if err := c.Err(); err != nil { b.Fatal(err) } c.Close() defer p.Close() b.StartTimer() for i := 0; i < b.N; i++ { c = p.Get() if _, err := c.Do("PING"); err != nil { b.Fatal(err) } c.Close() } } ================================================ FILE: vendor/github.com/garyburd/redigo/redis/pubsub.go ================================================ // Copyright 2012 Gary Burd // // Licensed under the Apache License, Version 2.0 (the "License"): you may // not use this file except in compliance with the License. You may obtain // a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. package redis import "errors" // Subscription represents a subscribe or unsubscribe notification. type Subscription struct { // Kind is "subscribe", "unsubscribe", "psubscribe" or "punsubscribe" Kind string // The channel that was changed. Channel string // The current number of subscriptions for connection. Count int } // Message represents a message notification. type Message struct { // The originating channel. Channel string // The message data. Data []byte } // PMessage represents a pmessage notification. type PMessage struct { // The matched pattern. Pattern string // The originating channel. Channel string // The message data. Data []byte } // Pong represents a pubsub pong notification. type Pong struct { Data string } // PubSubConn wraps a Conn with convenience methods for subscribers. type PubSubConn struct { Conn Conn } // Close closes the connection. func (c PubSubConn) Close() error { return c.Conn.Close() } // Subscribe subscribes the connection to the specified channels. func (c PubSubConn) Subscribe(channel ...interface{}) error { c.Conn.Send("SUBSCRIBE", channel...) return c.Conn.Flush() } // PSubscribe subscribes the connection to the given patterns. func (c PubSubConn) PSubscribe(channel ...interface{}) error { c.Conn.Send("PSUBSCRIBE", channel...) return c.Conn.Flush() } // Unsubscribe unsubscribes the connection from the given channels, or from all // of them if none is given. func (c PubSubConn) Unsubscribe(channel ...interface{}) error { c.Conn.Send("UNSUBSCRIBE", channel...) return c.Conn.Flush() } // PUnsubscribe unsubscribes the connection from the given patterns, or from all // of them if none is given. func (c PubSubConn) PUnsubscribe(channel ...interface{}) error { c.Conn.Send("PUNSUBSCRIBE", channel...) return c.Conn.Flush() } // Ping sends a PING to the server with the specified data. func (c PubSubConn) Ping(data string) error { c.Conn.Send("PING", data) return c.Conn.Flush() } // Receive returns a pushed message as a Subscription, Message, PMessage, Pong // or error. The return value is intended to be used directly in a type switch // as illustrated in the PubSubConn example. func (c PubSubConn) Receive() interface{} { reply, err := Values(c.Conn.Receive()) if err != nil { return err } var kind string reply, err = Scan(reply, &kind) if err != nil { return err } switch kind { case "message": var m Message if _, err := Scan(reply, &m.Channel, &m.Data); err != nil { return err } return m case "pmessage": var pm PMessage if _, err := Scan(reply, &pm.Pattern, &pm.Channel, &pm.Data); err != nil { return err } return pm case "subscribe", "psubscribe", "unsubscribe", "punsubscribe": s := Subscription{Kind: kind} if _, err := Scan(reply, &s.Channel, &s.Count); err != nil { return err } return s case "pong": var p Pong if _, err := Scan(reply, &p.Data); err != nil { return err } return p } return errors.New("redigo: unknown pubsub notification") } ================================================ FILE: vendor/github.com/garyburd/redigo/redis/pubsub_test.go ================================================ // Copyright 2012 Gary Burd // // Licensed under the Apache License, Version 2.0 (the "License"): you may // not use this file except in compliance with the License. You may obtain // a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. package redis_test import ( "fmt" "reflect" "sync" "testing" "github.com/garyburd/redigo/redis" ) func publish(channel, value interface{}) { c, err := dial() if err != nil { fmt.Println(err) return } defer c.Close() c.Do("PUBLISH", channel, value) } // Applications can receive pushed messages from one goroutine and manage subscriptions from another goroutine. func ExamplePubSubConn() { c, err := dial() if err != nil { fmt.Println(err) return } defer c.Close() var wg sync.WaitGroup wg.Add(2) psc := redis.PubSubConn{Conn: c} // This goroutine receives and prints pushed notifications from the server. // The goroutine exits when the connection is unsubscribed from all // channels or there is an error. go func() { defer wg.Done() for { switch n := psc.Receive().(type) { case redis.Message: fmt.Printf("Message: %s %s\n", n.Channel, n.Data) case redis.PMessage: fmt.Printf("PMessage: %s %s %s\n", n.Pattern, n.Channel, n.Data) case redis.Subscription: fmt.Printf("Subscription: %s %s %d\n", n.Kind, n.Channel, n.Count) if n.Count == 0 { return } case error: fmt.Printf("error: %v\n", n) return } } }() // This goroutine manages subscriptions for the connection. go func() { defer wg.Done() psc.Subscribe("example") psc.PSubscribe("p*") // The following function calls publish a message using another // connection to the Redis server. publish("example", "hello") publish("example", "world") publish("pexample", "foo") publish("pexample", "bar") // Unsubscribe from all connections. This will cause the receiving // goroutine to exit. psc.Unsubscribe() psc.PUnsubscribe() }() wg.Wait() // Output: // Subscription: subscribe example 1 // Subscription: psubscribe p* 2 // Message: example hello // Message: example world // PMessage: p* pexample foo // PMessage: p* pexample bar // Subscription: unsubscribe example 1 // Subscription: punsubscribe p* 0 } func expectPushed(t *testing.T, c redis.PubSubConn, message string, expected interface{}) { actual := c.Receive() if !reflect.DeepEqual(actual, expected) { t.Errorf("%s = %v, want %v", message, actual, expected) } } func TestPushed(t *testing.T) { pc, err := redis.DialDefaultServer() if err != nil { t.Fatalf("error connection to database, %v", err) } defer pc.Close() sc, err := redis.DialDefaultServer() if err != nil { t.Fatalf("error connection to database, %v", err) } defer sc.Close() c := redis.PubSubConn{Conn: sc} c.Subscribe("c1") expectPushed(t, c, "Subscribe(c1)", redis.Subscription{Kind: "subscribe", Channel: "c1", Count: 1}) c.Subscribe("c2") expectPushed(t, c, "Subscribe(c2)", redis.Subscription{Kind: "subscribe", Channel: "c2", Count: 2}) c.PSubscribe("p1") expectPushed(t, c, "PSubscribe(p1)", redis.Subscription{Kind: "psubscribe", Channel: "p1", Count: 3}) c.PSubscribe("p2") expectPushed(t, c, "PSubscribe(p2)", redis.Subscription{Kind: "psubscribe", Channel: "p2", Count: 4}) c.PUnsubscribe() expectPushed(t, c, "Punsubscribe(p1)", redis.Subscription{Kind: "punsubscribe", Channel: "p1", Count: 3}) expectPushed(t, c, "Punsubscribe()", redis.Subscription{Kind: "punsubscribe", Channel: "p2", Count: 2}) pc.Do("PUBLISH", "c1", "hello") expectPushed(t, c, "PUBLISH c1 hello", redis.Message{Channel: "c1", Data: []byte("hello")}) c.Ping("hello") expectPushed(t, c, `Ping("hello")`, redis.Pong{Data: "hello"}) c.Conn.Send("PING") c.Conn.Flush() expectPushed(t, c, `Send("PING")`, redis.Pong{}) } ================================================ FILE: vendor/github.com/garyburd/redigo/redis/redis.go ================================================ // Copyright 2012 Gary Burd // // Licensed under the Apache License, Version 2.0 (the "License"): you may // not use this file except in compliance with the License. You may obtain // a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. package redis // Error represents an error returned in a command reply. type Error string func (err Error) Error() string { return string(err) } // Conn represents a connection to a Redis server. type Conn interface { // Close closes the connection. Close() error // Err returns a non-nil value if the connection is broken. The returned // value is either the first non-nil value returned from the underlying // network connection or a protocol parsing error. Applications should // close broken connections. Err() error // Do sends a command to the server and returns the received reply. Do(commandName string, args ...interface{}) (reply interface{}, err error) // Send writes the command to the client's output buffer. Send(commandName string, args ...interface{}) error // Flush flushes the output buffer to the Redis server. Flush() error // Receive receives a single reply from the Redis server Receive() (reply interface{}, err error) } ================================================ FILE: vendor/github.com/garyburd/redigo/redis/reply.go ================================================ // Copyright 2012 Gary Burd // // Licensed under the Apache License, Version 2.0 (the "License"): you may // not use this file except in compliance with the License. You may obtain // a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. package redis import ( "errors" "fmt" "strconv" ) // ErrNil indicates that a reply value is nil. var ErrNil = errors.New("redigo: nil returned") // Int is a helper that converts a command reply to an integer. If err is not // equal to nil, then Int returns 0, err. Otherwise, Int converts the // reply to an int as follows: // // Reply type Result // integer int(reply), nil // bulk string parsed reply, nil // nil 0, ErrNil // other 0, error func Int(reply interface{}, err error) (int, error) { if err != nil { return 0, err } switch reply := reply.(type) { case int64: x := int(reply) if int64(x) != reply { return 0, strconv.ErrRange } return x, nil case []byte: n, err := strconv.ParseInt(string(reply), 10, 0) return int(n), err case nil: return 0, ErrNil case Error: return 0, reply } return 0, fmt.Errorf("redigo: unexpected type for Int, got type %T", reply) } // Int64 is a helper that converts a command reply to 64 bit integer. If err is // not equal to nil, then Int returns 0, err. Otherwise, Int64 converts the // reply to an int64 as follows: // // Reply type Result // integer reply, nil // bulk string parsed reply, nil // nil 0, ErrNil // other 0, error func Int64(reply interface{}, err error) (int64, error) { if err != nil { return 0, err } switch reply := reply.(type) { case int64: return reply, nil case []byte: n, err := strconv.ParseInt(string(reply), 10, 64) return n, err case nil: return 0, ErrNil case Error: return 0, reply } return 0, fmt.Errorf("redigo: unexpected type for Int64, got type %T", reply) } var errNegativeInt = errors.New("redigo: unexpected value for Uint64") // Uint64 is a helper that converts a command reply to 64 bit integer. If err is // not equal to nil, then Int returns 0, err. Otherwise, Int64 converts the // reply to an int64 as follows: // // Reply type Result // integer reply, nil // bulk string parsed reply, nil // nil 0, ErrNil // other 0, error func Uint64(reply interface{}, err error) (uint64, error) { if err != nil { return 0, err } switch reply := reply.(type) { case int64: if reply < 0 { return 0, errNegativeInt } return uint64(reply), nil case []byte: n, err := strconv.ParseUint(string(reply), 10, 64) return n, err case nil: return 0, ErrNil case Error: return 0, reply } return 0, fmt.Errorf("redigo: unexpected type for Uint64, got type %T", reply) } // Float64 is a helper that converts a command reply to 64 bit float. If err is // not equal to nil, then Float64 returns 0, err. Otherwise, Float64 converts // the reply to an int as follows: // // Reply type Result // bulk string parsed reply, nil // nil 0, ErrNil // other 0, error func Float64(reply interface{}, err error) (float64, error) { if err != nil { return 0, err } switch reply := reply.(type) { case []byte: n, err := strconv.ParseFloat(string(reply), 64) return n, err case nil: return 0, ErrNil case Error: return 0, reply } return 0, fmt.Errorf("redigo: unexpected type for Float64, got type %T", reply) } // String is a helper that converts a command reply to a string. If err is not // equal to nil, then String returns "", err. Otherwise String converts the // reply to a string as follows: // // Reply type Result // bulk string string(reply), nil // simple string reply, nil // nil "", ErrNil // other "", error func String(reply interface{}, err error) (string, error) { if err != nil { return "", err } switch reply := reply.(type) { case []byte: return string(reply), nil case string: return reply, nil case nil: return "", ErrNil case Error: return "", reply } return "", fmt.Errorf("redigo: unexpected type for String, got type %T", reply) } // Bytes is a helper that converts a command reply to a slice of bytes. If err // is not equal to nil, then Bytes returns nil, err. Otherwise Bytes converts // the reply to a slice of bytes as follows: // // Reply type Result // bulk string reply, nil // simple string []byte(reply), nil // nil nil, ErrNil // other nil, error func Bytes(reply interface{}, err error) ([]byte, error) { if err != nil { return nil, err } switch reply := reply.(type) { case []byte: return reply, nil case string: return []byte(reply), nil case nil: return nil, ErrNil case Error: return nil, reply } return nil, fmt.Errorf("redigo: unexpected type for Bytes, got type %T", reply) } // Bool is a helper that converts a command reply to a boolean. If err is not // equal to nil, then Bool returns false, err. Otherwise Bool converts the // reply to boolean as follows: // // Reply type Result // integer value != 0, nil // bulk string strconv.ParseBool(reply) // nil false, ErrNil // other false, error func Bool(reply interface{}, err error) (bool, error) { if err != nil { return false, err } switch reply := reply.(type) { case int64: return reply != 0, nil case []byte: return strconv.ParseBool(string(reply)) case nil: return false, ErrNil case Error: return false, reply } return false, fmt.Errorf("redigo: unexpected type for Bool, got type %T", reply) } // MultiBulk is a helper that converts an array command reply to a []interface{}. // // Deprecated: Use Values instead. func MultiBulk(reply interface{}, err error) ([]interface{}, error) { return Values(reply, err) } // Values is a helper that converts an array command reply to a []interface{}. // If err is not equal to nil, then Values returns nil, err. Otherwise, Values // converts the reply as follows: // // Reply type Result // array reply, nil // nil nil, ErrNil // other nil, error func Values(reply interface{}, err error) ([]interface{}, error) { if err != nil { return nil, err } switch reply := reply.(type) { case []interface{}: return reply, nil case nil: return nil, ErrNil case Error: return nil, reply } return nil, fmt.Errorf("redigo: unexpected type for Values, got type %T", reply) } // Strings is a helper that converts an array command reply to a []string. If // err is not equal to nil, then Strings returns nil, err. Nil array items are // converted to "" in the output slice. Strings returns an error if an array // item is not a bulk string or nil. func Strings(reply interface{}, err error) ([]string, error) { if err != nil { return nil, err } switch reply := reply.(type) { case []interface{}: result := make([]string, len(reply)) for i := range reply { if reply[i] == nil { continue } p, ok := reply[i].([]byte) if !ok { return nil, fmt.Errorf("redigo: unexpected element type for Strings, got type %T", reply[i]) } result[i] = string(p) } return result, nil case nil: return nil, ErrNil case Error: return nil, reply } return nil, fmt.Errorf("redigo: unexpected type for Strings, got type %T", reply) } // ByteSlices is a helper that converts an array command reply to a [][]byte. // If err is not equal to nil, then ByteSlices returns nil, err. Nil array // items are stay nil. ByteSlices returns an error if an array item is not a // bulk string or nil. func ByteSlices(reply interface{}, err error) ([][]byte, error) { if err != nil { return nil, err } switch reply := reply.(type) { case []interface{}: result := make([][]byte, len(reply)) for i := range reply { if reply[i] == nil { continue } p, ok := reply[i].([]byte) if !ok { return nil, fmt.Errorf("redigo: unexpected element type for ByteSlices, got type %T", reply[i]) } result[i] = p } return result, nil case nil: return nil, ErrNil case Error: return nil, reply } return nil, fmt.Errorf("redigo: unexpected type for ByteSlices, got type %T", reply) } // Ints is a helper that converts an array command reply to a []int. If // err is not equal to nil, then Ints returns nil, err. func Ints(reply interface{}, err error) ([]int, error) { var ints []int values, err := Values(reply, err) if err != nil { return ints, err } if err := ScanSlice(values, &ints); err != nil { return ints, err } return ints, nil } // StringMap is a helper that converts an array of strings (alternating key, value) // into a map[string]string. The HGETALL and CONFIG GET commands return replies in this format. // Requires an even number of values in result. func StringMap(result interface{}, err error) (map[string]string, error) { values, err := Values(result, err) if err != nil { return nil, err } if len(values)%2 != 0 { return nil, errors.New("redigo: StringMap expects even number of values result") } m := make(map[string]string, len(values)/2) for i := 0; i < len(values); i += 2 { key, okKey := values[i].([]byte) value, okValue := values[i+1].([]byte) if !okKey || !okValue { return nil, errors.New("redigo: ScanMap key not a bulk string value") } m[string(key)] = string(value) } return m, nil } // IntMap is a helper that converts an array of strings (alternating key, value) // into a map[string]int. The HGETALL commands return replies in this format. // Requires an even number of values in result. func IntMap(result interface{}, err error) (map[string]int, error) { values, err := Values(result, err) if err != nil { return nil, err } if len(values)%2 != 0 { return nil, errors.New("redigo: IntMap expects even number of values result") } m := make(map[string]int, len(values)/2) for i := 0; i < len(values); i += 2 { key, ok := values[i].([]byte) if !ok { return nil, errors.New("redigo: ScanMap key not a bulk string value") } value, err := Int(values[i+1], nil) if err != nil { return nil, err } m[string(key)] = value } return m, nil } // Int64Map is a helper that converts an array of strings (alternating key, value) // into a map[string]int64. The HGETALL commands return replies in this format. // Requires an even number of values in result. func Int64Map(result interface{}, err error) (map[string]int64, error) { values, err := Values(result, err) if err != nil { return nil, err } if len(values)%2 != 0 { return nil, errors.New("redigo: Int64Map expects even number of values result") } m := make(map[string]int64, len(values)/2) for i := 0; i < len(values); i += 2 { key, ok := values[i].([]byte) if !ok { return nil, errors.New("redigo: ScanMap key not a bulk string value") } value, err := Int64(values[i+1], nil) if err != nil { return nil, err } m[string(key)] = value } return m, nil } ================================================ FILE: vendor/github.com/garyburd/redigo/redis/reply_test.go ================================================ // Copyright 2012 Gary Burd // // Licensed under the Apache License, Version 2.0 (the "License"): you may // not use this file except in compliance with the License. You may obtain // a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. package redis_test import ( "fmt" "reflect" "testing" "github.com/garyburd/redigo/redis" ) type valueError struct { v interface{} err error } func ve(v interface{}, err error) valueError { return valueError{v, err} } var replyTests = []struct { name interface{} actual valueError expected valueError }{ { "ints([v1, v2])", ve(redis.Ints([]interface{}{[]byte("4"), []byte("5")}, nil)), ve([]int{4, 5}, nil), }, { "ints(nil)", ve(redis.Ints(nil, nil)), ve([]int(nil), redis.ErrNil), }, { "strings([v1, v2])", ve(redis.Strings([]interface{}{[]byte("v1"), []byte("v2")}, nil)), ve([]string{"v1", "v2"}, nil), }, { "strings(nil)", ve(redis.Strings(nil, nil)), ve([]string(nil), redis.ErrNil), }, { "byteslices([v1, v2])", ve(redis.ByteSlices([]interface{}{[]byte("v1"), []byte("v2")}, nil)), ve([][]byte{[]byte("v1"), []byte("v2")}, nil), }, { "byteslices(nil)", ve(redis.ByteSlices(nil, nil)), ve([][]byte(nil), redis.ErrNil), }, { "values([v1, v2])", ve(redis.Values([]interface{}{[]byte("v1"), []byte("v2")}, nil)), ve([]interface{}{[]byte("v1"), []byte("v2")}, nil), }, { "values(nil)", ve(redis.Values(nil, nil)), ve([]interface{}(nil), redis.ErrNil), }, { "float64(1.0)", ve(redis.Float64([]byte("1.0"), nil)), ve(float64(1.0), nil), }, { "float64(nil)", ve(redis.Float64(nil, nil)), ve(float64(0.0), redis.ErrNil), }, { "uint64(1)", ve(redis.Uint64(int64(1), nil)), ve(uint64(1), nil), }, { "uint64(-1)", ve(redis.Uint64(int64(-1), nil)), ve(uint64(0), redis.ErrNegativeInt), }, } func TestReply(t *testing.T) { for _, rt := range replyTests { if rt.actual.err != rt.expected.err { t.Errorf("%s returned err %v, want %v", rt.name, rt.actual.err, rt.expected.err) continue } if !reflect.DeepEqual(rt.actual.v, rt.expected.v) { t.Errorf("%s=%+v, want %+v", rt.name, rt.actual.v, rt.expected.v) } } } // dial wraps DialDefaultServer() with a more suitable function name for examples. func dial() (redis.Conn, error) { return redis.DialDefaultServer() } func ExampleBool() { c, err := dial() if err != nil { fmt.Println(err) return } defer c.Close() c.Do("SET", "foo", 1) exists, _ := redis.Bool(c.Do("EXISTS", "foo")) fmt.Printf("%#v\n", exists) // Output: // true } func ExampleInt() { c, err := dial() if err != nil { fmt.Println(err) return } defer c.Close() c.Do("SET", "k1", 1) n, _ := redis.Int(c.Do("GET", "k1")) fmt.Printf("%#v\n", n) n, _ = redis.Int(c.Do("INCR", "k1")) fmt.Printf("%#v\n", n) // Output: // 1 // 2 } func ExampleInts() { c, err := dial() if err != nil { fmt.Println(err) return } defer c.Close() c.Do("SADD", "set_with_integers", 4, 5, 6) ints, _ := redis.Ints(c.Do("SMEMBERS", "set_with_integers")) fmt.Printf("%#v\n", ints) // Output: // []int{4, 5, 6} } func ExampleString() { c, err := dial() if err != nil { fmt.Println(err) return } defer c.Close() c.Do("SET", "hello", "world") s, err := redis.String(c.Do("GET", "hello")) fmt.Printf("%#v\n", s) // Output: // "world" } ================================================ FILE: vendor/github.com/garyburd/redigo/redis/scan.go ================================================ // Copyright 2012 Gary Burd // // Licensed under the Apache License, Version 2.0 (the "License"): you may // not use this file except in compliance with the License. You may obtain // a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. package redis import ( "errors" "fmt" "reflect" "strconv" "strings" "sync" ) func ensureLen(d reflect.Value, n int) { if n > d.Cap() { d.Set(reflect.MakeSlice(d.Type(), n, n)) } else { d.SetLen(n) } } func cannotConvert(d reflect.Value, s interface{}) error { var sname string switch s.(type) { case string: sname = "Redis simple string" case Error: sname = "Redis error" case int64: sname = "Redis integer" case []byte: sname = "Redis bulk string" case []interface{}: sname = "Redis array" default: sname = reflect.TypeOf(s).String() } return fmt.Errorf("cannot convert from %s to %s", sname, d.Type()) } func convertAssignBulkString(d reflect.Value, s []byte) (err error) { switch d.Type().Kind() { case reflect.Float32, reflect.Float64: var x float64 x, err = strconv.ParseFloat(string(s), d.Type().Bits()) d.SetFloat(x) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: var x int64 x, err = strconv.ParseInt(string(s), 10, d.Type().Bits()) d.SetInt(x) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: var x uint64 x, err = strconv.ParseUint(string(s), 10, d.Type().Bits()) d.SetUint(x) case reflect.Bool: var x bool x, err = strconv.ParseBool(string(s)) d.SetBool(x) case reflect.String: d.SetString(string(s)) case reflect.Slice: if d.Type().Elem().Kind() != reflect.Uint8 { err = cannotConvert(d, s) } else { d.SetBytes(s) } default: err = cannotConvert(d, s) } return } func convertAssignInt(d reflect.Value, s int64) (err error) { switch d.Type().Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: d.SetInt(s) if d.Int() != s { err = strconv.ErrRange d.SetInt(0) } case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: if s < 0 { err = strconv.ErrRange } else { x := uint64(s) d.SetUint(x) if d.Uint() != x { err = strconv.ErrRange d.SetUint(0) } } case reflect.Bool: d.SetBool(s != 0) default: err = cannotConvert(d, s) } return } func convertAssignValue(d reflect.Value, s interface{}) (err error) { switch s := s.(type) { case []byte: err = convertAssignBulkString(d, s) case int64: err = convertAssignInt(d, s) default: err = cannotConvert(d, s) } return err } func convertAssignArray(d reflect.Value, s []interface{}) error { if d.Type().Kind() != reflect.Slice { return cannotConvert(d, s) } ensureLen(d, len(s)) for i := 0; i < len(s); i++ { if err := convertAssignValue(d.Index(i), s[i]); err != nil { return err } } return nil } func convertAssign(d interface{}, s interface{}) (err error) { // Handle the most common destination types using type switches and // fall back to reflection for all other types. switch s := s.(type) { case nil: // ingore case []byte: switch d := d.(type) { case *string: *d = string(s) case *int: *d, err = strconv.Atoi(string(s)) case *bool: *d, err = strconv.ParseBool(string(s)) case *[]byte: *d = s case *interface{}: *d = s case nil: // skip value default: if d := reflect.ValueOf(d); d.Type().Kind() != reflect.Ptr { err = cannotConvert(d, s) } else { err = convertAssignBulkString(d.Elem(), s) } } case int64: switch d := d.(type) { case *int: x := int(s) if int64(x) != s { err = strconv.ErrRange x = 0 } *d = x case *bool: *d = s != 0 case *interface{}: *d = s case nil: // skip value default: if d := reflect.ValueOf(d); d.Type().Kind() != reflect.Ptr { err = cannotConvert(d, s) } else { err = convertAssignInt(d.Elem(), s) } } case string: switch d := d.(type) { case *string: *d = string(s) default: err = cannotConvert(reflect.ValueOf(d), s) } case []interface{}: switch d := d.(type) { case *[]interface{}: *d = s case *interface{}: *d = s case nil: // skip value default: if d := reflect.ValueOf(d); d.Type().Kind() != reflect.Ptr { err = cannotConvert(d, s) } else { err = convertAssignArray(d.Elem(), s) } } case Error: err = s default: err = cannotConvert(reflect.ValueOf(d), s) } return } // Scan copies from src to the values pointed at by dest. // // The values pointed at by dest must be an integer, float, boolean, string, // []byte, interface{} or slices of these types. Scan uses the standard strconv // package to convert bulk strings to numeric and boolean types. // // If a dest value is nil, then the corresponding src value is skipped. // // If a src element is nil, then the corresponding dest value is not modified. // // To enable easy use of Scan in a loop, Scan returns the slice of src // following the copied values. func Scan(src []interface{}, dest ...interface{}) ([]interface{}, error) { if len(src) < len(dest) { return nil, errors.New("redigo.Scan: array short") } var err error for i, d := range dest { err = convertAssign(d, src[i]) if err != nil { err = fmt.Errorf("redigo.Scan: cannot assign to dest %d: %v", i, err) break } } return src[len(dest):], err } type fieldSpec struct { name string index []int omitEmpty bool } type structSpec struct { m map[string]*fieldSpec l []*fieldSpec } func (ss *structSpec) fieldSpec(name []byte) *fieldSpec { return ss.m[string(name)] } func compileStructSpec(t reflect.Type, depth map[string]int, index []int, ss *structSpec) { for i := 0; i < t.NumField(); i++ { f := t.Field(i) switch { case f.PkgPath != "" && !f.Anonymous: // Ignore unexported fields. case f.Anonymous: // TODO: Handle pointers. Requires change to decoder and // protection against infinite recursion. if f.Type.Kind() == reflect.Struct { compileStructSpec(f.Type, depth, append(index, i), ss) } default: fs := &fieldSpec{name: f.Name} tag := f.Tag.Get("redis") p := strings.Split(tag, ",") if len(p) > 0 { if p[0] == "-" { continue } if len(p[0]) > 0 { fs.name = p[0] } for _, s := range p[1:] { switch s { case "omitempty": fs.omitEmpty = true default: panic(fmt.Errorf("redigo: unknown field tag %s for type %s", s, t.Name())) } } } d, found := depth[fs.name] if !found { d = 1 << 30 } switch { case len(index) == d: // At same depth, remove from result. delete(ss.m, fs.name) j := 0 for i := 0; i < len(ss.l); i++ { if fs.name != ss.l[i].name { ss.l[j] = ss.l[i] j += 1 } } ss.l = ss.l[:j] case len(index) < d: fs.index = make([]int, len(index)+1) copy(fs.index, index) fs.index[len(index)] = i depth[fs.name] = len(index) ss.m[fs.name] = fs ss.l = append(ss.l, fs) } } } } var ( structSpecMutex sync.RWMutex structSpecCache = make(map[reflect.Type]*structSpec) defaultFieldSpec = &fieldSpec{} ) func structSpecForType(t reflect.Type) *structSpec { structSpecMutex.RLock() ss, found := structSpecCache[t] structSpecMutex.RUnlock() if found { return ss } structSpecMutex.Lock() defer structSpecMutex.Unlock() ss, found = structSpecCache[t] if found { return ss } ss = &structSpec{m: make(map[string]*fieldSpec)} compileStructSpec(t, make(map[string]int), nil, ss) structSpecCache[t] = ss return ss } var errScanStructValue = errors.New("redigo.ScanStruct: value must be non-nil pointer to a struct") // ScanStruct scans alternating names and values from src to a struct. The // HGETALL and CONFIG GET commands return replies in this format. // // ScanStruct uses exported field names to match values in the response. Use // 'redis' field tag to override the name: // // Field int `redis:"myName"` // // Fields with the tag redis:"-" are ignored. // // Integer, float, boolean, string and []byte fields are supported. Scan uses the // standard strconv package to convert bulk string values to numeric and // boolean types. // // If a src element is nil, then the corresponding field is not modified. func ScanStruct(src []interface{}, dest interface{}) error { d := reflect.ValueOf(dest) if d.Kind() != reflect.Ptr || d.IsNil() { return errScanStructValue } d = d.Elem() if d.Kind() != reflect.Struct { return errScanStructValue } ss := structSpecForType(d.Type()) if len(src)%2 != 0 { return errors.New("redigo.ScanStruct: number of values not a multiple of 2") } for i := 0; i < len(src); i += 2 { s := src[i+1] if s == nil { continue } name, ok := src[i].([]byte) if !ok { return fmt.Errorf("redigo.ScanStruct: key %d not a bulk string value", i) } fs := ss.fieldSpec(name) if fs == nil { continue } if err := convertAssignValue(d.FieldByIndex(fs.index), s); err != nil { return fmt.Errorf("redigo.ScanStruct: cannot assign field %s: %v", fs.name, err) } } return nil } var ( errScanSliceValue = errors.New("redigo.ScanSlice: dest must be non-nil pointer to a struct") ) // ScanSlice scans src to the slice pointed to by dest. The elements the dest // slice must be integer, float, boolean, string, struct or pointer to struct // values. // // Struct fields must be integer, float, boolean or string values. All struct // fields are used unless a subset is specified using fieldNames. func ScanSlice(src []interface{}, dest interface{}, fieldNames ...string) error { d := reflect.ValueOf(dest) if d.Kind() != reflect.Ptr || d.IsNil() { return errScanSliceValue } d = d.Elem() if d.Kind() != reflect.Slice { return errScanSliceValue } isPtr := false t := d.Type().Elem() if t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Struct { isPtr = true t = t.Elem() } if t.Kind() != reflect.Struct { ensureLen(d, len(src)) for i, s := range src { if s == nil { continue } if err := convertAssignValue(d.Index(i), s); err != nil { return fmt.Errorf("redigo.ScanSlice: cannot assign element %d: %v", i, err) } } return nil } ss := structSpecForType(t) fss := ss.l if len(fieldNames) > 0 { fss = make([]*fieldSpec, len(fieldNames)) for i, name := range fieldNames { fss[i] = ss.m[name] if fss[i] == nil { return fmt.Errorf("redigo.ScanSlice: ScanSlice bad field name %s", name) } } } if len(fss) == 0 { return errors.New("redigo.ScanSlice: no struct fields") } n := len(src) / len(fss) if n*len(fss) != len(src) { return errors.New("redigo.ScanSlice: length not a multiple of struct field count") } ensureLen(d, n) for i := 0; i < n; i++ { d := d.Index(i) if isPtr { if d.IsNil() { d.Set(reflect.New(t)) } d = d.Elem() } for j, fs := range fss { s := src[i*len(fss)+j] if s == nil { continue } if err := convertAssignValue(d.FieldByIndex(fs.index), s); err != nil { return fmt.Errorf("redigo.ScanSlice: cannot assign element %d to field %s: %v", i*len(fss)+j, fs.name, err) } } } return nil } // Args is a helper for constructing command arguments from structured values. type Args []interface{} // Add returns the result of appending value to args. func (args Args) Add(value ...interface{}) Args { return append(args, value...) } // AddFlat returns the result of appending the flattened value of v to args. // // Maps are flattened by appending the alternating keys and map values to args. // // Slices are flattened by appending the slice elements to args. // // Structs are flattened by appending the alternating names and values of // exported fields to args. If v is a nil struct pointer, then nothing is // appended. The 'redis' field tag overrides struct field names. See ScanStruct // for more information on the use of the 'redis' field tag. // // Other types are appended to args as is. func (args Args) AddFlat(v interface{}) Args { rv := reflect.ValueOf(v) switch rv.Kind() { case reflect.Struct: args = flattenStruct(args, rv) case reflect.Slice: for i := 0; i < rv.Len(); i++ { args = append(args, rv.Index(i).Interface()) } case reflect.Map: for _, k := range rv.MapKeys() { args = append(args, k.Interface(), rv.MapIndex(k).Interface()) } case reflect.Ptr: if rv.Type().Elem().Kind() == reflect.Struct { if !rv.IsNil() { args = flattenStruct(args, rv.Elem()) } } else { args = append(args, v) } default: args = append(args, v) } return args } func flattenStruct(args Args, v reflect.Value) Args { ss := structSpecForType(v.Type()) for _, fs := range ss.l { fv := v.FieldByIndex(fs.index) if fs.omitEmpty { var empty = false switch fv.Kind() { case reflect.Array, reflect.Map, reflect.Slice, reflect.String: empty = fv.Len() == 0 case reflect.Bool: empty = !fv.Bool() case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: empty = fv.Int() == 0 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: empty = fv.Uint() == 0 case reflect.Float32, reflect.Float64: empty = fv.Float() == 0 case reflect.Interface, reflect.Ptr: empty = fv.IsNil() } if empty { continue } } args = append(args, fs.name, fv.Interface()) } return args } ================================================ FILE: vendor/github.com/garyburd/redigo/redis/scan_test.go ================================================ // Copyright 2012 Gary Burd // // Licensed under the Apache License, Version 2.0 (the "License"): you may // not use this file except in compliance with the License. You may obtain // a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. package redis_test import ( "fmt" "math" "reflect" "testing" "github.com/garyburd/redigo/redis" ) var scanConversionTests = []struct { src interface{} dest interface{} }{ {[]byte("-inf"), math.Inf(-1)}, {[]byte("+inf"), math.Inf(1)}, {[]byte("0"), float64(0)}, {[]byte("3.14159"), float64(3.14159)}, {[]byte("3.14"), float32(3.14)}, {[]byte("-100"), int(-100)}, {[]byte("101"), int(101)}, {int64(102), int(102)}, {[]byte("103"), uint(103)}, {int64(104), uint(104)}, {[]byte("105"), int8(105)}, {int64(106), int8(106)}, {[]byte("107"), uint8(107)}, {int64(108), uint8(108)}, {[]byte("0"), false}, {int64(0), false}, {[]byte("f"), false}, {[]byte("1"), true}, {int64(1), true}, {[]byte("t"), true}, {"hello", "hello"}, {[]byte("hello"), "hello"}, {[]byte("world"), []byte("world")}, {[]interface{}{[]byte("foo")}, []interface{}{[]byte("foo")}}, {[]interface{}{[]byte("foo")}, []string{"foo"}}, {[]interface{}{[]byte("hello"), []byte("world")}, []string{"hello", "world"}}, {[]interface{}{[]byte("bar")}, [][]byte{[]byte("bar")}}, {[]interface{}{[]byte("1")}, []int{1}}, {[]interface{}{[]byte("1"), []byte("2")}, []int{1, 2}}, {[]interface{}{[]byte("1"), []byte("2")}, []float64{1, 2}}, {[]interface{}{[]byte("1")}, []byte{1}}, {[]interface{}{[]byte("1")}, []bool{true}}, } func TestScanConversion(t *testing.T) { for _, tt := range scanConversionTests { values := []interface{}{tt.src} dest := reflect.New(reflect.TypeOf(tt.dest)) values, err := redis.Scan(values, dest.Interface()) if err != nil { t.Errorf("Scan(%v) returned error %v", tt, err) continue } if !reflect.DeepEqual(tt.dest, dest.Elem().Interface()) { t.Errorf("Scan(%v) returned %v, want %v", tt, dest.Elem().Interface(), tt.dest) } } } var scanConversionErrorTests = []struct { src interface{} dest interface{} }{ {[]byte("1234"), byte(0)}, {int64(1234), byte(0)}, {[]byte("-1"), byte(0)}, {int64(-1), byte(0)}, {[]byte("junk"), false}, {redis.Error("blah"), false}, } func TestScanConversionError(t *testing.T) { for _, tt := range scanConversionErrorTests { values := []interface{}{tt.src} dest := reflect.New(reflect.TypeOf(tt.dest)) values, err := redis.Scan(values, dest.Interface()) if err == nil { t.Errorf("Scan(%v) did not return error", tt) } } } func ExampleScan() { c, err := dial() if err != nil { fmt.Println(err) return } defer c.Close() c.Send("HMSET", "album:1", "title", "Red", "rating", 5) c.Send("HMSET", "album:2", "title", "Earthbound", "rating", 1) c.Send("HMSET", "album:3", "title", "Beat") c.Send("LPUSH", "albums", "1") c.Send("LPUSH", "albums", "2") c.Send("LPUSH", "albums", "3") values, err := redis.Values(c.Do("SORT", "albums", "BY", "album:*->rating", "GET", "album:*->title", "GET", "album:*->rating")) if err != nil { fmt.Println(err) return } for len(values) > 0 { var title string rating := -1 // initialize to illegal value to detect nil. values, err = redis.Scan(values, &title, &rating) if err != nil { fmt.Println(err) return } if rating == -1 { fmt.Println(title, "not-rated") } else { fmt.Println(title, rating) } } // Output: // Beat not-rated // Earthbound 1 // Red 5 } type s0 struct { X int Y int `redis:"y"` Bt bool } type s1 struct { X int `redis:"-"` I int `redis:"i"` U uint `redis:"u"` S string `redis:"s"` P []byte `redis:"p"` B bool `redis:"b"` Bt bool Bf bool s0 } var scanStructTests = []struct { title string reply []string value interface{} }{ {"basic", []string{"i", "-1234", "u", "5678", "s", "hello", "p", "world", "b", "t", "Bt", "1", "Bf", "0", "X", "123", "y", "456"}, &s1{I: -1234, U: 5678, S: "hello", P: []byte("world"), B: true, Bt: true, Bf: false, s0: s0{X: 123, Y: 456}}, }, } func TestScanStruct(t *testing.T) { for _, tt := range scanStructTests { var reply []interface{} for _, v := range tt.reply { reply = append(reply, []byte(v)) } value := reflect.New(reflect.ValueOf(tt.value).Type().Elem()) if err := redis.ScanStruct(reply, value.Interface()); err != nil { t.Fatalf("ScanStruct(%s) returned error %v", tt.title, err) } if !reflect.DeepEqual(value.Interface(), tt.value) { t.Fatalf("ScanStruct(%s) returned %v, want %v", tt.title, value.Interface(), tt.value) } } } func TestBadScanStructArgs(t *testing.T) { x := []interface{}{"A", "b"} test := func(v interface{}) { if err := redis.ScanStruct(x, v); err == nil { t.Errorf("Expect error for ScanStruct(%T, %T)", x, v) } } test(nil) var v0 *struct{} test(v0) var v1 int test(&v1) x = x[:1] v2 := struct{ A string }{} test(&v2) } var scanSliceTests = []struct { src []interface{} fieldNames []string ok bool dest interface{} }{ { []interface{}{[]byte("1"), nil, []byte("-1")}, nil, true, []int{1, 0, -1}, }, { []interface{}{[]byte("1"), nil, []byte("2")}, nil, true, []uint{1, 0, 2}, }, { []interface{}{[]byte("-1")}, nil, false, []uint{1}, }, { []interface{}{[]byte("hello"), nil, []byte("world")}, nil, true, [][]byte{[]byte("hello"), nil, []byte("world")}, }, { []interface{}{[]byte("hello"), nil, []byte("world")}, nil, true, []string{"hello", "", "world"}, }, { []interface{}{[]byte("a1"), []byte("b1"), []byte("a2"), []byte("b2")}, nil, true, []struct{ A, B string }{{"a1", "b1"}, {"a2", "b2"}}, }, { []interface{}{[]byte("a1"), []byte("b1")}, nil, false, []struct{ A, B, C string }{{"a1", "b1", ""}}, }, { []interface{}{[]byte("a1"), []byte("b1"), []byte("a2"), []byte("b2")}, nil, true, []*struct{ A, B string }{{"a1", "b1"}, {"a2", "b2"}}, }, { []interface{}{[]byte("a1"), []byte("b1"), []byte("a2"), []byte("b2")}, []string{"A", "B"}, true, []struct{ A, C, B string }{{"a1", "", "b1"}, {"a2", "", "b2"}}, }, { []interface{}{[]byte("a1"), []byte("b1"), []byte("a2"), []byte("b2")}, nil, false, []struct{}{}, }, } func TestScanSlice(t *testing.T) { for _, tt := range scanSliceTests { typ := reflect.ValueOf(tt.dest).Type() dest := reflect.New(typ) err := redis.ScanSlice(tt.src, dest.Interface(), tt.fieldNames...) if tt.ok != (err == nil) { t.Errorf("ScanSlice(%v, []%s, %v) returned error %v", tt.src, typ, tt.fieldNames, err) continue } if tt.ok && !reflect.DeepEqual(dest.Elem().Interface(), tt.dest) { t.Errorf("ScanSlice(src, []%s) returned %#v, want %#v", typ, dest.Elem().Interface(), tt.dest) } } } func ExampleScanSlice() { c, err := dial() if err != nil { fmt.Println(err) return } defer c.Close() c.Send("HMSET", "album:1", "title", "Red", "rating", 5) c.Send("HMSET", "album:2", "title", "Earthbound", "rating", 1) c.Send("HMSET", "album:3", "title", "Beat", "rating", 4) c.Send("LPUSH", "albums", "1") c.Send("LPUSH", "albums", "2") c.Send("LPUSH", "albums", "3") values, err := redis.Values(c.Do("SORT", "albums", "BY", "album:*->rating", "GET", "album:*->title", "GET", "album:*->rating")) if err != nil { fmt.Println(err) return } var albums []struct { Title string Rating int } if err := redis.ScanSlice(values, &albums); err != nil { fmt.Println(err) return } fmt.Printf("%v\n", albums) // Output: // [{Earthbound 1} {Beat 4} {Red 5}] } var argsTests = []struct { title string actual redis.Args expected redis.Args }{ {"struct ptr", redis.Args{}.AddFlat(&struct { I int `redis:"i"` U uint `redis:"u"` S string `redis:"s"` P []byte `redis:"p"` M map[string]string `redis:"m"` Bt bool Bf bool }{ -1234, 5678, "hello", []byte("world"), map[string]string{"hello": "world"}, true, false, }), redis.Args{"i", int(-1234), "u", uint(5678), "s", "hello", "p", []byte("world"), "m", map[string]string{"hello": "world"}, "Bt", true, "Bf", false}, }, {"struct", redis.Args{}.AddFlat(struct{ I int }{123}), redis.Args{"I", 123}, }, {"slice", redis.Args{}.Add(1).AddFlat([]string{"a", "b", "c"}).Add(2), redis.Args{1, "a", "b", "c", 2}, }, {"struct omitempty", redis.Args{}.AddFlat(&struct { I int `redis:"i,omitempty"` U uint `redis:"u,omitempty"` S string `redis:"s,omitempty"` P []byte `redis:"p,omitempty"` M map[string]string `redis:"m,omitempty"` Bt bool `redis:"Bt,omitempty"` Bf bool `redis:"Bf,omitempty"` }{ 0, 0, "", []byte{}, map[string]string{}, true, false, }), redis.Args{"Bt", true}, }, } func TestArgs(t *testing.T) { for _, tt := range argsTests { if !reflect.DeepEqual(tt.actual, tt.expected) { t.Fatalf("%s is %v, want %v", tt.title, tt.actual, tt.expected) } } } func ExampleArgs() { c, err := dial() if err != nil { fmt.Println(err) return } defer c.Close() var p1, p2 struct { Title string `redis:"title"` Author string `redis:"author"` Body string `redis:"body"` } p1.Title = "Example" p1.Author = "Gary" p1.Body = "Hello" if _, err := c.Do("HMSET", redis.Args{}.Add("id1").AddFlat(&p1)...); err != nil { fmt.Println(err) return } m := map[string]string{ "title": "Example2", "author": "Steve", "body": "Map", } if _, err := c.Do("HMSET", redis.Args{}.Add("id2").AddFlat(m)...); err != nil { fmt.Println(err) return } for _, id := range []string{"id1", "id2"} { v, err := redis.Values(c.Do("HGETALL", id)) if err != nil { fmt.Println(err) return } if err := redis.ScanStruct(v, &p2); err != nil { fmt.Println(err) return } fmt.Printf("%+v\n", p2) } // Output: // {Title:Example Author:Gary Body:Hello} // {Title:Example2 Author:Steve Body:Map} } ================================================ FILE: vendor/github.com/garyburd/redigo/redis/script.go ================================================ // Copyright 2012 Gary Burd // // Licensed under the Apache License, Version 2.0 (the "License"): you may // not use this file except in compliance with the License. You may obtain // a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. package redis import ( "crypto/sha1" "encoding/hex" "io" "strings" ) // Script encapsulates the source, hash and key count for a Lua script. See // http://redis.io/commands/eval for information on scripts in Redis. type Script struct { keyCount int src string hash string } // NewScript returns a new script object. If keyCount is greater than or equal // to zero, then the count is automatically inserted in the EVAL command // argument list. If keyCount is less than zero, then the application supplies // the count as the first value in the keysAndArgs argument to the Do, Send and // SendHash methods. func NewScript(keyCount int, src string) *Script { h := sha1.New() io.WriteString(h, src) return &Script{keyCount, src, hex.EncodeToString(h.Sum(nil))} } func (s *Script) args(spec string, keysAndArgs []interface{}) []interface{} { var args []interface{} if s.keyCount < 0 { args = make([]interface{}, 1+len(keysAndArgs)) args[0] = spec copy(args[1:], keysAndArgs) } else { args = make([]interface{}, 2+len(keysAndArgs)) args[0] = spec args[1] = s.keyCount copy(args[2:], keysAndArgs) } return args } // Do evaluates the script. Under the covers, Do optimistically evaluates the // script using the EVALSHA command. If the command fails because the script is // not loaded, then Do evaluates the script using the EVAL command (thus // causing the script to load). func (s *Script) Do(c Conn, keysAndArgs ...interface{}) (interface{}, error) { v, err := c.Do("EVALSHA", s.args(s.hash, keysAndArgs)...) if e, ok := err.(Error); ok && strings.HasPrefix(string(e), "NOSCRIPT ") { v, err = c.Do("EVAL", s.args(s.src, keysAndArgs)...) } return v, err } // SendHash evaluates the script without waiting for the reply. The script is // evaluated with the EVALSHA command. The application must ensure that the // script is loaded by a previous call to Send, Do or Load methods. func (s *Script) SendHash(c Conn, keysAndArgs ...interface{}) error { return c.Send("EVALSHA", s.args(s.hash, keysAndArgs)...) } // Send evaluates the script without waiting for the reply. func (s *Script) Send(c Conn, keysAndArgs ...interface{}) error { return c.Send("EVAL", s.args(s.src, keysAndArgs)...) } // Load loads the script without evaluating it. func (s *Script) Load(c Conn) error { _, err := c.Do("SCRIPT", "LOAD", s.src) return err } ================================================ FILE: vendor/github.com/garyburd/redigo/redis/script_test.go ================================================ // Copyright 2012 Gary Burd // // Licensed under the Apache License, Version 2.0 (the "License"): you may // not use this file except in compliance with the License. You may obtain // a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. package redis_test import ( "fmt" "reflect" "testing" "time" "github.com/garyburd/redigo/redis" ) var ( // These variables are declared at package level to remove distracting // details from the examples. c redis.Conn reply interface{} err error ) func ExampleScript() { // Initialize a package-level variable with a script. var getScript = redis.NewScript(1, `return redis.call('get', KEYS[1])`) // In a function, use the script Do method to evaluate the script. The Do // method optimistically uses the EVALSHA command. If the script is not // loaded, then the Do method falls back to the EVAL command. reply, err = getScript.Do(c, "foo") } func TestScript(t *testing.T) { c, err := redis.DialDefaultServer() if err != nil { t.Fatalf("error connection to database, %v", err) } defer c.Close() // To test fall back in Do, we make script unique by adding comment with current time. script := fmt.Sprintf("--%d\nreturn {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}", time.Now().UnixNano()) s := redis.NewScript(2, script) reply := []interface{}{[]byte("key1"), []byte("key2"), []byte("arg1"), []byte("arg2")} v, err := s.Do(c, "key1", "key2", "arg1", "arg2") if err != nil { t.Errorf("s.Do(c, ...) returned %v", err) } if !reflect.DeepEqual(v, reply) { t.Errorf("s.Do(c, ..); = %v, want %v", v, reply) } err = s.Load(c) if err != nil { t.Errorf("s.Load(c) returned %v", err) } err = s.SendHash(c, "key1", "key2", "arg1", "arg2") if err != nil { t.Errorf("s.SendHash(c, ...) returned %v", err) } err = c.Flush() if err != nil { t.Errorf("c.Flush() returned %v", err) } v, err = c.Receive() if !reflect.DeepEqual(v, reply) { t.Errorf("s.SendHash(c, ..); c.Receive() = %v, want %v", v, reply) } err = s.Send(c, "key1", "key2", "arg1", "arg2") if err != nil { t.Errorf("s.Send(c, ...) returned %v", err) } err = c.Flush() if err != nil { t.Errorf("c.Flush() returned %v", err) } v, err = c.Receive() if !reflect.DeepEqual(v, reply) { t.Errorf("s.Send(c, ..); c.Receive() = %v, want %v", v, reply) } } ================================================ FILE: vendor/github.com/garyburd/redigo/redis/test_test.go ================================================ // Copyright 2012 Gary Burd // // Licensed under the Apache License, Version 2.0 (the "License"): you may // not use this file except in compliance with the License. You may obtain // a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. package redis import ( "bufio" "errors" "flag" "fmt" "io" "io/ioutil" "os" "os/exec" "strconv" "strings" "sync" "testing" "time" ) func SetNowFunc(f func() time.Time) { nowFunc = f } var ( ErrNegativeInt = errNegativeInt serverPath = flag.String("redis-server", "redis-server", "Path to redis server binary") serverBasePort = flag.Int("redis-port", 16379, "Beginning of port range for test servers") serverLogName = flag.String("redis-log", "", "Write Redis server logs to `filename`") serverLog = ioutil.Discard defaultServerMu sync.Mutex defaultServer *Server defaultServerErr error ) type Server struct { name string cmd *exec.Cmd done chan struct{} } func NewServer(name string, args ...string) (*Server, error) { s := &Server{ name: name, cmd: exec.Command(*serverPath, args...), done: make(chan struct{}), } r, err := s.cmd.StdoutPipe() if err != nil { return nil, err } err = s.cmd.Start() if err != nil { return nil, err } ready := make(chan error, 1) go s.watch(r, ready) select { case err = <-ready: case <-time.After(time.Second * 10): err = errors.New("timeout waiting for server to start") } if err != nil { s.Stop() return nil, err } return s, nil } func (s *Server) watch(r io.Reader, ready chan error) { fmt.Fprintf(serverLog, "%d START %s \n", s.cmd.Process.Pid, s.name) var listening bool var text string scn := bufio.NewScanner(r) for scn.Scan() { text = scn.Text() fmt.Fprintf(serverLog, "%s\n", text) if !listening { if strings.Contains(text, "The server is now ready to accept connections on port") { listening = true ready <- nil } } } if !listening { ready <- fmt.Errorf("server exited: %s", text) } s.cmd.Wait() fmt.Fprintf(serverLog, "%d STOP %s \n", s.cmd.Process.Pid, s.name) close(s.done) } func (s *Server) Stop() { s.cmd.Process.Signal(os.Interrupt) <-s.done } // stopDefaultServer stops the server created by DialDefaultServer. func stopDefaultServer() { defaultServerMu.Lock() defer defaultServerMu.Unlock() if defaultServer != nil { defaultServer.Stop() defaultServer = nil } } // startDefaultServer starts the default server if not already running. func startDefaultServer() error { defaultServerMu.Lock() defer defaultServerMu.Unlock() if defaultServer != nil || defaultServerErr != nil { return defaultServerErr } defaultServer, defaultServerErr = NewServer( "default", "--port", strconv.Itoa(*serverBasePort), "--save", "", "--appendonly", "no") return defaultServerErr } // DialDefaultServer starts the test server if not already started and dials a // connection to the server. func DialDefaultServer() (Conn, error) { if err := startDefaultServer(); err != nil { return nil, err } c, err := Dial("tcp", fmt.Sprintf(":%d", *serverBasePort), DialReadTimeout(1*time.Second), DialWriteTimeout(1*time.Second)) if err != nil { return nil, err } c.Do("FLUSHDB") return c, nil } func TestMain(m *testing.M) { os.Exit(func() int { flag.Parse() var f *os.File if *serverLogName != "" { var err error f, err = os.OpenFile(*serverLogName, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0600) if err != nil { fmt.Fprintf(os.Stderr, "Error opening redis-log: %v\n", err) return 1 } defer f.Close() serverLog = f } defer stopDefaultServer() return m.Run() }()) } ================================================ FILE: vendor/github.com/garyburd/redigo/redis/zpop_example_test.go ================================================ // Copyright 2013 Gary Burd // // Licensed under the Apache License, Version 2.0 (the "License"): you may // not use this file except in compliance with the License. You may obtain // a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. package redis_test import ( "fmt" "github.com/garyburd/redigo/redis" ) // zpop pops a value from the ZSET key using WATCH/MULTI/EXEC commands. func zpop(c redis.Conn, key string) (result string, err error) { defer func() { // Return connection to normal state on error. if err != nil { c.Do("DISCARD") } }() // Loop until transaction is successful. for { if _, err := c.Do("WATCH", key); err != nil { return "", err } members, err := redis.Strings(c.Do("ZRANGE", key, 0, 0)) if err != nil { return "", err } if len(members) != 1 { return "", redis.ErrNil } c.Send("MULTI") c.Send("ZREM", key, members[0]) queued, err := c.Do("EXEC") if err != nil { return "", err } if queued != nil { result = members[0] break } } return result, nil } // zpopScript pops a value from a ZSET. var zpopScript = redis.NewScript(1, ` local r = redis.call('ZRANGE', KEYS[1], 0, 0) if r ~= nil then r = r[1] redis.call('ZREM', KEYS[1], r) end return r `) // This example implements ZPOP as described at // http://redis.io/topics/transactions using WATCH/MULTI/EXEC and scripting. func Example_zpop() { c, err := dial() if err != nil { fmt.Println(err) return } defer c.Close() // Add test data using a pipeline. for i, member := range []string{"red", "blue", "green"} { c.Send("ZADD", "zset", i, member) } if _, err := c.Do(""); err != nil { fmt.Println(err) return } // Pop using WATCH/MULTI/EXEC v, err := zpop(c, "zset") if err != nil { fmt.Println(err) return } fmt.Println(v) // Pop using a script. v, err = redis.String(zpopScript.Do(c, "zset")) if err != nil { fmt.Println(err) return } fmt.Println(v) // Output: // red // blue } ================================================ FILE: vendor/github.com/garyburd/redigo/redisx/connmux.go ================================================ // Copyright 2014 Gary Burd // // Licensed under the Apache License, Version 2.0 (the "License"): you may // not use this file except in compliance with the License. You may obtain // a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. package redisx import ( "errors" "sync" "github.com/garyburd/redigo/internal" "github.com/garyburd/redigo/redis" ) // ConnMux multiplexes one or more connections to a single underlying // connection. The ConnMux connections do not support concurrency, commands // that associate server side state with the connection or commands that put // the connection in a special mode. type ConnMux struct { c redis.Conn sendMu sync.Mutex sendID uint recvMu sync.Mutex recvID uint recvWait map[uint]chan struct{} } func NewConnMux(c redis.Conn) *ConnMux { return &ConnMux{c: c, recvWait: make(map[uint]chan struct{})} } // Get gets a connection. The application must close the returned connection. func (p *ConnMux) Get() redis.Conn { c := &muxConn{p: p} c.ids = c.buf[:0] return c } // Close closes the underlying connection. func (p *ConnMux) Close() error { return p.c.Close() } type muxConn struct { p *ConnMux ids []uint buf [8]uint } func (c *muxConn) send(flush bool, cmd string, args ...interface{}) error { if internal.LookupCommandInfo(cmd).Set != 0 { return errors.New("command not supported by mux pool") } p := c.p p.sendMu.Lock() id := p.sendID c.ids = append(c.ids, id) p.sendID++ err := p.c.Send(cmd, args...) if flush { err = p.c.Flush() } p.sendMu.Unlock() return err } func (c *muxConn) Send(cmd string, args ...interface{}) error { return c.send(false, cmd, args...) } func (c *muxConn) Flush() error { p := c.p p.sendMu.Lock() err := p.c.Flush() p.sendMu.Unlock() return err } func (c *muxConn) Receive() (interface{}, error) { if len(c.ids) == 0 { return nil, errors.New("mux pool underflow") } id := c.ids[0] c.ids = c.ids[1:] if len(c.ids) == 0 { c.ids = c.buf[:0] } p := c.p p.recvMu.Lock() if p.recvID != id { ch := make(chan struct{}) p.recvWait[id] = ch p.recvMu.Unlock() <-ch p.recvMu.Lock() if p.recvID != id { panic("out of sync") } } v, err := p.c.Receive() id++ p.recvID = id ch, ok := p.recvWait[id] if ok { delete(p.recvWait, id) } p.recvMu.Unlock() if ok { ch <- struct{}{} } return v, err } func (c *muxConn) Close() error { var err error if len(c.ids) == 0 { return nil } c.Flush() for _ = range c.ids { _, err = c.Receive() } return err } func (c *muxConn) Do(cmd string, args ...interface{}) (interface{}, error) { if err := c.send(true, cmd, args...); err != nil { return nil, err } return c.Receive() } func (c *muxConn) Err() error { return c.p.c.Err() } ================================================ FILE: vendor/github.com/garyburd/redigo/redisx/connmux_test.go ================================================ // Copyright 2014 Gary Burd // // Licensed under the Apache License, Version 2.0 (the "License"): you may // not use this file except in compliance with the License. You may obtain // a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. package redisx_test import ( "net/textproto" "sync" "testing" "github.com/garyburd/redigo/internal/redistest" "github.com/garyburd/redigo/redis" "github.com/garyburd/redigo/redisx" ) func TestConnMux(t *testing.T) { c, err := redistest.Dial() if err != nil { t.Fatalf("error connection to database, %v", err) } m := redisx.NewConnMux(c) defer m.Close() c1 := m.Get() c2 := m.Get() c1.Send("ECHO", "hello") c2.Send("ECHO", "world") c1.Flush() c2.Flush() s, err := redis.String(c1.Receive()) if err != nil { t.Fatal(err) } if s != "hello" { t.Fatalf("echo returned %q, want %q", s, "hello") } s, err = redis.String(c2.Receive()) if err != nil { t.Fatal(err) } if s != "world" { t.Fatalf("echo returned %q, want %q", s, "world") } c1.Close() c2.Close() } func TestConnMuxClose(t *testing.T) { c, err := redistest.Dial() if err != nil { t.Fatalf("error connection to database, %v", err) } m := redisx.NewConnMux(c) defer m.Close() c1 := m.Get() c2 := m.Get() if err := c1.Send("ECHO", "hello"); err != nil { t.Fatal(err) } if err := c1.Close(); err != nil { t.Fatal(err) } if err := c2.Send("ECHO", "world"); err != nil { t.Fatal(err) } if err := c2.Flush(); err != nil { t.Fatal(err) } s, err := redis.String(c2.Receive()) if err != nil { t.Fatal(err) } if s != "world" { t.Fatalf("echo returned %q, want %q", s, "world") } c2.Close() } func BenchmarkConn(b *testing.B) { b.StopTimer() c, err := redistest.Dial() if err != nil { b.Fatalf("error connection to database, %v", err) } defer c.Close() b.StartTimer() for i := 0; i < b.N; i++ { if _, err := c.Do("PING"); err != nil { b.Fatal(err) } } } func BenchmarkConnMux(b *testing.B) { b.StopTimer() c, err := redistest.Dial() if err != nil { b.Fatalf("error connection to database, %v", err) } m := redisx.NewConnMux(c) defer m.Close() b.StartTimer() for i := 0; i < b.N; i++ { c := m.Get() if _, err := c.Do("PING"); err != nil { b.Fatal(err) } c.Close() } } func BenchmarkPool(b *testing.B) { b.StopTimer() p := redis.Pool{Dial: redistest.Dial, MaxIdle: 1} defer p.Close() // Fill the pool. c := p.Get() if err := c.Err(); err != nil { b.Fatal(err) } c.Close() b.StartTimer() for i := 0; i < b.N; i++ { c := p.Get() if _, err := c.Do("PING"); err != nil { b.Fatal(err) } c.Close() } } const numConcurrent = 10 func BenchmarkConnMuxConcurrent(b *testing.B) { b.StopTimer() c, err := redistest.Dial() if err != nil { b.Fatalf("error connection to database, %v", err) } defer c.Close() m := redisx.NewConnMux(c) var wg sync.WaitGroup wg.Add(numConcurrent) b.StartTimer() for i := 0; i < numConcurrent; i++ { go func() { defer wg.Done() for i := 0; i < b.N; i++ { c := m.Get() if _, err := c.Do("PING"); err != nil { b.Fatal(err) } c.Close() } }() } wg.Wait() } func BenchmarkPoolConcurrent(b *testing.B) { b.StopTimer() p := redis.Pool{Dial: redistest.Dial, MaxIdle: numConcurrent} defer p.Close() // Fill the pool. conns := make([]redis.Conn, numConcurrent) for i := range conns { c := p.Get() if err := c.Err(); err != nil { b.Fatal(err) } conns[i] = c } for _, c := range conns { c.Close() } var wg sync.WaitGroup wg.Add(numConcurrent) b.StartTimer() for i := 0; i < numConcurrent; i++ { go func() { defer wg.Done() for i := 0; i < b.N; i++ { c := p.Get() if _, err := c.Do("PING"); err != nil { b.Fatal(err) } c.Close() } }() } wg.Wait() } func BenchmarkPipelineConcurrency(b *testing.B) { b.StopTimer() c, err := redistest.Dial() if err != nil { b.Fatalf("error connection to database, %v", err) } defer c.Close() var wg sync.WaitGroup wg.Add(numConcurrent) var pipeline textproto.Pipeline b.StartTimer() for i := 0; i < numConcurrent; i++ { go func() { defer wg.Done() for i := 0; i < b.N; i++ { id := pipeline.Next() pipeline.StartRequest(id) c.Send("PING") c.Flush() pipeline.EndRequest(id) pipeline.StartResponse(id) _, err := c.Receive() if err != nil { b.Fatal(err) } pipeline.EndResponse(id) } }() } wg.Wait() } ================================================ FILE: vendor/github.com/garyburd/redigo/redisx/doc.go ================================================ // Copyright 2012 Gary Burd // // Licensed under the Apache License, Version 2.0 (the "License"): you may // not use this file except in compliance with the License. You may obtain // a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. // Package redisx contains experimental features for Redigo. Features in this // package may be modified or deleted at any time. package redisx // import "github.com/garyburd/redigo/redisx" ================================================ FILE: vendor/github.com/imroc/log/LICENSE ================================================ MIT License Copyright (c) 2016 roc 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: vendor/github.com/imroc/log/README.md ================================================ log ============== log is a logging framework of Go. see [API](https://godoc.org/github.com/imroc/log). ## Features * light weight * easy to use * level logging support * flexible ## Quick Start ##### Installation ``` sh go get github.com/imroc/log ``` ##### Simple Usage ``` go import ( "github.com/imroc/log" ) func main() { // DEBUG < INFO < WARN < ERROR < FATAL log.SetLevel(log.WARN) // level DEBUG and INFO will not output log.Debug("%s message", "debug") log.Info("%s message", "info") log.Warn("%s message", "warn") log.Error("%s message", "error") log.Fatal("%s message", "fatal") } ``` output: ``` 2016/10/04 14:38:38 [WARN] warn message 2016/10/04 14:38:38 [EROR] error message 2016/10/04 14:38:38 [FATL] fatal message ``` ##### More Control ``` go file, _ := os.OpenFile("test.log", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666) log.Set(log.INFO, file, log.Llongfile|log.LstdFlags) log.Debug("%s message", "debug") log.Info("%s message", "info") log.Warn("%s message", "warn") log.Error("%s message", "error") log.Fatal("%s message", "fatal") ``` output to test.log: ``` 2016/10/04 15:04:00 [INFO] /home/cpwl/go/dev/src/test/test.go:13: info message 2016/10/04 15:04:00 [WARN] /home/cpwl/go/dev/src/test/test.go:14: warn message 2016/10/04 15:04:00 [EROR] /home/cpwl/go/dev/src/test/test.go:15: error message 2016/10/04 15:04:00 [FATL] /home/cpwl/go/dev/src/test/test.go:16: fatal message ``` ## LICENSE log is is distributed under the terms of the MIT License. ================================================ FILE: vendor/github.com/imroc/log/log.go ================================================ package log import ( "fmt" "io" "os" "runtime" "sync" "time" ) // These flags define which text to prefix to each log entry generated by the Logger. const ( // Bits or'ed together to control what's printed. // There is no control over the order they appear (the order listed // here) or the format they present (as described in the comments). // The prefix is followed by a colon only when Llongfile or Lshortfile // is specified. // For example, flags Ldate | Ltime (or LstdFlags) produce, // 2009/01/23 01:23:23 message // while flags Ldate | Ltime | Lmicroseconds | Llongfile produce, // 2009/01/23 01:23:23.123123 /a/b/c/d.go:23: message Ldate = 1 << iota // the date in the local time zone: 2009/01/23 Ltime // the time in the local time zone: 01:23:23 Lmicroseconds // microsecond resolution: 01:23:23.123123. assumes Ltime. Llongfile // full file name and line number: /a/b/c/d.go:23 Lshortfile // final file name element and line number: d.go:23. overrides Llongfile LUTC // if Ldate or Ltime is set, use UTC rather than the local time zone LstdFlags = Ldate | Ltime // initial values for the standard logger ) // log levels const ( DEBUG int = iota INFO WARN ERROR FATAL ) // Log level strings var ( levelStrings = [...]string{"[DEBG]", "[INFO]", "[WARN]", "[EROR]", "[FATL]"} ) // A Logger represents an active logging object that generates lines of // output to an io.Writer. Each logging operation makes a single call to // the Writer's Write method. A Logger can be used simultaneously from // multiple goroutines; it guarantees to serialize access to the Writer. type Logger struct { level int // log level mu sync.Mutex // ensures atomic writes; protects the following fields flag int // properties out io.Writer // destination for output buf []byte // for accumulating text to write } // Set sets the wirter,log level and flags. func Set(level int, out io.Writer, flag int) { if out == nil || level < DEBUG || level > FATAL { panic("error logger arguments") } std = Logger{out: out, level: level, flag: flag} } var std = Logger{out: os.Stderr, level: DEBUG, flag: LstdFlags} // Cheap integer to fixed-width decimal ASCII. Give a negative width to avoid zero-padding. func itoa(buf *[]byte, i int, wid int) { // Assemble decimal in reverse order. var b [20]byte bp := len(b) - 1 for i >= 10 || wid > 1 { wid-- q := i / 10 b[bp] = byte('0' + i - q*10) bp-- i = q } // i < 10 b[bp] = byte('0' + i) *buf = append(*buf, b[bp:]...) } func (l *Logger) formatHeader(buf *[]byte, t time.Time, level string, file string, line int) { if l.flag&LUTC != 0 { t = t.UTC() } if l.flag&(Ldate|Ltime|Lmicroseconds) != 0 { if l.flag&Ldate != 0 { year, month, day := t.Date() itoa(buf, year, 4) *buf = append(*buf, '/') itoa(buf, int(month), 2) *buf = append(*buf, '/') itoa(buf, day, 2) *buf = append(*buf, ' ') } if l.flag&(Ltime|Lmicroseconds) != 0 { hour, min, sec := t.Clock() itoa(buf, hour, 2) *buf = append(*buf, ':') itoa(buf, min, 2) *buf = append(*buf, ':') itoa(buf, sec, 2) if l.flag&Lmicroseconds != 0 { *buf = append(*buf, '.') itoa(buf, t.Nanosecond()/1e3, 6) } *buf = append(*buf, ' ') } } *buf = append(*buf, level...) *buf = append(*buf, ' ') if l.flag&(Lshortfile|Llongfile) != 0 { if l.flag&Lshortfile != 0 { short := file for i := len(file) - 1; i > 0; i-- { if file[i] == '/' { short = file[i+1:] break } } file = short } *buf = append(*buf, file...) *buf = append(*buf, ':') itoa(buf, line, -1) *buf = append(*buf, ": "...) } } // Output outputs the string of lv level to the writer. func (l *Logger) Output(lv int, s string) error { now := time.Now() // get this early. var file string var line int l.mu.Lock() defer l.mu.Unlock() if l.flag&(Lshortfile|Llongfile) != 0 { // release lock while getting caller info - it's expensive. l.mu.Unlock() var ok bool _, file, line, ok = runtime.Caller(2) if !ok { file = "???" line = 0 } l.mu.Lock() } l.buf = l.buf[:0] l.formatHeader(&l.buf, now, levelStrings[lv], file, line) l.buf = append(l.buf, s...) if len(s) == 0 || s[len(s)-1] != '\n' { l.buf = append(l.buf, '\n') } _, err := l.out.Write(l.buf) return err } // SetOutput sets the output destination for the standard logger. func SetOutput(w io.Writer) { if w == nil { panic("output can not be nil") } std.mu.Lock() defer std.mu.Unlock() std.out = w } //SetLevel sets the log level for the standard logger. func SetLevel(level int) { if level < DEBUG || level > FATAL { panic("wrong log level") } std.mu.Lock() defer std.mu.Unlock() std.level = level } // SetFlags sets the output flags for the standard logger. func SetFlags(flag int) { std.flag = flag } // Debug output the debug info if currrent level is not less than DEBUG. func Debug(format string, a ...interface{}) { if DEBUG < std.level { return } std.Output(DEBUG, fmt.Sprintf(format, a...)) } // Info output the debug info if currrent level is not less than INFO. func Info(format string, a ...interface{}) { if INFO < std.level { return } std.Output(INFO, fmt.Sprintf(format, a...)) } // Warn output the debug info if currrent level is not less than WARN. func Warn(format string, a ...interface{}) { if WARN < std.level { return } std.Output(WARN, fmt.Sprintf(format, a...)) } // Error output the debug info if currrent level is not less than ERROR. func Error(format string, a ...interface{}) { if ERROR < std.level { return } std.Output(ERROR, fmt.Sprintf(format, a...)) } // Fatal output the debug info if currrent level is not less than Fatal. func Fatal(format string, a ...interface{}) { if FATAL < std.level { return } std.Output(FATAL, fmt.Sprintf(format, a...)) } ================================================ FILE: xf/README.md ================================================ xf ============== xf 是科大讯飞语音离线合成SDK的go封装. ##注意 使用该包的程序依赖 lib/libmsc.so 动态链接库文件,将其放入某路径并指定环境变量 LD_LIBRARY_PATH ,如:export LD_LIBRARY_PATH = /usr/local/lib ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/all__0_8js.html ================================================ MSC for Windows&Linux API: iFlytek MSC Reference Manual/search/all_0.js 文件参考
MSC for Windows&Linux API
all_0.js 文件参考

变量

var searchData
 

变量说明

var searchData
初始值:
=
[
['msp_5fcmn_2eh',['msp_cmn.h',['../msp__cmn_8h.html',1,'']]],
['mspgetparam',['MSPGetParam',['../msp__cmn_8h.html#a4d3fa0aad5e761cb2a2afe30ae2a9714',1,'msp_cmn.h']]],
['mspgetversion',['MSPGetVersion',['../msp__cmn_8h.html#a632008aeddf5eba09555920ce38686a4',1,'msp_cmn.h']]],
['msplogin',['MSPLogin',['../msp__cmn_8h.html#a137acfe684fe46cbe5baf19f7d4a7fcc',1,'msp_cmn.h']]],
['msplogout',['MSPLogout',['../msp__cmn_8h.html#a1e0f72cd113b4578afdf3d16ab34463e',1,'msp_cmn.h']]],
['mspsearch',['MSPSearch',['../msp__cmn_8h.html#ae7be2dd2c6ee318524621b952998c14d',1,'msp_cmn.h']]],
['mspuploaddata',['MSPUploadData',['../msp__cmn_8h.html#ada276fa6db4a66342d951820020e4e8f',1,'msp_cmn.h']]]
]
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/all__1_8js.html ================================================ MSC for Windows&Linux API: iFlytek MSC Reference Manual/search/all_1.js 文件参考
MSC for Windows&Linux API
all_1.js 文件参考

变量

var searchData
 

变量说明

var searchData
初始值:
=
[
['qisr_2eh',['qisr.h',['../qisr_8h.html',1,'']]],
['qisraudiowrite',['QISRAudioWrite',['../qisr_8h.html#a47fd2588fe834fa2d51fef1961d7aef4',1,'qisr.h']]],
['qisrgetparam',['QISRGetParam',['../qisr_8h.html#a2081e3cad9a8155c15790a2476be7044',1,'qisr.h']]],
['qisrgetresult',['QISRGetResult',['../qisr_8h.html#a2e7880db4792266a4d1439238c0b2c1b',1,'qisr.h']]],
['qisrsessionbegin',['QISRSessionBegin',['../qisr_8h.html#aaec4a5779275e07c4f7405ed8d739416',1,'qisr.h']]],
['qisrsessionend',['QISRSessionEnd',['../qisr_8h.html#ab50c4114e032100c4093ddd51329fecc',1,'qisr.h']]],
['qmfv_2eh',['qmfv.h',['../qmfv_8h.html',1,'']]],
['qmfvdatawrite',['QMFVDataWrite',['../qmfv_8h.html#a081a01b2add2dfac3010ec7cd8ba5eac',1,'qmfv.h']]],
['qmfvgetparam',['QMFVGetParam',['../qmfv_8h.html#a7174d943c2f1691f6a8c717429d43f8d',1,'qmfv.h']]],
['qmfvgetresult',['QMFVGetResult',['../qmfv_8h.html#aa87716ad6b28326982626c0c6a6ffcbd',1,'qmfv.h']]],
['qmfvsessionbegin',['QMFVSessionBegin',['../qmfv_8h.html#adbe23b402d4c50b4c06f47ca26253be5',1,'qmfv.h']]],
['qmfvsessionend',['QMFVSessionEnd',['../qmfv_8h.html#ad4ea72dd39285348cf26c627d67c6b65',1,'qmfv.h']]],
['qtts_2eh',['qtts.h',['../qtts_8h.html',1,'']]],
['qttsaudioget',['QTTSAudioGet',['../qtts_8h.html#a4e4f6bed4b9e4ea553aa00ccf539c22a',1,'qtts.h']]],
['qttsgetparam',['QTTSGetParam',['../qtts_8h.html#a0812612ff738a828490e4e3db59767e8',1,'qtts.h']]],
['qttssessionbegin',['QTTSSessionBegin',['../qtts_8h.html#a3fba4ad9599445073335851cc9479542',1,'qtts.h']]],
['qttssessionend',['QTTSSessionEnd',['../qtts_8h.html#a75d5047a2a889dbd890d116a6d0b550a',1,'qtts.h']]],
['qttstextput',['QTTSTextPut',['../qtts_8h.html#a5b7d146d6a35341d4d73efd720ae987b',1,'qtts.h']]]
]
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/dir_25539194184bab781b1c7ecd67774cd8.html ================================================ MSC for Windows&Linux API: iFlytek MSC Reference Manual/search 目录参考
MSC for Windows&Linux API
search 目录参考

文件

文件  all_0.js
 
文件  all_1.js
 
文件  files_0.js
 
文件  files_1.js
 
文件  functions_0.js
 
文件  functions_1.js
 
文件  search.js
 
文件  searchdata.js
 
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/dir_9a65024ac0a05d9abfc2bb6c7ff8f818.html ================================================ MSC for Windows&Linux API: iFlytek MSC Reference Manual 目录参考
MSC for Windows&Linux API
iFlytek MSC Reference Manual 目录参考

目录

目录  search
 

文件

文件  dynsections.js
 
文件  jquery.js
 
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/doxygen.css ================================================ /* The standard CSS for doxygen 1.8.9 */ body, table, div, p, dl { font: 400 14px/22px Roboto,sans-serif; } /* @group Heading Levels */ h1.groupheader { font-size: 150%; } .title { font: 400 14px/28px Roboto,sans-serif; font-size: 150%; font-weight: bold; margin: 10px 2px; } h2.groupheader { border-bottom: 1px solid #879ECB; color: #354C7B; font-size: 150%; font-weight: normal; margin-top: 1.75em; padding-top: 8px; padding-bottom: 4px; width: 100%; } h3.groupheader { font-size: 100%; } h1, h2, h3, h4, h5, h6 { -webkit-transition: text-shadow 0.5s linear; -moz-transition: text-shadow 0.5s linear; -ms-transition: text-shadow 0.5s linear; -o-transition: text-shadow 0.5s linear; transition: text-shadow 0.5s linear; margin-right: 15px; } h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow { text-shadow: 0 0 15px cyan; } dt { font-weight: bold; } div.multicol { -moz-column-gap: 1em; -webkit-column-gap: 1em; -moz-column-count: 3; -webkit-column-count: 3; } p.startli, p.startdd { margin-top: 2px; } p.starttd { margin-top: 0px; } p.endli { margin-bottom: 0px; } p.enddd { margin-bottom: 4px; } p.endtd { margin-bottom: 2px; } /* @end */ caption { font-weight: bold; } span.legend { font-size: 70%; text-align: center; } h3.version { font-size: 90%; text-align: center; } div.qindex, div.navtab{ background-color: #EBEFF6; border: 1px solid #A3B4D7; text-align: center; } div.qindex, div.navpath { width: 100%; line-height: 140%; } div.navtab { margin-right: 15px; } /* @group Link Styling */ a { color: #3D578C; font-weight: normal; text-decoration: none; } .contents a:visited { color: #4665A2; } a:hover { text-decoration: underline; } a.qindex { font-weight: bold; } a.qindexHL { font-weight: bold; background-color: #9CAFD4; color: #ffffff; border: 1px double #869DCA; } .contents a.qindexHL:visited { color: #ffffff; } a.el { font-weight: bold; } a.elRef { } a.code, a.code:visited, a.line, a.line:visited { color: #4665A2; } a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited { color: #4665A2; } /* @end */ dl.el { margin-left: -1cm; } pre.fragment { border: 1px solid #C4CFE5; background-color: #FBFCFD; padding: 4px 6px; margin: 4px 8px 4px 2px; overflow: auto; word-wrap: break-word; font-size: 9pt; line-height: 125%; font-family: monospace, fixed; font-size: 105%; } div.fragment { padding: 4px 6px; margin: 4px 8px 4px 2px; background-color: #FBFCFD; border: 1px solid #C4CFE5; } div.line { font-family: monospace, fixed; font-size: 13px; min-height: 13px; line-height: 1.0; text-wrap: unrestricted; white-space: -moz-pre-wrap; /* Moz */ white-space: -pre-wrap; /* Opera 4-6 */ white-space: -o-pre-wrap; /* Opera 7 */ white-space: pre-wrap; /* CSS3 */ word-wrap: break-word; /* IE 5.5+ */ text-indent: -53px; padding-left: 53px; padding-bottom: 0px; margin: 0px; -webkit-transition-property: background-color, box-shadow; -webkit-transition-duration: 0.5s; -moz-transition-property: background-color, box-shadow; -moz-transition-duration: 0.5s; -ms-transition-property: background-color, box-shadow; -ms-transition-duration: 0.5s; -o-transition-property: background-color, box-shadow; -o-transition-duration: 0.5s; transition-property: background-color, box-shadow; transition-duration: 0.5s; } div.line.glow { background-color: cyan; box-shadow: 0 0 10px cyan; } span.lineno { padding-right: 4px; text-align: right; border-right: 2px solid #0F0; background-color: #E8E8E8; white-space: pre; } span.lineno a { background-color: #D8D8D8; } span.lineno a:hover { background-color: #C8C8C8; } div.ah, span.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px; padding: 0.2em; border: solid thin #333; border-radius: 0.5em; -webkit-border-radius: .5em; -moz-border-radius: .5em; box-shadow: 2px 2px 3px #999; -webkit-box-shadow: 2px 2px 3px #999; -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444)); background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000); } div.classindex ul { list-style: none; padding-left: 0; } div.classindex span.ai { display: inline-block; } div.groupHeader { margin-left: 16px; margin-top: 12px; font-weight: bold; } div.groupText { margin-left: 16px; font-style: italic; } body { background-color: white; color: black; margin: 0; } div.contents { margin-top: 10px; margin-left: 12px; margin-right: 8px; } td.indexkey { background-color: #EBEFF6; font-weight: bold; border: 1px solid #C4CFE5; margin: 2px 0px 2px 0; padding: 2px 10px; white-space: nowrap; vertical-align: top; } td.indexvalue { background-color: #EBEFF6; border: 1px solid #C4CFE5; padding: 2px 10px; margin: 2px 0px; } tr.memlist { background-color: #EEF1F7; } p.formulaDsp { text-align: center; } img.formulaDsp { } img.formulaInl { vertical-align: middle; } div.center { text-align: center; margin-top: 0px; margin-bottom: 0px; padding: 0px; } div.center img { border: 0px; } address.footer { text-align: right; padding-right: 12px; } img.footer { border: 0px; vertical-align: middle; } /* @group Code Colorization */ span.keyword { color: #008000 } span.keywordtype { color: #604020 } span.keywordflow { color: #e08000 } span.comment { color: #800000 } span.preprocessor { color: #806020 } span.stringliteral { color: #002080 } span.charliteral { color: #008080 } span.vhdldigit { color: #ff00ff } span.vhdlchar { color: #000000 } span.vhdlkeyword { color: #700070 } span.vhdllogic { color: #ff0000 } blockquote { background-color: #F7F8FB; border-left: 2px solid #9CAFD4; margin: 0 24px 0 4px; padding: 0 12px 0 16px; } /* @end */ /* .search { color: #003399; font-weight: bold; } form.search { margin-bottom: 0px; margin-top: 0px; } input.search { font-size: 75%; color: #000080; font-weight: normal; background-color: #e8eef2; } */ td.tiny { font-size: 75%; } .dirtab { padding: 4px; border-collapse: collapse; border: 1px solid #A3B4D7; } th.dirtab { background: #EBEFF6; font-weight: bold; } hr { height: 0px; border: none; border-top: 1px solid #4A6AAA; } hr.footer { height: 1px; } /* @group Member Descriptions */ table.memberdecls { border-spacing: 0px; padding: 0px; } .memberdecls td, .fieldtable tr { -webkit-transition-property: background-color, box-shadow; -webkit-transition-duration: 0.5s; -moz-transition-property: background-color, box-shadow; -moz-transition-duration: 0.5s; -ms-transition-property: background-color, box-shadow; -ms-transition-duration: 0.5s; -o-transition-property: background-color, box-shadow; -o-transition-duration: 0.5s; transition-property: background-color, box-shadow; transition-duration: 0.5s; } .memberdecls td.glow, .fieldtable tr.glow { background-color: cyan; box-shadow: 0 0 15px cyan; } .mdescLeft, .mdescRight, .memItemLeft, .memItemRight, .memTemplItemLeft, .memTemplItemRight, .memTemplParams { background-color: #F9FAFC; border: none; margin: 4px; padding: 1px 0 0 8px; } .mdescLeft, .mdescRight { padding: 0px 8px 4px 8px; color: #555; } .memSeparator { border-bottom: 1px solid #DEE4F0; line-height: 1px; margin: 0px; padding: 0px; } .memItemLeft, .memTemplItemLeft { white-space: nowrap; } .memItemRight { width: 100%; } .memTemplParams { color: #4665A2; white-space: nowrap; font-size: 80%; } /* @end */ /* @group Member Details */ /* Styles for detailed member documentation */ .memtemplate { font-size: 80%; color: #4665A2; font-weight: normal; margin-left: 9px; } .memnav { background-color: #EBEFF6; border: 1px solid #A3B4D7; text-align: center; margin: 2px; margin-right: 15px; padding: 2px; } .mempage { width: 100%; } .memitem { padding: 0; margin-bottom: 10px; margin-right: 5px; -webkit-transition: box-shadow 0.5s linear; -moz-transition: box-shadow 0.5s linear; -ms-transition: box-shadow 0.5s linear; -o-transition: box-shadow 0.5s linear; transition: box-shadow 0.5s linear; display: table !important; width: 100%; } .memitem.glow { box-shadow: 0 0 15px cyan; } .memname { font-weight: bold; margin-left: 6px; } .memname td { vertical-align: bottom; } .memproto, dl.reflist dt { border-top: 1px solid #A8B8D9; border-left: 1px solid #A8B8D9; border-right: 1px solid #A8B8D9; padding: 6px 0px 6px 0px; color: #253555; font-weight: bold; text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); background-image:url('nav_f.png'); background-repeat:repeat-x; background-color: #E2E8F2; /* opera specific markup */ box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); border-top-right-radius: 4px; border-top-left-radius: 4px; /* firefox specific markup */ -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; -moz-border-radius-topright: 4px; -moz-border-radius-topleft: 4px; /* webkit specific markup */ -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); -webkit-border-top-right-radius: 4px; -webkit-border-top-left-radius: 4px; } .memdoc, dl.reflist dd { border-bottom: 1px solid #A8B8D9; border-left: 1px solid #A8B8D9; border-right: 1px solid #A8B8D9; padding: 6px 10px 2px 10px; background-color: #FBFCFD; border-top-width: 0; background-image:url('nav_g.png'); background-repeat:repeat-x; background-color: #FFFFFF; /* opera specific markup */ border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); /* firefox specific markup */ -moz-border-radius-bottomleft: 4px; -moz-border-radius-bottomright: 4px; -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; /* webkit specific markup */ -webkit-border-bottom-left-radius: 4px; -webkit-border-bottom-right-radius: 4px; -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); } dl.reflist dt { padding: 5px; } dl.reflist dd { margin: 0px 0px 10px 0px; padding: 5px; } .paramkey { text-align: right; } .paramtype { white-space: nowrap; } .paramname { color: #602020; white-space: nowrap; } .paramname em { font-style: normal; } .paramname code { line-height: 14px; } .params, .retval, .exception, .tparams { margin-left: 0px; padding-left: 0px; } .params .paramname, .retval .paramname { font-weight: bold; vertical-align: top; } .params .paramtype { font-style: italic; vertical-align: top; } .params .paramdir { font-family: "courier new",courier,monospace; vertical-align: top; } table.mlabels { border-spacing: 0px; } td.mlabels-left { width: 100%; padding: 0px; } td.mlabels-right { vertical-align: bottom; padding: 0px; white-space: nowrap; } span.mlabels { margin-left: 8px; } span.mlabel { background-color: #728DC1; border-top:1px solid #5373B4; border-left:1px solid #5373B4; border-right:1px solid #C4CFE5; border-bottom:1px solid #C4CFE5; text-shadow: none; color: white; margin-right: 4px; padding: 2px 3px; border-radius: 3px; font-size: 7pt; white-space: nowrap; vertical-align: middle; } /* @end */ /* these are for tree view inside a (index) page */ div.directory { margin: 10px 0px; border-top: 1px solid #9CAFD4; border-bottom: 1px solid #9CAFD4; width: 100%; } .directory table { border-collapse:collapse; } .directory td { margin: 0px; padding: 0px; vertical-align: top; } .directory td.entry { white-space: nowrap; padding-right: 6px; padding-top: 3px; } .directory td.entry a { outline:none; } .directory td.entry a img { border: none; } .directory td.desc { width: 100%; padding-left: 6px; padding-right: 6px; padding-top: 3px; border-left: 1px solid rgba(0,0,0,0.05); } .directory tr.even { padding-left: 6px; background-color: #F7F8FB; } .directory img { vertical-align: -30%; } .directory .levels { white-space: nowrap; width: 100%; text-align: right; font-size: 9pt; } .directory .levels span { cursor: pointer; padding-left: 2px; padding-right: 2px; color: #3D578C; } .arrow { color: #9CAFD4; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; cursor: pointer; font-size: 80%; display: inline-block; width: 16px; height: 22px; } .icon { font-family: Arial, Helvetica; font-weight: bold; font-size: 12px; height: 14px; width: 16px; display: inline-block; background-color: #728DC1; color: white; text-align: center; border-radius: 4px; margin-left: 2px; margin-right: 2px; } .icona { width: 24px; height: 22px; display: inline-block; } .iconfopen { width: 24px; height: 18px; margin-bottom: 4px; background-image:url('folderopen.png'); background-position: 0px -4px; background-repeat: repeat-y; vertical-align:top; display: inline-block; } .iconfclosed { width: 24px; height: 18px; margin-bottom: 4px; background-image:url('folderclosed.png'); background-position: 0px -4px; background-repeat: repeat-y; vertical-align:top; display: inline-block; } .icondoc { width: 24px; height: 18px; margin-bottom: 4px; background-image:url('doc.png'); background-position: 0px -4px; background-repeat: repeat-y; vertical-align:top; display: inline-block; } table.directory { font: 400 14px Roboto,sans-serif; } /* @end */ div.dynheader { margin-top: 8px; -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } address { font-style: normal; color: #2A3D61; } table.doxtable { border-collapse:collapse; margin-top: 4px; margin-bottom: 4px; } table.doxtable td, table.doxtable th { border: 1px solid #2D4068; padding: 3px 7px 2px; } table.doxtable th { background-color: #374F7F; color: #FFFFFF; font-size: 110%; padding-bottom: 4px; padding-top: 5px; } table.fieldtable { /*width: 100%;*/ margin-bottom: 10px; border: 1px solid #A8B8D9; border-spacing: 0px; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); } .fieldtable td, .fieldtable th { padding: 3px 7px 2px; } .fieldtable td.fieldtype, .fieldtable td.fieldname { white-space: nowrap; border-right: 1px solid #A8B8D9; border-bottom: 1px solid #A8B8D9; vertical-align: top; } .fieldtable td.fieldname { padding-top: 3px; } .fieldtable td.fielddoc { border-bottom: 1px solid #A8B8D9; /*width: 100%;*/ } .fieldtable td.fielddoc p:first-child { margin-top: 0px; } .fieldtable td.fielddoc p:last-child { margin-bottom: 2px; } .fieldtable tr:last-child td { border-bottom: none; } .fieldtable th { background-image:url('nav_f.png'); background-repeat:repeat-x; background-color: #E2E8F2; font-size: 90%; color: #253555; padding-bottom: 4px; padding-top: 5px; text-align:left; -moz-border-radius-topleft: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-left-radius: 4px; -webkit-border-top-right-radius: 4px; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom: 1px solid #A8B8D9; } .tabsearch { top: 0px; left: 10px; height: 36px; background-image: url('tab_b.png'); z-index: 101; overflow: hidden; font-size: 13px; } .navpath ul { font-size: 11px; background-image:url('tab_b.png'); background-repeat:repeat-x; background-position: 0 -5px; height:30px; line-height:30px; color:#8AA0CC; border:solid 1px #C2CDE4; overflow:hidden; margin:0px; padding:0px; } .navpath li { list-style-type:none; float:left; padding-left:10px; padding-right:15px; background-image:url('bc_s.png'); background-repeat:no-repeat; background-position:right; color:#364D7C; } .navpath li.navelem a { height:32px; display:block; text-decoration: none; outline: none; color: #283A5D; font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); text-decoration: none; } .navpath li.navelem a:hover { color:#6884BD; } .navpath li.footer { list-style-type:none; float:right; padding-left:10px; padding-right:15px; background-image:none; background-repeat:no-repeat; background-position:right; color:#364D7C; font-size: 8pt; } div.summary { float: right; font-size: 8pt; padding-right: 5px; width: 50%; text-align: right; } div.summary a { white-space: nowrap; } div.ingroups { font-size: 8pt; width: 50%; text-align: left; } div.ingroups a { white-space: nowrap; } div.header { background-image:url('nav_h.png'); background-repeat:repeat-x; background-color: #F9FAFC; margin: 0px; border-bottom: 1px solid #C4CFE5; } div.headertitle { padding: 5px 5px 5px 10px; } dl { padding: 0 0 0 10px; } /* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug */ dl.section { margin-left: 0px; padding-left: 0px; } dl.note { margin-left:-7px; padding-left: 3px; border-left:4px solid; border-color: #D0C000; } dl.warning, dl.attention { margin-left:-7px; padding-left: 3px; border-left:4px solid; border-color: #FF0000; } dl.pre, dl.post, dl.invariant { margin-left:-7px; padding-left: 3px; border-left:4px solid; border-color: #00D000; } dl.deprecated { margin-left:-7px; padding-left: 3px; border-left:4px solid; border-color: #505050; } dl.todo { margin-left:-7px; padding-left: 3px; border-left:4px solid; border-color: #00C0E0; } dl.test { margin-left:-7px; padding-left: 3px; border-left:4px solid; border-color: #3030E0; } dl.bug { margin-left:-7px; padding-left: 3px; border-left:4px solid; border-color: #C08050; } dl.section dd { margin-bottom: 6px; } #projectlogo { text-align: center; vertical-align: bottom; border-collapse: separate; } #projectlogo img { border: 0px none; } #projectname { font: 300% Tahoma, Arial,sans-serif; margin: 0px; padding: 2px 0px; } #projectbrief { font: 120% Tahoma, Arial,sans-serif; margin: 0px; padding: 0px; } #projectnumber { font: 50% Tahoma, Arial,sans-serif; margin: 0px; padding: 0px; } #titlearea { padding: 0px; margin: 0px; width: 100%; border-bottom: 1px solid #5373B4; } .image { text-align: center; } .dotgraph { text-align: center; } .mscgraph { text-align: center; } .diagraph { text-align: center; } .caption { font-weight: bold; } div.zoom { border: 1px solid #90A5CE; } dl.citelist { margin-bottom:50px; } dl.citelist dt { color:#334975; float:left; font-weight:bold; margin-right:10px; padding:5px; } dl.citelist dd { margin:2px 0; padding:5px 0; } div.toc { padding: 14px 25px; background-color: #F4F6FA; border: 1px solid #D8DFEE; border-radius: 7px 7px 7px 7px; float: right; height: auto; margin: 0 20px 10px 10px; width: 200px; } div.toc li { background: url("bdwn.png") no-repeat scroll 0 5px transparent; font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif; margin-top: 5px; padding-left: 10px; padding-top: 2px; } div.toc h3 { font: bold 12px/1.2 Arial,FreeSans,sans-serif; color: #4665A2; border-bottom: 0 none; margin: 0; } div.toc ul { list-style: none outside none; border: medium none; padding: 0px; } div.toc li.level1 { margin-left: 0px; } div.toc li.level2 { margin-left: 15px; } div.toc li.level3 { margin-left: 30px; } div.toc li.level4 { margin-left: 45px; } .inherit_header { font-weight: bold; color: gray; cursor: pointer; -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } .inherit_header td { padding: 6px 0px 2px 5px; } .inherit { display: none; } tr.heading h2 { margin-top: 12px; margin-bottom: 4px; } /* tooltip related style info */ .ttc { position: absolute; display: none; } #powerTip { cursor: default; white-space: nowrap; background-color: white; border: 1px solid gray; border-radius: 4px 4px 4px 4px; box-shadow: 1px 1px 7px gray; display: none; font-size: smaller; max-width: 80%; opacity: 0.9; padding: 1ex 1em 1em; position: absolute; z-index: 2147483647; } #powerTip div.ttdoc { color: grey; font-style: italic; } #powerTip div.ttname a { font-weight: bold; } #powerTip div.ttname { font-weight: bold; } #powerTip div.ttdeci { color: #006318; } #powerTip div { margin: 0px; padding: 0px; font: 12px/16px Roboto,sans-serif; } #powerTip:before, #powerTip:after { content: ""; position: absolute; margin: 0px; } #powerTip.n:after, #powerTip.n:before, #powerTip.s:after, #powerTip.s:before, #powerTip.w:after, #powerTip.w:before, #powerTip.e:after, #powerTip.e:before, #powerTip.ne:after, #powerTip.ne:before, #powerTip.se:after, #powerTip.se:before, #powerTip.nw:after, #powerTip.nw:before, #powerTip.sw:after, #powerTip.sw:before { border: solid transparent; content: " "; height: 0; width: 0; position: absolute; } #powerTip.n:after, #powerTip.s:after, #powerTip.w:after, #powerTip.e:after, #powerTip.nw:after, #powerTip.ne:after, #powerTip.sw:after, #powerTip.se:after { border-color: rgba(255, 255, 255, 0); } #powerTip.n:before, #powerTip.s:before, #powerTip.w:before, #powerTip.e:before, #powerTip.nw:before, #powerTip.ne:before, #powerTip.sw:before, #powerTip.se:before { border-color: rgba(128, 128, 128, 0); } #powerTip.n:after, #powerTip.n:before, #powerTip.ne:after, #powerTip.ne:before, #powerTip.nw:after, #powerTip.nw:before { top: 100%; } #powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after { border-top-color: #ffffff; border-width: 10px; margin: 0px -10px; } #powerTip.n:before { border-top-color: #808080; border-width: 11px; margin: 0px -11px; } #powerTip.n:after, #powerTip.n:before { left: 50%; } #powerTip.nw:after, #powerTip.nw:before { right: 14px; } #powerTip.ne:after, #powerTip.ne:before { left: 14px; } #powerTip.s:after, #powerTip.s:before, #powerTip.se:after, #powerTip.se:before, #powerTip.sw:after, #powerTip.sw:before { bottom: 100%; } #powerTip.s:after, #powerTip.se:after, #powerTip.sw:after { border-bottom-color: #ffffff; border-width: 10px; margin: 0px -10px; } #powerTip.s:before, #powerTip.se:before, #powerTip.sw:before { border-bottom-color: #808080; border-width: 11px; margin: 0px -11px; } #powerTip.s:after, #powerTip.s:before { left: 50%; } #powerTip.sw:after, #powerTip.sw:before { right: 14px; } #powerTip.se:after, #powerTip.se:before { left: 14px; } #powerTip.e:after, #powerTip.e:before { left: 100%; } #powerTip.e:after { border-left-color: #ffffff; border-width: 10px; top: 50%; margin-top: -10px; } #powerTip.e:before { border-left-color: #808080; border-width: 11px; top: 50%; margin-top: -11px; } #powerTip.w:after, #powerTip.w:before { right: 100%; } #powerTip.w:after { border-right-color: #ffffff; border-width: 10px; top: 50%; margin-top: -10px; } #powerTip.w:before { border-right-color: #808080; border-width: 11px; top: 50%; margin-top: -11px; } @media print { #top { display: none; } #side-nav { display: none; } #nav-path { display: none; } body { overflow:visible; } h1, h2, h3, h4, h5, h6 { page-break-after: avoid; } .summary { display: none; } .memitem { page-break-inside: avoid; } #doc-content { margin-left:0 !important; height:auto !important; width:auto !important; overflow:inherit; display:inline; } } ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/dynsections.js ================================================ function toggleVisibility(linkObj) { var base = $(linkObj).attr('id'); var summary = $('#'+base+'-summary'); var content = $('#'+base+'-content'); var trigger = $('#'+base+'-trigger'); var src=$(trigger).attr('src'); if (content.is(':visible')===true) { content.hide(); summary.show(); $(linkObj).addClass('closed').removeClass('opened'); $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png'); } else { content.show(); summary.hide(); $(linkObj).removeClass('closed').addClass('opened'); $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); } return false; } function updateStripes() { $('table.directory tr'). removeClass('even').filter(':visible:even').addClass('even'); } function toggleLevel(level) { $('table.directory tr').each(function() { var l = this.id.split('_').length-1; var i = $('#img'+this.id.substring(3)); var a = $('#arr'+this.id.substring(3)); if (l MSC for Windows&Linux API: iFlytek MSC Reference Manual/dynsections.js 文件参考
MSC for Windows&Linux API
dynsections.js 文件参考

函数

function toggleVisibility (linkObj)
 
function updateStripes ()
 
function toggleLevel (level)
 
function toggleFolder (id)
 
function toggleInherit (id)
 

函数说明

function toggleFolder (   id)
function toggleInherit (   id)
function toggleLevel (   level)
function toggleVisibility (   linkObj)
function updateStripes ( )
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/files.html ================================================ MSC for Windows&Linux API: 文件列表
MSC for Windows&Linux API
文件列表
这里列出了所有文件,并附带简要说明:
[详情级别 123]
  iFlytek MSC Reference Manual
  search
 all_0.js
 all_1.js
 files_0.js
 files_1.js
 functions_0.js
 functions_1.js
 search.js
 searchdata.js
 dynsections.js
 jquery.js
 msp_cmn.hMobile Speech Platform Common Interface Header File
 qisr.hIFLY Speech Recognizer Header File
 qmfv.hIFLY Speech Recognizer Header File
 qtts.hIFLY Speech Synthesizer Header File
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/files__0_8js.html ================================================ MSC for Windows&Linux API: iFlytek MSC Reference Manual/search/files_0.js 文件参考
MSC for Windows&Linux API
files_0.js 文件参考

变量

var searchData
 

变量说明

var searchData
初始值:
=
[
['msp_5fcmn_2eh',['msp_cmn.h',['../msp__cmn_8h.html',1,'']]]
]
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/files__1_8js.html ================================================ MSC for Windows&Linux API: iFlytek MSC Reference Manual/search/files_1.js 文件参考
MSC for Windows&Linux API
files_1.js 文件参考

变量

var searchData
 

变量说明

var searchData
初始值:
=
[
['qisr_2eh',['qisr.h',['../qisr_8h.html',1,'']]],
['qmfv_2eh',['qmfv.h',['../qmfv_8h.html',1,'']]],
['qtts_2eh',['qtts.h',['../qtts_8h.html',1,'']]]
]
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/functions__0_8js.html ================================================ MSC for Windows&Linux API: iFlytek MSC Reference Manual/search/functions_0.js 文件参考
MSC for Windows&Linux API
functions_0.js 文件参考

变量

var searchData
 

变量说明

var searchData
初始值:
=
[
['mspgetparam',['MSPGetParam',['../msp__cmn_8h.html#a4d3fa0aad5e761cb2a2afe30ae2a9714',1,'msp_cmn.h']]],
['mspgetversion',['MSPGetVersion',['../msp__cmn_8h.html#a632008aeddf5eba09555920ce38686a4',1,'msp_cmn.h']]],
['msplogin',['MSPLogin',['../msp__cmn_8h.html#a137acfe684fe46cbe5baf19f7d4a7fcc',1,'msp_cmn.h']]],
['msplogout',['MSPLogout',['../msp__cmn_8h.html#a1e0f72cd113b4578afdf3d16ab34463e',1,'msp_cmn.h']]],
['mspsearch',['MSPSearch',['../msp__cmn_8h.html#ae7be2dd2c6ee318524621b952998c14d',1,'msp_cmn.h']]],
['mspuploaddata',['MSPUploadData',['../msp__cmn_8h.html#ada276fa6db4a66342d951820020e4e8f',1,'msp_cmn.h']]]
]
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/functions__1_8js.html ================================================ MSC for Windows&Linux API: iFlytek MSC Reference Manual/search/functions_1.js 文件参考
MSC for Windows&Linux API
functions_1.js 文件参考

变量

var searchData
 

变量说明

var searchData
初始值:
=
[
['qisraudiowrite',['QISRAudioWrite',['../qisr_8h.html#a47fd2588fe834fa2d51fef1961d7aef4',1,'qisr.h']]],
['qisrgetparam',['QISRGetParam',['../qisr_8h.html#a2081e3cad9a8155c15790a2476be7044',1,'qisr.h']]],
['qisrgetresult',['QISRGetResult',['../qisr_8h.html#a2e7880db4792266a4d1439238c0b2c1b',1,'qisr.h']]],
['qisrsessionbegin',['QISRSessionBegin',['../qisr_8h.html#aaec4a5779275e07c4f7405ed8d739416',1,'qisr.h']]],
['qisrsessionend',['QISRSessionEnd',['../qisr_8h.html#ab50c4114e032100c4093ddd51329fecc',1,'qisr.h']]],
['qmfvdatawrite',['QMFVDataWrite',['../qmfv_8h.html#a081a01b2add2dfac3010ec7cd8ba5eac',1,'qmfv.h']]],
['qmfvgetparam',['QMFVGetParam',['../qmfv_8h.html#a7174d943c2f1691f6a8c717429d43f8d',1,'qmfv.h']]],
['qmfvgetresult',['QMFVGetResult',['../qmfv_8h.html#aa87716ad6b28326982626c0c6a6ffcbd',1,'qmfv.h']]],
['qmfvsessionbegin',['QMFVSessionBegin',['../qmfv_8h.html#adbe23b402d4c50b4c06f47ca26253be5',1,'qmfv.h']]],
['qmfvsessionend',['QMFVSessionEnd',['../qmfv_8h.html#ad4ea72dd39285348cf26c627d67c6b65',1,'qmfv.h']]],
['qttsaudioget',['QTTSAudioGet',['../qtts_8h.html#a4e4f6bed4b9e4ea553aa00ccf539c22a',1,'qtts.h']]],
['qttsgetparam',['QTTSGetParam',['../qtts_8h.html#a0812612ff738a828490e4e3db59767e8',1,'qtts.h']]],
['qttssessionbegin',['QTTSSessionBegin',['../qtts_8h.html#a3fba4ad9599445073335851cc9479542',1,'qtts.h']]],
['qttssessionend',['QTTSSessionEnd',['../qtts_8h.html#a75d5047a2a889dbd890d116a6d0b550a',1,'qtts.h']]],
['qttstextput',['QTTSTextPut',['../qtts_8h.html#a5b7d146d6a35341d4d73efd720ae987b',1,'qtts.h']]]
]
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/globals.html ================================================ MSC for Windows&Linux API: 文件成员
MSC for Windows&Linux API
这里列出了所有文件成员,并附带其所属的文件:

- a -

- b -

- c -

- e -

- g -

- i -

- k -

- l -

- m -

- p -

- q -

- s -

- t -

- u -

- z -

================================================ FILE: xf/doc/iFlytek MSC Reference Manual/globals_func.html ================================================ MSC for Windows&Linux API: 文件成员
MSC for Windows&Linux API
 

- b -

- c -

- e -

- g -

- i -

- m -

- p -

- q -

- s -

- t -

- u -

================================================ FILE: xf/doc/iFlytek MSC Reference Manual/globals_vars.html ================================================ MSC for Windows&Linux API: 文件成员
MSC for Windows&Linux API
 
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/index.html ================================================ MSC for Windows&Linux API: 首页
MSC for Windows&Linux API
MSC for Windows&Linux API 文档
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/jquery.js ================================================ /*! * jQuery JavaScript Library v1.7.1 * http://jquery.com/ * * Copyright 2011, John Resig * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * Includes Sizzle.js * http://sizzlejs.com/ * Copyright 2011, The Dojo Foundation * Released under the MIT, BSD, and GPL Licenses. * * Date: Mon Nov 21 21:11:03 2011 -0500 */ (function(bb,L){var av=bb.document,bu=bb.navigator,bl=bb.location;var b=(function(){var bF=function(b0,b1){return new bF.fn.init(b0,b1,bD)},bU=bb.jQuery,bH=bb.$,bD,bY=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,bM=/\S/,bI=/^\s+/,bE=/\s+$/,bA=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,bN=/^[\],:{}\s]*$/,bW=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,bP=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,bJ=/(?:^|:|,)(?:\s*\[)+/g,by=/(webkit)[ \/]([\w.]+)/,bR=/(opera)(?:.*version)?[ \/]([\w.]+)/,bQ=/(msie) ([\w.]+)/,bS=/(mozilla)(?:.*? rv:([\w.]+))?/,bB=/-([a-z]|[0-9])/ig,bZ=/^-ms-/,bT=function(b0,b1){return(b1+"").toUpperCase()},bX=bu.userAgent,bV,bC,e,bL=Object.prototype.toString,bG=Object.prototype.hasOwnProperty,bz=Array.prototype.push,bK=Array.prototype.slice,bO=String.prototype.trim,bv=Array.prototype.indexOf,bx={};bF.fn=bF.prototype={constructor:bF,init:function(b0,b4,b3){var b2,b5,b1,b6;if(!b0){return this}if(b0.nodeType){this.context=this[0]=b0;this.length=1;return this}if(b0==="body"&&!b4&&av.body){this.context=av;this[0]=av.body;this.selector=b0;this.length=1;return this}if(typeof b0==="string"){if(b0.charAt(0)==="<"&&b0.charAt(b0.length-1)===">"&&b0.length>=3){b2=[null,b0,null]}else{b2=bY.exec(b0)}if(b2&&(b2[1]||!b4)){if(b2[1]){b4=b4 instanceof bF?b4[0]:b4;b6=(b4?b4.ownerDocument||b4:av);b1=bA.exec(b0);if(b1){if(bF.isPlainObject(b4)){b0=[av.createElement(b1[1])];bF.fn.attr.call(b0,b4,true)}else{b0=[b6.createElement(b1[1])]}}else{b1=bF.buildFragment([b2[1]],[b6]);b0=(b1.cacheable?bF.clone(b1.fragment):b1.fragment).childNodes}return bF.merge(this,b0)}else{b5=av.getElementById(b2[2]);if(b5&&b5.parentNode){if(b5.id!==b2[2]){return b3.find(b0)}this.length=1;this[0]=b5}this.context=av;this.selector=b0;return this}}else{if(!b4||b4.jquery){return(b4||b3).find(b0)}else{return this.constructor(b4).find(b0)}}}else{if(bF.isFunction(b0)){return b3.ready(b0)}}if(b0.selector!==L){this.selector=b0.selector;this.context=b0.context}return bF.makeArray(b0,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return bK.call(this,0)},get:function(b0){return b0==null?this.toArray():(b0<0?this[this.length+b0]:this[b0])},pushStack:function(b1,b3,b0){var b2=this.constructor();if(bF.isArray(b1)){bz.apply(b2,b1)}else{bF.merge(b2,b1)}b2.prevObject=this;b2.context=this.context;if(b3==="find"){b2.selector=this.selector+(this.selector?" ":"")+b0}else{if(b3){b2.selector=this.selector+"."+b3+"("+b0+")"}}return b2},each:function(b1,b0){return bF.each(this,b1,b0)},ready:function(b0){bF.bindReady();bC.add(b0);return this},eq:function(b0){b0=+b0;return b0===-1?this.slice(b0):this.slice(b0,b0+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(bK.apply(this,arguments),"slice",bK.call(arguments).join(","))},map:function(b0){return this.pushStack(bF.map(this,function(b2,b1){return b0.call(b2,b1,b2)}))},end:function(){return this.prevObject||this.constructor(null)},push:bz,sort:[].sort,splice:[].splice};bF.fn.init.prototype=bF.fn;bF.extend=bF.fn.extend=function(){var b9,b2,b0,b1,b6,b7,b5=arguments[0]||{},b4=1,b3=arguments.length,b8=false;if(typeof b5==="boolean"){b8=b5;b5=arguments[1]||{};b4=2}if(typeof b5!=="object"&&!bF.isFunction(b5)){b5={}}if(b3===b4){b5=this;--b4}for(;b40){return}bC.fireWith(av,[bF]);if(bF.fn.trigger){bF(av).trigger("ready").off("ready")}}},bindReady:function(){if(bC){return}bC=bF.Callbacks("once memory");if(av.readyState==="complete"){return setTimeout(bF.ready,1)}if(av.addEventListener){av.addEventListener("DOMContentLoaded",e,false);bb.addEventListener("load",bF.ready,false)}else{if(av.attachEvent){av.attachEvent("onreadystatechange",e);bb.attachEvent("onload",bF.ready);var b0=false;try{b0=bb.frameElement==null}catch(b1){}if(av.documentElement.doScroll&&b0){bw()}}}},isFunction:function(b0){return bF.type(b0)==="function"},isArray:Array.isArray||function(b0){return bF.type(b0)==="array"},isWindow:function(b0){return b0&&typeof b0==="object"&&"setInterval" in b0},isNumeric:function(b0){return !isNaN(parseFloat(b0))&&isFinite(b0)},type:function(b0){return b0==null?String(b0):bx[bL.call(b0)]||"object"},isPlainObject:function(b2){if(!b2||bF.type(b2)!=="object"||b2.nodeType||bF.isWindow(b2)){return false}try{if(b2.constructor&&!bG.call(b2,"constructor")&&!bG.call(b2.constructor.prototype,"isPrototypeOf")){return false}}catch(b1){return false}var b0;for(b0 in b2){}return b0===L||bG.call(b2,b0)},isEmptyObject:function(b1){for(var b0 in b1){return false}return true},error:function(b0){throw new Error(b0)},parseJSON:function(b0){if(typeof b0!=="string"||!b0){return null}b0=bF.trim(b0);if(bb.JSON&&bb.JSON.parse){return bb.JSON.parse(b0)}if(bN.test(b0.replace(bW,"@").replace(bP,"]").replace(bJ,""))){return(new Function("return "+b0))()}bF.error("Invalid JSON: "+b0)},parseXML:function(b2){var b0,b1;try{if(bb.DOMParser){b1=new DOMParser();b0=b1.parseFromString(b2,"text/xml")}else{b0=new ActiveXObject("Microsoft.XMLDOM");b0.async="false";b0.loadXML(b2)}}catch(b3){b0=L}if(!b0||!b0.documentElement||b0.getElementsByTagName("parsererror").length){bF.error("Invalid XML: "+b2)}return b0},noop:function(){},globalEval:function(b0){if(b0&&bM.test(b0)){(bb.execScript||function(b1){bb["eval"].call(bb,b1)})(b0)}},camelCase:function(b0){return b0.replace(bZ,"ms-").replace(bB,bT)},nodeName:function(b1,b0){return b1.nodeName&&b1.nodeName.toUpperCase()===b0.toUpperCase()},each:function(b3,b6,b2){var b1,b4=0,b5=b3.length,b0=b5===L||bF.isFunction(b3);if(b2){if(b0){for(b1 in b3){if(b6.apply(b3[b1],b2)===false){break}}}else{for(;b40&&b0[0]&&b0[b1-1])||b1===0||bF.isArray(b0));if(b3){for(;b21?aJ.call(arguments,0):bG;if(!(--bw)){bC.resolveWith(bC,bx)}}}function bz(bF){return function(bG){bB[bF]=arguments.length>1?aJ.call(arguments,0):bG;bC.notifyWith(bE,bB)}}if(e>1){for(;bv
a";bI=bv.getElementsByTagName("*");bF=bv.getElementsByTagName("a")[0];if(!bI||!bI.length||!bF){return{}}bG=av.createElement("select");bx=bG.appendChild(av.createElement("option"));bE=bv.getElementsByTagName("input")[0];bJ={leadingWhitespace:(bv.firstChild.nodeType===3),tbody:!bv.getElementsByTagName("tbody").length,htmlSerialize:!!bv.getElementsByTagName("link").length,style:/top/.test(bF.getAttribute("style")),hrefNormalized:(bF.getAttribute("href")==="/a"),opacity:/^0.55/.test(bF.style.opacity),cssFloat:!!bF.style.cssFloat,checkOn:(bE.value==="on"),optSelected:bx.selected,getSetAttribute:bv.className!=="t",enctype:!!av.createElement("form").enctype,html5Clone:av.createElement("nav").cloneNode(true).outerHTML!=="<:nav>",submitBubbles:true,changeBubbles:true,focusinBubbles:false,deleteExpando:true,noCloneEvent:true,inlineBlockNeedsLayout:false,shrinkWrapBlocks:false,reliableMarginRight:true};bE.checked=true;bJ.noCloneChecked=bE.cloneNode(true).checked;bG.disabled=true;bJ.optDisabled=!bx.disabled;try{delete bv.test}catch(bC){bJ.deleteExpando=false}if(!bv.addEventListener&&bv.attachEvent&&bv.fireEvent){bv.attachEvent("onclick",function(){bJ.noCloneEvent=false});bv.cloneNode(true).fireEvent("onclick")}bE=av.createElement("input");bE.value="t";bE.setAttribute("type","radio");bJ.radioValue=bE.value==="t";bE.setAttribute("checked","checked");bv.appendChild(bE);bD=av.createDocumentFragment();bD.appendChild(bv.lastChild);bJ.checkClone=bD.cloneNode(true).cloneNode(true).lastChild.checked;bJ.appendChecked=bE.checked;bD.removeChild(bE);bD.appendChild(bv);bv.innerHTML="";if(bb.getComputedStyle){bA=av.createElement("div");bA.style.width="0";bA.style.marginRight="0";bv.style.width="2px";bv.appendChild(bA);bJ.reliableMarginRight=(parseInt((bb.getComputedStyle(bA,null)||{marginRight:0}).marginRight,10)||0)===0}if(bv.attachEvent){for(by in {submit:1,change:1,focusin:1}){bB="on"+by;bw=(bB in bv);if(!bw){bv.setAttribute(bB,"return;");bw=(typeof bv[bB]==="function")}bJ[by+"Bubbles"]=bw}}bD.removeChild(bv);bD=bG=bx=bA=bv=bE=null;b(function(){var bM,bU,bV,bT,bN,bO,bL,bS,bR,e,bP,bQ=av.getElementsByTagName("body")[0];if(!bQ){return}bL=1;bS="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;";bR="visibility:hidden;border:0;";e="style='"+bS+"border:5px solid #000;padding:0;'";bP="
";bM=av.createElement("div");bM.style.cssText=bR+"width:0;height:0;position:static;top:0;margin-top:"+bL+"px";bQ.insertBefore(bM,bQ.firstChild);bv=av.createElement("div");bM.appendChild(bv);bv.innerHTML="
t
";bz=bv.getElementsByTagName("td");bw=(bz[0].offsetHeight===0);bz[0].style.display="";bz[1].style.display="none";bJ.reliableHiddenOffsets=bw&&(bz[0].offsetHeight===0);bv.innerHTML="";bv.style.width=bv.style.paddingLeft="1px";b.boxModel=bJ.boxModel=bv.offsetWidth===2;if(typeof bv.style.zoom!=="undefined"){bv.style.display="inline";bv.style.zoom=1;bJ.inlineBlockNeedsLayout=(bv.offsetWidth===2);bv.style.display="";bv.innerHTML="
";bJ.shrinkWrapBlocks=(bv.offsetWidth!==2)}bv.style.cssText=bS+bR;bv.innerHTML=bP;bU=bv.firstChild;bV=bU.firstChild;bN=bU.nextSibling.firstChild.firstChild;bO={doesNotAddBorder:(bV.offsetTop!==5),doesAddBorderForTableAndCells:(bN.offsetTop===5)};bV.style.position="fixed";bV.style.top="20px";bO.fixedPosition=(bV.offsetTop===20||bV.offsetTop===15);bV.style.position=bV.style.top="";bU.style.overflow="hidden";bU.style.position="relative";bO.subtractsBorderForOverflowNotVisible=(bV.offsetTop===-5);bO.doesNotIncludeMarginInBodyOffset=(bQ.offsetTop!==bL);bQ.removeChild(bM);bv=bM=null;b.extend(bJ,bO)});return bJ})();var aS=/^(?:\{.*\}|\[.*\])$/,aA=/([A-Z])/g;b.extend({cache:{},uuid:0,expando:"jQuery"+(b.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:true,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:true},hasData:function(e){e=e.nodeType?b.cache[e[b.expando]]:e[b.expando];return !!e&&!S(e)},data:function(bx,bv,bz,by){if(!b.acceptData(bx)){return}var bG,bA,bD,bE=b.expando,bC=typeof bv==="string",bF=bx.nodeType,e=bF?b.cache:bx,bw=bF?bx[bE]:bx[bE]&&bE,bB=bv==="events";if((!bw||!e[bw]||(!bB&&!by&&!e[bw].data))&&bC&&bz===L){return}if(!bw){if(bF){bx[bE]=bw=++b.uuid}else{bw=bE}}if(!e[bw]){e[bw]={};if(!bF){e[bw].toJSON=b.noop}}if(typeof bv==="object"||typeof bv==="function"){if(by){e[bw]=b.extend(e[bw],bv)}else{e[bw].data=b.extend(e[bw].data,bv)}}bG=bA=e[bw];if(!by){if(!bA.data){bA.data={}}bA=bA.data}if(bz!==L){bA[b.camelCase(bv)]=bz}if(bB&&!bA[bv]){return bG.events}if(bC){bD=bA[bv];if(bD==null){bD=bA[b.camelCase(bv)]}}else{bD=bA}return bD},removeData:function(bx,bv,by){if(!b.acceptData(bx)){return}var bB,bA,bz,bC=b.expando,bD=bx.nodeType,e=bD?b.cache:bx,bw=bD?bx[bC]:bC;if(!e[bw]){return}if(bv){bB=by?e[bw]:e[bw].data;if(bB){if(!b.isArray(bv)){if(bv in bB){bv=[bv]}else{bv=b.camelCase(bv);if(bv in bB){bv=[bv]}else{bv=bv.split(" ")}}}for(bA=0,bz=bv.length;bA-1){return true}}return false},val:function(bx){var e,bv,by,bw=this[0];if(!arguments.length){if(bw){e=b.valHooks[bw.nodeName.toLowerCase()]||b.valHooks[bw.type];if(e&&"get" in e&&(bv=e.get(bw,"value"))!==L){return bv}bv=bw.value;return typeof bv==="string"?bv.replace(aU,""):bv==null?"":bv}return}by=b.isFunction(bx);return this.each(function(bA){var bz=b(this),bB;if(this.nodeType!==1){return}if(by){bB=bx.call(this,bA,bz.val())}else{bB=bx}if(bB==null){bB=""}else{if(typeof bB==="number"){bB+=""}else{if(b.isArray(bB)){bB=b.map(bB,function(bC){return bC==null?"":bC+""})}}}e=b.valHooks[this.nodeName.toLowerCase()]||b.valHooks[this.type];if(!e||!("set" in e)||e.set(this,bB,"value")===L){this.value=bB}})}});b.extend({valHooks:{option:{get:function(e){var bv=e.attributes.value;return !bv||bv.specified?e.value:e.text}},select:{get:function(e){var bA,bv,bz,bx,by=e.selectedIndex,bB=[],bC=e.options,bw=e.type==="select-one";if(by<0){return null}bv=bw?by:0;bz=bw?by+1:bC.length;for(;bv=0});if(!e.length){bv.selectedIndex=-1}return e}}},attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(bA,bx,bB,bz){var bw,e,by,bv=bA.nodeType;if(!bA||bv===3||bv===8||bv===2){return}if(bz&&bx in b.attrFn){return b(bA)[bx](bB)}if(typeof bA.getAttribute==="undefined"){return b.prop(bA,bx,bB)}by=bv!==1||!b.isXMLDoc(bA);if(by){bx=bx.toLowerCase();e=b.attrHooks[bx]||(ao.test(bx)?aY:be)}if(bB!==L){if(bB===null){b.removeAttr(bA,bx);return}else{if(e&&"set" in e&&by&&(bw=e.set(bA,bB,bx))!==L){return bw}else{bA.setAttribute(bx,""+bB);return bB}}}else{if(e&&"get" in e&&by&&(bw=e.get(bA,bx))!==null){return bw}else{bw=bA.getAttribute(bx);return bw===null?L:bw}}},removeAttr:function(bx,bz){var by,bA,bv,e,bw=0;if(bz&&bx.nodeType===1){bA=bz.toLowerCase().split(af);e=bA.length;for(;bw=0)}}})});var bd=/^(?:textarea|input|select)$/i,n=/^([^\.]*)?(?:\.(.+))?$/,J=/\bhover(\.\S+)?\b/,aO=/^key/,bf=/^(?:mouse|contextmenu)|click/,T=/^(?:focusinfocus|focusoutblur)$/,U=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,Y=function(e){var bv=U.exec(e);if(bv){bv[1]=(bv[1]||"").toLowerCase();bv[3]=bv[3]&&new RegExp("(?:^|\\s)"+bv[3]+"(?:\\s|$)")}return bv},j=function(bw,e){var bv=bw.attributes||{};return((!e[1]||bw.nodeName.toLowerCase()===e[1])&&(!e[2]||(bv.id||{}).value===e[2])&&(!e[3]||e[3].test((bv["class"]||{}).value)))},bt=function(e){return b.event.special.hover?e:e.replace(J,"mouseenter$1 mouseleave$1")};b.event={add:function(bx,bC,bJ,bA,by){var bD,bB,bK,bI,bH,bF,e,bG,bv,bz,bw,bE;if(bx.nodeType===3||bx.nodeType===8||!bC||!bJ||!(bD=b._data(bx))){return}if(bJ.handler){bv=bJ;bJ=bv.handler}if(!bJ.guid){bJ.guid=b.guid++}bK=bD.events;if(!bK){bD.events=bK={}}bB=bD.handle;if(!bB){bD.handle=bB=function(bL){return typeof b!=="undefined"&&(!bL||b.event.triggered!==bL.type)?b.event.dispatch.apply(bB.elem,arguments):L};bB.elem=bx}bC=b.trim(bt(bC)).split(" ");for(bI=0;bI=0){bG=bG.slice(0,-1);bw=true}if(bG.indexOf(".")>=0){bx=bG.split(".");bG=bx.shift();bx.sort()}if((!bA||b.event.customEvent[bG])&&!b.event.global[bG]){return}bv=typeof bv==="object"?bv[b.expando]?bv:new b.Event(bG,bv):new b.Event(bG);bv.type=bG;bv.isTrigger=true;bv.exclusive=bw;bv.namespace=bx.join(".");bv.namespace_re=bv.namespace?new RegExp("(^|\\.)"+bx.join("\\.(?:.*\\.)?")+"(\\.|$)"):null;by=bG.indexOf(":")<0?"on"+bG:"";if(!bA){e=b.cache;for(bC in e){if(e[bC].events&&e[bC].events[bG]){b.event.trigger(bv,bD,e[bC].handle.elem,true)}}return}bv.result=L;if(!bv.target){bv.target=bA}bD=bD!=null?b.makeArray(bD):[];bD.unshift(bv);bF=b.event.special[bG]||{};if(bF.trigger&&bF.trigger.apply(bA,bD)===false){return}bB=[[bA,bF.bindType||bG]];if(!bJ&&!bF.noBubble&&!b.isWindow(bA)){bI=bF.delegateType||bG;bH=T.test(bI+bG)?bA:bA.parentNode;bz=null;for(;bH;bH=bH.parentNode){bB.push([bH,bI]);bz=bH}if(bz&&bz===bA.ownerDocument){bB.push([bz.defaultView||bz.parentWindow||bb,bI])}}for(bC=0;bCbA){bH.push({elem:this,matches:bz.slice(bA)})}for(bC=0;bC0?this.on(e,null,bx,bw):this.trigger(e)};if(b.attrFn){b.attrFn[e]=true}if(aO.test(e)){b.event.fixHooks[e]=b.event.keyHooks}if(bf.test(e)){b.event.fixHooks[e]=b.event.mouseHooks}}); /*! * Sizzle CSS Selector Engine * Copyright 2011, The Dojo Foundation * Released under the MIT, BSD, and GPL Licenses. * More information: http://sizzlejs.com/ */ (function(){var bH=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,bC="sizcache"+(Math.random()+"").replace(".",""),bI=0,bL=Object.prototype.toString,bB=false,bA=true,bK=/\\/g,bO=/\r\n/g,bQ=/\W/;[0,0].sort(function(){bA=false;return 0});var by=function(bV,e,bY,bZ){bY=bY||[];e=e||av;var b1=e;if(e.nodeType!==1&&e.nodeType!==9){return[]}if(!bV||typeof bV!=="string"){return bY}var bS,b3,b6,bR,b2,b5,b4,bX,bU=true,bT=by.isXML(e),bW=[],b0=bV;do{bH.exec("");bS=bH.exec(b0);if(bS){b0=bS[3];bW.push(bS[1]);if(bS[2]){bR=bS[3];break}}}while(bS);if(bW.length>1&&bD.exec(bV)){if(bW.length===2&&bE.relative[bW[0]]){b3=bM(bW[0]+bW[1],e,bZ)}else{b3=bE.relative[bW[0]]?[e]:by(bW.shift(),e);while(bW.length){bV=bW.shift();if(bE.relative[bV]){bV+=bW.shift()}b3=bM(bV,b3,bZ)}}}else{if(!bZ&&bW.length>1&&e.nodeType===9&&!bT&&bE.match.ID.test(bW[0])&&!bE.match.ID.test(bW[bW.length-1])){b2=by.find(bW.shift(),e,bT);e=b2.expr?by.filter(b2.expr,b2.set)[0]:b2.set[0]}if(e){b2=bZ?{expr:bW.pop(),set:bF(bZ)}:by.find(bW.pop(),bW.length===1&&(bW[0]==="~"||bW[0]==="+")&&e.parentNode?e.parentNode:e,bT);b3=b2.expr?by.filter(b2.expr,b2.set):b2.set;if(bW.length>0){b6=bF(b3)}else{bU=false}while(bW.length){b5=bW.pop();b4=b5;if(!bE.relative[b5]){b5=""}else{b4=bW.pop()}if(b4==null){b4=e}bE.relative[b5](b6,b4,bT)}}else{b6=bW=[]}}if(!b6){b6=b3}if(!b6){by.error(b5||bV)}if(bL.call(b6)==="[object Array]"){if(!bU){bY.push.apply(bY,b6)}else{if(e&&e.nodeType===1){for(bX=0;b6[bX]!=null;bX++){if(b6[bX]&&(b6[bX]===true||b6[bX].nodeType===1&&by.contains(e,b6[bX]))){bY.push(b3[bX])}}}else{for(bX=0;b6[bX]!=null;bX++){if(b6[bX]&&b6[bX].nodeType===1){bY.push(b3[bX])}}}}}else{bF(b6,bY)}if(bR){by(bR,b1,bY,bZ);by.uniqueSort(bY)}return bY};by.uniqueSort=function(bR){if(bJ){bB=bA;bR.sort(bJ);if(bB){for(var e=1;e0};by.find=function(bX,e,bY){var bW,bS,bU,bT,bV,bR;if(!bX){return[]}for(bS=0,bU=bE.order.length;bS":function(bW,bR){var bV,bU=typeof bR==="string",bS=0,e=bW.length;if(bU&&!bQ.test(bR)){bR=bR.toLowerCase();for(;bS=0)){if(!bS){e.push(bV)}}else{if(bS){bR[bU]=false}}}}return false},ID:function(e){return e[1].replace(bK,"")},TAG:function(bR,e){return bR[1].replace(bK,"").toLowerCase()},CHILD:function(e){if(e[1]==="nth"){if(!e[2]){by.error(e[0])}e[2]=e[2].replace(/^\+|\s*/g,"");var bR=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(e[2]==="even"&&"2n"||e[2]==="odd"&&"2n+1"||!/\D/.test(e[2])&&"0n+"+e[2]||e[2]);e[2]=(bR[1]+(bR[2]||1))-0;e[3]=bR[3]-0}else{if(e[2]){by.error(e[0])}}e[0]=bI++;return e},ATTR:function(bU,bR,bS,e,bV,bW){var bT=bU[1]=bU[1].replace(bK,"");if(!bW&&bE.attrMap[bT]){bU[1]=bE.attrMap[bT]}bU[4]=(bU[4]||bU[5]||"").replace(bK,"");if(bU[2]==="~="){bU[4]=" "+bU[4]+" "}return bU},PSEUDO:function(bU,bR,bS,e,bV){if(bU[1]==="not"){if((bH.exec(bU[3])||"").length>1||/^\w/.test(bU[3])){bU[3]=by(bU[3],null,null,bR)}else{var bT=by.filter(bU[3],bR,bS,true^bV);if(!bS){e.push.apply(e,bT)}return false}}else{if(bE.match.POS.test(bU[0])||bE.match.CHILD.test(bU[0])){return true}}return bU},POS:function(e){e.unshift(true);return e}},filters:{enabled:function(e){return e.disabled===false&&e.type!=="hidden"},disabled:function(e){return e.disabled===true},checked:function(e){return e.checked===true},selected:function(e){if(e.parentNode){e.parentNode.selectedIndex}return e.selected===true},parent:function(e){return !!e.firstChild},empty:function(e){return !e.firstChild},has:function(bS,bR,e){return !!by(e[3],bS).length},header:function(e){return(/h\d/i).test(e.nodeName)},text:function(bS){var e=bS.getAttribute("type"),bR=bS.type;return bS.nodeName.toLowerCase()==="input"&&"text"===bR&&(e===bR||e===null)},radio:function(e){return e.nodeName.toLowerCase()==="input"&&"radio"===e.type},checkbox:function(e){return e.nodeName.toLowerCase()==="input"&&"checkbox"===e.type},file:function(e){return e.nodeName.toLowerCase()==="input"&&"file"===e.type},password:function(e){return e.nodeName.toLowerCase()==="input"&&"password"===e.type},submit:function(bR){var e=bR.nodeName.toLowerCase();return(e==="input"||e==="button")&&"submit"===bR.type},image:function(e){return e.nodeName.toLowerCase()==="input"&&"image"===e.type},reset:function(bR){var e=bR.nodeName.toLowerCase();return(e==="input"||e==="button")&&"reset"===bR.type},button:function(bR){var e=bR.nodeName.toLowerCase();return e==="input"&&"button"===bR.type||e==="button"},input:function(e){return(/input|select|textarea|button/i).test(e.nodeName)},focus:function(e){return e===e.ownerDocument.activeElement}},setFilters:{first:function(bR,e){return e===0},last:function(bS,bR,e,bT){return bR===bT.length-1},even:function(bR,e){return e%2===0},odd:function(bR,e){return e%2===1},lt:function(bS,bR,e){return bRe[3]-0},nth:function(bS,bR,e){return e[3]-0===bR},eq:function(bS,bR,e){return e[3]-0===bR}},filter:{PSEUDO:function(bS,bX,bW,bY){var e=bX[1],bR=bE.filters[e];if(bR){return bR(bS,bW,bX,bY)}else{if(e==="contains"){return(bS.textContent||bS.innerText||bw([bS])||"").indexOf(bX[3])>=0}else{if(e==="not"){var bT=bX[3];for(var bV=0,bU=bT.length;bV=0)}}},ID:function(bR,e){return bR.nodeType===1&&bR.getAttribute("id")===e},TAG:function(bR,e){return(e==="*"&&bR.nodeType===1)||!!bR.nodeName&&bR.nodeName.toLowerCase()===e},CLASS:function(bR,e){return(" "+(bR.className||bR.getAttribute("class"))+" ").indexOf(e)>-1},ATTR:function(bV,bT){var bS=bT[1],e=by.attr?by.attr(bV,bS):bE.attrHandle[bS]?bE.attrHandle[bS](bV):bV[bS]!=null?bV[bS]:bV.getAttribute(bS),bW=e+"",bU=bT[2],bR=bT[4];return e==null?bU==="!=":!bU&&by.attr?e!=null:bU==="="?bW===bR:bU==="*="?bW.indexOf(bR)>=0:bU==="~="?(" "+bW+" ").indexOf(bR)>=0:!bR?bW&&e!==false:bU==="!="?bW!==bR:bU==="^="?bW.indexOf(bR)===0:bU==="$="?bW.substr(bW.length-bR.length)===bR:bU==="|="?bW===bR||bW.substr(0,bR.length+1)===bR+"-":false},POS:function(bU,bR,bS,bV){var e=bR[2],bT=bE.setFilters[e];if(bT){return bT(bU,bS,bR,bV)}}}};var bD=bE.match.POS,bx=function(bR,e){return"\\"+(e-0+1)};for(var bz in bE.match){bE.match[bz]=new RegExp(bE.match[bz].source+(/(?![^\[]*\])(?![^\(]*\))/.source));bE.leftMatch[bz]=new RegExp(/(^(?:.|\r|\n)*?)/.source+bE.match[bz].source.replace(/\\(\d+)/g,bx))}var bF=function(bR,e){bR=Array.prototype.slice.call(bR,0);if(e){e.push.apply(e,bR);return e}return bR};try{Array.prototype.slice.call(av.documentElement.childNodes,0)[0].nodeType}catch(bP){bF=function(bU,bT){var bS=0,bR=bT||[];if(bL.call(bU)==="[object Array]"){Array.prototype.push.apply(bR,bU)}else{if(typeof bU.length==="number"){for(var e=bU.length;bS";e.insertBefore(bR,e.firstChild);if(av.getElementById(bS)){bE.find.ID=function(bU,bV,bW){if(typeof bV.getElementById!=="undefined"&&!bW){var bT=bV.getElementById(bU[1]);return bT?bT.id===bU[1]||typeof bT.getAttributeNode!=="undefined"&&bT.getAttributeNode("id").nodeValue===bU[1]?[bT]:L:[]}};bE.filter.ID=function(bV,bT){var bU=typeof bV.getAttributeNode!=="undefined"&&bV.getAttributeNode("id");return bV.nodeType===1&&bU&&bU.nodeValue===bT}}e.removeChild(bR);e=bR=null})();(function(){var e=av.createElement("div");e.appendChild(av.createComment(""));if(e.getElementsByTagName("*").length>0){bE.find.TAG=function(bR,bV){var bU=bV.getElementsByTagName(bR[1]);if(bR[1]==="*"){var bT=[];for(var bS=0;bU[bS];bS++){if(bU[bS].nodeType===1){bT.push(bU[bS])}}bU=bT}return bU}}e.innerHTML="";if(e.firstChild&&typeof e.firstChild.getAttribute!=="undefined"&&e.firstChild.getAttribute("href")!=="#"){bE.attrHandle.href=function(bR){return bR.getAttribute("href",2)}}e=null})();if(av.querySelectorAll){(function(){var e=by,bT=av.createElement("div"),bS="__sizzle__";bT.innerHTML="

";if(bT.querySelectorAll&&bT.querySelectorAll(".TEST").length===0){return}by=function(b4,bV,bZ,b3){bV=bV||av;if(!b3&&!by.isXML(bV)){var b2=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b4);if(b2&&(bV.nodeType===1||bV.nodeType===9)){if(b2[1]){return bF(bV.getElementsByTagName(b4),bZ)}else{if(b2[2]&&bE.find.CLASS&&bV.getElementsByClassName){return bF(bV.getElementsByClassName(b2[2]),bZ)}}}if(bV.nodeType===9){if(b4==="body"&&bV.body){return bF([bV.body],bZ)}else{if(b2&&b2[3]){var bY=bV.getElementById(b2[3]);if(bY&&bY.parentNode){if(bY.id===b2[3]){return bF([bY],bZ)}}else{return bF([],bZ)}}}try{return bF(bV.querySelectorAll(b4),bZ)}catch(b0){}}else{if(bV.nodeType===1&&bV.nodeName.toLowerCase()!=="object"){var bW=bV,bX=bV.getAttribute("id"),bU=bX||bS,b6=bV.parentNode,b5=/^\s*[+~]/.test(b4);if(!bX){bV.setAttribute("id",bU)}else{bU=bU.replace(/'/g,"\\$&")}if(b5&&b6){bV=bV.parentNode}try{if(!b5||b6){return bF(bV.querySelectorAll("[id='"+bU+"'] "+b4),bZ)}}catch(b1){}finally{if(!bX){bW.removeAttribute("id")}}}}}return e(b4,bV,bZ,b3)};for(var bR in e){by[bR]=e[bR]}bT=null})()}(function(){var e=av.documentElement,bS=e.matchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.msMatchesSelector;if(bS){var bU=!bS.call(av.createElement("div"),"div"),bR=false;try{bS.call(av.documentElement,"[test!='']:sizzle")}catch(bT){bR=true}by.matchesSelector=function(bW,bY){bY=bY.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!by.isXML(bW)){try{if(bR||!bE.match.PSEUDO.test(bY)&&!/!=/.test(bY)){var bV=bS.call(bW,bY);if(bV||!bU||bW.document&&bW.document.nodeType!==11){return bV}}}catch(bX){}}return by(bY,null,null,[bW]).length>0}}})();(function(){var e=av.createElement("div");e.innerHTML="
";if(!e.getElementsByClassName||e.getElementsByClassName("e").length===0){return}e.lastChild.className="e";if(e.getElementsByClassName("e").length===1){return}bE.order.splice(1,0,"CLASS");bE.find.CLASS=function(bR,bS,bT){if(typeof bS.getElementsByClassName!=="undefined"&&!bT){return bS.getElementsByClassName(bR[1])}};e=null})();function bv(bR,bW,bV,bZ,bX,bY){for(var bT=0,bS=bZ.length;bT0){bU=e;break}}}e=e[bR]}bZ[bT]=bU}}}if(av.documentElement.contains){by.contains=function(bR,e){return bR!==e&&(bR.contains?bR.contains(e):true)}}else{if(av.documentElement.compareDocumentPosition){by.contains=function(bR,e){return !!(bR.compareDocumentPosition(e)&16)}}else{by.contains=function(){return false}}}by.isXML=function(e){var bR=(e?e.ownerDocument||e:0).documentElement;return bR?bR.nodeName!=="HTML":false};var bM=function(bS,e,bW){var bV,bX=[],bU="",bY=e.nodeType?[e]:e;while((bV=bE.match.PSEUDO.exec(bS))){bU+=bV[0];bS=bS.replace(bE.match.PSEUDO,"")}bS=bE.relative[bS]?bS+"*":bS;for(var bT=0,bR=bY.length;bT0){for(bB=bA;bB=0:b.filter(e,this).length>0:this.filter(e).length>0)},closest:function(by,bx){var bv=[],bw,e,bz=this[0];if(b.isArray(by)){var bB=1;while(bz&&bz.ownerDocument&&bz!==bx){for(bw=0;bw-1:b.find.matchesSelector(bz,by)){bv.push(bz);break}else{bz=bz.parentNode;if(!bz||!bz.ownerDocument||bz===bx||bz.nodeType===11){break}}}}bv=bv.length>1?b.unique(bv):bv;return this.pushStack(bv,"closest",by)},index:function(e){if(!e){return(this[0]&&this[0].parentNode)?this.prevAll().length:-1}if(typeof e==="string"){return b.inArray(this[0],b(e))}return b.inArray(e.jquery?e[0]:e,this)},add:function(e,bv){var bx=typeof e==="string"?b(e,bv):b.makeArray(e&&e.nodeType?[e]:e),bw=b.merge(this.get(),bx);return this.pushStack(C(bx[0])||C(bw[0])?bw:b.unique(bw))},andSelf:function(){return this.add(this.prevObject)}});function C(e){return !e||!e.parentNode||e.parentNode.nodeType===11}b.each({parent:function(bv){var e=bv.parentNode;return e&&e.nodeType!==11?e:null},parents:function(e){return b.dir(e,"parentNode")},parentsUntil:function(bv,e,bw){return b.dir(bv,"parentNode",bw)},next:function(e){return b.nth(e,2,"nextSibling")},prev:function(e){return b.nth(e,2,"previousSibling")},nextAll:function(e){return b.dir(e,"nextSibling")},prevAll:function(e){return b.dir(e,"previousSibling")},nextUntil:function(bv,e,bw){return b.dir(bv,"nextSibling",bw)},prevUntil:function(bv,e,bw){return b.dir(bv,"previousSibling",bw)},siblings:function(e){return b.sibling(e.parentNode.firstChild,e)},children:function(e){return b.sibling(e.firstChild)},contents:function(e){return b.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:b.makeArray(e.childNodes)}},function(e,bv){b.fn[e]=function(by,bw){var bx=b.map(this,bv,by);if(!ab.test(e)){bw=by}if(bw&&typeof bw==="string"){bx=b.filter(bw,bx)}bx=this.length>1&&!ay[e]?b.unique(bx):bx;if((this.length>1||a9.test(bw))&&aq.test(e)){bx=bx.reverse()}return this.pushStack(bx,e,P.call(arguments).join(","))}});b.extend({filter:function(bw,e,bv){if(bv){bw=":not("+bw+")"}return e.length===1?b.find.matchesSelector(e[0],bw)?[e[0]]:[]:b.find.matches(bw,e)},dir:function(bw,bv,by){var e=[],bx=bw[bv];while(bx&&bx.nodeType!==9&&(by===L||bx.nodeType!==1||!b(bx).is(by))){if(bx.nodeType===1){e.push(bx)}bx=bx[bv]}return e},nth:function(by,e,bw,bx){e=e||1;var bv=0;for(;by;by=by[bw]){if(by.nodeType===1&&++bv===e){break}}return by},sibling:function(bw,bv){var e=[];for(;bw;bw=bw.nextSibling){if(bw.nodeType===1&&bw!==bv){e.push(bw)}}return e}});function aG(bx,bw,e){bw=bw||0;if(b.isFunction(bw)){return b.grep(bx,function(bz,by){var bA=!!bw.call(bz,by,bz);return bA===e})}else{if(bw.nodeType){return b.grep(bx,function(bz,by){return(bz===bw)===e})}else{if(typeof bw==="string"){var bv=b.grep(bx,function(by){return by.nodeType===1});if(bp.test(bw)){return b.filter(bw,bv,!e)}else{bw=b.filter(bw,bv)}}}}return b.grep(bx,function(bz,by){return(b.inArray(bz,bw)>=0)===e})}function a(e){var bw=aR.split("|"),bv=e.createDocumentFragment();if(bv.createElement){while(bw.length){bv.createElement(bw.pop())}}return bv}var aR="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ag=/ jQuery\d+="(?:\d+|null)"/g,ar=/^\s+/,R=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,d=/<([\w:]+)/,w=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},ac=a(av);ax.optgroup=ax.option;ax.tbody=ax.tfoot=ax.colgroup=ax.caption=ax.thead;ax.th=ax.td;if(!b.support.htmlSerialize){ax._default=[1,"div
","
"]}b.fn.extend({text:function(e){if(b.isFunction(e)){return this.each(function(bw){var bv=b(this);bv.text(e.call(this,bw,bv.text()))})}if(typeof e!=="object"&&e!==L){return this.empty().append((this[0]&&this[0].ownerDocument||av).createTextNode(e))}return b.text(this)},wrapAll:function(e){if(b.isFunction(e)){return this.each(function(bw){b(this).wrapAll(e.call(this,bw))})}if(this[0]){var bv=b(e,this[0].ownerDocument).eq(0).clone(true);if(this[0].parentNode){bv.insertBefore(this[0])}bv.map(function(){var bw=this;while(bw.firstChild&&bw.firstChild.nodeType===1){bw=bw.firstChild}return bw}).append(this)}return this},wrapInner:function(e){if(b.isFunction(e)){return this.each(function(bv){b(this).wrapInner(e.call(this,bv))})}return this.each(function(){var bv=b(this),bw=bv.contents();if(bw.length){bw.wrapAll(e)}else{bv.append(e)}})},wrap:function(e){var bv=b.isFunction(e);return this.each(function(bw){b(this).wrapAll(bv?e.call(this,bw):e)})},unwrap:function(){return this.parent().each(function(){if(!b.nodeName(this,"body")){b(this).replaceWith(this.childNodes)}}).end()},append:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1){this.appendChild(e)}})},prepend:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1){this.insertBefore(e,this.firstChild)}})},before:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(bv){this.parentNode.insertBefore(bv,this)})}else{if(arguments.length){var e=b.clean(arguments);e.push.apply(e,this.toArray());return this.pushStack(e,"before",arguments)}}},after:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(bv){this.parentNode.insertBefore(bv,this.nextSibling)})}else{if(arguments.length){var e=this.pushStack(this,"after",arguments);e.push.apply(e,b.clean(arguments));return e}}},remove:function(e,bx){for(var bv=0,bw;(bw=this[bv])!=null;bv++){if(!e||b.filter(e,[bw]).length){if(!bx&&bw.nodeType===1){b.cleanData(bw.getElementsByTagName("*"));b.cleanData([bw])}if(bw.parentNode){bw.parentNode.removeChild(bw)}}}return this},empty:function(){for(var e=0,bv;(bv=this[e])!=null;e++){if(bv.nodeType===1){b.cleanData(bv.getElementsByTagName("*"))}while(bv.firstChild){bv.removeChild(bv.firstChild)}}return this},clone:function(bv,e){bv=bv==null?false:bv;e=e==null?bv:e;return this.map(function(){return b.clone(this,bv,e)})},html:function(bx){if(bx===L){return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(ag,""):null}else{if(typeof bx==="string"&&!ae.test(bx)&&(b.support.leadingWhitespace||!ar.test(bx))&&!ax[(d.exec(bx)||["",""])[1].toLowerCase()]){bx=bx.replace(R,"<$1>");try{for(var bw=0,bv=this.length;bw1&&bw0?this.clone(true):this).get();b(bC[bA])[bv](by);bz=bz.concat(by)}return this.pushStack(bz,e,bC.selector)}}});function bg(e){if(typeof e.getElementsByTagName!=="undefined"){return e.getElementsByTagName("*")}else{if(typeof e.querySelectorAll!=="undefined"){return e.querySelectorAll("*")}else{return[]}}}function az(e){if(e.type==="checkbox"||e.type==="radio"){e.defaultChecked=e.checked}}function E(e){var bv=(e.nodeName||"").toLowerCase();if(bv==="input"){az(e)}else{if(bv!=="script"&&typeof e.getElementsByTagName!=="undefined"){b.grep(e.getElementsByTagName("input"),az)}}}function al(e){var bv=av.createElement("div");ac.appendChild(bv);bv.innerHTML=e.outerHTML;return bv.firstChild}b.extend({clone:function(by,bA,bw){var e,bv,bx,bz=b.support.html5Clone||!ah.test("<"+by.nodeName)?by.cloneNode(true):al(by);if((!b.support.noCloneEvent||!b.support.noCloneChecked)&&(by.nodeType===1||by.nodeType===11)&&!b.isXMLDoc(by)){ai(by,bz);e=bg(by);bv=bg(bz);for(bx=0;e[bx];++bx){if(bv[bx]){ai(e[bx],bv[bx])}}}if(bA){t(by,bz);if(bw){e=bg(by);bv=bg(bz);for(bx=0;e[bx];++bx){t(e[bx],bv[bx])}}}e=bv=null;return bz},clean:function(bw,by,bH,bA){var bF;by=by||av;if(typeof by.createElement==="undefined"){by=by.ownerDocument||by[0]&&by[0].ownerDocument||av}var bI=[],bB;for(var bE=0,bz;(bz=bw[bE])!=null;bE++){if(typeof bz==="number"){bz+=""}if(!bz){continue}if(typeof bz==="string"){if(!W.test(bz)){bz=by.createTextNode(bz)}else{bz=bz.replace(R,"<$1>");var bK=(d.exec(bz)||["",""])[1].toLowerCase(),bx=ax[bK]||ax._default,bD=bx[0],bv=by.createElement("div");if(by===av){ac.appendChild(bv)}else{a(by).appendChild(bv)}bv.innerHTML=bx[1]+bz+bx[2];while(bD--){bv=bv.lastChild}if(!b.support.tbody){var e=w.test(bz),bC=bK==="table"&&!e?bv.firstChild&&bv.firstChild.childNodes:bx[1]===""&&!e?bv.childNodes:[];for(bB=bC.length-1;bB>=0;--bB){if(b.nodeName(bC[bB],"tbody")&&!bC[bB].childNodes.length){bC[bB].parentNode.removeChild(bC[bB])}}}if(!b.support.leadingWhitespace&&ar.test(bz)){bv.insertBefore(by.createTextNode(ar.exec(bz)[0]),bv.firstChild)}bz=bv.childNodes}}var bG;if(!b.support.appendChecked){if(bz[0]&&typeof(bG=bz.length)==="number"){for(bB=0;bB=0){return bx+"px"}}else{return bx}}}});if(!b.support.opacity){b.cssHooks.opacity={get:function(bv,e){return au.test((e&&bv.currentStyle?bv.currentStyle.filter:bv.style.filter)||"")?(parseFloat(RegExp.$1)/100)+"":e?"1":""},set:function(by,bz){var bx=by.style,bv=by.currentStyle,e=b.isNumeric(bz)?"alpha(opacity="+bz*100+")":"",bw=bv&&bv.filter||bx.filter||"";bx.zoom=1;if(bz>=1&&b.trim(bw.replace(ak,""))===""){bx.removeAttribute("filter");if(bv&&!bv.filter){return}}bx.filter=ak.test(bw)?bw.replace(ak,e):bw+" "+e}}}b(function(){if(!b.support.reliableMarginRight){b.cssHooks.marginRight={get:function(bw,bv){var e;b.swap(bw,{display:"inline-block"},function(){if(bv){e=Z(bw,"margin-right","marginRight")}else{e=bw.style.marginRight}});return e}}}});if(av.defaultView&&av.defaultView.getComputedStyle){aI=function(by,bw){var bv,bx,e;bw=bw.replace(z,"-$1").toLowerCase();if((bx=by.ownerDocument.defaultView)&&(e=bx.getComputedStyle(by,null))){bv=e.getPropertyValue(bw);if(bv===""&&!b.contains(by.ownerDocument.documentElement,by)){bv=b.style(by,bw)}}return bv}}if(av.documentElement.currentStyle){aX=function(bz,bw){var bA,e,by,bv=bz.currentStyle&&bz.currentStyle[bw],bx=bz.style;if(bv===null&&bx&&(by=bx[bw])){bv=by}if(!bc.test(bv)&&bn.test(bv)){bA=bx.left;e=bz.runtimeStyle&&bz.runtimeStyle.left;if(e){bz.runtimeStyle.left=bz.currentStyle.left}bx.left=bw==="fontSize"?"1em":(bv||0);bv=bx.pixelLeft+"px";bx.left=bA;if(e){bz.runtimeStyle.left=e}}return bv===""?"auto":bv}}Z=aI||aX;function p(by,bw,bv){var bA=bw==="width"?by.offsetWidth:by.offsetHeight,bz=bw==="width"?an:a1,bx=0,e=bz.length;if(bA>0){if(bv!=="border"){for(;bx)<[^<]*)*<\/script>/gi,q=/^(?:select|textarea)/i,h=/\s+/,br=/([?&])_=[^&]*/,K=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,A=b.fn.load,aa={},r={},aE,s,aV=["*/"]+["*"];try{aE=bl.href}catch(aw){aE=av.createElement("a");aE.href="";aE=aE.href}s=K.exec(aE.toLowerCase())||[];function f(e){return function(by,bA){if(typeof by!=="string"){bA=by;by="*"}if(b.isFunction(bA)){var bx=by.toLowerCase().split(h),bw=0,bz=bx.length,bv,bB,bC;for(;bw=0){var e=bw.slice(by,bw.length);bw=bw.slice(0,by)}var bx="GET";if(bz){if(b.isFunction(bz)){bA=bz;bz=L}else{if(typeof bz==="object"){bz=b.param(bz,b.ajaxSettings.traditional);bx="POST"}}}var bv=this;b.ajax({url:bw,type:bx,dataType:"html",data:bz,complete:function(bC,bB,bD){bD=bC.responseText;if(bC.isResolved()){bC.done(function(bE){bD=bE});bv.html(e?b("
").append(bD.replace(a6,"")).find(e):bD)}if(bA){bv.each(bA,[bD,bB,bC])}}});return this},serialize:function(){return b.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?b.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||q.test(this.nodeName)||aZ.test(this.type))}).map(function(e,bv){var bw=b(this).val();return bw==null?null:b.isArray(bw)?b.map(bw,function(by,bx){return{name:bv.name,value:by.replace(bs,"\r\n")}}):{name:bv.name,value:bw.replace(bs,"\r\n")}}).get()}});b.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,bv){b.fn[bv]=function(bw){return this.on(bv,bw)}});b.each(["get","post"],function(e,bv){b[bv]=function(bw,by,bz,bx){if(b.isFunction(by)){bx=bx||bz;bz=by;by=L}return b.ajax({type:bv,url:bw,data:by,success:bz,dataType:bx})}});b.extend({getScript:function(e,bv){return b.get(e,L,bv,"script")},getJSON:function(e,bv,bw){return b.get(e,bv,bw,"json")},ajaxSetup:function(bv,e){if(e){am(bv,b.ajaxSettings)}else{e=bv;bv=b.ajaxSettings}am(bv,e);return bv},ajaxSettings:{url:aE,isLocal:aM.test(s[1]),global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":aV},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":bb.String,"text html":true,"text json":b.parseJSON,"text xml":b.parseXML},flatOptions:{context:true,url:true}},ajaxPrefilter:f(aa),ajaxTransport:f(r),ajax:function(bz,bx){if(typeof bz==="object"){bx=bz;bz=L}bx=bx||{};var bD=b.ajaxSetup({},bx),bS=bD.context||bD,bG=bS!==bD&&(bS.nodeType||bS instanceof b)?b(bS):b.event,bR=b.Deferred(),bN=b.Callbacks("once memory"),bB=bD.statusCode||{},bC,bH={},bO={},bQ,by,bL,bE,bI,bA=0,bw,bK,bJ={readyState:0,setRequestHeader:function(bT,bU){if(!bA){var e=bT.toLowerCase();bT=bO[e]=bO[e]||bT;bH[bT]=bU}return this},getAllResponseHeaders:function(){return bA===2?bQ:null},getResponseHeader:function(bT){var e;if(bA===2){if(!by){by={};while((e=aD.exec(bQ))){by[e[1].toLowerCase()]=e[2]}}e=by[bT.toLowerCase()]}return e===L?null:e},overrideMimeType:function(e){if(!bA){bD.mimeType=e}return this},abort:function(e){e=e||"abort";if(bL){bL.abort(e)}bF(0,e);return this}};function bF(bZ,bU,b0,bW){if(bA===2){return}bA=2;if(bE){clearTimeout(bE)}bL=L;bQ=bW||"";bJ.readyState=bZ>0?4:0;var bT,b4,b3,bX=bU,bY=b0?bj(bD,bJ,b0):L,bV,b2;if(bZ>=200&&bZ<300||bZ===304){if(bD.ifModified){if((bV=bJ.getResponseHeader("Last-Modified"))){b.lastModified[bC]=bV}if((b2=bJ.getResponseHeader("Etag"))){b.etag[bC]=b2}}if(bZ===304){bX="notmodified";bT=true}else{try{b4=G(bD,bY);bX="success";bT=true}catch(b1){bX="parsererror";b3=b1}}}else{b3=bX;if(!bX||bZ){bX="error";if(bZ<0){bZ=0}}}bJ.status=bZ;bJ.statusText=""+(bU||bX);if(bT){bR.resolveWith(bS,[b4,bX,bJ])}else{bR.rejectWith(bS,[bJ,bX,b3])}bJ.statusCode(bB);bB=L;if(bw){bG.trigger("ajax"+(bT?"Success":"Error"),[bJ,bD,bT?b4:b3])}bN.fireWith(bS,[bJ,bX]);if(bw){bG.trigger("ajaxComplete",[bJ,bD]);if(!(--b.active)){b.event.trigger("ajaxStop")}}}bR.promise(bJ);bJ.success=bJ.done;bJ.error=bJ.fail;bJ.complete=bN.add;bJ.statusCode=function(bT){if(bT){var e;if(bA<2){for(e in bT){bB[e]=[bB[e],bT[e]]}}else{e=bT[bJ.status];bJ.then(e,e)}}return this};bD.url=((bz||bD.url)+"").replace(bq,"").replace(c,s[1]+"//");bD.dataTypes=b.trim(bD.dataType||"*").toLowerCase().split(h);if(bD.crossDomain==null){bI=K.exec(bD.url.toLowerCase());bD.crossDomain=!!(bI&&(bI[1]!=s[1]||bI[2]!=s[2]||(bI[3]||(bI[1]==="http:"?80:443))!=(s[3]||(s[1]==="http:"?80:443))))}if(bD.data&&bD.processData&&typeof bD.data!=="string"){bD.data=b.param(bD.data,bD.traditional)}aW(aa,bD,bx,bJ);if(bA===2){return false}bw=bD.global;bD.type=bD.type.toUpperCase();bD.hasContent=!aQ.test(bD.type);if(bw&&b.active++===0){b.event.trigger("ajaxStart")}if(!bD.hasContent){if(bD.data){bD.url+=(M.test(bD.url)?"&":"?")+bD.data;delete bD.data}bC=bD.url;if(bD.cache===false){var bv=b.now(),bP=bD.url.replace(br,"$1_="+bv);bD.url=bP+((bP===bD.url)?(M.test(bD.url)?"&":"?")+"_="+bv:"")}}if(bD.data&&bD.hasContent&&bD.contentType!==false||bx.contentType){bJ.setRequestHeader("Content-Type",bD.contentType)}if(bD.ifModified){bC=bC||bD.url;if(b.lastModified[bC]){bJ.setRequestHeader("If-Modified-Since",b.lastModified[bC])}if(b.etag[bC]){bJ.setRequestHeader("If-None-Match",b.etag[bC])}}bJ.setRequestHeader("Accept",bD.dataTypes[0]&&bD.accepts[bD.dataTypes[0]]?bD.accepts[bD.dataTypes[0]]+(bD.dataTypes[0]!=="*"?", "+aV+"; q=0.01":""):bD.accepts["*"]);for(bK in bD.headers){bJ.setRequestHeader(bK,bD.headers[bK])}if(bD.beforeSend&&(bD.beforeSend.call(bS,bJ,bD)===false||bA===2)){bJ.abort();return false}for(bK in {success:1,error:1,complete:1}){bJ[bK](bD[bK])}bL=aW(r,bD,bx,bJ);if(!bL){bF(-1,"No Transport")}else{bJ.readyState=1;if(bw){bG.trigger("ajaxSend",[bJ,bD])}if(bD.async&&bD.timeout>0){bE=setTimeout(function(){bJ.abort("timeout")},bD.timeout)}try{bA=1;bL.send(bH,bF)}catch(bM){if(bA<2){bF(-1,bM)}else{throw bM}}}return bJ},param:function(e,bw){var bv=[],by=function(bz,bA){bA=b.isFunction(bA)?bA():bA;bv[bv.length]=encodeURIComponent(bz)+"="+encodeURIComponent(bA)};if(bw===L){bw=b.ajaxSettings.traditional}if(b.isArray(e)||(e.jquery&&!b.isPlainObject(e))){b.each(e,function(){by(this.name,this.value)})}else{for(var bx in e){v(bx,e[bx],bw,by)}}return bv.join("&").replace(k,"+")}});function v(bw,by,bv,bx){if(b.isArray(by)){b.each(by,function(bA,bz){if(bv||ap.test(bw)){bx(bw,bz)}else{v(bw+"["+(typeof bz==="object"||b.isArray(bz)?bA:"")+"]",bz,bv,bx)}})}else{if(!bv&&by!=null&&typeof by==="object"){for(var e in by){v(bw+"["+e+"]",by[e],bv,bx)}}else{bx(bw,by)}}}b.extend({active:0,lastModified:{},etag:{}});function bj(bD,bC,bz){var bv=bD.contents,bB=bD.dataTypes,bw=bD.responseFields,by,bA,bx,e;for(bA in bw){if(bA in bz){bC[bw[bA]]=bz[bA]}}while(bB[0]==="*"){bB.shift();if(by===L){by=bD.mimeType||bC.getResponseHeader("content-type")}}if(by){for(bA in bv){if(bv[bA]&&bv[bA].test(by)){bB.unshift(bA);break}}}if(bB[0] in bz){bx=bB[0]}else{for(bA in bz){if(!bB[0]||bD.converters[bA+" "+bB[0]]){bx=bA;break}if(!e){e=bA}}bx=bx||e}if(bx){if(bx!==bB[0]){bB.unshift(bx)}return bz[bx]}}function G(bH,bz){if(bH.dataFilter){bz=bH.dataFilter(bz,bH.dataType)}var bD=bH.dataTypes,bG={},bA,bE,bw=bD.length,bB,bC=bD[0],bx,by,bF,bv,e;for(bA=1;bA=bw.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();bw.animatedProperties[this.prop]=true;for(bA in bw.animatedProperties){if(bw.animatedProperties[bA]!==true){e=false}}if(e){if(bw.overflow!=null&&!b.support.shrinkWrapBlocks){b.each(["","X","Y"],function(bC,bD){bz.style["overflow"+bD]=bw.overflow[bC]})}if(bw.hide){b(bz).hide()}if(bw.hide||bw.show){for(bA in bw.animatedProperties){b.style(bz,bA,bw.orig[bA]);b.removeData(bz,"fxshow"+bA,true);b.removeData(bz,"toggle"+bA,true)}}bv=bw.complete;if(bv){bw.complete=false;bv.call(bz)}}return false}else{if(bw.duration==Infinity){this.now=bx}else{bB=bx-this.startTime;this.state=bB/bw.duration;this.pos=b.easing[bw.animatedProperties[this.prop]](this.state,bB,0,1,bw.duration);this.now=this.start+((this.end-this.start)*this.pos)}this.update()}return true}};b.extend(b.fx,{tick:function(){var bw,bv=b.timers,e=0;for(;e").appendTo(e),bw=bv.css("display");bv.remove();if(bw==="none"||bw===""){if(!a8){a8=av.createElement("iframe");a8.frameBorder=a8.width=a8.height=0}e.appendChild(a8);if(!m||!a8.createElement){m=(a8.contentWindow||a8.contentDocument).document;m.write((av.compatMode==="CSS1Compat"?"":"")+"");m.close()}bv=m.createElement(bx);m.body.appendChild(bv);bw=b.css(bv,"display");e.removeChild(a8)}Q[bx]=bw}return Q[bx]}var V=/^t(?:able|d|h)$/i,ad=/^(?:body|html)$/i;if("getBoundingClientRect" in av.documentElement){b.fn.offset=function(bI){var by=this[0],bB;if(bI){return this.each(function(e){b.offset.setOffset(this,bI,e)})}if(!by||!by.ownerDocument){return null}if(by===by.ownerDocument.body){return b.offset.bodyOffset(by)}try{bB=by.getBoundingClientRect()}catch(bF){}var bH=by.ownerDocument,bw=bH.documentElement;if(!bB||!b.contains(bw,by)){return bB?{top:bB.top,left:bB.left}:{top:0,left:0}}var bC=bH.body,bD=aK(bH),bA=bw.clientTop||bC.clientTop||0,bE=bw.clientLeft||bC.clientLeft||0,bv=bD.pageYOffset||b.support.boxModel&&bw.scrollTop||bC.scrollTop,bz=bD.pageXOffset||b.support.boxModel&&bw.scrollLeft||bC.scrollLeft,bG=bB.top+bv-bA,bx=bB.left+bz-bE;return{top:bG,left:bx}}}else{b.fn.offset=function(bF){var bz=this[0];if(bF){return this.each(function(bG){b.offset.setOffset(this,bF,bG)})}if(!bz||!bz.ownerDocument){return null}if(bz===bz.ownerDocument.body){return b.offset.bodyOffset(bz)}var bC,bw=bz.offsetParent,bv=bz,bE=bz.ownerDocument,bx=bE.documentElement,bA=bE.body,bB=bE.defaultView,e=bB?bB.getComputedStyle(bz,null):bz.currentStyle,bD=bz.offsetTop,by=bz.offsetLeft;while((bz=bz.parentNode)&&bz!==bA&&bz!==bx){if(b.support.fixedPosition&&e.position==="fixed"){break}bC=bB?bB.getComputedStyle(bz,null):bz.currentStyle;bD-=bz.scrollTop;by-=bz.scrollLeft;if(bz===bw){bD+=bz.offsetTop;by+=bz.offsetLeft;if(b.support.doesNotAddBorder&&!(b.support.doesAddBorderForTableAndCells&&V.test(bz.nodeName))){bD+=parseFloat(bC.borderTopWidth)||0;by+=parseFloat(bC.borderLeftWidth)||0}bv=bw;bw=bz.offsetParent}if(b.support.subtractsBorderForOverflowNotVisible&&bC.overflow!=="visible"){bD+=parseFloat(bC.borderTopWidth)||0;by+=parseFloat(bC.borderLeftWidth)||0}e=bC}if(e.position==="relative"||e.position==="static"){bD+=bA.offsetTop;by+=bA.offsetLeft}if(b.support.fixedPosition&&e.position==="fixed"){bD+=Math.max(bx.scrollTop,bA.scrollTop);by+=Math.max(bx.scrollLeft,bA.scrollLeft)}return{top:bD,left:by}}}b.offset={bodyOffset:function(e){var bw=e.offsetTop,bv=e.offsetLeft;if(b.support.doesNotIncludeMarginInBodyOffset){bw+=parseFloat(b.css(e,"marginTop"))||0;bv+=parseFloat(b.css(e,"marginLeft"))||0}return{top:bw,left:bv}},setOffset:function(bx,bG,bA){var bB=b.css(bx,"position");if(bB==="static"){bx.style.position="relative"}var bz=b(bx),bv=bz.offset(),e=b.css(bx,"top"),bE=b.css(bx,"left"),bF=(bB==="absolute"||bB==="fixed")&&b.inArray("auto",[e,bE])>-1,bD={},bC={},bw,by;if(bF){bC=bz.position();bw=bC.top;by=bC.left}else{bw=parseFloat(e)||0;by=parseFloat(bE)||0}if(b.isFunction(bG)){bG=bG.call(bx,bA,bv)}if(bG.top!=null){bD.top=(bG.top-bv.top)+bw}if(bG.left!=null){bD.left=(bG.left-bv.left)+by}if("using" in bG){bG.using.call(bx,bD)}else{bz.css(bD)}}};b.fn.extend({position:function(){if(!this[0]){return null}var bw=this[0],bv=this.offsetParent(),bx=this.offset(),e=ad.test(bv[0].nodeName)?{top:0,left:0}:bv.offset();bx.top-=parseFloat(b.css(bw,"marginTop"))||0;bx.left-=parseFloat(b.css(bw,"marginLeft"))||0;e.top+=parseFloat(b.css(bv[0],"borderTopWidth"))||0;e.left+=parseFloat(b.css(bv[0],"borderLeftWidth"))||0;return{top:bx.top-e.top,left:bx.left-e.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||av.body;while(e&&(!ad.test(e.nodeName)&&b.css(e,"position")==="static")){e=e.offsetParent}return e})}});b.each(["Left","Top"],function(bv,e){var bw="scroll"+e;b.fn[bw]=function(bz){var bx,by;if(bz===L){bx=this[0];if(!bx){return null}by=aK(bx);return by?("pageXOffset" in by)?by[bv?"pageYOffset":"pageXOffset"]:b.support.boxModel&&by.document.documentElement[bw]||by.document.body[bw]:bx[bw]}return this.each(function(){by=aK(this);if(by){by.scrollTo(!bv?bz:b(by).scrollLeft(),bv?bz:b(by).scrollTop())}else{this[bw]=bz}})}});function aK(e){return b.isWindow(e)?e:e.nodeType===9?e.defaultView||e.parentWindow:false}b.each(["Height","Width"],function(bv,e){var bw=e.toLowerCase();b.fn["inner"+e]=function(){var bx=this[0];return bx?bx.style?parseFloat(b.css(bx,bw,"padding")):this[bw]():null};b.fn["outer"+e]=function(by){var bx=this[0];return bx?bx.style?parseFloat(b.css(bx,bw,by?"margin":"border")):this[bw]():null};b.fn[bw]=function(bz){var bA=this[0];if(!bA){return bz==null?null:this}if(b.isFunction(bz)){return this.each(function(bE){var bD=b(this);bD[bw](bz.call(this,bE,bD[bw]()))})}if(b.isWindow(bA)){var bB=bA.document.documentElement["client"+e],bx=bA.document.body;return bA.document.compatMode==="CSS1Compat"&&bB||bx&&bx["client"+e]||bB}else{if(bA.nodeType===9){return Math.max(bA.documentElement["client"+e],bA.body["scroll"+e],bA.documentElement["scroll"+e],bA.body["offset"+e],bA.documentElement["offset"+e])}else{if(bz===L){var bC=b.css(bA,bw),by=parseFloat(bC);return b.isNumeric(by)?by:bC}else{return this.css(bw,typeof bz==="string"?bz:bz+"px")}}}}});bb.jQuery=bb.$=b;if(typeof define==="function"&&define.amd&&define.amd.jQuery){define("jquery",[],function(){return b})}})(window);/*! * jQuery UI 1.8.18 * * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI */ (function(a,d){a.ui=a.ui||{};if(a.ui.version){return}a.extend(a.ui,{version:"1.8.18",keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});a.fn.extend({propAttr:a.fn.prop||a.fn.attr,_focus:a.fn.focus,focus:function(e,f){return typeof e==="number"?this.each(function(){var g=this;setTimeout(function(){a(g).focus();if(f){f.call(g)}},e)}):this._focus.apply(this,arguments)},scrollParent:function(){var e;if((a.browser.msie&&(/(static|relative)/).test(this.css("position")))||(/absolute/).test(this.css("position"))){e=this.parents().filter(function(){return(/(relative|absolute|fixed)/).test(a.curCSS(this,"position",1))&&(/(auto|scroll)/).test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0)}else{e=this.parents().filter(function(){return(/(auto|scroll)/).test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0)}return(/fixed/).test(this.css("position"))||!e.length?a(document):e},zIndex:function(h){if(h!==d){return this.css("zIndex",h)}if(this.length){var f=a(this[0]),e,g;while(f.length&&f[0]!==document){e=f.css("position");if(e==="absolute"||e==="relative"||e==="fixed"){g=parseInt(f.css("zIndex"),10);if(!isNaN(g)&&g!==0){return g}}f=f.parent()}}return 0},disableSelection:function(){return this.bind((a.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(e){e.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});a.each(["Width","Height"],function(g,e){var f=e==="Width"?["Left","Right"]:["Top","Bottom"],h=e.toLowerCase(),k={innerWidth:a.fn.innerWidth,innerHeight:a.fn.innerHeight,outerWidth:a.fn.outerWidth,outerHeight:a.fn.outerHeight};function j(m,l,i,n){a.each(f,function(){l-=parseFloat(a.curCSS(m,"padding"+this,true))||0;if(i){l-=parseFloat(a.curCSS(m,"border"+this+"Width",true))||0}if(n){l-=parseFloat(a.curCSS(m,"margin"+this,true))||0}});return l}a.fn["inner"+e]=function(i){if(i===d){return k["inner"+e].call(this)}return this.each(function(){a(this).css(h,j(this,i)+"px")})};a.fn["outer"+e]=function(i,l){if(typeof i!=="number"){return k["outer"+e].call(this,i)}return this.each(function(){a(this).css(h,j(this,i,true,l)+"px")})}});function c(g,e){var j=g.nodeName.toLowerCase();if("area"===j){var i=g.parentNode,h=i.name,f;if(!g.href||!h||i.nodeName.toLowerCase()!=="map"){return false}f=a("img[usemap=#"+h+"]")[0];return !!f&&b(f)}return(/input|select|textarea|button|object/.test(j)?!g.disabled:"a"==j?g.href||e:e)&&b(g)}function b(e){return !a(e).parents().andSelf().filter(function(){return a.curCSS(this,"visibility")==="hidden"||a.expr.filters.hidden(this)}).length}a.extend(a.expr[":"],{data:function(g,f,e){return !!a.data(g,e[3])},focusable:function(e){return c(e,!isNaN(a.attr(e,"tabindex")))},tabbable:function(g){var e=a.attr(g,"tabindex"),f=isNaN(e);return(f||e>=0)&&c(g,!f)}});a(function(){var e=document.body,f=e.appendChild(f=document.createElement("div"));f.offsetHeight;a.extend(f.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});a.support.minHeight=f.offsetHeight===100;a.support.selectstart="onselectstart" in f;e.removeChild(f).style.display="none"});a.extend(a.ui,{plugin:{add:function(f,g,j){var h=a.ui[f].prototype;for(var e in j){h.plugins[e]=h.plugins[e]||[];h.plugins[e].push([g,j[e]])}},call:function(e,g,f){var j=e.plugins[g];if(!j||!e.element[0].parentNode){return}for(var h=0;h0){return true}h[e]=1;g=(h[e]>0);h[e]=0;return g},isOverAxis:function(f,e,g){return(f>e)&&(f<(e+g))},isOver:function(j,f,i,h,e,g){return a.ui.isOverAxis(j,i,e)&&a.ui.isOverAxis(f,h,g)}})})(jQuery);/*! * jQuery UI Widget 1.8.18 * * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Widget */ (function(b,d){if(b.cleanData){var c=b.cleanData;b.cleanData=function(f){for(var g=0,h;(h=f[g])!=null;g++){try{b(h).triggerHandler("remove")}catch(j){}}c(f)}}else{var a=b.fn.remove;b.fn.remove=function(e,f){return this.each(function(){if(!f){if(!e||b.filter(e,[this]).length){b("*",this).add([this]).each(function(){try{b(this).triggerHandler("remove")}catch(g){}})}}return a.call(b(this),e,f)})}}b.widget=function(f,h,e){var g=f.split(".")[0],j;f=f.split(".")[1];j=g+"-"+f;if(!e){e=h;h=b.Widget}b.expr[":"][j]=function(k){return !!b.data(k,f)};b[g]=b[g]||{};b[g][f]=function(k,l){if(arguments.length){this._createWidget(k,l)}};var i=new h();i.options=b.extend(true,{},i.options);b[g][f].prototype=b.extend(true,i,{namespace:g,widgetName:f,widgetEventPrefix:b[g][f].prototype.widgetEventPrefix||f,widgetBaseClass:j},e);b.widget.bridge(f,b[g][f])};b.widget.bridge=function(f,e){b.fn[f]=function(i){var g=typeof i==="string",h=Array.prototype.slice.call(arguments,1),j=this;i=!g&&h.length?b.extend.apply(null,[true,i].concat(h)):i;if(g&&i.charAt(0)==="_"){return j}if(g){this.each(function(){var k=b.data(this,f),l=k&&b.isFunction(k[i])?k[i].apply(k,h):k;if(l!==k&&l!==d){j=l;return false}})}else{this.each(function(){var k=b.data(this,f);if(k){k.option(i||{})._init()}else{b.data(this,f,new e(i,this))}})}return j}};b.Widget=function(e,f){if(arguments.length){this._createWidget(e,f)}};b.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:false},_createWidget:function(f,g){b.data(g,this.widgetName,this);this.element=b(g);this.options=b.extend(true,{},this.options,this._getCreateOptions(),f);var e=this;this.element.bind("remove."+this.widgetName,function(){e.destroy()});this._create();this._trigger("create");this._init()},_getCreateOptions:function(){return b.metadata&&b.metadata.get(this.element[0])[this.widgetName]},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled ui-state-disabled")},widget:function(){return this.element},option:function(f,g){var e=f;if(arguments.length===0){return b.extend({},this.options)}if(typeof f==="string"){if(g===d){return this.options[f]}e={};e[f]=g}this._setOptions(e);return this},_setOptions:function(f){var e=this;b.each(f,function(g,h){e._setOption(g,h)});return this},_setOption:function(e,f){this.options[e]=f;if(e==="disabled"){this.widget()[f?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled",f)}return this},enable:function(){return this._setOption("disabled",false)},disable:function(){return this._setOption("disabled",true)},_trigger:function(e,f,g){var j,i,h=this.options[e];g=g||{};f=b.Event(f);f.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase();f.target=this.element[0];i=f.originalEvent;if(i){for(j in i){if(!(j in f)){f[j]=i[j]}}}this.element.trigger(f,g);return !(b.isFunction(h)&&h.call(this.element[0],f,g)===false||f.isDefaultPrevented())}}})(jQuery);/*! * jQuery UI Mouse 1.8.18 * * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Mouse * * Depends: * jquery.ui.widget.js */ (function(b,c){var a=false;b(document).mouseup(function(d){a=false});b.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var d=this;this.element.bind("mousedown."+this.widgetName,function(e){return d._mouseDown(e)}).bind("click."+this.widgetName,function(e){if(true===b.data(e.target,d.widgetName+".preventClickEvent")){b.removeData(e.target,d.widgetName+".preventClickEvent");e.stopImmediatePropagation();return false}});this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName)},_mouseDown:function(f){if(a){return}(this._mouseStarted&&this._mouseUp(f));this._mouseDownEvent=f;var e=this,g=(f.which==1),d=(typeof this.options.cancel=="string"&&f.target.nodeName?b(f.target).closest(this.options.cancel).length:false);if(!g||d||!this._mouseCapture(f)){return true}this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet){this._mouseDelayTimer=setTimeout(function(){e.mouseDelayMet=true},this.options.delay)}if(this._mouseDistanceMet(f)&&this._mouseDelayMet(f)){this._mouseStarted=(this._mouseStart(f)!==false);if(!this._mouseStarted){f.preventDefault();return true}}if(true===b.data(f.target,this.widgetName+".preventClickEvent")){b.removeData(f.target,this.widgetName+".preventClickEvent")}this._mouseMoveDelegate=function(h){return e._mouseMove(h)};this._mouseUpDelegate=function(h){return e._mouseUp(h)};b(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);f.preventDefault();a=true;return true},_mouseMove:function(d){if(b.browser.msie&&!(document.documentMode>=9)&&!d.button){return this._mouseUp(d)}if(this._mouseStarted){this._mouseDrag(d);return d.preventDefault()}if(this._mouseDistanceMet(d)&&this._mouseDelayMet(d)){this._mouseStarted=(this._mouseStart(this._mouseDownEvent,d)!==false);(this._mouseStarted?this._mouseDrag(d):this._mouseUp(d))}return !this._mouseStarted},_mouseUp:function(d){b(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;if(d.target==this._mouseDownEvent.target){b.data(d.target,this.widgetName+".preventClickEvent",true)}this._mouseStop(d)}return false},_mouseDistanceMet:function(d){return(Math.max(Math.abs(this._mouseDownEvent.pageX-d.pageX),Math.abs(this._mouseDownEvent.pageY-d.pageY))>=this.options.distance)},_mouseDelayMet:function(d){return this.mouseDelayMet},_mouseStart:function(d){},_mouseDrag:function(d){},_mouseStop:function(d){},_mouseCapture:function(d){return true}})})(jQuery);(function(c,d){c.widget("ui.resizable",c.ui.mouse,{widgetEventPrefix:"resize",options:{alsoResize:false,animate:false,animateDuration:"slow",animateEasing:"swing",aspectRatio:false,autoHide:false,containment:false,ghost:false,grid:false,handles:"e,s,se",helper:false,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1000},_create:function(){var f=this,k=this.options;this.element.addClass("ui-resizable");c.extend(this,{_aspectRatio:!!(k.aspectRatio),aspectRatio:k.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:k.helper||k.ghost||k.animate?k.helper||"ui-resizable-helper":null});if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)){this.element.wrap(c('
').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle=this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=k.handles||(!c(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all"){this.handles="n,e,s,w,se,sw,ne,nw"}var l=this.handles.split(",");this.handles={};for(var g=0;g
');if(/sw|se|ne|nw/.test(j)){h.css({zIndex:++k.zIndex})}if("se"==j){h.addClass("ui-icon ui-icon-gripsmall-diagonal-se")}this.handles[j]=".ui-resizable-"+j;this.element.append(h)}}this._renderAxis=function(q){q=q||this.element;for(var n in this.handles){if(this.handles[n].constructor==String){this.handles[n]=c(this.handles[n],this.element).show()}if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var o=c(this.handles[n],this.element),p=0;p=/sw|ne|nw|se|n|s/.test(n)?o.outerHeight():o.outerWidth();var m=["padding",/ne|nw|n/.test(n)?"Top":/se|sw|s/.test(n)?"Bottom":/^e$/.test(n)?"Right":"Left"].join("");q.css(m,p);this._proportionallyResize()}if(!c(this.handles[n]).length){continue}}};this._renderAxis(this.element);this._handles=c(".ui-resizable-handle",this.element).disableSelection();this._handles.mouseover(function(){if(!f.resizing){if(this.className){var i=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)}f.axis=i&&i[1]?i[1]:"se"}});if(k.autoHide){this._handles.hide();c(this.element).addClass("ui-resizable-autohide").hover(function(){if(k.disabled){return}c(this).removeClass("ui-resizable-autohide");f._handles.show()},function(){if(k.disabled){return}if(!f.resizing){c(this).addClass("ui-resizable-autohide");f._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy();var e=function(g){c(g).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){e(this.element);var f=this.element;f.after(this.originalElement.css({position:f.css("position"),width:f.outerWidth(),height:f.outerHeight(),top:f.css("top"),left:f.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle);e(this.originalElement);return this},_mouseCapture:function(f){var g=false;for(var e in this.handles){if(c(this.handles[e])[0]==f.target){g=true}}return !this.options.disabled&&g},_mouseStart:function(g){var j=this.options,f=this.element.position(),e=this.element;this.resizing=true;this.documentScroll={top:c(document).scrollTop(),left:c(document).scrollLeft()};if(e.is(".ui-draggable")||(/absolute/).test(e.css("position"))){e.css({position:"absolute",top:f.top,left:f.left})}this._renderProxy();var k=b(this.helper.css("left")),h=b(this.helper.css("top"));if(j.containment){k+=c(j.containment).scrollLeft()||0;h+=c(j.containment).scrollTop()||0}this.offset=this.helper.offset();this.position={left:k,top:h};this.size=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalSize=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalPosition={left:k,top:h};this.sizeDiff={width:e.outerWidth()-e.width(),height:e.outerHeight()-e.height()};this.originalMousePosition={left:g.pageX,top:g.pageY};this.aspectRatio=(typeof j.aspectRatio=="number")?j.aspectRatio:((this.originalSize.width/this.originalSize.height)||1);var i=c(".ui-resizable-"+this.axis).css("cursor");c("body").css("cursor",i=="auto"?this.axis+"-resize":i);e.addClass("ui-resizable-resizing");this._propagate("start",g);return true},_mouseDrag:function(e){var h=this.helper,g=this.options,m={},q=this,j=this.originalMousePosition,n=this.axis;var r=(e.pageX-j.left)||0,p=(e.pageY-j.top)||0;var i=this._change[n];if(!i){return false}var l=i.apply(this,[e,r,p]),k=c.browser.msie&&c.browser.version<7,f=this.sizeDiff;this._updateVirtualBoundaries(e.shiftKey);if(this._aspectRatio||e.shiftKey){l=this._updateRatio(l,e)}l=this._respectSize(l,e);this._propagate("resize",e);h.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});if(!this._helper&&this._proportionallyResizeElements.length){this._proportionallyResize()}this._updateCache(l);this._trigger("resize",e,this.ui());return false},_mouseStop:function(h){this.resizing=false;var i=this.options,m=this;if(this._helper){var g=this._proportionallyResizeElements,e=g.length&&(/textarea/i).test(g[0].nodeName),f=e&&c.ui.hasScroll(g[0],"left")?0:m.sizeDiff.height,k=e?0:m.sizeDiff.width;var n={width:(m.helper.width()-k),height:(m.helper.height()-f)},j=(parseInt(m.element.css("left"),10)+(m.position.left-m.originalPosition.left))||null,l=(parseInt(m.element.css("top"),10)+(m.position.top-m.originalPosition.top))||null;if(!i.animate){this.element.css(c.extend(n,{top:l,left:j}))}m.helper.height(m.size.height);m.helper.width(m.size.width);if(this._helper&&!i.animate){this._proportionallyResize()}}c("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",h);if(this._helper){this.helper.remove()}return false},_updateVirtualBoundaries:function(g){var j=this.options,i,h,f,k,e;e={minWidth:a(j.minWidth)?j.minWidth:0,maxWidth:a(j.maxWidth)?j.maxWidth:Infinity,minHeight:a(j.minHeight)?j.minHeight:0,maxHeight:a(j.maxHeight)?j.maxHeight:Infinity};if(this._aspectRatio||g){i=e.minHeight*this.aspectRatio;f=e.minWidth/this.aspectRatio;h=e.maxHeight*this.aspectRatio;k=e.maxWidth/this.aspectRatio;if(i>e.minWidth){e.minWidth=i}if(f>e.minHeight){e.minHeight=f}if(hl.width),s=a(l.height)&&i.minHeight&&(i.minHeight>l.height);if(h){l.width=i.minWidth}if(s){l.height=i.minHeight}if(t){l.width=i.maxWidth}if(m){l.height=i.maxHeight}var f=this.originalPosition.left+this.originalSize.width,p=this.position.top+this.size.height;var k=/sw|nw|w/.test(q),e=/nw|ne|n/.test(q);if(h&&k){l.left=f-i.minWidth}if(t&&k){l.left=f-i.maxWidth}if(s&&e){l.top=p-i.minHeight}if(m&&e){l.top=p-i.maxHeight}var n=!l.width&&!l.height;if(n&&!l.left&&l.top){l.top=null}else{if(n&&!l.top&&l.left){l.left=null}}return l},_proportionallyResize:function(){var k=this.options;if(!this._proportionallyResizeElements.length){return}var g=this.helper||this.element;for(var f=0;f');var e=c.browser.msie&&c.browser.version<7,g=(e?1:0),h=(e?2:-1);this.helper.addClass(this._helper).css({width:this.element.outerWidth()+h,height:this.element.outerHeight()+h,position:"absolute",left:this.elementOffset.left-g+"px",top:this.elementOffset.top-g+"px",zIndex:++i.zIndex});this.helper.appendTo("body").disableSelection()}else{this.helper=this.element}},_change:{e:function(g,f,e){return{width:this.originalSize.width+f}},w:function(h,f,e){var j=this.options,g=this.originalSize,i=this.originalPosition;return{left:i.left+f,width:g.width-f}},n:function(h,f,e){var j=this.options,g=this.originalSize,i=this.originalPosition;return{top:i.top+e,height:g.height-e}},s:function(g,f,e){return{height:this.originalSize.height+e}},se:function(g,f,e){return c.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[g,f,e]))},sw:function(g,f,e){return c.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[g,f,e]))},ne:function(g,f,e){return c.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[g,f,e]))},nw:function(g,f,e){return c.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[g,f,e]))}},_propagate:function(f,e){c.ui.plugin.call(this,f,[e,this.ui()]);(f!="resize"&&this._trigger(f,e,this.ui()))},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}});c.extend(c.ui.resizable,{version:"1.8.18"});c.ui.plugin.add("resizable","alsoResize",{start:function(f,g){var e=c(this).data("resizable"),i=e.options;var h=function(j){c(j).each(function(){var k=c(this);k.data("resizable-alsoresize",{width:parseInt(k.width(),10),height:parseInt(k.height(),10),left:parseInt(k.css("left"),10),top:parseInt(k.css("top"),10)})})};if(typeof(i.alsoResize)=="object"&&!i.alsoResize.parentNode){if(i.alsoResize.length){i.alsoResize=i.alsoResize[0];h(i.alsoResize)}else{c.each(i.alsoResize,function(j){h(j)})}}else{h(i.alsoResize)}},resize:function(g,i){var f=c(this).data("resizable"),j=f.options,h=f.originalSize,l=f.originalPosition;var k={height:(f.size.height-h.height)||0,width:(f.size.width-h.width)||0,top:(f.position.top-l.top)||0,left:(f.position.left-l.left)||0},e=function(m,n){c(m).each(function(){var q=c(this),r=c(this).data("resizable-alsoresize"),p={},o=n&&n.length?n:q.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];c.each(o,function(s,u){var t=(r[u]||0)+(k[u]||0);if(t&&t>=0){p[u]=t||null}});q.css(p)})};if(typeof(j.alsoResize)=="object"&&!j.alsoResize.nodeType){c.each(j.alsoResize,function(m,n){e(m,n)})}else{e(j.alsoResize)}},stop:function(e,f){c(this).removeData("resizable-alsoresize")}});c.ui.plugin.add("resizable","animate",{stop:function(i,n){var p=c(this).data("resizable"),j=p.options;var h=p._proportionallyResizeElements,e=h.length&&(/textarea/i).test(h[0].nodeName),f=e&&c.ui.hasScroll(h[0],"left")?0:p.sizeDiff.height,l=e?0:p.sizeDiff.width;var g={width:(p.size.width-l),height:(p.size.height-f)},k=(parseInt(p.element.css("left"),10)+(p.position.left-p.originalPosition.left))||null,m=(parseInt(p.element.css("top"),10)+(p.position.top-p.originalPosition.top))||null;p.element.animate(c.extend(g,m&&k?{top:m,left:k}:{}),{duration:j.animateDuration,easing:j.animateEasing,step:function(){var o={width:parseInt(p.element.css("width"),10),height:parseInt(p.element.css("height"),10),top:parseInt(p.element.css("top"),10),left:parseInt(p.element.css("left"),10)};if(h&&h.length){c(h[0]).css({width:o.width,height:o.height})}p._updateCache(o);p._propagate("resize",i)}})}});c.ui.plugin.add("resizable","containment",{start:function(f,r){var t=c(this).data("resizable"),j=t.options,l=t.element;var g=j.containment,k=(g instanceof c)?g.get(0):(/parent/.test(g))?l.parent().get(0):g;if(!k){return}t.containerElement=c(k);if(/document/.test(g)||g==document){t.containerOffset={left:0,top:0};t.containerPosition={left:0,top:0};t.parentData={element:c(document),left:0,top:0,width:c(document).width(),height:c(document).height()||document.body.parentNode.scrollHeight}}else{var n=c(k),i=[];c(["Top","Right","Left","Bottom"]).each(function(p,o){i[p]=b(n.css("padding"+o))});t.containerOffset=n.offset();t.containerPosition=n.position();t.containerSize={height:(n.innerHeight()-i[3]),width:(n.innerWidth()-i[1])};var q=t.containerOffset,e=t.containerSize.height,m=t.containerSize.width,h=(c.ui.hasScroll(k,"left")?k.scrollWidth:m),s=(c.ui.hasScroll(k)?k.scrollHeight:e);t.parentData={element:k,left:q.left,top:q.top,width:h,height:s}}},resize:function(g,q){var t=c(this).data("resizable"),i=t.options,f=t.containerSize,p=t.containerOffset,m=t.size,n=t.position,r=t._aspectRatio||g.shiftKey,e={top:0,left:0},h=t.containerElement;if(h[0]!=document&&(/static/).test(h.css("position"))){e=p}if(n.left<(t._helper?p.left:0)){t.size.width=t.size.width+(t._helper?(t.position.left-p.left):(t.position.left-e.left));if(r){t.size.height=t.size.width/i.aspectRatio}t.position.left=i.helper?p.left:0}if(n.top<(t._helper?p.top:0)){t.size.height=t.size.height+(t._helper?(t.position.top-p.top):t.position.top);if(r){t.size.width=t.size.height*i.aspectRatio}t.position.top=t._helper?p.top:0}t.offset.left=t.parentData.left+t.position.left;t.offset.top=t.parentData.top+t.position.top;var l=Math.abs((t._helper?t.offset.left-e.left:(t.offset.left-e.left))+t.sizeDiff.width),s=Math.abs((t._helper?t.offset.top-e.top:(t.offset.top-p.top))+t.sizeDiff.height);var k=t.containerElement.get(0)==t.element.parent().get(0),j=/relative|absolute/.test(t.containerElement.css("position"));if(k&&j){l-=t.parentData.left}if(l+t.size.width>=t.parentData.width){t.size.width=t.parentData.width-l;if(r){t.size.height=t.size.width/t.aspectRatio}}if(s+t.size.height>=t.parentData.height){t.size.height=t.parentData.height-s;if(r){t.size.width=t.size.height*t.aspectRatio}}},stop:function(f,n){var q=c(this).data("resizable"),g=q.options,l=q.position,m=q.containerOffset,e=q.containerPosition,i=q.containerElement;var j=c(q.helper),r=j.offset(),p=j.outerWidth()-q.sizeDiff.width,k=j.outerHeight()-q.sizeDiff.height;if(q._helper&&!g.animate&&(/relative/).test(i.css("position"))){c(this).css({left:r.left-e.left-m.left,width:p,height:k})}if(q._helper&&!g.animate&&(/static/).test(i.css("position"))){c(this).css({left:r.left-e.left-m.left,width:p,height:k})}}});c.ui.plugin.add("resizable","ghost",{start:function(g,h){var e=c(this).data("resizable"),i=e.options,f=e.size;e.ghost=e.originalElement.clone();e.ghost.css({opacity:0.25,display:"block",position:"relative",height:f.height,width:f.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof i.ghost=="string"?i.ghost:"");e.ghost.appendTo(e.helper)},resize:function(f,g){var e=c(this).data("resizable"),h=e.options;if(e.ghost){e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})}},stop:function(f,g){var e=c(this).data("resizable"),h=e.options;if(e.ghost&&e.helper){e.helper.get(0).removeChild(e.ghost.get(0))}}});c.ui.plugin.add("resizable","grid",{resize:function(e,m){var p=c(this).data("resizable"),h=p.options,k=p.size,i=p.originalSize,j=p.originalPosition,n=p.axis,l=h._aspectRatio||e.shiftKey;h.grid=typeof h.grid=="number"?[h.grid,h.grid]:h.grid;var g=Math.round((k.width-i.width)/(h.grid[0]||1))*(h.grid[0]||1),f=Math.round((k.height-i.height)/(h.grid[1]||1))*(h.grid[1]||1);if(/^(se|s|e)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f}else{if(/^(ne)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f;p.position.top=j.top-f}else{if(/^(sw)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f;p.position.left=j.left-g}else{p.size.width=i.width+g;p.size.height=i.height+f;p.position.top=j.top-f;p.position.left=j.left-g}}}}});var b=function(e){return parseInt(e,10)||0};var a=function(e){return !isNaN(parseInt(e,10))}})(jQuery);/*! * jQuery hashchange event - v1.3 - 7/21/2010 * http://benalman.com/projects/jquery-hashchange-plugin/ * * Copyright (c) 2010 "Cowboy" Ben Alman * Dual licensed under the MIT and GPL licenses. * http://benalman.com/about/license/ */ (function($,e,b){var c="hashchange",h=document,f,g=$.event.special,i=h.documentMode,d="on"+c in e&&(i===b||i>7);function a(j){j=j||location.href;return"#"+j.replace(/^[^#]*#?(.*)$/,"$1")}$.fn[c]=function(j){return j?this.bind(c,j):this.trigger(c)};$.fn[c].delay=50;g[c]=$.extend(g[c],{setup:function(){if(d){return false}$(f.start)},teardown:function(){if(d){return false}$(f.stop)}});f=(function(){var j={},p,m=a(),k=function(q){return q},l=k,o=k;j.start=function(){p||n()};j.stop=function(){p&&clearTimeout(p);p=b};function n(){var r=a(),q=o(m);if(r!==m){l(m=r,q);$(e).trigger(c)}else{if(q!==m){location.href=location.href.replace(/#.*/,"")+q}}p=setTimeout(n,$.fn[c].delay)}$.browser.msie&&!d&&(function(){var q,r;j.start=function(){if(!q){r=$.fn[c].src;r=r&&r+a();q=$('
jquery.js 文件参考

函数

b extend ({cssHooks:{opacity:{get:function(bw, bv){if(bv){var e=Z(bw,"opacity","opacity");return e===""?"1":e}else{return bw.style.opacity}}}}, cssNumber:{fillOpacity:true, fontWeight:true, lineHeight:true, opacity:true, orphans:true, widows:true, zIndex:true, zoom:true}, cssProps:{"float":b.support.cssFloat?"cssFloat":"styleFloat"}, style:function(bx, bw, bD, by){if(!bx||bx.nodeType===3||bx.nodeType===8||!bx.style){return}var bB, bC, bz=b.camelCase(bw), bv=bx.style, bE=b.cssHooks[bz];bw=b.cssProps[bz]||bz;if(bD!==L){bC=typeof bD;if(bC==="string"&&(bB=I.exec(bD))){bD=(+(bB[1]+1)*+bB[2])+parseFloat(b.css(bx, bw));bC="number"}if(bD==null||bC==="number"&&isNaN(bD)){return}if(bC==="number"&&!b.cssNumber[bz]){bD+="px"}if(!bE||!("set"in bE)||(bD=bE.set(bx, bD))!==L){try{bv[bw]=bD}catch(bA){}}}else{if(bE &&"get"in bE &&(bB=bE.get(bx, false, by))!==L){return bB}return bv[bw]}}, css:function(by, bx, bv){var bw, e;bx=b.camelCase(bx);e=b.cssHooks[bx];bx=b.cssProps[bx]||bx;if(bx==="cssFloat"){bx="float"}if(e &&"get"in e &&(bw=e.get(by, true, bv))!==L){return bw}else{if(Z){return Z(by, bx)}}}, swap:function(bx, bw, by){var e={};for(var bv in bw){e[bv]=bx.style[bv];bx.style[bv]=bw[bv]}by.call(bx);for(bv in bw){bx.style[bv]=e[bv]}}})
 
b each (["height","width"], function(bv, e){b.cssHooks[e]={get:function(by, bx, bw){var bz;if(bx){if(by.offsetWidth!==0){return p(by, e, bw)}else{b.swap(by, a7, function(){bz=p(by, e, bw)})}return bz}}, set:function(bw, bx){if(bc.test(bx)){bx=parseFloat(bx);if(bx >=0){return bx+"px"}}else{return bx}}}})
 
 if (!b.support.opacity)
 
 b (function(){if(!b.support.reliableMarginRight){b.cssHooks.marginRight={get:function(bw, bv){var e;b.swap(bw,{display:"inline-block"}, function(){if(bv){e=Z(bw,"margin-right","marginRight")}else{e=bw.style.marginRight}});return e}}}})
 
 if (av.defaultView &&av.defaultView.getComputedStyle)
 
 if (av.documentElement.currentStyle)
 
function p (by, bw, bv)
 
 if (b.expr &&b.expr.filters)
 

变量

function bb
 
function L {var av=bb.document,bu=bb.navigator,bl=bb.location
 
var b
 
var au =/opacity=([^)]*)/,z=/([A-Z]|^ms)/g,bc=/^-?\d+(?:px)?$/i,bn=/^-?\d/,I=/^([\-+])=([\-+.\de]+)/,a7={position:"absolute",visibility:"hidden",display:"block"},an=["Left","Right"],a1=["Top","Bottom"],Z,aI,aX
 
b fn css =function(e,bv){if(arguments.length===2&&bv===L){return this}return b.access(this,e,bv,true,function(bx,bw,by){return by!==L?b.style(bx,bw,by):b.css(bx,bw)})}
 
b curCSS =b.css
 
 Z =aI||aX
 
var k =/%20/g
 
var ap =/\[\]$/
 
var bs =/\r?\n/g
 
var bq =/#.*$/
 
var aD =/^(.*?):[ \t]*([^\r\n]*)\r?$/mg
 
var aZ =/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i
 
var aM =/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/
 
var aQ =/^(?:GET|HEAD)$/
 
var c
 

函数说明

b ( function(){if(!b.support.reliableMarginRight){b.cssHooks.marginRight={get:function(bw, bv){var e;b.swap(bw,{display:"inline-block"}, function(){if(bv){e=Z(bw,"margin-right","marginRight")}else{e=bw.style.marginRight}});return e}}}}  )
b each ( function(bv, e){b.cssHooks[e]={get:function(by, bx, bw){var bz;if(bx){if(by.offsetWidth!==0){return p(by, e, bw)}else{b.swap(by, a7, function(){bz=p(by, e, bw)})}return bz}}, set:function(bw, bx){if(bc.test(bx)){bx=parseFloat(bx);if(bx >=0){return bx+"px"}}else{return bx}}}}  )
b extend ( {cssHooks:{opacity:{get:function(bw, bv){if(bv){var e=Z(bw,"opacity","opacity");return e===""?"1":e}else{return bw.style.opacity}}}}, cssNumber:{fillOpacity:true, fontWeight:true, lineHeight:true, opacity:true, orphans:true, widows:true, zIndex:true, zoom:true}, cssProps:{"float":b.support.cssFloat?"cssFloat":"styleFloat"}, style:function(bx, bw, bD, by){if(!bx||bx.nodeType===3||bx.nodeType===8||!bx.style){return}var bB, bC, bz=b.camelCase(bw), bv=bx.style, bE=b.cssHooks[bz];bw=b.cssProps[bz]||bz;if(bD!==L){bC=typeof bD;if(bC==="string"&&(bB=I.exec(bD))){bD=(+(bB[1]+1)*+bB[2])+parseFloat(b.css(bx, bw));bC="number"}if(bD==null||bC==="number"&&isNaN(bD)){return}if(bC==="number"&&!b.cssNumber[bz]){bD+="px"}if(!bE||!("set"in bE)||(bD=bE.set(bx, bD))!==L){try{bv[bw]=bD}catch(bA){}}}else{if(bE &&"get"in bE &&(bB=bE.get(bx, false, by))!==L){return bB}return bv[bw]}}, css:function(by, bx, bv){var bw, e;bx=b.camelCase(bx);e=b.cssHooks[bx];bx=b.cssProps[bx]||bx;if(bx==="cssFloat"){bx="float"}if(e &&"get"in e &&(bw=e.get(by, true, bv))!==L){return bw}else{if(Z){return Z(by, bx)}}}, swap:function(bx, bw, by){var e={};for(var bv in bw){e[bv]=bx.style[bv];bx.style[bv]=bw[bv]}by.call(bx);for(bv in bw){bx.style[bv]=e[bv]}}}  )
if ( av.documentElement.  currentStyle)
if ( av.defaultView &&av.defaultView.  getComputedStyle)
if ( b.expr &&b.expr.  filters)
if ( !b.support.  opacity)
function p (   by,
  bw,
  bv 
)

变量说明

var aD =/^(.*?):[ \t]*([^\r\n]*)\r?$/mg
var aM =/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/
var ap =/\[\]$/
var aQ =/^(?:GET|HEAD)$/
var au =/opacity=([^)]*)/,z=/([A-Z]|^ms)/g,bc=/^-?\d+(?:px)?$/i,bn=/^-?\d/,I=/^([\-+])=([\-+.\de]+)/,a7={position:"absolute",visibility:"hidden",display:"block"},an=["Left","Right"],a1=["Top","Bottom"],Z,aI,aX
var aZ =/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i
var b
初始值:
=(function(){var bF=function(b0,b1){return new bF.fn.init(b0,b1,bD)},bU=bb.jQuery,bH=bb.$,bD,bY=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,bM=/\S/,bI=/^\s+/,bE=/\s+$/,bA=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,bN=/^[\],:{}\s]*$/,bW=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,bP=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,bJ=/(?:^|:|,)(?:\s*\[)+/g,by=/(webkit)[ \/]([\w.]+)/,bR=/(opera)(?:.*version)?[ \/]([\w.]+)/,bQ=/(msie) ([\w.]+)/,bS=/(mozilla)(?:.*? rv:([\w.]+))?/,bB=/-([a-z]|[0-9])/ig,bZ=/^-ms-/,bT=function(b0,b1){return(b1+"").toUpperCase()},bX=bu.userAgent,bV,bC,e,bL=Object.prototype.toString,bG=Object.prototype.hasOwnProperty,bz=Array.prototype.push,bK=Array.prototype.slice,bO=String.prototype.trim,bv=Array.prototype.indexOf,bx={};bF.fn=bF.prototype={constructor:bF,init:function(b0,b4,b3){var b2,b5,b1,b6;if(!b0){return this}if(b0.nodeType){this.context=this[0]=b0;this.length=1;return this}if(b0==="body"&&!b4&&av.body){this.context=av;this[0]=av.body;this.selector=b0;this.length=1;return this}if(typeof b0==="string"){if(b0.charAt(0)==="<"&&b0.charAt(b0.length-1)===">"&&b0.length>=3){b2=[null,b0,null]}else{b2=bY.exec(b0)}if(b2&&(b2[1]||!b4)){if(b2[1]){b4=b4 instanceof bF?b4[0]:b4;b6=(b4?b4.ownerDocument||b4:av);b1=bA.exec(b0);if(b1){if(bF.isPlainObject(b4)){b0=[av.createElement(b1[1])];bF.fn.attr.call(b0,b4,true)}else{b0=[b6.createElement(b1[1])]}}else{b1=bF.buildFragment([b2[1]],[b6]);b0=(b1.cacheable?bF.clone(b1.fragment):b1.fragment).childNodes}return bF.merge(this,b0)}else{b5=av.getElementById(b2[2]);if(b5&&b5.parentNode){if(b5.id!==b2[2]){return b3.find(b0)}this.length=1;this[0]=b5}this.context=av;this.selector=b0;return this}}else{if(!b4||b4.jquery){return(b4||b3).find(b0)}else{return this.constructor(b4).find(b0)}}}else{if(bF.isFunction(b0)){return b3.ready(b0)}}if(b0.selector!==L){this.selector=b0.selector;this.context=b0.context}return bF.makeArray(b0,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return bK.call(this,0)},get:function(b0){return b0==null?this.toArray():(b0<0?this[this.length+b0]:this[b0])},pushStack:function(b1,b3,b0){var b2=this.constructor();if(bF.isArray(b1)){bz.apply(b2,b1)}else{bF.merge(b2,b1)}b2.prevObject=this;b2.context=this.context;if(b3==="find"){b2.selector=this.selector+(this.selector?" ":"")+b0}else{if(b3){b2.selector=this.selector+"."+b3+"("+b0+")"}}return b2},each:function(b1,b0){return bF.each(this,b1,b0)},ready:function(b0){bF.bindReady();bC.add(b0);return this},eq:function(b0){b0=+b0;return b0===-1?this.slice(b0):this.slice(b0,b0+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(bK.apply(this,arguments),"slice",bK.call(arguments).join(","))},map:function(b0){return this.pushStack(bF.map(this,function(b2,b1){return b0.call(b2,b1,b2)}))},end:function(){return this.prevObject||this.constructor(null)},push:bz,sort:[].sort,splice:[].splice};bF.fn.init.prototype=bF.fn;bF.extend=bF.fn.extend=function(){var b9,b2,b0,b1,b6,b7,b5=arguments[0]||{},b4=1,b3=arguments.length,b8=false;if(typeof b5==="boolean"){b8=b5;b5=arguments[1]||{};b4=2}if(typeof b5!=="object"&&!bF.isFunction(b5)){b5={}}if(b3===b4){b5=this;--b4}for(;b4<b3;b4++){if((b9=arguments[b4])!=null){for(b2 in b9){b0=b5[b2];b1=b9[b2];if(b5===b1){continue}if(b8&&b1&&(bF.isPlainObject(b1)||(b6=bF.isArray(b1)))){if(b6){b6=false;b7=b0&&bF.isArray(b0)?b0:[]}else{b7=b0&&bF.isPlainObject(b0)?b0:{}}b5[b2]=bF.extend(b8,b7,b1)}else{if(b1!==L){b5[b2]=b1}}}}}return b5};bF.extend({noConflict:function(b0){if(bb.$===bF){bb.$=bH}if(b0&&bb.jQuery===bF){bb.jQuery=bU}return bF},isReady:false,readyWait:1,holdReady:function(b0){if(b0){bF.readyWait++}else{bF.ready(true)}},ready:function(b0){if((b0===true&&!--bF.readyWait)||(b0!==true&&!bF.isReady)){if(!av.body){return setTimeout(bF.ready,1)}bF.isReady=true;if(b0!==true&&--bF.readyWait>0){return}bC.fireWith(av,[bF]);if(bF.fn.trigger){bF(av).trigger("ready").off("ready")}}},bindReady:function(){if(bC){return}bC=bF.Callbacks("once memory");if(av.readyState==="complete"){return setTimeout(bF.ready,1)}if(av.addEventListener){av.addEventListener("DOMContentLoaded",e,false);bb.addEventListener("load",bF.ready,false)}else{if(av.attachEvent){av.attachEvent("onreadystatechange",e);bb.attachEvent("onload",bF.ready);var b0=false;try{b0=bb.frameElement==null}catch(b1){}if(av.documentElement.doScroll&&b0){bw()}}}},isFunction:function(b0){return bF.type(b0)==="function"},isArray:Array.isArray||function(b0){return bF.type(b0)==="array"},isWindow:function(b0){return b0&&typeof b0==="object"&&"setInterval" in b0},isNumeric:function(b0){return !isNaN(parseFloat(b0))&&isFinite(b0)},type:function(b0){return b0==null?String(b0):bx[bL.call(b0)]||"object"},isPlainObject:function(b2){if(!b2||bF.type(b2)!=="object"||b2.nodeType||bF.isWindow(b2)){return false}try{if(b2.constructor&&!bG.call(b2,"constructor")&&!bG.call(b2.constructor.prototype,"isPrototypeOf")){return false}}catch(b1){return false}var b0;for(b0 in b2){}return b0===L||bG.call(b2,b0)},isEmptyObject:function(b1){for(var b0 in b1){return false}return true},error:function(b0){throw new Error(b0)},parseJSON:function(b0){if(typeof b0!=="string"||!b0){return null}b0=bF.trim(b0);if(bb.JSON&&bb.JSON.parse){return bb.JSON.parse(b0)}if(bN.test(b0.replace(bW,"@").replace(bP,"]").replace(bJ,""))){return(new Function("return "+b0))()}bF.error("Invalid JSON: "+b0)},parseXML:function(b2){var b0,b1;try{if(bb.DOMParser){b1=new DOMParser();b0=b1.parseFromString(b2,"text/xml")}else{b0=new ActiveXObject("Microsoft.XMLDOM");b0.async="false";b0.loadXML(b2)}}catch(b3){b0=L}if(!b0||!b0.documentElement||b0.getElementsByTagName("parsererror").length){bF.error("Invalid XML: "+b2)}return b0},noop:function(){},globalEval:function(b0){if(b0&&bM.test(b0)){(bb.execScript||function(b1){bb["eval"].call(bb,b1)})(b0)}},camelCase:function(b0){return b0.replace(bZ,"ms-").replace(bB,bT)},nodeName:function(b1,b0){return b1.nodeName&&b1.nodeName.toUpperCase()===b0.toUpperCase()},each:function(b3,b6,b2){var b1,b4=0,b5=b3.length,b0=b5===L||bF.isFunction(b3);if(b2){if(b0){for(b1 in b3){if(b6.apply(b3[b1],b2)===false){break}}}else{for(;b4<b5;){if(b6.apply(b3[b4++],b2)===false){break}}}}else{if(b0){for(b1 in b3){if(b6.call(b3[b1],b1,b3[b1])===false){break}}}else{for(;b4<b5;){if(b6.call(b3[b4],b4,b3[b4++])===false){break}}}}return b3},trim:bO?function(b0){return b0==null?"":bO.call(b0)}:function(b0){return b0==null?"":b0.toString().replace(bI,"").replace(bE,"")},makeArray:function(b3,b1){var b0=b1||[];if(b3!=null){var b2=bF.type(b3);if(b3.length==null||b2==="string"||b2==="function"||b2==="regexp"||bF.isWindow(b3)){bz.call(b0,b3)}else{bF.merge(b0,b3)}}return b0},inArray:function(b2,b3,b1){var b0;if(b3){if(bv){return bv.call(b3,b2,b1)}b0=b3.length;b1=b1?b1<0?Math.max(0,b0+b1):b1:0;for(;b1<b0;b1++){if(b1 in b3&&b3[b1]===b2){return b1}}}return -1},merge:function(b4,b2){var b3=b4.length,b1=0;if(typeof b2.length==="number"){for(var b0=b2.length;b1<b0;b1++){b4[b3++]=b2[b1]}}else{while(b2[b1]!==L){b4[b3++]=b2[b1++]}}b4.length=b3;return b4},grep:function(b1,b6,b0){var b2=[],b5;b0=!!b0;for(var b3=0,b4=b1.length;b3<b4;b3++){b5=!!b6(b1[b3],b3);if(b0!==b5){b2.push(b1[b3])}}return b2},map:function(b0,b7,b8){var b5,b6,b4=[],b2=0,b1=b0.length,b3=b0 instanceof bF||b1!==L&&typeof b1==="number"&&((b1>0&&b0[0]&&b0[b1-1])||b1===0||bF.isArray(b0));if(b3){for(;b2<b1;b2++){b5=b7(b0[b2],b2,b8);if(b5!=null){b4[b4.length]=b5}}}else{for(b6 in b0){b5=b7(b0[b6],b6,b8);if(b5!=null){b4[b4.length]=b5}}}return b4.concat.apply([],b4)},guid:1,proxy:function(b4,b3){if(typeof b3==="string"){var b2=b4[b3];b3=b4;b4=b2}if(!bF.isFunction(b4)){return L}var b0=bK.call(arguments,2),b1=function(){return b4.apply(b3,b0.concat(bK.call(arguments)))};b1.guid=b4.guid=b4.guid||b1.guid||bF.guid++;return b1},access:function(b0,b8,b6,b2,b5,b7){var b1=b0.length;if(typeof b8==="object"){for(var b3 in b8){bF.access(b0,b3,b8[b3],b2,b5,b6)}return b0}if(b6!==L){b2=!b7&&b2&&bF.isFunction(b6);for(var b4=0;b4<b1;b4++){b5(b0[b4],b8,b2?b6.call(b0[b4],b4,b5(b0[b4],b8)):b6,b7)}return b0}return b1?b5(b0[0],b8):L},now:function(){return(new Date()).getTime()},uaMatch:function(b1){b1=b1.toLowerCase();var b0=by.exec(b1)||bR.exec(b1)||bQ.exec(b1)||b1.indexOf("compatible")<0&&bS.exec(b1)||[];return{browser:b0[1]||"",version:b0[2]||"0"}},sub:function(){function b0(b3,b4){return new b0.fn.init(b3,b4)}bF.extend(true,b0,this);b0.superclass=this;b0.fn=b0.prototype=this();b0.fn.constructor=b0;b0.sub=this.sub;b0.fn.init=function b2(b3,b4){if(b4&&b4 instanceof bF&&!(b4 instanceof b0)){b4=b0(b4)}return bF.fn.init.call(this,b3,b4,b1)};b0.fn.init.prototype=b0.fn;var b1=b0(av);return b0},browser:{}});bF.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(b1,b0){bx["[object "+b0+"]"]=b0.toLowerCase()});bV=bF.uaMatch(bX);if(bV.browser){bF.browser[bV.browser]=true;bF.browser.version=bV.version}if(bF.browser.webkit){bF.browser.safari=true}if(bM.test("\xA0")){bI=/^[\s\xA0]+/;bE=/[\s\xA0]+$/}bD=bF(av);if(av.addEventListener){e=function(){av.removeEventListener("DOMContentLoaded",e,false);bF.ready()}}else{if(av.attachEvent){e=function(){if(av.readyState==="complete"){av.detachEvent("onreadystatechange",e);bF.ready()}}}}function bw(){if(bF.isReady){return}try{av.documentElement.doScroll("left")}catch(b0){setTimeout(bw,1);return}bF.ready()}return bF})();var a2={};function X(e){var bv=a2[e]={},bw,bx;e=e.split(/\s+/);for(bw=0,bx=e.length;bw<bx;bw++){bv[e[bw]]=true}return bv}b.Callbacks=function(bw){bw=bw?(a2[bw]||X(bw)):{};var bB=[],bC=[],bx,by,bv,bz,bA,bE=function(bF){var bG,bJ,bI,bH,bK;for(bG=0,bJ=bF.length;bG<bJ;bG++){bI=bF[bG];bH=b.type(bI);if(bH==="array"){bE(bI)}else{if(bH==="function"){if(!bw.unique||!bD.has(bI)){bB.push(bI)}}}}},e=function(bG,bF){bF=bF||[];bx=!bw.memory||[bG,bF];by=true;bA=bv||0;bv=0;bz=bB.length;for(;bB&&bA<bz;bA++){if(bB[bA].apply(bG,bF)===false&&bw.stopOnFalse){bx=true;break}}by=false;if(bB){if(!bw.once){if(bC&&bC.length){bx=bC.shift();bD.fireWith(bx[0],bx[1])}}else{if(bx===true){bD.disable()}else{bB=[]}}}},bD={add:function(){if(bB){var bF=bB.length;bE(arguments);if(by){bz=bB.length}else{if(bx&&bx!==true){bv=bF;e(bx[0],bx[1])}}}return this},remove:function(){if(bB){var bF=arguments,bH=0,bI=bF.length;for(;bH<bI;bH++){for(var bG=0;bG<bB.length;bG++){if(bF[bH]===bB[bG]){if(by){if(bG<=bz){bz--;if(bG<=bA){bA--}}}bB.splice(bG--,1);if(bw.unique){break}}}}}return this},has:function(bG){if(bB){var bF=0,bH=bB.length;for(;bF<bH;bF++){if(bG===bB[bF]){return true}}}return false},empty:function(){bB=[];return this},disable:function(){bB=bC=bx=L;return this},disabled:function(){return !bB},lock:function(){bC=L;if(!bx||bx===true){bD.disable()}return this},locked:function(){return !bC},fireWith:function(bG,bF){if(bC){if(by){if(!bw.once){bC.push([bG,bF])}}else{if(!(bw.once&&bx)){e(bG,bF)}}}return this},fire:function(){bD.fireWith(this,arguments);return this},fired:function(){return !!bx}};return bD};var aJ=[].slice;b.extend({Deferred:function(by){var bx=b.Callbacks("once memory"),bw=b.Callbacks("once memory"),bv=b.Callbacks("memory"),e="pending",bA={resolve:bx,reject:bw,notify:bv},bC={done:bx.add,fail:bw.add,progress:bv.add,state:function(){return e},isResolved:bx.fired,isRejected:bw.fired,then:function(bE,bD,bF){bB.done(bE).fail(bD).progress(bF);return this},always:function(){bB.done.apply(bB,arguments).fail.apply(bB,arguments);return this},pipe:function(bF,bE,bD){return b.Deferred(function(bG){b.each({done:[bF,"resolve"],fail:[bE,"reject"],progress:[bD,"notify"]},function(bI,bL){var bH=bL[0],bK=bL[1],bJ;if(b.isFunction(bH)){bB[bI](function(){bJ=bH.apply(this,arguments);if(bJ&&b.isFunction(bJ.promise)){bJ.promise().then(bG.resolve,bG.reject,bG.notify)}else{bG[bK+"With"](this===bB?bG:this,[bJ])}})}else{bB[bI](bG[bK])}})}).promise()},promise:function(bE){if(bE==null){bE=bC}else{for(var bD in bC){bE[bD]=bC[bD]}}return bE}},bB=bC.promise({}),bz;for(bz in bA){bB[bz]=bA[bz].fire;bB[bz+"With"]=bA[bz].fireWith}bB.done(function(){e="resolved"},bw.disable,bv.lock).fail(function(){e="rejected"},bx.disable,bv.lock);if(by){by.call(bB,bB)}return bB},when:function(bA){var bx=aJ.call(arguments,0),bv=0,e=bx.length,bB=new Array(e),bw=e,by=e,bC=e<=1&&bA&&b.isFunction(bA.promise)?bA:b.Deferred(),bE=bC.promise();function bD(bF){return function(bG){bx[bF]=arguments.length>1?aJ.call(arguments,0):bG;if(!(--bw)){bC.resolveWith(bC,bx)}}}function bz(bF){return function(bG){bB[bF]=arguments.length>1?aJ.call(arguments,0):bG;bC.notifyWith(bE,bB)}}if(e>1){for(;bv<e;bv++){if(bx[bv]&&bx[bv].promise&&b.isFunction(bx[bv].promise)){bx[bv].promise().then(bD(bv),bC.reject,bz(bv))}else{--bw}}if(!bw){bC.resolveWith(bC,bx)}}else{if(bC!==bA){bC.resolveWith(bC,e?[bA]:[])}}return bE}});b.support=(function(){var bJ,bI,bF,bG,bx,bE,bA,bD,bz,bK,bB,by,bw,bv=av.createElement("div"),bH=av.documentElement;bv.setAttribute("className","t");bv.innerHTML=" <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";bI=bv.getElementsByTagName("*");bF=bv.getElementsByTagName("a")[0];if(!bI||!bI.length||!bF){return{}}bG=av.createElement("select");bx=bG.appendChild(av.createElement("option"));bE=bv.getElementsByTagName("input")[0];bJ={leadingWhitespace:(bv.firstChild.nodeType===3),tbody:!bv.getElementsByTagName("tbody").length,htmlSerialize:!!bv.getElementsByTagName("link").length,style:/top/.test(bF.getAttribute("style")),hrefNormalized:(bF.getAttribute("href")==="/a"),opacity:/^0.55/.test(bF.style.opacity),cssFloat:!!bF.style.cssFloat,checkOn:(bE.value==="on"),optSelected:bx.selected,getSetAttribute:bv.className!=="t",enctype:!!av.createElement("form").enctype,html5Clone:av.createElement("nav").cloneNode(true).outerHTML!=="<:nav></:nav>",submitBubbles:true,changeBubbles:true,focusinBubbles:false,deleteExpando:true,noCloneEvent:true,inlineBlockNeedsLayout:false,shrinkWrapBlocks:false,reliableMarginRight:true};bE.checked=true;bJ.noCloneChecked=bE.cloneNode(true).checked;bG.disabled=true;bJ.optDisabled=!bx.disabled;try{delete bv.test}catch(bC){bJ.deleteExpando=false}if(!bv.addEventListener&&bv.attachEvent&&bv.fireEvent){bv.attachEvent("onclick",function(){bJ.noCloneEvent=false});bv.cloneNode(true).fireEvent("onclick")}bE=av.createElement("input");bE.value="t";bE.setAttribute("type","radio");bJ.radioValue=bE.value==="t";bE.setAttribute("checked","checked");bv.appendChild(bE);bD=av.createDocumentFragment();bD.appendChild(bv.lastChild);bJ.checkClone=bD.cloneNode(true).cloneNode(true).lastChild.checked;bJ.appendChecked=bE.checked;bD.removeChild(bE);bD.appendChild(bv);bv.innerHTML="";if(bb.getComputedStyle){bA=av.createElement("div");bA.style.width="0";bA.style.marginRight="0";bv.style.width="2px";bv.appendChild(bA);bJ.reliableMarginRight=(parseInt((bb.getComputedStyle(bA,null)||{marginRight:0}).marginRight,10)||0)===0}if(bv.attachEvent){for(by in {submit:1,change:1,focusin:1}){bB="on"+by;bw=(bB in bv);if(!bw){bv.setAttribute(bB,"return;");bw=(typeof bv[bB]==="function")}bJ[by+"Bubbles"]=bw}}bD.removeChild(bv);bD=bG=bx=bA=bv=bE=null;b(function(){var bM,bU,bV,bT,bN,bO,bL,bS,bR,e,bP,bQ=av.getElementsByTagName("body")[0];if(!bQ){return}bL=1;bS="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;";bR="visibility:hidden;border:0;";e="style='"+bS+"border:5px solid #000;padding:0;'";bP="<div "+e+"><div></div></div><table "+e+" cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";bM=av.createElement("div");bM.style.cssText=bR+"width:0;height:0;position:static;top:0;margin-top:"+bL+"px";bQ.insertBefore(bM,bQ.firstChild);bv=av.createElement("div");bM.appendChild(bv);bv.innerHTML="<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";bz=bv.getElementsByTagName("td");bw=(bz[0].offsetHeight===0);bz[0].style.display="";bz[1].style.display="none";bJ.reliableHiddenOffsets=bw&&(bz[0].offsetHeight===0);bv.innerHTML="";bv.style.width=bv.style.paddingLeft="1px";b.boxModel=bJ.boxModel=bv.offsetWidth===2;if(typeof bv.style.zoom!=="undefined"){bv.style.display="inline";bv.style.zoom=1;bJ.inlineBlockNeedsLayout=(bv.offsetWidth===2);bv.style.display="";bv.innerHTML="<div style='width:4px;'></div>";bJ.shrinkWrapBlocks=(bv.offsetWidth!==2)}bv.style.cssText=bS+bR;bv.innerHTML=bP;bU=bv.firstChild;bV=bU.firstChild;bN=bU.nextSibling.firstChild.firstChild;bO={doesNotAddBorder:(bV.offsetTop!==5),doesAddBorderForTableAndCells:(bN.offsetTop===5)};bV.style.position="fixed";bV.style.top="20px";bO.fixedPosition=(bV.offsetTop===20||bV.offsetTop===15);bV.style.position=bV.style.top="";bU.style.overflow="hidden";bU.style.position="relative";bO.subtractsBorderForOverflowNotVisible=(bV.offsetTop===-5);bO.doesNotIncludeMarginInBodyOffset=(bQ.offsetTop!==bL);bQ.removeChild(bM);bv=bM=null;b.extend(bJ,bO)});return bJ})();var aS=/^(?:\{.*\}|\[.*\])$/,aA=/([A-Z])/g;b.extend({cache:{},uuid:0,expando:"jQuery"+(b.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:true,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:true},hasData:function(e){e=e.nodeType?b.cache[e[b.expando]]:e[b.expando];return !!e&&!S(e)},data:function(bx,bv,bz,by){if(!b.acceptData(bx)){return}var bG,bA,bD,bE=b.expando,bC=typeof bv==="string",bF=bx.nodeType,e=bF?b.cache:bx,bw=bF?bx[bE]:bx[bE]&&bE,bB=bv==="events";if((!bw||!e[bw]||(!bB&&!by&&!e[bw].data))&&bC&&bz===L){return}if(!bw){if(bF){bx[bE]=bw=++b.uuid}else{bw=bE}}if(!e[bw]){e[bw]={};if(!bF){e[bw].toJSON=b.noop}}if(typeof bv==="object"||typeof bv==="function"){if(by){e[bw]=b.extend(e[bw],bv)}else{e[bw].data=b.extend(e[bw].data,bv)}}bG=bA=e[bw];if(!by){if(!bA.data){bA.data={}}bA=bA.data}if(bz!==L){bA[b.camelCase(bv)]=bz}if(bB&&!bA[bv]){return bG.events}if(bC){bD=bA[bv];if(bD==null){bD=bA[b.camelCase(bv)]}}else{bD=bA}return bD},removeData:function(bx,bv,by){if(!b.acceptData(bx)){return}var bB,bA,bz,bC=b.expando,bD=bx.nodeType,e=bD?b.cache:bx,bw=bD?bx[bC]:bC;if(!e[bw]){return}if(bv){bB=by?e[bw]:e[bw].data;if(bB){if(!b.isArray(bv)){if(bv in bB){bv=[bv]}else{bv=b.camelCase(bv);if(bv in bB){bv=[bv]}else{bv=bv.split(" ")}}}for(bA=0,bz=bv.length;bA<bz;bA++){delete bB[bv[bA]]}if(!(by?S:b.isEmptyObject)(bB)){return}}}if(!by){delete e[bw].data;if(!S(e[bw])){return}}if(b.support.deleteExpando||!e.setInterval){delete e[bw]}else{e[bw]=null}if(bD){if(b.support.deleteExpando){delete bx[bC]}else{if(bx.removeAttribute){bx.removeAttribute(bC)}else{bx[bC]=null}}}},_data:function(bv,e,bw){return b.data(bv,e,bw,true)},acceptData:function(bv){if(bv.nodeName){var e=b.noData[bv.nodeName.toLowerCase()];if(e){return !(e===true||bv.getAttribute("classid")!==e)}}return true}});b.fn.extend({data:function(by,bA){var bB,e,bw,bz=null;if(typeof by==="undefined"){if(this.length){bz=b.data(this[0]);if(this[0].nodeType===1&&!b._data(this[0],"parsedAttrs")){e=this[0].attributes;for(var bx=0,bv=e.length;bx<bv;bx++){bw=e[bx].name;if(bw.indexOf("data-")===0){bw=b.camelCase(bw.substring(5));a5(this[0],bw,bz[bw])}}b._data(this[0],"parsedAttrs",true)}}return bz}else{if(typeof by==="object"){return this.each(function(){b.data(this,by)})}}bB=by.split(".");bB[1]=bB[1]?"."+bB[1]:"";if(bA===L){bz=this.triggerHandler("getData"+bB[1]+"!",[bB[0]]);if(bz===L&&this.length){bz=b.data(this[0],by);bz=a5(this[0],by,bz)}return bz===L&&bB[1]?this.data(bB[0]):bz}else{return this.each(function(){var bC=b(this),bD=[bB[0],bA];bC.triggerHandler("setData"+bB[1]+"!",bD);b.data(this,by,bA);bC.triggerHandler("changeData"+bB[1]+"!",bD)})}},removeData:function(e){return this.each(function(){b.removeData(this,e)})}});function a5(bx,bw,by){if(by===L&&bx.nodeType===1){var bv="data-"+bw.replace(aA,"-$1").toLowerCase();by=bx.getAttribute(bv);if(typeof by==="string"){try{by=by==="true"?true:by==="false"?false:by==="null"?null:b.isNumeric(by)?parseFloat(by):aS.test(by)?b.parseJSON(by):by}catch(bz){}b.data(bx,bw,by)}else{by=L}}return by}function S(bv){for(var e in bv){if(e==="data"&&b.isEmptyObject(bv[e])){continue}if(e!=="toJSON"){return false}}return true}function bi(by,bx,bA){var bw=bx+"defer",bv=bx+"queue",e=bx+"mark",bz=b._data(by,bw);if(bz&&(bA==="queue"||!b._data(by,bv))&&(bA==="mark"||!b._data(by,e))){setTimeout(function(){if(!b._data(by,bv)&&!b._data(by,e)){b.removeData(by,bw,true);bz.fire()}},0)}}b.extend({_mark:function(bv,e){if(bv){e=(e||"fx")+"mark";b._data(bv,e,(b._data(bv,e)||0)+1)}},_unmark:function(by,bx,bv){if(by!==true){bv=bx;bx=by;by=false}if(bx){bv=bv||"fx";var e=bv+"mark",bw=by?0:((b._data(bx,e)||1)-1);if(bw){b._data(bx,e,bw)}else{b.removeData(bx,e,true);bi(bx,bv,"mark")}}},queue:function(bv,e,bx){var bw;if(bv){e=(e||"fx")+"queue";bw=b._data(bv,e);if(bx){if(!bw||b.isArray(bx)){bw=b._data(bv,e,b.makeArray(bx))}else{bw.push(bx)}}return bw||[]}},dequeue:function(by,bx){bx=bx||"fx";var bv=b.queue(by,bx),bw=bv.shift(),e={};if(bw==="inprogress"){bw=bv.shift()}if(bw){if(bx==="fx"){bv.unshift("inprogress")}b._data(by,bx+".run",e);bw.call(by,function(){b.dequeue(by,bx)},e)}if(!bv.length){b.removeData(by,bx+"queue "+bx+".run",true);bi(by,bx,"queue")}}});b.fn.extend({queue:function(e,bv){if(typeof e!=="string"){bv=e;e="fx"}if(bv===L){return b.queue(this[0],e)}return this.each(function(){var bw=b.queue(this,e,bv);if(e==="fx"&&bw[0]!=="inprogress"){b.dequeue(this,e)}})},dequeue:function(e){return this.each(function(){b.dequeue(this,e)})},delay:function(bv,e){bv=b.fx?b.fx.speeds[bv]||bv:bv;e=e||"fx";return this.queue(e,function(bx,bw){var by=setTimeout(bx,bv);bw.stop=function(){clearTimeout(by)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(bD,bw){if(typeof bD!=="string"){bw=bD;bD=L}bD=bD||"fx";var e=b.Deferred(),bv=this,by=bv.length,bB=1,bz=bD+"defer",bA=bD+"queue",bC=bD+"mark",bx;function bE(){if(!(--bB)){e.resolveWith(bv,[bv])}}while(by--){if((bx=b.data(bv[by],bz,L,true)||(b.data(bv[by],bA,L,true)||b.data(bv[by],bC,L,true))&&b.data(bv[by],bz,b.Callbacks("once memory"),true))){bB++;bx.add(bE)}}bE();return e.promise()}});var aP=/[\n\t\r]/g,af=/\s+/,aU=/\r/g,g=/^(?:button|input)$/i,D=/^(?:button|input|object|select|textarea)$/i,l=/^a(?:rea)?$/i,ao=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,F=b.support.getSetAttribute,be,aY,aF;b.fn.extend({attr:function(e,bv){return b.access(this,e,bv,true,b.attr)},removeAttr:function(e){return this.each(function(){b.removeAttr(this,e)})},prop:function(e,bv){return b.access(this,e,bv,true,b.prop)},removeProp:function(e){e=b.propFix[e]||e;return this.each(function(){try{this[e]=L;delete this[e]}catch(bv){}})},addClass:function(by){var bA,bw,bv,bx,bz,bB,e;if(b.isFunction(by)){return this.each(function(bC){b(this).addClass(by.call(this,bC,this.className))})}if(by&&typeof by==="string"){bA=by.split(af);for(bw=0,bv=this.length;bw<bv;bw++){bx=this[bw];if(bx.nodeType===1){if(!bx.className&&bA.length===1){bx.className=by}else{bz=" "+bx.className+" ";for(bB=0,e=bA.length;bB<e;bB++){if(!~bz.indexOf(" "+bA[bB]+" ")){bz+=bA[bB]+" "}}bx.className=b.trim(bz)}}}}return this},removeClass:function(bz){var bA,bw,bv,by,bx,bB,e;if(b.isFunction(bz)){return this.each(function(bC){b(this).removeClass(bz.call(this,bC,this.className))})}if((bz&&typeof bz==="string")||bz===L){bA=(bz||"").split(af);for(bw=0,bv=this.length;bw<bv;bw++){by=this[bw];if(by.nodeType===1&&by.className){if(bz){bx=(" "+by.className+" ").replace(aP," ");for(bB=0,e=bA.length;bB<e;bB++){bx=bx.replace(" "+bA[bB]+" "," ")}by.className=b.trim(bx)}else{by.className=""}}}}return this},toggleClass:function(bx,bv){var bw=typeof bx,e=typeof bv==="boolean";if(b.isFunction(bx)){return this.each(function(by){b(this).toggleClass(bx.call(this,by,this.className,bv),bv)})}return this.each(function(){if(bw==="string"){var bA,bz=0,by=b(this),bB=bv,bC=bx.split(af);while((bA=bC[bz++])){bB=e?bB:!by.hasClass(bA);by[bB?"addClass":"removeClass"](bA)}}else{if(bw==="undefined"||bw==="boolean"){if(this.className){b._data(this,"__className__",this.className)}this.className=this.className||bx===false?"":b._data(this,"__className__")||""}}})},hasClass:function(e){var bx=" "+e+" ",bw=0,bv=this.length;for(;bw<bv;bw++){if(this[bw].nodeType===1&&(" "+this[bw].className+" ").replace(aP," ").indexOf(bx)>-1){return true}}return false},val:function(bx){var e,bv,by,bw=this[0];if(!arguments.length){if(bw){e=b.valHooks[bw.nodeName.toLowerCase()]||b.valHooks[bw.type];if(e&&"get" in e&&(bv=e.get(bw,"value"))!==L){return bv}bv=bw.value;return typeof bv==="string"?bv.replace(aU,""):bv==null?"":bv}return}by=b.isFunction(bx);return this.each(function(bA){var bz=b(this),bB;if(this.nodeType!==1){return}if(by){bB=bx.call(this,bA,bz.val())}else{bB=bx}if(bB==null){bB=""}else{if(typeof bB==="number"){bB+=""}else{if(b.isArray(bB)){bB=b.map(bB,function(bC){return bC==null?"":bC+""})}}}e=b.valHooks[this.nodeName.toLowerCase()]||b.valHooks[this.type];if(!e||!("set" in e)||e.set(this,bB,"value")===L){this.value=bB}})}});b.extend({valHooks:{option:{get:function(e){var bv=e.attributes.value;return !bv||bv.specified?e.value:e.text}},select:{get:function(e){var bA,bv,bz,bx,by=e.selectedIndex,bB=[],bC=e.options,bw=e.type==="select-one";if(by<0){return null}bv=bw?by:0;bz=bw?by+1:bC.length;for(;bv<bz;bv++){bx=bC[bv];if(bx.selected&&(b.support.optDisabled?!bx.disabled:bx.getAttribute("disabled")===null)&&(!bx.parentNode.disabled||!b.nodeName(bx.parentNode,"optgroup"))){bA=b(bx).val();if(bw){return bA}bB.push(bA)}}if(bw&&!bB.length&&bC.length){return b(bC[by]).val()}return bB},set:function(bv,bw){var e=b.makeArray(bw);b(bv).find("option").each(function(){this.selected=b.inArray(b(this).val(),e)>=0});if(!e.length){bv.selectedIndex=-1}return e}}},attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(bA,bx,bB,bz){var bw,e,by,bv=bA.nodeType;if(!bA||bv===3||bv===8||bv===2){return}if(bz&&bx in b.attrFn){return b(bA)[bx](bB)}if(typeof bA.getAttribute==="undefined"){return b.prop(bA,bx,bB)}by=bv!==1||!b.isXMLDoc(bA);if(by){bx=bx.toLowerCase();e=b.attrHooks[bx]||(ao.test(bx)?aY:be)}if(bB!==L){if(bB===null){b.removeAttr(bA,bx);return}else{if(e&&"set" in e&&by&&(bw=e.set(bA,bB,bx))!==L){return bw}else{bA.setAttribute(bx,""+bB);return bB}}}else{if(e&&"get" in e&&by&&(bw=e.get(bA,bx))!==null){return bw}else{bw=bA.getAttribute(bx);return bw===null?L:bw}}},removeAttr:function(bx,bz){var by,bA,bv,e,bw=0;if(bz&&bx.nodeType===1){bA=bz.toLowerCase().split(af);e=bA.length;for(;bw<e;bw++){bv=bA[bw];if(bv){by=b.propFix[bv]||bv;b.attr(bx,bv,"");bx.removeAttribute(F?bv:by);if(ao.test(bv)&&by in bx){bx[by]=false}}}}},attrHooks:{type:{set:function(e,bv){if(g.test(e.nodeName)&&e.parentNode){b.error("type property can't be changed")}else{if(!b.support.radioValue&&bv==="radio"&&b.nodeName(e,"input")){var bw=e.value;e.setAttribute("type",bv);if(bw){e.value=bw}return bv}}}},value:{get:function(bv,e){if(be&&b.nodeName(bv,"button")){return be.get(bv,e)}return e in bv?bv.value:null},set:function(bv,bw,e){if(be&&b.nodeName(bv,"button")){return be.set(bv,bw,e)}bv.value=bw}}},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(bz,bx,bA){var bw,e,by,bv=bz.nodeType;if(!bz||bv===3||bv===8||bv===2){return}by=bv!==1||!b.isXMLDoc(bz);if(by){bx=b.propFix[bx]||bx;e=b.propHooks[bx]}if(bA!==L){if(e&&"set" in e&&(bw=e.set(bz,bA,bx))!==L){return bw}else{return(bz[bx]=bA)}}else{if(e&&"get" in e&&(bw=e.get(bz,bx))!==null){return bw}else{return bz[bx]}}},propHooks:{tabIndex:{get:function(bv){var e=bv.getAttributeNode("tabindex");return e&&e.specified?parseInt(e.value,10):D.test(bv.nodeName)||l.test(bv.nodeName)&&bv.href?0:L}}}});b.attrHooks.tabindex=b.propHooks.tabIndex;aY={get:function(bv,e){var bx,bw=b.prop(bv,e);return bw===true||typeof bw!=="boolean"&&(bx=bv.getAttributeNode(e))&&bx.nodeValue!==false?e.toLowerCase():L},set:function(bv,bx,e){var bw;if(bx===false){b.removeAttr(bv,e)}else{bw=b.propFix[e]||e;if(bw in bv){bv[bw]=true}bv.setAttribute(e,e.toLowerCase())}return e}};if(!F){aF={name:true,id:true};be=b.valHooks.button={get:function(bw,bv){var e;e=bw.getAttributeNode(bv);return e&&(aF[bv]?e.nodeValue!=="":e.specified)?e.nodeValue:L},set:function(bw,bx,bv){var e=bw.getAttributeNode(bv);if(!e){e=av.createAttribute(bv);bw.setAttributeNode(e)}return(e.nodeValue=bx+"")}};b.attrHooks.tabindex.set=be.set;b.each(["width","height"],function(bv,e){b.attrHooks[e]=b.extend(b.attrHooks[e],{set:function(bw,bx){if(bx===""){bw.setAttribute(e,"auto");return bx}}})});b.attrHooks.contenteditable={get:be.get,set:function(bv,bw,e){if(bw===""){bw="false"}be.set(bv,bw,e)}}}if(!b.support.hrefNormalized){b.each(["href","src","width","height"],function(bv,e){b.attrHooks[e]=b.extend(b.attrHooks[e],{get:function(bx){var bw=bx.getAttribute(e,2);return bw===null?L:bw}})})}if(!b.support.style){b.attrHooks.style={get:function(e){return e.style.cssText.toLowerCase()||L},set:function(e,bv){return(e.style.cssText=""+bv)}}}if(!b.support.optSelected){b.propHooks.selected=b.extend(b.propHooks.selected,{get:function(bv){var e=bv.parentNode;if(e){e.selectedIndex;if(e.parentNode){e.parentNode.selectedIndex}}return null}})}if(!b.support.enctype){b.propFix.enctype="encoding"}if(!b.support.checkOn){b.each(["radio","checkbox"],function(){b.valHooks[this]={get:function(e){return e.getAttribute("value")===null?"on":e.value}}})}b.each(["radio","checkbox"],function(){b.valHooks[this]=b.extend(b.valHooks[this],{set:function(e,bv){if(b.isArray(bv)){return(e.checked=b.inArray(b(e).val(),bv)>=0)}}})});var bd=/^(?:textarea|input|select)$/i,n=/^([^\.]*)?(?:\.(.+))?$/,J=/\bhover(\.\S+)?\b/,aO=/^key/,bf=/^(?:mouse|contextmenu)|click/,T=/^(?:focusinfocus|focusoutblur)$/,U=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,Y=function(e){var bv=U.exec(e);if(bv){bv[1]=(bv[1]||"").toLowerCase();bv[3]=bv[3]&&new RegExp("(?:^|\\s)"+bv[3]+"(?:\\s|$)")}return bv},j=function(bw,e){var bv=bw.attributes||{};return((!e[1]||bw.nodeName.toLowerCase()===e[1])&&(!e[2]||(bv.id||{}).value===e[2])&&(!e[3]||e[3].test((bv["class"]||{}).value)))},bt=function(e){return b.event.special.hover?e:e.replace(J,"mouseenter$1 mouseleave$1")};b.event={add:function(bx,bC,bJ,bA,by){var bD,bB,bK,bI,bH,bF,e,bG,bv,bz,bw,bE;if(bx.nodeType===3||bx.nodeType===8||!bC||!bJ||!(bD=b._data(bx))){return}if(bJ.handler){bv=bJ;bJ=bv.handler}if(!bJ.guid){bJ.guid=b.guid++}bK=bD.events;if(!bK){bD.events=bK={}}bB=bD.handle;if(!bB){bD.handle=bB=function(bL){return typeof b!=="undefined"&&(!bL||b.event.triggered!==bL.type)?b.event.dispatch.apply(bB.elem,arguments):L};bB.elem=bx}bC=b.trim(bt(bC)).split(" ");for(bI=0;bI<bC.length;bI++){bH=n.exec(bC[bI])||[];bF=bH[1];e=(bH[2]||"").split(".").sort();bE=b.event.special[bF]||{};bF=(by?bE.delegateType:bE.bindType)||bF;bE=b.event.special[bF]||{};bG=b.extend({type:bF,origType:bH[1],data:bA,handler:bJ,guid:bJ.guid,selector:by,quick:Y(by),namespace:e.join(".")},bv);bw=bK[bF];if(!bw){bw=bK[bF]=[];bw.delegateCount=0;if(!bE.setup||bE.setup.call(bx,bA,e,bB)===false){if(bx.addEventListener){bx.addEventListener(bF,bB,false)}else{if(bx.attachEvent){bx.attachEvent("on"+bF,bB)}}}}if(bE.add){bE.add.call(bx,bG);if(!bG.handler.guid){bG.handler.guid=bJ.guid}}if(by){bw.splice(bw.delegateCount++,0,bG)}else{bw.push(bG)}b.event.global[bF]=true}bx=null},global:{},remove:function(bJ,bE,bv,bH,bB){var bI=b.hasData(bJ)&&b._data(bJ),bF,bx,bz,bL,bC,bA,bG,bw,by,bK,bD,e;if(!bI||!(bw=bI.events)){return}bE=b.trim(bt(bE||"")).split(" ");for(bF=0;bF<bE.length;bF++){bx=n.exec(bE[bF])||[];bz=bL=bx[1];bC=bx[2];if(!bz){for(bz in bw){b.event.remove(bJ,bz+bE[bF],bv,bH,true)}continue}by=b.event.special[bz]||{};bz=(bH?by.delegateType:by.bindType)||bz;bD=bw[bz]||[];bA=bD.length;bC=bC?new RegExp("(^|\\.)"+bC.split(".").sort().join("\\.(?:.*\\.)?")+"(\\.|$)"):null;for(bG=0;bG<bD.length;bG++){e=bD[bG];if((bB||bL===e.origType)&&(!bv||bv.guid===e.guid)&&(!bC||bC.test(e.namespace))&&(!bH||bH===e.selector||bH==="**"&&e.selector)){bD.splice(bG--,1);if(e.selector){bD.delegateCount--}if(by.remove){by.remove.call(bJ,e)}}}if(bD.length===0&&bA!==bD.length){if(!by.teardown||by.teardown.call(bJ,bC)===false){b.removeEvent(bJ,bz,bI.handle)}delete bw[bz]}}if(b.isEmptyObject(bw)){bK=bI.handle;if(bK){bK.elem=null}b.removeData(bJ,["events","handle"],true)}},customEvent:{getData:true,setData:true,changeData:true},trigger:function(bv,bD,bA,bJ){if(bA&&(bA.nodeType===3||bA.nodeType===8)){return}var bG=bv.type||bv,bx=[],e,bw,bC,bH,bz,by,bF,bE,bB,bI;if(T.test(bG+b.event.triggered)){return}if(bG.indexOf("!")>=0){bG=bG.slice(0,-1);bw=true}if(bG.indexOf(".")>=0){bx=bG.split(".");bG=bx.shift();bx.sort()}if((!bA||b.event.customEvent[bG])&&!b.event.global[bG]){return}bv=typeof bv==="object"?bv[b.expando]?bv:new b.Event(bG,bv):new b.Event(bG);bv.type=bG;bv.isTrigger=true;bv.exclusive=bw;bv.namespace=bx.join(".");bv.namespace_re=bv.namespace?new RegExp("(^|\\.)"+bx.join("\\.(?:.*\\.)?")+"(\\.|$)"):null;by=bG.indexOf(":")<0?"on"+bG:"";if(!bA){e=b.cache;for(bC in e){if(e[bC].events&&e[bC].events[bG]){b.event.trigger(bv,bD,e[bC].handle.elem,true)}}return}bv.result=L;if(!bv.target){bv.target=bA}bD=bD!=null?b.makeArray(bD):[];bD.unshift(bv);bF=b.event.special[bG]||{};if(bF.trigger&&bF.trigger.apply(bA,bD)===false){return}bB=[[bA,bF.bindType||bG]];if(!bJ&&!bF.noBubble&&!b.isWindow(bA)){bI=bF.delegateType||bG;bH=T.test(bI+bG)?bA:bA.parentNode;bz=null;for(;bH;bH=bH.parentNode){bB.push([bH,bI]);bz=bH}if(bz&&bz===bA.ownerDocument){bB.push([bz.defaultView||bz.parentWindow||bb,bI])}}for(bC=0;bC<bB.length&&!bv.isPropagationStopped();bC++){bH=bB[bC][0];bv.type=bB[bC][1];bE=(b._data(bH,"events")||{})[bv.type]&&b._data(bH,"handle");if(bE){bE.apply(bH,bD)}bE=by&&bH[by];if(bE&&b.acceptData(bH)&&bE.apply(bH,bD)===false){bv.preventDefault()}}bv.type=bG;if(!bJ&&!bv.isDefaultPrevented()){if((!bF._default||bF._default.apply(bA.ownerDocument,bD)===false)&&!(bG==="click"&&b.nodeName(bA,"a"))&&b.acceptData(bA)){if(by&&bA[bG]&&((bG!=="focus"&&bG!=="blur")||bv.target.offsetWidth!==0)&&!b.isWindow(bA)){bz=bA[by];if(bz){bA[by]=null}b.event.triggered=bG;bA[bG]();b.event.triggered=L;if(bz){bA[by]=bz}}}}return bv.result},dispatch:function(e){e=b.event.fix(e||bb.event);var bz=((b._data(this,"events")||{})[e.type]||[]),bA=bz.delegateCount,bG=[].slice.call(arguments,0),by=!e.exclusive&&!e.namespace,bH=[],bC,bB,bK,bx,bF,bE,bv,bD,bI,bw,bJ;bG[0]=e;e.delegateTarget=this;if(bA&&!e.target.disabled&&!(e.button&&e.type==="click")){bx=b(this);bx.context=this.ownerDocument||this;for(bK=e.target;bK!=this;bK=bK.parentNode||this){bE={};bD=[];bx[0]=bK;for(bC=0;bC<bA;bC++){bI=bz[bC];bw=bI.selector;if(bE[bw]===L){bE[bw]=(bI.quick?j(bK,bI.quick):bx.is(bw))}if(bE[bw]){bD.push(bI)}}if(bD.length){bH.push({elem:bK,matches:bD})}}}if(bz.length>bA){bH.push({elem:this,matches:bz.slice(bA)})}for(bC=0;bC<bH.length&&!e.isPropagationStopped();bC++){bv=bH[bC];e.currentTarget=bv.elem;for(bB=0;bB<bv.matches.length&&!e.isImmediatePropagationStopped();bB++){bI=bv.matches[bB];if(by||(!e.namespace&&!bI.namespace)||e.namespace_re&&e.namespace_re.test(bI.namespace)){e.data=bI.data;e.handleObj=bI;bF=((b.event.special[bI.origType]||{}).handle||bI.handler).apply(bv.elem,bG);if(bF!==L){e.result=bF;if(bF===false){e.preventDefault();e.stopPropagation()}}}}}return e.result},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(bv,e){if(bv.which==null){bv.which=e.charCode!=null?e.charCode:e.keyCode}return bv}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(bx,bw){var by,bz,e,bv=bw.button,bA=bw.fromElement;if(bx.pageX==null&&bw.clientX!=null){by=bx.target.ownerDocument||av;bz=by.documentElement;e=by.body;bx.pageX=bw.clientX+(bz&&bz.scrollLeft||e&&e.scrollLeft||0)-(bz&&bz.clientLeft||e&&e.clientLeft||0);bx.pageY=bw.clientY+(bz&&bz.scrollTop||e&&e.scrollTop||0)-(bz&&bz.clientTop||e&&e.clientTop||0)}if(!bx.relatedTarget&&bA){bx.relatedTarget=bA===bx.target?bw.toElement:bA}if(!bx.which&&bv!==L){bx.which=(bv&1?1:(bv&2?3:(bv&4?2:0)))}return bx}},fix:function(bw){if(bw[b.expando]){return bw}var bv,bz,e=bw,bx=b.event.fixHooks[bw.type]||{},by=bx.props?this.props.concat(bx.props):this.props;bw=b.Event(e);for(bv=by.length;bv;){bz=by[--bv];bw[bz]=e[bz]}if(!bw.target){bw.target=e.srcElement||av}if(bw.target.nodeType===3){bw.target=bw.target.parentNode}if(bw.metaKey===L){bw.metaKey=bw.ctrlKey}return bx.filter?bx.filter(bw,e):bw},special:{ready:{setup:b.bindReady},load:{noBubble:true},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(bw,bv,e){if(b.isWindow(this)){this.onbeforeunload=e}},teardown:function(bv,e){if(this.onbeforeunload===e){this.onbeforeunload=null}}}},simulate:function(bw,by,bx,bv){var bz=b.extend(new b.Event(),bx,{type:bw,isSimulated:true,originalEvent:{}});if(bv){b.event.trigger(bz,null,by)}else{b.event.dispatch.call(by,bz)}if(bz.isDefaultPrevented()){bx.preventDefault()}}};b.event.handle=b.event.dispatch;b.removeEvent=av.removeEventListener?function(bv,e,bw){if(bv.removeEventListener){bv.removeEventListener(e,bw,false)}}:function(bv,e,bw){if(bv.detachEvent){bv.detachEvent("on"+e,bw)}};b.Event=function(bv,e){if(!(this instanceof b.Event)){return new b.Event(bv,e)}if(bv&&bv.type){this.originalEvent=bv;this.type=bv.type;this.isDefaultPrevented=(bv.defaultPrevented||bv.returnValue===false||bv.getPreventDefault&&bv.getPreventDefault())?i:bk}else{this.type=bv}if(e){b.extend(this,e)}this.timeStamp=bv&&bv.timeStamp||b.now();this[b.expando]=true};function bk(){return false}function i(){return true}b.Event.prototype={preventDefault:function(){this.isDefaultPrevented=i;var bv=this.originalEvent;if(!bv){return}if(bv.preventDefault){bv.preventDefault()}else{bv.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=i;var bv=this.originalEvent;if(!bv){return}if(bv.stopPropagation){bv.stopPropagation()}bv.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=i;this.stopPropagation()},isDefaultPrevented:bk,isPropagationStopped:bk,isImmediatePropagationStopped:bk};b.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(bv,e){b.event.special[bv]={delegateType:e,bindType:e,handle:function(bz){var bB=this,bA=bz.relatedTarget,by=bz.handleObj,bw=by.selector,bx;if(!bA||(bA!==bB&&!b.contains(bB,bA))){bz.type=by.origType;bx=by.handler.apply(this,arguments);bz.type=e}return bx}}});if(!b.support.submitBubbles){b.event.special.submit={setup:function(){if(b.nodeName(this,"form")){return false}b.event.add(this,"click._submit keypress._submit",function(bx){var bw=bx.target,bv=b.nodeName(bw,"input")||b.nodeName(bw,"button")?bw.form:L;if(bv&&!bv._submit_attached){b.event.add(bv,"submit._submit",function(e){if(this.parentNode&&!e.isTrigger){b.event.simulate("submit",this.parentNode,e,true)}});bv._submit_attached=true}})},teardown:function(){if(b.nodeName(this,"form")){return false}b.event.remove(this,"._submit")}}}if(!b.support.changeBubbles){b.event.special.change={setup:function(){if(bd.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio"){b.event.add(this,"propertychange._change",function(e){if(e.originalEvent.propertyName==="checked"){this._just_changed=true}});b.event.add(this,"click._change",function(e){if(this._just_changed&&!e.isTrigger){this._just_changed=false;b.event.simulate("change",this,e,true)}})}return false}b.event.add(this,"beforeactivate._change",function(bw){var bv=bw.target;if(bd.test(bv.nodeName)&&!bv._change_attached){b.event.add(bv,"change._change",function(e){if(this.parentNode&&!e.isSimulated&&!e.isTrigger){b.event.simulate("change",this.parentNode,e,true)}});bv._change_attached=true}})},handle:function(bv){var e=bv.target;if(this!==e||bv.isSimulated||bv.isTrigger||(e.type!=="radio"&&e.type!=="checkbox")){return bv.handleObj.handler.apply(this,arguments)}},teardown:function(){b.event.remove(this,"._change");return bd.test(this.nodeName)}}}if(!b.support.focusinBubbles){b.each({focus:"focusin",blur:"focusout"},function(bx,e){var bv=0,bw=function(by){b.event.simulate(e,by.target,b.event.fix(by),true)};b.event.special[e]={setup:function(){if(bv++===0){av.addEventListener(bx,bw,true)}},teardown:function(){if(--bv===0){av.removeEventListener(bx,bw,true)}}}})}b.fn.extend({on:function(bw,e,bz,by,bv){var bA,bx;if(typeof bw==="object"){if(typeof e!=="string"){bz=e;e=L}for(bx in bw){this.on(bx,e,bz,bw[bx],bv)}return this}if(bz==null&&by==null){by=e;bz=e=L}else{if(by==null){if(typeof e==="string"){by=bz;bz=L}else{by=bz;bz=e;e=L}}}if(by===false){by=bk}else{if(!by){return this}}if(bv===1){bA=by;by=function(bB){b().off(bB);return bA.apply(this,arguments)};by.guid=bA.guid||(bA.guid=b.guid++)}return this.each(function(){b.event.add(this,bw,by,bz,e)})},one:function(bv,e,bx,bw){return this.on.call(this,bv,e,bx,bw,1)},off:function(bw,e,by){if(bw&&bw.preventDefault&&bw.handleObj){var bv=bw.handleObj;b(bw.delegateTarget).off(bv.namespace?bv.type+"."+bv.namespace:bv.type,bv.selector,bv.handler);return this}if(typeof bw==="object"){for(var bx in bw){this.off(bx,e,bw[bx])}return this}if(e===false||typeof e==="function"){by=e;e=L}if(by===false){by=bk}return this.each(function(){b.event.remove(this,bw,by,e)})},bind:function(e,bw,bv){return this.on(e,null,bw,bv)},unbind:function(e,bv){return this.off(e,null,bv)},live:function(e,bw,bv){b(this.context).on(e,this.selector,bw,bv);return this},die:function(e,bv){b(this.context).off(e,this.selector||"**",bv);return this},delegate:function(e,bv,bx,bw){return this.on(bv,e,bx,bw)},undelegate:function(e,bv,bw){return arguments.length==1?this.off(e,"**"):this.off(bv,e,bw)},trigger:function(e,bv){return this.each(function(){b.event.trigger(e,bv,this)})},triggerHandler:function(e,bv){if(this[0]){return b.event.trigger(e,bv,this[0],true)}},toggle:function(bx){var bv=arguments,e=bx.guid||b.guid++,bw=0,by=function(bz){var bA=(b._data(this,"lastToggle"+bx.guid)||0)%bw;b._data(this,"lastToggle"+bx.guid,bA+1);bz.preventDefault();return bv[bA].apply(this,arguments)||false};by.guid=e;while(bw<bv.length){bv[bw++].guid=e}return this.click(by)},hover:function(e,bv){return this.mouseenter(e).mouseleave(bv||e)}});b.each(("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu").split(" "),function(bv,e){b.fn[e]=function(bx,bw){if(bw==null){bw=bx;bx=null}return arguments.length>0?this.on(e,null,bx,bw):this.trigger(e)};if(b.attrFn){b.attrFn[e]=true}if(aO.test(e)){b.event.fixHooks[e]=b.event.keyHooks}if(bf.test(e)){b.event.fixHooks[e]=b.event.mouseHooks}});
(function(){var bH=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,bC="sizcache"+(Math.random()+"").replace(".",""),bI=0,bL=Object.prototype.toString,bB=false,bA=true,bK=/\\/g,bO=/\r\n/g,bQ=/\W/;[0,0].sort(function(){bA=false;return 0});var by=function(bV,e,bY,bZ){bY=bY||[];e=e||av;var b1=e;if(e.nodeType!==1&&e.nodeType!==9){return[]}if(!bV||typeof bV!=="string"){return bY}var bS,b3,b6,bR,b2,b5,b4,bX,bU=true,bT=by.isXML(e),bW=[],b0=bV;do{bH.exec("");bS=bH.exec(b0);if(bS){b0=bS[3];bW.push(bS[1]);if(bS[2]){bR=bS[3];break}}}while(bS);if(bW.length>1&&bD.exec(bV)){if(bW.length===2&&bE.relative[bW[0]]){b3=bM(bW[0]+bW[1],e,bZ)}else{b3=bE.relative[bW[0]]?[e]:by(bW.shift(),e);while(bW.length){bV=bW.shift();if(bE.relative[bV]){bV+=bW.shift()}b3=bM(bV,b3,bZ)}}}else{if(!bZ&&bW.length>1&&e.nodeType===9&&!bT&&bE.match.ID.test(bW[0])&&!bE.match.ID.test(bW[bW.length-1])){b2=by.find(bW.shift(),e,bT);e=b2.expr?by.filter(b2.expr,b2.set)[0]:b2.set[0]}if(e){b2=bZ?{expr:bW.pop(),set:bF(bZ)}:by.find(bW.pop(),bW.length===1&&(bW[0]==="~"||bW[0]==="+")&&e.parentNode?e.parentNode:e,bT);b3=b2.expr?by.filter(b2.expr,b2.set):b2.set;if(bW.length>0){b6=bF(b3)}else{bU=false}while(bW.length){b5=bW.pop();b4=b5;if(!bE.relative[b5]){b5=""}else{b4=bW.pop()}if(b4==null){b4=e}bE.relative[b5](b6,b4,bT)}}else{b6=bW=[]}}if(!b6){b6=b3}if(!b6){by.error(b5||bV)}if(bL.call(b6)==="[object Array]"){if(!bU){bY.push.apply(bY,b6)}else{if(e&&e.nodeType===1){for(bX=0;b6[bX]!=null;bX++){if(b6[bX]&&(b6[bX]===true||b6[bX].nodeType===1&&by.contains(e,b6[bX]))){bY.push(b3[bX])}}}else{for(bX=0;b6[bX]!=null;bX++){if(b6[bX]&&b6[bX].nodeType===1){bY.push(b3[bX])}}}}}else{bF(b6,bY)}if(bR){by(bR,b1,bY,bZ);by.uniqueSort(bY)}return bY};by.uniqueSort=function(bR){if(bJ){bB=bA;bR.sort(bJ);if(bB){for(var e=1;e<bR.length;e++){if(bR[e]===bR[e-1]){bR.splice(e--,1)}}}}return bR};by.matches=function(e,bR){return by(e,null,null,bR)};by.matchesSelector=function(e,bR){return by(bR,null,null,[e]).length>0};by.find=function(bX,e,bY){var bW,bS,bU,bT,bV,bR;if(!bX){return[]}for(bS=0,bU=bE.order.length;bS<bU;bS++){bV=bE.order[bS];if((bT=bE.leftMatch[bV].exec(bX))){bR=bT[1];bT.splice(1,1);if(bR.substr(bR.length-1)!=="\\"){bT[1]=(bT[1]||"").replace(bK,"");bW=bE.find[bV](bT,e,bY);if(bW!=null){bX=bX.replace(bE.match[bV],"");break}}}}if(!bW){bW=typeof e.getElementsByTagName!=="undefined"?e.getElementsByTagName("*"):[]}return{set:bW,expr:bX}};by.filter=function(b1,b0,b4,bU){var bW,e,bZ,b6,b3,bR,bT,bV,b2,bS=b1,b5=[],bY=b0,bX=b0&&b0[0]&&by.isXML(b0[0]);while(b1&&b0.length){for(bZ in bE.filter){if((bW=bE.leftMatch[bZ].exec(b1))!=null&&bW[2]){bR=bE.filter[bZ];bT=bW[1];e=false;bW.splice(1,1);if(bT.substr(bT.length-1)==="\\"){continue}if(bY===b5){b5=[]}if(bE.preFilter[bZ]){bW=bE.preFilter[bZ](bW,bY,b4,b5,bU,bX);if(!bW){e=b6=true}else{if(bW===true){continue}}}if(bW){for(bV=0;(b3=bY[bV])!=null;bV++){if(b3){b6=bR(b3,bW,bV,bY);b2=bU^b6;if(b4&&b6!=null){if(b2){e=true}else{bY[bV]=false}}else{if(b2){b5.push(b3);e=true}}}}}if(b6!==L){if(!b4){bY=b5}b1=b1.replace(bE.match[bZ],"");if(!e){return[]}break}}}if(b1===bS){if(e==null){by.error(b1)}else{break}}bS=b1}return bY};by.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)};var bw=by.getText=function(bU){var bS,bT,e=bU.nodeType,bR="";if(e){if(e===1||e===9){if(typeof bU.textContent==="string"){return bU.textContent}else{if(typeof bU.innerText==="string"){return bU.innerText.replace(bO,"")}else{for(bU=bU.firstChild;bU;bU=bU.nextSibling){bR+=bw(bU)}}}}else{if(e===3||e===4){return bU.nodeValue}}}else{for(bS=0;(bT=bU[bS]);bS++){if(bT.nodeType!==8){bR+=bw(bT)}}}return bR};var bE=by.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(e){return e.getAttribute("href")},type:function(e){return e.getAttribute("type")}},relative:{"+":function(bW,bR){var bT=typeof bR==="string",bV=bT&&!bQ.test(bR),bX=bT&&!bV;if(bV){bR=bR.toLowerCase()}for(var bS=0,e=bW.length,bU;bS<e;bS++){if((bU=bW[bS])){while((bU=bU.previousSibling)&&bU.nodeType!==1){}bW[bS]=bX||bU&&bU.nodeName.toLowerCase()===bR?bU||false:bU===bR}}if(bX){by.filter(bR,bW,true)}},">":function(bW,bR){var bV,bU=typeof bR==="string",bS=0,e=bW.length;if(bU&&!bQ.test(bR)){bR=bR.toLowerCase();for(;bS<e;bS++){bV=bW[bS];if(bV){var bT=bV.parentNode;bW[bS]=bT.nodeName.toLowerCase()===bR?bT:false}}}else{for(;bS<e;bS++){bV=bW[bS];if(bV){bW[bS]=bU?bV.parentNode:bV.parentNode===bR}}if(bU){by.filter(bR,bW,true)}}},"":function(bT,bR,bV){var bU,bS=bI++,e=bN;if(typeof bR==="string"&&!bQ.test(bR)){bR=bR.toLowerCase();bU=bR;e=bv}e("parentNode",bR,bS,bT,bU,bV)},"~":function(bT,bR,bV){var bU,bS=bI++,e=bN;if(typeof bR==="string"&&!bQ.test(bR)){bR=bR.toLowerCase();bU=bR;e=bv}e("previousSibling",bR,bS,bT,bU,bV)}},find:{ID:function(bR,bS,bT){if(typeof bS.getElementById!=="undefined"&&!bT){var e=bS.getElementById(bR[1]);return e&&e.parentNode?[e]:[]}},NAME:function(bS,bV){if(typeof bV.getElementsByName!=="undefined"){var bR=[],bU=bV.getElementsByName(bS[1]);for(var bT=0,e=bU.length;bT<e;bT++){if(bU[bT].getAttribute("name")===bS[1]){bR.push(bU[bT])}}return bR.length===0?null:bR}},TAG:function(e,bR){if(typeof bR.getElementsByTagName!=="undefined"){return bR.getElementsByTagName(e[1])}}},preFilter:{CLASS:function(bT,bR,bS,e,bW,bX){bT=" "+bT[1].replace(bK,"")+" ";if(bX){return bT}for(var bU=0,bV;(bV=bR[bU])!=null;bU++){if(bV){if(bW^(bV.className&&(" "+bV.className+" ").replace(/[\t\n\r]/g," ").indexOf(bT)>=0)){if(!bS){e.push(bV)}}else{if(bS){bR[bU]=false}}}}return false},ID:function(e){return e[1].replace(bK,"")},TAG:function(bR,e){return bR[1].replace(bK,"").toLowerCase()},CHILD:function(e){if(e[1]==="nth"){if(!e[2]){by.error(e[0])}e[2]=e[2].replace(/^\+|\s*/g,"");var bR=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(e[2]==="even"&&"2n"||e[2]==="odd"&&"2n+1"||!/\D/.test(e[2])&&"0n+"+e[2]||e[2]);e[2]=(bR[1]+(bR[2]||1))-0;e[3]=bR[3]-0}else{if(e[2]){by.error(e[0])}}e[0]=bI++;return e},ATTR:function(bU,bR,bS,e,bV,bW){var bT=bU[1]=bU[1].replace(bK,"");if(!bW&&bE.attrMap[bT]){bU[1]=bE.attrMap[bT]}bU[4]=(bU[4]||bU[5]||"").replace(bK,"");if(bU[2]==="~="){bU[4]=" "+bU[4]+" "}return bU},PSEUDO:function(bU,bR,bS,e,bV){if(bU[1]==="not"){if((bH.exec(bU[3])||"").length>1||/^\w/.test(bU[3])){bU[3]=by(bU[3],null,null,bR)}else{var bT=by.filter(bU[3],bR,bS,true^bV);if(!bS){e.push.apply(e,bT)}return false}}else{if(bE.match.POS.test(bU[0])||bE.match.CHILD.test(bU[0])){return true}}return bU},POS:function(e){e.unshift(true);return e}},filters:{enabled:function(e){return e.disabled===false&&e.type!=="hidden"},disabled:function(e){return e.disabled===true},checked:function(e){return e.checked===true},selected:function(e){if(e.parentNode){e.parentNode.selectedIndex}return e.selected===true},parent:function(e){return !!e.firstChild},empty:function(e){return !e.firstChild},has:function(bS,bR,e){return !!by(e[3],bS).length},header:function(e){return(/h\d/i).test(e.nodeName)},text:function(bS){var e=bS.getAttribute("type"),bR=bS.type;return bS.nodeName.toLowerCase()==="input"&&"text"===bR&&(e===bR||e===null)},radio:function(e){return e.nodeName.toLowerCase()==="input"&&"radio"===e.type},checkbox:function(e){return e.nodeName.toLowerCase()==="input"&&"checkbox"===e.type},file:function(e){return e.nodeName.toLowerCase()==="input"&&"file"===e.type},password:function(e){return e.nodeName.toLowerCase()==="input"&&"password"===e.type},submit:function(bR){var e=bR.nodeName.toLowerCase();return(e==="input"||e==="button")&&"submit"===bR.type},image:function(e){return e.nodeName.toLowerCase()==="input"&&"image"===e.type},reset:function(bR){var e=bR.nodeName.toLowerCase();return(e==="input"||e==="button")&&"reset"===bR.type},button:function(bR){var e=bR.nodeName.toLowerCase();return e==="input"&&"button"===bR.type||e==="button"},input:function(e){return(/input|select|textarea|button/i).test(e.nodeName)},focus:function(e){return e===e.ownerDocument.activeElement}},setFilters:{first:function(bR,e){return e===0},last:function(bS,bR,e,bT){return bR===bT.length-1},even:function(bR,e){return e%2===0},odd:function(bR,e){return e%2===1},lt:function(bS,bR,e){return bR<e[3]-0},gt:function(bS,bR,e){return bR>e[3]-0},nth:function(bS,bR,e){return e[3]-0===bR},eq:function(bS,bR,e){return e[3]-0===bR}},filter:{PSEUDO:function(bS,bX,bW,bY){var e=bX[1],bR=bE.filters[e];if(bR){return bR(bS,bW,bX,bY)}else{if(e==="contains"){return(bS.textContent||bS.innerText||bw([bS])||"").indexOf(bX[3])>=0}else{if(e==="not"){var bT=bX[3];for(var bV=0,bU=bT.length;bV<bU;bV++){if(bT[bV]===bS){return false}}return true}else{by.error(e)}}}},CHILD:function(bS,bU){var bT,b0,bW,bZ,e,bV,bY,bX=bU[1],bR=bS;switch(bX){case"only":case"first":while((bR=bR.previousSibling)){if(bR.nodeType===1){return false}}if(bX==="first"){return true}bR=bS;case"last":while((bR=bR.nextSibling)){if(bR.nodeType===1){return false}}return true;case"nth":bT=bU[2];b0=bU[3];if(bT===1&&b0===0){return true}bW=bU[0];bZ=bS.parentNode;if(bZ&&(bZ[bC]!==bW||!bS.nodeIndex)){bV=0;for(bR=bZ.firstChild;bR;bR=bR.nextSibling){if(bR.nodeType===1){bR.nodeIndex=++bV}}bZ[bC]=bW}bY=bS.nodeIndex-b0;if(bT===0){return bY===0}else{return(bY%bT===0&&bY/bT>=0)}}},ID:function(bR,e){return bR.nodeType===1&&bR.getAttribute("id")===e},TAG:function(bR,e){return(e==="*"&&bR.nodeType===1)||!!bR.nodeName&&bR.nodeName.toLowerCase()===e},CLASS:function(bR,e){return(" "+(bR.className||bR.getAttribute("class"))+" ").indexOf(e)>-1},ATTR:function(bV,bT){var bS=bT[1],e=by.attr?by.attr(bV,bS):bE.attrHandle[bS]?bE.attrHandle[bS](bV):bV[bS]!=null?bV[bS]:bV.getAttribute(bS),bW=e+"",bU=bT[2],bR=bT[4];return e==null?bU==="!=":!bU&&by.attr?e!=null:bU==="="?bW===bR:bU==="*="?bW.indexOf(bR)>=0:bU==="~="?(" "+bW+" ").indexOf(bR)>=0:!bR?bW&&e!==false:bU==="!="?bW!==bR:bU==="^="?bW.indexOf(bR)===0:bU==="$="?bW.substr(bW.length-bR.length)===bR:bU==="|="?bW===bR||bW.substr(0,bR.length+1)===bR+"-":false},POS:function(bU,bR,bS,bV){var e=bR[2],bT=bE.setFilters[e];if(bT){return bT(bU,bS,bR,bV)}}}};var bD=bE.match.POS,bx=function(bR,e){return"\\"+(e-0+1)};for(var bz in bE.match){bE.match[bz]=new RegExp(bE.match[bz].source+(/(?![^\[]*\])(?![^\(]*\))/.source));bE.leftMatch[bz]=new RegExp(/(^(?:.|\r|\n)*?)/.source+bE.match[bz].source.replace(/\\(\d+)/g,bx))}var bF=function(bR,e){bR=Array.prototype.slice.call(bR,0);if(e){e.push.apply(e,bR);return e}return bR};try{Array.prototype.slice.call(av.documentElement.childNodes,0)[0].nodeType}catch(bP){bF=function(bU,bT){var bS=0,bR=bT||[];if(bL.call(bU)==="[object Array]"){Array.prototype.push.apply(bR,bU)}else{if(typeof bU.length==="number"){for(var e=bU.length;bS<e;bS++){bR.push(bU[bS])}}else{for(;bU[bS];bS++){bR.push(bU[bS])}}}return bR}}var bJ,bG;if(av.documentElement.compareDocumentPosition){bJ=function(bR,e){if(bR===e){bB=true;return 0}if(!bR.compareDocumentPosition||!e.compareDocumentPosition){return bR.compareDocumentPosition?-1:1}return bR.compareDocumentPosition(e)&4?-1:1}}else{bJ=function(bY,bX){if(bY===bX){bB=true;return 0}else{if(bY.sourceIndex&&bX.sourceIndex){return bY.sourceIndex-bX.sourceIndex}}var bV,bR,bS=[],e=[],bU=bY.parentNode,bW=bX.parentNode,bZ=bU;if(bU===bW){return bG(bY,bX)}else{if(!bU){return -1}else{if(!bW){return 1}}}while(bZ){bS.unshift(bZ);bZ=bZ.parentNode}bZ=bW;while(bZ){e.unshift(bZ);bZ=bZ.parentNode}bV=bS.length;bR=e.length;for(var bT=0;bT<bV&&bT<bR;bT++){if(bS[bT]!==e[bT]){return bG(bS[bT],e[bT])}}return bT===bV?bG(bY,e[bT],-1):bG(bS[bT],bX,1)};bG=function(bR,e,bS){if(bR===e){return bS}var bT=bR.nextSibling;while(bT){if(bT===e){return -1}bT=bT.nextSibling}return 1}}(function(){var bR=av.createElement("div"),bS="script"+(new Date()).getTime(),e=av.documentElement;bR.innerHTML="<a name='"+bS+"'/>";e.insertBefore(bR,e.firstChild);if(av.getElementById(bS)){bE.find.ID=function(bU,bV,bW){if(typeof bV.getElementById!=="undefined"&&!bW){var bT=bV.getElementById(bU[1]);return bT?bT.id===bU[1]||typeof bT.getAttributeNode!=="undefined"&&bT.getAttributeNode("id").nodeValue===bU[1]?[bT]:L:[]}};bE.filter.ID=function(bV,bT){var bU=typeof bV.getAttributeNode!=="undefined"&&bV.getAttributeNode("id");return bV.nodeType===1&&bU&&bU.nodeValue===bT}}e.removeChild(bR);e=bR=null})();(function(){var e=av.createElement("div");e.appendChild(av.createComment(""));if(e.getElementsByTagName("*").length>0){bE.find.TAG=function(bR,bV){var bU=bV.getElementsByTagName(bR[1]);if(bR[1]==="*"){var bT=[];for(var bS=0;bU[bS];bS++){if(bU[bS].nodeType===1){bT.push(bU[bS])}}bU=bT}return bU}}e.innerHTML="<a href='#'></a>";if(e.firstChild&&typeof e.firstChild.getAttribute!=="undefined"&&e.firstChild.getAttribute("href")!=="#"){bE.attrHandle.href=function(bR){return bR.getAttribute("href",2)}}e=null})();if(av.querySelectorAll){(function(){var e=by,bT=av.createElement("div"),bS="__sizzle__";bT.innerHTML="<p class='TEST'></p>";if(bT.querySelectorAll&&bT.querySelectorAll(".TEST").length===0){return}by=function(b4,bV,bZ,b3){bV=bV||av;if(!b3&&!by.isXML(bV)){var b2=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b4);if(b2&&(bV.nodeType===1||bV.nodeType===9)){if(b2[1]){return bF(bV.getElementsByTagName(b4),bZ)}else{if(b2[2]&&bE.find.CLASS&&bV.getElementsByClassName){return bF(bV.getElementsByClassName(b2[2]),bZ)}}}if(bV.nodeType===9){if(b4==="body"&&bV.body){return bF([bV.body],bZ)}else{if(b2&&b2[3]){var bY=bV.getElementById(b2[3]);if(bY&&bY.parentNode){if(bY.id===b2[3]){return bF([bY],bZ)}}else{return bF([],bZ)}}}try{return bF(bV.querySelectorAll(b4),bZ)}catch(b0){}}else{if(bV.nodeType===1&&bV.nodeName.toLowerCase()!=="object"){var bW=bV,bX=bV.getAttribute("id"),bU=bX||bS,b6=bV.parentNode,b5=/^\s*[+~]/.test(b4);if(!bX){bV.setAttribute("id",bU)}else{bU=bU.replace(/'/g,"\\$&")}if(b5&&b6){bV=bV.parentNode}try{if(!b5||b6){return bF(bV.querySelectorAll("[id='"+bU+"'] "+b4),bZ)}}catch(b1){}finally{if(!bX){bW.removeAttribute("id")}}}}}return e(b4,bV,bZ,b3)};for(var bR in e){by[bR]=e[bR]}bT=null})()}(function(){var e=av.documentElement,bS=e.matchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.msMatchesSelector;if(bS){var bU=!bS.call(av.createElement("div"),"div"),bR=false;try{bS.call(av.documentElement,"[test!='']:sizzle")}catch(bT){bR=true}by.matchesSelector=function(bW,bY){bY=bY.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!by.isXML(bW)){try{if(bR||!bE.match.PSEUDO.test(bY)&&!/!=/.test(bY)){var bV=bS.call(bW,bY);if(bV||!bU||bW.document&&bW.document.nodeType!==11){return bV}}}catch(bX){}}return by(bY,null,null,[bW]).length>0}}})();(function(){var e=av.createElement("div");e.innerHTML="<div class='test e'></div><div class='test'></div>";if(!e.getElementsByClassName||e.getElementsByClassName("e").length===0){return}e.lastChild.className="e";if(e.getElementsByClassName("e").length===1){return}bE.order.splice(1,0,"CLASS");bE.find.CLASS=function(bR,bS,bT){if(typeof bS.getElementsByClassName!=="undefined"&&!bT){return bS.getElementsByClassName(bR[1])}};e=null})();function bv(bR,bW,bV,bZ,bX,bY){for(var bT=0,bS=bZ.length;bT<bS;bT++){var e=bZ[bT];if(e){var bU=false;e=e[bR];while(e){if(e[bC]===bV){bU=bZ[e.sizset];break}if(e.nodeType===1&&!bY){e[bC]=bV;e.sizset=bT}if(e.nodeName.toLowerCase()===bW){bU=e;break}e=e[bR]}bZ[bT]=bU}}}function bN(bR,bW,bV,bZ,bX,bY){for(var bT=0,bS=bZ.length;bT<bS;bT++){var e=bZ[bT];if(e){var bU=false;e=e[bR];while(e){if(e[bC]===bV){bU=bZ[e.sizset];break}if(e.nodeType===1){if(!bY){e[bC]=bV;e.sizset=bT}if(typeof bW!=="string"){if(e===bW){bU=true;break}}else{if(by.filter(bW,[e]).length>0){bU=e;break}}}e=e[bR]}bZ[bT]=bU}}}if(av.documentElement.contains){by.contains=function(bR,e){return bR!==e&&(bR.contains?bR.contains(e):true)}}else{if(av.documentElement.compareDocumentPosition){by.contains=function(bR,e){return !!(bR.compareDocumentPosition(e)&16)}}else{by.contains=function(){return false}}}by.isXML=function(e){var bR=(e?e.ownerDocument||e:0).documentElement;return bR?bR.nodeName!=="HTML":false};var bM=function(bS,e,bW){var bV,bX=[],bU="",bY=e.nodeType?[e]:e;while((bV=bE.match.PSEUDO.exec(bS))){bU+=bV[0];bS=bS.replace(bE.match.PSEUDO,"")}bS=bE.relative[bS]?bS+"*":bS;for(var bT=0,bR=bY.length;bT<bR;bT++){by(bS,bY[bT],bX,bW)}return by.filter(bU,bX)};by.attr=b.attr;by.selectors.attrMap={};b.find=by;b.expr=by.selectors;b.expr[":"]=b.expr.filters;b.unique=by.uniqueSort;b.text=by.getText;b.isXMLDoc=by.isXML;b.contains=by.contains})();var ab=/Until$/,aq=/^(?:parents|prevUntil|prevAll)/,a9=/,/,bp=/^.[^:#\[\.,]*$/,P=Array.prototype.slice,H=b.expr.match.POS,ay={children:true,contents:true,next:true,prev:true};b.fn.extend({find:function(e){var bw=this,by,bv;if(typeof e!=="string"){return b(e).filter(function(){for(by=0,bv=bw.length;by<bv;by++){if(b.contains(bw[by],this)){return true}}})}var bx=this.pushStack("","find",e),bA,bB,bz;for(by=0,bv=this.length;by<bv;by++){bA=bx.length;b.find(e,this[by],bx);if(by>0){for(bB=bA;bB<bx.length;bB++){for(bz=0;bz<bA;bz++){if(bx[bz]===bx[bB]){bx.splice(bB--,1);break}}}}}return bx},has:function(bv){var e=b(bv);return this.filter(function(){for(var bx=0,bw=e.length;bx<bw;bx++){if(b.contains(this,e[bx])){return true}}})},not:function(e){return this.pushStack(aG(this,e,false),"not",e)},filter:function(e){return this.pushStack(aG(this,e,true),"filter",e)},is:function(e){return !!e&&(typeof e==="string"?H.test(e)?b(e,this.context).index(this[0])>=0:b.filter(e,this).length>0:this.filter(e).length>0)},closest:function(by,bx){var bv=[],bw,e,bz=this[0];if(b.isArray(by)){var bB=1;while(bz&&bz.ownerDocument&&bz!==bx){for(bw=0;bw<by.length;bw++){if(b(bz).is(by[bw])){bv.push({selector:by[bw],elem:bz,level:bB})}}bz=bz.parentNode;bB++}return bv}var bA=H.test(by)||typeof by!=="string"?b(by,bx||this.context):0;for(bw=0,e=this.length;bw<e;bw++){bz=this[bw];while(bz){if(bA?bA.index(bz)>-1:b.find.matchesSelector(bz,by)){bv.push(bz);break}else{bz=bz.parentNode;if(!bz||!bz.ownerDocument||bz===bx||bz.nodeType===11){break}}}}bv=bv.length>1?b.unique(bv):bv;return this.pushStack(bv,"closest",by)},index:function(e){if(!e){return(this[0]&&this[0].parentNode)?this.prevAll().length:-1}if(typeof e==="string"){return b.inArray(this[0],b(e))}return b.inArray(e.jquery?e[0]:e,this)},add:function(e,bv){var bx=typeof e==="string"?b(e,bv):b.makeArray(e&&e.nodeType?[e]:e),bw=b.merge(this.get(),bx);return this.pushStack(C(bx[0])||C(bw[0])?bw:b.unique(bw))},andSelf:function(){return this.add(this.prevObject)}});function C(e){return !e||!e.parentNode||e.parentNode.nodeType===11}b.each({parent:function(bv){var e=bv.parentNode;return e&&e.nodeType!==11?e:null},parents:function(e){return b.dir(e,"parentNode")},parentsUntil:function(bv,e,bw){return b.dir(bv,"parentNode",bw)},next:function(e){return b.nth(e,2,"nextSibling")},prev:function(e){return b.nth(e,2,"previousSibling")},nextAll:function(e){return b.dir(e,"nextSibling")},prevAll:function(e){return b.dir(e,"previousSibling")},nextUntil:function(bv,e,bw){return b.dir(bv,"nextSibling",bw)},prevUntil:function(bv,e,bw){return b.dir(bv,"previousSibling",bw)},siblings:function(e){return b.sibling(e.parentNode.firstChild,e)},children:function(e){return b.sibling(e.firstChild)},contents:function(e){return b.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:b.makeArray(e.childNodes)}},function(e,bv){b.fn[e]=function(by,bw){var bx=b.map(this,bv,by);if(!ab.test(e)){bw=by}if(bw&&typeof bw==="string"){bx=b.filter(bw,bx)}bx=this.length>1&&!ay[e]?b.unique(bx):bx;if((this.length>1||a9.test(bw))&&aq.test(e)){bx=bx.reverse()}return this.pushStack(bx,e,P.call(arguments).join(","))}});b.extend({filter:function(bw,e,bv){if(bv){bw=":not("+bw+")"}return e.length===1?b.find.matchesSelector(e[0],bw)?[e[0]]:[]:b.find.matches(bw,e)},dir:function(bw,bv,by){var e=[],bx=bw[bv];while(bx&&bx.nodeType!==9&&(by===L||bx.nodeType!==1||!b(bx).is(by))){if(bx.nodeType===1){e.push(bx)}bx=bx[bv]}return e},nth:function(by,e,bw,bx){e=e||1;var bv=0;for(;by;by=by[bw]){if(by.nodeType===1&&++bv===e){break}}return by},sibling:function(bw,bv){var e=[];for(;bw;bw=bw.nextSibling){if(bw.nodeType===1&&bw!==bv){e.push(bw)}}return e}});function aG(bx,bw,e){bw=bw||0;if(b.isFunction(bw)){return b.grep(bx,function(bz,by){var bA=!!bw.call(bz,by,bz);return bA===e})}else{if(bw.nodeType){return b.grep(bx,function(bz,by){return(bz===bw)===e})}else{if(typeof bw==="string"){var bv=b.grep(bx,function(by){return by.nodeType===1});if(bp.test(bw)){return b.filter(bw,bv,!e)}else{bw=b.filter(bw,bv)}}}}return b.grep(bx,function(bz,by){return(b.inArray(bz,bw)>=0)===e})}function a(e){var bw=aR.split("|"),bv=e.createDocumentFragment();if(bv.createElement){while(bw.length){bv.createElement(bw.pop())}}return bv}var aR="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ag=/ jQuery\d+="(?:\d+|null)"/g,ar=/^\s+/,R=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,d=/<([\w:]+)/,w=/<tbody/i,W=/<|&#?\w+;/,ae=/<(?:script|style)/i,O=/<(?:script|object|embed|option|style)/i,ah=new RegExp("<(?:"+aR+")","i"),o=/checked\s*(?:[^=]|=\s*.checked.)/i,bm=/\/(java|ecma)script/i,aN=/^\s*<!(?:\[CDATA\[|\-\-)/,ax={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,"",""]},ac=a(av);ax.optgroup=ax.option;ax.tbody=ax.tfoot=ax.colgroup=ax.caption=ax.thead;ax.th=ax.td;if(!b.support.htmlSerialize){ax._default=[1,"div<div>","</div>"]}b.fn.extend({text:function(e){if(b.isFunction(e)){return this.each(function(bw){var bv=b(this);bv.text(e.call(this,bw,bv.text()))})}if(typeof e!=="object"&&e!==L){return this.empty().append((this[0]&&this[0].ownerDocument||av).createTextNode(e))}return b.text(this)},wrapAll:function(e){if(b.isFunction(e)){return this.each(function(bw){b(this).wrapAll(e.call(this,bw))})}if(this[0]){var bv=b(e,this[0].ownerDocument).eq(0).clone(true);if(this[0].parentNode){bv.insertBefore(this[0])}bv.map(function(){var bw=this;while(bw.firstChild&&bw.firstChild.nodeType===1){bw=bw.firstChild}return bw}).append(this)}return this},wrapInner:function(e){if(b.isFunction(e)){return this.each(function(bv){b(this).wrapInner(e.call(this,bv))})}return this.each(function(){var bv=b(this),bw=bv.contents();if(bw.length){bw.wrapAll(e)}else{bv.append(e)}})},wrap:function(e){var bv=b.isFunction(e);return this.each(function(bw){b(this).wrapAll(bv?e.call(this,bw):e)})},unwrap:function(){return this.parent().each(function(){if(!b.nodeName(this,"body")){b(this).replaceWith(this.childNodes)}}).end()},append:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1){this.appendChild(e)}})},prepend:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1){this.insertBefore(e,this.firstChild)}})},before:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(bv){this.parentNode.insertBefore(bv,this)})}else{if(arguments.length){var e=b.clean(arguments);e.push.apply(e,this.toArray());return this.pushStack(e,"before",arguments)}}},after:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(bv){this.parentNode.insertBefore(bv,this.nextSibling)})}else{if(arguments.length){var e=this.pushStack(this,"after",arguments);e.push.apply(e,b.clean(arguments));return e}}},remove:function(e,bx){for(var bv=0,bw;(bw=this[bv])!=null;bv++){if(!e||b.filter(e,[bw]).length){if(!bx&&bw.nodeType===1){b.cleanData(bw.getElementsByTagName("*"));b.cleanData([bw])}if(bw.parentNode){bw.parentNode.removeChild(bw)}}}return this},empty:function(){for(var e=0,bv;(bv=this[e])!=null;e++){if(bv.nodeType===1){b.cleanData(bv.getElementsByTagName("*"))}while(bv.firstChild){bv.removeChild(bv.firstChild)}}return this},clone:function(bv,e){bv=bv==null?false:bv;e=e==null?bv:e;return this.map(function(){return b.clone(this,bv,e)})},html:function(bx){if(bx===L){return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(ag,""):null}else{if(typeof bx==="string"&&!ae.test(bx)&&(b.support.leadingWhitespace||!ar.test(bx))&&!ax[(d.exec(bx)||["",""])[1].toLowerCase()]){bx=bx.replace(R,"<$1></$2>");try{for(var bw=0,bv=this.length;bw<bv;bw++){if(this[bw].nodeType===1){b.cleanData(this[bw].getElementsByTagName("*"));this[bw].innerHTML=bx}}}catch(by){this.empty().append(bx)}}else{if(b.isFunction(bx)){this.each(function(bz){var e=b(this);e.html(bx.call(this,bz,e.html()))})}else{this.empty().append(bx)}}}return this},replaceWith:function(e){if(this[0]&&this[0].parentNode){if(b.isFunction(e)){return this.each(function(bx){var bw=b(this),bv=bw.html();bw.replaceWith(e.call(this,bx,bv))})}if(typeof e!=="string"){e=b(e).detach()}return this.each(function(){var bw=this.nextSibling,bv=this.parentNode;b(this).remove();if(bw){b(bw).before(e)}else{b(bv).append(e)}})}else{return this.length?this.pushStack(b(b.isFunction(e)?e():e),"replaceWith",e):this}},detach:function(e){return this.remove(e,true)},domManip:function(bB,bF,bE){var bx,by,bA,bD,bC=bB[0],bv=[];if(!b.support.checkClone&&arguments.length===3&&typeof bC==="string"&&o.test(bC)){return this.each(function(){b(this).domManip(bB,bF,bE,true)})}if(b.isFunction(bC)){return this.each(function(bH){var bG=b(this);bB[0]=bC.call(this,bH,bF?bG.html():L);bG.domManip(bB,bF,bE)})}if(this[0]){bD=bC&&bC.parentNode;if(b.support.parentNode&&bD&&bD.nodeType===11&&bD.childNodes.length===this.length){bx={fragment:bD}}else{bx=b.buildFragment(bB,this,bv)}bA=bx.fragment;if(bA.childNodes.length===1){by=bA=bA.firstChild}else{by=bA.firstChild}if(by){bF=bF&&b.nodeName(by,"tr");for(var bw=0,e=this.length,bz=e-1;bw<e;bw++){bE.call(bF?ba(this[bw],by):this[bw],bx.cacheable||(e>1&&bw<bz)?b.clone(bA,true,true):bA)}}if(bv.length){b.each(bv,bo)}}return this}});function ba(e,bv){return b.nodeName(e,"table")?(e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody"))):e}function t(bB,bv){if(bv.nodeType!==1||!b.hasData(bB)){return}var by,bx,e,bA=b._data(bB),bz=b._data(bv,bA),bw=bA.events;if(bw){delete bz.handle;bz.events={};for(by in bw){for(bx=0,e=bw[by].length;bx<e;bx++){b.event.add(bv,by+(bw[by][bx].namespace?".":"")+bw[by][bx].namespace,bw[by][bx],bw[by][bx].data)}}}if(bz.data){bz.data=b.extend({},bz.data)}}function ai(bv,e){var bw;if(e.nodeType!==1){return}if(e.clearAttributes){e.clearAttributes()}if(e.mergeAttributes){e.mergeAttributes(bv)}bw=e.nodeName.toLowerCase();if(bw==="object"){e.outerHTML=bv.outerHTML}else{if(bw==="input"&&(bv.type==="checkbox"||bv.type==="radio")){if(bv.checked){e.defaultChecked=e.checked=bv.checked}if(e.value!==bv.value){e.value=bv.value}}else{if(bw==="option"){e.selected=bv.defaultSelected}else{if(bw==="input"||bw==="textarea"){e.defaultValue=bv.defaultValue}}}}e.removeAttribute(b.expando)}b.buildFragment=function(bz,bx,bv){var by,e,bw,bA,bB=bz[0];if(bx&&bx[0]){bA=bx[0].ownerDocument||bx[0]}if(!bA.createDocumentFragment){bA=av}if(bz.length===1&&typeof bB==="string"&&bB.length<512&&bA===av&&bB.charAt(0)==="<"&&!O.test(bB)&&(b.support.checkClone||!o.test(bB))&&(b.support.html5Clone||!ah.test(bB))){e=true;bw=b.fragments[bB];if(bw&&bw!==1){by=bw}}if(!by){by=bA.createDocumentFragment();b.clean(bz,bA,by,bv)}if(e){b.fragments[bB]=bw?by:1}return{fragment:by,cacheable:e}};b.fragments={};b.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,bv){b.fn[e]=function(bw){var bz=[],bC=b(bw),bB=this.length===1&&this[0].parentNode;if(bB&&bB.nodeType===11&&bB.childNodes.length===1&&bC.length===1){bC[bv](this[0]);return this}else{for(var bA=0,bx=bC.length;bA<bx;bA++){var by=(bA>0?this.clone(true):this).get();b(bC[bA])[bv](by);bz=bz.concat(by)}return this.pushStack(bz,e,bC.selector)}}});function bg(e){if(typeof e.getElementsByTagName!=="undefined"){return e.getElementsByTagName("*")}else{if(typeof e.querySelectorAll!=="undefined"){return e.querySelectorAll("*")}else{return[]}}}function az(e){if(e.type==="checkbox"||e.type==="radio"){e.defaultChecked=e.checked}}function E(e){var bv=(e.nodeName||"").toLowerCase();if(bv==="input"){az(e)}else{if(bv!=="script"&&typeof e.getElementsByTagName!=="undefined"){b.grep(e.getElementsByTagName("input"),az)}}}function al(e){var bv=av.createElement("div");ac.appendChild(bv);bv.innerHTML=e.outerHTML;return bv.firstChild}b.extend({clone:function(by,bA,bw){var e,bv,bx,bz=b.support.html5Clone||!ah.test("<"+by.nodeName)?by.cloneNode(true):al(by);if((!b.support.noCloneEvent||!b.support.noCloneChecked)&&(by.nodeType===1||by.nodeType===11)&&!b.isXMLDoc(by)){ai(by,bz);e=bg(by);bv=bg(bz);for(bx=0;e[bx];++bx){if(bv[bx]){ai(e[bx],bv[bx])}}}if(bA){t(by,bz);if(bw){e=bg(by);bv=bg(bz);for(bx=0;e[bx];++bx){t(e[bx],bv[bx])}}}e=bv=null;return bz},clean:function(bw,by,bH,bA){var bF;by=by||av;if(typeof by.createElement==="undefined"){by=by.ownerDocument||by[0]&&by[0].ownerDocument||av}var bI=[],bB;for(var bE=0,bz;(bz=bw[bE])!=null;bE++){if(typeof bz==="number"){bz+=""}if(!bz){continue}if(typeof bz==="string"){if(!W.test(bz)){bz=by.createTextNode(bz)}else{bz=bz.replace(R,"<$1></$2>");var bK=(d.exec(bz)||["",""])[1].toLowerCase(),bx=ax[bK]||ax._default,bD=bx[0],bv=by.createElement("div");if(by===av){ac.appendChild(bv)}else{a(by).appendChild(bv)}bv.innerHTML=bx[1]+bz+bx[2];while(bD--){bv=bv.lastChild}if(!b.support.tbody){var e=w.test(bz),bC=bK==="table"&&!e?bv.firstChild&&bv.firstChild.childNodes:bx[1]==="<table>"&&!e?bv.childNodes:[];for(bB=bC.length-1;bB>=0;--bB){if(b.nodeName(bC[bB],"tbody")&&!bC[bB].childNodes.length){bC[bB].parentNode.removeChild(bC[bB])}}}if(!b.support.leadingWhitespace&&ar.test(bz)){bv.insertBefore(by.createTextNode(ar.exec(bz)[0]),bv.firstChild)}bz=bv.childNodes}}var bG;if(!b.support.appendChecked){if(bz[0]&&typeof(bG=bz.length)==="number"){for(bB=0;bB<bG;bB++){E(bz[bB])}}else{E(bz)}}if(bz.nodeType){bI.push(bz)}else{bI=b.merge(bI,bz)}}if(bH){bF=function(bL){return !bL.type||bm.test(bL.type)};for(bE=0;bI[bE];bE++){if(bA&&b.nodeName(bI[bE],"script")&&(!bI[bE].type||bI[bE].type.toLowerCase()==="text/javascript")){bA.push(bI[bE].parentNode?bI[bE].parentNode.removeChild(bI[bE]):bI[bE])}else{if(bI[bE].nodeType===1){var bJ=b.grep(bI[bE].getElementsByTagName("script"),bF);bI.splice.apply(bI,[bE+1,0].concat(bJ))}bH.appendChild(bI[bE])}}}return bI},cleanData:function(bv){var by,bw,e=b.cache,bB=b.event.special,bA=b.support.deleteExpando;for(var bz=0,bx;(bx=bv[bz])!=null;bz++){if(bx.nodeName&&b.noData[bx.nodeName.toLowerCase()]){continue}bw=bx[b.expando];if(bw){by=e[bw];if(by&&by.events){for(var bC in by.events){if(bB[bC]){b.event.remove(bx,bC)}else{b.removeEvent(bx,bC,by.handle)}}if(by.handle){by.handle.elem=null}}if(bA){delete bx[b.expando]}else{if(bx.removeAttribute){bx.removeAttribute(b.expando)}}delete e[bw]}}}});function bo(e,bv){if(bv.src){b.ajax({url:bv.src,async:false,dataType:"script"})}else{b.globalEval((bv.text||bv.textContent||bv.innerHTML||"").replace(aN,"/*$0*/"))}if(bv.parentNode){bv.parentNode.removeChild(bv)}}var ak=/alpha\([^)]*\)/i
function p(by, bw, bv)
Definition: jquery.js:23
b fn css
Definition: jquery.js:23
if(!b.support.opacity)
Definition: jquery.js:23
function L
Definition: jquery.js:16
b each(["height","width"], function(bv, e){b.cssHooks[e]={get:function(by, bx, bw){var bz;if(bx){if(by.offsetWidth!==0){return p(by, e, bw)}else{b.swap(by, a7, function(){bz=p(by, e, bw)})}return bz}}, set:function(bw, bx){if(bc.test(bx)){bx=parseFloat(bx);if(bx >=0){return bx+"px"}}else{return bx}}}})
function bb
Definition: jquery.js:16
var b
Definition: jquery.js:16
Z
Definition: jquery.js:23
function bb

jQuery JavaScript Library v1.7.1 http://jquery.com/

Copyright 2011, John Resig Dual licensed under the MIT or GPL Version 2 licenses. http://jquery.org/license

Includes Sizzle.js http://sizzlejs.com/ Copyright 2011, The Dojo Foundation Released under the MIT, BSD, and GPL Licenses.

Date: Mon Nov 21 21:11:03 2011 -0500

var bq =/#.*$/
var bs =/\r?\n/g
var c
初始值:
=/^\/\
* jQuery UI 1.8.18
*
* Copyright 2011
b fn css =function(e,bv){if(arguments.length===2&&bv===L){return this}return b.access(this,e,bv,true,function(bx,bw,by){return by!==L?b.style(bx,bw,by):b.css(bx,bw)})}
b curCSS =b.css
var k =/%20/g
function L {var av=bb.document,bu=bb.navigator,bl=bb.location
Z =aI||aX
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/msp__cmn_8h.html ================================================ MSC for Windows&Linux API: msp_cmn.h 文件参考
MSC for Windows&Linux API
msp_cmn.h 文件参考

Mobile Speech Platform Common Interface Header File. 更多...

浏览源代码.

函数

int MSPAPI MSPLogin (const char *usr, const char *pwd, const char *params)
 初始化msc,用户登录。 更多...
 
const char *MSPAPI MSPUploadData (const char *dataName, void *data, unsigned int dataLen, const char *params, int *errorCode)
 用户数据上传。 更多...
 
const char *MSPAPI MSPSearch (const char *params, const char *text, unsigned int *dataLen, int *errorCode)
 文本搜索。 更多...
 
int MSPAPI MSPLogout ()
 退出登录。 更多...
 
int MSPAPI MSPGetParam (const char *paramName, char *paramValue, unsigned int *valueLen)
 获取MSC的设置信息 更多...
 
const char *MSPAPI MSPGetVersion (const char *verName, int *errorCode)
 获取MSC或本地引擎版本信息 更多...
 

详细描述

Mobile Speech Platform Common Interface Header File.

This file contains the quick common programming interface (API) declarations of MSP. Developer can include this file in your project to build applications. For more information, please read the developer guide.

Use of this software is subject to certain restrictions and limitations set forth in a license agreement entered into between iFLYTEK, Co,LTD. and the licensee of this software. Please refer to the license agreement for license use rights and restrictions.

Copyright (C) 1999 - 2015 by iFLYTEK, Co,LTD. All rights reserved.

作者
MSC
版本
5.0
日期
2015/03/19
参见

History:

Version Date Author Notes
5.0 2015/03/19 MSC Create this file

函数说明

int MSPAPI MSPGetParam ( const char *  paramName,
char *  paramValue,
unsigned int *  valueLen 
)

获取MSC的设置信息

参数
paramName[in]参数名,一次调用只支持查询一个参数。参数如下:
参数描述
upflow上行数据量
downflow下行数据量
paramValue[in/out]输入:buffer首地址
输出:向该buffer写入获取到的信息
valueLen[in/out]输入:buffer的大小
输出:信息实际长度(不含'\0')
返回
函数调用成功返回MSP_SUCCESS,否则返回错误代码,详见错误码列表
备注
以查询上行流量为例,获取到的是当前累计的上行流量。下行流量查询与此相似。
参见
const char* para_name = "upflow";
char para_value[32] = {'\0'};
unsigned int value_len = 32;
int ret = MSPGetParam (para_name, para_value, &value_len);
if(MSP_SUCCESS != ret)
{
    printf("MSPGetParam failed, error code is: %d", ret);
}
.
const char* MSPAPI MSPGetVersion ( const char *  verName,
int *  errorCode 
)

获取MSC或本地引擎版本信息

参数
verName[in]参数名,一次调用只支持查询一个参数。参数如下:
参数描述
ver_mscMSC版本号
ver_asr离线识别版本号,目前不支持
ver_tts离线合成版本号
ver_ivw离线唤醒版本号
errorCode[out]如果函数调用成功返回MSP_SUCCESS,否则返回错误代码,详见错误码列表
返回
成功返回缓冲区指针,失败或数据不存在返回NULL。
参见
int MSPAPI MSPLogin ( const char *  usr,
const char *  pwd,
const char *  params 
)

初始化msc,用户登录。

参数
usr[in]此参数保留,传入NULL即可。
pwd[in]此参数保留,传入NULL即可。
params[in]参见下表:
参数 参数说明 是否必要
appid 应用ID。SDK申请成功后获取到的appid。申请SDK请前往http://open.voicecloud.cn
app.name 描述应用的一个名字。用户所传的参数值必须和注册资料的对应项一致
app.path 应用程序的路径。用户所传的参数值必须和语音云申请时所填资料中的对应项一致
auth_id mfv业务用户标识,此参数仅在mfv业务下使用,由长度不超过64位的字母、下划线、数字组成
返回
成功返回MSP_SUCCESS,否则返回错误代码,详见错误码列表
备注
使用其他接口前必须先调用MSPLogin,可以在应用程序启动时调用。
参见
const char* usr = NULL;
const char* pwd = NULL;
const char* lgi_param = "appid = ********";
int ret = MSPLogin(usr, pwd, lgi_param);
if( MSP_SUCCESS != ret )
{
    printf( "MSPLogin failed, error code is: %d", ret );
}
.
int MSPAPI MSPLogout ( )

退出登录。

返回
如果函数调用成功返回MSP_SUCCESS,否则返回错误代码,详见错误码列表
备注
本接口和MSPLogin配合使用。确保其他接口调用结束之后调用MSPLogout,否则结果不可预期。
参见
int ret = MSPLogout( );
if(MSP_SUCCESS != ret)
{
    printf("MSPLogout failed, error code is: %d", ret);
}
.
const char* MSPAPI MSPSearch ( const char *  params,
const char *  text,
unsigned int *  dataLen,
int *  errorCode 
)

文本搜索。

参数
params[in]参见下表:
参数 参数说明
nlp_version 语义版本 1.0:老版本语义,返回结果为xml格式
2.0:新版本语义,场景比1.0支持的更多,返回结果为原生json
默认为1.0
text[in]上传文本,文本须为UTF-8编码。
dataLen[in]上传文本长度(如果是字符串,则不包含'\0')。
errorCode[out]如果函数调用成功返回MSP_SUCCESS,否则返回错误代码,详见错误码列表
返回
成功返回缓冲区指针,失败或数据不存在返回NULL。
参见
FILE * fw = NULL;
FILE * fr = NULL;
int txtSize = 0;
unsigned int str_len=0;
char *text = NULL;
const char * rec_text=NULL;
if(NULL==(fr=fopen("source.txt","rb")))
{
    ...   //错误处理
}
if(NULL != fr)
{
    fseek(fr, 0, SEEK_END);
    txtSize = ftell(fr);
    fseek(fr, 0, SEEK_SET);
    text = (char *)malloc(txtSize);
    fread((void *)text, txtSize, 1, fr);
    text[txtSize] = '\0';
    fclose(fr);
    fr = NULL;
}
str_len = strlen(text);
rec_text = MSPSearch("nlp_version=2.0",text,&str_len,&ret);
if(MSP_SUCCESS !=ret)
{
    printf("MSPSearch failed ,error code is:%d\n",ret);
}
if(NULL==(fw=fopen("result.txt","wb")))
{
    ...//错误处理
}
if(1!=fwrite(rec_text,strlen(rec_text),1,fw))
{
    printf("file write error\n");
}
fclose(fw);
.
const char* MSPAPI MSPUploadData ( const char *  dataName,
void *  data,
unsigned int  dataLen,
const char *  params,
int *  errorCode 
)

用户数据上传。

参数
dataName[in]数据名称字符串。
data[in]待上传数据缓冲区的起始地址。
dataLen[in]数据长度(如果是字符串,则不包含'\0')。
params[in]目前支持以下四种。具体如下:
参数 功能 应用业务 文件编码
"sub = uup,dtt = userword" 上传用户词表 iat UTF-8
"sub = uup,dtt = contact" 上传联系人 iat UTF-8
"sub = asr,dtt = abnf"或
"sub = asr,dtt = xml"
上传识别语法 asr UTF-8或GB2312
"sub = asr" 上传关键词 asr UTF-8
语法详见:http://club.voicecloud.cn/forum.php?mod=viewthread&tid=7595
errorCode[out]函数调用成功返回MSP_SUCCESS,否则返回错误代码,详见错误码列表
返回
上传成功后,联系人、用户词表功能返回值NULL,识别语法、关键词功能会返回一个字符串格式的ID,该ID是此次上传数据的唯一标识。上传的数据会被永久保存,需要使用时,只要在相应接口传入对应ID即可。
参见
const char* dataname = "userword";
const char* params = "sub=uup,dtt=userword";
const char* result = NULL;
char* data = NULL;
int data_len = 0;
FILE* fp = fopen("userwords.txt ", "rb");
if(NULL==fp)
{
    ...   //错误处理
}
fseek(fp, 0, SEEK_END);
data_len = ftell(fp);
fseek(fp, 0, SEEK_SET);
data = (char*)malloc(data_len+1);
if(NULL==data)
{
    ...   //错误处理
}
data_len = fread(data,1,data_len,fp);
if(data_len == 0)
{
    ...   //错误处理
}
data[data_len] = '\0';
result = MSPUploadData( dataName, data, data_len, params, &errorcode);
if( MSP_SUCCESS != errorcode )
{
    printf( "MSPUploadData failed, error code is: %d", ret );
}
fclose(fp);
.
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/msp__cmn_8h_source.html ================================================ MSC for Windows&Linux API: msp_cmn.h 源文件
MSC for Windows&Linux API
msp_cmn.h
浏览该文件的文档.
1 
59 int MSPAPI MSPLogin(const char* usr, const char* pwd, const char* params);
60 
113 const char* MSPAPI MSPUploadData(const char* dataName, void* data, unsigned int dataLen, const char* params, int* errorCode);
167 const char* MSPAPI MSPSearch(const char* params, const char* text, unsigned int* dataLen, int* errorCode);
184 int MSPAPI MSPLogout();
185 
212 int MSPAPI MSPGetParam( const char *paramName, char *paramValue, unsigned int *valueLen );
228  const char* MSPAPI MSPGetVersion(const char *verName, int *errorCode);
const char *MSPAPI MSPUploadData(const char *dataName, void *data, unsigned int dataLen, const char *params, int *errorCode)
用户数据上传。
int MSPAPI MSPLogin(const char *usr, const char *pwd, const char *params)
初始化msc,用户登录。
const char *MSPAPI MSPSearch(const char *params, const char *text, unsigned int *dataLen, int *errorCode)
文本搜索。
int MSPAPI MSPGetParam(const char *paramName, char *paramValue, unsigned int *valueLen)
获取MSC的设置信息
int MSPAPI MSPLogout()
退出登录。
const char *MSPAPI MSPGetVersion(const char *verName, int *errorCode)
获取MSC或本地引擎版本信息
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/qisr_8h.html ================================================ MSC for Windows&Linux API: qisr.h 文件参考
MSC for Windows&Linux API
qisr.h 文件参考

iFLY Speech Recognizer Header File 更多...

浏览源代码.

函数

const char *MSPAPI QISRSessionBegin (const char *grammarList, const char *params, int *errorCode)
 开始一次语音识别。 更多...
 
int MSPAPI QISRAudioWrite (const char *sessionID, const void *waveData, unsigned int waveLen, int audioStatus, int *epStatus, int *recogStatus)
 写入本次识别的音频。 更多...
 
const char *MSPAPI QISRGetResult (const char *sessionID, int *rsltStatus, int waitTime, int *errorCode)
 获取识别结果。 更多...
 
int MSPAPI QISRSessionEnd (const char *sessionID, const char *hints)
 结束本次语音识别。 更多...
 
int MSPAPI QISRGetParam (const char *sessionID, const char *paramName, char *paramValue, unsigned int *valueLen)
 获取当次语音识别信息,如上行流量、下行流量等。 更多...
 

详细描述

iFLY Speech Recognizer Header File

This file contains the quick application programming interface (API) declarations of ISR. Developer can include this file in your project to build applications. For more information, please read the developer guide.

Use of this software is subject to certain restrictions and limitations set forth in a license agreement entered into between iFLYTEK, Co,LTD. and the licensee of this software. Please refer to the license agreement for license use rights and restrictions.

Copyright (C) 1999 - 2015 by iFLYTEK, Co,LTD. All rights reserved.

作者
MSC
版本
5.0
日期
2015/03/19
参见

History:

Version Date Author Notes
5.0 2015/03/19 MSC Create this file

函数说明

int MSPAPI QISRAudioWrite ( const char *  sessionID,
const void *  waveData,
unsigned int  waveLen,
int  audioStatus,
int *  epStatus,
int *  recogStatus 
)

写入本次识别的音频。

参数
sessionID[in]由QISRSessionBegin返回的句柄。
waveData[in]音频数据缓冲区起始地址。
waveLen[in]音频数据长度,单位字节。
audioStatus[in]用来告知MSC音频发送是否完成,典型值如下:
枚举常量 描述
MSP_AUDIO_SAMPLE_FIRST = 1 第一块音频
MSP_AUDIO_SAMPLE_CONTINUE = 2 还有后继音频
MSP_AUDIO_SAMPLE_LAST = 4 最后一块音频
epStatus[out]端点检测(End-point detected)器所处的状态,可能的值如下:
枚举常量 描述
MSP_EP_LOOKING_FOR_SPEECH = 0 还没有检测到音频的前端点
MSP_EP_IN_SPEECH = 1 已经检测到了音频前端点,正在进行正常的音频处理
MSP_EP_AFTER_SPEECH = 3 检测到音频的后端点,后继的音频会被MSC忽略
MSP_EP_TIMEOUT = 4 超时
MSP_EP_ERROR = 5 出现错误
MSP_EP_MAX_SPEECH = 6 音频过大
注意:当epStatus大于等于3时,用户应当停止写入音频的操作,否则写入MSC的音频会被忽略。
recogStatus[out]识别器返回的状态,提醒用户及时开始\停止获取识别结果。典型值如下:
枚举常量 描述
MSP_REC_STATUS_SUCCESS = 0 识别成功,有识别结果返回
MSP_REC_STATUS_NO_MATCH = 1 识别结束,没有识别结果
MSP_REC_STATUS_INCOMPLETE = 2 正在识别
MSP_REC_STATUS_COMPLETE = 5 识别结束,有识别结果返回
返回
函数调用成功返回MSP_SUCCESS,否则返回错误代码,详见错误码列表
备注
本接口需不断调用,直到音频全部写入为止。上传音频时,需更新audioStatus的值。具体来说:
当写入首块音频时,将audioStatus置为MSP_AUDIO_SAMPLE_FIRST
当写入最后一块音频时,将audioStatus置为MSP_AUDIO_SAMPLE_LAST
其余情况下,将audioStatus置为MSP_AUDIO_SAMPLE_CONTINUE

同时,需定时检查两个变量:epStatus和rsltStatus。具体来说:
当epStatus显示已检测到后端点时,MSC已不再接收音频,应及时停止音频写入
当rsltStatus显示有识别结果返回时,即可从MSC缓存中获取结果
参见
char audio_data[5120] ={'\0'};
unsigned int   audio_len = 0;
int audio_status = 2;
int ep_status = 0;
int rec_status = 0;
int ret = 0;
while(MSP_AUDIO_SAMPLE_LAST != audio_status )
{
    // 读取音频到缓冲区audio_data中,设置音频长度audio_len,音频状态audio_status。
    ret = QISRAudioWrite( sessionID, audio_data, audio_len, audio_status, &ep_status, &rec_status );
    if( MSP_SUCCESS != ret )
    {
        printf( "QISRAudioWrite failed, error code is: %d", ret );
        break;
    }
    else if(MSP_EP_AFTER_SPEECH == ep_status )//检测到音频后端点,停止写入音频 
    {
        printf( "end point of speech has been detected!" );
        break;
    }
    //如果是实时采集音频,可以省略此操作。5KB大小的16KPCM持续的时间是160毫秒 
    Sleep( 160 );  
}
.
int MSPAPI QISRGetParam ( const char *  sessionID,
const char *  paramName,
char *  paramValue,
unsigned int *  valueLen 
)

获取当次语音识别信息,如上行流量、下行流量等。

参数
sessionID[in]由QISRSessionEnd返回的句柄,如果为NULL,获取MSC的设置信息。
paramName[in]参数名,一次调用只支持查询一个参数。参数如下:
参数描述
sid服务端会话ID,长度为32字节
upflow上行数据量,单位字节
downflow下行数据量,单位字节
volume最近一次写入的音频的音量
paramValue[in/out]输入:buffer首地址
输出:向该buffer写入获取到的信息
valueLen[in/out]输入:buffer的大小,valueLen大小需根据结果大小做调整
输出:信息实际长度(不含’\0’),长度需+1
返回
函数调用成功返回MSP_SUCCESS,否则返回错误代码,详见错误码列表
备注
以查询上行流量为例,获取到的是本次识别当前累计的上行流量。下行流量查询与此相似。
参见
const char * para_name = "sid";
char para_value[33] = {'\0'};
unsigned int value_len = 33;
int ret = QISRGetParam ( sessionID, para_name, para_value, &value_len );
if( MSP_SUCCESS != ret )
{
    printf( "QISRGetParam failed, error code is: %d", ret );
}
.
const char* MSPAPI QISRGetResult ( const char *  sessionID,
int *  rsltStatus,
int  waitTime,
int *  errorCode 
)

获取识别结果。

参数
sessionID[in]由QISRSessionBegin返回的句柄。
rsltStatus[out]识别结果的状态,其取值范围和含义请参考QISRAudioWrite的参数recogStatus。
waitTime[in]此参数做保留用。
errorCode[out]函数调用成功返回MSP_SUCCESS,否则返回错误代码,详见错误码列表
返回
函数执行成功且有识别结果时,返回结果字符串指针;其他情况(失败或无结果)返回NULL。
备注
当写入音频过程中已经有部分识别结果返回时,可以获取结果。在音频写入完毕后,用户需反复调用此接口,直到识别结果获取完毕(rlstStatus值为5)或返回错误码。
注意:如果某次成功调用后暂未获得识别结果,请将当前线程sleep一段时间,以防频繁调用浪费CPU资源。
参见
char rslt_str[2048] ={'\0'};
const char* rec_result = NULL;
int rslt_status = 0;
int ret = 0;
while(MSP_REC_STATUS_COMPLETE != rslt_status )
{
    rec_result = QISRGetResult ( sessionID, &rslt_status, 5000, &ret );
    if( MSP_SUCCESS != ret )
    {
        printf( "QISRGetResult failed, error code is: %d", ret );
        break;
    }
    if( NULL != rec_result )
    {
        strcat( rslt_str, rec_result );//用户可以用其他的方式保存识别结果
        continue;
    }
    //sleep一下很有必要,防止MSC端无缓存的识别结果时浪费CPU资源
    Sleep( 200 );
}
.
const char* MSPAPI QISRSessionBegin ( const char *  grammarList,
const char *  params,
int *  errorCode 
)

开始一次语音识别。

参数
grammarList[in]进行连续语音识别(sub=iat)时,此参数设为NULL。进行关键字、语法识别(sub=asr)时,上传方式如下:
类型 说明
关键词识别 传入调用MSPUploadData接口上传关键词的返回值。关键词会永久生效。
语法识别 除上述方法外,也可在此处传入语法字符串指针,并在params参数中添加"grammartype=abnf"或" grammartype=xml"。
此方法仅在本次识别有效。
params[in]本次识别参数,可设置的参数列表如下:
参数 参数说明
sub 本次识别请求的类型 iat:连续语音识别
asr:语法、关键词识别。默认为iat
ptt 添加标点符号(仅sub=iat时有效) 0:无标点符号;1:有标点符号。默认为1
sch 是否使用语义功能(仅sub=iat时有效) 0:不使用语义;1:使用语义。默认为0
nlp_version 语义版本(仅在使用语义功能时有效) 1.0:老版本语义,返回结果为xml格式;2.0:新版本语义,场景比1.0支持的更多,返回结果为原生json,默认为1.0
aue 音频编码格式和压缩等级 编码算法:raw;speex;speex-wb;
编码等级:raw:无等级。speex系列:0-10;
默认为speex-wb;7
speex对应sample_rate=8000
speex-wb对应sample_rate=16000
sample_rate 音频格式 8000
16000
默认为16000
result_encoding 识别结果字符串所用编码格式 gb2312;utf8;unicode
不同的格式支持不同的编码:
plain:utf8
xml:gb2312, utf8, unicode
json:utf8
grammartype 语法类型(仅sub=asr时有效) abnf
xml
vad_bos 允许头部静音的最长时间 0-10000毫秒。默认为1000
如果静音时长超过了此值,则认为用户此次无有效音频输入。此参数仅在打开VAD功能时有效。
vad_eos 允许尾部静音的最长时间 0-10000毫秒。默认为2000
如果尾部静音时长超过了此值,则认为用户音频已经结束,此参数仅在打开VAD功能时有效。
result_type 识别结果格式 sub=asr时:支持plain,xml,json
sub=iat时:支持plain,json
domain 领域 iat:连续语音识别
asr:语法、关键词识别
search:热词
video:视频
poi:地名
music:音乐
默认为iat。
注意:sub=asr时,domain只能为asr
language 语言 zh_cn:简体中文
zh_tw:繁体中文
en_us:英语
默认为zh_cn
accent 口音 mandarin:普通话
cantonese:粤语
默认为mandarin
注意:没有默认值的参数必须由外部设定其值
errorCode[out]函数调用成功则其值为MSP_SUCCESS,否则返回错误代码,详见错误码列表
返回
函数调用成功返回字符串格式的sessionID,失败返回NULL。sessionID是本次识别的句柄。
备注
参数只在当次识别中生效。
当使用连续语音识别(sub=iat)时,为了保证识别结果的个性化,可调用MSPUploadData接口上传联系人、用户词表。用法请参照MSPUploadData接口。
参见
const char * params = "sub=iat,aue=speex-wb;7,result_type=plain,result_encoding=utf8,language=zh_cn,
                      accent=mandarin,sample_rate=16000,domain=music,vad_bos=1000,vad_eos=1000";
int    ret = 0;
const char* sessionID = QISRSessionBegin( NULL, params, &ret );
if( MSP_SUCCESS != ret )
{
    printf( "QISRSessionBegin failed, error code is: %d", ret );
}
.
int MSPAPI QISRSessionEnd ( const char *  sessionID,
const char *  hints 
)

结束本次语音识别。

参数
sessionID[in]由QISRSessionBegin返回的句柄。
hints[in]结束本次语音识别的原因描述,为用户自定义内容。
返回
函数调用成功返回MSP_SUCCESS,否则返回错误代码,详见错误码列表
备注
本接口和QISRSessionBegin对应,调用此接口后,该句柄对应的相关资源(参数、语法、音频、实例等)都会被释放,用户不应再使用该句柄。
参见
int ret = QISRSessionEnd ( sessionID, "normal end" );
if( MSP_SUCCESS != ret )
{
    printf( "QISRSessionEnd failed, error code is: %d", ret );
}
sessionID = NULL;
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/qisr_8h_source.html ================================================ MSC for Windows&Linux API: qisr.h 源文件
MSC for Windows&Linux API
qisr.h
浏览该文件的文档.
1 
76 const char* MSPAPI QISRSessionBegin(const char* grammarList, const char* params, int* errorCode);
77 
78 
79 
145 int MSPAPI QISRAudioWrite(const char* sessionID, const void* waveData, unsigned int waveLen, int audioStatus, int *epStatus, int *recogStatus);
146 
147 
183 const char * MSPAPI QISRGetResult(const char* sessionID, int* rsltStatus, int waitTime, int *errorCode);
184 
185 
186 
187 
205 int MSPAPI QISRSessionEnd(const char* sessionID, const char* hints);
206 
207 
237 int MSPAPI QISRGetParam(const char* sessionID, const char* paramName, char* paramValue, unsigned int* valueLen);
238 
239 
240 
241 
int MSPAPI QISRSessionEnd(const char *sessionID, const char *hints)
结束本次语音识别。
const char *MSPAPI QISRSessionBegin(const char *grammarList, const char *params, int *errorCode)
开始一次语音识别。
const char *MSPAPI QISRGetResult(const char *sessionID, int *rsltStatus, int waitTime, int *errorCode)
获取识别结果。
int MSPAPI QISRAudioWrite(const char *sessionID, const void *waveData, unsigned int waveLen, int audioStatus, int *epStatus, int *recogStatus)
写入本次识别的音频。
int MSPAPI QISRGetParam(const char *sessionID, const char *paramName, char *paramValue, unsigned int *valueLen)
获取当次语音识别信息,如上行流量、下行流量等。
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/qmfv_8h.html ================================================ MSC for Windows&Linux API: qmfv.h 文件参考
MSC for Windows&Linux API
qmfv.h 文件参考

iFLY Speech Recognizer Header File 更多...

浏览源代码.

函数

const char *MSPAPI QMFVSessionBegin (const char *params, int *errorCode)
 开始一次身份验证。 更多...
 
int MSPAPI QMFVDataWrite (const char *sessionID, const char *params, const void *data, unsigned int dataLen, int *resultStatus)
 写入本次身份验证的数据。 更多...
 
const void *MSPAPI QMFVGetResult (const char *sessionID, unsigned int *resultLen, int *resultStatus, int *errorCode)
 获取身份验证结果。 更多...
 
int MSPAPI QMFVGetParam (const char *sessionID, const char *paramName, char *paramValue, unsigned int *valueLen)
 获取当次身份验证信息,如上行流量、下行流量等。 更多...
 
int MSPAPI QMFVSessionEnd (const char *sessionID, const char *hints)
 结束本次身份验证。 更多...
 

详细描述

iFLY Speech Recognizer Header File

This file contains the quick application programming interface (API) declarations of MFV. Developer can include this file in your project to build applications. For more information, please read the developer guide.

Use of this software is subject to certain restrictions and limitations set forth in a license agreement entered into between iFLYTEK, Co,LTD. and the licensee of this software. Please refer to the license agreement for license use rights and restrictions.

Copyright (C) 1999 - 2015 by iFLYTEK, Co,LTD. All rights reserved.

作者
MSC
版本
5.0
日期
2015/02/10
参见

History:

Version Date Author Notes
5.0 2015/02/10 MSC Create this file

函数说明

int MSPAPI QMFVDataWrite ( const char *  sessionID,
const char *  params,
const void *  data,
unsigned int  dataLen,
int *  resultStatus 
)

写入本次身份验证的数据。

参数
sessionID[in]由QMFVSessionBegin返回的句柄。
params[in]传入的参数列表,支持以下参数:
应用领域 参数 参数说明
通用 data_status 数据当前状态 1:第一块数据
2:追加数据(后继数据)
4:最后一块数据
无默认值
通用 ssub 子业务类型,如:声纹、人脸、指纹、虹膜 ivp: 声纹业务
ifr:人脸业务
无默认值
人脸业务(ssub=ifr)sst会话类型,描述不同人脸功能enroll:注册
verify:确认
delete:删除模型
无默认值
人脸业务(ssub=ifr)data_format图片数据格式jpg(默认值)
png
bmp
人脸业务(ssub=ifr)data_encoding图片数据压缩编码raw(默认值),MSC不对传入的图片数据进行压缩
声纹业务(ssub=ivp)sst会话类型,描述不同声纹功能enroll:注册
verify:确认
delete:删除模型
query:查询
download:下载
删除,查询,下载不需要QMFVDataWrite写入数据,data = NULL,datalen = 0即可
无默认值
声纹业务(ssub=ivp)rgn注册时表示注册所需的音频条数
数字密码下载时表示数字串的数目
[2,9]
无默认值
声纹业务(ssub=ivp)ptxt指定声纹密码训练时使用的声纹密码内容从服务端下载,比如数字密码所需的数字串,<bt>无默认值
声纹业务(ssub=ivp)pwdt指定声纹密码训练时使用的声纹密码类型1:文本密码
2:自由说
3:数字密码
无默认值
声纹业务(ssub=ivp)fin取消本次注册0或false(默认值):不取消
1或true:取消本次注册
声纹业务(ssub=ivp)vad_enable是否启用VAD处理0或false:不开启
1或true(默认值):开启
声纹业务(ssub=ivp)vad_bos如果头部静音长度超过了此值,则认为用户此次无有效音频输入。此参数仅在打开VAD功能时有效。[0,30000]
默认值10000ms
声纹业务(ssub=ivp)vad_eos如果尾部静音长度超过了此值,则认为用户音频已经结束,此参数仅在打开VAD功能时有效。[0,30000]
默认值2000ms
声纹业务(ssub=ivp)data_format在声纹业务中作为音频采样率16000(默认值)
8000
声纹业务(ssub=ivp)data_encoding音频编码格式和压缩等级编码算法:raw;speex;speex-wb;
编码等级:raw:无等级。speex系列:0-10;
默认为speex-wb;7
speex对应sample_rate=8000
speex-wb对应sample_rate=16000
注意:没有默认值的参数必须由外部设定其值
data[in]身份验证数据缓冲区起始地址。
dataLen[in]身份验证数据长度,单位字节。
resultStatus[out]识别器返回的状态,提醒用户及时开始\停止获取识别结果。典型值如下:
枚举常量 描述
MSP_REC_STATUS_SUCCESS = 0 身份验证成功,有结果返回
MSP_REC_STATUS_NO_MATCH = 1 身份验证结束,没有结果
MSP_REC_STATUS_INCOMPLETE = 2 正在身份验证
MSP_REC_STATUS_COMPLETE = 5 身份验证结束,有结果返回
返回
函数调用成功返回MSP_SUCCESS,否则返回错误代码,详见错误码列表
参见
int MSPAPI QMFVGetParam ( const char *  sessionID,
const char *  paramName,
char *  paramValue,
unsigned int *  valueLen 
)

获取当次身份验证信息,如上行流量、下行流量等。

参数
sessionID[in]由QMFVSessionEnd返回的句柄,如果为NULL,获取MSC的设置信息。
paramName[in]参数名,一次调用只支持查询一个参数。参数如下:
参数描述
sid服务端会话ID,长度为32字节
upflow上行数据量,单位字节
downflow下行数据量,单位字节
ivp_sret声纹错误码,长度为6字节
ifr_sret人脸错误码,长度为6字节
volume最近一次写入的音频的音量
paramValue[in/out]输入:buffer首地址
输出:向该buffer写入获取到的信息
valueLen[in/out]输入:buffer的大小,valueLen大小需根据结果大小做调整
输出:信息实际长度(不含’\0’),长度需+1
返回
函数调用成功返回MSP_SUCCESS,否则返回错误代码,详见错误码列表
备注
以查询上行流量为例,获取到的是本次身份验证当前累计的上行流量。下行流量查询与此相似。
参见
const char * para_name = "sid";
char para_value[33] = {'\0'};
unsigned int value_len = 33;
int ret = QMFVGetParam ( sessionID, para_name, para_value, &value_len );
if( MSP_SUCCESS != ret )
{
    printf( "QMFVGetParam failed, error code is: %d", ret );
}
.
const void* MSPAPI QMFVGetResult ( const char *  sessionID,
unsigned int *  resultLen,
int *  resultStatus,
int *  errorCode 
)

获取身份验证结果。

参数
sessionID[in]由QMFVSessionBegin返回的句柄。
resultLen[out]身份验证结果的长度。
resultStatus[out]身份验证结果的状态,其取值范围和含义请参考QMFVAudioWrite的参数resultStatus。
errorCode[out]函数调用成功返回MSP_SUCCESS,否则返回错误代码,详见错误码列表
返回
函数执行成功且有身份验证结果时,返回结果字符串指针;其他情况(失败或无结果)返回NULL。
备注
当删除人脸模型时,不会有结果返回,当删除声纹时,如果删除成功会返回“true”。
参见
const char* MSPAPI QMFVSessionBegin ( const char *  params,
int *  errorCode 
)

开始一次身份验证。

参数
params[in]传入的参数列表,支持以下参数:
参数 参数说明
sub 请求业务类型 mfv
scene_mode 场景参数,仅在mfv业务下使用 gen:通用场景(注册、查询、删除)
vfy:融合验证场景
无默认值
vcm 融合验证模式,仅在融合验证场景下使用sin:single,单一生物特征数据验证
mix:mix,混合生物特征数据验证,一次sessionbegin
agi:agility,灵活生物特征数据验证,用户可以在设定的生命周期内至少进行一种生物特征数据的验证,可根据实际情况灵活调整,一次特征验证调用一次sessionbegin。
无默认值
scenes 特征场景,用来说明本次会话涉及的子业务ivp,ifr,ivp|ifr(或者ifr|ivp)
两个场景都存在时:1.写入数据的顺序要与场景顺序一致,2.删除或混合注册时,一个场景业务失败不会影响另一个,无默认值
afc 确认周期(affirmance cycle),用户设置的确认超时时间,仅在灵活融合验证(vcm=agi),场景特征为scenes=ifr|ivp或ifr|ivp下使用 0~43200
无默认值
注意:没有默认值的参数必须由外部设定其值
errorCode[out]函数调用成功则其值为MSP_SUCCESS,否则返回错误代码,详见错误码列表
返回
函数调用成功返回字符串格式的sessionID,失败返回NULL。sessionID是本次识别的句柄。
备注
调用mfv业务需要注意,MSPLogin接口需要传入auth_id
参见
int MSPAPI QMFVSessionEnd ( const char *  sessionID,
const char *  hints 
)

结束本次身份验证。

参数
sessionID[in]由QMFVSessionBegin返回的句柄。
hints[in]结束本次身份验证的原因描述,为用户自定义内容。
返回
函数调用成功返回MSP_SUCCESS,否则返回错误代码,详见错误码列表
备注
本接口和QMFVSessionBegin对应,调用此接口后,该句柄对应的相关资源(参数、语法、音频、实例等)都会被释放,用户不应再使用该句柄。
参见
int ret = QMFVSessionEnd ( sessionID, "normal end" );
if( MSP_SUCCESS != ret )
{
    printf( "QMFVSessionEnd failed, error code is: %d", ret );
}
sessionID = NULL;
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/qmfv_8h_source.html ================================================ MSC for Windows&Linux API: qmfv.h 源文件
MSC for Windows&Linux API
qmfv.h
浏览该文件的文档.
1 
51 const char* MSPAPI QMFVSessionBegin(const char* params, int* errorCode);
52 
53 
92 int MSPAPI QMFVDataWrite(const char* sessionID, const char* params, const void* data, unsigned int dataLen, int *resultStatus);
93 
106 const void * MSPAPI QMFVGetResult(const char* sessionID, unsigned int* resultLen, int* resultStatus, int *errorCode);
107 
139 int MSPAPI QMFVGetParam(const char* sessionID, const char* paramName, char* paramValue, unsigned int* valueLen);
140 
141 
159 int MSPAPI QMFVSessionEnd(const char* sessionID, const char* hints);
int MSPAPI QMFVSessionEnd(const char *sessionID, const char *hints)
结束本次身份验证。
const char *MSPAPI QMFVSessionBegin(const char *params, int *errorCode)
开始一次身份验证。
int MSPAPI QMFVDataWrite(const char *sessionID, const char *params, const void *data, unsigned int dataLen, int *resultStatus)
写入本次身份验证的数据。
int MSPAPI QMFVGetParam(const char *sessionID, const char *paramName, char *paramValue, unsigned int *valueLen)
获取当次身份验证信息,如上行流量、下行流量等。
const void *MSPAPI QMFVGetResult(const char *sessionID, unsigned int *resultLen, int *resultStatus, int *errorCode)
获取身份验证结果。
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/qtts_8h.html ================================================ MSC for Windows&Linux API: qtts.h 文件参考
MSC for Windows&Linux API
qtts.h 文件参考

iFLY Speech Synthesizer Header File 更多...

浏览源代码.

函数

const char *MSPAPI QTTSSessionBegin (const char *params, int *errorCode)
 开始一次语音合成,分配语音合成资源。 更多...
 
int MSPAPI QTTSTextPut (const char *sessionID, const char *textString, unsigned int textLen, const char *params)
 写入待合成的文本。 更多...
 
const void *MSPAPI QTTSAudioGet (const char *sessionID, unsigned int *audioLen, int *synthStatus, int *errorCode)
 获取合成音频。 更多...
 
int MSPAPI QTTSGetParam (const char *sessionID, const char *paramName, char *paramValue, unsigned int *valueLen)
 获取当前语音合成信息,如当前合成音频对应文本结束位置、上行流量、下行流量等。 更多...
 
int MSPAPI QTTSSessionEnd (const char *sessionID, const char *hints)
 结束本次语音合成。 更多...
 

详细描述

iFLY Speech Synthesizer Header File

This file contains the quick application programming interface (API) declarations of TTS. Developer can include this file in your project to build applications. For more information, please read the developer guide.

Use of this software is subject to certain restrictions and limitations set forth in a license agreement entered into between iFLYTEK, Co,LTD. and the licensee of this software. Please refer to the license agreement for license use rights and restrictions.

Copyright (C) 1999 - 2015 by iFLYTEK, Co,LTD. All rights reserved.

作者
MSC
版本
5.0
日期
2015/03/19
参见

History:

Version Date Author Notes
5.0 2015/03/19 MSC Create this file

函数说明

const void* MSPAPI QTTSAudioGet ( const char *  sessionID,
unsigned int *  audioLen,
int *  synthStatus,
int *  errorCode 
)

获取合成音频。

参数
sessionID[in]由QTTSSessionBegin返回的句柄。
audioLen[out]合成音频长度,单位字节。
synthStatus[out]合成音频状态,可能的值如下:
枚举常量 描述
MSP_TTS_FLAG_STILL_HAVE_DATA = 1 音频未取完,还有后继音频
MSP_TTS_FLAG_DATA_END = 2 音频已经取完
errorCode[out]函数调用成功返回MSP_SUCCESS,否则返回错误代码,详见错误码列表
返回
函数调用成功且有音频数据时返回非空指针。调用失败或无音频数据时,返回NULL。
备注
用户需要反复获取音频,直到音频获取完毕或函数调用失败。在重复获取音频时,如果暂未获得音频数据,需要将当前线程sleep一段时间,以防频繁调用浪费CPU资源。
参见
FILE* fp = fopen("tts.pcm", "wb");
while (1)
{
    const void * data = QTTSAudioGet(sessionID, &audio_len, &synth_status, &ret);
    if (NULL != data)
    {
        fwrite(data, audio_len, 1, fp);
    }
    if (MSP_TTS_FLAG_DATA_END == synth_status || MSP_SUCCESS != ret)
    {
        break;
    }
}
fclose(fp);
.
int MSPAPI QTTSGetParam ( const char *  sessionID,
const char *  paramName,
char *  paramValue,
unsigned int *  valueLen 
)

获取当前语音合成信息,如当前合成音频对应文本结束位置、上行流量、下行流量等。

参数
sessionID[in]由QTTSSessionBegin返回的句柄,如果为NULL,获取MSC的设置信息。
paramName[in]参数名,一次调用只支持查询一个参数。参数如下:
参数描述
sid服务端会话ID,长度为32字节
upflow上行数据量,单位字节
downflow下行数据量,单位字节
volume最近一次写入的音频的音量
ced当前合成音频对应文本结束位置
paramValue[in/out]输入:buffer首地址
输出:向该buffer写入获取到的信息
valueLen[in/out]输入:buffer的大小,valueLen大小需根据结果大小做调整
输出:信息实际长度(不含’\0’),长度需+1
返回
函数调用成功返回MSP_SUCCESS,否则返回错误代码,详见错误码列表
备注
以查询上行流量为例,获取到的是本次合成当前累计的上行流量。下行流量查询与此相似。
参见
const char * para_name = "sid";
char para_value[33] = {'\0'};
unsigned int value_len = 33;
int ret = QTTSGetParam ( sessionID, para_name, para_value, &value_len );
if( MSP_SUCCESS != ret )
{
    printf( “QTTSGetParam failed, error code is: %d”, ret );
}
.
const char* MSPAPI QTTSSessionBegin ( const char *  params,
int *  errorCode 
)

开始一次语音合成,分配语音合成资源。

参数
params[in]传入的参数列表,支持以下参数:
参数 参数说明
voice_name 发音人。如男声、女声、童声等。 详见《发音人》列表
speed 合成音频语速 0-100之间的整数,数值越大语速越快。默认为50
volume 合成音频音量 0-100之间的整数,数值越大音量越大。默认为50
pitch 合成音频音调 0-100之间的整数,数值越大音调越高。默认为50
text_encoding 合成文本编码 GB2312;GBK;BIG5;UNICODE;GB18030;UTF8
background_sound 合成音频中的背景音 0:无背景音乐 1:有背景音乐。默认为0
aue 音频编码格式和压缩等级 编码算法:raw;speex;speex-wb;
编码等级:raw:无等级。speex系列:0-10;
默认为speex-wb;7
speex对应sample_rate=8000
speex-wb对应sample_rate=16000
sample_rate 合成音频格式 8000
16000
默认为16000
ttp 合成文本类型 text: 普通格式文本;ssml:ssml格式文本。默认为text
rdn 合成音频数字发音 0:数值优先,1:完全数值,2:完全字符串,3:字符串优先。
默认为0
注意:没有默认值的参数必须由外部设定其值
发音人列表:
发音人 参数名称 语种/方言 音色
小燕 xiaoyan 普通话 青年女声
燕平 yanping 普通话 青年女声
宇峰 yufeng 普通话 青年男声
晓婧 jinger 普通话 青年女声
唐老鸭 donaldduck 普通话 卡通
许小宝 babyxu 普通话 童声
楠楠 nannan 普通话 童声
晓梦 xiaomeng 普通话 青年女声
晓琳 xiaolin 台湾普通话 青年女声
晓倩 xiaoqian 东北话 青年女声
晓蓉 xiaorong 四川话 青年女声
小坤 xiaokun 河南话 青年男声
小强 xiaoqiang 湖南话 青年男声
晓美 xiaomei 粤语 青年女声
大龙 dalong 粤语 青年男声
Catherine catherine 美式纯英文 青年女声
John john 美式纯英文 青年男声
henry henry 英文 青年男声
玛丽安 Mariane 法语 青年女声
阿拉本 Allabent 俄罗斯语 青年女声
加芙列拉 Gabriela 西班牙语 青年女声
艾伯哈 Abha 印地语 青年女声
小云 XiaoYun 越南语 青年女声
errorCode[out]调用成功返回MSP_SUCCESS,否则返回错误代码,详见错误码列表
返回
函数调用成功返回字符串格式的sessionID,失败返回NULL。sessionID是本次合成的句柄。
备注
参数只在本次合成中生效。
参见
const char * ssb_param = "voice_name = xiaoyan, aue = speex-wb;7, sample_rate = 16000, speed = 50, volume = 50, pitch = 50, rdn = 2";
int ret = -1;
const char * sessionID = QTTSSessionBegin( ssb_param, &ret );
if( MSP_SUCCESS != ret )
{
    printf( “QTTSSessionBegin failed, error code is: %d”, ret );
}
.
int MSPAPI QTTSSessionEnd ( const char *  sessionID,
const char *  hints 
)

结束本次语音合成。

参数
sessionID[in]由QTTSSessionBegin返回的句柄。
hints[in]结束本次语音合成的原因描述,为用户自定义内容。
返回
函数调用成功返回MSP_SUCCESS,否则返回错误代码,详见错误码列表
备注
本接口和QTTSSessionBegin对应,调用此接口后,该句柄对应的相关资源(参数,合成文本,实例等)都会被释放,用户不应再使用该句柄。
参见
int ret = QTTSSessionEnd ( sessionID, “normal end” );
if( MSP_SUCCESS != ret )
{
    printf( “QTTSSessionEnd failed, error code is: %d”, ret );
}
.
int MSPAPI QTTSTextPut ( const char *  sessionID,
const char *  textString,
unsigned int  textLen,
const char *  params 
)

写入待合成的文本。

参数
sessionID[in]由QTTSSessionBegin返回的句柄。
textString[in]字符串指针。指向待合成的文本字符串。
textLen[in]合成文本长度,最大支持8192个字节(不含’\0’)。
params[in]本次合成所用的参数,只对本次合成的文本有效。
返回
函数调用成功返回MSP_SUCCESS,否则返回错误代码。详见错误码列表
参见
const char* src_text = “科大讯飞股份有限公司”;
unsigned int text_len = strlen(src_text); //textLen参数为合成文本所占字节数
int ret = QTTSTextPut( sessionID, src_text, text_len, NULL );
if( MSP_SUCCESS != ret )
{
    printf( “QTTSTextPut failed, error code is: %d”, ret );
}
.
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/qtts_8h_source.html ================================================ MSC for Windows&Linux API: qtts.h 源文件
MSC for Windows&Linux API
qtts.h
浏览该文件的文档.
1 
92 const char* MSPAPI QTTSSessionBegin(const char* params, int* errorCode);
93 
94 
115 int MSPAPI QTTSTextPut(const char* sessionID, const char* textString, unsigned int textLen, const char* params);
116 
117 
152 const void* MSPAPI QTTSAudioGet(const char* sessionID, unsigned int* audioLen, int* synthStatus, int* errorCode);
153 
154 
155 
156 
188 int MSPAPI QTTSGetParam(const char* sessionID, const char* paramName, char* paramValue, unsigned int* valueLen);
206 int MSPAPI QTTSSessionEnd(const char* sessionID, const char* hints);
207 
227 //const char* MSPAPI QTTSAudioInfo(const char* sessionID,int* errorCode);
228 
229 
const char *MSPAPI QTTSSessionBegin(const char *params, int *errorCode)
开始一次语音合成,分配语音合成资源。
const void *MSPAPI QTTSAudioGet(const char *sessionID, unsigned int *audioLen, int *synthStatus, int *errorCode)
获取合成音频。
int MSPAPI QTTSSessionEnd(const char *sessionID, const char *hints)
结束本次语音合成。
int MSPAPI QTTSGetParam(const char *sessionID, const char *paramName, char *paramValue, unsigned int *valueLen)
获取当前语音合成信息,如当前合成音频对应文本结束位置、上行流量、下行流量等。
int MSPAPI QTTSTextPut(const char *sessionID, const char *textString, unsigned int textLen, const char *params)
写入待合成的文本。
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/all_0.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/all_0.js ================================================ var searchData= [ ['ad',['aD',['../jquery_8js.html#ad223f5fba68c41c1236671ac5c5b0fcb',1,'jquery.js']]], ['all_5f0_2ejs',['all_0.js',['../all__0_8js.html',1,'']]], ['all_5f1_2ejs',['all_1.js',['../all__1_8js.html',1,'']]], ['am',['aM',['../jquery_8js.html#a8cc6111a5def3ea889157d13fb9a9672',1,'jquery.js']]], ['ap',['ap',['../jquery_8js.html#a6ddf393cc7f9a8828e197bb0d9916c44',1,'jquery.js']]], ['aq',['aQ',['../jquery_8js.html#a79eb58dc6cdf0aef563d5dc1ded27df5',1,'jquery.js']]], ['au',['au',['../jquery_8js.html#a4fd8ddfab07c8d7c7cae0ab0e052cad3',1,'jquery.js']]], ['az',['aZ',['../jquery_8js.html#ac87125cdee1a5e57da4ef619af49bc7d',1,'jquery.js']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/all_1.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/all_1.js ================================================ var searchData= [ ['b',['b',['../jquery_8js.html#aa4026ad5544b958e54ce5e106fa1c805',1,'b(): jquery.js'],['../jquery_8js.html#a2fa551895933fae935a0a6b87282241d',1,'b(function(){if(!b.support.reliableMarginRight){b.cssHooks.marginRight={get:function(bw, bv){var e;b.swap(bw,{display:"inline-block"}, function(){if(bv){e=Z(bw,"margin-right","marginRight")}else{e=bw.style.marginRight}});return e}}}}): jquery.js']]], ['bb',['bb',['../jquery_8js.html#a1d6558865876e1c8cca029fce41a4bdb',1,'jquery.js']]], ['bq',['bq',['../jquery_8js.html#af6ee77c71b2c89bdb365145ac5ad1219',1,'jquery.js']]], ['bs',['bs',['../jquery_8js.html#ae77642f8ef73fb9c20c2a737d956acda',1,'jquery.js']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/all_10.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/all_10.js ================================================ var searchData= [ ['updatestripes',['updateStripes',['../dynsections_8js.html#a8f7493ad859d4fbf2523917511ee7177',1,'dynsections.js']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/all_11.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/all_11.js ================================================ var searchData= [ ['z',['Z',['../jquery_8js.html#adc18d83abfd9f87d396e8fd6b6ac0fe1',1,'jquery.js']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/all_2.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/all_2.js ================================================ var searchData= [ ['c',['c',['../jquery_8js.html#abce695e0af988ece0826d9ad59b8160d',1,'jquery.js']]], ['converttoid',['convertToId',['../search_8js.html#a196a29bd5a5ee7cd5b485e0753a49e57',1,'search.js']]], ['createresults',['createResults',['../search_8js.html#a6b2c651120de3ed1dcf0d85341d51895',1,'search.js']]], ['css',['css',['../jquery_8js.html#a89ad527fcd82c01ebb587332f5b4fcd4',1,'jquery.js']]], ['curcss',['curCSS',['../jquery_8js.html#a88b21f8ba3af86d6981b1da520ece33b',1,'jquery.js']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/all_3.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/all_3.js ================================================ var searchData= [ ['dynsections_2ejs',['dynsections.js',['../dynsections_8js.html',1,'']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/all_4.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/all_4.js ================================================ var searchData= [ ['each',['each',['../jquery_8js.html#a871ff39db627c54c710a3e9909b8234c',1,'jquery.js']]], ['extend',['extend',['../jquery_8js.html#a5fb206c91c64d1be35fde236706eab86',1,'jquery.js']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/all_5.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/all_5.js ================================================ var searchData= [ ['files_5f0_2ejs',['files_0.js',['../files__0_8js.html',1,'']]], ['files_5f1_2ejs',['files_1.js',['../files__1_8js.html',1,'']]], ['functions_5f0_2ejs',['functions_0.js',['../functions__0_8js.html',1,'']]], ['functions_5f1_2ejs',['functions_1.js',['../functions__1_8js.html',1,'']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/all_6.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/all_6.js ================================================ var searchData= [ ['getxpos',['getXPos',['../search_8js.html#a76d24aea0009f892f8ccc31d941c0a2b',1,'search.js']]], ['getypos',['getYPos',['../search_8js.html#a8d7b405228661d7b6216b6925d2b8a69',1,'search.js']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/all_7.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/all_7.js ================================================ var searchData= [ ['if',['if',['../jquery_8js.html#a9db6d45a025ad692282fe23e69eeba43',1,'if(!b.support.opacity): jquery.js'],['../jquery_8js.html#a30d3d2cd5b567c9f31b2aa30b9cb3bb8',1,'if(av.defaultView &&av.defaultView.getComputedStyle): jquery.js'],['../jquery_8js.html#a2c54bd8ed7482e89d19331ba61fe221c',1,'if(av.documentElement.currentStyle): jquery.js'],['../jquery_8js.html#a42cbfadee2b4749e8f699ea8d745a0e4',1,'if(b.expr &&b.expr.filters): jquery.js']]], ['indexsectionlabels',['indexSectionLabels',['../searchdata_8js.html#a529972e449c82dc118cbbd3bcf50c44d',1,'searchdata.js']]], ['indexsectionnames',['indexSectionNames',['../searchdata_8js.html#a77149ceed055c6c6ce40973b5bdc19ad',1,'searchdata.js']]], ['indexsectionswithcontent',['indexSectionsWithContent',['../searchdata_8js.html#a6250af3c9b54dee6efc5f55f40c78126',1,'searchdata.js']]], ['init_5fsearch',['init_search',['../search_8js.html#ae95ec7d5d450d0a8d6928a594798aaf4',1,'search.js']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/all_8.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/all_8.js ================================================ var searchData= [ ['jquery_2ejs',['jquery.js',['../jquery_8js.html',1,'']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/all_9.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/all_9.js ================================================ var searchData= [ ['k',['k',['../jquery_8js.html#ab26645c014aa005ecedef329ecf58c99',1,'jquery.js']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/all_a.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/all_a.js ================================================ var searchData= [ ['l',['L',['../jquery_8js.html#a38ee4c0b5f4fe2a18d0c783af540d253',1,'jquery.js']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/all_b.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/all_b.js ================================================ var searchData= [ ['msp_5fcmn_2eh',['msp_cmn.h',['../msp__cmn_8h.html',1,'']]], ['mspgetparam',['MSPGetParam',['../msp__cmn_8h.html#a4d3fa0aad5e761cb2a2afe30ae2a9714',1,'msp_cmn.h']]], ['mspgetversion',['MSPGetVersion',['../msp__cmn_8h.html#a632008aeddf5eba09555920ce38686a4',1,'msp_cmn.h']]], ['msplogin',['MSPLogin',['../msp__cmn_8h.html#a137acfe684fe46cbe5baf19f7d4a7fcc',1,'msp_cmn.h']]], ['msplogout',['MSPLogout',['../msp__cmn_8h.html#a1e0f72cd113b4578afdf3d16ab34463e',1,'msp_cmn.h']]], ['mspsearch',['MSPSearch',['../msp__cmn_8h.html#ae7be2dd2c6ee318524621b952998c14d',1,'msp_cmn.h']]], ['mspuploaddata',['MSPUploadData',['../msp__cmn_8h.html#ada276fa6db4a66342d951820020e4e8f',1,'msp_cmn.h']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/all_c.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/all_c.js ================================================ var searchData= [ ['p',['p',['../jquery_8js.html#a2335e57f79b6acfb6de59c235dc8a83e',1,'jquery.js']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/all_d.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/all_d.js ================================================ var searchData= [ ['qisr_2eh',['qisr.h',['../qisr_8h.html',1,'']]], ['qisraudiowrite',['QISRAudioWrite',['../qisr_8h.html#a47fd2588fe834fa2d51fef1961d7aef4',1,'qisr.h']]], ['qisrgetparam',['QISRGetParam',['../qisr_8h.html#a2081e3cad9a8155c15790a2476be7044',1,'qisr.h']]], ['qisrgetresult',['QISRGetResult',['../qisr_8h.html#a2e7880db4792266a4d1439238c0b2c1b',1,'qisr.h']]], ['qisrsessionbegin',['QISRSessionBegin',['../qisr_8h.html#aaec4a5779275e07c4f7405ed8d739416',1,'qisr.h']]], ['qisrsessionend',['QISRSessionEnd',['../qisr_8h.html#ab50c4114e032100c4093ddd51329fecc',1,'qisr.h']]], ['qmfv_2eh',['qmfv.h',['../qmfv_8h.html',1,'']]], ['qmfvdatawrite',['QMFVDataWrite',['../qmfv_8h.html#a081a01b2add2dfac3010ec7cd8ba5eac',1,'qmfv.h']]], ['qmfvgetparam',['QMFVGetParam',['../qmfv_8h.html#a7174d943c2f1691f6a8c717429d43f8d',1,'qmfv.h']]], ['qmfvgetresult',['QMFVGetResult',['../qmfv_8h.html#aa87716ad6b28326982626c0c6a6ffcbd',1,'qmfv.h']]], ['qmfvsessionbegin',['QMFVSessionBegin',['../qmfv_8h.html#adbe23b402d4c50b4c06f47ca26253be5',1,'qmfv.h']]], ['qmfvsessionend',['QMFVSessionEnd',['../qmfv_8h.html#ad4ea72dd39285348cf26c627d67c6b65',1,'qmfv.h']]], ['qtts_2eh',['qtts.h',['../qtts_8h.html',1,'']]], ['qttsaudioget',['QTTSAudioGet',['../qtts_8h.html#a4e4f6bed4b9e4ea553aa00ccf539c22a',1,'qtts.h']]], ['qttsgetparam',['QTTSGetParam',['../qtts_8h.html#a0812612ff738a828490e4e3db59767e8',1,'qtts.h']]], ['qttssessionbegin',['QTTSSessionBegin',['../qtts_8h.html#a3fba4ad9599445073335851cc9479542',1,'qtts.h']]], ['qttssessionend',['QTTSSessionEnd',['../qtts_8h.html#a75d5047a2a889dbd890d116a6d0b550a',1,'qtts.h']]], ['qttstextput',['QTTSTextPut',['../qtts_8h.html#a5b7d146d6a35341d4d73efd720ae987b',1,'qtts.h']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/all_e.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/all_e.js ================================================ var searchData= [ ['search_2ejs',['search.js',['../search_8js.html',1,'']]], ['searchbox',['SearchBox',['../search_8js.html#a52066106482f8136aa9e0ec859e8188f',1,'search.js']]], ['searchdata',['searchData',['../all__0_8js.html#ad01a7523f103d6242ef9b0451861231e',1,'searchData(): all_0.js'],['../all__1_8js.html#ad01a7523f103d6242ef9b0451861231e',1,'searchData(): all_1.js'],['../files__0_8js.html#ad01a7523f103d6242ef9b0451861231e',1,'searchData(): files_0.js'],['../files__1_8js.html#ad01a7523f103d6242ef9b0451861231e',1,'searchData(): files_1.js'],['../functions__0_8js.html#ad01a7523f103d6242ef9b0451861231e',1,'searchData(): functions_0.js'],['../functions__1_8js.html#ad01a7523f103d6242ef9b0451861231e',1,'searchData(): functions_1.js']]], ['searchdata_2ejs',['searchdata.js',['../searchdata_8js.html',1,'']]], ['searchresults',['SearchResults',['../search_8js.html#a9189b9f7a32b6bc78240f40348f7fe03',1,'search.js']]], ['setclassattr',['setClassAttr',['../search_8js.html#a499422fc054a5278ae32801ec0082c56',1,'search.js']]], ['setkeyactions',['setKeyActions',['../search_8js.html#a98192fa2929bb8e4b0a890a4909ab9b2',1,'search.js']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/all_f.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/all_f.js ================================================ var searchData= [ ['togglefolder',['toggleFolder',['../dynsections_8js.html#af244da4527af2d845dca04f5656376cd',1,'dynsections.js']]], ['toggleinherit',['toggleInherit',['../dynsections_8js.html#ac057b640b17ff32af11ced151c9305b4',1,'dynsections.js']]], ['togglelevel',['toggleLevel',['../dynsections_8js.html#a19f577cc1ba571396a85bb1f48bf4df2',1,'dynsections.js']]], ['togglevisibility',['toggleVisibility',['../dynsections_8js.html#a1922c462474df7dfd18741c961d59a25',1,'dynsections.js']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/files_0.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/files_0.js ================================================ var searchData= [ ['all_5f0_2ejs',['all_0.js',['../all__0_8js.html',1,'']]], ['all_5f1_2ejs',['all_1.js',['../all__1_8js.html',1,'']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/files_1.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/files_1.js ================================================ var searchData= [ ['dynsections_2ejs',['dynsections.js',['../dynsections_8js.html',1,'']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/files_2.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/files_2.js ================================================ var searchData= [ ['files_5f0_2ejs',['files_0.js',['../files__0_8js.html',1,'']]], ['files_5f1_2ejs',['files_1.js',['../files__1_8js.html',1,'']]], ['functions_5f0_2ejs',['functions_0.js',['../functions__0_8js.html',1,'']]], ['functions_5f1_2ejs',['functions_1.js',['../functions__1_8js.html',1,'']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/files_3.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/files_3.js ================================================ var searchData= [ ['jquery_2ejs',['jquery.js',['../jquery_8js.html',1,'']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/files_4.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/files_4.js ================================================ var searchData= [ ['msp_5fcmn_2eh',['msp_cmn.h',['../msp__cmn_8h.html',1,'']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/files_5.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/files_5.js ================================================ var searchData= [ ['qisr_2eh',['qisr.h',['../qisr_8h.html',1,'']]], ['qmfv_2eh',['qmfv.h',['../qmfv_8h.html',1,'']]], ['qtts_2eh',['qtts.h',['../qtts_8h.html',1,'']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/files_6.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/files_6.js ================================================ var searchData= [ ['search_2ejs',['search.js',['../search_8js.html',1,'']]], ['searchdata_2ejs',['searchdata.js',['../searchdata_8js.html',1,'']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/functions_0.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/functions_0.js ================================================ var searchData= [ ['b',['b',['../jquery_8js.html#a2fa551895933fae935a0a6b87282241d',1,'jquery.js']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/functions_1.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/functions_1.js ================================================ var searchData= [ ['converttoid',['convertToId',['../search_8js.html#a196a29bd5a5ee7cd5b485e0753a49e57',1,'search.js']]], ['createresults',['createResults',['../search_8js.html#a6b2c651120de3ed1dcf0d85341d51895',1,'search.js']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/functions_2.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/functions_2.js ================================================ var searchData= [ ['each',['each',['../jquery_8js.html#a871ff39db627c54c710a3e9909b8234c',1,'jquery.js']]], ['extend',['extend',['../jquery_8js.html#a5fb206c91c64d1be35fde236706eab86',1,'jquery.js']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/functions_3.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/functions_3.js ================================================ var searchData= [ ['getxpos',['getXPos',['../search_8js.html#a76d24aea0009f892f8ccc31d941c0a2b',1,'search.js']]], ['getypos',['getYPos',['../search_8js.html#a8d7b405228661d7b6216b6925d2b8a69',1,'search.js']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/functions_4.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/functions_4.js ================================================ var searchData= [ ['if',['if',['../jquery_8js.html#a9db6d45a025ad692282fe23e69eeba43',1,'if(!b.support.opacity): jquery.js'],['../jquery_8js.html#a30d3d2cd5b567c9f31b2aa30b9cb3bb8',1,'if(av.defaultView &&av.defaultView.getComputedStyle): jquery.js'],['../jquery_8js.html#a2c54bd8ed7482e89d19331ba61fe221c',1,'if(av.documentElement.currentStyle): jquery.js'],['../jquery_8js.html#a42cbfadee2b4749e8f699ea8d745a0e4',1,'if(b.expr &&b.expr.filters): jquery.js']]], ['init_5fsearch',['init_search',['../search_8js.html#ae95ec7d5d450d0a8d6928a594798aaf4',1,'search.js']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/functions_5.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/functions_5.js ================================================ var searchData= [ ['mspgetparam',['MSPGetParam',['../msp__cmn_8h.html#a4d3fa0aad5e761cb2a2afe30ae2a9714',1,'msp_cmn.h']]], ['mspgetversion',['MSPGetVersion',['../msp__cmn_8h.html#a632008aeddf5eba09555920ce38686a4',1,'msp_cmn.h']]], ['msplogin',['MSPLogin',['../msp__cmn_8h.html#a137acfe684fe46cbe5baf19f7d4a7fcc',1,'msp_cmn.h']]], ['msplogout',['MSPLogout',['../msp__cmn_8h.html#a1e0f72cd113b4578afdf3d16ab34463e',1,'msp_cmn.h']]], ['mspsearch',['MSPSearch',['../msp__cmn_8h.html#ae7be2dd2c6ee318524621b952998c14d',1,'msp_cmn.h']]], ['mspuploaddata',['MSPUploadData',['../msp__cmn_8h.html#ada276fa6db4a66342d951820020e4e8f',1,'msp_cmn.h']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/functions_6.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/functions_6.js ================================================ var searchData= [ ['p',['p',['../jquery_8js.html#a2335e57f79b6acfb6de59c235dc8a83e',1,'jquery.js']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/functions_7.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/functions_7.js ================================================ var searchData= [ ['qisraudiowrite',['QISRAudioWrite',['../qisr_8h.html#a47fd2588fe834fa2d51fef1961d7aef4',1,'qisr.h']]], ['qisrgetparam',['QISRGetParam',['../qisr_8h.html#a2081e3cad9a8155c15790a2476be7044',1,'qisr.h']]], ['qisrgetresult',['QISRGetResult',['../qisr_8h.html#a2e7880db4792266a4d1439238c0b2c1b',1,'qisr.h']]], ['qisrsessionbegin',['QISRSessionBegin',['../qisr_8h.html#aaec4a5779275e07c4f7405ed8d739416',1,'qisr.h']]], ['qisrsessionend',['QISRSessionEnd',['../qisr_8h.html#ab50c4114e032100c4093ddd51329fecc',1,'qisr.h']]], ['qmfvdatawrite',['QMFVDataWrite',['../qmfv_8h.html#a081a01b2add2dfac3010ec7cd8ba5eac',1,'qmfv.h']]], ['qmfvgetparam',['QMFVGetParam',['../qmfv_8h.html#a7174d943c2f1691f6a8c717429d43f8d',1,'qmfv.h']]], ['qmfvgetresult',['QMFVGetResult',['../qmfv_8h.html#aa87716ad6b28326982626c0c6a6ffcbd',1,'qmfv.h']]], ['qmfvsessionbegin',['QMFVSessionBegin',['../qmfv_8h.html#adbe23b402d4c50b4c06f47ca26253be5',1,'qmfv.h']]], ['qmfvsessionend',['QMFVSessionEnd',['../qmfv_8h.html#ad4ea72dd39285348cf26c627d67c6b65',1,'qmfv.h']]], ['qttsaudioget',['QTTSAudioGet',['../qtts_8h.html#a4e4f6bed4b9e4ea553aa00ccf539c22a',1,'qtts.h']]], ['qttsgetparam',['QTTSGetParam',['../qtts_8h.html#a0812612ff738a828490e4e3db59767e8',1,'qtts.h']]], ['qttssessionbegin',['QTTSSessionBegin',['../qtts_8h.html#a3fba4ad9599445073335851cc9479542',1,'qtts.h']]], ['qttssessionend',['QTTSSessionEnd',['../qtts_8h.html#a75d5047a2a889dbd890d116a6d0b550a',1,'qtts.h']]], ['qttstextput',['QTTSTextPut',['../qtts_8h.html#a5b7d146d6a35341d4d73efd720ae987b',1,'qtts.h']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/functions_8.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/functions_8.js ================================================ var searchData= [ ['searchbox',['SearchBox',['../search_8js.html#a52066106482f8136aa9e0ec859e8188f',1,'search.js']]], ['searchresults',['SearchResults',['../search_8js.html#a9189b9f7a32b6bc78240f40348f7fe03',1,'search.js']]], ['setclassattr',['setClassAttr',['../search_8js.html#a499422fc054a5278ae32801ec0082c56',1,'search.js']]], ['setkeyactions',['setKeyActions',['../search_8js.html#a98192fa2929bb8e4b0a890a4909ab9b2',1,'search.js']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/functions_9.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/functions_9.js ================================================ var searchData= [ ['togglefolder',['toggleFolder',['../dynsections_8js.html#af244da4527af2d845dca04f5656376cd',1,'dynsections.js']]], ['toggleinherit',['toggleInherit',['../dynsections_8js.html#ac057b640b17ff32af11ced151c9305b4',1,'dynsections.js']]], ['togglelevel',['toggleLevel',['../dynsections_8js.html#a19f577cc1ba571396a85bb1f48bf4df2',1,'dynsections.js']]], ['togglevisibility',['toggleVisibility',['../dynsections_8js.html#a1922c462474df7dfd18741c961d59a25',1,'dynsections.js']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/functions_a.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/functions_a.js ================================================ var searchData= [ ['updatestripes',['updateStripes',['../dynsections_8js.html#a8f7493ad859d4fbf2523917511ee7177',1,'dynsections.js']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/nomatches.html ================================================
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/search.css ================================================ /*---------------- Search Box */ #FSearchBox { float: left; } #MSearchBox { white-space : nowrap; position: absolute; float: none; display: inline; margin-top: 8px; right: 0px; width: 170px; z-index: 102; background-color: white; } #MSearchBox .left { display:block; position:absolute; left:10px; width:20px; height:19px; background:url('search_l.png') no-repeat; background-position:right; } #MSearchSelect { display:block; position:absolute; width:20px; height:19px; } .left #MSearchSelect { left:4px; } .right #MSearchSelect { right:5px; } #MSearchField { display:block; position:absolute; height:19px; background:url('search_m.png') repeat-x; border:none; width:111px; margin-left:20px; padding-left:4px; color: #909090; outline: none; font: 9pt Arial, Verdana, sans-serif; } #FSearchBox #MSearchField { margin-left:15px; } #MSearchBox .right { display:block; position:absolute; right:10px; top:0px; width:20px; height:19px; background:url('search_r.png') no-repeat; background-position:left; } #MSearchClose { display: none; position: absolute; top: 4px; background : none; border: none; margin: 0px 4px 0px 0px; padding: 0px 0px; outline: none; } .left #MSearchClose { left: 6px; } .right #MSearchClose { right: 2px; } .MSearchBoxActive #MSearchField { color: #000000; } /*---------------- Search filter selection */ #MSearchSelectWindow { display: none; position: absolute; left: 0; top: 0; border: 1px solid #90A5CE; background-color: #F9FAFC; z-index: 1; padding-top: 4px; padding-bottom: 4px; -moz-border-radius: 4px; -webkit-border-top-left-radius: 4px; -webkit-border-top-right-radius: 4px; -webkit-border-bottom-left-radius: 4px; -webkit-border-bottom-right-radius: 4px; -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); } .SelectItem { font: 8pt Arial, Verdana, sans-serif; padding-left: 2px; padding-right: 12px; border: 0px; } span.SelectionMark { margin-right: 4px; font-family: monospace; outline-style: none; text-decoration: none; } a.SelectItem { display: block; outline-style: none; color: #000000; text-decoration: none; padding-left: 6px; padding-right: 12px; } a.SelectItem:focus, a.SelectItem:active { color: #000000; outline-style: none; text-decoration: none; } a.SelectItem:hover { color: #FFFFFF; background-color: #3D578C; outline-style: none; text-decoration: none; cursor: pointer; display: block; } /*---------------- Search results window */ iframe#MSearchResults { width: 60ex; height: 15em; } #MSearchResultsWindow { display: none; position: absolute; left: 0; top: 0; border: 1px solid #000; background-color: #EEF1F7; } /* ----------------------------------- */ #SRIndex { clear:both; padding-bottom: 15px; } .SREntry { font-size: 10pt; padding-left: 1ex; } .SRPage .SREntry { font-size: 8pt; padding: 1px 5px; } body.SRPage { margin: 5px 2px; } .SRChildren { padding-left: 3ex; padding-bottom: .5em } .SRPage .SRChildren { display: none; } .SRSymbol { font-weight: bold; color: #425E97; font-family: Arial, Verdana, sans-serif; text-decoration: none; outline: none; } a.SRScope { display: block; color: #425E97; font-family: Arial, Verdana, sans-serif; text-decoration: none; outline: none; } a.SRSymbol:focus, a.SRSymbol:active, a.SRScope:focus, a.SRScope:active { text-decoration: underline; } span.SRScope { padding-left: 4px; } .SRPage .SRStatus { padding: 2px 5px; font-size: 8pt; font-style: italic; } .SRResult { display: none; } DIV.searchresults { margin-left: 10px; margin-right: 10px; } /*---------------- External search page results */ .searchresult { background-color: #F0F3F8; } .pages b { color: white; padding: 5px 5px 3px 5px; background-image: url("../tab_a.png"); background-repeat: repeat-x; text-shadow: 0 1px 1px #000000; } .pages { line-height: 17px; margin-left: 4px; text-decoration: none; } .hl { font-weight: bold; } #searchresults { margin-bottom: 20px; } .searchpages { margin-top: 10px; } ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/search.js ================================================ function convertToId(search) { var result = ''; for (i=0;i do a search { this.Search(); } } this.OnSearchSelectKey = function(evt) { var e = (evt) ? evt : window.event; // for IE if (e.keyCode==40 && this.searchIndex0) // Up { this.searchIndex--; this.OnSelectItem(this.searchIndex); } else if (e.keyCode==13 || e.keyCode==27) { this.OnSelectItem(this.searchIndex); this.CloseSelectionWindow(); this.DOMSearchField().focus(); } return false; } // --------- Actions // Closes the results window. this.CloseResultsWindow = function() { this.DOMPopupSearchResultsWindow().style.display = 'none'; this.DOMSearchClose().style.display = 'none'; this.Activate(false); } this.CloseSelectionWindow = function() { this.DOMSearchSelectWindow().style.display = 'none'; } // Performs a search. this.Search = function() { this.keyTimeout = 0; // strip leading whitespace var searchValue = this.DOMSearchField().value.replace(/^ +/, ""); var code = searchValue.toLowerCase().charCodeAt(0); var idxChar = searchValue.substr(0, 1).toLowerCase(); if ( 0xD800 <= code && code <= 0xDBFF && searchValue > 1) // surrogate pair { idxChar = searchValue.substr(0, 2); } var resultsPage; var resultsPageWithSearch; var hasResultsPage; var idx = indexSectionsWithContent[this.searchIndex].indexOf(idxChar); if (idx!=-1) { var hexCode=idx.toString(16); resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + '.html'; resultsPageWithSearch = resultsPage+'?'+escape(searchValue); hasResultsPage = true; } else // nothing available for this search term { resultsPage = this.resultsPath + '/nomatches.html'; resultsPageWithSearch = resultsPage; hasResultsPage = false; } window.frames.MSearchResults.location = resultsPageWithSearch; var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow(); if (domPopupSearchResultsWindow.style.display!='block') { var domSearchBox = this.DOMSearchBox(); this.DOMSearchClose().style.display = 'inline'; if (this.insideFrame) { var domPopupSearchResults = this.DOMPopupSearchResults(); domPopupSearchResultsWindow.style.position = 'relative'; domPopupSearchResultsWindow.style.display = 'block'; var width = document.body.clientWidth - 8; // the -8 is for IE :-( domPopupSearchResultsWindow.style.width = width + 'px'; domPopupSearchResults.style.width = width + 'px'; } else { var domPopupSearchResults = this.DOMPopupSearchResults(); var left = getXPos(domSearchBox) + 150; // domSearchBox.offsetWidth; var top = getYPos(domSearchBox) + 20; // domSearchBox.offsetHeight + 1; domPopupSearchResultsWindow.style.display = 'block'; left -= domPopupSearchResults.offsetWidth; domPopupSearchResultsWindow.style.top = top + 'px'; domPopupSearchResultsWindow.style.left = left + 'px'; } } this.lastSearchValue = searchValue; this.lastResultsPage = resultsPage; } // -------- Activation Functions // Activates or deactivates the search panel, resetting things to // their default values if necessary. this.Activate = function(isActive) { if (isActive || // open it this.DOMPopupSearchResultsWindow().style.display == 'block' ) { this.DOMSearchBox().className = 'MSearchBoxActive'; var searchField = this.DOMSearchField(); if (searchField.value == this.searchLabel) // clear "Search" term upon entry { searchField.value = ''; this.searchActive = true; } } else if (!isActive) // directly remove the panel { this.DOMSearchBox().className = 'MSearchBoxInactive'; this.DOMSearchField().value = this.searchLabel; this.searchActive = false; this.lastSearchValue = '' this.lastResultsPage = ''; } } } // ----------------------------------------------------------------------- // The class that handles everything on the search results page. function SearchResults(name) { // The number of matches from the last run of . this.lastMatchCount = 0; this.lastKey = 0; this.repeatOn = false; // Toggles the visibility of the passed element ID. this.FindChildElement = function(id) { var parentElement = document.getElementById(id); var element = parentElement.firstChild; while (element && element!=parentElement) { if (element.nodeName == 'DIV' && element.className == 'SRChildren') { return element; } if (element.nodeName == 'DIV' && element.hasChildNodes()) { element = element.firstChild; } else if (element.nextSibling) { element = element.nextSibling; } else { do { element = element.parentNode; } while (element && element!=parentElement && !element.nextSibling); if (element && element!=parentElement) { element = element.nextSibling; } } } } this.Toggle = function(id) { var element = this.FindChildElement(id); if (element) { if (element.style.display == 'block') { element.style.display = 'none'; } else { element.style.display = 'block'; } } } // Searches for the passed string. If there is no parameter, // it takes it from the URL query. // // Always returns true, since other documents may try to call it // and that may or may not be possible. this.Search = function(search) { if (!search) // get search word from URL { search = window.location.search; search = search.substring(1); // Remove the leading '?' search = unescape(search); } search = search.replace(/^ +/, ""); // strip leading spaces search = search.replace(/ +$/, ""); // strip trailing spaces search = search.toLowerCase(); search = convertToId(search); var resultRows = document.getElementsByTagName("div"); var matches = 0; var i = 0; while (i < resultRows.length) { var row = resultRows.item(i); if (row.className == "SRResult") { var rowMatchName = row.id.toLowerCase(); rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); // strip 'sr123_' if (search.length<=rowMatchName.length && rowMatchName.substr(0, search.length)==search) { row.style.display = 'block'; matches++; } else { row.style.display = 'none'; } } i++; } document.getElementById("Searching").style.display='none'; if (matches == 0) // no results { document.getElementById("NoMatches").style.display='block'; } else // at least one result { document.getElementById("NoMatches").style.display='none'; } this.lastMatchCount = matches; return true; } // return the first item with index index or higher that is visible this.NavNext = function(index) { var focusItem; while (1) { var focusName = 'Item'+index; focusItem = document.getElementById(focusName); if (focusItem && focusItem.parentNode.parentNode.style.display=='block') { break; } else if (!focusItem) // last element { break; } focusItem=null; index++; } return focusItem; } this.NavPrev = function(index) { var focusItem; while (1) { var focusName = 'Item'+index; focusItem = document.getElementById(focusName); if (focusItem && focusItem.parentNode.parentNode.style.display=='block') { break; } else if (!focusItem) // last element { break; } focusItem=null; index--; } return focusItem; } this.ProcessKeys = function(e) { if (e.type == "keydown") { this.repeatOn = false; this.lastKey = e.keyCode; } else if (e.type == "keypress") { if (!this.repeatOn) { if (this.lastKey) this.repeatOn = true; return false; // ignore first keypress after keydown } } else if (e.type == "keyup") { this.lastKey = 0; this.repeatOn = false; } return this.lastKey!=0; } this.Nav = function(evt,itemIndex) { var e = (evt) ? evt : window.event; // for IE if (e.keyCode==13) return true; if (!this.ProcessKeys(e)) return false; if (this.lastKey==38) // Up { var newIndex = itemIndex-1; var focusItem = this.NavPrev(newIndex); if (focusItem) { var child = this.FindChildElement(focusItem.parentNode.parentNode.id); if (child && child.style.display == 'block') // children visible { var n=0; var tmpElem; while (1) // search for last child { tmpElem = document.getElementById('Item'+newIndex+'_c'+n); if (tmpElem) { focusItem = tmpElem; } else // found it! { break; } n++; } } } if (focusItem) { focusItem.focus(); } else // return focus to search field { parent.document.getElementById("MSearchField").focus(); } } else if (this.lastKey==40) // Down { var newIndex = itemIndex+1; var focusItem; var item = document.getElementById('Item'+itemIndex); var elem = this.FindChildElement(item.parentNode.parentNode.id); if (elem && elem.style.display == 'block') // children visible { focusItem = document.getElementById('Item'+itemIndex+'_c0'); } if (!focusItem) focusItem = this.NavNext(newIndex); if (focusItem) focusItem.focus(); } else if (this.lastKey==39) // Right { var item = document.getElementById('Item'+itemIndex); var elem = this.FindChildElement(item.parentNode.parentNode.id); if (elem) elem.style.display = 'block'; } else if (this.lastKey==37) // Left { var item = document.getElementById('Item'+itemIndex); var elem = this.FindChildElement(item.parentNode.parentNode.id); if (elem) elem.style.display = 'none'; } else if (this.lastKey==27) // Escape { parent.searchBox.CloseResultsWindow(); parent.document.getElementById("MSearchField").focus(); } else if (this.lastKey==13) // Enter { return true; } return false; } this.NavChild = function(evt,itemIndex,childIndex) { var e = (evt) ? evt : window.event; // for IE if (e.keyCode==13) return true; if (!this.ProcessKeys(e)) return false; if (this.lastKey==38) // Up { if (childIndex>0) { var newIndex = childIndex-1; document.getElementById('Item'+itemIndex+'_c'+newIndex).focus(); } else // already at first child, jump to parent { document.getElementById('Item'+itemIndex).focus(); } } else if (this.lastKey==40) // Down { var newIndex = childIndex+1; var elem = document.getElementById('Item'+itemIndex+'_c'+newIndex); if (!elem) // last child, jump to parent next parent { elem = this.NavNext(itemIndex+1); } if (elem) { elem.focus(); } } else if (this.lastKey==27) // Escape { parent.searchBox.CloseResultsWindow(); parent.document.getElementById("MSearchField").focus(); } else if (this.lastKey==13) // Enter { return true; } return false; } } function setKeyActions(elem,action) { elem.setAttribute('onkeydown',action); elem.setAttribute('onkeypress',action); elem.setAttribute('onkeyup',action); } function setClassAttr(elem,attr) { elem.setAttribute('class',attr); elem.setAttribute('className',attr); } function createResults() { var results = document.getElementById("SRResults"); for (var e=0; e
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/variables_0.js ================================================ var searchData= [ ['ad',['aD',['../jquery_8js.html#ad223f5fba68c41c1236671ac5c5b0fcb',1,'jquery.js']]], ['am',['aM',['../jquery_8js.html#a8cc6111a5def3ea889157d13fb9a9672',1,'jquery.js']]], ['ap',['ap',['../jquery_8js.html#a6ddf393cc7f9a8828e197bb0d9916c44',1,'jquery.js']]], ['aq',['aQ',['../jquery_8js.html#a79eb58dc6cdf0aef563d5dc1ded27df5',1,'jquery.js']]], ['au',['au',['../jquery_8js.html#a4fd8ddfab07c8d7c7cae0ab0e052cad3',1,'jquery.js']]], ['az',['aZ',['../jquery_8js.html#ac87125cdee1a5e57da4ef619af49bc7d',1,'jquery.js']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/variables_1.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/variables_1.js ================================================ var searchData= [ ['b',['b',['../jquery_8js.html#aa4026ad5544b958e54ce5e106fa1c805',1,'jquery.js']]], ['bb',['bb',['../jquery_8js.html#a1d6558865876e1c8cca029fce41a4bdb',1,'jquery.js']]], ['bq',['bq',['../jquery_8js.html#af6ee77c71b2c89bdb365145ac5ad1219',1,'jquery.js']]], ['bs',['bs',['../jquery_8js.html#ae77642f8ef73fb9c20c2a737d956acda',1,'jquery.js']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/variables_2.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/variables_2.js ================================================ var searchData= [ ['c',['c',['../jquery_8js.html#abce695e0af988ece0826d9ad59b8160d',1,'jquery.js']]], ['css',['css',['../jquery_8js.html#a89ad527fcd82c01ebb587332f5b4fcd4',1,'jquery.js']]], ['curcss',['curCSS',['../jquery_8js.html#a88b21f8ba3af86d6981b1da520ece33b',1,'jquery.js']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/variables_3.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/variables_3.js ================================================ var searchData= [ ['indexsectionlabels',['indexSectionLabels',['../searchdata_8js.html#a529972e449c82dc118cbbd3bcf50c44d',1,'searchdata.js']]], ['indexsectionnames',['indexSectionNames',['../searchdata_8js.html#a77149ceed055c6c6ce40973b5bdc19ad',1,'searchdata.js']]], ['indexsectionswithcontent',['indexSectionsWithContent',['../searchdata_8js.html#a6250af3c9b54dee6efc5f55f40c78126',1,'searchdata.js']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/variables_4.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/variables_4.js ================================================ var searchData= [ ['k',['k',['../jquery_8js.html#ab26645c014aa005ecedef329ecf58c99',1,'jquery.js']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/variables_5.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/variables_5.js ================================================ var searchData= [ ['l',['L',['../jquery_8js.html#a38ee4c0b5f4fe2a18d0c783af540d253',1,'jquery.js']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/variables_6.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/variables_6.js ================================================ var searchData= [ ['searchdata',['searchData',['../all__0_8js.html#ad01a7523f103d6242ef9b0451861231e',1,'searchData(): all_0.js'],['../all__1_8js.html#ad01a7523f103d6242ef9b0451861231e',1,'searchData(): all_1.js'],['../files__0_8js.html#ad01a7523f103d6242ef9b0451861231e',1,'searchData(): files_0.js'],['../files__1_8js.html#ad01a7523f103d6242ef9b0451861231e',1,'searchData(): files_1.js'],['../functions__0_8js.html#ad01a7523f103d6242ef9b0451861231e',1,'searchData(): functions_0.js'],['../functions__1_8js.html#ad01a7523f103d6242ef9b0451861231e',1,'searchData(): functions_1.js']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/variables_7.html ================================================
载入中...
搜索中...
未找到
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search/variables_7.js ================================================ var searchData= [ ['z',['Z',['../jquery_8js.html#adc18d83abfd9f87d396e8fd6b6ac0fe1',1,'jquery.js']]] ]; ================================================ FILE: xf/doc/iFlytek MSC Reference Manual/search_8js.html ================================================ MSC for Windows&Linux API: iFlytek MSC Reference Manual/search/search.js 文件参考
MSC for Windows&Linux API
search.js 文件参考

函数

function convertToId (search)
 
function getXPos (item)
 
function getYPos (item)
 
function SearchBox (name, resultsPath, inFrame, label)
 
function SearchResults (name)
 
function setKeyActions (elem, action)
 
function setClassAttr (elem, attr)
 
function createResults ()
 
function init_search ()
 

函数说明

function convertToId (   search)
function createResults ( )
function getXPos (   item)
function getYPos (   item)
function init_search ( )
function SearchBox (   name,
  resultsPath,
  inFrame,
  label 
)
function SearchResults (   name)
function setClassAttr (   elem,
  attr 
)
function setKeyActions (   elem,
  action 
)
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/searchdata_8js.html ================================================ MSC for Windows&Linux API: iFlytek MSC Reference Manual/search/searchdata.js 文件参考
MSC for Windows&Linux API
searchdata.js 文件参考

变量

var indexSectionsWithContent
 
var indexSectionNames
 
var indexSectionLabels
 

变量说明

var indexSectionLabels
初始值:
=
{
0: "全部",
1: "文件",
2: "函数"
}
var indexSectionNames
初始值:
=
{
0: "all",
1: "files",
2: "functions"
}
var indexSectionsWithContent
初始值:
=
{
0: "mq",
1: "mq",
2: "mq"
}
================================================ FILE: xf/doc/iFlytek MSC Reference Manual/tabs.css ================================================ .tabs, .tabs2, .tabs3 { background-image: url('tab_b.png'); width: 100%; z-index: 101; font-size: 13px; font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; } .tabs2 { font-size: 10px; } .tabs3 { font-size: 9px; } .tablist { margin: 0; padding: 0; display: table; } .tablist li { float: left; display: table-cell; background-image: url('tab_b.png'); line-height: 36px; list-style: none; } .tablist a { display: block; padding: 0 20px; font-weight: bold; background-image:url('tab_s.png'); background-repeat:no-repeat; background-position:right; color: #283A5D; text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); text-decoration: none; outline: none; } .tabs3 .tablist a { padding: 0 10px; } .tablist a:hover { background-image: url('tab_h.png'); background-repeat:repeat-x; color: #fff; text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); text-decoration: none; } .tablist li.current a { background-image: url('tab_a.png'); background-repeat:repeat-x; color: #fff; text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); } ================================================ FILE: xf/doc/tts_sample/32bit_make.sh ================================================ #编译32位可执行文件 make clean;make #设置libmsc.so库搜索路径 export LD_LIBRARY_PATH=$(pwd)/../../libs/x86/ ================================================ FILE: xf/doc/tts_sample/64bit_make.sh ================================================ #编译64位可执行文件 make clean;make LINUX64=1 #设置libmsc.so库搜索路径 export LD_LIBRARY_PATH=$(pwd)/../../libs/x64/ ================================================ FILE: xf/doc/tts_sample/Makefile ================================================ #common makefile header DIR_INC = ../../include DIR_BIN = ../../bin DIR_LIB = ../../libs TARGET = tts_sample BIN_TARGET = $(DIR_BIN)/$(TARGET) CROSS_COMPILE = CFLAGS = -g -Wall -I$(DIR_INC) ifdef LINUX64 LDFLAGS := -L$(DIR_LIB)/x64 else LDFLAGS := -L$(DIR_LIB)/x86 endif LDFLAGS += -lmsc -lrt -ldl -lpthread OBJECTS := $(patsubst %.c,%.o,$(wildcard *.c)) $(BIN_TARGET) : $(OBJECTS) $(CROSS_COMPILE)gcc $(CFLAGS) $^ -o $@ $(LDFLAGS) %.o : %.c $(CROSS_COMPILE)gcc -c $(CFLAGS) $< -o $@ clean: @rm -f *.o $(BIN_TARGET) .PHONY:clean #common makefile foot ================================================ FILE: xf/doc/tts_sample/tts_sample.c ================================================ /* * 语音合成(Text To Speech,TTS)技术能够自动将任意文字实时转换为连续的 * 自然语音,是一种能够在任何时间、任何地点,向任何人提供语音信息服务的 * 高效便捷手段,非常符合信息时代海量数据、动态更新和个性化查询的需求。 */ #include #include #include #include #include "qtts.h" #include "msp_cmn.h" #include "msp_errors.h" /* wav音频头部格式 */ typedef struct _wave_pcm_hdr { char riff[4]; // = "RIFF" int size_8; // = FileSize - 8 char wave[4]; // = "WAVE" char fmt[4]; // = "fmt " int fmt_size; // = 下一个结构体的大小 : 16 short int format_tag; // = PCM : 1 short int channels; // = 通道数 : 1 int samples_per_sec; // = 采样率 : 8000 | 6000 | 11025 | 16000 int avg_bytes_per_sec; // = 每秒字节数 : samples_per_sec * bits_per_sample / 8 short int block_align; // = 每采样点字节数 : wBitsPerSample / 8 short int bits_per_sample; // = 量化比特数: 8 | 16 char data[4]; // = "data"; int data_size; // = 纯数据长度 : FileSize - 44 } wave_pcm_hdr; /* 默认wav音频头部数据 */ wave_pcm_hdr default_wav_hdr = { { 'R', 'I', 'F', 'F' }, 0, {'W', 'A', 'V', 'E'}, {'f', 'm', 't', ' '}, 16, 1, 1, 16000, 32000, 2, 16, {'d', 'a', 't', 'a'}, 0 }; /* 文本合成 */ int text_to_speech(const char* src_text, const char* des_path, const char* params) { int ret = -1; FILE* fp = NULL; const char* sessionID = NULL; unsigned int audio_len = 0; wave_pcm_hdr wav_hdr = default_wav_hdr; int synth_status = MSP_TTS_FLAG_STILL_HAVE_DATA; if (NULL == src_text || NULL == des_path) { printf("params is error!\n"); return ret; } fp = fopen(des_path, "wb"); if (NULL == fp) { printf("open %s error.\n", des_path); return ret; } /* 开始合成 */ sessionID = QTTSSessionBegin(params, &ret); if (MSP_SUCCESS != ret) { printf("QTTSSessionBegin failed, error code: %d.\n", ret); fclose(fp); return ret; } ret = QTTSTextPut(sessionID, src_text, (unsigned int)strlen(src_text), NULL); if (MSP_SUCCESS != ret) { printf("QTTSTextPut failed, error code: %d.\n",ret); QTTSSessionEnd(sessionID, "TextPutError"); fclose(fp); return ret; } printf("正在合成 ...\n"); fwrite(&wav_hdr, sizeof(wav_hdr) ,1, fp); //添加wav音频头,使用采样率为16000 while (1) { /* 获取合成音频 */ const void* data = QTTSAudioGet(sessionID, &audio_len, &synth_status, &ret); if (MSP_SUCCESS != ret) break; if (NULL != data) { fwrite(data, audio_len, 1, fp); wav_hdr.data_size += audio_len; //计算data_size大小 } if (MSP_TTS_FLAG_DATA_END == synth_status) break; printf(">"); usleep(150*1000); //防止频繁占用CPU }//合成状态synth_status取值请参阅《讯飞语音云API文档》 printf("\n"); if (MSP_SUCCESS != ret) { printf("QTTSAudioGet failed, error code: %d.\n",ret); QTTSSessionEnd(sessionID, "AudioGetError"); fclose(fp); return ret; } /* 修正wav文件头数据的大小 */ wav_hdr.size_8 += wav_hdr.data_size + (sizeof(wav_hdr) - 8); /* 将修正过的数据写回文件头部,音频文件为wav格式 */ fseek(fp, 4, 0); fwrite(&wav_hdr.size_8,sizeof(wav_hdr.size_8), 1, fp); //写入size_8的值 fseek(fp, 40, 0); //将文件指针偏移到存储data_size值的位置 fwrite(&wav_hdr.data_size,sizeof(wav_hdr.data_size), 1, fp); //写入data_size的值 fclose(fp); fp = NULL; /* 合成完毕 */ ret = QTTSSessionEnd(sessionID, "Normal"); if (MSP_SUCCESS != ret) { printf("QTTSSessionEnd failed, error code: %d.\n",ret); } return ret; } int main(int argc, char* argv[]) { int ret = MSP_SUCCESS; const char* login_params = "appid = 5808ae7e, work_dir = .";//登录参数,appid与msc库绑定,请勿随意改动 /* * rdn: 合成音频数字发音方式 * volume: 合成音频的音量 * pitch: 合成音频的音调 * speed: 合成音频对应的语速 * voice_name: 合成发音人 * sample_rate: 合成音频采样率 * text_encoding: 合成文本编码格式 * * 详细参数说明请参阅《讯飞语音云MSC--API文档》 */ const char* session_begin_params = "voice_name = xiaoyan, text_encoding = utf8, sample_rate = 16000, speed = 50, volume = 50, pitch = 50, rdn = 2"; const char* filename = "tts_sample.wav"; //合成的语音文件名称 const char* text = "亲爱的用户,您好,这是一个语音合成示例,感谢您对科大讯飞语音技术的支持!科大讯飞是亚太地区最大的语音上市公司,股票代码:002230"; //合成文本 /* 用户登录 */ ret = MSPLogin(NULL, NULL, login_params);//第一个参数是用户名,第二个参数是密码,第三个参数是登录参数,用户名和密码可在http://open.voicecloud.cn注册获取 if (MSP_SUCCESS != ret) { printf("MSPLogin failed, error code: %d.\n", ret); goto exit ;//登录失败,退出登录 } printf("\n###########################################################################\n"); printf("## 语音合成(Text To Speech,TTS)技术能够自动将任意文字实时转换为连续的 ##\n"); printf("## 自然语音,是一种能够在任何时间、任何地点,向任何人提供语音信息服务的 ##\n"); printf("## 高效便捷手段,非常符合信息时代海量数据、动态更新和个性化查询的需求。 ##\n"); printf("###########################################################################\n\n"); /* 文本合成 */ printf("开始合成 ...\n"); ret = text_to_speech(text, filename, session_begin_params); if (MSP_SUCCESS != ret) { printf("text_to_speech failed, error code: %d.\n", ret); } printf("合成完毕\n"); exit: printf("按任意键退出 ...\n"); getchar(); MSPLogout(); //退出登录 return 0; } ================================================ FILE: xf/include/convert.h ================================================ #include #include #include #include #include #include "qtts.h" #include "msp_cmn.h" #include "msp_errors.h" // wav音频头部格式 typedef struct _wave_pcm_hdr { char riff[4]; // = "RIFF" int size_8; // = FileSize - 8 char wave[4]; // = "WAVE" char fmt[4]; // = "fmt " int fmt_size; // = 下一个结构体的大小 : 16 short int format_tag; // = PCM : 1 short int channels; // = 通道数 : 1 int samples_per_sec; // = 采样率 : 8000 | 6000 | 11025 | 16000 int avg_bytes_per_sec; // = 每秒字节数 : samples_per_sec * bits_per_sample / 8 short int block_align; // = 每采样点字节数 : wBitsPerSample / 8 short int bits_per_sample; // = 量化比特数: 8 | 16 char data[4]; // = "data"; int data_size; // = 纯数据长度 : FileSize - 44 } wave_pcm_hdr; // 默认wav音频头部数据 wave_pcm_hdr default_wav_hdr = { { 'R', 'I', 'F', 'F' }, 0, {'W', 'A', 'V', 'E'}, {'f', 'm', 't', ' '}, 16, 1, 1, 8000, 16000, 2, 16, {'d', 'a', 't', 'a'}, 0 }; // 文本合成 int text_to_speech(const char* src_text, const char* des_path, const char* params, int sleep_time) { int ret = -1; FILE* fp = NULL; const char* sessionID = NULL; unsigned int audio_len = 0; wave_pcm_hdr wav_hdr = default_wav_hdr; int synth_status = MSP_TTS_FLAG_STILL_HAVE_DATA; if (NULL == src_text || NULL == des_path) { return ret; } fp = fopen(des_path, "wb"); if (NULL == fp) { return ret; } //开始合成 sessionID = QTTSSessionBegin(params, &ret); if (MSP_SUCCESS != ret) { fclose(fp); return ret; } ret = QTTSTextPut(sessionID, src_text, (unsigned int)strlen(src_text), NULL); if (MSP_SUCCESS != ret) { QTTSSessionEnd(sessionID, "TextPutError"); fclose(fp); return ret; } fwrite(&wav_hdr, sizeof(wav_hdr) ,1, fp); //添加wav音频头,使用采样率为8000 while (1) { /* 获取合成音频 */ const void* data = QTTSAudioGet(sessionID, &audio_len, &synth_status, &ret); if (MSP_SUCCESS != ret) break; if (NULL != data) { fwrite(data, audio_len, 1, fp); wav_hdr.data_size += audio_len; //计算data_size大小 } if (MSP_TTS_FLAG_DATA_END == synth_status) break; usleep(sleep_time); //防止频繁占用CPU }//合成状态synth_status取值请参阅《讯飞语音云API文档》 if (MSP_SUCCESS != ret) { QTTSSessionEnd(sessionID, "AudioGetError"); fclose(fp); return ret; } // 修正wav文件头数据的大小 wav_hdr.size_8 += wav_hdr.data_size + (sizeof(wav_hdr) - 8); // 将修正过的数据写回文件头部,音频文件为wav格式 fseek(fp, 4, 0); fwrite(&wav_hdr.size_8,sizeof(wav_hdr.size_8), 1, fp); //写入size_8的值 fseek(fp, 40, 0); //将文件指针偏移到存储data_size值的位置 fwrite(&wav_hdr.data_size,sizeof(wav_hdr.data_size), 1, fp); //写入data_size的值 fclose(fp); fp = NULL; // 合成完毕 ret = QTTSSessionEnd(sessionID, "Normal"); return ret; } ================================================ FILE: xf/include/msp_cmn.h ================================================ /** * @file msp_cmn.h * @brief Mobile Speech Platform Common Interface Header File * * This file contains the quick common programming interface (API) declarations * of MSP. Developer can include this file in your project to build applications. * For more information, please read the developer guide. * Use of this software is subject to certain restrictions and limitations set * forth in a license agreement entered into between iFLYTEK, Co,LTD. * and the licensee of this software. Please refer to the license * agreement for license use rights and restrictions. * * Copyright (C) 1999 - 2012 by ANHUI USTC iFLYTEK, Co,LTD. * All rights reserved. * * @author Speech Dept. iFLYTEK. * @version 1.0 * @date 2012/09/01 * * @see * * History: * index version date author notes * 0 1.0 2012/09/01 MSC40 Create this file */ #ifndef __MSP_CMN_H__ #define __MSP_CMN_H__ #include "msp_types.h" #ifdef __cplusplus extern "C" { #endif /* C++ */ //#ifdef MSP_WCHAR_SUPPORT /** * @fn Wchar2Mbytes * @brief wchar to mbytes * * User login. * * @return int MSPAPI - Return 0 in success, otherwise return error code. * @param const wchar_t* wcstr - [in] Null-terminated source string(wchar_t *). * @param char* mbstr - [in] Destination string(char *). * @param int len - [in] The maximum number of bytes that can be stored in the multibyte output string. * @see */ char *Wchar2Mbytes(const wchar_t* wcstr); /** * @fn Mbytes2Wchar * @brief mbytes to wchar * * User login. * * @return int MSPAPI - Return 0 in success, otherwise return error code. * @param const char* mbstr - [in] Null-terminated source string(char *). * @param wchar_t* wcstr - [in] Destination string(wchar_t *). * @param int wlen - [in] The maximum number of multibyte characters to convert. * @see */ wchar_t *Mbytes2Wchar(const char *mbstr); //#endif /*MSP_WCHAR_SUPPORT*/ /** * @fn MSPLogin * @brief user login interface * * User login. * * @return int MSPAPI - Return 0 in success, otherwise return error code. * @param const char* usr - [in] user name. * @param const char* pwd - [in] password. * @param const char* params - [in] parameters when user login. * @see */ int MSPAPI MSPLogin(const char* usr, const char* pwd, const char* params); typedef int (MSPAPI *Proc_MSPLogin)(const char* usr, const char* pwd, const char* params); //#ifdef MSP_WCHAR_SUPPORT int MSPAPI MSPLoginW(const wchar_t* usr, const wchar_t* pwd, const wchar_t* params); typedef int (MSPAPI *Proc_MSPLoginW)(const wchar_t* usr, const wchar_t* pwd, const wchar_t* params); //#endif/*MSP_WCHAR_SUPPORT*/ /** * @fn MSPLogout * @brief user logout interface * * User logout * * @return int MSPAPI - Return 0 in success, otherwise return error code. * @see */ int MSPAPI MSPLogout(); typedef int (MSPAPI *Proc_MSPLogout)(); //#ifdef MSP_WCHAR_SUPPORT int MSPAPI MSPLogoutW(); typedef int (MSPAPI *Proc_MSPLogoutW)(); //#endif/*MSP_WCHAR_SUPPORT*/ /** * @fn MSPUpload * @brief Upload User Specific Data * * Upload data such as user config, custom grammar, etc. * * @return int MSPAPI - Return 0 in success, otherwise return error code. * @param const char* dataName - [in] data name, should be unique to diff other data. * @param const char* params - [in] parameters about uploading data. * @param const char* dataID - [in] id of the data to be operated. * @see */ int MSPAPI MSPUpload( const char* dataName, const char* params, const char* dataID); typedef int (MSPAPI* Proc_MSPUpload)( const char* dataName, const char* params, const char* dataID); /** * @fn MSPDownload * @brief Download User Specific Data * * Download data such as user config, etc. * * @return int MSPAPI - Return 0 in success, otherwise return error code. * @param const char* params - [in] parameters about data to be downloaded. * @see */ typedef int (*DownloadStatusCB)(int errorCode, long param1, const void *param2, void *userData); typedef int (*DownloadResultCB)(const void *data, long dataLen, void *userData); int MSPAPI MSPDownload(const char* dataName, const char* params, DownloadStatusCB statusCb, DownloadResultCB resultCb, void*userData); typedef int (MSPAPI* Proc_MSPDownload)(const char* dataName, const char* params, DownloadStatusCB statusCb, DownloadResultCB resultCb, void*userData); int MSPAPI MSPDownloadW(const wchar_t* wdataName, const wchar_t* wparams, DownloadStatusCB statusCb, DownloadResultCB resultCb, void*userData); typedef int (MSPAPI* Proc_MSPDownloadW) (const wchar_t* wdataName, const wchar_t* wparams, DownloadStatusCB statusCb, DownloadResultCB resultCb, void*userData); /** * @fn MSPAppendData * @brief Append Data. * * Write data to msc, such as data to be uploaded, searching text, etc. * * @return int MSPAPI - Return 0 in success, otherwise return error code. * @param void* data - [in] the data buffer pointer, data could be binary. * @param unsigned int dataLen - [in] length of data. * @param unsigned int dataStatus - [in] data status, 2: first or continuous, 4: last. * @see */ int MSPAPI MSPAppendData(void* data, unsigned int dataLen, unsigned int dataStatus); typedef int (MSPAPI* Proc_MSPAppendData)(void* data, unsigned int dataLen, unsigned int dataStatus); /** * @fn MSPGetResult * @brief Get Result * * Get result of uploading, downloading or searching, etc. * * @return const char* MSPAPI - Return result of uploading, downloading or searching, etc. * @param int* rsltLen - [out] Length of result returned. * @param int* rsltStatus - [out] Status of result returned. * @param int* errorCode - [out] Return 0 in success, otherwise return error code. * @see */ const char* MSPAPI MSPGetResult(unsigned int* rsltLen, int* rsltStatus, int *errorCode); typedef const char * (MSPAPI *Proc_MSPGetResult)(unsigned int* rsltLen, int* rsltStatus, int *errorCode); /** * @fn MSPSetParam * @brief set params of msc * * set param of msc * * @return int - Return 0 if success, otherwise return errcode. * @param const char* paramName - [in] param name. * @param const char* paramValue - [in] param value * @see */ int MSPAPI MSPSetParam( const char* paramName, const char* paramValue ); typedef int (MSPAPI *Proc_MSPSetParam)(const char* paramName, const char* paramValue); /** * @fn MSPGetParam * @brief get params of msc * * get param of msc * * @return int - Return 0 if success, otherwise return errcode. * @param const char* paramName - [in] param name. * @param const char* paramValue - [out] param value * @param const char* valueLen - [in/out] param value (buffer) length * @see */ int MSPAPI MSPGetParam( const char *paramName, char *paramValue, unsigned int *valueLen ); typedef int (MSPAPI *Proc_MSPGetParam)( const char *paramName, char *paramValue, unsigned int *valueLen ); /** * @fn MSPUploadData * @brief Upload User Specific Data * * Upload data such as user config, custom grammar, etc. * * @return const char* MSPAPI - data id returned by Server, used for special command. * @param const char* dataName - [in] data name, should be unique to diff other data. * @param void* data - [in] the data buffer pointer, data could be binary. * @param unsigned int dataLen - [in] length of data. * @param const char* params - [in] parameters about uploading data. * @param int* errorCode - [out] Return 0 in success, otherwise return error code. * @see */ const char* MSPAPI MSPUploadData(const char* dataName, void* data, unsigned int dataLen, const char* params, int* errorCode); typedef const char* (MSPAPI* Proc_MSPUploadData)(const char* dataName, void* data, unsigned int dataLen, const char* params, int* errorCode); /** * @fn MSPDownloadData * @brief Download User Specific Data * * Download data such as user config, etc. * * @return const void* MSPAPI - received data buffer pointer, data could be binary, NULL if failed or data does not exsit. * @param const char* params - [in] parameters about data to be downloaded. * @param unsigned int* dataLen - [out] length of received data. * @param int* errorCode - [out] Return 0 in success, otherwise return error code. * @see */ const void* MSPAPI MSPDownloadData(const char* params, unsigned int* dataLen, int* errorCode); typedef const void* (MSPAPI* Proc_MSPDownloadData)(const char* params, unsigned int* dataLen, int* errorCode); //#ifdef MSP_WCHAR_SUPPORT const void* MSPAPI MSPDownloadDataW(const wchar_t* params, unsigned int* dataLen, int* errorCode); typedef const void* (MSPAPI* Proc_MSPDownloadDataW)(const wchar_t* params, unsigned int* dataLen, int* errorCode); //#endif/*MSP_WCHAR_SUPPORT*/ /** * @fn MSPSearch * @brief Search text for result * * Search text content, and got text result * * @return const void* MSPAPI - received data buffer pointer, data could be binary, NULL if failed or data does not exsit. * @param const char* params - [in] parameters about data to be downloaded. * @param unsigned int* dataLen - [out] length of received data. * @param int* errorCode - [out] Return 0 in success, otherwise return error code. * @see */ const char* MSPAPI MSPSearch(const char* params, const char* text, unsigned int* dataLen, int* errorCode); typedef const char* (MSPAPI* Proc_MSPSearch)(const char* params, const char* text, unsigned int* dataLen, int* errorCode); typedef int (*NLPSearchCB)(const char *sessionID, int errorCode, int status, const void* result, long rsltLen, void *userData); const char* MSPAPI MSPNlpSearch(const char* params, const char* text, unsigned int textLen, int *errorCode, NLPSearchCB callback, void *userData); typedef const char* (MSPAPI* Proc_MSPNlpSearch)(const char* params, const char* text, unsigned int textLen, int *errorCode, NLPSearchCB callback, void *userData); int MSPAPI MSPNlpSchCancel(const char *sessionID, const char *hints); /** * @fn MSPRegisterNotify * @brief Register a Callback * * Register a Callback * * @return int - * @param msp_status_ntf_handler statusCb - [in] notify handler * @param void *userData - [in] userData * @see */ typedef void ( *msp_status_ntf_handler)( int type, int status, int param1, const void *param2, void *userData ); int MSPAPI MSPRegisterNotify( msp_status_ntf_handler statusCb, void *userData ); typedef const char* (MSPAPI* Proc_MSPRegisterNotify)( msp_status_ntf_handler statusCb, void *userData ); /** * @fn MSPGetVersion * @brief Get version of MSC or Local Engine * * Get version of MSC or Local Engine * * @return const char * MSPAPI - Return version value if success, NULL if fail. * @param const char *verName - [in] version name, could be "msc", "aitalk", "aisound", "ivw". * @param int *errorCode - [out] Return 0 in success, otherwise return error code. * @see */ const char* MSPAPI MSPGetVersion(const char *verName, int *errorCode); typedef const char* (MSPAPI * Proc_MSPGetVersion)(const char *verName, int *errorCode); #ifdef __cplusplus } /* extern "C" */ #endif /* C++ */ #endif /* __MSP_CMN_H__ */ ================================================ FILE: xf/include/msp_errors.h ================================================ #ifndef __MSP_ERRORS_H__ #define __MSP_ERRORS_H__ #define MSP_HTTP_ERROR(x) ((x) + MSP_ERROR_HTTP_BASE ) enum { MSP_SUCCESS = 0, MSP_ERROR_FAIL = -1, MSP_ERROR_EXCEPTION = -2, /* General errors 10100(0x2774) */ MSP_ERROR_GENERAL = 10100, /* 0x2774 */ MSP_ERROR_OUT_OF_MEMORY = 10101, /* 0x2775 */ MSP_ERROR_FILE_NOT_FOUND = 10102, /* 0x2776 */ MSP_ERROR_NOT_SUPPORT = 10103, /* 0x2777 */ MSP_ERROR_NOT_IMPLEMENT = 10104, /* 0x2778 */ MSP_ERROR_ACCESS = 10105, /* 0x2779 */ MSP_ERROR_INVALID_PARA = 10106, /* 0x277A */ /* ȱٲ */ MSP_ERROR_INVALID_PARA_VALUE = 10107, /* 0x277B */ /* Чֵ */ MSP_ERROR_INVALID_HANDLE = 10108, /* 0x277C */ MSP_ERROR_INVALID_DATA = 10109, /* 0x277D */ MSP_ERROR_NO_LICENSE = 10110, /* 0x277E */ /* Ȩ */ MSP_ERROR_NOT_INIT = 10111, /* 0x277F */ /* δʼ, */ MSP_ERROR_NULL_HANDLE = 10112, /* 0x2780 */ MSP_ERROR_OVERFLOW = 10113, /* 0x2781 */ /* ûģ(10), */ /* ֻڲʱһûвע */ MSP_ERROR_TIME_OUT = 10114, /* 0x2782 */ /* ʱ */ MSP_ERROR_OPEN_FILE = 10115, /* 0x2783 */ MSP_ERROR_NOT_FOUND = 10116, /* 0x2784 */ /* ݿģͲ */ MSP_ERROR_NO_ENOUGH_BUFFER = 10117, /* 0x2785 */ MSP_ERROR_NO_DATA = 10118, /* 0x2786 */ /* ӿͻ˶Ƶλȡʱ */ MSP_ERROR_NO_MORE_DATA = 10119, /* 0x2787 */ MSP_ERROR_NO_RESPONSE_DATA = 10120, /* 0x2788 */ MSP_ERROR_ALREADY_EXIST = 10121, /* 0x2789 */ /* ݿģѴ */ MSP_ERROR_LOAD_MODULE = 10122, /* 0x278A */ MSP_ERROR_BUSY = 10123, /* 0x278B */ MSP_ERROR_INVALID_CONFIG = 10124, /* 0x278C */ MSP_ERROR_VERSION_CHECK = 10125, /* 0x278D */ MSP_ERROR_CANCELED = 10126, /* 0x278E */ MSP_ERROR_INVALID_MEDIA_TYPE = 10127, /* 0x278F */ MSP_ERROR_CONFIG_INITIALIZE = 10128, /* 0x2790 */ MSP_ERROR_CREATE_HANDLE = 10129, /* 0x2791 */ MSP_ERROR_CODING_LIB_NOT_LOAD = 10130, /* 0x2792 */ MSP_ERROR_USER_CANCELLED = 10131, /* 0x2793 */ MSP_ERROR_INVALID_OPERATION = 10132, /* 0x2794 */ MSP_ERROR_MESSAGE_NOT_COMPLETE = 10133, /* 0x2795 */ /* flash */ MSP_ERROR_NO_EID = 10134, /* 0x2795 */ MSP_ERROE_OVER_REQ = 10135, /* 0x2797 */ /* client Redundancy request */ MSP_ERROR_USER_ACTIVE_ABORT = 10136, /* 0x2798 */ /* user abort */ MSP_ERROR_BUSY_GRMBUILDING = 10137, /* 0x2799 */ MSP_ERROR_BUSY_LEXUPDATING = 10138, /* 0x279A */ MSP_ERROR_SESSION_RESET = 10139, /* 0x279B */ /* mscֹỰ׼ش */ MSP_ERROR_BOS_TIMEOUT = 10140, /* 0x279C */ /* VADǰ˵㳬ʱ */ MSP_ERROR_STREAM_FILTER = 10141, /* 0X279D */ /* AIUIǰStream */ /* Error codes of network 10200(0x27D8)*/ MSP_ERROR_NET_GENERAL = 10200, /* 0x27D8 */ MSP_ERROR_NET_OPENSOCK = 10201, /* 0x27D9 */ /* Open socket */ MSP_ERROR_NET_CONNECTSOCK = 10202, /* 0x27DA */ /* Connect socket */ MSP_ERROR_NET_ACCEPTSOCK = 10203, /* 0x27DB */ /* Accept socket */ MSP_ERROR_NET_SENDSOCK = 10204, /* 0x27DC */ /* Send socket data */ MSP_ERROR_NET_RECVSOCK = 10205, /* 0x27DD */ /* Recv socket data */ MSP_ERROR_NET_INVALIDSOCK = 10206, /* 0x27DE */ /* Invalid socket handle */ MSP_ERROR_NET_BADADDRESS = 10207, /* 0x27EF */ /* Bad network address */ MSP_ERROR_NET_BINDSEQUENCE = 10208, /* 0x27E0 */ /* Bind after listen/connect */ MSP_ERROR_NET_NOTOPENSOCK = 10209, /* 0x27E1 */ /* Socket is not opened */ MSP_ERROR_NET_NOTBIND = 10210, /* 0x27E2 */ /* Socket is not bind to an address */ MSP_ERROR_NET_NOTLISTEN = 10211, /* 0x27E3 */ /* Socket is not listening */ MSP_ERROR_NET_CONNECTCLOSE = 10212, /* 0x27E4 */ /* The other side of connection is closed */ MSP_ERROR_NET_NOTDGRAMSOCK = 10213, /* 0x27E5 */ /* The socket is not datagram type */ MSP_ERROR_NET_DNS = 10214, /* 0x27E6 */ /* domain name is invalid or dns server does not function well */ MSP_ERROR_NET_INIT = 10215, /* 0x27E7 */ /* ssl ctx create failed */ /*nfl error*/ MSP_ERROR_NFL_INNER_ERROR = 10216, /* NFL inner error */ MSP_ERROR_MSS_TIME_OUT = 10217, /* MSS TIMEOUT */ MSP_ERROT_CLIENT_TIME_OUT = 10218, /* CLIENT TIMEOUT */ MSP_ERROR_CLIENT_CLOSE = 10219, /* CLIENT CLOSED CONNECTION */ MSP_ERROR_CLIENT_AREA_CHANGE = 10220, MSP_ERROR_NET_SSL_HANDSHAKE = 10221, MSP_ERROR_NET_INVALID_ROOT_CERT = 10222, MSP_ERROR_NET_INVALID_CLIENT_CERT = 10223, MSP_ERROR_NET_INVALID_SERVER_CERT = 10224, MSP_ERROR_NET_INVALID_KEY = 10225, MSP_ERROR_NET_CERT_VERIFY_FAILED = 10226, /* Error codes of mssp message 10300(0x283C) */ MSP_ERROR_MSG_GENERAL = 10300, /* 0x283C */ MSP_ERROR_MSG_PARSE_ERROR = 10301, /* 0x283D */ MSP_ERROR_MSG_BUILD_ERROR = 10302, /* 0x283E */ MSP_ERROR_MSG_PARAM_ERROR = 10303, /* 0x283F */ MSP_ERROR_MSG_CONTENT_EMPTY = 10304, /* 0x2840 */ MSP_ERROR_MSG_INVALID_CONTENT_TYPE = 10305, /* 0x2841 */ MSP_ERROR_MSG_INVALID_CONTENT_LENGTH = 10306, /* 0x2842 */ MSP_ERROR_MSG_INVALID_CONTENT_ENCODE = 10307, /* 0x2843 */ MSP_ERROR_MSG_INVALID_KEY = 10308, /* 0x2844 */ MSP_ERROR_MSG_KEY_EMPTY = 10309, /* 0x2845 */ MSP_ERROR_MSG_SESSION_ID_EMPTY = 10310, /* 0x2846 */ /* ỰIDΪ */ MSP_ERROR_MSG_LOGIN_ID_EMPTY = 10311, /* 0x2847 */ /* ƵIDΪ */ MSP_ERROR_MSG_SYNC_ID_EMPTY = 10312, /* 0x2848 */ MSP_ERROR_MSG_APP_ID_EMPTY = 10313, /* 0x2849 */ MSP_ERROR_MSG_EXTERN_ID_EMPTY = 10314, /* 0x284A */ MSP_ERROR_MSG_INVALID_CMD = 10315, /* 0x284B */ MSP_ERROR_MSG_INVALID_SUBJECT = 10316, /* 0x284C */ MSP_ERROR_MSG_INVALID_VERSION = 10317, /* 0x284D */ MSP_ERROR_MSG_NO_CMD = 10318, /* 0x284E */ MSP_ERROR_MSG_NO_SUBJECT = 10319, /* 0x284F */ MSP_ERROR_MSG_NO_VERSION = 10320, /* 0x2850 */ MSP_ERROR_MSG_MSSP_EMPTY = 10321, /* 0x2851 */ MSP_ERROR_MSG_NEW_RESPONSE = 10322, /* 0x2852 */ MSP_ERROR_MSG_NEW_CONTENT = 10323, /* 0x2853 */ MSP_ERROR_MSG_INVALID_SESSION_ID = 10324, /* 0x2854 */ /* ЧĻỰID(sid) */ MSP_ERROR_MSG_INVALID_CONTENT = 10325, /* 0x2855 */ /* Error codes of DataBase 10400(0x28A0)*/ MSP_ERROR_DB_GENERAL = 10400, /* 0x28A0 */ /* ݿ쳣 */ MSP_ERROR_DB_EXCEPTION = 10401, /* 0x28A1 */ MSP_ERROR_DB_NO_RESULT = 10402, /* 0x28A2 */ /* redisûҵỰID(sid) */ MSP_ERROR_DB_INVALID_USER = 10403, /* 0x28A3 */ MSP_ERROR_DB_INVALID_PWD = 10404, /* 0x28A4 */ MSP_ERROR_DB_CONNECT = 10405, /* 0x28A5 */ MSP_ERROR_DB_INVALID_SQL = 10406, /* 0x28A6 */ MSP_ERROR_DB_INVALID_APPID = 10407, /* 0x28A7 */ MSP_ERROR_DB_NO_UID = 10408, /* Error codes of Resource 10500(0x2904)*/ MSP_ERROR_RES_GENERAL = 10500, /* 0x2904 */ MSP_ERROR_RES_LOAD = 10501, /* 0x2905 */ /* Load resource */ MSP_ERROR_RES_FREE = 10502, /* 0x2906 */ /* Free resource */ MSP_ERROR_RES_MISSING = 10503, /* 0x2907 */ /* Resource File Missing */ MSP_ERROR_RES_INVALID_NAME = 10504, /* 0x2908 */ /* Invalid resource file name */ MSP_ERROR_RES_INVALID_ID = 10505, /* 0x2909 */ /* Invalid resource ID */ MSP_ERROR_RES_INVALID_IMG = 10506, /* 0x290A */ /* Invalid resource image pointer */ MSP_ERROR_RES_WRITE = 10507, /* 0x290B */ /* Write read-only resource */ MSP_ERROR_RES_LEAK = 10508, /* 0x290C */ /* Resource leak out */ MSP_ERROR_RES_HEAD = 10509, /* 0x290D */ /* Resource head currupt */ MSP_ERROR_RES_DATA = 10510, /* 0x290E */ /* Resource data currupt */ MSP_ERROR_RES_SKIP = 10511, /* 0x290F */ /* Resource file skipped */ /* Error codes of TTS 10600(0x2968)*/ MSP_ERROR_TTS_GENERAL = 10600, /* 0x2968 */ MSP_ERROR_TTS_TEXTEND = 10601, /* 0x2969 */ /* Meet text end */ MSP_ERROR_TTS_TEXT_EMPTY = 10602, /* 0x296A */ /* no synth text */ MSP_ERROR_TTS_LTTS_ERROR = 10603, /* 0x296B */ /* Error codes of Recognizer 10700(0x29CC) */ MSP_ERROR_REC_GENERAL = 10700, /* 0x29CC */ /* 쳣 */ MSP_ERROR_REC_INACTIVE = 10701, /* 0x29CD */ MSP_ERROR_REC_GRAMMAR_ERROR = 10702, /* 0x29CE */ MSP_ERROR_REC_NO_ACTIVE_GRAMMARS = 10703, /* 0x29CF */ MSP_ERROR_REC_DUPLICATE_GRAMMAR = 10704, /* 0x29D0 */ MSP_ERROR_REC_INVALID_MEDIA_TYPE = 10705, /* 0x29D1 */ MSP_ERROR_REC_INVALID_LANGUAGE = 10706, /* 0x29D2 */ MSP_ERROR_REC_URI_NOT_FOUND = 10707, /* 0x29D3 */ MSP_ERROR_REC_URI_TIMEOUT = 10708, /* 0x29D4 */ MSP_ERROR_REC_URI_FETCH_ERROR = 10709, /* 0x29D5 */ MSP_ERROR_REC_PROC_MOD = 10710, /* 0x29D6 */ /* Error codes of Speech Detector 10800(0x2A30) */ MSP_ERROR_EP_GENERAL = 10800, /* 0x2A30 */ MSP_ERROR_EP_NO_SESSION_NAME = 10801, /* 0x2A31 */ MSP_ERROR_EP_INACTIVE = 10802, /* 0x2A32 */ MSP_ERROR_EP_INITIALIZED = 10803, /* 0x2A33 */ /* Error codes of TUV */ MSP_ERROR_TUV_GENERAL = 10900, /* 0x2A94 */ MSP_ERROR_TUV_GETHIDPARAM = 10901, /* 0x2A95 */ /* Get Busin Param huanid*/ MSP_ERROR_TUV_TOKEN = 10902, /* 0x2A96 */ /* Get Token */ MSP_ERROR_TUV_CFGFILE = 10903, /* 0x2A97 */ /* Open cfg file */ MSP_ERROR_TUV_RECV_CONTENT = 10904, /* 0x2A98 */ /* received content is error */ MSP_ERROR_TUV_VERFAIL = 10905, /* 0x2A99 */ /* Verify failure */ /* Error codes of IMTV */ MSP_ERROR_LOGIN_SUCCESS = 11000, /* 0x2AF8 */ /* ɹ */ MSP_ERROR_LOGIN_NO_LICENSE = 11001, /* 0x2AF9 */ /* ôûҪ */ MSP_ERROR_LOGIN_SESSIONID_INVALID = 11002, /* 0x2AFA */ /* SessionIdʧЧҪµ¼֤ͨ */ MSP_ERROR_LOGIN_SESSIONID_ERROR = 11003, /* 0x2AFB */ /* SessionIdΪգ߷Ƿ */ MSP_ERROR_LOGIN_UNLOGIN = 11004, /* 0x2AFC */ /* δ¼֤ͨ */ MSP_ERROR_LOGIN_INVALID_USER = 11005, /* 0x2AFD */ /* ûIDЧ */ MSP_ERROR_LOGIN_INVALID_PWD = 11006, /* 0x2AFE */ /* ûЧ */ MSP_ERROR_LOGIN_SYSTEM_ERROR = 11099, /* 0x2B5B */ /* ϵͳ */ /* Error codes of HCR */ MSP_ERROR_HCR_GENERAL = 11100, MSP_ERROR_HCR_RESOURCE_NOT_EXIST = 11101, MSP_ERROR_HCR_CREATE = 11102, MSP_ERROR_HCR_DESTROY = 11103, MSP_ERROR_HCR_START = 11104, MSP_ERROR_HCR_APPEND_STROKES = 11105, MSP_ERROR_HCR_INIT = 11106, MSP_ERROR_HCR_POINT_DECODE = 11107, MSP_ERROR_HCR_DISPATCH = 11108, MSP_ERROR_HCR_GETRESULT = 11109, MSP_ERROR_HCR_RESOURCE = 11110, /* Error Codes using in local engine */ MSP_ERROR_AUTH_NO_LICENSE = 11200, /* 0x2BC0 */ /* Ȩ */ MSP_ERROR_AUTH_NO_ENOUGH_LICENSE = 11201, /* 0x2BC1 */ /* Ȩ */ MSP_ERROR_AUTH_INVALID_LICENSE = 11202, /* 0x2BC2 */ /* ЧȨ */ MSP_ERROR_AUTH_LICENSE_EXPIRED = 11203, /* 0x2BC3 */ /* Ȩ */ MSP_ERROR_AUTH_NEED_MORE_DATA = 11204, /* 0x2BC4 */ /* 豸Ϣ */ MSP_ERROR_AUTH_LICENSE_TO_BE_EXPIRED = 11205, /* 0x2BC5 */ /* ȨڣԴ */ MSP_ERROR_AUTH_INVALID_MACHINE_ID = 11206, /* 0x2BC6 */ /* ЧĻ */ MSP_ERROR_AUTH_LOCAL_ASR_FORBIDDEN = 11207, /* 0x2BC7 */ /* ֹʹñʶ */ MSP_ERROR_AUTH_LOCAL_TTS_FORBIDDEN = 11208, /* 0x2BC8 */ /* ֹʹñغϳ */ MSP_ERROR_AUTH_LOCAL_IVW_FORBIDDEN = 11209, /* 0x2BC9 */ /* ֹʹñػ */ MSP_ERROR_AUTH_APPID_NOT_MATCH = 11210, /* 0x2BCA */ /* ԴappidӦappidƥ */ MSP_ERROR_AUTH_UID_NOT_MATCH = 11211, /* 0x2BCB */ /* Դuid͵¼ûuidƥ */ MSP_ERROR_AUTH_TRIAL_EXPIRED = 11212, /* 0x2BCC */ /* Դ */ MSP_ERROR_AUTH_LOCAL_IFD_FORBIDDEN = 11213, /* 0x2BC9 */ /* ֹʹñ */ /*Error Codes of Authorization*/ MSP_ERROR_AUTH_DVC_NO_LICENSE = 11300, MSP_ERROR_AUTH_DVC_NO_ENOUGH_LICENSE = 11301, MSP_ERROR_AUTH_DVC_INVALID_LICENSE = 11302, MSP_ERROR_AUTH_DVC_LICENSE_EXPIRED = 11303, MSP_ERROR_AUTH_DVC_NEED_MORE_DATA = 11304, MSP_ERROR_AUTH_DVC_LICENSE_TO_BE_EXPIRED = 11305, MSP_ERROR_AUTH_DVC_EXCEED_LICENSE = 11306, /* Error codes of Ise */ MSP_ERROR_ASE_EXCEP_SILENCE = 11401, MSP_ERROR_ASE_EXCEP_SNRATIO = 11402, MSP_ERROR_ASE_EXCEP_PAPERDATA = 11403, MSP_ERROR_ASE_EXCEP_PAPERCONTENTS = 11404, MSP_ERROR_ASE_EXCEP_NOTMONO = 11405, MSP_ERROR_ASE_EXCEP_OTHERS = 11406, MSP_ERROR_ASE_EXCEP_PAPERFMT = 11407, MSP_ERROR_ASE_EXCEP_ULISTWORD = 11408, /* Error codes of IVP */ MSP_ERROR_IVP_GENERAL = 11600, // ں쳣 MSP_ERROR_IVP_EXTRA_RGN_SOPPORT = 11601, // עʱдƵ(9) MSP_ERROR_IVP_TRUNCATED = 11602, // Ƶط(źŲεķ̫󣬶ϵͳԷΧ)¼Ƶ MSP_ERROR_IVP_MUCH_NOISE = 11603, // Ƶȹ MSP_ERROR_IVP_TOO_LOW = 11604, // Ƶ MSP_ERROR_IVP_ZERO_AUDIO = 11605, // Ƶ MSP_ERROR_IVP_UTTER_TOO_SHORT = 11606, // Ƶ̫ MSP_ERROR_IVP_TEXT_NOT_MATCH = 11607, // 1.Ƶıƥ䣬ԭ1.(ڰ¼֮ǰ) // 2.¼¼ƵƵг 3.ȷʵƥ" MSP_ERROR_IVP_NO_ENOUGH_AUDIO = 11608, // Ƶע˵дƵֲʱᱨߵ߼Ƶ MSP_ERROR_IVP_MODEL_NOT_FOUND_IN_HBASE = 11610, // ģhbaseûҵ /* Error codes of Face */ MSP_ERROR_IFR_NOT_FACE_IMAGE = 11700, // Ӧ20200 MSP_ERROR_FACE_IMAGE_FULL_LEFT = 11701, // 󣬶Ӧ20201 MSP_ERROR_FACE_IMAGE_FULL_RIGHT = 11702, // ңӦ20202 MSP_ERROR_IMAGE_CLOCKWISE_WHIRL = 11703, // ˳ʱתӦ20203 MSP_ERROR_IMAGE_COUNTET_CLOCKWISE_WHIRL = 11704, // ʱתӦ20204 MSP_ERROR_VALID_IMAGE_SIZE = 11705, // ͼƬС쳣 Ӧ20205 MSP_ERROR_ILLUMINATION = 11706, // 쳣Ӧ20206 MSP_ERROR_FACE_OCCULTATION = 11707, // ڵӦ20207 MSP_ERROR_FACE_INVALID_MODEL = 11708, // ǷģݣӦ20208 MSP_ERROR_FUSION_INVALID_INPUT_TYPE = 11709, // ͷǷӦ20300 MSP_ERROR_FUSION_NO_ENOUGH_DATA = 11710, // ݲӦ20301 MSP_ERROR_FUSION_ENOUGH_DATA = 11711, // ݹ࣬Ӧ20302 /*Error Codes of AIUI*/ MSP_ERROR_AIUI_CID_EXPIRED = 11800, /* Error codes of http 12000(0x2EE0) */ MSP_ERROR_HTTP_BASE = 12000, /* 0x2EE0 */ MSP_ERROR_HTTP_400 = 12400, MSP_ERROR_HTTP_401 = 12401, MSP_ERROR_HTTP_402 = 12402, MSP_ERROR_HTTP_403 = 12403, MSP_ERROR_HTTP_404 = 12404, MSP_ERROR_HTTP_405 = 12405, MSP_ERROR_HTTP_406 = 12406, MSP_ERROR_HTTP_407 = 12407, MSP_ERROR_HTTP_408 = 12408, MSP_ERROR_HTTP_409 = 12409, MSP_ERROR_HTTP_410 = 12410, MSP_ERROR_HTTP_411 = 12411, MSP_ERROR_HTTP_412 = 12412, MSP_ERROR_HTTP_413 = 12413, MSP_ERROR_HTTP_414 = 12414, MSP_ERROR_HTTP_415 = 12415, MSP_ERROR_HTTP_416 = 12416, MSP_ERROR_HTTP_417 = 12417, MSP_ERROR_HTTP_500 = 12500, MSP_ERROR_HTTP_501 = 12501, MSP_ERROR_HTTP_502 = 12502, MSP_ERROR_HTTP_503 = 12503, MSP_ERROR_HTTP_504 = 12504, MSP_ERROR_HTTP_505 = 12505, /*Error codes of ISV */ MSP_ERROR_ISV_NO_USER = 13000, /* 32C8 */ /* the user doesn't exist */ /* Error codes of Lua scripts */ MSP_ERROR_LUA_BASE = 14000, /* 0x36B0 */ MSP_ERROR_LUA_YIELD = 14001, /* 0x36B1 */ MSP_ERROR_LUA_ERRRUN = 14002, /* 0x36B2 */ MSP_ERROR_LUA_ERRSYNTAX = 14003, /* 0x36B3 */ MSP_ERROR_LUA_ERRMEM = 14004, /* 0x36B4 */ MSP_ERROR_LUA_ERRERR = 14005, /* 0x36B5 */ MSP_ERROR_LUA_INVALID_PARAM = 14006, /* 0x36B6 */ /* Error codes of MMP */ MSP_ERROR_MMP_BASE = 15000, /* 0x3A98 */ MSP_ERROR_MMP_MYSQL_INITFAIL = 15001, /* 0x3A99 */ MSP_ERROR_MMP_REDIS_INITFAIL = 15002, /* 0x3A9A */ MSP_ERROR_MMP_NETDSS_INITFAIL = 15003, /* 0x3A9B */ MSP_ERROR_MMP_TAIR_INITFAIL = 15004, /* 0x3A9C */ MSP_ERROR_MMP_MAIL_SESSION_FAIL = 15006, /* 0x3A9E */ /* ʼ½ʱỰ*/ MSP_ERROR_MMP_MAIL_LOGON_FAIL = 15007, /* 0x3A9F */ /* ʼ½ʱܾ½*/ MSP_ERROR_MMP_MAIL_USER_ILLEGAL = 15008, /* 0x3AA0 */ /* ʼ½ʱûǷ*/ MSP_ERROR_MMP_MAIL_PWD_ERR = 15009, /* 0x3AA1 */ /* ʼ½ʱ*/ MSP_ERROR_MMP_MAIL_SOCKET_ERR = 15010, /* 0x3AA2 */ /* ʼ͹׽ִ*/ MSP_ERROR_MMP_MAIL_INIT_FAIL = 15011, /* 0x3AA3 */ /* ʼʼ*/ MSP_ERROR_MMP_STORE_MNR_NO_INIT = 15012, /* 0x3AA4 */ /* store_managerδʼʼʧ*/ MSP_ERROR_MMP_STORE_MNR_POOL_FULL = 15013, /* 0x3AA5 */ /* store_managerӳ*/ MSP_ERROR_MMP_STRATGY_PARAM_ILLEGAL = 15014, /* 0x3AA6 */ /* ԱʽǷ*/ MSP_ERROR_MMP_STRATGY_PARAM_TOOLOOG = 15015, /* 0x3AA7 */ /* Աʽ̫*/ MSP_ERROR_MMP_PARAM_NULL = 15016, /* 0x3AA8 */ /* Ϊ*/ MSP_ERROR_MMP_ERR_MORE_TOTAL = 15017, /* 0x3AA9 */ /* pmsݿдܱݣ > ܴ*/ MSP_ERROR_MMP_PROC_THRESHOLD = 15018, /* 0x3AAA */ /* ̼طֵô*/ MSP_ERROR_MMP_SERVER_THRESHOLD = 15019, /* 0x3AAB */ /* طֵô*/ MSP_ERROR_MMP_PYTHON_NO_EXIST = 15020, /* 0x3AAC */ /* pythonűļ */ MSP_ERROR_MMP_PYTHON_IMPORT_FAILED = 15021, /* 0x3AAD */ /* pythonű */ MSP_ERROR_MMP_PYTHON_BAD_FUNC = 15022, /* 0x3AAE */ /* pythonűʽ */ MSP_ERROR_MMP_DB_DATA_ILLEGAL = 15023, /* 0x3AAF */ /* ݿеݸʽ */ MSP_ERROR_MMP_REDIS_NOT_CONN = 15024, /* 0x3AB0 */ /* redisûӵ */ MSP_ERROR_MMP_PMA_NOT_FOUND_STRATEGY = 15025, /* 0x3AB1 */ /* ûҵ */ MSP_ERROR_MMP_TAIR_CONNECT = 15026, /* 0x3AB2 */ /* tairȺʧ */ MSP_ERROR_MMP_PMC_SERVINFO_INVALID = 15027, /* Ox3AB3 */ /* pmcķϢѾЧ */ MSP_ERROR_MMP_ALARM_GROUP_NULL = 15028, /* Ox3AB4 */ /* ĶűʼΪ */ MSP_ERROR_MMP_ALARM_CONTXT_NULL = 15029, /* Ox3AB5 */ /* ıΪ */ /* Error codes of MSC(lmod loader) */ MSP_ERROR_LMOD_BASE = 16000, /* 0x3E80 */ MSP_ERROR_LMOD_NOT_FOUND = 16001, /* 0x3E81 */ /* ûҵlmodļ */ MSP_ERROR_LMOD_UNEXPECTED_BIN = 16002, /* 0x3E82 */ /* Чlmod */ MSP_ERROR_LMOD_LOADCODE = 16003, /* 0x3E83 */ /* lmodָʧ */ MSP_ERROR_LMOD_PRECALL = 16004, /* 0x3E84 */ /* ʼlmodʧ */ MSP_ERROR_LMOD_RUNTIME_EXCEPTION = 16005, /* 0x3E85 */ /* lmodʱ쳣 */ MSP_ERROR_LMOD_ALREADY_LOADED = 16006, /* 0x3E86 */ /* lmodظ */ // Error code of Third Business MSP_ERROR_BIZ_BASE = 17000, /* 0x4268 */ /* ҵ */ //Error of Nginx errlog file increase exception MSP_ERROR_NGX_LOG_MORE_TOTEL_SIZE = 18000, /*nginx־С쳣*/ //Error of Flash client when network checking MSP_ERROR_FLASH_NETWORK_CONNECT_FIALED = 19000, /*flashʧ*/ MSP_ERROR_FLASH_NETWORK_CHECK_FIALED = 19001, /*flashӦ쳣Ϣ*/ MSP_ERROR_FLASH_NETWORK_CHECK_TIMEOUT = 19002, /*flash糬ʱ*/ MSP_ERROR_FLASH_NETWORK_CLOSED_EXCEPTION = 19003, /*flash쳣ر*/ /*Error Code Of Speech plus*/ SPEECH_ERROR_NO_NETWORK = 20001, /* Ч*/ SPEECH_ERROR_NETWORK_TIMEOUT = 20002, /* ӳʱ*/ SPEECH_ERROR_NET_EXPECTION = 20003, /* 쳣*/ SPEECH_ERROR_INVALID_RESULT = 20004, /* ЧĽ*/ SPEECH_ERROR_NO_MATCH = 20005, /* ƥ */ SPEECH_ERROR_AUDIO_RECORD = 20006, /* ¼ʧ */ SPEECH_ERROR_NO_SPPECH = 20007, /* δ⵽*/ SPEECH_ERROR_SPEECH_TIMEOUT = 20008, /* Ƶ볬ʱ*/ SPEECH_ERROR_EMPTY_UTTERANCE = 20009, /* Чı */ SPEECH_ERROR_FILE_ACCESS = 20010, /* ļдʧ */ SPEECH_ERROR_PLAY_MEDIA = 20011, /* Ƶʧ */ SPEECH_ERROR_INVALID_PARAM = 20012, /* ЧIJ*/ SPEECH_ERROR_TEXT_OVERFLOW = 20013, /* ı */ SPEECH_ERROR_INVALID_DATA = 20014, /* Ч */ SPEECH_ERROR_LOGIN = 20015, /* ûδ½*/ SPEECH_ERROR_PERMISSION_DENIED = 20016, /* ЧȨ */ SPEECH_ERROR_INTERRUPT = 20017, /* 쳣 */ SPEECH_ERROR_VERSION_LOWER = 20018, /* 汾 */ SPEECH_CLIENT_ERROR_ISUSING = 20019, /* ¼ռ(iOSƽ̨) */ SPEECH_ERROR_SYSTEM_PREINSTALL = 20020, /* ϵͳԤð汾 */ SPEECH_ERROR_UNSATISFIED_LINK = 20021, /* δʵֵNative */ SPEECH_ERROR_UNKNOWN = 20999, /* δ֪ */ SPEECH_ERROR_COMPONENT_NOT_INSTALLED = 21001, /* ûаװ */ SPEECH_ERROR_ENGINE_NOT_SUPPORTED = 21002, /* 治֧ */ SPEECH_ERROR_ENGINE_INIT_FAIL = 21003, /* ʼʧ */ SPEECH_ERROR_ENGINE_CALL_FAIL = 21004, /* ʧ */ SPEECH_ERROR_ENGINE_BUSY = 21005, /* 深æ */ SPEECH_ERROR_LOCAL_NO_INIT = 22001, /* δʼ */ SPEECH_ERROR_LOCAL_RESOURCE = 22002, /* Դ */ SPEECH_ERROR_LOCAL_ENGINE = 22003, /* ڲ */ SPEECH_ERROR_IVW_INTERRUPT = 22004, /* ػ汻쳣 */ /*Error Code Of Local iflytek Engines*/ /*Error Code Of AiTalk*/ /*Error Code Of AiTalk Operation*/ SPEECH_SUCCESS = 0 , // ivErr_OK = 0 /*ɹ״̬*/ SPEECH_ERROR_ASR_CLIENT = 23000, /*ͻӦó*///????????? SPEECH_ERROR_ASR_INVALID_PARA = 23001, /*ЧIJ*/ SPEECH_ERROR_ASR_INVALID_PARA_VALUE = 23002, /*ЧIJֵ*/ SPEECH_ERROR_ASR_OUT_OF_MEMORY = 23003, /*ڴľ*/ SPEECH_ERROR_ASR_CREATE_HANDLE_FAILED = 23004, /*ʧ*/ SPEECH_ERROR_ASR_ENGINE_INIT_FAILED = 23005, /*ʼʧ*/ SPEECH_ERROR_ASR_ENGINE_STARTED = 23006, /*Ѿ*/ SPEECH_ERROR_ASR_ENGINE_UNINIT = 23007, /*δʼ*/ SPEECH_ERROR_ASR_SPEECH_TIMEOUT = 23008, /*ʶʱVADûûм⵽˵㣩*/ SPEECH_ERROR_ASR_NO_RECOGNIZED_RESULT = 23009, /*ʶ*/ SPEECH_ERROR_ASR_INVALID_HANDLE = 23010, /*Чľ*/ SPEECH_ERROR_ASR_FILE_ACCESS = 23011, /*ļʧ*/ /*Error Code Of AiTalk Engine*/ SPEECH_ERROR_AITALK_FALSE = 23100, // ivErr_FALSE = 1 /* For license check */ SPEECH_ERROR_AITALK_PERMISSION_DENIED = 23101, // ivErr_InvSN = 2 /* General */ SPEECH_ERROR_AITALK_INVALID_PARA = 23102, // ivErr_InvArg = 3 SPEECH_ERROR_AITALK_BUFFER_OVERFLOW = 23103, // ivErr_BufferFull = 4 /*Ƶݻ*/ SPEECH_ERROR_AITALK_FAILED = 23104, // ivErr_Failed = 5 SPEECH_ERROR_AITALK_NOT_SUPPORTED = 23105, // ivErr_NotSupport = 6 /*治֧*/ SPEECH_ERROR_AITALK_OUT_OF_MEMORY = 23106, // ivErr_OutOfMemory = 7 SPEECH_ERROR_AITALK_INVALID_RESOURCE = 23107, // ivErr_InvResource = 8 /*ԴЧ*/ SPEECH_ERROR_AITALK_NOT_FOUND = 23108, // ivErr_NotFound = 9 /*ļʧ*/ SPEECH_ERROR_AITALK_INVALID_GRAMMAR = 23109, // ivErr_InvGrmr = 10 /*ʶ﷨*/ /* For object status */ SPEECH_ERROR_AITALK_INVALID_CALL = 23110, // ivErr_InvCall = 11 /*Ч*/ /* For ASR Input */ SPEECH_ERROR_AITALK_SYNTAX_ERROR = 23111, // ivErr_InvCall = 12 /* For Message Call Back */ SPEECH_ERROR_AITALK_RESET = 23112, // ivErr_Reset = 13 SPEECH_ERROR_AITALK_ENDED = 23113, // ivErr_Ended = 14 SPEECH_ERROR_AITALK_IDLE = 23114, // ivErr_Idle = 15 SPEECH_ERROR_AITALK_CANNOT_SAVE_FILE = 23115, // ivErr_CanNotSaveFile = 16 /* For Lexicon name */ SPEECH_ERROR_AITALK_INVALID_GRAMMAR_NAME = 23116, // ivErr_InvName = 17 /*ķʵƷǷ*/ SPEECH_ERROR_AITALK_BUFFER_EMPTY = 23117, // ivErr_BufferEmpty = 18 SPEECH_ERROR_AITALK_GET_RESULT = 23118, // ivErr_GetResult = 19 SPEECH_ERROR_AITALK_REACT_OUT_TIME = 23119, // ivErr_ReactOutTime = 20 /*Ӧʱ*/ SPEECH_ERROR_AITALK_SPEECH_OUT_TIME = 23120, // ivErr_SpeechOutTime = 21 /*ʱ*/ SPEECH_ERROR_AITALK_AUDIO_CUT = 23121, // ivErr_CUT = 22 /*¼*/ SPEECH_ERROR_AITALK_AUDIO_LOWER = 23122, // ivErr_LOWER = 23 /*¼*/ SPEECH_ERROR_AITALK_INSUFFICIENT_PERMISSIONS = 23123, // ivErr_Limitted = 24 /*Ȩ*/ SPEECH_ERROR_AITALK_RESULT_ERROR = 23124, // ivErr_ResultError = 25 /*WfstȻcmd*/ SPEECH_ERROR_AITALK_SHORT_PAUSE = 23125, // ivErr_ShortPause = 26 SPEECH_ERROR_AITALK_BUSY = 23126, // ivErr_Busy = 27 SPEECH_ERROR_AITALK_GRM_NOT_UPDATE = 23127, // ivErr_GrmNotUpdate = 28 /*﷨δ*/ SPEECH_ERROR_AITALK_STARTED = 23128, // ivErr_Started = 29 SPEECH_ERROR_AITALK_STOPPED = 23129, // ivErr_Stopped = 30 SPEECH_ERROR_AITALK_ALREADY_STARTED = 23130, // ivErr_AlreadyStarted = 31 SPEECH_ERROR_AITALK_ALREADY_STOPPED = 23131, // ivErr_AlreadyStopped = 32 SPEECH_ERROR_AITALK_TOO_MANY_COMMAND = 23132, // ivErr_TooManyCmd = 33 SPEECH_ERROR_AITALK_WAIT = 23133, // ivErr_Wait = 34 /*һЩ߳Ҫȴ*/ SPEECH_ERROR_AITALK_MAE_RIGHT = 23134, // ivErr_MAERight = 35 SPEECH_ERROR_AITALK_MAE_WRONG = 23135, // ivErr_MAEWrong = 36 SPEECH_ERROR_AITALK_GRM_ERR = 23300, // ﷨ /*Error Code Of AiSound*/ /*Error Code Of AiSound Operation*/ SPEECH_ERROR_TTS_INVALID_PARA = 24000, /* */ SPEECH_ERROR_TTS_INVALID_PARA_VALUE = 24001, /* ЧIJֵ*/ SPEECH_ERROR_TTS_OUT_OF_MEMORY = 24002, /* ڴ治*/ SPEECH_ERROR_TTS_INVALID_HANDLE = 24003, /* Чľ*/ SPEECH_ERROR_TTS_CREATE_HANDLE_FAILED = 24004, /* ʧ*/ SPEECH_ERROR_TTS_INVALID_RESOURCE = 24005, /* ЧԴ */ SPEECH_ERROR_TTS_INVALID_VOICE_NAME = 24006, /* Ч*/ SPEECH_ERROR_TTS_ENGINE_UNINIT = 24007, /* δʼ */ SPEECH_ERROR_TTS_ENGINE_INIT_FAILED = 24008, /* ʼʧ */ SPEECH_ERROR_TTS_ENGINE_BUSY = 24009, /* æ */ /*Error Code Of AiSound Engine*/ SPEECH_ERROR_AISOUND_BASE = 24100, SPEECH_ERROR_AISOUND_UNIMPEMENTED = 24100, /* unimplemented function */ SPEECH_ERROR_AISOUND_UNSUPPORTED = 24101, /* unsupported on this platform */ SPEECH_ERROR_AISOUND_INVALID_HANDLE = 24102, /* invalid handle */ SPEECH_ERROR_AISOUND_INVALID_PARA = 24103, /* invalid parameter(s) */ SPEECH_ERROR_AISOUND_INSUFFICIENT_HEAP = 24104, /* insufficient heap size */ SPEECH_ERROR_AISOUND_STATE_REFUSE = 24105, /* refuse to do in current state */ SPEECH_ERROR_AISOUND_INVALID_PARA_ID = 24106, /* invalid parameter ID */ SPEECH_ERROR_AISOUND_INVALID_PARA_VALUE = 24107, /* invalid parameter value */ SPEECH_ERROR_AISOUND_RESOURCE = 24108, /* Resource is error */ SPEECH_ERROR_AISOUND_RESOURCE_READ = 24109, /* read resource error */ SPEECH_ERROR_AISOUND_LBENDIAN = 24110, /* the Endian of SDK is error */ SPEECH_ERROR_AISOUND_HEADFILE = 24111, /* the HeadFile is different of the SDK */ SPEECH_ERROR_AISOUND_BUFFER_OVERFLOW = 24112, /* get data size exceed the data buffer */ SPEECH_ERROR_AISOUND_INVALID_ISAMPA = 24113, /* !Invalid iSampa format or input iSampa text contain invalid alphabet*/ SPEECH_ERROR_AISOUND_INVALID_CSSML = 24114, /* !Invalid cssml format */ /*Error Code Of ivw*/ /*Error Code Of ivw Operation*/ SPEECH_ERROR_IVW_ENGINE_UNINI = 25000, /* δʼ */ SPEECH_ERROR_IVW_RESVER_NOMATCH = 25001, /* Դ汾ƥ */ SPEECH_ERROR_IVW_BUFFERED_AUDIOD_LITTLE = 25002, /* Ѽʶ𻺴Ƶ */ SPEECH_ERROR_IVW_INVALID_RESTYPE = 25003, /* ϷԴ */ /*Error Code Of ivw Engine*/ SPEECH_ERROR_IVW_INVALID_CALL = 25101, // IvwErr_InvCal = 1 SPEECH_ERROR_IVW_INVALID_ARG = 25102, // IvwErr_InvArg = 2 SPEECH_ERROR_IVW_TELL_SIZE = 25103, // IvwErr_TellSize = 3 SPEECH_ERROR_IVW_OUT_OF_MEMORY = 25104, // IvwErr_OutOfMemory = 4 SPEECH_ERROR_IVW_OUT_BUFFER_FULL = 25105, // IvwErr_BufferFull = 5 SPEECH_ERROR_IVW_OUT_BUFFER_EMPTY = 25106, // IvwErr_BufferEmpty = 6 SPEECH_ERROR_IVW_INVALID_RESOURCE = 25107, // IvwErr_InvRes = 7 SPEECH_ERROR_IVW_REPETITIOPN_ENTER = 25108, // IvwErr_ReEnter = 8 SPEECH_ERROR_IVW_NOT_SUPPORT = 25109, // IvwErr_NotSupport = 9 SPEECH_ERROR_IVW_NOT_FOUND = 25110, // IvwErr_NotFound = 10 SPEECH_ERROR_IVW_INVALID_SN = 25111, // IvwErr_InvSN = 11 SPEECH_ERROR_IVW_LIMITTED = 25112, // IvwErr_Limitted = 12 SPEECH_ERROR_IVW_TIME_OUT = 25113, // IvwErr_TimeOut = 13 SPEECH_ERROR_IVW_ENROLL1_SUCESS = 25114, // IvwErr_Enroll1_Success = 14 SPEECH_ERROR_IVW_ENROLL1_FAILED = 25115, // IvwErr_Enroll1_Failed = 15 SPEECH_ERROR_IVW_ENROLL2_SUCESS = 25116, // IvwErr_Enroll2_Success = 16 SPEECH_ERROR_IVW_ENROLL2_FAILED = 25117, // IvwErr_Enroll2_Failed = 17 SPEECH_ERROR_IVW_ENROLL3_SUCESS = 25118, // IvwErr_Enroll3_Success = 18 SPEECH_ERROR_IVW_ENROLL3_FAILED = 25119, // IvwErr_Enroll3_Failed = 19 SPEECH_ERROR_IVW_SPEECH_TOO_SHORT = 25120, // IvwErr_SpeechTooShort = 20 SPEECH_ERROR_IVW_SPEECH_STOP = 25121 // IvwErr_SpeechStop = 21 }; #endif /* __MSP_ERRORS_H__ */ ================================================ FILE: xf/include/msp_types.h ================================================ #ifndef __MSP_TYPES_H__ #define __MSP_TYPES_H__ #if !defined(MSPAPI) #if defined(WIN32) || defined(WINPHONE8) || defined(WIN8) #define MSPAPI __stdcall #else #define MSPAPI #endif /* WIN32 */ #endif /* MSPAPI */ /** * MSPSampleStatus indicates how the sample buffer should be handled * MSP_AUDIO_SAMPLE_FIRST - The sample buffer is the start of audio * If recognizer was already recognizing, it will discard * audio received to date and re-start the recognition * MSP_AUDIO_SAMPLE_CONTINUE - The sample buffer is continuing audio * MSP_AUDIO_SAMPLE_LAST - The sample buffer is the end of audio * The recognizer will cease processing audio and * return results * Note that sample statii can be combined; for example, for file-based input * the entire file can be written with SAMPLE_FIRST | SAMPLE_LAST as the * status. * Other flags may be added in future to indicate other special audio * conditions such as the presence of AGC */ enum { MSP_AUDIO_SAMPLE_INIT = 0x00, MSP_AUDIO_SAMPLE_FIRST = 0x01, MSP_AUDIO_SAMPLE_CONTINUE = 0x02, MSP_AUDIO_SAMPLE_LAST = 0x04, }; /* * The enumeration MSPRecognizerStatus contains the recognition status * MSP_REC_STATUS_SUCCESS - successful recognition with partial results * MSP_REC_STATUS_NO_MATCH - recognition rejected * MSP_REC_STATUS_INCOMPLETE - recognizer needs more time to compute results * MSP_REC_STATUS_NON_SPEECH_DETECTED - discard status, no more in use * MSP_REC_STATUS_SPEECH_DETECTED - recognizer has detected audio, this is delayed status * MSP_REC_STATUS_COMPLETE - recognizer has return all result * MSP_REC_STATUS_MAX_CPU_TIME - CPU time limit exceeded * MSP_REC_STATUS_MAX_SPEECH - maximum speech length exceeded, partial results may be returned * MSP_REC_STATUS_STOPPED - recognition was stopped * MSP_REC_STATUS_REJECTED - recognizer rejected due to low confidence * MSP_REC_STATUS_NO_SPEECH_FOUND - recognizer still found no audio, this is delayed status */ enum { MSP_REC_STATUS_SUCCESS = 0, MSP_REC_STATUS_NO_MATCH = 1, MSP_REC_STATUS_INCOMPLETE = 2, MSP_REC_STATUS_NON_SPEECH_DETECTED = 3, MSP_REC_STATUS_SPEECH_DETECTED = 4, MSP_REC_STATUS_COMPLETE = 5, MSP_REC_STATUS_MAX_CPU_TIME = 6, MSP_REC_STATUS_MAX_SPEECH = 7, MSP_REC_STATUS_STOPPED = 8, MSP_REC_STATUS_REJECTED = 9, MSP_REC_STATUS_NO_SPEECH_FOUND = 10, MSP_REC_STATUS_FAILURE = MSP_REC_STATUS_NO_MATCH, }; /** * The enumeration MSPepState contains the current endpointer state * MSP_EP_LOOKING_FOR_SPEECH - Have not yet found the beginning of speech * MSP_EP_IN_SPEECH - Have found the beginning, but not the end of speech * MSP_EP_AFTER_SPEECH - Have found the beginning and end of speech * MSP_EP_TIMEOUT - Have not found any audio till timeout * MSP_EP_ERROR - The endpointer has encountered a serious error * MSP_EP_MAX_SPEECH - Have arrive the max size of speech */ enum { MSP_EP_LOOKING_FOR_SPEECH = 0, MSP_EP_IN_SPEECH = 1, MSP_EP_AFTER_SPEECH = 3, MSP_EP_TIMEOUT = 4, MSP_EP_ERROR = 5, MSP_EP_MAX_SPEECH = 6, MSP_EP_IDLE = 7 // internal state after stop and before start }; /* Synthesizing process flags */ enum { MSP_TTS_FLAG_STILL_HAVE_DATA = 1, MSP_TTS_FLAG_DATA_END = 2, MSP_TTS_FLAG_CMD_CANCELED = 4, }; /* Handwriting process flags */ enum { MSP_HCR_DATA_FIRST = 1, MSP_HCR_DATA_CONTINUE = 2, MSP_HCR_DATA_END = 4, }; /*ivw message type */ enum { MSP_IVW_MSG_WAKEUP = 1, MSP_IVW_MSG_ERROR = 2, MSP_IVW_MSG_ISR_RESULT = 3, MSP_IVW_MSG_ISR_EPS = 4, MSP_IVW_MSG_VOLUME = 5, MSP_IVW_MSG_ENROLL = 6, MSP_IVW_MSG_RESET = 7 }; /* Upload data process flags */ enum { MSP_DATA_SAMPLE_INIT = 0x00, MSP_DATA_SAMPLE_FIRST = 0x01, MSP_DATA_SAMPLE_CONTINUE = 0x02, MSP_DATA_SAMPLE_LAST = 0x04, }; #endif /* __MSP_TYPES_H__ */ ================================================ FILE: xf/include/qtts.h ================================================ /** * @file qtts.h * @brief iFLY Speech Synthesizer Header File * * This file contains the quick application programming interface (API) declarations * of TTS. Developer can include this file in your project to build applications. * For more information, please read the developer guide. * Use of this software is subject to certain restrictions and limitations set * forth in a license agreement entered into between iFLYTEK, Co,LTD. * and the licensee of this software. Please refer to the license * agreement for license use rights and restrictions. * * Copyright (C) 1999 - 2009 by ANHUI USTC iFLYTEK, Co,LTD. * All rights reserved. * * @author Speech Dept. * @version 1.0 * @date 2009/11/26 * * @see * * History:
* * * *
Version Date Author Notes
1.0 2009/11/26 Speech Create this file
* */ #ifndef __QTTS_H__ #define __QTTS_H__ #if !defined(MSPAPI) #if defined(WIN32) #define MSPAPI __stdcall #else #define MSPAPI #endif /* WIN32 */ #endif /* MSPAPI */ #ifdef __cplusplus extern "C" { #endif /* C++ */ #include "msp_types.h" /** * @fn QTTSSessionBegin * @brief Begin a TTS Session * * Create a tts session to synthesize data. * * @return const char* - Return the new session id in success, otherwise return NULL, error code. * @param const char* params - [in] parameters when the session created. * @param const char** sessionID - [out] return a string to this session. * @see */ const char* MSPAPI QTTSSessionBegin(const char* params, int* errorCode); typedef const char* (MSPAPI *Proc_QTTSSessionBegin)(const char* params, int* errorCode); #ifdef MSP_WCHAR_SUPPORT const wchar_t* MSPAPI QTTSSessionBeginW(const wchar_t* params, int* errorCode); typedef const wchar_t* (MSPAPI *Proc_QTTSSessionBeginW)(const wchar_t* params, int* errorCode); #endif /** * @fn QTTSTextPut * @brief Put Text Buffer to TTS Session * * Writing text string to synthesizer. * * @return int MSPAPI - Return 0 in success, otherwise return error code. * @param const char* sessionID - [in] The session id returned by sesson begin * @param const char* textString - [in] text buffer * @param unsigned int textLen - [in] text size in bytes * @see */ int MSPAPI QTTSTextPut(const char* sessionID, const char* textString, unsigned int textLen, const char* params); typedef int (MSPAPI *Proc_QTTSTextPut)(const char* sessionID, const char* textString, unsigned int textLen, const char* params); #ifdef MSP_WCHAR_SUPPORT int MSPAPI QTTSTextPutW(const wchar_t* sessionID, const wchar_t* textString, unsigned int textLen, const wchar_t* params); typedef int (MSPAPI *Proc_QTTSTextPutW)(const wchar_t* sessionID, const wchar_t* textString, unsigned int textLen, const wchar_t* params); #endif /** * @fn QTTSAudioGet * @brief Synthesize text to audio * * Synthesize text to audio, and return audio information. * * @return const void* - Return current synthesized audio data buffer, size returned by QTTSTextSynth. * @param const char* sessionID - [in] session id returned by session begin * @param unsigned int* audioLen - [out] synthesized audio size in bytes * @param int* synthStatus - [out] synthesizing status * @param int* errorCode - [out] error code if failed, 0 to success. * @see */ const void* MSPAPI QTTSAudioGet(const char* sessionID, unsigned int* audioLen, int* synthStatus, int* errorCode); typedef const void* (MSPAPI *Proc_QTTSAudioGet)(const char* sessionID, unsigned int* audioLen, int* synthStatus, int* errorCode); #ifdef MSP_WCHAR_SUPPORT const void* MSPAPI QTTSAudioGetW(const wchar_t* sessionID, unsigned int* audioLen, int* synthStatus, int* errorCode); typedef const void* (MSPAPI *Proc_QTTSAudioGetW)(const wchar_t* sessionID, unsigned int* audioLen, int* synthStatus, int* errorCode); #endif /** * @fn QTTSAudioInfo * @brief Get Synthesized Audio information * * Get synthesized audio data information. * * @return const char * - Return audio info string. * @param const char* sessionID - [in] session id returned by session begin * @see */ const char* MSPAPI QTTSAudioInfo(const char* sessionID); typedef const char* (MSPAPI *Proc_QTTSAudioInfo)(const char* sessionID); #ifdef MSP_WCHAR_SUPPORT const wchar_t* MSPAPI QTTSAudioInfoW(const wchar_t* sessionID); typedef const wchar_t* (MSPAPI *Proc_QTTSAudioInfoW)(const wchar_t* sessionID); #endif /** * @fn QTTSSessionEnd * @brief End a Recognizer Session * * End the recognizer session, release all resource. * * @return int MSPAPI - Return 0 in success, otherwise return error code. * @param const char* session_id - [in] session id string to end * @param const char* hints - [in] user hints to end session, hints will be logged to CallLog * @see */ int MSPAPI QTTSSessionEnd(const char* sessionID, const char* hints); typedef int (MSPAPI *Proc_QTTSSessionEnd)(const char* sessionID, const char* hints); #ifdef MSP_WCHAR_SUPPORT int MSPAPI QTTSSessionEndW(const wchar_t* sessionID, const wchar_t* hints); typedef int (MSPAPI *Proc_QTTSSessionEndW)(const wchar_t* sessionID, const wchar_t* hints); #endif /** * @fn QTTSGetParam * @brief get params related with msc * * the params could be local or server param, we only support netflow params "upflow" & "downflow" now * * @return int - Return 0 if success, otherwise return errcode. * @param const char* sessionID - [in] session id of related param, set NULL to got global param * @param const char* paramName - [in] param name,could pass more than one param split by ','';'or'\n' * @param const char* paramValue - [in] param value buffer, malloced by user * @param int *valueLen - [in, out] pass in length of value buffer, and return length of value string * @see */ int MSPAPI QTTSGetParam(const char* sessionID, const char* paramName, char* paramValue, unsigned int* valueLen); typedef int (MSPAPI *Proc_QTTSGetParam)(const char* sessionID, const char* paramName, char* paramValue, unsigned int* valueLen); #ifdef MSP_WCHAR_SUPPORT int MSPAPI QTTSGetParamW(const wchar_t* sessionID, const wchar_t* paramName, wchar_t* paramValue, unsigned int* valueLen); typedef int (MSPAPI *Proc_QTTSGetParamW)(const wchar_t* sessionID, const wchar_t* paramName, wchar_t* paramValue, unsigned int* valueLen); #endif /** * @fn QTTSSetParam * @brief set params related with msc * * the params could be local or server param, we only support netflow params "upflow" & "downflow" now * * @return int - Return 0 if success, otherwise return errcode. * @param const char* sessionID - [in] session id of related param, set NULL to got global param * @param const char* paramName - [in] param name,could pass more than one param split by ','';'or'\n' * @param const char* paramValue - [in] param value buffer, malloced by user * @see */ int MSPAPI QTTSSetParam(const char *sessionID, const char *paramName, const char *paramValue); typedef int (MSPAPI *Proc_QTTSSetParam)(const char* sessionID, const char* paramName, char* paramValue); #ifdef MSP_WCHAR_SUPPORT int MSPAPI QTTSSetParamW(const wchar_t* sessionID, const wchar_t* paramName, wchar_t* paramValue); typedef int (MSPAPI *Proc_QTTSSetParamW)(const wchar_t* sessionID, const wchar_t* paramName, wchar_t* paramValue); #endif typedef void ( *tts_result_ntf_handler)( const char *sessionID, const char *audio, int audioLen, int synthStatus, int ced, const char *audioInfo, int audioInfoLen, void *userData ); typedef void ( *tts_status_ntf_handler)( const char *sessionID, int type, int status, int param1, const void *param2, void *userData); typedef void ( *tts_error_ntf_handler)(const char *sessionID, int errorCode, const char *detail, void *userData); int MSPAPI QTTSRegisterNotify(const char *sessionID, tts_result_ntf_handler rsltCb, tts_status_ntf_handler statusCb, tts_error_ntf_handler errCb, void *userData); #ifdef __cplusplus } /* extern "C" */ #endif /* C++ */ #endif /* __QTTS_H__ */ ================================================ FILE: xf/xf.go ================================================ package xf /* #cgo CFLAGS:-g -Wall -I./include #cgo LDFLAGS:-L./lib -lmsc -lrt -ldl -lpthread #include "convert.h" */ import "C" import ( "fmt" "unsafe" ) /* * rdn: 合成音频数字发音方式 * volume: 合成音频的音量 * pitch: 合成音频的音调 * speed: 合成音频对应的语速 * voice_name: 合成发音人 * sample_rate: 合成音频采样率 * text_encoding: 合成文本编码格式 * * 详细参数说明请参阅《iFlytek MSC Reference Manual》 */ var ttsParams *C.char var sleep C.int = C.int(0) func SetTTSParams(params string) { ttsParams = C.CString(params) } func SetSleep(t int) { sleep = C.int(t) } func Login(loginParams string) error { l := C.CString(loginParams) defer C.free(unsafe.Pointer(l)) ret := C.MSPLogin(nil, nil, C.CString(loginParams)) if ret != C.MSP_SUCCESS { return fmt.Errorf("登录失败,错误码:%d", int(ret)) } return nil } func Logout() error { ret := C.MSPLogout() if ret != C.MSP_SUCCESS { return fmt.Errorf("注销失败,错误码:%d", int(ret)) } return nil } func TextToSpeech(text, outPath string) error { t := C.CString(text) o := C.CString(outPath) defer C.free(unsafe.Pointer(t)) defer C.free(unsafe.Pointer(o)) ret := C.text_to_speech(t, o, ttsParams, sleep) if ret != C.MSP_SUCCESS { return fmt.Errorf("音频生成失败,错误码:%d", int(ret)) } return nil }