├── .gitignore ├── History.md ├── Readme.md ├── go.mod ├── go.sum ├── main.go ├── template.yml └── template_yml.go /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | test.js 3 | .envrc 4 | lambda.zip 5 | .terraform/ 6 | terraform.tfstate 7 | terraform.tfstate.backup 8 | Makefile 9 | -------------------------------------------------------------------------------- /History.md: -------------------------------------------------------------------------------- 1 | 2 | v1.0.1 / 2020-08-14 3 | =================== 4 | 5 | * fix AWS region for fetching the log groups 6 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | 2 | # CloudWatch → Apex Logs 3 | 4 | The `logs-cloudwatch` command-line tool provides an easy way to send AWS CloudWatch Logs to [Apex Logs](https://apex.sh/logs/). 5 | 6 | ## Installation 7 | 8 | ``` 9 | $ curl -sf https://gobinaries.com/apex/logs-cloudwatch | sh 10 | ``` 11 | 12 | ## Usage 13 | 14 | Command usage: 15 | 16 | ``` 17 | logs-cloudwatch 18 | 19 | Flags: 20 | --version Displays the program version string. 21 | -h --help Displays help with available flag, subcommand, and positional value parameters. 22 | --project-id Apex Logs destination project ID 23 | --auth-token Apex Logs authentication token 24 | --endpoint Apex Logs integration endpoint URL 25 | --region AWS region id 26 | --stack-name AWS CloudFormation stack name (default: ApexLogs) 27 | --exclude AWS CloudWatch log group filters 28 | --include AWS CloudWatch log group filters 29 | --confirm Confirm creation of the stack (default: false) 30 | --template Output the template and exit 31 | 32 | ``` 33 | 34 | ## Example 35 | 36 | Provide your Apex Logs destination project ID, API endpoint (with `/integrations/cloudwatch` as the path), and API token to provide AWS write-access to your logs. For help creating an API token visit the [Apex Logs documentation](https://apex.sh/docs/logs/api/#authentication). 37 | 38 | ``` 39 | logs-cloudwatch \ 40 | --project-id \ 41 | --endpoint https:///integrations/cloudwatch \ 42 | --auth-token \ 43 | --include /aws/lambda/ \ 44 | --region us-west-2 45 | ``` 46 | 47 | Omitting the `--confirm` flag will output a preview of the matching log groups: 48 | 49 | ``` 50 | ==> Finding log groups 51 | ==> Found 4 matching log groups: 52 | 53 | /aws/lambda/logs-api 54 | /aws/lambda/news-api 55 | /aws/lambda/primary-api 56 | /aws/lambda/up-api 57 | 58 | ==> Run command again with --confirm to create the stack 59 | ``` 60 | 61 | Tweak your `--include` and `--exclude` filters as necessary to get the log groups you want, then add the `--confirm` flag to generate the stack. 62 | 63 | ## Filtering 64 | 65 | Running `logs-cloudwatch` without `--include` or `--exclude` flags will subscribe to all log groups. The filter patterns are simply sub-string matches, for example `get_` would match `/aws/lambda/get_team_members`, and `API` would match `API-Gateway-Execution-Logs_g2sdfdwn5rkc6/production`. 66 | 67 | ### Examples 68 | 69 | Send all logs: 70 | 71 | ```sh 72 | $ logs-cloudwatch 73 | ``` 74 | 75 | Include only AWS Lambda logs, matching groups such as `/aws/lambda/get_team_members`: 76 | 77 | ```sh 78 | $ logs-cloudwatch --include /aws/lambda/ 79 | ``` 80 | 81 | Include only AWS Lambda logs, matching groups such as `/aws/lambda/get_team_members`, but excluding a few. 82 | 83 | ```sh 84 | $ logs-cloudwatch --include /aws/lambda/ --exclude /aws/lambda/api,/aws/lambda/app 85 | ``` 86 | 87 | Exclude RDS and API Gateway logs: 88 | 89 | ```sh 90 | $ logs-cloudwatch --exclude API-Gateway,RDS 91 | ``` 92 | 93 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/apex/logs-cloudwatch 2 | 3 | go 1.15 4 | 5 | require ( 6 | github.com/aws/aws-sdk-go v1.34.2 7 | github.com/integrii/flaggy v1.4.4 8 | github.com/tj/go-tea v0.6.1 9 | github.com/tj/go-terminput v1.0.0 10 | ) 11 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/apex/apex v0.16.0/go.mod h1:kof13vptkdeeeQe+P1xgCKzHCq2L7/Il8QM1HfjI7qY= 2 | github.com/aws/aws-sdk-go v1.34.2 h1:9vCknCdTAmmV4ht7lPuda7aJXzllXwEQyCMZKJHjBrM= 3 | github.com/aws/aws-sdk-go v1.34.2/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= 4 | github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= 5 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 6 | github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= 7 | github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= 8 | github.com/integrii/flaggy v1.4.4 h1:8fGyiC14o0kxhTqm2VBoN19fDKPZsKipP7yggreTMDc= 9 | github.com/integrii/flaggy v1.4.4/go.mod h1:tnTxHeTJbah0gQ6/K0RW0J7fMUBk9MCF5blhm43LNpI= 10 | github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc= 11 | github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= 12 | github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= 13 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 14 | github.com/pkg/term v0.0.0-20190109203006-aa71e9d9e942 h1:A7GG7zcGjl3jqAqGPmcNjd/D9hzL95SuoOQAaFNdLU0= 15 | github.com/pkg/term v0.0.0-20190109203006-aa71e9d9e942/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ= 16 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 17 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 18 | github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= 19 | github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= 20 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 21 | github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= 22 | github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= 23 | github.com/tj/go-tea v0.6.1 h1:QFti8BrNFpHJsQ0OAF9asw23t1BhHNJtrfo1n6qmX7k= 24 | github.com/tj/go-tea v0.6.1/go.mod h1:FI5K2KVV8qztF4wjlz6FIuOI29NM9ULUI2a/H4ZduHg= 25 | github.com/tj/go-terminput v1.0.0 h1:X928u7ohxr7Dfzlxppvc5Zql5Lwd1bOH5VyIL2RPrFw= 26 | github.com/tj/go-terminput v1.0.0/go.mod h1:8zzAs+cqdjZlTxE9DbGyjKDfGNxaJjC5bvg4vkWX2V0= 27 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 28 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 29 | golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjutRKlBEZQ6wTn8ozI/nI= 30 | golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 31 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 32 | golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756 h1:9nuHUbU8dRnRRfj9KjWUVrJeoexdbeMjttk6Oh1rD10= 33 | golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 34 | golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= 35 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 36 | golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 37 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 38 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 39 | gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= 40 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 41 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | //go:generate file2go -in template.yml -pkg main 2 | 3 | // Package main provides a command-line tool for setting up the CloudWatch Logs integration for Apex Logs. 4 | package main 5 | 6 | import ( 7 | "bytes" 8 | "fmt" 9 | "io/ioutil" 10 | "log" 11 | "os" 12 | "os/exec" 13 | "strings" 14 | "text/template" 15 | 16 | flag "github.com/integrii/flaggy" 17 | 18 | "github.com/aws/aws-sdk-go/aws" 19 | "github.com/aws/aws-sdk-go/aws/session" 20 | "github.com/aws/aws-sdk-go/service/cloudwatchlogs" 21 | ) 22 | 23 | // version string. 24 | var version string 25 | 26 | // Config struct. 27 | type Config struct { 28 | StackName string 29 | ProjectID string 30 | Region string 31 | Endpoint string 32 | AuthToken string 33 | Include []string 34 | Exclude []string 35 | Template bool 36 | Create bool 37 | } 38 | 39 | // TemplateConfig struct. 40 | type TemplateConfig struct { 41 | Groups []string 42 | } 43 | 44 | func main() { 45 | c := Config{ 46 | StackName: "ApexLogs", 47 | } 48 | 49 | // flags 50 | flag.SetVersion(version) 51 | flag.String(&c.ProjectID, "", "project-id", "Apex Logs destination project ID") 52 | flag.String(&c.AuthToken, "", "auth-token", "Apex Logs authentication token") 53 | flag.String(&c.Endpoint, "", "endpoint", "Apex Logs integration endpoint URL") 54 | flag.String(&c.Region, "", "region", "AWS region id") 55 | flag.String(&c.StackName, "", "stack-name", "AWS CloudFormation stack name") 56 | flag.StringSlice(&c.Exclude, "", "exclude", "AWS CloudWatch log group filters") 57 | flag.StringSlice(&c.Include, "", "include", "AWS CloudWatch log group filters") 58 | flag.Bool(&c.Create, "", "confirm", "Confirm creation of the stack") 59 | flag.Bool(&c.Template, "", "template", "Output the template and exit") 60 | flag.Parse() 61 | 62 | // why you no allow required flags :D 63 | if c.ProjectID == "" { 64 | log.Fatalf("error: project-id required") 65 | } 66 | 67 | if c.Endpoint == "" { 68 | log.Fatalf("error: endpoint required") 69 | } 70 | 71 | if c.AuthToken == "" { 72 | log.Fatalf("error: auth-token required") 73 | } 74 | 75 | if c.Region == "" { 76 | log.Fatalf("error: region required") 77 | } 78 | 79 | // fetch log groups 80 | fmt.Printf("==> Finding log groups\n") 81 | groups, err := getLogGroups(c) 82 | if err != nil { 83 | log.Fatalf("error fetching log groups: %s", err) 84 | } 85 | 86 | fmt.Printf("==> Found %d matching log groups:\n\n", len(groups)) 87 | for _, g := range groups { 88 | fmt.Printf(" %s\n", g) 89 | } 90 | fmt.Printf("\n") 91 | 92 | // render template 93 | tmpl, err := renderTemplate(TemplateConfig{ 94 | Groups: groups, 95 | }) 96 | 97 | if err != nil { 98 | log.Fatalf("error rendering template: %s", err) 99 | } 100 | 101 | // output template 102 | if c.Template { 103 | fmt.Printf("%s\n", tmpl) 104 | return 105 | } 106 | 107 | f, err := ioutil.TempFile(os.TempDir(), "apex-logs-template-*.yml") 108 | if err != nil { 109 | log.Fatalf("error creating tmpfile: %s", err) 110 | } 111 | 112 | _, err = f.WriteString(tmpl) 113 | if err != nil { 114 | log.Fatalf("error writing template file: %s", err) 115 | } 116 | 117 | err = f.Close() 118 | if err != nil { 119 | log.Fatalf("error writing template file: %s", err) 120 | } 121 | 122 | // create stack 123 | if c.Create { 124 | fmt.Printf("==> Creating CloudFormation stack\n") 125 | err = createStack(f.Name(), c) 126 | if err != nil { 127 | log.Fatalf("error creating stack: %s", err) 128 | } 129 | return 130 | } 131 | 132 | fmt.Printf("==> Run command again with --confirm to create the stack\n") 133 | } 134 | 135 | // createStack creates a CloudFormation stack. 136 | func createStack(tmplPath string, c Config) error { 137 | cmd := exec.Command("aws", "cloudformation", "create-stack", 138 | "--stack-name", c.StackName, 139 | "--region", c.Region, 140 | "--template-body", "file://"+tmplPath, 141 | "--capabilities", "CAPABILITY_IAM", 142 | "--parameters", 143 | "ParameterKey=Endpoint,ParameterValue="+c.Endpoint, 144 | "ParameterKey=AuthToken,ParameterValue="+c.AuthToken, 145 | "ParameterKey=ProjectID,ParameterValue="+c.ProjectID, 146 | ) 147 | 148 | cmd.Stdout = os.Stdout 149 | cmd.Stderr = os.Stderr 150 | 151 | return cmd.Run() 152 | } 153 | 154 | // getLogGroups returns all log groups. 155 | func getLogGroups(c Config) ([]string, error) { 156 | conf := aws.NewConfig().WithRegion(c.Region) 157 | logs := cloudwatchlogs.New(session.New(conf)) 158 | 159 | var groups []string 160 | var cursor *string 161 | 162 | for { 163 | res, err := logs.DescribeLogGroups(&cloudwatchlogs.DescribeLogGroupsInput{ 164 | NextToken: cursor, 165 | }) 166 | 167 | if err != nil { 168 | return nil, fmt.Errorf("describing log groups: %w", err) 169 | } 170 | 171 | cursor = res.NextToken 172 | 173 | for _, group := range res.LogGroups { 174 | name := *group.LogGroupName 175 | if filter(name, c.Include, c.Exclude) { 176 | groups = append(groups, name) 177 | } 178 | } 179 | 180 | if cursor == nil { 181 | break 182 | } 183 | } 184 | 185 | return groups, nil 186 | } 187 | 188 | // renderTemplate returns a rendered CloudFormation template. 189 | func renderTemplate(c TemplateConfig) (string, error) { 190 | t := template.Must(template.New("template.yml").Parse(string(TemplateYml))) 191 | var buf bytes.Buffer 192 | err := t.Execute(&buf, c) 193 | if err != nil { 194 | return "", err 195 | } 196 | return buf.String(), nil 197 | } 198 | 199 | // filter returns true if the string matches the filters. 200 | func filter(s string, include, exclude []string) bool { 201 | if include != nil { 202 | return match(s, include) && !match(s, exclude) 203 | } 204 | 205 | return !match(s, exclude) 206 | } 207 | 208 | // match returns true if s matches any of patterns. 209 | func match(s string, patterns []string) bool { 210 | for _, p := range patterns { 211 | if strings.Contains(s, p) { 212 | return true 213 | } 214 | } 215 | return false 216 | } 217 | -------------------------------------------------------------------------------- /template.yml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: 2010-09-09 2 | 3 | Parameters: 4 | Endpoint: 5 | Type: String 6 | Description: The Apex Logs CloudWatch Logs integration URL. 7 | AllowedPattern: ".+" 8 | AuthToken: 9 | Type: String 10 | Description: The Apex Logs API token with write access. 11 | AllowedPattern: ".+" 12 | ProjectID: 13 | Type: String 14 | Description: The Apex Logs destination project ID. 15 | AllowedPattern: ".+" 16 | BufferInterval: 17 | Type: Number 18 | Description: The buffer flush interval in seconds. 19 | Default: 60 20 | BufferSize: 21 | Type: Number 22 | Description: The buffer max size in megabytes. 23 | Default: 1 24 | 25 | Resources: 26 | S3Bucket: 27 | Type: AWS::S3::Bucket 28 | Properties: 29 | LifecycleConfiguration: 30 | Rules: 31 | - ExpirationInDays: 7 32 | Status: Enabled 33 | 34 | LogsRole: 35 | Type: AWS::IAM::Role 36 | Properties: 37 | AssumeRolePolicyDocument: 38 | Version: 2012-10-17 39 | Statement: 40 | - Sid: '' 41 | Effect: Allow 42 | Principal: 43 | Service: !Sub "logs.${AWS::Region}.amazonaws.com" 44 | Action: 'sts:AssumeRole' 45 | 46 | LogsPolicy: 47 | Type: AWS::IAM::Policy 48 | Properties: 49 | PolicyName: logs_policy 50 | PolicyDocument: 51 | Version: 2012-10-17 52 | Statement: 53 | - Sid: '' 54 | Effect: Allow 55 | Action: 56 | - 'firehose:*' 57 | Resource: 58 | - !Sub "arn:aws:firehose:${AWS::Region}:${AWS::AccountId}:*" 59 | Roles: 60 | - !Ref LogsRole 61 | 62 | DeliveryRole: 63 | Type: AWS::IAM::Role 64 | Properties: 65 | AssumeRolePolicyDocument: 66 | Version: 2012-10-17 67 | Statement: 68 | - Sid: '' 69 | Effect: Allow 70 | Principal: 71 | Service: firehose.amazonaws.com 72 | Action: 'sts:AssumeRole' 73 | 74 | DeliveryPolicy: 75 | Type: AWS::IAM::Policy 76 | Properties: 77 | PolicyName: firehose_delivery_policy 78 | PolicyDocument: 79 | Version: 2012-10-17 80 | Statement: 81 | - Effect: Allow 82 | Action: 83 | - 's3:AbortMultipartUpload' 84 | - 's3:GetBucketLocation' 85 | - 's3:GetObject' 86 | - 's3:ListBucket' 87 | - 's3:ListBucketMultipartUploads' 88 | - 's3:PutObject' 89 | Resource: 90 | - !Sub 'arn:aws:s3:::${S3Bucket}' 91 | - !Sub 'arn:aws:s3:::${S3Bucket}*' 92 | Roles: 93 | - !Ref DeliveryRole 94 | 95 | DeliveryStream: 96 | Type: AWS::KinesisFirehose::DeliveryStream 97 | Properties: 98 | DeliveryStreamType: DirectPut 99 | HttpEndpointDestinationConfiguration: 100 | EndpointConfiguration: 101 | Name: "ApexLogs" 102 | AccessKey: !Ref AuthToken 103 | Url: !Ref Endpoint 104 | S3Configuration: 105 | BucketARN: !GetAtt S3Bucket.Arn 106 | RoleARN: !GetAtt DeliveryRole.Arn 107 | RetryOptions: 108 | DurationInSeconds: 300 109 | RequestConfiguration: 110 | ContentEncoding: NONE 111 | CommonAttributes: 112 | - AttributeName: project_id 113 | AttributeValue: !Ref ProjectID 114 | - AttributeName: aws_region 115 | AttributeValue: !Ref AWS::Region 116 | BufferingHints: 117 | IntervalInSeconds: !Ref BufferInterval 118 | SizeInMBs: !Ref BufferSize 119 | RoleARN: !GetAtt DeliveryRole.Arn 120 | 121 | {{range $index, $group := .Groups}} 122 | LogsSubscription{{$index}}: 123 | Type: AWS::Logs::SubscriptionFilter 124 | Properties: 125 | LogGroupName: {{printf "%q" $group}} 126 | FilterPattern: "" 127 | DestinationArn: !GetAtt DeliveryStream.Arn 128 | RoleArn: !GetAtt LogsRole.Arn 129 | DependsOn: DeliveryStream 130 | {{end}} 131 | -------------------------------------------------------------------------------- /template_yml.go: -------------------------------------------------------------------------------- 1 | // Code generated by "file2go -in template.yml -pkg main"; DO NOT EDIT. 2 | 3 | package main 4 | 5 | // TemplateYml holds content of template.yml 6 | var TemplateYml = []byte{ 7 | 0x41, 0x57, 0x53, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x46, 8 | 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 9 | 0x3a, 0x20, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x39, 10 | 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 11 | 0x3a, 0x20, 0x0a, 0x20, 0x20, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 12 | 0x74, 0x3a, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, 0x65, 13 | 0x3a, 0x20, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x0a, 0x20, 0x20, 0x20, 14 | 0x20, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 15 | 0x3a, 0x20, 0x54, 0x68, 0x65, 0x20, 0x41, 0x70, 0x65, 0x78, 0x20, 0x4c, 16 | 0x6f, 0x67, 0x73, 0x20, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x57, 0x61, 0x74, 17 | 0x63, 0x68, 0x20, 0x4c, 0x6f, 0x67, 0x73, 0x20, 0x69, 0x6e, 0x74, 0x65, 18 | 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x55, 0x52, 0x4c, 0x2e, 19 | 0x0a, 0x20, 0x20, 0x20, 0x20, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 20 | 0x50, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x3a, 0x20, 0x22, 0x2e, 0x2b, 21 | 0x22, 0x0a, 0x20, 0x20, 0x41, 0x75, 0x74, 0x68, 0x54, 0x6f, 0x6b, 0x65, 22 | 0x6e, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, 0x65, 0x3a, 23 | 0x20, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x0a, 0x20, 0x20, 0x20, 0x20, 24 | 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 25 | 0x20, 0x54, 0x68, 0x65, 0x20, 0x41, 0x70, 0x65, 0x78, 0x20, 0x4c, 0x6f, 26 | 0x67, 0x73, 0x20, 0x41, 0x50, 0x49, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 27 | 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x20, 28 | 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x0a, 0x20, 0x20, 0x20, 0x20, 29 | 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x50, 0x61, 0x74, 0x74, 0x65, 30 | 0x72, 0x6e, 0x3a, 0x20, 0x22, 0x2e, 0x2b, 0x22, 0x0a, 0x20, 0x20, 0x50, 31 | 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x44, 0x3a, 0x0a, 0x20, 0x20, 32 | 0x20, 0x20, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x53, 0x74, 0x72, 0x69, 33 | 0x6e, 0x67, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x44, 0x65, 0x73, 0x63, 0x72, 34 | 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x54, 0x68, 0x65, 0x20, 35 | 0x41, 0x70, 0x65, 0x78, 0x20, 0x4c, 0x6f, 0x67, 0x73, 0x20, 0x64, 0x65, 36 | 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x72, 37 | 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x49, 0x44, 0x2e, 0x0a, 0x20, 0x20, 38 | 0x20, 0x20, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x50, 0x61, 0x74, 39 | 0x74, 0x65, 0x72, 0x6e, 0x3a, 0x20, 0x22, 0x2e, 0x2b, 0x22, 0x0a, 0x20, 40 | 0x20, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x49, 0x6e, 0x74, 0x65, 0x72, 41 | 0x76, 0x61, 0x6c, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, 42 | 0x65, 0x3a, 0x20, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x0a, 0x20, 0x20, 43 | 0x20, 0x20, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 44 | 0x6e, 0x3a, 0x20, 0x54, 0x68, 0x65, 0x20, 0x62, 0x75, 0x66, 0x66, 0x65, 45 | 0x72, 0x20, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x20, 0x69, 0x6e, 0x74, 0x65, 46 | 0x72, 0x76, 0x61, 0x6c, 0x20, 0x69, 0x6e, 0x20, 0x73, 0x65, 0x63, 0x6f, 47 | 0x6e, 0x64, 0x73, 0x2e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x44, 0x65, 0x66, 48 | 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x20, 0x36, 0x30, 0x0a, 0x20, 0x20, 0x42, 49 | 0x75, 0x66, 0x66, 0x65, 0x72, 0x53, 0x69, 0x7a, 0x65, 0x3a, 0x0a, 0x20, 50 | 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x4e, 0x75, 0x6d, 51 | 0x62, 0x65, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x44, 0x65, 0x73, 0x63, 52 | 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x54, 0x68, 0x65, 53 | 0x20, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x20, 0x6d, 0x61, 0x78, 0x20, 54 | 0x73, 0x69, 0x7a, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x6d, 0x65, 0x67, 0x61, 55 | 0x62, 0x79, 0x74, 0x65, 0x73, 0x2e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x44, 56 | 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x20, 0x31, 0x0a, 0x0a, 0x52, 57 | 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x3a, 0x0a, 0x20, 0x20, 58 | 0x53, 0x33, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x3a, 0x0a, 0x20, 0x20, 59 | 0x20, 0x20, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x41, 0x57, 0x53, 0x3a, 60 | 0x3a, 0x53, 0x33, 0x3a, 0x3a, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x0a, 61 | 0x20, 0x20, 0x20, 0x20, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 62 | 0x65, 0x73, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4c, 0x69, 63 | 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 64 | 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x0a, 0x20, 0x20, 65 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x3a, 66 | 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, 67 | 0x20, 0x45, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 68 | 0x6e, 0x44, 0x61, 0x79, 0x73, 0x3a, 0x20, 0x37, 0x0a, 0x20, 0x20, 0x20, 69 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x74, 0x61, 70 | 0x74, 0x75, 0x73, 0x3a, 0x20, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 71 | 0x0a, 0x0a, 0x20, 0x20, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x6f, 0x6c, 0x65, 72 | 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 73 | 0x41, 0x57, 0x53, 0x3a, 0x3a, 0x49, 0x41, 0x4d, 0x3a, 0x3a, 0x52, 0x6f, 74 | 0x6c, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x50, 0x72, 0x6f, 0x70, 0x65, 75 | 0x72, 0x74, 0x69, 0x65, 0x73, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 76 | 0x20, 0x41, 0x73, 0x73, 0x75, 0x6d, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x50, 77 | 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 78 | 0x74, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x56, 79 | 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x32, 0x30, 0x31, 0x32, 80 | 0x2d, 0x31, 0x30, 0x2d, 0x31, 0x37, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 81 | 0x20, 0x20, 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 82 | 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 83 | 0x2d, 0x20, 0x53, 0x69, 0x64, 0x3a, 0x20, 0x27, 0x27, 0x0a, 0x20, 0x20, 84 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x66, 85 | 0x66, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x0a, 86 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 87 | 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x3a, 0x0a, 0x20, 88 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 89 | 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x3a, 0x20, 0x21, 0x53, 90 | 0x75, 0x62, 0x20, 0x22, 0x6c, 0x6f, 0x67, 0x73, 0x2e, 0x24, 0x7b, 0x41, 91 | 0x57, 0x53, 0x3a, 0x3a, 0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x7d, 0x2e, 92 | 0x61, 0x6d, 0x61, 0x7a, 0x6f, 0x6e, 0x61, 0x77, 0x73, 0x2e, 0x63, 0x6f, 93 | 0x6d, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 94 | 0x20, 0x20, 0x20, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x27, 95 | 0x73, 0x74, 0x73, 0x3a, 0x41, 0x73, 0x73, 0x75, 0x6d, 0x65, 0x52, 0x6f, 96 | 0x6c, 0x65, 0x27, 0x0a, 0x0a, 0x20, 0x20, 0x4c, 0x6f, 0x67, 0x73, 0x50, 97 | 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 98 | 0x79, 0x70, 0x65, 0x3a, 0x20, 0x41, 0x57, 0x53, 0x3a, 0x3a, 0x49, 0x41, 99 | 0x4d, 0x3a, 0x3a, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x0a, 0x20, 0x20, 100 | 0x20, 0x20, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 101 | 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x6f, 0x6c, 0x69, 102 | 0x63, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x6c, 0x6f, 0x67, 0x73, 103 | 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x0a, 0x20, 0x20, 0x20, 0x20, 104 | 0x20, 0x20, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x44, 0x6f, 0x63, 0x75, 105 | 0x6d, 0x65, 0x6e, 0x74, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 106 | 0x20, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x32, 107 | 0x30, 0x31, 0x32, 0x2d, 0x31, 0x30, 0x2d, 0x31, 0x37, 0x0a, 0x20, 0x20, 108 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 109 | 0x65, 0x6e, 0x74, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 110 | 0x20, 0x20, 0x20, 0x2d, 0x20, 0x53, 0x69, 0x64, 0x3a, 0x20, 0x27, 0x27, 111 | 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 112 | 0x20, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x41, 0x6c, 0x6c, 113 | 0x6f, 0x77, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 114 | 0x20, 0x20, 0x20, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x0a, 0x20, 115 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 116 | 0x20, 0x2d, 0x20, 0x27, 0x66, 0x69, 0x72, 0x65, 0x68, 0x6f, 0x73, 0x65, 117 | 0x3a, 0x2a, 0x27, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 118 | 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 119 | 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 120 | 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x21, 0x53, 0x75, 0x62, 0x20, 0x22, 121 | 0x61, 0x72, 0x6e, 0x3a, 0x61, 0x77, 0x73, 0x3a, 0x66, 0x69, 0x72, 0x65, 122 | 0x68, 0x6f, 0x73, 0x65, 0x3a, 0x24, 0x7b, 0x41, 0x57, 0x53, 0x3a, 0x3a, 123 | 0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x7d, 0x3a, 0x24, 0x7b, 0x41, 0x57, 124 | 0x53, 0x3a, 0x3a, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, 125 | 0x7d, 0x3a, 0x2a, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 126 | 0x6f, 0x6c, 0x65, 0x73, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 127 | 0x20, 0x20, 0x2d, 0x20, 0x21, 0x52, 0x65, 0x66, 0x20, 0x4c, 0x6f, 0x67, 128 | 0x73, 0x52, 0x6f, 0x6c, 0x65, 0x0a, 0x0a, 0x20, 0x20, 0x44, 0x65, 0x6c, 129 | 0x69, 0x76, 0x65, 0x72, 0x79, 0x52, 0x6f, 0x6c, 0x65, 0x3a, 0x0a, 0x20, 130 | 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x41, 0x57, 0x53, 131 | 0x3a, 0x3a, 0x49, 0x41, 0x4d, 0x3a, 0x3a, 0x52, 0x6f, 0x6c, 0x65, 0x0a, 132 | 0x20, 0x20, 0x20, 0x20, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 133 | 0x65, 0x73, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x73, 134 | 0x73, 0x75, 0x6d, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x50, 0x6f, 0x6c, 0x69, 135 | 0x63, 0x79, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x3a, 0x0a, 136 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x56, 0x65, 0x72, 0x73, 137 | 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x32, 0x30, 0x31, 0x32, 0x2d, 0x31, 0x30, 138 | 0x2d, 0x31, 0x37, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 139 | 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x3a, 0x0a, 0x20, 140 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x53, 141 | 0x69, 0x64, 0x3a, 0x20, 0x27, 0x27, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 142 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x66, 0x66, 0x65, 0x63, 143 | 0x74, 0x3a, 0x20, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x0a, 0x20, 0x20, 0x20, 144 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x72, 0x69, 145 | 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 146 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x65, 147 | 0x72, 0x76, 0x69, 0x63, 0x65, 0x3a, 0x20, 0x66, 0x69, 0x72, 0x65, 0x68, 148 | 0x6f, 0x73, 0x65, 0x2e, 0x61, 0x6d, 0x61, 0x7a, 0x6f, 0x6e, 0x61, 0x77, 149 | 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 150 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 151 | 0x3a, 0x20, 0x27, 0x73, 0x74, 0x73, 0x3a, 0x41, 0x73, 0x73, 0x75, 0x6d, 152 | 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x27, 0x0a, 0x0a, 0x20, 0x20, 0x44, 0x65, 153 | 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 154 | 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 155 | 0x41, 0x57, 0x53, 0x3a, 0x3a, 0x49, 0x41, 0x4d, 0x3a, 0x3a, 0x50, 0x6f, 156 | 0x6c, 0x69, 0x63, 0x79, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x50, 0x72, 0x6f, 157 | 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x3a, 0x0a, 0x20, 0x20, 0x20, 158 | 0x20, 0x20, 0x20, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4e, 0x61, 0x6d, 159 | 0x65, 0x3a, 0x20, 0x66, 0x69, 0x72, 0x65, 0x68, 0x6f, 0x73, 0x65, 0x5f, 160 | 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x5f, 0x70, 0x6f, 0x6c, 161 | 0x69, 0x63, 0x79, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x6f, 162 | 0x6c, 0x69, 0x63, 0x79, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 163 | 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x56, 0x65, 164 | 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x32, 0x30, 0x31, 0x32, 0x2d, 165 | 0x31, 0x30, 0x2d, 0x31, 0x37, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 166 | 0x20, 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x3a, 167 | 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, 168 | 0x20, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x41, 0x6c, 0x6c, 169 | 0x6f, 0x77, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 170 | 0x20, 0x20, 0x20, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x0a, 0x20, 171 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 172 | 0x20, 0x2d, 0x20, 0x27, 0x73, 0x33, 0x3a, 0x41, 0x62, 0x6f, 0x72, 0x74, 173 | 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74, 0x55, 0x70, 0x6c, 174 | 0x6f, 0x61, 0x64, 0x27, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 175 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x27, 0x73, 0x33, 176 | 0x3a, 0x47, 0x65, 0x74, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x4c, 0x6f, 177 | 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x27, 0x0a, 0x20, 0x20, 0x20, 0x20, 178 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 179 | 0x27, 0x73, 0x33, 0x3a, 0x47, 0x65, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 180 | 0x74, 0x27, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 181 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x27, 0x73, 0x33, 0x3a, 0x4c, 182 | 0x69, 0x73, 0x74, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x27, 0x0a, 0x20, 183 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 184 | 0x20, 0x2d, 0x20, 0x27, 0x73, 0x33, 0x3a, 0x4c, 0x69, 0x73, 0x74, 0x42, 185 | 0x75, 0x63, 0x6b, 0x65, 0x74, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 186 | 0x72, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x27, 0x0a, 0x20, 187 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 188 | 0x20, 0x2d, 0x20, 0x27, 0x73, 0x33, 0x3a, 0x50, 0x75, 0x74, 0x4f, 0x62, 189 | 0x6a, 0x65, 0x63, 0x74, 0x27, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 190 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 191 | 0x63, 0x65, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 192 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x21, 0x53, 0x75, 0x62, 193 | 0x20, 0x27, 0x61, 0x72, 0x6e, 0x3a, 0x61, 0x77, 0x73, 0x3a, 0x73, 0x33, 194 | 0x3a, 0x3a, 0x3a, 0x24, 0x7b, 0x53, 0x33, 0x42, 0x75, 0x63, 0x6b, 0x65, 195 | 0x74, 0x7d, 0x27, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 196 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x21, 0x53, 0x75, 0x62, 197 | 0x20, 0x27, 0x61, 0x72, 0x6e, 0x3a, 0x61, 0x77, 0x73, 0x3a, 0x73, 0x33, 198 | 0x3a, 0x3a, 0x3a, 0x24, 0x7b, 0x53, 0x33, 0x42, 0x75, 0x63, 0x6b, 0x65, 199 | 0x74, 0x7d, 0x2a, 0x27, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 200 | 0x6f, 0x6c, 0x65, 0x73, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 201 | 0x20, 0x20, 0x2d, 0x20, 0x21, 0x52, 0x65, 0x66, 0x20, 0x44, 0x65, 0x6c, 202 | 0x69, 0x76, 0x65, 0x72, 0x79, 0x52, 0x6f, 0x6c, 0x65, 0x0a, 0x0a, 0x20, 203 | 0x20, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x53, 0x74, 0x72, 204 | 0x65, 0x61, 0x6d, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, 205 | 0x65, 0x3a, 0x20, 0x41, 0x57, 0x53, 0x3a, 0x3a, 0x4b, 0x69, 0x6e, 0x65, 206 | 0x73, 0x69, 0x73, 0x46, 0x69, 0x72, 0x65, 0x68, 0x6f, 0x73, 0x65, 0x3a, 207 | 0x3a, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x53, 0x74, 0x72, 208 | 0x65, 0x61, 0x6d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x50, 0x72, 0x6f, 0x70, 209 | 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 210 | 0x20, 0x20, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x53, 0x74, 211 | 0x72, 0x65, 0x61, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x44, 0x69, 212 | 0x72, 0x65, 0x63, 0x74, 0x50, 0x75, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 213 | 0x20, 0x20, 0x48, 0x74, 0x74, 0x70, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 214 | 0x6e, 0x74, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 215 | 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 216 | 0x6f, 0x6e, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 217 | 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 218 | 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x0a, 0x20, 219 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4e, 0x61, 0x6d, 220 | 0x65, 0x3a, 0x20, 0x22, 0x41, 0x70, 0x65, 0x78, 0x4c, 0x6f, 0x67, 0x73, 221 | 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 222 | 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x3a, 0x20, 0x21, 223 | 0x52, 0x65, 0x66, 0x20, 0x41, 0x75, 0x74, 0x68, 0x54, 0x6f, 0x6b, 0x65, 224 | 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 225 | 0x55, 0x72, 0x6c, 0x3a, 0x20, 0x21, 0x52, 0x65, 0x66, 0x20, 0x45, 0x6e, 226 | 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 227 | 0x20, 0x20, 0x20, 0x53, 0x33, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 228 | 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 229 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 230 | 0x41, 0x52, 0x4e, 0x3a, 0x20, 0x21, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 231 | 0x20, 0x53, 0x33, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x41, 0x72, 232 | 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 233 | 0x52, 0x6f, 0x6c, 0x65, 0x41, 0x52, 0x4e, 0x3a, 0x20, 0x21, 0x47, 0x65, 234 | 0x74, 0x41, 0x74, 0x74, 0x20, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 235 | 0x79, 0x52, 0x6f, 0x6c, 0x65, 0x2e, 0x41, 0x72, 0x6e, 0x0a, 0x20, 0x20, 236 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 0x74, 0x72, 0x79, 0x4f, 237 | 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 238 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 239 | 0x6f, 0x6e, 0x49, 0x6e, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x3a, 240 | 0x20, 0x33, 0x30, 0x30, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 241 | 0x20, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66, 242 | 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x0a, 0x20, 243 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x6f, 0x6e, 244 | 0x74, 0x65, 0x6e, 0x74, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 245 | 0x3a, 0x20, 0x4e, 0x4f, 0x4e, 0x45, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 246 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x41, 247 | 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x3a, 0x0a, 0x20, 248 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, 249 | 0x20, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4e, 0x61, 250 | 0x6d, 0x65, 0x3a, 0x20, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 251 | 0x69, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 252 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 253 | 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x20, 0x21, 0x52, 0x65, 254 | 0x66, 0x20, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x44, 0x0a, 255 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 256 | 0x2d, 0x20, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4e, 257 | 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x61, 0x77, 0x73, 0x5f, 0x72, 0x65, 0x67, 258 | 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 259 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 260 | 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x20, 0x21, 0x52, 261 | 0x65, 0x66, 0x20, 0x41, 0x57, 0x53, 0x3a, 0x3a, 0x52, 0x65, 0x67, 0x69, 262 | 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x42, 263 | 0x75, 0x66, 0x66, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x48, 0x69, 0x6e, 0x74, 264 | 0x73, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 265 | 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x49, 0x6e, 0x53, 266 | 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x3a, 0x20, 0x21, 0x52, 0x65, 0x66, 267 | 0x20, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x49, 0x6e, 0x74, 0x65, 0x72, 268 | 0x76, 0x61, 0x6c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 269 | 0x20, 0x20, 0x53, 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x4d, 0x42, 0x73, 0x3a, 270 | 0x20, 0x21, 0x52, 0x65, 0x66, 0x20, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 271 | 0x53, 0x69, 0x7a, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 272 | 0x20, 0x52, 0x6f, 0x6c, 0x65, 0x41, 0x52, 0x4e, 0x3a, 0x20, 0x21, 0x47, 273 | 0x65, 0x74, 0x41, 0x74, 0x74, 0x20, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 274 | 0x72, 0x79, 0x52, 0x6f, 0x6c, 0x65, 0x2e, 0x41, 0x72, 0x6e, 0x0a, 0x20, 275 | 0x20, 0x20, 0x20, 0x0a, 0x7b, 0x7b, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x20, 276 | 0x24, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2c, 0x20, 0x24, 0x67, 0x72, 0x6f, 277 | 0x75, 0x70, 0x20, 0x3a, 0x3d, 0x20, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 278 | 0x73, 0x7d, 0x7d, 0x0a, 0x20, 0x20, 0x4c, 0x6f, 0x67, 0x73, 0x53, 0x75, 279 | 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x7b, 0x7b, 280 | 0x24, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x7d, 0x7d, 0x3a, 0x0a, 0x20, 0x20, 281 | 0x20, 0x20, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x41, 0x57, 0x53, 0x3a, 282 | 0x3a, 0x4c, 0x6f, 0x67, 0x73, 0x3a, 0x3a, 0x53, 0x75, 0x62, 0x73, 0x63, 283 | 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x6c, 0x74, 0x65, 284 | 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 285 | 0x74, 0x69, 0x65, 0x73, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 286 | 0x4c, 0x6f, 0x67, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 287 | 0x3a, 0x20, 0x7b, 0x7b, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x66, 0x20, 0x22, 288 | 0x25, 0x71, 0x22, 0x20, 0x24, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x7d, 0x7d, 289 | 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x46, 0x69, 0x6c, 0x74, 0x65, 290 | 0x72, 0x50, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x3a, 0x20, 0x22, 0x22, 291 | 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x44, 0x65, 0x73, 0x74, 0x69, 292 | 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x72, 0x6e, 0x3a, 0x20, 0x21, 293 | 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x20, 0x44, 0x65, 0x6c, 0x69, 0x76, 294 | 0x65, 0x72, 0x79, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2e, 0x41, 0x72, 295 | 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x6f, 0x6c, 0x65, 296 | 0x41, 0x72, 0x6e, 0x3a, 0x20, 0x21, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 297 | 0x20, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x6f, 0x6c, 0x65, 0x2e, 0x41, 0x72, 298 | 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 299 | 0x73, 0x4f, 0x6e, 0x3a, 0x20, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 300 | 0x79, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x0a, 0x7b, 0x7b, 0x65, 0x6e, 301 | 0x64, 0x7d, 0x7d, 0x0a, 302 | } 303 | --------------------------------------------------------------------------------