diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index d9791342..82ca4937 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -3,8 +3,8 @@ name: docker-push on: push: branches: - - 'docker' - - 'master' + - 'ci-test/*' + - 'release/*' tags: - 'v*' @@ -37,6 +37,6 @@ jobs: with: context: . platforms: linux/amd64,linux/386,linux/arm64/v8,linux/arm/v7,linux/arm/v6 - push: true + push: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} diff --git a/.github/workflows/go.yaml b/.github/workflows/go.yaml index 99a0a5ef..8b57c280 100644 --- a/.github/workflows/go.yaml +++ b/.github/workflows/go.yaml @@ -11,7 +11,7 @@ jobs: go-version: [ '1.x' ] include: - os: ubuntu-latest - go-version: '1.16' + go-version: '1.19' runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v3 diff --git a/Dockerfile b/Dockerfile index e2f67b35..79a78ef1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ FROM golang:alpine as builder -RUN apk add --no-cache git +RUN apk add --no-cache git ca-certificates WORKDIR /src ADD go.mod go.sum ./ RUN go mod download @@ -10,11 +10,14 @@ FROM scratch LABEL org.opencontainers.image.source=https://github.com/la5nta/pat LABEL org.opencontainers.image.description="Pat - A portable Winlink client for amateur radio email" LABEL org.opencontainers.image.licenses=MIT +COPY --from=builder /etc/ssl/certs /etc/ssl/certs COPY --from=builder /src/pat /bin/pat USER 65534:65534 WORKDIR /app ENV XDG_CONFIG_HOME=/app ENV XDG_DATA_HOME=/app ENV XDG_STATE_HOME=/app +ENV PAT_HTTPADDR=:8080 EXPOSE 8080 -ENTRYPOINT ["/bin/pat", "http", "--addr", ":8080"] +ENTRYPOINT ["/bin/pat"] +CMD ["http"] diff --git a/cfg/config.go b/cfg/config.go index 9075aceb..2c0fc005 100644 --- a/cfg/config.go +++ b/cfg/config.go @@ -124,7 +124,7 @@ type Config struct { } type HamlibConfig struct { - // The network type ("serial" or "tcp"). Use 'tcp' for rigctld. + // The network type ("serial" or "tcp"). Use 'tcp' for rigctld (default). // // (For serial support: build with "-tags libhamlib".) Network string `json:"network,omitempty"` diff --git a/cli_composer.go b/cli_composer.go index 13749135..ef6e19b6 100644 --- a/cli_composer.go +++ b/cli_composer.go @@ -270,7 +270,7 @@ func readAttachment(path string) (*fbb.File, error) { name := filepath.Base(path) var resizeImage bool - if isImageMediaType(name, "") { + if isConvertableImageMediaType(name, "") { fmt.Print("This seems to be an image. Auto resize? [Y/n]: ") ans := readLine() resizeImage = ans == "" || strings.EqualFold("y", ans) @@ -332,8 +332,10 @@ func composeFormReport(ctx context.Context, args []string) { msg.SetBody(formMsg.Body) - attachmentFile := fbb.NewFile(formMsg.AttachmentName, []byte(formMsg.AttachmentXML)) - msg.AddFile(attachmentFile) + if xml := formMsg.AttachmentXML; xml != "" { + attachmentFile := fbb.NewFile(formMsg.AttachmentName, []byte(xml)) + msg.AddFile(attachmentFile) + } postMessage(msg) } diff --git a/config.go b/config.go index 5c7a5284..5884837f 100644 --- a/config.go +++ b/config.go @@ -6,20 +6,36 @@ package main import ( "encoding/json" + "fmt" "log" "os" "path" "strings" + "github.com/kelseyhightower/envconfig" "github.com/la5nta/pat/cfg" + "github.com/la5nta/pat/internal/buildinfo" "github.com/la5nta/pat/internal/debug" ) func LoadConfig(cfgPath string, fallback cfg.Config) (config cfg.Config, err error) { config, err = ReadConfig(cfgPath) - if os.IsNotExist(err) { - return fallback, WriteConfig(fallback, cfgPath) - } else if err != nil { + switch { + case os.IsNotExist(err): + config = fallback + if err := WriteConfig(config, cfgPath); err != nil { + return config, err + } + case err != nil: + return config, err + } + + // Environment variables overrides values from the config file + if err := envconfig.Process(buildinfo.AppName, &config); err != nil { + return config, err + } + // Environment variables for hamlib rigs (custom syntax not handled by envconfig) + if err := readRigsFromEnv(&config.HamlibRigs); err != nil { return config, err } @@ -110,6 +126,42 @@ func LoadConfig(cfgPath string, fallback cfg.Config) (config cfg.Config, err err return config, nil } +// readRigsFromEnv reads hamlib rigs config from environment. +// Syntax: PAT_HAMLIB_RIGS_{rig name}_{ATTRIBUTE} +// _{ATTRIBUTE} is optional (defaults to _ADDRESS). +// Examples: +// - PAT_HAMLIB_RIGS_rig1_NETWORK=tcp +// - PAT_HAMLIB_RIGS_rig1_ADDRESS=localhost:8080 +// - PAT_HAMLIB_RIGS_rig1_VFO=A +// - PAT_HAMLIB_RIGS_rig2=localhost:8080 +func readRigsFromEnv(rigs *map[string]cfg.HamlibConfig) error { + prefix := strings.ToUpper(buildinfo.AppName) + "_HAMLIB_RIGS_" + for _, env := range os.Environ() { + attribute, value, _ := strings.Cut(env, "=") + if !strings.HasPrefix(attribute, prefix) { + continue + } + attribute = strings.TrimPrefix(attribute, prefix) + name, attribute, _ := strings.Cut(attribute, "_") + if *rigs == nil { + *rigs = make(map[string]cfg.HamlibConfig) + } + rig := (*rigs)[name] + switch attribute { + case "ADDRESS", "": + rig.Address = value + case "NETWORK": + rig.Network = value + case "VFO": + rig.VFO = value + default: + return fmt.Errorf("invalid attribute '%s' for rig '%s'", attribute, name) + } + (*rigs)[name] = rig + } + return nil +} + func ReadConfig(path string) (config cfg.Config, err error) { data, err := os.ReadFile(path) if err != nil { diff --git a/config_test.go b/config_test.go new file mode 100644 index 00000000..5d7653cc --- /dev/null +++ b/config_test.go @@ -0,0 +1,62 @@ +package main + +import ( + "os" + "strings" + "testing" + + "github.com/la5nta/pat/cfg" +) + +func TestReadRigsFromEnv(t *testing.T) { + const prefix = "PAT_HAMLIB_RIGS" + unset := func() { + for _, env := range os.Environ() { + key, _, _ := strings.Cut(env, "=") + if strings.HasPrefix(key, prefix) { + os.Unsetenv(key) + } + } + } + t.Run("simple", func(t *testing.T) { + defer unset() + var rigs map[string]cfg.HamlibConfig + os.Setenv(prefix+"_rig", "localhost:4532") + if err := readRigsFromEnv(&rigs); err != nil { + t.Fatal(err) + } + if got := rigs["rig"]; (got != cfg.HamlibConfig{Address: "localhost:4532"}) { + t.Fatalf("Got unexpected config: %#v", got) + } + }) + t.Run("with VFO", func(t *testing.T) { + defer unset() + var rigs map[string]cfg.HamlibConfig + os.Setenv(prefix+"_rig", "localhost:4532") + os.Setenv(prefix+"_rig_VFO", "A") + if err := readRigsFromEnv(&rigs); err != nil { + t.Fatal(err) + } + if got := rigs["rig"]; (got != cfg.HamlibConfig{Address: "localhost:4532", VFO: "A"}) { + t.Fatalf("Got unexpected config: %#v", got) + } + }) + t.Run("full", func(t *testing.T) { + defer unset() + var rigs map[string]cfg.HamlibConfig + os.Setenv(prefix+"_rig_ADDRESS", "/dev/ttyS0") + os.Setenv(prefix+"_rig_NETWORK", "serial") + os.Setenv(prefix+"_rig_VFO", "B") + if err := readRigsFromEnv(&rigs); err != nil { + t.Fatal(err) + } + expect := cfg.HamlibConfig{ + Address: "/dev/ttyS0", + Network: "serial", + VFO: "B", + } + if got := rigs["rig"]; got != expect { + t.Fatalf("Got unexpected config: %#v", got) + } + }) +} diff --git a/connect.go b/connect.go index 89ef58bd..df8614eb 100644 --- a/connect.go +++ b/connect.go @@ -316,6 +316,9 @@ func initVaraHFModem() error { if varaHFModem != nil && varaHFModem.Ping() { return nil } + if varaHFModem != nil { + varaHFModem.Close() + } m, err := initVaraModem(MethodVaraHF, config.VaraHF) if err != nil { return err @@ -334,6 +337,9 @@ func initVaraFMModem() error { if varaFMModem != nil && varaFMModem.Ping() { return nil } + if varaFMModem != nil { + varaFMModem.Close() + } m, err := initVaraModem(MethodVaraFM, config.VaraFM) if err != nil { return err diff --git a/convert_image.go b/convert_image.go index e1459efe..c67329c9 100644 --- a/convert_image.go +++ b/convert_image.go @@ -17,7 +17,7 @@ import ( "github.com/nfnt/resize" ) -func isImageMediaType(filename, contentType string) bool { +func isConvertableImageMediaType(filename, contentType string) bool { var mediaType string if contentType != "" { mediaType, _, _ = mime.ParseMediaType(contentType) @@ -26,7 +26,13 @@ func isImageMediaType(filename, contentType string) bool { mediaType = mime.TypeByExtension(path.Ext(filename)) } - return strings.HasPrefix(mediaType, "image/") + switch mediaType { + case "image/svg+xml": + // This is a text file + return false + default: + return strings.HasPrefix(mediaType, "image/") + } } func convertImage(orig []byte) ([]byte, error) { diff --git a/debian/changelog b/debian/changelog index 4aed2f9e..d2a835ad 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,17 @@ +pat (0.15.1) stable; urgency=medium + + * Support config overrides using env variables + * Only attach Forms XML if a viewer file is defined + * Fix handling of SVG attachments (don't attempt auto resize) + * VARA: Silence "got a vara command I wasn't expecting..." messages + * VARA: Fix leak when re-initializing the modem connection + * hamlib: Fix compatibility with rigctld in VFO Mode + * hamlib: Fix tests and compilation when statically linking libhamlib + * New experiment FW_AUX_ONLY_EXPERIMENT (disabled by default) + * Require Go 1.19 or later (due to updated dependencies) + + -- Martin Hebnes Pedersen Sun, 5 Nov 2023 12:44:08 +0100 + pat (0.15.0) stable; urgency=medium * Restore previous connect parameters from browser's local storage diff --git a/go.mod b/go.mod index 76086032..b5238483 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/la5nta/pat -go 1.16 +go 1.19 require ( github.com/adrg/xdg v0.3.3 @@ -12,15 +12,29 @@ require ( github.com/gorilla/websocket v1.4.2 github.com/harenber/ptc-go/v2 v2.2.3 github.com/howeyc/gopass v0.0.0-20190910152052-7cb4b85ec19c - github.com/la5nta/wl2k-go v0.11.4 - github.com/mattn/go-runewidth v0.0.13 // indirect + github.com/kelseyhightower/envconfig v1.4.0 + github.com/la5nta/wl2k-go v0.11.8 github.com/microcosm-cc/bluemonday v1.0.16 - github.com/n8jja/Pat-Vara v1.1.2 + github.com/n8jja/Pat-Vara v1.1.4 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 github.com/pd0mz/go-maidenhead v1.0.0 github.com/peterh/liner v1.2.1 github.com/spf13/pflag v1.0.5 +) + +require ( + dario.cat/mergo v1.0.0 // indirect + github.com/albenik/go-serial/v2 v2.6.0 // indirect + github.com/aymerick/douceur v0.2.0 // indirect + github.com/creack/goselect v0.1.2 // indirect + github.com/gorilla/css v1.0.0 // indirect + github.com/howeyc/crc16 v0.0.0-20171223171357-2b2a61e366a6 // indirect + github.com/mattn/go-runewidth v0.0.13 // indirect + github.com/paulrosania/go-charset v0.0.0-20190326053356-55c9d7a5834c // indirect + github.com/rivo/uniseg v0.2.0 // indirect + go.uber.org/multierr v1.11.0 // indirect golang.org/x/crypto v0.0.0-20210813211128-0a44fdfbc16e // indirect golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d // indirect + golang.org/x/sys v0.13.0 // indirect golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect ) diff --git a/go.sum b/go.sum index b1dc8105..849ab08d 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,11 @@ +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/adrg/xdg v0.3.3 h1:s/tV7MdqQnzB1nKY8aqHvAMD+uCiuEDzVB5HLRY849U= github.com/adrg/xdg v0.3.3/go.mod h1:61xAR2VZcggl2St4O9ohF5qCKe08+JDmE4VNzPFQvOQ= github.com/albenik/go-serial/v2 v2.4.0/go.mod h1:JUrQKdczCMB0FlXt2rlJJ8zbfFzmjTIAkLPyyVfr5ho= -github.com/albenik/go-serial/v2 v2.5.0 h1:I4oUK+zxjHBNtcYHyHifyxBhMX33jCFY9ieUXPsdSAI= github.com/albenik/go-serial/v2 v2.5.0/go.mod h1:ySdCqoERscw1xluK1n62R8Faoyu+jXKwVHPa1lSSAew= +github.com/albenik/go-serial/v2 v2.6.0 h1:UX30WZPL0qouDrKu4xwVFgvQA3YDTNhk3+aVC6X0jYg= +github.com/albenik/go-serial/v2 v2.6.0/go.mod h1:sqQA6eeZHKUB6rAgrBsP/8d3Go5Md5cjCof1WcyaK0o= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/bndr/gotabulate v1.1.3-0.20170315142410-bc555436bfd5 h1:D48YSLPNJ8WpdwDqYF8bMMKUB2bgdWEiFx1MGwPIdbs= @@ -31,23 +34,23 @@ github.com/howeyc/crc16 v0.0.0-20171223171357-2b2a61e366a6 h1:IIVxLyDUYErC950b8k github.com/howeyc/crc16 v0.0.0-20171223171357-2b2a61e366a6/go.mod h1:JslaLRrzGsOKJgFEPBP65Whn+rdwDQSk0I0MCRFe2Zw= github.com/howeyc/gopass v0.0.0-20190910152052-7cb4b85ec19c h1:aY2hhxLhjEAbfXOx2nRJxCXezC6CO2V/yN+OCr1srtk= github.com/howeyc/gopass v0.0.0-20190910152052-7cb4b85ec19c/go.mod h1:lADxMC39cJJqL93Duh1xhAs4I2Zs8mKS89XWXFGp9cs= -github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= -github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= +github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/la5nta/wl2k-go v0.7.3/go.mod h1:rTQaxPiAFD3pWGWN8Lh+BskN3Fpii84GoVwpTHNiCjE= -github.com/la5nta/wl2k-go v0.9.2/go.mod h1:0c+/9KyDj7Ra7C/O4rVUYx1CzvdtS65di/93wlI22fo= -github.com/la5nta/wl2k-go v0.11.4 h1:BjguMdnLiLptlZKIHVlm7/APBwKQoZtKxbKd3Mw/Br0= -github.com/la5nta/wl2k-go v0.11.4/go.mod h1:0c+/9KyDj7Ra7C/O4rVUYx1CzvdtS65di/93wlI22fo= +github.com/la5nta/wl2k-go v0.11.5/go.mod h1:0c+/9KyDj7Ra7C/O4rVUYx1CzvdtS65di/93wlI22fo= +github.com/la5nta/wl2k-go v0.11.8 h1:fTrOYm7oJu/b+3RmQMGX9TfpADnrFFkLzkDpfRTaEIs= +github.com/la5nta/wl2k-go v0.11.8/go.mod h1:rUK5mVAldeSuru47APLp9wJMJ5BiaZZ3YxZafSNs6CI= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/microcosm-cc/bluemonday v1.0.16 h1:kHmAq2t7WPWLjiGvzKa5o3HzSfahUKiOq7fAPUiMNIc= github.com/microcosm-cc/bluemonday v1.0.16/go.mod h1:Z0r70sCuXHig8YpBzCc5eGHAap2K7e/u082ZUpDRRqM= -github.com/n8jja/Pat-Vara v1.1.2 h1:5ChxlKlWPW/xrPqc6kN6Jh/ZYJpm07uRkQlQl0zyWq0= -github.com/n8jja/Pat-Vara v1.1.2/go.mod h1:eVJvcJZDzHuDoHShGHgNRBhd1i8IOr/Qktc79Tb+dBY= +github.com/n8jja/Pat-Vara v1.1.4 h1:yXqQjQQmpcXc9dA5XjRVvC1eYaFoErxvFeIHzLlPA90= +github.com/n8jja/Pat-Vara v1.1.4/go.mod h1:9ovT5w1MeVtQ336AqhoPmgiQ4eGDgNiygBxFvAiSJbc= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= github.com/paulrosania/go-charset v0.0.0-20151028000031-621bb39fcc83/go.mod h1:YnNlZP7l4MhyGQ4CBRwv6ohZTPrUJJZtEv4ZgADkbs4= @@ -65,18 +68,17 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= github.com/tarm/goserial v0.0.0-20151007205400-b3440c3c6355/go.mod h1:jcMo2Odv5FpDA6rp8bnczbUolcICW6t54K3s9gOlgII= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.7.0 h1:zaiO/rmgFjbmCXdSYJWQcdvOCsthmdaHfr3Gm2Kx4Ec= go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= golang.org/x/crypto v0.0.0-20210813211128-0a44fdfbc16e h1:VvfwVmMH40bpMeizC9/K7ipM5Qjucuu16RWfneFPyhQ= golang.org/x/crypto v0.0.0-20210813211128-0a44fdfbc16e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d h1:LO7XpTYMwTqxjLcGWPijK3vRXg1aWdlNOVOHRq45d7c= golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -84,19 +86,17 @@ golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210223212115-eede4237b368/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b h1:9zKuko04nR4gjZ4+DNjHqRlAJqbJETHwiNKDqTfOjfE= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/http.go b/http.go index bd6be852..11dea589 100644 --- a/http.go +++ b/http.go @@ -121,16 +121,18 @@ func ListenAndServe(ctx context.Context, addr string) error { r.HandleFunc("/api/current_gps_position", positionHandler).Methods("GET") r.HandleFunc("/api/qsy", qsyHandler).Methods("POST") r.HandleFunc("/api/rmslist", rmslistHandler).Methods("GET") + + r.PathPrefix("/dist/").Handler(distHandler()) r.HandleFunc("/ws", wsHandler) r.HandleFunc("/ui", uiHandler()).Methods("GET") r.HandleFunc("/", rootHandler).Methods("GET") - http.Handle("/", r) - http.Handle("/dist/", distHandler()) - websocketHub = NewWSHub() - srv := http.Server{Addr: addr} + srv := http.Server{ + Addr: addr, + Handler: r, + } errs := make(chan error, 1) go func() { errs <- srv.ListenAndServe() @@ -282,8 +284,10 @@ func postOutboundMessageHandler(w http.ResponseWriter, r *http.Request) { cookie, err := r.Cookie("forminstance") if err == nil { formData := formsMgr.GetPostedFormData(cookie.Value) - name := formsMgr.GetXMLAttachmentNameForForm(formData.TargetForm, formData.IsReply) - msg.AddFile(fbb.NewFile(name, []byte(formData.MsgXML))) + if xml := formData.MsgXML; xml != "" { + name := formsMgr.GetXMLAttachmentNameForForm(formData.TargetForm, formData.IsReply) + msg.AddFile(fbb.NewFile(name, []byte(formData.MsgXML))) + } } // Other fields @@ -359,7 +363,7 @@ func attachFile(f *multipart.FileHeader, msg *fbb.Message) error { return HTTPError{err, http.StatusInternalServerError} } - if isImageMediaType(f.Filename, f.Header.Get("Content-Type")) { + if isConvertableImageMediaType(f.Filename, f.Header.Get("Content-Type")) { log.Printf("Auto converting '%s' [%s]...", f.Filename, f.Header.Get("Content-Type")) if converted, err := convertImage(p); err != nil { diff --git a/internal/buildinfo/VERSION.go b/internal/buildinfo/VERSION.go index 665fcd15..440d12ff 100644 --- a/internal/buildinfo/VERSION.go +++ b/internal/buildinfo/VERSION.go @@ -15,5 +15,5 @@ const ( // Forks should NOT bump this unless they use a unique AppName. The Winlink // system uses this to derive the "these users should upgrade" wall of shame // from CMS connects. - Version = "0.15.0" + Version = "0.15.1" ) diff --git a/internal/forms/date.go b/internal/forms/date.go new file mode 100644 index 00000000..af0af8e4 --- /dev/null +++ b/internal/forms/date.go @@ -0,0 +1,14 @@ +package forms + +import ( + "strings" + "time" +) + +func formatDateTime(t time.Time) string { return t.Format("2006-01-02 15:04:05") } +func formatDateTimeUTC(t time.Time) string { return t.UTC().Format("2006-01-02 15:04:05Z07:00") } +func formatDate(t time.Time) string { return t.Format("2006-01-02") } +func formatTime(t time.Time) string { return t.Format("15:04:05") } +func formatDateUTC(t time.Time) string { return t.UTC().Format("2006-01-02Z07:00") } +func formatTimeUTC(t time.Time) string { return t.UTC().Format("15:04:05Z07:00") } +func formatUDTG(t time.Time) string { return strings.ToUpper(t.UTC().Format("021504Z07:00 Jan 2006")) } diff --git a/internal/forms/date_test.go b/internal/forms/date_test.go new file mode 100644 index 00000000..c5434da9 --- /dev/null +++ b/internal/forms/date_test.go @@ -0,0 +1,29 @@ +package forms + +import ( + "testing" + "time" +) + +func TestDateFormat(t *testing.T) { + now := time.Date(2023, 12, 31, 23, 59, 59, 0, time.FixedZone("UTC-4", -4*60*60)) + + tests := []struct { + fn func(t time.Time) string + expect string + }{ + {formatDateTime, "2023-12-31 23:59:59"}, + {formatDateTimeUTC, "2024-01-01 03:59:59Z"}, + {formatDate, "2023-12-31"}, + {formatTime, "23:59:59"}, + {formatDateUTC, "2024-01-01Z"}, + {formatTimeUTC, "03:59:59Z"}, + {formatUDTG, "010359Z JAN 2024"}, + } + + for i, tt := range tests { + if got := tt.fn(now); got != tt.expect { + t.Errorf("%d: got %q expected %q", i, got, tt.expect) + } + } +} diff --git a/internal/forms/forms.go b/internal/forms/forms.go index 21c24e22..3eaadfd1 100644 --- a/internal/forms/forms.go +++ b/internal/forms/forms.go @@ -631,17 +631,18 @@ func (m *Manager) buildFormFromTxt(txtPath string) (Form, error) { l := scanner.Text() switch { case strings.HasPrefix(l, "Form:"): - trimmed := strings.TrimSpace(strings.TrimPrefix(l, "Form:")) - fileNames := strings.Split(trimmed, ",") - if len(fileNames) >= 2 { - initial := strings.TrimSpace(fileNames[0]) - viewer := strings.TrimSpace(fileNames[1]) - form.InitialURI = path.Join(baseURI, initial) - form.ViewerURI = path.Join(baseURI, viewer) - } else { - view := strings.TrimSpace(fileNames[0]) - form.InitialURI = path.Join(baseURI, view) - form.ViewerURI = path.Join(baseURI, view) + // Form: , + files := strings.Split(strings.TrimPrefix(l, "Form:"), ",") + // Extend to absolute paths and add missing html extension + for i := range files { + files[i] = path.Join(baseURI, strings.TrimSpace(files[i])) + if ext := path.Ext(files[i]); ext == "" { + files[i] += ".html" + } + } + form.InitialURI = files[0] + if len(files) > 1 { + form.ViewerURI = files[1] } case strings.HasPrefix(l, "ReplyTemplate:"): form.ReplyTxtFileURI = path.Join(baseURI, strings.TrimSpace(strings.TrimPrefix(l, "ReplyTemplate:"))) @@ -813,16 +814,7 @@ func (m *Manager) fillFormTemplate(absPathTemplate string, formDestURL string, p log.Printf("Warning: unsupported string encoding in template %s, expected utf-8", absPathTemplate) } - var ( - now = time.Now() - nowDateTime = now.Format("2006-01-02 15:04:05") - nowDateTimeUTC = now.UTC().Format("2006-01-02 15:04:05Z") - nowDate = now.Format("2006-01-02") - nowTime = now.Format("15:04:05") - nowDateUTC = now.UTC().Format("2006-01-02Z") - nowTimeUTC = now.UTC().Format("15:04:05Z") - udtg = strings.ToUpper(now.UTC().Format("021504Z Jan 2006")) - ) + now := time.Now() validPos := "NO" nowPos, err := m.gpsPos() if err != nil { @@ -842,13 +834,13 @@ func (m *Manager) fillFormTemplate(absPathTemplate string, formDestURL string, p l = strings.ReplaceAll(l, "{MsgSender}", m.config.MyCall) l = strings.ReplaceAll(l, "{Callsign}", m.config.MyCall) l = strings.ReplaceAll(l, "{ProgramVersion}", "Pat "+m.config.AppVersion) - l = strings.ReplaceAll(l, "{DateTime}", nowDateTime) - l = strings.ReplaceAll(l, "{UDateTime}", nowDateTimeUTC) - l = strings.ReplaceAll(l, "{Date}", nowDate) - l = strings.ReplaceAll(l, "{UDate}", nowDateUTC) - l = strings.ReplaceAll(l, "{UDTG}", udtg) - l = strings.ReplaceAll(l, "{Time}", nowTime) - l = strings.ReplaceAll(l, "{UTime}", nowTimeUTC) + l = strings.ReplaceAll(l, "{DateTime}", formatDateTime(now)) + l = strings.ReplaceAll(l, "{UDateTime}", formatDateTimeUTC(now)) + l = strings.ReplaceAll(l, "{Date}", formatDate(now)) + l = strings.ReplaceAll(l, "{UDate}", formatDateUTC(now)) + l = strings.ReplaceAll(l, "{UDTG}", formatUDTG(now)) + l = strings.ReplaceAll(l, "{Time}", formatTime(now)) + l = strings.ReplaceAll(l, "{UTime}", formatTimeUTC(now)) l = strings.ReplaceAll(l, "{GPS}", gpsFmt(degreeMinute, nowPos)) l = strings.ReplaceAll(l, "{GPS_DECIMAL}", gpsFmt(decimal, nowPos)) l = strings.ReplaceAll(l, "{GPS_SIGNED_DECIMAL}", gpsFmt(signedDecimal, nowPos)) @@ -949,7 +941,10 @@ func (b formMessageBuilder) build() (MessageForm, error) { if err != nil { return MessageForm{}, err } - msgForm.AttachmentXML = fmt.Sprintf(`%s + + // Add XML if a viewer is defined for this form + if b.Template.ViewerURI != "" { + msgForm.AttachmentXML = fmt.Sprintf(`%s %s %s @@ -964,16 +959,18 @@ func (b formMessageBuilder) build() (MessageForm, error) { `, - xml.Header, - "1.0", - b.FormsMgr.config.AppVersion, - time.Now().UTC().Format("20060102150405"), - b.FormsMgr.config.MyCall, - b.FormsMgr.config.Locator, - viewer, - replier, - formVarsAsXML) - msgForm.AttachmentName = b.FormsMgr.GetXMLAttachmentNameForForm(b.Template, false) + xml.Header, + "1.0", + b.FormsMgr.config.AppVersion, + time.Now().UTC().Format("20060102150405"), + b.FormsMgr.config.MyCall, + b.FormsMgr.config.Locator, + viewer, + replier, + formVarsAsXML) + msgForm.AttachmentName = b.FormsMgr.GetXMLAttachmentNameForForm(b.Template, false) + } + msgForm.To = strings.TrimSpace(msgForm.To) msgForm.Cc = strings.TrimSpace(msgForm.Cc) msgForm.Subject = strings.TrimSpace(msgForm.Subject) diff --git a/internal/gpsd/gpsd.go b/internal/gpsd/gpsd.go index a133c26b..294931ca 100644 --- a/internal/gpsd/gpsd.go +++ b/internal/gpsd/gpsd.go @@ -127,8 +127,8 @@ func (c *Conn) Close() error { // Next returns the next object sent from the daemon, or an error. // // The empty interface returned can be any of the following types: -// * Sky: A Sky object reports a sky view of the GPS satellite positions. -// * TPV: A TPV object is a time-position-velocity report. +// - Sky: A Sky object reports a sky view of the GPS satellite positions. +// - TPV: A TPV object is a time-position-velocity report. func (c *Conn) Next() (interface{}, error) { c.mu.Lock() defer c.mu.Unlock() diff --git a/main.go b/main.go index 55f98336..73b506a7 100644 --- a/main.go +++ b/main.go @@ -534,6 +534,9 @@ func loadHamlibRigs() map[string]hamlib.VFO { log.Printf("Missing address-field for rig '%s', skipping.", name) continue } + if conf.Network == "" { + conf.Network = "tcp" + } rig, err := hamlib.Open(conf.Network, conf.Address) if err != nil { diff --git a/make.bash b/make.bash index 8798b9c8..8f973294 100755 --- a/make.bash +++ b/make.bash @@ -9,9 +9,9 @@ if [ -d $CGO_ENABLED ]; then CGO_ENABLED=$(go env CGO_ENABLED); else OS=$CGO_ENA GITREV=$(git rev-parse --short HEAD) VERSION=$(grep "Version =" internal/buildinfo/VERSION.go|cut -d '"' -f2) -# Go 1.16 or later is required +# Go 1.19 or later is required GO_POINT_VERSION=$(go version| perl -ne 'm/go1\.(\d+)/; print $1;') -[ "$GO_POINT_VERSION" -lt "16" ] && echo "Go 1.16 or later required" && exit 1; +[ "$GO_POINT_VERSION" -lt "19" ] && echo "Go 1.19 or later required" && exit 1; AX25VERSION="0.0.12-rc4" AX25DIST="libax25-${AX25VERSION}" diff --git a/osx/pat.pkgproj b/osx/pat.pkgproj index f597cb1b..b5a2a24e 100644 --- a/osx/pat.pkgproj +++ b/osx/pat.pkgproj @@ -588,7 +588,7 @@ USE_HFS+_COMPRESSION VERSION - 0.15.0 + 0.15.1 UUID 5562F199-B4C6-48BC-98FA-5BBA494CB61F diff --git a/riglist.go b/riglist.go index 7a49e4d2..744f55be 100644 --- a/riglist.go +++ b/riglist.go @@ -8,6 +8,7 @@ package main import ( + "context" "fmt" "strings" @@ -25,7 +26,10 @@ func init() { commands = append(commands[:8], append([]Command{cmd}, commands[8:]...)...) } -func riglistHandle(args []string) { +func riglistHandle(ctx context.Context, args []string) { + if args[0] == "" { + fmt.Println("Missing argument") + } term := strings.ToLower(args[0]) fmt.Print("id\ttransceiver\n") diff --git a/web/.nvmrc b/web/.nvmrc index 7480d3c8..c32828c2 100644 --- a/web/.nvmrc +++ b/web/.nvmrc @@ -1 +1 @@ -lts/fermium \ No newline at end of file +lts/hydrogen \ No newline at end of file diff --git a/web/dist/js/app.js b/web/dist/js/app.js index 2c461f1d..e202eccc 100644 --- a/web/dist/js/app.js +++ b/web/dist/js/app.js @@ -1,3 +1,3 @@ /*! For license information please see app.js.LICENSE.txt */ -!function(t){var e={};function n(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return t[i].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=t,n.c=e,n.d=function(t,e,i){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:i})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)n.d(i,o,function(e){return t[e]}.bind(null,o));return i},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="../",n(n.s=5)}([function(t,e,n){var i;!function(e,n){"use strict";"object"==typeof t.exports?t.exports=e.document?n(e,!0):function(t){if(!t.document)throw new Error("jQuery requires a window with a document");return n(t)}:n(e)}("undefined"!=typeof window?window:this,(function(n,o){"use strict";var r=[],s=Object.getPrototypeOf,a=r.slice,l=r.flat?function(t){return r.flat.call(t)}:function(t){return r.concat.apply([],t)},c=r.push,u=r.indexOf,p={},d=p.toString,h=p.hasOwnProperty,f=h.toString,m=f.call(Object),g={},v=function(t){return"function"==typeof t&&"number"!=typeof t.nodeType&&"function"!=typeof t.item},y=function(t){return null!=t&&t===t.window},b=n.document,x={type:!0,src:!0,nonce:!0,noModule:!0};function w(t,e,n){var i,o,r=(n=n||b).createElement("script");if(r.text=t,e)for(i in x)(o=e[i]||e.getAttribute&&e.getAttribute(i))&&r.setAttribute(i,o);n.head.appendChild(r).parentNode.removeChild(r)}function k(t){return null==t?t+"":"object"==typeof t||"function"==typeof t?p[d.call(t)]||"object":typeof t}var $="3.6.0",C=function(t,e){return new C.fn.init(t,e)};function T(t){var e=!!t&&"length"in t&&t.length,n=k(t);return!v(t)&&!y(t)&&("array"===n||0===e||"number"==typeof e&&e>0&&e-1 in t)}C.fn=C.prototype={jquery:$,constructor:C,length:0,toArray:function(){return a.call(this)},get:function(t){return null==t?a.call(this):t<0?this[t+this.length]:this[t]},pushStack:function(t){var e=C.merge(this.constructor(),t);return e.prevObject=this,e},each:function(t){return C.each(this,t)},map:function(t){return this.pushStack(C.map(this,(function(e,n){return t.call(e,n,e)})))},slice:function(){return this.pushStack(a.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(C.grep(this,(function(t,e){return(e+1)%2})))},odd:function(){return this.pushStack(C.grep(this,(function(t,e){return e%2})))},eq:function(t){var e=this.length,n=+t+(t<0?e:0);return this.pushStack(n>=0&&n+~]|[\\x20\\t\\r\\n\\f])[\\x20\\t\\r\\n\\f]*"),B=new RegExp(L+"|>"),Q=new RegExp(F),V=new RegExp("^"+z+"$"),G={ID:new RegExp("^#("+z+")"),CLASS:new RegExp("^\\.("+z+")"),TAG:new RegExp("^("+z+"|[*])"),ATTR:new RegExp("^"+R),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\([\\x20\\t\\r\\n\\f]*(even|odd|(([+-]|)(\\d*)n|)[\\x20\\t\\r\\n\\f]*(?:([+-]|)[\\x20\\t\\r\\n\\f]*(\\d+)|))[\\x20\\t\\r\\n\\f]*\\)|)","i"),bool:new RegExp("^(?:"+q+")$","i"),needsContext:new RegExp("^[\\x20\\t\\r\\n\\f]*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\([\\x20\\t\\r\\n\\f]*((?:-\\d)?\\d*)[\\x20\\t\\r\\n\\f]*\\)|)(?=[^-]|$)","i")},X=/HTML$/i,J=/^(?:input|select|textarea|button)$/i,K=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,tt=/[+~]/,et=new RegExp("\\\\[\\da-fA-F]{1,6}[\\x20\\t\\r\\n\\f]?|\\\\([^\\r\\n\\f])","g"),nt=function(t,e){var n="0x"+t.slice(1)-65536;return e||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},it=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ot=function(t,e){return e?"\0"===t?"�":t.slice(0,-1)+"\\"+t.charCodeAt(t.length-1).toString(16)+" ":"\\"+t},rt=function(){d()},st=xt((function(t){return!0===t.disabled&&"fieldset"===t.nodeName.toLowerCase()}),{dir:"parentNode",next:"legend"});try{N.apply(D=P.call(w.childNodes),w.childNodes),D[w.childNodes.length].nodeType}catch(t){N={apply:D.length?function(t,e){j.apply(t,P.call(e))}:function(t,e){for(var n=t.length,i=0;t[n++]=e[i++];);t.length=n-1}}}function at(t,e,i,o){var r,a,c,u,p,f,v,y=e&&e.ownerDocument,w=e?e.nodeType:9;if(i=i||[],"string"!=typeof t||!t||1!==w&&9!==w&&11!==w)return i;if(!o&&(d(e),e=e||h,m)){if(11!==w&&(p=Z.exec(t)))if(r=p[1]){if(9===w){if(!(c=e.getElementById(r)))return i;if(c.id===r)return i.push(c),i}else if(y&&(c=y.getElementById(r))&&b(e,c)&&c.id===r)return i.push(c),i}else{if(p[2])return N.apply(i,e.getElementsByTagName(t)),i;if((r=p[3])&&n.getElementsByClassName&&e.getElementsByClassName)return N.apply(i,e.getElementsByClassName(r)),i}if(n.qsa&&!_[t+" "]&&(!g||!g.test(t))&&(1!==w||"object"!==e.nodeName.toLowerCase())){if(v=t,y=e,1===w&&(B.test(t)||W.test(t))){for((y=tt.test(t)&&vt(e.parentNode)||e)===e&&n.scope||((u=e.getAttribute("id"))?u=u.replace(it,ot):e.setAttribute("id",u=x)),a=(f=s(t)).length;a--;)f[a]=(u?"#"+u:":scope")+" "+bt(f[a]);v=f.join(",")}try{return N.apply(i,y.querySelectorAll(v)),i}catch(e){_(t,!0)}finally{u===x&&e.removeAttribute("id")}}}return l(t.replace(M,"$1"),e,i,o)}function lt(){var t=[];return function e(n,o){return t.push(n+" ")>i.cacheLength&&delete e[t.shift()],e[n+" "]=o}}function ct(t){return t[x]=!0,t}function ut(t){var e=h.createElement("fieldset");try{return!!t(e)}catch(t){return!1}finally{e.parentNode&&e.parentNode.removeChild(e),e=null}}function pt(t,e){for(var n=t.split("|"),o=n.length;o--;)i.attrHandle[n[o]]=e}function dt(t,e){var n=e&&t,i=n&&1===t.nodeType&&1===e.nodeType&&t.sourceIndex-e.sourceIndex;if(i)return i;if(n)for(;n=n.nextSibling;)if(n===e)return-1;return t?1:-1}function ht(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function ft(t){return function(e){var n=e.nodeName.toLowerCase();return("input"===n||"button"===n)&&e.type===t}}function mt(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&st(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function gt(t){return ct((function(e){return e=+e,ct((function(n,i){for(var o,r=t([],n.length,e),s=r.length;s--;)n[o=r[s]]&&(n[o]=!(i[o]=n[o]))}))}))}function vt(t){return t&&void 0!==t.getElementsByTagName&&t}for(e in n=at.support={},r=at.isXML=function(t){var e=t&&t.namespaceURI,n=t&&(t.ownerDocument||t).documentElement;return!X.test(e||n&&n.nodeName||"HTML")},d=at.setDocument=function(t){var e,o,s=t?t.ownerDocument||t:w;return s!=h&&9===s.nodeType&&s.documentElement?(f=(h=s).documentElement,m=!r(h),w!=h&&(o=h.defaultView)&&o.top!==o&&(o.addEventListener?o.addEventListener("unload",rt,!1):o.attachEvent&&o.attachEvent("onunload",rt)),n.scope=ut((function(t){return f.appendChild(t).appendChild(h.createElement("div")),void 0!==t.querySelectorAll&&!t.querySelectorAll(":scope fieldset div").length})),n.attributes=ut((function(t){return t.className="i",!t.getAttribute("className")})),n.getElementsByTagName=ut((function(t){return t.appendChild(h.createComment("")),!t.getElementsByTagName("*").length})),n.getElementsByClassName=Y.test(h.getElementsByClassName),n.getById=ut((function(t){return f.appendChild(t).id=x,!h.getElementsByName||!h.getElementsByName(x).length})),n.getById?(i.filter.ID=function(t){var e=t.replace(et,nt);return function(t){return t.getAttribute("id")===e}},i.find.ID=function(t,e){if(void 0!==e.getElementById&&m){var n=e.getElementById(t);return n?[n]:[]}}):(i.filter.ID=function(t){var e=t.replace(et,nt);return function(t){var n=void 0!==t.getAttributeNode&&t.getAttributeNode("id");return n&&n.value===e}},i.find.ID=function(t,e){if(void 0!==e.getElementById&&m){var n,i,o,r=e.getElementById(t);if(r){if((n=r.getAttributeNode("id"))&&n.value===t)return[r];for(o=e.getElementsByName(t),i=0;r=o[i++];)if((n=r.getAttributeNode("id"))&&n.value===t)return[r]}return[]}}),i.find.TAG=n.getElementsByTagName?function(t,e){return void 0!==e.getElementsByTagName?e.getElementsByTagName(t):n.qsa?e.querySelectorAll(t):void 0}:function(t,e){var n,i=[],o=0,r=e.getElementsByTagName(t);if("*"===t){for(;n=r[o++];)1===n.nodeType&&i.push(n);return i}return r},i.find.CLASS=n.getElementsByClassName&&function(t,e){if(void 0!==e.getElementsByClassName&&m)return e.getElementsByClassName(t)},v=[],g=[],(n.qsa=Y.test(h.querySelectorAll))&&(ut((function(t){var e;f.appendChild(t).innerHTML="",t.querySelectorAll("[msallowcapture^='']").length&&g.push("[*^$]=[\\x20\\t\\r\\n\\f]*(?:''|\"\")"),t.querySelectorAll("[selected]").length||g.push("\\[[\\x20\\t\\r\\n\\f]*(?:value|"+q+")"),t.querySelectorAll("[id~="+x+"-]").length||g.push("~="),(e=h.createElement("input")).setAttribute("name",""),t.appendChild(e),t.querySelectorAll("[name='']").length||g.push("\\[[\\x20\\t\\r\\n\\f]*name[\\x20\\t\\r\\n\\f]*=[\\x20\\t\\r\\n\\f]*(?:''|\"\")"),t.querySelectorAll(":checked").length||g.push(":checked"),t.querySelectorAll("a#"+x+"+*").length||g.push(".#.+[+~]"),t.querySelectorAll("\\\f"),g.push("[\\r\\n\\f]")})),ut((function(t){t.innerHTML="";var e=h.createElement("input");e.setAttribute("type","hidden"),t.appendChild(e).setAttribute("name","D"),t.querySelectorAll("[name=d]").length&&g.push("name[\\x20\\t\\r\\n\\f]*[*^$|!~]?="),2!==t.querySelectorAll(":enabled").length&&g.push(":enabled",":disabled"),f.appendChild(t).disabled=!0,2!==t.querySelectorAll(":disabled").length&&g.push(":enabled",":disabled"),t.querySelectorAll("*,:x"),g.push(",.*:")}))),(n.matchesSelector=Y.test(y=f.matches||f.webkitMatchesSelector||f.mozMatchesSelector||f.oMatchesSelector||f.msMatchesSelector))&&ut((function(t){n.disconnectedMatch=y.call(t,"*"),y.call(t,"[s!='']:x"),v.push("!=",F)})),g=g.length&&new RegExp(g.join("|")),v=v.length&&new RegExp(v.join("|")),e=Y.test(f.compareDocumentPosition),b=e||Y.test(f.contains)?function(t,e){var n=9===t.nodeType?t.documentElement:t,i=e&&e.parentNode;return t===i||!(!i||1!==i.nodeType||!(n.contains?n.contains(i):t.compareDocumentPosition&&16&t.compareDocumentPosition(i)))}:function(t,e){if(e)for(;e=e.parentNode;)if(e===t)return!0;return!1},E=e?function(t,e){if(t===e)return p=!0,0;var i=!t.compareDocumentPosition-!e.compareDocumentPosition;return i||(1&(i=(t.ownerDocument||t)==(e.ownerDocument||e)?t.compareDocumentPosition(e):1)||!n.sortDetached&&e.compareDocumentPosition(t)===i?t==h||t.ownerDocument==w&&b(w,t)?-1:e==h||e.ownerDocument==w&&b(w,e)?1:u?O(u,t)-O(u,e):0:4&i?-1:1)}:function(t,e){if(t===e)return p=!0,0;var n,i=0,o=t.parentNode,r=e.parentNode,s=[t],a=[e];if(!o||!r)return t==h?-1:e==h?1:o?-1:r?1:u?O(u,t)-O(u,e):0;if(o===r)return dt(t,e);for(n=t;n=n.parentNode;)s.unshift(n);for(n=e;n=n.parentNode;)a.unshift(n);for(;s[i]===a[i];)i++;return i?dt(s[i],a[i]):s[i]==w?-1:a[i]==w?1:0},h):h},at.matches=function(t,e){return at(t,null,null,e)},at.matchesSelector=function(t,e){if(d(t),n.matchesSelector&&m&&!_[e+" "]&&(!v||!v.test(e))&&(!g||!g.test(e)))try{var i=y.call(t,e);if(i||n.disconnectedMatch||t.document&&11!==t.document.nodeType)return i}catch(t){_(e,!0)}return at(e,h,null,[t]).length>0},at.contains=function(t,e){return(t.ownerDocument||t)!=h&&d(t),b(t,e)},at.attr=function(t,e){(t.ownerDocument||t)!=h&&d(t);var o=i.attrHandle[e.toLowerCase()],r=o&&A.call(i.attrHandle,e.toLowerCase())?o(t,e,!m):void 0;return void 0!==r?r:n.attributes||!m?t.getAttribute(e):(r=t.getAttributeNode(e))&&r.specified?r.value:null},at.escape=function(t){return(t+"").replace(it,ot)},at.error=function(t){throw new Error("Syntax error, unrecognized expression: "+t)},at.uniqueSort=function(t){var e,i=[],o=0,r=0;if(p=!n.detectDuplicates,u=!n.sortStable&&t.slice(0),t.sort(E),p){for(;e=t[r++];)e===t[r]&&(o=i.push(r));for(;o--;)t.splice(i[o],1)}return u=null,t},o=at.getText=function(t){var e,n="",i=0,r=t.nodeType;if(r){if(1===r||9===r||11===r){if("string"==typeof t.textContent)return t.textContent;for(t=t.firstChild;t;t=t.nextSibling)n+=o(t)}else if(3===r||4===r)return t.nodeValue}else for(;e=t[i++];)n+=o(e);return n},i=at.selectors={cacheLength:50,createPseudo:ct,match:G,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(t){return t[1]=t[1].replace(et,nt),t[3]=(t[3]||t[4]||t[5]||"").replace(et,nt),"~="===t[2]&&(t[3]=" "+t[3]+" "),t.slice(0,4)},CHILD:function(t){return t[1]=t[1].toLowerCase(),"nth"===t[1].slice(0,3)?(t[3]||at.error(t[0]),t[4]=+(t[4]?t[5]+(t[6]||1):2*("even"===t[3]||"odd"===t[3])),t[5]=+(t[7]+t[8]||"odd"===t[3])):t[3]&&at.error(t[0]),t},PSEUDO:function(t){var e,n=!t[6]&&t[2];return G.CHILD.test(t[0])?null:(t[3]?t[2]=t[4]||t[5]||"":n&&Q.test(n)&&(e=s(n,!0))&&(e=n.indexOf(")",n.length-e)-n.length)&&(t[0]=t[0].slice(0,e),t[2]=n.slice(0,e)),t.slice(0,3))}},filter:{TAG:function(t){var e=t.replace(et,nt).toLowerCase();return"*"===t?function(){return!0}:function(t){return t.nodeName&&t.nodeName.toLowerCase()===e}},CLASS:function(t){var e=C[t+" "];return e||(e=new RegExp("(^|[\\x20\\t\\r\\n\\f])"+t+"("+L+"|$)"))&&C(t,(function(t){return e.test("string"==typeof t.className&&t.className||void 0!==t.getAttribute&&t.getAttribute("class")||"")}))},ATTR:function(t,e,n){return function(i){var o=at.attr(i,t);return null==o?"!="===e:!e||(o+="","="===e?o===n:"!="===e?o!==n:"^="===e?n&&0===o.indexOf(n):"*="===e?n&&o.indexOf(n)>-1:"$="===e?n&&o.slice(-n.length)===n:"~="===e?(" "+o.replace(H," ")+" ").indexOf(n)>-1:"|="===e&&(o===n||o.slice(0,n.length+1)===n+"-"))}},CHILD:function(t,e,n,i,o){var r="nth"!==t.slice(0,3),s="last"!==t.slice(-4),a="of-type"===e;return 1===i&&0===o?function(t){return!!t.parentNode}:function(e,n,l){var c,u,p,d,h,f,m=r!==s?"nextSibling":"previousSibling",g=e.parentNode,v=a&&e.nodeName.toLowerCase(),y=!l&&!a,b=!1;if(g){if(r){for(;m;){for(d=e;d=d[m];)if(a?d.nodeName.toLowerCase()===v:1===d.nodeType)return!1;f=m="only"===t&&!f&&"nextSibling"}return!0}if(f=[s?g.firstChild:g.lastChild],s&&y){for(b=(h=(c=(u=(p=(d=g)[x]||(d[x]={}))[d.uniqueID]||(p[d.uniqueID]={}))[t]||[])[0]===k&&c[1])&&c[2],d=h&&g.childNodes[h];d=++h&&d&&d[m]||(b=h=0)||f.pop();)if(1===d.nodeType&&++b&&d===e){u[t]=[k,h,b];break}}else if(y&&(b=h=(c=(u=(p=(d=e)[x]||(d[x]={}))[d.uniqueID]||(p[d.uniqueID]={}))[t]||[])[0]===k&&c[1]),!1===b)for(;(d=++h&&d&&d[m]||(b=h=0)||f.pop())&&((a?d.nodeName.toLowerCase()!==v:1!==d.nodeType)||!++b||(y&&((u=(p=d[x]||(d[x]={}))[d.uniqueID]||(p[d.uniqueID]={}))[t]=[k,b]),d!==e)););return(b-=o)===i||b%i==0&&b/i>=0}}},PSEUDO:function(t,e){var n,o=i.pseudos[t]||i.setFilters[t.toLowerCase()]||at.error("unsupported pseudo: "+t);return o[x]?o(e):o.length>1?(n=[t,t,"",e],i.setFilters.hasOwnProperty(t.toLowerCase())?ct((function(t,n){for(var i,r=o(t,e),s=r.length;s--;)t[i=O(t,r[s])]=!(n[i]=r[s])})):function(t){return o(t,0,n)}):o}},pseudos:{not:ct((function(t){var e=[],n=[],i=a(t.replace(M,"$1"));return i[x]?ct((function(t,e,n,o){for(var r,s=i(t,null,o,[]),a=t.length;a--;)(r=s[a])&&(t[a]=!(e[a]=r))})):function(t,o,r){return e[0]=t,i(e,null,r,n),e[0]=null,!n.pop()}})),has:ct((function(t){return function(e){return at(t,e).length>0}})),contains:ct((function(t){return t=t.replace(et,nt),function(e){return(e.textContent||o(e)).indexOf(t)>-1}})),lang:ct((function(t){return V.test(t||"")||at.error("unsupported lang: "+t),t=t.replace(et,nt).toLowerCase(),function(e){var n;do{if(n=m?e.lang:e.getAttribute("xml:lang")||e.getAttribute("lang"))return(n=n.toLowerCase())===t||0===n.indexOf(t+"-")}while((e=e.parentNode)&&1===e.nodeType);return!1}})),target:function(e){var n=t.location&&t.location.hash;return n&&n.slice(1)===e.id},root:function(t){return t===f},focus:function(t){return t===h.activeElement&&(!h.hasFocus||h.hasFocus())&&!!(t.type||t.href||~t.tabIndex)},enabled:mt(!1),disabled:mt(!0),checked:function(t){var e=t.nodeName.toLowerCase();return"input"===e&&!!t.checked||"option"===e&&!!t.selected},selected:function(t){return t.parentNode&&t.parentNode.selectedIndex,!0===t.selected},empty:function(t){for(t=t.firstChild;t;t=t.nextSibling)if(t.nodeType<6)return!1;return!0},parent:function(t){return!i.pseudos.empty(t)},header:function(t){return K.test(t.nodeName)},input:function(t){return J.test(t.nodeName)},button:function(t){var e=t.nodeName.toLowerCase();return"input"===e&&"button"===t.type||"button"===e},text:function(t){var e;return"input"===t.nodeName.toLowerCase()&&"text"===t.type&&(null==(e=t.getAttribute("type"))||"text"===e.toLowerCase())},first:gt((function(){return[0]})),last:gt((function(t,e){return[e-1]})),eq:gt((function(t,e,n){return[n<0?n+e:n]})),even:gt((function(t,e){for(var n=0;ne?e:n;--i>=0;)t.push(i);return t})),gt:gt((function(t,e,n){for(var i=n<0?n+e:n;++i1?function(e,n,i){for(var o=t.length;o--;)if(!t[o](e,n,i))return!1;return!0}:t[0]}function kt(t,e,n,i,o){for(var r,s=[],a=0,l=t.length,c=null!=e;a-1&&(r[c]=!(s[c]=p))}}else v=kt(v===s?v.splice(f,v.length):v),o?o(null,s,v,l):N.apply(s,v)}))}function Ct(t){for(var e,n,o,r=t.length,s=i.relative[t[0].type],a=s||i.relative[" "],l=s?1:0,u=xt((function(t){return t===e}),a,!0),p=xt((function(t){return O(e,t)>-1}),a,!0),d=[function(t,n,i){var o=!s&&(i||n!==c)||((e=n).nodeType?u(t,n,i):p(t,n,i));return e=null,o}];l1&&wt(d),l>1&&bt(t.slice(0,l-1).concat({value:" "===t[l-2].type?"*":""})).replace(M,"$1"),n,l0,o=t.length>0,r=function(r,s,a,l,u){var p,f,g,v=0,y="0",b=r&&[],x=[],w=c,$=r||o&&i.find.TAG("*",u),C=k+=null==w?1:Math.random()||.1,T=$.length;for(u&&(c=s==h||s||u);y!==T&&null!=(p=$[y]);y++){if(o&&p){for(f=0,s||p.ownerDocument==h||(d(p),a=!m);g=t[f++];)if(g(p,s||h,a)){l.push(p);break}u&&(k=C)}n&&((p=!g&&p)&&v--,r&&b.push(p))}if(v+=y,n&&y!==v){for(f=0;g=e[f++];)g(b,x,s,a);if(r){if(v>0)for(;y--;)b[y]||x[y]||(x[y]=I.call(l));x=kt(x)}N.apply(l,x),u&&!r&&x.length>0&&v+e.length>1&&at.uniqueSort(l)}return u&&(k=C,c=w),b};return n?ct(r):r}(r,o)),a.selector=t}return a},l=at.select=function(t,e,n,o){var r,l,c,u,p,d="function"==typeof t&&t,h=!o&&s(t=d.selector||t);if(n=n||[],1===h.length){if((l=h[0]=h[0].slice(0)).length>2&&"ID"===(c=l[0]).type&&9===e.nodeType&&m&&i.relative[l[1].type]){if(!(e=(i.find.ID(c.matches[0].replace(et,nt),e)||[])[0]))return n;d&&(e=e.parentNode),t=t.slice(l.shift().value.length)}for(r=G.needsContext.test(t)?0:l.length;r--&&(c=l[r],!i.relative[u=c.type]);)if((p=i.find[u])&&(o=p(c.matches[0].replace(et,nt),tt.test(l[0].type)&&vt(e.parentNode)||e))){if(l.splice(r,1),!(t=o.length&&bt(l)))return N.apply(n,o),n;break}}return(d||a(t,h))(o,e,!m,n,!e||tt.test(t)&&vt(e.parentNode)||e),n},n.sortStable=x.split("").sort(E).join("")===x,n.detectDuplicates=!!p,d(),n.sortDetached=ut((function(t){return 1&t.compareDocumentPosition(h.createElement("fieldset"))})),ut((function(t){return t.innerHTML="","#"===t.firstChild.getAttribute("href")}))||pt("type|href|height|width",(function(t,e,n){if(!n)return t.getAttribute(e,"type"===e.toLowerCase()?1:2)})),n.attributes&&ut((function(t){return t.innerHTML="",t.firstChild.setAttribute("value",""),""===t.firstChild.getAttribute("value")}))||pt("value",(function(t,e,n){if(!n&&"input"===t.nodeName.toLowerCase())return t.defaultValue})),ut((function(t){return null==t.getAttribute("disabled")}))||pt(q,(function(t,e,n){var i;if(!n)return!0===t[e]?e.toLowerCase():(i=t.getAttributeNode(e))&&i.specified?i.value:null})),at}(n);C.find=S,C.expr=S.selectors,C.expr[":"]=C.expr.pseudos,C.uniqueSort=C.unique=S.uniqueSort,C.text=S.getText,C.isXMLDoc=S.isXML,C.contains=S.contains,C.escapeSelector=S.escape;var _=function(t,e,n){for(var i=[],o=void 0!==n;(t=t[e])&&9!==t.nodeType;)if(1===t.nodeType){if(o&&C(t).is(n))break;i.push(t)}return i},E=function(t,e){for(var n=[];t;t=t.nextSibling)1===t.nodeType&&t!==e&&n.push(t);return n},A=C.expr.match.needsContext;function D(t,e){return t.nodeName&&t.nodeName.toLowerCase()===e.toLowerCase()}var I=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(t,e,n){return v(e)?C.grep(t,(function(t,i){return!!e.call(t,i,t)!==n})):e.nodeType?C.grep(t,(function(t){return t===e!==n})):"string"!=typeof e?C.grep(t,(function(t){return u.call(e,t)>-1!==n})):C.filter(e,t,n)}C.filter=function(t,e,n){var i=e[0];return n&&(t=":not("+t+")"),1===e.length&&1===i.nodeType?C.find.matchesSelector(i,t)?[i]:[]:C.find.matches(t,C.grep(e,(function(t){return 1===t.nodeType})))},C.fn.extend({find:function(t){var e,n,i=this.length,o=this;if("string"!=typeof t)return this.pushStack(C(t).filter((function(){for(e=0;e1?C.uniqueSort(n):n},filter:function(t){return this.pushStack(j(this,t||[],!1))},not:function(t){return this.pushStack(j(this,t||[],!0))},is:function(t){return!!j(this,"string"==typeof t&&A.test(t)?C(t):t||[],!1).length}});var N,P=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(C.fn.init=function(t,e,n){var i,o;if(!t)return this;if(n=n||N,"string"==typeof t){if(!(i="<"===t[0]&&">"===t[t.length-1]&&t.length>=3?[null,t,null]:P.exec(t))||!i[1]&&e)return!e||e.jquery?(e||n).find(t):this.constructor(e).find(t);if(i[1]){if(e=e instanceof C?e[0]:e,C.merge(this,C.parseHTML(i[1],e&&e.nodeType?e.ownerDocument||e:b,!0)),I.test(i[1])&&C.isPlainObject(e))for(i in e)v(this[i])?this[i](e[i]):this.attr(i,e[i]);return this}return(o=b.getElementById(i[2]))&&(this[0]=o,this.length=1),this}return t.nodeType?(this[0]=t,this.length=1,this):v(t)?void 0!==n.ready?n.ready(t):t(C):C.makeArray(t,this)}).prototype=C.fn,N=C(b);var O=/^(?:parents|prev(?:Until|All))/,q={children:!0,contents:!0,next:!0,prev:!0};function L(t,e){for(;(t=t[e])&&1!==t.nodeType;);return t}C.fn.extend({has:function(t){var e=C(t,this),n=e.length;return this.filter((function(){for(var t=0;t-1:1===n.nodeType&&C.find.matchesSelector(n,t))){r.push(n);break}return this.pushStack(r.length>1?C.uniqueSort(r):r)},index:function(t){return t?"string"==typeof t?u.call(C(t),this[0]):u.call(this,t.jquery?t[0]:t):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(t,e){return this.pushStack(C.uniqueSort(C.merge(this.get(),C(t,e))))},addBack:function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}}),C.each({parent:function(t){var e=t.parentNode;return e&&11!==e.nodeType?e:null},parents:function(t){return _(t,"parentNode")},parentsUntil:function(t,e,n){return _(t,"parentNode",n)},next:function(t){return L(t,"nextSibling")},prev:function(t){return L(t,"previousSibling")},nextAll:function(t){return _(t,"nextSibling")},prevAll:function(t){return _(t,"previousSibling")},nextUntil:function(t,e,n){return _(t,"nextSibling",n)},prevUntil:function(t,e,n){return _(t,"previousSibling",n)},siblings:function(t){return E((t.parentNode||{}).firstChild,t)},children:function(t){return E(t.firstChild)},contents:function(t){return null!=t.contentDocument&&s(t.contentDocument)?t.contentDocument:(D(t,"template")&&(t=t.content||t),C.merge([],t.childNodes))}},(function(t,e){C.fn[t]=function(n,i){var o=C.map(this,e,n);return"Until"!==t.slice(-5)&&(i=n),i&&"string"==typeof i&&(o=C.filter(i,o)),this.length>1&&(q[t]||C.uniqueSort(o),O.test(t)&&o.reverse()),this.pushStack(o)}}));var z=/[^\x20\t\r\n\f]+/g;function R(t){return t}function F(t){throw t}function H(t,e,n,i){var o;try{t&&v(o=t.promise)?o.call(t).done(e).fail(n):t&&v(o=t.then)?o.call(t,e,n):e.apply(void 0,[t].slice(i))}catch(t){n.apply(void 0,[t])}}C.Callbacks=function(t){t="string"==typeof t?function(t){var e={};return C.each(t.match(z)||[],(function(t,n){e[n]=!0})),e}(t):C.extend({},t);var e,n,i,o,r=[],s=[],a=-1,l=function(){for(o=o||t.once,i=e=!0;s.length;a=-1)for(n=s.shift();++a-1;)r.splice(n,1),n<=a&&a--})),this},has:function(t){return t?C.inArray(t,r)>-1:r.length>0},empty:function(){return r&&(r=[]),this},disable:function(){return o=s=[],r=n="",this},disabled:function(){return!r},lock:function(){return o=s=[],n||e||(r=n=""),this},locked:function(){return!!o},fireWith:function(t,n){return o||(n=[t,(n=n||[]).slice?n.slice():n],s.push(n),e||l()),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!i}};return c},C.extend({Deferred:function(t){var e=[["notify","progress",C.Callbacks("memory"),C.Callbacks("memory"),2],["resolve","done",C.Callbacks("once memory"),C.Callbacks("once memory"),0,"resolved"],["reject","fail",C.Callbacks("once memory"),C.Callbacks("once memory"),1,"rejected"]],i="pending",o={state:function(){return i},always:function(){return r.done(arguments).fail(arguments),this},catch:function(t){return o.then(null,t)},pipe:function(){var t=arguments;return C.Deferred((function(n){C.each(e,(function(e,i){var o=v(t[i[4]])&&t[i[4]];r[i[1]]((function(){var t=o&&o.apply(this,arguments);t&&v(t.promise)?t.promise().progress(n.notify).done(n.resolve).fail(n.reject):n[i[0]+"With"](this,o?[t]:arguments)}))})),t=null})).promise()},then:function(t,i,o){var r=0;function s(t,e,i,o){return function(){var a=this,l=arguments,c=function(){var n,c;if(!(t=r&&(i!==F&&(a=void 0,l=[n]),e.rejectWith(a,l))}};t?u():(C.Deferred.getStackHook&&(u.stackTrace=C.Deferred.getStackHook()),n.setTimeout(u))}}return C.Deferred((function(n){e[0][3].add(s(0,n,v(o)?o:R,n.notifyWith)),e[1][3].add(s(0,n,v(t)?t:R)),e[2][3].add(s(0,n,v(i)?i:F))})).promise()},promise:function(t){return null!=t?C.extend(t,o):o}},r={};return C.each(e,(function(t,n){var s=n[2],a=n[5];o[n[1]]=s.add,a&&s.add((function(){i=a}),e[3-t][2].disable,e[3-t][3].disable,e[0][2].lock,e[0][3].lock),s.add(n[3].fire),r[n[0]]=function(){return r[n[0]+"With"](this===r?void 0:this,arguments),this},r[n[0]+"With"]=s.fireWith})),o.promise(r),t&&t.call(r,r),r},when:function(t){var e=arguments.length,n=e,i=Array(n),o=a.call(arguments),r=C.Deferred(),s=function(t){return function(n){i[t]=this,o[t]=arguments.length>1?a.call(arguments):n,--e||r.resolveWith(i,o)}};if(e<=1&&(H(t,r.done(s(n)).resolve,r.reject,!e),"pending"===r.state()||v(o[n]&&o[n].then)))return r.then();for(;n--;)H(o[n],s(n),r.reject);return r.promise()}});var M=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;C.Deferred.exceptionHook=function(t,e){n.console&&n.console.warn&&t&&M.test(t.name)&&n.console.warn("jQuery.Deferred exception: "+t.message,t.stack,e)},C.readyException=function(t){n.setTimeout((function(){throw t}))};var U=C.Deferred();function W(){b.removeEventListener("DOMContentLoaded",W),n.removeEventListener("load",W),C.ready()}C.fn.ready=function(t){return U.then(t).catch((function(t){C.readyException(t)})),this},C.extend({isReady:!1,readyWait:1,ready:function(t){(!0===t?--C.readyWait:C.isReady)||(C.isReady=!0,!0!==t&&--C.readyWait>0||U.resolveWith(b,[C]))}}),C.ready.then=U.then,"complete"===b.readyState||"loading"!==b.readyState&&!b.documentElement.doScroll?n.setTimeout(C.ready):(b.addEventListener("DOMContentLoaded",W),n.addEventListener("load",W));var B=function(t,e,n,i,o,r,s){var a=0,l=t.length,c=null==n;if("object"===k(n))for(a in o=!0,n)B(t,e,a,n[a],!0,r,s);else if(void 0!==i&&(o=!0,v(i)||(s=!0),c&&(s?(e.call(t,i),e=null):(c=e,e=function(t,e,n){return c.call(C(t),n)})),e))for(;a1,null,!0)},removeData:function(t){return this.each((function(){Z.remove(this,t)}))}}),C.extend({queue:function(t,e,n){var i;if(t)return e=(e||"fx")+"queue",i=Y.get(t,e),n&&(!i||Array.isArray(n)?i=Y.access(t,e,C.makeArray(n)):i.push(n)),i||[]},dequeue:function(t,e){e=e||"fx";var n=C.queue(t,e),i=n.length,o=n.shift(),r=C._queueHooks(t,e);"inprogress"===o&&(o=n.shift(),i--),o&&("fx"===e&&n.unshift("inprogress"),delete r.stop,o.call(t,(function(){C.dequeue(t,e)}),r)),!i&&r&&r.empty.fire()},_queueHooks:function(t,e){var n=e+"queueHooks";return Y.get(t,n)||Y.access(t,n,{empty:C.Callbacks("once memory").add((function(){Y.remove(t,[e+"queue",n])}))})}}),C.fn.extend({queue:function(t,e){var n=2;return"string"!=typeof t&&(e=t,t="fx",n--),arguments.length\x20\t\r\n\f]*)/i,yt=/^$|^module$|\/(?:java|ecma)script/i;ft=b.createDocumentFragment().appendChild(b.createElement("div")),(mt=b.createElement("input")).setAttribute("type","radio"),mt.setAttribute("checked","checked"),mt.setAttribute("name","t"),ft.appendChild(mt),g.checkClone=ft.cloneNode(!0).cloneNode(!0).lastChild.checked,ft.innerHTML="",g.noCloneChecked=!!ft.cloneNode(!0).lastChild.defaultValue,ft.innerHTML="",g.option=!!ft.lastChild;var bt={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function xt(t,e){var n;return n=void 0!==t.getElementsByTagName?t.getElementsByTagName(e||"*"):void 0!==t.querySelectorAll?t.querySelectorAll(e||"*"):[],void 0===e||e&&D(t,e)?C.merge([t],n):n}function wt(t,e){for(var n=0,i=t.length;n",""]);var kt=/<|&#?\w+;/;function $t(t,e,n,i,o){for(var r,s,a,l,c,u,p=e.createDocumentFragment(),d=[],h=0,f=t.length;h-1)o&&o.push(r);else if(c=at(r),s=xt(p.appendChild(r),"script"),c&&wt(s),n)for(u=0;r=s[u++];)yt.test(r.type||"")&&n.push(r);return p}var Ct=/^([^.]*)(?:\.(.+)|)/;function Tt(){return!0}function St(){return!1}function _t(t,e){return t===function(){try{return b.activeElement}catch(t){}}()==("focus"===e)}function Et(t,e,n,i,o,r){var s,a;if("object"==typeof e){for(a in"string"!=typeof n&&(i=i||n,n=void 0),e)Et(t,a,n,i,e[a],r);return t}if(null==i&&null==o?(o=n,i=n=void 0):null==o&&("string"==typeof n?(o=i,i=void 0):(o=i,i=n,n=void 0)),!1===o)o=St;else if(!o)return t;return 1===r&&(s=o,o=function(t){return C().off(t),s.apply(this,arguments)},o.guid=s.guid||(s.guid=C.guid++)),t.each((function(){C.event.add(this,e,o,i,n)}))}function At(t,e,n){n?(Y.set(t,e,!1),C.event.add(t,e,{namespace:!1,handler:function(t){var i,o,r=Y.get(this,e);if(1&t.isTrigger&&this[e]){if(r.length)(C.event.special[e]||{}).delegateType&&t.stopPropagation();else if(r=a.call(arguments),Y.set(this,e,r),i=n(this,e),this[e](),r!==(o=Y.get(this,e))||i?Y.set(this,e,!1):o={},r!==o)return t.stopImmediatePropagation(),t.preventDefault(),o&&o.value}else r.length&&(Y.set(this,e,{value:C.event.trigger(C.extend(r[0],C.Event.prototype),r.slice(1),this)}),t.stopImmediatePropagation())}})):void 0===Y.get(t,e)&&C.event.add(t,e,Tt)}C.event={global:{},add:function(t,e,n,i,o){var r,s,a,l,c,u,p,d,h,f,m,g=Y.get(t);if(J(t))for(n.handler&&(n=(r=n).handler,o=r.selector),o&&C.find.matchesSelector(st,o),n.guid||(n.guid=C.guid++),(l=g.events)||(l=g.events=Object.create(null)),(s=g.handle)||(s=g.handle=function(e){return void 0!==C&&C.event.triggered!==e.type?C.event.dispatch.apply(t,arguments):void 0}),c=(e=(e||"").match(z)||[""]).length;c--;)h=m=(a=Ct.exec(e[c])||[])[1],f=(a[2]||"").split(".").sort(),h&&(p=C.event.special[h]||{},h=(o?p.delegateType:p.bindType)||h,p=C.event.special[h]||{},u=C.extend({type:h,origType:m,data:i,handler:n,guid:n.guid,selector:o,needsContext:o&&C.expr.match.needsContext.test(o),namespace:f.join(".")},r),(d=l[h])||((d=l[h]=[]).delegateCount=0,p.setup&&!1!==p.setup.call(t,i,f,s)||t.addEventListener&&t.addEventListener(h,s)),p.add&&(p.add.call(t,u),u.handler.guid||(u.handler.guid=n.guid)),o?d.splice(d.delegateCount++,0,u):d.push(u),C.event.global[h]=!0)},remove:function(t,e,n,i,o){var r,s,a,l,c,u,p,d,h,f,m,g=Y.hasData(t)&&Y.get(t);if(g&&(l=g.events)){for(c=(e=(e||"").match(z)||[""]).length;c--;)if(h=m=(a=Ct.exec(e[c])||[])[1],f=(a[2]||"").split(".").sort(),h){for(p=C.event.special[h]||{},d=l[h=(i?p.delegateType:p.bindType)||h]||[],a=a[2]&&new RegExp("(^|\\.)"+f.join("\\.(?:.*\\.|)")+"(\\.|$)"),s=r=d.length;r--;)u=d[r],!o&&m!==u.origType||n&&n.guid!==u.guid||a&&!a.test(u.namespace)||i&&i!==u.selector&&("**"!==i||!u.selector)||(d.splice(r,1),u.selector&&d.delegateCount--,p.remove&&p.remove.call(t,u));s&&!d.length&&(p.teardown&&!1!==p.teardown.call(t,f,g.handle)||C.removeEvent(t,h,g.handle),delete l[h])}else for(h in l)C.event.remove(t,h+e[c],n,i,!0);C.isEmptyObject(l)&&Y.remove(t,"handle events")}},dispatch:function(t){var e,n,i,o,r,s,a=new Array(arguments.length),l=C.event.fix(t),c=(Y.get(this,"events")||Object.create(null))[l.type]||[],u=C.event.special[l.type]||{};for(a[0]=l,e=1;e=1))for(;c!==this;c=c.parentNode||this)if(1===c.nodeType&&("click"!==t.type||!0!==c.disabled)){for(r=[],s={},n=0;n-1:C.find(o,this,null,[c]).length),s[o]&&r.push(i);r.length&&a.push({elem:c,handlers:r})}return c=this,l\s*$/g;function Nt(t,e){return D(t,"table")&&D(11!==e.nodeType?e:e.firstChild,"tr")&&C(t).children("tbody")[0]||t}function Pt(t){return t.type=(null!==t.getAttribute("type"))+"/"+t.type,t}function Ot(t){return"true/"===(t.type||"").slice(0,5)?t.type=t.type.slice(5):t.removeAttribute("type"),t}function qt(t,e){var n,i,o,r,s,a;if(1===e.nodeType){if(Y.hasData(t)&&(a=Y.get(t).events))for(o in Y.remove(e,"handle events"),a)for(n=0,i=a[o].length;n1&&"string"==typeof f&&!g.checkClone&&It.test(f))return t.each((function(o){var r=t.eq(o);m&&(e[0]=f.call(this,o,r.html())),zt(r,e,n,i)}));if(d&&(r=(o=$t(e,t[0].ownerDocument,!1,t,i)).firstChild,1===o.childNodes.length&&(o=r),r||i)){for(a=(s=C.map(xt(o,"script"),Pt)).length;p0&&wt(s,!l&&xt(t,"script")),a},cleanData:function(t){for(var e,n,i,o=C.event.special,r=0;void 0!==(n=t[r]);r++)if(J(n)){if(e=n[Y.expando]){if(e.events)for(i in e.events)o[i]?C.event.remove(n,i):C.removeEvent(n,i,e.handle);n[Y.expando]=void 0}n[Z.expando]&&(n[Z.expando]=void 0)}}}),C.fn.extend({detach:function(t){return Rt(this,t,!0)},remove:function(t){return Rt(this,t)},text:function(t){return B(this,(function(t){return void 0===t?C.text(this):this.empty().each((function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=t)}))}),null,t,arguments.length)},append:function(){return zt(this,arguments,(function(t){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||Nt(this,t).appendChild(t)}))},prepend:function(){return zt(this,arguments,(function(t){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var e=Nt(this,t);e.insertBefore(t,e.firstChild)}}))},before:function(){return zt(this,arguments,(function(t){this.parentNode&&this.parentNode.insertBefore(t,this)}))},after:function(){return zt(this,arguments,(function(t){this.parentNode&&this.parentNode.insertBefore(t,this.nextSibling)}))},empty:function(){for(var t,e=0;null!=(t=this[e]);e++)1===t.nodeType&&(C.cleanData(xt(t,!1)),t.textContent="");return this},clone:function(t,e){return t=null!=t&&t,e=null==e?t:e,this.map((function(){return C.clone(this,t,e)}))},html:function(t){return B(this,(function(t){var e=this[0]||{},n=0,i=this.length;if(void 0===t&&1===e.nodeType)return e.innerHTML;if("string"==typeof t&&!Dt.test(t)&&!bt[(vt.exec(t)||["",""])[1].toLowerCase()]){t=C.htmlPrefilter(t);try{for(;n=0&&(l+=Math.max(0,Math.ceil(t["offset"+e[0].toUpperCase()+e.slice(1)]-r-l-a-.5))||0),l}function ne(t,e,n){var i=Ht(t),o=(!g.boxSizingReliable()||n)&&"border-box"===C.css(t,"boxSizing",!1,i),r=o,s=Wt(t,e,i),a="offset"+e[0].toUpperCase()+e.slice(1);if(Ft.test(s)){if(!n)return s;s="auto"}return(!g.boxSizingReliable()&&o||!g.reliableTrDimensions()&&D(t,"tr")||"auto"===s||!parseFloat(s)&&"inline"===C.css(t,"display",!1,i))&&t.getClientRects().length&&(o="border-box"===C.css(t,"boxSizing",!1,i),(r=a in t)&&(s=t[a])),(s=parseFloat(s)||0)+ee(t,e,n||(o?"border":"content"),r,i,s)+"px"}function ie(t,e,n,i,o){return new ie.prototype.init(t,e,n,i,o)}C.extend({cssHooks:{opacity:{get:function(t,e){if(e){var n=Wt(t,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(t,e,n,i){if(t&&3!==t.nodeType&&8!==t.nodeType&&t.style){var o,r,s,a=X(e),l=Kt.test(e),c=t.style;if(l||(e=Xt(a)),s=C.cssHooks[e]||C.cssHooks[a],void 0===n)return s&&"get"in s&&void 0!==(o=s.get(t,!1,i))?o:c[e];"string"===(r=typeof n)&&(o=ot.exec(n))&&o[1]&&(n=ut(t,e,o),r="number"),null!=n&&n==n&&("number"!==r||l||(n+=o&&o[3]||(C.cssNumber[a]?"":"px")),g.clearCloneStyle||""!==n||0!==e.indexOf("background")||(c[e]="inherit"),s&&"set"in s&&void 0===(n=s.set(t,n,i))||(l?c.setProperty(e,n):c[e]=n))}},css:function(t,e,n,i){var o,r,s,a=X(e);return Kt.test(e)||(e=Xt(a)),(s=C.cssHooks[e]||C.cssHooks[a])&&"get"in s&&(o=s.get(t,!0,n)),void 0===o&&(o=Wt(t,e,i)),"normal"===o&&e in Zt&&(o=Zt[e]),""===n||n?(r=parseFloat(o),!0===n||isFinite(r)?r||0:o):o}}),C.each(["height","width"],(function(t,e){C.cssHooks[e]={get:function(t,n,i){if(n)return!Jt.test(C.css(t,"display"))||t.getClientRects().length&&t.getBoundingClientRect().width?ne(t,e,i):Mt(t,Yt,(function(){return ne(t,e,i)}))},set:function(t,n,i){var o,r=Ht(t),s=!g.scrollboxSize()&&"absolute"===r.position,a=(s||i)&&"border-box"===C.css(t,"boxSizing",!1,r),l=i?ee(t,e,i,a,r):0;return a&&s&&(l-=Math.ceil(t["offset"+e[0].toUpperCase()+e.slice(1)]-parseFloat(r[e])-ee(t,e,"border",!1,r)-.5)),l&&(o=ot.exec(n))&&"px"!==(o[3]||"px")&&(t.style[e]=n,n=C.css(t,e)),te(0,n,l)}}})),C.cssHooks.marginLeft=Bt(g.reliableMarginLeft,(function(t,e){if(e)return(parseFloat(Wt(t,"marginLeft"))||t.getBoundingClientRect().left-Mt(t,{marginLeft:0},(function(){return t.getBoundingClientRect().left})))+"px"})),C.each({margin:"",padding:"",border:"Width"},(function(t,e){C.cssHooks[t+e]={expand:function(n){for(var i=0,o={},r="string"==typeof n?n.split(" "):[n];i<4;i++)o[t+rt[i]+e]=r[i]||r[i-2]||r[0];return o}},"margin"!==t&&(C.cssHooks[t+e].set=te)})),C.fn.extend({css:function(t,e){return B(this,(function(t,e,n){var i,o,r={},s=0;if(Array.isArray(e)){for(i=Ht(t),o=e.length;s1)}}),C.Tween=ie,ie.prototype={constructor:ie,init:function(t,e,n,i,o,r){this.elem=t,this.prop=n,this.easing=o||C.easing._default,this.options=e,this.start=this.now=this.cur(),this.end=i,this.unit=r||(C.cssNumber[n]?"":"px")},cur:function(){var t=ie.propHooks[this.prop];return t&&t.get?t.get(this):ie.propHooks._default.get(this)},run:function(t){var e,n=ie.propHooks[this.prop];return this.options.duration?this.pos=e=C.easing[this.easing](t,this.options.duration*t,0,1,this.options.duration):this.pos=e=t,this.now=(this.end-this.start)*e+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):ie.propHooks._default.set(this),this}},ie.prototype.init.prototype=ie.prototype,ie.propHooks={_default:{get:function(t){var e;return 1!==t.elem.nodeType||null!=t.elem[t.prop]&&null==t.elem.style[t.prop]?t.elem[t.prop]:(e=C.css(t.elem,t.prop,""))&&"auto"!==e?e:0},set:function(t){C.fx.step[t.prop]?C.fx.step[t.prop](t):1!==t.elem.nodeType||!C.cssHooks[t.prop]&&null==t.elem.style[Xt(t.prop)]?t.elem[t.prop]=t.now:C.style(t.elem,t.prop,t.now+t.unit)}}},ie.propHooks.scrollTop=ie.propHooks.scrollLeft={set:function(t){t.elem.nodeType&&t.elem.parentNode&&(t.elem[t.prop]=t.now)}},C.easing={linear:function(t){return t},swing:function(t){return.5-Math.cos(t*Math.PI)/2},_default:"swing"},C.fx=ie.prototype.init,C.fx.step={};var oe,re,se=/^(?:toggle|show|hide)$/,ae=/queueHooks$/;function le(){re&&(!1===b.hidden&&n.requestAnimationFrame?n.requestAnimationFrame(le):n.setTimeout(le,C.fx.interval),C.fx.tick())}function ce(){return n.setTimeout((function(){oe=void 0})),oe=Date.now()}function ue(t,e){var n,i=0,o={height:t};for(e=e?1:0;i<4;i+=2-e)o["margin"+(n=rt[i])]=o["padding"+n]=t;return e&&(o.opacity=o.width=t),o}function pe(t,e,n){for(var i,o=(de.tweeners[e]||[]).concat(de.tweeners["*"]),r=0,s=o.length;r1)},removeAttr:function(t){return this.each((function(){C.removeAttr(this,t)}))}}),C.extend({attr:function(t,e,n){var i,o,r=t.nodeType;if(3!==r&&8!==r&&2!==r)return void 0===t.getAttribute?C.prop(t,e,n):(1===r&&C.isXMLDoc(t)||(o=C.attrHooks[e.toLowerCase()]||(C.expr.match.bool.test(e)?he:void 0)),void 0!==n?null===n?void C.removeAttr(t,e):o&&"set"in o&&void 0!==(i=o.set(t,n,e))?i:(t.setAttribute(e,n+""),n):o&&"get"in o&&null!==(i=o.get(t,e))?i:null==(i=C.find.attr(t,e))?void 0:i)},attrHooks:{type:{set:function(t,e){if(!g.radioValue&&"radio"===e&&D(t,"input")){var n=t.value;return t.setAttribute("type",e),n&&(t.value=n),e}}}},removeAttr:function(t,e){var n,i=0,o=e&&e.match(z);if(o&&1===t.nodeType)for(;n=o[i++];)t.removeAttribute(n)}}),he={set:function(t,e,n){return!1===e?C.removeAttr(t,n):t.setAttribute(n,n),n}},C.each(C.expr.match.bool.source.match(/\w+/g),(function(t,e){var n=fe[e]||C.find.attr;fe[e]=function(t,e,i){var o,r,s=e.toLowerCase();return i||(r=fe[s],fe[s]=o,o=null!=n(t,e,i)?s:null,fe[s]=r),o}}));var me=/^(?:input|select|textarea|button)$/i,ge=/^(?:a|area)$/i;function ve(t){return(t.match(z)||[]).join(" ")}function ye(t){return t.getAttribute&&t.getAttribute("class")||""}function be(t){return Array.isArray(t)?t:"string"==typeof t&&t.match(z)||[]}C.fn.extend({prop:function(t,e){return B(this,C.prop,t,e,arguments.length>1)},removeProp:function(t){return this.each((function(){delete this[C.propFix[t]||t]}))}}),C.extend({prop:function(t,e,n){var i,o,r=t.nodeType;if(3!==r&&8!==r&&2!==r)return 1===r&&C.isXMLDoc(t)||(e=C.propFix[e]||e,o=C.propHooks[e]),void 0!==n?o&&"set"in o&&void 0!==(i=o.set(t,n,e))?i:t[e]=n:o&&"get"in o&&null!==(i=o.get(t,e))?i:t[e]},propHooks:{tabIndex:{get:function(t){var e=C.find.attr(t,"tabindex");return e?parseInt(e,10):me.test(t.nodeName)||ge.test(t.nodeName)&&t.href?0:-1}}},propFix:{for:"htmlFor",class:"className"}}),g.optSelected||(C.propHooks.selected={get:function(t){var e=t.parentNode;return e&&e.parentNode&&e.parentNode.selectedIndex,null},set:function(t){var e=t.parentNode;e&&(e.selectedIndex,e.parentNode&&e.parentNode.selectedIndex)}}),C.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],(function(){C.propFix[this.toLowerCase()]=this})),C.fn.extend({addClass:function(t){var e,n,i,o,r,s,a,l=0;if(v(t))return this.each((function(e){C(this).addClass(t.call(this,e,ye(this)))}));if((e=be(t)).length)for(;n=this[l++];)if(o=ye(n),i=1===n.nodeType&&" "+ve(o)+" "){for(s=0;r=e[s++];)i.indexOf(" "+r+" ")<0&&(i+=r+" ");o!==(a=ve(i))&&n.setAttribute("class",a)}return this},removeClass:function(t){var e,n,i,o,r,s,a,l=0;if(v(t))return this.each((function(e){C(this).removeClass(t.call(this,e,ye(this)))}));if(!arguments.length)return this.attr("class","");if((e=be(t)).length)for(;n=this[l++];)if(o=ye(n),i=1===n.nodeType&&" "+ve(o)+" "){for(s=0;r=e[s++];)for(;i.indexOf(" "+r+" ")>-1;)i=i.replace(" "+r+" "," ");o!==(a=ve(i))&&n.setAttribute("class",a)}return this},toggleClass:function(t,e){var n=typeof t,i="string"===n||Array.isArray(t);return"boolean"==typeof e&&i?e?this.addClass(t):this.removeClass(t):v(t)?this.each((function(n){C(this).toggleClass(t.call(this,n,ye(this),e),e)})):this.each((function(){var e,o,r,s;if(i)for(o=0,r=C(this),s=be(t);e=s[o++];)r.hasClass(e)?r.removeClass(e):r.addClass(e);else void 0!==t&&"boolean"!==n||((e=ye(this))&&Y.set(this,"__className__",e),this.setAttribute&&this.setAttribute("class",e||!1===t?"":Y.get(this,"__className__")||""))}))},hasClass:function(t){var e,n,i=0;for(e=" "+t+" ";n=this[i++];)if(1===n.nodeType&&(" "+ve(ye(n))+" ").indexOf(e)>-1)return!0;return!1}});var xe=/\r/g;C.fn.extend({val:function(t){var e,n,i,o=this[0];return arguments.length?(i=v(t),this.each((function(n){var o;1===this.nodeType&&(null==(o=i?t.call(this,n,C(this).val()):t)?o="":"number"==typeof o?o+="":Array.isArray(o)&&(o=C.map(o,(function(t){return null==t?"":t+""}))),(e=C.valHooks[this.type]||C.valHooks[this.nodeName.toLowerCase()])&&"set"in e&&void 0!==e.set(this,o,"value")||(this.value=o))}))):o?(e=C.valHooks[o.type]||C.valHooks[o.nodeName.toLowerCase()])&&"get"in e&&void 0!==(n=e.get(o,"value"))?n:"string"==typeof(n=o.value)?n.replace(xe,""):null==n?"":n:void 0}}),C.extend({valHooks:{option:{get:function(t){var e=C.find.attr(t,"value");return null!=e?e:ve(C.text(t))}},select:{get:function(t){var e,n,i,o=t.options,r=t.selectedIndex,s="select-one"===t.type,a=s?null:[],l=s?r+1:o.length;for(i=r<0?l:s?r:0;i-1)&&(n=!0);return n||(t.selectedIndex=-1),r}}}}),C.each(["radio","checkbox"],(function(){C.valHooks[this]={set:function(t,e){if(Array.isArray(e))return t.checked=C.inArray(C(t).val(),e)>-1}},g.checkOn||(C.valHooks[this].get=function(t){return null===t.getAttribute("value")?"on":t.value})})),g.focusin="onfocusin"in n;var we=/^(?:focusinfocus|focusoutblur)$/,ke=function(t){t.stopPropagation()};C.extend(C.event,{trigger:function(t,e,i,o){var r,s,a,l,c,u,p,d,f=[i||b],m=h.call(t,"type")?t.type:t,g=h.call(t,"namespace")?t.namespace.split("."):[];if(s=d=a=i=i||b,3!==i.nodeType&&8!==i.nodeType&&!we.test(m+C.event.triggered)&&(m.indexOf(".")>-1&&(g=m.split("."),m=g.shift(),g.sort()),c=m.indexOf(":")<0&&"on"+m,(t=t[C.expando]?t:new C.Event(m,"object"==typeof t&&t)).isTrigger=o?2:3,t.namespace=g.join("."),t.rnamespace=t.namespace?new RegExp("(^|\\.)"+g.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=void 0,t.target||(t.target=i),e=null==e?[t]:C.makeArray(e,[t]),p=C.event.special[m]||{},o||!p.trigger||!1!==p.trigger.apply(i,e))){if(!o&&!p.noBubble&&!y(i)){for(l=p.delegateType||m,we.test(l+m)||(s=s.parentNode);s;s=s.parentNode)f.push(s),a=s;a===(i.ownerDocument||b)&&f.push(a.defaultView||a.parentWindow||n)}for(r=0;(s=f[r++])&&!t.isPropagationStopped();)d=s,t.type=r>1?l:p.bindType||m,(u=(Y.get(s,"events")||Object.create(null))[t.type]&&Y.get(s,"handle"))&&u.apply(s,e),(u=c&&s[c])&&u.apply&&J(s)&&(t.result=u.apply(s,e),!1===t.result&&t.preventDefault());return t.type=m,o||t.isDefaultPrevented()||p._default&&!1!==p._default.apply(f.pop(),e)||!J(i)||c&&v(i[m])&&!y(i)&&((a=i[c])&&(i[c]=null),C.event.triggered=m,t.isPropagationStopped()&&d.addEventListener(m,ke),i[m](),t.isPropagationStopped()&&d.removeEventListener(m,ke),C.event.triggered=void 0,a&&(i[c]=a)),t.result}},simulate:function(t,e,n){var i=C.extend(new C.Event,n,{type:t,isSimulated:!0});C.event.trigger(i,null,e)}}),C.fn.extend({trigger:function(t,e){return this.each((function(){C.event.trigger(t,e,this)}))},triggerHandler:function(t,e){var n=this[0];if(n)return C.event.trigger(t,e,n,!0)}}),g.focusin||C.each({focus:"focusin",blur:"focusout"},(function(t,e){var n=function(t){C.event.simulate(e,t.target,C.event.fix(t))};C.event.special[e]={setup:function(){var i=this.ownerDocument||this.document||this,o=Y.access(i,e);o||i.addEventListener(t,n,!0),Y.access(i,e,(o||0)+1)},teardown:function(){var i=this.ownerDocument||this.document||this,o=Y.access(i,e)-1;o?Y.access(i,e,o):(i.removeEventListener(t,n,!0),Y.remove(i,e))}}}));var $e=n.location,Ce={guid:Date.now()},Te=/\?/;C.parseXML=function(t){var e,i;if(!t||"string"!=typeof t)return null;try{e=(new n.DOMParser).parseFromString(t,"text/xml")}catch(t){}return i=e&&e.getElementsByTagName("parsererror")[0],e&&!i||C.error("Invalid XML: "+(i?C.map(i.childNodes,(function(t){return t.textContent})).join("\n"):t)),e};var Se=/\[\]$/,_e=/\r?\n/g,Ee=/^(?:submit|button|image|reset|file)$/i,Ae=/^(?:input|select|textarea|keygen)/i;function De(t,e,n,i){var o;if(Array.isArray(e))C.each(e,(function(e,o){n||Se.test(t)?i(t,o):De(t+"["+("object"==typeof o&&null!=o?e:"")+"]",o,n,i)}));else if(n||"object"!==k(e))i(t,e);else for(o in e)De(t+"["+o+"]",e[o],n,i)}C.param=function(t,e){var n,i=[],o=function(t,e){var n=v(e)?e():e;i[i.length]=encodeURIComponent(t)+"="+encodeURIComponent(null==n?"":n)};if(null==t)return"";if(Array.isArray(t)||t.jquery&&!C.isPlainObject(t))C.each(t,(function(){o(this.name,this.value)}));else for(n in t)De(n,t[n],e,o);return i.join("&")},C.fn.extend({serialize:function(){return C.param(this.serializeArray())},serializeArray:function(){return this.map((function(){var t=C.prop(this,"elements");return t?C.makeArray(t):this})).filter((function(){var t=this.type;return this.name&&!C(this).is(":disabled")&&Ae.test(this.nodeName)&&!Ee.test(t)&&(this.checked||!gt.test(t))})).map((function(t,e){var n=C(this).val();return null==n?null:Array.isArray(n)?C.map(n,(function(t){return{name:e.name,value:t.replace(_e,"\r\n")}})):{name:e.name,value:n.replace(_e,"\r\n")}})).get()}});var Ie=/%20/g,je=/#.*$/,Ne=/([?&])_=[^&]*/,Pe=/^(.*?):[ \t]*([^\r\n]*)$/gm,Oe=/^(?:GET|HEAD)$/,qe=/^\/\//,Le={},ze={},Re="*/".concat("*"),Fe=b.createElement("a");function He(t){return function(e,n){"string"!=typeof e&&(n=e,e="*");var i,o=0,r=e.toLowerCase().match(z)||[];if(v(n))for(;i=r[o++];)"+"===i[0]?(i=i.slice(1)||"*",(t[i]=t[i]||[]).unshift(n)):(t[i]=t[i]||[]).push(n)}}function Me(t,e,n,i){var o={},r=t===ze;function s(a){var l;return o[a]=!0,C.each(t[a]||[],(function(t,a){var c=a(e,n,i);return"string"!=typeof c||r||o[c]?r?!(l=c):void 0:(e.dataTypes.unshift(c),s(c),!1)})),l}return s(e.dataTypes[0])||!o["*"]&&s("*")}function Ue(t,e){var n,i,o=C.ajaxSettings.flatOptions||{};for(n in e)void 0!==e[n]&&((o[n]?t:i||(i={}))[n]=e[n]);return i&&C.extend(!0,t,i),t}Fe.href=$e.href,C.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:$e.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test($e.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Re,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":C.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(t,e){return e?Ue(Ue(t,C.ajaxSettings),e):Ue(C.ajaxSettings,t)},ajaxPrefilter:He(Le),ajaxTransport:He(ze),ajax:function(t,e){"object"==typeof t&&(e=t,t=void 0),e=e||{};var i,o,r,s,a,l,c,u,p,d,h=C.ajaxSetup({},e),f=h.context||h,m=h.context&&(f.nodeType||f.jquery)?C(f):C.event,g=C.Deferred(),v=C.Callbacks("once memory"),y=h.statusCode||{},x={},w={},k="canceled",$={readyState:0,getResponseHeader:function(t){var e;if(c){if(!s)for(s={};e=Pe.exec(r);)s[e[1].toLowerCase()+" "]=(s[e[1].toLowerCase()+" "]||[]).concat(e[2]);e=s[t.toLowerCase()+" "]}return null==e?null:e.join(", ")},getAllResponseHeaders:function(){return c?r:null},setRequestHeader:function(t,e){return null==c&&(t=w[t.toLowerCase()]=w[t.toLowerCase()]||t,x[t]=e),this},overrideMimeType:function(t){return null==c&&(h.mimeType=t),this},statusCode:function(t){var e;if(t)if(c)$.always(t[$.status]);else for(e in t)y[e]=[y[e],t[e]];return this},abort:function(t){var e=t||k;return i&&i.abort(e),T(0,e),this}};if(g.promise($),h.url=((t||h.url||$e.href)+"").replace(qe,$e.protocol+"//"),h.type=e.method||e.type||h.method||h.type,h.dataTypes=(h.dataType||"*").toLowerCase().match(z)||[""],null==h.crossDomain){l=b.createElement("a");try{l.href=h.url,l.href=l.href,h.crossDomain=Fe.protocol+"//"+Fe.host!=l.protocol+"//"+l.host}catch(t){h.crossDomain=!0}}if(h.data&&h.processData&&"string"!=typeof h.data&&(h.data=C.param(h.data,h.traditional)),Me(Le,h,e,$),c)return $;for(p in(u=C.event&&h.global)&&0==C.active++&&C.event.trigger("ajaxStart"),h.type=h.type.toUpperCase(),h.hasContent=!Oe.test(h.type),o=h.url.replace(je,""),h.hasContent?h.data&&h.processData&&0===(h.contentType||"").indexOf("application/x-www-form-urlencoded")&&(h.data=h.data.replace(Ie,"+")):(d=h.url.slice(o.length),h.data&&(h.processData||"string"==typeof h.data)&&(o+=(Te.test(o)?"&":"?")+h.data,delete h.data),!1===h.cache&&(o=o.replace(Ne,"$1"),d=(Te.test(o)?"&":"?")+"_="+Ce.guid+++d),h.url=o+d),h.ifModified&&(C.lastModified[o]&&$.setRequestHeader("If-Modified-Since",C.lastModified[o]),C.etag[o]&&$.setRequestHeader("If-None-Match",C.etag[o])),(h.data&&h.hasContent&&!1!==h.contentType||e.contentType)&&$.setRequestHeader("Content-Type",h.contentType),$.setRequestHeader("Accept",h.dataTypes[0]&&h.accepts[h.dataTypes[0]]?h.accepts[h.dataTypes[0]]+("*"!==h.dataTypes[0]?", "+Re+"; q=0.01":""):h.accepts["*"]),h.headers)$.setRequestHeader(p,h.headers[p]);if(h.beforeSend&&(!1===h.beforeSend.call(f,$,h)||c))return $.abort();if(k="abort",v.add(h.complete),$.done(h.success),$.fail(h.error),i=Me(ze,h,e,$)){if($.readyState=1,u&&m.trigger("ajaxSend",[$,h]),c)return $;h.async&&h.timeout>0&&(a=n.setTimeout((function(){$.abort("timeout")}),h.timeout));try{c=!1,i.send(x,T)}catch(t){if(c)throw t;T(-1,t)}}else T(-1,"No Transport");function T(t,e,s,l){var p,d,b,x,w,k=e;c||(c=!0,a&&n.clearTimeout(a),i=void 0,r=l||"",$.readyState=t>0?4:0,p=t>=200&&t<300||304===t,s&&(x=function(t,e,n){for(var i,o,r,s,a=t.contents,l=t.dataTypes;"*"===l[0];)l.shift(),void 0===i&&(i=t.mimeType||e.getResponseHeader("Content-Type"));if(i)for(o in a)if(a[o]&&a[o].test(i)){l.unshift(o);break}if(l[0]in n)r=l[0];else{for(o in n){if(!l[0]||t.converters[o+" "+l[0]]){r=o;break}s||(s=o)}r=r||s}if(r)return r!==l[0]&&l.unshift(r),n[r]}(h,$,s)),!p&&C.inArray("script",h.dataTypes)>-1&&C.inArray("json",h.dataTypes)<0&&(h.converters["text script"]=function(){}),x=function(t,e,n,i){var o,r,s,a,l,c={},u=t.dataTypes.slice();if(u[1])for(s in t.converters)c[s.toLowerCase()]=t.converters[s];for(r=u.shift();r;)if(t.responseFields[r]&&(n[t.responseFields[r]]=e),!l&&i&&t.dataFilter&&(e=t.dataFilter(e,t.dataType)),l=r,r=u.shift())if("*"===r)r=l;else if("*"!==l&&l!==r){if(!(s=c[l+" "+r]||c["* "+r]))for(o in c)if((a=o.split(" "))[1]===r&&(s=c[l+" "+a[0]]||c["* "+a[0]])){!0===s?s=c[o]:!0!==c[o]&&(r=a[0],u.unshift(a[1]));break}if(!0!==s)if(s&&t.throws)e=s(e);else try{e=s(e)}catch(t){return{state:"parsererror",error:s?t:"No conversion from "+l+" to "+r}}}return{state:"success",data:e}}(h,x,$,p),p?(h.ifModified&&((w=$.getResponseHeader("Last-Modified"))&&(C.lastModified[o]=w),(w=$.getResponseHeader("etag"))&&(C.etag[o]=w)),204===t||"HEAD"===h.type?k="nocontent":304===t?k="notmodified":(k=x.state,d=x.data,p=!(b=x.error))):(b=k,!t&&k||(k="error",t<0&&(t=0))),$.status=t,$.statusText=(e||k)+"",p?g.resolveWith(f,[d,k,$]):g.rejectWith(f,[$,k,b]),$.statusCode(y),y=void 0,u&&m.trigger(p?"ajaxSuccess":"ajaxError",[$,h,p?d:b]),v.fireWith(f,[$,k]),u&&(m.trigger("ajaxComplete",[$,h]),--C.active||C.event.trigger("ajaxStop")))}return $},getJSON:function(t,e,n){return C.get(t,e,n,"json")},getScript:function(t,e){return C.get(t,void 0,e,"script")}}),C.each(["get","post"],(function(t,e){C[e]=function(t,n,i,o){return v(n)&&(o=o||i,i=n,n=void 0),C.ajax(C.extend({url:t,type:e,dataType:o,data:n,success:i},C.isPlainObject(t)&&t))}})),C.ajaxPrefilter((function(t){var e;for(e in t.headers)"content-type"===e.toLowerCase()&&(t.contentType=t.headers[e]||"")})),C._evalUrl=function(t,e,n){return C.ajax({url:t,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,converters:{"text script":function(){}},dataFilter:function(t){C.globalEval(t,e,n)}})},C.fn.extend({wrapAll:function(t){var e;return this[0]&&(v(t)&&(t=t.call(this[0])),e=C(t,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&e.insertBefore(this[0]),e.map((function(){for(var t=this;t.firstElementChild;)t=t.firstElementChild;return t})).append(this)),this},wrapInner:function(t){return v(t)?this.each((function(e){C(this).wrapInner(t.call(this,e))})):this.each((function(){var e=C(this),n=e.contents();n.length?n.wrapAll(t):e.append(t)}))},wrap:function(t){var e=v(t);return this.each((function(n){C(this).wrapAll(e?t.call(this,n):t)}))},unwrap:function(t){return this.parent(t).not("body").each((function(){C(this).replaceWith(this.childNodes)})),this}}),C.expr.pseudos.hidden=function(t){return!C.expr.pseudos.visible(t)},C.expr.pseudos.visible=function(t){return!!(t.offsetWidth||t.offsetHeight||t.getClientRects().length)},C.ajaxSettings.xhr=function(){try{return new n.XMLHttpRequest}catch(t){}};var We={0:200,1223:204},Be=C.ajaxSettings.xhr();g.cors=!!Be&&"withCredentials"in Be,g.ajax=Be=!!Be,C.ajaxTransport((function(t){var e,i;if(g.cors||Be&&!t.crossDomain)return{send:function(o,r){var s,a=t.xhr();if(a.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(s in t.xhrFields)a[s]=t.xhrFields[s];for(s in t.mimeType&&a.overrideMimeType&&a.overrideMimeType(t.mimeType),t.crossDomain||o["X-Requested-With"]||(o["X-Requested-With"]="XMLHttpRequest"),o)a.setRequestHeader(s,o[s]);e=function(t){return function(){e&&(e=i=a.onload=a.onerror=a.onabort=a.ontimeout=a.onreadystatechange=null,"abort"===t?a.abort():"error"===t?"number"!=typeof a.status?r(0,"error"):r(a.status,a.statusText):r(We[a.status]||a.status,a.statusText,"text"!==(a.responseType||"text")||"string"!=typeof a.responseText?{binary:a.response}:{text:a.responseText},a.getAllResponseHeaders()))}},a.onload=e(),i=a.onerror=a.ontimeout=e("error"),void 0!==a.onabort?a.onabort=i:a.onreadystatechange=function(){4===a.readyState&&n.setTimeout((function(){e&&i()}))},e=e("abort");try{a.send(t.hasContent&&t.data||null)}catch(t){if(e)throw t}},abort:function(){e&&e()}}})),C.ajaxPrefilter((function(t){t.crossDomain&&(t.contents.script=!1)})),C.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(t){return C.globalEval(t),t}}}),C.ajaxPrefilter("script",(function(t){void 0===t.cache&&(t.cache=!1),t.crossDomain&&(t.type="GET")})),C.ajaxTransport("script",(function(t){var e,n;if(t.crossDomain||t.scriptAttrs)return{send:function(i,o){e=C("