├── .gitignore
├── LICENSE
├── README.md
├── tutorial 1 - canary release
├── canary.ingress
├── canary.yaml
├── production.ingress
└── production.yaml
├── tutorial 2 - local helm repo
└── redis.tgz
├── tutorial 3 - install-gitlab-harbor
├── gitlab-harbor.sh
└── install-gitlab-harbor.yml
├── tutorial 4 - s2i-b2i
├── b2i-binary
├── b2i-jar-java11.jar
├── b2i-jar-java8.jar
├── b2i-war-java11.war
└── b2i-war-java8.war
├── tutorial 5 - app-store
├── emq-dashboard.png
├── emqx-logo.png
├── emqx-v1.0.0-beta.1.tgz
├── emqx-v1.0.0-beta.2.tgz
├── emqx-v1.0.0-rc.1.tgz
├── emqx-v4.0.2.tgz
├── redis-11.3.4.tgz
└── redis-12.0.0.tgz
└── tutorial 6 - skywalking
├── 6.5.0
├── 6.5.0
│ ├── apm-springcloud-demo
│ │ ├── kdep-apm-eureka.yml
│ │ ├── kdep-apm-item.yml
│ │ ├── kser-apm-eureka.yml
│ │ └── kser-apm-item.yml
│ ├── busybox.yml
│ ├── docker
│ │ ├── base
│ │ │ ├── Dockerfile
│ │ │ └── build-image.sh
│ │ ├── oap
│ │ │ ├── Dockerfile
│ │ │ ├── README.md
│ │ │ ├── build-image.sh
│ │ │ ├── docker-entrypoint.sh
│ │ │ └── log4j2.xml
│ │ └── ui
│ │ │ ├── Dockerfile
│ │ │ ├── README.md
│ │ │ ├── build-image.sh
│ │ │ ├── docker-entrypoint.sh
│ │ │ └── logback.xml
│ ├── elasticsearch
│ │ ├── 01-pv.yml
│ │ ├── 01-storageclass.yml
│ │ ├── 02-service.yml
│ │ └── 03-statefulset.yml
│ ├── istio
│ │ ├── 01-metrictemplate.yml
│ │ ├── 02-skywalingadapter.yml
│ │ ├── 03-operator_cfg.yml
│ │ └── README.md
│ ├── namespace.yml
│ ├── oap
│ │ ├── 00-rbac.yml
│ │ ├── 01-config.yml
│ │ ├── 02-service.yml
│ │ └── 03-deployment.yml
│ └── ui
│ │ ├── 01-service.yml
│ │ └── 02-deployment.yml
└── apm-springcloud-demo
│ ├── kdep-apm-eureka.yml
│ ├── kdep-apm-item.yml
│ ├── kser-apm-eureka.yml
│ └── kser-apm-item.yml
└── 8.1.0
├── README.md
└── apm-springcloud-demo
├── kdep-apm-eureka.yml
├── kdep-apm-item.yml
├── kser-apm-eureka.yml
└── kser-apm-item.yml
/.gitignore:
--------------------------------------------------------------------------------
1 | # Binaries for programs and plugins
2 | *.exe
3 | *.exe~
4 | *.dll
5 | *.so
6 | *.dylib
7 |
8 | # Test binary, build with `go test -c`
9 | *.test
10 |
11 | # Output of the go coverage tool, specifically when used with LiteIDE
12 | *.out
13 |
14 | # macOS hidden file
15 | .DS_Store
16 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # tutorial
2 | KubeSphere tutorial repo, include samples code, docs etc.
3 |
4 | - [Tutorial 1 - 使用 Ingress-Nginx 进行灰度发布](https://kubesphere.io/docs/advanced-v2.0/zh-CN/quick-start/ingress-canary/)
--------------------------------------------------------------------------------
/tutorial 1 - canary release/canary.ingress:
--------------------------------------------------------------------------------
1 | apiVersion: extensions/v1beta1
2 | kind: Ingress
3 | metadata:
4 | name: canary
5 | annotations:
6 | kubernetes.io/ingress.class: nginx
7 | nginx.ingress.kubernetes.io/canary: "true"
8 | nginx.ingress.kubernetes.io/canary-weight: "30"
9 | spec:
10 | rules:
11 | - host: kubesphere.io
12 | http:
13 | paths:
14 | - backend:
15 | serviceName: canary
16 | servicePort: 80
--------------------------------------------------------------------------------
/tutorial 1 - canary release/canary.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: extensions/v1beta1
2 | kind: Deployment
3 | metadata:
4 | name: canary
5 | spec:
6 | replicas: 1
7 | selector:
8 | matchLabels:
9 | app: canary
10 | template:
11 | metadata:
12 | labels:
13 | app: canary
14 | spec:
15 | containers:
16 | - name: canary
17 | image: mirrorgooglecontainers/echoserver:1.10
18 | ports:
19 | - containerPort: 8080
20 | env:
21 | - name: NODE_NAME
22 | valueFrom:
23 | fieldRef:
24 | fieldPath: spec.nodeName
25 | - name: POD_NAME
26 | valueFrom:
27 | fieldRef:
28 | fieldPath: metadata.name
29 | - name: POD_NAMESPACE
30 | valueFrom:
31 | fieldRef:
32 | fieldPath: metadata.namespace
33 | - name: POD_IP
34 | valueFrom:
35 | fieldRef:
36 | fieldPath: status.podIP
37 |
38 | ---
39 |
40 | apiVersion: v1
41 | kind: Service
42 | metadata:
43 | name: canary
44 | labels:
45 | app: canary
46 | spec:
47 | ports:
48 | - port: 80
49 | targetPort: 8080
50 | protocol: TCP
51 | name: http
52 | selector:
53 | app: canary
--------------------------------------------------------------------------------
/tutorial 1 - canary release/production.ingress:
--------------------------------------------------------------------------------
1 | apiVersion: extensions/v1beta1
2 | kind: Ingress
3 | metadata:
4 | name: production
5 | annotations:
6 | kubernetes.io/ingress.class: nginx
7 | spec:
8 | rules:
9 | - host: kubesphere.io
10 | http:
11 | paths:
12 | - backend:
13 | serviceName: production
14 | servicePort: 80
--------------------------------------------------------------------------------
/tutorial 1 - canary release/production.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: extensions/v1beta1
2 | kind: Deployment
3 | metadata:
4 | name: production
5 | spec:
6 | replicas: 1
7 | selector:
8 | matchLabels:
9 | app: production
10 | template:
11 | metadata:
12 | labels:
13 | app: production
14 | spec:
15 | containers:
16 | - name: production
17 | image: mirrorgooglecontainers/echoserver:1.10
18 | ports:
19 | - containerPort: 8080
20 | env:
21 | - name: NODE_NAME
22 | valueFrom:
23 | fieldRef:
24 | fieldPath: spec.nodeName
25 | - name: POD_NAME
26 | valueFrom:
27 | fieldRef:
28 | fieldPath: metadata.name
29 | - name: POD_NAMESPACE
30 | valueFrom:
31 | fieldRef:
32 | fieldPath: metadata.namespace
33 | - name: POD_IP
34 | valueFrom:
35 | fieldRef:
36 | fieldPath: status.podIP
37 |
38 | ---
39 |
40 | apiVersion: v1
41 | kind: Service
42 | metadata:
43 | name: production
44 | labels:
45 | app: production
46 | spec:
47 | ports:
48 | - port: 80
49 | targetPort: 8080
50 | protocol: TCP
51 | name: http
52 | selector:
53 | app: production
--------------------------------------------------------------------------------
/tutorial 2 - local helm repo/redis.tgz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kubesphere/tutorial/9b6596c8b9efdea161329066352cb033d36de599/tutorial 2 - local helm repo/redis.tgz
--------------------------------------------------------------------------------
/tutorial 3 - install-gitlab-harbor/gitlab-harbor.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 |
4 |
5 | BASE_FOLDER=$(dirname $(readlink -f "$0"))
6 |
7 | function menu() {
8 |
9 | title="gitlab-harbor Installer Menu"
10 | url="https://kubesphere.io/"
11 | time=`date +%Y-%m-%d`
12 |
13 | cat << eof
14 |
15 |
16 | ################################################
17 | `echo -e "\033[36m$title\033[0m"`
18 | ################################################
19 | * 1) Harbor
20 | * 2) Gitlab
21 | * 3) Harbor-Gitlab
22 | ################################################
23 | $url $time
24 | ################################################
25 | eof
26 |
27 | }
28 |
29 |
30 | function install-harbor(){
31 | ansible-playbook -i $1 $BASE_FOLDER/../kubesphere/install-gitlab-harbor.yml \
32 | -b \
33 | -e harbor_enable=true
34 | if [[ $? -eq 0 ]]; then
35 | #statements
36 | str="successsful!"
37 | echo -e "\033[30;47m$str\033[0m"
38 | else
39 | str="failed!"
40 | echo -e "\033[31;47m$str\033[0m"
41 | exit
42 | fi
43 | }
44 |
45 | function install-gitlab(){
46 | ansible-playbook -i $1 $BASE_FOLDER/../kubesphere/install-gitlab-harbor.yml \
47 | -b \
48 | -e gitlab_enable=true
49 | if [[ $? -eq 0 ]]; then
50 | #statements
51 | str="successsful!"
52 | echo -e "\033[30;47m$str\033[0m"
53 | else
54 | str="failed!"
55 | echo -e "\033[31;47m$str\033[0m"
56 | exit
57 | fi
58 | }
59 |
60 | function install-gitlab-harbor(){
61 | ansible-playbook -i $1 $BASE_FOLDER/../kubesphere/install-gitlab-harbor.yml \
62 | -b \
63 | -e gitlab_enable=true \
64 | -e harbor_enable=true
65 | if [[ $? -eq 0 ]]; then
66 | #statements
67 | str="successsful!"
68 | echo -e "\033[30;47m$str\033[0m"
69 | else
70 | str="failed!"
71 | echo -e "\033[31;47m$str\033[0m"
72 | exit
73 | fi
74 | }
75 |
76 | function exec(){
77 | menu
78 | # all-in-one tends to install everything on one node.
79 | read -p "Please input an option: " option
80 | echo $option
81 |
82 | case $option in
83 | 1)
84 | install-harbor $1
85 | exit
86 | ;;
87 | 2)
88 | install-gitlab $1
89 | exit
90 | ;;
91 | 3)
92 | install-gitlab-harbor $1
93 | exit
94 | ;;
95 | esac
96 | }
97 |
98 |
99 | function multinode(){
100 | hostmultinode=$BASE_FOLDER/../k8s/inventory/my_cluster/hosts.ini
101 | exec ${hostmultinode}
102 | }
103 |
104 | function allinone(){
105 | hostallinone=$BASE_FOLDER/../k8s/inventory/local/hosts.ini
106 | exec ${hostallinone}
107 | }
108 |
109 | hostname=$(hostname)
110 |
111 | if [[ $hostname != "ks-allinone" ]]; then
112 | multinode
113 | else
114 | allinone
115 | fi
116 |
--------------------------------------------------------------------------------
/tutorial 3 - install-gitlab-harbor/install-gitlab-harbor.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - hosts: k8s-cluster
4 | roles:
5 | - kubesphere-defaults
6 | - prepare/nodes
7 |
8 | - hosts: kube-master[0]
9 | roles:
10 | - kubesphere-defaults
11 | - { role: ks-devops/harbor, when: "harbor_enable|default(false)" }
12 | - { role: ks-devops/gitlab, when: "gitlab_enable|default(false)" }
13 |
--------------------------------------------------------------------------------
/tutorial 4 - s2i-b2i/b2i-binary:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kubesphere/tutorial/9b6596c8b9efdea161329066352cb033d36de599/tutorial 4 - s2i-b2i/b2i-binary
--------------------------------------------------------------------------------
/tutorial 4 - s2i-b2i/b2i-jar-java11.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kubesphere/tutorial/9b6596c8b9efdea161329066352cb033d36de599/tutorial 4 - s2i-b2i/b2i-jar-java11.jar
--------------------------------------------------------------------------------
/tutorial 4 - s2i-b2i/b2i-jar-java8.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kubesphere/tutorial/9b6596c8b9efdea161329066352cb033d36de599/tutorial 4 - s2i-b2i/b2i-jar-java8.jar
--------------------------------------------------------------------------------
/tutorial 4 - s2i-b2i/b2i-war-java11.war:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kubesphere/tutorial/9b6596c8b9efdea161329066352cb033d36de599/tutorial 4 - s2i-b2i/b2i-war-java11.war
--------------------------------------------------------------------------------
/tutorial 4 - s2i-b2i/b2i-war-java8.war:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kubesphere/tutorial/9b6596c8b9efdea161329066352cb033d36de599/tutorial 4 - s2i-b2i/b2i-war-java8.war
--------------------------------------------------------------------------------
/tutorial 5 - app-store/emq-dashboard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kubesphere/tutorial/9b6596c8b9efdea161329066352cb033d36de599/tutorial 5 - app-store/emq-dashboard.png
--------------------------------------------------------------------------------
/tutorial 5 - app-store/emqx-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kubesphere/tutorial/9b6596c8b9efdea161329066352cb033d36de599/tutorial 5 - app-store/emqx-logo.png
--------------------------------------------------------------------------------
/tutorial 5 - app-store/emqx-v1.0.0-beta.1.tgz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kubesphere/tutorial/9b6596c8b9efdea161329066352cb033d36de599/tutorial 5 - app-store/emqx-v1.0.0-beta.1.tgz
--------------------------------------------------------------------------------
/tutorial 5 - app-store/emqx-v1.0.0-beta.2.tgz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kubesphere/tutorial/9b6596c8b9efdea161329066352cb033d36de599/tutorial 5 - app-store/emqx-v1.0.0-beta.2.tgz
--------------------------------------------------------------------------------
/tutorial 5 - app-store/emqx-v1.0.0-rc.1.tgz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kubesphere/tutorial/9b6596c8b9efdea161329066352cb033d36de599/tutorial 5 - app-store/emqx-v1.0.0-rc.1.tgz
--------------------------------------------------------------------------------
/tutorial 5 - app-store/emqx-v4.0.2.tgz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kubesphere/tutorial/9b6596c8b9efdea161329066352cb033d36de599/tutorial 5 - app-store/emqx-v4.0.2.tgz
--------------------------------------------------------------------------------
/tutorial 5 - app-store/redis-11.3.4.tgz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kubesphere/tutorial/9b6596c8b9efdea161329066352cb033d36de599/tutorial 5 - app-store/redis-11.3.4.tgz
--------------------------------------------------------------------------------
/tutorial 5 - app-store/redis-12.0.0.tgz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kubesphere/tutorial/9b6596c8b9efdea161329066352cb033d36de599/tutorial 5 - app-store/redis-12.0.0.tgz
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/6.5.0/6.5.0/apm-springcloud-demo/kdep-apm-eureka.yml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: apm-eureka
5 | namespace: demo
6 | labels:
7 | deploy: apm-eureka
8 | spec:
9 | replicas: 1
10 | selector:
11 | matchLabels:
12 | app: apm-eureka
13 | template:
14 | metadata:
15 | name: apm-eureka
16 | labels:
17 | app: apm-eureka
18 | spec:
19 | initContainers:
20 | - name: sidecar
21 | image: apache/skywalking-base:6.5.0 # 容器镜像,包含静态资源文件
22 | imagePullPolicy: IfNotPresent
23 | command: ["cp", "-r", "/skywalking/agent", "/sidecar"]
24 | volumeMounts:
25 | - name: sidecar
26 | mountPath: /sidecar
27 | containers:
28 | - name: apm-eureka
29 | image: evanxuhe/apm-eureka:6.1.0
30 | imagePullPolicy: IfNotPresent
31 | env:
32 | - name: JAVA_OPTS
33 | value: -javaagent:/sidecar/agent/skywalking-agent.jar
34 | - name: SW_AGENT_NAME
35 | value: apm-eureka
36 | - name: SW_AGENT_COLLECTOR_BACKEND_SERVICES
37 | value: skywalk-1h6lqf-skywalking-skywalking-oap.demo:11800 # skywalk oap 后端服务
38 | ports:
39 | - name: http
40 | containerPort: 8761
41 | volumeMounts:
42 | - name: sidecar
43 | mountPath: /sidecar
44 | volumes:
45 | - name: sidecar #共享agent文件夹
46 | emptyDir: {}
47 | restartPolicy: Always
48 |
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/6.5.0/6.5.0/apm-springcloud-demo/kdep-apm-item.yml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: apm-item
5 | namespace: demo
6 | labels:
7 | app: apm-item
8 | spec:
9 | replicas: 1
10 | selector:
11 | matchLabels:
12 | app: apm-item
13 | template:
14 | metadata:
15 | name: apm-item
16 | labels:
17 | app: apm-item
18 | spec:
19 | initContainers:
20 | - name: sidecar
21 | image: apache/skywalking-base:6.5.0 # 容器镜像,包含静态资源文件
22 | imagePullPolicy: IfNotPresent
23 | command: ["cp", "-r", "/skywalking/agent", "/sidecar"]
24 | volumeMounts:
25 | - name: sidecar
26 | mountPath: /sidecar
27 | containers:
28 | - name: apm-item
29 | image: evanxuhe/apm-item:6.1.0
30 | imagePullPolicy: IfNotPresent
31 | env:
32 | - name: JAVA_OPTS
33 | value: -javaagent:/sidecar/agent/skywalking-agent.jar
34 | - name: SW_AGENT_NAME
35 | value: apm-item
36 | - name: SW_AGENT_COLLECTOR_BACKEND_SERVICES
37 | value: skywalk-1h6lqf-skywalking-skywalking-oap.demo:11800 # skywalk oap 后端服务
38 | - name: EUREKA_HOSTNAME
39 | value: apm-eureka
40 | - name: EUREKA_PORT
41 | value: '8761'
42 | ports:
43 | - name: http
44 | containerPort: 8082
45 | volumeMounts:
46 | - name: sidecar
47 | mountPath: /sidecar
48 | volumes:
49 | - name: sidecar #共享agent文件夹
50 | emptyDir: {}
51 | restartPolicy: Always
52 |
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/6.5.0/6.5.0/apm-springcloud-demo/kser-apm-eureka.yml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: apm-eureka
5 | namespace: demo
6 | labels:
7 | service: apm-eureka
8 | spec:
9 | type: NodePort
10 | selector:
11 | app: apm-eureka
12 | ports:
13 | - port: 8761
14 | name: register
15 | targetPort: 8761
16 | nodePort: 30761
17 | - port: 8080
18 | name: index
19 | targetPort: 8080
20 | nodePort: 30080
21 |
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/6.5.0/6.5.0/apm-springcloud-demo/kser-apm-item.yml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: apm-item
5 | namespace: demo
6 | labels:
7 | service: apm-item
8 | spec:
9 | type: NodePort
10 | selector:
11 | app: apm-item
12 | ports:
13 | - port: 8082
14 | name: item
15 | targetPort: 8082
16 | nodePort: 30082
17 |
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/6.5.0/6.5.0/busybox.yml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: busybox
5 | namespace: skywalking
6 | spec:
7 | selector:
8 | matchLabels:
9 | app: busybox
10 | replicas: 1
11 | template:
12 | metadata:
13 | labels:
14 | app: busybox
15 | spec:
16 | containers:
17 | - name: busybox
18 | image: busybox
19 | resources:
20 | requests:
21 | cpu: 1000m
22 | # ephemeral-storage: 100Ki
23 | memory: 1Gi
24 | limits:
25 | cpu: 1000m
26 | # ephemeral-storage: 100Ki
27 | memory: 1Gi
28 | command:
29 | - sleep
30 | - "3600"
31 | imagePullPolicy: Always
32 | ports:
33 | - containerPort: 80
34 | protocol: TCP
35 |
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/6.5.0/6.5.0/docker/base/Dockerfile:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | FROM openjdk:8-jre-alpine AS build
18 |
19 |
20 | # Install required packages
21 | RUN apk add --no-cache \
22 | bash \
23 | python \
24 | su-exec
25 |
26 | # 时区修改为东八区
27 | RUN apk add --no-cache tzdata
28 | ENV TZ=Asia/Shanghai
29 | RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
30 |
31 | ENV SKYWALKING_HOME=/skywalking
32 | RUN mkdir -p "${SKYWALKING_HOME}"
33 | WORKDIR $SKYWALKING_HOME
34 |
35 | ENV GPG_KEYS A968F6905E0ACB59E5B24C15D3D9CD50820184C2 B0801BC746F965029A1338072EF5026E70A55777 D360AB2AB20B28403270E2CBE8608938DB25E06B
36 | ENV SKYWALKING_VERSION=6.1.0
37 | ENV SKYWALKING_SHA512 54fe85c984c369fd2731aa10190ee7e82e15e2c7c9528234993f6c3d4db34d19735b5467875e20dc3f8476e8d6d56d4fcd6118b4aff49f7b5a7215ee032918c0
38 |
39 | ENV SKYWALKING_TGZ_URLS \
40 | https://www.apache.org/dyn/closer.cgi?action=download&filename=skywalking/$SKYWALKING_VERSION/apache-skywalking-apm-$SKYWALKING_VERSION.tar.gz \
41 | # if the version is outdated, we might have to pull from the dist/archive :/
42 | https://www-us.apache.org/dist/skywalking/$SKYWALKING_VERSION/apache-skywalking-apm-$SKYWALKING_VERSION.tar.gz \
43 | https://www.apache.org/dist/skywalking/$SKYWALKING_VERSION/apache-skywalking-apm-$SKYWALKING_VERSION.tar.gz \
44 | https://archive.apache.org/dist/skywalking/$SKYWALKING_VERSION/apache-skywalking-apm-$SKYWALKING_VERSION.tar.gz
45 |
46 | ENV SKYWALKING_ASC_URLS \
47 | https://www.apache.org/dyn/closer.cgi?action=download&filename=skywalking/$SKYWALKING_VERSION/apache-skywalking-apm-$SKYWALKING_VERSION.tar.gz.asc \
48 | # if the version is outdated, we might have to pull from the dist/archive :/
49 | https://www-us.apache.org/dist/skywalking/$SKYWALKING_VERSION/apache-skywalking-apm-$SKYWALKING_VERSION.tar.gz.asc \
50 | https://www.apache.org/dist/skywalking/$SKYWALKING_VERSION/apache-skywalking-apm-$SKYWALKING_VERSION.tar.gz.asc \
51 | https://archive.apache.org/dist/skywalking/$SKYWALKING_VERSION/apache-skywalking-apm-$SKYWALKING_VERSION.tar.gz.asc
52 |
53 | RUN set -eux; \
54 | \
55 | apk add --no-cache --virtual .fetch-deps \
56 | gnupg \
57 | \
58 | ca-certificates \
59 | openssl \
60 | ; \
61 | \
62 | export GNUPGHOME="$(mktemp -d)"; \
63 | for key in $GPG_KEYS; do \
64 | gpg --batch --keyserver pgp.surfnet.nl --recv-keys "$key"; \
65 | done; \
66 | \
67 | success=; \
68 | for url in $SKYWALKING_TGZ_URLS; do \
69 | if wget -O skywalking.tar.gz "$url"; then \
70 | success=1; \
71 | break; \
72 | fi; \
73 | done; \
74 | [ -n "$success" ]; \
75 | \
76 | echo "$SKYWALKING_SHA512 *skywalking.tar.gz" | sha512sum -c -; \
77 | \
78 | success=; \
79 | for url in $SKYWALKING_ASC_URLS; do \
80 | if wget -O skywalking.tar.gz.asc "$url"; then \
81 | success=1; \
82 | break; \
83 | fi; \
84 | done; \
85 | [ -n "$success" ]; \
86 | \
87 | gpg --batch --verify skywalking.tar.gz.asc skywalking.tar.gz; \
88 | tar -xvf skywalking.tar.gz --strip-components=1; \
89 | rm -rf bin/; \
90 | rm skywalking.tar.gz*; \
91 | command -v gpgconf && gpgconf --kill all || :; \
92 | rm -rf "$GNUPGHOME"; \
93 | apk del .fetch-deps
94 |
95 | FROM openjdk:8-jre-alpine
96 |
97 | COPY --from=build /skywalking /skywalking
98 |
99 | RUN apk add --no-cache \
100 | bash
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/6.5.0/6.5.0/docker/base/build-image.sh:
--------------------------------------------------------------------------------
1 | docker build -t 你的仓库/skywalking/base:6.1.0 .
2 | docker push 你的仓库/skywalking/base:6.1.0
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/6.5.0/6.5.0/docker/oap/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM reg.chehejia.com/chj-k8s-change/public/skywalking/base:6.1.0
2 |
3 | # 时区修改为东八区
4 | RUN apk add --no-cache tzdata
5 | ENV TZ=Asia/Shanghai
6 | RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
7 |
8 | ENV JAVA_OPTS=" -Xms256M " \
9 | SW_CLUSTER="standalone" \
10 | SW_STORAGE="h2"
11 |
12 | WORKDIR skywalking
13 |
14 | RUN set -eux; \
15 | rm -rf "config/log4j2.xml"; \
16 | rm -rf "webapp"; rm -rf "agent";
17 |
18 | COPY log4j2.xml config/
19 | COPY docker-entrypoint.sh .
20 |
21 | EXPOSE 12800 11800 1234
22 |
23 | ENTRYPOINT ["bash", "docker-entrypoint.sh"]
24 |
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/6.5.0/6.5.0/docker/oap/README.md:
--------------------------------------------------------------------------------
1 | # Apache SkyWalking OAP Server Docker Files
2 |
3 |
4 |
5 | **SkyWalking**: an APM(application performance monitor) system, especially designed for
6 | microservices, cloud native and container-based (Docker, Kubernetes, Mesos) architectures.
7 |
8 | # How to use this image
9 |
10 | ## Start a `standlone` container with `H2` storage
11 |
12 | ```
13 | $ docker run --name oap --restart always -d apache/skywalking-oap-server:6.1.0
14 | ```
15 |
16 | ## Start a `standlone` container with `elasticsearch` storage whose address is `elasticsearch:9200`
17 |
18 | ```
19 | $ docker run --name oap --restart always -d -e SW_STORAGE=elasticsearch -e SW_STORAGE_ES_CLUSTER_NODES=elasticsearch:9200 apache/skywalking-oap-server:6.1.0
20 | ```
21 |
22 | # Configuration
23 |
24 | We could set up environment variables to configure this image. Most of them are defined in [backend-setup](https://github.com/apache/skywalking/blob/v6.1.0/docs/en/setup/backend/backend-setup.md), but Apache SkyWalking Docker Image adds extra environment variables to help the user to compose it properly. The details are located in [docker-entrypoint.sh](docker-entrypoint.sh)
25 |
26 | ## SW_CLUSTER
27 | Default value is `standalone`, avaliable values are:
28 |
29 | - `standlone`, If set this value, all enviroment variables of `cluster.standlone` in `application.yml` are avaliable.
30 | - `zookeeper`, If set this value, all enviroment variables of `cluster.zookeeper` in `application.yml` are avaliable.
31 | - `kubernetes`, If set this value, all enviroment variables of `cluster.kubernetes` in `application.yml` are avaliable.
32 | - `consul`, If set this value, all enviroment variables of `cluster.consul` in `application.yml` are avaliable.
33 |
34 | ## SW_STORAGE
35 | Default value is `H2`, avaliable values are:
36 |
37 | - `H2`, If set this value, all enviroment variables of `storage.h2` in `application.yml` are avaliable.
38 | - `elasticsearch`, If set this value, all enviroment variables of `stroage.elasticsearch` in `application.yml` are avaliable.
39 | - `mysql`, If set this value, all enviroment variables of `stroage.mysql` in `application.yml` are avaliable.
40 |
41 | ## XXX_ENABLED
42 |
43 | There are also some other configuration switchers to extend default configuration, they also have a suffix `_ENABLED`.
44 |
45 | - `SW_RECEIVER_ZIPKIN_ENABLED` turns on/off zipkin receiver
46 | - `SW_RECEIVER_JAEGER_ENABLED` turns on/off jaeger receiver
47 | - `SW_EXPORTER_ENABLED` turns on/off exporter
48 |
49 | # License
50 | [Apache 2.0 License.](/LICENSE)
51 |
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/6.5.0/6.5.0/docker/oap/build-image.sh:
--------------------------------------------------------------------------------
1 | docker build -t 你的仓库/skywalking/base:6.1.0 .
2 | docker push 你的仓库/skywalking/base:6.1.0
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/6.5.0/6.5.0/docker/oap/docker-entrypoint.sh:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | #!/bin/bash
18 |
19 | set -e
20 |
21 | var_application_file="config/application.yml"
22 |
23 | generateClusterStandalone() {
24 | echo "cluster:" >> ${var_application_file}
25 | echo " standalone:" >> ${var_application_file}
26 | }
27 |
28 | generateClusterZookeeper() {
29 | cat <> ${var_application_file}
30 | cluster:
31 | zookeeper:
32 | nameSpace: \${SW_NAMESPACE:""}
33 | hostPort: \${SW_CLUSTER_ZK_HOST_PORT:localhost:2181}
34 | #Retry Policy
35 | baseSleepTimeMs: \${SW_CLUSTER_ZK_SLEEP_TIME:1000} # initial amount of time to wait between retries
36 | maxRetries: \${SW_CLUSTER_ZK_MAX_RETRIES:3} # max number of times to retry
37 | EOT
38 | }
39 |
40 | generateClusterK8s() {
41 | cat <> ${var_application_file}
42 | cluster:
43 | kubernetes:
44 | watchTimeoutSeconds: \${SW_CLUSTER_K8S_WATCH_TIMEOUT:60}
45 | namespace: \${SW_CLUSTER_K8S_NAMESPACE:default}
46 | labelSelector: \${SW_CLUSTER_K8S_LABEL:app=collector,release=skywalking}
47 | uidEnvName: \${SW_CLUSTER_K8S_UID:SKYWALKING_COLLECTOR_UID}
48 | EOT
49 | }
50 |
51 | generateClusterConsul() {
52 | cat <> ${var_application_file}
53 | cluster:
54 | consul:
55 | serviceName: \${SW_SERVICE_NAME:"SkyWalking_OAP_Cluster"}
56 | Consul cluster nodes, example: 10.0.0.1:8500,10.0.0.2:8500,10.0.0.3:8500
57 | hostPort: \${SW_CLUSTER_CONSUL_HOST_PORT:localhost:8500}
58 | EOT
59 | }
60 |
61 | generateStorageElastisearch() {
62 | cat <> ${var_application_file}
63 | storage:
64 | elasticsearch:
65 | nameSpace: \${SW_NAMESPACE:""}
66 | clusterNodes: \${SW_STORAGE_ES_CLUSTER_NODES:localhost:9200}
67 | user: \${SW_ES_USER:""}
68 | password: \${SW_ES_PASSWORD:""}
69 | indexShardsNumber: \${SW_STORAGE_ES_INDEX_SHARDS_NUMBER:2}
70 | indexReplicasNumber: \${SW_STORAGE_ES_INDEX_REPLICAS_NUMBER:0}
71 | # Batch process setting, refer to https://www.elastic.co/guide/en/elasticsearch/client/java-api/5.5/java-docs-bulk-processor.html
72 | bulkActions: \${SW_STORAGE_ES_BULK_ACTIONS:2000} # Execute the bulk every 2000 requests
73 | bulkSize: \${SW_STORAGE_ES_BULK_SIZE:20} # flush the bulk every 20mb
74 | flushInterval: \${SW_STORAGE_ES_FLUSH_INTERVAL:10} # flush the bulk every 10 seconds whatever the number of requests
75 | concurrentRequests: \${SW_STORAGE_ES_CONCURRENT_REQUESTS:2} # the number of concurrent requests
76 | metadataQueryMaxSize: \${SW_STORAGE_ES_QUERY_MAX_SIZE:5000}
77 | segmentQueryMaxSize: \${SW_STORAGE_ES_QUERY_SEGMENT_SIZE:200}
78 | EOT
79 | }
80 |
81 | generateStorageH2() {
82 | cat <> ${var_application_file}
83 | storage:
84 | h2:
85 | driver: \${SW_STORAGE_H2_DRIVER:org.h2.jdbcx.JdbcDataSource}
86 | url: \${SW_STORAGE_H2_URL:jdbc:h2:mem:skywalking-oap-db}
87 | user: \${SW_STORAGE_H2_USER:sa}
88 | metadataQueryMaxSize: \${SW_STORAGE_H2_QUERY_MAX_SIZE:5000}
89 | EOT
90 | }
91 |
92 | generateStorageMySQL() {
93 | cat <> ${var_application_file}
94 | storage:
95 | mysql:
96 | metadataQueryMaxSize: \${SW_STORAGE_H2_QUERY_MAX_SIZE:5000}
97 | EOT
98 | }
99 |
100 | validateVariables() {
101 | name=$1; value=$2; list=$3
102 | valid=false
103 | for c in ${list} ; do
104 | if [[ "$c" = "$value" ]]; then
105 | valid=true
106 | fi
107 | done
108 |
109 | if ! ${valid}; then
110 | echo "Error: $name=$value please specify $name = $list"
111 | exit 1
112 | fi
113 | }
114 |
115 | generateApplicationYaml() {
116 | # validate
117 | [[ -z "$SW_CLUSTER" ]] && [[ -z "$SW_STORAGE" ]] && { echo "Error: please specify \"SW_CLUSTER\" \"SW_STORAGE\""; exit 1; }
118 |
119 | validateVariables "SW_CLUSTER" "$SW_CLUSTER" "standalone zookeeper kubernetes consul"
120 |
121 | validateVariables "SW_STORAGE" "$SW_STORAGE" "elasticsearch h2 mysql"
122 |
123 | echo "# Generated by 'docker-entrypoint.sh'" > ${var_application_file}
124 | #generate cluster
125 | case ${SW_CLUSTER} in
126 | standalone) generateClusterStandalone;;
127 | zookeeper) generateClusterZookeeper;;
128 | kubernetes) generateClusterK8s;;
129 | consul) generateClusterConsul;;
130 | esac
131 |
132 | #generate core
133 | cat <> ${var_application_file}
134 | core:
135 | default:
136 | # Mixed: Receive agent data, Level 1 aggregate, Level 2 aggregate
137 | # Receiver: Receive agent data, Level 1 aggregate
138 | # Aggregator: Level 2 aggregate
139 | role: \${SW_CORE_ROLE:Mixed} # Mixed/Receiver/Aggregator
140 | restHost: \${SW_CORE_REST_HOST:0.0.0.0}
141 | restPort: \${SW_CORE_REST_PORT:12800}
142 | restContextPath: \${SW_CORE_REST_CONTEXT_PATH:/}
143 | gRPCHost: \${SW_CORE_GRPC_HOST:0.0.0.0}
144 | gRPCPort: \${SW_CORE_GRPC_PORT:11800}
145 | downsampling:
146 | - Hour
147 | - Day
148 | - Month
149 | # Set a timeout on metrics data. After the timeout has expired, the metrics data will automatically be deleted.
150 | recordDataTTL: \${SW_CORE_RECORD_DATA_TTL:90} # Unit is minute
151 | minuteMetricsDataTTL: \${SW_CORE_MINUTE_METRIC_DATA_TTL:90} # Unit is minute
152 | hourMetricsDataTTL: \${SW_CORE_HOUR_METRIC_DATA_TTL:36} # Unit is hour
153 | dayMetricsDataTTL: \${SW_CORE_DAY_METRIC_DATA_TTL:45} # Unit is day
154 | monthMetricsDataTTL: \${SW_CORE_MONTH_METRIC_DATA_TTL:18} # Unit is month
155 | EOT
156 |
157 | # generate storage
158 | case ${SW_STORAGE} in
159 | elasticsearch) generateStorageElastisearch;;
160 | h2) generateStorageH2;;
161 | mysql) generateStorageMySQL;;
162 | esac
163 |
164 | cat <> ${var_application_file}
165 | receiver-sharing-server:
166 | default:
167 | receiver-register:
168 | default:
169 | receiver-trace:
170 | default:
171 | bufferPath: \${SW_RECEIVER_BUFFER_PATH:../trace-buffer/} # Path to trace buffer files, suggest to use absolute path
172 | bufferOffsetMaxFileSize: \${SW_RECEIVER_BUFFER_OFFSET_MAX_FILE_SIZE:100} # Unit is MB
173 | bufferDataMaxFileSize: \${SW_RECEIVER_BUFFER_DATA_MAX_FILE_SIZE:500} # Unit is MB
174 | bufferFileCleanWhenRestart: \${SW_RECEIVER_BUFFER_FILE_CLEAN_WHEN_RESTART:false}
175 | sampleRate: \${SW_TRACE_SAMPLE_RATE:10000} # The sample rate precision is 1/10000. 10000 means 100% sample in default.
176 | slowDBAccessThreshold: \${SW_SLOW_DB_THRESHOLD:default:200,mongodb:100} # The slow database access thresholds. Unit ms.
177 | receiver-jvm:
178 | default:
179 | receiver-clr:
180 | default:
181 | service-mesh:
182 | default:
183 | bufferPath: \${SW_SERVICE_MESH_BUFFER_PATH:../mesh-buffer/} # Path to trace buffer files, suggest to use absolute path
184 | bufferOffsetMaxFileSize: \${SW_SERVICE_MESH_OFFSET_MAX_FILE_SIZE:100} # Unit is MB
185 | bufferDataMaxFileSize: \${SW_SERVICE_MESH_BUFFER_DATA_MAX_FILE_SIZE:500} # Unit is MB
186 | bufferFileCleanWhenRestart: \${SW_SERVICE_MESH_BUFFER_FILE_CLEAN_WHEN_RESTART:false}
187 | istio-telemetry:
188 | default:
189 | envoy-metric:
190 | default:
191 | query:
192 | graphql:
193 | path: \${SW_QUERY_GRAPHQL_PATH:/graphql}
194 | alarm:
195 | default:
196 | telemetry:
197 | prometheus:
198 | host: \${SW_TELEMETRY_PROMETHEUS_HOST:0.0.0.0}
199 | port: \${SW_TELEMETRY_PROMETHEUS_PORT:1234}
200 | EOT
201 |
202 | if [[ "$SW_RECEIVER_ZIPKIN_ENABLED" = "true" ]]; then
203 | cat <> ${var_application_file}
204 | receiver_zipkin:
205 | default:
206 | host: \${SW_RECEIVER_ZIPKIN_HOST:0.0.0.0}
207 | port: \${SW_RECEIVER_ZIPKIN_PORT:9411}
208 | contextPath: \${SW_RECEIVER_ZIPKIN_CONTEXT_PATH:/}
209 | EOT
210 | fi
211 |
212 | if [[ "$SW_RECEIVER_JAEGER_ENABLED" = "true" ]]; then
213 | cat <> ${var_application_file}
214 | receiver_jaeger:
215 | default:
216 | gRPCHost: \${SW_RECEIVER_JAEGER_HOST:0.0.0.0}
217 | gRPCPort: \${SW_RECEIVER_JAEGER_PORT:14250}
218 | EOT
219 | fi
220 |
221 | if [[ "$SW_EXPORTER_ENABLED" = "true" ]]; then
222 | cat <> \${var_application_file}
223 | exporter:
224 | grpc:
225 | targetHost: \${SW_EXPORTER_GRPC_HOST:127.0.0.1}
226 | targetPort: \${SW_EXPORTER_GRPC_PORT:9870}
227 | EOT
228 | fi
229 | }
230 |
231 | echo "[Entrypoint] Apache SkyWalking Docker Image"
232 |
233 | if [[ -z "$SW_L0AD_CONFIG_FILE_FROM_VOLUME" ]] || [[ "$SW_L0AD_CONFIG_FILE_FROM_VOLUME" != "true" ]]; then
234 | generateApplicationYaml
235 | echo "Generated application.yml"
236 | echo "-------------------------"
237 | cat ${var_application_file}
238 | echo "-------------------------"
239 | fi
240 |
241 | CLASSPATH="config:$CLASSPATH"
242 | for i in oap-libs/*.jar
243 | do
244 | CLASSPATH="$i:$CLASSPATH"
245 | done
246 |
247 | exec java -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap \
248 | ${JAVA_OPTS} -classpath ${CLASSPATH} org.apache.skywalking.oap.server.starter.OAPServerStartUp "$@"
249 |
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/6.5.0/6.5.0/docker/oap/log4j2.xml:
--------------------------------------------------------------------------------
1 |
2 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/6.5.0/6.5.0/docker/ui/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM reg.chehejia.com/chj-k8s-change/public/skywalking/base:6.1.0
2 |
3 | # 时区修改为东八区
4 | RUN apk add --no-cache tzdata
5 | ENV TZ=Asia/Shanghai
6 | RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
7 |
8 | ENV JAVA_OPTS=" -Xms256M " \
9 | SW_OAP_ADDRESS="127.0.0.1:12800" \
10 | SW_TIMEOUT="20000"
11 |
12 | WORKDIR skywalking
13 |
14 | RUN set -eux; \
15 | rm -rf "config"; rm -rf "oap-libs"; \
16 | rm -rf "agent";
17 |
18 | COPY docker-entrypoint.sh .
19 | COPY logback.xml webapp/
20 |
21 | EXPOSE 8080
22 |
23 | ENTRYPOINT ["bash", "docker-entrypoint.sh"]
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/6.5.0/6.5.0/docker/ui/README.md:
--------------------------------------------------------------------------------
1 | # Apache SkyWalking UI Docker Files
2 |
3 |
4 |
5 | **SkyWalking**: an APM(application performance monitor) system, especially designed for
6 | microservices, cloud native and container-based (Docker, Kubernetes, Mesos) architectures.
7 |
8 | # How to use this image
9 |
10 | ## Start a container to connect oap server whose address is `oap:12800`
11 |
12 | ```
13 | $ docker run --name oap --restart always -d -e SW_OAP_ADDRESS=oap:12800 apache/skywalking-ui:6.1.0
14 | ```
15 |
16 | # Configuration
17 |
18 | We could set up environment variables to configure this image.
19 |
20 | ## SW_OAP_ADDRESS
21 | The address of OAP server. Default value is `127.0.0.1:12800`.
22 |
23 | ## SW_TIMEOUT
24 | Reading timeout. Default value is `20000`(millisecond).
25 |
26 | # License
27 | [Apache 2.0 License.](/LICENSE)
28 |
29 |
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/6.5.0/6.5.0/docker/ui/build-image.sh:
--------------------------------------------------------------------------------
1 | docker build -t 你的仓库/skywalking/base:6.1.0 .
2 | docker push 你的仓库/skywalking/base:6.1.0
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/6.5.0/6.5.0/docker/ui/docker-entrypoint.sh:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | #!/bin/bash
18 |
19 | set -e
20 |
21 | export LOGGING_CONFIG="webapp/logback.xml"
22 |
23 | [[ ! -z "$SW_OAP_ADDRESS" ]] && export COLLECTOR_RIBBON_LISTOFSERVERS=${SW_OAP_ADDRESS} && echo "COLLECTOR_RIBBON_LISTOFSERVERS=$COLLECTOR_RIBBON_LISTOFSERVERS"
24 | [[ ! -z "$SW_TIMEOUT" ]] && export COLLECTOR_RIBBON_READTIMEOUT=${SW_TIMEOUT} && echo "COLLECTOR_RIBBON_READTIMEOUT=$COLLECTOR_RIBBON_READTIMEOUT"
25 |
26 | exec java -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -jar webapp/skywalking-webapp.jar "$@"
27 |
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/6.5.0/6.5.0/docker/ui/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/6.5.0/6.5.0/elasticsearch/01-pv.yml:
--------------------------------------------------------------------------------
1 | # 在node xuhe-latop
2 | # 上创建一个本地磁盘local-pv 对应的本地路径为/data
3 | apiVersion: v1
4 | kind: PersistentVolume
5 | metadata:
6 | name: local-pv
7 | spec:
8 | capacity:
9 | storage: 100Gi
10 | accessModes:
11 | - ReadWriteOnce
12 | persistentVolumeReclaimPolicy: Retain
13 | storageClassName: local-storage
14 | local:
15 | #修改这里为本地路径
16 | path: /data
17 | nodeAffinity:
18 | required:
19 | nodeSelectorTerms:
20 | - matchExpressions:
21 | - key: kubernetes.io/hostname
22 | operator: In
23 | #这里修改为节点名,也就是你电脑的hostname
24 | values:
25 | - xuhe-laptop
26 |
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/6.5.0/6.5.0/elasticsearch/01-storageclass.yml:
--------------------------------------------------------------------------------
1 | kind: StorageClass
2 | apiVersion: storage.k8s.io/v1
3 | metadata:
4 | name: local-storage
5 | provisioner: kubernetes.io/no-provisioner
6 | volumeBindingMode: WaitForFirstConsumer
7 |
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/6.5.0/6.5.0/elasticsearch/02-service.yml:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | apiVersion: v1
18 | kind: Service
19 | metadata:
20 | name: elasticsearch
21 | namespace: skywalking
22 | labels:
23 | service: elasticsearch
24 | spec:
25 | clusterIP: None
26 | ports:
27 | - port: 9200
28 | name: serving
29 | - port: 9300
30 | name: node-to-node
31 | selector:
32 | service: elasticsearch
33 |
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/6.5.0/6.5.0/elasticsearch/03-statefulset.yml:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | apiVersion: apps/v1
18 | kind: StatefulSet
19 | metadata:
20 | name: elasticsearch
21 | namespace: skywalking
22 | labels:
23 | service: elasticsearch
24 | spec:
25 | serviceName: elasticsearch
26 | # NOTE: This is number of nodes that we want to run
27 | # you may update this
28 | replicas: 1
29 | selector:
30 | matchLabels:
31 | service: elasticsearch
32 | template:
33 | metadata:
34 | labels:
35 | service: elasticsearch
36 | spec:
37 | terminationGracePeriodSeconds: 300
38 | initContainers:
39 | # NOTE:
40 | # This is to fix the permission on the volume
41 | # By default elasticsearch container is not run as
42 | # non root user.
43 | # https://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html#_notes_for_production_use_and_defaults
44 | - name: fix-the-volume-permission
45 | image: busybox
46 | imagePullPolicy: IfNotPresent
47 | command:
48 | - sh
49 | - -c
50 | - chown -R 1000:1000 /usr/share/elasticsearch/data
51 | securityContext:
52 | privileged: true
53 | volumeMounts:
54 | - name: data
55 | mountPath: /usr/share/elasticsearch/data
56 | # NOTE:
57 | # To increase the default vm.max_map_count to 262144
58 | # https://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html#docker-cli-run-prod-mode
59 | - name: increase-the-vm-max-map-count
60 | image: busybox
61 | imagePullPolicy: IfNotPresent
62 | command:
63 | - sysctl
64 | - -w
65 | - vm.max_map_count=262144
66 | securityContext:
67 | privileged: true
68 | # To increase the ulimit
69 | # https://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html#_notes_for_production_use_and_defaults
70 | - name: increase-the-ulimit
71 | image: busybox
72 | imagePullPolicy: IfNotPresent
73 | command:
74 | - sh
75 | - -c
76 | - ulimit -n 65536
77 | securityContext:
78 | privileged: true
79 | containers:
80 | - name: elasticsearch
81 | image: docker.elastic.co/elasticsearch/elasticsearch-oss:6.3.2
82 | imagePullPolicy: IfNotPresent
83 | ports:
84 | - containerPort: 9200
85 | name: http
86 | - containerPort: 9300
87 | name: tcp
88 | # NOTE: you can increase this resources
89 | resources:
90 | requests:
91 | memory: 4Gi
92 | limits:
93 | memory: 4Gi
94 | env:
95 | # NOTE: the cluster name; update this
96 | - name: cluster.name
97 | value: elasticsearch-cluster
98 | - name: node.name
99 | valueFrom:
100 | fieldRef:
101 | fieldPath: metadata.name
102 | # NOTE: This will tell the elasticsearch node where to connect to other nodes to form a cluster
103 | - name: discovery.zen.ping.unicast.hosts
104 | value: elasticsearch:9300
105 | # NOTE: You can increase the heap size
106 | - name: ES_JAVA_OPTS
107 | value: -Xms3g -Xmx3g
108 | volumeMounts:
109 | - name: data
110 | mountPath: /usr/share/elasticsearch/data
111 | volumeClaimTemplates:
112 | - metadata:
113 | name: data
114 | spec:
115 | accessModes:
116 | - ReadWriteOnce
117 | storageClassName: local-storage
118 | # NOTE: You can increase the storage size
119 | resources:
120 | requests:
121 | storage: 50Gi
122 |
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/6.5.0/6.5.0/istio/01-metrictemplate.yml:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | apiVersion: "config.istio.io/v1alpha2"
18 | kind: template
19 | metadata:
20 | name: metric
21 | namespace: istio-system
22 | spec:
23 | descriptor: "CsD3AgogZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8SD2dvb2dsZS5wcm90b2J1ZiJNChFGaWxlRGVzY3JpcHRvclNldBI4CgRmaWxlGAEgAygLMiQuZ29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG9SBGZpbGUi5AQKE0ZpbGVEZXNjcmlwdG9yUHJvdG8SEgoEbmFtZRgBIAEoCVIEbmFtZRIYCgdwYWNrYWdlGAIgASgJUgdwYWNrYWdlEh4KCmRlcGVuZGVuY3kYAyADKAlSCmRlcGVuZGVuY3kSKwoRcHVibGljX2RlcGVuZGVuY3kYCiADKAVSEHB1YmxpY0RlcGVuZGVuY3kSJwoPd2Vha19kZXBlbmRlbmN5GAsgAygFUg53ZWFrRGVwZW5kZW5jeRJDCgxtZXNzYWdlX3R5cGUYBCADKAsyIC5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvUgttZXNzYWdlVHlwZRJBCgllbnVtX3R5cGUYBSADKAsyJC5nb29nbGUucHJvdG9idWYuRW51bURlc2NyaXB0b3JQcm90b1IIZW51bVR5cGUSQQoHc2VydmljZRgGIAMoCzInLmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvUgdzZXJ2aWNlEkMKCWV4dGVuc2lvbhgHIAMoCzIlLmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90b1IJZXh0ZW5zaW9uEjYKB29wdGlvbnMYCCABKAsyHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnNSB29wdGlvbnMSSQoQc291cmNlX2NvZGVfaW5mbxgJIAEoCzIfLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mb1IOc291cmNlQ29kZUluZm8SFgoGc3ludGF4GAwgASgJUgZzeW50YXgiuQYKD0Rlc2NyaXB0b3JQcm90bxISCgRuYW1lGAEgASgJUgRuYW1lEjsKBWZpZWxkGAIgAygLMiUuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvUgVmaWVsZBJDCglleHRlbnNpb24YBiADKAsyJS5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG9SCWV4dGVuc2lvbhJBCgtuZXN0ZWRfdHlwZRgDIAMoCzIgLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9SCm5lc3RlZFR5cGUSQQoJZW51bV90eXBlGAQgAygLMiQuZ29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG9SCGVudW1UeXBlElgKD2V4dGVuc2lvbl9yYW5nZRgFIAMoCzIvLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uRXh0ZW5zaW9uUmFuZ2VSDmV4dGVuc2lvblJhbmdlEkQKCm9uZW9mX2RlY2wYCCADKAsyJS5nb29nbGUucHJvdG9idWYuT25lb2ZEZXNjcmlwdG9yUHJvdG9SCW9uZW9mRGVjbBI5CgdvcHRpb25zGAcgASgLMh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zUgdvcHRpb25zElUKDnJlc2VydmVkX3JhbmdlGAkgAygLMi4uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5SZXNlcnZlZFJhbmdlUg1yZXNlcnZlZFJhbmdlEiMKDXJlc2VydmVkX25hbWUYCiADKAlSDHJlc2VydmVkTmFtZRp6Cg5FeHRlbnNpb25SYW5nZRIUCgVzdGFydBgBIAEoBVIFc3RhcnQSEAoDZW5kGAIgASgFUgNlbmQSQAoHb3B0aW9ucxgDIAEoCzImLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SYW5nZU9wdGlvbnNSB29wdGlvbnMaNwoNUmVzZXJ2ZWRSYW5nZRIUCgVzdGFydBgBIAEoBVIFc3RhcnQSEAoDZW5kGAIgASgFUgNlbmQifAoVRXh0ZW5zaW9uUmFuZ2VPcHRpb25zElgKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uUhN1bmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIimAYKFEZpZWxkRGVzY3JpcHRvclByb3RvEhIKBG5hbWUYASABKAlSBG5hbWUSFgoGbnVtYmVyGAMgASgFUgZudW1iZXISQQoFbGFiZWwYBCABKA4yKy5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uTGFiZWxSBWxhYmVsEj4KBHR5cGUYBSABKA4yKi5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uVHlwZVIEdHlwZRIbCgl0eXBlX25hbWUYBiABKAlSCHR5cGVOYW1lEhoKCGV4dGVuZGVlGAIgASgJUghleHRlbmRlZRIjCg1kZWZhdWx0X3ZhbHVlGAcgASgJUgxkZWZhdWx0VmFsdWUSHwoLb25lb2ZfaW5kZXgYCSABKAVSCm9uZW9mSW5kZXgSGwoJanNvbl9uYW1lGAogASgJUghqc29uTmFtZRI3CgdvcHRpb25zGAggASgLMh0uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9uc1IHb3B0aW9ucyK2AgoEVHlwZRIPCgtUWVBFX0RPVUJMRRABEg4KClRZUEVfRkxPQVQQAhIOCgpUWVBFX0lOVDY0EAMSDwoLVFlQRV9VSU5UNjQQBBIOCgpUWVBFX0lOVDMyEAUSEAoMVFlQRV9GSVhFRDY0EAYSEAoMVFlQRV9GSVhFRDMyEAcSDQoJVFlQRV9CT09MEAgSDwoLVFlQRV9TVFJJTkcQCRIOCgpUWVBFX0dST1VQEAoSEAoMVFlQRV9NRVNTQUdFEAsSDgoKVFlQRV9CWVRFUxAMEg8KC1RZUEVfVUlOVDMyEA0SDQoJVFlQRV9FTlVNEA4SEQoNVFlQRV9TRklYRUQzMhAPEhEKDVRZUEVfU0ZJWEVENjQQEBIPCgtUWVBFX1NJTlQzMhAREg8KC1RZUEVfU0lOVDY0EBIiQwoFTGFiZWwSEgoOTEFCRUxfT1BUSU9OQUwQARISCg5MQUJFTF9SRVFVSVJFRBACEhIKDkxBQkVMX1JFUEVBVEVEEAMiYwoUT25lb2ZEZXNjcmlwdG9yUHJvdG8SEgoEbmFtZRgBIAEoCVIEbmFtZRI3CgdvcHRpb25zGAIgASgLMh0uZ29vZ2xlLnByb3RvYnVmLk9uZW9mT3B0aW9uc1IHb3B0aW9ucyLjAgoTRW51bURlc2NyaXB0b3JQcm90bxISCgRuYW1lGAEgASgJUgRuYW1lEj8KBXZhbHVlGAIgAygLMikuZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZURlc2NyaXB0b3JQcm90b1IFdmFsdWUSNgoHb3B0aW9ucxgDIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9uc1IHb3B0aW9ucxJdCg5yZXNlcnZlZF9yYW5nZRgEIAMoCzI2Lmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvLkVudW1SZXNlcnZlZFJhbmdlUg1yZXNlcnZlZFJhbmdlEiMKDXJlc2VydmVkX25hbWUYBSADKAlSDHJlc2VydmVkTmFtZRo7ChFFbnVtUmVzZXJ2ZWRSYW5nZRIUCgVzdGFydBgBIAEoBVIFc3RhcnQSEAoDZW5kGAIgASgFUgNlbmQigwEKGEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bxISCgRuYW1lGAEgASgJUgRuYW1lEhYKBm51bWJlchgCIAEoBVIGbnVtYmVyEjsKB29wdGlvbnMYAyABKAsyIS5nb29nbGUucHJvdG9idWYuRW51bVZhbHVlT3B0aW9uc1IHb3B0aW9ucyKnAQoWU2VydmljZURlc2NyaXB0b3JQcm90bxISCgRuYW1lGAEgASgJUgRuYW1lEj4KBm1ldGhvZBgCIAMoCzImLmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG9SBm1ldGhvZBI5CgdvcHRpb25zGAMgASgLMh8uZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zUgdvcHRpb25zIokCChVNZXRob2REZXNjcmlwdG9yUHJvdG8SEgoEbmFtZRgBIAEoCVIEbmFtZRIdCgppbnB1dF90eXBlGAIgASgJUglpbnB1dFR5cGUSHwoLb3V0cHV0X3R5cGUYAyABKAlSCm91dHB1dFR5cGUSOAoHb3B0aW9ucxgEIAEoCzIeLmdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zUgdvcHRpb25zEjAKEGNsaWVudF9zdHJlYW1pbmcYBSABKAg6BWZhbHNlUg9jbGllbnRTdHJlYW1pbmcSMAoQc2VydmVyX3N0cmVhbWluZxgGIAEoCDoFZmFsc2VSD3NlcnZlclN0cmVhbWluZyKzCAoLRmlsZU9wdGlvbnMSIQoMamF2YV9wYWNrYWdlGAEgASgJUgtqYXZhUGFja2FnZRIwChRqYXZhX291dGVyX2NsYXNzbmFtZRgIIAEoCVISamF2YU91dGVyQ2xhc3NuYW1lEjUKE2phdmFfbXVsdGlwbGVfZmlsZXMYCiABKAg6BWZhbHNlUhFqYXZhTXVsdGlwbGVGaWxlcxJECh1qYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaBgUIAEoCEICGAFSGWphdmFHZW5lcmF0ZUVxdWFsc0FuZEhhc2gSOgoWamF2YV9zdHJpbmdfY2hlY2tfdXRmOBgbIAEoCDoFZmFsc2VSE2phdmFTdHJpbmdDaGVja1V0ZjgSUwoMb3B0aW1pemVfZm9yGAkgASgOMikuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLk9wdGltaXplTW9kZToFU1BFRURSC29wdGltaXplRm9yEh0KCmdvX3BhY2thZ2UYCyABKAlSCWdvUGFja2FnZRI1ChNjY19nZW5lcmljX3NlcnZpY2VzGBAgASgIOgVmYWxzZVIRY2NHZW5lcmljU2VydmljZXMSOQoVamF2YV9nZW5lcmljX3NlcnZpY2VzGBEgASgIOgVmYWxzZVITamF2YUdlbmVyaWNTZXJ2aWNlcxI1ChNweV9nZW5lcmljX3NlcnZpY2VzGBIgASgIOgVmYWxzZVIRcHlHZW5lcmljU2VydmljZXMSNwoUcGhwX2dlbmVyaWNfc2VydmljZXMYKiABKAg6BWZhbHNlUhJwaHBHZW5lcmljU2VydmljZXMSJQoKZGVwcmVjYXRlZBgXIAEoCDoFZmFsc2VSCmRlcHJlY2F0ZWQSLwoQY2NfZW5hYmxlX2FyZW5hcxgfIAEoCDoFZmFsc2VSDmNjRW5hYmxlQXJlbmFzEioKEW9iamNfY2xhc3NfcHJlZml4GCQgASgJUg9vYmpjQ2xhc3NQcmVmaXgSKQoQY3NoYXJwX25hbWVzcGFjZRglIAEoCVIPY3NoYXJwTmFtZXNwYWNlEiEKDHN3aWZ0X3ByZWZpeBgnIAEoCVILc3dpZnRQcmVmaXgSKAoQcGhwX2NsYXNzX3ByZWZpeBgoIAEoCVIOcGhwQ2xhc3NQcmVmaXgSIwoNcGhwX25hbWVzcGFjZRgpIAEoCVIMcGhwTmFtZXNwYWNlElgKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uUhN1bmludGVycHJldGVkT3B0aW9uIjoKDE9wdGltaXplTW9kZRIJCgVTUEVFRBABEg0KCUNPREVfU0laRRACEhAKDExJVEVfUlVOVElNRRADKgkI6AcQgICAgAIixQIKDk1lc3NhZ2VPcHRpb25zEjwKF21lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0GAEgASgIOgVmYWxzZVIUbWVzc2FnZVNldFdpcmVGb3JtYXQSTAofbm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvchgCIAEoCDoFZmFsc2VSHG5vU3RhbmRhcmREZXNjcmlwdG9yQWNjZXNzb3ISJQoKZGVwcmVjYXRlZBgDIAEoCDoFZmFsc2VSCmRlcHJlY2F0ZWQSGwoJbWFwX2VudHJ5GAcgASgIUghtYXBFbnRyeRJYChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvblITdW5pbnRlcnByZXRlZE9wdGlvbioJCOgHEICAgIACItwDCgxGaWVsZE9wdGlvbnMSQQoFY3R5cGUYASABKA4yIy5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLkNUeXBlOgZTVFJJTkdSBWN0eXBlEhYKBnBhY2tlZBgCIAEoCFIGcGFja2VkEkcKBmpzdHlwZRgGIAEoDjIkLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuSlNUeXBlOglKU19OT1JNQUxSBmpzdHlwZRIZCgRsYXp5GAUgASgIOgVmYWxzZVIEbGF6eRIlCgpkZXByZWNhdGVkGAMgASgIOgVmYWxzZVIKZGVwcmVjYXRlZBIZCgR3ZWFrGAogASgIOgVmYWxzZVIEd2VhaxJYChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvblITdW5pbnRlcnByZXRlZE9wdGlvbiIvCgVDVHlwZRIKCgZTVFJJTkcQABIICgRDT1JEEAESEAoMU1RSSU5HX1BJRUNFEAIiNQoGSlNUeXBlEg0KCUpTX05PUk1BTBAAEg0KCUpTX1NUUklORxABEg0KCUpTX05VTUJFUhACKgkI6AcQgICAgAIicwoMT25lb2ZPcHRpb25zElgKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uUhN1bmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIiugEKC0VudW1PcHRpb25zEh8KC2FsbG93X2FsaWFzGAIgASgIUgphbGxvd0FsaWFzEiUKCmRlcHJlY2F0ZWQYAyABKAg6BWZhbHNlUgpkZXByZWNhdGVkElgKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uUhN1bmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIingEKEEVudW1WYWx1ZU9wdGlvbnMSJQoKZGVwcmVjYXRlZBgBIAEoCDoFZmFsc2VSCmRlcHJlY2F0ZWQSWAoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb25SE3VuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAiKcAQoOU2VydmljZU9wdGlvbnMSJQoKZGVwcmVjYXRlZBghIAEoCDoFZmFsc2VSCmRlcHJlY2F0ZWQSWAoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb25SE3VuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAiLgAgoNTWV0aG9kT3B0aW9ucxIlCgpkZXByZWNhdGVkGCEgASgIOgVmYWxzZVIKZGVwcmVjYXRlZBJxChFpZGVtcG90ZW5jeV9sZXZlbBgiIAEoDjIvLmdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zLklkZW1wb3RlbmN5TGV2ZWw6E0lERU1QT1RFTkNZX1VOS05PV05SEGlkZW1wb3RlbmN5TGV2ZWwSWAoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb25SE3VuaW50ZXJwcmV0ZWRPcHRpb24iUAoQSWRlbXBvdGVuY3lMZXZlbBIXChNJREVNUE9URU5DWV9VTktOT1dOEAASEwoPTk9fU0lERV9FRkZFQ1RTEAESDgoKSURFTVBPVEVOVBACKgkI6AcQgICAgAIimgMKE1VuaW50ZXJwcmV0ZWRPcHRpb24SQQoEbmFtZRgCIAMoCzItLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLk5hbWVQYXJ0UgRuYW1lEikKEGlkZW50aWZpZXJfdmFsdWUYAyABKAlSD2lkZW50aWZpZXJWYWx1ZRIsChJwb3NpdGl2ZV9pbnRfdmFsdWUYBCABKARSEHBvc2l0aXZlSW50VmFsdWUSLAoSbmVnYXRpdmVfaW50X3ZhbHVlGAUgASgDUhBuZWdhdGl2ZUludFZhbHVlEiEKDGRvdWJsZV92YWx1ZRgGIAEoAVILZG91YmxlVmFsdWUSIQoMc3RyaW5nX3ZhbHVlGAcgASgMUgtzdHJpbmdWYWx1ZRInCg9hZ2dyZWdhdGVfdmFsdWUYCCABKAlSDmFnZ3JlZ2F0ZVZhbHVlGkoKCE5hbWVQYXJ0EhsKCW5hbWVfcGFydBgBIAIoCVIIbmFtZVBhcnQSIQoMaXNfZXh0ZW5zaW9uGAIgAigIUgtpc0V4dGVuc2lvbiKnAgoOU291cmNlQ29kZUluZm8SRAoIbG9jYXRpb24YASADKAsyKC5nb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb25SCGxvY2F0aW9uGs4BCghMb2NhdGlvbhIWCgRwYXRoGAEgAygFQgIQAVIEcGF0aBIWCgRzcGFuGAIgAygFQgIQAVIEc3BhbhIpChBsZWFkaW5nX2NvbW1lbnRzGAMgASgJUg9sZWFkaW5nQ29tbWVudHMSKwoRdHJhaWxpbmdfY29tbWVudHMYBCABKAlSEHRyYWlsaW5nQ29tbWVudHMSOgoZbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cxgGIAMoCVIXbGVhZGluZ0RldGFjaGVkQ29tbWVudHMi0QEKEUdlbmVyYXRlZENvZGVJbmZvEk0KCmFubm90YXRpb24YASADKAsyLS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8uQW5ub3RhdGlvblIKYW5ub3RhdGlvbhptCgpBbm5vdGF0aW9uEhYKBHBhdGgYASADKAVCAhABUgRwYXRoEh8KC3NvdXJjZV9maWxlGAIgASgJUgpzb3VyY2VGaWxlEhQKBWJlZ2luGAMgASgFUgViZWdpbhIQCgNlbmQYBCABKAVSA2VuZEJbChNjb20uZ29vZ2xlLnByb3RvYnVmQhBEZXNjcmlwdG9yUHJvdG9zSAFaCmRlc2NyaXB0b3L4AQGiAgNHUEKqAhpHb29nbGUuUHJvdG9idWYuUmVmbGVjdGlvbkrNvQIKBxIFJwDlBgEKqg8KAQwSAycAEjLBDCBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgogaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KCiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKIG1ldDoKCiAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAogbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgogICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQogY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgogaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQogZGlzdHJpYnV0aW9uLgogICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cwogY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUwogIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgogQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCiBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQogT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJ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IG1lc3NhZ2UgY2FsbGVkIHVuaW50ZXJwcmV0ZWRfb3B0aW9uLiBUaGlzIGZpZWxkIG11c3QgaGF2ZSB0aGUgc2FtZSBuYW1lCiBhY3Jvc3MgYWxsICpPcHRpb25zIG1lc3NhZ2VzLiBXZSB0aGVuIHVzZSB0aGlzIGZpZWxkIHRvIHBvcHVsYXRlIHRoZQogZXh0ZW5zaW9ucyB3aGVuIHdlIGJ1aWxkIGEgZGVzY3JpcHRvciwgYXQgd2hpY2ggcG9pbnQgYWxsIHByb3RvcyBoYXZlIGJlZW4KIHBhcnNlZCBhbmQgc28gYWxsIGV4dGVuc2lvbnMgYXJlIGtub3duLgoKIEV4dGVuc2lvbiBudW1iZXJzIGZvciBjdXN0b20gb3B0aW9ucyBtYXkgYmUgY2hvc2VuIGFzIGZvbGxvd3M6CiAqIEZvciBvcHRpb25zIHdoaWNoIHdpbGwgb25seSBiZSB1c2VkIHdpdGhpbiBhIHNpbmdsZSBhcHBsaWNhdGlvbiBvcgogICBvcmdhbml6YXRpb24sIG9yIGZvciBleHBlcmltZW50YWwgb3B0aW9ucywgdXNlIGZpZWxkIG51bWJlcnMgNTAwMDAKICAgdGhyb3VnaCA5OTk5OS4gIEl0IGlzIHVwIHRvIHlvdSB0byBlbnN1cmUgdGhhdCB5b3UgZG8gbm90IHVzZSB0aGUKICAgc2FtZSBudW1iZXIgZm9yIG11bHRpcGxlIG9wdGlvbnMuCiAqIEZvciBvcHRpb25zIHdoaWNoIHdpbGwgYmUgcHVibGlzaGVkIGFuZCB1c2VkIHB1YmxpY2x5IGJ5IG11bHRpcGxlCiAgIGluZGVwZW5kZW50IGVudGl0aWVzLCBlLW1haWwgcHJvdG9idWYtZ2xvYmFsLWV4dGVuc2lvbi1yZWdpc3RyeUBnb29nbGUuY29tCiAgIHRvIHJlc2VydmUgZXh0ZW5zaW9uIG51bWJlcnMuIFNpbXBseSBwcm92aWRlIHlvdXIgcHJvamVjdCBuYW1lIChlLmcuCiAgIE9iamVjdGl2ZS1DIHBsdWdpbikgYW5kIHlvdXIgcHJvamVjdCB3ZWJzaXRlIChpZiBhdmFpbGFibGUpIC0tIHRoZXJlJ3Mgbm8KICAgbmVlZCB0byBleHBsYWluIGhvdyB5b3UgaW50ZW5kIHRvIHVzZSB0aGVtLiBVc3VhbGx5IHlvdSBvbmx5IG5lZWQgb25lCiAgIGV4dGVuc2lvbiBudW1iZXIuIFlvdSBjYW4gZGVjbGFyZSBtdWx0aXBsZSBvcHRpb25zIHdpdGggb25seSBvbmUgZXh0ZW5zaW9uCiAgIG51bWJlciBieSBwdXR0aW5nIHRoZW0gaW4gYSBzdWItbWVzc2FnZS4gU2VlIHRoZSBDdXN0b20gT3B0aW9ucyBzZWN0aW9uIG9mCiAgIHRoZSBkb2NzIGZvciBleGFtcGxlczoKICAgaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy9kb2NzL3Byb3RvI29wdGlvbnMKICAgSWYgdGhpcyB0dXJucyBvdXQgdG8gYmUgcG9wdWxhciwgYSB3ZWIgc2VydmljZSB3aWxsIGJlIHNldCB1cAogICB0byBhdXRvbWF0aWNhbGx5IGFzc2lnbiBvcHRpb24gbnVtYmVycy4KCgsKAwQKARIEvQIIEwr0AQoEBAoCABIEwwICIxrlASBTZXRzIHRoZSBKYXZhIHBhY2thZ2Ugd2hlcmUgY2xhc3NlcyBnZW5lcmF0ZWQgZnJvbSB0aGlzIC5wcm90byB3aWxsIGJlCiBwbGFjZWQuICBCeSBkZWZhdWx0LCB0aGUgcHJvdG8gcGFja2FnZSBpcyB1c2VkLCBidXQgdGhpcyBpcyBvZnRlbgogaW5hcHByb3ByaWF0ZSBiZWNhdXNlIHByb3RvIHBhY2thZ2VzIGRvIG5vdCBub3JtYWxseSBzdGFydCB3aXRoIGJhY2t3YXJkcwogZG9tYWluIG5hbWVzLgoKDQoFBAoCAAQSBMMCAgoKDQoFBAoCAAUSBMMCCxEKDQoFBAoCAAESBMMCEh4KDQoFBAoCAAMSBMMCISIKvwIKBAQKAgESBMsCAisasAIgSWYgc2V0LCBhbGwgdGhlIGNsYXNzZXMgZnJvbSB0aGUgLnByb3RvIGZpbGUgYXJlIHdyYXBwZWQgaW4gYSBzaW5nbGUKIG91dGVyIGNsYXNzIHdpdGggdGhlIGdpdmVuIG5hbWUuICBUaGlzIGFwcGxpZXMgdG8gYm90aCBQcm90bzEKIChlcXVpdmFsZW50IHRvIHRoZSBvbGQgIi0tb25l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6AICOQoNCgUECgIFBBIE6AICCgoNCgUECgIFBhIE6AILFwoNCgUECgIFARIE6AIYJAoNCgUECgIFAxIE6AInKAoNCgUECgIFCBIE6AIpOAoNCgUECgIFBxIE6AIyNwriAgoEBAoCBhIE7wICIhrTAiBTZXRzIHRoZSBHbyBwYWNrYWdlIHdoZXJlIHN0cnVjdHMgZ2VuZXJhdGVkIGZyb20gdGhpcyAucHJvdG8gd2lsbCBiZQogcGxhY2VkLiBJZiBvbWl0dGVkLCB0aGUgR28gcGFja2FnZSB3aWxsIGJlIGRlcml2ZWQgZnJvbSB0aGUgZm9sbG93aW5nOgogICAtIFRoZSBiYXNlbmFtZSBvZiB0aGUgcGFja2FnZSBpbXBvcnQgcGF0aCwgaWYgcHJvdmlkZWQuCiAgIC0gT3RoZXJ3aXNlLCB0aGUgcGFja2FnZSBzdGF0ZW1lbnQgaW4gdGhlIC5wcm90byBmaWxlLCBpZiBwcmVzZW50LgogICAtIE90aGVyd2lzZSwgdGhlIGJhc2VuYW1lIG9mIHRoZSAucHJvdG8gZmlsZSwgd2l0aG91dCBleHRlbnNpb24uCgoNCgUECgIGBBIE7wICCgoNCgUECgIGBRIE7wILEQoNCgUECgIGARIE7wISHAoNCgUECgIGAxIE7wIfIQrUBAoEBAoCBxIE/QICORrFBCBTaG91bGQgZ2VuZXJpYyBzZXJ2aWNlcyBiZSBnZW5lcmF0ZWQgaW4gZWFjaCBsYW5ndWFnZT8gICJHZW5lcmljIiBzZXJ2aWNlcwogYXJlIG5vdCBzcGVjaWZpYyB0byBhbnkgcGFydGljdWxhciBSUEMgc3lzdGVtLiAgVGhleSBhcmUgZ2VuZXJhdGVkIGJ5IHRoZQogbWFpbiBjb2RlIGdlbmVyYXRvcnMgaW4gZWFjaCBsYW5ndWFnZSAod2l0aG91dCBhZGRpdGlvbmFsIHBsdWdpbnMpLgogR2VuZXJpYyBzZXJ2aWNlcyB3ZXJlIHRoZSBvbmx5IGtpbmQgb2Ygc2VydmljZSBnZW5lcmF0aW9uIHN1cHBvcnRlZCBieQogZWFybHkgdmVyc2lvbnMgb2YgZ29vZ2xlLnByb3RvYnVmLgoKIEdlbmVyaWMgc2VydmljZXMgYXJlIG5vdyBjb25zaWRlcmVkIGRlcHJl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b3IgYmFja3dhcmRzLWNvbXBhdGliaWxpdHkgd2l0aCB0aGUgTWVzc2FnZVNldCB3aXJlCiBmb3JtYXQuICBZb3Ugc2hvdWxkIG5vdCB1c2UgdGhpcyBmb3IgYW55IG90aGVyIHJlYXNvbjogIEl0J3MgbGVzcwogZWZmaWNpZW50LCBoYXMgZmV3ZXIgZmVhdHVyZXMsIGFuZCBpcyBtb3JlIGNvbXBsaWNhdGVkLgoKIFRoZSBtZXNzYWdlIG11c3QgYmUgZGVmaW5lZCBleGFjdGx5IGFzIGZvbGxvd3M6CiAgIG1lc3NhZ2UgRm9vIHsKICAgICBvcHRpb24gbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQgPSB0cnVlOwogICAgIGV4dGVuc2lvbnMgNCB0byBtYXg7CiAgIH0KIE5vdGUgdGhhdCB0aGUgbWVzc2FnZSBjYW5ub3QgaGF2ZSBhbnkgZGVmaW5lZCBmaWVsZHM7IE1lc3NhZ2VTZXRzIG9ubHkKIGhhdmUgZXh0ZW5zaW9ucy4KCiBBbGwgZXh0ZW5zaW9ucyBvZiB5b3VyIHR5cGUgbXVzdCBiZSBzaW5ndWxhciBtZXNzYWdlczsgZS5nLiB0aGV5IGNhbm5vdAogYmUgaW50MzJzLCBlbnVtcywgb3IgcmVwZWF0ZWQgbWVzc2FnZXMuCgogQmVjYXVzZSB0aGlzIGlzIGFuIG9wdGlvbiwgdGhlIGFib3ZlIHR3byByZXN0cmljdGlvbnMgYXJlIG5vdCBlbmZvcmNlZCBieQogdGhlIHByb3RvY29sIGNvbXBpbGVyLgoKDQoFBAsCAAQSBL8DAgoKDQoFBAsCAAUSBL8DCw8KDQoFBAsCAAESBL8DECcKDQoFBAsCAAMSBL8DKisKDQoFBAsCAAgSBL8DLDsKDQoFBAsCAAcSBL8DNToK6wEKBAQLAgESBMQDAkQa3AEgRGlzYWJsZXMgdGhlIGdlbmVyYXRpb24gb2YgdGhlIHN0YW5kYXJkICJkZXNjcmlwdG9yKCkiIGFjY2Vzc29yLCB3aGljaCBjYW4KIGNvbmZsaWN0IHdpdGggYSBmaWVsZCBvZiB0aGUgc2FtZSBuYW1lLiAgVGhpcyBpcyBtZWFudCB0byBtYWtlIG1pZ3JhdGlvbgogZnJvbSBwcm90bzEgZWFzaWVy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GRoKmgUKBAQMAgISBI0EAjMaiwUgVGhlIGpzdHlwZSBvcHRpb24gZGV0ZXJtaW5lcyB0aGUgSmF2YVNjcmlwdCB0eXBlIHVzZWQgZm9yIHZhbHVlcyBvZiB0aGUKIGZpZWxkLiAgVGhlIG9wdGlvbiBpcyBwZXJtaXR0ZWQgb25seSBmb3IgNjQgYml0IGludGVncmFsIGFuZCBmaXhlZCB0eXBlcwogKGludDY0LCB1aW50NjQsIHNpbnQ2NCwgZml4ZWQ2NCwgc2ZpeGVkNjQpLiAgQSBmaWVsZCB3aXRoIGpzdHlwZSBKU19TVFJJTkcKIGlzIHJlcHJlc2VudGVkIGFzIEphdmFTY3JpcHQgc3RyaW5nLCB3aGljaCBhdm9pZHMgbG9zcyBvZiBwcmVjaXNpb24gdGhhdAogY2FuIGhhcHBlbiB3aGVuIGEgbGFyZ2UgdmFsdWUgaXMgY29udmVydGVkIHRvIGEgZmxvYXRpbmcgcG9pbnQgSmF2YVNjcmlwdC4KIFNwZWNpZnlpbmcgSlNfTlVNQkVSIGZvciB0aGUganN0eXBlIGNhdXNlcyB0aGUgZ2VuZXJhdGVkIEphdmFTY3JpcHQgY29kZSB0bwogdXNlIHRoZSBKYXZhU2NyaXB0ICJudW1iZXIiIHR5cGUuICBUaGUgYmVoYXZpb3Igb2YgdGhlIGRlZmF1bHQgb3B0aW9uCiBKU19OT1JNQUwgaXMgaW1wbGVtZW50YXRpb24gZGVwZW5kZW50LgoKIFRoaXMgb3B0aW9uIGlzIGFuIGVudW0gdG8gcGVybWl0IGFkZGl0aW9uYWwgdHlwZXMgdG8gYmUgYWRkZWQsIGUuZy4KIGdvb2cubWF0aC5JbnRlZ2VyLgoKDQoFBAwCAgQSBI0EAgoKDQoFBAwCAgYSBI0ECxEKDQoFBAwCAgESBI0EEhgKDQoFBAwCAgMSBI0EGxwKDQoFBAwCAggSBI0EHTIKDQoFBAwCAgcSBI0EKDEKDgoEBAwEARIGjgQClwQDCg0KBQQMBAEBEgSOBAcNCicKBgQMBAECABIEkAQEEhoXIFVzZSB0aGUgZGVmYXVsdCB0eXBlLgoKDwoHBAwEAQIAARIEkAQEDQoPCgcEDAQBAgACEgSQBBARCikKBgQMBAECARIEkwQEEhoZIFVzZSBKYXZhU2NyaXB0IHN0cmluZ3MuCgoPCgcEDAQBAgEBEgSTBAQNCg8KBwQMBAECAQISBJMEEBEKKQoGBAwEAQICEgSWBAQSGhkgVXNlIEphdmFTY3JpcHQgbnVtYmVycy4KCg8KBwQMBAECAgESBJYEBA0KDwoHBAwEAQICAhIElgQQEQrvDAoEBAwCAxIEtQQCKRrgDCBTaG91bGQgdGhpcyBmaWVsZCBiZSBwYXJzZWQgbGF6aWx5PyAgTGF6eSBhcHBsaWVzIG9ubHkgdG8gbWVzc2FnZS10eXBlCiBmaWVsZHMuICBJdCBtZWFucyB0aGF0IHdoZW4gdGhlIG91dGVyIG1lc3NhZ2UgaXMgaW5pdGlhbGx5IHBhcnNlZCwgdGhlCiBpbm5lciBtZXNzYWdlJ3MgY29udGVudHMgd2lsbCBub3QgYmUgcGFyc2VkIGJ1dCBpbnN0ZWFkIHN0b3JlZCBpbiBlbmNvZGVkCiBmb3JtLiAgVGhlIGlubmVyIG1lc3NhZ2Ugd2lsbCBhY3R1YWxseSBiZSBwYXJzZWQgd2hlbiBpdCBpcyBmaXJzdCBhY2Nlc3NlZC4KCiBUaGlzIGlzIG9ubHkgYSBoaW50LiAgSW1wbGVtZW50YXRpb25zIGFyZSBmcmVlIHRvIGNob29zZSB3aGV0aGVyIHRvIHVzZQogZWFnZXIgb3IgbGF6eSBwYXJzaW5nIHJlZ2FyZGxlc3Mgb2YgdGhlIHZhbHVlIG9mIHRoaXMgb3B0aW9uLiAgSG93ZXZlciwKIHNldHRpbmcgdGhpcyBvcHRpb24gdHJ1ZSBzdWdnZXN0cyB0aGF0IHRoZSBwcm90b2NvbCBhdXRob3IgYmVsaWV2ZXMgdGhhdAogdXNpbmcgbGF6eSBwYXJzaW5nIG9uIHRoaXMgZmllbGQgaXMgd29ydGggdGhlIGFkZGl0aW9uYWwgYm9va2tlZXBpbmcKIG92ZXJoZWFkIHR5cGljYWxseSBuZWVkZWQgdG8gaW1wbGVtZW50IGl0LgoKIFRoaXMgb3B0aW9uIGRvZXMgbm90IGFmZmVjdCB0aGUgcHVibGljIGludGVyZmFjZSBvZiBhbnkgZ2VuZXJhdGVkIGNvZGU7CiBhbGwgbWV0aG9kIHNpZ25hdHVyZXMgcmVtYWluIHRoZSBzYW1lLiAgRnVydGhlcm1vcmUsIHRocmVhZC1zYWZldHkgb2YgdGhlCiBpbnRlcmZhY2UgaXMgbm90IGFmZmVjdGVkIGJ5IHRoaXMgb3B0aW9uOyBjb25zdCBtZXRob2RzIHJlbWFpbiBzYWZlIHRvCiBjYWxsIGZyb20gbXVsdGlwbGUgdGhyZWFkcyBjb25jdXJyZW50bHksIHdoaWxlIG5vbi1jb25zdCBtZXRob2RzIGNvbnRpbnVlCiB0byByZXF1aXJlIGV4Y2x1c2l2ZSBhY2Nlc3MuCgoKIE5vdGUgdGhhdCBpbXBsZW1lbnRhdGlvbnMgbWF5IGNob29zZSBub3QgdG8gY2hlY2sgcmVxdWlyZWQgZmllbGRzIHdpdGhpbgogYSBsYXp5IHN1Yi1tZXNzYWdlLiAgVGhhdCBpcywgY2FsbGluZyBJc0luaXRpYWxpemVkKCkgb24gdGhlIG91dGVyIG1lc3NhZ2UKIG1heSByZXR1cm4gdHJ1ZSBldmVuIGlmIHRoZSBpbm5lciBtZXNzYWdlIGhhcyBtaXNzaW5nIHJlcXVpcmVkIGZpZWxkcy4KIFRoaXMgaXMgbmVjZXNzYXJ5IGJlY2F1c2Ugb3RoZXJ3aXNlIHRoZSBpbm5lciBtZXNzYWdlIHdvdWxkIGhhdmUgdG8gYmUKIHBhcnNlZCBpbiBvcmRlciB0byBwZXJmb3JtIHRoZSBjaGVjaywgZGVmZWF0aW5nIHRoZSBwdXJwb3NlIG9mIGxhenkKIHBhcnNpbmcuICBBbiBpbXBsZW1lbnRhdGlvbiB3aGljaCBjaG9vc2VzIG5vdCB0byBjaGVjayByZXF1aXJlZCBmaWVsZHMKIG11c3QgYmUgY29uc2lzdGVudCBhYm91dCBpdC4gIFRoYXQgaXMsIGZvciBhbnkgcGFydGljdWxhciBzdWItbWVzc2FnZSwgdGhlCiBpbXBsZW1lbnRhdGlvbiBtdXN0IGVpdGhlciAqYWx3YXlzKiBjaGVjayBpdHMgcmVxdWlyZWQgZmllbGRzLCBvciAqbmV2ZXIqCiBjaGVjayBpdHMgcmVxdWlyZWQgZmllbGRzLCByZWdhcmRsZXNzIG9mIHdoZXRoZXIgb3Igbm90IHRoZSBtZXNzYWdlIGhhcwogYmVlbiBwYXJzZWQuCgoNCgUEDAIDBBIEtQQCCgoNCgUEDAIDBRIEtQQL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b2xsb3dpbmcgbG9jYXRpb25zOgogICBzcGFuICAgcGF0aCAgICAgICAgICAgICAgIHJlcHJlc2VudHMKICAgW2EsaSkgIFsgNCwgMCwgMiwgMCBdICAgICBUaGUgd2hvbGUgZmllbGQgZGVmaW5pdGlvbi4KICAgW2EsYikgIFsgNCwgMCwgMiwgMCwgNCBdICBUaGUgbGFiZWwgKG9wdGlvbmFsKS4KICAgW2MsZCkgIFsgNCwgMCwgMiwgMCwgNSBdICBUaGUgdHlwZSAoc3RyaW5nKS4KICAgW2UsZikgIFsgNCwgMCwgMiwgMCwgMSBdICBUaGUgbmFtZSAoZm9vKS4KICAgW2csaCkgIFsgNCwgMCwgMiwgMCwgMyBdICBUaGUgbnVtYmVyICgxKS4KCiBOb3RlczoKIC0gQSBsb2NhdGlvbiBtYXkgcmVmZXIgdG8gYSByZXBlYXRlZCBmaWVsZCBpdHNlbGYgKGkuZS4gbm90IHRvIGFueQogICBwYXJ0aWN1bGFyIGluZGV4IHdpdGhpbiBpdCkuICBUaGlzIGlzIHVzZWQgd2hlbmV2ZXIgYSBzZXQgb2YgZWxlbWVudHMgYXJlCiAgIGxvZ2ljYWxseSBlbmNsb3NlZCBpbiBhIHNpbmdsZSBjb2RlIHNlZ21lbnQuICBGb3IgZXhhbXBsZSwgYW4gZW50aXJlCiAgIGV4dGVuZCBibG9jayAocG9zc2libHkgY29udGFpbmluZyBtdWx0aXBsZSBleHRlbnNpb24gZGVmaW5pdGlvbnMpIHdpbGwKICAgaGF2ZSBhbiBvdXRlciBsb2NhdGlvbiB3aG9zZSBwYXRoIHJlZmVycyB0byB0aGUgImV4dGVuc2lvbnMiIHJlcGVhdGVkCiAgIGZpZWxkIHdpdGhvdXQgYW4gaW5kZXguCiAtIE11bHRpcGxlIGxvY2F0aW9ucyBtYXkgaGF2ZSB0aGUgc2FtZSBwYXRoLiAgVGhpcyBoYXBwZW5zIHdoZW4gYSBzaW5nbGUKICAgbG9naWNhbCBkZWNsYXJhdGlvbiBpcyBzcHJlYWQgb3V0IGFjcm9zcyBtdWx0aXBsZSBwbGFjZXMuICBUaGUgbW9zdAogICBvYnZpb3VzIGV4YW1wbGUgaXMgdGhlICJleHRlbmQiIGJsb2NrIGFnYWluIC0tIHRoZXJlIG1heSBiZSBtdWx0aXBsZQogICBleHRlbmQgYmxvY2tzIGluIHRoZSBzYW1lIHNjb3BlLCBlYWNoIG9mIHdoaWNoIHdpbGwgaGF2ZSB0aGUgc2FtZSBwYXRoLgogLSBBIGxvY2F0aW9uJ3Mgc3BhbiBpcyBub3QgYWx3YXlzIGEgc3Vic2V0IG9mIGl0cyBwYXJlbnQncyBzcGFuLiAgRm9yCiAgIGV4YW1wbGUsIHRoZSAiZXh0ZW5kZWUiIG9mIGFuIGV4dGVuc2lvbiBkZWNsYXJhdGlvbiBhcHBlYXJzIGF0IHRoZQogICBiZWdpbm5pbmcgb2YgdGhlICJleHRlbmQiIGJsb2NrIGFuZCBpcyBzaGFyZWQgYnkgYWxsIGV4dGVuc2lvbnMgd2l0aGluCiAgIHRoZSBibG9jay4KIC0gSnVzdCBiZWNhdXNlIGEgbG9jYXRpb24ncyBzcGFuIGlzIGEgc3Vic2V0IG9mIHNvbWUgb3RoZXIgbG9jYXRpb24ncyBzcGFuCiAgIGRvZXMgbm90IG1lYW4gdGhhdCBpdCBpcyBhIGRlc2NlbmRlbnQuICBGb3IgZXhhbXBsZSwgYSAiZ3JvdXAiIGRlZmluZXMKICAgYm90aCBhIHR5cGUgYW5kIGEgZmllbGQgaW4gYSBzaW5nbGUgZGVjbGFyYXRpb24uICBUaHVzLCB0aGUgbG9jYXRpb25zCiAgIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHR5cGUgYW5kIGZpZWxkIGFuZCB0aGVpciBjb21wb25lbnRzIHdpbGwgb3ZlcmxhcC4KIC0gQ29kZSB3aGljaCB0cmllcyB0byBpbnRlcnByZXQgbG9jYXRpb25zIHNob3VsZCBwcm9iYWJseSBiZSBkZXNpZ25lZCB0bwogICBpZ25vcmUgdGhvc2UgdGhhdCBpdCBkb2Vzbid0IHVuZGVyc3RhbmQsIGFzIG1vcmUgdHlwZXMgb2YgbG9jYXRpb25zIGNvdWxkCiAgIGJlIHJlY29yZGVkIGluIHRoZSBmdXR1cmUuCgoNCgUEEwIABBIE9gUCCgoNCgUEEwIABhIE9gULEwoNCgUEEwIAARIE9gUUHAoNCgUEEwIAAxIE9gUfIAoOCgQEEwMAEgb3BQLKBgMKDQoFBBMDAAESBPcFChIKgwcKBgQTAwACABIEjwYEKhryBiBJZGVudGlmaWVzIHdoaWNoIHBhcnQgb2YgdGhlIEZpbGVEZXNjcmlwdG9yUHJvdG8gd2FzIGRlZmluZWQgYXQgdGhpcwogbG9jYXRpb24uCgogRWFjaCBlbGVtZW50IGlzIGEgZmllbGQgbnVtYmVyIG9yIGFuIGluZGV4LiAgVGhleSBmb3JtIGEgcGF0aCBmcm9tCiB0aGUgcm9vdCBGaWxlRGVzY3JpcHRvclByb3RvIHRvIHRoZSBwbGFjZSB3aGVyZSB0aGUgZGVmaW5pdGlvbi4gIEZvcgogZXhhbXBsZSwgdGhpcyBwYXRoOgogICBbIDQsIDMsIDIsIDcsIDEgXQogcmVmZXJzIHRvOgogICBmaWxlLm1lc3NhZ2VfdHlwZSgzKSAgLy8gNCwgMwogICAgICAgLmZpZWxkKDcpICAgICAgICAgLy8gMiwgNwogICAgICAgLm5hbWUoKSAgICAgICAgICAgLy8gMQogVGhpcyBpcyBiZWNhdXNlIEZpbGVEZXNjcmlwdG9yUHJvdG8ubWVzc2FnZV90eXBlIGhhcyBmaWVsZCBudW1iZXIgNDoKICAgcmVwZWF0ZWQgRGVzY3JpcHRvclByb3RvIG1lc3NhZ2VfdHlwZSA9IDQ7CiBhbmQgRGVzY3JpcHRvclByb3RvLmZpZWxkIGhhcyBmaWVsZCBudW1iZXIgMjoKICAgcmVwZWF0ZWQgRmllbGREZXNjcmlwdG9yUHJvdG8gZmllbGQgPSAyOwogYW5kIEZpZWxkRGVzY3JpcHRvclByb3RvLm5hbWUgaGFzIGZpZWxkIG51bWJlciAxOgogICBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CgogVGh1cywgdGhlIGFib3ZlIHBhdGggZ2l2ZXMgdGhlIGxvY2F0aW9uIG9mIGEgZmllbGQgbmFtZS4gIElmIHdlIHJlbW92ZWQKIHRoZSBsYXN0IGVsZW1lbnQ6CiAgIFsgNCwgMywgMiwgNyBdCiB0aGlzIHBhdGggcmVmZXJzIHRvIHRoZSB3aG9sZSBmaWVsZCBkZWNsYXJhdGlvbiAoZnJvbSB0aGUgYmVnaW5uaW5nCiBvZiB0aGUgbGFiZWwgdG8gdGhlIHRlcm1pbmF0aW5nIHNlbWljb2xvbikuCgoPCgcEEwMAAgAEEgSPBgQMCg8KBwQTAwACAAUSBI8GDRIKDwoHBBMDAAIAARIEjwYTFwoPCgcEEwMAAgADEgSPBhobCg8KBwQTAwACAAgSBI8GHCkKEgoKBBMDAAIACOcHABIEjwYdKAoTCgsEEwMAAgAI5wcAAhIEjwYdIwoUCgwEEwMAAgAI5wcAAgASBI8GHSMKFQoNBBMDAAIACOcHAAIAARIEjwYdIwoTCgsEEwMAAgAI5wcAAxIEjwYkKArSAgoGBBMDAAIBEgSWBgQqGsECIEFsd2F5cyBoYXMgZXhhY3RseSB0aHJlZSBvciBmb3VyIGVsZW1lbnRzOiBzdGFydCBsaW5lLCBzdGFydCBjb2x1bW4sCiBlbmQgbGluZSAob3B0aW9uYWwsIG90aGVyd2lzZSBhc3N1bWVkIHNhbWUgYXMgc3RhcnQgbGluZSksIGVuZCBjb2x1bW4uCiBUaGVzZSBhcmUgcGFja2VkIGludG8gYSBzaW5nbGUgZmllbGQgZm9yIGVmZmljaWVuY3kuICBOb3RlIHRoYXQgbGluZQogYW5kIGNvbHVtbiBudW1iZXJzIGFyZSB6ZXJvLWJhc2VkIC0tIHR5cGljYWxseSB5b3Ugd2lsbCB3YW50IHRvIGFkZAogMSB0byBlYWNoIGJlZm9yZSBkaXNwbGF5aW5nIHRvIGEgdXNlci4KCg8KBwQTAwACAQQSBJYGBAwKDwoHBBMDAAIBBRIElgYNEgoPCgcEEwMAAgEBEgSWBhMXCg8KBwQTAwACAQMSBJYGGhsKDwoHBBMDAAIBCBIElgYcKQoSCgoEEwMAAgEI5wcAEgSWBh0oChMKCwQTAwACAQjnBwACEgSWBh0jChQKDAQTAwACAQjnBwACABIElgYdIwoVCg0EEwMAAgEI5wcAAgABEgSWBh0jChMKCwQTAwACAQjnBwADEgSWBiQoCqUMCgYEEwMAAgISBMcGBCkalAwgSWYgdGhpcyBTb3VyY2VDb2RlSW5mbyByZXByZXNlbnRzIGEgY29tcGxldGUgZGVjbGFyYXRpb24sIHRoZXNlIGFyZSBhbnkKIGNvbW1lbnRzIGFwcGVhcmluZyBiZWZvcmUgYW5kIGFmdGVyIHRoZSBkZWNsYXJhdGlvbiB3aGljaCBhcHBlYXIgdG8gYmUKIGF0dGFjaGVkIHRvIHRoZSBkZWNsYXJhdGlvbi4KCiBBIHNlcmllcyBvZiBsaW5lIGNvbW1lbnRzIGFwcGVhcmluZyBvbiBjb25zZWN1dGl2ZSBsaW5lcywgd2l0aCBubyBvdGhlcgogdG9rZW5zIGFwcGVhcmluZyBvbiB0aG9zZSBsaW5lcywgd2lsbCBiZSB0cmVhdGVkIGFzIGEgc2luZ2xlIGNvbW1lbnQuCgogbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyB3aWxsIGtlZXAgcGFyYWdyYXBocyBvZiBjb21tZW50cyB0aGF0IGFwcGVhcgogYmVmb3JlIChidXQgbm90IGNvbm5lY3RlZCB0bykgdGhlIGN1cnJlbnQgZWxlbWVudC4gRWFjaCBwYXJhZ3JhcGgsCiBzZXBhcmF0ZWQgYnkgZW1wdHkgbGluZXMsIHdpbGwgYmUgb25lIGNvbW1lbnQgZWxlbWVudCBpbiB0aGUgcmVwZWF0ZWQKIGZpZWxkLgoKIE9ubHkgdGhlIGNvbW1lbnQgY29udGVudCBpcyBwcm92aWRlZDsgY29tbWVudCBtYXJrZXJzIChlLmcuIC8vKSBhcmUKIHN0cmlwcGVkIG91dC4gIEZvciBibG9jayBjb21tZW50cywgbGVhZGluZyB3aGl0ZXNwYWNlIGFuZCBhbiBhc3Rlcmlzawogd2lsbCBiZSBzdHJpcHBlZCBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgZWFjaCBsaW5lIG90aGVyIHRoYW4gdGhlIGZpcnN0LgogTmV3bGluZXMgYXJlIGluY2x1ZGVkIGluIHRoZSBvdXRwdXQuCgogRXhhbXBsZXM6CgogICBvcHRpb25hbCBpbnQzMiBmb28gPSAxOyAgLy8gQ29tbWVudCBhdHRhY2hlZCB0byBmb28uCiAgIC8vIENvbW1lbnQgYXR0YWNoZWQgdG8gYmFyLgogICBvcHRpb25hbCBpbnQzMiBiYXIgPSAyOwoKICAgb3B0aW9uYWwgc3RyaW5nIGJheiA9IDM7CiAgIC8vIENvbW1lbnQgYXR0YWNoZWQgdG8gYmF6LgogICAvLyBBbm90aGVyIGxpbmUgYXR0YWNoZWQgdG8gYmF6LgoKICAgLy8gQ29tbWVudCBhdHRhY2hlZCB0byBxdXguCiAgIC8vCiAgIC8v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ZCBvYmplY3QuCgoPCgcEFAMAAgIEEgTeBgQMCg8KBwQUAwACAgUSBN4GDRIKDwoHBBQDAAICARIE3gYTGAoPCgcEFAMAAgIDEgTeBhscCtsBCgYEFAMAAgMSBOMGBBsaygEgSWRlbnRpZmllcyB0aGUgZW5kaW5nIG9mZnNldCBpbiBieXRlcyBpbiB0aGUgZ2VuZXJhdGVkIGNvZGUgdGhhdAogcmVsYXRlcyB0byB0aGUgaWRlbnRpZmllZCBvZmZzZXQuIFRoZSBlbmQgb2Zmc2V0IHNob3VsZCBiZSBvbmUgcGFzdAogdGhlIGxhc3QgcmVsZXZhbnQgYnl0ZSAoc28gdGhlIGxlbmd0aCBvZiB0aGUgdGV4dCA9IGVuZCAtIGJlZ2luKS4KCg8KBwQUAwACAwQSBOMGBAwKDwoHBBQDAAIDBRIE4wYNEgoPCgcEFAMAAgMBEgTjBhMWCg8KBwQUAwACAwMSBOMGGRoK/loKFGdvZ29wcm90by9nb2dvLnByb3RvEglnb2dvcHJvdG8aIGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvOk4KE2dvcHJvdG9fZW51bV9wcmVmaXgSHC5nb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnMYseQDIAEoCFIRZ29wcm90b0VudW1QcmVmaXg6UgoVZ29wcm90b19lbnVtX3N0cmluZ2VyEhwuZ29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zGMXkAyABKAhSE2dvcHJvdG9FbnVtU3RyaW5nZXI6QwoNZW51bV9zdHJpbmdlchIcLmdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucxjG5AMgASgIUgxlbnVtU3RyaW5nZXI6RwoPZW51bV9jdXN0b21uYW1lEhwuZ29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zGMfkAyABKAlSDmVudW1DdXN0b21uYW1lOjoKCGVudW1kZWNsEhwuZ29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zGMjkAyABKAhSCGVudW1kZWNsOlYKFGVudW12YWx1ZV9jdXN0b21uYW1lEiEuZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnMY0YMEIAEoCVITZW51bXZhbHVlQ3VzdG9tbmFtZTpOChNnb3Byb3RvX2dldHRlcnNfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGJnsAyABKAhSEWdvcHJvdG9HZXR0ZXJzQWxsOlUKF2dvcHJvdG9fZW51bV9wcmVmaXhfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGJrsAyABKAhSFGdvcHJvdG9FbnVtUHJlZml4QWxsOlAKFGdvcHJvdG9fc3RyaW5nZXJfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGJvsAyABKAhSEmdvcHJvdG9TdHJpbmdlckFsbDpKChF2ZXJib3NlX2VxdWFsX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxic7AMgASgIUg92ZXJib3NlRXF1YWxBbGw6OQoIZmFjZV9hbGwSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMYnewDIAEoCFIHZmFjZUFsbDpBCgxnb3N0cmluZ19hbGwSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMYnuwDIAEoCFILZ29zdHJpbmdBbGw6QQoMcG9wdWxhdGVfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGJ/sAyABKAhSC3BvcHVsYXRlQWxsOkEKDHN0cmluZ2VyX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxig7AMgASgIUgtzdHJpbmdlckFsbDo/Cgtvbmx5b25lX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxih7AMgASgIUgpvbmx5b25lQWxsOjsKCWVxdWFsX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxil7AMgASgIUghlcXVhbEFsbDpHCg9kZXNjcmlwdGlvbl9hbGwSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMYpuwDIAEoCFIOZGVzY3JpcHRpb25BbGw6PwoLdGVzdGdlbl9hbGwSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMYp+wDIAEoCFIKdGVzdGdlbkFsbDpBCgxiZW5jaGdlbl9hbGwSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMYqOwDIAEoCFILYmVuY2hnZW5BbGw6QwoNbWFyc2hhbGVyX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxip7AMgASgIUgxtYXJzaGFsZXJBbGw6RwoPdW5tYXJzaGFsZXJfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGKrsAyABKAhSDnVubWFyc2hhbGVyQWxsOlAKFHN0YWJsZV9tYXJzaGFsZXJfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGKvsAyABKAhSEnN0YWJsZU1hcnNoYWxlckFsbDo7CglzaXplcl9hbGwSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMYrOwDIAEoCFIIc2l6ZXJBbGw6WQoZZ29wcm90b19lbnVtX3N0cmluZ2VyX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxit7AMgASgIUhZnb3Byb3RvRW51bVN0cmluZ2VyQWxsOkoKEWVudW1fc3RyaW5nZXJfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGK7sAyABKAhSD2VudW1TdHJpbmdlckFsbDpQChR1bnNhZmVfbWFyc2hhbGVyX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxiv7AMgASgIUhJ1bnNhZmVNYXJzaGFsZXJBbGw6VAoWdW5zYWZlX3VubWFyc2hhbGVyX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxiw7AMgASgIUhR1bnNhZmVVbm1hcnNoYWxlckFsbDpbChpnb3Byb3RvX2V4dGVuc2lvbnNfbWFwX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxix7AMgASgIUhdnb3Byb3RvRXh0ZW5zaW9uc01hcEFsbDpYChhnb3Byb3RvX3VucmVjb2duaXplZF9hbGwSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMYsuwDIAEoCFIWZ29wcm90b1VucmVjb2duaXplZEFsbDpJChBnb2dvcHJvdG9faW1wb3J0EhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGLPsAyABKAhSD2dvZ29wcm90b0ltcG9ydDpFCg5wcm90b3NpemVyX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxi07AMgASgIUg1wcm90b3NpemVyQWxsOj8KC2NvbXBhcmVfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGLXsAyABKAhSCmNvbXBhcmVBbGw6QQoMdHlwZWRlY2xfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGLbsAyABKAhSC3R5cGVkZWNsQWxsOkEKDGVudW1kZWNsX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxi37AMgASgIUgtlbnVtZGVjbEFsbDpRChRnb3Byb3RvX3JlZ2lzdHJhdGlvbhIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxi47AMgASgIUhNnb3Byb3RvUmVnaXN0cmF0aW9uOkoKD2dvcHJvdG9fZ2V0dGVycxIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxiB9AMgASgIUg5nb3Byb3RvR2V0dGVyczpMChBnb3Byb3RvX3N0cmluZ2VyEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGIP0AyABKAhSD2dvcHJvdG9TdHJpbmdlcjpGCg12ZXJib3NlX2VxdWFsEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGIT0AyABKAhSDHZlcmJvc2VFcXVhbDo1CgRmYWNlEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGIX0AyABKAhSBGZhY2U6PQoIZ29zdHJpbmcSHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYhvQDIAEoCFIIZ29zdHJpbmc6PQoIcG9wdWxhdGUSHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYh/QDIAEoCFIIcG9wdWxhdGU6PQoIc3RyaW5nZXISHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYwIsEIAEoCFIIc3RyaW5nZXI6OwoHb25seW9uZRIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxiJ9AMgASgIUgdvbmx5b25lOjcKBWVxdWFsEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGI30AyABKAhSBWVxdWFsOkMKC2Rlc2NyaXB0aW9uEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGI70AyABKAhSC2Rlc2NyaXB0aW9uOjsKB3Rlc3RnZW4SHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYj/QDIAEoCFIHdGVzdGdlbjo9CghiZW5jaGdlbhIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxiQ9AMgASgIUghiZW5jaGdlbjo/CgltYXJzaGFsZXISHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYkfQDIAEoCFIJbWFyc2hhbGVyOkMKC3VubWFyc2hhbGVyEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGJL0AyABKAhSC3VubWFyc2hhbGVyOkwKEHN0YWJsZV9tYXJzaGFsZXISHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYk/QDIAEoCFIPc3RhYmxlTWFyc2hhbGVyOjcKBXNpemVyEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGJT0AyABKAhSBXNpemVyOkwKEHVuc2FmZV9tYXJzaGFsZXISHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYl/QDIAEoCFIPdW5zYWZlTWFyc2hhbGVyOlAKEnVuc2FmZV91bm1hcnNoYWxlchIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxiY9AMgASgIUhF1bnNhZmVVbm1hcnNoYWxlcjpXChZnb3Byb3RvX2V4dGVuc2lvbnNfbWFwEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGJn0AyABKAhSFGdvcHJvdG9FeHRlbnNpb25zTWFwOlQKFGdvcHJvdG9fdW5yZWNvZ25pemVkEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGJr0AyABKAhSE2dvcHJvdG9VbnJlY29nbml6ZWQ6QQoKcHJvdG9zaXplchIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxic9AMgASgIUgpwcm90b3NpemVyOjsKB2NvbXBhcmUSHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYnfQDIAEoCFIHY29tcGFyZTo9Cgh0eXBlZGVjbBIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxie9AMgASgIUgh0eXBlZGVjbDo7CghudWxsYWJsZRIdLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMY6fsDIAEoCFIIbnVsbGFibGU6NQoFZW1iZWQSHS5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zGOr7AyABKAhSBWVtYmVkOj8KCmN1c3RvbXR5cGUSHS5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zGOv7AyABKAlSCmN1c3RvbXR5cGU6PwoKY3VzdG9tbmFtZRIdLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMY7PsDIAEoCVIKY3VzdG9tbmFtZTo5Cgdqc29udGFnEh0uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucxjt+wMgASgJUgdqc29udGFnOjsKCG1vcmV0YWdzEh0uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucxju+wMgASgJUghtb3JldGFnczo7CghjYXN0dHlwZRIdLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMY7/sDIAEoCVIIY2FzdHR5cGU6OQoHY2FzdGtleRIdLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMY8PsDIAEoCVIHY2FzdGtleTo9CgljYXN0dmFsdWUSHS5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zGPH7AyABKAlSCWNhc3R2YWx1ZTo5CgdzdGR0aW1lEh0uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucxjy+wMgASgIUgdzdGR0aW1lOkEKC3N0ZGR1cmF0aW9uEh0uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucxjz+wMgASgIUgtzdGRkdXJhdGlvbkJFChNjb20uZ29vZ2xlLnByb3RvYnVmQgpHb0dvUHJvdG9zWiJnaXRodWIuY29tL2dvZ28vcHJvdG9idWYvZ29nb3Byb3RvSv0zCgcSBRwAhAEBCvwKCgEMEgMcABIy8QogUHJvdG9jb2wgQnVmZmVycyBmb3IgR28gd2l0aCBHYWRnZXRzCgogQ29weXJpZ2h0IChjKSAyMDEzLCBUaGUgR29HbyBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogaHR0cDovL2dpdGh1Yi5jb20vZ29nby9wcm90b2J1ZgoKIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQogbWV0OgoKICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCiAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCiBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCiBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCiBkaXN0cmlidXRpb24uCgogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUwogIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgogQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKIE9XTkVSIE9S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ARIDfhggCgoKAwdAAxIDfiMoCgkKAgdBEgN/CCgKCgoDB0ECEgN3ByMKCgoDB0EEEgN/CBAKCgoDB0EFEgN/ERcKCgoDB0EBEgN/GB8KCgoDB0EDEgN/IicKCgoCB0ISBIABCCoKCgoDB0ICEgN3ByMKCwoDB0IEEgSAAQgQCgsKAwdCBRIEgAERFwoLCgMHQgESBIABGCEKCwoDB0IDEgSAASQpCgoKAgdDEgSCAQgmCgoKAwdDAhIDdwcjCgsKAwdDBBIEggEIEAoLCgMHQwUSBIIBERUKCwoDB0MBEgSCARYdCgsKAwdDAxIEggEgJQoKCgIHRBIEgwEIKgoKCgMHRAISA3cHIwoLCgMHRAQSBIMBCBAKCwoDB0QFEgSDAREVCgsKAwdEARIEgwEWIQoLCgMHRAMSBIMBJCkKixUKLG1peGVyL2FkYXB0ZXIvbW9kZWwvdjFiZXRhMS9leHRlbnNpb25zLnByb3RvEiFpc3Rpby5taXhlci5hZGFwdGVyLm1vZGVsLnYxYmV0YTEaIGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvKpABCg9UZW1wbGF0ZVZhcmlldHkSGgoWVEVNUExBVEVfVkFSSUVUWV9DSEVDSxAAEhsKF1RFTVBMQVRFX1ZBUklFVFlfUkVQT1JUEAESGgoWVEVNUExBVEVfVkFSSUVUWV9RVU9UQRACEigKJFRFTVBMQVRFX1ZBUklFVFlfQVRUUklCVVRFX0dFTkVSQVRPUhADOn4KEHRlbXBsYXRlX3ZhcmlldHkSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMYr8q8IiABKA4yMi5pc3Rpby5taXhlci5hZGFwdGVyLm1vZGVsLnYxYmV0YTEuVGVtcGxhdGVWYXJpZXR5Ug90ZW1wbGF0ZVZhcmlldHk6RAoNdGVtcGxhdGVfbmFtZRIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxjQy7wiIAEoCVIMdGVtcGxhdGVOYW1lQipaKGlzdGlvLmlvL2FwaS9taXhlci9hZGFwdGVyL21vZGVsL3YxYmV0YTFKiBEKBhIEDgAvAQq/BAoBDBIDDgASMrQEIENvcHlyaWdodCAyMDE4IElzdGlvIEF1dGhvcnMKCiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKCiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KCggKAQISAxAIKQoICgEIEgMSAD0KCwoECOcHABIDEgA9CgwKBQjnBwACEgMSBxEKDQoGCOcHAAIAEgMSBxEKDgoHCOcHAAIAARIDEgcRCgwKBQjnBwAHEgMSEjwKCQoCAwASAxQHKQp5CgIFABIEGAAlARptIFRoZSBhdmFpbGFibGUgdmFyaWV0aWVzIG9mIHRlbXBsYXRlcywgY29udHJvbGxpbmcgdGhlIHNlbWFudGljcyBvZiB3aGF0IGFuIGFkYXB0ZXIgZG9lcyB3aXRoIGVhY2ggaW5zdGFuY2UuCgoKCgMFAAESAxgFFArIAQoEBQACABIDGwQfGroBIE1ha2VzIHRoZSB0ZW1wbGF0ZSBhcHBsaWNhYmxlIGZvciBNaXhlcidzIGNoZWNrIGNhbGxzLiBJbnN0YW5jZXMgb2Ygc3VjaCB0ZW1wbGF0ZSBhcmUgY3JlYXRlZCBkdXJpbmcKIHJlcG9ydCBjYWxscyBpbiBNaXhlciBhbmQgcGFzc2VkIHRvIHRoZSBoYW5kbGVycyBiYXNlZCBvbiB0aGUgcnVsZSBjb25maWd1cmF0aW9ucy4KCgwKBQUAAgABEgMbBBoKDAoFBQACAAISAxsdHgrIAQoEBQACARIDHgQgGroBIE1ha2VzIHRoZSB0ZW1wbGF0ZSBhcHBsaWNhYmxlIGZvciBNaXhlcidzIHJlcG9ydCBjYWxscy4gSW5zdGFuY2VzIG9mIHN1Y2ggdGVtcGxhdGUgYXJlIGNyZWF0ZWQgZHVyaW5nCiBjaGVjayBjYWxscyBpbiBNaXhlciBhbmQgcGFzc2VkIHRvIHRoZSBoYW5kbGVycyBiYXNlZCBvbiB0aGUgcnVsZSBjb25maWd1cmF0aW9ucy4KCgwKBQUAAgEBEgMeBBsKDAoFBQACAQISAx4eHwrNAQoEBQACAhIDIQQfGr8BIE1ha2VzIHRoZSB0ZW1wbGF0ZSBhcHBsaWNhYmxlIGZvciBNaXhlcidzIHF1b3RhIGNhbGxzLiBJbnN0YW5jZXMgb2Ygc3VjaCB0ZW1wbGF0ZSBhcmUgY3JlYXRlZCBkdXJpbmcKIHF1b3RhIGNoZWNrIGNhbGxzIGluIE1peGVyIGFuZCBwYXNzZWQgdG8gdGhlIGhhbmRsZXJzIGJhc2VkIG9uIHRoZSBydWxlIGNvbmZpZ3VyYXRpb25zLgoKDAoFBQACAgESAyEEGgoMCgUFAAICAhIDIR0eCusBCgQFAAIDEgMkBC0a3QEgTWFrZXMgdGhlIHRlbXBsYXRlIGFwcGxpY2FibGUgZm9yIE1peGVyJ3MgYXR0cmlidXRlIGdlbmVyYXRpb24gcGhhc2UuIEluc3RhbmNlcyBvZiBzdWNoIHRlbXBsYXRlIGFyZSBjcmVhdGVkIGR1cmluZwogcHJlLXByb2Nlc3NpbmcgYXR0cmlidXRlIGdlbmVyYXRpb24gcGhhc2UgYW5kIHBhc3NlZCB0byB0aGUgaGFuZGxlcnMgYmFzZWQgb24gdGhlIHJ1bGUgY29uZmlndXJhdGlvbnMuCgoMCgUFAAIDARIDJAQoCgwKBQUAAgMCEgMkKywKMQoBBxIEKAAvARomIEZpbGUgbGV2ZWwgb3B0aW9ucyBmb3IgdGhlIHRlbXBsYXRlLgoKNgoCBwASAyoEMBorIFJlcXVpcmVkOiBvcHRpb24gZm9yIHRoZSBUZW1wbGF0ZVZhcmlldHkuCgoKCgMHAAISAygHIgoLCgMHAAQSBCoEKCQKCgoDBwAGEgMqBBMKCgoDBwABEgMqFCQKCgoDBwADEgMqJy8KpAEKAgcBEgMuBCQamAEgT3B0aW9uYWw6IG9wdGlvbiBmb3IgdGhlIHRlbXBsYXRlIG5hbWUuCiBJZiBub3Qgc3BlY2lmaWVkLCB0aGUgbGFzdCBzZWdtZW50IG9mIHRoZSB0ZW1wbGF0ZSBwcm90bydzIHBhY2thZ2UgbmFtZSBpcyB1c2VkIHRvCiBkZXJpdmUgdGhlIHRlbXBsYXRlIG5hbWUuCgoKCgMHAQISAygHIgoLCgMHAQQSBC4EKjAKCgoDBwEFEgMuBAoKCgoDBwEBEgMuCxgKCgoDBwEDEgMuGyNiBnByb3RvMwq8LAoZZ29vZ2xlL3Byb3RvYnVmL2FueS5wcm90bxIPZ29vZ2xlLnByb3RvYnVmIjYKA0FueRIZCgh0eXBlX3VybBgBIAEoCVIHdHlwZVVybBIUCgV2YWx1ZRgCIAEoDFIFdmFsdWVCTwoTY29tLmdvb2dsZS5wcm90b2J1ZkIIQW55UHJvdG9QAVoFdHlwZXOiAgNHUEKqAh5Hb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlwZXNK/CoKBxIFHgCUAQEKzAwKAQwSAx4AEjLBDCBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgogaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KCiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKIG1ldDoKCiAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAogbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgogICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQogY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgogaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQogZGlzdHJpYnV0aW9uLgogICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cwogY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUwogIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgogQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCiBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQogT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KCggKAQISAyAIFwoICgEIEgMiADsKCwoECOcHABIDIgA7CgwKBQjnBwACEgMiBxcKDQoGCOcHAAIAEgMiBxcKDgoHCOcHAAIAARIDIgcXCgwKBQjnBwAHEgMiGjoKCAoBCBIDIwAcCgsKBAjnBwESAyMAHAoMCgUI5wcBAhIDIwcRCg0KBgjnBwECABIDIwcRCg4KBwjnBwECAAESAyMHEQoMCgUI5wcBBxIDIxQbCggKAQgSAyQALAoLCgQI5wcCEgMkACwKDAoFCOcHAgISAyQHEwoNCgYI5wcCAgASAyQHEwoOCgcI5wcCAgABEgMkBxMKDAoFCOcHAgcSAyQWKwoICgEIEgMlACkKCwoECOcHAxIDJQApCgwKBQjnBwMCEgMlBxsKDQoGCOcHAwIAEgMlBxsKDgoHCOcHAwIAARIDJQcbCgwKBQjnBwMHEgMlHigKCAoBCBIDJgAiCgsKBAjnBwQSAyYAIgoMCgUI5wcEAhIDJgcaCg0KBgjnBwQCABIDJgcaCg4KBwjnBwQCAAESAyYHGgoMCgUI5wcEAxIDJh0hCggKAQgSAycAIQoLCgQI5wcFEgMnACEKDAoFCOcHBQISAycHGAoNCgYI5wcFAgASAycHGAoOCgcI5wcFAgABEgMnBxgKDAoFCOcHBQcSAycbIArkEAoCBAASBXkAlAEBGtYQIGBBbnlgIGNvbnRhaW5zIGFuIGFyYml0cmFyeSBzZXJpYWxpemVkIHByb3RvY29sIGJ1ZmZlciBtZXNzYWdlIGFsb25nIHdpdGggYQogVVJMIHRoYXQgZGVzY3JpYmVzIHRoZSB0eXBlIG9mIHRoZSBzZXJpYWxpemVkIG1lc3NhZ2UuCgogUHJvdG9idWYgbGlicmFyeSBwcm92aWRlcyBzdXBwb3J0IHRvIHBhY2svdW5wYWNrIEFueSB2YWx1ZXMgaW4gdGhlIGZvcm0KIG9mIHV0aWxpdHkgZnVuY3Rpb25zIG9yIGFkZGl0aW9uYWwgZ2VuZXJhdGVkIG1ldGhvZHMgb2YgdGhlIEFueSB0eXBlLgoKIEV4YW1wbGUgMTogUGFjayBhbmQgdW5wYWNrIGEgbWVzc2FnZSBpbiBDKysuCgogICAgIEZvbyBmb28gPSAuLi47CiAgICAgQW55IGFueTsKICAgICBhbnkuUGFja0Zyb20oZm9vKTsKICAgICAuLi4KICAgICBpZiAoYW55LlVucGFja1RvKCZmb28pKSB7CiAgICAgICAuLi4KICAgICB9CgogRXhhbXBsZSAyOiBQYWNrIGFuZCB1bnBhY2sgYSBtZXNzYWdlIGluIEphdmEuCgogICAgIEZvbyBmb28gPSAuLi47CiAgICAgQW55IGFueSA9IEFueS5wYWNrKGZvbyk7CiAgICAgLi4uCiAgICAgaWYgKGFueS5pcyhGb28uY2xhc3MpKSB7CiAgICAgICBmb28gPSBhbnkudW5wYWNrKEZvby5jbGFzcyk7CiAgICAgfQoKICBFeGFtcGxlIDM6IFBhY2sgYW5kIHVucGFjayBhIG1lc3NhZ2UgaW4gUHl0aG9uLgoKICAgICBmb28gPSBGb28oLi4uKQogICAgIGFueSA9IEFueSgpCiAgICAgYW55LlBhY2soZm9vKQogICAgIC4uLgogICAgIGlmIGFueS5JcyhGb28uREVTQ1JJUFRPUik6CiAgICAgICBhbnkuVW5wYWNrKGZvbykKICAgICAgIC4uLgoKICBFeGFtcGxlIDQ6IFBhY2sgYW5kIHVucGFjayBhIG1lc3NhZ2UgaW4gR28KCiAgICAgIGZvbyA6PSAmcGIuRm9vey4uLn0KICAgICAgYW55LCBlcnIgOj0gcHR5cGVzLk1hcnNoYWxBbnkoZm9vKQogICAgICAuLi4KICAgICAgZm9vIDo9ICZwYi5Gb297fQogICAgICBpZiBlcnIgOj0gcHR5cGVzLlVubWFyc2hhbEFueShhbnksIGZvbyk7IGVyciAhPSBuaWwgewogICAgICAgIC4uLgogICAgICB9CgogVGhlIHBhY2sgbWV0aG9kcyBwcm92aWRlZCBieSBwcm90b2J1ZiBsaWJyYXJ5IHdpbGwgYnkgZGVmYXVsdCB1c2UKICd0eXBlLmdvb2dsZWFwaXMuY29tL2Z1bGwudHlwZS5uYW1lJyBhcyB0aGUgdHlwZSBVUkwgYW5kIHRoZSB1bnBhY2sKIG1ldGhvZHMgb25seSB1c2UgdGhlIGZ1bGx5IHF1YWxpZmllZCB0eXBlIG5hbWUgYWZ0ZXIgdGhlIGxhc3QgJy8nCiBpbiB0aGUgdHlwZSBVUkwsIGZvciBleGFtcGxlICJmb28uYmFyLmNvbS94L3kueiIgd2lsbCB5aWVsZCB0eXBlCiBuYW1lICJ5LnoiLgoKCiBKU09OCiA9PT09CiBUaGUgSlNPTiByZXByZXNlbnRhdGlvbiBvZiBhbiBgQW55YCB2YWx1ZSB1c2VzIHRoZSByZWd1bGFyCiByZXByZXNlbnRhdGlvbiBvZiB0aGUgZGVzZXJpYWxpemVkLCBlbWJlZGRlZCBtZXNzYWdlLCB3aXRoIGFuCiBhZGRpdGlvbmFsIGZpZWxkIGBAdHlwZWAgd2hpY2ggY29udGFpbnMgdGhlIHR5cGUgVVJMLiBFeGFtcGxlOgoKICAgICBwYWNrYWdlIGdvb2dsZS5wcm9maWxlOwogICAgIG1lc3NhZ2UgUGVyc29uIHsKICAgICAgIHN0cmluZyBmaXJzdF9uYW1lID0gMTsKICAgICAgIHN0cmluZyBsYXN0X25hbWUgPSAyOwogICAgIH0KCiAgICAgewogICAgICAgIkB0eXBlIjogInR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLnByb2ZpbGUuUGVyc29uIiwKICAgICAgICJmaXJzdE5hbWUiOiA8c3RyaW5nPiwKICAgICAgICJsYXN0TmFtZSI6IDxzdHJpbmc+CiAgICAgfQoKIElmIHRoZSBlbWJlZGRlZCBtZXNzYWdlIHR5cGUgaXMgd2VsbC1rbm93biBhbmQgaGFzIGEgY3VzdG9tIEpTT04KIHJlcHJlc2VudGF0aW9uLCB0aGF0IHJlcHJlc2VudGF0aW9uIHdpbGwgYmUgZW1iZWRkZWQgYWRkaW5nIGEgZmllbGQKIGB2YWx1ZWAgd2hpY2ggaG9sZHMgdGhlIGN1c3RvbSBKU09OIGluIGFkZGl0aW9uIHRvIHRoZSBgQHR5cGVgCiBmaWVsZC4gRXhhbXBsZSAoZm9yIG1lc3NhZ2UgW2dvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbl1bXSk6CgogICAgIHsKICAgICAgICJAdHlwZSI6ICJ0eXBlLmdvb2dsZWFwaXMuY29tL2dvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiIsCiAgICAgICAidmFsdWUiOiAiMS4yMTJzIgogICAgIH0KCgoKCgMEAAESA3kICwrkBwoEBAACABIEkAECFhrVByBBIFVSTC9yZXNvdXJjZSBuYW1lIHdob3NlIGNvbnRlbnQgZGVzY3JpYmVzIHRoZSB0eXBlIG9mIHRoZQogc2VyaWFsaXplZCBwcm90b2NvbCBidWZmZXIgbWVzc2FnZS4KCiBGb3IgVVJMcyB3aGljaCB1c2UgdGhlIHNjaGVtZSBgaHR0cGAsIGBodHRwc2AsIG9yIG5vIHNjaGVtZSwgdGhlCiBmb2xsb3dpbmcgcmVzdHJpY3Rpb25zIGFuZCBpbnRlcnByZXRhdGlvbnMgYXBwbHk6CgogKiBJZiBubyBzY2hlbWUgaXMgcHJvdmlkZWQsIGBodHRwc2AgaXMgYXNzdW1lZC4KICogVGhlIGxhc3Qgc2VnbWVudCBvZiB0aGUgVVJMJ3MgcGF0aCBtdXN0IHJlcHJlc2VudCB0aGUgZnVsbHkKICAgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIHR5cGUgKGFzIGluIGBwYXRoL2dvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbmApLgogICBUaGUgbmFtZSBzaG91bGQgYmUgaW4gYSBjYW5vbmljYWwgZm9ybSAoZS5nLiwgbGVhZGluZyAiLiIgaXMKICAgbm90IGFjY2VwdGVkKS4KICogQW4gSFRUUCBHRVQgb24gdGhlIFVSTCBtdXN0IHlpZWxkIGEgW2dvb2dsZS5wcm90b2J1Zi5UeXBlXVtdCiAgIHZhbHVlIGluIGJpbmFyeSBmb3JtYXQsIG9yIHByb2R1Y2UgYW4gZXJyb3IuCiAqIEFwcGxpY2F0aW9ucyBhcmUgYWxsb3dlZCB0byBjYWNoZSBsb29rdXAgcmVzdWx0cyBiYXNlZCBvbiB0aGUKICAgVVJMLCBvciBoYXZlIHRoZW0gcHJlY29tcGlsZWQgaW50byBhIGJpbmFyeSB0byBhdm9pZCBhbnkKICAgbG9va3VwLiBUaGVyZWZvcmUsIGJpbmFyeSBjb21wYXRpYmlsaXR5IG5lZWRzIHRvIGJlIHByZXNlcnZlZAogICBvbiBjaGFuZ2VzIHRvIHR5cGVzLiAoVXNlIHZlcnNpb25lZCB0eXBlIG5hbWVzIHRvIG1hbmFnZQogICBicmVha2luZyBjaGFuZ2VzLikKCiBTY2hlbWVzIG90aGVyIHRoYW4gYGh0dHBgLCBgaHR0cHNgIChvciB0aGUgZW1wdHkgc2NoZW1lKSBtaWdodCBiZQogdXNlZCB3aXRoIGltcGxlbWVudGF0aW9uIHNwZWNpZmljIHNlbWFudGljcy4KCgoOCgUEAAIABBIFkAECeQ0KDQoFBAACAAUSBJABAggKDQoFBAACAAESBJABCREKDQoFBAACAAMSBJABFBUKVwoEBAACARIEkwECEhpJIE11c3QgYmUgYSB2YWxpZCBzZXJpYWxpemVkIHByb3RvY29sIGJ1ZmZlciBvZiB0aGUgYWJvdmUgc3BlY2lmaWVkIHR5cGUuCgoPCgUEAAIBBBIGkwECkAEWCg0KBQQAAgEFEgSTAQIHCg0KBQQAAgEBEgSTAQgNCg0KBQQAAgEDEgSTARARYgZwcm90bzMKngkKKG1peGVyL2FkYXB0ZXIvbW9kZWwvdjFiZXRhMS9yZXBvcnQucHJvdG8SIWlzdGlvLm1peGVyLmFkYXB0ZXIubW9kZWwudjFiZXRhMRoUZ29nb3Byb3RvL2dvZ28ucHJvdG8iDgoMUmVwb3J0UmVzdWx0QjZaKGlzdGlvLmlvL2FwaS9taXhlci9hZGFwdGVyL21vZGVsL3YxYmV0YTHI4R4AqOIeAPDhHgBK6AcKBhIEDgAbFwq/BAoBDBIDDgASMrQEIENvcHlyaWdodCAyMDE4IElzdGlvIEF1dGhvcnMKCiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKCiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KCggKAQISAxAIKQoICgEIEgMSAD0KCwoECOcHABIDEgA9CgwKBQjnBwACEgMSBxEKDQoGCOcHAAIAEgMSBxEKDgoHCOcHAAIAARIDEgcRCgwKBQjnBwAHEgMSEjwKCQoCAwASAxQHHQoICgEIEgMWAC8KCwoECOcHARIDFgAvCgwKBQjnBwECEgMWByYKDQoGCOcHAQIAEgMWByYKDgoHCOcHAQIAARIDFgglCgwKBQjnBwEDEgMWKS4KCAoBCBIDFwAlCgsKBAjnBwISAxcAJQoMCgUI5wcCAhIDFwccCg0KBgjnBwICABIDFwccCg4KBwjnBwICAAESAxcIGwoMCgUI5wcCAxIDFx8kCggKAQgSAxgAKAoLCgQI5wcDEgMYACgKDAoFCOcHAwISAxgHHwoNCgYI5wcDAgASAxgHHwoOCgcI5wcDAgABEgMYCB4KDAoFCOcHAwMSAxgiJwozCgIEABIDGwAXGiggRXhwcmVzc2VzIHRoZSByZXN1bHQgb2YgYSByZXBvcnQgY2FsbC4KCgoKAwQAARIDGwgUYgZwcm90bzMK1BAKH3BvbGljeS92MWJldGExL3ZhbHVlX3R5cGUucHJvdG8SFGlzdGlvLnBvbGljeS52MWJldGExKrsBCglWYWx1ZVR5cGUSGgoWVkFMVUVfVFlQRV9VTlNQRUNJRklFRBAAEgoKBlNUUklORxABEgkKBUlOVDY0EAISCgoGRE9VQkxFEAMSCAoEQk9PTBAEEg0KCVRJTUVTVEFNUBAFEg4KCklQX0FERFJFU1MQBhIRCg1FTUFJTF9BRERSRVNTEAcSBwoDVVJJEAgSDAoIRE5TX05BTUUQCRIMCghEVVJBVElPThAKEg4KClNUUklOR19NQVAQC0IdWhtpc3Rpby5pby9hcGkvcG9saWN5L3YxYmV0YTFKtQ4KBhIEDgA8AQq/BAoBDBIDDgASMrQEIENvcHlyaWdodCAyMDE4IElzdGlvIEF1dGhvcnMKCiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKCiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KCggKAQISAxAIHAoICgEIEgMSADAKCwoECOcHABIDEgAwCgwKBQjnBwACEgMSBxEKDQoGCOcHAAIAEgMSBxEKDgoHCOcHAAIAARIDEgcRCgwKBQjnBwAHEgMSEi8KlgIKAgUAEgQYADwBGokCIFZhbHVlVHlwZSBkZXNjcmliZXMgdGhlIHR5cGVzIHRoYXQgdmFsdWVzIGluIHRoZSBJc3RpbyBzeXN0ZW0gY2FuIHRha2UuIFRoZXNlCiBhcmUgdXNlZCB0byBkZXNjcmliZSB0aGUgdHlwZSBvZiBBdHRyaWJ1dGVzIGF0IHJ1biB0aW1lLCBkZXNjcmliZSB0aGUgdHlwZSBvZgogdGhlIHJlc3VsdCBvZiBldmFsdWF0aW5nIGFuIGV4cHJlc3Npb24sIGFuZCB0byBkZXNjcmliZSB0aGUgcnVudGltZSB0eXBlIG9mCiBmaWVsZHMgb2Ygb3RoZXIgZGVzY3JpcHRvcnMuCgoKCgMFAAESAxgFDgomCgQFAAIAEgMaBB8aGSBJbnZhbGlkLCBkZWZhdWx0IHZhbHVlLgoKDAoFBQACAAESAxoEGgoMCgUFAAIAAhIDGh0eCjkKBAUAAgESAx0EDxosIEFuIHVuZGlzY3JpbWluYXRlZCB2YXJpYWJsZS1sZW5ndGggc3RyaW5nLgoKDAoFBQACAQESAx0ECgoMCgUFAAIBAhIDHQ0OCjgKBAUAAgISAyAEDhorIEFuIHVuZGlzY3JpbWluYXRlZCA2NC1iaXQgc2lnbmVkIGludGVnZXIuCgoMCgUFAAICARIDIAQJCgwKBQUAAgICEgMgDA0KPgoEBQACAxIDIwQPGjEgQW4gdW5kaXNjcmltaW5hdGVkIDY0LWJpdCBmbG9hdGluZy1wb2ludCB2YWx1ZS4KCgwKBQUAAgMBEgMjBAoKDAoFBQACAwISAyMNDgowCgQFAAIEEgMmBA0aIyBBbiB1bmRpc2NyaW1pbmF0ZWQgYm9vbGVhbiB2YWx1ZS4KCgwKBQUAAgQBEgMmBAgKDAoFBQACBAISAyYLDAofCgQFAAIFEgMpBBIaEiBBIHBvaW50IGluIHRpbWUuCgoMCgUFAAIFARIDKQQNCgwKBQUAAgUCEgMpEBEKHQoEBQACBhIDLAQTGhAgQW4gSVAgYWRkcmVzcy4KCgwKBQUAAgYBEgMsBA4KDAoFBQACBgISAywREgogCgQFAAIHEgMvBBYaEyBBbiBlbWFpbCBhZGRyZXNzLgoKDAoFBQACBwESAy8EEQoMCgUFAAIHAhIDLxQVChUKBAUAAggSAzIEDBoIIEEgVVJJLgoKDAoFBQACCAESAzIEBwoMCgUFAAIIAhIDMgoLChoKBAUAAgkSAzUEERoNIEEgRE5TIG5hbWUuCgoMCgUFAAIJARIDNQQMCgwKBQUAAgkCEgM1DxAKMQoEBQACChIDOAQSGiQgQSBzcGFuIGJldHdlZW4gdHdvIHBvaW50cyBpbiB0aW1lLgoKDAoFBQACCgESAzgEDAoMCgUFAAIKAhIDOA8RCkEKBAUAAgsSAzsEFBo0IEEgbWFwIHN0cmluZyAtPiBzdHJpbmcsIHR5cGljYWxseSB1c2VkIGJ5IGhlYWRlcnMuCgoMCgUFAAILARIDOwQOCgwKBQUAAgsCEgM7ERNiBnByb3RvMwr1KAoeZ29vZ2xlL3Byb3RvYnVmL2R1cmF0aW9uLnByb3RvEg9nb29nbGUucHJvdG9idWYiOgoIRHVyYXRpb24SGAoHc2Vjb25kcxgBIAEoA1IHc2Vjb25kcxIUCgVuYW5vcxgCIAEoBVIFbmFub3NCVwoTY29tLmdvb2dsZS5wcm90b2J1ZkINRHVyYXRpb25Qcm90b1ABWgV0eXBlc/gBAaICA0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc0qkJwoGEgQeAHQBCswMCgEMEgMeABIywQwgUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CiBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCgogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCiBtZXQ6CgogICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKIGRpc3RyaWJ1dGlvbi4KICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCiB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgoKIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCiBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCiBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAogREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCiBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCgoICgECEgMgCBcKCAoBCBIDIgA7CgsKBAjnBwASAyIAOwoMCgUI5wcAAhIDIgcXCg0KBgjnBwACABIDIgcXCg4KBwjnBwACAAESAyIHFwoMCgUI5wcABxIDIho6CggKAQgSAyMAHwoLCgQI5wcBEgMjAB8KDAoFCOcHAQISAyMHFwoNCgYI5wcBAgASAyMHFwoOCgcI5wcBAgABEgMjBxcKDAoFCOcHAQMSAyMaHgoICgEIEgMkABwKCwoECOcHAhIDJAAcCgwKBQjnBwICEgMkBxEKDQoGCOcHAgIAEgMkBxEKDgoHCOcHAgIAARIDJAcRCgwKBQjnBwIHEgMkFBsKCAoBCBIDJQAsCgsKBAjnBwMSAyUALAoMCgUI5wcDAhIDJQcTCg0KBgjnBwMCABIDJQcTCg4KBwjnBwMCAAESAyUHEwoMCgUI5wcDBxIDJRYrCggKAQgSAyYALgoLCgQI5wcEEgMmAC4KDAoFCOcHBAISAyYHGwoNCgYI5wcEAgASAyYHGwoOCgcI5wcEAgABEgMmBxsKDAoFCOcHBAcSAyYeLQoICgEIEgMnACIKCwoECOcHBRIDJwAiCgwKBQjnBwUCEgMnBxoKDQoGCOcHBQIAEgMnBxoKDgoHCOcHBQIAARIDJwcaCgwKBQjnBwUDEgMnHSEKCAoBCBIDKAAhCgsKBAjnBwYSAygAIQoMCgUI5wcGAhIDKAcYCg0KBgjnBwYCABIDKAcYCg4KBwjnBwYCAAESAygHGAoMCgUI5wcGBxIDKBsgCp8QCgIEABIEZgB0ARqSECBBIER1cmF0aW9uIHJlcHJlc2VudHMgYSBzaWduZWQsIGZpeGVkLWxlbmd0aCBzcGFuIG9mIHRpbWUgcmVwcmVzZW50ZWQKIGFzIGEgY291bnQgb2Ygc2Vjb25kcyBhbmQgZnJhY3Rpb25zIG9mIHNlY29uZHMgYXQgbmFub3NlY29uZAogcmVzb2x1dGlvbi4gSXQgaXMgaW5kZXBlbmRlbnQgb2YgYW55IGNhbGVuZGFyIGFuZCBjb25jZXB0cyBsaWtlICJkYXkiCiBvciAibW9udGgiLiBJdCBpcyByZWxhdGVkIHRvIFRpbWVzdGFtcCBpbiB0aGF0IHRoZSBkaWZmZXJlbmNlIGJldHdlZW4KIHR3byBUaW1lc3RhbXAgdmFsdWVzIGlzIGEgRHVyYXRpb24gYW5kIGl0IGNhbiBiZSBhZGRlZCBvciBzdWJ0cmFjdGVkCiBmcm9tIGEgVGltZXN0YW1wLiBSYW5nZSBpcyBhcHByb3hpbWF0ZWx5ICstMTAsMDAwIHllYXJzLgoKICMgRXhhbXBsZXMKCiBFeGFtcGxlIDE6IENvbXB1dGUgRHVyYXRpb24gZnJvbSB0d28gVGltZXN0YW1wcyBpbiBwc2V1ZG8gY29kZS4KCiAgICAgVGltZXN0YW1wIHN0YXJ0ID0gLi4uOwogICAgIFRpbWVzdGFtcCBlbmQgPSAuLi47CiAgICAgRHVyYXRpb24gZHVyYXRpb24gPSAuLi47CgogICAgIGR1cmF0aW9uLnNlY29uZHMgPSBlbmQuc2Vjb25kcyAtIHN0YXJ0LnNlY29uZHM7CiAgICAgZHVyYXRpb24ubmFub3MgPSBlbmQubmFub3MgLSBzdGFydC5uYW5vczsKCiAgICAgaWYgKGR1cmF0aW9uLnNlY29uZHMgPCAwICYmIGR1cmF0aW9uLm5hbm9zID4gMCkgewogICAgICAgZHVyYXRpb24uc2Vjb25kcyArPSAxOwogICAgICAgZHVyYXRpb24ubmFub3MgLT0gMTAwMDAwMDAwMDsKICAgICB9IGVsc2UgaWYgKGR1cmF0aW9ucy5zZWNvbmRzID4gMCAmJiBkdXJhdGlvbi5uYW5vcyA8IDApIHsKICAgICAgIGR1cmF0aW9uLnNlY29uZHMgLT0gMTsKICAgICAgIGR1cmF0aW9uLm5hbm9zICs9IDEwMDAwMDAwMDA7CiAgICAgfQoKIEV4YW1wbGUgMjogQ29tcHV0ZSBUaW1lc3RhbXAgZnJvbSBUaW1lc3RhbXAgKyBEdXJhdGlvbiBpbiBwc2V1ZG8gY29kZS4KCiAgICAgVGltZXN0YW1wIHN0YXJ0ID0gLi4uOwogICAgIER1cmF0aW9uIGR1cmF0aW9uID0gLi4uOwogICAgIFRpbWVzdGFtcCBlbmQgPSAuLi47CgogICAgIGVuZC5zZWNvbmRzID0gc3RhcnQuc2Vjb25kcyArIGR1cmF0aW9uLnNlY29uZHM7CiAgICAgZW5kLm5hbm9zID0gc3RhcnQubmFub3MgKyBkdXJhdGlvbi5uYW5vczsKCiAgICAgaWYgKGVuZC5uYW5vcyA8IDApIHsKICAgICAgIGVuZC5zZWNvbmRzIC09IDE7CiAgICAgICBlbmQubmFub3MgKz0gMTAwMDAwMDAwMDsKICAgICB9IGVsc2UgaWYgKGVuZC5uYW5vcyA+PSAxMDAwMDAwMDAwKSB7CiAgICAgICBlbmQuc2Vjb25kcyArPSAxOwogICAgICAgZW5kLm5hbm9zIC09IDEwMDAwMDAwMDA7CiAgICAgfQoKIEV4YW1wbGUgMzogQ29tcHV0ZSBEdXJhdGlvbiBmcm9tIGRhdGV0aW1lLnRpbWVkZWx0YSBpbiBQeXRob24uCgogICAgIHRkID0gZGF0ZXRpbWUudGltZWRlbHRhKGRheXM9MywgbWludXRlcz0xMCkKICAgICBkdXJhdGlvbiA9IER1cmF0aW9uKCkKICAgICBkdXJhdGlvbi5Gcm9tVGltZWRlbHRhKHRkKQoKICMgSlNPTiBNYXBwaW5nCgogSW4gSlNPTiBmb3JtYXQsIHRoZSBEdXJhdGlvbiB0eXBlIGlzIGVuY29kZWQgYXMgYSBzdHJpbmcgcmF0aGVyIHRoYW4gYW4KIG9iamVjdCwgd2hlcmUgdGhlIHN0cmluZyBlbmRzIGluIHRoZSBzdWZmaXggInMiIChpbmRpY2F0aW5nIHNlY29uZHMpIGFuZAogaXMgcHJlY2VkZWQgYnkgdGhlIG51bWJlciBvZiBzZWNvbmRzLCB3aXRoIG5hbm9zZWNvbmRzIGV4cHJlc3NlZCBhcwogZnJhY3Rpb25hbCBzZWNvbmRzLiBGb3IgZXhhbXBsZSwgMyBzZWNvbmRzIHdpdGggMCBuYW5vc2Vjb25kcyBzaG91bGQgYmUKIGVuY29kZWQgaW4gSlNPTiBmb3JtYXQgYXMgIjNzIiwgd2hpbGUgMyBzZWNvbmRzIGFuZCAxIG5hbm9zZWNvbmQgc2hvdWxkCiBiZSBleHByZXNzZWQgaW4gSlNPTiBmb3JtYXQgYXMgIjMuMDAwMDAwMDAxcyIsIGFuZCAzIHNlY29uZHMgYW5kIDEKIG1pY3Jvc2Vjb25kIHNob3VsZCBiZSBleHByZXNzZWQgaW4gSlNPTiBmb3JtYXQgYXMgIjMuMDAwMDAxcyIuCgoKCgoKAwQAARIDZggQCtwBCgQEAAIAEgNrAhQazgEgU2lnbmVkIHNlY29uZHMgb2YgdGhlIHNwYW4gb2YgdGltZS4gTXVzdCBiZSBmcm9tIC0zMTUsNTc2LDAwMCwwMDAKIHRvICszMTUsNTc2LDAwMCwwMDAgaW5jbHVzaXZlLiBOb3RlOiB0aGVzZSBib3VuZHMgYXJlIGNvbXB1dGVkIGZyb206CiA2MCBzZWMvbWluICogNjAgbWluL2hyICogMjQgaHIvZGF5ICogMzY1LjI1IGRheXMveWVhciAqIDEwMDAwIHllYXJzCgoNCgUEAAIABBIEawJmEgoMCgUEAAIABRIDawIHCgwKBQQAAgABEgNrCA8KDAoFBAACAAMSA2sSEwqDAwoEBAACARIDcwISGvUCIFNpZ25lZCBmcmFjdGlvbnMgb2YgYSBzZWNvbmQgYXQgbmFub3NlY29uZCByZXNvbHV0aW9uIG9mIHRoZSBzcGFuCiBvZiB0aW1lLiBEdXJhdGlvbnMgbGVzcyB0aGFuIG9uZSBzZWNvbmQgYXJlIHJlcHJlc2VudGVkIHdpdGggYSAwCiBgc2Vjb25kc2AgZmllbGQgYW5kIGEgcG9zaXRpdmUgb3IgbmVnYXRpdmUgYG5hbm9zYCBmaWVsZC4gRm9yIGR1cmF0aW9ucwogb2Ygb25lIHNlY29uZCBvciBtb3JlLCBhIG5vbi16ZXJvIHZhbHVlIGZvciB0aGUgYG5hbm9zYCBmaWVsZCBtdXN0IGJlCiBvZiB0aGUgc2FtZSBzaWduIGFzIHRoZSBgc2Vjb25kc2AgZmllbGQuIE11c3QgYmUgZnJvbSAtOTk5LDk5OSw5OTkKIHRvICs5OTksOTk5LDk5OSBpbmNsdXNpdmUuCgoNCgUEAAIBBBIEcwJrFAoMCgUEAAIBBRIDcwIHCgwKBQQAAgEBEgNzCA0KDAoFBAACAQMSA3MQEWIGcHJvdG8zCqAxCh9nb29nbGUvcHJvdG9idWYvdGltZXN0YW1wLnByb3RvEg9nb29nbGUucHJvdG9idWYiOwoJVGltZXN0YW1wEhgKB3NlY29uZHMYASABKANSB3NlY29uZHMSFAoFbmFub3MYAiABKAVSBW5hbm9zQlgKE2NvbS5nb29nbGUucHJvdG9idWZCDlRpbWVzdGFtcFByb3RvUAFaBXR5cGVz+AEBogIDR1BCqgIeR29vZ2xlLlByb3RvYnVmLldlbGxLbm93blR5cGVzSswvCgcSBR4AhAEBCswMCgEMEgMeABIywQwgUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CiBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCgogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCiBtZXQ6CgogICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKIGRpc3RyaWJ1dGlvbi4KICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCiB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgoKIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCiBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCiBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAogREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCiBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCgoICgECEgMgCBcKCAoBCBIDIgA7CgsKBAjnBwASAyIAOwoMCgUI5wcAAhIDIgcXCg0KBgjnBwACABIDIgcXCg4KBwjnBwACAAESAyIHFwoMCgUI5wcABxIDIho6CggKAQgSAyMAHwoLCgQI5wcBEgMjAB8KDAoFCOcHAQISAyMHFwoNCgYI5wcBAgASAyMHFwoOCgcI5wcBAgABEgMjBxcKDAoFCOcHAQMSAyMaHgoICgEIEgMkABwKCwoECOcHAhIDJAAcCgwKBQjnBwICEgMkBxEKDQoGCOcHAgIAEgMkBxEKDgoHCOcHAgIAARIDJAcRCgwKBQjnBwIHEgMkFBsKCAoBCBIDJQAsCgsKBAjnBwMSAyUALAoMCgUI5wcDAhIDJQcTCg0KBgjnBwMCABIDJQcTCg4KBwjnBwMCAAESAyUHEwoMCgUI5wcDBxIDJRYrCggKAQgSAyYALwoLCgQI5wcEEgMmAC8KDAoFCOcHBAISAyYHGwoNCgYI5wcEAgASAyYHGwoOCgcI5wcEAgABEgMmBxsKDAoFCOcHBAcSAyYeLgoICgEIEgMnACIKCwoECOcHBRIDJwAiCgwKBQjnBwUCEgMnBxoKDQoGCOcHBQIAEgMnBxoKDgoHCOcHBQIAARIDJwcaCgwKBQjnBwUDEgMnHSEKCAoBCBIDKAAhCgsKBAjnBwYSAygAIQoMCgUI5wcGAhIDKAcYCg0KBgjnBwYCABIDKAcYCg4KBwjnBwYCAAESAygHGAoMCgUI5wcGBxIDKBsgCqAaCgIEABIFeACEAQEakhogQSBUaW1lc3RhbXAgcmVwcmVzZW50cyBhIHBvaW50IGluIHRpbWUgaW5kZXBlbmRlbnQgb2YgYW55IHRpbWUgem9uZQogb3IgY2FsZW5kYXIsIHJlcHJlc2VudGVkIGFzIHNlY29uZHMgYW5kIGZyYWN0aW9ucyBvZiBzZWNvbmRzIGF0CiBuYW5vc2Vjb25kIHJlc29sdXRpb24gaW4gVVRDIEVwb2NoIHRpbWUuIEl0IGlzIGVuY29kZWQgdXNpbmcgdGhlCiBQcm9sZXB0aWMgR3JlZ29yaWFuIENhbGVuZGFyIHdoaWNoIGV4dGVuZHMgdGhlIEdyZWdvcmlhbiBjYWxlbmRhcgogYmFja3dhcmRzIHRvIHllYXIgb25lLiBJdCBpcyBlbmNvZGVkIGFzc3VtaW5nIGFsbCBtaW51dGVzIGFyZSA2MAogc2Vjb25kcyBsb25nLCBpLmUuIGxlYXAgc2Vjb25kcyBhcmUgInNtZWFyZWQiIHNvIHRoYXQgbm8gbGVhcCBzZWNvbmQKIHRhYmxlIGlzIG5lZWRlZCBmb3IgaW50ZXJwcmV0YXRpb24uIFJhbmdlIGlzIGZyb20KIDAwMDEtMDEtMDFUMDA6MDA6MDBaIHRvIDk5OTktMTItMzFUMjM6NTk6NTkuOTk5OTk5OTk5Wi4KIEJ5IHJlc3RyaWN0aW5nIHRvIHRoYXQgcmFuZ2UsIHdlIGVuc3VyZSB0aGF0IHdlIGNhbiBjb252ZXJ0IHRvCiBhbmQgZnJvbSAgUkZDIDMzMzkgZGF0ZSBzdHJpbmdzLgogU2VlIFtodHRwczovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzMzOS50eHRdKGh0dHBzOi8vd3d3LmlldGYub3JnL3JmYy9yZmMzMzM5LnR4dCkuCgogIyBFeGFtcGxlcwoKIEV4YW1wbGUgMTogQ29tcHV0ZSBUaW1lc3RhbXAgZnJvbSBQT1NJWCBgdGltZSgpYC4KCiAgICAgVGltZXN0YW1wIHRpbWVzdGFtcDsKICAgICB0aW1lc3RhbXAuc2V0X3NlY29uZHModGltZShOVUxMKSk7CiAgICAgdGltZXN0YW1wLnNldF9uYW5vcygwKTsKCiBFeGFtcGxlIDI6IENvbXB1dGUgVGltZXN0YW1wIGZyb20gUE9TSVggYGdldHRpbWVvZmRheSgpYC4KCiAgICAgc3RydWN0IHRpbWV2YWwgdHY7CiAgICAgZ2V0dGltZW9mZGF5KCZ0diwgTlVMTCk7CgogICAgIFRpbWVzdGFtcCB0aW1lc3RhbXA7CiAgICAgdGltZXN0YW1wLnNldF9zZWNvbmRzKHR2LnR2X3NlYyk7CiAgICAgdGltZXN0YW1wLnNldF9uYW5vcyh0di50dl91c2VjICogMTAwMCk7CgogRXhhbXBsZSAzOiBDb21wdXRlIFRpbWVzdGFtcCBmcm9tIFdpbjMyIGBHZXRTeXN0ZW1UaW1lQXNGaWxlVGltZSgpYC4KCiAgICAgRklMRVRJTUUgZnQ7CiAgICAgR2V0U3lzdGVtVGltZUFzRmlsZVRpbWUoJmZ0KTsKICAgICBVSU5UNjQgdGlja3MgPSAoKChVSU5UNjQpZnQuZHdIaWdoRGF0ZVRpbWUpIDw8IDMyKSB8IGZ0LmR3TG93RGF0ZVRpbWU7CgogICAgIC8vIEEgV2luZG93cyB0aWNrIGlzIDEwMCBuYW5vc2Vjb25kcy4gV2luZG93cyBlcG9jaCAxNjAxLTAxLTAxVDAwOjAwOjAwWgogICAgIC8vIGlzIDExNjQ0NDczNjAwIHNlY29uZHMgYmVmb3JlIFVuaXggZXBvY2ggMTk3MC0wMS0wMVQwMDowMDowMFouCiAgICAgVGltZXN0YW1wIHRpbWVzdGFtcDsKICAgICB0aW1lc3RhbXAuc2V0X3NlY29uZHMoKElOVDY0KSAoKHRpY2tzIC8gMTAwMDAwMDApIC0gMTE2NDQ0NzM2MDBMTCkpOwogICAgIHRpbWVzdGFtcC5zZXRfbmFub3MoKElOVDMyKSAoKHRpY2tzICUgMTAwMDAwMDApICogMTAwKSk7CgogRXhhbXBsZSA0OiBDb21wdXRlIFRpbWVzdGFtcCBmcm9tIEphdmEgYFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpYC4KCiAgICAgbG9uZyBtaWxsaXMgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKCiAgICAgVGltZXN0YW1wIHRpbWVzdGFtcCA9IFRpbWVzdGFtcC5uZXdCdWlsZGVyKCkuc2V0U2Vjb25kcyhtaWxsaXMgLyAxMDAwKQogICAgICAgICAuc2V0TmFub3MoKGludCkgKChtaWxsaXMgJSAxMDAwKSAqIDEwMDAwMDApKS5idWlsZCgpOwoKCiBFeGFtcGxlIDU6IENvbXB1dGUgVGltZXN0YW1wIGZyb20gY3VycmVudCB0aW1lIGluIFB5dGhvbi4KCiAgICAgdGltZXN0YW1wID0gVGltZXN0YW1wKCkKICAgICB0aW1lc3RhbXAuR2V0Q3VycmVudFRpbWUoKQoKICMgSlNPTiBNYXBwaW5nCgogSW4gSlNPTiBmb3JtYXQsIHRoZSBUaW1lc3RhbXAgdHlwZSBpcyBlbmNvZGVkIGFzIGEgc3RyaW5nIGluIHRoZQogW1JGQyAzMzM5XShodHRwczovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzMzOS50eHQpIGZvcm1hdC4gVGhhdCBpcywgdGhlCiBmb3JtYXQgaXMgInt5ZWFyfS17bW9udGh9LXtkYXl9VHtob3VyfTp7bWlufTp7c2VjfVsue2ZyYWNfc2VjfV1aIgogd2hlcmUge3llYXJ9IGlzIGFsd2F5cyBleHByZXNzZWQgdXNpbmcgZm91ciBkaWdpdHMgd2hpbGUge21vbnRofSwge2RheX0sCiB7aG91cn0sIHttaW59LCBhbmQge3NlY30gYXJlIHplcm8tcGFkZGVkIHRvIHR3byBkaWdpdHMgZWFjaC4gVGhlIGZyYWN0aW9uYWwKIHNlY29uZHMsIHdoaWNoIGNhbiBnbyB1cCB0byA5IGRpZ2l0cyAoaS5lLiB1cCB0byAxIG5hbm9zZWNvbmQgcmVzb2x1dGlvbiksCiBhcmUgb3B0aW9uYWwuIFRoZSAiWiIgc3VmZml4IGluZGljYXRlcyB0aGUgdGltZXpvbmUgKCJVVEMiKTsgdGhlIHRpbWV6b25lCiBpcyByZXF1aXJlZCwgdGhvdWdoIG9ubHkgVVRDIChhcyBpbmRpY2F0ZWQgYnkgIloiKSBpcyBwcmVzZW50bHkgc3VwcG9ydGVkLgoKIEZvciBleGFtcGxlLCAiMjAxNy0wMS0xNVQwMTozMDoxNS4wMVoiIGVuY29kZXMgMTUuMDEgc2Vjb25kcyBwYXN0CiAwMTozMCBVVEMgb24gSmFudWFyeSAxNSwgMjAxNy4KCiBJbiBKYXZhU2NyaXB0LCBvbmUgY2FuIGNvbnZlcnQgYSBEYXRlIG9iamVjdCB0byB0aGlzIGZvcm1hdCB1c2luZyB0aGUKIHN0YW5kYXJkIFt0b0lTT1N0cmluZygpXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9EYXRlL3RvSVNPU3RyaW5nXQogbWV0aG9kLiBJbiBQeXRob24sIGEgc3RhbmRhcmQgYGRhdGV0aW1lLmRhdGV0aW1lYCBvYmplY3QgY2FuIGJlIGNvbnZlcnRlZAogdG8gdGhpcyBmb3JtYXQgdXNpbmcgW2BzdHJmdGltZWBdKGh0dHBzOi8vZG9jcy5weXRob24ub3JnLzIvbGlicmFyeS90aW1lLmh0bWwjdGltZS5zdHJmdGltZSkKIHdpdGggdGhlIHRpbWUgZm9ybWF0IHNwZWMgJyVZLSVtLSVkVCVIOiVNOiVTLiVmWicuIExpa2V3aXNlLCBpbiBKYXZhLCBvbmUKIGNhbiB1c2UgdGhlIEpvZGEgVGltZSdzIFtgSVNPRGF0ZVRpbWVGb3JtYXQuZGF0ZVRpbWUoKWBdKAogaHR0cDovL2pvZGEtdGltZS5zb3VyY2Vmb3JnZS5uZXQvYXBpZG9jcy9vcmcvam9kYS90aW1lL2Zvcm1hdC9JU09EYXRlVGltZUZvcm1hdC5odG1sI2RhdGVUaW1lKCkpCiB0byBvYnRhaW4gYSBmb3JtYXR0ZXIgY2FwYWJsZSBvZiBnZW5lcmF0aW5nIHRpbWVzdGFtcHMgaW4gdGhpcyBmb3JtYXQuCgoKCgoKAwQAARIDeAgRCpwBCgQEAAIAEgN9AhQajgEgUmVwcmVzZW50cyBzZWNvbmRzIG9mIFVUQyB0aW1lIHNpbmNlIFVuaXggZXBvY2gKIDE5NzAtMDEtMDFUMDA6MDA6MDBaLiBNdXN0IGJlIGZyb20gMDAwMS0wMS0wMVQwMDowMDowMFogdG8KIDk5OTktMTItMzFUMjM6NTk6NTlaIGluY2x1c2l2ZS4KCg0KBQQAAgAEEgR9AngTCgwKBQQAAgAFEgN9AgcKDAoFBAACAAESA30IDwoMCgUEAAIAAxIDfRITCuUBCgQEAAIBEgSDAQISGtYBIE5vbi1uZWdhdGl2ZSBmcmFjdGlvbnMgb2YgYSBzZWNvbmQgYXQgbmFub3NlY29uZCByZXNvbHV0aW9uLiBOZWdhdGl2ZQogc2Vjb25kIHZhbHVlcyB3aXRoIGZyYWN0aW9ucyBtdXN0IHN0aWxsIGhhdmUgbm9uLW5lZ2F0aXZlIG5hbm9zIHZhbHVlcwogdGhhdCBjb3VudCBmb3J3YXJkIGluIHRpbWUuIE11c3QgYmUgZnJvbSAwIHRvIDk5OSw5OTksOTk5CiBpbmNsdXNpdmUuCgoOCgUEAAIBBBIFgwECfRQKDQoFBAACAQUSBIMBAgcKDQoFBAACAQESBIMBCA0KDQoFBAACAQMSBIMBEBFiBnByb3RvMwqnLwoZcG9saWN5L3YxYmV0YTEvdHlwZS5wcm90bxIUaXN0aW8ucG9saWN5LnYxYmV0YTEaHmdvb2dsZS9wcm90b2J1Zi9kdXJhdGlvbi5wcm90bxofZ29vZ2xlL3Byb3RvYnVmL3RpbWVzdGFtcC5wcm90byLXBAoFVmFsdWUSIwoMc3RyaW5nX3ZhbHVlGAEgASgJSABSC3N0cmluZ1ZhbHVlEiEKC2ludDY0X3ZhbHVlGAIgASgDSABSCmludDY0VmFsdWUSIwoMZG91YmxlX3ZhbHVlGAMgASgBSABSC2RvdWJsZVZhbHVlEh8KCmJvb2xfdmFsdWUYBCABKAhIAFIJYm9vbFZhbHVlEksKEGlwX2FkZHJlc3NfdmFsdWUYBSABKAsyHy5pc3Rpby5wb2xpY3kudjFiZXRhMS5JUEFkZHJlc3NIAFIOaXBBZGRyZXNzVmFsdWUSSgoPdGltZXN0YW1wX3ZhbHVlGAYgASgLMh8uaXN0aW8ucG9saWN5LnYxYmV0YTEuVGltZVN0YW1wSABSDnRpbWVzdGFtcFZhbHVlEkcKDmR1cmF0aW9uX3ZhbHVlGAcgASgLMh4uaXN0aW8ucG9saWN5LnYxYmV0YTEuRHVyYXRpb25IAFINZHVyYXRpb25WYWx1ZRJUChNlbWFpbF9hZGRyZXNzX3ZhbHVlGAggASgLMiIuaXN0aW8ucG9saWN5LnYxYmV0YTEuRW1haWxBZGRyZXNzSABSEWVtYWlsQWRkcmVzc1ZhbHVlEkUKDmRuc19uYW1lX3ZhbHVlGAkgASgLMh0uaXN0aW8ucG9saWN5LnYxYmV0YTEuRE5TTmFtZUgAUgxkbnNOYW1lVmFsdWUSOAoJdXJpX3ZhbHVlGAogASgLMhkuaXN0aW8ucG9saWN5LnYxYmV0YTEuVXJpSABSCHVyaVZhbHVlQgcKBXZhbHVlIiEKCUlQQWRkcmVzcxIUCgV2YWx1ZRgBIAEoDFIFdmFsdWUiOwoIRHVyYXRpb24SLwoFdmFsdWUYASABKAsyGS5nb29nbGUucHJvdG9idWYuRHVyYXRpb25SBXZhbHVlIj0KCVRpbWVTdGFtcBIwCgV2YWx1ZRgBIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBSBXZhbHVlIh8KB0ROU05hbWUSFAoFdmFsdWUYASABKAlSBXZhbHVlIiQKDEVtYWlsQWRkcmVzcxIUCgV2YWx1ZRgBIAEoCVIFdmFsdWUiGwoDVXJpEhQKBXZhbHVlGAEgASgJUgV2YWx1ZUIdWhtpc3Rpby5pby9hcGkvcG9saWN5L3YxYmV0YTFKricKBhIEDgB+AQq/BAoBDBIDDgASMrQEIENvcHlyaWdodCAyMDE4IElzdGlvIEF1dGhvcnMKCiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKCiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KCggKAQISAxAIHAoICgEIEgMSADAKCwoECOcHABIDEgAwCgwKBQjnBwACEgMSBxEKDQoGCOcHAAIAEgMSBxEKDgoHCOcHAAIAARIDEgcRCgwKBQjnBwAHEgMSEi8KCQoCAwASAxQHJwoJCgIDARIDFQcoCsgGCgIEABIEIABAARq7BiBBbiBpbnN0YW5jZSBmaWVsZCBvZiB0eXBlIFZhbHVlIGRlbm90ZXMgdGhhdCB0aGUgZXhwcmVzc2lvbiBmb3IgdGhlIGZpZWxkIGlzIG9mIGR5bmFtaWMgdHlwZSBhbmQgY2FuIGV2YWxhdXRlIHRvIGFueQogW1ZhbHVlVHlwZV1baXN0aW8ucG9saWN5LnYxYmV0YTEuVmFsdWVUeXBlXSBlbnVtIHZhbHVlcy4gRm9yIGV4YW1wbGUsIHdoZW4KIGF1dGhvcmluZyBhbiBpbnN0YW5jZSBjb25maWd1cmF0aW9uIGZvciBhIHRlbXBsYXRlIHRoYXQgaGFzIGEgZmllbGQgYGRhdGFgIG9mIHR5cGUgYGlzdGlvLnBvbGljeS52MWJldGExLlZhbHVlYCwKIGJvdGggb2YgdGhlIGZvbGxvd2luZyBleHByZXNzaW9ucyBhcmUgdmFsaWQgYGRhdGE6IHNvdXJjZS5pcCB8IGlwKCIwLjAuMC4wIilgLCBgZGF0YTogcmVxdWVzdC5pZCB8ICIiYDsKIHRoZSByZXN1bHRpbmcgdHlwZSBpcyBlaXRoZXIgVmFsdWVUeXBlLklQX0FERFJFU1Mgb3IgVmFsdWVUeXBlLlNUUklORyBmb3IgdGhlIHR3byBjYXNlcyByZXNwZWN0aXZlbHkuCgogT2JqZWN0cyBvZiB0eXBlIFZhbHVlIGFyZSBhbHNvIHBhc3NlZCB0byB0aGUgYWRhcHRlcnMgZHVyaW5nIHJlcXVlc3QtdGltZS4gVGhlcmUgaXMgYSAxOjEgbWFwcGluZyBiZXR3ZWVuCiBvbmVvZiBmaWVsZHMgaW4gYFZhbHVlYCBhbmQgZW51bSB2YWx1ZXMgaW5zaWRlIGBWYWx1ZVR5cGVgLiBEZXBlbmRpbmcgb24gdGhlIGV4cHJlc3Npb24ncyBldmFsdWF0ZWQgYFZhbHVlVHlwZWAsCiB0aGUgZXF1aXZhbGVudCBvbmVvZiBmaWVsZCBpbiBgVmFsdWVgIGlzIHBvcHVsYXRlZCBieSBNaXhlciBhbmQgcGFzc2VkIHRvIHRoZSBhZGFwdGVycy4KCgoKAwQAARIDIAgNCgwKBAQACAASBCEEPwUKDAoFBAAIAAESAyEKDwotCgQEAAIAEgMjCCAaICBVc2VkIGZvciB2YWx1ZXMgb2YgdHlwZSBTVFJJTkcKCgwKBQQAAgAFEgMjCA4KDAoFBAACAAESAyMPGwoMCgUEAAIAAxIDIx4fCiwKBAQAAgESAyYIHhofIFVzZWQgZm9yIHZhbHVlcyBvZiB0eXBlIElOVDY0CgoMCgUEAAIBBRIDJggNCgwKBQQAAgEBEgMmDhkKDAoFBAACAQMSAyYcHQotCgQEAAICEgMpCCAaICBVc2VkIGZvciB2YWx1ZXMgb2YgdHlwZSBET1VCTEUKCgwKBQQAAgIFEgMpCA4KDAoFBAACAgESAykPGwoMCgUEAAICAxIDKR4fCisKBAQAAgMSAywIHBoeIFVzZWQgZm9yIHZhbHVlcyBvZiB0eXBlIEJPT0wKCgwKBQQAAgMFEgMsCAwKDAoFBAACAwESAywNFwoMCgUEAAIDAxIDLBobCjAKBAQAAgQSAy8IJxojIFVzZWQgZm9yIHZhbHVlcyBvZiB0eXBlIElQQWRkcmVzcwoKDAoFBAACBAYSAy8IEQoMCgUEAAIEARIDLxIiCgwKBQQAAgQDEgMvJSYKMAoEBAACBRIDMggmGiMgVXNlZCBmb3IgdmFsdWVzIG9mIHR5cGUgVElNRVNUQU1QCgoMCgUEAAIFBhIDMggRCgwKBQQAAgUBEgMyEiEKDAoFBAACBQMSAzIkJQovCgQEAAIGEgM1CCQaIiBVc2VkIGZvciB2YWx1ZXMgb2YgdHlwZSBEVVJBVElPTgoKDAoFBAACBgYSAzUIEAoMCgUEAAIGARIDNREfCgwKBQQAAgYDEgM1IiMKMwoEBAACBxIDOAgtGiYgVXNlZCBmb3IgdmFsdWVzIG9mIHR5cGUgRW1haWxBZGRyZXNzCgoMCgUEAAIHBhIDOAgUCgwKBQQAAgcBEgM4FSgKDAoFBAACBwMSAzgrLAouCgQEAAIIEgM7CCMaISBVc2VkIGZvciB2YWx1ZXMgb2YgdHlwZSBETlNOYW1lCgoMCgUEAAIIBhIDOwgPCgwKBQQAAggBEgM7EB4KDAoFBAACCAMSAzshIgoqCgQEAAIJEgM+CBsaHSBVc2VkIGZvciB2YWx1ZXMgb2YgdHlwZSBVcmkKCgwKBQQAAgkGEgM+CAsKDAoFBAACCQESAz4MFQoMCgUEAAIJAxIDPhgaCqsCCgIEARIERwBKARqeAiBBbiBpbnN0YW5jZSBmaWVsZCBvZiB0eXBlIElQQWRkcmVzcyBkZW5vdGVzIHRoYXQgdGhlIGV4cHJlc3Npb24gZm9yIHRoZSBmaWVsZCBtdXN0IGV2YWxhdXRlIHRvCiBbVmFsdWVUeXBlLklQX0FERFJFU1NdW2lzdGlvLnBvbGljeS52MWJldGExLlZhbHVlVHlwZS5JUF9BRERSRVNTXQoKIE9iamVjdHMgb2YgdHlwZSBJUEFkZHJlc3MgYXJlIGFsc28gcGFzc2VkIHRvIHRoZSBhZGFwdGVycyBkdXJpbmcgcmVxdWVzdC10aW1lIGZvciB0aGUgaW5zdGFuY2UgZmllbGRzIG9mCiB0eXBlIElQQWRkcmVzcwoKCgoDBAEBEgNHCBEKKgoEBAECABIDSQQUGh0gSVBBZGRyZXNzIGVuY29kZWQgYXMgYnl0ZXMuCgoNCgUEAQIABBIESQRHEwoMCgUEAQIABRIDSQQJCgwKBQQBAgABEgNJCg8KDAoFBAECAAMSA0kSEwqkAgoCBAISBFEAVAEalwIgQW4gaW5zdGFuY2UgZmllbGQgb2YgdHlwZSBEdXJhdGlvbiBkZW5vdGVzIHRoYXQgdGhlIGV4cHJlc3Npb24gZm9yIHRoZSBmaWVsZCBtdXN0IGV2YWxhdXRlIHRvCiBbVmFsdWVUeXBlLkRVUkFUSU9OXVtpc3Rpby5wb2xpY3kudjFiZXRhMS5WYWx1ZVR5cGUuRFVSQVRJT05dCgogT2JqZWN0cyBvZiB0eXBlIER1cmF0aW9uIGFyZSBhbHNvIHBhc3NlZCB0byB0aGUgYWRhcHRlcnMgZHVyaW5nIHJlcXVlc3QtdGltZSBmb3IgdGhlIGluc3RhbmNlIGZpZWxkcyBvZgogdHlwZSBEdXJhdGlvbgoKCgoDBAIBEgNRCBAKPAoEBAICABIDUwQnGi8gRHVyYXRpb24gZW5jb2RlZCBhcyBnb29nbGUucHJvdG9idWYuRHVyYXRpb24uCgoNCgUEAgIABBIEUwRREgoMCgUEAgIABhIDUwQcCgwKBQQCAgABEgNTHSIKDAoFBAICAAMSA1MlJgqpAgoCBAMSBFsAXgEanAIgQW4gaW5zdGFuY2UgZmllbGQgb2YgdHlwZSBUaW1lU3RhbXAgZGVub3RlcyB0aGF0IHRoZSBleHByZXNzaW9uIGZvciB0aGUgZmllbGQgbXVzdCBldmFsYXV0ZSB0bwogW1ZhbHVlVHlwZS5USU1FU1RBTVBdW2lzdGlvLnBvbGljeS52MWJldGExLlZhbHVlVHlwZS5USU1FU1RBTVBdCgogT2JqZWN0cyBvZiB0eXBlIFRpbWVTdGFtcCBhcmUgYWxzbyBwYXNzZWQgdG8gdGhlIGFkYXB0ZXJzIGR1cmluZyByZXF1ZXN0LXRpbWUgZm9yIHRoZSBpbnN0YW5jZSBmaWVsZHMgb2YKIHR5cGUgVGltZVN0YW1wCgoKCgMEAwESA1sIEQo+CgQEAwIAEgNdBCgaMSBUaW1lU3RhbXAgZW5jb2RlZCBhcyBnb29nbGUucHJvdG9idWYuVGltZXN0YW1wLgoKDQoFBAMCAAQSBF0EWxMKDAoFBAMCAAYSA10EHQoMCgUEAwIAARIDXR4jCgwKBQQDAgADEgNdJicKoQIKAgQEEgRlAGgBGpQCIEFuIGluc3RhbmNlIGZpZWxkIG9mIHR5cGUgRE5TTmFtZSBkZW5vdGVzIHRoYXQgdGhlIGV4cHJlc3Npb24gZm9yIHRoZSBmaWVsZCBtdXN0IGV2YWxhdXRlIHRvCiBbVmFsdWVUeXBlLkROU19OQU1FXVtpc3Rpby5wb2xpY3kudjFiZXRhMS5WYWx1ZVR5cGUuRE5TX05BTUVdCgogT2JqZWN0cyBvZiB0eXBlIEROU05hbWUgYXJlIGFsc28gcGFzc2VkIHRvIHRoZSBhZGFwdGVycyBkdXJpbmcgcmVxdWVzdC10aW1lIGZvciB0aGUgaW5zdGFuY2UgZmllbGRzIG9mCiB0eXBlIEROU05hbWUKCgoKAwQEARIDZQgPCikKBAQEAgASA2cEFRocIEROU05hbWUgZW5jb2RlZCBhcyBzdHJpbmcuCgoNCgUEBAIABBIEZwRlEQoMCgUEBAIABRIDZwQKCgwKBQQEAgABEgNnCxAKDAoFBAQCAAMSA2cTFArbAgoCBAUSBHAAcwEazgIgRE8gTk9UIFVTRSAhISBVbmRlciBEZXZlbG9wbWVudAogQW4gaW5zdGFuY2UgZmllbGQgb2YgdHlwZSBFbWFpbEFkZHJlc3MgZGVub3RlcyB0aGF0IHRoZSBleHByZXNzaW9uIGZvciB0aGUgZmllbGQgbXVzdCBldmFsYXV0ZSB0bwogW1ZhbHVlVHlwZS5FTUFJTF9BRERSRVNTXVtpc3Rpby5wb2xpY3kudjFiZXRhMS5WYWx1ZVR5cGUuRU1BSUxfQUREUkVTU10KCiBPYmplY3RzIG9mIHR5cGUgRW1haWxBZGRyZXNzIGFyZSBhbHNvIHBhc3NlZCB0byB0aGUgYWRhcHRlcnMgZHVyaW5nIHJlcXVlc3QtdGltZSBmb3IgdGhlIGluc3RhbmNlIGZpZWxkcyBvZgogdHlwZSBFbWFpbEFkZHJlc3MKCgoKAwQFARIDcAgUCi4KBAQFAgASA3IEFRohIEVtYWlsQWRkcmVzcyBlbmNvZGVkIGFzIHN0cmluZy4KCg0KBQQFAgAEEgRyBHAWCgwKBQQFAgAFEgNyBAoKDAoFBAUCAAESA3ILEAoMCgUEBQIAAxIDchMUCqwCCgIEBhIEewB+ARqfAiBETyBOT1QgVVNFICEhIFVuZGVyIERldmVsb3BtZW50CiBBbiBpbnN0YW5jZSBmaWVsZCBvZiB0eXBlIFVyaSBkZW5vdGVzIHRoYXQgdGhlIGV4cHJlc3Npb24gZm9yIHRoZSBmaWVsZCBtdXN0IGV2YWxhdXRlIHRvCiBbVmFsdWVUeXBlLlVSSV1baXN0aW8ucG9saWN5LnYxYmV0YTEuVmFsdWVUeXBlLlVSSV0KCiBPYmplY3RzIG9mIHR5cGUgVXJpIGFyZSBhbHNvIHBhc3NlZCB0byB0aGUgYWRhcHRlcnMgZHVyaW5nIHJlcXVlc3QtdGltZSBmb3IgdGhlIGluc3RhbmNlIGZpZWxkcyBvZgogdHlwZSBVcmkKCgoKAwQGARIDewgLCiUKBAQGAgASA30EFRoYIFVyaSBlbmNvZGVkIGFzIHN0cmluZy4KCg0KBQQGAgAEEgR9BHsNCgwKBQQGAgAFEgN9BAoKDAoFBAYCAAESA30LEAoMCgUEBgIAAxIDfRMUYgZwcm90bzMK+kIKNG1peGVyL3RlbXBsYXRlL21ldHJpYy90ZW1wbGF0ZV9oYW5kbGVyX3NlcnZpY2UucHJvdG8SBm1ldHJpYxoUZ29nb3Byb3RvL2dvZ28ucHJvdG8aLG1peGVyL2FkYXB0ZXIvbW9kZWwvdjFiZXRhMS9leHRlbnNpb25zLnByb3RvGhlnb29nbGUvcHJvdG9idWYvYW55LnByb3RvGihtaXhlci9hZGFwdGVyL21vZGVsL3YxYmV0YTEvcmVwb3J0LnByb3RvGh9wb2xpY3kvdjFiZXRhMS92YWx1ZV90eXBlLnByb3RvGhlwb2xpY3kvdjFiZXRhMS90eXBlLnByb3RvIqABChNIYW5kbGVNZXRyaWNSZXF1ZXN0EjEKCWluc3RhbmNlcxgBIAMoCzITLm1ldHJpYy5JbnN0YW5jZU1zZ1IJaW5zdGFuY2VzEjsKDmFkYXB0ZXJfY29uZmlnGAIgASgLMhQuZ29vZ2xlLnByb3RvYnVmLkFueVINYWRhcHRlckNvbmZpZxIZCghkZWR1cF9pZBgDIAEoCVIHZGVkdXBJZCKXBAoLSW5zdGFuY2VNc2cSFQoEbmFtZRivyrwiIAEoCVIEbmFtZRIxCgV2YWx1ZRgBIAEoCzIbLmlzdGlvLnBvbGljeS52MWJldGExLlZhbHVlUgV2YWx1ZRJDCgpkaW1lbnNpb25zGAIgAygLMiMubWV0cmljLkluc3RhbmNlTXNnLkRpbWVuc2lvbnNFbnRyeVIKZGltZW5zaW9ucxI2Chdtb25pdG9yZWRfcmVzb3VyY2VfdHlwZRgDIAEoCVIVbW9uaXRvcmVkUmVzb3VyY2VUeXBlEngKHW1vbml0b3JlZF9yZXNvdXJjZV9kaW1lbnNpb25zGAQgAygLMjQubWV0cmljLkluc3RhbmNlTXNnLk1vbml0b3JlZFJlc291cmNlRGltZW5zaW9uc0VudHJ5Uhttb25pdG9yZWRSZXNvdXJjZURpbWVuc2lvbnMaWgoPRGltZW5zaW9uc0VudHJ5EhAKA2tleRgBIAEoCVIDa2V5EjEKBXZhbHVlGAIgASgLMhsuaXN0aW8ucG9saWN5LnYxYmV0YTEuVmFsdWVSBXZhbHVlOgI4ARprCiBNb25pdG9yZWRSZXNvdXJjZURpbWVuc2lvbnNFbnRyeRIQCgNrZXkYASABKAlSA2tleRIxCgV2YWx1ZRgCIAEoCzIbLmlzdGlvLnBvbGljeS52MWJldGExLlZhbHVlUgV2YWx1ZToCOAEivwMKBFR5cGUSNQoFdmFsdWUYASABKA4yHy5pc3Rpby5wb2xpY3kudjFiZXRhMS5WYWx1ZVR5cGVSBXZhbHVlEjwKCmRpbWVuc2lvbnMYAiADKAsyHC5tZXRyaWMuVHlwZS5EaW1lbnNpb25zRW50cnlSCmRpbWVuc2lvbnMScQodbW9uaXRvcmVkX3Jlc291cmNlX2RpbWVuc2lvbnMYBCADKAsyLS5tZXRyaWMuVHlwZS5Nb25pdG9yZWRSZXNvdXJjZURpbWVuc2lvbnNFbnRyeVIbbW9uaXRvcmVkUmVzb3VyY2VEaW1lbnNpb25zGl4KD0RpbWVuc2lvbnNFbnRyeRIQCgNrZXkYASABKAlSA2tleRI1CgV2YWx1ZRgCIAEoDjIfLmlzdGlvLnBvbGljeS52MWJldGExLlZhbHVlVHlwZVIFdmFsdWU6AjgBGm8KIE1vbml0b3JlZFJlc291cmNlRGltZW5zaW9uc0VudHJ5EhAKA2tleRgBIAEoCVIDa2V5EjUKBXZhbHVlGAIgASgOMh8uaXN0aW8ucG9saWN5LnYxYmV0YTEuVmFsdWVUeXBlUgV2YWx1ZToCOAEirwMKDUluc3RhbmNlUGFyYW0SFAoFdmFsdWUYASABKAlSBXZhbHVlEkUKCmRpbWVuc2lvbnMYAiADKAsyJS5tZXRyaWMuSW5zdGFuY2VQYXJhbS5EaW1lbnNpb25zRW50cnlSCmRpbWVuc2lvbnMSNgoXbW9uaXRvcmVkX3Jlc291cmNlX3R5cGUYAyABKAlSFW1vbml0b3JlZFJlc291cmNlVHlwZRJ6Ch1tb25pdG9yZWRfcmVzb3VyY2VfZGltZW5zaW9ucxgEIAMoCzI2Lm1ldHJpYy5JbnN0YW5jZVBhcmFtLk1vbml0b3JlZFJlc291cmNlRGltZW5zaW9uc0VudHJ5Uhttb25pdG9yZWRSZXNvdXJjZURpbWVuc2lvbnMaPQoPRGltZW5zaW9uc0VudHJ5EhAKA2tleRgBIAEoCVIDa2V5EhQKBXZhbHVlGAIgASgJUgV2YWx1ZToCOAEaTgogTW9uaXRvcmVkUmVzb3VyY2VEaW1lbnNpb25zRW50cnkSEAoDa2V5GAEgASgJUgNrZXkSFAoFdmFsdWUYAiABKAlSBXZhbHVlOgI4ATJzChNIYW5kbGVNZXRyaWNTZXJ2aWNlElwKDEhhbmRsZU1ldHJpYxIbLm1ldHJpYy5IYW5kbGVNZXRyaWNSZXF1ZXN0Gi8uaXN0aW8ubWl4ZXIuYWRhcHRlci5tb2RlbC52MWJldGExLlJlcG9ydFJlc3VsdEIe+NLkkwIBgt3kkwIGbWV0cmljyOEeAKjiHgDw4R4ASqYzCgcSBRAAlQEBCugECgEMEgMQABIytAQgQ29weXJpZ2h0IDIwMTcgSXN0aW8gQXV0aG9ycwoKIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CgogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgoyJyBUSElTIEZJTEUgSVMgQVVUT01BVElDQUxMWSBHRU5FUkFURUQuCgqTCQoBAhIDLggOGogJIFRoZSBgbWV0cmljYCB0ZW1wbGF0ZSBpcyBkZXNpZ25lZCB0byBsZXQgeW91IGRlc2NyaWJlIHJ1bnRpbWUgbWV0cmljIHRvIGRpc3BhdGNoIHRvCiBtb25pdG9yaW5nIGJhY2tlbmRzLgogCiBFeGFtcGxlIGNvbmZpZzoKIAogYGBgeWFtbAogYXBpVmVyc2lvbjogImNvbmZpZy5pc3Rpby5pby92MWFscGhhMiIKIGtpbmQ6IG1ldHJpYwogbWV0YWRhdGE6CiAgIG5hbWU6IHJlcXVlc3RzaXplCiAgIG5hbWVzcGFjZTogaXN0aW8tc3lzdGVtCiBzcGVjOgogICB2YWx1ZTogcmVxdWVzdC5zaXplIHwgMAogICBkaW1lbnNpb25zOgogICAgIHNvdXJjZV9zZXJ2aWNlOiBzb3VyY2Uuc2VydmljZSB8ICJ1bmtub3duIgogICAgIHNvdXJjZV92ZXJzaW9uOiBzb3VyY2UubGFiZWxzWyJ2ZXJzaW9uIl0gfCAidW5rbm93biIKICAgICBkZXN0aW5hdGlvbl9zZXJ2aWNlOiBkZXN0aW5hdGlvbi5zZXJ2aWNlIHwgInVua25vd24iCiAgICAgZGVzdGluYXRpb25fdmVyc2lvbjogZGVzdGluYXRpb24ubGFiZWxzWyJ2ZXJzaW9uIl0gfCAidW5rbm93biIKICAgICByZXNwb25zZV9jb2RlOiByZXNwb25zZS5jb2RlIHwgMjAwCiAgIG1vbml0b3JlZF9yZXNvdXJjZV90eXBlOiAnIlVOU1BFQ0lGSUVEIicKIGBgYAoKIFRoZSBgbWV0cmljYCB0ZW1wbGF0ZSByZXByZXNlbnRzIGEgc2luZ2xlIHBpZWNlIG9mIGRhdGEgdG8gcmVwb3J0LgogCiBXaGVuIHdyaXRpbmcgdGhlIGNvbmZpZ3VyYXRpb24sIHRoZSB2YWx1ZSBmb3IgdGhlIGZpZWxkcyBhc3NvY2lhdGVkIHdpdGggdGhpcyB0ZW1wbGF0ZSBjYW4gZWl0aGVyIGJlIGEKIGxpdGVyYWwgb3IgYW4gW2V4cHJlc3Npb25dKGh0dHBzOi8vaXN0aW8uaW8vZG9jcy9yZWZlcmVuY2UvL2NvbmZpZy9wb2xpY3ktYW5kLXRlbGVtZXRyeS9leHByZXNzaW9uLWxhbmd1YWdlLykuIFBsZWFzZSBub3RlIHRoYXQgaWYgdGhlIGRhdGF0eXBlIG9mIGEgZmllbGQgaXMgbm90IGlzdGlvLnBvbGljeS52MWJldGExLlZhbHVlLAogdGhlbiB0aGUgZXhwcmVzc2lvbidzIFtpbmZlcnJlZCB0eXBlXShodHRwczovL2lzdGlvLmlvL2RvY3MvcmVmZXJlbmNlLy9jb25maWcvcG9saWN5LWFuZC10ZWxlbWV0cnkvZXhwcmVzc2lvbi1sYW5ndWFnZS8jdHlwZS1jaGVja2luZykgbXVzdCBtYXRjaCB0aGUgZGF0YXR5cGUgb2YgdGhlIGZpZWxkLgoKCQoCAwASAzEHHQoJCgIDARIDMgc1CgkKAgMCEgMzByIKCQoCAwMSAzQHMQoJCgIDBBIDNQcoCgkKAgMFEgM2ByIKCAoBCBIDOABWCgsKBAjnBwASAzgAVgoMCgUI5wcAAhIDOAc7Cg0KBgjnBwACABIDOAc7Cg4KBwjnBwACAAESAzgIOgoMCgUI5wcAAxIDOD5VCggKAQgSAzkARAoLCgQI5wcBEgM5AEQKDAoFCOcHAQISAzkHOAoNCgYI5wcBAgASAzkHOAoOCgcI5wcBAgABEgM5CDcKDAoFCOcHAQcSAzk7QwoICgEIEgM7AC8KCwoECOcHAhIDOwAvCgwKBQjnBwICEgM7ByYKDQoGCOcHAgIAEgM7ByYKDgoHCOcHAgIAARIDOwglCgwKBQjnBwIDEgM7KS4KCAoBCBIDPAAlCgsKBAjnBwMSAzwAJQoMCgUI5wcDAhIDPAccCg0KBgjnBwMCABIDPAccCg4KBwjnBwMCAAESAzwIGwoMCgUI5wcDAxIDPB8kCggKAQgSAz0AKAoLCgQI5wcEEgM9ACgKDAoFCOcHBAISAz0HHwoNCgYI5wcEAgASAz0HHwoOCgcI5wcEAgABEgM9CB4KDAoFCOcHBAMSAz0iJwpyCgIGABIEQABEARpmIEhhbmRsZU1ldHJpY1NlcnZpY2UgaXMgaW1wbGVtZW50ZWQgYnkgYmFja2VuZHMgdGhhdCB3YW50cyB0byBoYW5kbGUgcmVxdWVzdC10aW1lICdtZXRyaWMnIGluc3RhbmNlcy4KCgoKAwYAARIDQAgbCmwKBAYAAgASA0IEYxpfIEhhbmRsZU1ldHJpYyBpcyBjYWxsZWQgYnkgTWl4ZXIgYXQgcmVxdWVzdC10aW1lIHRvIGRlbGl2ZXIgJ21ldHJpYycgaW5zdGFuY2VzIHRvIHRoZSBiYWNrZW5kLgoKDAoFBgACAAESA0IIFAoMCgUGAAIAAhIDQhUoCgwKBQYAAgADEgNCM2EKNgoCBAASBEcAVgEaKiBSZXF1ZXN0IG1lc3NhZ2UgZm9yIEhhbmRsZU1ldHJpYyBtZXRob2QuCgoKCgMEAAESA0cIGwoiCgQEAAIAEgNKBCcaFSAnbWV0cmljJyBpbnN0YW5jZXMuCgoMCgUEAAIABBIDSgQMCgwKBQQAAgAGEgNKDRgKDAoFBAACAAESA0oZIgoMCgUEAAIAAxIDSiUmCrkECgQEAAIBEgNSBCsaqwQgQWRhcHRlciBzcGVjaWZpYyBoYW5kbGVyIGNvbmZpZ3VyYXRpb24uCgogTm90ZTogQmFja2VuZHMgY2FuIGFsc28gaW1wbGVtZW50IFtJbmZyYXN0cnVjdHVyZUJhY2tlbmRdW2h0dHBzOi8vaXN0aW8uaW8vZG9jcy9yZWZlcmVuY2UvY29uZmlnL21peGVyL2lzdGlvLm1peGVyLmFkYXB0ZXIubW9kZWwudjFiZXRhMS5odG1sI0luZnJhc3RydWN0dXJlQmFja2VuZF0KIHNlcnZpY2UgYW5kIHRoZXJlZm9yZSBvcHQgdG8gcmVjZWl2ZSBoYW5kbGVyIGNvbmZpZ3VyYXRpb24gZHVyaW5nIHNlc3Npb24gY3JlYXRpb24gdGhyb3VnaCBbSW5mcmFzdHJ1Y3R1cmVCYWNrZW5kLkNyZWF0ZVNlc3Npb25dW1RPRE86IExpbmsgdG8gdGhpcyBmcmFnbWVudF0KIGNhbGwuIEluIHRoYXQgY2FzZSwgYWRhcHRlcl9jb25maWcgd2lsbCBoYXZlIHR5cGVfdXJsIGFzICdnb29nbGUucHJvdG9idWYuQW55LnR5cGVfdXJsJyBhbmQgd291bGQgY29udGFpbiBzdHJpbmcKIHZhbHVlIG9mIHNlc3Npb25faWQgKHJldHVybmVkIGZyb20gSW5mcmFzdHJ1Y3R1cmVCYWNrZW5kLkNyZWF0ZVNlc3Npb24pLgoKDQoFBAACAQQSBFIESicKDAoFBAACAQYSA1IEFwoMCgUEAAIBARIDUhgmCgwKBQQAAgEDEgNSKSoKOgoEBAACAhIDVQQYGi0gSWQgdG8gZGVkdXBlIGlkZW50aWNhbCByZXF1ZXN0cyBmcm9tIE1peGVyLgoKDQoFBAACAgQSBFUEUisKDAoFBAACAgUSA1UECgoMCgUEAAICARIDVQsTCgwKBQQAAgIDEgNVFhcKqAEKAgQBEgRaAG8BGpsBIENvbnRhaW5zIGluc3RhbmNlIHBheWxvYWQgZm9yICdtZXRyaWMnIHRlbXBsYXRlLiBUaGlzIGlzIHBhc3NlZCB0byBpbmZyYXN0cnVjdHVyZSBiYWNrZW5kcyBkdXJpbmcgcmVxdWVzdC10aW1lCiB0aHJvdWdoIEhhbmRsZU1ldHJpY1NlcnZpY2UuSGFuZGxlTWV0cmljLgoKCgoDBAEBEgNaCBMKQgoEBAECABIDXQQbGjUgTmFtZSBvZiB0aGUgaW5zdGFuY2UgYXMgc3BlY2lmaWVkIGluIGNvbmZpZ3VyYXRpb24uCgoNCgUEAQIABBIEXQRaFQoMCgUEAQIABRIDXQQKCgwKBQQBAgABEgNdCw8KDAoFBAECAAMSA10SGgooCgQEAQIBEgNgBCkaGyBUaGUgdmFsdWUgYmVpbmcgcmVwb3J0ZWQuCgoNCgUEAQIBBBIEYARdGwoMCgUEAQIBBhIDYAQeCgwKBQQBAgEBEgNgHyQKDAoFBAECAQMSA2AnKApGCgQEAQICEgNjBDsaOSBUaGUgdW5pcXVlIGlkZW50aXR5IG9mIHRoZSBwYXJ0aWN1bGFyIG1ldHJpYyB0byByZXBvcnQuCgoNCgUEAQICBBIEYwRgKQoMCgUEAQICBhIDYwQrCgwKBQQBAgIBEgNjLDYKDAoFBAECAgMSA2M5OgqVAgoEBAECAxIDaAQnGocCIE9wdGlvbmFsLiBBbiBleHByZXNzaW9uIHRvIGNvbXB1dGUgdGhlIHR5cGUgb2YgdGhlIG1vbml0b3JlZCByZXNvdXJjZSB0aGlzIG1ldHJpYyBpcyBiZWluZyByZXBvcnRlZCBvbi4KIElmIHRoZSBtZXRyaWMgYmFja2VuZCBzdXBwb3J0cyBtb25pdG9yZWQgcmVzb3VyY2VzLCB0aGVzZSBmaWVsZHMgYXJlIHVzZWQgdG8gcG9wdWxhdGUgdGhhdCByZXNvdXJjZS4gT3RoZXJ3aXNlCiB0aGVzZSBmaWVsZHMgd2lsbCBiZSBpZ25vcmVkIGJ5IHRoZSBhZGFwdGVyLgoKDQoFBAECAwQSBGgEYzsKDAoFBAECAwUSA2gECgoMCgUEAQIDARIDaAsiCgwKBQQBAgMDEgNoJSYKpgIKBAQBAgQSA20EThqYAiBPcHRpb25hbC4gQSBzZXQgb2YgZXhwcmVzc2lvbnMgdGhhdCB3aWxsIGZvcm0gdGhlIGRpbWVuc2lvbnMgb2YgdGhlIG1vbml0b3JlZCByZXNvdXJjZSB0aGlzIG1ldHJpYyBpcyBiZWluZyByZXBvcnRlZCBvbi4KIElmIHRoZSBtZXRyaWMgYmFja2VuZCBzdXBwb3J0cyBtb25pdG9yZWQgcmVzb3VyY2VzLCB0aGVzZSBmaWVsZHMgYXJlIHVzZWQgdG8gcG9wdWxhdGUgdGhhdCByZXNvdXJjZS4gT3RoZXJ3aXNlCiB0aGVzZSBmaWVsZHMgd2lsbCBiZSBpZ25vcmVkIGJ5IHRoZSBhZGFwdGVyLgoKDQoFBAECBAQSBG0EaCcKDAoFBAECBAYSA20EKwoMCgUEAQIEARIDbSxJCgwKBQQBAgQDEgNtTE0K8QEKAgQCEgVzAIABARrjASBDb250YWlucyBpbmZlcnJlZCB0eXBlIGluZm9ybWF0aW9uIGFib3V0IHNwZWNpZmljIGluc3RhbmNlIG9mICdtZXRyaWMnIHRlbXBsYXRlLiBUaGlzIGlzIHBhc3NlZCB0bwogaW5mcmFzdHJ1Y3R1cmUgYmFja2VuZHMgZHVyaW5nIGNvbmZpZ3VyYXRpb24tdGltZSB0aHJvdWdoIFtJbmZyYXN0cnVjdHVyZUJhY2tlbmQuQ3JlYXRlU2Vzc2lvbl1bVE9ETzogTGluayB0byB0aGlzIGZyYWdtZW50XS4KCgoKAwQCARIDcwgMCigKBAQCAgASA3YELRobIFRoZSB2YWx1ZSBiZWluZyByZXBvcnRlZC4KCg0KBQQCAgAEEgR2BHMOCgwKBQQCAgAGEgN2BCIKDAoFBAICAAESA3YjKAoMCgUEAgIAAxIDdissCkYKBAQCAgESA3kEPxo5IFRoZSB1bmlxdWUgaWRlbnRpdHkgb2YgdGhlIHBhcnRpY3VsYXIgbWV0cmljIHRvIHJlcG9ydC4KCg0KBQQCAgEEEgR5BHYtCgwKBQQCAgEGEgN5BC8KDAoFBAICAQESA3kwOgoMCgUEAgIBAxIDeT0+CqYCCgQEAgICEgN+BFIamAIgT3B0aW9uYWwuIEEgc2V0IG9mIGV4cHJlc3Npb25zIHRoYXQgd2lsbCBmb3JtIHRoZSBkaW1lbnNpb25zIG9mIHRoZSBtb25pdG9yZWQgcmVzb3VyY2UgdGhpcyBtZXRyaWMgaXMgYmVpbmcgcmVwb3J0ZWQgb24uCiBJZiB0aGUgbWV0cmljIGJhY2tlbmQgc3VwcG9ydHMgbW9uaXRvcmVkIHJlc291cmNlcywgdGhlc2UgZmllbGRzIGFyZSB1c2VkIHRvIHBvcHVsYXRlIHRoYXQgcmVzb3VyY2UuIE90aGVyd2lzZQogdGhlc2UgZmllbGRzIHdpbGwgYmUgaWdub3JlZCBieSB0aGUgYWRhcHRlci4KCg0KBQQCAgIEEgR+BHk/CgwKBQQCAgIGEgN+BC8KDAoFBAICAgESA34wTQoMCgUEAgICAxIDflBRCk8KAgQDEgaDAQCVAQEaQSBSZXByZXNlbnRzIGluc3RhbmNlIGNvbmZpZ3VyYXRpb24gc2NoZW1hIGZvciAnbWV0cmljJyB0ZW1wbGF0ZS4KCgsKAwQDARIEgwEIFQopCgQEAwIAEgSGAQQVGhsgVGhlIHZhbHVlIGJlaW5nIHJlcG9ydGVkLgoKDwoFBAMCAAQSBoYBBIMBFwoNCgUEAwIABRIEhgEECgoNCgUEAwIAARIEhgELEAoNCgUEAwIAAxIEhgETFApHCgQEAwIBEgSJAQQnGjkgVGhlIHVuaXF1ZSBpZGVudGl0eSBvZiB0aGUgcGFydGljdWxhciBtZXRyaWMgdG8gcmVwb3J0LgoKDwoFBAMCAQQSBokBBIYBFQoNCgUEAwIBBhIEiQEEFwoNCgUEAwIBARIEiQEYIgoNCgUEAwIBAxIEiQElJgqWAgoEBAMCAhIEjgEEJxqHAiBPcHRpb25hbC4gQW4gZXhwcmVzc2lvbiB0byBjb21wdXRlIHRoZSB0eXBlIG9mIHRoZSBtb25pdG9yZWQgcmVzb3VyY2UgdGhpcyBtZXRyaWMgaXMgYmVpbmcgcmVwb3J0ZWQgb24uCiBJZiB0aGUgbWV0cmljIGJhY2tlbmQgc3VwcG9ydHMgbW9uaXRvcmVkIHJlc291cmNlcywgdGhlc2UgZmllbGRzIGFyZSB1c2VkIHRvIHBvcHVsYXRlIHRoYXQgcmVzb3VyY2UuIE90aGVyd2lzZQogdGhlc2UgZmllbGRzIHdpbGwgYmUgaWdub3JlZCBieSB0aGUgYWRhcHRlci4KCg8KBQQDAgIEEgaOAQSJAScKDQoFBAMCAgUSBI4BBAoKDQoFBAMCAgESBI4BCyIKDQoFBAMCAgMSBI4BJSYKpwIKBAQDAgMSBJMBBDoamAIgT3B0aW9uYWwuIEEgc2V0IG9mIGV4cHJlc3Npb25zIHRoYXQgd2lsbCBmb3JtIHRoZSBkaW1lbnNpb25zIG9mIHRoZSBtb25pdG9yZWQgcmVzb3VyY2UgdGhpcyBtZXRyaWMgaXMgYmVpbmcgcmVwb3J0ZWQgb24uCiBJZiB0aGUgbWV0cmljIGJhY2tlbmQgc3VwcG9ydHMgbW9uaXRvcmVkIHJlc291cmNlcywgdGhlc2UgZmllbGRzIGFyZSB1c2VkIHRvIHBvcHVsYXRlIHRoYXQgcmVzb3VyY2UuIE90aGVyd2lzZQogdGhlc2UgZmllbGRzIHdpbGwgYmUgaWdub3JlZCBieSB0aGUgYWRhcHRlci4KCg8KBQQDAgMEEgaTAQSOAScKDQoFBAMCAwYSBJMBBBcKDQoFBAMCAwESBJMBGDUKDQoFBAMCAwMSBJMBODliBnByb3RvMw=="
24 | ---
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/6.5.0/6.5.0/istio/02-skywalingadapter.yml:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | apiVersion: "config.istio.io/v1alpha2"
18 | kind: adapter
19 | metadata:
20 | name: swadapter
21 | namespace: istio-system
22 | spec:
23 | description:
24 | session_based: false
25 | templates:
26 | - metric
27 |
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/6.5.0/6.5.0/istio/03-operator_cfg.yml:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | apiVersion: "config.istio.io/v1alpha2"
18 | kind: handler
19 | metadata:
20 | name: sw
21 | namespace: istio-system
22 | spec:
23 | adapter: swadapter
24 | connection:
25 | address: "oap.skywalking.svc.cluster.local:11800"
26 | ---
27 |
28 | # instance for template metric
29 | apiVersion: "config.istio.io/v1alpha2"
30 | kind: instance
31 | metadata:
32 | name: swmetric
33 | namespace: istio-system
34 | spec:
35 | template: metric
36 | params:
37 | value: request.size | 0
38 | dimensions:
39 | sourceService: source.workload.name | ""
40 | sourceNamespace: source.workload.namespace | ""
41 | sourceUID: source.uid | ""
42 | destinationService: destination.workload.name | ""
43 | destinationNamespace: destination.workload.namespace | ""
44 | destinationUID: destination.uid | ""
45 | requestMethod: request.method | ""
46 | requestPath: request.path | ""
47 | requestScheme: request.scheme | ""
48 | requestTime: request.time
49 | responseTime: response.time
50 | responseCode: response.code | 200
51 | reporter: conditional((context.reporter.kind | "inbound") == "outbound", "source", "destination")
52 | apiProtocol: api.protocol | ""
53 | ---
54 |
55 | # rule to dispatch to handler sw
56 | apiVersion: "config.istio.io/v1alpha2"
57 | kind: rule
58 | metadata:
59 | name: swmetric-rule
60 | namespace: istio-system
61 | spec:
62 | actions:
63 | - handler: sw.istio-system
64 | instances:
65 | - swmetric
66 |
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/6.5.0/6.5.0/istio/README.md:
--------------------------------------------------------------------------------
1 | # SkyWalking Istio adaptor
2 | The SkyWalking uses Istio bypass adapter collects metrics. Use `kubectl apply -f` with the `yaml`(s) in this folder to setup.
3 |
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/6.5.0/6.5.0/namespace.yml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Namespace
3 | metadata:
4 | name: skywalking
5 | labels:
6 | name: skywalking
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/6.5.0/6.5.0/oap/00-rbac.yml:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 |
18 | apiVersion: v1
19 | kind: ServiceAccount
20 | metadata:
21 | name: skywalking-oap
22 | namespace: skywalking
23 |
24 | ---
25 |
26 | apiVersion: rbac.authorization.k8s.io/v1
27 | kind: RoleBinding
28 | metadata:
29 | name: skywalking-oap
30 | namespace: skywalking
31 | roleRef:
32 | apiGroup: rbac.authorization.k8s.io
33 | kind: Role
34 | name: skywalking-oap
35 | subjects:
36 | - kind: ServiceAccount
37 | name: skywalking-oap
38 | namespace: skywalking
39 |
40 | ---
41 |
42 | kind: Role
43 | apiVersion: rbac.authorization.k8s.io/v1
44 | metadata:
45 | namespace: skywalking
46 | name: skywalking-oap
47 | rules:
48 | - apiGroups: [""]
49 | resources: ["pods"]
50 | verbs: ["get", "watch", "list"]
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/6.5.0/6.5.0/oap/01-config.yml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: ConfigMap
3 | metadata:
4 | name: oap-config
5 | namespace: skywalking
6 | data:
7 | application.yml: |-
8 | cluster:
9 | # standalone:
10 | # Please check your ZooKeeper is 3.5+, However, it is also compatible with ZooKeeper 3.4.x. Replace the ZooKeeper 3.5+
11 | # library the oap-libs folder with your ZooKeeper 3.4.x library.
12 | # zookeeper:
13 | # nameSpace: ${SW_NAMESPACE:""}
14 | # hostPort: ${SW_CLUSTER_ZK_HOST_PORT:localhost:2181}
15 | # #Retry Policy
16 | # baseSleepTimeMs: ${SW_CLUSTER_ZK_SLEEP_TIME:1000} # initial amount of time to wait between retries
17 | # maxRetries: ${SW_CLUSTER_ZK_MAX_RETRIES:3} # max number of times to retry
18 | kubernetes:
19 | watchTimeoutSeconds: ${SW_CLUSTER_K8S_WATCH_TIMEOUT:60}
20 | namespace: ${SW_CLUSTER_K8S_NAMESPACE:skywalking}
21 | labelSelector: ${SW_CLUSTER_K8S_LABEL:app=oap,release=skywalking}
22 | uidEnvName: ${SW_CLUSTER_K8S_UID:SKYWALKING_COLLECTOR_UID}
23 | # consul:
24 | # serviceName: ${SW_SERVICE_NAME:"SkyWalking_OAP_Cluster"}
25 | # Consul cluster nodes, example: 10.0.0.1:8500,10.0.0.2:8500,10.0.0.3:8500
26 | # hostPort: ${SW_CLUSTER_CONSUL_HOST_PORT:localhost:8500}
27 | core:
28 | default:
29 | # Mixed: Receive agent data, Level 1 aggregate, Level 2 aggregate
30 | # Receiver: Receive agent data, Level 1 aggregate
31 | # Aggregator: Level 2 aggregate
32 | role: ${SW_CORE_ROLE:Mixed} # Mixed/Receiver/Aggregator
33 | restHost: ${SW_CORE_REST_HOST:0.0.0.0}
34 | restPort: ${SW_CORE_REST_PORT:12800}
35 | restContextPath: ${SW_CORE_REST_CONTEXT_PATH:/}
36 | gRPCHost: ${SW_CORE_GRPC_HOST:0.0.0.0}
37 | gRPCPort: ${SW_CORE_GRPC_PORT:11800}
38 | downsampling:
39 | - Hour
40 | - Day
41 | - Month
42 | # Set a timeout on metric data. After the timeout has expired, the metric data will automatically be deleted.
43 | recordDataTTL: ${SW_CORE_RECORD_DATA_TTL:90} # Unit is minute
44 | minuteMetricsDataTTL: ${SW_CORE_MINUTE_METRIC_DATA_TTL:90} # Unit is minute
45 | hourMetricsDataTTL: ${SW_CORE_HOUR_METRIC_DATA_TTL:36} # Unit is hour
46 | dayMetricsDataTTL: ${SW_CORE_DAY_METRIC_DATA_TTL:45} # Unit is day
47 | monthMetricsDataTTL: ${SW_CORE_MONTH_METRIC_DATA_TTL:18} # Unit is month
48 | storage:
49 | elasticsearch:
50 | nameSpace: ${SW_NAMESPACE:""}
51 | clusterNodes: ${SW_STORAGE_ES_CLUSTER_NODES:elasticsearch:9200}
52 | user: ${SW_ES_USER:""}
53 | password: ${SW_ES_PASSWORD:""}
54 | indexShardsNumber: ${SW_STORAGE_ES_INDEX_SHARDS_NUMBER:2}
55 | indexReplicasNumber: ${SW_STORAGE_ES_INDEX_REPLICAS_NUMBER:0}
56 | # Batch process setting, refer to https://www.elastic.co/guide/en/elasticsearch/client/java-api/5.5/java-docs-bulk-processor.html
57 | bulkActions: ${SW_STORAGE_ES_BULK_ACTIONS:2000} # Execute the bulk every 2000 requests
58 | bulkSize: ${SW_STORAGE_ES_BULK_SIZE:20} # flush the bulk every 20mb
59 | flushInterval: ${SW_STORAGE_ES_FLUSH_INTERVAL:10} # flush the bulk every 10 seconds whatever the number of requests
60 | concurrentRequests: ${SW_STORAGE_ES_CONCURRENT_REQUESTS:2} # the number of concurrent requests
61 | metadataQueryMaxSize: ${SW_STORAGE_ES_QUERY_MAX_SIZE:5000}
62 | segmentQueryMaxSize: ${SW_STORAGE_ES_QUERY_SEGMENT_SIZE:200}
63 | # h2:
64 | # driver: ${SW_STORAGE_H2_DRIVER:org.h2.jdbcx.JdbcDataSource}
65 | # url: ${SW_STORAGE_H2_URL:jdbc:h2:mem:skywalking-oap-db}
66 | # user: ${SW_STORAGE_H2_USER:sa}
67 | # metadataQueryMaxSize: ${SW_STORAGE_H2_QUERY_MAX_SIZE:5000}
68 | # mysql:
69 | # metadataQueryMaxSize: ${SW_STORAGE_H2_QUERY_MAX_SIZE:5000}
70 | receiver-sharing-server:
71 | default:
72 | receiver-register:
73 | default:
74 | receiver-trace:
75 | default:
76 | bufferPath: ${SW_RECEIVER_BUFFER_PATH:../trace-buffer/} # Path to trace buffer files, suggest to use absolute path
77 | bufferOffsetMaxFileSize: ${SW_RECEIVER_BUFFER_OFFSET_MAX_FILE_SIZE:100} # Unit is MB
78 | bufferDataMaxFileSize: ${SW_RECEIVER_BUFFER_DATA_MAX_FILE_SIZE:500} # Unit is MB
79 | bufferFileCleanWhenRestart: ${SW_RECEIVER_BUFFER_FILE_CLEAN_WHEN_RESTART:false}
80 | sampleRate: ${SW_TRACE_SAMPLE_RATE:10000} # The sample rate precision is 1/10000. 10000 means 100% sample in default.
81 | slowDBAccessThreshold: ${SW_SLOW_DB_THRESHOLD:default:200,mongodb:100} # The slow database access thresholds. Unit ms.
82 | receiver-jvm:
83 | default:
84 | receiver-clr:
85 | default:
86 | service-mesh:
87 | default:
88 | bufferPath: ${SW_SERVICE_MESH_BUFFER_PATH:../mesh-buffer/} # Path to trace buffer files, suggest to use absolute path
89 | bufferOffsetMaxFileSize: ${SW_SERVICE_MESH_OFFSET_MAX_FILE_SIZE:100} # Unit is MB
90 | bufferDataMaxFileSize: ${SW_SERVICE_MESH_BUFFER_DATA_MAX_FILE_SIZE:500} # Unit is MB
91 | bufferFileCleanWhenRestart: ${SW_SERVICE_MESH_BUFFER_FILE_CLEAN_WHEN_RESTART:false}
92 | istio-telemetry:
93 | default:
94 | envoy-metric:
95 | default:
96 | #receiver_zipkin:
97 | # default:
98 | # host: ${SW_RECEIVER_ZIPKIN_HOST:0.0.0.0}
99 | # port: ${SW_RECEIVER_ZIPKIN_PORT:9411}
100 | # contextPath: ${SW_RECEIVER_ZIPKIN_CONTEXT_PATH:/}
101 | query:
102 | graphql:
103 | path: ${SW_QUERY_GRAPHQL_PATH:/graphql}
104 | alarm:
105 | default:
106 | telemetry:
107 | none:
108 | log4j2.xml: |-
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 | alarm-settings.yml: |-
127 | rules:
128 | service_resp_time_rule:
129 | indicator-name: service_resp_time
130 | include-names:
131 | - dubbox-provider
132 | - dubbox-consumer
133 | threshold: 1000
134 | op: ">"
135 | period: 10
136 | count: 1
137 | webhooks:
138 | component-libraries.yml: |-
139 | Tomcat:
140 | id: 1
141 | languages: Java
142 | HttpClient:
143 | id: 2
144 | languages: Java,C#,Node.js
145 | Dubbo:
146 | id: 3
147 | languages: Java
148 | H2:
149 | id: 4
150 | languages: Java
151 | Mysql:
152 | id: 5
153 | languages: Java,C#,Node.js
154 | ORACLE:
155 | id: 6
156 | languages: Java
157 | Redis:
158 | id: 7
159 | languages: Java,C#,Node.js
160 | Motan:
161 | id: 8
162 | languages: Java
163 | MongoDB:
164 | id: 9
165 | languages: Java,C#,Node.js
166 | Resin:
167 | id: 10
168 | languages: Java
169 | Feign:
170 | id: 11
171 | languages: Java
172 | OKHttp:
173 | id: 12
174 | languages: Java
175 | SpringRestTemplate:
176 | id: 13
177 | languages: Java
178 | SpringMVC:
179 | id: 14
180 | languages: Java
181 | Struts2:
182 | id: 15
183 | languages: Java
184 | NutzMVC:
185 | id: 16
186 | languages: Java
187 | NutzHttp:
188 | id: 17
189 | languages: Java
190 | JettyClient:
191 | id: 18
192 | languages: Java
193 | JettyServer:
194 | id: 19
195 | languages: Java
196 | Memcached:
197 | id: 20
198 | languages: Java
199 | ShardingJDBC:
200 | id: 21
201 | languages: Java
202 | PostgreSQL:
203 | id: 22
204 | languages: Java,C#,Node.js
205 | GRPC:
206 | id: 23
207 | languages: Java
208 | ElasticJob:
209 | id: 24
210 | languages: Java
211 | RocketMQ:
212 | id: 25
213 | languages: Java
214 | httpasyncclient:
215 | id: 26
216 | languages: Java
217 | Kafka:
218 | id: 27
219 | languages: Java
220 | ServiceComb:
221 | id: 28
222 | languages: Java
223 | Hystrix:
224 | id: 29
225 | languages: Java
226 | Jedis:
227 | id: 30
228 | languages: Java
229 | SQLite:
230 | id: 31
231 | languages: Java,C#
232 | h2-jdbc-driver:
233 | id: 32
234 | languages: Java
235 | mysql-connector-java:
236 | id: 33
237 | languages: Java
238 | ojdbc:
239 | id: 34
240 | languages: Java
241 | Spymemcached:
242 | id: 35
243 | languages: Java
244 | Xmemcached:
245 | id: 36
246 | languages: Java
247 | postgresql-jdbc-driver:
248 | id: 37
249 | languages: Java
250 | rocketMQ-producer:
251 | id: 38
252 | languages: Java
253 | rocketMQ-consumer:
254 | id: 39
255 | languages: Java
256 | kafka-producer:
257 | id: 40
258 | languages: Java
259 | kafka-consumer:
260 | id: 41
261 | languages: Java
262 | mongodb-driver:
263 | id: 42
264 | languages: Java
265 | SOFARPC:
266 | id: 43
267 | languages: Java
268 | ActiveMQ:
269 | id: 44
270 | languages: Java
271 | activemq-producer:
272 | id: 45
273 | languages: Java
274 | activemq-consumer:
275 | id: 46
276 | languages: Java
277 | Elasticsearch:
278 | id: 47
279 | languages: Java
280 | transport-client:
281 | id: 48
282 | languages: Java
283 | http:
284 | id: 49
285 | languages: Java,C#,Node.js
286 | rpc:
287 | id: 50
288 | languages: Java,C#,Node.js
289 | RabbitMQ:
290 | id: 51
291 | languages: Java
292 | rabbitmq-producer:
293 | id: 52
294 | languages: Java
295 | rabbitmq-consumer:
296 | id: 53
297 | languages: Java
298 | Canal:
299 | id: 54
300 | languages: Java
301 | Gson:
302 | id: 55
303 | languages: Java
304 | Redisson:
305 | id: 56
306 | languages: Java
307 | AspNetCore:
308 | id: 3001
309 | languages: C#
310 | EntityFrameworkCore:
311 | id: 3002
312 | languages: C#
313 | SqlClient:
314 | id: 3003
315 | languages: C#
316 | CAP:
317 | id: 3004
318 | languages: C#
319 | StackExchange.Redis:
320 | id: 3005
321 | languages: C#
322 | SqlServer:
323 | id: 3006
324 | languages: C#
325 | Npgsql:
326 | id: 3007
327 | languages: C#
328 | MySqlConnector:
329 | id: 3008
330 | languages: C#
331 | EntityFrameworkCore.InMemory:
332 | id: 3009
333 | languages: C#
334 | EntityFrameworkCore.SqlServer:
335 | id: 3010
336 | languages: C#
337 | EntityFrameworkCore.Sqlite:
338 | id: 3011
339 | languages: C#
340 | Pomelo.EntityFrameworkCore.MySql:
341 | id: 3012
342 | languages: C#
343 | Npgsql.EntityFrameworkCore.PostgreSQL:
344 | id: 3013
345 | languages: C#
346 | InMemoryDatabase:
347 | id: 3014
348 | languages: C#
349 | AspNet:
350 | id: 3015
351 | languages: C#
352 | # NoeJS components
353 | # [4000, 5000) for Node.js agent
354 | HttpServer:
355 | id: 4001
356 | languages: Node.js
357 | express:
358 | id: 4002
359 | languages: Node.js
360 | Egg:
361 | id: 4003
362 | languages: Node.js
363 | Koa:
364 | id: 4004
365 | languages: Node.js
366 | # Component Server mapping defines the server display names of some components
367 | # e.g.
368 | # Jedis is a client library in Java for Redis server
369 | Component-Server-Mappings:
370 | mongodb-driver: MongoDB
371 | rocketMQ-producer: RocketMQ
372 | rocketMQ-consumer: RocketMQ
373 | kafka-producer: Kafka
374 | kafka-consumer: Kafka
375 | activemq-producer: ActiveMQ
376 | activemq-consumer: ActiveMQ
377 | rabbitmq-producer: RabbitMQ
378 | rabbitmq-consumer: RabbitMQ
379 | postgresql-jdbc-driver: PostgreSQL
380 | Xmemcached: Memcached
381 | Spymemcached: Memcached
382 | h2-jdbc-driver: H2
383 | mysql-connector-java: Mysql
384 | Jedis: Redis
385 | StackExchange.Redis: Redis
386 | Redisson: Redis
387 | SqlClient: SqlServer
388 | Npgsql: PostgreSQL
389 | MySqlConnector: Mysql
390 | EntityFrameworkCore.InMemory: InMemoryDatabase
391 | EntityFrameworkCore.SqlServer: SqlServer
392 | EntityFrameworkCore.Sqlite: SQLite
393 | Pomelo.EntityFrameworkCore.MySql: Mysql
394 | Npgsql.EntityFrameworkCore.PostgreSQL: PostgreSQL
395 | transport-client: Elasticsearch
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/6.5.0/6.5.0/oap/02-service.yml:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | apiVersion: v1
18 | kind: Service
19 | metadata:
20 | name: oap
21 | namespace: skywalking
22 | labels:
23 | service: oap
24 | spec:
25 | ports:
26 | - port: 12800
27 | name: rest
28 | - port: 11800
29 | name: grpc
30 | - port: 1234
31 | name: page
32 | selector:
33 | app: oap
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/6.5.0/6.5.0/oap/03-deployment.yml:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | apiVersion: apps/v1
18 | kind: Deployment
19 | metadata:
20 | name: oap
21 | namespace: skywalking
22 | spec:
23 | replicas: 3
24 | selector:
25 | matchLabels:
26 | app: oap
27 | template:
28 | metadata:
29 | labels:
30 | app: oap
31 | release: skywalking
32 | spec:
33 | serviceAccountName: skywalking-oap
34 | initContainers:
35 | - name: sidecar-init
36 | image: evanxuhe/skywalking-agent-sidecar:6.1.0 # 容器镜像,包含静态资源文件
37 | command: ["cp", "-r", "/data/agent", "/sidecar"]
38 | volumeMounts:
39 | - name: sidecar
40 | mountPath: /sidecar
41 | containers:
42 | - name: oap
43 | image: evanxuhe/skywalking-oap-server:6.1.0
44 | imagePullPolicy: IfNotPresent
45 | ports:
46 | - containerPort: 11800
47 | name: grpc
48 | - containerPort: 12800
49 | name: rest
50 | resources:
51 | requests:
52 | memory: 1Gi
53 | limits:
54 | memory: 2Gi
55 | env:
56 | - name: JAVA_OPTS
57 | value: -Xms256M -Xmx512M
58 | #从volume载入配置 否则由于挂载config时 会与镜像内路径冲突 报错read only filesystem
59 | - name: SW_L0AD_CONFIG_FILE_FROM_VOLUME
60 | value: "true"
61 | # - name: SW_STORAGE
62 | # value: elasticsearch
63 | # - name: SW_STORAGE_ES_CLUSTER_NODES
64 | # value: "192.168.78.136:9200"
65 | # - name: SW_CLUSTER
66 | # value: kubernetes
67 | # - name: SW_CLUSTER_K8S_NAMESPACE
68 | # value: skywalking
69 | # - name: SW_SERVICE_MESH_OFFSET_MAX_FILE_SIZE
70 | # value: "200"
71 | # - name: SW_RECEIVER_BUFFER_DATA_MAX_FILE_SIZE
72 | # value: "800"
73 | # - name: SW_RECEIVER_BUFFER_FILE_CLEAN_WHEN_RESTART
74 | # value: "true"
75 | - name: SKYWALKING_oap_UID
76 | valueFrom:
77 | fieldRef:
78 | fieldPath: metadata.uid
79 | volumeMounts:
80 | - name: sidecar
81 | mountPath: /sidecar
82 | - name: config
83 | mountPath: /skywalking/config
84 | volumes:
85 | - name: sidecar
86 | emptyDir: {}
87 | - name: config
88 | configMap:
89 | name: oap-config
90 |
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/6.5.0/6.5.0/ui/01-service.yml:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | apiVersion: v1
18 | kind: Service
19 | metadata:
20 | name: ui
21 | namespace: skywalking
22 | labels:
23 | service: ui
24 | spec:
25 | ports:
26 | - port: 8080
27 | name: page
28 | nodePort: 31234
29 | type: NodePort
30 | selector:
31 | app: ui
32 |
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/6.5.0/6.5.0/ui/02-deployment.yml:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | apiVersion: apps/v1
18 | kind: Deployment
19 | metadata:
20 | name: ui-deployment
21 | namespace: skywalking
22 | labels:
23 | app: ui
24 | spec:
25 | replicas: 1
26 | selector:
27 | matchLabels:
28 | app: ui
29 | template:
30 | metadata:
31 | labels:
32 | app: ui
33 | spec:
34 | containers:
35 | - name: ui
36 | image: apache/skywalking-ui:6.1.0
37 | ports:
38 | - containerPort: 8080
39 | name: page
40 | resources:
41 | requests:
42 | memory: 1Gi
43 | limits:
44 | memory: 2Gi
45 | env:
46 | - name: SW_OAP_ADDRESS
47 | value: oap:12800
48 |
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/6.5.0/apm-springcloud-demo/kdep-apm-eureka.yml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: apm-eureka
5 | namespace: demo
6 | labels:
7 | deploy: apm-eureka
8 | spec:
9 | replicas: 1
10 | selector:
11 | matchLabels:
12 | app: apm-eureka
13 | template:
14 | metadata:
15 | name: apm-eureka
16 | labels:
17 | app: apm-eureka
18 | spec:
19 | initContainers:
20 | - name: sidecar
21 | image: apache/skywalking-base:6.5.0 # 容器镜像,包含静态资源文件
22 | imagePullPolicy: IfNotPresent
23 | command: ["cp", "-r", "/skywalking/agent", "/sidecar"]
24 | volumeMounts:
25 | - name: sidecar
26 | mountPath: /sidecar
27 | containers:
28 | - name: apm-eureka
29 | image: evanxuhe/apm-eureka:6.1.0
30 | imagePullPolicy: IfNotPresent
31 | env:
32 | - name: JAVA_OPTS
33 | value: -javaagent:/sidecar/agent/skywalking-agent.jar
34 | - name: SW_AGENT_NAME
35 | value: apm-eureka
36 | - name: SW_AGENT_COLLECTOR_BACKEND_SERVICES
37 | value: skywalk-1h6lqf-skywalking-skywalking-oap.demo:11800 # skywalk oap 后端服务
38 | ports:
39 | - name: http
40 | containerPort: 8761
41 | volumeMounts:
42 | - name: sidecar
43 | mountPath: /sidecar
44 | volumes:
45 | - name: sidecar #共享agent文件夹
46 | emptyDir: {}
47 | restartPolicy: Always
48 |
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/6.5.0/apm-springcloud-demo/kdep-apm-item.yml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: apm-item
5 | namespace: demo
6 | labels:
7 | app: apm-item
8 | spec:
9 | replicas: 1
10 | selector:
11 | matchLabels:
12 | app: apm-item
13 | template:
14 | metadata:
15 | name: apm-item
16 | labels:
17 | app: apm-item
18 | spec:
19 | initContainers:
20 | - name: sidecar
21 | image: apache/skywalking-base:6.5.0 # 容器镜像,包含静态资源文件
22 | imagePullPolicy: IfNotPresent
23 | command: ["cp", "-r", "/skywalking/agent", "/sidecar"]
24 | volumeMounts:
25 | - name: sidecar
26 | mountPath: /sidecar
27 | containers:
28 | - name: apm-item
29 | image: evanxuhe/apm-item:6.1.0
30 | imagePullPolicy: IfNotPresent
31 | env:
32 | - name: JAVA_OPTS
33 | value: -javaagent:/sidecar/agent/skywalking-agent.jar
34 | - name: SW_AGENT_NAME
35 | value: apm-item
36 | - name: SW_AGENT_COLLECTOR_BACKEND_SERVICES
37 | value: skywalk-1h6lqf-skywalking-skywalking-oap.demo:11800 # skywalk oap 后端服务
38 | - name: EUREKA_HOSTNAME
39 | value: apm-eureka
40 | - name: EUREKA_PORT
41 | value: '8761'
42 | ports:
43 | - name: http
44 | containerPort: 8082
45 | volumeMounts:
46 | - name: sidecar
47 | mountPath: /sidecar
48 | volumes:
49 | - name: sidecar #共享agent文件夹
50 | emptyDir: {}
51 | restartPolicy: Always
52 |
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/6.5.0/apm-springcloud-demo/kser-apm-eureka.yml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: apm-eureka
5 | namespace: demo
6 | labels:
7 | service: apm-eureka
8 | spec:
9 | type: NodePort
10 | selector:
11 | app: apm-eureka
12 | ports:
13 | - port: 8761
14 | name: register
15 | targetPort: 8761
16 | nodePort: 30761
17 | - port: 8080
18 | name: index
19 | targetPort: 8080
20 | nodePort: 30080
21 |
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/6.5.0/apm-springcloud-demo/kser-apm-item.yml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: apm-item
5 | namespace: demo
6 | labels:
7 | service: apm-item
8 | spec:
9 | type: NodePort
10 | selector:
11 | app: apm-item
12 | ports:
13 | - port: 8082
14 | name: item
15 | targetPort: 8082
16 | nodePort: 30082
17 |
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/8.1.0/README.md:
--------------------------------------------------------------------------------
1 | - Create `demo` namespace
2 |
3 | ```bash
4 | kubectl create namespace demo
5 | ```
6 |
7 | - Install skywalking
8 |
9 | ```bash
10 | helm repo add elastic https://helm.elastic.co
11 | helm dep up skywalking
12 | helm install skywalking skywalking -n demo
13 | ```
14 |
15 | - Install sample apps
16 |
17 | ```bash
18 | kubectl apply -f apm-springcloud-demo
19 | ```
20 |
21 | - Generate some traffics to the sample apps
22 |
23 | ```bash
24 | # should be executed inside a pod
25 | curl apm-eureka.demo.svc:8761/eureka/apps/APM-ITEM/apm-item-6fccf65776-dx4hv:apm-item:8082
26 | curl apm-eureka.demo.svc:8761/eureka/apps/delta
27 | curl apm-eureka.demo.svc:8761/eureka/apps/APM-ITEM
28 | ```
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/8.1.0/apm-springcloud-demo/kdep-apm-eureka.yml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: apm-eureka
5 | namespace: demo
6 | labels:
7 | deploy: apm-eureka
8 | spec:
9 | replicas: 1
10 | selector:
11 | matchLabels:
12 | app: apm-eureka
13 | template:
14 | metadata:
15 | name: apm-eureka
16 | labels:
17 | app: apm-eureka
18 | spec:
19 | initContainers:
20 | - name: sidecar
21 | image: apache/skywalking-base:8.1.0-es7 # 容器镜像,包含静态资源文件
22 | imagePullPolicy: IfNotPresent
23 | command: ["cp", "-r", "/skywalking/agent", "/sidecar"]
24 | volumeMounts:
25 | - name: sidecar
26 | mountPath: /sidecar
27 | containers:
28 | - name: apm-eureka
29 | image: evanxuhe/apm-eureka:6.1.0
30 | imagePullPolicy: IfNotPresent
31 | env:
32 | - name: JAVA_OPTS
33 | value: -javaagent:/sidecar/agent/skywalking-agent.jar
34 | - name: SW_AGENT_NAME
35 | value: apm-eureka
36 | - name: SW_AGENT_COLLECTOR_BACKEND_SERVICES
37 | value: skywalking-oap.demo.svc:11800 # skywalk oap 后端服务
38 | ports:
39 | - name: http
40 | containerPort: 8761
41 | volumeMounts:
42 | - name: sidecar
43 | mountPath: /sidecar
44 | volumes:
45 | - name: sidecar #共享agent文件夹
46 | emptyDir: {}
47 | restartPolicy: Always
48 |
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/8.1.0/apm-springcloud-demo/kdep-apm-item.yml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: apm-item
5 | namespace: demo
6 | labels:
7 | app: apm-item
8 | spec:
9 | replicas: 1
10 | selector:
11 | matchLabels:
12 | app: apm-item
13 | template:
14 | metadata:
15 | name: apm-item
16 | labels:
17 | app: apm-item
18 | spec:
19 | initContainers:
20 | - name: sidecar
21 | image: apache/skywalking-base:8.1.0-es7 # 容器镜像,包含静态资源文件
22 | imagePullPolicy: IfNotPresent
23 | command: ["cp", "-r", "/skywalking/agent", "/sidecar"]
24 | volumeMounts:
25 | - name: sidecar
26 | mountPath: /sidecar
27 | containers:
28 | - name: apm-item
29 | image: evanxuhe/apm-item:6.1.0
30 | imagePullPolicy: IfNotPresent
31 | env:
32 | - name: JAVA_OPTS
33 | value: -javaagent:/sidecar/agent/skywalking-agent.jar
34 | - name: SW_AGENT_NAME
35 | value: apm-item
36 | - name: SW_AGENT_COLLECTOR_BACKEND_SERVICES
37 | value: skywalking-oap.demo.svc:11800 # skywalk oap 后端服务
38 | - name: EUREKA_HOSTNAME
39 | value: apm-eureka
40 | - name: EUREKA_PORT
41 | value: '8761'
42 | ports:
43 | - name: http
44 | containerPort: 8082
45 | volumeMounts:
46 | - name: sidecar
47 | mountPath: /sidecar
48 | volumes:
49 | - name: sidecar #共享agent文件夹
50 | emptyDir: {}
51 | restartPolicy: Always
52 |
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/8.1.0/apm-springcloud-demo/kser-apm-eureka.yml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: apm-eureka
5 | namespace: demo
6 | labels:
7 | service: apm-eureka
8 | spec:
9 | type: NodePort
10 | selector:
11 | app: apm-eureka
12 | ports:
13 | - port: 8761
14 | name: register
15 | targetPort: 8761
16 | nodePort: 30761
17 | - port: 8080
18 | name: index
19 | targetPort: 8080
20 | nodePort: 30080
21 |
--------------------------------------------------------------------------------
/tutorial 6 - skywalking/8.1.0/apm-springcloud-demo/kser-apm-item.yml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: apm-item
5 | namespace: demo
6 | labels:
7 | service: apm-item
8 | spec:
9 | type: NodePort
10 | selector:
11 | app: apm-item
12 | ports:
13 | - port: 8082
14 | name: item
15 | targetPort: 8082
16 | nodePort: 30082
17 |
--------------------------------------------------------------------------------