blob: 3982d12f603656fe7de37a2b70c3863ac26bf7e0 [file] [log] [blame]
Adam Lesinski59e04c62016-02-04 15:59:23 -08001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Ryan Mitchell833a1a62018-07-10 13:51:36 -070017#include "Dump.h"
18
Adam Lesinski93190b72017-11-03 15:20:17 -070019#include <cinttypes>
Adam Lesinskice5e56e2016-10-21 17:56:45 -070020#include <vector>
21
Adam Lesinski93190b72017-11-03 15:20:17 -070022#include "android-base/stringprintf.h"
MÃ¥rten Kongstad24c9aa62018-06-20 08:46:41 +020023#include "androidfw/ConfigDescription.h"
Adam Lesinskid5083f62017-01-16 15:07:21 -080024#include "androidfw/StringPiece.h"
25
Adam Lesinski59e04c62016-02-04 15:59:23 -080026#include "Debug.h"
27#include "Diagnostics.h"
Ryan Mitchell5d275512018-07-19 14:29:00 -070028#include "LoadedApk.h"
29#include "Util.h"
Adam Lesinski00451162017-10-03 07:44:08 -070030#include "format/Container.h"
Adam Lesinski46708052017-09-29 14:49:15 -070031#include "format/binary/BinaryResourceParser.h"
Ryan Mitchell5d275512018-07-19 14:29:00 -070032#include "format/binary/XmlFlattener.h"
Adam Lesinski46708052017-09-29 14:49:15 -070033#include "format/proto/ProtoDeserialize.h"
Adam Lesinski00451162017-10-03 07:44:08 -070034#include "io/FileStream.h"
Adam Lesinski64587af2016-02-18 18:33:06 -080035#include "io/ZipArchive.h"
Adam Lesinski59e04c62016-02-04 15:59:23 -080036#include "process/IResourceTableConsumer.h"
Adam Lesinski93190b72017-11-03 15:20:17 -070037#include "text/Printer.h"
Adam Lesinski59e04c62016-02-04 15:59:23 -080038#include "util/Files.h"
Adam Lesinskid5083f62017-01-16 15:07:21 -080039
Adam Lesinski93190b72017-11-03 15:20:17 -070040using ::aapt::text::Printer;
Adam Lesinski4ffea042017-08-10 15:37:28 -070041using ::android::StringPiece;
Adam Lesinski93190b72017-11-03 15:20:17 -070042using ::android::base::StringPrintf;
Adam Lesinski59e04c62016-02-04 15:59:23 -080043
Adam Lesinski59e04c62016-02-04 15:59:23 -080044namespace aapt {
45
Adam Lesinski00451162017-10-03 07:44:08 -070046static const char* ResourceFileTypeToString(const ResourceFile::Type& type) {
47 switch (type) {
48 case ResourceFile::Type::kPng:
49 return "PNG";
50 case ResourceFile::Type::kBinaryXml:
51 return "BINARY_XML";
52 case ResourceFile::Type::kProtoXml:
53 return "PROTO_XML";
54 default:
55 break;
Adam Lesinskicacb28f2016-10-19 12:18:14 -070056 }
Adam Lesinski00451162017-10-03 07:44:08 -070057 return "UNKNOWN";
Adam Lesinski59e04c62016-02-04 15:59:23 -080058}
59
Adam Lesinski00451162017-10-03 07:44:08 -070060static void DumpCompiledFile(const ResourceFile& file, const Source& source, off64_t offset,
Adam Lesinski93190b72017-11-03 15:20:17 -070061 size_t len, Printer* printer) {
62 printer->Print("Resource: ");
63 printer->Println(file.name.to_string());
64
65 printer->Print("Config: ");
66 printer->Println(file.config.to_string());
67
68 printer->Print("Source: ");
69 printer->Println(file.source.to_string());
70
71 printer->Print("Type: ");
72 printer->Println(ResourceFileTypeToString(file.type));
73
74 printer->Println(StringPrintf("Data: offset=%" PRIi64 " length=%zd", offset, len));
Adam Lesinski00451162017-10-03 07:44:08 -070075}
76
Adam Lesinski00451162017-10-03 07:44:08 -070077namespace {
78
Adam Lesinski59e04c62016-02-04 15:59:23 -080079class DumpContext : public IAaptContext {
Adam Lesinskicacb28f2016-10-19 12:18:14 -070080 public:
Adam Lesinskib522f042017-04-21 16:57:59 -070081 PackageType GetPackageType() override {
82 // Doesn't matter.
83 return PackageType::kApp;
84 }
85
Adam Lesinskid0f492d2017-04-03 18:12:45 -070086 IDiagnostics* GetDiagnostics() override {
87 return &diagnostics_;
88 }
Adam Lesinski59e04c62016-02-04 15:59:23 -080089
Adam Lesinskice5e56e2016-10-21 17:56:45 -070090 NameMangler* GetNameMangler() override {
Adam Lesinski00451162017-10-03 07:44:08 -070091 UNIMPLEMENTED(FATAL);
Adam Lesinskicacb28f2016-10-19 12:18:14 -070092 return nullptr;
93 }
Adam Lesinski59e04c62016-02-04 15:59:23 -080094
Adam Lesinskice5e56e2016-10-21 17:56:45 -070095 const std::string& GetCompilationPackage() override {
Adam Lesinskicacb28f2016-10-19 12:18:14 -070096 static std::string empty;
97 return empty;
98 }
Adam Lesinski59e04c62016-02-04 15:59:23 -080099
Adam Lesinskid0f492d2017-04-03 18:12:45 -0700100 uint8_t GetPackageId() override {
101 return 0;
102 }
Adam Lesinski59e04c62016-02-04 15:59:23 -0800103
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700104 SymbolTable* GetExternalSymbols() override {
Adam Lesinski00451162017-10-03 07:44:08 -0700105 UNIMPLEMENTED(FATAL);
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700106 return nullptr;
107 }
Adam Lesinski59e04c62016-02-04 15:59:23 -0800108
Adam Lesinskid0f492d2017-04-03 18:12:45 -0700109 bool IsVerbose() override {
110 return verbose_;
111 }
Adam Lesinski355f2852016-02-13 20:26:45 -0800112
Adam Lesinskid0f492d2017-04-03 18:12:45 -0700113 void SetVerbose(bool val) {
114 verbose_ = val;
115 }
Adam Lesinski355f2852016-02-13 20:26:45 -0800116
Adam Lesinskid0f492d2017-04-03 18:12:45 -0700117 int GetMinSdkVersion() override {
118 return 0;
119 }
Adam Lesinskifb6312f2016-06-28 14:40:32 -0700120
Udam Sainib228df32019-06-18 16:50:34 -0700121 const std::set<std::string>& GetSplitNameDependencies() override {
122 UNIMPLEMENTED(FATAL) << "Split Name Dependencies should not be necessary";
123 static std::set<std::string> empty;
124 return empty;
125 }
126
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700127 private:
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700128 StdErrDiagnostics diagnostics_;
129 bool verbose_ = false;
Adam Lesinski59e04c62016-02-04 15:59:23 -0800130};
131
Adam Lesinski00451162017-10-03 07:44:08 -0700132} // namespace
133
Ryan Mitchell5d275512018-07-19 14:29:00 -0700134int DumpAPCCommand::Action(const std::vector<std::string>& args) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700135 DumpContext context;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700136 DebugPrintTableOptions print_options;
137 print_options.show_sources = true;
138 print_options.show_values = !no_values_;
139
140 if (args.size() < 1) {
Ryan Mitchell214846d2018-09-19 16:57:01 -0700141 diag_->Error(DiagMessage() << "No dump container specified");
Ryan Mitchell5d275512018-07-19 14:29:00 -0700142 return 1;
143 }
144
Ryan Mitchell214846d2018-09-19 16:57:01 -0700145 bool error = false;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700146 for (auto container : args) {
147 io::FileInputStream input(container);
148 if (input.HadError()) {
149 context.GetDiagnostics()->Error(DiagMessage(container)
Ryan Mitchell214846d2018-09-19 16:57:01 -0700150 << "failed to open file: " << input.GetError());
151 error = true;
152 continue;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700153 }
154
155 // Try as a compiled file.
156 ContainerReader reader(&input);
157 if (reader.HadError()) {
158 context.GetDiagnostics()->Error(DiagMessage(container)
Ryan Mitchell214846d2018-09-19 16:57:01 -0700159 << "failed to read container: " << reader.GetError());
160 error = true;
161 continue;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700162 }
163
Ryan Mitchell214846d2018-09-19 16:57:01 -0700164 printer_->Println("AAPT2 Container (APC)");
Ryan Mitchell5d275512018-07-19 14:29:00 -0700165 ContainerReaderEntry* entry;
166 std::string error;
167 while ((entry = reader.Next()) != nullptr) {
168 if (entry->Type() == ContainerEntryType::kResTable) {
Ryan Mitchell214846d2018-09-19 16:57:01 -0700169 printer_->Println("kResTable");
Ryan Mitchell5d275512018-07-19 14:29:00 -0700170
171 pb::ResourceTable pb_table;
172 if (!entry->GetResTable(&pb_table)) {
173 context.GetDiagnostics()->Error(DiagMessage(container)
Ryan Mitchell214846d2018-09-19 16:57:01 -0700174 << "failed to parse proto table: " << entry->GetError());
175 error = true;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700176 continue;
177 }
178
179 ResourceTable table;
180 error.clear();
181 if (!DeserializeTableFromPb(pb_table, nullptr /*files*/, &table, &error)) {
182 context.GetDiagnostics()->Error(DiagMessage(container)
Ryan Mitchell214846d2018-09-19 16:57:01 -0700183 << "failed to parse table: " << error);
184 error = true;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700185 continue;
186 }
187
Ryan Mitchell214846d2018-09-19 16:57:01 -0700188 printer_->Indent();
189 Debug::PrintTable(table, print_options, printer_);
190 printer_->Undent();
Ryan Mitchell5d275512018-07-19 14:29:00 -0700191 } else if (entry->Type() == ContainerEntryType::kResFile) {
Ryan Mitchell214846d2018-09-19 16:57:01 -0700192 printer_->Println("kResFile");
Ryan Mitchell5d275512018-07-19 14:29:00 -0700193 pb::internal::CompiledFile pb_compiled_file;
194 off64_t offset;
195 size_t length;
196 if (!entry->GetResFileOffsets(&pb_compiled_file, &offset, &length)) {
Ryan Mitchell214846d2018-09-19 16:57:01 -0700197 context.GetDiagnostics()->Error(DiagMessage(container)
198 << "failed to parse compiled proto file: "
199 << entry->GetError());
200 error = true;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700201 continue;
202 }
203
204 ResourceFile file;
205 if (!DeserializeCompiledFileFromPb(pb_compiled_file, &file, &error)) {
206 context.GetDiagnostics()->Warn(DiagMessage(container)
Ryan Mitchell214846d2018-09-19 16:57:01 -0700207 << "failed to parse compiled file: " << error);
208 error = true;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700209 continue;
210 }
211
Ryan Mitchell214846d2018-09-19 16:57:01 -0700212 printer_->Indent();
213 DumpCompiledFile(file, Source(container), offset, length, printer_);
214 printer_->Undent();
Ryan Mitchell5d275512018-07-19 14:29:00 -0700215 }
Pierre Lecesneaadf27e2017-05-05 14:58:21 +0100216 }
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700217 }
Ryan Mitchell5d275512018-07-19 14:29:00 -0700218
Ryan Mitchell214846d2018-09-19 16:57:01 -0700219 return (error) ? 1 : 0;
Adam Lesinski59e04c62016-02-04 15:59:23 -0800220}
221
Ryan Mitchell214846d2018-09-19 16:57:01 -0700222int DumpBadgerCommand::Action(const std::vector<std::string>& args) {
223 printer_->Print(StringPrintf("%s", kBadgerData));
224 printer_->Print("Did you mean \"aapt2 dump badging\"?\n");
225 return 1;
226}
Ryan Mitchell5d275512018-07-19 14:29:00 -0700227
Ryan Mitchell214846d2018-09-19 16:57:01 -0700228int DumpConfigsCommand::Dump(LoadedApk* apk) {
229 ResourceTable* table = apk->GetResourceTable();
Ryan Mitchellfc225b22018-08-21 14:52:51 -0700230 if (!table) {
Ryan Mitchell214846d2018-09-19 16:57:01 -0700231 GetDiagnostics()->Error(DiagMessage() << "Failed to retrieve resource table");
Ryan Mitchellfc225b22018-08-21 14:52:51 -0700232 return 1;
233 }
234
Ryan Mitchell5d275512018-07-19 14:29:00 -0700235 // Comparison function used to order configurations
MÃ¥rten Kongstad24c9aa62018-06-20 08:46:41 +0200236 auto compare = [](android::ConfigDescription c1, android::ConfigDescription c2) -> bool {
Ryan Mitchell214846d2018-09-19 16:57:01 -0700237 return c1.compare(c2) < 0;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700238 };
239
240 // Insert the configurations into a set in order to keep every configuarion seen
MÃ¥rten Kongstad24c9aa62018-06-20 08:46:41 +0200241 std::set<android::ConfigDescription, decltype(compare)> configs(compare);
Ryan Mitchellfc225b22018-08-21 14:52:51 -0700242 for (auto& package : table->packages) {
Ryan Mitchell5d275512018-07-19 14:29:00 -0700243 for (auto& type : package->types) {
244 for (auto& entry : type->entries) {
245 for (auto& value : entry->values) {
246 configs.insert(value->config);
247 }
248 }
249 }
250 }
251
252 // Print the configurations in order
253 for (auto& config : configs) {
Ryan Mitchell214846d2018-09-19 16:57:01 -0700254 GetPrinter()->Print(StringPrintf("%s\n", config.to_string().data()));
Ryan Mitchell5d275512018-07-19 14:29:00 -0700255 }
Ryan Mitchell5d275512018-07-19 14:29:00 -0700256 return 0;
257}
258
Ryan Mitchell214846d2018-09-19 16:57:01 -0700259int DumpPackageNameCommand::Dump(LoadedApk* apk) {
Aurimas Liutikas13e6a1d2018-09-25 16:11:40 -0700260 Maybe<std::string> package_name = GetPackageName(apk);
261 if (!package_name) {
Ryan Mitchell5d275512018-07-19 14:29:00 -0700262 return 1;
263 }
264
Aurimas Liutikas13e6a1d2018-09-25 16:11:40 -0700265 GetPrinter()->Println(package_name.value());
Ryan Mitchell5d275512018-07-19 14:29:00 -0700266 return 0;
267}
268
Ryan Mitchell214846d2018-09-19 16:57:01 -0700269int DumpStringsCommand::Dump(LoadedApk* apk) {
270 ResourceTable* table = apk->GetResourceTable();
271 if (!table) {
272 GetDiagnostics()->Error(DiagMessage() << "Failed to retrieve resource table");
Ryan Mitchell5d275512018-07-19 14:29:00 -0700273 return 1;
274 }
275
Ryan Mitchell214846d2018-09-19 16:57:01 -0700276 // Load the run-time xml string pool using the flattened data
277 BigBuffer buffer(4096);
278 StringPool::FlattenUtf8(&buffer, table->string_pool, GetDiagnostics());
279 auto data = buffer.to_string();
280 android::ResStringPool pool(data.data(), data.size(), false);
281 Debug::DumpResStringPool(&pool, GetPrinter());
282 return 0;
283}
284
Aurimas Liutikas13e6a1d2018-09-25 16:11:40 -0700285int DumpStyleParentCommand::Dump(LoadedApk* apk) {
286 Maybe<std::string> package_name = GetPackageName(apk);
287 if (!package_name) {
288 return 1;
289 }
290
291 const auto target_style = ResourceName(package_name.value(), ResourceType::kStyle, style_);
292 const auto table = apk->GetResourceTable();
293
294 if (!table) {
295 GetDiagnostics()->Error(DiagMessage() << "Failed to retrieve resource table");
296 return 1;
297 }
298
299 Maybe<ResourceTable::SearchResult> target = table->FindResource(target_style);
300 if (!target) {
301 GetDiagnostics()->Error(
302 DiagMessage() << "Target style \"" << target_style.entry << "\" does not exist");
303 return 1;
304 }
305
306 Debug::PrintStyleGraph(table, target_style);
307 return 0;
308}
309
Ryan Mitchell214846d2018-09-19 16:57:01 -0700310int DumpTableCommand::Dump(LoadedApk* apk) {
311 if (apk->GetApkFormat() == ApkFormat::kProto) {
312 GetPrinter()->Println("Proto APK");
313 } else {
314 GetPrinter()->Println("Binary APK");
315 }
316
317 ResourceTable* table = apk->GetResourceTable();
318 if (!table) {
319 GetDiagnostics()->Error(DiagMessage() << "Failed to retrieve resource table");
320 return 1;
321 }
Ryan Mitchell5d275512018-07-19 14:29:00 -0700322
323 DebugPrintTableOptions print_options;
324 print_options.show_sources = true;
325 print_options.show_values = !no_values_;
Ryan Mitchell214846d2018-09-19 16:57:01 -0700326 Debug::PrintTable(*table, print_options, GetPrinter());
Ryan Mitchell5d275512018-07-19 14:29:00 -0700327 return 0;
328}
329
Ryan Mitchell214846d2018-09-19 16:57:01 -0700330int DumpXmlStringsCommand::Dump(LoadedApk* apk) {
Ryan Mitchell5d275512018-07-19 14:29:00 -0700331 DumpContext context;
Ryan Mitchell214846d2018-09-19 16:57:01 -0700332 bool error = false;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700333 for (auto xml_file : files_) {
334 android::ResXMLTree tree;
335
Ryan Mitchell214846d2018-09-19 16:57:01 -0700336 if (apk->GetApkFormat() == ApkFormat::kProto) {
337 auto xml = apk->LoadXml(xml_file, GetDiagnostics());
Ryan Mitchell5d275512018-07-19 14:29:00 -0700338 if (!xml) {
Ryan Mitchell214846d2018-09-19 16:57:01 -0700339 error = true;
340 continue;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700341 }
342
343 // Flatten the xml document to get a binary representation of the proto xml file
344 BigBuffer buffer(4096);
345 XmlFlattenerOptions options = {};
346 options.keep_raw_values = true;
347 XmlFlattener flattener(&buffer, options);
348 if (!flattener.Consume(&context, xml.get())) {
Ryan Mitchell214846d2018-09-19 16:57:01 -0700349 error = true;
350 continue;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700351 }
352
353 // Load the run-time xml tree using the flattened data
354 std::string data = buffer.to_string();
355 tree.setTo(data.data(), data.size(), /** copyData */ true);
356
Ryan Mitchell214846d2018-09-19 16:57:01 -0700357 } else if (apk->GetApkFormat() == ApkFormat::kBinary) {
358 io::IFile* file = apk->GetFileCollection()->FindFile(xml_file);
Ryan Mitchell5d275512018-07-19 14:29:00 -0700359 if (!file) {
Ryan Mitchell214846d2018-09-19 16:57:01 -0700360 GetDiagnostics()->Error(DiagMessage(xml_file)
361 << "File '" << xml_file << "' not found in APK");
362 error = true;
363 continue;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700364 }
365
366 std::unique_ptr<io::IData> data = file->OpenAsData();
367 if (!data) {
Ryan Mitchell214846d2018-09-19 16:57:01 -0700368 GetDiagnostics()->Error(DiagMessage() << "Failed to open " << xml_file);
369 error = true;
370 continue;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700371 }
372
373 // Load the run-time xml tree from the file data
374 tree.setTo(data->data(), data->size(), /** copyData */ true);
Ryan Mitchell214846d2018-09-19 16:57:01 -0700375 } else {
376 GetDiagnostics()->Error(DiagMessage(apk->GetSource()) << "Unknown APK format");
377 error = true;
378 continue;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700379 }
380
Ryan Mitchell214846d2018-09-19 16:57:01 -0700381 Debug::DumpResStringPool(&tree.getStrings(), GetPrinter());
Ryan Mitchell5d275512018-07-19 14:29:00 -0700382 }
Ryan Mitchell214846d2018-09-19 16:57:01 -0700383 return (error) ? 1 : 0;
384}
Ryan Mitchell5d275512018-07-19 14:29:00 -0700385
Ryan Mitchell214846d2018-09-19 16:57:01 -0700386int DumpXmlTreeCommand::Dump(LoadedApk* apk) {
387 for (auto file : files_) {
388 auto xml = apk->LoadXml(file, GetDiagnostics());
389 if (!xml) {
390 return 1;
391 }
392 Debug::DumpXml(*xml, GetPrinter());
393 }
Ryan Mitchell5d275512018-07-19 14:29:00 -0700394 return 0;
395}
396
MÃ¥rten Kongstad1d3b64852019-09-17 13:02:32 +0200397int DumpOverlayableCommand::Dump(LoadedApk* apk) {
398 ResourceTable* table = apk->GetResourceTable();
399 if (!table) {
400 GetDiagnostics()->Error(DiagMessage() << "Failed to retrieve resource table");
401 return 1;
402 }
403
404 Debug::DumpOverlayable(*table, GetPrinter());
405 return 0;
406}
407
Ryan Mitchell214846d2018-09-19 16:57:01 -0700408const char DumpBadgerCommand::kBadgerData[2925] = {
409 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
410 32, 32, 32, 32, 32, 32, 95, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
411 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
412 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
413 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 63, 86, 35, 40, 46, 46,
414 95, 95, 95, 95, 97, 97, 44, 32, 46, 124, 42, 33, 83, 62, 32, 32, 32, 32, 32,
415 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32,
416 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
417 32, 32, 58, 46, 58, 59, 61, 59, 61, 81, 81, 81, 81, 66, 96, 61, 61, 58, 46,
418 46, 46, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
419 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
420 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 58, 106, 81, 81,
421 81, 81, 102, 59, 61, 59, 59, 61, 61, 61, 58, 46, 32, 32, 32, 32, 32, 32, 32,
422 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32,
423 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
424 61, 59, 59, 59, 58, 109, 81, 81, 81, 81, 61, 59, 59, 59, 59, 59, 58, 59, 59,
425 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
426 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
427 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 60, 81, 81, 81, 81, 87, 58,
428 59, 59, 59, 59, 59, 59, 61, 119, 44, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
429 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
430 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 47, 61, 59, 59,
431 58, 100, 81, 81, 81, 81, 35, 58, 59, 59, 59, 59, 59, 58, 121, 81, 91, 32, 32,
432 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32,
433 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
434 32, 32, 32, 46, 109, 58, 59, 59, 61, 81, 81, 81, 81, 81, 109, 58, 59, 59, 59,
435 59, 61, 109, 81, 81, 76, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
436 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
437 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 87, 59, 61, 59, 41, 81, 81,
438 81, 81, 81, 81, 59, 61, 59, 59, 58, 109, 81, 81, 87, 39, 46, 32, 32, 32, 32,
439 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32,
440 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
441 60, 81, 91, 59, 59, 61, 81, 81, 81, 81, 81, 87, 43, 59, 58, 59, 60, 81, 81,
442 81, 76, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
443 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
444 32, 32, 32, 32, 32, 32, 32, 32, 32, 52, 91, 58, 45, 59, 87, 81, 81, 81, 81,
445 70, 58, 58, 58, 59, 106, 81, 81, 81, 91, 32, 32, 32, 32, 32, 32, 32, 32, 32,
446 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32,
447 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 93, 40,
448 32, 46, 59, 100, 81, 81, 81, 81, 40, 58, 46, 46, 58, 100, 81, 81, 68, 32, 32,
449 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
450 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 46, 46, 32, 46,
451 46, 46, 32, 46, 32, 46, 45, 91, 59, 61, 58, 109, 81, 81, 81, 87, 46, 58, 61,
452 59, 60, 81, 81, 80, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
453 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 46, 46,
454 61, 59, 61, 61, 61, 59, 61, 61, 59, 59, 59, 58, 58, 46, 46, 41, 58, 59, 58,
455 81, 81, 81, 81, 69, 58, 59, 59, 60, 81, 81, 68, 32, 32, 32, 32, 32, 32, 32,
456 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32,
457 32, 32, 32, 32, 58, 59, 61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
458 59, 59, 61, 61, 46, 61, 59, 93, 81, 81, 81, 81, 107, 58, 59, 58, 109, 87, 68,
459 96, 32, 32, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
460 32, 32, 32, 32, 32, 10, 32, 32, 32, 46, 60, 61, 61, 59, 59, 59, 59, 59, 59,
461 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 58, 58, 58, 115, 109, 68, 41, 36,
462 81, 109, 46, 61, 61, 81, 69, 96, 46, 58, 58, 46, 58, 46, 46, 32, 32, 32, 32,
463 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 46, 32, 95, 81, 67,
464 61, 61, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
465 59, 59, 58, 68, 39, 61, 105, 61, 63, 81, 119, 58, 106, 80, 32, 58, 61, 59, 59,
466 61, 59, 61, 59, 61, 46, 95, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
467 32, 32, 10, 32, 32, 36, 81, 109, 105, 59, 61, 59, 59, 59, 59, 59, 59, 59, 59,
468 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 46, 58, 37, 73, 108, 108, 62, 52, 81,
469 109, 34, 32, 61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 59, 61, 61, 46, 46,
470 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 46, 45, 57, 101, 43, 43, 61,
471 61, 59, 59, 59, 59, 59, 59, 61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 58, 97,
472 46, 61, 108, 62, 126, 58, 106, 80, 96, 46, 61, 61, 59, 59, 59, 59, 59, 59, 59,
473 59, 59, 59, 59, 59, 59, 61, 61, 97, 103, 97, 32, 32, 32, 32, 32, 32, 32, 10,
474 32, 32, 32, 32, 45, 46, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 45,
475 58, 59, 59, 59, 59, 61, 119, 81, 97, 124, 105, 124, 124, 39, 126, 95, 119, 58, 61,
476 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 119, 81, 81,
477 99, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
478 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 58, 106, 81, 81, 81, 109, 119,
479 119, 119, 109, 109, 81, 81, 122, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
480 59, 59, 59, 58, 115, 81, 87, 81, 102, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32,
481 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 58,
482 59, 61, 81, 81, 81, 81, 81, 81, 87, 87, 81, 81, 81, 81, 81, 58, 59, 59, 59,
483 59, 59, 59, 59, 59, 58, 45, 45, 45, 59, 59, 59, 41, 87, 66, 33, 32, 32, 32,
484 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
485 32, 32, 32, 32, 32, 32, 58, 59, 59, 93, 81, 81, 81, 81, 81, 81, 81, 81, 81,
486 81, 81, 81, 81, 40, 58, 59, 59, 59, 58, 45, 32, 46, 32, 32, 32, 32, 32, 46,
487 32, 126, 96, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32,
488 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 59, 58, 81,
489 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 40, 58, 59, 59, 59, 58, 32,
490 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
491 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
492 32, 32, 32, 58, 59, 59, 58, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
493 81, 40, 58, 59, 59, 59, 46, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
494 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
495 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 59, 60, 81, 81, 81, 81,
496 81, 81, 81, 81, 81, 81, 81, 81, 81, 59, 61, 59, 59, 61, 32, 32, 32, 32, 32,
497 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32,
498 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
499 58, 59, 59, 93, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 40, 59,
500 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
501 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
502 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 58, 106, 81, 81, 81, 81, 81, 81, 81,
503 81, 81, 81, 81, 81, 81, 76, 58, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32,
504 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32,
505 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 58, 58,
506 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 87, 58, 59, 59, 59, 59,
507 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
508 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
509 32, 32, 32, 32, 32, 58, 59, 61, 41, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
510 81, 81, 87, 59, 61, 58, 59, 59, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
511 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32,
512 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 58, 61, 81, 81,
513 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 107, 58, 59, 59, 59, 59, 58, 32, 32,
514 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
515 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
516 32, 32, 58, 59, 59, 58, 51, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 102, 94,
517 59, 59, 59, 59, 59, 61, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
518 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
519 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 59, 59, 59, 43, 63, 36, 81,
520 81, 81, 87, 64, 86, 102, 58, 59, 59, 59, 59, 59, 59, 59, 46, 32, 32, 32, 32,
521 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32,
522 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 61,
523 59, 59, 59, 59, 59, 59, 59, 43, 33, 58, 126, 126, 58, 59, 59, 59, 59, 59, 59,
524 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
525 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
526 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 58, 45, 58, 61, 59, 58, 58, 58, 61,
527 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 58, 32, 46, 32, 32, 32, 32,
528 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32,
529 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 59, 59,
530 58, 95, 32, 45, 61, 59, 61, 59, 59, 59, 59, 59, 59, 59, 45, 58, 59, 59, 59,
531 59, 61, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
532 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
533 32, 58, 61, 59, 59, 59, 59, 59, 61, 59, 61, 46, 46, 32, 45, 45, 45, 59, 58,
534 45, 45, 46, 58, 59, 59, 59, 59, 59, 59, 61, 46, 32, 32, 32, 32, 32, 32, 32,
535 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32,
536 32, 32, 32, 32, 32, 32, 32, 32, 46, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59,
537 61, 59, 46, 32, 32, 46, 32, 46, 32, 58, 61, 59, 59, 59, 59, 59, 59, 59, 59,
538 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10,
539 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45,
540 59, 59, 59, 59, 59, 59, 59, 59, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61,
541 59, 59, 59, 59, 59, 59, 59, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
542 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
543 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 59, 59, 59, 59, 32, 46, 32,
544 32, 32, 32, 32, 32, 61, 46, 61, 59, 59, 59, 59, 59, 59, 58, 32, 32, 32, 32,
545 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32,
546 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59, 59,
547 59, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 32, 46, 61, 58, 59, 59,
548 59, 59, 59, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
549 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
550 32, 32, 32, 32, 58, 59, 59, 59, 59, 59, 59, 59, 59, 46, 46, 32, 32, 32, 32,
551 32, 32, 32, 61, 59, 59, 59, 59, 59, 59, 59, 45, 32, 32, 32, 32, 32, 32, 32,
552 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32,
553 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 32, 45, 61, 59, 59, 59, 59,
554 59, 58, 32, 46, 32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 59, 59, 59, 58, 45,
555 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
556 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
557 32, 32, 32, 32, 45, 45, 45, 45, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32,
558 32, 45, 61, 59, 58, 45, 45, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
559 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
560 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
561 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 32, 32, 46, 32, 32, 32, 32, 32, 32,
562 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10};
Ryan Mitchell5d275512018-07-19 14:29:00 -0700563
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700564} // namespace aapt