blob: 429aff1ff594bcda8ed8e3f47a069e579ecebdef [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
Ryan Mitchell214846d2018-09-19 16:57:01 -0700397const char DumpBadgerCommand::kBadgerData[2925] = {
398 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
399 32, 32, 32, 32, 32, 32, 95, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
400 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
401 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
402 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 63, 86, 35, 40, 46, 46,
403 95, 95, 95, 95, 97, 97, 44, 32, 46, 124, 42, 33, 83, 62, 32, 32, 32, 32, 32,
404 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32,
405 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
406 32, 32, 58, 46, 58, 59, 61, 59, 61, 81, 81, 81, 81, 66, 96, 61, 61, 58, 46,
407 46, 46, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
408 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
409 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 58, 106, 81, 81,
410 81, 81, 102, 59, 61, 59, 59, 61, 61, 61, 58, 46, 32, 32, 32, 32, 32, 32, 32,
411 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32,
412 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
413 61, 59, 59, 59, 58, 109, 81, 81, 81, 81, 61, 59, 59, 59, 59, 59, 58, 59, 59,
414 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
415 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
416 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 60, 81, 81, 81, 81, 87, 58,
417 59, 59, 59, 59, 59, 59, 61, 119, 44, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
418 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
419 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 47, 61, 59, 59,
420 58, 100, 81, 81, 81, 81, 35, 58, 59, 59, 59, 59, 59, 58, 121, 81, 91, 32, 32,
421 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32,
422 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
423 32, 32, 32, 46, 109, 58, 59, 59, 61, 81, 81, 81, 81, 81, 109, 58, 59, 59, 59,
424 59, 61, 109, 81, 81, 76, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
425 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
426 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 87, 59, 61, 59, 41, 81, 81,
427 81, 81, 81, 81, 59, 61, 59, 59, 58, 109, 81, 81, 87, 39, 46, 32, 32, 32, 32,
428 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32,
429 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
430 60, 81, 91, 59, 59, 61, 81, 81, 81, 81, 81, 87, 43, 59, 58, 59, 60, 81, 81,
431 81, 76, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
432 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
433 32, 32, 32, 32, 32, 32, 32, 32, 32, 52, 91, 58, 45, 59, 87, 81, 81, 81, 81,
434 70, 58, 58, 58, 59, 106, 81, 81, 81, 91, 32, 32, 32, 32, 32, 32, 32, 32, 32,
435 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32,
436 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 93, 40,
437 32, 46, 59, 100, 81, 81, 81, 81, 40, 58, 46, 46, 58, 100, 81, 81, 68, 32, 32,
438 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
439 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 46, 46, 32, 46,
440 46, 46, 32, 46, 32, 46, 45, 91, 59, 61, 58, 109, 81, 81, 81, 87, 46, 58, 61,
441 59, 60, 81, 81, 80, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
442 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 46, 46,
443 61, 59, 61, 61, 61, 59, 61, 61, 59, 59, 59, 58, 58, 46, 46, 41, 58, 59, 58,
444 81, 81, 81, 81, 69, 58, 59, 59, 60, 81, 81, 68, 32, 32, 32, 32, 32, 32, 32,
445 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32,
446 32, 32, 32, 32, 58, 59, 61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
447 59, 59, 61, 61, 46, 61, 59, 93, 81, 81, 81, 81, 107, 58, 59, 58, 109, 87, 68,
448 96, 32, 32, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
449 32, 32, 32, 32, 32, 10, 32, 32, 32, 46, 60, 61, 61, 59, 59, 59, 59, 59, 59,
450 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 58, 58, 58, 115, 109, 68, 41, 36,
451 81, 109, 46, 61, 61, 81, 69, 96, 46, 58, 58, 46, 58, 46, 46, 32, 32, 32, 32,
452 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 46, 32, 95, 81, 67,
453 61, 61, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
454 59, 59, 58, 68, 39, 61, 105, 61, 63, 81, 119, 58, 106, 80, 32, 58, 61, 59, 59,
455 61, 59, 61, 59, 61, 46, 95, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
456 32, 32, 10, 32, 32, 36, 81, 109, 105, 59, 61, 59, 59, 59, 59, 59, 59, 59, 59,
457 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 46, 58, 37, 73, 108, 108, 62, 52, 81,
458 109, 34, 32, 61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 59, 61, 61, 46, 46,
459 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 46, 45, 57, 101, 43, 43, 61,
460 61, 59, 59, 59, 59, 59, 59, 61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 58, 97,
461 46, 61, 108, 62, 126, 58, 106, 80, 96, 46, 61, 61, 59, 59, 59, 59, 59, 59, 59,
462 59, 59, 59, 59, 59, 59, 61, 61, 97, 103, 97, 32, 32, 32, 32, 32, 32, 32, 10,
463 32, 32, 32, 32, 45, 46, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 45,
464 58, 59, 59, 59, 59, 61, 119, 81, 97, 124, 105, 124, 124, 39, 126, 95, 119, 58, 61,
465 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 119, 81, 81,
466 99, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
467 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 58, 106, 81, 81, 81, 109, 119,
468 119, 119, 109, 109, 81, 81, 122, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
469 59, 59, 59, 58, 115, 81, 87, 81, 102, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32,
470 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 58,
471 59, 61, 81, 81, 81, 81, 81, 81, 87, 87, 81, 81, 81, 81, 81, 58, 59, 59, 59,
472 59, 59, 59, 59, 59, 58, 45, 45, 45, 59, 59, 59, 41, 87, 66, 33, 32, 32, 32,
473 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
474 32, 32, 32, 32, 32, 32, 58, 59, 59, 93, 81, 81, 81, 81, 81, 81, 81, 81, 81,
475 81, 81, 81, 81, 40, 58, 59, 59, 59, 58, 45, 32, 46, 32, 32, 32, 32, 32, 46,
476 32, 126, 96, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32,
477 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 59, 58, 81,
478 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 40, 58, 59, 59, 59, 58, 32,
479 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
480 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
481 32, 32, 32, 58, 59, 59, 58, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
482 81, 40, 58, 59, 59, 59, 46, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
483 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
484 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 59, 60, 81, 81, 81, 81,
485 81, 81, 81, 81, 81, 81, 81, 81, 81, 59, 61, 59, 59, 61, 32, 32, 32, 32, 32,
486 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32,
487 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
488 58, 59, 59, 93, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 40, 59,
489 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
490 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
491 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 58, 106, 81, 81, 81, 81, 81, 81, 81,
492 81, 81, 81, 81, 81, 81, 76, 58, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32,
493 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32,
494 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 58, 58,
495 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 87, 58, 59, 59, 59, 59,
496 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
497 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
498 32, 32, 32, 32, 32, 58, 59, 61, 41, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
499 81, 81, 87, 59, 61, 58, 59, 59, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
500 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32,
501 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 58, 61, 81, 81,
502 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 107, 58, 59, 59, 59, 59, 58, 32, 32,
503 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
504 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
505 32, 32, 58, 59, 59, 58, 51, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 102, 94,
506 59, 59, 59, 59, 59, 61, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
507 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
508 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 59, 59, 59, 43, 63, 36, 81,
509 81, 81, 87, 64, 86, 102, 58, 59, 59, 59, 59, 59, 59, 59, 46, 32, 32, 32, 32,
510 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32,
511 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 61,
512 59, 59, 59, 59, 59, 59, 59, 43, 33, 58, 126, 126, 58, 59, 59, 59, 59, 59, 59,
513 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
514 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
515 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 58, 45, 58, 61, 59, 58, 58, 58, 61,
516 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 58, 32, 46, 32, 32, 32, 32,
517 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32,
518 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 59, 59,
519 58, 95, 32, 45, 61, 59, 61, 59, 59, 59, 59, 59, 59, 59, 45, 58, 59, 59, 59,
520 59, 61, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
521 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
522 32, 58, 61, 59, 59, 59, 59, 59, 61, 59, 61, 46, 46, 32, 45, 45, 45, 59, 58,
523 45, 45, 46, 58, 59, 59, 59, 59, 59, 59, 61, 46, 32, 32, 32, 32, 32, 32, 32,
524 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32,
525 32, 32, 32, 32, 32, 32, 32, 32, 46, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59,
526 61, 59, 46, 32, 32, 46, 32, 46, 32, 58, 61, 59, 59, 59, 59, 59, 59, 59, 59,
527 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10,
528 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45,
529 59, 59, 59, 59, 59, 59, 59, 59, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61,
530 59, 59, 59, 59, 59, 59, 59, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
531 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
532 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 59, 59, 59, 59, 32, 46, 32,
533 32, 32, 32, 32, 32, 61, 46, 61, 59, 59, 59, 59, 59, 59, 58, 32, 32, 32, 32,
534 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32,
535 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59, 59,
536 59, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 32, 46, 61, 58, 59, 59,
537 59, 59, 59, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
538 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
539 32, 32, 32, 32, 58, 59, 59, 59, 59, 59, 59, 59, 59, 46, 46, 32, 32, 32, 32,
540 32, 32, 32, 61, 59, 59, 59, 59, 59, 59, 59, 45, 32, 32, 32, 32, 32, 32, 32,
541 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32,
542 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 32, 45, 61, 59, 59, 59, 59,
543 59, 58, 32, 46, 32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 59, 59, 59, 58, 45,
544 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
545 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
546 32, 32, 32, 32, 45, 45, 45, 45, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32,
547 32, 45, 61, 59, 58, 45, 45, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
548 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
549 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
550 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 32, 32, 46, 32, 32, 32, 32, 32, 32,
551 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 -0700552
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700553} // namespace aapt