pax_global_header00006660000000000000000000000064136603130750014516gustar00rootroot0000000000000052 comment=da79ff13b3a439f96e560d2690d23791cb27e559 goipp-1.0.0/000077500000000000000000000000001366031307500126325ustar00rootroot00000000000000goipp-1.0.0/.gitignore000066400000000000000000000000231366031307500146150ustar00rootroot00000000000000ipp-usb tags *.swp goipp-1.0.0/LICENSE000066400000000000000000000024571366031307500136470ustar00rootroot00000000000000BSD 2-Clause License Copyright (c) 2020, Alexander Pevzner All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. goipp-1.0.0/Makefile000066400000000000000000000000641366031307500142720ustar00rootroot00000000000000all: -gotags -R . > tags go build test: go test goipp-1.0.0/README.md000066400000000000000000000015321366031307500141120ustar00rootroot00000000000000# goipp [![godoc.org](https://godoc.org/github.com/OpenPrinting/goipp?status.svg)](http://godoc.org/github.com/OpenPrinting/goipp) ![GitHub](https://img.shields.io/github/license/OpenPrinting/goipp) [![Go Report Card](https://goreportcard.com/badge/github.com/OpenPrinting/goipp)](https://goreportcard.com/report/github.com/OpenPrinting/goipp) The goipp library is fairly complete implementation of IPP core protocol in pure Go. Essentially, it is IPP messages parser/composer. Transport is not implemented here, because Go standard library has an excellent built-in HTTP client, and it doesn't make a lot of sense to wrap it here. High-level requests, like "print a file" are also not implemented, only the low-level stuff. All documentation is on godoc.org -- follow the link above. Pull requests are welcomed, assuming they don't break existing API. goipp-1.0.0/_config.yml000066400000000000000000000000351366031307500147570ustar00rootroot00000000000000theme: jekyll-theme-architectgoipp-1.0.0/attr.go000066400000000000000000000036761366031307500141470ustar00rootroot00000000000000/* Go IPP - IPP core protocol implementation in pure Go * * Copyright (C) 2020 and up by Alexander Pevzner (pzz@apevzner.com) * See LICENSE for license terms and conditions * * Message attributes */ package goipp import ( "fmt" ) // Attributes represents a slice of attributes type Attributes []Attribute // Add Attribute to Attributes func (attrs *Attributes) Add(attr Attribute) { *attrs = append(*attrs, attr) } // Equal checks that attrs and attrs2 are equal func (attrs Attributes) Equal(attrs2 Attributes) bool { if len(attrs) != len(attrs2) { return false } for i, attr := range attrs { attr2 := attrs2[i] if !attr.Equal(attr2) { return false } } return true } // Attribute represents a single attribute type Attribute struct { Name string // Attribute name Values Values // Slice of values } // MakeAttribute makes Attribute with single value func MakeAttribute(name string, tag Tag, value Value) Attribute { attr := Attribute{Name: name} attr.Values.Add(tag, value) return attr } // Equal checks that Attribute is equal to another Attribute // (i.e., names are the same and values are equal func (a Attribute) Equal(a2 Attribute) bool { return a.Name == a2.Name && a.Values.Equal(a2.Values) } // Unpack attribute value func (a *Attribute) unpack(tag Tag, value []byte) error { var err error var val Value switch tag.Type() { case TypeVoid, TypeCollection: val = Void{} case TypeInteger: val = Integer(0) case TypeBoolean: val = Boolean(false) case TypeString: val = String("") case TypeDateTime: val = Time{} case TypeResolution: val = Resolution{} case TypeRange: val = Range{} case TypeTextWithLang: val = TextWithLang{} case TypeBinary: val = Binary(nil) default: panic(fmt.Sprintf("(Attribute) uppack(): tag=%s type=%s", tag, tag.Type())) } val, err = val.decode(value) if err == nil { a.Values.Add(tag, val) } else { err = fmt.Errorf("%s: %s", tag, err) } return err } goipp-1.0.0/const.go000066400000000000000000000006351366031307500143130ustar00rootroot00000000000000/* Go IPP - IPP core protocol implementation in pure Go * * Copyright (C) 2020 and up by Alexander Pevzner (pzz@apevzner.com) * See LICENSE for license terms and conditions * * Various constants */ package goipp const ( // ContentType is the HTTP content type for IPP messages ContentType = "application/ipp" // msgPrintIndent used for indentation by message pretty-printer msgPrintIndent = " " ) goipp-1.0.0/decoder.go000066400000000000000000000153211366031307500145700ustar00rootroot00000000000000/* Go IPP - IPP core protocol implementation in pure Go * * Copyright (C) 2020 and up by Alexander Pevzner (pzz@apevzner.com) * See LICENSE for license terms and conditions * * IPP Message decoder */ package goipp import ( "encoding/binary" "errors" "fmt" "io" ) // Type messageDecoder represents Message decoder type messageDecoder struct { in io.Reader // Input stream off int // Offset of last read cnt int // Count of read bytes } // Decode the message func (md *messageDecoder) decode(m *Message) error { // Wire format: // // 2 bytes: Version // 2 bytes: Code (Operation or Status) // 4 bytes: RequestID // variable: attributes // 1 byte: TagEnd // Parse message header var err error m.Version, err = md.decodeVersion() if err == nil { m.Code, err = md.decodeCode() } if err == nil { m.RequestID, err = md.decodeU32() } // Now parse attributes done := false var group *Attributes var attr Attribute var prev *Attribute for err == nil && !done { var tag Tag tag, err = md.decodeTag() if tag.IsDelimiter() { prev = nil } switch tag { case TagZero: err = errors.New("Invalid tag 0") case TagEnd: done = true case TagOperationGroup: group = &m.Operation case TagJobGroup: group = &m.Job case TagPrinterGroup: group = &m.Printer case TagUnsupportedGroup: group = &m.Unsupported case TagSubscriptionGroup: group = &m.Subscription case TagEventNotificationGroup: group = &m.EventNotification case TagResourceGroup: group = &m.Resource case TagDocumentGroup: group = &m.Document case TagSystemGroup: group = &m.System case TagFuture11Group: group = &m.Future11 case TagFuture12Group: group = &m.Future12 case TagFuture13Group: group = &m.Future13 case TagFuture14Group: group = &m.Future14 case TagFuture15Group: group = &m.Future15 default: // Decode attribute if tag == TagMemberName || tag == TagEndCollection { err = fmt.Errorf("Unexpected tag %s", tag) } else { attr, err = md.decodeAttribute(tag) } if err == nil && tag == TagBeginCollection { attr.Values[0].V, err = md.decodeCollection() } // If everything is OK, save attribute switch { case err != nil: case attr.Name == "": if prev != nil { prev.Values.Add(attr.Values[0].T, attr.Values[0].V) } else { err = errors.New("Additional value without preceding attribute") } case group != nil: group.Add(attr) prev = &(*group)[len(*group)-1] default: err = errors.New("Attribute without a group") } } } if err != nil { err = fmt.Errorf("%s at 0x%x", err, md.off) } return err } // Decode a Collection func (md *messageDecoder) decodeCollection() (Collection, error) { collection := make(Collection, 0) //var name string for { tag, err := md.decodeTag() if err != nil { return nil, err } // Delimiter cannot be inside a collection if tag.IsDelimiter() { err = fmt.Errorf("collection: unexpected %s", tag) return nil, err } // We are about to finish with current attribute (if any), // either because we've got an end of collection, or a next // attribute name. Check that we are leaving the current // attribute in a consistent state (i.e., with at least one value) if tag == TagMemberName || tag == TagEndCollection { l := len(collection) if l > 0 && len(collection[l-1].Values) == 0 { err = fmt.Errorf("collection: unexpected %s, expected value tag", tag) return nil, err } } // Fetch next attribute attr, err := md.decodeAttribute(tag) if err != nil { return nil, err } // Process next attribute switch { case tag == TagEndCollection: return collection, nil case tag == TagMemberName: attr.Name = string(attr.Values[0].V.(String)) attr.Values = nil if attr.Name == "" { err = fmt.Errorf("collection: %s contains empty attribute name", tag) return nil, err } collection = append(collection, attr) case len(collection) == 0: // We've got a value without preceding TagMemberName err = fmt.Errorf("collection: unexpected %s, expected %s", tag, TagMemberName) return nil, err default: if tag == TagBeginCollection { attr.Values[0].V, err = md.decodeCollection() if err != nil { return nil, err } } l := len(collection) collection[l-1].Values.Add(tag, attr.Values[0].V) } } } // Decode a tag func (md *messageDecoder) decodeTag() (Tag, error) { t, err := md.decodeU8() return Tag(t), err } // Decode a Version func (md *messageDecoder) decodeVersion() (Version, error) { code, err := md.decodeU16() return Version(code), err } // Decode a Code func (md *messageDecoder) decodeCode() (Code, error) { code, err := md.decodeU16() return Code(code), err } // Decode a single attribute func (md *messageDecoder) decodeAttribute(tag Tag) (Attribute, error) { var attr Attribute var value []byte var err error // Obtain attribute name and raw value attr.Name, err = md.decodeString() if err != nil { goto ERROR } value, err = md.decodeBytes() if err != nil { goto ERROR } // Handle TagExtension if tag == TagExtension { if len(value) < 4 { err = errors.New("Extension tag truncated") goto ERROR } t := binary.BigEndian.Uint32(value[:4]) value = value[4:] if t > 0x7fffffff { err = errors.New("Extension tag out of range") goto ERROR } tag = Tag(t) } // Unpack value err = attr.unpack(tag, value) if err != nil { goto ERROR } return attr, nil // Return a error ERROR: return Attribute{}, err } // Decode a 8-bit integer func (md *messageDecoder) decodeU8() (uint8, error) { buf := make([]byte, 1) err := md.read(buf) return buf[0], err } // Decode a 16-bit integer func (md *messageDecoder) decodeU16() (uint16, error) { buf := make([]byte, 2) err := md.read(buf) return binary.BigEndian.Uint16(buf[:]), err } // Decode a 32-bit integer func (md *messageDecoder) decodeU32() (uint32, error) { buf := make([]byte, 4) err := md.read(buf) return binary.BigEndian.Uint32(buf[:]), err } // Decode sequence of bytes func (md *messageDecoder) decodeBytes() ([]byte, error) { length, err := md.decodeU16() if err != nil { return nil, err } data := make([]byte, length) err = md.read(data) if err != nil { return nil, err } return data, nil } // Decode string func (md *messageDecoder) decodeString() (string, error) { data, err := md.decodeBytes() if err != nil { return "", err } return string(data), nil } // Read a piece of raw data from input stream func (md *messageDecoder) read(data []byte) error { md.off = md.cnt for len(data) > 0 { n, err := md.in.Read(data) if n > 0 { md.cnt += n data = data[n:] } else if err != nil { md.off = md.cnt return err } } return nil } goipp-1.0.0/doc.go000066400000000000000000000040361366031307500137310ustar00rootroot00000000000000/* Go IPP - IPP core protocol implementation in pure Go /* * Copyright (C) 2020 and up by Alexander Pevzner (pzz@apevzner.com) * See LICENSE for license terms and conditions * * Package documentation */ /* Package goipp implements IPP core protocol, as defined by RFC 8010 It doesn't implement high-level operations, such as "print a document", "cancel print job" and so on. It's scope is limited to proper generation and parsing of IPP requests and responses. IPP protocol uses the following simple model: 1. Send a request 2. Receive a response Request and response both has a similar format, represented here by type Message, with the only difference, that Code field of that Message is the Operation code in request and Status code in response. So most of operations are common for request and response messages Example: package main import ( "bytes" "net/http" "os" "github.com/OpenPrinting/goipp" ) const uri = "http://192.168.1.102:631" // Build IPP OpGetPrinterAttributes request func makeRequest() ([]byte, error) { m := goipp.NewRequest(goipp.DefaultVersion, goipp.OpGetPrinterAttributes, 1) m.Operation.Add(goipp.MakeAttribute("attributes-charset", goipp.TagCharset, goipp.String("utf-8"))) m.Operation.Add(goipp.MakeAttribute("attributes-natural-language", goipp.TagLanguage, goipp.String("en-US"))) m.Operation.Add(goipp.MakeAttribute("printer-uri", goipp.TagURI, goipp.String(uri))) m.Operation.Add(goipp.MakeAttribute("requested-attributes", goipp.TagKeyword, goipp.String("all"))) return m.EncodeBytes() } // Check that there is no error func check(err error) { if err != nil { panic(err) } } func main() { request, err := makeRequest() check(err) resp, err := http.Post(uri, goipp.ContentType, bytes.NewBuffer(request)) check(err) var respMsg goipp.Message err = respMsg.Decode(resp.Body) check(err) respMsg.Print(os.Stdout, false) } */ package goipp goipp-1.0.0/encoder.go000066400000000000000000000106211366031307500146000ustar00rootroot00000000000000/* Go IPP - IPP core protocol implementation in pure Go * * Copyright (C) 2020 and up by Alexander Pevzner (pzz@apevzner.com) * See LICENSE for license terms and conditions * * IPP Message encoder */ package goipp import ( "errors" "fmt" "io" "math" ) // Type messageEncoder represents Message encoder type messageEncoder struct { out io.Writer // Output stream } // Encode the message func (me *messageEncoder) encode(m *Message) error { // Wire format: // // 2 bytes: Version // 2 bytes: Code (Operation or Status) // 4 bytes: RequestID // variable: attributes // 1 byte: TagEnd // Encode message header var err error err = me.encodeU16(uint16(m.Version)) if err == nil { err = me.encodeU16(uint16(m.Code)) } if err == nil { err = me.encodeU32(uint32(m.RequestID)) } // Encode attributes for _, grp := range m.attrGroups() { err = me.encodeTag(grp.tag) if err == nil { for _, attr := range grp.attrs { if attr.Name == "" { err = errors.New("Attribute without name") } else { err = me.encodeAttr(attr, true) } } } if err != nil { break } } if err == nil { err = me.encodeTag(TagEnd) } return err } // Encode attribute func (me *messageEncoder) encodeAttr(attr Attribute, checkTag bool) error { // Wire format // 1 byte: Tag // 2 bytes: len(Name) // variable: name // 2 bytes: len(Value) // variable Value // // And each additional value comes as attribute // without name if len(attr.Values) == 0 { return errors.New("Attribute without value") } name := attr.Name for _, val := range attr.Values { tag := val.T if checkTag { if tag.IsDelimiter() || tag == TagMemberName || tag == TagEndCollection { return fmt.Errorf("Tag %s cannot be used with value", tag) } } err := me.encodeTag(tag) if err != nil { return err } err = me.encodeName(name) if err != nil { return err } err = me.encodeValue(val.T, val.V) if err != nil { return err } name = "" // Each additional value comes without name } return nil } // Encode 8-bit integer func (me *messageEncoder) encodeU8(v uint8) error { return me.write([]byte{v}) } // Encode 16-bit integer func (me *messageEncoder) encodeU16(v uint16) error { return me.write([]byte{byte(v >> 8), byte(v)}) } // Encode 32-bit integer func (me *messageEncoder) encodeU32(v uint32) error { return me.write([]byte{byte(v >> 24), byte(v >> 16), byte(v >> 8), byte(v)}) } // Encode Tag func (me *messageEncoder) encodeTag(tag Tag) error { return me.encodeU8(byte(tag)) } // Encode Attribute name func (me *messageEncoder) encodeName(name string) error { if len(name) > math.MaxInt16 { return fmt.Errorf("Attribute name exceeds %d bytes", math.MaxInt16) } err := me.encodeU16(uint16(len(name))) if err == nil { err = me.write([]byte(name)) } return err } // Encode Attribute value func (me *messageEncoder) encodeValue(tag Tag, v Value) error { // Check Value type vs the Tag tagType := tag.Type() switch tagType { case TypeInvalid: return fmt.Errorf("Tag %s cannot be used for value", tag) case TypeVoid: v = Void{} // Ignore supplied value default: if tagType != v.Type() { return fmt.Errorf("Tag %s: %s value required, %s present", tag, tagType, v.Type()) } } // Encode the value data, err := v.encode() if err != nil { return err } if len(data) > math.MaxInt16 { return fmt.Errorf("Attribute value exceeds %d bytes", math.MaxInt16) } err = me.encodeU16(uint16(len(data))) if err == nil { err = me.write(data) } // Handle collection if collection, ok := v.(Collection); ok { return me.encodeCollection(tag, collection) } return err } // Encode collection func (me *messageEncoder) encodeCollection(tag Tag, collection Collection) error { for _, attr := range collection { if attr.Name == "" { return errors.New("Collection member without name") } attrName := MakeAttribute("", TagMemberName, String(attr.Name)) err := me.encodeAttr(attrName, false) if err == nil { err = me.encodeAttr(Attribute{Name: "", Values: attr.Values}, true) } if err != nil { return err } } return me.encodeAttr(MakeAttribute("", TagEndCollection, Void{}), false) } // Write a piece of raw data to output stream func (me *messageEncoder) write(data []byte) error { for len(data) > 0 { n, err := me.out.Write(data) if err != nil { return err } data = data[n:] } return nil } goipp-1.0.0/go.mod000066400000000000000000000000561366031307500137410ustar00rootroot00000000000000module github.com/OpenPrinting/goipp go 1.11 goipp-1.0.0/goipp_test.go000066400000000000000000003174441366031307500153530ustar00rootroot00000000000000/* Go IPP - IPP core protocol implementation in pure Go * * Copyright (C) 2020 and up by Alexander Pevzner (pzz@apevzner.com) * See LICENSE for license terms and conditions */ package goipp import ( "bytes" "io/ioutil" "reflect" "testing" "time" ) // Check that err == nil func assertNoError(t *testing.T, err error) { if err != nil { t.Errorf("%s", err) } } // Check that err != nil func assertWithError(t *testing.T, err error) { if err == nil { t.Errorf("Error expected") } } // Check that value type is as specified func assertValueType(t *testing.T, val Value, typ Type) { if val.Type() != typ { t.Errorf("%s: type is %s, must be %s", reflect.TypeOf(val).Name(), val.Type(), typ) } } func assertDataSize(t *testing.T, data []byte, size int) { if len(data) != size { t.Errorf("data size must be %d, present %d", size, len(data)) } } // Check that encode() works without error and returns expected size func assertEncodeSize(t *testing.T, encode func() ([]byte, error), size int) { data, err := encode() assertNoError(t, err) assertDataSize(t, data, size) } // Check that decode() works without error and returns expected value func assertDecode(t *testing.T, data []byte, expected Value) { val, err := expected.decode(data) assertNoError(t, err) if !ValueEqual(val, expected) { t.Errorf("decode: expected %s, present %s", val, expected) } } // Check that decode returns error func assertDecodeErr(t *testing.T, data []byte, val Value) { _, err := val.decode(data) if err == nil { t.Errorf("decode: expected error") } } // Test Void Value func TestVoidValue(t *testing.T) { var v Void assertValueType(t, v, TypeVoid) assertEncodeSize(t, v.encode, 0) assertDecode(t, []byte{}, Void{}) assertDecode(t, []byte{1, 2, 3, 4}, Void{}) } // Test Integer Value func TestIntegerValue(t *testing.T) { var v Integer assertValueType(t, v, TypeInteger) assertEncodeSize(t, v.encode, 4) assertDecode(t, []byte{1, 2, 3, 4}, Integer(0x01020304)) assertDecodeErr(t, []byte{1, 2, 3}, Integer(0)) } // Test Boolean Value func TestBooleanValue(t *testing.T) { var v Boolean assertValueType(t, v, TypeBoolean) assertEncodeSize(t, v.encode, 1) assertDecode(t, []byte{0}, Boolean(false)) assertDecode(t, []byte{1}, Boolean(true)) assertDecodeErr(t, []byte{1, 2, 3}, Integer(0)) } // Test String Value func TestStringValue(t *testing.T) { var v String assertValueType(t, v, TypeString) assertEncodeSize(t, v.encode, 0) v = "12345" assertEncodeSize(t, v.encode, 5) assertDecode(t, []byte{}, String("")) assertDecode(t, []byte("hello"), String("hello")) } // Test Time Value func TestDateTimeValue(t *testing.T) { var v Time assertValueType(t, v, TypeDateTime) assertEncodeSize(t, v.encode, 11) tm := time.Date(2020, 1, 13, 15, 35, 12, 300000000, time.UTC) v = Time{tm} data, _ := v.encode() assertDecode(t, data, Time{tm}) assertDecodeErr(t, []byte{1, 2, 3}, Time{}) } // Test Resolution value func TestResolutionValue(t *testing.T) { v := Resolution{100, 100, UnitsDpi} assertValueType(t, v, TypeResolution) assertEncodeSize(t, v.encode, 9) data, _ := v.encode() assertDecode(t, data, v) assertDecodeErr(t, []byte{1, 2, 3}, Resolution{}) } // Test Range value func TestRangeValue(t *testing.T) { v := Range{100, 200} assertValueType(t, v, TypeRange) assertEncodeSize(t, v.encode, 8) data, _ := v.encode() assertDecode(t, data, v) assertDecodeErr(t, []byte{1, 2, 3}, Range{}) } // Test TextWithLang value func TestTextWithLang(t *testing.T) { v := TextWithLang{"ru_RU", "строка на росском языке"} data, err := v.encode() if err != nil { t.Errorf("(TestTextWithLang) encode(): %s", err) } v2, err := v.decode(data) if err != nil { t.Errorf("(TestTextWithLang) decode(): %s", err) } //if v != v2.(TextWithLang) { if !ValueEqual(v, v2) { t.Errorf("TestTextWithLang not the same after encode and decode") } } // Test Binary value func TestBinaryValue(t *testing.T) { v := Binary([]byte("12345")) assertValueType(t, v, TypeBinary) assertEncodeSize(t, v.encode, 5) data, _ := v.encode() assertDecode(t, data, v) } // Test (Attributes) Equal() func TestAttributesEqual(t *testing.T) { attr1 := MakeAttribute("attr1", TagInteger, Integer(1)) attr2 := MakeAttribute("attr2", TagInteger, Integer(2)) attr3 := MakeAttribute("attr3", TagInteger, Integer(3)) var attrs1, attrs2 Attributes attrs1.Add(attr1) attrs1.Add(attr2) attrs2.Add(attr1) attrs2.Add(attr2) if !attrs1.Equal(attrs2) { t.Errorf("(Attributes) Equal(): failed for equal attributes") } attrs2.Add(attr3) if attrs1.Equal(attrs2) { t.Errorf("(Attributes) Equal(): failed attributes of different length") } attrs2 = attrs2[:2] if !attrs1.Equal(attrs2) { t.Errorf("(Attributes) Equal(): failed for equal attributes") } attrs2[1] = attr3 if attrs1.Equal(attrs2) { t.Errorf("(Attributes) Equal(): failed attributes of different value") } } // Test Version func TestVersion(t *testing.T) { v := MakeVersion(1, 2) if v.Major() != 1 || v.Minor() != 2 { t.Errorf("Version test failed") } if v.String() != "1.2" { t.Errorf("(Version)String() test failed") } } // Test message decoding func testDecode(t *testing.T, data []byte, mustFail bool) { var m Message err := m.Decode(bytes.NewBuffer(data)) if mustFail { assertWithError(t, err) } else { assertNoError(t, err) } if err != nil { return } if !m.Equal(m) { t.Errorf("Message is not equal to itself") } buf, err := m.EncodeBytes() assertNoError(t, err) if !bytes.Equal(buf, data) { t.Errorf("Message is not the same after decoding and encoding") } // We can't test a lot of (*Message) Print(), so lets test // at least that it doesn't hand m.Print(ioutil.Discard, true) } func TestDecodeGoodMessage1(t *testing.T) { testDecode(t, good_message_1, false) } func TestDecodeGoodMessage2(t *testing.T) { testDecode(t, good_message_2, false) } func TestDecodeBadMessage1(t *testing.T) { testDecode(t, bad_message_1, true) } func TestDecodeBigMessage(t *testing.T) { testDecode(t, big_message, false) } // ------------------------ Test Data ------------------------ // The good message - 1 var good_message_1 = []byte{ 0x01, 0x01, // IPP version 0x00, 0x02, // Print-Job operation 0x00, 0x00, 0x00, 0x01, // Request ID uint8(TagOperationGroup), uint8(TagCharset), 0x00, 0x12, // Name length + name 'a', 't', 't', 'r', 'i', 'b', 'u', 't', 'e', 's', '-', 'c', 'h', 'a', 'r', 's', 'e', 't', 0x00, 0x05, // Value length + value 'u', 't', 'f', '-', '8', uint8(TagLanguage), 0x00, 0x1b, // Name length + name 'a', 't', 't', 'r', 'i', 'b', 'u', 't', 'e', 's', '-', 'n', 'a', 't', 'u', 'r', 'a', 'l', '-', 'l', 'a', 'n', 'g', 'u', 'a', 'g', 'e', 0x00, 0x02, // Value length + value 'e', 'n', uint8(TagURI), 0x00, 0x0b, // Name length + name 'p', 'r', 'i', 'n', 't', 'e', 'r', '-', 'u', 'r', 'i', 0x00, 0x1c, // Value length + value 'i', 'p', 'p', ':', '/', '/', 'l', 'o', 'c', 'a', 'l', 'h', 'o', 's', 't', '/', 'p', 'r', 'i', 'n', 't', 'e', 'r', 's', '/', 'f', 'o', 'o', uint8(TagJobGroup), uint8(TagBeginCollection), 0x00, 0x09, // Name length + name 'm', 'e', 'd', 'i', 'a', '-', 'c', 'o', 'l', 0x00, 0x00, // No value uint8(TagMemberName), 0x00, 0x00, // No name 0x00, 0x0a, // Value length + value 'm', 'e', 'd', 'i', 'a', '-', 's', 'i', 'z', 'e', uint8(TagBeginCollection), 0x00, 0x00, // Name length + name 0x00, 0x00, // No value uint8(TagMemberName), 0x00, 0x00, // No name 0x00, 0x0b, // Value length + value 'x', '-', 'd', 'i', 'm', 'e', 'n', 's', 'i', 'o', 'n', uint8(TagInteger), 0x00, 0x00, // No name 0x00, 0x04, // Value length + value 0x00, 0x00, 0x54, 0x56, uint8(TagMemberName), 0x00, 0x00, // No name 0x00, 0x0b, // Value length + value 'y', '-', 'd', 'i', 'm', 'e', 'n', 's', 'i', 'o', 'n', uint8(TagInteger), 0x00, 0x00, // No name 0x00, 0x04, // Value length + value 0x00, 0x00, 0x6d, 0x24, uint8(TagEndCollection), 0x00, 0x00, // No name 0x00, 0x00, // No value uint8(TagMemberName), 0x00, 0x00, // No name 0x00, 0x0b, // Value length + value 'm', 'e', 'd', 'i', 'a', '-', 'c', 'o', 'l', 'o', 'r', uint8(TagKeyword), 0x00, 0x00, // No name 0x00, 0x04, // Value length + value 'b', 'l', 'u', 'e', uint8(TagMemberName), 0x00, 0x00, // No name 0x00, 0x0a, // Value length + value 'm', 'e', 'd', 'i', 'a', '-', 't', 'y', 'p', 'e', uint8(TagKeyword), 0x00, 0x00, // No name 0x00, 0x05, // Value length + value 'p', 'l', 'a', 'i', 'n', uint8(TagEndCollection), 0x00, 0x00, // No name 0x00, 0x00, // No value uint8(TagBeginCollection), 0x00, 0x00, // No name 0x00, 0x00, // No value uint8(TagMemberName), 0x00, 0x00, // No name 0x00, 0x0a, // Value length + value 'm', 'e', 'd', 'i', 'a', '-', 's', 'i', 'z', 'e', uint8(TagBeginCollection), 0x00, 0x00, // Name length + name 0x00, 0x00, // No value uint8(TagMemberName), 0x00, 0x00, // No name 0x00, 0x0b, // Value length + value 'x', '-', 'd', 'i', 'm', 'e', 'n', 's', 'i', 'o', 'n', uint8(TagInteger), 0x00, 0x00, // No name 0x00, 0x04, // Value length + value 0x00, 0x00, 0x52, 0x08, uint8(TagMemberName), 0x00, 0x00, // No name 0x00, 0x0b, // Value length + value 'y', '-', 'd', 'i', 'm', 'e', 'n', 's', 'i', 'o', 'n', uint8(TagInteger), 0x00, 0x00, // No name 0x00, 0x04, // Value length + value 0x00, 0x00, 0x74, 0x04, uint8(TagEndCollection), 0x00, 0x00, // No name 0x00, 0x00, // No value uint8(TagMemberName), 0x00, 0x00, // No name 0x00, 0x0b, // Value length + value 'm', 'e', 'd', 'i', 'a', '-', 'c', 'o', 'l', 'o', 'r', uint8(TagKeyword), 0x00, 0x00, // No name 0x00, 0x05, // Value length + value 'p', 'l', 'a', 'i', 'd', uint8(TagMemberName), 0x00, 0x00, // No name 0x00, 0x0a, // Value length + value 'm', 'e', 'd', 'i', 'a', '-', 't', 'y', 'p', 'e', uint8(TagKeyword), 0x00, 0x00, // No name 0x00, 0x06, // Value length + value 'g', 'l', 'o', 's', 's', 'y', uint8(TagEndCollection), 0x00, 0x00, // No name 0x00, 0x00, // No value uint8(TagEnd), } // The good message - 2 var good_message_2 = []byte{ 0x01, 0x01, // IPP version 0x00, 0x02, // Print-Job operation 0x00, 0x00, 0x00, 0x01, // Request ID uint8(TagOperationGroup), uint8(TagInteger), 0x00, 0x1f, // Name length + name 'n', 'o', 't', 'i', 'f', 'y', '-', 'l', 'e', 'a', 's', 'e', '-', 'd', 'u', 'r', 'a', 't', 'i', 'o', 'n', '-', 's', 'u', 'p', 'p', 'o', 'r', 't', 'e', 'd', 0x00, 0x04, // Value length + value 0x00, 0x00, 0x00, 0x01, uint8(TagRange), 0x00, 0x00, // No name 0x00, 0x08, // Value length + value 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x20, uint8(TagEnd), } // The bad message - 1 var bad_message_1 = []byte{ 0x01, 0x01, // IPP version */ 0x00, 0x02, // Print-Job operation */ 0x00, 0x00, 0x00, 0x01, // Request ID */ uint8(TagOperationGroup), uint8(TagCharset), 0x00, 0x12, // Name length + name 'a', 't', 't', 'r', 'i', 'b', 'u', 't', 'e', 's', '-', 'c', 'h', 'a', 'r', 's', 'e', 't', 0x00, 0x05, // Value length + value 'u', 't', 'f', '-', '8', uint8(TagLanguage), 0x00, 0x1b, // Name length + name 'a', 't', 't', 'r', 'i', 'b', 'u', 't', 'e', 's', '-', 'n', 'a', 't', 'u', 'r', 'a', 'l', '-', 'l', 'a', 'n', 'g', 'u', 'a', 'g', 'e', 0x00, 0x02, // Value length + value 'e', 'n', uint8(TagURI), 0x00, 0x0b, // Name length + name 'p', 'r', 'i', 'n', 't', 'e', 'r', '-', 'u', 'r', 'i', 0x00, 0x1c, // Value length + value 'i', 'p', 'p', ':', '/', '/', 'l', 'o', 'c', 'a', 'l', 'h', 'o', 's', 't', '/', 'p', 'r', 'i', 'n', 't', 'e', 'r', 's', '/', 'f', 'o', 'o', uint8(TagJobGroup), uint8(TagBeginCollection), 0x00, 0x09, // Name length + name 'm', 'e', 'd', 'i', 'a', '-', 'c', 'o', 'l', 0x00, 0x00, // No value uint8(TagBeginCollection), 0x00, 0x0a, // Name length + name 'm', 'e', 'd', 'i', 'a', '-', 's', 'i', 'z', 'e', 0x00, 0x00, // No value uint8(TagInteger), 0x00, 0x0b, // Name length + name 'x', '-', 'd', 'i', 'm', 'e', 'n', 's', 'i', 'o', 'n', 0x00, 0x04, // Value length + value 0x00, 0x00, 0x54, 0x56, uint8(TagInteger), 0x00, 0x0b, // Name length + name 'y', '-', 'd', 'i', 'm', 'e', 'n', 's', 'i', 'o', 'n', 0x00, 0x04, // Value length + value 0x00, 0x00, 0x6d, 0x24, uint8(TagEndCollection), 0x00, 0x00, // No name 0x00, 0x00, // No value uint8(TagEndCollection), 0x00, 0x00, // No name 0x00, 0x00, // No value uint8(TagEnd), } // The big real example, Get-Printer-Attributes output // from the HP OfficeJet Pro 8730 var big_message = []byte{ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x47, 0x00, 0x12, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2d, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x00, 0x05, 0x75, 0x74, 0x66, 0x2d, 0x38, 0x48, 0x00, 0x1b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2d, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x61, 0x6c, 0x2d, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x00, 0x02, 0x65, 0x6e, 0x04, 0x45, 0x00, 0x15, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x75, 0x72, 0x69, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x19, 0x69, 0x70, 0x70, 0x3a, 0x2f, 0x2f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x2f, 0x69, 0x70, 0x70, 0x2f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x45, 0x00, 0x00, 0x00, 0x1e, 0x69, 0x70, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x34, 0x34, 0x33, 0x2f, 0x69, 0x70, 0x70, 0x2f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x44, 0x00, 0x16, 0x75, 0x72, 0x69, 0x2d, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x04, 0x6e, 0x6f, 0x6e, 0x65, 0x44, 0x00, 0x00, 0x00, 0x03, 0x74, 0x6c, 0x73, 0x44, 0x00, 0x1c, 0x75, 0x72, 0x69, 0x2d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x14, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2d, 0x75, 0x73, 0x65, 0x72, 0x2d, 0x6e, 0x61, 0x6d, 0x65, 0x44, 0x00, 0x00, 0x00, 0x14, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2d, 0x75, 0x73, 0x65, 0x72, 0x2d, 0x6e, 0x61, 0x6d, 0x65, 0x44, 0x00, 0x25, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x73, 0x65, 0x74, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x11, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x77, 0x69, 0x66, 0x69, 0x2d, 0x73, 0x73, 0x69, 0x64, 0x44, 0x00, 0x00, 0x00, 0x15, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x77, 0x69, 0x66, 0x69, 0x2d, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x42, 0x00, 0x11, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x77, 0x69, 0x66, 0x69, 0x2d, 0x73, 0x73, 0x69, 0x64, 0x00, 0x09, 0x41, 0x31, 0x2d, 0x35, 0x45, 0x46, 0x33, 0x37, 0x31, 0x23, 0x00, 0x12, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x77, 0x69, 0x66, 0x69, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x65, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x42, 0x00, 0x0c, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x08, 0x48, 0x50, 0x30, 0x38, 0x43, 0x32, 0x32, 0x39, 0x41, 0x00, 0x10, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x45, 0x00, 0x11, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x6d, 0x6f, 0x72, 0x65, 0x2d, 0x69, 0x6e, 0x66, 0x6f, 0x00, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x2f, 0x23, 0x68, 0x49, 0x64, 0x2d, 0x70, 0x67, 0x41, 0x69, 0x72, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x41, 0x00, 0x0c, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x69, 0x6e, 0x66, 0x6f, 0x00, 0x1e, 0x48, 0x50, 0x20, 0x4f, 0x66, 0x66, 0x69, 0x63, 0x65, 0x4a, 0x65, 0x74, 0x20, 0x50, 0x72, 0x6f, 0x20, 0x38, 0x37, 0x33, 0x30, 0x20, 0x5b, 0x30, 0x38, 0x43, 0x32, 0x32, 0x39, 0x5d, 0x42, 0x00, 0x13, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, 0x2d, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x1e, 0x48, 0x50, 0x20, 0x4f, 0x66, 0x66, 0x69, 0x63, 0x65, 0x4a, 0x65, 0x74, 0x20, 0x50, 0x72, 0x6f, 0x20, 0x38, 0x37, 0x33, 0x30, 0x20, 0x5b, 0x30, 0x38, 0x43, 0x32, 0x32, 0x39, 0x5d, 0x41, 0x00, 0x16, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x6d, 0x61, 0x6b, 0x65, 0x2d, 0x61, 0x6e, 0x64, 0x2d, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x00, 0x15, 0x48, 0x50, 0x20, 0x4f, 0x66, 0x66, 0x69, 0x63, 0x65, 0x4a, 0x65, 0x74, 0x20, 0x50, 0x72, 0x6f, 0x20, 0x38, 0x37, 0x33, 0x30, 0x23, 0x00, 0x0d, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x65, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x44, 0x00, 0x15, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2d, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x73, 0x00, 0x1a, 0x77, 0x69, 0x66, 0x69, 0x2d, 0x6e, 0x6f, 0x74, 0x2d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x64, 0x2d, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x41, 0x00, 0x15, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2d, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x00, 0x00, 0x44, 0x00, 0x16, 0x69, 0x70, 0x70, 0x2d, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x03, 0x31, 0x2e, 0x30, 0x44, 0x00, 0x00, 0x00, 0x03, 0x31, 0x2e, 0x31, 0x44, 0x00, 0x00, 0x00, 0x03, 0x32, 0x2e, 0x30, 0x23, 0x00, 0x14, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x23, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x23, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x23, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x39, 0x23, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x23, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0a, 0x23, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0b, 0x23, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x23, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x23, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x13, 0x23, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x29, 0x23, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x2a, 0x23, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x23, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x07, 0x23, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x3b, 0x23, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x3c, 0x47, 0x00, 0x12, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x2d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x64, 0x00, 0x05, 0x75, 0x74, 0x66, 0x2d, 0x38, 0x47, 0x00, 0x11, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x05, 0x75, 0x74, 0x66, 0x2d, 0x38, 0x48, 0x00, 0x1b, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x61, 0x6c, 0x2d, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x64, 0x00, 0x02, 0x65, 0x6e, 0x48, 0x00, 0x24, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x2d, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x61, 0x6c, 0x2d, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x02, 0x65, 0x6e, 0x48, 0x00, 0x00, 0x00, 0x02, 0x66, 0x72, 0x48, 0x00, 0x00, 0x00, 0x02, 0x64, 0x65, 0x48, 0x00, 0x00, 0x00, 0x02, 0x65, 0x73, 0x48, 0x00, 0x00, 0x00, 0x02, 0x69, 0x74, 0x48, 0x00, 0x00, 0x00, 0x02, 0x73, 0x76, 0x48, 0x00, 0x00, 0x00, 0x02, 0x64, 0x61, 0x48, 0x00, 0x00, 0x00, 0x02, 0x6e, 0x6f, 0x48, 0x00, 0x00, 0x00, 0x02, 0x6e, 0x6c, 0x48, 0x00, 0x00, 0x00, 0x02, 0x66, 0x69, 0x48, 0x00, 0x00, 0x00, 0x02, 0x6a, 0x61, 0x48, 0x00, 0x00, 0x00, 0x02, 0x70, 0x74, 0x48, 0x00, 0x00, 0x00, 0x02, 0x70, 0x6c, 0x48, 0x00, 0x00, 0x00, 0x02, 0x74, 0x72, 0x48, 0x00, 0x00, 0x00, 0x05, 0x7a, 0x68, 0x2d, 0x74, 0x77, 0x48, 0x00, 0x00, 0x00, 0x05, 0x7a, 0x68, 0x2d, 0x63, 0x6e, 0x48, 0x00, 0x00, 0x00, 0x02, 0x72, 0x75, 0x48, 0x00, 0x00, 0x00, 0x02, 0x63, 0x73, 0x48, 0x00, 0x00, 0x00, 0x02, 0x68, 0x75, 0x48, 0x00, 0x00, 0x00, 0x02, 0x6b, 0x6f, 0x48, 0x00, 0x00, 0x00, 0x02, 0x68, 0x65, 0x48, 0x00, 0x00, 0x00, 0x02, 0x65, 0x6c, 0x48, 0x00, 0x00, 0x00, 0x02, 0x61, 0x72, 0x48, 0x00, 0x00, 0x00, 0x02, 0x62, 0x67, 0x48, 0x00, 0x00, 0x00, 0x02, 0x68, 0x72, 0x48, 0x00, 0x00, 0x00, 0x02, 0x72, 0x6f, 0x48, 0x00, 0x00, 0x00, 0x02, 0x73, 0x6b, 0x48, 0x00, 0x00, 0x00, 0x02, 0x73, 0x6c, 0x48, 0x00, 0x23, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x2d, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x73, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x02, 0x65, 0x6e, 0x48, 0x00, 0x00, 0x00, 0x02, 0x66, 0x72, 0x48, 0x00, 0x00, 0x00, 0x02, 0x64, 0x65, 0x48, 0x00, 0x00, 0x00, 0x02, 0x65, 0x73, 0x48, 0x00, 0x00, 0x00, 0x02, 0x69, 0x74, 0x48, 0x00, 0x00, 0x00, 0x02, 0x73, 0x76, 0x48, 0x00, 0x00, 0x00, 0x02, 0x64, 0x61, 0x48, 0x00, 0x00, 0x00, 0x02, 0x6e, 0x6f, 0x48, 0x00, 0x00, 0x00, 0x02, 0x6e, 0x6c, 0x48, 0x00, 0x00, 0x00, 0x02, 0x66, 0x69, 0x48, 0x00, 0x00, 0x00, 0x02, 0x6a, 0x61, 0x48, 0x00, 0x00, 0x00, 0x02, 0x70, 0x74, 0x48, 0x00, 0x00, 0x00, 0x02, 0x70, 0x6c, 0x48, 0x00, 0x00, 0x00, 0x02, 0x74, 0x72, 0x48, 0x00, 0x00, 0x00, 0x05, 0x7a, 0x68, 0x2d, 0x74, 0x77, 0x48, 0x00, 0x00, 0x00, 0x05, 0x7a, 0x68, 0x2d, 0x63, 0x6e, 0x48, 0x00, 0x00, 0x00, 0x02, 0x72, 0x75, 0x48, 0x00, 0x00, 0x00, 0x02, 0x63, 0x73, 0x48, 0x00, 0x00, 0x00, 0x02, 0x68, 0x75, 0x48, 0x00, 0x00, 0x00, 0x02, 0x6b, 0x6f, 0x48, 0x00, 0x00, 0x00, 0x02, 0x68, 0x65, 0x48, 0x00, 0x00, 0x00, 0x02, 0x65, 0x6c, 0x48, 0x00, 0x00, 0x00, 0x02, 0x61, 0x72, 0x48, 0x00, 0x00, 0x00, 0x02, 0x62, 0x67, 0x48, 0x00, 0x00, 0x00, 0x02, 0x68, 0x72, 0x48, 0x00, 0x00, 0x00, 0x02, 0x72, 0x6f, 0x48, 0x00, 0x00, 0x00, 0x02, 0x73, 0x6b, 0x48, 0x00, 0x00, 0x00, 0x02, 0x73, 0x6c, 0x45, 0x00, 0x13, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x2d, 0x75, 0x72, 0x69, 0x00, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x2f, 0x69, 0x70, 0x70, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x65, 0x6e, 0x2e, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x49, 0x00, 0x17, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2d, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x00, 0x18, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x2d, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x49, 0x00, 0x19, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2d, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x16, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x6e, 0x64, 0x2e, 0x68, 0x70, 0x2d, 0x50, 0x43, 0x4c, 0x49, 0x00, 0x00, 0x00, 0x18, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x6e, 0x64, 0x2e, 0x68, 0x70, 0x2d, 0x50, 0x43, 0x4c, 0x58, 0x4c, 0x49, 0x00, 0x00, 0x00, 0x16, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x70, 0x6f, 0x73, 0x74, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x49, 0x00, 0x00, 0x00, 0x0f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x70, 0x64, 0x66, 0x49, 0x00, 0x00, 0x00, 0x0a, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x6a, 0x70, 0x65, 0x67, 0x49, 0x00, 0x00, 0x00, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x50, 0x43, 0x4c, 0x6d, 0x49, 0x00, 0x00, 0x00, 0x09, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x75, 0x72, 0x66, 0x49, 0x00, 0x00, 0x00, 0x10, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x70, 0x77, 0x67, 0x2d, 0x72, 0x61, 0x73, 0x74, 0x65, 0x72, 0x49, 0x00, 0x00, 0x00, 0x18, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x2d, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x41, 0x00, 0x21, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2d, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2d, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x05, 0x50, 0x43, 0x4c, 0x35, 0x63, 0x41, 0x00, 0x00, 0x00, 0x05, 0x50, 0x43, 0x4c, 0x58, 0x4c, 0x41, 0x00, 0x00, 0x00, 0x04, 0x50, 0x53, 0x2f, 0x33, 0x41, 0x00, 0x00, 0x00, 0x0c, 0x4e, 0x41, 0x54, 0x49, 0x56, 0x45, 0x4f, 0x46, 0x46, 0x49, 0x43, 0x45, 0x41, 0x00, 0x00, 0x00, 0x07, 0x50, 0x44, 0x46, 0x2f, 0x31, 0x2e, 0x37, 0x41, 0x00, 0x00, 0x00, 0x07, 0x50, 0x43, 0x4c, 0x33, 0x47, 0x55, 0x49, 0x41, 0x00, 0x00, 0x00, 0x04, 0x50, 0x43, 0x4c, 0x33, 0x41, 0x00, 0x00, 0x00, 0x03, 0x50, 0x4a, 0x4c, 0x41, 0x00, 0x00, 0x00, 0x09, 0x41, 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x41, 0x00, 0x00, 0x00, 0x04, 0x4a, 0x50, 0x45, 0x47, 0x41, 0x00, 0x00, 0x00, 0x04, 0x50, 0x43, 0x4c, 0x4d, 0x41, 0x00, 0x00, 0x00, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x52, 0x61, 0x73, 0x74, 0x65, 0x72, 0x41, 0x00, 0x00, 0x00, 0x09, 0x50, 0x57, 0x47, 0x52, 0x61, 0x73, 0x74, 0x65, 0x72, 0x22, 0x00, 0x19, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x69, 0x73, 0x2d, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6e, 0x67, 0x2d, 0x6a, 0x6f, 0x62, 0x73, 0x00, 0x01, 0x01, 0x21, 0x00, 0x10, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x2d, 0x6a, 0x6f, 0x62, 0x2d, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x16, 0x70, 0x64, 0x6c, 0x2d, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x09, 0x61, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x65, 0x64, 0x21, 0x00, 0x0f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x75, 0x70, 0x2d, 0x74, 0x69, 0x6d, 0x65, 0x00, 0x04, 0x00, 0x00, 0x07, 0xdf, 0x31, 0x00, 0x14, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x69, 0x6d, 0x65, 0x00, 0x0b, 0x07, 0xe4, 0x01, 0x13, 0x0b, 0x17, 0x17, 0x00, 0x2b, 0x00, 0x00, 0x44, 0x00, 0x15, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x04, 0x6e, 0x6f, 0x6e, 0x65, 0x44, 0x00, 0x00, 0x00, 0x07, 0x64, 0x65, 0x66, 0x6c, 0x61, 0x74, 0x65, 0x44, 0x00, 0x00, 0x00, 0x04, 0x67, 0x7a, 0x69, 0x70, 0x22, 0x00, 0x0f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x01, 0x01, 0x44, 0x00, 0x21, 0x6a, 0x6f, 0x62, 0x2d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x06, 0x63, 0x6f, 0x70, 0x69, 0x65, 0x73, 0x44, 0x00, 0x00, 0x00, 0x0a, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x44, 0x00, 0x00, 0x00, 0x0e, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2d, 0x63, 0x6f, 0x6c, 0x44, 0x00, 0x00, 0x00, 0x11, 0x6a, 0x6f, 0x62, 0x2d, 0x70, 0x61, 0x67, 0x65, 0x73, 0x2d, 0x70, 0x65, 0x72, 0x2d, 0x73, 0x65, 0x74, 0x44, 0x00, 0x00, 0x00, 0x05, 0x73, 0x69, 0x64, 0x65, 0x73, 0x44, 0x00, 0x00, 0x00, 0x15, 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x44, 0x00, 0x00, 0x00, 0x05, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x44, 0x00, 0x00, 0x00, 0x0d, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2d, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x44, 0x00, 0x00, 0x00, 0x12, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x0a, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x2d, 0x62, 0x69, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x09, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x63, 0x6f, 0x6c, 0x44, 0x00, 0x00, 0x00, 0x0b, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x2d, 0x6d, 0x6f, 0x64, 0x65, 0x44, 0x00, 0x00, 0x00, 0x16, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x44, 0x00, 0x00, 0x00, 0x16, 0x70, 0x63, 0x6c, 0x6d, 0x2d, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2d, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x10, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x2d, 0x6d, 0x6f, 0x64, 0x65, 0x44, 0x00, 0x00, 0x00, 0x16, 0x69, 0x70, 0x70, 0x2d, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x2d, 0x66, 0x69, 0x64, 0x65, 0x6c, 0x69, 0x74, 0x79, 0x44, 0x00, 0x00, 0x00, 0x08, 0x6a, 0x6f, 0x62, 0x2d, 0x6e, 0x61, 0x6d, 0x65, 0x44, 0x00, 0x00, 0x00, 0x0b, 0x70, 0x61, 0x67, 0x65, 0x2d, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x44, 0x00, 0x00, 0x00, 0x1a, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x2d, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2d, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x69, 0x6e, 0x67, 0x44, 0x00, 0x00, 0x00, 0x18, 0x6a, 0x6f, 0x62, 0x2d, 0x6d, 0x61, 0x6e, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x2d, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x44, 0x00, 0x00, 0x00, 0x09, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x44, 0x00, 0x00, 0x00, 0x16, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2d, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2d, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x44, 0x00, 0x00, 0x00, 0x0d, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2d, 0x73, 0x63, 0x61, 0x6c, 0x69, 0x6e, 0x67, 0x46, 0x00, 0x1f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x2d, 0x75, 0x72, 0x69, 0x2d, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x73, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x04, 0x68, 0x74, 0x74, 0x70, 0x46, 0x00, 0x00, 0x00, 0x05, 0x68, 0x74, 0x74, 0x70, 0x73, 0x41, 0x00, 0x11, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2d, 0x69, 0x64, 0x01, 0x99, 0x4d, 0x46, 0x47, 0x3a, 0x48, 0x50, 0x3b, 0x4d, 0x44, 0x4c, 0x3a, 0x48, 0x50, 0x20, 0x4f, 0x66, 0x66, 0x69, 0x63, 0x65, 0x4a, 0x65, 0x74, 0x20, 0x50, 0x72, 0x6f, 0x20, 0x38, 0x37, 0x33, 0x30, 0x3b, 0x43, 0x4d, 0x44, 0x3a, 0x50, 0x43, 0x4c, 0x35, 0x63, 0x2c, 0x50, 0x43, 0x4c, 0x58, 0x4c, 0x2c, 0x50, 0x4f, 0x53, 0x54, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x2c, 0x4e, 0x41, 0x54, 0x49, 0x56, 0x45, 0x4f, 0x46, 0x46, 0x49, 0x43, 0x45, 0x2c, 0x50, 0x44, 0x46, 0x2c, 0x50, 0x43, 0x4c, 0x33, 0x47, 0x55, 0x49, 0x2c, 0x50, 0x43, 0x4c, 0x33, 0x2c, 0x50, 0x4a, 0x4c, 0x2c, 0x41, 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x2c, 0x4a, 0x50, 0x45, 0x47, 0x2c, 0x50, 0x43, 0x4c, 0x4d, 0x2c, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x52, 0x61, 0x73, 0x74, 0x65, 0x72, 0x2c, 0x50, 0x57, 0x47, 0x52, 0x61, 0x73, 0x74, 0x65, 0x72, 0x2c, 0x38, 0x30, 0x32, 0x2e, 0x31, 0x31, 0x2c, 0x38, 0x30, 0x32, 0x2e, 0x33, 0x2c, 0x44, 0x45, 0x53, 0x4b, 0x4a, 0x45, 0x54, 0x2c, 0x44, 0x59, 0x4e, 0x3b, 0x43, 0x4c, 0x53, 0x3a, 0x50, 0x52, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x3b, 0x44, 0x45, 0x53, 0x3a, 0x44, 0x39, 0x4c, 0x32, 0x30, 0x41, 0x3b, 0x43, 0x49, 0x44, 0x3a, 0x48, 0x50, 0x49, 0x4a, 0x56, 0x49, 0x50, 0x41, 0x56, 0x39, 0x3b, 0x4c, 0x45, 0x44, 0x4d, 0x44, 0x49, 0x53, 0x3a, 0x55, 0x53, 0x42, 0x23, 0x46, 0x46, 0x23, 0x43, 0x43, 0x23, 0x30, 0x30, 0x2c, 0x55, 0x53, 0x42, 0x23, 0x46, 0x46, 0x23, 0x30, 0x34, 0x23, 0x30, 0x31, 0x3b, 0x4d, 0x43, 0x54, 0x3a, 0x4d, 0x46, 0x3b, 0x4d, 0x43, 0x4c, 0x3a, 0x44, 0x49, 0x3b, 0x4d, 0x43, 0x56, 0x3a, 0x33, 0x2e, 0x30, 0x3b, 0x53, 0x4e, 0x3a, 0x43, 0x4e, 0x37, 0x38, 0x33, 0x46, 0x36, 0x30, 0x57, 0x31, 0x3b, 0x53, 0x3a, 0x30, 0x33, 0x38, 0x30, 0x38, 0x30, 0x43, 0x34, 0x38, 0x34, 0x31, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x35, 0x38, 0x30, 0x30, 0x38, 0x30, 0x30, 0x30, 0x30, 0x34, 0x34, 0x31, 0x38, 0x30, 0x30, 0x33, 0x63, 0x34, 0x35, 0x31, 0x38, 0x30, 0x30, 0x34, 0x36, 0x34, 0x36, 0x31, 0x38, 0x30, 0x30, 0x33, 0x63, 0x34, 0x31, 0x31, 0x38, 0x30, 0x30, 0x34, 0x36, 0x3b, 0x5a, 0x3a, 0x30, 0x35, 0x30, 0x30, 0x30, 0x30, 0x30, 0x39, 0x30, 0x30, 0x30, 0x30, 0x30, 0x39, 0x30, 0x30, 0x30, 0x30, 0x30, 0x39, 0x30, 0x30, 0x30, 0x30, 0x30, 0x39, 0x30, 0x30, 0x30, 0x30, 0x30, 0x39, 0x2c, 0x31, 0x32, 0x30, 0x30, 0x30, 0x2c, 0x31, 0x37, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x2c, 0x31, 0x38, 0x31, 0x3b, 0x30, 0x00, 0x0d, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x00, 0x27, 0x63, 0x6f, 0x64, 0x65, 0x3d, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x3b, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x3d, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x3b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x3d, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x30, 0x00, 0x00, 0x00, 0x27, 0x63, 0x6f, 0x64, 0x65, 0x3d, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x3b, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x3d, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x3b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x3d, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x30, 0x00, 0x00, 0x00, 0x27, 0x63, 0x6f, 0x64, 0x65, 0x3d, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x3b, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x3d, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x3b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x3d, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x30, 0x00, 0x00, 0x00, 0x27, 0x63, 0x6f, 0x64, 0x65, 0x3d, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x3b, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x3d, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x3b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x3d, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x41, 0x00, 0x19, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x2d, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x09, 0x67, 0x65, 0x6e, 0x75, 0x69, 0x6e, 0x65, 0x48, 0x50, 0x41, 0x00, 0x00, 0x00, 0x09, 0x67, 0x65, 0x6e, 0x75, 0x69, 0x6e, 0x65, 0x48, 0x50, 0x41, 0x00, 0x00, 0x00, 0x09, 0x67, 0x65, 0x6e, 0x75, 0x69, 0x6e, 0x65, 0x48, 0x50, 0x41, 0x00, 0x00, 0x00, 0x09, 0x67, 0x65, 0x6e, 0x75, 0x69, 0x6e, 0x65, 0x48, 0x50, 0x45, 0x00, 0x0c, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x75, 0x75, 0x69, 0x64, 0x00, 0x2d, 0x75, 0x72, 0x6e, 0x3a, 0x75, 0x75, 0x69, 0x64, 0x3a, 0x64, 0x62, 0x63, 0x63, 0x34, 0x62, 0x35, 0x38, 0x2d, 0x66, 0x63, 0x34, 0x63, 0x2d, 0x66, 0x36, 0x66, 0x64, 0x2d, 0x62, 0x34, 0x64, 0x36, 0x2d, 0x32, 0x62, 0x30, 0x30, 0x64, 0x35, 0x35, 0x34, 0x61, 0x64, 0x34, 0x37, 0x23, 0x00, 0x29, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x63, 0x61, 0x70, 0x65, 0x2d, 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x2d, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x34, 0x00, 0x19, 0x6a, 0x6f, 0x62, 0x2d, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x73, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x2d, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x00, 0x00, 0x00, 0x0f, 0x66, 0x75, 0x6c, 0x6c, 0x62, 0x6c, 0x65, 0x65, 0x64, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x73, 0x4a, 0x00, 0x00, 0x00, 0x10, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x74, 0x6f, 0x70, 0x2d, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x13, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x2d, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x11, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x2d, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x12, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x2d, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x05, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x44, 0x00, 0x00, 0x00, 0x14, 0x6e, 0x61, 0x5f, 0x69, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x5f, 0x35, 0x2e, 0x35, 0x78, 0x38, 0x2e, 0x35, 0x69, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x12, 0x6e, 0x61, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2d, 0x35, 0x78, 0x38, 0x5f, 0x35, 0x78, 0x38, 0x69, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x14, 0x6e, 0x61, 0x5f, 0x6f, 0x66, 0x69, 0x63, 0x69, 0x6f, 0x5f, 0x38, 0x2e, 0x35, 0x78, 0x31, 0x33, 0x2e, 0x34, 0x69, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x10, 0x6f, 0x6d, 0x5f, 0x31, 0x36, 0x6b, 0x5f, 0x31, 0x39, 0x35, 0x78, 0x32, 0x37, 0x30, 0x6d, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x10, 0x6f, 0x6d, 0x5f, 0x31, 0x36, 0x6b, 0x5f, 0x31, 0x38, 0x34, 0x78, 0x32, 0x36, 0x30, 0x6d, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x14, 0x72, 0x6f, 0x63, 0x5f, 0x31, 0x36, 0x6b, 0x5f, 0x37, 0x2e, 0x37, 0x35, 0x78, 0x31, 0x30, 0x2e, 0x37, 0x35, 0x69, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x14, 0x6a, 0x70, 0x6e, 0x5f, 0x6f, 0x75, 0x66, 0x75, 0x6b, 0x75, 0x5f, 0x31, 0x34, 0x38, 0x78, 0x32, 0x30, 0x30, 0x6d, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x18, 0x6e, 0x61, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x2d, 0x31, 0x30, 0x5f, 0x34, 0x2e, 0x31, 0x32, 0x35, 0x78, 0x39, 0x2e, 0x35, 0x69, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x16, 0x6e, 0x61, 0x5f, 0x6d, 0x6f, 0x6e, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x33, 0x2e, 0x38, 0x37, 0x35, 0x78, 0x37, 0x2e, 0x35, 0x69, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x10, 0x69, 0x73, 0x6f, 0x5f, 0x62, 0x35, 0x5f, 0x31, 0x37, 0x36, 0x78, 0x32, 0x35, 0x30, 0x6d, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x10, 0x69, 0x73, 0x6f, 0x5f, 0x63, 0x35, 0x5f, 0x31, 0x36, 0x32, 0x78, 0x32, 0x32, 0x39, 0x6d, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x10, 0x69, 0x73, 0x6f, 0x5f, 0x63, 0x36, 0x5f, 0x31, 0x31, 0x34, 0x78, 0x31, 0x36, 0x32, 0x6d, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x10, 0x69, 0x73, 0x6f, 0x5f, 0x64, 0x6c, 0x5f, 0x31, 0x31, 0x30, 0x78, 0x32, 0x32, 0x30, 0x6d, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x13, 0x6a, 0x70, 0x6e, 0x5f, 0x63, 0x68, 0x6f, 0x75, 0x33, 0x5f, 0x31, 0x32, 0x30, 0x78, 0x32, 0x33, 0x35, 0x6d, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x12, 0x6a, 0x70, 0x6e, 0x5f, 0x63, 0x68, 0x6f, 0x75, 0x34, 0x5f, 0x39, 0x30, 0x78, 0x32, 0x30, 0x35, 0x6d, 0x6d, 0x37, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x2d, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x00, 0x00, 0x00, 0x0c, 0x64, 0x75, 0x70, 0x6c, 0x65, 0x78, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x4a, 0x00, 0x00, 0x00, 0x05, 0x73, 0x69, 0x64, 0x65, 0x73, 0x44, 0x00, 0x00, 0x00, 0x14, 0x74, 0x77, 0x6f, 0x2d, 0x73, 0x69, 0x64, 0x65, 0x64, 0x2d, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x2d, 0x65, 0x64, 0x67, 0x65, 0x44, 0x00, 0x00, 0x00, 0x13, 0x74, 0x77, 0x6f, 0x2d, 0x73, 0x69, 0x64, 0x65, 0x64, 0x2d, 0x6c, 0x6f, 0x6e, 0x67, 0x2d, 0x65, 0x64, 0x67, 0x65, 0x4a, 0x00, 0x00, 0x00, 0x05, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x44, 0x00, 0x00, 0x00, 0x12, 0x6e, 0x61, 0x5f, 0x6c, 0x65, 0x74, 0x74, 0x65, 0x72, 0x5f, 0x38, 0x2e, 0x35, 0x78, 0x31, 0x31, 0x69, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x11, 0x6e, 0x61, 0x5f, 0x6c, 0x65, 0x67, 0x61, 0x6c, 0x5f, 0x38, 0x2e, 0x35, 0x78, 0x31, 0x34, 0x69, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x18, 0x6e, 0x61, 0x5f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x37, 0x2e, 0x32, 0x35, 0x78, 0x31, 0x30, 0x2e, 0x35, 0x69, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x14, 0x6e, 0x61, 0x5f, 0x66, 0x6f, 0x6f, 0x6c, 0x73, 0x63, 0x61, 0x70, 0x5f, 0x38, 0x2e, 0x35, 0x78, 0x31, 0x33, 0x69, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x10, 0x69, 0x73, 0x6f, 0x5f, 0x61, 0x34, 0x5f, 0x32, 0x31, 0x30, 0x78, 0x32, 0x39, 0x37, 0x6d, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x10, 0x6a, 0x69, 0x73, 0x5f, 0x62, 0x35, 0x5f, 0x31, 0x38, 0x32, 0x78, 0x32, 0x35, 0x37, 0x6d, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x14, 0x6e, 0x61, 0x5f, 0x6f, 0x66, 0x69, 0x63, 0x69, 0x6f, 0x5f, 0x38, 0x2e, 0x35, 0x78, 0x31, 0x33, 0x2e, 0x34, 0x69, 0x6e, 0x4a, 0x00, 0x00, 0x00, 0x0a, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x44, 0x00, 0x00, 0x00, 0x15, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x70, 0x2e, 0x61, 0x64, 0x76, 0x61, 0x6e, 0x63, 0x65, 0x64, 0x2d, 0x70, 0x68, 0x6f, 0x74, 0x6f, 0x44, 0x00, 0x00, 0x00, 0x09, 0x63, 0x61, 0x72, 0x64, 0x73, 0x74, 0x6f, 0x63, 0x6b, 0x37, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x2d, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x00, 0x00, 0x00, 0x0c, 0x64, 0x75, 0x70, 0x6c, 0x65, 0x78, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x73, 0x4a, 0x00, 0x00, 0x00, 0x05, 0x73, 0x69, 0x64, 0x65, 0x73, 0x44, 0x00, 0x00, 0x00, 0x14, 0x74, 0x77, 0x6f, 0x2d, 0x73, 0x69, 0x64, 0x65, 0x64, 0x2d, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x2d, 0x65, 0x64, 0x67, 0x65, 0x44, 0x00, 0x00, 0x00, 0x13, 0x74, 0x77, 0x6f, 0x2d, 0x73, 0x69, 0x64, 0x65, 0x64, 0x2d, 0x6c, 0x6f, 0x6e, 0x67, 0x2d, 0x65, 0x64, 0x67, 0x65, 0x4a, 0x00, 0x00, 0x00, 0x05, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x44, 0x00, 0x00, 0x00, 0x14, 0x6e, 0x61, 0x5f, 0x69, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x5f, 0x35, 0x2e, 0x35, 0x78, 0x38, 0x2e, 0x35, 0x69, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x12, 0x6e, 0x61, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2d, 0x33, 0x78, 0x35, 0x5f, 0x33, 0x78, 0x35, 0x69, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x12, 0x6e, 0x61, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2d, 0x34, 0x78, 0x36, 0x5f, 0x34, 0x78, 0x36, 0x69, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x0c, 0x6e, 0x61, 0x5f, 0x35, 0x78, 0x37, 0x5f, 0x35, 0x78, 0x37, 0x69, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x12, 0x6e, 0x61, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2d, 0x35, 0x78, 0x38, 0x5f, 0x35, 0x78, 0x38, 0x69, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x10, 0x69, 0x73, 0x6f, 0x5f, 0x61, 0x35, 0x5f, 0x31, 0x34, 0x38, 0x78, 0x32, 0x31, 0x30, 0x6d, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x10, 0x69, 0x73, 0x6f, 0x5f, 0x61, 0x36, 0x5f, 0x31, 0x30, 0x35, 0x78, 0x31, 0x34, 0x38, 0x6d, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x12, 0x6f, 0x65, 0x5f, 0x70, 0x68, 0x6f, 0x74, 0x6f, 0x2d, 0x6c, 0x5f, 0x33, 0x2e, 0x35, 0x78, 0x35, 0x69, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x18, 0x6f, 0x6d, 0x5f, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x2d, 0x70, 0x68, 0x6f, 0x74, 0x6f, 0x5f, 0x31, 0x30, 0x30, 0x78, 0x31, 0x35, 0x30, 0x6d, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x10, 0x6f, 0x6d, 0x5f, 0x31, 0x36, 0x6b, 0x5f, 0x31, 0x39, 0x35, 0x78, 0x32, 0x37, 0x30, 0x6d, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x10, 0x6f, 0x6d, 0x5f, 0x31, 0x36, 0x6b, 0x5f, 0x31, 0x38, 0x34, 0x78, 0x32, 0x36, 0x30, 0x6d, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x14, 0x72, 0x6f, 0x63, 0x5f, 0x31, 0x36, 0x6b, 0x5f, 0x37, 0x2e, 0x37, 0x35, 0x78, 0x31, 0x30, 0x2e, 0x37, 0x35, 0x69, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x14, 0x6a, 0x70, 0x6e, 0x5f, 0x68, 0x61, 0x67, 0x61, 0x6b, 0x69, 0x5f, 0x31, 0x30, 0x30, 0x78, 0x31, 0x34, 0x38, 0x6d, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x14, 0x6a, 0x70, 0x6e, 0x5f, 0x6f, 0x75, 0x66, 0x75, 0x6b, 0x75, 0x5f, 0x31, 0x34, 0x38, 0x78, 0x32, 0x30, 0x30, 0x6d, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x18, 0x6e, 0x61, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x2d, 0x31, 0x30, 0x5f, 0x34, 0x2e, 0x31, 0x32, 0x35, 0x78, 0x39, 0x2e, 0x35, 0x69, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x16, 0x6e, 0x61, 0x5f, 0x6d, 0x6f, 0x6e, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x33, 0x2e, 0x38, 0x37, 0x35, 0x78, 0x37, 0x2e, 0x35, 0x69, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x10, 0x69, 0x73, 0x6f, 0x5f, 0x62, 0x35, 0x5f, 0x31, 0x37, 0x36, 0x78, 0x32, 0x35, 0x30, 0x6d, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x10, 0x69, 0x73, 0x6f, 0x5f, 0x63, 0x35, 0x5f, 0x31, 0x36, 0x32, 0x78, 0x32, 0x32, 0x39, 0x6d, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x10, 0x69, 0x73, 0x6f, 0x5f, 0x63, 0x36, 0x5f, 0x31, 0x31, 0x34, 0x78, 0x31, 0x36, 0x32, 0x6d, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x10, 0x69, 0x73, 0x6f, 0x5f, 0x64, 0x6c, 0x5f, 0x31, 0x31, 0x30, 0x78, 0x32, 0x32, 0x30, 0x6d, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x13, 0x6a, 0x70, 0x6e, 0x5f, 0x63, 0x68, 0x6f, 0x75, 0x33, 0x5f, 0x31, 0x32, 0x30, 0x78, 0x32, 0x33, 0x35, 0x6d, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x12, 0x6a, 0x70, 0x6e, 0x5f, 0x63, 0x68, 0x6f, 0x75, 0x34, 0x5f, 0x39, 0x30, 0x78, 0x32, 0x30, 0x35, 0x6d, 0x6d, 0x37, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x17, 0x6a, 0x6f, 0x62, 0x2d, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x73, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x2d, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x00, 0x00, 0x00, 0x0f, 0x66, 0x75, 0x6c, 0x6c, 0x62, 0x6c, 0x65, 0x65, 0x64, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x73, 0x4a, 0x00, 0x00, 0x00, 0x10, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x74, 0x6f, 0x70, 0x2d, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x28, 0x4a, 0x00, 0x00, 0x00, 0x13, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x2d, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x28, 0x4a, 0x00, 0x00, 0x00, 0x11, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x2d, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x28, 0x4a, 0x00, 0x00, 0x00, 0x12, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x2d, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x28, 0x37, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x2d, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x00, 0x00, 0x00, 0x0c, 0x64, 0x75, 0x70, 0x6c, 0x65, 0x78, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x4a, 0x00, 0x00, 0x00, 0x05, 0x73, 0x69, 0x64, 0x65, 0x73, 0x44, 0x00, 0x00, 0x00, 0x09, 0x6f, 0x6e, 0x65, 0x2d, 0x73, 0x69, 0x64, 0x65, 0x64, 0x37, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x2d, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x00, 0x00, 0x00, 0x0c, 0x64, 0x75, 0x70, 0x6c, 0x65, 0x78, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x73, 0x4a, 0x00, 0x00, 0x00, 0x05, 0x73, 0x69, 0x64, 0x65, 0x73, 0x44, 0x00, 0x00, 0x00, 0x09, 0x6f, 0x6e, 0x65, 0x2d, 0x73, 0x69, 0x64, 0x65, 0x64, 0x37, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x16, 0x69, 0x70, 0x70, 0x2d, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x0c, 0x61, 0x69, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2d, 0x31, 0x2e, 0x35, 0x44, 0x00, 0x00, 0x00, 0x0e, 0x69, 0x70, 0x70, 0x2d, 0x65, 0x76, 0x65, 0x72, 0x79, 0x77, 0x68, 0x65, 0x72, 0x65, 0x44, 0x00, 0x14, 0x77, 0x68, 0x69, 0x63, 0x68, 0x2d, 0x6a, 0x6f, 0x62, 0x73, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x44, 0x00, 0x00, 0x00, 0x0d, 0x6e, 0x6f, 0x74, 0x2d, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x44, 0x00, 0x00, 0x00, 0x03, 0x61, 0x6c, 0x6c, 0x22, 0x00, 0x11, 0x6a, 0x6f, 0x62, 0x2d, 0x69, 0x64, 0x73, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x01, 0x01, 0x22, 0x00, 0x1d, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2d, 0x75, 0x73, 0x65, 0x72, 0x2d, 0x75, 0x72, 0x69, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x01, 0x01, 0x44, 0x00, 0x22, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x2d, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x74, 0x69, 0x6d, 0x65, 0x2d, 0x6f, 0x75, 0x74, 0x2d, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x0b, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x2d, 0x6a, 0x6f, 0x62, 0x12, 0x00, 0x14, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x67, 0x65, 0x6f, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x41, 0x00, 0x10, 0x6d, 0x6f, 0x70, 0x72, 0x69, 0x61, 0x2d, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x00, 0x03, 0x31, 0x2e, 0x33, 0x22, 0x00, 0x1e, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x2d, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x01, 0x00, 0x31, 0x00, 0x1f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2d, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2d, 0x64, 0x61, 0x74, 0x65, 0x2d, 0x74, 0x69, 0x6d, 0x65, 0x00, 0x0b, 0x07, 0xe4, 0x01, 0x13, 0x0a, 0x31, 0x10, 0x00, 0x2b, 0x00, 0x00, 0x21, 0x00, 0x1a, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2d, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2d, 0x74, 0x69, 0x6d, 0x65, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x1e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2d, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2d, 0x64, 0x61, 0x74, 0x65, 0x2d, 0x74, 0x69, 0x6d, 0x65, 0x00, 0x0b, 0x07, 0xe4, 0x01, 0x13, 0x0a, 0x31, 0x10, 0x00, 0x2b, 0x00, 0x00, 0x21, 0x00, 0x19, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2d, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2d, 0x74, 0x69, 0x6d, 0x65, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x1b, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2d, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x0c, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x6b, 0x69, 0x6e, 0x64, 0x00, 0x08, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x00, 0x00, 0x00, 0x08, 0x65, 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x44, 0x00, 0x00, 0x00, 0x05, 0x70, 0x68, 0x6f, 0x74, 0x6f, 0x44, 0x00, 0x00, 0x00, 0x08, 0x70, 0x6f, 0x73, 0x74, 0x63, 0x61, 0x72, 0x64, 0x44, 0x00, 0x0f, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x12, 0x6e, 0x61, 0x5f, 0x6c, 0x65, 0x74, 0x74, 0x65, 0x72, 0x5f, 0x38, 0x2e, 0x35, 0x78, 0x31, 0x31, 0x69, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x11, 0x6e, 0x61, 0x5f, 0x6c, 0x65, 0x67, 0x61, 0x6c, 0x5f, 0x38, 0x2e, 0x35, 0x78, 0x31, 0x34, 0x69, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x18, 0x6e, 0x61, 0x5f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x37, 0x2e, 0x32, 0x35, 0x78, 0x31, 0x30, 0x2e, 0x35, 0x69, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x14, 0x6e, 0x61, 0x5f, 0x69, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x5f, 0x35, 0x2e, 0x35, 0x78, 0x38, 0x2e, 0x35, 0x69, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x14, 0x6e, 0x61, 0x5f, 0x66, 0x6f, 0x6f, 0x6c, 0x73, 0x63, 0x61, 0x70, 0x5f, 0x38, 0x2e, 0x35, 0x78, 0x31, 0x33, 0x69, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x12, 0x6e, 0x61, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2d, 0x33, 0x78, 0x35, 0x5f, 0x33, 0x78, 0x35, 0x69, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x12, 0x6e, 0x61, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2d, 0x34, 0x78, 0x36, 0x5f, 0x34, 0x78, 0x36, 0x69, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x0c, 0x6e, 0x61, 0x5f, 0x35, 0x78, 0x37, 0x5f, 0x35, 0x78, 0x37, 0x69, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x12, 0x6e, 0x61, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2d, 0x35, 0x78, 0x38, 0x5f, 0x35, 0x78, 0x38, 0x69, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x10, 0x69, 0x73, 0x6f, 0x5f, 0x61, 0x34, 0x5f, 0x32, 0x31, 0x30, 0x78, 0x32, 0x39, 0x37, 0x6d, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x10, 0x69, 0x73, 0x6f, 0x5f, 0x61, 0x35, 0x5f, 0x31, 0x34, 0x38, 0x78, 0x32, 0x31, 0x30, 0x6d, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x10, 0x69, 0x73, 0x6f, 0x5f, 0x61, 0x36, 0x5f, 0x31, 0x30, 0x35, 0x78, 0x31, 0x34, 0x38, 0x6d, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x10, 0x6a, 0x69, 0x73, 0x5f, 0x62, 0x35, 0x5f, 0x31, 0x38, 0x32, 0x78, 0x32, 0x35, 0x37, 0x6d, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x12, 0x6f, 0x65, 0x5f, 0x70, 0x68, 0x6f, 0x74, 0x6f, 0x2d, 0x6c, 0x5f, 0x33, 0x2e, 0x35, 0x78, 0x35, 0x69, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x18, 0x6f, 0x6d, 0x5f, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x2d, 0x70, 0x68, 0x6f, 0x74, 0x6f, 0x5f, 0x31, 0x30, 0x30, 0x78, 0x31, 0x35, 0x30, 0x6d, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x14, 0x6e, 0x61, 0x5f, 0x6f, 0x66, 0x69, 0x63, 0x69, 0x6f, 0x5f, 0x38, 0x2e, 0x35, 0x78, 0x31, 0x33, 0x2e, 0x34, 0x69, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x10, 0x6f, 0x6d, 0x5f, 0x31, 0x36, 0x6b, 0x5f, 0x31, 0x39, 0x35, 0x78, 0x32, 0x37, 0x30, 0x6d, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x10, 0x6f, 0x6d, 0x5f, 0x31, 0x36, 0x6b, 0x5f, 0x31, 0x38, 0x34, 0x78, 0x32, 0x36, 0x30, 0x6d, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x14, 0x72, 0x6f, 0x63, 0x5f, 0x31, 0x36, 0x6b, 0x5f, 0x37, 0x2e, 0x37, 0x35, 0x78, 0x31, 0x30, 0x2e, 0x37, 0x35, 0x69, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x14, 0x6a, 0x70, 0x6e, 0x5f, 0x68, 0x61, 0x67, 0x61, 0x6b, 0x69, 0x5f, 0x31, 0x30, 0x30, 0x78, 0x31, 0x34, 0x38, 0x6d, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x14, 0x6a, 0x70, 0x6e, 0x5f, 0x6f, 0x75, 0x66, 0x75, 0x6b, 0x75, 0x5f, 0x31, 0x34, 0x38, 0x78, 0x32, 0x30, 0x30, 0x6d, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x18, 0x6e, 0x61, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x2d, 0x31, 0x30, 0x5f, 0x34, 0x2e, 0x31, 0x32, 0x35, 0x78, 0x39, 0x2e, 0x35, 0x69, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x16, 0x6e, 0x61, 0x5f, 0x6d, 0x6f, 0x6e, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x33, 0x2e, 0x38, 0x37, 0x35, 0x78, 0x37, 0x2e, 0x35, 0x69, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x10, 0x69, 0x73, 0x6f, 0x5f, 0x62, 0x35, 0x5f, 0x31, 0x37, 0x36, 0x78, 0x32, 0x35, 0x30, 0x6d, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x10, 0x69, 0x73, 0x6f, 0x5f, 0x63, 0x35, 0x5f, 0x31, 0x36, 0x32, 0x78, 0x32, 0x32, 0x39, 0x6d, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x10, 0x69, 0x73, 0x6f, 0x5f, 0x63, 0x36, 0x5f, 0x31, 0x31, 0x34, 0x78, 0x31, 0x36, 0x32, 0x6d, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x10, 0x69, 0x73, 0x6f, 0x5f, 0x64, 0x6c, 0x5f, 0x31, 0x31, 0x30, 0x78, 0x32, 0x32, 0x30, 0x6d, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x13, 0x6a, 0x70, 0x6e, 0x5f, 0x63, 0x68, 0x6f, 0x75, 0x33, 0x5f, 0x31, 0x32, 0x30, 0x78, 0x32, 0x33, 0x35, 0x6d, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x12, 0x6a, 0x70, 0x6e, 0x5f, 0x63, 0x68, 0x6f, 0x75, 0x34, 0x5f, 0x39, 0x30, 0x78, 0x32, 0x30, 0x35, 0x6d, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x10, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x6d, 0x69, 0x6e, 0x5f, 0x33, 0x78, 0x35, 0x69, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x13, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x38, 0x2e, 0x35, 0x78, 0x31, 0x34, 0x69, 0x6e, 0x44, 0x00, 0x0d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x00, 0x10, 0x69, 0x73, 0x6f, 0x5f, 0x61, 0x34, 0x5f, 0x32, 0x31, 0x30, 0x78, 0x32, 0x39, 0x37, 0x6d, 0x6d, 0x44, 0x00, 0x13, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x0a, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x44, 0x00, 0x00, 0x00, 0x0a, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x44, 0x00, 0x00, 0x00, 0x10, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x74, 0x6f, 0x70, 0x2d, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x11, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x2d, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x12, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x2d, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x13, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x2d, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x44, 0x00, 0x00, 0x00, 0x0c, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x00, 0x00, 0x00, 0x0f, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x2d, 0x6e, 0x61, 0x6d, 0x65, 0x34, 0x00, 0x11, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x63, 0x6f, 0x6c, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0a, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x78, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x52, 0x08, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x79, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x74, 0x04, 0x37, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x10, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x74, 0x6f, 0x70, 0x2d, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x28, 0x4a, 0x00, 0x00, 0x00, 0x13, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x2d, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x28, 0x4a, 0x00, 0x00, 0x00, 0x11, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x2d, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x28, 0x4a, 0x00, 0x00, 0x00, 0x12, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x2d, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x28, 0x4a, 0x00, 0x00, 0x00, 0x0c, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x00, 0x00, 0x00, 0x04, 0x6d, 0x61, 0x69, 0x6e, 0x4a, 0x00, 0x00, 0x00, 0x0a, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x44, 0x00, 0x00, 0x00, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x79, 0x37, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x17, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2d, 0x63, 0x6f, 0x6c, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x00, 0x00, 0x21, 0x00, 0x1b, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x2d, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x04, 0x00, 0x00, 0x01, 0x28, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x1c, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x2d, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x04, 0x00, 0x00, 0x01, 0x28, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x1a, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x74, 0x6f, 0x70, 0x2d, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x04, 0x00, 0x00, 0x01, 0x28, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x1d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x2d, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x04, 0x00, 0x00, 0x01, 0x28, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x16, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x04, 0x6d, 0x61, 0x69, 0x6e, 0x44, 0x00, 0x14, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x79, 0x44, 0x00, 0x00, 0x00, 0x14, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x70, 0x2e, 0x65, 0x63, 0x6f, 0x73, 0x6d, 0x61, 0x72, 0x74, 0x2d, 0x6c, 0x69, 0x74, 0x65, 0x44, 0x00, 0x00, 0x00, 0x21, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x70, 0x2e, 0x70, 0x72, 0x65, 0x6d, 0x69, 0x75, 0x6d, 0x2d, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x44, 0x00, 0x00, 0x00, 0x25, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x70, 0x2e, 0x74, 0x72, 0x69, 0x66, 0x6f, 0x6c, 0x64, 0x2d, 0x62, 0x72, 0x6f, 0x63, 0x68, 0x75, 0x72, 0x65, 0x2d, 0x67, 0x6c, 0x6f, 0x73, 0x73, 0x79, 0x2d, 0x31, 0x38, 0x30, 0x67, 0x73, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x15, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x70, 0x2e, 0x62, 0x72, 0x6f, 0x63, 0x68, 0x75, 0x72, 0x65, 0x2d, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x44, 0x00, 0x00, 0x00, 0x16, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x70, 0x2e, 0x62, 0x72, 0x6f, 0x63, 0x68, 0x75, 0x72, 0x65, 0x2d, 0x67, 0x6c, 0x6f, 0x73, 0x73, 0x79, 0x44, 0x00, 0x00, 0x00, 0x15, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x70, 0x2e, 0x61, 0x64, 0x76, 0x61, 0x6e, 0x63, 0x65, 0x64, 0x2d, 0x70, 0x68, 0x6f, 0x74, 0x6f, 0x44, 0x00, 0x00, 0x00, 0x16, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x79, 0x2d, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x44, 0x00, 0x00, 0x00, 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x70, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x44, 0x00, 0x00, 0x00, 0x09, 0x63, 0x61, 0x72, 0x64, 0x73, 0x74, 0x6f, 0x63, 0x6b, 0x44, 0x00, 0x00, 0x00, 0x16, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x79, 0x2d, 0x68, 0x65, 0x61, 0x76, 0x79, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x44, 0x00, 0x00, 0x00, 0x15, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x79, 0x2d, 0x6c, 0x65, 0x74, 0x74, 0x65, 0x72, 0x68, 0x65, 0x61, 0x64, 0x34, 0x00, 0x14, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x78, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x54, 0x56, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x79, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x6d, 0x24, 0x37, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x78, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x54, 0x56, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x79, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x8a, 0xe8, 0x37, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x78, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x47, 0xef, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x79, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x68, 0x2e, 0x37, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x78, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x36, 0x92, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x79, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x54, 0x56, 0x37, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x78, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x54, 0x56, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x79, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x80, 0xfc, 0x37, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x78, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x1d, 0xc4, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x79, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x31, 0x9c, 0x37, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x78, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x27, 0xb0, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x79, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x3b, 0x88, 0x37, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x78, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x31, 0x9c, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x79, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x45, 0x74, 0x37, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x78, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x31, 0x9c, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x79, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x4f, 0x60, 0x37, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x78, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x52, 0x08, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x79, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x74, 0x04, 0x37, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x78, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x39, 0xd0, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x79, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x52, 0x08, 0x37, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x78, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x29, 0x04, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x79, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x39, 0xd0, 0x37, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x78, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x47, 0x18, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x79, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x64, 0x64, 0x37, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x78, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x22, 0xba, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x79, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x31, 0x9c, 0x37, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x78, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x27, 0x10, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x79, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x3a, 0x98, 0x37, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x78, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x54, 0x56, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x79, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x84, 0xf4, 0x37, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x78, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x4c, 0x2c, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x79, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x69, 0x78, 0x37, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x78, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x47, 0xe0, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x79, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x65, 0x90, 0x37, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x78, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x4c, 0xe5, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x79, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x6a, 0xa9, 0x37, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x78, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x27, 0x10, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x79, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x39, 0xd0, 0x37, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x78, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x39, 0xd0, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x79, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x4e, 0x20, 0x37, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x78, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x28, 0xed, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x79, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x5e, 0x42, 0x37, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x78, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x26, 0x72, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x79, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x4a, 0x6a, 0x37, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x78, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x44, 0xc0, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x79, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x61, 0xa8, 0x37, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x78, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x3f, 0x48, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x79, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x59, 0x74, 0x37, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x78, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x2c, 0x88, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x79, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x3f, 0x48, 0x37, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x78, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x2a, 0xf8, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x79, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x55, 0xf0, 0x37, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x78, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x2e, 0xe0, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x79, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x5b, 0xcc, 0x37, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x78, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x23, 0x28, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x79, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x50, 0x14, 0x37, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x78, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x33, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x1d, 0xc4, 0x00, 0x00, 0x54, 0x56, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x79, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x33, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x31, 0x9c, 0x00, 0x00, 0x8a, 0xe8, 0x37, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x0b, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x72, 0x65, 0x61, 0x64, 0x79, 0x00, 0x10, 0x69, 0x73, 0x6f, 0x5f, 0x61, 0x34, 0x5f, 0x32, 0x31, 0x30, 0x78, 0x32, 0x39, 0x37, 0x6d, 0x6d, 0x34, 0x00, 0x0f, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x63, 0x6f, 0x6c, 0x2d, 0x72, 0x65, 0x61, 0x64, 0x79, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0a, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x78, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x52, 0x08, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x79, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x74, 0x04, 0x37, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x10, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x74, 0x6f, 0x70, 0x2d, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x28, 0x4a, 0x00, 0x00, 0x00, 0x13, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x2d, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x28, 0x4a, 0x00, 0x00, 0x00, 0x11, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x2d, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x28, 0x4a, 0x00, 0x00, 0x00, 0x12, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x2d, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x28, 0x4a, 0x00, 0x00, 0x00, 0x0c, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x00, 0x00, 0x00, 0x04, 0x6d, 0x61, 0x69, 0x6e, 0x4a, 0x00, 0x00, 0x00, 0x0a, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x44, 0x00, 0x00, 0x00, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x79, 0x37, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0a, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x78, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x52, 0x08, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x79, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x74, 0x04, 0x37, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x10, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x74, 0x6f, 0x70, 0x2d, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x13, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x2d, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x11, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x2d, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x12, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x2d, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0c, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x00, 0x00, 0x00, 0x04, 0x6d, 0x61, 0x69, 0x6e, 0x4a, 0x00, 0x00, 0x00, 0x0a, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x44, 0x00, 0x00, 0x00, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x79, 0x37, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0a, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x78, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x52, 0x08, 0x4a, 0x00, 0x00, 0x00, 0x0b, 0x79, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x74, 0x04, 0x37, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x10, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x74, 0x6f, 0x70, 0x2d, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x28, 0x4a, 0x00, 0x00, 0x00, 0x13, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x2d, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x28, 0x4a, 0x00, 0x00, 0x00, 0x11, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x2d, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x28, 0x4a, 0x00, 0x00, 0x00, 0x12, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x2d, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x28, 0x4a, 0x00, 0x00, 0x00, 0x0c, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x00, 0x00, 0x00, 0x04, 0x6d, 0x61, 0x69, 0x6e, 0x4a, 0x00, 0x00, 0x00, 0x0a, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x44, 0x00, 0x00, 0x00, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x79, 0x37, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x14, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2d, 0x63, 0x6f, 0x6c, 0x2d, 0x72, 0x65, 0x61, 0x64, 0x79, 0x00, 0x00, 0x44, 0x00, 0x18, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2d, 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x12, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x2d, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x30, 0x00, 0x10, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x72, 0x00, 0x00, 0x30, 0x00, 0x1c, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x72, 0x2d, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x21, 0x00, 0x10, 0x70, 0x61, 0x67, 0x65, 0x73, 0x2d, 0x70, 0x65, 0x72, 0x2d, 0x6d, 0x69, 0x6e, 0x75, 0x74, 0x65, 0x00, 0x04, 0x00, 0x00, 0x00, 0x18, 0x21, 0x00, 0x16, 0x70, 0x61, 0x67, 0x65, 0x73, 0x2d, 0x70, 0x65, 0x72, 0x2d, 0x6d, 0x69, 0x6e, 0x75, 0x74, 0x65, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x33, 0x00, 0x17, 0x6a, 0x70, 0x65, 0x67, 0x2d, 0x6b, 0x2d, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x73, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x33, 0x00, 0x1a, 0x6a, 0x70, 0x65, 0x67, 0x2d, 0x78, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x33, 0x00, 0x1a, 0x6a, 0x70, 0x65, 0x67, 0x2d, 0x79, 0x2d, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x40, 0x00, 0x33, 0x00, 0x16, 0x70, 0x64, 0x66, 0x2d, 0x6b, 0x2d, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x73, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x33, 0x00, 0x14, 0x70, 0x64, 0x66, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x2d, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x73, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x22, 0x00, 0x17, 0x70, 0x64, 0x66, 0x2d, 0x66, 0x69, 0x74, 0x2d, 0x74, 0x6f, 0x2d, 0x70, 0x61, 0x67, 0x65, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x00, 0x01, 0x00, 0x22, 0x00, 0x19, 0x70, 0x64, 0x66, 0x2d, 0x66, 0x69, 0x74, 0x2d, 0x74, 0x6f, 0x2d, 0x70, 0x61, 0x67, 0x65, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x01, 0x00, 0x44, 0x00, 0x16, 0x70, 0x64, 0x66, 0x2d, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x10, 0x69, 0x73, 0x6f, 0x2d, 0x33, 0x32, 0x30, 0x30, 0x30, 0x2d, 0x31, 0x5f, 0x32, 0x30, 0x30, 0x38, 0x44, 0x00, 0x00, 0x00, 0x09, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2d, 0x31, 0x2e, 0x37, 0x44, 0x00, 0x00, 0x00, 0x09, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2d, 0x31, 0x2e, 0x36, 0x44, 0x00, 0x00, 0x00, 0x09, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2d, 0x31, 0x2e, 0x35, 0x44, 0x00, 0x00, 0x00, 0x10, 0x69, 0x73, 0x6f, 0x2d, 0x31, 0x39, 0x30, 0x30, 0x35, 0x2d, 0x31, 0x5f, 0x32, 0x30, 0x30, 0x35, 0x44, 0x00, 0x00, 0x00, 0x09, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2d, 0x31, 0x2e, 0x34, 0x44, 0x00, 0x00, 0x00, 0x09, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2d, 0x31, 0x2e, 0x33, 0x44, 0x00, 0x00, 0x00, 0x09, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2d, 0x31, 0x2e, 0x32, 0x44, 0x00, 0x0d, 0x75, 0x72, 0x66, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x03, 0x43, 0x50, 0x31, 0x44, 0x00, 0x00, 0x00, 0x0f, 0x4d, 0x54, 0x31, 0x2d, 0x32, 0x2d, 0x38, 0x2d, 0x39, 0x2d, 0x31, 0x30, 0x2d, 0x31, 0x31, 0x44, 0x00, 0x00, 0x00, 0x07, 0x50, 0x51, 0x33, 0x2d, 0x34, 0x2d, 0x35, 0x44, 0x00, 0x00, 0x00, 0x09, 0x52, 0x53, 0x33, 0x30, 0x30, 0x2d, 0x36, 0x30, 0x30, 0x44, 0x00, 0x00, 0x00, 0x06, 0x53, 0x52, 0x47, 0x42, 0x32, 0x34, 0x44, 0x00, 0x00, 0x00, 0x04, 0x4f, 0x42, 0x31, 0x30, 0x44, 0x00, 0x00, 0x00, 0x02, 0x57, 0x38, 0x44, 0x00, 0x00, 0x00, 0x05, 0x44, 0x45, 0x56, 0x57, 0x38, 0x44, 0x00, 0x00, 0x00, 0x08, 0x44, 0x45, 0x56, 0x52, 0x47, 0x42, 0x32, 0x34, 0x44, 0x00, 0x00, 0x00, 0x0a, 0x41, 0x44, 0x4f, 0x42, 0x45, 0x52, 0x47, 0x42, 0x32, 0x34, 0x44, 0x00, 0x00, 0x00, 0x03, 0x44, 0x4d, 0x33, 0x44, 0x00, 0x00, 0x00, 0x03, 0x46, 0x4e, 0x33, 0x44, 0x00, 0x00, 0x00, 0x05, 0x49, 0x53, 0x31, 0x2d, 0x32, 0x44, 0x00, 0x00, 0x00, 0x04, 0x56, 0x31, 0x2e, 0x34, 0x42, 0x00, 0x0c, 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x72, 0x2d, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x00, 0x08, 0x63, 0x79, 0x61, 0x6e, 0x20, 0x69, 0x6e, 0x6b, 0x42, 0x00, 0x00, 0x00, 0x0b, 0x6d, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x61, 0x20, 0x69, 0x6e, 0x6b, 0x42, 0x00, 0x00, 0x00, 0x0a, 0x79, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x20, 0x69, 0x6e, 0x6b, 0x42, 0x00, 0x00, 0x00, 0x09, 0x62, 0x6c, 0x61, 0x63, 0x6b, 0x20, 0x69, 0x6e, 0x6b, 0x42, 0x00, 0x0d, 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x73, 0x00, 0x07, 0x23, 0x30, 0x30, 0x46, 0x46, 0x46, 0x46, 0x42, 0x00, 0x00, 0x00, 0x07, 0x23, 0x46, 0x46, 0x30, 0x30, 0x46, 0x46, 0x42, 0x00, 0x00, 0x00, 0x07, 0x23, 0x46, 0x46, 0x46, 0x46, 0x30, 0x30, 0x42, 0x00, 0x00, 0x00, 0x07, 0x23, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x44, 0x00, 0x0c, 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x72, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x00, 0x0d, 0x69, 0x6e, 0x6b, 0x2d, 0x63, 0x61, 0x72, 0x74, 0x72, 0x69, 0x64, 0x67, 0x65, 0x44, 0x00, 0x00, 0x00, 0x0d, 0x69, 0x6e, 0x6b, 0x2d, 0x63, 0x61, 0x72, 0x74, 0x72, 0x69, 0x64, 0x67, 0x65, 0x44, 0x00, 0x00, 0x00, 0x0d, 0x69, 0x6e, 0x6b, 0x2d, 0x63, 0x61, 0x72, 0x74, 0x72, 0x69, 0x64, 0x67, 0x65, 0x44, 0x00, 0x00, 0x00, 0x0d, 0x69, 0x6e, 0x6b, 0x2d, 0x63, 0x61, 0x72, 0x74, 0x72, 0x69, 0x64, 0x67, 0x65, 0x21, 0x00, 0x11, 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x72, 0x2d, 0x6c, 0x6f, 0x77, 0x2d, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x73, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x21, 0x00, 0x12, 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x72, 0x2d, 0x68, 0x69, 0x67, 0x68, 0x2d, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x73, 0x00, 0x04, 0x00, 0x00, 0x00, 0x64, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x64, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x64, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x64, 0x21, 0x00, 0x0d, 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x72, 0x2d, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x73, 0x00, 0x04, 0x00, 0x00, 0x00, 0x3c, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x46, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x3c, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x46, 0x30, 0x00, 0x0e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x00, 0x65, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x69, 0x6e, 0x6b, 0x43, 0x61, 0x72, 0x74, 0x72, 0x69, 0x64, 0x67, 0x65, 0x3b, 0x6d, 0x61, 0x78, 0x63, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x3d, 0x31, 0x30, 0x30, 0x3b, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x3d, 0x36, 0x30, 0x3b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x54, 0x68, 0x61, 0x74, 0x49, 0x73, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x3b, 0x75, 0x6e, 0x69, 0x74, 0x3d, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x3b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x61, 0x6e, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x63, 0x79, 0x61, 0x6e, 0x3b, 0x30, 0x00, 0x00, 0x00, 0x68, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x69, 0x6e, 0x6b, 0x43, 0x61, 0x72, 0x74, 0x72, 0x69, 0x64, 0x67, 0x65, 0x3b, 0x6d, 0x61, 0x78, 0x63, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x3d, 0x31, 0x30, 0x30, 0x3b, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x3d, 0x37, 0x30, 0x3b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x54, 0x68, 0x61, 0x74, 0x49, 0x73, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x3b, 0x75, 0x6e, 0x69, 0x74, 0x3d, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x3b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x61, 0x6e, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x6d, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x61, 0x3b, 0x30, 0x00, 0x00, 0x00, 0x67, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x69, 0x6e, 0x6b, 0x43, 0x61, 0x72, 0x74, 0x72, 0x69, 0x64, 0x67, 0x65, 0x3b, 0x6d, 0x61, 0x78, 0x63, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x3d, 0x31, 0x30, 0x30, 0x3b, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x3d, 0x36, 0x30, 0x3b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x54, 0x68, 0x61, 0x74, 0x49, 0x73, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x3b, 0x75, 0x6e, 0x69, 0x74, 0x3d, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x3b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x61, 0x6e, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x79, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x3b, 0x30, 0x00, 0x00, 0x00, 0x66, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x69, 0x6e, 0x6b, 0x43, 0x61, 0x72, 0x74, 0x72, 0x69, 0x64, 0x67, 0x65, 0x3b, 0x6d, 0x61, 0x78, 0x63, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x3d, 0x31, 0x30, 0x30, 0x3b, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x3d, 0x37, 0x30, 0x3b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x54, 0x68, 0x61, 0x74, 0x49, 0x73, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x3b, 0x75, 0x6e, 0x69, 0x74, 0x3d, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x3b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x61, 0x6e, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x62, 0x6c, 0x61, 0x63, 0x6b, 0x3b, 0x41, 0x00, 0x1a, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x2d, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x0e, 0x43, 0x79, 0x61, 0x6e, 0x20, 0x43, 0x61, 0x72, 0x74, 0x72, 0x69, 0x64, 0x67, 0x65, 0x41, 0x00, 0x00, 0x00, 0x11, 0x4d, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x61, 0x20, 0x43, 0x61, 0x72, 0x74, 0x72, 0x69, 0x64, 0x67, 0x65, 0x41, 0x00, 0x00, 0x00, 0x10, 0x59, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x20, 0x43, 0x61, 0x72, 0x74, 0x72, 0x69, 0x64, 0x67, 0x65, 0x41, 0x00, 0x00, 0x00, 0x0f, 0x42, 0x6c, 0x61, 0x63, 0x6b, 0x20, 0x43, 0x61, 0x72, 0x74, 0x72, 0x69, 0x64, 0x67, 0x65, 0x42, 0x00, 0x15, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x66, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x2d, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x16, 0x57, 0x45, 0x42, 0x50, 0x44, 0x4c, 0x50, 0x50, 0x31, 0x4e, 0x30, 0x30, 0x31, 0x2e, 0x31, 0x39, 0x31, 0x39, 0x41, 0x2e, 0x30, 0x30, 0x41, 0x00, 0x1f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x66, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x2d, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2d, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x00, 0x16, 0x57, 0x45, 0x42, 0x50, 0x44, 0x4c, 0x50, 0x50, 0x31, 0x4e, 0x30, 0x30, 0x31, 0x2e, 0x31, 0x39, 0x31, 0x39, 0x41, 0x2e, 0x30, 0x30, 0x30, 0x00, 0x18, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x66, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x2d, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x00, 0x16, 0x57, 0x45, 0x42, 0x50, 0x44, 0x4c, 0x50, 0x50, 0x31, 0x4e, 0x30, 0x30, 0x31, 0x2e, 0x31, 0x39, 0x31, 0x39, 0x41, 0x2e, 0x30, 0x30, 0x30, 0x00, 0x12, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x2d, 0x74, 0x72, 0x61, 0x79, 0x00, 0x86, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x73, 0x68, 0x65, 0x65, 0x74, 0x46, 0x65, 0x65, 0x64, 0x41, 0x75, 0x74, 0x6f, 0x4e, 0x6f, 0x6e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x61, 0x62, 0x6c, 0x65, 0x3b, 0x64, 0x69, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x3d, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x3b, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x66, 0x65, 0x65, 0x64, 0x3d, 0x32, 0x39, 0x37, 0x30, 0x30, 0x30, 0x3b, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x78, 0x66, 0x65, 0x65, 0x64, 0x3d, 0x32, 0x31, 0x30, 0x30, 0x30, 0x30, 0x3b, 0x6d, 0x61, 0x78, 0x63, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x3d, 0x2d, 0x32, 0x3b, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x3d, 0x2d, 0x32, 0x3b, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3d, 0x30, 0x3b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x54, 0x72, 0x61, 0x79, 0x31, 0x30, 0x00, 0x13, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x2d, 0x74, 0x72, 0x61, 0x79, 0x00, 0x6e, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x3b, 0x6d, 0x61, 0x78, 0x63, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x3d, 0x2d, 0x32, 0x3b, 0x72, 0x65, 0x6d, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x3d, 0x2d, 0x32, 0x3b, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3d, 0x35, 0x3b, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3d, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x3b, 0x70, 0x61, 0x67, 0x65, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x3d, 0x66, 0x61, 0x63, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x3b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x54, 0x72, 0x61, 0x79, 0x31, 0x21, 0x00, 0x0e, 0x63, 0x6f, 0x70, 0x69, 0x65, 0x73, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x23, 0x00, 0x12, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x13, 0x00, 0x16, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2d, 0x63, 0x6f, 0x6c, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x00, 0x00, 0x23, 0x00, 0x1d, 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x23, 0x00, 0x15, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2d, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x32, 0x00, 0x1a, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x00, 0x09, 0x00, 0x00, 0x02, 0x58, 0x00, 0x00, 0x02, 0x58, 0x03, 0x44, 0x00, 0x0d, 0x73, 0x69, 0x64, 0x65, 0x73, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x00, 0x09, 0x6f, 0x6e, 0x65, 0x2d, 0x73, 0x69, 0x64, 0x65, 0x64, 0x44, 0x00, 0x12, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x2d, 0x62, 0x69, 0x6e, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x00, 0x09, 0x66, 0x61, 0x63, 0x65, 0x2d, 0x64, 0x6f, 0x77, 0x6e, 0x44, 0x00, 0x13, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x2d, 0x6d, 0x6f, 0x64, 0x65, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x00, 0x04, 0x61, 0x75, 0x74, 0x6f, 0x44, 0x00, 0x18, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x2d, 0x6d, 0x6f, 0x64, 0x65, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x00, 0x04, 0x61, 0x75, 0x74, 0x6f, 0x44, 0x00, 0x22, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x2d, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2d, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x69, 0x6e, 0x67, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x00, 0x24, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x2d, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2d, 0x75, 0x6e, 0x63, 0x6f, 0x6c, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x2d, 0x63, 0x6f, 0x70, 0x69, 0x65, 0x73, 0x21, 0x00, 0x11, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x2d, 0x75, 0x70, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x44, 0x00, 0x28, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x2d, 0x75, 0x70, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x00, 0x10, 0x74, 0x6f, 0x72, 0x69, 0x67, 0x68, 0x74, 0x2d, 0x74, 0x6f, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x44, 0x00, 0x1e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2d, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2d, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x00, 0x04, 0x61, 0x75, 0x74, 0x6f, 0x44, 0x00, 0x15, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2d, 0x73, 0x63, 0x61, 0x6c, 0x69, 0x6e, 0x67, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x00, 0x04, 0x61, 0x75, 0x74, 0x6f, 0x33, 0x00, 0x10, 0x63, 0x6f, 0x70, 0x69, 0x65, 0x73, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x63, 0x23, 0x00, 0x14, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x33, 0x00, 0x1b, 0x6a, 0x6f, 0x62, 0x2d, 0x70, 0x61, 0x67, 0x65, 0x73, 0x2d, 0x70, 0x65, 0x72, 0x2d, 0x73, 0x65, 0x74, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x7f, 0xff, 0xff, 0xff, 0x23, 0x00, 0x1f, 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x23, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x23, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x23, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x23, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x07, 0x23, 0x00, 0x17, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2d, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x23, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x23, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x32, 0x00, 0x1c, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x09, 0x00, 0x00, 0x01, 0x2c, 0x00, 0x00, 0x01, 0x2c, 0x03, 0x32, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x02, 0x58, 0x00, 0x00, 0x02, 0x58, 0x03, 0x32, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x04, 0xb0, 0x00, 0x00, 0x04, 0xb0, 0x03, 0x44, 0x00, 0x0f, 0x73, 0x69, 0x64, 0x65, 0x73, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x09, 0x6f, 0x6e, 0x65, 0x2d, 0x73, 0x69, 0x64, 0x65, 0x64, 0x44, 0x00, 0x00, 0x00, 0x14, 0x74, 0x77, 0x6f, 0x2d, 0x73, 0x69, 0x64, 0x65, 0x64, 0x2d, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x2d, 0x65, 0x64, 0x67, 0x65, 0x44, 0x00, 0x00, 0x00, 0x13, 0x74, 0x77, 0x6f, 0x2d, 0x73, 0x69, 0x64, 0x65, 0x64, 0x2d, 0x6c, 0x6f, 0x6e, 0x67, 0x2d, 0x65, 0x64, 0x67, 0x65, 0x44, 0x00, 0x14, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x2d, 0x62, 0x69, 0x6e, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x09, 0x66, 0x61, 0x63, 0x65, 0x2d, 0x64, 0x6f, 0x77, 0x6e, 0x44, 0x00, 0x15, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x2d, 0x6d, 0x6f, 0x64, 0x65, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x04, 0x61, 0x75, 0x74, 0x6f, 0x44, 0x00, 0x00, 0x00, 0x0f, 0x61, 0x75, 0x74, 0x6f, 0x2d, 0x6d, 0x6f, 0x6e, 0x6f, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x44, 0x00, 0x00, 0x00, 0x0a, 0x6d, 0x6f, 0x6e, 0x6f, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x44, 0x00, 0x00, 0x00, 0x05, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, 0x00, 0x1a, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x2d, 0x6d, 0x6f, 0x64, 0x65, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x04, 0x61, 0x75, 0x74, 0x6f, 0x44, 0x00, 0x00, 0x00, 0x0f, 0x61, 0x75, 0x74, 0x6f, 0x2d, 0x6d, 0x6f, 0x6e, 0x6f, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x44, 0x00, 0x00, 0x00, 0x0a, 0x6d, 0x6f, 0x6e, 0x6f, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x44, 0x00, 0x00, 0x00, 0x05, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, 0x00, 0x00, 0x00, 0x12, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x2d, 0x6d, 0x6f, 0x6e, 0x6f, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x22, 0x00, 0x15, 0x70, 0x61, 0x67, 0x65, 0x2d, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x01, 0x01, 0x44, 0x00, 0x24, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x2d, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2d, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x69, 0x6e, 0x67, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x24, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x2d, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2d, 0x75, 0x6e, 0x63, 0x6f, 0x6c, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x2d, 0x63, 0x6f, 0x70, 0x69, 0x65, 0x73, 0x44, 0x00, 0x00, 0x00, 0x22, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x2d, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2d, 0x63, 0x6f, 0x6c, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x2d, 0x63, 0x6f, 0x70, 0x69, 0x65, 0x73, 0x21, 0x00, 0x13, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x2d, 0x75, 0x70, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x44, 0x00, 0x2a, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x2d, 0x75, 0x70, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x10, 0x74, 0x6f, 0x72, 0x69, 0x67, 0x68, 0x74, 0x2d, 0x74, 0x6f, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x44, 0x00, 0x13, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x05, 0x70, 0x61, 0x67, 0x65, 0x73, 0x44, 0x00, 0x00, 0x00, 0x05, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x44, 0x00, 0x00, 0x00, 0x09, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2d, 0x63, 0x6f, 0x6c, 0x44, 0x00, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2d, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2d, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x04, 0x61, 0x75, 0x74, 0x6f, 0x44, 0x00, 0x00, 0x00, 0x0a, 0x70, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x75, 0x61, 0x6c, 0x44, 0x00, 0x17, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2d, 0x73, 0x63, 0x61, 0x6c, 0x69, 0x6e, 0x67, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x04, 0x61, 0x75, 0x74, 0x6f, 0x44, 0x00, 0x00, 0x00, 0x08, 0x61, 0x75, 0x74, 0x6f, 0x2d, 0x66, 0x69, 0x74, 0x44, 0x00, 0x00, 0x00, 0x04, 0x66, 0x69, 0x6c, 0x6c, 0x44, 0x00, 0x00, 0x00, 0x03, 0x66, 0x69, 0x74, 0x44, 0x00, 0x00, 0x00, 0x04, 0x6e, 0x6f, 0x6e, 0x65, 0x45, 0x00, 0x0d, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x69, 0x63, 0x6f, 0x6e, 0x73, 0x00, 0x31, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x2f, 0x77, 0x65, 0x62, 0x41, 0x70, 0x70, 0x73, 0x2f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x2e, 0x70, 0x6e, 0x67, 0x45, 0x00, 0x00, 0x00, 0x2b, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x2f, 0x77, 0x65, 0x62, 0x41, 0x70, 0x70, 0x73, 0x2f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x6e, 0x67, 0x45, 0x00, 0x00, 0x00, 0x31, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x2f, 0x77, 0x65, 0x62, 0x41, 0x70, 0x70, 0x73, 0x2f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x2e, 0x70, 0x6e, 0x67, 0x45, 0x00, 0x17, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x2d, 0x69, 0x6e, 0x66, 0x6f, 0x2d, 0x75, 0x72, 0x69, 0x00, 0x26, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x2f, 0x23, 0x68, 0x49, 0x64, 0x2d, 0x70, 0x67, 0x49, 0x6e, 0x6b, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x44, 0x00, 0x1e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x00, 0x04, 0x61, 0x75, 0x74, 0x6f, 0x44, 0x00, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x04, 0x61, 0x75, 0x74, 0x6f, 0x44, 0x00, 0x00, 0x00, 0x05, 0x70, 0x68, 0x6f, 0x74, 0x6f, 0x44, 0x00, 0x00, 0x00, 0x08, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x44, 0x00, 0x00, 0x00, 0x04, 0x74, 0x65, 0x78, 0x74, 0x44, 0x00, 0x00, 0x00, 0x11, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6e, 0x64, 0x2d, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x44, 0x00, 0x1e, 0x70, 0x77, 0x67, 0x2d, 0x72, 0x61, 0x73, 0x74, 0x65, 0x72, 0x2d, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2d, 0x73, 0x68, 0x65, 0x65, 0x74, 0x2d, 0x62, 0x61, 0x63, 0x6b, 0x00, 0x07, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x64, 0x44, 0x00, 0x22, 0x70, 0x77, 0x67, 0x2d, 0x72, 0x61, 0x73, 0x74, 0x65, 0x72, 0x2d, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x07, 0x73, 0x67, 0x72, 0x61, 0x79, 0x5f, 0x38, 0x44, 0x00, 0x00, 0x00, 0x06, 0x73, 0x72, 0x67, 0x62, 0x5f, 0x38, 0x44, 0x00, 0x00, 0x00, 0x0b, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2d, 0x72, 0x67, 0x62, 0x5f, 0x38, 0x44, 0x00, 0x00, 0x00, 0x05, 0x72, 0x67, 0x62, 0x5f, 0x38, 0x32, 0x00, 0x28, 0x70, 0x77, 0x67, 0x2d, 0x72, 0x61, 0x73, 0x74, 0x65, 0x72, 0x2d, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2d, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x09, 0x00, 0x00, 0x01, 0x2c, 0x00, 0x00, 0x01, 0x2c, 0x03, 0x32, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x02, 0x58, 0x00, 0x00, 0x02, 0x58, 0x03, 0x41, 0x00, 0x16, 0x65, 0x70, 0x63, 0x6c, 0x2d, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x03, 0x31, 0x2e, 0x30, 0x22, 0x00, 0x17, 0x6d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x2d, 0x64, 0x75, 0x70, 0x6c, 0x65, 0x78, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x01, 0x00, 0x32, 0x00, 0x20, 0x70, 0x63, 0x6c, 0x6d, 0x2d, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2d, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x09, 0x00, 0x00, 0x01, 0x2c, 0x00, 0x00, 0x01, 0x2c, 0x03, 0x32, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x02, 0x58, 0x00, 0x00, 0x02, 0x58, 0x03, 0x32, 0x00, 0x1e, 0x70, 0x63, 0x6c, 0x6d, 0x2d, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2d, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x00, 0x09, 0x00, 0x00, 0x02, 0x58, 0x00, 0x00, 0x02, 0x58, 0x03, 0x21, 0x00, 0x1b, 0x70, 0x63, 0x6c, 0x6d, 0x2d, 0x73, 0x74, 0x72, 0x69, 0x70, 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x21, 0x00, 0x1b, 0x70, 0x63, 0x6c, 0x6d, 0x2d, 0x73, 0x74, 0x72, 0x69, 0x70, 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x2d, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x44, 0x00, 0x15, 0x70, 0x63, 0x6c, 0x6d, 0x2d, 0x72, 0x61, 0x73, 0x74, 0x65, 0x72, 0x2d, 0x62, 0x61, 0x63, 0x6b, 0x2d, 0x73, 0x69, 0x64, 0x65, 0x00, 0x07, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x64, 0x44, 0x00, 0x21, 0x70, 0x63, 0x6c, 0x6d, 0x2d, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2d, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x2d, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x00, 0x04, 0x6a, 0x70, 0x65, 0x67, 0x44, 0x00, 0x00, 0x00, 0x05, 0x66, 0x6c, 0x61, 0x74, 0x65, 0x44, 0x00, 0x00, 0x00, 0x03, 0x72, 0x6c, 0x65, 0x44, 0x00, 0x22, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2d, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2d, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x2d, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x00, 0x06, 0x63, 0x6f, 0x70, 0x69, 0x65, 0x73, 0x44, 0x00, 0x00, 0x00, 0x15, 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x44, 0x00, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x67, 0x65, 0x74, 0x2d, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x0f, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2d, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x41, 0x00, 0x14, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x41, 0x00, 0x1b, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2d, 0x75, 0x6e, 0x69, 0x74, 0x00, 0x00, 0x44, 0x00, 0x18, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x2d, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x00, 0x07, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x44, 0x00, 0x1a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x2d, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x07, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x44, 0x00, 0x00, 0x00, 0x05, 0x73, 0x6f, 0x75, 0x6e, 0x64, 0x44, 0x00, 0x00, 0x00, 0x03, 0x70, 0x69, 0x6e, 0x23, 0x00, 0x1a, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x2d, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0a, 0x21, 0x00, 0x1b, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x2d, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x74, 0x69, 0x6d, 0x65, 0x2d, 0x6f, 0x75, 0x74, 0x00, 0x04, 0x00, 0x00, 0x00, 0x78, 0x22, 0x00, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x2d, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2d, 0x6a, 0x6f, 0x62, 0x73, 0x2d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x01, 0x00, 0x03, } goipp-1.0.0/index.md000066400000000000000000000015221366031307500142630ustar00rootroot00000000000000# goipp [![godoc.org](https://godoc.org/github.com/OpenPrinting/goipp?status.svg)](http://godoc.org/github.com/OpenPrinting/goipp) ![GitHub](https://img.shields.io/github/license/OpenPrinting/goipp) The goipp library is fairly complete implementation of IPP core protocol in pure Go. Essentially, it is IPP messages parser/composer. Transport is not implemented here, because Go standard library has an excellent built-in HTTP client, and it doesn't make a lot of sense to wrap it here. High-level requests, like "print a file" are also not implemented, only the low-level stuff. All documentation is on godoc.org -- follow the link above. Pull requests are welcomed, assuming they don't break existing API. For more information and software downloads, please visit the [Project's page at GitHub](https://github.com/OpenPrinting/sane-airscan) goipp-1.0.0/message.go000066400000000000000000000141301366031307500146040ustar00rootroot00000000000000/* Go IPP - IPP core protocol implementation in pure Go * * Copyright (C) 2020 and up by Alexander Pevzner (pzz@apevzner.com) * See LICENSE for license terms and conditions * * IPP protocol messages */ package goipp import ( "bytes" "fmt" "io" ) // Code represents Op(operation) or Status codes type Code uint16 // Version represents a protocol version. It consist // of Major and Minor version codes, packed into a single // 16-bit word type Version uint16 // DefaultVersion is the default IPP version const DefaultVersion Version = 0x0200 // MakeVersion makes version from major and minor parts func MakeVersion(major, minor uint8) Version { return Version(major)<<8 | Version(minor) } // Major returns a major part of version func (v Version) Major() uint8 { return uint8(v >> 8) } // Minor returns a minor part of version func (v Version) Minor() uint8 { return uint8(v) } // String() converts version to string (i.e., 2.0) func (v Version) String() string { return fmt.Sprintf("%d.%d", v.Major(), v.Minor()) } // Message represents a single IPP message, which may be either // client request or server response type Message struct { // Common header Version Version // Protocol version Code Code // Operation for request, status for response RequestID uint32 // Set in request, returned in response // Attributes, by group Operation Attributes // Operation attributes Job Attributes // Job attributes Printer Attributes // Printer attributes Unsupported Attributes // Unsupported attributes Subscription Attributes // Subscription attributes EventNotification Attributes // Event Notification attributes Resource Attributes // Resource attributes Document Attributes // Document attributes System Attributes // System attributes Future11 Attributes // \ Future12 Attributes // \ Future13 Attributes // | Reserved for future extensions Future14 Attributes // / Future15 Attributes // / } // NewRequest creates a new request message // // Use DefaultVersion as a first argument, if you don't // have any specific needs func NewRequest(v Version, op Op, id uint32) *Message { return &Message{ Version: v, Code: Code(op), RequestID: id, } } // NewResponse creates a new response message // // Use DefaultVersion as a first argument, if you don't func NewResponse(v Version, status Status, id uint32) *Message { return &Message{ Version: v, Code: Code(status), RequestID: id, } } // Equal checks that two messages are equal func (m Message) Equal(m2 Message) bool { if m.Version != m2.Version || m.Code != m2.Code || m.RequestID != m2.RequestID { return false } groups1 := m.attrGroups() groups2 := m2.attrGroups() if len(groups1) != len(groups2) { return false } for i, grp1 := range groups1 { grp2 := groups2[i] if grp1.tag != grp2.tag || !grp1.attrs.Equal(grp2.attrs) { return false } } return true } // Reset the message into initial state func (m *Message) Reset() { *m = Message{} } // Encode message func (m *Message) Encode(out io.Writer) error { me := messageEncoder{ out: out, } return me.encode(m) } // EncodeBytes encodes message to byte slice func (m *Message) EncodeBytes() ([]byte, error) { var buf bytes.Buffer err := m.Encode(&buf) return buf.Bytes(), err } // Decode message func (m *Message) Decode(in io.Reader) error { md := messageDecoder{ in: in, } m.Reset() return md.decode(m) } // DecodeBytes decodes message from byte slice func (m *Message) DecodeBytes(data []byte) error { return m.Decode(bytes.NewBuffer(data)) } // Print pretty-prints the message. The 'request' parameter affects // interpretation of Message.Code: it is interpreted either // as Op or as Status func (m *Message) Print(out io.Writer, request bool) { out.Write([]byte("{\n")) fmt.Fprintf(out, msgPrintIndent+"VERSION %s\n", m.Version) if request { fmt.Fprintf(out, msgPrintIndent+"OPERATION %s\n", Op(m.Code)) } else { fmt.Fprintf(out, msgPrintIndent+"STATUS %s\n", Status(m.Code)) } for _, grp := range m.attrGroups() { fmt.Fprintf(out, "\n"+msgPrintIndent+"GROUP %s\n", grp.tag) for _, attr := range grp.attrs { m.printAttribute(out, attr, 1) out.Write([]byte("\n")) } } out.Write([]byte("}\n")) } // Pretty-print an attribute. Handles Collection attributes // recursively func (m *Message) printAttribute(out io.Writer, attr Attribute, indent int) { m.printIndent(out, indent) fmt.Fprintf(out, "ATTR %q", attr.Name) tag := TagZero for _, val := range attr.Values { if val.T != tag { fmt.Fprintf(out, " %s:", val.T) tag = val.T } if collection, ok := val.V.(Collection); ok { out.Write([]byte(" {\n")) for _, attr2 := range collection { m.printAttribute(out, attr2, indent+1) out.Write([]byte("\n")) } m.printIndent(out, indent) out.Write([]byte("}")) } else { fmt.Fprintf(out, " %s", val.V) } } } // Print indentation func (m *Message) printIndent(out io.Writer, indent int) { for i := 0; i < indent; i++ { out.Write([]byte(msgPrintIndent)) } } // Get attributes by group. Groups with nil Attributes are skipped, // but groups with non-nil are not, even if len(Attributes) == 0 // // This is a helper function for message encoder and pretty-printer func (m *Message) attrGroups() []struct { tag Tag attrs Attributes } { // Initialize slice of groups groups := []struct { tag Tag attrs Attributes }{ {TagOperationGroup, m.Operation}, {TagJobGroup, m.Job}, {TagPrinterGroup, m.Printer}, {TagUnsupportedGroup, m.Unsupported}, {TagSubscriptionGroup, m.Subscription}, {TagEventNotificationGroup, m.EventNotification}, {TagResourceGroup, m.Resource}, {TagDocumentGroup, m.Document}, {TagSystemGroup, m.System}, {TagFuture11Group, m.Future11}, {TagFuture12Group, m.Future12}, {TagFuture13Group, m.Future13}, {TagFuture14Group, m.Future14}, {TagFuture15Group, m.Future15}, } // Skip all empty groups out := 0 for in := 0; in < len(groups); in++ { if groups[in].attrs != nil { groups[out] = groups[in] out++ } } return groups[:out] } goipp-1.0.0/op.go000066400000000000000000000414711366031307500136060ustar00rootroot00000000000000/* Go IPP - IPP core protocol implementation in pure Go * * Copyright (C) 2020 and up by Alexander Pevzner (pzz@apevzner.com) * See LICENSE for license terms and conditions * * IPP Operation Codes */ package goipp import ( "fmt" ) // Op represents an IPP Operation Code type Op Code const ( OpPrintJob Op = 0x0002 // Print-Job: Print a single file OpPrintURI Op = 0x0003 // Print-URI: Print a single URL OpValidateJob Op = 0x0004 // Validate-Job: Validate job values prior to submission OpCreateJob Op = 0x0005 // Create-Job: Create an empty print job OpSendDocument Op = 0x0006 // Send-Document: Add a file to a job OpSendURI Op = 0x0007 // Send-URI: Add a URL to a job OpCancelJob Op = 0x0008 // Cancel-Job: Cancel a job OpGetJobAttributes Op = 0x0009 // Get-Job-Attribute: Get information about a job OpGetJobs Op = 0x000a // Get-Jobs: Get a list of jobs OpGetPrinterAttributes Op = 0x000b // Get-Printer-Attributes: Get information about a printer OpHoldJob Op = 0x000c // Hold-Job: Hold a job for printing OpReleaseJob Op = 0x000d // Release-Job: Release a job for printing OpRestartJob Op = 0x000e // Restart-Job: Reprint a job OpPausePrinter Op = 0x0010 // Pause-Printer: Stop a printer OpResumePrinter Op = 0x0011 // Resume-Printer: Start a printer OpPurgeJobs Op = 0x0012 // Purge-Jobs: Delete all jobs OpSetPrinterAttributes Op = 0x0013 // Set-Printer-Attributes: Set printer values OpSetJobAttributes Op = 0x0014 // Set-Job-Attributes: Set job values OpGetPrinterSupportedValues Op = 0x0015 // Get-Printer-Supported-Values: Get supported values OpCreatePrinterSubscriptions Op = 0x0016 // Create-Printer-Subscriptions: Create one or more printer subscriptions OpCreateJobSubscriptions Op = 0x0017 // Create-Job-Subscriptions: Create one of more job subscriptions OpGetSubscriptionAttributes Op = 0x0018 // Get-Subscription-Attributes: Get subscription information OpGetSubscriptions Op = 0x0019 // Get-Subscriptions: Get list of subscriptions OpRenewSubscription Op = 0x001a // Renew-Subscription: Renew a printer subscription OpCancelSubscription Op = 0x001b // Cancel-Subscription: Cancel a subscription OpGetNotifications Op = 0x001c // Get-Notifications: Get notification events OpSendNotifications Op = 0x001d // Send-Notifications: Send notification events OpGetResourceAttributes Op = 0x001e // Get-Resource-Attributes: Get resource information OpGetResourceData Op = 0x001f // Get-Resource-Data: Get resource data OpGetResources Op = 0x0020 // Get-Resources: Get list of resources OpGetPrintSupportFiles Op = 0x0021 // Get-Printer-Support-Files: Get printer support files OpEnablePrinter Op = 0x0022 // Enable-Printer: Accept new jobs for a printer OpDisablePrinter Op = 0x0023 // Disable-Printer: Reject new jobs for a printer OpPausePrinterAfterCurrentJob Op = 0x0024 // Pause-Printer-After-Current-Job: Stop printer after the current job OpHoldNewJobs Op = 0x0025 // Hold-New-Jobs: Hold new jobs OpReleaseHeldNewJobs Op = 0x0026 // Release-Held-New-Jobs: Release new jobs that were previously held OpDeactivatePrinter Op = 0x0027 // Deactivate-Printer: Stop a printer and do not accept jobs OpActivatePrinter Op = 0x0028 // Activate-Printer: Start a printer and accept jobs OpRestartPrinter Op = 0x0029 // Restart-Printer: Restart a printer OpShutdownPrinter Op = 0x002a // Shutdown-Printer: Turn a printer off OpStartupPrinter Op = 0x002b // Startup-Printer: Turn a printer on OpReprocessJob Op = 0x002c // Reprocess-Job: Reprint a job OpCancelCurrentJob Op = 0x002d // Cancel-Current-Job: Cancel the current job OpSuspendCurrentJob Op = 0x002e // Suspend-Current-Job: Suspend the current job OpResumeJob Op = 0x002f // Resume-Job: Resume the current job OpPromoteJob Op = 0x0030 // Promote-Job: Promote a job to print sooner OpScheduleJobAfter Op = 0x0031 // Schedule-Job-After: Schedule a job to print after another OpCancelDocument Op = 0x0033 // Cancel-Document: Cancel a document OpGetDocumentAttributes Op = 0x0034 // Get-Document-Attributes: Get document information OpGetDocuments Op = 0x0035 // Get-Documents: Get a list of documents in a job OpDeleteDocument Op = 0x0036 // Delete-Document: Delete a document OpSetDocumentAttributes Op = 0x0037 // Set-Document-Attributes: Set document values OpCancelJobs Op = 0x0038 // Cancel-Jobs: Cancel all jobs (administrative) OpCancelMyJobs Op = 0x0039 // Cancel-My-Jobs: Cancel a user's jobs OpResubmitJob Op = 0x003a // Resubmit-Job: Copy and reprint a job OpCloseJob Op = 0x003b // Close-Job: Close a job and start printing OpIdentifyPrinter Op = 0x003c // Identify-Printer: Make the printer beep, flash, or display a message for identification OpValidateDocument Op = 0x003d // Validate-Document: Validate document values prior to submission OpAddDocumentImages Op = 0x003e // Add-Document-Images: Add image(s) from the specified scanner source OpAcknowledgeDocument Op = 0x003f // Acknowledge-Document: Acknowledge processing of a document OpAcknowledgeIdentifyPrinter Op = 0x0040 // Acknowledge-Identify-Printer: Acknowledge action on an Identify-Printer request OpAcknowledgeJob Op = 0x0041 // Acknowledge-Job: Acknowledge processing of a job OpFetchDocument Op = 0x0042 // Fetch-Document: Fetch a document for processing OpFetchJob Op = 0x0043 // Fetch-Job: Fetch a job for processing OpGetOutputDeviceAttributes Op = 0x0044 // Get-Output-Device-Attributes: Get printer information for a specific output device OpUpdateActiveJobs Op = 0x0045 // Update-Active-Jobs: Update the list of active jobs that a proxy has processed OpDeregisterOutputDevice Op = 0x0046 // Deregister-Output-Device: Remove an output device OpUpdateDocumentStatus Op = 0x0047 // Update-Document-Status: Update document values OpUpdateJobStatus Op = 0x0048 // Update-Job-Status: Update job values OpupdateOutputDeviceAttributes Op = 0x0049 // Update-Output-Device-Attributes: Update output device values OpGetNextDocumentData Op = 0x004a // Get-Next-Document-Data: Scan more document data OpAllocatePrinterResources Op = 0x004b // Allocate-Printer-Resources: Use resources for a printer OpCreatePrinter Op = 0x004c // Create-Printer: Create a new service OpDeallocatePrinterResources Op = 0x004d // Deallocate-Printer-Resources: Stop using resources for a printer OpDeletePrinter Op = 0x004e // Delete-Printer: Delete an existing service OpGetPrinters Op = 0x004f // Get-Printers: Get a list of services OpShutdownOnePrinter Op = 0x0050 // Shutdown-One-Printer: Shutdown a service OpStartupOnePrinter Op = 0x0051 // Startup-One-Printer: Start a service OpCancelResource Op = 0x0052 // Cancel-Resource: Uninstall a resource OpCreateResource Op = 0x0053 // Create-Resource: Create a new (empty) resource OpInstallResource Op = 0x0054 // Install-Resource: Install a resource OpSendResourceData Op = 0x0055 // Send-Resource-Data: Upload the data for a resource OpSetResourceAttributes Op = 0x0056 // Set-Resource-Attributes: Set resource object attributes OpCreateResourceSubscriptions Op = 0x0057 // Create-Resource-Subscriptions: Create event subscriptions for a resource OpCreateSystemSubscriptions Op = 0x0058 // Create-System-Subscriptions: Create event subscriptions for a system OpDisableAllPrinters Op = 0x0059 // Disable-All-Printers: Stop accepting new jobs on all services OpEnableAllPrinters Op = 0x005a // Enable-All-Printers: Start accepting new jobs on all services OpGetSystemAttributes Op = 0x005b // Get-System-Attributes: Get system object attributes OpGetSystemSupportedValues Op = 0x005c // Get-System-Supported-Values: Get supported values for system object attributes OpPauseAllPrinters Op = 0x005d // Pause-All-Printers: Stop all services immediately OpPauseAllPrintersAfterCurrentJob Op = 0x005e // Pause-All-Printers-After-Current-Job: Stop all services after processing the current jobs OpRegisterOutputDevice Op = 0x005f // Register-Output-Device: Register a remote service OpRestartSystem Op = 0x0060 // Restart-System: Restart all services OpResumeAllPrinters Op = 0x0061 // Resume-All-Printers: Start job processing on all services OpSetSystemAttributes Op = 0x0062 // Set-System-Attributes: Set system object attributes OpShutdownAllPrinters Op = 0x0063 // Shutdown-All-Printers: Shutdown all services OpStartupAllPrinters Op = 0x0064 // Startup-All-Printers: Startup all services OpCupsGetDefault Op = 0x4001 // CUPS-Get-Default: Get the default printer OpCupsGetPrinters Op = 0x4002 // CUPS-Get-Printers: Get a list of printers and/or classes OpCupsAddModifyPrinter Op = 0x4003 // CUPS-Add-Modify-Printer: Add or modify a printer OpCupsDeletePrinter Op = 0x4004 // CUPS-Delete-Printer: Delete a printer OpCupsGetClasses Op = 0x4005 // CUPS-Get-Classes: Get a list of classes OpCupsAddModifyClass Op = 0x4006 // CUPS-Add-Modify-Class: Add or modify a class OpCupsDeleteClass Op = 0x4007 // CUPS-Delete-Class: Delete a class OpCupsAcceptJobs Op = 0x4008 // CUPS-Accept-Jobs: Accept new jobs on a printer OpCupsRejectJobs Op = 0x4009 // CUPS-Reject-Jobs: Reject new jobs on a printer OpCupsSetDefault Op = 0x400a // CUPS-Set-Default: Set the default printer OpCupsGetDevices Op = 0x400b // CUPS-Get-Devices: Get a list of supported devices OpCupsGetPpds Op = 0x400c // CUPS-Get-PPDs: Get a list of supported drivers OpCupsMoveJob Op = 0x400d // CUPS-Move-Job: Move a job to a different printer OpCupsAuthenticateJob Op = 0x400e // CUPS-Authenticate-Job: Authenticate a job OpCupsGetPpd Op = 0x400f // CUPS-Get-PPD: Get a PPD file OpCupsGetDocument Op = 0x4027 // CUPS-Get-Document: Get a document file OpCupsCreateLocalPrinter Op = 0x4028 // CUPS-Create-Local-Printer: Create a local (temporary) printer ) // String() returns a Status name, as defined by RFC 8010 func (op Op) String() string { switch op { case OpPrintJob: return "Print-Job" case OpPrintURI: return "Print-URI" case OpValidateJob: return "Validate-Job" case OpCreateJob: return "Create-Job" case OpSendDocument: return "Send-Document" case OpSendURI: return "Send-URI" case OpCancelJob: return "Cancel-Job" case OpGetJobAttributes: return "Get-Job-Attribute" case OpGetJobs: return "Get-Jobs" case OpGetPrinterAttributes: return "Get-Printer-Attributes" case OpHoldJob: return "Hold-Job" case OpReleaseJob: return "Release-Job" case OpRestartJob: return "Restart-Job" case OpPausePrinter: return "Pause-Printer" case OpResumePrinter: return "Resume-Printer" case OpPurgeJobs: return "Purge-Jobs" case OpSetPrinterAttributes: return "Set-Printer-Attributes" case OpSetJobAttributes: return "Set-Job-Attributes" case OpGetPrinterSupportedValues: return "Get-Printer-Supported-Values" case OpCreatePrinterSubscriptions: return "Create-Printer-Subscriptions" case OpCreateJobSubscriptions: return "Create-Job-Subscriptions" case OpGetSubscriptionAttributes: return "Get-Subscription-Attributes" case OpGetSubscriptions: return "Get-Subscriptions" case OpRenewSubscription: return "Renew-Subscription" case OpCancelSubscription: return "Cancel-Subscription" case OpGetNotifications: return "Get-Notifications" case OpSendNotifications: return "Send-Notifications" case OpGetResourceAttributes: return "Get-Resource-Attributes" case OpGetResourceData: return "Get-Resource-Data" case OpGetResources: return "Get-Resources" case OpGetPrintSupportFiles: return "Get-Printer-Support-Files" case OpEnablePrinter: return "Enable-Printer" case OpDisablePrinter: return "Disable-Printer" case OpPausePrinterAfterCurrentJob: return "Pause-Printer-After-Current-Job" case OpHoldNewJobs: return "Hold-New-Jobs" case OpReleaseHeldNewJobs: return "Release-Held-New-Jobs" case OpDeactivatePrinter: return "Deactivate-Printer" case OpActivatePrinter: return "Activate-Printer" case OpRestartPrinter: return "Restart-Printer" case OpShutdownPrinter: return "Shutdown-Printer" case OpStartupPrinter: return "Startup-Printer" case OpReprocessJob: return "Reprocess-Job" case OpCancelCurrentJob: return "Cancel-Current-Job" case OpSuspendCurrentJob: return "Suspend-Current-Job" case OpResumeJob: return "Resume-Job" case OpPromoteJob: return "Promote-Job" case OpScheduleJobAfter: return "Schedule-Job-After" case OpCancelDocument: return "Cancel-Document" case OpGetDocumentAttributes: return "Get-Document-Attributes" case OpGetDocuments: return "Get-Documents" case OpDeleteDocument: return "Delete-Document" case OpSetDocumentAttributes: return "Set-Document-Attributes" case OpCancelJobs: return "Cancel-Jobs" case OpCancelMyJobs: return "Cancel-My-Jobs" case OpResubmitJob: return "Resubmit-Job" case OpCloseJob: return "Close-Job" case OpIdentifyPrinter: return "Identify-Printer" case OpValidateDocument: return "Validate-Document" case OpAddDocumentImages: return "Add-Document-Images" case OpAcknowledgeDocument: return "Acknowledge-Document" case OpAcknowledgeIdentifyPrinter: return "Acknowledge-Identify-Printer" case OpAcknowledgeJob: return "Acknowledge-Job" case OpFetchDocument: return "Fetch-Document" case OpFetchJob: return "Fetch-Job" case OpGetOutputDeviceAttributes: return "Get-Output-Device-Attributes" case OpUpdateActiveJobs: return "Update-Active-Jobs" case OpDeregisterOutputDevice: return "Deregister-Output-Device" case OpUpdateDocumentStatus: return "Update-Document-Status" case OpUpdateJobStatus: return "Update-Job-Status" case OpupdateOutputDeviceAttributes: return "Update-Output-Device-Attributes" case OpGetNextDocumentData: return "Get-Next-Document-Data" case OpAllocatePrinterResources: return "Allocate-Printer-Resources" case OpCreatePrinter: return "Create-Printer" case OpDeallocatePrinterResources: return "Deallocate-Printer-Resources" case OpDeletePrinter: return "Delete-Printer" case OpGetPrinters: return "Get-Printers" case OpShutdownOnePrinter: return "Shutdown-One-Printer" case OpStartupOnePrinter: return "Startup-One-Printer" case OpCancelResource: return "Cancel-Resource" case OpCreateResource: return "Create-Resource" case OpInstallResource: return "Install-Resource" case OpSendResourceData: return "Send-Resource-Data" case OpSetResourceAttributes: return "Set-Resource-Attributes" case OpCreateResourceSubscriptions: return "Create-Resource-Subscriptions" case OpCreateSystemSubscriptions: return "Create-System-Subscriptions" case OpDisableAllPrinters: return "Disable-All-Printers" case OpEnableAllPrinters: return "Enable-All-Printers" case OpGetSystemAttributes: return "Get-System-Attributes" case OpGetSystemSupportedValues: return "Get-System-Supported-Values" case OpPauseAllPrinters: return "Pause-All-Printers" case OpPauseAllPrintersAfterCurrentJob: return "Pause-All-Printers-After-Current-Job" case OpRegisterOutputDevice: return "Register-Output-Device" case OpRestartSystem: return "Restart-System" case OpResumeAllPrinters: return "Resume-All-Printers" case OpSetSystemAttributes: return "Set-System-Attributes" case OpShutdownAllPrinters: return "Shutdown-All-Printers" case OpStartupAllPrinters: return "Startup-All-Printers" case OpCupsGetDefault: return "CUPS-Get-Default" case OpCupsGetPrinters: return "CUPS-Get-Printers" case OpCupsAddModifyPrinter: return "CUPS-Add-Modify-Printer" case OpCupsDeletePrinter: return "CUPS-Delete-Printer" case OpCupsGetClasses: return "CUPS-Get-Classes" case OpCupsAddModifyClass: return "CUPS-Add-Modify-Class" case OpCupsDeleteClass: return "CUPS-Delete-Class" case OpCupsAcceptJobs: return "CUPS-Accept-Jobs" case OpCupsRejectJobs: return "CUPS-Reject-Jobs" case OpCupsSetDefault: return "CUPS-Set-Default" case OpCupsGetDevices: return "CUPS-Get-Devices" case OpCupsGetPpds: return "CUPS-Get-PPDs" case OpCupsMoveJob: return "CUPS-Move-Job" case OpCupsAuthenticateJob: return "CUPS-Authenticate-Job" case OpCupsGetPpd: return "CUPS-Get-PPD" case OpCupsGetDocument: return "CUPS-Get-Document" case OpCupsCreateLocalPrinter: return "CUPS-Create-Local-Printer" } return fmt.Sprintf("0x%4.4x", int(op)) } goipp-1.0.0/status.go000066400000000000000000000232151366031307500145070ustar00rootroot00000000000000/* Go IPP - IPP core protocol implementation in pure Go * * Copyright (C) 2020 and up by Alexander Pevzner (pzz@apevzner.com) * See LICENSE for license terms and conditions * * IPP Status Codes */ package goipp import ( "fmt" ) // Status represents an IPP Status Code type Status Code const ( StatusOk Status = 0x0000 // successful-ok StatusOkIgnoredOrSubstituted Status = 0x0001 // successful-ok-ignored-or-substituted-attributes StatusOkConflicting Status = 0x0002 // successful-ok-conflicting-attributes StatusOkIgnoredSubscriptions Status = 0x0003 // successful-ok-ignored-subscriptions StatusOkIgnoredNotifications Status = 0x0004 // successful-ok-ignored-notifications StatusOkTooManyEvents Status = 0x0005 // successful-ok-too-many-events StatusOkButCancelSubscription Status = 0x0006 // successful-ok-but-cancel-subscription StatusOkEventsComplete Status = 0x0007 // successful-ok-events-complete StatusRedirectionOtherSite Status = 0x0200 // redirection-other-site StatusCupsSeeOther Status = 0x0280 // cups-see-other StatusErrorBadRequest Status = 0x0400 // client-error-bad-request StatusErrorForbidden Status = 0x0401 // client-error-forbidden StatusErrorNotAuthenticated Status = 0x0402 // client-error-not-authenticated StatusErrorNotAuthorized Status = 0x0403 // client-error-not-authorized StatusErrorNotPossible Status = 0x0404 // client-error-not-possible StatusErrorTimeout Status = 0x0405 // client-error-timeout StatusErrorNotFound Status = 0x0406 // client-error-not-found StatusErrorGone Status = 0x0407 // client-error-gone StatusErrorRequestEntity Status = 0x0408 // client-error-request-entity-too-large StatusErrorRequestValue Status = 0x0409 // client-error-request-value-too-long StatusErrorDocumentFormatNotSupported Status = 0x040a // client-error-document-format-not-supported StatusErrorAttributesOrValues Status = 0x040b // client-error-attributes-or-values-not-supported StatusErrorURIScheme Status = 0x040c // client-error-uri-scheme-not-supported StatusErrorCharset Status = 0x040d // client-error-charset-not-supported StatusErrorConflicting Status = 0x040e // client-error-conflicting-attributes StatusErrorCompressionNotSupported Status = 0x040f // client-error-compression-not-supported StatusErrorCompressionError Status = 0x0410 // client-error-compression-error StatusErrorDocumentFormatError Status = 0x0411 // client-error-document-format-error StatusErrorDocumentAccess Status = 0x0412 // client-error-document-access-error StatusErrorAttributesNotSettable Status = 0x0413 // client-error-attributes-not-settable StatusErrorIgnoredAllSubscriptions Status = 0x0414 // client-error-ignored-all-subscriptions StatusErrorTooManySubscriptions Status = 0x0415 // client-error-too-many-subscriptions StatusErrorIgnoredAllNotifications Status = 0x0416 // client-error-ignored-all-notifications StatusErrorPrintSupportFileNotFound Status = 0x0417 // client-error-print-support-file-not-found StatusErrorDocumentPassword Status = 0x0418 // client-error-document-password-error StatusErrorDocumentPermission Status = 0x0419 // client-error-document-permission-error StatusErrorDocumentSecurity Status = 0x041a // client-error-document-security-error StatusErrorDocumentUnprintable Status = 0x041b // client-error-document-unprintable-error StatusErrorAccountInfoNeeded Status = 0x041c // client-error-account-info-needed StatusErrorAccountClosed Status = 0x041d // client-error-account-closed StatusErrorAccountLimitReached Status = 0x041e // client-error-account-limit-reached StatusErrorAccountAuthorizationFailed Status = 0x041f // client-error-account-authorization-failed StatusErrorNotFetchable Status = 0x0420 // client-error-not-fetchable StatusErrorInternal Status = 0x0500 // server-error-internal-error StatusErrorOperationNotSupported Status = 0x0501 // server-error-operation-not-supported StatusErrorServiceUnavailable Status = 0x0502 // server-error-service-unavailable StatusErrorVersionNotSupported Status = 0x0503 // server-error-version-not-supported StatusErrorDevice Status = 0x0504 // server-error-device-error StatusErrorTemporary Status = 0x0505 // server-error-temporary-error StatusErrorNotAcceptingJobs Status = 0x0506 // server-error-not-accepting-jobs StatusErrorBusy Status = 0x0507 // server-error-busy StatusErrorJobCanceled Status = 0x0508 // server-error-job-canceled StatusErrorMultipleJobsNotSupported Status = 0x0509 // server-error-multiple-document-jobs-not-supported StatusErrorPrinterIsDeactivated Status = 0x050a // server-error-printer-is-deactivated StatusErrorTooManyJobs Status = 0x050b // server-error-too-many-jobs StatusErrorTooManyDocuments Status = 0x050c // server-error-too-many-documents ) // String() returns a Status name, as defined by RFC 8010 func (s Status) String() string { switch s { case StatusOk: return "successful-ok" case StatusOkIgnoredOrSubstituted: return "successful-ok-ignored-or-substituted-attributes" case StatusOkConflicting: return "successful-ok-conflicting-attributes" case StatusOkIgnoredSubscriptions: return "successful-ok-ignored-subscriptions" case StatusOkIgnoredNotifications: return "successful-ok-ignored-notifications" case StatusOkTooManyEvents: return "successful-ok-too-many-events" case StatusOkButCancelSubscription: return "successful-ok-but-cancel-subscription" case StatusOkEventsComplete: return "successful-ok-events-complete" case StatusRedirectionOtherSite: return "redirection-other-site" case StatusCupsSeeOther: return "cups-see-other" case StatusErrorBadRequest: return "client-error-bad-request" case StatusErrorForbidden: return "client-error-forbidden" case StatusErrorNotAuthenticated: return "client-error-not-authenticated" case StatusErrorNotAuthorized: return "client-error-not-authorized" case StatusErrorNotPossible: return "client-error-not-possible" case StatusErrorTimeout: return "client-error-timeout" case StatusErrorNotFound: return "client-error-not-found" case StatusErrorGone: return "client-error-gone" case StatusErrorRequestEntity: return "client-error-request-entity-too-large" case StatusErrorRequestValue: return "client-error-request-value-too-long" case StatusErrorDocumentFormatNotSupported: return "client-error-document-format-not-supported" case StatusErrorAttributesOrValues: return "client-error-attributes-or-values-not-supported" case StatusErrorURIScheme: return "client-error-uri-scheme-not-supported" case StatusErrorCharset: return "client-error-charset-not-supported" case StatusErrorConflicting: return "client-error-conflicting-attributes" case StatusErrorCompressionNotSupported: return "client-error-compression-not-supported" case StatusErrorCompressionError: return "client-error-compression-error" case StatusErrorDocumentFormatError: return "client-error-document-format-error" case StatusErrorDocumentAccess: return "client-error-document-access-error" case StatusErrorAttributesNotSettable: return "client-error-attributes-not-settable" case StatusErrorIgnoredAllSubscriptions: return "client-error-ignored-all-subscriptions" case StatusErrorTooManySubscriptions: return "client-error-too-many-subscriptions" case StatusErrorIgnoredAllNotifications: return "client-error-ignored-all-notifications" case StatusErrorPrintSupportFileNotFound: return "client-error-print-support-file-not-found" case StatusErrorDocumentPassword: return "client-error-document-password-error" case StatusErrorDocumentPermission: return "client-error-document-permission-error" case StatusErrorDocumentSecurity: return "client-error-document-security-error" case StatusErrorDocumentUnprintable: return "client-error-document-unprintable-error" case StatusErrorAccountInfoNeeded: return "client-error-account-info-needed" case StatusErrorAccountClosed: return "client-error-account-closed" case StatusErrorAccountLimitReached: return "client-error-account-limit-reached" case StatusErrorAccountAuthorizationFailed: return "client-error-account-authorization-failed" case StatusErrorNotFetchable: return "client-error-not-fetchable" case StatusErrorInternal: return "server-error-internal-error" case StatusErrorOperationNotSupported: return "server-error-operation-not-supported" case StatusErrorServiceUnavailable: return "server-error-service-unavailable" case StatusErrorVersionNotSupported: return "server-error-version-not-supported" case StatusErrorDevice: return "server-error-device-error" case StatusErrorTemporary: return "server-error-temporary-error" case StatusErrorNotAcceptingJobs: return "server-error-not-accepting-jobs" case StatusErrorBusy: return "server-error-busy" case StatusErrorJobCanceled: return "server-error-job-canceled" case StatusErrorMultipleJobsNotSupported: return "server-error-multiple-document-jobs-not-supported" case StatusErrorPrinterIsDeactivated: return "server-error-printer-is-deactivated" case StatusErrorTooManyJobs: return "server-error-too-many-jobs" case StatusErrorTooManyDocuments: return "server-error-too-many-documents" } return fmt.Sprintf("0x%4.4x", int(s)) } goipp-1.0.0/tag.go000066400000000000000000000132031366031307500137330ustar00rootroot00000000000000/* Go IPP - IPP core protocol implementation in pure Go * * Copyright (C) 2020 and up by Alexander Pevzner (pzz@apevzner.com) * See LICENSE for license terms and conditions * * IPP Tags */ package goipp import ( "fmt" ) // Tag represents a tag used in a binary representation // of the IPP message type Tag int const ( // Delimiter tags TagZero Tag = 0x00 // Zero tag - used for separators TagOperationGroup Tag = 0x01 // Operation group TagJobGroup Tag = 0x02 // Job group TagEnd Tag = 0x03 // End-of-attributes TagPrinterGroup Tag = 0x04 // Printer group TagUnsupportedGroup Tag = 0x05 // Unsupported attributes group TagSubscriptionGroup Tag = 0x06 // Subscription group TagEventNotificationGroup Tag = 0x07 // Event group TagResourceGroup Tag = 0x08 // Resource group TagDocumentGroup Tag = 0x09 // Document group TagSystemGroup Tag = 0x0a // System group TagFuture11Group Tag = 0x0b // Future group 11 TagFuture12Group Tag = 0x0c // Future group 11 TagFuture13Group Tag = 0x0d // Future group 11 TagFuture14Group Tag = 0x0e // Future group 11 TagFuture15Group Tag = 0x0f // Future group 11 // Value tags TagUnsupportedValue Tag = 0x10 // Unsupported value TagDefault Tag = 0x11 // Default value TagUnknown Tag = 0x12 // Unknown value TagNoValue Tag = 0x13 // No-value value TagNotSettable Tag = 0x15 // Not-settable value TagDeleteAttr Tag = 0x16 // Delete-attribute value TagAdminDefine Tag = 0x17 // Admin-defined value TagInteger Tag = 0x21 // Integer value TagBoolean Tag = 0x22 // Boolean value TagEnum Tag = 0x23 // Enumeration value TagString Tag = 0x30 // Octet string value TagDateTime Tag = 0x31 // Date/time value TagResolution Tag = 0x32 // Resolution value TagRange Tag = 0x33 // Range value TagBeginCollection Tag = 0x34 // Beginning of collection value TagTextLang Tag = 0x35 // Text-with-language value TagNameLang Tag = 0x36 // Name-with-language value TagEndCollection Tag = 0x37 // End of collection value TagText Tag = 0x41 // Text value TagName Tag = 0x42 // Name value TagReservedString Tag = 0x43 // Reserved for future string value TagKeyword Tag = 0x44 // Keyword value TagURI Tag = 0x45 // URI value TagURIScheme Tag = 0x46 // URI scheme value TagCharset Tag = 0x47 // Character set value TagLanguage Tag = 0x48 // Language value TagMimeType Tag = 0x49 // MIME media type value TagMemberName Tag = 0x4a // Collection member name value TagExtension Tag = 0x7f // Extension point for 32-bit tags ) // IsDelimiter returns true for delimiter tags func (tag Tag) IsDelimiter() bool { return tag < 0x10 } // Type returns Type of Value that corresponds to the tag func (tag Tag) Type() Type { if tag.IsDelimiter() { return TypeInvalid } switch tag { case TagInteger, TagEnum: return TypeInteger case TagBoolean: return TypeBoolean case TagUnsupportedValue, TagDefault, TagUnknown, TagNotSettable, TagDeleteAttr, TagAdminDefine: // These tags not expected to have value return TypeVoid case TagText, TagName, TagReservedString, TagKeyword, TagURI, TagURIScheme, TagCharset, TagLanguage, TagMimeType, TagMemberName: return TypeString case TagDateTime: return TypeDateTime case TagResolution: return TypeResolution case TagRange: return TypeRange case TagTextLang, TagNameLang: return TypeTextWithLang case TagBeginCollection: return TypeCollection case TagEndCollection: return TypeVoid default: return TypeBinary } } // String() returns a tag name, as defined by RFC 8010 func (tag Tag) String() string { switch tag { case TagZero: return "zero" case TagOperationGroup: return "operation-attributes-tag" case TagJobGroup: return "job-attributes-tag" case TagEnd: return "end-of-attributes-tag" case TagPrinterGroup: return "printer-attributes-tag" case TagUnsupportedGroup: return "unsupported-attributes-tag" case TagSubscriptionGroup: return "subscription-attributes-tag" case TagEventNotificationGroup: return "event-notification-attributes-tag" case TagResourceGroup: return "resource-attributes-tag" case TagDocumentGroup: return "document-attributes-tag" case TagSystemGroup: return "system-attributes-tag" // Value tags case TagUnsupportedValue: return "unsupported" case TagDefault: return "default" case TagUnknown: return "unknown" case TagNoValue: return "no-value" case TagNotSettable: return "not-settable" case TagDeleteAttr: return "delete-attribute" case TagAdminDefine: return "admin-define" case TagInteger: return "integer" case TagBoolean: return "boolean" case TagEnum: return "enum" case TagString: return "octetString" case TagDateTime: return "dateTime" case TagResolution: return "resolution" case TagRange: return "rangeOfInteger" case TagBeginCollection: return "collection" case TagTextLang: return "textWithLanguage" case TagNameLang: return "nameWithLanguage" case TagEndCollection: return "endCollection" case TagText: return "textWithoutLanguage" case TagName: return "nameWithoutLanguage" case TagKeyword: return "keyword" case TagURI: return "uri" case TagURIScheme: return "uriScheme" case TagCharset: return "charset" case TagLanguage: return "naturalLanguage" case TagMimeType: return "mimeMediaType" case TagMemberName: return "memberAttrName" } return fmt.Sprintf("0x%2.2x", int(tag)) } goipp-1.0.0/type.go000066400000000000000000000020511366031307500141400ustar00rootroot00000000000000/* Go IPP - IPP core protocol implementation in pure Go * * Copyright (C) 2020 and up by Alexander Pevzner (pzz@apevzner.com) * See LICENSE for license terms and conditions * * Enumeration of value types */ package goipp import ( "fmt" ) // Type enumerates all possible value types type Type int const ( TypeInvalid Type = -1 TypeVoid Type = iota TypeInteger TypeBoolean TypeString TypeDateTime TypeResolution TypeRange TypeTextWithLang TypeBinary TypeCollection ) // String converts Type to string, for debugging func (t Type) String() string { switch t { case TypeInvalid: return "Invalid" case TypeVoid: return "Void" case TypeInteger: return "Integer" case TypeBoolean: return "Boolean" case TypeString: return "String" case TypeDateTime: return "DateTime" case TypeResolution: return "Resolution" case TypeRange: return "Range" case TypeTextWithLang: return "TextWithLang" case TypeBinary: return "Binary" case TypeCollection: return "Collection" } return fmt.Sprintf("Unknown type %d", int(t)) } goipp-1.0.0/value.go000066400000000000000000000311631366031307500143010ustar00rootroot00000000000000/* Go IPP - IPP core protocol implementation in pure Go * * Copyright (C) 2020 and up by Alexander Pevzner (pzz@apevzner.com) * See LICENSE for license terms and conditions * * Values for message attributes */ package goipp import ( "bytes" "encoding/binary" "errors" "fmt" "math" "time" ) // Values represents a slice of Attribute values with tags type Values []struct { T Tag // The tag V Value // The value } // Add value to Values func (values *Values) Add(t Tag, v Value) { *values = append(*values, struct { T Tag V Value }{t, v}) } // String() converts Values to string func (values Values) String() string { if len(values) == 1 { return values[0].V.String() } var buf bytes.Buffer buf.Write([]byte("[")) for i, v := range values { if i != 0 { buf.Write([]byte(",")) } buf.Write([]byte(v.V.String())) } buf.Write([]byte("]")) return buf.String() } // Equal checks that two Values are equal func (values Values) Equal(values2 Values) bool { if len(values) != len(values2) { return false } for i, v := range values { v2 := values2[i] if v.T != v2.T || !ValueEqual(v.V, v2.V) { return false } } return true } // Value represents an attribute value type Value interface { String() string Type() Type encode() ([]byte, error) decode([]byte) (Value, error) } // ValueEqual checks if two values are equal func ValueEqual(v1, v2 Value) bool { if v1.Type() != v2.Type() { return false } switch v1.Type() { case TypeDateTime: return v1.(Time).Equal(v2.(Time).Time) case TypeBinary: return bytes.Equal(v1.(Binary), v2.(Binary)) case TypeCollection: c1 := Attributes(v1.(Collection)) c2 := Attributes(v2.(Collection)) return c1.Equal(c2) } return v1 == v2 } // Void represents "no value" // // Use with: TagUnsupportedValue, TagDefault, TagUnknown, // TagNotSettable, TagDeleteAttr, TagAdminDefine type Void struct{} // String() converts Void Value to string func (Void) String() string { return "" } // Type returns type of Value func (Void) Type() Type { return TypeVoid } // Encode Void Value into wire format func (v Void) encode() ([]byte, error) { return []byte{}, nil } // Decode Void Value from wire format func (Void) decode([]byte) (Value, error) { return Void{}, nil } // Integer represents an Integer Value // // Use with: TagInteger, TagEnum type Integer int32 // String() converts Integer value to string func (v Integer) String() string { return fmt.Sprintf("%d", int32(v)) } // Type returns type of Value func (Integer) Type() Type { return TypeInteger } // Encode Integer Value into wire format func (v Integer) encode() ([]byte, error) { return []byte{byte(v >> 24), byte(v >> 16), byte(v >> 8), byte(v)}, nil } // Decode Integer Value from wire format func (Integer) decode(data []byte) (Value, error) { if len(data) != 4 { return nil, errors.New("value must be 4 bytes") } return Integer(binary.BigEndian.Uint32(data)), nil } // Boolean represents a boolean Value // // Use with: TagBoolean type Boolean bool // String() converts Boolean value to string func (v Boolean) String() string { return fmt.Sprintf("%t", bool(v)) } // Type returns type of Value func (Boolean) Type() Type { return TypeBoolean } // Encode Boolean Value into wire format func (v Boolean) encode() ([]byte, error) { if v { return []byte{1}, nil } return []byte{0}, nil } // Decode Boolean Value from wire format func (Boolean) decode(data []byte) (Value, error) { if len(data) != 1 { return nil, errors.New("value must be 1 byte") } return Boolean(data[0] != 0), nil } // String represents a string Value // // Use with: TagText, TagName, TagReservedString, TagKeyword, TagURI, // TagURIScheme, TagCharset, TagLanguage, TagMimeType, TagMemberName type String string // String() converts String value to string func (v String) String() string { return string(v) } // Type returns type of Value func (String) Type() Type { return TypeString } // Encode String Value into wire format func (v String) encode() ([]byte, error) { return []byte(v), nil } // Decode String Value from wire format func (String) decode(data []byte) (Value, error) { return String(data), nil } // Time represents a DateTime Value // // Use with: TagTime type Time struct{ time.Time } // String() converts Time value to string func (v Time) String() string { return v.Time.Format(time.RFC3339) } // Type returns type of Value func (Time) Type() Type { return TypeDateTime } // Encode Time Value into wire format func (v Time) encode() ([]byte, error) { // From RFC2579: // // field octets contents range // ----- ------ -------- ----- // 1 1-2 year* 0..65536 // 2 3 month 1..12 // 3 4 day 1..31 // 4 5 hour 0..23 // 5 6 minutes 0..59 // 6 7 seconds 0..60 // (use 60 for leap-second) // 7 8 deci-seconds 0..9 // 8 9 direction from UTC '+' / '-' // 9 10 hours from UTC* 0..13 // 10 11 minutes from UTC 0..59 // // * Notes: // - the value of year is in network-byte order // - daylight saving time in New Zealand is +13 year := v.Year() _, zone := v.Zone() dir := byte('+') if zone < 0 { zone = -zone dir = '-' } return []byte{ byte(year >> 8), byte(year), byte(v.Month()), byte(v.Day()), byte(v.Hour()), byte(v.Minute()), byte(v.Second()), byte(v.Nanosecond() / 100000000), dir, byte(zone / 3600), byte((zone / 60) % 60), }, nil } // Decode Time Value from wire format func (Time) decode(data []byte) (Value, error) { // Check size if len(data) != 9 && len(data) != 11 { return nil, errors.New("value must be 9 or 11 bytes") } // Decode time zone var l *time.Location switch { case len(data) == 9: l = time.UTC case data[8] == '+', data[8] == '-': name := fmt.Sprintf("UTC%c%d", data[8], data[9]) if data[10] != 0 { name += fmt.Sprintf(":%d", data[10]) } off := 3600*int(data[9]) + 60*int(data[10]) if data[8] == '-' { off = -off } l = time.FixedZone(name, off) default: return nil, errors.New("invalid data format") } // Decode time t := time.Date( int(binary.BigEndian.Uint16(data[0:2])), // year time.Month(data[2]), // month int(data[3]), // day int(data[4]), // hour int(data[5]), // min int(data[6]), // sec int(data[7])*100000000, // nsec l, // time zone ) return Time{t}, nil } // Resolution represents a resolution Value // // Use with: TagResolution type Resolution struct { Xres, Yres int // X/Y resolutions Units Units // Resolution units } // String() converts Resolution value to string func (v Resolution) String() string { return fmt.Sprintf("%dx%d%s", v.Xres, v.Yres, v.Units) } // Type returns type of Value func (Resolution) Type() Type { return TypeResolution } // Encode Resolution Value into wire format func (v Resolution) encode() ([]byte, error) { // Wire format // 4 bytes: Xres // 4 bytes: Yres // 1 byte: Units x, y := v.Xres, v.Yres return []byte{ byte(x >> 24), byte(x >> 16), byte(x >> 8), byte(x), byte(y >> 24), byte(y >> 16), byte(y >> 8), byte(y), byte(v.Units), }, nil } // Decode Resolution Value from wire format func (Resolution) decode(data []byte) (Value, error) { if len(data) != 9 { return nil, errors.New("value must be 9 bytes") } return Resolution{ Xres: int(binary.BigEndian.Uint32(data[0:4])), Yres: int(binary.BigEndian.Uint32(data[4:8])), Units: Units(data[8]), }, nil } // Units represents resolution units type Units uint8 const ( UnitsDpi Units = 3 // Dots per inch UnitsDpcm Units = 4 // Dots per cm ) // String() converts Units to string func (u Units) String() string { switch u { case UnitsDpi: return "dpi" case UnitsDpcm: return "dpcm" default: return fmt.Sprintf("0x%2.2x", uint8(u)) } } // Range represents a range of integers Value // // Use with: TagRange type Range struct { Lower, Upper int // Lower/upper bounds } // String() converts Range value to string func (v Range) String() string { return fmt.Sprintf("%d-%d", v.Lower, v.Upper) } // Type returns type of Value func (Range) Type() Type { return TypeRange } // Encode Range Value into wire format func (v Range) encode() ([]byte, error) { // Wire format // 4 bytes: Lower // 4 bytes: Upper l, u := v.Lower, v.Upper return []byte{ byte(l >> 24), byte(l >> 16), byte(l >> 8), byte(l), byte(u >> 24), byte(u >> 16), byte(u >> 8), byte(u), }, nil } // Decode Range Value from wire format func (Range) decode(data []byte) (Value, error) { if len(data) != 8 { return nil, errors.New("value must be 9 bytes") } return Range{ Lower: int(binary.BigEndian.Uint32(data[0:4])), Upper: int(binary.BigEndian.Uint32(data[4:8])), }, nil } // TextWithLang represents a combination of two strings: // one is a name of natural language and second is a text // on this language // // Use with: TagTextLang, TagNameLang type TextWithLang struct { Lang, Text string // Language and text } // String() converts TextWithLang value to string func (v TextWithLang) String() string { return v.Text + " [" + v.Lang + "]" } // Type returns type of Value func (TextWithLang) Type() Type { return TypeTextWithLang } // Encode TextWithLang Value into wire format func (v TextWithLang) encode() ([]byte, error) { // Wire format // 2 bytes: len(Lang) // variable: Lang // 2 bytes: len(Text) // variable: Text lang := []byte(v.Lang) text := []byte(v.Text) if len(lang) > math.MaxUint16 { return nil, fmt.Errorf("Lang exceeds %d bytes", math.MaxUint16) } if len(text) > math.MaxUint16 { return nil, fmt.Errorf("Text exceeds %d bytes", math.MaxUint16) } data := make([]byte, 2+2+len(lang)+len(text)) binary.BigEndian.PutUint16(data, uint16(len(lang))) copy(data[2:], []byte(lang)) data2 := data[2+len(lang):] binary.BigEndian.PutUint16(data2, uint16(len(text))) copy(data2[2:], []byte(text)) return data, nil } // Decode TextWithLang Value from wire format func (TextWithLang) decode(data []byte) (Value, error) { var langLen, textLen int var lang, text string // Unpack language length if len(data) < 2 { goto ERROR } langLen = int(binary.BigEndian.Uint16(data[0:2])) data = data[2:] // Unpack language value if len(data) < langLen { goto ERROR } lang = string(data[:langLen]) data = data[langLen:] // Unpack text length if len(data) < 2 { goto ERROR } textLen = int(binary.BigEndian.Uint16(data[0:2])) data = data[2:] // Unpack text value if len(data) < textLen { goto ERROR } text = string(data[:textLen]) data = data[textLen:] // We must have consumed all bytes at this point if len(data) != 0 { goto ERROR } // Return a value return TextWithLang{Lang: lang, Text: text}, nil ERROR: return nil, errors.New("invalid data format") } // Binary represents a raw binary Value type Binary []byte // String() converts Range value to string func (v Binary) String() string { return fmt.Sprintf("%x", []byte(v)) } // Type returns type of Value func (Binary) Type() Type { return TypeBinary } // Encode TextWithLang Value into wire format func (v Binary) encode() ([]byte, error) { return []byte(v), nil } // Decode Binary Value from wire format func (Binary) decode(data []byte) (Value, error) { return Binary(data), nil } // Collection represents a collection of attributes // // Use with: TagBeginCollection type Collection Attributes // Add Attribute to Attributes func (collection *Collection) Add(attr Attribute) { *collection = append(*collection, attr) } // Equal checks that two collections are equal func (c1 Collection) Equal(c2 Attributes) bool { return Attributes(c1).Equal(Attributes(c2)) } // String() converts Collection to string func (v Collection) String() string { var buf bytes.Buffer buf.Write([]byte("{")) for i, attr := range v { if i > 0 { buf.Write([]byte(" ")) } fmt.Fprintf(&buf, "%s=%s", attr.Name, attr.Values) } buf.Write([]byte("}")) return buf.String() } // Type returns type of Value func (Collection) Type() Type { return TypeCollection } // Encode Collection Value into wire format func (v Collection) encode() ([]byte, error) { // Note, TagBeginCollection attribute contains // no data, collection itself handled the different way return []byte{}, nil } // Decode Collection Value from wire format func (Collection) decode(data []byte) (Value, error) { panic("internal error") }