blob: 06e4622d949a32702c4ecfea430bfa2f0ed269ce [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
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700121 private:
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700122 StdErrDiagnostics diagnostics_;
123 bool verbose_ = false;
Adam Lesinski59e04c62016-02-04 15:59:23 -0800124};
125
Adam Lesinski00451162017-10-03 07:44:08 -0700126} // namespace
127
Ryan Mitchell5d275512018-07-19 14:29:00 -0700128int DumpAPCCommand::Action(const std::vector<std::string>& args) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700129 DumpContext context;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700130 DebugPrintTableOptions print_options;
131 print_options.show_sources = true;
132 print_options.show_values = !no_values_;
133
134 if (args.size() < 1) {
Ryan Mitchell214846d2018-09-19 16:57:01 -0700135 diag_->Error(DiagMessage() << "No dump container specified");
Ryan Mitchell5d275512018-07-19 14:29:00 -0700136 return 1;
137 }
138
Ryan Mitchell214846d2018-09-19 16:57:01 -0700139 bool error = false;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700140 for (auto container : args) {
141 io::FileInputStream input(container);
142 if (input.HadError()) {
143 context.GetDiagnostics()->Error(DiagMessage(container)
Ryan Mitchell214846d2018-09-19 16:57:01 -0700144 << "failed to open file: " << input.GetError());
145 error = true;
146 continue;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700147 }
148
149 // Try as a compiled file.
150 ContainerReader reader(&input);
151 if (reader.HadError()) {
152 context.GetDiagnostics()->Error(DiagMessage(container)
Ryan Mitchell214846d2018-09-19 16:57:01 -0700153 << "failed to read container: " << reader.GetError());
154 error = true;
155 continue;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700156 }
157
Ryan Mitchell214846d2018-09-19 16:57:01 -0700158 printer_->Println("AAPT2 Container (APC)");
Ryan Mitchell5d275512018-07-19 14:29:00 -0700159 ContainerReaderEntry* entry;
160 std::string error;
161 while ((entry = reader.Next()) != nullptr) {
162 if (entry->Type() == ContainerEntryType::kResTable) {
Ryan Mitchell214846d2018-09-19 16:57:01 -0700163 printer_->Println("kResTable");
Ryan Mitchell5d275512018-07-19 14:29:00 -0700164
165 pb::ResourceTable pb_table;
166 if (!entry->GetResTable(&pb_table)) {
167 context.GetDiagnostics()->Error(DiagMessage(container)
Ryan Mitchell214846d2018-09-19 16:57:01 -0700168 << "failed to parse proto table: " << entry->GetError());
169 error = true;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700170 continue;
171 }
172
173 ResourceTable table;
174 error.clear();
175 if (!DeserializeTableFromPb(pb_table, nullptr /*files*/, &table, &error)) {
176 context.GetDiagnostics()->Error(DiagMessage(container)
Ryan Mitchell214846d2018-09-19 16:57:01 -0700177 << "failed to parse table: " << error);
178 error = true;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700179 continue;
180 }
181
Ryan Mitchell214846d2018-09-19 16:57:01 -0700182 printer_->Indent();
183 Debug::PrintTable(table, print_options, printer_);
184 printer_->Undent();
Ryan Mitchell5d275512018-07-19 14:29:00 -0700185 } else if (entry->Type() == ContainerEntryType::kResFile) {
Ryan Mitchell214846d2018-09-19 16:57:01 -0700186 printer_->Println("kResFile");
Ryan Mitchell5d275512018-07-19 14:29:00 -0700187 pb::internal::CompiledFile pb_compiled_file;
188 off64_t offset;
189 size_t length;
190 if (!entry->GetResFileOffsets(&pb_compiled_file, &offset, &length)) {
Ryan Mitchell214846d2018-09-19 16:57:01 -0700191 context.GetDiagnostics()->Error(DiagMessage(container)
192 << "failed to parse compiled proto file: "
193 << entry->GetError());
194 error = true;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700195 continue;
196 }
197
198 ResourceFile file;
199 if (!DeserializeCompiledFileFromPb(pb_compiled_file, &file, &error)) {
200 context.GetDiagnostics()->Warn(DiagMessage(container)
Ryan Mitchell214846d2018-09-19 16:57:01 -0700201 << "failed to parse compiled file: " << error);
202 error = true;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700203 continue;
204 }
205
Ryan Mitchell214846d2018-09-19 16:57:01 -0700206 printer_->Indent();
207 DumpCompiledFile(file, Source(container), offset, length, printer_);
208 printer_->Undent();
Ryan Mitchell5d275512018-07-19 14:29:00 -0700209 }
Pierre Lecesneaadf27e2017-05-05 14:58:21 +0100210 }
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700211 }
Ryan Mitchell5d275512018-07-19 14:29:00 -0700212
Ryan Mitchell214846d2018-09-19 16:57:01 -0700213 return (error) ? 1 : 0;
Adam Lesinski59e04c62016-02-04 15:59:23 -0800214}
215
Ryan Mitchell214846d2018-09-19 16:57:01 -0700216int DumpBadgerCommand::Action(const std::vector<std::string>& args) {
217 printer_->Print(StringPrintf("%s", kBadgerData));
218 printer_->Print("Did you mean \"aapt2 dump badging\"?\n");
219 return 1;
220}
Ryan Mitchell5d275512018-07-19 14:29:00 -0700221
Ryan Mitchell214846d2018-09-19 16:57:01 -0700222int DumpConfigsCommand::Dump(LoadedApk* apk) {
223 ResourceTable* table = apk->GetResourceTable();
Ryan Mitchellfc225b22018-08-21 14:52:51 -0700224 if (!table) {
Ryan Mitchell214846d2018-09-19 16:57:01 -0700225 GetDiagnostics()->Error(DiagMessage() << "Failed to retrieve resource table");
Ryan Mitchellfc225b22018-08-21 14:52:51 -0700226 return 1;
227 }
228
Ryan Mitchell5d275512018-07-19 14:29:00 -0700229 // Comparison function used to order configurations
MÃ¥rten Kongstad24c9aa62018-06-20 08:46:41 +0200230 auto compare = [](android::ConfigDescription c1, android::ConfigDescription c2) -> bool {
Ryan Mitchell214846d2018-09-19 16:57:01 -0700231 return c1.compare(c2) < 0;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700232 };
233
234 // Insert the configurations into a set in order to keep every configuarion seen
MÃ¥rten Kongstad24c9aa62018-06-20 08:46:41 +0200235 std::set<android::ConfigDescription, decltype(compare)> configs(compare);
Ryan Mitchellfc225b22018-08-21 14:52:51 -0700236 for (auto& package : table->packages) {
Ryan Mitchell5d275512018-07-19 14:29:00 -0700237 for (auto& type : package->types) {
238 for (auto& entry : type->entries) {
239 for (auto& value : entry->values) {
240 configs.insert(value->config);
241 }
242 }
243 }
244 }
245
246 // Print the configurations in order
247 for (auto& config : configs) {
Ryan Mitchell214846d2018-09-19 16:57:01 -0700248 GetPrinter()->Print(StringPrintf("%s\n", config.to_string().data()));
Ryan Mitchell5d275512018-07-19 14:29:00 -0700249 }
Ryan Mitchell5d275512018-07-19 14:29:00 -0700250 return 0;
251}
252
Ryan Mitchell214846d2018-09-19 16:57:01 -0700253int DumpPackageNameCommand::Dump(LoadedApk* apk) {
254 xml::Element* manifest_el = apk->GetManifest()->root.get();
255 if (!manifest_el) {
256 GetDiagnostics()->Error(DiagMessage() << "No AndroidManifest");
Ryan Mitchell5d275512018-07-19 14:29:00 -0700257 return 1;
258 }
259
Ryan Mitchell214846d2018-09-19 16:57:01 -0700260 xml::Attribute* attr = manifest_el->FindAttribute({}, "package");
261 if (!attr) {
262 GetDiagnostics()->Error(DiagMessage() << "No package name");
263 return 1;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700264 }
265
Ryan Mitchell214846d2018-09-19 16:57:01 -0700266 GetPrinter()->Println(StringPrintf("%s", attr->value.c_str()));
Ryan Mitchell5d275512018-07-19 14:29:00 -0700267 return 0;
268}
269
Ryan Mitchell214846d2018-09-19 16:57:01 -0700270int DumpStringsCommand::Dump(LoadedApk* apk) {
271 ResourceTable* table = apk->GetResourceTable();
272 if (!table) {
273 GetDiagnostics()->Error(DiagMessage() << "Failed to retrieve resource table");
Ryan Mitchell5d275512018-07-19 14:29:00 -0700274 return 1;
275 }
276
Ryan Mitchell214846d2018-09-19 16:57:01 -0700277 // Load the run-time xml string pool using the flattened data
278 BigBuffer buffer(4096);
279 StringPool::FlattenUtf8(&buffer, table->string_pool, GetDiagnostics());
280 auto data = buffer.to_string();
281 android::ResStringPool pool(data.data(), data.size(), false);
282 Debug::DumpResStringPool(&pool, GetPrinter());
283 return 0;
284}
285
286int DumpTableCommand::Dump(LoadedApk* apk) {
287 if (apk->GetApkFormat() == ApkFormat::kProto) {
288 GetPrinter()->Println("Proto APK");
289 } else {
290 GetPrinter()->Println("Binary APK");
291 }
292
293 ResourceTable* table = apk->GetResourceTable();
294 if (!table) {
295 GetDiagnostics()->Error(DiagMessage() << "Failed to retrieve resource table");
296 return 1;
297 }
Ryan Mitchell5d275512018-07-19 14:29:00 -0700298
299 DebugPrintTableOptions print_options;
300 print_options.show_sources = true;
301 print_options.show_values = !no_values_;
Ryan Mitchell214846d2018-09-19 16:57:01 -0700302 Debug::PrintTable(*table, print_options, GetPrinter());
Ryan Mitchell5d275512018-07-19 14:29:00 -0700303 return 0;
304}
305
Ryan Mitchell214846d2018-09-19 16:57:01 -0700306int DumpXmlStringsCommand::Dump(LoadedApk* apk) {
Ryan Mitchell5d275512018-07-19 14:29:00 -0700307 DumpContext context;
Ryan Mitchell214846d2018-09-19 16:57:01 -0700308 bool error = false;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700309 for (auto xml_file : files_) {
310 android::ResXMLTree tree;
311
Ryan Mitchell214846d2018-09-19 16:57:01 -0700312 if (apk->GetApkFormat() == ApkFormat::kProto) {
313 auto xml = apk->LoadXml(xml_file, GetDiagnostics());
Ryan Mitchell5d275512018-07-19 14:29:00 -0700314 if (!xml) {
Ryan Mitchell214846d2018-09-19 16:57:01 -0700315 error = true;
316 continue;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700317 }
318
319 // Flatten the xml document to get a binary representation of the proto xml file
320 BigBuffer buffer(4096);
321 XmlFlattenerOptions options = {};
322 options.keep_raw_values = true;
323 XmlFlattener flattener(&buffer, options);
324 if (!flattener.Consume(&context, xml.get())) {
Ryan Mitchell214846d2018-09-19 16:57:01 -0700325 error = true;
326 continue;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700327 }
328
329 // Load the run-time xml tree using the flattened data
330 std::string data = buffer.to_string();
331 tree.setTo(data.data(), data.size(), /** copyData */ true);
332
Ryan Mitchell214846d2018-09-19 16:57:01 -0700333 } else if (apk->GetApkFormat() == ApkFormat::kBinary) {
334 io::IFile* file = apk->GetFileCollection()->FindFile(xml_file);
Ryan Mitchell5d275512018-07-19 14:29:00 -0700335 if (!file) {
Ryan Mitchell214846d2018-09-19 16:57:01 -0700336 GetDiagnostics()->Error(DiagMessage(xml_file)
337 << "File '" << xml_file << "' not found in APK");
338 error = true;
339 continue;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700340 }
341
342 std::unique_ptr<io::IData> data = file->OpenAsData();
343 if (!data) {
Ryan Mitchell214846d2018-09-19 16:57:01 -0700344 GetDiagnostics()->Error(DiagMessage() << "Failed to open " << xml_file);
345 error = true;
346 continue;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700347 }
348
349 // Load the run-time xml tree from the file data
350 tree.setTo(data->data(), data->size(), /** copyData */ true);
Ryan Mitchell214846d2018-09-19 16:57:01 -0700351 } else {
352 GetDiagnostics()->Error(DiagMessage(apk->GetSource()) << "Unknown APK format");
353 error = true;
354 continue;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700355 }
356
Ryan Mitchell214846d2018-09-19 16:57:01 -0700357 Debug::DumpResStringPool(&tree.getStrings(), GetPrinter());
Ryan Mitchell5d275512018-07-19 14:29:00 -0700358 }
Ryan Mitchell214846d2018-09-19 16:57:01 -0700359 return (error) ? 1 : 0;
360}
Ryan Mitchell5d275512018-07-19 14:29:00 -0700361
Ryan Mitchell214846d2018-09-19 16:57:01 -0700362int DumpXmlTreeCommand::Dump(LoadedApk* apk) {
363 for (auto file : files_) {
364 auto xml = apk->LoadXml(file, GetDiagnostics());
365 if (!xml) {
366 return 1;
367 }
368 Debug::DumpXml(*xml, GetPrinter());
369 }
Ryan Mitchell5d275512018-07-19 14:29:00 -0700370 return 0;
371}
372
Ryan Mitchell214846d2018-09-19 16:57:01 -0700373const char DumpBadgerCommand::kBadgerData[2925] = {
374 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
375 32, 32, 32, 32, 32, 32, 95, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
376 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
377 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
378 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 63, 86, 35, 40, 46, 46,
379 95, 95, 95, 95, 97, 97, 44, 32, 46, 124, 42, 33, 83, 62, 32, 32, 32, 32, 32,
380 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32,
381 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
382 32, 32, 58, 46, 58, 59, 61, 59, 61, 81, 81, 81, 81, 66, 96, 61, 61, 58, 46,
383 46, 46, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
384 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
385 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 58, 106, 81, 81,
386 81, 81, 102, 59, 61, 59, 59, 61, 61, 61, 58, 46, 32, 32, 32, 32, 32, 32, 32,
387 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32,
388 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
389 61, 59, 59, 59, 58, 109, 81, 81, 81, 81, 61, 59, 59, 59, 59, 59, 58, 59, 59,
390 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
391 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
392 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 60, 81, 81, 81, 81, 87, 58,
393 59, 59, 59, 59, 59, 59, 61, 119, 44, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
394 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
395 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 47, 61, 59, 59,
396 58, 100, 81, 81, 81, 81, 35, 58, 59, 59, 59, 59, 59, 58, 121, 81, 91, 32, 32,
397 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32,
398 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
399 32, 32, 32, 46, 109, 58, 59, 59, 61, 81, 81, 81, 81, 81, 109, 58, 59, 59, 59,
400 59, 61, 109, 81, 81, 76, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
401 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
402 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 87, 59, 61, 59, 41, 81, 81,
403 81, 81, 81, 81, 59, 61, 59, 59, 58, 109, 81, 81, 87, 39, 46, 32, 32, 32, 32,
404 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32,
405 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
406 60, 81, 91, 59, 59, 61, 81, 81, 81, 81, 81, 87, 43, 59, 58, 59, 60, 81, 81,
407 81, 76, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
408 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
409 32, 32, 32, 32, 32, 32, 32, 32, 32, 52, 91, 58, 45, 59, 87, 81, 81, 81, 81,
410 70, 58, 58, 58, 59, 106, 81, 81, 81, 91, 32, 32, 32, 32, 32, 32, 32, 32, 32,
411 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32,
412 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 93, 40,
413 32, 46, 59, 100, 81, 81, 81, 81, 40, 58, 46, 46, 58, 100, 81, 81, 68, 32, 32,
414 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
415 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 46, 46, 32, 46,
416 46, 46, 32, 46, 32, 46, 45, 91, 59, 61, 58, 109, 81, 81, 81, 87, 46, 58, 61,
417 59, 60, 81, 81, 80, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
418 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 46, 46,
419 61, 59, 61, 61, 61, 59, 61, 61, 59, 59, 59, 58, 58, 46, 46, 41, 58, 59, 58,
420 81, 81, 81, 81, 69, 58, 59, 59, 60, 81, 81, 68, 32, 32, 32, 32, 32, 32, 32,
421 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32,
422 32, 32, 32, 32, 58, 59, 61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
423 59, 59, 61, 61, 46, 61, 59, 93, 81, 81, 81, 81, 107, 58, 59, 58, 109, 87, 68,
424 96, 32, 32, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
425 32, 32, 32, 32, 32, 10, 32, 32, 32, 46, 60, 61, 61, 59, 59, 59, 59, 59, 59,
426 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 58, 58, 58, 115, 109, 68, 41, 36,
427 81, 109, 46, 61, 61, 81, 69, 96, 46, 58, 58, 46, 58, 46, 46, 32, 32, 32, 32,
428 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 46, 32, 95, 81, 67,
429 61, 61, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
430 59, 59, 58, 68, 39, 61, 105, 61, 63, 81, 119, 58, 106, 80, 32, 58, 61, 59, 59,
431 61, 59, 61, 59, 61, 46, 95, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
432 32, 32, 10, 32, 32, 36, 81, 109, 105, 59, 61, 59, 59, 59, 59, 59, 59, 59, 59,
433 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 46, 58, 37, 73, 108, 108, 62, 52, 81,
434 109, 34, 32, 61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 59, 61, 61, 46, 46,
435 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 46, 45, 57, 101, 43, 43, 61,
436 61, 59, 59, 59, 59, 59, 59, 61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 58, 97,
437 46, 61, 108, 62, 126, 58, 106, 80, 96, 46, 61, 61, 59, 59, 59, 59, 59, 59, 59,
438 59, 59, 59, 59, 59, 59, 61, 61, 97, 103, 97, 32, 32, 32, 32, 32, 32, 32, 10,
439 32, 32, 32, 32, 45, 46, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 45,
440 58, 59, 59, 59, 59, 61, 119, 81, 97, 124, 105, 124, 124, 39, 126, 95, 119, 58, 61,
441 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 119, 81, 81,
442 99, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
443 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 58, 106, 81, 81, 81, 109, 119,
444 119, 119, 109, 109, 81, 81, 122, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
445 59, 59, 59, 58, 115, 81, 87, 81, 102, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32,
446 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 58,
447 59, 61, 81, 81, 81, 81, 81, 81, 87, 87, 81, 81, 81, 81, 81, 58, 59, 59, 59,
448 59, 59, 59, 59, 59, 58, 45, 45, 45, 59, 59, 59, 41, 87, 66, 33, 32, 32, 32,
449 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
450 32, 32, 32, 32, 32, 32, 58, 59, 59, 93, 81, 81, 81, 81, 81, 81, 81, 81, 81,
451 81, 81, 81, 81, 40, 58, 59, 59, 59, 58, 45, 32, 46, 32, 32, 32, 32, 32, 46,
452 32, 126, 96, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32,
453 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 59, 58, 81,
454 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 40, 58, 59, 59, 59, 58, 32,
455 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
456 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
457 32, 32, 32, 58, 59, 59, 58, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
458 81, 40, 58, 59, 59, 59, 46, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
459 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
460 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 59, 60, 81, 81, 81, 81,
461 81, 81, 81, 81, 81, 81, 81, 81, 81, 59, 61, 59, 59, 61, 32, 32, 32, 32, 32,
462 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32,
463 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
464 58, 59, 59, 93, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 40, 59,
465 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
466 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
467 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 58, 106, 81, 81, 81, 81, 81, 81, 81,
468 81, 81, 81, 81, 81, 81, 76, 58, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32,
469 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32,
470 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 58, 58,
471 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 87, 58, 59, 59, 59, 59,
472 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
473 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
474 32, 32, 32, 32, 32, 58, 59, 61, 41, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
475 81, 81, 87, 59, 61, 58, 59, 59, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
476 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32,
477 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 58, 61, 81, 81,
478 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 107, 58, 59, 59, 59, 59, 58, 32, 32,
479 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
480 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
481 32, 32, 58, 59, 59, 58, 51, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 102, 94,
482 59, 59, 59, 59, 59, 61, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
483 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
484 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58, 61, 59, 59, 59, 43, 63, 36, 81,
485 81, 81, 87, 64, 86, 102, 58, 59, 59, 59, 59, 59, 59, 59, 46, 32, 32, 32, 32,
486 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32,
487 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 61,
488 59, 59, 59, 59, 59, 59, 59, 43, 33, 58, 126, 126, 58, 59, 59, 59, 59, 59, 59,
489 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
490 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
491 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 58, 45, 58, 61, 59, 58, 58, 58, 61,
492 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 58, 32, 46, 32, 32, 32, 32,
493 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32,
494 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 59, 59,
495 58, 95, 32, 45, 61, 59, 61, 59, 59, 59, 59, 59, 59, 59, 45, 58, 59, 59, 59,
496 59, 61, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
497 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
498 32, 58, 61, 59, 59, 59, 59, 59, 61, 59, 61, 46, 46, 32, 45, 45, 45, 59, 58,
499 45, 45, 46, 58, 59, 59, 59, 59, 59, 59, 61, 46, 32, 32, 32, 32, 32, 32, 32,
500 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32,
501 32, 32, 32, 32, 32, 32, 32, 32, 46, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59,
502 61, 59, 46, 32, 32, 46, 32, 46, 32, 58, 61, 59, 59, 59, 59, 59, 59, 59, 59,
503 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10,
504 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45,
505 59, 59, 59, 59, 59, 59, 59, 59, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61,
506 59, 59, 59, 59, 59, 59, 59, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
507 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
508 32, 32, 32, 32, 32, 32, 32, 46, 61, 59, 59, 59, 59, 59, 59, 59, 32, 46, 32,
509 32, 32, 32, 32, 32, 61, 46, 61, 59, 59, 59, 59, 59, 59, 58, 32, 32, 32, 32,
510 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32,
511 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 61, 59, 59, 59,
512 59, 59, 59, 59, 59, 32, 46, 32, 32, 32, 32, 32, 32, 32, 46, 61, 58, 59, 59,
513 59, 59, 59, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
514 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
515 32, 32, 32, 32, 58, 59, 59, 59, 59, 59, 59, 59, 59, 46, 46, 32, 32, 32, 32,
516 32, 32, 32, 61, 59, 59, 59, 59, 59, 59, 59, 45, 32, 32, 32, 32, 32, 32, 32,
517 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32,
518 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 32, 45, 61, 59, 59, 59, 59,
519 59, 58, 32, 46, 32, 32, 32, 32, 32, 32, 32, 58, 59, 59, 59, 59, 59, 58, 45,
520 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
521 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
522 32, 32, 32, 32, 45, 45, 45, 45, 32, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32,
523 32, 45, 61, 59, 58, 45, 45, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
524 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
525 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
526 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 32, 32, 46, 32, 32, 32, 32, 32, 32,
527 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 -0700528
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700529} // namespace aapt