|
|
<!DOCTYPE html>
|
|
|
<html lang="en">
|
|
|
<head>
|
|
|
<meta charset="UTF-8"/>
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
|
|
<title>R8 Configuration Analyzer</title>
|
|
|
<style>/* ==========================================================================
|
|
|
1. VARIABLES & THEME CONFIGURATION
|
|
|
========================================================================== */
|
|
|
:root {
|
|
|
/* --- Colors: Backgrounds --- */
|
|
|
--bg-body: #f8fafc;
|
|
|
/* --- Colors: Borders --- */
|
|
|
--border-color: #e2e8f0;
|
|
|
/* --- Colors: Functional (Status) --- */
|
|
|
--text-green-600: oklch(37.1% 0 0);
|
|
|
/* --- Colors: Palette (Extended) --- */
|
|
|
--text-blue-600: #2563eb;
|
|
|
/* --- Colors: Text --- */
|
|
|
--text-main: #0f172a;
|
|
|
/* --- Shadows --- */
|
|
|
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
|
|
/* --- Typography --- */
|
|
|
--font-family-base: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
|
|
--bg-active: #e5e7eb;
|
|
|
--bg-card: #ffffff;
|
|
|
--bg-green-light: #dcfce7;
|
|
|
--bg-header: #ffffff;
|
|
|
--bg-hover: #f3f4f6;
|
|
|
--bg-red-light: #fee2e2;
|
|
|
--bg-selected: #eff6ff;
|
|
|
--bg-subtle: #f9fafb;
|
|
|
--bg-tooltip: #1f2937;
|
|
|
--bg-yellow-light: #fef9c3;
|
|
|
--border-interactive: #d1d5db;
|
|
|
--border-light: #f1f5f9;
|
|
|
--font-family-mono: "SF Mono", "Consolas", "Liberation Mono", Menlo, monospace;
|
|
|
--text-muted: #94a3b8;
|
|
|
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
|
|
|
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1);
|
|
|
--text-blue-700: #1d4ed8;
|
|
|
--text-gray-500: #6b7280;
|
|
|
--text-gray-900: #111827;
|
|
|
--text-inverse: #ffffff;
|
|
|
--text-link-hover: #1d4ed8;
|
|
|
--text-link: #2563eb;
|
|
|
--text-orange-600: #ea580c;
|
|
|
--text-red-600: #dc2626;
|
|
|
--text-subtle: #64748b;
|
|
|
--text-yellow-600: #ca8a04;
|
|
|
}
|
|
|
|
|
|
/* ==========================================================================
|
|
|
2. RESET & BASE STYLES
|
|
|
========================================================================== */
|
|
|
* {
|
|
|
box-sizing: border-box;
|
|
|
margin: 0;
|
|
|
padding: 0;
|
|
|
scrollbar-color: var(--border-color) transparent;
|
|
|
scrollbar-width: thin;
|
|
|
}
|
|
|
|
|
|
/* Custom Scrollbar */
|
|
|
::-webkit-scrollbar {
|
|
|
height: 8px;
|
|
|
width: 8px;
|
|
|
}
|
|
|
|
|
|
::-webkit-scrollbar-track {
|
|
|
background: transparent;
|
|
|
}
|
|
|
|
|
|
::-webkit-scrollbar-thumb {
|
|
|
background-color: #cbd5e1;
|
|
|
border-radius: 4px;
|
|
|
}
|
|
|
|
|
|
::-webkit-scrollbar-thumb:hover {
|
|
|
background-color: #94a3b8;
|
|
|
}
|
|
|
|
|
|
html,
|
|
|
body {
|
|
|
height: 100%;
|
|
|
overflow: hidden;
|
|
|
}
|
|
|
|
|
|
body {
|
|
|
background-color: var(--bg-body);
|
|
|
color: var(--text-main);
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
font-family: var(--font-family-base);
|
|
|
-webkit-font-smoothing: antialiased;
|
|
|
line-height: 1.5;
|
|
|
}
|
|
|
|
|
|
a {
|
|
|
color: inherit;
|
|
|
text-decoration: none;
|
|
|
}
|
|
|
|
|
|
input {
|
|
|
font-family: inherit;
|
|
|
outline: none;
|
|
|
}
|
|
|
|
|
|
button {
|
|
|
background: none;
|
|
|
border: none;
|
|
|
cursor: pointer;
|
|
|
font-family: inherit;
|
|
|
outline: none;
|
|
|
}
|
|
|
|
|
|
/* ==========================================================================
|
|
|
3. UTILITY CLASSES
|
|
|
========================================================================== */
|
|
|
.hidden {
|
|
|
display: none !important;
|
|
|
}
|
|
|
|
|
|
.flex {
|
|
|
display: flex;
|
|
|
}
|
|
|
|
|
|
.flex-col {
|
|
|
flex-direction: column;
|
|
|
}
|
|
|
|
|
|
.flex-1 {
|
|
|
flex: 1 1 0%;
|
|
|
}
|
|
|
|
|
|
.items-center {
|
|
|
align-items: center;
|
|
|
}
|
|
|
|
|
|
.justify-between {
|
|
|
justify-content: space-between;
|
|
|
}
|
|
|
|
|
|
.justify-center {
|
|
|
justify-content: center;
|
|
|
}
|
|
|
|
|
|
.relative {
|
|
|
position: relative;
|
|
|
}
|
|
|
|
|
|
.text-center {
|
|
|
text-align: center;
|
|
|
}
|
|
|
|
|
|
.text-left {
|
|
|
text-align: left;
|
|
|
}
|
|
|
|
|
|
.font-bold {
|
|
|
font-weight: 700;
|
|
|
}
|
|
|
|
|
|
.font-medium {
|
|
|
font-weight: 500;
|
|
|
}
|
|
|
|
|
|
.text-sm {
|
|
|
font-size: 0.875rem;
|
|
|
}
|
|
|
|
|
|
.text-xs {
|
|
|
font-size: 0.75rem;
|
|
|
}
|
|
|
|
|
|
.truncate {
|
|
|
overflow: hidden;
|
|
|
text-overflow: ellipsis;
|
|
|
white-space: nowrap;
|
|
|
}
|
|
|
|
|
|
.cursor-pointer {
|
|
|
cursor: pointer;
|
|
|
}
|
|
|
|
|
|
/* Colors */
|
|
|
.text-green-600 {
|
|
|
color: var(--text-green-600);
|
|
|
}
|
|
|
|
|
|
.text-yellow-600 {
|
|
|
color: var(--text-yellow-600);
|
|
|
}
|
|
|
|
|
|
.text-orange-600 {
|
|
|
color: var(--text-orange-600);
|
|
|
}
|
|
|
|
|
|
.text-red-600 {
|
|
|
color: var(--text-red-600);
|
|
|
}
|
|
|
|
|
|
.text-gray-500 {
|
|
|
color: var(--text-gray-500);
|
|
|
}
|
|
|
|
|
|
/* Backgrounds & Interaction */
|
|
|
.hover-bg-gray-100:hover {
|
|
|
background-color: var(--bg-hover) !important;
|
|
|
}
|
|
|
|
|
|
.bg-gray-200 {
|
|
|
background-color: var(--bg-active) !important;
|
|
|
color: var(--text-gray-900) !important;
|
|
|
font-weight: 500;
|
|
|
}
|
|
|
|
|
|
/* ==========================================================================
|
|
|
4. LAYOUT & CONTAINER
|
|
|
========================================================================== */
|
|
|
header {
|
|
|
background-color: var(--bg-header);
|
|
|
border-bottom: 1px solid var(--border-color);
|
|
|
box-shadow: var(--shadow-sm);
|
|
|
flex-shrink: 0;
|
|
|
z-index: 50;
|
|
|
}
|
|
|
|
|
|
.container-custom {
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
flex: 1;
|
|
|
margin: 0 auto;
|
|
|
max-width: 1800px;
|
|
|
min-height: 0;
|
|
|
overflow: visible;
|
|
|
padding: 1.5rem;
|
|
|
width: 100%;
|
|
|
}
|
|
|
|
|
|
main {
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
flex: 1;
|
|
|
min-height: 0;
|
|
|
overflow: visible;
|
|
|
}
|
|
|
|
|
|
/* ==========================================================================
|
|
|
5. HEADER COMPONENTS
|
|
|
========================================================================== */
|
|
|
.header-top-row {
|
|
|
align-items: center;
|
|
|
border-bottom: 1px solid var(--border-light);
|
|
|
display: flex;
|
|
|
justify-content: space-between;
|
|
|
margin: 0 auto;
|
|
|
max-width: 1800px;
|
|
|
padding: 0.5rem 1.5rem;
|
|
|
}
|
|
|
|
|
|
.header-branding {
|
|
|
/* border-right: 1px solid var(--border-color); */
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
padding-right: 1rem;
|
|
|
}
|
|
|
|
|
|
.header-branding .header-title {
|
|
|
color: var(--text-main);
|
|
|
font-size: 1.25rem;
|
|
|
font-weight: 700;
|
|
|
letter-spacing: -0.025em;
|
|
|
}
|
|
|
|
|
|
p#report-date {
|
|
|
font-size: 0.8125rem;
|
|
|
color: var(--text-subtle);
|
|
|
margin-top: 0.125rem;
|
|
|
}
|
|
|
|
|
|
#ts-all-state {
|
|
|
align-items: center;
|
|
|
display: flex;
|
|
|
gap: 0.2rem;
|
|
|
justify-content: center;
|
|
|
}
|
|
|
|
|
|
.header-stats {
|
|
|
display: flex;
|
|
|
gap: 2rem;
|
|
|
}
|
|
|
|
|
|
.stat-item {
|
|
|
align-items: flex-start;
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
}
|
|
|
|
|
|
.stat-label {
|
|
|
color: var(--text-muted);
|
|
|
font-size: 0.7rem;
|
|
|
font-weight: 500;
|
|
|
text-transform: uppercase;
|
|
|
}
|
|
|
|
|
|
.stat-value {
|
|
|
font-size: 0.95rem;
|
|
|
font-weight: 700;
|
|
|
}
|
|
|
|
|
|
.header-toolbar {
|
|
|
background-color: #ffffff;
|
|
|
}
|
|
|
|
|
|
.header-toolbar-inner {
|
|
|
align-items: center;
|
|
|
display: flex;
|
|
|
gap: 1rem;
|
|
|
height: 46px;
|
|
|
justify-content: space-between;
|
|
|
margin: 0 auto;
|
|
|
max-width: 1800px;
|
|
|
padding: 0 1.5rem;
|
|
|
width: 100%;
|
|
|
}
|
|
|
|
|
|
/* ==========================================================================
|
|
|
6. INTERACTIVE COMPONENTS (Buttons, Inputs, Chips)
|
|
|
========================================================================== */
|
|
|
/* Icon Buttons */
|
|
|
.icon-btn {
|
|
|
background: transparent;
|
|
|
border-radius: 0.375rem;
|
|
|
border: 1px solid transparent;
|
|
|
color: var(--text-subtle);
|
|
|
cursor: pointer;
|
|
|
display: flex;
|
|
|
height: 32px;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
transition: all 0.2s;
|
|
|
width: 32px;
|
|
|
color: var(--text-subtle);
|
|
|
}
|
|
|
|
|
|
button#group-by-btn:hover,
|
|
|
.icon-btn:hover,
|
|
|
.icon-btn.active {
|
|
|
background-color: var(--bg-hover) !important;
|
|
|
color: var(--text-main) !important;
|
|
|
}
|
|
|
|
|
|
/* Filter Chips */
|
|
|
.filter-chip {
|
|
|
/* blue-50 */
|
|
|
color: #1e40af;
|
|
|
/* blue-800 */
|
|
|
border: 1px solid #dbeafe;
|
|
|
/* blue-100 */
|
|
|
border-radius: 9999px;
|
|
|
align-items: center;
|
|
|
background-color: #eff6ff;
|
|
|
cursor: pointer;
|
|
|
display: inline-flex;
|
|
|
font-size: 0.8125rem;
|
|
|
font-weight: 500;
|
|
|
gap: 0.375rem;
|
|
|
padding: 0.25rem 0.5rem;
|
|
|
transition: all 0.2s;
|
|
|
white-space: nowrap;
|
|
|
}
|
|
|
|
|
|
.filter-chip:hover {
|
|
|
background-color: #dbeafe;
|
|
|
}
|
|
|
|
|
|
.filter-chip.active {
|
|
|
box-shadow: 0 0 0 2px #2563eb;
|
|
|
}
|
|
|
|
|
|
.chip-close {
|
|
|
border-radius: 9999px;
|
|
|
color: #2563eb;
|
|
|
display: inline-flex;
|
|
|
margin-left: 0.25rem;
|
|
|
margin-right: -0.25rem;
|
|
|
padding: 0.125rem;
|
|
|
transition: background-color 0.2s, color 0.2s;
|
|
|
}
|
|
|
|
|
|
.chip-close:hover {
|
|
|
background-color: #bfdbfe;
|
|
|
color: #1e40af;
|
|
|
}
|
|
|
|
|
|
.filter-icon {
|
|
|
align-items: center;
|
|
|
color: var(--text-gray-500);
|
|
|
display: flex;
|
|
|
justify-content: center;
|
|
|
}
|
|
|
|
|
|
/* Add Filter Button */
|
|
|
.add-filter-btn {
|
|
|
align-items: center;
|
|
|
background: transparent;
|
|
|
border-radius: 0.375rem;
|
|
|
border: 1px dashed var(--border-interactive);
|
|
|
color: var(--text-gray-500);
|
|
|
cursor: pointer;
|
|
|
display: flex;
|
|
|
font-size: 0.8125rem;
|
|
|
font-weight: 500;
|
|
|
gap: 0.25rem;
|
|
|
padding: 0.25rem 0.5rem;
|
|
|
transition: all 0.2s;
|
|
|
}
|
|
|
|
|
|
.add-filter-btn:hover {
|
|
|
background-color: var(--bg-hover);
|
|
|
border-color: var(--text-gray-500);
|
|
|
color: var(--text-gray-900);
|
|
|
}
|
|
|
|
|
|
/* Segmented Controls */
|
|
|
.segmented-control {
|
|
|
background-color: var(--bg-hover);
|
|
|
border-radius: 0.375rem;
|
|
|
display: flex;
|
|
|
padding: 2px;
|
|
|
}
|
|
|
|
|
|
.segment-btn {
|
|
|
align-items: center;
|
|
|
background-color: transparent;
|
|
|
border-radius: 0.25rem;
|
|
|
border: none;
|
|
|
color: var(--text-gray-500);
|
|
|
cursor: pointer;
|
|
|
display: flex;
|
|
|
font-size: 0.8125rem;
|
|
|
font-weight: 500;
|
|
|
height: 24px;
|
|
|
justify-content: center;
|
|
|
padding: 0 1rem;
|
|
|
transition: all 0.2s ease;
|
|
|
}
|
|
|
|
|
|
.segment-btn:hover:not(.active) {
|
|
|
color: var(--text-gray-900);
|
|
|
}
|
|
|
|
|
|
.segment-btn.active {
|
|
|
background-color: #ffffff;
|
|
|
box-shadow: var(--shadow-sm);
|
|
|
color: var(--text-link);
|
|
|
}
|
|
|
|
|
|
/* Search Bar */
|
|
|
.search-bar-container {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
width: 32px;
|
|
|
height: 32px;
|
|
|
border-radius: 0.375rem;
|
|
|
border: 1px solid transparent;
|
|
|
background: transparent;
|
|
|
color: var(--text-subtle);
|
|
|
transition: all 0.2s;
|
|
|
cursor: pointer;
|
|
|
}
|
|
|
|
|
|
.search-bar-container:hover {
|
|
|
background-color: var(--bg-hover);
|
|
|
color: var(--text-main);
|
|
|
}
|
|
|
|
|
|
.search-bar-container.active {
|
|
|
border-color: var(--border-interactive);
|
|
|
background-color: #ffffff;
|
|
|
padding: 0.25rem 0.5rem;
|
|
|
width: auto;
|
|
|
height: auto;
|
|
|
}
|
|
|
|
|
|
.search-bar-input {
|
|
|
border: none;
|
|
|
outline: none;
|
|
|
padding: 0;
|
|
|
font-size: 0.8125rem;
|
|
|
width: 0;
|
|
|
transition: width 0.2s, padding 0.2s;
|
|
|
background: transparent;
|
|
|
}
|
|
|
|
|
|
.search-bar-container.active .search-bar-input {
|
|
|
width: 150px;
|
|
|
padding: 0.25rem 0.5rem;
|
|
|
}
|
|
|
|
|
|
.search-bar-icon {
|
|
|
color: var(--text-gray-500);
|
|
|
width: 16px;
|
|
|
height: 16px;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
}
|
|
|
|
|
|
/* Dropdowns */
|
|
|
.dropdown-menu {
|
|
|
/* Changed from hidden to allow submenus */
|
|
|
animation: fadeIn 0.1s ease-out;
|
|
|
background: var(--bg-card);
|
|
|
border-radius: 0.5rem;
|
|
|
border: 1px solid var(--border-color);
|
|
|
box-shadow: var(--shadow-lg);
|
|
|
left: 0;
|
|
|
margin-top: 0.5rem;
|
|
|
min-width: 180px;
|
|
|
overflow: visible;
|
|
|
position: absolute;
|
|
|
top: 100%;
|
|
|
z-index: 100;
|
|
|
}
|
|
|
|
|
|
.dropdown-menu.right-0 {
|
|
|
left: auto;
|
|
|
right: 0;
|
|
|
}
|
|
|
|
|
|
.dropdown-menu:not(.hidden) {
|
|
|
display: block;
|
|
|
}
|
|
|
|
|
|
/* Ensure visibility toggling works */
|
|
|
.dropdown-item {
|
|
|
color: var(--text-gray-900);
|
|
|
cursor: pointer;
|
|
|
display: block;
|
|
|
font-size: 0.875rem;
|
|
|
padding: 0.5rem 1rem;
|
|
|
transition: background-color 0.15s;
|
|
|
}
|
|
|
|
|
|
.dropdown-item:hover {
|
|
|
background-color: var(--bg-hover);
|
|
|
}
|
|
|
|
|
|
/* Popover Content */
|
|
|
.popover-search-container {
|
|
|
background: var(--bg-card);
|
|
|
border-bottom: 1px solid var(--border-color);
|
|
|
padding: 0.5rem;
|
|
|
position: sticky;
|
|
|
top: 0;
|
|
|
z-index: 2;
|
|
|
}
|
|
|
|
|
|
.popover-search {
|
|
|
border-radius: 0.375rem;
|
|
|
border: 1px solid var(--border-interactive);
|
|
|
font-size: 0.8125rem;
|
|
|
padding: 0.375rem 0.5rem;
|
|
|
width: 100%;
|
|
|
}
|
|
|
|
|
|
.popover-search:focus {
|
|
|
border-color: var(--text-link);
|
|
|
}
|
|
|
|
|
|
.popover-list {
|
|
|
max-height: 250px;
|
|
|
overflow-y: auto;
|
|
|
padding: 0.25rem 0;
|
|
|
}
|
|
|
|
|
|
.popover-item {
|
|
|
align-items: center;
|
|
|
color: var(--text-gray-900);
|
|
|
cursor: pointer;
|
|
|
display: flex;
|
|
|
font-size: 0.875rem;
|
|
|
gap: 0.5rem;
|
|
|
padding: 0.375rem 1rem;
|
|
|
transition: background-color 0.15s;
|
|
|
}
|
|
|
|
|
|
.popover-item:hover {
|
|
|
background-color: var(--bg-hover);
|
|
|
}
|
|
|
|
|
|
.active-item {
|
|
|
background-color: var(--bg-selected);
|
|
|
color: var(--text-link);
|
|
|
font-weight: 600;
|
|
|
}
|
|
|
|
|
|
.popover-checkbox {
|
|
|
accent-color: var(--text-link);
|
|
|
height: 1rem;
|
|
|
margin-top: 1px;
|
|
|
width: 1rem;
|
|
|
}
|
|
|
|
|
|
/* Action-Based Dropdown Styles */
|
|
|
.dropdown-action-zone {
|
|
|
align-items: center;
|
|
|
background-color: var(--bg-subtle);
|
|
|
border-bottom: 1px solid var(--border-color);
|
|
|
display: flex;
|
|
|
justify-content: space-between;
|
|
|
padding: 0.5rem 1rem;
|
|
|
position: sticky;
|
|
|
top: 0;
|
|
|
z-index: 10;
|
|
|
}
|
|
|
|
|
|
.dropdown-action-btn {
|
|
|
background: none;
|
|
|
border: none;
|
|
|
color: var(--text-link);
|
|
|
cursor: pointer;
|
|
|
font-size: 0.8125rem;
|
|
|
font-weight: 600;
|
|
|
padding: 0;
|
|
|
}
|
|
|
|
|
|
.dropdown-action-btn:hover {
|
|
|
color: var(--text-link-hover);
|
|
|
text-decoration: underline;
|
|
|
}
|
|
|
|
|
|
.dropdown-scroll-zone {
|
|
|
max-height: 250px;
|
|
|
overflow-y: auto;
|
|
|
padding: 0.25rem 0;
|
|
|
}
|
|
|
|
|
|
/* ==========================================================================
|
|
|
7. BREADCRUMBS
|
|
|
========================================================================== */
|
|
|
.breadcrumb-row {
|
|
|
align-items: center;
|
|
|
display: flex;
|
|
|
height: 28px;
|
|
|
justify-content: space-between;
|
|
|
margin-bottom: 1rem;
|
|
|
}
|
|
|
|
|
|
.breadcrumb-pill {
|
|
|
border-radius: 0.375rem;
|
|
|
color: #4b5563;
|
|
|
cursor: pointer;
|
|
|
font-size: 0.875rem;
|
|
|
font-weight: 500;
|
|
|
padding: 0.25rem 0.5rem;
|
|
|
transition: all 0.2s;
|
|
|
}
|
|
|
|
|
|
.breadcrumb-pill:hover {
|
|
|
background-color: var(--bg-selected);
|
|
|
border-color: var(--text-link);
|
|
|
color: var(--text-link-hover);
|
|
|
}
|
|
|
|
|
|
.breadcrumb-text {
|
|
|
color: var(--text-gray-900);
|
|
|
font-size: 0.875rem;
|
|
|
font-weight: 600;
|
|
|
padding: 0.25rem 0.5rem;
|
|
|
}
|
|
|
|
|
|
div#flat-breadcrumbs .mx-1 {
|
|
|
opacity: .2;
|
|
|
}
|
|
|
|
|
|
/* ==========================================================================
|
|
|
8. TABLES & DATA GRID
|
|
|
========================================================================== */
|
|
|
.table-container {
|
|
|
background: var(--bg-card);
|
|
|
border-radius: 0.5rem;
|
|
|
border: 1px solid var(--border-color);
|
|
|
box-shadow: var(--shadow-sm);
|
|
|
flex: 1;
|
|
|
overflow-x: auto;
|
|
|
}
|
|
|
|
|
|
table {
|
|
|
border-collapse: collapse;
|
|
|
min-width: 800px;
|
|
|
text-align: left;
|
|
|
width: 100%;
|
|
|
}
|
|
|
|
|
|
thead {
|
|
|
background: #f8fafc;
|
|
|
position: sticky;
|
|
|
top: 0;
|
|
|
z-index: 20;
|
|
|
}
|
|
|
|
|
|
th {
|
|
|
border-bottom: 1px solid var(--border-color);
|
|
|
color: var(--text-subtle);
|
|
|
font-size: 0.75rem;
|
|
|
font-weight: 600;
|
|
|
letter-spacing: 0.05em;
|
|
|
padding: 0.75rem 1rem;
|
|
|
text-transform: uppercase;
|
|
|
white-space: nowrap;
|
|
|
}
|
|
|
|
|
|
td {
|
|
|
border-bottom: 1px solid var(--border-color);
|
|
|
color: var(--text-main);
|
|
|
font-size: 0.875rem;
|
|
|
padding: 0.75rem 1rem;
|
|
|
transition: padding 0.2s ease;
|
|
|
white-space: nowrap;
|
|
|
}
|
|
|
|
|
|
tr {
|
|
|
background: var(--bg-card);
|
|
|
transition: background 0.2s;
|
|
|
}
|
|
|
|
|
|
tbody tr:hover {
|
|
|
background-color: var(--bg-selected) !important;
|
|
|
}
|
|
|
|
|
|
/* Sticky Columns (Name) */
|
|
|
.sticky-name {
|
|
|
background: inherit;
|
|
|
border-right: 1px solid var(--border-color);
|
|
|
box-shadow: 2px 0 4px -2px rgba(0, 0, 0, 0.05);
|
|
|
left: 0;
|
|
|
max-width: 400px;
|
|
|
position: sticky;
|
|
|
white-space: normal;
|
|
|
width: 400px;
|
|
|
word-break: break-all;
|
|
|
z-index: 10;
|
|
|
}
|
|
|
|
|
|
thead th.sticky-name {
|
|
|
z-index: 30;
|
|
|
}
|
|
|
|
|
|
th.truncate,
|
|
|
td.truncate {
|
|
|
border-right: 1px solid var(--border-color);
|
|
|
max-width: 150px !important;
|
|
|
}
|
|
|
|
|
|
td.truncate span {
|
|
|
overflow: hidden;
|
|
|
text-overflow: ellipsis;
|
|
|
white-space: nowrap;
|
|
|
}
|
|
|
|
|
|
@keyframes fadeIn {
|
|
|
from {
|
|
|
opacity: 0;
|
|
|
transform: translateY(-4px);
|
|
|
}
|
|
|
|
|
|
to {
|
|
|
opacity: 1;
|
|
|
transform: translateY(0);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@keyframes blink-animation {
|
|
|
0% {
|
|
|
background-color: rgba(253, 224, 71, 0.5);
|
|
|
}
|
|
|
|
|
|
50% {
|
|
|
background-color: rgba(253, 224, 71, 0.1);
|
|
|
}
|
|
|
|
|
|
100% {
|
|
|
background-color: transparent;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* CSS Tooltip */
|
|
|
[data-tooltip] {
|
|
|
position: relative;
|
|
|
}
|
|
|
|
|
|
[data-tooltip]:hover::after {
|
|
|
animation: 0.15s ease-out;
|
|
|
background-color: var(--bg-tooltip);
|
|
|
border-radius: 0.25rem;
|
|
|
top: 150%;
|
|
|
box-shadow: var(--shadow-md);
|
|
|
color: var(--text-inverse);
|
|
|
content: attr(data-tooltip);
|
|
|
font-size: 0.75rem;
|
|
|
left: 50%;
|
|
|
padding: 0.25rem 0.5rem;
|
|
|
pointer-events: none;
|
|
|
position: absolute;
|
|
|
transform: translateX(-50%);
|
|
|
white-space: normal;
|
|
|
z-index: 1000;
|
|
|
width: 260px;
|
|
|
text-transform: none;
|
|
|
font-size: 12px;
|
|
|
font-weight: 300;
|
|
|
}
|
|
|
|
|
|
/* Impact Tags */
|
|
|
.impact-container {
|
|
|
display: flex;
|
|
|
flex-wrap: wrap;
|
|
|
gap: 0.5rem;
|
|
|
}
|
|
|
|
|
|
.impact-tag {
|
|
|
background-color: var(--bg-hover);
|
|
|
border-radius: 0.25rem;
|
|
|
border: 1px solid var(--border-color);
|
|
|
color: var(--text-gray-900);
|
|
|
font-size: 0.7rem;
|
|
|
font-weight: 600;
|
|
|
letter-spacing: 0.025em;
|
|
|
padding: 0.125rem 0.375rem;
|
|
|
text-transform: uppercase;
|
|
|
}
|
|
|
|
|
|
#report-view .breadcrumb-row {
|
|
|
margin-bottom: 1rem !important;
|
|
|
}
|
|
|
|
|
|
/* Floating Action Button */
|
|
|
.fab {
|
|
|
position: fixed;
|
|
|
bottom: 1.5rem;
|
|
|
right: 1.5rem;
|
|
|
padding: 0.5rem 1rem;
|
|
|
border-radius: 2rem;
|
|
|
background-color: #1a202c;
|
|
|
color: #ffffff;
|
|
|
display: none;
|
|
|
align-items: center;
|
|
|
gap: 0.5rem;
|
|
|
box-shadow: var(--shadow-lg);
|
|
|
cursor: pointer;
|
|
|
transition: transform 0.2s, background-color 0.2s;
|
|
|
z-index: 1000;
|
|
|
border: none;
|
|
|
font-size: 0.875rem;
|
|
|
font-weight: 600;
|
|
|
}
|
|
|
|
|
|
.fab:hover {
|
|
|
background-color: #2d3748;
|
|
|
transform: scale(1.05);
|
|
|
}
|
|
|
|
|
|
/* Side Panel */
|
|
|
.side-panel {
|
|
|
position: fixed;
|
|
|
top: 0;
|
|
|
right: 0;
|
|
|
width: 400px;
|
|
|
height: 100%;
|
|
|
background-color: #ffffff;
|
|
|
box-shadow: var(--shadow-lg);
|
|
|
z-index: 1001;
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
transition: transform 0.3s ease-in-out;
|
|
|
transform: translateX(100%);
|
|
|
border-left: 1px solid var(--border-color);
|
|
|
}
|
|
|
|
|
|
.side-panel.open {
|
|
|
transform: translateX(0);
|
|
|
}
|
|
|
|
|
|
.side-panel-header {
|
|
|
padding: 1rem 1.5rem;
|
|
|
border-bottom: 1px solid var(--border-color);
|
|
|
display: flex;
|
|
|
justify-content: space-between;
|
|
|
align-items: center;
|
|
|
}
|
|
|
|
|
|
.side-panel-header .header-left {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
gap: 0.5rem;
|
|
|
}
|
|
|
|
|
|
.side-panel-header h2 {
|
|
|
font-size: 1.5rem;
|
|
|
font-weight: 700;
|
|
|
color: #000000;
|
|
|
}
|
|
|
|
|
|
.side-panel-content {
|
|
|
padding: 1.5rem;
|
|
|
overflow-y: auto;
|
|
|
flex: 1;
|
|
|
}
|
|
|
|
|
|
.help-section {
|
|
|
margin-bottom: 1.5rem;
|
|
|
}
|
|
|
|
|
|
.help-section-title {
|
|
|
font-size: 0.75rem;
|
|
|
font-weight: 700;
|
|
|
color: #718096;
|
|
|
text-transform: uppercase;
|
|
|
letter-spacing: 0.05em;
|
|
|
margin-bottom: 0.75rem;
|
|
|
}
|
|
|
|
|
|
.help-section p {
|
|
|
font-size: 0.875rem;
|
|
|
color: #2d3748;
|
|
|
line-height: 1.6;
|
|
|
}
|
|
|
|
|
|
/* Legend Cards (Accordion) */
|
|
|
.legend-list {
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
gap: 0.5rem;
|
|
|
}
|
|
|
|
|
|
.legend-item {
|
|
|
background-color: #ffffff;
|
|
|
border: 1px solid #e2e8f0;
|
|
|
border-radius: 0.5rem;
|
|
|
cursor: pointer;
|
|
|
transition: background-color 0.2s, border-color 0.2s;
|
|
|
overflow: hidden;
|
|
|
}
|
|
|
|
|
|
.legend-item:hover {
|
|
|
background-color: #f8fafc;
|
|
|
border-color: #cbd5e1;
|
|
|
}
|
|
|
|
|
|
.legend-item-header {
|
|
|
display: flex;
|
|
|
justify-content: space-between;
|
|
|
align-items: center;
|
|
|
padding: 0.75rem 1rem;
|
|
|
}
|
|
|
|
|
|
.legend-item-title {
|
|
|
font-size: 0.875rem;
|
|
|
font-weight: 500;
|
|
|
color: #1a202c;
|
|
|
}
|
|
|
|
|
|
.legend-item-arrow {
|
|
|
color: #a0aec0;
|
|
|
transition: transform 0.2s;
|
|
|
}
|
|
|
|
|
|
.legend-item.open .legend-item-arrow {
|
|
|
transform: rotate(90deg);
|
|
|
}
|
|
|
|
|
|
.legend-item-content {
|
|
|
padding: 0 1rem 0.75rem 1rem;
|
|
|
font-size: 0.875rem;
|
|
|
color: #4a5568;
|
|
|
line-height: 1.5;
|
|
|
display: none;
|
|
|
}
|
|
|
|
|
|
.legend-item.open .legend-item-content {
|
|
|
display: block;
|
|
|
}
|
|
|
|
|
|
/* Documentation Links (Cards) */
|
|
|
.doc-list {
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
gap: 0.75rem;
|
|
|
}
|
|
|
|
|
|
.doc-card {
|
|
|
display: flex;
|
|
|
justify-content: space-between;
|
|
|
align-items: self-start;
|
|
|
padding: 0.75rem 1rem;
|
|
|
background-color: #ffffff;
|
|
|
border: 1px solid #e2e8f0;
|
|
|
border-radius: 0.5rem;
|
|
|
text-decoration: none;
|
|
|
transition: background-color 0.2s, border-color 0.2s;
|
|
|
}
|
|
|
|
|
|
.doc-card:hover {
|
|
|
background-color: #f8fafc;
|
|
|
border-color: #cbd5e1;
|
|
|
}
|
|
|
|
|
|
.doc-card-info {
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
gap: 0.25rem;
|
|
|
}
|
|
|
|
|
|
.doc-card-title {
|
|
|
font-size: 0.875rem;
|
|
|
font-weight: 500;
|
|
|
color: #2563eb;
|
|
|
}
|
|
|
|
|
|
.doc-card-domain {
|
|
|
font-size: 0.75rem;
|
|
|
color: #718096;
|
|
|
}
|
|
|
|
|
|
.doc-card-desc {
|
|
|
font-size: 0.75rem;
|
|
|
color: #4a5568;
|
|
|
}
|
|
|
|
|
|
.doc-card-icon {
|
|
|
color: #a0aec0;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Tooltip Icon */
|
|
|
.tooltip-icon {
|
|
|
display: inline-flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
width: 1rem;
|
|
|
height: 1rem;
|
|
|
color: #a0aec0;
|
|
|
cursor: pointer;
|
|
|
margin-left: 0.25rem;
|
|
|
vertical-align: middle;
|
|
|
border: 1px solid #a0aec0;
|
|
|
border-radius: 50%;
|
|
|
font-size: 0.75rem;
|
|
|
}
|
|
|
|
|
|
.tooltip-icon:hover {
|
|
|
color: #718096;
|
|
|
}
|
|
|
|
|
|
.divider {
|
|
|
border-top: 1px solid #e2e8f0;
|
|
|
margin: 1.5rem 0;
|
|
|
}</style>
|
|
|
<script src="https://cdn.jsdelivr.net/npm/protobufjs@7.2.4/dist/protobuf.min.js"></script>
|
|
|
</head>
|
|
|
<body>
|
|
|
<header>
|
|
|
<div class="header-top-row">
|
|
|
<div class="flex items-center" style="display: flex; align-items: center">
|
|
|
<div class="header-branding">
|
|
|
<h1 class="header-title" id="report-name"><a href="#" id="header-link" style="color: inherit; text-decoration: none;">R8 Configuration Analyzer</a></h1>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="header-stats">
|
|
|
<div class="stat-item">
|
|
|
<span class="stat-label">Shrinking</span><span class="stat-value" id="total-shrinking"></span>
|
|
|
</div>
|
|
|
<div class="stat-item">
|
|
|
<span class="stat-label">Optimization</span><span class="stat-value" id="total-optimization"></span>
|
|
|
</div>
|
|
|
<div class="stat-item">
|
|
|
<span class="stat-label">Obfuscation</span><span class="stat-value" id="total-obfuscation"></span>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="header-toolbar">
|
|
|
<div id="report-view-controls" class="header-toolbar-inner">
|
|
|
<div class="flex-1" style="display: flex; align-items: center; gap: 1rem; justify-content: flex-start">
|
|
|
<div class="filter-icon" title="Filter Options">
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="none" viewBox="0 0 24 24"
|
|
|
stroke="currentColor" stroke-width="2">
|
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M4 6h16M7 12h10M10 18h4" />
|
|
|
</svg>
|
|
|
</div>
|
|
|
<div id="filter-chips-container" style="display: flex; align-items: center; gap: 0.5rem">
|
|
|
<div class="segmented-control" id="lens-tabs">
|
|
|
<button class="segment-btn active" data-lens="All">All Rules</button>
|
|
|
<button class="segment-btn" data-lens="Identical">Identical</button>
|
|
|
<button class="segment-btn" data-lens="Subsumed">Subsumed</button>
|
|
|
<button class="segment-btn" data-lens="Unused">Unused</button>
|
|
|
</div>
|
|
|
<span class="tooltip-icon" id="lenses-tooltip-icon" style="cursor: pointer; margin-right: 0.5rem;"
|
|
|
data-tooltip="Filter rules to a specific opportunity.">?</span>
|
|
|
<div class="relative" id="add-filter-container">
|
|
|
<button id="add-filter-btn" class="add-filter-btn">
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 24 24"
|
|
|
stroke="currentColor" stroke-width="2">
|
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M12 4v16m8-8H4" />
|
|
|
</svg>
|
|
|
Add filter
|
|
|
</button>
|
|
|
<div id="add-filter-dropdown" class="dropdown-menu hidden" style="min-width: 10rem">
|
|
|
<div id="add-filter-list"></div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="relative hidden" id="cls-chip-container">
|
|
|
<button id="cls-filter-btn" class="filter-chip">
|
|
|
<span id="cls-filter-text">Classes: All</span>
|
|
|
</button>
|
|
|
<div id="cls-dropdown" class="dropdown-menu hidden"></div>
|
|
|
</div>
|
|
|
<div class="relative hidden" id="field-chip-container">
|
|
|
<button id="field-filter-btn" class="filter-chip">
|
|
|
<span id="field-filter-text">Fields: All</span>
|
|
|
</button>
|
|
|
<div id="field-dropdown" class="dropdown-menu hidden"></div>
|
|
|
</div>
|
|
|
<div class="relative hidden" id="method-chip-container">
|
|
|
<button id="method-filter-btn" class="filter-chip">
|
|
|
<span id="method-filter-text">Methods: All</span>
|
|
|
</button>
|
|
|
<div id="method-dropdown" class="dropdown-menu hidden"></div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="flex-1" style="display: flex; align-items: center; gap: 0.75rem; justify-content: flex-end">
|
|
|
<div id="search-container" class="search-bar-container relative">
|
|
|
<div class="search-bar-icon" id="search-icon-btn">
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="none" viewBox="0 0 24 24"
|
|
|
stroke="currentColor" stroke-width="2">
|
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z">
|
|
|
</path>
|
|
|
</svg>
|
|
|
</div>
|
|
|
<input type="text" id="search-input" class="search-bar-input" placeholder="Search report...">
|
|
|
<button id="clear-search-btn" class="hidden"
|
|
|
style="color: var(--text-gray-500); display: flex; align-items: center; justify-content: center;">
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="none" viewBox="0 0 24 24"
|
|
|
stroke="currentColor" stroke-width="2">
|
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z">
|
|
|
</path>
|
|
|
</svg>
|
|
|
</button>
|
|
|
</div>
|
|
|
<div class="relative" id="columns-toggle-container">
|
|
|
<button id="toggle-columns-btn" class="icon-btn" title="Toggle Columns">
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="none" viewBox="0 0 24 24"
|
|
|
stroke="currentColor" stroke-width="2">
|
|
|
<path stroke-linecap="round" stroke-linejoin="round"
|
|
|
d="M9 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h4m0-18h10a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H9m0-18v18"></path>
|
|
|
</svg>
|
|
|
</button>
|
|
|
<div id="columns-dropdown" class="dropdown-menu right-0 hidden" style="min-width: 150px">
|
|
|
<label class="popover-item"
|
|
|
style="display: flex; align-items: center; gap: 0.5rem; padding: 0.5rem 0.75rem; cursor: pointer;">
|
|
|
<input type="checkbox" class="popover-checkbox" id="toggle-blocked-by-rule-cb" checked>
|
|
|
<span style="font-size: 0.75rem; font-weight: 500; color: var(--text-main);">Blocked by Rule</span>
|
|
|
</label>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="relative" id="group-by-container">
|
|
|
<button id="group-by-btn" class="dropdown-btn"
|
|
|
style="border: none; background: #f8f8f8; padding: 0.5rem 0.75rem; display: flex; align-items: center; border-radius: 4px;">
|
|
|
<span style="font-weight: 500; color: var(--text-gray-400)">Group by:</span>
|
|
|
<span id="group-by-text" style="font-weight: 600; color: var(--text-gray-500); margin-left: 0.25rem">Keep
|
|
|
Rules</span>
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 24 24"
|
|
|
stroke="currentColor"
|
|
|
style="margin-left: 0.25rem; color: var(--text-gray-500); width: 16px; height: 16px;">
|
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
|
|
|
</svg>
|
|
|
</button>
|
|
|
<div id="group-by-dropdown" class="dropdown-menu right-0 hidden" style="min-width: 150px">
|
|
|
<div class="dropdown-item" data-value="modules">Keep Rules</div>
|
|
|
<div class="dropdown-item" data-value="packages">Keep Rule Files</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</header>
|
|
|
<div id="report-view" class="container-custom">
|
|
|
<main>
|
|
|
<div class="breadcrumb-row" style="margin-bottom: 2rem; height: auto;">
|
|
|
<div id="flat-breadcrumbs"></div>
|
|
|
</div>
|
|
|
<div id="stats-container" style="display: flex; gap: 1rem; padding: 0rem; margin-bottom: 1rem;">
|
|
|
<!-- Shrinking Card -->
|
|
|
<div class="stat-card"
|
|
|
style="background: #ffffff; padding: 1rem; border-radius: 0.5rem; border: 1px solid var(--border-color); flex: 1;">
|
|
|
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.5rem;">
|
|
|
<div style="color: var(--text-muted); font-size: 0.75rem; text-transform: uppercase; font-weight: 600; display: flex; align-items: center; gap: 0.25rem;">
|
|
|
Shrinking <span class="tooltip-icon" data-tooltip="Shrinking score tracks the percentage of unused code and resources that have been successfully removed from your application. When R8 performs shrinking, it reduces the overall size of your application by identifying and eliminating code and resources that are not actually being used, ensuring your final build is as lean as possible.">?</span></div>
|
|
|
<div id="card-total-shrinking" style="font-size: 1rem; font-weight: 700; color: var(--text-yellow-600);">
|
|
|
--</div>
|
|
|
</div>
|
|
|
<div style="display: flex; flex-direction: column; gap: 0.5rem;">
|
|
|
<!-- Classes -->
|
|
|
<div style="display: flex; align-items: center; justify-content: space-between; font-size: 0.75rem;">
|
|
|
<span style="color: var(--text-gray-500); width: 60px;">Classes</span>
|
|
|
<div style="flex: 1; height: 4px; background: var(--bg-hover); border-radius: 2px; margin: 0 1rem;">
|
|
|
<div id="card-shrinking-classes-bar"
|
|
|
style="height: 100%; background: var(--text-yellow-600); border-radius: 2px; width: 0%;"></div>
|
|
|
</div>
|
|
|
<span id="card-shrinking-classes-val" style="color: var(--text-gray-900); font-weight: 500;">--</span>
|
|
|
</div>
|
|
|
<!-- Fields -->
|
|
|
<div style="display: flex; align-items: center; justify-content: space-between; font-size: 0.75rem;">
|
|
|
<span style="color: var(--text-gray-500); width: 60px;">Fields</span>
|
|
|
<div style="flex: 1; height: 4px; background: var(--bg-hover); border-radius: 2px; margin: 0 1rem;">
|
|
|
<div id="card-shrinking-fields-bar"
|
|
|
style="height: 100%; background: var(--text-yellow-600); border-radius: 2px; width: 0%;"></div>
|
|
|
</div>
|
|
|
<span id="card-shrinking-fields-val" style="color: var(--text-gray-900); font-weight: 500;">--</span>
|
|
|
</div>
|
|
|
<!-- Methods -->
|
|
|
<div style="display: flex; align-items: center; justify-content: space-between; font-size: 0.75rem;">
|
|
|
<span style="color: var(--text-gray-500); width: 60px;">Methods</span>
|
|
|
<div style="flex: 1; height: 4px; background: var(--bg-hover); border-radius: 2px; margin: 0 1rem;">
|
|
|
<div id="card-shrinking-methods-bar"
|
|
|
style="height: 100%; background: var(--text-yellow-600); border-radius: 2px; width: 0%;"></div>
|
|
|
</div>
|
|
|
<span id="card-shrinking-methods-val" style="color: var(--text-gray-900); font-weight: 500;">--</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- Optimization Card -->
|
|
|
<div class="stat-card"
|
|
|
style="background: #ffffff; padding: 1rem; border-radius: 0.5rem; border: 1px solid var(--border-color); flex: 1;">
|
|
|
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.5rem;">
|
|
|
<div style="color: var(--text-muted); font-size: 0.75rem; text-transform: uppercase; font-weight: 600; display: flex; align-items: center; gap: 0.25rem;">
|
|
|
Optimization <span class="tooltip-icon" data-tooltip="Optimization score tracks the number of classes, fields and methods optimized by R8 through techniques such as method inlining, class merging to the total number of classes in the codebase. These optimizations improve the performance and size of the app.">?</span></div>
|
|
|
<div id="card-total-optimization" style="font-size: 1rem; font-weight: 700; color: var(--text-yellow-600);">
|
|
|
--</div>
|
|
|
</div>
|
|
|
<div style="display: flex; flex-direction: column; gap: 0.5rem;">
|
|
|
<!-- Classes -->
|
|
|
<div style="display: flex; align-items: center; justify-content: space-between; font-size: 0.75rem;">
|
|
|
<span style="color: var(--text-gray-500); width: 60px;">Classes</span>
|
|
|
<div style="flex: 1; height: 4px; background: var(--bg-hover); border-radius: 2px; margin: 0 1rem;">
|
|
|
<div id="card-optimization-classes-bar"
|
|
|
style="height: 100%; background: var(--text-yellow-600); border-radius: 2px; width: 0%;"></div>
|
|
|
</div>
|
|
|
<span id="card-optimization-classes-val" style="color: var(--text-gray-900); font-weight: 500;">--</span>
|
|
|
</div>
|
|
|
<!-- Fields -->
|
|
|
<div style="display: flex; align-items: center; justify-content: space-between; font-size: 0.75rem;">
|
|
|
<span style="color: var(--text-gray-500); width: 60px;">Fields</span>
|
|
|
<div style="flex: 1; height: 4px; background: var(--bg-hover); border-radius: 2px; margin: 0 1rem;">
|
|
|
<div id="card-optimization-fields-bar"
|
|
|
style="height: 100%; background: var(--text-yellow-600); border-radius: 2px; width: 0%;"></div>
|
|
|
</div>
|
|
|
<span id="card-optimization-fields-val" style="color: var(--text-gray-900); font-weight: 500;">--</span>
|
|
|
</div>
|
|
|
<!-- Methods -->
|
|
|
<div style="display: flex; align-items: center; justify-content: space-between; font-size: 0.75rem;">
|
|
|
<span style="color: var(--text-gray-500); width: 60px;">Methods</span>
|
|
|
<div style="flex: 1; height: 4px; background: var(--bg-hover); border-radius: 2px; margin: 0 1rem;">
|
|
|
<div id="card-optimization-methods-bar"
|
|
|
style="height: 100%; background: var(--text-yellow-600); border-radius: 2px; width: 0%;"></div>
|
|
|
</div>
|
|
|
<span id="card-optimization-methods-val" style="color: var(--text-gray-900); font-weight: 500;">--</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- Obfuscation Card -->
|
|
|
<div class="stat-card"
|
|
|
style="background: #ffffff; padding: 1rem; border-radius: 0.5rem; border: 1px solid var(--border-color); flex: 1;">
|
|
|
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.5rem;">
|
|
|
<div style="color: var(--text-muted); font-size: 0.75rem; text-transform: uppercase; font-weight: 600; display: flex; align-items: center; gap: 0.25rem;">
|
|
|
Obfuscation <span class="tooltip-icon" data-tooltip="Obfuscation Score measures the percentage of symbols renamed within your codebase. By tracking this score, you can gauge the effectiveness of R8's obfuscation, which is crucial for reducing your application's metadata footprint to save memory">?</span></div>
|
|
|
<div id="card-total-obfuscation" style="font-size: 1rem; font-weight: 700; color: var(--text-yellow-600);">
|
|
|
--</div>
|
|
|
</div>
|
|
|
<div style="display: flex; flex-direction: column; gap: 0.5rem;">
|
|
|
<!-- Classes -->
|
|
|
<div style="display: flex; align-items: center; justify-content: space-between; font-size: 0.75rem;">
|
|
|
<span style="color: var(--text-gray-500); width: 60px;">Classes</span>
|
|
|
<div style="flex: 1; height: 4px; background: var(--bg-hover); border-radius: 2px; margin: 0 1rem;">
|
|
|
<div id="card-obfuscation-classes-bar"
|
|
|
style="height: 100%; background: var(--text-yellow-600); border-radius: 2px; width: 0%;"></div>
|
|
|
</div>
|
|
|
<span id="card-obfuscation-classes-val" style="color: var(--text-gray-900); font-weight: 500;">--</span>
|
|
|
</div>
|
|
|
<!-- Fields -->
|
|
|
<div style="display: flex; align-items: center; justify-content: space-between; font-size: 0.75rem;">
|
|
|
<span style="color: var(--text-gray-500); width: 60px;">Fields</span>
|
|
|
<div style="flex: 1; height: 4px; background: var(--bg-hover); border-radius: 2px; margin: 0 1rem;">
|
|
|
<div id="card-obfuscation-fields-bar"
|
|
|
style="height: 100%; background: var(--text-yellow-600); border-radius: 2px; width: 0%;"></div>
|
|
|
</div>
|
|
|
<span id="card-obfuscation-fields-val" style="color: var(--text-gray-900); font-weight: 500;">--</span>
|
|
|
</div>
|
|
|
<!-- Methods -->
|
|
|
<div style="display: flex; align-items: center; justify-content: space-between; font-size: 0.75rem;">
|
|
|
<span style="color: var(--text-gray-500); width: 60px;">Methods</span>
|
|
|
<div style="flex: 1; height: 4px; background: var(--bg-hover); border-radius: 2px; margin: 0 1rem;">
|
|
|
<div id="card-obfuscation-methods-bar"
|
|
|
style="height: 100%; background: var(--text-yellow-600); border-radius: 2px; width: 0%;"></div>
|
|
|
</div>
|
|
|
<span id="card-obfuscation-methods-val" style="color: var(--text-gray-900); font-weight: 500;">--</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="breadcrumb-row"
|
|
|
style="display: flex; flex-direction: column; align-items: start; margin-bottom: 1.5rem; gap: 0.25rem; height: auto;">
|
|
|
<span class="breadcrumb-text" style="font-size: 0.875rem; font-weight: 600; color: var(--text-gray-900);">Keep Rule Analysis</span>
|
|
|
<div style="font-size: 0.75rem; color: var(--text-gray-500); font-weight: 400; text-transform: none; letter-spacing: normal; line-height: 1.4; padding: 0rem 0.5rem;">
|
|
|
Keep rules prevent R8 from optimizing designated code segments. Review the list below to identify and refine overly broad rules, which will directly improve overall application performance.
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="table-container">
|
|
|
<table id="main-table">
|
|
|
<thead id="table-headers"></thead>
|
|
|
<tbody id="table-data"></tbody>
|
|
|
</table>
|
|
|
</div>
|
|
|
</main>
|
|
|
</div>
|
|
|
<div id="details-view" class="container-custom" style="display: none">
|
|
|
<main>
|
|
|
<div class="breadcrumb-row" style="margin-bottom: 2rem; height: auto;">
|
|
|
<div id="details-breadcrumbs"></div>
|
|
|
</div>
|
|
|
<div
|
|
|
style="flex: 1; display: flex; flex-direction: column; gap: 1.5rem; min-height: 0; overflow-y: auto; padding-right: 0.5rem;">
|
|
|
<div class="table-container" style="flex: none;">
|
|
|
<div
|
|
|
style="padding: 0.75rem 1rem; border-bottom: 1px solid var(--border-color); background-color: var(--bg-subtle); display: flex; justify-content: space-between; align-items: center;">
|
|
|
<h2 style="font-size: 0.875rem; font-weight: 500; color: var(--text-gray-900);">Keep Rule</h2>
|
|
|
</div>
|
|
|
<div id="details-rule-container" style="padding: 1rem;">
|
|
|
<!-- Content rendered by JS -->
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="table-container" style="flex: none;">
|
|
|
<div
|
|
|
style="padding: 0.75rem 1rem; border-bottom: 1px solid var(--border-color); background-color: var(--bg-subtle); display: flex; justify-content: space-between; align-items: center;">
|
|
|
<h2 style="font-size: 0.875rem; font-weight: 500; color: var(--text-gray-900);">Impact</h2>
|
|
|
</div>
|
|
|
<div id="details-impact-container" style="padding: 1rem;">
|
|
|
<!-- Content rendered by JS -->
|
|
|
</div>
|
|
|
</div>
|
|
|
<div id="related-rules-container" style="flex: none;">
|
|
|
<!-- Content rendered by JS -->
|
|
|
</div>
|
|
|
<div
|
|
|
style="flex: 1; display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 1.5rem; min-height: 400px; overflow: hidden;">
|
|
|
<div class="table-container" style="display: flex; flex-direction: column;">
|
|
|
<div
|
|
|
style="padding: 0.75rem 1rem; border-bottom: 1px solid var(--border-color); background-color: var(--bg-subtle); display: flex; flex-direction: column; gap: 0.5rem;">
|
|
|
<div style="display: flex; justify-content: space-between; align-items: center; width: 100%;">
|
|
|
<div>
|
|
|
<span style="font-size: 0.875rem; font-weight: 600; color: var(--text-gray-900);">Kept Classes</span>
|
|
|
<span style="color: var(--text-gray-500); font-size: 0.75rem; margin-left: 0.25rem;"
|
|
|
id="details-classes-count">· 0</span>
|
|
|
</div>
|
|
|
<button class="icon-btn search-toggle-btn" data-target="classes" style="color: var(--text-muted); padding: 2px;">
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
|
|
|
</svg>
|
|
|
</button>
|
|
|
</div>
|
|
|
<div id="classes-search-container" style="display: none; width: 100%;">
|
|
|
<input type="text" id="classes-search-input" placeholder="Search kept classes..."
|
|
|
style="width: 100%; padding: 0.25rem 0.5rem; border: 1px solid var(--border-color); border-radius: 4px; font-size: 0.75rem; outline: none; background-color: var(--bg-body); color: var(--text-main);">
|
|
|
</div>
|
|
|
</div>
|
|
|
<div id="details-classes-content" style="flex: 1; overflow-y: auto; padding: 0.5rem;"></div>
|
|
|
</div>
|
|
|
<div class="table-container" style="display: flex; flex-direction: column;">
|
|
|
<div
|
|
|
style="padding: 0.75rem 1rem; border-bottom: 1px solid var(--border-color); background-color: var(--bg-subtle); display: flex; flex-direction: column; gap: 0.5rem;">
|
|
|
<div style="display: flex; justify-content: space-between; align-items: center; width: 100%;">
|
|
|
<div>
|
|
|
<span style="font-size: 0.875rem; font-weight: 600; color: var(--text-gray-900);">Kept Fields</span>
|
|
|
<span style="color: var(--text-gray-500); font-size: 0.75rem; margin-left: 0.25rem;"
|
|
|
id="details-fields-count">· 0</span>
|
|
|
</div>
|
|
|
<button class="icon-btn search-toggle-btn" data-target="fields" style="color: var(--text-muted); padding: 2px;">
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
|
|
|
</svg>
|
|
|
</button>
|
|
|
</div>
|
|
|
<div id="fields-search-container" style="display: none; width: 100%;">
|
|
|
<input type="text" id="fields-search-input" placeholder="Search kept fields..."
|
|
|
style="width: 100%; padding: 0.25rem 0.5rem; border: 1px solid var(--border-color); border-radius: 4px; font-size: 0.75rem; outline: none; background-color: var(--bg-body); color: var(--text-main);">
|
|
|
</div>
|
|
|
</div>
|
|
|
<div id="details-fields-content" style="flex: 1; overflow-y: auto; padding: 0.5rem;"></div>
|
|
|
</div>
|
|
|
<div class="table-container" style="display: flex; flex-direction: column;">
|
|
|
<div
|
|
|
style="padding: 0.75rem 1rem; border-bottom: 1px solid var(--border-color); background-color: var(--bg-subtle); display: flex; flex-direction: column; gap: 0.5rem;">
|
|
|
<div style="display: flex; justify-content: space-between; align-items: center; width: 100%;">
|
|
|
<div>
|
|
|
<span style="font-size: 0.875rem; font-weight: 600; color: var(--text-gray-900);">Kept Methods</span>
|
|
|
<span style="color: var(--text-gray-500); font-size: 0.75rem; margin-left: 0.25rem;"
|
|
|
id="details-methods-count">· 0</span>
|
|
|
</div>
|
|
|
<button class="icon-btn search-toggle-btn" data-target="methods" style="color: var(--text-muted); padding: 2px;">
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
|
|
|
</svg>
|
|
|
</button>
|
|
|
</div>
|
|
|
<div id="methods-search-container" style="display: none; width: 100%;">
|
|
|
<input type="text" id="methods-search-input" placeholder="Search kept methods..."
|
|
|
style="width: 100%; padding: 0.25rem 0.5rem; border: 1px solid var(--border-color); border-radius: 4px; font-size: 0.75rem; outline: none; background-color: var(--bg-body); color: var(--text-main);">
|
|
|
</div>
|
|
|
</div>
|
|
|
<div id="details-methods-content" style="flex: 1; overflow-y: auto; padding: 0.5rem;"></div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</main>
|
|
|
</div>
|
|
|
<div id="file-details-view" class="container-custom" style="display: none">
|
|
|
<main>
|
|
|
<div class="breadcrumb-row" style="margin-bottom: 2rem; height: auto;">
|
|
|
<div id="file-details-breadcrumbs"></div>
|
|
|
</div>
|
|
|
<div
|
|
|
style="flex: 1; display: flex; flex-direction: column; gap: 1.5rem; min-height: 0; overflow-y: auto; padding-right: 0.5rem;">
|
|
|
<div class="table-container" style="flex: none;">
|
|
|
<div
|
|
|
style="padding: 1rem; border-bottom: 1px solid var(--border-color); background-color: var(--bg-gray-50);">
|
|
|
<h2 style="font-size: 1rem; font-weight: 700;">Impact</h2>
|
|
|
</div>
|
|
|
<table style="width: 100%; border-collapse: collapse;">
|
|
|
<thead>
|
|
|
<tr>
|
|
|
<th class="text-center text-xs font-medium text-gray-500 border-b border-gray-200"
|
|
|
style="padding: 0.75rem 0.5rem; text-transform: uppercase;">
|
|
|
Kept Classes
|
|
|
</th>
|
|
|
<th class="text-center text-xs font-medium text-gray-500 border-l border-b border-gray-200"
|
|
|
style="padding: 0.75rem 0.5rem; text-transform: uppercase;">
|
|
|
Kept fields
|
|
|
</th>
|
|
|
<th class="text-center text-xs font-medium text-gray-500 border-l border-b border-gray-200"
|
|
|
style="padding: 0.75rem 0.5rem; text-transform: uppercase;">
|
|
|
Kept methods
|
|
|
</th>
|
|
|
</tr>
|
|
|
</thead>
|
|
|
<tbody id="file-details-impact-body"></tbody>
|
|
|
</table>
|
|
|
</div>
|
|
|
<div class="table-container" style="flex: 1; display: flex; flex-direction: column;">
|
|
|
<div
|
|
|
style="padding: 1rem; border-bottom: 1px solid var(--border-color); background-color: var(--bg-gray-50);">
|
|
|
<h2 style="font-size: 1rem; font-weight: 700;">Keep Rules</h2>
|
|
|
</div>
|
|
|
<div style="flex: 1; overflow-y: auto;">
|
|
|
<table style="width: 100%; border-collapse: collapse;">
|
|
|
<thead id="file-details-rules-header">
|
|
|
<tr>
|
|
|
<th rowspan="2" class="text-left bg-gray-50 z-30"
|
|
|
style="padding: 1rem; width: 600px; min-width: 600px; border-bottom: 1px solid var(--border-color);">
|
|
|
Rule
|
|
|
</th>
|
|
|
<th colspan="4" class="text-center border-l border-gray-200 bg-gray-50"
|
|
|
style="padding: 0.5rem; border-bottom: 1px solid var(--border-color);">
|
|
|
Kept Items <span style="color: var(--text-muted);text-transform: none;font-weight: 500;">Higher is
|
|
|
worse</span>
|
|
|
</th>
|
|
|
<th rowspan="2" colspan="3" class="text-center border-l border-gray-200 bg-gray-50"
|
|
|
style="padding: 0.5rem; width: 150px; min-width: 150px; border-bottom: 1px solid var(--border-color);">
|
|
|
Steps blocked by rule
|
|
|
</th>
|
|
|
</tr>
|
|
|
<tr>
|
|
|
<th class="text-center text-xs font-medium text-gray-500 border-l border-gray-200"
|
|
|
style="padding: 0.5rem; width: 100px; min-width: 100px; border-bottom: 1px solid var(--border-color);">
|
|
|
Total
|
|
|
</th>
|
|
|
<th class="text-center text-xs font-medium text-gray-500 border-l border-gray-200"
|
|
|
style="padding: 0.5rem; width: 100px; min-width: 100px; border-bottom: 1px solid var(--border-color);">
|
|
|
Classes
|
|
|
</th>
|
|
|
<th class="text-center text-xs font-medium text-gray-500 border-l border-gray-200"
|
|
|
style="padding: 0.5rem; width: 100px; min-width: 100px; border-bottom: 1px solid var(--border-color);">
|
|
|
Fields
|
|
|
</th>
|
|
|
<th class="text-center text-xs font-medium text-gray-500 border-l border-gray-200"
|
|
|
style="padding: 0.5rem; width: 100px; min-width: 100px; border-bottom: 1px solid var(--border-color);">
|
|
|
Methods
|
|
|
</th>
|
|
|
</tr>
|
|
|
</thead>
|
|
|
<tbody id="file-details-rules-body"></tbody>
|
|
|
</table>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</main>
|
|
|
</div>
|
|
|
|
|
|
<script id="keepradius-proto" type="text/plain">// Copyright (c) 2026, the R8 project authors. Please see the AUTHORS file
|
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
syntax = "proto3";
|
|
|
|
|
|
package com.android.tools.r8.keepradius.proto;
|
|
|
|
|
|
// Don't put all messages under the outer class.
|
|
|
option java_multiple_files = true;
|
|
|
|
|
|
// Camel-case the outer class name.
|
|
|
option java_outer_classname = "KeepRadiusProtos";
|
|
|
|
|
|
// Java package consistent with R8 convention.
|
|
|
option java_package = "com.android.tools.r8.keepradius.proto";
|
|
|
|
|
|
// Information about a single keep rule and its immediate keep radius.
|
|
|
message KeepRuleKeepRadius {
|
|
|
int32 id = 1;
|
|
|
// Textual representation of the keep rule.
|
|
|
string source = 2;
|
|
|
// What this keep rule prohibits (e.g., optimization).
|
|
|
// Id into KeepConstraints.
|
|
|
int32 constraints_id = 3;
|
|
|
// Where this rule comes from.
|
|
|
TextFileOrigin origin = 4;
|
|
|
// Keep radius information.
|
|
|
KeepRadius keep_radius = 5;
|
|
|
// Keep rule tags.
|
|
|
repeated KeepRuleTag tags = 6;
|
|
|
}
|
|
|
|
|
|
enum KeepRuleTag {
|
|
|
PACKAGE_WIDE = 0;
|
|
|
}
|
|
|
|
|
|
message KeepRadius {
|
|
|
// Which rules subsume this rule. Note: This information could in principle
|
|
|
// be computed offline using the kept_by info of Kept*Info.
|
|
|
// Ids into KeepAnnotationKeepRadius and KeepRuleKeepRadius.
|
|
|
repeated int32 subsumed_by = 1;
|
|
|
// The immediate keep radius of this rule.
|
|
|
// - Ids into KeptClassInfo.
|
|
|
repeated int32 class_keep_radius = 2;
|
|
|
// - Ids into KeptFieldInfo.
|
|
|
repeated int32 field_keep_radius = 3;
|
|
|
// - Ids into KeptMethodInfo.
|
|
|
repeated int32 method_keep_radius = 4;
|
|
|
}
|
|
|
|
|
|
// The ids of GlobalKeepRuleKeepRadius and KeepRuleKeepRadius are
|
|
|
// non-overlapping by design, so that a single int32 id can be used to
|
|
|
// unambiguously reference a GlobalKeepRuleKeepRadius or KeepRuleKeepRadius.
|
|
|
message GlobalKeepRuleKeepRadius {
|
|
|
int32 id = 1;
|
|
|
// Textual representation of the keep rule.
|
|
|
string source = 2;
|
|
|
// Where this rule comes from.
|
|
|
TextFileOrigin origin = 3;
|
|
|
}
|
|
|
|
|
|
// Information about the constraints of a single keep annotation or rule,
|
|
|
// i.e., what is prohibited by it.
|
|
|
//
|
|
|
// This is encoded as a message to support keep constraints that cannot be
|
|
|
// encoded as a bit in the future.
|
|
|
message KeepConstraints {
|
|
|
int32 id = 1;
|
|
|
repeated KeepConstraint constraints = 2;
|
|
|
}
|
|
|
|
|
|
enum KeepConstraint {
|
|
|
DONT_OBFUSCATE = 0;
|
|
|
DONT_OPTIMIZE = 1;
|
|
|
DONT_SHRINK = 2;
|
|
|
}
|
|
|
|
|
|
// Information about a class in the app/library and which keep rules that
|
|
|
// keep it.
|
|
|
message KeptClassInfo {
|
|
|
int32 id = 1;
|
|
|
// Id into TypeReference.
|
|
|
int32 class_reference_id = 2;
|
|
|
// Id into FileOrigin or ClassFileInJarOrigin.
|
|
|
int32 file_origin_id = 3;
|
|
|
// Ids into KeepRuleKeepRadius, telling which rules keep this class.
|
|
|
// Allows reasoning about properties such as:
|
|
|
// - Which keep rules are fully subsumed by other keep rules?
|
|
|
// - Which keep rules keep the most classes/fields/methods
|
|
|
// not kept by rules?
|
|
|
repeated int32 kept_by = 4;
|
|
|
}
|
|
|
|
|
|
message KeptFieldInfo {
|
|
|
int32 id = 1;
|
|
|
// Id into FieldReference.
|
|
|
int32 field_reference_id = 2;
|
|
|
// Id into FileOrigin or ClassFileInJarOrigin.
|
|
|
int32 file_origin_id = 3;
|
|
|
// Ids into KeepRuleKeepRadius, telling which rules keep this field.
|
|
|
repeated int32 kept_by = 4;
|
|
|
}
|
|
|
|
|
|
message KeptMethodInfo {
|
|
|
int32 id = 1;
|
|
|
// Id into MethodReference.
|
|
|
int32 method_reference_id = 2;
|
|
|
// Id into FileOrigin or ClassFileInJarOrigin.
|
|
|
int32 file_origin_id = 3;
|
|
|
// Ids into KeepRuleKeepRadius, telling which rules keep this method.
|
|
|
repeated int32 kept_by = 4;
|
|
|
}
|
|
|
|
|
|
// References:
|
|
|
|
|
|
message FieldReference {
|
|
|
int32 id = 1;
|
|
|
// The class on which the field is declared.
|
|
|
// Id into TypeReference.
|
|
|
int32 class_reference_id = 2;
|
|
|
// The type of the field.
|
|
|
// Id into type reference.
|
|
|
int32 type_reference_id = 3;
|
|
|
// The name of the field.
|
|
|
string name = 4;
|
|
|
}
|
|
|
|
|
|
message MethodReference {
|
|
|
int32 id = 1;
|
|
|
// The class on which the method is declared.
|
|
|
// Id into TypeReference.
|
|
|
int32 class_reference_id = 2;
|
|
|
// The proto (return type, parameter types) of the method.
|
|
|
// Id into ProtoReference.
|
|
|
int32 proto_reference_id = 3;
|
|
|
// The name of the method.
|
|
|
string name = 4;
|
|
|
}
|
|
|
|
|
|
message ProtoReference {
|
|
|
int32 id = 1;
|
|
|
// Id into TypeReferenceList.
|
|
|
int32 parameters_id = 2;
|
|
|
// Id into TypeReference.
|
|
|
int32 return_type_id = 3;
|
|
|
}
|
|
|
|
|
|
message TypeReference {
|
|
|
int32 id = 1;
|
|
|
// The descriptor, e.g.,
|
|
|
// - Z
|
|
|
// - Ljava/lang/Object;
|
|
|
// - [[Ljava/lang/Object;
|
|
|
string java_descriptor = 2;
|
|
|
}
|
|
|
|
|
|
message TypeReferenceList {
|
|
|
int32 id = 1;
|
|
|
repeated int32 type_reference_ids = 2;
|
|
|
}
|
|
|
|
|
|
// Origins:
|
|
|
|
|
|
message FileOrigin {
|
|
|
int32 id = 1;
|
|
|
string filename = 2;
|
|
|
MavenCoordinate maven_coordinate = 3;
|
|
|
bool provided_by_build_system = 4;
|
|
|
}
|
|
|
|
|
|
// The ids of ClassFileInJarOrigin and FileOrigin are non-overlapping
|
|
|
// by design, so that a single int32 id can be used to
|
|
|
// unambiguously reference a ClassFileInJarOrigin or FileOrigin.
|
|
|
message ClassFileInJarOrigin {
|
|
|
int32 id = 1;
|
|
|
int32 file_origin_id = 2;
|
|
|
string entry = 3;
|
|
|
}
|
|
|
|
|
|
// Intentionally doesn't declare an id since each keep rule has its own
|
|
|
// TextFileOrigin, i.e., there is no sharing of TextFileOrigin.
|
|
|
message TextFileOrigin {
|
|
|
// Id into FileOrigin
|
|
|
int32 file_origin_id = 1;
|
|
|
int32 line_number = 2;
|
|
|
int32 column_number = 3;
|
|
|
}
|
|
|
|
|
|
message MavenCoordinate {
|
|
|
int32 id = 1;
|
|
|
string group_id = 2;
|
|
|
string artifact_id = 3;
|
|
|
string version = 4;
|
|
|
}
|
|
|
|
|
|
message BuildInfo {
|
|
|
int32 class_count = 1;
|
|
|
int32 field_count = 2;
|
|
|
int32 method_count = 3;
|
|
|
int32 live_class_count = 4;
|
|
|
int32 live_field_count = 5;
|
|
|
int32 live_method_count = 6;
|
|
|
}
|
|
|
|
|
|
// Container.
|
|
|
|
|
|
message KeepRadiusContainer {
|
|
|
// Origins.
|
|
|
repeated FileOrigin file_origin_table = 1;
|
|
|
repeated ClassFileInJarOrigin class_file_in_jar_origin_table = 2;
|
|
|
repeated MavenCoordinate maven_coordinate_table = 3;
|
|
|
|
|
|
// References.
|
|
|
repeated FieldReference field_reference_table = 4;
|
|
|
repeated MethodReference method_reference_table = 5;
|
|
|
repeated ProtoReference proto_reference_table = 6;
|
|
|
repeated TypeReference type_reference_table = 7;
|
|
|
repeated TypeReferenceList type_reference_list_table = 8;
|
|
|
|
|
|
// Kept items.
|
|
|
repeated KeptClassInfo kept_class_info_table = 9;
|
|
|
repeated KeptFieldInfo kept_field_info_table = 10;
|
|
|
repeated KeptMethodInfo kept_method_info_table = 11;
|
|
|
|
|
|
// Keep specifications.
|
|
|
repeated KeepConstraints keep_constraints_table = 12;
|
|
|
repeated KeepRuleKeepRadius keep_rule_keep_radius_table = 13;
|
|
|
repeated GlobalKeepRuleKeepRadius global_keep_rule_keep_radius_table = 14;
|
|
|
|
|
|
// Build info.
|
|
|
BuildInfo build_info = 15;
|
|
|
}
|
|
|
</script>
|
|
|
<script id="keepradius-data" type="application/octet-stream">CnwSei9Vc2Vycy9hamVzaHIvLmdyYWRsZS9jYWNoZXMvOS40LjAvdHJhbnNmb3Jtcy80YWM1ZjVlYjFhNjI2YzA0YjVkZGRiY2Y3MWVkMDEzYS90cmFuc2Zvcm1lZC9uYXZpZ2F0aW9uMy1ydW50aW1lLXJ1bnRpbWUuamFyCnUIARJxL1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zL2U3MDYyZWI0MmZlYTk2YWZlZWFiYTlmZDQyN2UyMWJiL3RyYW5zZm9ybWVkL3NhdmVkc3RhdGUtcnVudGltZS5qYXIKaggCEmYvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvZmY5ZDEyMTZhNjI2ZjcyMzE1MzNmNmRiOTc1ZDllMDcvdHJhbnNmb3JtZWQvY2xhc3Nlcy5qYXIKaggDEmYvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvNDE0OTgzZDBmMDc0MDRhNmI3ODNjMTI0ZTFkMTRhZDUvdHJhbnNmb3JtZWQvY2xhc3Nlcy5qYXIKaggEEmYvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvYzUwYTE0NjFkYTFlNzM3MzFjMTNjZjIxYzQ3MjhhZjkvdHJhbnNmb3JtZWQvY2xhc3Nlcy5qYXIKaggFEmYvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvOWE4NTBkMDM5OGM0ZWNjMGE2MTYxZjA1OGFiNTNhM2MvdHJhbnNmb3JtZWQvY2xhc3Nlcy5qYXIKaggGEmYvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvMWIwOWUzZTViNWIwOGM2YmZhZTdkYjYxY2I4ZGM4NTIvdHJhbnNmb3JtZWQvY2xhc3Nlcy5qYXIKaggHEmYvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvZjJlZjg2NTc5NzdiZjdiMDZkNThlMTk0ODk0YjYxOTIvdHJhbnNmb3JtZWQvY2xhc3Nlcy5qYXIKfQgIEnkvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvYzI5NTBkNzBlNDY0NDM1MGEzZDBmMDY0OWIyMjRkZDEvdHJhbnNmb3JtZWQva290bGlueC1kYXRldGltZS1qdm0tMC42LjEuamFyCogBCAkSgwEvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvNTM4YTFiNmYzNzVlOTIwNzM1ZmNiOGVhOGMzZjIxMWEvdHJhbnNmb3JtZWQva290bGlueC1zZXJpYWxpemF0aW9uLWpzb24tanZtLTEuOC4wLmphcgqrAQgKEqYBL1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zLzdhMTljYWI1ZWIyNTA4ODBhNWY5MDQxMjhkZmZmYTkwL3RyYW5zZm9ybWVkL3Nocmluay1ydWxlcy9saWIvTUVUQS1JTkYvY29tLmFuZHJvaWQudG9vbHMvcjgva290bGlueC1zZXJpYWxpemF0aW9uLXI4LnBybwqvAQgLEqoBL1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zLzdhMTljYWI1ZWIyNTA4ODBhNWY5MDQxMjhkZmZmYTkwL3RyYW5zZm9ybWVkL3Nocmluay1ydWxlcy9saWIvTUVUQS1JTkYvY29tLmFuZHJvaWQudG9vbHMvcjgva290bGlueC1zZXJpYWxpemF0aW9uLWNvbW1vbi5wcm8KdwgMEnMvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvZGU0MjViMzE3M2U2YmU2YmE2Y2RiMDU4NTUwYzVjZTUvdHJhbnNmb3JtZWQvd2luZG93LTEuNS4wLXJ1bnRpbWUuamFyCngIDRJ0L1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zL2IwMGM3OWE3M2U3N2Y4MjgyZmI4NzAzNzE3Yjc5Y2RmL3RyYW5zZm9ybWVkL3dpbmRvdy0xLjUuMC9wcm9ndWFyZC50eHQKkAEIDhKLAS9Vc2Vycy9hamVzaHIvLmdyYWRsZS9jYWNoZXMvOS40LjAvdHJhbnNmb3Jtcy8yN2NlOGQyYjJlZGEzOWM5MDI5ZDgzNjBkYTEwY2E4Ny90cmFuc2Zvcm1lZC9zaHJpbmstcnVsZXMvbGliL01FVEEtSU5GL3Byb2d1YXJkL3JldHJvZml0Mi5wcm8KeQgPEnUvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvMDI3YjZhYzIwNzQ0ZDQ5NjE0ZDA2ODljOWRmNDU4NWIvdHJhbnNmb3JtZWQvZnJhZ21lbnQtMS41LjQtcnVudGltZS5qYXIKhQEIEBKAAS9Vc2Vycy9hamVzaHIvLmdyYWRsZS9jYWNoZXMvOS40LjAvdHJhbnNmb3Jtcy9iZjY0N2NmNzQxYmE5YzMxMDJhMTFkMGEwNmZjNGFiYi90cmFuc2Zvcm1lZC9wbGF5LXNlcnZpY2VzLWJhc2UtMTguNS4wLXJ1bnRpbWUuamFyCokBCBEShAEvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvN2UxNzI5NzBjMmZiNDg2NWZmNmI5ZTJkOWM5NjQyNjcvdHJhbnNmb3JtZWQvcGxheS1zZXJ2aWNlcy1iYXNlbWVudC0xOC40LjAtcnVudGltZS5qYXIKeggSEnYvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvNzkwNjJhMWI3YTZmMmU4NzZhNDExYzc5NzYyODAyMTUvdHJhbnNmb3JtZWQvZnJhZ21lbnQtMS41LjQvcHJvZ3VhcmQudHh0CoYBCBMSgQEvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvZWM4OTA0MzJiMzlkNWViOGNkZmEzMjQwNDMxMDA4ZjYvdHJhbnNmb3JtZWQvbGlmZWN5Y2xlLXJ1bnRpbWUtY29tcG9zZS9wcm9ndWFyZC50eHQKfggUEnovVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvOGIwNTBhZjhmOWI2NWEyNDVkMmQxNmFiYzE5NjA1OWIvdHJhbnNmb3JtZWQvc2F2ZWRzdGF0ZS1jb21wb3NlL3Byb2d1YXJkLnR4dAqIAQgVEoMBL1VzZXJzL2FqZXNoci9TdHVkaW9Qcm9qZWN0cy9ub3dpbmFuZHJvaWQvYXBwL2J1aWxkL2ludGVybWVkaWF0ZXMvZGVmYXVsdF9wcm9ndWFyZF9maWxlcy9nbG9iYWwvcHJvZ3VhcmQtYW5kcm9pZC1vcHRpbWl6ZS50eHQtOS4wLjAKhwEIFhKCAS9Vc2Vycy9hamVzaHIvLmdyYWRsZS9jYWNoZXMvOS40LjAvdHJhbnNmb3Jtcy82YTJjZjM5YTczYjJkYjM4YjAxY2Q3OTgzNDgwMTFlNy90cmFuc2Zvcm1lZC90cmFuc3BvcnQtYmFja2VuZC1jY3QtMy4zLjAtcnVudGltZS5qYXIKgQEIFxJ9L1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zL2ZjMDM4MTBmZTRiZmIwOWJlZWZmZjAxZGE1Y2NjZGU0L3RyYW5zZm9ybWVkL2ZpcmViYXNlLWNvbW1vbi0yMS4wLjAtcnVudGltZS5qYXIKfggYEnovVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvZTcwMWIzMjdmN2Y1MDFlZDhlMTdhMjE0YWUzMTE3ZWMvdHJhbnNmb3JtZWQvZmlyZWJhc2UtYWJ0LTIxLjEuMS1ydW50aW1lLmphcgqQAQgZEosBL1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zLzA0Y2EwMGE0MjUzNjIyODI2NWJkYzFmOTlhNTVkNmFiL3RyYW5zZm9ybWVkL3BsYXktc2VydmljZXMtbWVhc3VyZW1lbnQtYXBpLTIyLjEuMi1ydW50aW1lLmphcgqHAQgaEoIBL1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zLzMxZDNiM2JjZjA2ZTU0OTYzNzMxZDIwYzk3Mjk0MDQ3L3RyYW5zZm9ybWVkL2ZpcmViYXNlLWNyYXNobHl0aWNzLTE5LjMuMC1ydW50aW1lLmphcgqJAQgbEoQBL1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zL2RlZmY0YWIxNjZkMTk5Mzk1MmRlNzE1NDBlZGFjZmEyL3RyYW5zZm9ybWVkL2ZpcmViYXNlLWRhdGF0cmFuc3BvcnQtMTkuMC4wLXJ1bnRpbWUuamFyCokBCBwShAEvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvMzkwZTAzN2M3YWM1MTUxODJkZjg2Y2M3ZWI4MjA2OTIvdHJhbnNmb3JtZWQvZmlyZWJhc2UtaW5zdGFsbGF0aW9ucy0xOC4wLjAtcnVudGltZS5qYXIKhgEIHRKBAS9Vc2Vycy9hamVzaHIvLmdyYWRsZS9jYWNoZXMvOS40LjAvdHJhbnNmb3Jtcy8wZmRjYzgxZTVkYmMxODUxZTY1ZmI1MGMxNDI1Yjk0NC90cmFuc2Zvcm1lZC9maXJlYmFzZS1jb21tb24ta3R4LTIxLjAuMC1ydW50aW1lLmphcgqFAQgeEoABL1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zLzA4YTBlNzQzZTM2Y2NiMmE5YTM0OWYzNDYxMjFkYmNjL3RyYW5zZm9ybWVkL2ZpcmViYXNlLW1lc3NhZ2luZy0yNC4xLjAtcnVudGltZS5qYXIKfwgfEnsvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvYjQ4OTQyNjI5YjZkMDNhNGE3OTUyMWJkNDJmMDY4MjkvdHJhbnNmb3JtZWQvZmlyZWJhc2UtcGVyZi0yMS4wLjMtcnVudGltZS5qYXIKgQEIIBJ9L1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zLzZiZTc2ZDExNmM0MTNmNTZiMGQ3Yjc0NWIzYTdlYzMyL3RyYW5zZm9ybWVkL2ZpcmViYXNlLWNvbmZpZy0yMi4wLjEtcnVudGltZS5qYXIKggEIIRJ+L1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zLzIxZmQ5NDYyYWRlYWM4ZmM5YTllMzU2NmMyMDM2MTQ0L3RyYW5zZm9ybWVkL2ZpcmViYXNlLXNlc3Npb25zLTIuMC43LXJ1bnRpbWUuamFyCooBCCIShQEvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvZmU4ZjQ3NzZkNTA5MjdhYWE0NjAxNGYzOTYzMGQwZjgvdHJhbnNmb3JtZWQvcGxheS1zZXJ2aWNlcy1iYXNlbWVudC0xOC40LjAvcHJvZ3VhcmQudHh0CpsBCCMSlgEvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvNDE2Y2UzODMyYTY2ZWFjNmFjYmFjZmY5ZTNhYTUyNTkvdHJhbnNmb3JtZWQvc2hyaW5rLXJ1bGVzL2xpYi9NRVRBLUlORi9wcm9ndWFyZC9hbmRyb2lkeC1hbm5vdGF0aW9ucy5wcm8KkAEIJBKLAS9Vc2Vycy9hamVzaHIvLmdyYWRsZS9jYWNoZXMvOS40LjAvdHJhbnNmb3Jtcy8xMTI5ODU0YTY1NjNkY2EyMGExNWFjYjQ2ZmJiMGYzNi90cmFuc2Zvcm1lZC9wbGF5LXNlcnZpY2VzLW1lYXN1cmVtZW50LXNkay0yMi4xLjItcnVudGltZS5qYXIKkQEIJRKMAS9Vc2Vycy9hamVzaHIvLmdyYWRsZS9jYWNoZXMvOS40LjAvdHJhbnNmb3Jtcy9hZjQyYTI5ODY1N2YyZDFkY2E5MzFlM2MxZGJkMzc3ZS90cmFuc2Zvcm1lZC9wbGF5LXNlcnZpY2VzLW1lYXN1cmVtZW50LWJhc2UtMjIuMS4yLXJ1bnRpbWUuamFyCncIJhJzL1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zLzE3ODFhYTJjNmIwMDI2ODBkNTJjZjRkMjlkNWRiYjFhL3RyYW5zZm9ybWVkL2Fubm90YXRpb24tanZtLTEuOS4xLmphcgp+CCcSei9Vc2Vycy9hamVzaHIvLmdyYWRsZS9jYWNoZXMvOS40LjAvdHJhbnNmb3Jtcy80MjFhMDljMzgwYTdlNmRiNmMzNjNiMjYxYmVlMDYxMC90cmFuc2Zvcm1lZC93b3JrLXJ1bnRpbWUtMi4xMC4wLXJ1bnRpbWUuamFyCmoIKBJmL1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zLzVmMGM3YTJmODdkMjQ0ZjQxZGU3OWFjZTFmNTQyOTVjL3RyYW5zZm9ybWVkL2NsYXNzZXMuamFyCngIKRJ0L1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zLzhjNWEwYjM5ZGJmMzY5OTZhNGJkMzAwNTlhNTIxM2QxL3RyYW5zZm9ybWVkL3Jvb20tcnVudGltZS9wcm9ndWFyZC50eHQKiQEIKhKEAS9Vc2Vycy9hamVzaHIvLmdyYWRsZS9jYWNoZXMvOS40LjAvdHJhbnNmb3Jtcy81YmEyZjIyOTM4NjgyZmUwOTc3NDBlODkzMTY4OTA4Mi90cmFuc2Zvcm1lZC9ydW50aW1lLXRyYWNpbmctMS4xMC4wLWJldGEwMi1ydW50aW1lLmphcgp3CCsScy9Vc2Vycy9hamVzaHIvLmdyYWRsZS9jYWNoZXMvOS40LjAvdHJhbnNmb3Jtcy82ZWRiN2EyMzAxODc0Y2UxMTBhMWNjZTUwNTcwNTM1NC90cmFuc2Zvcm1lZC9lbW9qaTItMS40LjAtcnVudGltZS5qYXIKgwEILBJ/L1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zL2U5MWM2MWFjODBmZWZjOGIxM2MzNDI4YTIxMWNjZTkzL3RyYW5zZm9ybWVkL2xpZmVjeWNsZS1wcm9jZXNzLTIuMTAuMC1ydW50aW1lLmphcgqBAQgtEn0vVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvZTdiZmQ3NmQ5NzUyNzU5YjUwM2JiMWY5MDVjYTBhMTEvdHJhbnNmb3JtZWQvcHJvZmlsZWluc3RhbGxlci0xLjQuMS1ydW50aW1lLmphcgqBAQguEn0vVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvMWJkZTEyNWY1NDJmNGU4ZmM0NzA0NmIzNWY5NjA5YmUvdHJhbnNmb3JtZWQvdHJhY2luZy1wZXJmZXR0by0xLjAuMC1ydW50aW1lLmphcgqBAQgvEn0vVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvNmMyYzU0N2ZhY2NiZWM3OGJmYzA1NTk1ODIwZjlkODMvdHJhbnNmb3JtZWQvc3RhcnR1cC1ydW50aW1lLTEuMS4xL3Byb2d1YXJkLnR4dAp9CDASeS9Vc2Vycy9hamVzaHIvLmdyYWRsZS9jYWNoZXMvOS40LjAvdHJhbnNmb3Jtcy82ZDQ2ZDVkNzRmNGZkMWJmZGMzYmQ3YjQ1M2NmZTRmYy90cmFuc2Zvcm1lZC9saWZlY3ljbGUtcnVudGltZS9wcm9ndWFyZC50eHQKdggxEnIvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvODJjMmExMTc3ODRkMDViYzdmODBlNDkzNWY3ZmQyZTQvdHJhbnNmb3JtZWQvY29yZS0xLjE2LjAtcnVudGltZS5qYXIKhQEIMhKAAS9Vc2Vycy9hamVzaHIvLmdyYWRsZS9jYWNoZXMvOS40LjAvdHJhbnNmb3Jtcy84M2QxZTUwMDczZThhOThmMTk2ZTJkOWJjYmJkZGQyMi90cmFuc2Zvcm1lZC92ZXJzaW9uZWRwYXJjZWxhYmxlLTEuMS4xLXJ1bnRpbWUuamFyCoYBCDMSgQEvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvYjI4ODRhZTJjNTUzN2EyMGM5NDkwNTIzNmU1NTU1MjAvdHJhbnNmb3JtZWQvdmVyc2lvbmVkcGFyY2VsYWJsZS0xLjEuMS9wcm9ndWFyZC50eHQKnwEINBKaAS9Vc2Vycy9hamVzaHIvU3R1ZGlvUHJvamVjdHMvbm93aW5hbmRyb2lkL215bGlicmFyeS9idWlsZC9pbnRlcm1lZGlhdGVzL2NvbnN1bWVyX3Byb2d1YXJkX2Rpci9yZWxlYXNlL2V4cG9ydFJlbGVhc2VDb25zdW1lclByb2d1YXJkRmlsZXMvbGliMC9wcm9ndWFyZC50eHQKhwEINRKCAS9Vc2Vycy9hamVzaHIvLmdyYWRsZS9jYWNoZXMvOS40LjAvdHJhbnNmb3Jtcy84ZWFmMGI5Nzk4MWUwYmY1MGZjZDcyMWEwNTU0OWE2Ny90cmFuc2Zvcm1lZC9maXJlYmFzZS1jb21wb25lbnRzLTE4LjAuMC9wcm9ndWFyZC50eHQKfwg2EnsvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvZmI4MTk0MTUwMjIzNjMxMWJhYmQ2MmI0ZmM1ZDk5ODUvdHJhbnNmb3JtZWQvd29yay1ydW50aW1lLTIuMTAuMC9wcm9ndWFyZC50eHQKagg3EmYvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvN2FmMzQxYzk0YjlkMWRkMTA0ZDg5OTczMmI4MGMxN2IvdHJhbnNmb3JtZWQvY2xhc3Nlcy5qYXIKfAg4EngvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvN2UxN2U0ZTc2MTQwNmRkNWEyZWZhNTIyYmUyOWU2NjAvdHJhbnNmb3JtZWQvaGlsdC1hbmRyb2lkLTIuNTktcnVudGltZS5qYXIKfQg5EnkvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvZjI0Mzg2ZTdjZGE1NDQ2MDQ0NmI1YTc4NDNmNjI4ODkvdHJhbnNmb3JtZWQvaGlsdC1hbmRyb2lkLTIuNTkvcHJvZ3VhcmQudHh0CtABCDoSywEvVXNlcnMvYWplc2hyL1N0dWRpb1Byb2plY3RzL25vd2luYW5kcm9pZC9hcHAvYnVpbGQvaW50ZXJtZWRpYXRlcy9jbGFzc2VzL3Byb2RCZW5jaG1hcmsvdHJhbnNmb3JtUHJvZEJlbmNobWFya0NsYXNzZXNXaXRoQXNtL2RpcnMvY29tL2dvb2dsZS9zYW1wbGVzL2FwcHMvbm93aW5hbmRyb2lkL01haW5BY3Rpdml0eV9HZW5lcmF0ZWRJbmplY3Rvci5jbGFzcwrSAQg7Es0BL1VzZXJzL2FqZXNoci9TdHVkaW9Qcm9qZWN0cy9ub3dpbmFuZHJvaWQvYXBwL2J1aWxkL2ludGVybWVkaWF0ZXMvY2xhc3Nlcy9wcm9kQmVuY2htYXJrL3RyYW5zZm9ybVByb2RCZW5jaG1hcmtDbGFzc2VzV2l0aEFzbS9kaXJzL2NvbS9nb29nbGUvc2FtcGxlcy9hcHBzL25vd2luYW5kcm9pZC9OaWFBcHBsaWNhdGlvbl9HZW5lcmF0ZWRJbmplY3Rvci5jbGFzcwp0CDwScC9Vc2Vycy9hamVzaHIvLmdyYWRsZS9jYWNoZXMvOS40LjAvdHJhbnNmb3Jtcy84MTgyMWZkM2JkOGE4NjNkYjc2NTM4YWQxNTk4YTdkZS90cmFuc2Zvcm1lZC9hbmltYXRpb24tcnVudGltZS5qYXIKdQg9EnEvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvYTAxNzViM2VjNjRkODExYTdlN2IwMzY5NTUzNzRiZjUvdHJhbnNmb3JtZWQvZm91bmRhdGlvbi1ydW50aW1lLmphcgp8CD4SeC9Vc2Vycy9hamVzaHIvLmdyYWRsZS9jYWNoZXMvOS40LjAvdHJhbnNmb3Jtcy8xNmJmMDc0NGQzN2E0YTUwYmIzY2Q3MTI4MWI2NDFhYi90cmFuc2Zvcm1lZC9mb3VuZGF0aW9uLWxheW91dC1ydW50aW1lLmphcgp0CD8ScC9Vc2Vycy9hamVzaHIvLmdyYWRsZS9jYWNoZXMvOS40LjAvdHJhbnNmb3Jtcy85MjNmYjlmYjY1MzQ1MGY5ZjU4MjZlYjNkMjQ0ZjhmYi90cmFuc2Zvcm1lZC9tYXRlcmlhbDMtcnVudGltZS5qYXIKeghAEnYvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvZTZlOWU4MDk2NzU0Mjk5MDFhY2RkZmUyOWQ4NTg4ZWUvdHJhbnNmb3JtZWQvYWRhcHRpdmUtbGF5b3V0LXJ1bnRpbWUuamFyCm0IQRJpL1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zL2ExODk4ZDAwOGY0NjgyMWYyYjljN2I3MTdmZTg5NzIwL3RyYW5zZm9ybWVkL3VpLXJ1bnRpbWUuamFyCmoIQhJmL1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zLzNkNzIyMmEyNTBiYzJkYzU5ZDA0OGU2MWUwNDBmMjU3L3RyYW5zZm9ybWVkL2NsYXNzZXMuamFyCm4IQxJqL1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zL2ViMzVmN2QzNDYyMjg4N2NkZjY2ZWI2OTZmYzc0NTA3L3RyYW5zZm9ybWVkL3VpL3Byb2d1YXJkLnR4dArHAQhEEsIBL1VzZXJzL2FqZXNoci9TdHVkaW9Qcm9qZWN0cy9ub3dpbmFuZHJvaWQvYXBwL2J1aWxkL2ludGVybWVkaWF0ZXMvY2xhc3Nlcy9wcm9kQmVuY2htYXJrL3RyYW5zZm9ybVByb2RCZW5jaG1hcmtDbGFzc2VzV2l0aEFzbS9kaXJzL2NvbS9nb29nbGUvc2FtcGxlcy9hcHBzL25vd2luYW5kcm9pZC9NYWluQWN0aXZpdHlWaWV3TW9kZWwuY2xhc3MKogEIRRKdAS9Vc2Vycy9hamVzaHIvU3R1ZGlvUHJvamVjdHMvbm93aW5hbmRyb2lkL2FwcC9idWlsZC9pbnRlcm1lZGlhdGVzL2dlbmVyYXRlZF9wcm9ndWFyZF9maWxlL3Byb2RCZW5jaG1hcmsvbWVyZ2VQcm9kQmVuY2htYXJrR2VuZXJhdGVkUHJvZ3VhcmRGaWxlcy9wcm9ndWFyZC50eHQKaghGEmYvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvOWMwYjJhYWFiMmJmYjYxMzBhZjJlMjg1NWI2ODA0ZjMvdHJhbnNmb3JtZWQvY2xhc3Nlcy5qYXIKtAEIRxKvAS9Vc2Vycy9hamVzaHIvU3R1ZGlvUHJvamVjdHMvbm93aW5hbmRyb2lkL2ZlYXR1cmUvYm9va21hcmtzL2ltcGwvYnVpbGQvaW50ZXJtZWRpYXRlcy9jb25zdW1lcl9wcm9ndWFyZF9kaXIvcHJvZFJlbGVhc2UvZXhwb3J0UHJvZFJlbGVhc2VDb25zdW1lclByb2d1YXJkRmlsZXMvbGliMC9wcm9ndWFyZC50eHQKaghIEmYvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvMmI0MTk0M2M5YjE0MDFhYjQ2YzE0NDE5MWFkMzJlZGEvdHJhbnNmb3JtZWQvY2xhc3Nlcy5qYXIKsQEISRKsAS9Vc2Vycy9hamVzaHIvU3R1ZGlvUHJvamVjdHMvbm93aW5hbmRyb2lkL2ZlYXR1cmUvZm9yeW91L2ltcGwvYnVpbGQvaW50ZXJtZWRpYXRlcy9jb25zdW1lcl9wcm9ndWFyZF9kaXIvcHJvZFJlbGVhc2UvZXhwb3J0UHJvZFJlbGVhc2VDb25zdW1lclByb2d1YXJkRmlsZXMvbGliMC9wcm9ndWFyZC50eHQKaghKEmYvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvZjI1MWZmNGZjMWQzMTcxM2QyNjU0NGVhNzkyZWNkOWQvdHJhbnNmb3JtZWQvY2xhc3Nlcy5qYXIKtAEISxKvAS9Vc2Vycy9hamVzaHIvU3R1ZGlvUHJvamVjdHMvbm93aW5hbmRyb2lkL2ZlYXR1cmUvaW50ZXJlc3RzL2ltcGwvYnVpbGQvaW50ZXJtZWRpYXRlcy9jb25zdW1lcl9wcm9ndWFyZF9kaXIvcHJvZFJlbGVhc2UvZXhwb3J0UHJvZFJlbGVhc2VDb25zdW1lclByb2d1YXJkRmlsZXMvbGliMC9wcm9ndWFyZC50eHQKaghMEmYvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvYWEyOTJiNDU1ZGNmZDdiMThlODY4NDc3Mzg0NTA3Y2IvdHJhbnNmb3JtZWQvY2xhc3Nlcy5qYXIKsQEITRKsAS9Vc2Vycy9hamVzaHIvU3R1ZGlvUHJvamVjdHMvbm93aW5hbmRyb2lkL2ZlYXR1cmUvc2VhcmNoL2ltcGwvYnVpbGQvaW50ZXJtZWRpYXRlcy9jb25zdW1lcl9wcm9ndWFyZF9kaXIvcHJvZFJlbGVhc2UvZXhwb3J0UHJvZFJlbGVhc2VDb25zdW1lclByb2d1YXJkRmlsZXMvbGliMC9wcm9ndWFyZC50eHQKaghOEmYvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvMjdiZTVmY2QzY2E5OGJjNDczZDdkMGU3YWY5MDM4ZmUvdHJhbnNmb3JtZWQvY2xhc3Nlcy5qYXIKswEITxKuAS9Vc2Vycy9hamVzaHIvU3R1ZGlvUHJvamVjdHMvbm93aW5hbmRyb2lkL2ZlYXR1cmUvc2V0dGluZ3MvaW1wbC9idWlsZC9pbnRlcm1lZGlhdGVzL2NvbnN1bWVyX3Byb2d1YXJkX2Rpci9wcm9kUmVsZWFzZS9leHBvcnRQcm9kUmVsZWFzZUNvbnN1bWVyUHJvZ3VhcmRGaWxlcy9saWIwL3Byb2d1YXJkLnR4dApqCFASZi9Vc2Vycy9hamVzaHIvLmdyYWRsZS9jYWNoZXMvOS40LjAvdHJhbnNmb3Jtcy81ZDVmOGFlMTdiNWUzODczZjNhZTYwN2QwNTQ2NzM1ZC90cmFuc2Zvcm1lZC9jbGFzc2VzLmphcgqwAQhREqsBL1VzZXJzL2FqZXNoci9TdHVkaW9Qcm9qZWN0cy9ub3dpbmFuZHJvaWQvZmVhdHVyZS90b3BpYy9pbXBsL2J1aWxkL2ludGVybWVkaWF0ZXMvY29uc3VtZXJfcHJvZ3VhcmRfZGlyL3Byb2RSZWxlYXNlL2V4cG9ydFByb2RSZWxlYXNlQ29uc3VtZXJQcm9ndWFyZEZpbGVzL2xpYjAvcHJvZ3VhcmQudHh0CnYIUhJyL1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zLzlhMmZkNWJiNzY2NzMwOGU3YWEzNDdlMmY2ODA4NzdiL3RyYW5zZm9ybWVkL2tvdGxpbi1zdGRsaWItMi4zLjAuamFyCnIIUxJuL1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zLzNiMGY3MDFhOGU1MmYzN2RkMTEwZmY0MjZiNzVmMDMyL3RyYW5zZm9ybWVkL3JldHJvZml0LTIuMTEuMC5qYXIKhgEIVBKBAS9Vc2Vycy9hamVzaHIvLmdyYWRsZS9jYWNoZXMvOS40LjAvdHJhbnNmb3Jtcy82NTNiNGI4NDAwN2EzOWM0MzdkYzEyY2IwODRjNDBhNS90cmFuc2Zvcm1lZC9maXJlYmFzZS1jb21wb25lbnRzLTE4LjAuMC1ydW50aW1lLmphcgp+CFUSei9Vc2Vycy9hamVzaHIvLmdyYWRsZS9jYWNoZXMvOS40LjAvdHJhbnNmb3Jtcy8xZjk3ZjIyM2I4YTEwNWQ2YzQyMWRiMzU2MmJiZDA2NC90cmFuc2Zvcm1lZC9ncmFwaGljcy1wYXRoLTEuMC4xLXJ1bnRpbWUuamFyCnoIVhJ2L1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zLzU1ZTdiMGZjMjc3NTg5MmU3ZmMyM2ZiZDkzZWE4NWI0L3RyYW5zZm9ybWVkL2RhdGFzdG9yZS1jb3JlL3Byb2d1YXJkLnR4dAqRAQhXEowBL1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zLzIwMDQyZDVhYzdjYmE0MmRlYmM5MDA5ODc3M2ZkODc5L3RyYW5zZm9ybWVkL3BsYXktc2VydmljZXMtbWVhc3VyZW1lbnQtaW1wbC0yMi4xLjItcnVudGltZS5qYXIKfwhYEnsvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvYTc0YWI0ZGUyZDQxNWNjNDE3MGJmYTU3YzE3MzdlMWYvdHJhbnNmb3JtZWQvZ3JhcGhpY3MtcGF0aC0xLjAuMS9wcm9ndWFyZC50eHQKfAhZEngvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvMGEzMTVhOGIxMzczZDVlMTU1N2M5MmRjZDQ4Zjk2NjYvdHJhbnNmb3JtZWQvbGlmZWN5Y2xlLXJ1bnRpbWUtcnVudGltZS5qYXIKeghaEnYvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvNWQ0MGYxMTE2MzY4YjdmYjI0OTViOWE2NDQzM2JjMmMvdHJhbnNmb3JtZWQvYXBwY29tcGF0LTEuNy4wLXJ1bnRpbWUuamFyCnsIWxJ3L1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zLzVmOWY0MjYyZmQ5MjQ2M2VkNzNlNmM1ZmVlOWFkOTk1L3RyYW5zZm9ybWVkL2FwcGNvbXBhdC0xLjcuMC9wcm9ndWFyZC50eHQKdwhcEnMvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvMWM3OGMwMWQ5NTdiY2YxNTEzYTgyYWI1NDExMTU0MDYvdHJhbnNmb3JtZWQvY29yZS0xLjE2LjAvcHJvZ3VhcmQudHh0CnoIXRJ2L1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zL2YzYWQ1MzEzMDY3N2E3OGM0NmIzZjAwNWFjYWU4YWJhL3RyYW5zZm9ybWVkL2FjdGl2aXR5LTEuMTIuMC1ydW50aW1lLmphcgqFAQheEoABL1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zLzQyNDg4NDNlZjdiNGI2NzdjNzk3NGE4ZTI5YzFkNmFlL3RyYW5zZm9ybWVkL2RhdGFzdG9yZS1wcmVmZXJlbmNlcy1wcm90by0xLjIuMC5qYXIKkQEIXxKMAS9Vc2Vycy9hamVzaHIvLmdyYWRsZS9jYWNoZXMvOS40LjAvdHJhbnNmb3Jtcy80OTEyMTcxNDg2ZTAwODRhNDhhNTg1ZjdhM2Y1ZWQzMi90cmFuc2Zvcm1lZC9kYXRhc3RvcmUtcHJlZmVyZW5jZXMtZXh0ZXJuYWwtcHJvdG9idWYtMS4yLjAuamFyCocBCGASggEvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvNzY5YTVhZTdhY2Q1YTg2MDZlYmE4NmU2MGM5MGMzMWUvdHJhbnNmb3JtZWQvZGF0YXN0b3JlLXByZWZlcmVuY2VzLWNvcmUvcHJvZ3VhcmQudHh0CoUBCGESgAEvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvYmRhMTIyYzAyZmQ5M2ZkYjRmZDBiZjEyODJhN2QyMzMvdHJhbnNmb3JtZWQvbGlmZWN5Y2xlLXByb2Nlc3MtMi4xMC4wL3Byb2d1YXJkLnR4dAqMAQhiEocBL1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zLzIzNGYxNGVjNGVlMjc3M2I0NDgyZDRiOGZlZWFkZjhhL3RyYW5zZm9ybWVkL3BsYXktc2VydmljZXMtbWVhc3VyZW1lbnQtMjIuMS4yLXJ1bnRpbWUuamFyCo0BCGMSiAEvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvMjFiMGMxMDFlOTZlNTQ0OTAxNmE0YjRhNDg1ZGViZDIvdHJhbnNmb3JtZWQvcGxheS1zZXJ2aWNlcy1tZWFzdXJlbWVudC0yMi4xLjIvcHJvZ3VhcmQudHh0CnsIZBJ3L1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zL2JmZWEwOGQ0ZTM3ZWQ3MDkwOWEwMTRjMDBlNDA0NjU3L3RyYW5zZm9ybWVkL3Byb3RvYnVmLWphdmFsaXRlLTQuMjkuMi5qYXIKcghlEm4vVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvZmMzMGNlZWNlOGEyNDQzOTZkZDBiYzk5NzAyODM2MDkvdHJhbnNmb3JtZWQvZGF0YXN0b3JlLXByb3RvLmphcgqsAQhmEqcBL1VzZXJzL2FqZXNoci9TdHVkaW9Qcm9qZWN0cy9ub3dpbmFuZHJvaWQvY29yZS9kYXRhc3RvcmUvYnVpbGQvaW50ZXJtZWRpYXRlcy9jb25zdW1lcl9wcm9ndWFyZF9kaXIvcHJvZFJlbGVhc2UvZXhwb3J0UHJvZFJlbGVhc2VDb25zdW1lclByb2d1YXJkRmlsZXMvbGliMC9wcm9ndWFyZC50eHQKcghnEm4vVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvZDkxZTg0NGY3NmY5OTdiOTQ5ZTk5MDJlZThlMzdkMmIvdHJhbnNmb3JtZWQvcnVudGltZS1ydW50aW1lLmphcgp7CGgSdy9Vc2Vycy9hamVzaHIvLmdyYWRsZS9jYWNoZXMvOS40LjAvdHJhbnNmb3Jtcy8zNTAwMjQ4OWI3NjdhMWQyMDhmY2Q3OGIyNzhjZmJmYi90cmFuc2Zvcm1lZC9jdXN0b212aWV3LTEuMC4wLXJ1bnRpbWUuamFyCnoIaRJ2L1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zLzM5ZDRkMWM5NDdiYjIyZTk4OTFlNmYwNTI4YWY0OTEzL3RyYW5zZm9ybWVkL2NvaWwtYmFzZS0yLjcuMC1ydW50aW1lLmphcgqQAQhqEosBL1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zLzVmNzU4YzVkZmE5MDIyZGU1ZjExNjgzMzNlMWE0ODFlL3RyYW5zZm9ybWVkL3BsYXktc2VydmljZXMtY2xvdWQtbWVzc2FnaW5nLTE3LjIuMC1ydW50aW1lLmphcgqNAQhrEogBL1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zLzYzYzhiZTY4YjExYzM2MGZmMDA5NzZmZmE0MDI3ZjU2L3RyYW5zZm9ybWVkL3BsYXktc2VydmljZXMtb3NzLWxpY2Vuc2VzLTE3LjEuMC1ydW50aW1lLmphcgp3CGwScy9Vc2Vycy9hamVzaHIvLmdyYWRsZS9jYWNoZXMvOS40LjAvdHJhbnNmb3Jtcy9iMmRiNmNmMDg1YTZlNTAzNTBmZDJhZDU2YzBiNDZkNS90cmFuc2Zvcm1lZC91aS1ncmFwaGljcy9wcm9ndWFyZC50eHQKdghtEnIvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvZDljOTg0OGI2MGYyNTIwYzgxMDU1MjI3MmFiNjI2M2EvdHJhbnNmb3JtZWQvdWktZ3JhcGhpY3MtcnVudGltZS5qYXIKggEIbhJ+L1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zLzY0MmE2ODdkZWQ3ZmM4ZmY3ODA3NTgzOGY5MzllOTE0L3RyYW5zZm9ybWVkL3RyYWNpbmctcGVyZmV0dG8tMS4wLjAvcHJvZ3VhcmQudHh0CnsIbxJ3L1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zL2FiMjRiMTc1ZDgzOThiZTYxYTQxYWEyYzMwY2MzMTlkL3RyYW5zZm9ybWVkL3RyYW5zaXRpb24tMS42LjAtcnVudGltZS5qYXIKfAhwEngvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvZDBhNjAzNmMxNmNkOWJhNjFlNmRhNjA1YzYwNDA5MWYvdHJhbnNmb3JtZWQvdHJhbnNpdGlvbi0xLjYuMC9wcm9ndWFyZC50eHQKfwhxEnsvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvOTgyNmE0ODc2ZTc1NjA0YTY2NDgzZjBiOTlhMDhlNjMvdHJhbnNmb3JtZWQvdmVjdG9yZHJhd2FibGUtMS4xLjAtcnVudGltZS5qYXIKigEIchKFAS9Vc2Vycy9hamVzaHIvLmdyYWRsZS9jYWNoZXMvOS40LjAvdHJhbnNmb3Jtcy84NjM1MmQ0ZTIyZDc4MjNhMTY0Zjc0N2YwMjdhNGQ5YS90cmFuc2Zvcm1lZC92ZWN0b3JkcmF3YWJsZS1hbmltYXRlZC0xLjEuMC9wcm9ndWFyZC50eHQKhgEIcxKBAS9Vc2Vycy9hamVzaHIvLmdyYWRsZS9jYWNoZXMvOS40LjAvdHJhbnNmb3Jtcy83NGZiODdmYTgwNTExNjg1MzFkOWQ0NmE2MzIyODExYS90cmFuc2Zvcm1lZC9wbGF5LXNlcnZpY2VzLWJhc2UtMTguNS4wL3Byb2d1YXJkLnR4dAqdAQh0EpgBL1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zL2Q2ZGE2ODM4Y2NmMmI3OWMwMDkzZmQ4NWMzNGEwNTM2L3RyYW5zZm9ybWVkL3Nocmluay1ydWxlcy9saWIvTUVUQS1JTkYvY29tLmFuZHJvaWQudG9vbHMvcjgvY29yb3V0aW5lcy5wcm8KhgEIdRKBAS9Vc2Vycy9hamVzaHIvLmdyYWRsZS9jYWNoZXMvOS40LjAvdHJhbnNmb3Jtcy83YTEwYTE2ODBmYWVlYzE5YmQ3M2Q1NzJhZGVmMTk5Mi90cmFuc2Zvcm1lZC9rb3RsaW54LWNvcm91dGluZXMtY29yZS1qdm0tMS4xMC4xLmphcgqFAQh2EoABL1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zL2I0YWQ1NGI5YjA4N2VmYmMzYWQ1ODMzOGVkODEwZmZlL3RyYW5zZm9ybWVkL2tvdGxpbngtY29yb3V0aW5lcy1hbmRyb2lkLTEuMTAuMS5qYXIKeQh3EnUvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvOGI4YzZiM2NjMTE4ZThmMDRmMjExODkxM2UyZmE3Y2EvdHJhbnNmb3JtZWQvYW5pbWF0aW9uLWNvcmUtcnVudGltZS5qYXIKjwEIeBKKAS9Vc2Vycy9hamVzaHIvLmdyYWRsZS9jYWNoZXMvOS40LjAvdHJhbnNmb3Jtcy85OTVmNGM3NjBkMjM1MDg2Mjg3MmVjNzZjNTYwN2UzZC90cmFuc2Zvcm1lZC9tYXRlcmlhbDMtYWRhcHRpdmUtbmF2aWdhdGlvbi1zdWl0ZS1ydW50aW1lLmphcgpyCHkSbi9Vc2Vycy9hamVzaHIvLmdyYWRsZS9jYWNoZXMvOS40LjAvdHJhbnNmb3Jtcy8xNzU1MjI3ZDgxYWY4MGIxOGIxM2IxMzNkMTJhODcyNy90cmFuc2Zvcm1lZC91aS10ZXh0LXJ1bnRpbWUuamFyCnIIehJuL1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zLzk2ZWVjNjFmNTFmMjcxNWJiN2QwZjliNmQ0NzBmNzNkL3RyYW5zZm9ybWVkL3VpLXVuaXQtcnVudGltZS5qYXIKewh7EncvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvZDJlNTVhYWZlMWFmNDU4N2I5MzZiMmIyNWI5NjRjM2EvdHJhbnNmb3JtZWQvY29uY3VycmVudC1mdXR1cmVzLTEuMS4wLmphcgp+CHwSei9Vc2Vycy9hamVzaHIvLmdyYWRsZS9jYWNoZXMvOS40LjAvdHJhbnNmb3Jtcy82MmFjNGM0ZWMxYWYyYTJjNjA4MmI5YTA2OTUxOTI2YS90cmFuc2Zvcm1lZC9saWZlY3ljbGUtY29tbW9uLWp2bS0yLjEwLjAuamFyCncIfRJzL1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zLzY3MTY4NGVjMDAxZWRlOTUxYzIxMjMyZDAyNjhlYjJlL3RyYW5zZm9ybWVkL2xvYWRlci0xLjAuMC1ydW50aW1lLmphcgp3CH4Scy9Vc2Vycy9hamVzaHIvLmdyYWRsZS9jYWNoZXMvOS40LjAvdHJhbnNmb3Jtcy9lZmYzYjdhNzgzNDExNDM0Y2IxMjJjMGIxNWM3MDI3Yi90cmFuc2Zvcm1lZC9yb29tLXJ1bnRpbWUtcnVudGltZS5qYXIKewh/EncvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvZjQyNGQzN2MzZjViODYwYTE5YzE4NzhhZGQ4OGIyZjUvdHJhbnNmb3JtZWQvc3FsaXRlLWZyYW1ld29yay1ydW50aW1lLmphcgp/CIABEnovVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvOTY3ZDk1ZGVhOGI1MDdkMTU4YWExNDg1NGVmOWZlOWEvdHJhbnNmb3JtZWQvdHJhbnNwb3J0LWFwaS0zLjIuMC1ydW50aW1lLmphcgqDAQiBARJ+L1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zLzA5MDZhMmU2ZTVlMzY0ODI5ZDk5ZWE3ZDE2ZmI5MWEzL3RyYW5zZm9ybWVkL3RyYW5zcG9ydC1ydW50aW1lLTMuMy4wLXJ1bnRpbWUuamFyCnYIggEScS9Vc2Vycy9hamVzaHIvLmdyYWRsZS9jYWNoZXMvOS40LjAvdHJhbnNmb3Jtcy8wYThlZDUzYjhmMGYwOGIwOTM0OTJhZjM2YTRjN2UyNi90cmFuc2Zvcm1lZC9ndWF2YS0zMS4xLWFuZHJvaWQuamFyCoIBCIMBEn0vVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvMzAwMzFlNTc3NGUzMjA5YWE0NDlhZmFhNGFlOWVjMTkvdHJhbnNmb3JtZWQvZmlyZWJhc2UtZW5jb2RlcnMtcHJvdG8tMTYuMC4wLmphcgprCIQBEmYvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvNzhkMjZhY2MyYWYxMWRlNzVkOTAyMDRjZWEzZWMwZDcvdHJhbnNmb3JtZWQvY2xhc3Nlcy5qYXIKaQiFARJkL1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zLzg2YjdiNGExN2ZkZmNhYzBiMTU3MjRhNTdmOTAwZTY3L3RyYW5zZm9ybWVkL21vZGVsLmphcgpxCIYBEmwvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvZWE3MGEyMDMyODcyMmFiOWMzOGE3MjQ4YjZmNTkxODAvdHJhbnNmb3JtZWQvb2todHRwLTQuMTIuMC5qYXIKfgiHARJ5L1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zL2UxZTcyZDdjMTNlZTA5NWY1MmU2NjUyMGFjNjY0MGE1L3RyYW5zZm9ybWVkL2xvZ2dpbmctaW50ZXJjZXB0b3ItNC4xMi4wLmphcgp7CIgBEnYvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvYWE3MDIwOTIwNzM1ZjU1NjA3M2E1M2VkNmM3OGEyYjEvdHJhbnNmb3JtZWQvbWF0ZXJpYWwtcmlwcGxlLXJ1bnRpbWUuamFyCoABCIkBEnsvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvZDBhOTYyZGFhMzZmYjRhYmI3ODZmNjlmM2ZjYTMxOTIvdHJhbnNmb3JtZWQvbGlmZWN5Y2xlLXZpZXdtb2RlbC9wcm9ndWFyZC50eHQKjAEIigEShgEvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvMGI5NDU3NDQ2YzY0ZGQ3ODFiYTA4ZGYyYzFjM2NiZDkvdHJhbnNmb3JtZWQvbGlmZWN5Y2xlLXZpZXdtb2RlbC1zYXZlZHN0YXRlL3Byb2d1YXJkLnR4dAqLAQiLARKFAS9Vc2Vycy9hamVzaHIvLmdyYWRsZS9jYWNoZXMvOS40LjAvdHJhbnNmb3Jtcy8zMjlkOGZmNTVjMTEyYWI5MjY5MjQ4ZTIwZDAyZWUwNC90cmFuc2Zvcm1lZC9saWZlY3ljbGUtdmlld21vZGVsLXNhdmVkc3RhdGUtcnVudGltZS5qYXIKjAEIjAEShgEvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvMWViYTUxNzBiMDE1N2NmM2U5YTQ5ZjA1ZTA3ODM1Y2EvdHJhbnNmb3JtZWQvbGlmZWN5Y2xlLXZpZXdtb2RlbC1uYXZpZ2F0aW9uMy1ydW50aW1lLmphcgp3CI0BEnIvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvY2MzNmZjN2MyYjViZjliMDBiM2ZmYzAxOWMxNjNhMTMvdHJhbnNmb3JtZWQvc2F2ZWRzdGF0ZS9wcm9ndWFyZC50eHQKhgEIjgESgAEvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvNTBmMmQxZDk3MzNiMjBjZWMyYjE4OTAwOTM3YTVmYjgvdHJhbnNmb3JtZWQvYXBwY29tcGF0LXJlc291cmNlcy0xLjcuMC1ydW50aW1lLmphcgp5CI8BEnQvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvZjczNWFmMDQyMzYwNWI1MWJjNjNjOGYwNjY2NGNjNGEvdHJhbnNmb3JtZWQvYnJvd3Nlci0xLjguMC1ydW50aW1lLmphcgp/CJABEnovVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvNjM3Njc0NjM4YmNhZmU2Zjc1YmQ0ZTBkZjIzYmMxYmEvdHJhbnNmb3JtZWQvZXhpZmludGVyZmFjZS0xLjMuNy1ydW50aW1lLmphcgqIAQiRARKCAS9Vc2Vycy9hamVzaHIvLmdyYWRsZS9jYWNoZXMvOS40LjAvdHJhbnNmb3Jtcy8xZjlkZWI2NjhiYjgxY2QyZmM5OTAzMDM3OTIyZTViOS90cmFuc2Zvcm1lZC9hZHMtYWRzZXJ2aWNlcy0xLjAuMC1iZXRhMDUtcnVudGltZS5qYXIKjQEIkgEShwEvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvMmEzOGFlZGJjNjRmNjc1OWFhNmEwOWZhYTMzNzUxMDIvdHJhbnNmb3JtZWQvYWRzLWFkc2VydmljZXMtamF2YS0xLjAuMC1iZXRhMDUtcnVudGltZS5qYXIKgQEIkwESfC9Vc2Vycy9hamVzaHIvLmdyYWRsZS9jYWNoZXMvOS40LjAvdHJhbnNmb3Jtcy8zOWVhNDg0NmRiNmQ3MDJlMmVkY2Q5NGZlZDJhMzcyNS90cmFuc2Zvcm1lZC90cmFjaW5nLTEuMy4wLWFscGhhMDItcnVudGltZS5qYXIKegiUARJ1L1VzZXJzL2FqZXNoci8uZ3JhZGxlL2NhY2hlcy85LjQuMC90cmFuc2Zvcm1zLzE2NWE4MmFiMThjMzY4MTcyNGE1NDY0Mzk4NzM2YjhkL3RyYW5zZm9ybWVkL3J1bnRpbWUtcmV0YWluLXJ1bnRpbWUuamFyCnMIlQESbi9Vc2Vycy9hamVzaHIvLmdyYWRsZS9jYWNoZXMvOS40LjAvdHJhbnNmb3Jtcy8yYmQzYWM3NTJjMmEwNzlhMjgyZDNiN2ZlOWNhYzEwMS90cmFuc2Zvcm1lZC91aS11dGlsLXJ1bnRpbWUuamFyCncIlgESci9Vc2Vycy9hamVzaHIvLmdyYWRsZS9jYWNoZXMvOS40LjAvdHJhbnNmb3Jtcy8zNjMzMmUwNzJiZmU3NzU3ZmZmZjE3YTFlYTE4ZDkzZC90cmFuc2Zvcm1lZC9mb3VuZGF0aW9uL3Byb2d1YXJkLnR4dAp7CJcBEnYvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvZjRiY2RiYzY5MGM2MTljMTNjMjA2Y2M5MGM0ZGIwZmUvdHJhbnNmb3JtZWQvYW5pbWF0aW9uLWNvcmUvcHJvZ3VhcmQudHh0CnQImAESby9Vc2Vycy9hamVzaHIvLmdyYWRsZS9jYWNoZXMvOS40LjAvdHJhbnNmb3Jtcy82OGMzNzc3ZWZjM2EwZjQ1NTM4MjI1NTdkN2FlODJmMS90cmFuc2Zvcm1lZC9ydW50aW1lL3Byb2d1YXJkLnR4dAp8CJkBEncvVXNlcnMvYWplc2hyLy5ncmFkbGUvY2FjaGVzLzkuNC4wL3RyYW5zZm9ybXMvYTk5ZWQ2MTc0NTE4ZDU2NGRmNzYxNjVlNjA1MTc3MjYvdHJhbnNmb3JtZWQvaGlsdC13b3JrLTEuMi4wL3Byb2d1YXJkLnR4dAqPAQiaARKJAS9Vc2Vycy9hamVzaHIvLmdyYWRsZS9jYWNoZXMvOS40LjAvdHJhbnNmb3Jtcy8xZWM4ZDBlNTNjZWFkN2E3ZDUyNjM5MWEwZDQ2MDU0NC90cmFuc2Zvcm1lZC9zaHJpbmstcnVsZXMvbGliL01FVEEtSU5GL3Byb2d1YXJkL29raHR0cDMucHJvIg0YFiIJQ29tcGFuaW9uIhEIARABGBciCUNvbXBhbmlvbiIRCAIQAhgYIglDb21wYW5pb24iEQgDEAMYGSIJQ29tcGFuaW9uIhEIBBAEGBoiCUNvbXBhbmlvbiIRCAUQBRgbIglDb21wYW5pb24iEQgGEAgYHCIJQ29tcGFuaW9uIhEIBxAKGB0iCUNvbXBhbmlvbiIRCAgQCxgeIglDb21wYW5pb24iEQgJEAwYHyIJQ29tcGFuaW9uIhEIChANGCAiCUNvbXBhbmlvbiIRCAsQDhghIglDb21wYW5pb24iEQgMEA8YIiIJQ29tcGFuaW9uIhEIDRAQGCMiCUNvbXBhbmlvbiIRCA4QERgkIglDb21wYW5pb24iEQgPEBIYJSIJQ29tcGFuaW9uIhEIEBAUGCYiCUNvbXBhbmlvbiIRCBEQFRgnIglDb21wYW5pb24iEAgSEAYYBiIISU5TVEFOQ0UiEAgTEAcYByIISU5TVEFOQ0UiEAgUEAkYCSIISU5TVEFOQ0UiEAgVEBMYEyIISU5TVEFOQ0UiFAgWEDUYSCIMTElCUkFSWV9OQU1FIhEIFxA3GEkiCUNvbXBhbmlvbiIRCBgQOBhKIglDb21wYW5pb24iFAgZEDkYSCIMTElCUkFSWV9OQU1FIhQIGhA6GEgiDExJQlJBUllfTkFNRSIUCBsQPRhIIgxMSUJSQVJZX05BTUUiGggcED8YSCISRUFSTFlfTElCUkFSWV9OQU1FIhQIHRA/GEgiDExJQlJBUllfTkFNRSIYCB4QSxhMIhBhcHBTdGF0ZUNhbGxiYWNrIhcIHxBLGE0iD2FwcFN0YXRlTW9uaXRvciIXCCAQSxhOIg9jdXJyZW50QXBwU3RhdGUiHwghEEsYTyIXaXNSZWdpc3RlcmVkRm9yQXBwU3RhdGUiKQgiEEAYUCIhRkVUQ0hfTkVWRVJfSEFQUEVORURfVElNRVNUQU1QX01TIiMIIxBAGEgiG0ZJUkVQRVJGX0ZSQ19OQU1FU1BBQ0VfTkFNRSIrCCQQQBhQIiNNSU5fQVBQX1NUQVJUX0NPTkZJR19GRVRDSF9ERUxBWV9NUyIuCCUQQBhRIiZSQU5ET01fQVBQX1NUQVJUX0NPTkZJR19GRVRDSF9ERUxBWV9NUyI3CCYQQBhQIi9USU1FX0FGVEVSX1dISUNIX0FfRkVUQ0hfSVNfQ09OU0lERVJFRF9TVEFMRV9NUyIWCCcQQBhSIg5hbGxSY0NvbmZpZ01hcCIkCCgQQBhQIhxhcHBTdGFydENvbmZpZ0ZldGNoRGVsYXlJbk1zIhgIKRBAGFAiEGFwcFN0YXJ0VGltZUluTXMiDQgqEEAYUyIFY2FjaGUiEAgrEEAYVCIIZXhlY3V0b3IiHAgsEEAYVSIUZmlyZWJhc2VSZW1vdGVDb25maWciMAgtEEAYUCIoZmlyZWJhc2VSZW1vdGVDb25maWdMYXN0RmV0Y2hUaW1lc3RhbXBNcyIkCC4QQBhWIhxmaXJlYmFzZVJlbW90ZUNvbmZpZ1Byb3ZpZGVyIhAILxBAGEAiCGluc3RhbmNlIg4IMBBAGFciBmxvZ2dlciIXCDEQQhhNIg9hcHBTdGF0ZU1vbml0b3IiDwgyEEIYWCIHY2xpZW50cyIUCDMQQhhDIgxnYXVnZU1hbmFnZXIiEAg0EEIYQiIIaW5zdGFuY2UiEwg1EEIYWSILcGVyZlNlc3Npb24iFgg2EEIYWiIOc3luY0luaXRGdXR1cmUiNQg3EEMYUCItQVBQUk9YX05VTUJFUl9PRl9EQVRBX1BPSU5UU19QRVJfR0FVR0VfTUVUUklDIioIOBBDGFAiIklOVkFMSURfR0FVR0VfQ09MTEVDVElPTl9GUkVRVUVOQ1kiNAg5EEMYUCIsVElNRV9UT19XQUlUX0JFRk9SRV9GTFVTSElOR19HQVVHRVNfUVVFVUVfTVMiHwg6EEMYTiIXYXBwbGljYXRpb25Qcm9jZXNzU3RhdGUiFgg7EEMYWyIOY29uZmlnUmVzb2x2ZXIiGQg8EEMYXCIRY3B1R2F1Z2VDb2xsZWN0b3IiJQg9EEMYXSIdZ2F1Z2VNYW5hZ2VyRGF0YUNvbGxlY3Rpb25Kb2IiHAg+EEMYXCIUZ2F1Z2VNYW5hZ2VyRXhlY3V0b3IiHAg/EEMYXiIUZ2F1Z2VNZXRhZGF0YU1hbmFnZXIiEAhAEEMYQyIIaW5zdGFuY2UiDghBEEMYVyIGbG9nZ2VyIhwIQhBDGFwiFG1lbW9yeUdhdWdlQ29sbGVjdG9yIhEIQxBDGEgiCXNlc3Npb25JZCIYCEQQQxhfIhB0cmFuc3BvcnRNYW5hZ2VyIhQIRRBFGEgiDExJQlJBUllfTkFNRSIRCEYQRxhgIglDb21wYW5pb24iFAhHEEcYSCIMTElCUkFSWV9OQU1FIhwISBBHGGEiFGJhY2tncm91bmREaXNwYXRjaGVyIhoISRBHGGEiEmJsb2NraW5nRGlzcGF0Y2hlciITCEoQRxhhIgtmaXJlYmFzZUFwcCIgCEsQRxhhIhhmaXJlYmFzZUluc3RhbGxhdGlvbnNBcGkiJQhMEEcYYSIdc2Vzc2lvbkxpZmVjeWNsZVNlcnZpY2VCaW5kZXIiGAhNEEcYYSIQc2Vzc2lvbnNTZXR0aW5ncyIYCE4QRxhhIhB0cmFuc3BvcnRGYWN0b3J5IhUITxB/GIIBIgxzQ2xhc3NMb2FkZXIiEghQEIABGEgiCU1PRFVMRV9JRCIXCFEQgAEYUSIOTU9EVUxFX1ZFUlNJT04iEAhSEKoCGE8iB21BY3RpdmUiDwhTEKoCGEgiBm1BcHBJZCIbCFQQqgIYUCISbUNyZWF0aW9uVGltZXN0YW1wIhoIVRCqAhhIIhFtRXhwaXJlZEV2ZW50TmFtZSIdCFYQqgIYhwEiE21FeHBpcmVkRXZlbnRQYXJhbXMiDghXEKoCGEgiBW1OYW1lIhAIWBCqAhhIIgdtT3JpZ2luIhQIWRCqAhhQIgttVGltZVRvTGl2ZSIbCFoQqgIYSCISbVRpbWVkT3V0RXZlbnROYW1lIh4IWxCqAhiHASIUbVRpbWVkT3V0RXZlbnRQYXJhbXMiGghcEKoCGEgiEW1UcmlnZ2VyRXZlbnROYW1lIhgIXRCqAhhQIg9tVHJpZ2dlclRpbWVvdXQiHAheEKoCGEgiE21UcmlnZ2VyZWRFdmVudE5hbWUiHwhfEKoCGIcBIhVtVHJpZ2dlcmVkRXZlbnRQYXJhbXMiHAhgEKoCGFAiE21UcmlnZ2VyZWRUaW1lc3RhbXAiDwhhEKoCGG8iBm1WYWx1ZSIRCGIQqwIYrAIiB0NSRUFUT1IiGghjEIYDGIYDIhBERUZBVUxUX0lOU1RBTkNFIhAIZBCGAxiHAyIGUEFSU0VSIiEIZRCGAxhRIhhQUkVGRVJFTkNFU19GSUVMRF9OVU1CRVIiFghmEIYDGIgDIgxwcmVmZXJlbmNlc18iGghnEIkDGIkDIhBERUZBVUxUX0lOU1RBTkNFIhAIaBCJAxiHAyIGUEFSU0VSIh0IaRCJAxhRIhRTVFJJTkdTX0ZJRUxEX05VTUJFUiISCGoQiQMYigMiCHN0cmluZ3NfIh0IaxCLAxhRIhRCT09MRUFOX0ZJRUxEX05VTUJFUiIbCGwQiwMYUSISQllURVNfRklFTERfTlVNQkVSIhoIbRCLAxiLAyIQREVGQVVMVF9JTlNUQU5DRSIc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CN4DEMUDGFEiGkdPT0dMRV9BUFBfSURfRklFTERfTlVNQkVSIhEI3wMQxQMYwwMiBlBBUlNFUiIaCOADEMUDGMIDIg9hbmRyb2lkQXBwSW5mb18iGAjhAxDFAxhIIg5hcHBJbnN0YW5jZUlkXyIiCOIDEMUDGFEiGGFwcGxpY2F0aW9uUHJvY2Vzc1N0YXRlXyIUCOMDEMUDGFEiCmJpdEZpZWxkMF8iHAjkAxDFAxjGAyIRY3VzdG9tQXR0cmlidXRlc18iFgjlAxDFAxhIIgxnb29nbGVBcHBJZF8iJQjmAxDHAxhRIhtDTElFTlRfVElNRV9VU19GSUVMRF9OVU1CRVIiGwjnAxDHAxjHAyIQREVGQVVMVF9JTlNUQU5DRSIRCOgDEMcDGMMDIgZQQVJTRVIiJQjpAxDHAxhRIhtTWVNURU1fVElNRV9VU19GSUVMRF9OVU1CRVIiIwjqAxDHAxhRIhlVU0VSX1RJTUVfVVNfRklFTERfTlVNQkVSIhQI6wMQxwMYUSIKYml0RmllbGQwXyIXCOwDEMcDGFAiDWNsaWVudFRpbWVVc18iFwjtAxDHAxhQIg1zeXN0ZW1UaW1lVXNfIhUI7gMQxwMYUCILdXNlclRpbWVVc18iKAjvAxB3GFEiH0NQVV9DTE9DS19SQVRFX0tIWl9GSUVMRF9OVU1CRVIiKQjwAxB3GFEiIENQVV9QUk9DRVNTT1JfQ09VTlRfRklFTERfTlVNQkVSIhkI8QMQdxh3IhBERUZBVUxUX0lOU1RBTkNFIigI8gMQdxhRIh9ERVZJQ0VfUkFNX1NJWkVfS0JfRklFTERfTlVNQkVSIjEI8wMQdxhRIihNQVhfQVBQX0pBVkFfSEVBUF9NRU1PUllfS0JfRklFTERfTlVNQkVSIjwI9AMQdxhRIjNNQVhfRU5DT1VSQUdFRF9BUFBfSkFWQV9IRUFQX01FTU9SWV9LQl9GSUVMRF9OVU1CRVIiEAj1AxB3GMMDIgZQQVJTRVIiIgj2AxB3GFEiGVBST0NFU1NfTkFNRV9GSUVMRF9OVU1CRVIiEwj3AxB3GFEiCmJpdEZpZWxkMF8iGQj4AxB3GFEiEGNwdUNsb2NrUmF0ZUtoel8iGwj5AxB3GFEiEmNwdVByb2Nlc3NvckNvdW50XyIZCPoDEHcYUSIQZGV2aWNlUmFtU2l6ZUtiXyIgCPsDEHcYUSIXbWF4QXBwSmF2YUhlYXBNZW1vcnlLYl8iKgj8AxB3GFEiIW1heEVuY291cmFnZWRBcHBKYXZhSGVhcE1lbW9yeUtiXyIVCP0DEHcYSCIMcHJvY2Vzc05hbWVfIi4I/gMQyAMYUSIkQU5EUk9JRF9NRU1PUllfUkVBRElOR1NfRklFTERfTlVNQkVSIioI/wMQyAMYUSIgQ1BVX01FVFJJQ19SRUFESU5HU19GSUVMRF9OVU1CRVIiGwiABBDIAxjIAyIQREVGQVVMVF9JTlNUQU5DRSIlCIEEEMgDGFEiG0dBVUdFX01FVEFEQVRBX0ZJRUxEX05VTUJFUiIRCIIEEMgDGMMDIgZQQVJTRVIiIQiDBBDIAxhRIhdTRVNTSU9OX0lEX0ZJRUxEX05VTUJFUiIhCIQEEMgDGMkDIhZhbmRyb2lkTWVtb3J5UmVhZGluZ3NfIhQIhQQQyAMYUSIKYml0RmllbGQwXyIdCIYEEMgDGMkDIhJjcHVNZXRyaWNSZWFkaW5nc18iGAiHBBDIAxh3Ig5nYXVnZU1ldGFkYXRhXyIUCIgEEMgDGEgiCnNlc3Npb25JZF8iKwiJBBDKAxhRIiFDTElFTlRfU1RBUlRfVElNRV9VU19GSUVMRF9OVU1CRVIiKAiKBBDKAxhRIh5DVVNUT01fQVRUUklCVVRFU19GSUVMRF9OVU1CRVIiGwiLBBDKAxjKAyIQREVGQVVMVF9JTlNUQU5DRSIiCIwEEMoDGFEiGEhUVFBfTUVUSE9EX0ZJRUxEX05VTUJFUiIpCI0EEMoDGFEiH0hUVFBfUkVTUE9OU0VfQ09ERV9GSUVMRF9OVU1CRVIiMgiOBBDKAxhRIihORVRXT1JLX0NMSUVOVF9FUlJPUl9SRUFTT05fRklFTERfTlVNQkVSIhEIjwQQygMYwwMiBlBBUlNFUiIkCJAEEMoDGFEiGlBFUkZfU0VTU0lPTlNfRklFTERfTlVNQkVSIiwIkQQQygMYUSIiUkVRVUVTVF9QQVlMT0FEX0JZVEVTX0ZJRUxEX05VTUJFUiIsCJIEEMoDGFEiIlJFU1BPTlNFX0NPTlRFTlRfVFlQRV9GSUVMRF9OVU1CRVIiLQiTBBDKAxhRIiNSRVNQT05TRV9QQVlMT0FEX0JZVEVTX0ZJRUxEX05VTUJFUiIzCJQEEMoDGFEiKVRJTUVfVE9fUkVRVUVTVF9DT01QTEVURURfVVNfRklFTERfTlVNQkVSIjQIlQQQygMYUSIqVElNRV9UT19SRVNQT05TRV9DT01QTEVURURfVVNfRklFTERfTlVNQkVSIjQIlgQQygMYUSIqVElNRV9UT19SRVNQT05TRV9JTklUSUFURURfVVNfRklFTERfTlVNQkVSIhoIlwQQygMYUSIQVVJMX0ZJRUxEX05VTUJFUiIUCJgEEMoDGFEiCmJpdEZpZWxkMF8iHAiZBBDKAxhQIhJjbGllbnRTdGFydFRpbWVVc18iHAiaBBDKAxjGAyIRY3VzdG9tQXR0cmlidXRlc18iFQibBBDKAxhRIgtodHRwTWV0aG9kXyIbCJwEEMoDGFEiEWh0dHBSZXNwb25zZUNvZGVfIiMInQQQygMYUSIZbmV0d29ya0NsaWVudEVycm9yUmVhc29uXyIYCJ4EEMoDGMkDIg1wZXJmU2Vzc2lvbnNfIh4InwQQygMYUCIUcmVxdWVzdFBheWxvYWRCeXRlc18iHgigBBDKAxhIIhRyZXNwb25zZUNvbnRlbnRUeXBlXyIfCKEEEMoDGFAiFXJlc3BvbnNlUGF5bG9hZEJ5dGVzXyIjCKIEEMoDGFAiGXRpbWVUb1JlcXVlc3RDb21wbGV0ZWRVc18iJAijBBDKAxhQIhp0aW1lVG9SZXNwb25zZUNvbXBsZXRlZFVzXyIkCKQEEMoDGFAiGnRpbWVUb1Jlc3BvbnNlSW5pdGlhdGVkVXNfIg4IpQQQygMYSCIEdXJsXyInCKYEEMsDGFEiHUFQUExJQ0FUSU9OX0lORk9fRklFTERfTlVNQkVSIhsIpwQQywMYywMiEERFRkFVTFRfSU5TVEFOQ0UiIwioBBDLAxhRIhlHQVVHRV9NRVRSSUNfRklFTERfTlVNQkVSIi0IqQQQywMYUSIjTkVUV09SS19SRVFVRVNUX01FVFJJQ19GSUVMRF9OVU1CRVIiEQiqBBDLAxjDAyIGUEFSU0VSIiMIqwQQywMYUSIZVFJBQ0VfTUVUUklDX0ZJRUxEX05VTUJFUiIlCKwEEMsDGFEiG1RSQU5TUE9SVF9JTkZPX0ZJRUxEX05VTUJFUiIbCK0EEMsDGMUDIhBhcHBsaWNhdGlvbkluZm9fIhQIrgQQywMYUSIKYml0RmllbGQwXyIXCK8EEMsDGMgDIgxnYXVnZU1ldHJpY18iIAiwBBDLAxjKAyIVbmV0d29ya1JlcXVlc3RNZXRyaWNfIhcIsQQQywMYzAMiDHRyYWNlTWV0cmljXyIZCLIEEMsDGM0DIg50cmFuc3BvcnRJbmZvXyIbCLMEEM4DGM4DIhBERUZBVUxUX0lOU1RBTkNFIhEItAQQzgMYwwMiBlBBUlNFUiIhCLUEEM4DGFEiF1NFU1NJT05fSURfRklFTERfTlVNQkVSIigItgQQzgMYUSIeU0VTU0lPTl9WRVJCT1NJVFlfRklFTERfTlVNQkVSIhQItwQQzgMYUSIKYml0RmllbGQwXyIUCLgEEM4DGEgiCnNlc3Npb25JZF8iHAi5BBDOAxjPAyIRc2Vzc2lvblZlcmJvc2l0eV8iJgi6BBDOAxjQAyIbc2Vzc2lvblZlcmJvc2l0eV9jb252ZXJ0ZXJfIisIuwQQzAMYUSIhQ0xJRU5UX1NUQVJUX1RJTUVfVVNfRklFTERfTlVNQkVSIh8IvAQQzAMYUSIVQ09VTlRFUlNfRklFTERfTlVNQkVSIigIvQQQzAMYUSIeQ1VTVE9NX0FUVFJJQlVURVNfRklFTERfTlVNQkVSIhsIvgQQzAMYzAMiEERFRkFVTFRfSU5TVEFOQ0UiIgi/BBDMAxhRIhhEVVJBVElPTl9VU19GSUVMRF9OVU1CRVIiHgjABBDMAxhRIhRJU19BVVRPX0ZJRUxEX05VTUJFUiIbCMEEEMwDGFEiEU5BTUVfRklFTERfTlVNQkVSIhEIwgQQzAMYwwMiBlBBUlNFUiIkCMMEEMwDGFEiGlBFUkZfU0VTU0lPTlNfRklFTERfTlVNQkVSIiAIxAQQzAMYUSIWU1VCVFJBQ0VTX0ZJRUxEX05VTUJFUiIUCMUEEMwDGFEiCmJpdEZpZWxkMF8iHAjGBBDMAxhQIhJjbGllbnRTdGFydFRpbWVVc18iFAjHBBDMAxjGAyIJY291bnRlcnNfIhwIyAQQzAMYxgMiEWN1c3RvbUF0dHJpYnV0ZXNfIhUIyQQQzAMYUCILZHVyYXRpb25Vc18iEQjKBBDMAxhPIgdpc0F1dG9fIg8IywQQzAMYSCIFbmFtZV8iGAjMBBDMAxjJAyINcGVyZlNlc3Npb25zXyIVCM0EEMwDGMkDIgpzdWJ0cmFjZXNfIhsIzgQQzQMYzQMiEERFRkFVTFRfSU5TVEFOQ0UiKwjPBBDNAxhRIiFESVNQQVRDSF9ERVNUSU5BVElPTl9GSUVMRF9OVU1CRVIiEQjQBBDNAxjDAyIGUEFSU0VSIhQI0QQQzQMYUSIKYml0RmllbGQwXyIeCNIEEM0DGFEiFGRpc3BhdGNoRGVzdGluYXRpb25fIhoI0wQQ0QMYUSIQbWVtb2l6ZWRIYXNoQ29kZSIaCNQEENIDGNMDIg9kZWZhdWx0SW5zdGFuY2UiEwjVBBDSAxjTAyIIaW5zdGFuY2UiJwjWBBDTAxhRIh1NRU1PSVpFRF9TRVJJQUxJWkVEX1NJWkVfTUFTSyIbCNcEENMDGFEiEU1VVEFCTEVfRkxBR19NQVNLIiEI2AQQ0wMYUSIXVU5JTklUSUFMSVpFRF9IQVNIX0NPREUiJwjZBBDTAxhRIh1VTklOSVRJQUxJWkVEX1NFUklBTElaRURfU0laRSIcCNoEENMDGHMiEmRlZmF1bHRJbnN0YW5jZU1hcCIgCNsEENMDGFEiFm1lbW9pemVkU2VyaWFsaXplZFNpemUiGAjcBBDTAxjUAyINdW5rbm93bkZpZWxkcyIuCN0EENUDGFEiJEFVVEhPUkNIQU5HRUxJU1RWRVJTSU9OX0ZJRUxEX05VTUJFUiIzCN4EENUDGFEiKUJPT0tNQVJLRURfTkVXU19SRVNPVVJDRV9JRFNfRklFTERfTlVNQkVSIigI3wQQ1QMYUSIeREFSS19USEVNRV9DT05GSUdfRklFTERfTlVNQkVSIhsI4AQQ1QMY1QMiEERFRkFVTFRfSU5TVEFOQ0UiPgjhBBDVAxhRIjRERVBSRUNBVEVEX0JPT0tNQVJLRURfTkVXU19SRVNPVVJDRV9JRFNfRklFTERfTlVNQkVSIjUI4gQQ1QMYUSIrREVQUkVDQVRFRF9GT0xMT1dFRF9BVVRIT1JfSURTX0ZJRUxEX05VTUJFUiI0COMEENUDGFEiKkRFUFJFQ0FURURfRk9MTE9XRURfVE9QSUNfSURTX0ZJRUxEX05VTUJFUiI5COQEENUDGFEiL0RFUFJFQ0FURURfSU5UX0ZPTExPV0VEX0FVVEhPUl9JRFNfRklFTERfTlVNQkVSIjgI5QQQ1QMYUSIuREVQUkVDQVRFRF9JTlRfRk9MTE9XRURfVE9QSUNfSURTX0ZJRUxEX05VTUJFUiIqCOYEENUDGFEiIEZPTExPV0VEX0FVVEhPUl9JRFNfRklFTERfTlVNQkVSIikI5wQQ1QMYUSIfRk9MTE9XRURfVE9QSUNfSURTX0ZJRUxEX05VTUJFUiI6COgEENUDGFEiMEhBU19ET05FX0lOVF9UT19TVFJJTkdfSURfTUlHUkFUSU9OX0ZJRUxEX05VTUJFUiI1COkEENUDGFEiK0hBU19ET05FX0xJU1RfVE9fTUFQX01JR1JBVElPTl9GSUVMRF9OVU1CRVIiNAjqBBDVAxhRIipORVdTUkVTT1VSQ0VDSEFOR0VMSVNUVkVSU0lPTl9GSUVMRF9OVU1CRVIiEQjrBBDVAxjDAyIGUEFSU0VSIi0I7AQQ1QMYUSIjU0hPVUxEX0hJREVfT05CT0FSRElOR19GSUVMRF9OVU1CRVIiIgjtBBDVAxhRIhhUSEVNRV9CUkFORF9GSUVMRF9OVU1CRVIiLQjuBBDVAxhRIiNUT1BJQ0NIQU5HRUxJU1RWRVJTSU9OX0ZJRUxEX05VTUJFUiIoCO8EENUDGFEiHlVTRV9EWU5BTUlDX0NPTE9SX0ZJRUxEX05VTUJFUiIvCPAEENUDGFEiJVZJRVdFRF9ORVdTX1JFU09VUkNFX0lEU19GSUVMRF9OVU1CRVIiIgjxBBDVAxhRIhhhdXRob3JDaGFuZ2VMaXN0VmVyc2lvbl8iJQjyBBDVAxjGAyIaYm9va21hcmtlZE5ld3NSZXNvdXJjZUlkc18iGgjzBBDVAxhRIhBkYXJrVGhlbWVDb25maWdfIi8I9AQQ1QMYyQMiJGRlcHJlY2F0ZWRCb29rbWFya2VkTmV3c1Jlc291cmNlSWRzXyInCPUEENUDGMkDIhxkZXByZWNhdGVkRm9sbG93ZWRBdXRob3JJZHNfIiYI9gQQ1QMYyQMiG2RlcHJlY2F0ZWRGb2xsb3dlZFRvcGljSWRzXyI+CPcEENUDGFEiNGRlcHJlY2F0ZWRJbnRGb2xsb3dlZEF1dGhvcklkc01lbW9pemVkU2VyaWFsaXplZFNpemUiKgj4BBDVAxjPAyIfZGVwcmVjYXRlZEludEZvbGxvd2VkQXV0aG9ySWRzXyI9CPkEENUDGFEiM2RlcHJlY2F0ZWRJbnRGb2xsb3dl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CMYFEJwEGFEiC2RlYnVnU3RhdHVzIhwIxwUQngQYUSISX2RlY2lzaW9uJHZvbGF0aWxlIg8IyAUQnwQYbyIFX2hlYXAiGwjJBRCgBBhvIhFfZGVsYXllZCR2b2xhdGlsZSIfCMoFEKAEGFEiFV9pc0NvbXBsZXRlZCR2b2xhdGlsZSIZCMsFEKAEGG8iD19xdWV1ZSR2b2xhdGlsZSIbCMwFEKEEGFEiEV9pbnZva2VkJHZvbGF0aWxlIiQIzQUQogQYbyIaX2V4Y2VwdGlvbnNIb2xkZXIkdm9sYXRpbGUiIAjOBRCiBBhRIhZfaXNDb21wbGV0aW5nJHZvbGF0aWxlIh0IzwUQogQYbyITX3Jvb3RDYXVzZSR2b2xhdGlsZSIgCNAFEKMEGG8iFl9wYXJlbnRIYW5kbGUkdm9sYXRpbGUiGQjRBRCjBBhvIg9fc3RhdGUkdm9sYXRpbGUiGQjSBRCkBBhRIg9fc3RhdGUkdm9sYXRpbGUiGgjTBRClBBhPIhB0aHJlYWRMb2NhbElzU2V0IhUI1AUQpgQYbyILX3ByZUhhbmRsZXIiGAjVBRCnBBioBCINY2hvcmVvZ3JhcGhlciIeCNYFEKkEGG8iFF9jbG9zZUNhdXNlJHZvbGF0aWxlIhwI1wUQqQQYUCISYnVmZmVyRW5kJHZvbGF0aWxlIiMI2AUQqQQYbyIZYnVmZmVyRW5kU2VnbWVudCR2b2xhdGlsZSIfCNkFEKkEGG8iFWNsb3NlSGFuZGxlciR2b2xhdGlsZSI1CNoFEKkEGFAiK2NvbXBsZXRlZEV4cGFuZEJ1ZmZlcnNBbmRQYXVzZUZsYWckdm9sYXRpbGUiIQjbBRCpBBhvIhdyZWNlaXZlU2VnbWVudCR2b2xhdGlsZSIcCNwFEKkEGFAiEnJlY2VpdmVycyR2b2xhdGlsZSIeCN0FEKkEGG8iFHNlbmRTZWdtZW50JHZvbGF0aWxlIigI3gUQqQQYUCIec2VuZGVyc0FuZENsb3NlU3RhdHVzJHZvbGF0aWxlIhkI3wUQqgQYbyIPX3N0YXRlJHZvbGF0aWxlIhgI4AUQqwQYbyIOX25leHQkdm9sYXRpbGUiGAjhBRCrBBhvIg5fcHJldiR2b2xhdGlsZSIzCOIFEKwEGG8iKV9yZXVzYWJsZUNhbmNlbGxhYmxlQ29udGludWF0aW9uJHZvbGF0aWxlIiEI4wUQrQQYUSIXcnVubmluZ1dvcmtlcnMkdm9sYXRpbGUiGAjkBRCuBBhvIg5fbmV4dCR2b2xhdGlsZSIYCOUFEK4EGG8iDl9wcmV2JHZvbGF0aWxlIh4I5gUQrgQYbyIUX3JlbW92ZWRSZWYkdm9sYXRpbGUiFwjnBRCvBBhvIg1fY3VyJHZvbGF0aWxlIhgI6AUQsAQYbyIOX25leHQkdm9sYXRpbGUiGQjpBRCwBBhQIg9fc3RhdGUkdm9sYXRpbGUiEAjqBRCxBBiyBCIFYXJyYXkiJQjrBRCzBBhRIhtjbGVhbmVkQW5kUG9pbnRlcnMkdm9sYXRpbGUiGAjsBRC0BBhRIg5fc2l6ZSR2b2xhdGlsZSIWCO0FELUEGFEiDGluZGV4SW5BcnJheSIaCO4FELUEGG8iEG5leHRQYXJrZWRXb3JrZXIiHAjvBRC1BBhRIhJ3b3JrZXJDdGwkdm9sYXRpbGUiIAjwBRC2BBhRIhZfaXNUZXJtaW5hdGVkJHZvbGF0aWxlIh8I8QUQtgQYUCIVY29udHJvbFN0YXRlJHZvbGF0aWxlIiUI8gUQtgQYUCIbcGFya2VkV29ya2Vyc1N0YWNrJHZvbGF0aWxlIigI8wUQtwQYUSIeYmxvY2tpbmdUYXNrc0luQnVmZmVyJHZvbGF0aWxlIiAI9AUQtwQYUSIWY29uc3VtZXJJbmRleCR2b2xhdGlsZSIkCPUFELcEGG8iGmxhc3RTY2hlZHVsZWRUYXNrJHZvbGF0aWxlIiAI9gUQtwQYUSIWcHJvZHVjZXJJbmRleCR2b2xhdGlsZSIYCPcFELgEGG8iDm93bmVyJHZvbGF0aWxlIiQI+AUQuQQYUSIaX2F2YWlsYWJsZVBlcm1pdHMkdm9sYXRpbGUiGQj5BRC5BBhQIg9kZXFJZHgkdm9sYXRpbGUiGQj6BRC5BBhQIg9lbnFJZHgkdm9sYXRpbGUiFwj7BRC5BBhvIg1oZWFkJHZvbGF0aWxlIhcI/AUQuQQYbyINdGFpbCR2b2xhdGlsZSITCP0FENYFGMEHIggkRU5UUklFUyISCP4FENYFGNcFIgckVkFMVUVTIhQI/wUQ1gUYwgciCUNvbXBhbmlvbiIRCIAGENYFGNYFIgZPTl9BTlkiFAiBBhDWBRjWBSIJT05fQ1JFQVRFIhUIggYQ1gUY1gUiCk9OX0RFU1RST1kiEwiDBhDWBRjWBSIIT05fUEFVU0UiFAiEBhDWBRjWBSIJT05fUkVTVU1FIhMIhQYQ1gUY1gUiCE9OX1NUQVJUIhIIhgYQ1gUY1gUiB09OX1NUT1AiFQiHBhDbCBjcCCIKZGVzY3JpcHRvciIVCIgGEN0IGNwIIgpkZXNjcmlwdG9yIhUIiQYQ3ggY3AgiCmRlc2NyaXB0b3IiFQiKBhDfCBjcCCIKZGVzY3JpcHRvciIVCIsGEOAIGNwIIgpkZXNjcmlwdG9yIhUIjAYQ4QgY3AgiCmRlc2NyaXB0b3IiFQiNBhDiCBjcCCIKZGVzY3JpcHRvcioOEAYiCnNlcmlhbGl6ZXIqEAgBEAciCnNlcmlhbGl6ZXIqEAgCEAkiCnNlcmlhbGl6ZXIqEAgDEBMiCnNlcmlhbGl6ZXIqEggEEBYYASIKc2VyaWFsaXplcioSCAUQFxgBIgpzZXJpYWxpemVyKhAIBhAYIgpzZXJpYWxpemVyKhAIBxAZIgpzZXJpYWxpemVyKhAICBAaIgpzZXJpYWxpemVyKhIICRAbGAEiCnNlcmlhbGl6ZXIqEAgKEBwiCnNlcmlhbGl6ZXIqEAgLEB0iCnNlcmlhbGl6ZXIqEAgMEB4iCnNlcmlhbGl6ZXIqEAgNEB8iCnNlcmlhbGl6ZXIqEAgOECAiCnNlcmlhbGl6ZXIqEAgPECEiCnNlcmlhbGl6ZXIqEAgQECIiCnNlcmlhbGl6ZXIqEAgRECMiCnNlcmlhbGl6ZXIqEAgSECQiCnNlcmlhbGl6ZXIqEAgTECUiCnNlcmlhbGl6ZXIqEAgUECYiCnNlcmlhbGl6ZXIqEAgVECciCnNlcmlhbGl6ZXIqHAgWECkYAiIUb25EZXZpY2VTdGF0ZUNoYW5nZWQqHQgXECkYAyIVb25XaW5kb3dMYXlvdXRDaGFuZ2VkKhwIGBAqGAIiFG9uRGV2aWNlU3RhdGVDaGFuZ2VkKh0IGRAqGAMiFW9uV2luZG93TGF5b3V0Q2hhbmdlZCoOCBoQMBgEIgY8aW5pdD4qDggbEDEYBCIGPGluaXQ+Kg4IHBAyGAQiBjxpbml0PioOCB0QMxgEIgY8aW5pdD4qDggeEDMYBSIGY3JlYXRlKg4IHxA0GAQiBjxpbml0PioVCCAQNBgGIg1nZXRDb21wb25lbnRzKg4IIRA1GAQiBjxpbml0PioVCCIQNRgGIg1nZXRDb21wb25lbnRzKh4IIxA1GAciFmxhbWJkYSRnZXRDb21wb25lbnRzJDAqDggkEDYYBCIGPGluaXQ+KhUIJRA2GAYiDWdldENvbXBvbmVudHMqHggmEDYYCCIWbGFtYmRhJGdldENvbXBvbmVudHMkMCoOCCcQNxgEIgY8aW5pdD4qFQgoEDcYBiINZ2V0Q29tcG9uZW50cyoOCCkQOBgEIgY8aW5pdD4qFQgqEDgYBiINZ2V0Q29tcG9uZW50cyoOCCsQORgEIgY8aW5pdD4qFQgsEDkYBiINZ2V0Q29tcG9uZW50cyoeCC0QORgJIhZsYW1iZGEkZ2V0Q29tcG9uZW50cyQwKh4ILhA5GAkiFmxhbWJkYSRnZXRDb21wb25lbnRzJDEqHggvEDkYCSIWbGFtYmRhJGdldENvbXBvbmVudHMkMioOCDAQOhgEIgY8aW5pdD4qFQgxEDoYBiINZ2V0Q29tcG9uZW50cyoeCDIQOhgKIhZsYW1iZGEkZ2V0Q29tcG9uZW50cyQwKg4IMxA7GAQiBjxpbml0PioVCDQQOxgGIg1nZXRDb21wb25lbnRzKg4INRA8GAQiBjxpbml0PioVCDYQPBgGIg1nZXRDb21wb25lbnRzKg4INxA9GAQiBjxpbml0PioVCDgQPRgGIg1nZXRDb21wb25lbnRzKh4IORA9GAsiFmxhbWJkYSRnZXRDb21wb25lbnRzJDAqDgg6ED4YBCIGPGluaXQ+KhUIOxA+GAYiDWdldENvbXBvbmVudHMqDgg8ED8YBCIGPGluaXQ+KhUIPRA/GAYiDWdldENvbXBvbmVudHMqHgg+ED8YDCIWbGFtYmRhJGdldENvbXBvbmVudHMkMCojCD8QPxgNIhtwcm92aWRlc0ZpcmViYXNlUGVyZm9ybWFuY2UqEwhAEEsYDiILZ2V0QXBwU3RhdGUqGwhBEEsYDyITZ2V0QXBwU3RhdGVDYWxsYmFjayoaCEIQSxgQIhJpbmNyZW1lbnRUc25zQ291bnQqGwhDEEsYBCITcmVnaXN0ZXJGb3JBcHBTdGF0ZSodCEQQSxgEIhV1bnJlZ2lzdGVyRm9yQXBwU3RhdGUqDghFEEAYBCIGPGluaXQ+Kg4IRhBAGBEiBjxpbml0PioSCEcQQBgSIgpnZXRCb29sZWFuKiIISBBAGBMiGmdldEN1cnJlbnRTeXN0ZW1UaW1lTWlsbGlzKhEISRBAGBIiCWdldERvdWJsZSofCEoQQBgTIhdnZXRJbml0aWFsU3RhcnR1cE1pbGxpcyoTCEsQQBgUIgtnZXRJbnN0YW5jZSoPCEwQQBgSIgdnZXRMb25nKhwITRBAGBUiFGdldFJlbW90ZUNvbmZpZ1ZhbHVlKiUIThBAGBYiHWdldFJlbW90ZUNvbmZpZ1ZhbHVlT3JEZWZhdWx0KhEITxBAGBIiCWdldFN0cmluZyoWCFAQQBgXIg5nZXRWZXJzaW9uQ29kZSoqCFEQQBgYIiJoYXNBcHBTdGFydENvbmZpZ0ZldGNoRGVsYXlFbGFwc2VkKh8IUhBAGBgiF2hhc0xhc3RGZXRjaEJlY29tZVN0YWxlKicIUxBAGBkiH2lzRmlyZWJhc2VSZW1vdGVDb25maWdBdmFpbGFibGUqGQhUEEAYGSIRaXNMYXN0RmV0Y2hGYWlsZWQqTQhVEEAYGiJFbGFtYmRhJHRyaWdnZXJGaXJlYmFzZVJlbW90ZUNvbmZpZ0ZldGNoQW5kQWN0aXZhdGVPblN1Y2Nlc3NmdWxGZXRjaCQwKk0IVhBAGBsiRWxhbWJkYSR0cmlnZ2VyRmlyZWJhc2VSZW1vdGVDb25maWdGZXRjaEFuZEFjdGl2YXRlT25TdWNjZXNzZnVsRmV0Y2gkMSonCFcQQBgcIh9zZXRGaXJlYmFzZVJlbW90ZUNvbmZpZ1Byb3ZpZGVyKjAIWBBAGBkiKHNob3VsZEZldGNoQW5kQWN0aXZhdGVSZW1vdGVDb25maWdWYWx1ZXMqGAhZEEAYHSIQc3luY0NvbmZpZ1ZhbHVlcypECFoQQBgEIjx0cmlnZ2VyRmlyZWJhc2VSZW1vdGVDb25maWdGZXRjaEFuZEFjdGl2YXRlT25TdWNjZXNzZnVsRmV0Y2gqKwhbEEAYBCIjdHJpZ2dlclJlbW90ZUNvbmZpZ0ZldGNoSWZOZWNlc3NhcnkqDghcEEEYBCIGPGluaXQ+KhUIXRBBGAYiDWdldENvbXBvbmVudHMqDgheEEIYBCIGPGluaXQ+Kg4IXxBCGB4iBjxpbml0PioTCGAQQhgfIgtnZXRJbnN0YW5jZSoZCGEQQhggIhFnZXRTeW5jSW5pdEZ1dHVyZSohCGIQQhgEIhlpbml0aWFsaXplR2F1Z2VDb2xsZWN0aW9uKiYIYxBCGCEiHmxhbWJkYSRzZXRBcHBsaWNhdGlvbkNvbnRleHQkMCorCGQQQhgiIiNsb2dHYXVnZU1ldGFkYXRhSWZDb2xsZWN0aW9uRW5hYmxlZCoYCGUQQhgiIhBvblVwZGF0ZUFwcFN0YXRlKhMIZhBCGCMiC3BlcmZTZXNzaW9uKiEIZxBCGCQiGXJlZ2lzdGVyRm9yU2Vzc2lvblVwZGF0ZXMqHQhoEEIYJSIVc2V0QXBwbGljYXRpb25Db250ZXh0KhYIaRBCGCYiDnNldFBlcmZTZXNzaW9uKiMIahBCGCIiG3N0YXJ0T3JTdG9wQ29sbGVjdGluZ0dhdWdlcyoyCGsQQhgEIipzdG9wR2F1Z2VDb2xsZWN0aW9uSWZTZXNzaW9uUnVubmluZ1Rvb0xvbmcqIwhsEEIYJCIbdW5yZWdpc3RlckZvclNlc3Npb25VcGRhdGVzKhkIbRBCGCYiEXVwZGF0ZVBlcmZTZXNzaW9uKg4IbhBDGAQiBjxpbml0PioOCG8QQxgnIgY8aW5pdD4qHghwEEMYKCIWY29sbGVjdEdhdWdlTWV0cmljT25jZSoeCHEQQxgpIhZjb2xsZWN0R2F1Z2VNZXRyaWNPbmNlKigIchBDGCoiIGdldENwdUdhdWdlQ29sbGVjdGlvbkZyZXF1ZW5jeU1zKhgIcxBDGCsiEGdldEdhdWdlTWV0YWRhdGEqEwh0EEMYLCILZ2V0SW5zdGFuY2UqKwh1EEMYKiIjZ2V0TWVtb3J5R2F1Z2VDb2xsZWN0aW9uRnJlcXVlbmN5TXMqJgh2EEMYJSIeaW5pdGlhbGl6ZUdhdWdlTWV0YWRhdGFNYW5hZ2VyKhQIdxBDGC0iDGxhbWJkYSRuZXckMCoUCHgQQxguIgxsYW1iZGEkbmV3JDEqJgh5EEMYLyIebGFtYmRhJHN0YXJ0Q29sbGVjdGluZ0dhdWdlcyQyKiUIehBDGC8iHWxhbWJkYSRzdG9wQ29sbGVjdGluZ0dhdWdlcyQzKhgIexBDGDAiEGxvZ0dhdWdlTWV0YWRhdGEqIQh8EEMYMSIZc3RhcnRDb2xsZWN0aW5nQ3B1TWV0cmljcyodCH0QQxgyIhVzdGFydENvbGxlY3RpbmdHYXVnZXMqHQh+EEMYMyIVc3RhcnRDb2xsZWN0aW5nR2F1Z2VzKiQIfxBDGDEiHHN0YXJ0Q29sbGVjdGluZ01lbW9yeU1ldHJpY3MqHQiAARBDGAQiFHN0b3BDb2xsZWN0aW5nR2F1Z2VzKhIIgQEQQxgvIglzeW5jRmx1c2gqDwiCARBEGAQiBjxpbml0PioWCIMBEEQYBiINZ2V0Q29tcG9uZW50cyoPCIQBEEUYBCIGPGluaXQ+KhYIhQEQRRgGIg1nZXRDb21wb25lbnRzKh8IhgEQRRg0IhZsYW1iZGEkZ2V0Q29tcG9uZW50cyQwKg8IhwEQRhgEIgY8aW5pdD4qFgiIARBGGAYiDWdldENvbXBvbmVudHMqDwiJARBHGAQiBjxpbml0PioWCIoBEEcYBiINZ2V0Q29tcG9uZW50cyofCIsBEEcYNSIWZ2V0Q29tcG9uZW50cyRsYW1iZGEkMCofCIwBEEcYNiIWZ2V0Q29tcG9uZW50cyRsYW1iZGEkMSofCI0BEEcYNyIWZ2V0Q29tcG9uZW50cyRsYW1iZGEkMiofCI4BEEcYOCIWZ2V0Q29tcG9uZW50cyRsYW1iZGEkMyofCI8BEEcYOSIWZ2V0Q29tcG9uZW50cyRsYW1iZGEkNCofCJABEEcYOiIWZ2V0Q29tcG9uZW50cyRsYW1iZGEkNSoPCJEBEH8YBCIGPGluaXQ+KhAIkgEQgAEYBCIGPGluaXQ+KhIIkwEQgwEYOyIIYXNCaW5kZXIqFAiUARCDARg8IgpvblRyYW5zYWN0KhUIlQEQhQEYPSILYXNJbnRlcmZhY2UqEAiWARCBARgEIgY8aW5pdD4qHQiXARCBARg+IhNiZWdpbkFkVW5pdEV4cG9zdXJlKiYImAEQgQEYPyIcY2xlYXJDb25kaXRpb25hbFVzZXJQcm9wZXJ0eSohCJkBEIEBGEAiF2NsZWFyTWVhc3VyZW1lbnRFbmFibGVkKhsImgEQgQEYPiIRZW5kQWRVbml0RXhwb3N1cmUqGQibARCBARhBIg9nZW5lcmF0ZUV2ZW50SWQqGgicARCBARhBIhBnZXRBcHBJbnN0YW5jZUlkKiAInQEQgQEYQSIWZ2V0Q2FjaGVkQXBwSW5zdGFuY2VJZComCJ4BEIEBGEIiHGdldENvbmRpdGlvbmFsVXNlclByb3BlcnRpZXMqHwifARCBARhBIhVnZXRDdXJyZW50U2NyZWVuQ2xhc3MqHgigARCBARhBIhRnZXRDdXJyZW50U2NyZWVuTmFtZSoVCKEBEIEBGEEiC2dldEdtcEFwcElkKh4IogEQgQEYQyIUZ2V0TWF4VXNlclByb3BlcnRpZXMqFgijARCBARhBIgxnZXRTZXNzaW9uSWQqFQikARCBARhEIgtnZXRUZXN0RmxhZyobCKUBEIEBGEUiEWdldFVzZXJQcm9wZXJ0aWVzKhYIpgEQgQEYHSIMaW5pdEZvclRlc3RzKhQIpwEQgQEYRiIKaW5pdGlhbGl6ZSohCKgBEIEBGEEiF2lzRGF0YUNvbGxlY3Rpb25FbmFibGVkKhIIqQEQgQEYRyIIbG9nRXZlbnQqGwiqARCBARhIIhFsb2dFdmVudEFuZEJ1bmRsZSoXCKsBEIEBGEkiDWxvZ0hlYWx0aERhdGEqGwisARCBARhKIhFvbkFjdGl2aXR5Q3JlYXRlZCodCK0BEIEBGEsiE29uQWN0aXZpdHlEZXN0cm95ZWQqGgiuARCBARhLIhBvbkFjdGl2aXR5UGF1c2VkKhsIrwEQgQEYSyIRb25BY3Rpdml0eVJlc3VtZWQqJQiwARCBARhMIhtvbkFjdGl2aXR5U2F2ZUluc3RhbmNlU3RhdGUqGwixARCBARhLIhFvbkFjdGl2aXR5U3RhcnRlZCobCLIBEIEBGEsiEW9uQWN0aXZpdHlTdG9wcGVkKhcIswEQgQEYTSINcGVyZm9ybUFjdGlvbiosCLQBEIEBGE4iInJlZ2lzdGVyT25NZWFzdXJlbWVudEV2ZW50TGlzdGVuZXIqHAi1ARCBARhAIhJyZXNldEFuYWx5dGljc0RhdGEqJAi2ARCBARhPIhpzZXRDb25kaXRpb25hbFVzZXJQcm9wZXJ0eSoUCLcBEIEBGE8iCnNldENvbnNlbnQqHgi4ARCBARhPIhRzZXRDb25zZW50VGhpcmRQYXJ0eSoaCLkBEIEBGFAiEHNldEN1cnJlbnRTY3JlZW4qIgi6ARCBARhRIhhzZXREYXRhQ29sbGVjdGlvbkVuYWJsZWQqIwi7ARCBARhSIhlzZXREZWZhdWx0RXZlbnRQYXJhbWV0ZXJzKh0IvAEQgQEYTiITc2V0RXZlbnRJbnRlcmNlcHRvciofCL0BEIEBGFMiFXNldEluc3RhbmNlSWRQcm92aWRlciofCL4BEIEBGFQiFXNldE1lYXN1cmVtZW50RW5hYmxlZCojCL8BEIEBGEAiGXNldE1pbmltdW1TZXNzaW9uRHVyYXRpb24qIwjAARCBARhAIhlzZXRTZXNzaW9uVGltZW91dER1cmF0aW9uKhoIwQEQgQEYVSIQc2V0U2d0bURlYnVnSW5mbyoTCMIBEIEBGD4iCXNldFVzZXJJZCoZCMMBEIEBGFYiD3NldFVzZXJQcm9wZXJ0eSouCMQBEIEBGE4iJHVucmVnaXN0ZXJPbk1lYXN1cmVtZW50RXZlbnRMaXN0ZW5lcioQCMUBEJEBGAQiBjxpbml0PioQCMYBEJIBGAQiBjxpbml0PioQCMcBEJMBGAQiBjxpbml0PioQCMgBEJQBGAQiBjxpbml0PioQCMkBEJUBGAQiBjxpbml0PioQCMoBEJYBGAQiBjxpbml0PioQCMsBEJcBGAQiBjxpbml0PioQCMwBEJgBGAQiBjxpbml0PioQCM0BEJkBGAQiBjxpbml0PioQCM4BEJoBGAQiBjxpbml0PiogCM8BEKcBGFciFmdldFByZXNlbnRhdGlvbkNvbnRleHQqHQjQARCnARhYIhNzZXRQcmVzZW50YXRpb25WaWV3KiUI0QEQqAEYWSIbZ2V0V2luZG93QXJlYURpc3BsYXlNZXRyaWNzKh0I0gEQqAEYWiITZ2V0V2luZG93QXJlYVN0YXR1cyoyCNMBEKkBGFsiKGFkZFJlYXJEaXNwbGF5UHJlc2VudGF0aW9uU3RhdHVzTGlzdGVuZXIqJgjUARCpARhbIhxhZGRSZWFyRGlzcGxheVN0YXR1c0xpc3RlbmVyKisI1QEQqQEYBCIhZW5kUmVhckRpc3BsYXlQcmVzZW50YXRpb25TZXNzaW9uKh8I1gEQqQEYBCIVZW5kUmVhckRpc3BsYXlTZXNzaW9uKh8I1wEQqQEYWSIVZ2V0UmVhckRpc3BsYXlNZXRyaWNzKiQI2AEQqQEYXCIaZ2V0UmVhckRpc3BsYXlQcmVzZW50YXRpb24qNQjZARCpARhbIityZW1vdmVSZWFyRGlzcGxheVByZXNlbnRhdGlvblN0YXR1c0xpc3RlbmVyKikI2gEQqQEYWyIfcmVtb3ZlUmVhckRpc3BsYXlTdGF0dXNMaXN0ZW5lciotCNsBEKkBGF0iI3N0YXJ0UmVhckRpc3BsYXlQcmVzZW50YXRpb25TZXNzaW9uKiEI3AEQqQEYXSIXc3RhcnRSZWFyRGlzcGxheVNlc3Npb24qEAjdARCvARheIgZhY2NlcHQqDwjeARCwARhfIgVhcHBseSoOCN8BELEBGGAiBHRlc3QqEAjgARCyARgEIgY8aW5pdD4qDgjhARCyARhhIgRyZWFkKg8I4gEQsgEYYiIFd3JpdGUqEAjjARCzARgEIgY8aW5pdD4qDgjkARCzARhjIgRyZWFkKg8I5QEQswEYZCIFd3JpdGUqEAjmARC1ARgEIgY8aW5pdD4qDgjnARC1ARhhIgRyZWFkKg8I6AEQtQEYYiIFd3JpdGUqEAjpARC2ARgEIgY8aW5pdD4qDgjqARC2ARhjIgRyZWFkKg8I6wEQtgEYZCIFd3JpdGUqEAjsARChAhhlIgZhY2NlcHQqIwjtARCkAhhmIhlpbnRlcm5hbENvbmljVG9RdWFkcmF0aWNzKiQI7gEQpQIYZyIaY3JlYXRlSW50ZXJuYWxQYXRoSXRlcmF0b3IqJQjvARClAhhAIhtkZXN0cm95SW50ZXJuYWxQYXRoSXRlcmF0b3IqJQjwARClAhgYIhtpbnRlcm5hbFBhdGhJdGVyYXRvckhhc05leHQqIgjxARClAhhoIhhpbnRlcm5hbFBhdGhJdGVyYXRvck5leHQqIgjyARClAhhpIhhpbnRlcm5hbFBhdGhJdGVyYXRvclBlZWsqJQjzARClAhhpIhtpbnRlcm5hbFBhdGhJdGVyYXRvclJhd1NpemUqIgj0ARClAhhpIhhpbnRlcm5hbFBhdGhJdGVyYXRvclNpemUqJAj1ARCmAhgEIhpuYXRpdmVSZWdpc3RlcldpdGhQZXJmZXR0byofCPYBEKYCGGoiFW5hdGl2ZVRyYWNlRXZlbnRCZWdpbiodCPcBEKYCGAQiE25hdGl2ZVRyYWNlRXZlbnRFbmQqFwj4ARCmAhhrIg1uYXRpdmVWZXJzaW9uKikI+QEQrQIYbCIfZ2V0Q2hpbWVyYUxpZmVjeWNsZUZyYWdtZW50SW1wbCodCPoBEK4CGG0iE2JlZ2luQWRVbml0RXhwb3N1cmUqJgj7ARCuAhg/IhxjbGVhckNvbmRpdGlvbmFsVXNlclByb3BlcnR5KhsI/AEQrgIYbSIRZW5kQWRVbml0RXhwb3N1cmUqGQj9ARCuAhgTIg9nZW5lcmF0ZUV2ZW50SWQqGgj+ARCuAhhrIhBnZXRBcHBJbnN0YW5jZUlkKiYI/wEQrgIYbiIcZ2V0Q29uZGl0aW9uYWxVc2VyUHJvcGVydGllcyofCIACEK4CGGsiFWdldEN1cnJlbnRTY3JlZW5DbGFzcyoeCIECEK4CGGsiFGdldEN1cnJlbnRTY3JlZW5OYW1lKhUIggIQrgIYayILZ2V0R21wQXBwSWQqFQiDAhCuAhhvIgtnZXRJbnN0YW5jZSoeCIQCEK4CGHAiFGdldE1heFVzZXJQcm9wZXJ0aWVzKhsIhQIQrgIYcSIRZ2V0VXNlclByb3BlcnRpZXMqGgiGAhCuAhg/IhBsb2dFdmVudEludGVybmFsKiQIhwIQrgIYciIac2V0Q29uZGl0aW9uYWxVc2VyUHJvcGVydHkqHwiIAhCvAhhrIhVnZXRGaXJlYmFzZUluc3RhbmNlSWQqFQiJAhCvAhhzIgtnZXRJbnN0YW5jZSorCIoCEK8CGHQiIWdldFNjaW9uRnJvbnRlbmRBcGlJbXBsZW1lbnRhdGlvbioaCIsCEK8CGHUiEHNldEN1cnJlbnRTY3JlZW4qFAiMAhBqGHYiC2dldEluc3RhbmNlKiAIjQIQsAIYBCIWb25BcHBFbnRlcmVkQmFja2dyb3VuZCogCI4CELACGAQiFm9uQXBwRW50ZXJlZEZvcmVncm91bmQqKQiPAhCwAhhtIh9zZXRMYXVuY2hlckFjdGl2aXR5T25DcmVhdGVUaW1lKikIkAIQsAIYbSIfc2V0TGF1bmNoZXJBY3Rpdml0eU9uUmVzdW1lVGltZSooCJECELACGG0iHnNldExhdW5jaGVyQWN0aXZpdHlPblN0YXJ0VGltZSoaCJICEKsCGFoiEGRlc2NyaWJlQ29udGVudHMqFgiTAhCrAhh3IgxnZXRBdHRyaWJ1dGUqFwiUAhCrAhh4Ig1nZXRBdHRyaWJ1dGVzKhcIlQIQqwIYeSINZ2V0TG9uZ01ldHJpYyoZCJYCEKsCGD4iD2luY3JlbWVudE1ldHJpYyoWCJcCEKsCGHoiDHB1dEF0dHJpYnV0ZSoTCJgCEKsCGD4iCXB1dE1ldHJpYyoZCJkCEKsCGG0iD3JlbW92ZUF0dHJpYnV0ZSoPCJoCEKsCGAQiBXN0YXJ0Kg4ImwIQqwIYBCIEc3RvcCoXCJwCEKsCGHsiDXdyaXRlVG9QYXJjZWwqEQidAhCxAhh8IgdleGVjdXRlKhEIngIQsQIYfSIHZXhlY3V0ZSoRCJ8CELECGH4iB2V4ZWN1dGUqEQigAhCxAhh/IgdleGVjdXRlKhIIoQIQsQIYgAEiB2V4ZWN1dGUqEgiiAhCxAhiBASIHZXhlY3V0ZSoSCKMCELECGIIBIgdleGVjdXRlKhIIpAIQsQIYgwEiB2V4ZWN1dGUqEgilAhCyAhiEASIHZW5xdWV1ZSoSCKYCELICGIUBIgdleGVjdXRlKhUIpwIQswIYhgEiCmdldENvbnRlbnQqFQioAhCzAhiHASIKZ2V0Q29udGVudCoUCKkCELMCGF8iCmluc3RydW1lbnQqFQiqAhCzAhiIASIKb3BlblN0cmVhbSoQCKsCELQCGIkBIgVmZXRjaCoQCKwCEMoCGAQiBjxpbml0PioQCK0CEMsCGAQiBjxpbml0PiolCK4CEMsCGIoBIhpjb21wdXRlQW5kU2V0VGV4dERpcmVjdGlvbioQCK8CEM4CGAQiBjxpbml0PiolCLACEM4CGIoBIhpjb21wdXRlQW5kU2V0VGV4dERpcmVjdGlvbiojCLECEM4CGIsBIhhpc0hvcml6b250YWxseVNjcm9sbGFibGUqEAiyAhDPAhgEIgY8aW5pdD4qJQizAhDPAhiKASIaY29tcHV0ZUFuZFNldFRleHREaXJlY3Rpb24qIwi0AhDPAhiLASIYaXNIb3Jpem9udGFsbHlTY3JvbGxhYmxlKhoItQIQ0AIYjAEiD3NldEJpZ0xhcmdlSWNvbioYCLYCENMCGIwBIg1zZXRCaWdQaWN0dXJlKiAItwIQ0wIYjQEiFXNldENvbnRlbnREZXNjcmlwdGlvbiomCLgCENMCGI4BIhtzaG93QmlnUGljdHVyZVdoZW5Db2xsYXBzZWQqFQi5AhDVAhiPASIKdG9QbGF0Zm9ybSoVCLoCENgCGI8BIgp0b1BsYXRmb3JtKhAIuwIQ2QIYkAEiBWJ1aWxkKhgIvAIQ2QIYkQEiDWNyZWF0ZUJ1aWxkZXIqGQi9AhDZAhiSASIOc2V0Q29udGVudFR5cGUqEwi+AhDZAhiSASIIc2V0VXNhZ2UqJAi/AhDcAhiTASIZZGlzcGF0Y2hBcHBseVdpbmRvd0luc2V0cyoeCMACENwCGJMBIhNvbkFwcGx5V2luZG93SW5zZXRzKhwIwQIQ3AIYWCIScmVxdWVzdEFwcGx5SW5zZXRzKhEIwgIQ3gIYlAEiBjxpbml0PioeCMMCEN4CGJMBIhNvbkFwcGx5V2luZG93SW5zZXRzKisIxAIQ4AIYlQEiIGNhbGxDb21wYXRJbnNldEFuaW1hdGlvbkNhbGxiYWNrKiQIxQIQ4AIYlgEiGWNvbXB1dGVTeXN0ZW1XaW5kb3dJbnNldHMqIAjGAhDgAhiXASIVZ2V0QmFja2dyb3VuZFRpbnRMaXN0KiAIxwIQ4AIYmAEiFWdldEJhY2tncm91bmRUaW50TW9kZSocCMgCEOACGJkBIhFnZXRUcmFuc2l0aW9uTmFtZSogCMkCEOACGJoBIhVzZXRCYWNrZ3JvdW5kVGludExpc3QqIAjKAhDgAhibASIVc2V0QmFja2dyb3VuZFRpbnRNb2RlKhcIywIQ4AIYnAEiDHNldEVsZXZhdGlvbiopCMwCEOACGJQBIh5zZXRPbkFwcGx5V2luZG93SW5zZXRzTGlzdGVuZXIqHAjNAhDgAhidASIRc2V0VHJhbnNpdGlvbk5hbWUqGgjOAhDgAhhYIhBzdG9wTmVzdGVkU2Nyb2xsKh4IzwIQ5QIYngEiE2dldFJvb3RXaW5kb3dJbnNldHMqHgjQAhDlAhifASITc2V0U2Nyb2xsSW5kaWNhdG9ycyokCNECEOYCGKABIhlnZXRBY2Nlc3NpYmlsaXR5UGFuZVRpdGxlKiEI0gIQ5gIYoQEiFmlzQWNjZXNzaWJpbGl0eUhlYWRpbmcqIgjTAhDmAhihASIXaXNTY3JlZW5SZWFkZXJGb2N1c2FibGUqIgjUAhDmAhiiASIXc2V0QWNjZXNzaWJpbGl0eUhlYWRpbmcqJAjVAhDmAhijASIZc2V0QWNjZXNzaWJpbGl0eVBhbmVUaXRsZSojCNYCEOYCGKIBIhhzZXRTY3JlZW5SZWFkZXJGb2N1c2FibGUqIwjXAhDnAhikASIYZ2V0QWNjZXNzaWJpbGl0eURlbGVnYXRlKigI2AIQ5wIYpQEiHXNhdmVBdHRyaWJ1dGVEYXRhRm9yU3R5bGVhYmxlKiQI2QIQ7AIYkwEiGWRpc3BhdGNoQXBwbHlXaW5kb3dJbnNldHMqHgjaAhDsAhigASITZ2V0U3RhdGVEZXNjcmlwdGlvbioeCNsCEOwCGKMBIhNzZXRTdGF0ZURlc2NyaXB0aW9uKiUI3AIQ7QIYpgEiGmdldFJlY2VpdmVDb250ZW50TWltZVR5cGVzKiAI3QIQ7QIYpwEiFXBlcmZvcm1SZWNlaXZlQ29udGVudCoQCN4CEPACGAQiBjxpbml0PioRCN8CEPACGKgBIgY8aW5pdD4qEAjgAhDwAhipASIFYnVpbGQqJQjhAhDwAhiqASIaY3JlYXRlV2luZG93SW5zZXRzSW5zdGFuY2UqGgjiAhDwAhirASIPc2V0U3RhYmxlSW5zZXRzKiAI4wIQ8AIYqwEiFXNldFN5c3RlbVdpbmRvd0luc2V0cyoQCOQCEPICGAQiBjxpbml0PioRCOUCEPICGKgBIgY8aW5pdD4qEAjmAhDyAhipASIFYnVpbGQqKgjnAhDyAhirASIfc2V0TWFuZGF0b3J5U3lzdGVtR2VzdHVyZUluc2V0cyoaCOgCEPICGKsBIg9zZXRTdGFibGVJbnNldHMqIQjpAhDyAhirASIWc2V0U3lzdGVtR2VzdHVyZUluc2V0cyogCOoCEPICGKsBIhVzZXRTeXN0ZW1XaW5kb3dJbnNldHMqIwjrAhDyAhirASIYc2V0VGFwcGFibGVFbGVtZW50SW5zZXRzKhAI7AIQ8wIYBCIGPGluaXQ+KhEI7QIQ8wIYqAEiBjxpbml0PioUCO4CEPMCGKwBIglzZXRJbnNldHMqEAjvAhD0AhgEIgY8aW5pdD4qEQjwAhD0AhioASIGPGluaXQ+KhQI8QIQ9AIYrAEiCXNldEluc2V0cyoQCPICEPUCGAQiBjxpbml0PioRCPMCEPUCGKgBIgY8aW5pdD4qGQj0AhD1AhgEIg9hcHBseUluc2V0VHlwZXMqEAj1AhD1AhipASIFYnVpbGQqFAj2AhD1AhisASIJc2V0SW5zZXRzKioI9wIQ9QIYqwEiH3NldE1hbmRhdG9yeVN5c3RlbUdlc3R1cmVJbnNldHMqGgj4AhD1AhirASIPc2V0U3RhYmxlSW5zZXRzKiEI+QIQ9QIYqwEiFnNldFN5c3RlbUdlc3R1cmVJbnNldHMqIAj6AhD1AhirASIVc2V0U3lzdGVtV2luZG93SW5zZXRzKiMI+wIQ9QIYqwEiGHNldFRhcHBhYmxlRWxlbWVudEluc2V0cyoRCPwCEPYCGK0BIgY8aW5pdD4qEQj9AhD2AhiuASIGPGluaXQ+KhwI/gIQ9gIYWCISY29weVJvb3RWaWV3Qm91bmRzKh0I/wIQ9gIYqAEiEmNvcHlXaW5kb3dEYXRhSW50byoQCIADEPYCGGAiBmVxdWFscyoUCIEDEPYCGK8BIglnZXRJbnNldHMqFAiCAxD2AhiwASIJZ2V0SW5zZXRzKhsIgwMQ9gIYsAEiEGdldEluc2V0c0ZvclR5cGUqJgiEAxD2AhivASIbZ2V0SW5zZXRzSWdub3JpbmdWaXNpYmlsaXR5Kh4IhQMQ9gIYsQEiE2dldFJvb3RTdGFibGVJbnNldHMqIAiGAxD2AhixASIVZ2V0U3lzdGVtV2luZG93SW5zZXRzKhsIhwMQ9gIYsgEiEGdldFZpc2libGVJbnNldHMqEAiIAxD2AhizASIFaW5zZXQqEQiJAxD2AhgZIgdpc1JvdW5kKhgIigMQ9gIYtAEiDWlzVHlwZVZpc2libGUqFAiLAxD2Ahi0ASIJaXNWaXNpYmxlKh0IjAMQ9gIYBCITbG9hZFJlZmxlY3Rpb25GaWVsZCoeCI0DEPYCGLUBIhNzZXRPdmVycmlkZGVuSW5zZXRzKhoIjgMQ9gIYqwEiD3NldFJvb3RWaWV3RGF0YSoeCI8DEPYCGKgBIhNzZXRSb290V2luZG93SW5zZXRzKh8IkAMQ9gIYECIVc2V0U3lzdGVtVWlWaXNpYmlsaXR5KiQIkQMQ9gIYtgEiGXN5c3RlbUJhclZpc2liaWxpdHlFcXVhbHMqEQiSAxD4AhitASIGPGluaXQ+KhEIkwMQ+AIYtwEiBjxpbml0PioeCJQDEPgCGKkBIhNjb25zdW1lU3RhYmxlSW5zZXRzKiQIlQMQ+AIYqQEiGWNvbnN1bWVTeXN0ZW1XaW5kb3dJbnNldHMqGgiWAxD4AhixASIPZ2V0U3RhYmxlSW5zZXRzKhQIlwMQ+AIYGSIKaXNDb25zdW1lZCoaCJgDEPgCGKsBIg9zZXRTdGFibGVJbnNldHMqEQiZAxD5AhitASIGPGluaXQ+KhEImgMQ+QIYuAEiBjxpbml0PiofCJsDEPkCGKkBIhRjb25zdW1lRGlzcGxheUN1dG91dCoQCJwDEPkCGGAiBmVxdWFscyobCJ0DEPkCGLkBIhBnZXREaXNwbGF5Q3V0b3V0KhIIngMQ+QIYWiIIaGFzaENvZGUqEQifAxD7AhitASIGPGluaXQ+KhEIoAMQ+wIYugEiBjxpbml0PioqCKEDEPsCGLEBIh9nZXRNYW5kYXRvcnlTeXN0ZW1HZXN0dXJlSW5zZXRzKiEIogMQ+wIYsQEiFmdldFN5c3RlbUdlc3R1cmVJbnNldHMqIwijAxD7AhixASIYZ2V0VGFwcGFibGVFbGVtZW50SW5zZXRzKhAIpAMQ+wIYswEiBWluc2V0KhoIpQMQ+wIYqwEiD3NldFN0YWJsZUluc2V0cyoRCKYDEPwCGK0BIgY8aW5pdD4qEQinAxD8Ahi7ASIGPGluaXQ+KhwIqAMQ/AIYWCISY29weVJvb3RWaWV3Qm91bmRzKhQIqQMQ/AIYrwEiCWdldEluc2V0cyomCKoDEPwCGK8BIhtnZXRJbnNldHNJZ25vcmluZ1Zpc2liaWxpdHkqFAirAxD8Ahi0ASIJaXNWaXNpYmxlKhEIrAMQ/QIYrQEiBjxpbml0PioRCK0DEP0CGLwBIgY8aW5pdD4qFAiuAxD9AhivASIJZ2V0SW5zZXRzKiYIrwMQ/QIYrwEiG2dldEluc2V0c0lnbm9yaW5nVmlzaWJpbGl0eSoUCLADEP0CGLQBIglpc1Zpc2libGUqEQixAxD+AhioASIGPGluaXQ+Kh8IsgMQ/gIYqQEiFGNvbnN1bWVEaXNwbGF5Q3V0b3V0Kh4IswMQ/gIYqQEiE2NvbnN1bWVTdGFibGVJbnNldHMqJAi0AxD+AhipASIZY29uc3VtZVN5c3RlbVdpbmRvd0luc2V0cyocCLUDEP4CGFgiEmNvcHlSb290Vmlld0JvdW5kcyodCLYDEP4CGKgBIhJjb3B5V2luZG93RGF0YUludG8qEAi3AxD+AhhgIgZlcXVhbHMqGwi4AxD+Ahi5ASIQZ2V0RGlzcGxheUN1dG91dCoUCLkDEP4CGK8BIglnZXRJbnNldHMqJgi6AxD+AhivASIbZ2V0SW5zZXRzSWdub3JpbmdWaXNpYmlsaXR5KioIuwMQ/gIYsQEiH2dldE1hbmRhdG9yeVN5c3RlbUdlc3R1cmVJbnNldHMqGgi8AxD+AhixASIPZ2V0U3RhYmxlSW5zZXRzKiEIvQMQ/gIYsQEiFmdldFN5c3RlbUdlc3R1cmVJbnNldHMqIAi+AxD+AhixASIVZ2V0U3lzdGVtV2luZG93SW5zZXRzKiMIvwMQ/gIYsQEiGGdldFRhcHBhYmxlRWxlbWVudEluc2V0cyoSCMADEP4CGFoiCGhhc2hDb2RlKhAIwQMQ/gIYswEiBWluc2V0KhQIwgMQ/gIYGSIKaXNDb25zdW1lZCoRCMMDEP4CGBkiB2lzUm91bmQqFAjEAxD+Ahi0ASIJaXNWaXNpYmxlKh4IxQMQ/gIYtQEiE3NldE92ZXJyaWRkZW5JbnNldHMqGgjGAxD+AhirASIPc2V0Um9vdFZpZXdEYXRhKh4IxwMQ/gIYqAEiE3NldFJvb3RXaW5kb3dJbnNldHMqGgjIAxD+AhirASIPc2V0U3RhYmxlSW5zZXRzKh8IyQMQ/gIYECIVc2V0U3lzdGVtVWlWaXNpYmlsaXR5KhkIygMQ/wIYvQEiDnRvUGxhdGZvcm1UeXBlKhkIywMQgAMYvQEiDnRvUGxhdGZvcm1UeXBlKhEIzAMQgQMYvgEiBm9uUHVsbCoRCM0DEIMDGL8BIgZjcmVhdGUqFgjOAxCDAxjAASILZ2V0RGlzdGFuY2UqGQjPAxCDAxjBASIOb25QdWxsRGlzdGFuY2UqGAjQAxCEAxhYIg5zZXRDb250ZW50VmlldyoYCNEDEIUDGFgiDnNldENvbnRlbnRWaWV3KhwI0gMQkgMYwgEiEW9uQWN0aXZpdHlDcmVhdGVkKh4I0wMQkgMYwwEiE29uQWN0aXZpdHlEZXN0cm95ZWQqGwjUAxCSAxjDASIQb25BY3Rpdml0eVBhdXNlZCocCNUDEJIDGMMBIhFvbkFjdGl2aXR5UmVzdW1lZComCNYDEJIDGMIBIhtvbkFjdGl2aXR5U2F2ZUluc3RhbmNlU3RhdGUqHAjXAxCSAxjDASIRb25BY3Rpdml0eVN0YXJ0ZWQqHAjYAxCSAxjDASIRb25BY3Rpdml0eVN0b3BwZWQqEAjZAxCTAxgEIgY8aW5pdD4qHAjaAxCTAxjCASIRb25BY3Rpdml0eUNyZWF0ZWQqEQjbAxCPAxjEASIGPGluaXQ+KiAI3AMQjwMYwwEiFW9uQWN0aXZpdHlQb3N0UmVzdW1lZCogCN0DEI8DGMMBIhVvbkFjdGl2aXR5UG9zdFN0YXJ0ZWQqEQjeAxCRAxjEASIGPGluaXQ+KhwI3wMQkQMYwgEiEW9uQWN0aXZpdHlDcmVhdGVkKhsI4AMQkQMYwwEiEG9uQWN0aXZpdHlQYXVzZWQqHwjhAxCRAxjCASIUb25BY3Rpdml0eVByZUNyZWF0ZWQqHAjiAxCRAxjDASIRb25BY3Rpdml0eVN0b3BwZWQqEAjjAxCUAxgEIgY8aW5pdD4qIAjkAxCIBBgEIhZkaXNwYXRjaEdldERpc3BsYXlMaXN0Ki0I5QMQiQQYxQEiImZpbmRWaWV3QnlBY2Nlc3NpYmlsaXR5SWRUcmF2ZXJzYWwqEAjmAxCKBBgEIgY8aW5pdD4qHAjnAxCKBBjCASIRb25BY3Rpdml0eUNyZWF0ZWQqHgjoAxCKBBjDASITb25BY3Rpdml0eURlc3Ryb3llZCobCOkDEIoEGMMBIhBvbkFjdGl2aXR5UGF1c2VkKiAI6gMQigQYwgEiFW9uQWN0aXZpdHlQb3N0Q3JlYXRlZCogCOsDEIoEGMMBIhVvbkFjdGl2aXR5UG9zdFJlc3VtZWQqIAjsAxCKBBjDASIVb25BY3Rpdml0eVBvc3RTdGFydGVkKiEI7QMQigQYwwEiFm9uQWN0aXZpdHlQcmVEZXN0cm95ZWQqHgjuAxCKBBjDASITb25BY3Rpdml0eVByZVBhdXNlZCofCO8DEIoEGMMBIhRvbkFjdGl2aXR5UHJlU3RvcHBlZCocCPADEIoEGMMBIhFvbkFjdGl2aXR5UmVzdW1lZComCPEDEIoEGMIBIhtvbkFjdGl2aXR5U2F2ZUluc3RhbmNlU3RhdGUqHAjyAxCKBBjDASIRb25BY3Rpdml0eVN0YXJ0ZWQqHAjzAxCKBBjDASIRb25BY3Rpdml0eVN0b3BwZWQqFQj0AxCKBBjDASIKcmVnaXN0ZXJJbioXCPUDEI4EGMYBIgxnZXRGaWxsQWxwaGEqFgj2AxCOBBhaIgxnZXRGaWxsQ29sb3IqGQj3AxCOBBjGASIOZ2V0U3Ryb2tlQWxwaGEqGAj4AxCOBBhaIg5nZXRTdHJva2VDb2xvcioZCPkDEI4EGMYBIg5nZXRTdHJva2VXaWR0aCoZCPoDEI4EGMYBIg5nZXRUcmltUGF0aEVu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IgtnZXRJdGVtRGF0YSoWCJAHEMMHGFEiDHNldENoZWNrYWJsZSoUCJEHEMMHGFEiCnNldENoZWNrZWQqGwiSBxDDBxhRIhFzZXRFeHBhbmRlZEZvcm1hdCoSCJMHEMMHGL0EIgdzZXRJY29uKhkIlAcQwwcYvgQiDnNldEl0ZW1JbnZva2VyKhsIlQcQwwcYvwQiEHNldFBvcHVwQ2FsbGJhY2sqEwiWBxDDBxjABCIIc2V0VGl0bGUqHQiXBxDIBxhaIhNnZXRXaW5kb3dBbmltYXRpb25zKhYImAcQyQcYwQQiC2dldEluZmxhdGVyKhYImQcQyQcYvAQiC2dldEl0ZW1EYXRhKhYImgcQyQcYUSIMc2V0Q2hlY2thYmxlKhQImwcQyQcYUSIKc2V0Q2hlY2tlZCoaCJwHEMkHGFEiEHNldEZvcmNlU2hvd0ljb24qIAidBxDJBxhRIhZzZXRHcm91cERpdmlkZXJFbmFibGVkKhIIngcQyQcYvQQiB3NldEljb24qIAifBxDJBxhRIhZzZXRTdWJNZW51QXJyb3dWaXNpYmxlKhMIoAcQyQcYwAQiCHNldFRpdGxlKhoIoQcQywcYwgQiD2dldFRhYkNvbnRhaW5lciofCKIHEMsHGL0EIhRzZXRQcmltYXJ5QmFja2dyb3VuZCodCKMHEMsHGL0EIhJzZXRTcGxpdEJhY2tncm91bmQqHwikBxDLBxi9BCIUc2V0U3RhY2tlZEJhY2tncm91bmQqGgilBxDLBxjDBCIPc2V0VGFiQ29udGFpbmVyKhoIpgcQywcYUSIQc2V0VHJhbnNpdGlvbmluZyoXCKcHEMsHGBAiDXNldFZpc2liaWxpdHkqHwioBxDNBxhaIhVnZXRBbmltYXRlZFZpc2liaWxpdHkqGgipBxDNBxhaIhBnZXRDb250ZW50SGVpZ2h0KhYIqgcQzQcYuwQiC2dldFN1YnRpdGxlKhMIqwcQzQcYuwQiCGdldFRpdGxlKhoIrAcQzQcYECIQc2V0Q29udGVudEhlaWdodCoXCK0HEM0HGFgiDXNldEN1c3RvbVZpZXcqFgiuBxDNBxjABCILc2V0U3VidGl0bGUqEwivBxDNBxjABCIIc2V0VGl0bGUqGgiwBxDNBxhRIhBzZXRUaXRsZU9wdGlvbmFsKhcIsQcQzQcYECINc2V0VmlzaWJpbGl0eSogCLIHEM4HGFoiFmdldEFjdGlvbkJhckhpZGVPZmZzZXQqHQizBxDOBxhaIhNnZXROZXN0ZWRTY3JvbGxBeGVzKhMItAcQzgcYuwQiCGdldFRpdGxlKiAItQcQzgcYECIWc2V0QWN0aW9uQmFySGlkZU9mZnNldCopCLYHEM4HGMQEIh5zZXRBY3Rpb25CYXJWaXNpYmlsaXR5Q2FsbGJhY2sqHwi3BxDOBxhRIhVzZXRIYXNOb25FbWJlZGRlZFRhYnMqJwi4BxDOBxhRIh1zZXRIaWRlT25Db250ZW50U2Nyb2xsRW5hYmxlZCoRCLkHEM4HGBAiB3NldEljb24qEgi6BxDOBxi9BCIHc2V0SWNvbioRCLsHEM4HGBAiB3NldExvZ28qGAi8BxDOBxhRIg5zZXRPdmVybGF5TW9kZSohCL0HEM4HGFEiF3NldFNob3dpbmdGb3JBY3Rpb25Nb2RlKhYIvgcQzgcYECIMc2V0VWlPcHRpb25zKhwIvwcQzgcYxQQiEXNldFdpbmRvd0NhbGxiYWNrKhkIwAcQzgcYwAQiDnNldFdpbmRvd1RpdGxlKhIIwQcQ0QcYxgQiB2dldE1lbnUqGgjCBxDRBxjHBCIPZ2V0T3ZlcmZsb3dJY29uKhcIwwcQ0QcYWiINZ2V0UG9wdXBUaGVtZSodCMQHENEHGFoiE2dldFdpbmRvd0FuaW1hdGlvbnMqKQjFBxDRBxhRIh9zZXRFeHBhbmRlZEFjdGlvblZpZXdzRXhjbHVzaXZlKiUIxgcQ0QcYyAQiGnNldE9uTWVudUl0ZW1DbGlja0xpc3RlbmVyKhoIxwcQ0QcYvQQiD3NldE92ZXJmbG93SWNvbiodCMgHENEHGFEiE3NldE92ZXJmbG93UmVzZXJ2ZWQqFwjJBxDRBxgQIg1zZXRQb3B1cFRoZW1lKhcIygcQ0QcYyQQiDHNldFByZXNlbnRlciovCMsHENUHGMoEIiRnZXRDdXN0b21TZWxlY3Rpb25BY3Rpb25Nb2RlQ2FsbGJhY2sqJwjMBxDVBxjLBCIcZ2V0U3VwcG9ydEJhY2tncm91bmRUaW50TGlzdConCM0HENUHGMwEIhxnZXRTdXBwb3J0QmFja2dyb3VuZFRpbnRNb2RlKi4IzgcQ1QcYywQiI2dldFN1cHBvcnRDb21wb3VuZERyYXdhYmxlc1RpbnRMaXN0Ki4IzwcQ1QcYzAQiI2dldFN1cHBvcnRDb21wb3VuZERyYXdhYmxlc1RpbnRNb2RlKiAI0AcQ1QcYvQQiFXNldEJhY2tncm91bmREcmF3YWJsZSofCNEHENUHGBAiFXNldEJhY2tncm91bmRSZXNvdXJjZSovCNIHENUHGM0EIiRzZXRDdXN0b21TZWxlY3Rpb25BY3Rpb25Nb2RlQ2FsbGJhY2sqJwjTBxDVBxgQIh1zZXREcm9wRG93bkJhY2tncm91bmRSZXNvdXJjZSofCNQHENUHGFEiFXNldEVtb2ppQ29tcGF0RW5hYmxlZCoZCNUHENUHGM4EIg5zZXRLZXlMaXN0ZW5lcionCNYHENUHGM8EIhxzZXRTdXBwb3J0QmFja2dyb3VuZFRpbnRMaXN0KicI1wcQ1QcY0AQiHHNldFN1cHBvcnRCYWNrZ3JvdW5kVGludE1vZGUqLgjYBxDVBxjPBCIjc2V0U3VwcG9ydENvbXBvdW5kRHJhd2FibGVzVGludExpc3QqLgjZBxDVBxjQBCIjc2V0U3VwcG9ydENvbXBvdW5kRHJhd2FibGVzVGludE1vZGUqIAjaBxDYBxhaIhZnZXRBdXRvU2l6ZU1heFRleHRTaXplKiAI2wcQ2AcYWiIWZ2V0QXV0b1NpemVNaW5UZXh0U2l6ZSokCNwHENgHGFoiGmdldEF1dG9TaXplU3RlcEdyYW51bGFyaXR5KigI3QcQ2AcY0QQiHWdldEF1dG9TaXplVGV4dEF2YWlsYWJsZVNpemVzKh0I3gcQ2AcYWiITZ2V0QXV0b1NpemVUZXh0VHlwZSovCN8HENgHGMoEIiRnZXRDdXN0b21TZWxlY3Rpb25BY3Rpb25Nb2RlQ2FsbGJhY2sqIQjgBxDYBxjSBCIWZ2V0RW1vamlUZXh0Vmlld0hlbHBlcionCOEHENgHGMsEIhxnZXRTdXBwb3J0QmFja2dyb3VuZFRpbnRMaXN0KicI4gcQ2AcYzAQiHGdldFN1cHBvcnRCYWNrZ3JvdW5kVGludE1vZGUqLgjjBxDYBxjLBCIjZ2V0U3VwcG9ydENvbXBvdW5kRHJhd2FibGVzVGludExpc3QqLgjkBxDYBxjMBCIjZ2V0U3VwcG9ydENvbXBvdW5kRHJhd2FibGVzVGludE1vZGUqFAjlBxDYBxhRIgpzZXRBbGxDYXBzKikI5gcQ2AcYECIfc2V0QXV0b1NpemVUZXh0VHlwZVdpdGhEZWZhdWx0cyogCOcHENgHGL0EIhVzZXRCYWNrZ3JvdW5kRHJhd2FibGUqHwjoBxDYBxgQIhVzZXRCYWNrZ3JvdW5kUmVzb3VyY2UqLwjpBxDYBxjNBCIkc2V0Q3VzdG9tU2VsZWN0aW9uQWN0aW9uTW9kZUNhbGxiYWNrKh8I6gcQ2AcYUSIVc2V0RW1vamlDb21wYXRFbmFibGVkKhUI6wcQ2AcY0wQiCnNldEZpbHRlcnMqGwjsBxDYBxhRIhFzZXRTdXBwb3J0QWxsQ2FwcyonCO0HENgHGM8EIhxzZXRTdXBwb3J0QmFja2dyb3VuZFRpbnRMaXN0KicI7gcQ2AcY0AQiHHNldFN1cHBvcnRCYWNrZ3JvdW5kVGludE1vZGUqLgjvBxDYBxjPBCIjc2V0U3VwcG9ydENvbXBvdW5kRHJhd2FibGVzVGludExpc3QqLgjwBxDYBxjQBCIjc2V0U3VwcG9ydENvbXBvdW5kRHJhd2FibGVzVGludE1vZGUqIQjxBxDbBxjSBCIWZ2V0RW1vamlUZXh0Vmlld0hlbHBlcionCPIHENsHGMsEIhxnZXRTdXBwb3J0QmFja2dyb3VuZFRpbnRMaXN0KicI8wcQ2wcYzAQiHGdldFN1cHBvcnRCYWNrZ3JvdW5kVGludE1vZGUqIwj0BxDbBxjLBCIYZ2V0U3VwcG9ydEJ1dHRvblRpbnRMaXN0KiMI9QcQ2wcYzAQiGGdldFN1cHBvcnRCdXR0b25UaW50TW9kZSouCPYHENsHGMsEIiNnZXRTdXBwb3J0Q29tcG91bmREcmF3YWJsZXNUaW50TGlzdCouCPcHENsHGMwEIiNnZXRTdXBwb3J0Q29tcG91bmREcmF3YWJsZXNUaW50TW9kZSoUCPgHENsHGFEiCnNldEFsbENhcHMqIAj5BxDbBxi9BCIVc2V0QmFja2dyb3VuZERyYXdhYmxlKh8I+gcQ2wcYECIVc2V0QmFja2dyb3VuZFJlc291cmNlKhsI+wcQ2wcYECIRc2V0QnV0dG9uRHJhd2FibGUqHAj8BxDbBxi9BCIRc2V0QnV0dG9uRHJhd2FibGUqHwj9BxDbBxhRIhVzZXRFbW9qaUNvbXBhdEVuYWJsZWQqFQj+BxDbBxjTBCIKc2V0RmlsdGVycyonCP8HENsHGM8EIhxzZXRTdXBwb3J0QmFja2dyb3VuZFRpbnRMaXN0KicIgAgQ2wcY0AQiHHNldFN1cHBvcnRCYWNrZ3JvdW5kVGludE1vZGUqIwiBCBDbBxjPBCIYc2V0U3VwcG9ydEJ1dHRvblRpbnRMaXN0KiMIgggQ2wcY0AQiGHNldFN1cHBvcnRCdXR0b25UaW50TW9kZSouCIMIENsHGM8EIiNzZXRTdXBwb3J0Q29tcG91bmREcmF3YWJsZXNUaW50TGlzdCouCIQIENsHGNAEIiNzZXRTdXBwb3J0Q29tcG91bmREcmF3YWJsZXNUaW50TW9kZSovCIUIENwHGMoEIiRnZXRDdXN0b21TZWxlY3Rpb25BY3Rpb25Nb2RlQ2FsbGJhY2sqIQiGCBDcBxjSBCIWZ2V0RW1vamlUZXh0Vmlld0hlbHBlcionCIcIENwHGMsEIhxnZXRTdXBwb3J0QmFja2dyb3VuZFRpbnRMaXN0KicIiAgQ3AcYzAQiHGdldFN1cHBvcnRCYWNrZ3JvdW5kVGludE1vZGUqJgiJCBDcBxjLBCIbZ2V0U3VwcG9ydENoZWNrTWFya1RpbnRMaXN0KiYIiggQ3AcYzAQiG2dldFN1cHBvcnRDaGVja01hcmtUaW50TW9kZSouCIsIENwHGMsEIiNnZXRTdXBwb3J0Q29tcG91bmREcmF3YWJsZXNUaW50TGlzdCouCIwIENwHGMwEIiNnZXRTdXBwb3J0Q29tcG91bmREcmF3YWJsZXNUaW50TW9kZSoUCI0IENwHGFEiCnNldEFsbENhcHMqIAiOCBDcBxi9BCIVc2V0QmFja2dyb3VuZERyYXdhYmxlKh8IjwgQ3AcYECIVc2V0QmFja2dyb3VuZFJlc291cmNlKh4IkAgQ3AcYECIUc2V0Q2hlY2tNYXJrRHJhd2FibGUqHwiRCBDcBxi9BCIUc2V0Q2hlY2tNYXJrRHJhd2FibGUqLwiSCBDcBxjNBCIkc2V0Q3VzdG9tU2VsZWN0aW9uQWN0aW9uTW9kZUNhbGxiYWNrKh8IkwgQ3AcYUSIVc2V0RW1vamlDb21wYXRFbmFibGVkKicIlAgQ3AcYzwQiHHNldFN1cHBvcnRCYWNrZ3JvdW5kVGludExpc3QqJwiVCBDcBxjQBCIcc2V0U3VwcG9ydEJhY2tncm91bmRUaW50TW9kZSomCJYIENwHGM8EIhtzZXRTdXBwb3J0Q2hlY2tNYXJrVGludExpc3QqJgiXCBDcBxjQBCIbc2V0U3VwcG9ydENoZWNrTWFya1RpbnRNb2RlKi4ImAgQ3AcYzwQiI3NldFN1cHBvcnRDb21wb3VuZERyYXdhYmxlc1RpbnRMaXN0Ki4ImQgQ3AcY0AQiI3NldFN1cHBvcnRDb21wb3VuZERyYXdhYmxlc1RpbnRNb2RlKi8ImggQ3QcYygQiJGdldEN1c3RvbVNlbGVjdGlvbkFjdGlvbk1vZGVDYWxsYmFjayoZCJsIEN0HGNQEIg5nZXRTdXBlckNhbGxlcionCJwIEN0HGMsEIhxnZXRTdXBwb3J0QmFja2dyb3VuZFRpbnRMaXN0KicInQgQ3QcYzAQiHGdldFN1cHBvcnRCYWNrZ3JvdW5kVGludE1vZGUqLgieCBDdBxjLBCIjZ2V0U3VwcG9ydENvbXBvdW5kRHJhd2FibGVzVGludExpc3QqLgifCBDdBxjMBCIjZ2V0U3VwcG9ydENvbXBvdW5kRHJhd2FibGVzVGludE1vZGUqEgigCBDdBxjVBCIHZ2V0VGV4dCoSCKEIEN0HGLsEIgdnZXRUZXh0KhwIoggQ3QcY1gQiEWdldFRleHRDbGFzc2lmaWVyKiAIowgQ3QcYvQQiFXNldEJhY2tncm91bmREcmF3YWJsZSofCKQIEN0HGBAiFXNldEJhY2tncm91bmRSZXNvdXJjZSovCKUIEN0HGM0EIiRzZXRDdXN0b21TZWxlY3Rpb25BY3Rpb25Nb2RlQ2FsbGJhY2sqHwimCBDdBxhRIhVzZXRFbW9qaUNvbXBhdEVuYWJsZWQqGQinCBDdBxjOBCIOc2V0S2V5TGlzdGVuZXIqJwioCBDdBxjPBCIcc2V0U3VwcG9ydEJhY2tncm91bmRUaW50TGlzdConCKkIEN0HGNAEIhxzZXRTdXBwb3J0QmFja2dyb3VuZFRpbnRNb2RlKi4IqggQ3QcYzwQiI3NldFN1cHBvcnRDb21wb3VuZERyYXdhYmxlc1RpbnRMaXN0Ki4IqwgQ3QcY0AQiI3NldFN1cHBvcnRDb21wb3VuZERyYXdhYmxlc1RpbnRNb2RlKhwIrAgQ3QcY1wQiEXNldFRleHRDbGFzc2lmaWVyKicIrQgQ4QcYywQiHGdldFN1cHBvcnRCYWNrZ3JvdW5kVGludExpc3QqJwiuCBDhBxjMBCIcZ2V0U3VwcG9ydEJhY2tncm91bmRUaW50TW9kZSoiCK8IEOEHGMsEIhdnZXRTdXBwb3J0SW1hZ2VUaW50TGlzdCoiCLAIEOEHGMwEIhdnZXRTdXBwb3J0SW1hZ2VUaW50TW9kZSogCLEIEOEHGL0EIhVzZXRCYWNrZ3JvdW5kRHJhd2FibGUqHwiyCBDhBxgQIhVzZXRCYWNrZ3JvdW5kUmVzb3VyY2UqGQizCBDhBxjYBCIOc2V0SW1hZ2VCaXRtYXAqGwi0CBDhBxi9BCIQc2V0SW1hZ2VEcmF3YWJsZSoXCLUIEOEHGBAiDXNldEltYWdlTGV2ZWwqGgi2CBDhBxgQIhBzZXRJbWFnZVJlc291cmNlKhYItwgQ4QcY2QQiC3NldEltYWdlVVJJKicIuAgQ4QcYzwQiHHNldFN1cHBvcnRCYWNrZ3JvdW5kVGludExpc3QqJwi5CBDhBxjQBCIcc2V0U3VwcG9ydEJhY2tncm91bmRUaW50TW9kZSoiCLoIEOEHGM8EIhdzZXRTdXBwb3J0SW1hZ2VUaW50TGlzdCoiCLsIEOEHGNAEIhdzZXRTdXBwb3J0SW1hZ2VUaW50TW9kZSonCLwIEOQHGMsEIhxnZXRTdXBwb3J0QmFja2dyb3VuZFRpbnRMaXN0KicIvQgQ5AcYzAQiHGdldFN1cHBvcnRCYWNrZ3JvdW5kVGludE1vZGUqIgi+CBDkBxjLBCIXZ2V0U3VwcG9ydEltYWdlVGludExpc3QqIgi/CBDkBxjMBCIXZ2V0U3VwcG9ydEltYWdlVGludE1vZGUqIAjACBDkBxi9BCIVc2V0QmFja2dyb3VuZERyYXdhYmxlKh8IwQgQ5AcYECIVc2V0QmFja2dyb3VuZFJlc291cmNlKhkIwggQ5AcY2AQiDnNldEltYWdlQml0bWFwKhsIwwgQ5AcYvQQiEHNldEltYWdlRHJhd2FibGUqFwjECBDkBxgQIg1zZXRJbWFnZUxldmVsKhoIxQgQ5AcYECIQc2V0SW1hZ2VSZXNvdXJjZSoWCMYIEOQHGNkEIgtzZXRJbWFnZVVSSSonCMcIEOQHGM8EIhxzZXRTdXBwb3J0QmFja2dyb3VuZFRpbnRMaXN0KicIyAgQ5AcY0AQiHHNldFN1cHBvcnRCYWNrZ3JvdW5kVGludE1vZGUqIgjJCBDkBxjPBCIXc2V0U3VwcG9ydEltYWdlVGludExpc3QqIgjKCBDkBxjQBCIXc2V0U3VwcG9ydEltYWdlVGludE1vZGUqJwjLCBDlBxjLBCIcZ2V0U3VwcG9ydEJhY2tncm91bmRUaW50TGlzdConCMwIEOUHGMwEIhxnZXRTdXBwb3J0QmFja2dyb3VuZFRpbnRNb2RlKi4IzQgQ5QcYywQiI2dldFN1cHBvcnRDb21wb3VuZERyYXdhYmxlc1RpbnRMaXN0Ki4IzggQ5QcYzAQiI2dldFN1cHBvcnRDb21wb3VuZERyYXdhYmxlc1RpbnRNb2RlKiAIzwgQ5QcYvQQiFXNldEJhY2tncm91bmREcmF3YWJsZSofCNAIEOUHGBAiFXNldEJhY2tncm91bmRSZXNvdXJjZSonCNEIEOUHGBAiHXNldERyb3BEb3duQmFja2dyb3VuZFJlc291cmNlKh8I0ggQ5QcYUSIVc2V0RW1vamlDb21wYXRFbmFibGVkKhkI0wgQ5QcYzgQiDnNldEtleUxpc3RlbmVyKicI1AgQ5QcYzwQiHHNldFN1cHBvcnRCYWNrZ3JvdW5kVGludExpc3QqJwjVCBDlBxjQBCIcc2V0U3VwcG9ydEJhY2tncm91bmRUaW50TW9kZSouCNYIEOUHGM8EIiNzZXRTdXBwb3J0Q29tcG91bmREcmF3YWJsZXNUaW50TGlzdCouCNcIEOUHGNAEIiNzZXRTdXBwb3J0Q29tcG91bmREcmF3YWJsZXNUaW50TW9kZSohCNgIEOYHGNIEIhZnZXRFbW9qaVRleHRWaWV3SGVscGVyKicI2QgQ5gcYywQiHGdldFN1cHBvcnRCYWNrZ3JvdW5kVGludExpc3QqJwjaCBDmBxjMBCIcZ2V0U3VwcG9ydEJhY2tncm91bmRUaW50TW9kZSojCNsIEOYHGMsEIhhnZXRTdXBwb3J0QnV0dG9uVGludExpc3QqIwjcCBDmBxjMBCIYZ2V0U3VwcG9ydEJ1dHRvblRpbnRNb2RlKi4I3QgQ5gcYywQiI2dldFN1cHBvcnRDb21wb3VuZERyYXdhYmxlc1RpbnRMaXN0Ki4I3ggQ5gcYzAQiI2dldFN1cHBvcnRDb21wb3VuZERyYXdhYmxlc1RpbnRNb2RlKhQI3wgQ5gcYUSIKc2V0QWxsQ2FwcyogCOAIEOYHGL0EIhVzZXRCYWNrZ3JvdW5kRHJhd2FibGUqHwjhCBDmBxgQIhVzZXRCYWNrZ3JvdW5kUmVzb3VyY2UqGwjiCBDmBxgQIhFzZXRCdXR0b25EcmF3YWJsZSocCOMIEOYHGL0EIhFzZXRCdXR0b25EcmF3YWJsZSofCOQIEOYHGFEiFXNldEVtb2ppQ29tcGF0RW5hYmxlZCoVCOUIEOYHGNMEIgpzZXRGaWx0ZXJzKicI5ggQ5gcYzwQiHHNldFN1cHBvcnRCYWNrZ3JvdW5kVGludExpc3QqJwjnCBDmBxjQBCIcc2V0U3VwcG9ydEJhY2tncm91bmRUaW50TW9kZSojCOgIEOYHGM8EIhhzZXRTdXBwb3J0QnV0dG9uVGludExpc3QqIwjpCBDmBxjQBCIYc2V0U3VwcG9ydEJ1dHRvblRpbnRNb2RlKi4I6ggQ5gcYzwQiI3NldFN1cHBvcnRDb21wb3VuZERyYXdhYmxlc1RpbnRMaXN0Ki4I6wgQ5gcY0AQiI3NldFN1cHBvcnRDb21wb3VuZERyYXdhYmxlc1RpbnRNb2RlKiUI7AgQ5wcYWiIbZ2V0RHJvcERvd25Ib3Jpem9udGFsT2Zmc2V0KiMI7QgQ5wcYWiIZZ2V0RHJvcERvd25WZXJ0aWNhbE9mZnNldCoaCO4IEOcHGFoiEGdldERyb3BEb3duV2lkdGgqGwjvCBDnBxjaBCIQZ2V0SW50ZXJuYWxQb3B1cCodCPAIEOcHGMcEIhJnZXRQb3B1cEJhY2tncm91bmQqGQjxCBDnBxhXIg9nZXRQb3B1cENvbnRleHQqFAjyCBDnBxi7BCIJZ2V0UHJvbXB0KicI8wgQ5wcYywQiHGdldFN1cHBvcnRCYWNrZ3JvdW5kVGludExpc3QqJwj0CBDnBxjMBCIcZ2V0U3VwcG9ydEJhY2tncm91bmRUaW50TW9kZSoVCPUIEOcHGNsEIgpzZXRBZGFwdGVyKhUI9ggQ5wcY3AQiCnNldEFkYXB0ZXIqIAj3CBDnBxi9BCIVc2V0QmFja2dyb3VuZERyYXdhYmxlKh8I+AgQ5wcYECIVc2V0QmFja2dyb3VuZFJlc291cmNlKiUI+QgQ5wcYECIbc2V0RHJvcERvd25Ib3Jpem9udGFsT2Zmc2V0KiMI+ggQ5wcYECIZc2V0RHJvcERvd25WZXJ0aWNhbE9mZnNldCoaCPsIEOcHGBAiEHNldERyb3BEb3duV2lkdGgqJQj8CBDnBxi9BCIac2V0UG9wdXBCYWNrZ3JvdW5kRHJhd2FibGUqJAj9CBDnBxgQIhpzZXRQb3B1cEJhY2tncm91bmRSZXNvdXJjZSoUCP4IEOcHGMAEIglzZXRQcm9tcHQqJwj/CBDnBxjPBCIcc2V0U3VwcG9ydEJhY2tncm91bmRUaW50TGlzdConCIAJEOcHGNAEIhxzZXRTdXBwb3J0QmFja2dyb3VuZFRpbnRNb2RlKiAIgQkQ6wcYWiIWZ2V0QXV0b1NpemVNYXhUZXh0U2l6ZSogCIIJEOsHGFoiFmdldEF1dG9TaXplTWluVGV4dFNpemUqJAiDCRDrBxhaIhpnZXRBdXRvU2l6ZVN0ZXBHcmFudWxhcml0eSooCIQJEOsHGNEEIh1nZXRBdXRvU2l6ZVRleHRBdmFpbGFibGVTaXplcyodCIUJEOsHGFoiE2dldEF1dG9TaXplVGV4dFR5cGUqLwiGCRDrBxjKBCIkZ2V0Q3VzdG9tU2VsZWN0aW9uQWN0aW9uTW9kZUNhbGxiYWNrKiEIhwkQ6wcY0gQiFmdldEVtb2ppVGV4dFZpZXdIZWxwZXIqJQiICRDrBxhaIhtnZXRGaXJzdEJhc2VsaW5lVG9Ub3BIZWlnaHQqJwiJCRDrBxhaIh1nZXRMYXN0QmFzZWxpbmVUb0JvdHRvbUhlaWdodCoZCIoJEOsHGN0EIg5nZXRTdXBlckNhbGxlcionCIsJEOsHGMsEIhxnZXRTdXBwb3J0QmFja2dyb3VuZFRpbnRMaXN0KicIjAkQ6wcYzAQiHGdldFN1cHBvcnRCYWNrZ3JvdW5kVGludE1vZGUqLgiNCRDrBxjLBCIjZ2V0U3VwcG9ydENvbXBvdW5kRHJhd2FibGVzVGludExpc3QqLgiOCRDrBxjMBCIjZ2V0U3VwcG9ydENvbXBvdW5kRHJhd2FibGVzVGludE1vZGUqEgiPCRDrBxi7BCIHZ2V0VGV4dCocCJAJEOsHGNYEIhFnZXRUZXh0Q2xhc3NpZmllciolCJEJEOsHGN4EIhpnZXRUZXh0TWV0cmljc1BhcmFtc0NvbXBhdCoUCJIJEOsHGFEiCnNldEFsbENhcHMqKQiTCRDrBxgQIh9zZXRBdXRvU2l6ZVRleHRUeXBlV2l0aERlZmF1bHRzKiAIlAkQ6wcYvQQiFXNldEJhY2tncm91bmREcmF3YWJsZSofCJUJEOsHGBAiFXNldEJhY2tncm91bmRSZXNvdXJjZSovCJYJEOsHGM0EIiRzZXRDdXN0b21TZWxlY3Rpb25BY3Rpb25Nb2RlQ2FsbGJhY2sqHwiXCRDrBxhRIhVzZXRFbW9qaUNvbXBhdEVuYWJsZWQqFQiYCRDrBxjTBCIKc2V0RmlsdGVycyolCJkJEOsHGBAiG3NldEZpcnN0QmFzZWxpbmVUb1RvcEhlaWdodConCJoJEOsHGBAiHXNldExhc3RCYXNlbGluZVRvQm90dG9tSGVpZ2h0KhcImwkQ6wcYECINc2V0TGluZUhlaWdodCodCJwJEOsHGN8EIhJzZXRQcmVjb21wdXRlZFRleHQqJwidCRDrBxjPBCIcc2V0U3VwcG9ydEJhY2tncm91bmRUaW50TGlzdConCJ4JEOsHGNAEIhxzZXRTdXBwb3J0QmFja2dyb3VuZFRpbnRNb2RlKi4InwkQ6wcYzwQiI3NldFN1cHBvcnRDb21wb3VuZERyYXdhYmxlc1RpbnRMaXN0Ki4IoAkQ6wcY0AQiI3NldFN1cHBvcnRDb21wb3VuZERyYXdhYmxlc1RpbnRNb2RlKhwIoQkQ6wcY1wQiEXNldFRleHRDbGFzc2lmaWVyKhgIogkQ6wcY4AQiDXNldFRleHRGdXR1cmUqJQijCRDrBxjhBCIac2V0VGV4dE1ldHJpY3NQYXJhbXNDb21wYXQqIQikCRDvBxjSBCIWZ2V0RW1vamlUZXh0Vmlld0hlbHBlcionCKUJEO8HGMsEIhxnZXRTdXBwb3J0QmFja2dyb3VuZFRpbnRMaXN0KicIpgkQ7wcYzAQiHGdldFN1cHBvcnRCYWNrZ3JvdW5kVGludE1vZGUqLginCRDvBxjLBCIjZ2V0U3VwcG9ydENvbXBvdW5kRHJhd2FibGVzVGludExpc3QqLgioCRDvBxjMBCIjZ2V0U3VwcG9ydENvbXBvdW5kRHJhd2FibGVzVGludE1vZGUqFAipCRDvBxhRIgpzZXRBbGxDYXBzKiAIqgkQ7wcYvQQiFXNldEJhY2tncm91bmREcmF3YWJsZSofCKsJEO8HGBAiFXNldEJhY2tncm91bmRSZXNvdXJjZSofCKwJEO8HGFEiFXNldEVtb2ppQ29tcGF0RW5hYmxlZCoVCK0JEO8HGNMEIgpzZXRGaWx0ZXJzKicIrgkQ7wcYzwQiHHNldFN1cHBvcnRCYWNrZ3JvdW5kVGludExpc3QqJwivCRDvBxjQBCIcc2V0U3VwcG9ydEJhY2tncm91bmRUaW50TW9kZSouCLAJEO8HGM8EIiNzZXRTdXBwb3J0Q29tcG91bmREcmF3YWJsZXNUaW50TGlzdCouCLEJEO8HGNAEIiNzZXRTdXBwb3J0Q29tcG91bmREcmF3YWJsZXNUaW50TW9kZSoaCLIJEPAHGFEiEHNldEFsbG93U3RhY2tpbmcqFAizCRDwBxhRIgpzZXRTdGFja2VkKh4ItAkQ8QcY4gQiE2dldEZpeGVkSGVpZ2h0TWFqb3IqHgi1CRDxBxjiBCITZ2V0Rml4ZWRIZWlnaHRNaW5vciodCLYJEPEHGOIEIhJnZXRGaXhlZFdpZHRoTWFqb3IqHQi3CRDxBxjiBCISZ2V0Rml4ZWRXaWR0aE1pbm9yKhsIuAkQ8QcY4gQiEGdldE1pbldpZHRoTWFqb3IqGwi5CRDxBxjiBCIQZ2V0TWluV2lkdGhNaW5vciocCLoJEPEHGOMEIhFzZXRBdHRhY2hMaXN0ZW5lciogCLsJEPQHGFEiFnNldExpc3RTZWxlY3Rpb25IaWRkZW4qKAi8CRD1BxjkBCIdc2V0T25GaXRTeXN0ZW1XaW5kb3dzTGlzdGVuZXIqKAi9CRD3BxjkBCIdc2V0T25GaXRTeXN0ZW1XaW5kb3dzTGlzdGVuZXIqFQi+CRD4BxhaIgtnZXRCYXNlbGluZSomCL8JEPgHGFoiHGdldEJhc2VsaW5lQWxpZ25lZENoaWxkSW5kZXgqHQjACRD4BxjHBCISZ2V0RGl2aWRlckRyYXdhYmxlKhsIwQkQ+AcYWiIRZ2V0RGl2aWRlclBhZGRpbmcqGQjCCRD4BxhaIg9nZXREaXZpZGVyV2lkdGgqFAjDCRD4BxhaIgpnZXRHcmF2aXR5KhgIxAkQ+AcYWiIOZ2V0T3JpZW50YXRpb24qGQjFCRD4BxhaIg9nZXRTaG93RGl2aWRlcnMqHgjGCRD4BxhaIhRnZXRWaXJ0dWFsQ2hpbGRDb3VudCoXCMcJEPgHGMYBIgxnZXRXZWlnaHRTdW0qHAjICRD4BxhRIhJzZXRCYXNlbGluZUFsaWduZWQqJgjJCRD4BxgQIhxzZXRCYXNlbGluZUFsaWduZWRDaGlsZEluZGV4Kh0IygkQ+AcYvQQiEnNldERpdmlkZXJEcmF3YWJsZSobCMsJEPgHGBAiEXNldERpdmlkZXJQYWRkaW5nKhQIzAkQ+AcYECIKc2V0R3Jhdml0eSoeCM0JEPgHGBAiFHNldEhvcml6b250YWxHcmF2aXR5KisIzgkQ+AcYUSIhc2V0TWVhc3VyZVdpdGhMYXJnZXN0Q2hpbGRFbmFibGVkKhgIzwkQ+AcYECIOc2V0T3JpZW50YXRpb24qGQjQCRD4BxgQIg9zZXRTaG93RGl2aWRlcnMqHAjRCRD4BxgQIhJzZXRWZXJ0aWNhbEdyYXZpdHkqFwjSCRD4BxjHASIMc2V0V2VpZ2h0U3VtKhsI0wkQ+QcY5QQiEHNldEhvdmVyTGlzdGVuZXIqFgjUCRD5Bxi9BCILc2V0U2VsZWN0b3IqJQjVCRD7BxhaIhtnZXRTZWFyY2hWaWV3VGV4dE1pbldpZHRoRHAqGgjWCRD7BxhRIhBzZXRJbWVWaXNpYmlsaXR5KhgI1wkQ+wcY5gQiDXNldFNlYXJjaFZpZXcqFgjYCRD7BxgQIgxzZXRUaHJlc2hvbGQqKAjZCRD9Bxi7BCIdZ2V0Q29sbGFwc2VDb250ZW50RGVzY3JpcHRpb24qGgjaCRD9BxjHBCIPZ2V0Q29sbGFwc2VJY29uKhwI2wkQ/QcYWiISZ2V0Q29udGVudEluc2V0RW5kKicI3AkQ/QcYWiIdZ2V0Q29udGVudEluc2V0RW5kV2l0aEFjdGlvbnMqHQjdCRD9BxhaIhNnZXRDb250ZW50SW5zZXRMZWZ0Kh4I3gkQ/QcYWiIUZ2V0Q29udGVudEluc2V0UmlnaHQqHgjfCRD9BxhaIhRnZXRDb250ZW50SW5zZXRTdGFydCosCOAJEP0HGFoiImdldENvbnRlbnRJbnNldFN0YXJ0V2l0aE5hdmlnYXRpb24qIwjhCRD9BxhaIhlnZXRDdXJyZW50Q29udGVudEluc2V0RW5kKiQI4gkQ/QcYWiIaZ2V0Q3VycmVudENvbnRlbnRJbnNldExlZnQqJQjjCRD9BxhaIhtnZXRDdXJyZW50Q29udGVudEluc2V0UmlnaHQqJQjkCRD9BxhaIhtnZXRDdXJyZW50Q29udGVudEluc2V0U3RhcnQqHgjlCRD9BxjnBCITZ2V0Q3VycmVudE1lbnVJdGVtcyoSCOYJEP0HGMcEIgdnZXRMb2dvKh0I5wkQ/QcYuwQiEmdldExvZ29EZXNjcmlwdGlvbioSCOgJEP0HGMYEIgdnZXRNZW51KhoI6QkQ/QcY6AQiD2dldE1lbnVJbmZsYXRlciobCOoJEP0HGMIEIhBnZXROYXZCdXR0b25WaWV3KioI6wkQ/QcYuwQiH2dldE5hdmlnYXRpb25Db250ZW50RGVzY3JpcHRpb24qHAjsCRD9BxjHBCIRZ2V0TmF2aWdhdGlvbkljb24qJgjtCRD9BxjpBCIbZ2V0T3V0ZXJBY3Rpb25NZW51UHJlc2VudGVyKhoI7gkQ/QcYxwQiD2dldE92ZXJmbG93SWNvbioZCO8JEP0HGFciD2dldFBvcHVwQ29udGV4dCoXCPAJEP0HGFoiDWdldFBvcHVwVGhlbWUqFgjxCRD9Bxi7BCILZ2V0U3VidGl0bGUqHgjyCRD9BxjqBCITZ2V0U3VidGl0bGVUZXh0VmlldyoTCPMJEP0HGLsEIghnZXRUaXRsZSoeCPQJEP0HGFoiFGdldFRpdGxlTWFyZ2luQm90dG9tKhsI9QkQ/QcYWiIRZ2V0VGl0bGVNYXJnaW5FbmQqHQj2CRD9BxhaIhNnZXRUaXRsZU1hcmdpblN0YXJ0KhsI9wkQ/QcYWiIRZ2V0VGl0bGVNYXJnaW5Ub3AqGwj4CRD9BxjqBCIQZ2V0VGl0bGVUZXh0VmlldyoVCPkJEP0HGOsEIgpnZXRXcmFwcGVyKicI+gkQ/QcYUSIdc2V0QmFja0ludm9rZWRDYWxsYmFja0VuYWJsZWQqJwj7CRD9BxgQIh1zZXRDb2xsYXBzZUNvbnRlbnREZXNjcmlwdGlvbiooCPwJEP0HGMAEIh1zZXRDb2xsYXBzZUNvbnRlbnREZXNjcmlwdGlvbioZCP0JEP0HGBAiD3NldENvbGxhcHNlSWNvbioaCP4JEP0HGL0EIg9zZXRDb2xsYXBzZUljb24qGAj/CRD9BxhRIg5zZXRDb2xsYXBzaWJsZSonCIAKEP0HGBAiHXNldENvbnRlbnRJbnNldEVuZFdpdGhBY3Rpb25zKiwIgQoQ/QcYECIic2V0Q29udGVudEluc2V0U3RhcnRXaXRoTmF2aWdhdGlvbioRCIIKEP0HGBAiB3NldExvZ28qEgiDChD9Bxi9BCIHc2V0TG9nbyocCIQKEP0HGBAiEnNldExvZ29EZXNjcmlwdGlvbiodCIUKEP0HGMAEIhJzZXRMb2dvRGVzY3JpcHRpb24qKQiGChD9BxgQIh9zZXROYXZpZ2F0aW9uQ29udGVudERlc2NyaXB0aW9uKioIhwoQ/QcYwAQiH3NldE5hdmlnYXRpb25Db250ZW50RGVzY3JpcHRpb24qGwiIChD9BxgQIhFzZXROYXZpZ2F0aW9uSWNvbiocCIkKEP0HGL0EIhFzZXROYXZpZ2F0aW9uSWNvbionCIoKEP0HGOwEIhxzZXROYXZpZ2F0aW9uT25DbGlja0xpc3RlbmVyKiUIiwoQ/QcY7QQiGnNldE9uTWVudUl0ZW1DbGlja0xpc3RlbmVyKhoIjAoQ/QcYvQQiD3NldE92ZXJmbG93SWNvbioXCI0KEP0HGBAiDXNldFBvcHVwVGhlbWUqFQiOChD9BxgQIgtzZXRTdWJ0aXRsZSoWCI8KEP0HGMAEIgtzZXRTdWJ0aXRsZSoeCJAKEP0HGBAiFHNldFN1YnRpdGxlVGV4dENvbG9yKh8IkQoQ/QcYzwQiFHNldFN1YnRpdGxlVGV4dENvbG9yKhIIkgoQ/QcYECIIc2V0VGl0bGUqEwiTChD9BxjABCIIc2V0VGl0bGUqHgiUChD9BxgQIhRzZXRUaXRsZU1hcmdpbkJvdHRvbSobCJUKEP0HGBAiEXNldFRpdGxlTWFyZ2luRW5kKh0IlgoQ/QcYECITc2V0VGl0bGVNYXJnaW5TdGFydCobCJcKEP0HGBAiEXNldFRpdGxlTWFyZ2luVG9wKhsImAoQ/QcYECIRc2V0VGl0bGVUZXh0Q29sb3IqHAiZChD9BxjPBCIRc2V0VGl0bGVUZXh0Q29sb3IqFwiaChCDCBhaIg1nZXRJbmZsYXRlZElkKhwImwoQgwgYwQQiEWdldExheW91dEluZmxhdGVyKhsInAoQgwgYWiIRZ2V0TGF5b3V0UmVzb3VyY2UqFwidChCDCBgQIg1zZXRJbmZsYXRlZElkKhwIngoQgwgY7gQiEXNldExheW91dEluZmxhdGVyKhsInwoQgwgYECIRc2V0TGF5b3V0UmVzb3VyY2UqHwigChCDCBjvBCIUc2V0T25JbmZsYXRlTGlzdGVuZXIqFwihChCDCBgQIg1zZXRWaXNpYmlsaXR5KhgIogoQhQgYUSIOc2V0UmlwcGxlU3RhdGUqIgijChCFCBjwBCIXc2V0UmlwcGxlU3RhdGUkbGFtYmRhJDIqLwikChCGCBgZIiVnZXRDYW5Vc2VDb21wb3NpdGluZ0xheWVyJHVpX2dyYXBoaWNzKhoIpQoQhggY8QQiD2dldENhbnZhc0hvbGRlcioXCKYKEIYIGMIEIgxnZXRPd25lclZpZXcqLwinChCGCBhRIiVzZXRDYW5Vc2VDb21wb3NpdGluZ0xheWVyJHVpX2dyYXBoaWNzKhgIqAoQhggYUSIOc2V0SW52YWxpZGF0ZWQqFwipChCICBhaIg1nZXRDaGlsZENvdW50KisIqgoQiQgYWiIhZ2V0QXV0b0NsZWFyRm9jdXNCZWhhdmlvci00VXRSUGQ0KjcIqwoQiQgYBCItZ2V0RGlzcG9zZVZpZXdDb21wb3NpdGlvblN0cmF0ZWd5JGFubm90YXRpb25zKhsIrAoQiQgYGSIRZ2V0SGFzQ29tcG9zaXRpb24qNgitChCJCBgZIixnZXRTaG91bGRDcmVhdGVDb21wb3NpdGlvbk9uQXR0YWNoZWRUb1dpbmRvdyodCK4KEIkIGBkiE2dldFNob3dMYXlvdXRCb3VuZHMqKQivChCJCBgEIh9nZXRTaG93TGF5b3V0Qm91bmRzJGFubm90YXRpb25zKisIsAoQiQgYECIhc2V0QXV0b0NsZWFyRm9jdXNCZWhhdmlvci0xN3RmSnhNKiYIsQoQiQgY8gQiG3NldFBhcmVudENvbXBvc2l0aW9uQ29udGV4dCobCLIKEIkIGPIEIhBzZXRQYXJlbnRDb250ZXh0KikIswoQiQgY8wQiHnNldFByZXZpb3VzQXR0YWNoZWRXaW5kb3dUb2tlbiodCLQKEIkIGFEiE3NldFNob3dMYXlvdXRCb3VuZHMqHAi1ChCJCBhRIhJzZXRUcmFuc2l0aW9uR3JvdXAqJQi2ChCJCBj0BCIac2V0Vmlld0NvbXBvc2l0aW9uU3RyYXRlZ3kqIgi3ChCJBBj1BCIXZ2V0QWNjZXNzaWJpbGl0eU1hbmFnZXIqIgi4ChCJBBj2BCIXZ2V0QWNjZXNzaWJpbGl0eU1hbmFnZXIqJAi5ChCJBBj3BCIZZ2V0QW5kcm9pZFZpZXdzSGFuZGxlciR1aSoWCLoKEIkEGPgEIgtnZXRBdXRvZmlsbCodCLsKEIkEGPkEIhJnZXRBdXRvZmlsbE1hbmFnZXIqGgi8ChCJBBj6BCIPZ2V0QXV0b2ZpbGxUcmVlKhcIvQoQiQQY+wQiDGdldENsaXBib2FyZCoXCL4KEIkEGPwEIgxnZXRDbGlwYm9hcmQqHgi/ChCJBBj9BCITZ2V0Q2xpcGJvYXJkTWFuYWdlcioeCMAKEIkEGP4EIhNnZXRDbGlwYm9hcmRNYW5hZ2VyKhsIwQoQiQQY/wQiEGdldENvbmZpZ3VyYXRpb24qJgjCChCJBBiABSIbZ2V0Q29udGVudENhcHR1cmVNYW5hZ2VyJHVpKh4IwwoQiQQYgQUiE2dldENvcm91dGluZUNvbnRleHQqFQjEChCJBBiCBSIKZ2V0RGVuc2l0eSogCMUKEIkEGIMFIhVnZXREcmFnQW5kRHJvcE1hbmFnZXIqIAjGChCJBBiEBSIVZ2V0RHJhZ0FuZERyb3BNYW5hZ2VyKiMIxwoQiQQYhQUiGGdldEVtYmVkZGVkVmlld0ZvY3VzUmVjdCoYCMgKEIkEGIYFIg1nZXRGb2N1c093bmVyKiAIyQoQiQQYhwUiFWdldEZvbnRGYW1pbHlSZXNvbHZlcioYCMoKEIkEGIgFIg1nZXRGb250TG9hZGVyKiMIywoQiQQYBCIZZ2V0Rm9udExvYWRlciRhbm5vdGF0aW9ucyoiCMwKEIkEGIkFIhdnZXRGcmFtZUVuZFNjaGVkdWxlciR1aSodCM0KEIkEGIoFIhJnZXRHcmFwaGljc0NvbnRleHQqHAjOChCJBBiLBSIRZ2V0SGFwdGljRmVlZEJhY2sqJgjPChCJBBgZIhxnZXRIYXNQZW5kaW5nTWVhc3VyZU9yTGF5b3V0KiEI0AoQiQQYWiIXZ2V0SW1wb3J0YW50Rm9yQXV0b2ZpbGwqHgjRChCJBBiMBSITZ2V0SW5wdXRNb2RlTWFuYWdlciocCNIKEIkEGI0FIhFnZXRJbnNldHNMaXN0ZW5lcio0CNMKEIkEGBMiKmdldExhc3RNYXRyaXhSZWNhbGN1bGF0aW9uQW5pbWF0aW9uVGltZSR1aSpACNQKEIkEGAQiNmdldExhc3RNYXRyaXhSZWNhbGN1bGF0aW9uQW5pbWF0aW9uVGltZSR1aSRhbm5vdGF0aW9ucyodCNUKEIkEGI4FIhJnZXRMYXlvdXREaXJlY3Rpb24qGQjWChCJBBiPBSIOZ2V0TGF5b3V0Tm9kZXMqGQjXChCJBBiQBSIOZ2V0TGF5b3V0Tm9kZXMqHQjYChCJBBgTIhNnZXRNZWFzdXJlSXRlcmF0aW9uKiII2QoQiQQYkQUiF2dldE1vZGlmaWVyTG9jYWxNYW5hZ2VyKiAI2goQiQQYkgUiFWdldE91dE9mRnJhbWVFeGVjdXRvciogCNsKEIkEGJMFIhVnZXRPdXRPZkZyYW1lRXhlY3V0b3IqHAjcChCJBBiUBSIRZ2V0UGxhY2VtZW50U2NvcGUqIAjdChCJBBiVBSIVZ2V0UG9pbnRlckljb25TZXJ2aWNlKj0I3goQiQQYlgUiMmdldFByaW1hcnlEaXJlY3Rpb25hbE1vdGlvbkF4aXNPdmVycmlkZS1kcU5OQmJVJHVpKkgI3woQiQQYBCI+Z2V0UHJpbWFyeURpcmVjdGlvbmFsTW90aW9uQXhpc092ZXJyaWRlLWRxTk5CYlUkdWkkYW5ub3RhdGlvbnMqGQjgChCJBBiXBSIOZ2V0UmVjdE1hbmFnZXIqIQjhChCJBBiYBSIWZ2V0UmV0YWluZWRWYWx1ZXNTdG9yZSoSCOIKEIkEGJkFIgdnZXRSb290Kh0I4woQiQQYBCITZ2V0Um9vdCRhbm5vdGF0aW9ucyoZCOQKEIkEGJoFIg5nZXRSb290Rm9yVGVzdConCOUKEIkEGBkiHWdldFNjcm9sbENhcHR1cmVJblByb2dyZXNzJHVpKhwI5goQiQQYmwUiEWdldFNlbWFudGljc093bmVyKh0I5woQiQQYnAUiEmdldFNoYXJlZERyYXdTY29wZSodCOgKEIkEGBkiE2dldFNob3dMYXlvdXRCb3VuZHMqKQjpChCJBBgEIh9nZXRTaG93TGF5b3V0Qm91bmRzJGFubm90YXRpb25zKh4I6goQiQQYnQUiE2dldFNuYXBzaG90T2JzZXJ2ZXIqKAjrChCJBBieBSIdZ2V0U29mdHdhcmVLZXlib2FyZENvbnRyb2xsZXIqHgjsChCJBBifBSITZ2V0VGV4dElucHV0U2VydmljZSopCO0KEIkEGAQiH2dldFRleHRJbnB1dFNlcnZpY2UkYW5ub3RhdGlvbnMqGQjuChCJBBigBSIOZ2V0VGV4dFRvb2xiYXIqKQjvChCJBBihBSIeZ2V0VW5jYXVnaHRFeGNlcHRpb25IYW5kbGVyJHVpKhII8AoQiQQYwgQiB2dldFZpZXcqHwjxChCJBBiiBSIUZ2V0Vmlld0NvbmZpZ3VyYXRpb24qHAjyChCJBBijBSIRZ2V0Vmlld1RyZWVPd25lcnMqGAjzChCJBBikBSINZ2V0V2luZG93SW5mbyohCPQKEIkEGKUFIhZnZXRfYXV0b2ZpbGxNYW5hZ2VyJHVpKh0I9QoQiQQYowUiEmdldF92aWV3VHJlZU93bmVycyoyCPYKEIkEGEAiKHNldEFjY2Vzc2liaWxpdHlFdmVudEJhdGNoSW50ZXJ2YWxNaWxsaXMqGwj3ChCJBBimBSIQc2V0Q29uZmlndXJhdGlvbiomCPgKEIkEGKcFIhtzZXRDb250ZW50Q2FwdHVyZU1hbmFnZXIkdWkqHgj5ChCJBBioBSITc2V0Q29yb3V0aW5lQ29udGV4dCoVCPoKEIkEGKkFIgpzZXREZW5zaXR5KiAI+woQiQQYqgUiFXNldEZvbnRGYW1pbHlSZXNvbHZlcioiCPwKEIkEGKsFIhdzZXRGcmFtZUVuZFNjaGVkdWxlciR1aSo0CP0KEIkEGEAiKnNldExhc3RNYXRyaXhSZWNhbGN1bGF0aW9uQW5pbWF0aW9uVGltZSR1aSodCP4KEIkEGKwFIhJzZXRMYXlvdXREaXJlY3Rpb24qJwj/ChCJBBitBSIcc2V0T25WaWV3VHJlZU93bmVyc0F2YWlsYWJsZSo9CIALEIkEGK4FIjJzZXRQcmltYXJ5RGlyZWN0aW9uYWxNb3Rpb25BeGlzT3ZlcnJpZGUtcjJlcEx0OCR1aSodCIELEIkEGFEiE3NldFNob3dMYXlvdXRCb3VuZHMqJgiCCxCJBBivBSIbc2V0VW5jYXVnaHRFeGNlcHRpb25IYW5kbGVyKikIgwsQiQQYrwUiHnNldFVuY2F1Z2h0RXhjZXB0aW9uSGFuZGxlciR1aSodCIQLEIkEGLAFIhJzZXRfdmlld1RyZWVPd25lcnMqIAiFCxCOCBixBSIVZ2V0SG9sZGVyVG9MYXlvdXROb2RlKiAIhgsQjggYsQUiFWdldExheW91dE5vZGVUb0hvbGRlciokCIcLEL0IGLsEIhlnZXRBY2Nlc3NpYmlsaXR5Q2xhc3NOYW1lKjYIiAsQvQgYGSIsZ2V0U2hvdWxkQ3JlYXRlQ29tcG9zaXRpb25PbkF0dGFjaGVkVG9XaW5kb3cqQgiJCxC9CBgEIjhnZXRTaG91bGRDcmVhdGVDb21wb3NpdGlvbk9uQXR0YWNoZWRUb1dpbmRvdyRhbm5vdGF0aW9ucyoVCIoLEL0IGLIFIgpzZXRDb250ZW50KiEIiwsQvwgYGSIXZ2V0Q2FuQ2FsY3VsYXRlUG9zaXRpb24qFQiMCxC/CBizBSIKZ2V0Q29udGVudCoXCI0LEL8IGLQFIgxnZXRQYXJhbXMkdWkqIgiOCxC/CBgEIhhnZXRQYXJhbXMkdWkkYW5ub3RhdGlvbnMqJQiPCxC/CBi1BSIaZ2V0UGFyZW50TGF5b3V0Q29vcmRpbmF0ZXMqIwiQCxC/CBiOBSIYZ2V0UGFyZW50TGF5b3V0RGlyZWN0aW9uKiYIkQsQvwgYtgUiG2dldFBvcHVwQ29udGVudFNpemUtYk9NNnRYdyoeCJILEL8IGLcFIhNnZXRQb3NpdGlvblByb3ZpZGVyKjYIkwsQvwgYGSIsZ2V0U2hvdWxkQ3JlYXRlQ29tcG9zaXRpb25PbkF0dGFjaGVkVG9XaW5kb3cqIAiUCxC/CBi4BSIVZ2V0U3ViQ29tcG9zaXRpb25WaWV3KhQIlQsQvwgYayIKZ2V0VGVzdFRhZyoWCJYLEL8IGMIEIgtnZXRWaWV3Um9vdCoiCJcLEL8IGLkFIhdnZXRWaXNpYmxlRGlzcGxheUJvdW5kcyoVCJgLEL8IGLIFIgpzZXRDb250ZW50KhwImQsQvwgYECISc2V0TGF5b3V0RGlyZWN0aW9uKiUImgsQvwgYugUiGnNldFBhcmVudExheW91dENvb3JkaW5hdGVzKiMImwsQvwgYrAUiGHNldFBhcmVudExheW91dERpcmVjdGlvbiomCJwLEL8IGLsFIhtzZXRQb3B1cENvbnRlbnRTaXplLWZoeGpyUEEqHgidCxC/CBi8BSITc2V0UG9zaXRpb25Qcm92aWRlcioUCJ4LEL8IGG0iCnNldFRlc3RUYWcqLAifCxDFCBi9BSIhZ2V0T3JJbnN0YWxsU3lzdGVtQmFyU3RhdGVNb25pdG9yKhkIoAsQxQgYvgUiDnNldFByb3RlY3Rpb25zKiYIoQsQxwgYxgEiG2dldEJvdHRvbUZhZGluZ0VkZ2VTdHJlbmd0aCocCKILEMcIGFoiEmdldE1heFNjcm9sbEFtb3VudCodCKMLEMcIGFoiE2dldE5lc3RlZFNjcm9sbEF4ZXMqJAikCxDHCBi/BSIZZ2V0U2Nyb2xsRmVlZGJhY2tQcm92aWRlcioYCKULEMcIGFoiDmdldFNjcm9sbFJhbmdlKiMIpgsQxwgYxgEiGGdldFRvcEZhZGluZ0VkZ2VTdHJlbmd0aCooCKcLEMcIGMYBIh1nZXRWZXJ0aWNhbFNjcm9sbEZhY3RvckNvbXBhdCoZCKgLEMcIGFEiD3NldEZpbGxWaWV3cG9ydCojCKkLEMcIGFEiGXNldE5lc3RlZFNjcm9sbGluZ0VuYWJsZWQqJAiqCxDHCBjABSIZc2V0T25TY3JvbGxDaGFuZ2VMaXN0ZW5lciojCKsLEMcIGFEiGXNldFNtb290aFNjcm9sbGluZ0VuYWJsZWQqFgisCxDKCBjBBSILZ2V0RnJhZ21lbnQqJgitCxDKCBhRIhxzZXREcmF3RGlzYXBwZWFyaW5nVmlld3NMYXN0Kh4IrgsQyggYwgUiE3NldExheW91dFRyYW5zaXRpb24qKQivCxDKCBjDBSIec2V0T25BcHBseVdpbmRvd0luc2V0c0xpc3RlbmVyKhEIsAsQzggYxAUiBjxpbml0PioRCLELEM8IGMQFIgY8aW5pdD4qEQiyCxDQCBjEBSIGPGluaXQ+KhEIswsQ0QgYxAUiBjxpbml0PioRCLQLENIIGMQFIgY8aW5pdD4qEQi1CxDTCBjFBSIGPGluaXQ+KhAItgsQ4wgYBCIGPGluaXQ+KhAItwsQ5AgYBCIGPGluaXQ+KhAIuAsQ5QgYBCIGPGluaXQ+KhAIuQsQ5ggYBCIGPGluaXQ+KhAIugsQ5wgYBCIGPGluaXQ+KhAIuwsQ6AgYxgUiBXNldFVwKhAIvAsQ6wgYxgUiBXNldFVwKioIvQsQ7AgYxwUiH2FkanVzdExheW91dEluRGlzcGxheUN1dG91dE1vZGUqEAi+CxDtCBjGBSIFc2V0VXAqKgi/CxDuCBjHBSIfYWRqdXN0TGF5b3V0SW5EaXNwbGF5Q3V0b3V0TW9kZSoQCMALEO8IGMYFIgVzZXRVcCokCMELEPAIGMgFIhlsb2NhbGVMaXN0Rm9yTGFuZ3VhZ2VUYWdzKi0IwgsQ8ggYyQUiImxvY2FsZU1hbmFnZXJHZXRBcHBsaWNhdGlvbkxvY2FsZXMqLQjDCxDyCBjKBSIibG9jYWxlTWFuYWdlclNldEFwcGxpY2F0aW9uTG9jYWxlcyoaCMQLEPMIGMsFIg9pc1Bvd2VyU2F2ZU1vZGUqGAjFCxDzCBjMBSINdG9MYW5ndWFnZVRhZyolCMYLEPYIGM0FIhpnZW5lcmF0ZUNvbmZpZ0RlbHRhX2xvY2FsZSoVCMcLEPYIGM4FIgpnZXRMb2NhbGVzKhwIyAsQ9ggYzwUiEXNldERlZmF1bHRMb2NhbGVzKhUIyQsQ9ggY0AUiCnNldExvY2FsZXMqJQjKCxD4CBjRBSIaZ2V0T25CYWNrSW52b2tlZERpc3BhdGNoZXIqKAjLCxD4CBjSBSIdcmVnaXN0ZXJPbkJhY2tQcmVzc2VkQ2FsbGJhY2sqKgjMCxD4CBjTBSIfdW5yZWdpc3Rlck9uQmFja0ludm9rZWRDYWxsYmFjayoiCM0LEPwIGFoiGGdldERpc2FibGVkQ29tcG9uZW50RmxhZyodCM4LEP0IGNQFIhJjcmVhdGVGcm9tWG1sSW5uZXIqJAjPCxD9CBjVBSIZZ2V0Q2hhbmdpbmdDb25maWd1cmF0aW9ucyoSCNALEP0IGNYFIgdpbmZsYXRlKhwI0QsQgQkY1wUiEW9uU2VhcmNoUmVxdWVzdGVkKiUI0gsQgQkY2AUiGm9uV2luZG93U3RhcnRpbmdBY3Rpb25Nb2RlKiUI0wsQhAkY2QUiGm9uUHJvdmlkZUtleWJvYXJkU2hvcnRjdXRzKiII1AsQhQkY2gUiF29uUG9pbnRlckNhcHR1cmVDaGFuZ2VkKhwI1QsQhgkY2wUiEW9uRHJvcEZvclRleHRWaWV3KhgI1gsQhgkY3AUiDW9uRHJvcEZvclZpZXcqHwjXCxCICRjdBSIUc2V0RHJvcERvd25WaWV3VGhlbWUqHAjYCxCKCRjeBSIRZ2V0VGV4dENsYXNzaWZpZXIqGQjZCxCLCRjfBSIOZm9yTGFuZ3VhZ2VUYWcqGgjaCxCMCRjIBSIPZm9yTGFuZ3VhZ2VUYWdzKhkI2wsQjAkY4AUiDnNldFRleHRMb2NhbGVzKiUI3AsQjQkY4QUiGmdldEF1dG9TaXplU3RlcEdyYW51bGFyaXR5KjYI3QsQjQkY4gUiK3NldEF1dG9TaXplVGV4dFR5cGVVbmlmb3JtV2l0aENvbmZpZ3VyYXRpb24qNAjeCxCNCRjjBSIpc2V0QXV0b1NpemVUZXh0VHlwZVVuaWZvcm1XaXRoUHJlc2V0U2l6ZXMqIwjfCxCNCRjkBSIYc2V0Rm9udFZhcmlhdGlvblNldHRpbmdzKhEI4AsQjgkY5QUiBmNyZWF0ZSopCOELEJAJGOYFIh5jcmVhdGVTdGF0aWNMYXlvdXRGb3JNZWFzdXJpbmcqIQjiCxCUCRjnBSIWZHJhd2FibGVIb3RzcG90Q2hhbmdlZColCOMLEJUJGOgFIhppc1NlbGVjdGVkQ2hpbGRWaWV3RW5hYmxlZComCOQLEJUJGOkFIhtzZXRTZWxlY3RlZENoaWxkVmlld0VuYWJsZWQqIAjlCxCXCRjqBSIVZ2V0TWF4QXZhaWxhYmxlSGVpZ2h0Kh0I5gsQmQkY6wUiEnNldEVwaWNlbnRlckJvdW5kcyofCOcLEJkJGOwFIhRzZXRJc0NsaXBwZWRUb1NjcmVlbiodCOgLEJoJGO0FIhJzZXRFbnRlclRyYW5zaXRpb24qHAjpCxCaCRjtBSIRc2V0RXhpdFRyYW5zaXRpb24qGAjqCxCcCRjsBSINc2V0VG91Y2hNb2RhbColCOsLEJ0JGO4FIhpyZWZyZXNoQXV0b0NvbXBsZXRlUmVzdWx0cyodCOwLEJ0JGO8FIhJzZXRJbnB1dE1ldGhvZE1vZGUqJgjtCxCfCRjwBSIbZmluZE9uQmFja0ludm9rZWREaXNwYXRjaGVyKiMI7gsQnwkY8QUiGG5ld09uQmFja0ludm9rZWRDYWxsYmFjayorCO8LEJ8JGNMFIiB0cnlSZWdpc3Rlck9uQmFja0ludm9rZWRDYWxsYmFjayotCPALEJ8JGNMFIiJ0cnlVbnJlZ2lzdGVyT25CYWNrSW52b2tlZENhbGxiYWNrKhkI8QsQoQkYowEiDnNldFRvb2x0aXBUZXh0KiII8gsQogkY8gUiF2NvbXB1dGVGaXRTeXN0ZW1XaW5kb3dzKiMI8wsQowkY8wUiGG1ha2VCYXNpY0FjdGl2aXR5T3B0aW9ucyoaCPQLEKUJGGsiEGdldERlZmF1bHRMb2NhbGUqIgj1CxCmCRj0BSIXc2V0U2hhcmVJZGVudGl0eUVuYWJsZWQqFwj2CxCnCRj1BSIMc2V0Q2xhc3NOYW1lKhsI9wsQqQkYWCIRZGlzYWxsb3dGb3JjZURhcmsqGwj4CxCqCRj2BSIQc3RhcnREcmFnQW5kRHJvcComCPkLEK0JGFgiHGNsZWFyVmlld1RyYW5zbGF0aW9uQ2FsbGJhY2sqJAj6CxCtCRhYIhpzZXRWaWV3VHJhbnNsYXRpb25DYWxsYmFjayoZCPsLEK4JGPcFIg5zZXRQb2ludGVySWNvbioUCPwLELAJGPgFIglmb2N1c2FibGUqIAj9CxCxCRihASIVaXNTaG93aW5nTGF5b3V0Qm91bmRzKiAI/gsQsgkYnAEiFXNldFJlcXVlc3RlZEZyYW1lUmF0ZSoqCP8LELMJGPkFIh9jYWxjdWxhdGVNYXRyaXhUb1dpbmRvdy1FTDhCVGk4Kh0IgAwQtAkY+gUiEmlzVmFsaWRNb3Rpb25FdmVudCoeCIEMELYJGBciFGZvbnRXZWlnaHRBZGp1c3RtZW50KjUIggwQtwkY+wUiKmdldE1heERpYWxvZ0hlaWdodEV4Y2x1ZGluZ1N5c3RlbUJhckluc2V0cyojCIMMELgJGPwFIhhzZXRMYXlvdXRJbkRpc3BsYXlDdXRvdXQqNQiEDBC5CRj7BSIqZ2V0TWF4RGlhbG9nSGVpZ2h0RXhjbHVkaW5nU3lzdGVtQmFySW5zZXRzKhwIhQwQuQkY/QUiEXNldEZpdEluc2V0c1NpZGVzKhwIhgwQuQkY/QUiEXNldEZpdEluc2V0c1R5cGVzKhYIhwwQugkY/gUiC2NyZWF0ZUFzeW5jKhgIiAwQvQkY/wUiDWdldEV4Y2x1c2lvbnMqEAiJDBC+CRiABiIFY2xvc2UqDgiKDBC+CRiBBiIDZHVwKhAIiwwQvgkYggYiBWxzZWVrKhgIjAwQwAkYgwYiDXNldERhdGFTb3VyY2UqHgiNDBDDCRhaIhRnZXRBZFNlcnZpY2VzVmVyc2lvbiojCI4MEMQJGIQGIhhkZWxldGVSZWdpc3RyYXRpb25zQXN5bmMqJwiPDBDECRiFBiIcZ2V0TWVhc3VyZW1lbnRBcGlTdGF0dXNBc3luYyoeCJAMEMQJGIYGIhNyZWdpc3RlclNvdXJjZUFzeW5jKh8IkQwQxAkYhwYiFHJlZ2lzdGVyVHJpZ2dlckFzeW5jKiEIkgwQxAkYiAYiFnJlZ2lzdGVyV2ViU291cmNlQXN5bmMqIgiTDBDECRiJBiIXcmVnaXN0ZXJXZWJUcmlnZ2VyQXN5bmMqHgiUDBDKCRiKBiITZGVsZXRlUmVnaXN0cmF0aW9ucyoiCJUMEMoJGIsGIhdnZXRNZWFzdXJlbWVudEFwaVN0YXR1cyoZCJYMEMoJGIwGIg5yZWdpc3RlclNvdXJjZSoaCJcMEMoJGI0GIg9yZWdpc3RlclRyaWdnZXIqHAiYDBDKCRiOBiIRcmVnaXN0ZXJXZWJTb3VyY2UqHQiZDBDKCRiPBiIScmVnaXN0ZXJXZWJUcmlnZ2VyKhMImgwQywkYGSIJaXNFbmFibGVkKicImwwQzAkYbSIddGhyb3dJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24qJAicDBDMCRhtIhp0aHJvd0lsbGVnYWxTdGF0ZUV4Y2VwdGlvbionCJ0MEM0JGG0iHXRocm93SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKiQIngwQzQkYbSIadGhyb3dJbGxlZ2FsU3RhdGVFeGNlcHRpb24qKAifDBDNCRhtIh50aHJvd0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24qJwigDBDOCRhtIh10aHJvd0lsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiokCKEMEM4JGG0iGnRocm93SWxsZWdhbFN0YXRlRXhjZXB0aW9uKicIogwQzwkYbSIddGhyb3dJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24qJAijDBDPCRhtIhp0aHJvd0lsbGVnYWxTdGF0ZUV4Y2VwdGlvbiouCKQMENAJGAQiJHRocm93Q29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbiotCKUMENEJGJAGIiJ0aHJvd0xpc3RJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKiUIpgwQ0QkYECIbdGhyb3dOZWdhdGl2ZUluZGV4RXhjZXB0aW9uKiMIpwwQ0QkYkAYiGHRocm93T3V0T2ZSYW5nZUV4Y2VwdGlvbiooCKgMENEJGJAGIh10aHJvd1JldmVyc2VkSW5kaWNlc0V4Y2VwdGlvbiokCKkMENIJGG0iGnRocm93SWxsZWdhbFN0YXRlRXhjZXB0aW9uKiQIqgwQ0wkYbSIadGhyb3dJbGxlZ2FsU3RhdGVFeGNlcHRpb24qJwirDBDUCRhtIh10aHJvd0lsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbionCKwMENUJGG0iHXRocm93SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKiQIrQwQ1QkYbSIadGhyb3dJbGxlZ2FsU3RhdGVFeGNlcHRpb24qKAiuDBDVCRhtIh50aHJvd0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24qJwivDBDWCRhtIh10aHJvd0lsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiokCLAMENYJGG0iGnRocm93SWxsZWdhbFN0YXRlRXhjZXB0aW9uKioIsQwQ1wkYkAYiH3Rocm93SW52YWxpZENvbnN0cmFpbnRFeGNlcHRpb24qLwiyDBDXCRiRBiIkdGhyb3dJbnZhbGlkQ29uc3RyYWludHNTaXplRXhjZXB0aW9uKicIswwQ2QkYbSIddGhyb3dJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24qJAi0DBDZCRhtIhp0aHJvd0lsbGVnYWxTdGF0ZUV4Y2VwdGlvbiomCLUMENoJGJIGIht0aHJvd05vU3VjaEVsZW1lbnRFeGNlcHRpb24qLAi2DBDaCRhtIiJ0aHJvd1Vuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKjQItwwQzQkYkgYiKXRocm93SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uRm9yTnVsbENoZWNrKjEIuAwQzQkYkgYiJnRocm93SWxsZWdhbFN0YXRlRXhjZXB0aW9uRm9yTnVsbENoZWNrKjQIuQwQ1QkYkgYiKXRocm93SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uRm9yTnVsbENoZWNrKjEIugwQ1QkYkgYiJnRocm93SWxsZWdhbFN0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GP8EMggIkQIQCRiABTIGCJICGIEFMggIkwIQCRiCBTIGCJQCGIMFMggIlQIQCRiEBTIGCJYCGIUFMggIlwIQCRiGBTIGCJgCGIcFMggImQIQCRiIBTIGCJoCGIkFMggImwIQCRiKBTIGCJwCGIsFMggInQIQCRiMBTIGCJ4CGI0FMggInwIQCRiOBTIGCKACGI8FMggIoQIQCRiQBTIGCKICGJEFMggIowIQCRiSBTIGCKQCGJMFMggIpQIQCRiUBTIGCKYCGJUFMggIpwIQCRiWBTIGCKgCGJcFMggIqQIQCRiYBTIGCKoCGJkFMggIqwIQCRiaBTIGCKwCGJsFMggIrQIQCRicBTIGCK4CGJ0FMggIrwIQCRieBTIGCLACGJ8FMggIsQIQCRigBTIGCLICGKEFMggIswIQCRiiBTIGCLQCGKMFMggItQIQCRikBTIGCLYCGKUFMggItwIQCRimBTIGCLgCGKcFMggIuQIQCRioBTIGCLoCGKkFMggIuwIQCRiqBTIGCLwCGKsFMggIvQIQCRisBTIGCL4CGK0FMggIvwIQCRiuBTIGCMACGK8FMggIwQIQCRiwBTIGCMICGLEFMggIwwIQCRiyBTIGCMQCGLMFMggIxQIQCRi0BTIGCMYCGLUFMggIxwIQCRi2BTIGCMgCGLcFMggIyQIQCRi4BTIGCMoCGLkFMggIywIQCRi6BTIGCMwCGLsFMggIzQIQCRi8BTIGCM4CGL0FMggIzwIQCRi+BTIGCNACGL8FMggI0QIQCRjABTIGCNICGMEFMggI0wIQCRjCBTIGCNQCGMMFMggI1QIQCRjEBTIGCNYCGMUFMggI1wIQCRjGBTIGCNgCGMcFMggI2QIQCRjIBTIGCNoCGMkFMggI2wIQCRjKBTIGCNwCGMsFMggI3QIQCRjMBTIGCN4CGM0FMggI3wIQCRjOBTIGCOACGM8FMggI4QIQCRjQBTIGCOICGNEFMggI4wIQCRjSBTIGCOQCGNMFMggI5QIQCRjUBTIGCOYCGNUFMggI5wIQCRjWBTIGCOgCGNcFMggI6QIQCRjYBTIGCOoCGNkFMggI6wIQCRjaBTIGCOwCGNsFMggI7QIQCRjcBTIGCO4CGN0FMggI7wIQCRjeBTIGCPACGN8FMggI8QIQCRjgBTIGCPICGOEFMggI8wIQCRjiBTIGCPQCGOMFMggI9QIQCRjkBTIGCPYCGOUFMggI9wIQCRjmBTIGCPgCGOcFMggI+QIQCRjoBTIGCPoCGOkFMggI+wIQCRjqBTIGCPwCGOsFMggI/QIQCRjsBTIGCP4CGO0FMggI/wIQCRjuBTIGCIADGO8FMggIgQMQCRjwBTIGCIIDGPEFMggIgwMQCRjyBTIGCIQDGPMFMggIhQMQCRj0BTIGCIYDGPUFMggIhwMQCRj2BTIGCIgDGPcFMggIiQMQCRj4BTIGCIoDGPkFMggIiwMQCRj6BTIGCIwDGPsFMggIjQMQCRj8BTIGCI4DGP0FMggIjwMQCRj+BTIGCJADGP8FMggIkQMQCRiABjIGCJIDGIEGMggIkwMQCRiCBjIGCJQDGIMGMggIlQMQCRiEBjIGCJYDGIUGMggIlwMQCRiGBjIGCJgDGIcGMggImQMQCRiIBjIGCJoDGIkGMggImwMQCRiKBjIGCJwDGIsGMggInQMQCRiMBjIGCJ4DGI0GMggInwMQCRiOBjIGCKADGI8GMggIoQMQCRiQBjIGCKIDGJEGMgYIowMYkwYyBgikAxiVBjIGCKUDGJcGMgYIpgMYmQYyBginAxibBjIGCKgDGJ0GMgYIqQMYnwYyBgiqAxihBjIGCKsDGKMGMgYIrAMYpQYyBgitAxinBjIGCK4DGKkGMgYIrwMYqwYyBgiwAxitBjIGCLEDGK8GMgYIsgMYsQYyBgizAxizBjIGCLQDGLUGMgYItQMYtwYyBgi2Axi5BjIGCLcDGLsGMgYIuAMYvQYyBgi5Axi/BjIGCLoDGMEGMggIuwMQCRjCBjIGCLwDGMMGMggIvQMQCRjEBjIGCL4DGMUGMggIvwMQCRjGBjIGCMADGMcGMggIwQMQCRjIBjIGCMIDGMkGMggIwwMQCRjKBjIGCMQDGMsGMggIxQMQCRjMBjIGCMYDGM0GMggIxwMQCRjOBjIGCMgDGM8GMggIyQMQCRjQBjIGCMoDGNEGMggIywMQCRjSBjIGCMwDGNMGMggIzQMQCRjUBjIGCM4DGNUGMggIzwMQCRjWBjIGCNADGNcGMggI0QMQCRjYBjIGCNIDGNkGMggI0wMQCRjaBjIGCNQDGNsGMggI1QMQCRjcBjIGCNYDGN0GMggI1wMQCRjeBjIGCNgDGN8GMggI2QMQCRjgBjIGCNoDGOEGMggI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6gEYLDIJCIQGEOsBGMYJMgYIhQYYxgkyCQiGBhDsARjGCTIJCIcGEJMBGMYJMgkIiAYQ7QEYxgkyCQiJBhDuARjGCTIICIoGEO8BGG8yCAiLBhDwARhvMggIjAYQ8QEYbzIICI0GEPIBGG8yCAiOBhDzARhvMggIjwYQ9AEYbzIHCJAGEHUYLDIICJEGEAcY2AkyCAiSBhAJGNgJMggIkwYQ9QEYSDIICJQGEPYBGG8yCAiVBhD3ARhvMggIlgYQ+AEYbzotEitMYW5kcm9pZHgvbmF2aWdhdGlvbjMvcnVudGltZS9OYXZCYWNrU3RhY2s7Ol4IARJaTGFuZHJvaWR4L3NhdmVkc3RhdGUvc2VyaWFsaXphdGlvbi9zZXJpYWxpemVycy9TcGFyc2VBcnJheVNlcmlhbGl6ZXIkU3BhcnNlQXJyYXlTdXJyb2dhdGU7Ok8IAhJLTGNvbS9nb29nbGUvc2FtcGxlcy9hcHBzL25vd2luYW5kcm9pZC9jb3JlL25ldHdvcmsvbW9kZWwvTmV0d29ya0NoYW5nZUxpc3Q7OlEIAxJNTGNvbS9nb29nbGUvc2FtcGxlcy9hcHBzL25vd2luYW5kcm9pZC9jb3JlL25ldHdvcmsvbW9kZWwvTmV0d29ya05ld3NSZXNvdXJjZTs6SggEEkZMY29tL2dvb2dsZS9zYW1wbGVzL2FwcHMvbm93aW5hbmRyb2lkL2NvcmUvbmV0d29yay9tb2RlbC9OZXR3b3JrVG9waWM7OlAIBRJMTGNvbS9nb29nbGUvc2FtcGxlcy9hcHBzL25vd2luYW5kcm9pZC9jb3JlL25ldHdvcmsvcmV0cm9maXQvTmV0d29ya1Jlc3BvbnNlOzpbCAYSV0xjb20vZ29vZ2xlL3NhbXBsZXMvYXBwcy9ub3dpbmFuZHJvaWQvZmVhdHVyZS9ib29rbWFya3MvYXBpL25hdmlnYXRpb24vQm9va21hcmtzTmF2S2V5OzpVCAcSUUxjb20vZ29vZ2xlL3NhbXBsZXMvYXBwcy9ub3dpbmFuZHJvaWQvZmVhdHVyZS9mb3J5b3UvYXBpL25hdmlnYXRpb24vRm9yWW91TmF2S2V5OzpbCAgSV0xjb20vZ29vZ2xlL3NhbXBsZXMvYXBwcy9ub3dpbmFuZHJvaWQvZmVhdHVyZS9pbnRlcmVzdHMvYXBpL25hdmlnYXRpb24vSW50ZXJlc3RzTmF2S2V5OzpVCAkSUUxjb20vZ29vZ2xlL3NhbXBsZXMvYXBwcy9ub3dpbmFuZHJvaWQvZmVhdHVyZS9zZWFyY2gvYXBpL25hdmlnYXRpb24vU2VhcmNoTmF2S2V5OzpTCAoST0xjb20vZ29vZ2xlL3NhbXBsZXMvYXBwcy9ub3dpbmFuZHJvaWQvZmVhdHVyZS90b3BpYy9hcGkvbmF2aWdhdGlvbi9Ub3BpY05hdktleTs6KggLEiZMa290bGlueC9kYXRldGltZS9GaXhlZE9mZnNldFRpbWVab25lOzoeCAwSGkxrb3RsaW54L2RhdGV0aW1lL0luc3RhbnQ7OiAIDRIcTGtvdGxpbngvZGF0ZXRpbWUvTG9jYWxEYXRlOzogCA4SHExrb3RsaW54L2RhdGV0aW1lL0xvY2FsVGltZTs6HwgPEhtMa290bGlueC9kYXRldGltZS9UaW1lWm9uZTs6IAgQEhxMa290bGlueC9kYXRldGltZS9VdGNPZmZzZXQ7OioIERImTGtvdGxpbngvc2VyaWFsaXphdGlvbi9qc29uL0pzb25BcnJheTs6LAgSEihMa290bGlueC9zZXJpYWxpemF0aW9uL2pzb24vSnNvbkVsZW1lbnQ7OikIExIlTGtvdGxpbngvc2VyaWFsaXphdGlvbi9qc29uL0pzb25OdWxsOzorCBQSJ0xrb3RsaW54L3NlcmlhbGl6YXRpb24vanNvbi9Kc29uT2JqZWN0OzouCBUSKkxrb3RsaW54L3NlcmlhbGl6YXRpb24vanNvbi9Kc29uUHJpbWl0aXZlOzo5CBYSNUxhbmRyb2lkeC9uYXZpZ2F0aW9uMy9ydW50aW1lL05hdkJhY2tTdGFjayRDb21wYW5pb247OmgIFxJkTGFuZHJvaWR4L3NhdmVkc3RhdGUvc2VyaWFsaXphdGlvbi9zZXJpYWxpemVycy9TcGFyc2VBcnJheVNlcmlhbGl6ZXIkU3BhcnNlQXJyYXlTdXJyb2dhdGUkQ29tcGFuaW9uOzpZCBgSVUxjb20vZ29vZ2xlL3NhbXBsZXMvYXBwcy9ub3dpbmFuZHJvaWQvY29yZS9uZXR3b3JrL21vZGVsL05ldHdvcmtDaGFuZ2VMaXN0JENvbXBhbmlvbjs6WwgZEldMY29tL2dvb2dsZS9zYW1wbGVzL2FwcHMvbm93aW5hbmRyb2lkL2NvcmUvbmV0d29yay9tb2RlbC9OZXR3b3JrTmV3c1Jlc291cmNlJENvbXBhbmlvbjs6VAgaElBMY29tL2dvb2dsZS9zYW1wbGVzL2FwcHMvbm93aW5hbmRyb2lkL2NvcmUvbmV0d29yay9tb2RlbC9OZXR3b3JrVG9waWMkQ29tcGFuaW9uOzpaCBsSVkxjb20vZ29vZ2xlL3NhbXBsZXMvYXBwcy9ub3dpbmFuZHJvaWQvY29yZS9uZXR3b3JrL3JldHJvZml0L05ldHdvcmtSZXNwb25zZSRDb21wYW5pb247OmUIHBJhTGNvbS9nb29nbGUvc2FtcGxlcy9hcHBzL25vd2luYW5kcm9pZC9mZWF0dXJlL2ludGVyZXN0cy9hcGkvbmF2aWdhdGlvbi9JbnRlcmVzdHNOYXZLZXkkQ29tcGFuaW9uOzpdCB0SWUxjb20vZ29vZ2xlL3NhbXBsZXMvYXBwcy9ub3dpbmFuZHJvaWQvZmVhdHVyZS90b3BpYy9hcGkvbmF2aWdhdGlvbi9Ub3BpY05hdktleSRDb21wYW5pb247OjQIHhIwTGtvdGxpbngvZGF0ZXRpbWUvRml4ZWRPZmZzZXRUaW1lWm9uZSRDb21wYW5pb247OigIHxIkTGtvdGxpbngvZGF0ZXRpbWUvSW5zdGFudCRDb21wYW5pb247OioIIBImTGtvdGxpbngvZGF0ZXRpbWUvTG9jYWxEYXRlJENvbXBhbmlvbjs6KgghEiZMa290bGlueC9kYXRldGltZS9Mb2NhbFRpbWUkQ29tcGFuaW9uOzopCCISJUxrb3RsaW54L2RhdGV0aW1lL1RpbWVab25lJENvbXBhbmlvbjs6KggjEiZMa290bGlueC9kYXRldGltZS9VdGNPZmZzZXQkQ29tcGFuaW9uOzo0CCQSMExrb3RsaW54L3NlcmlhbGl6YXRpb24vanNvbi9Kc29uQXJyYXkkQ29tcGFuaW9uOzo2CCUSMkxrb3RsaW54L3NlcmlhbGl6YXRpb24vanNvbi9Kc29uRWxlbWVudCRDb21wYW5pb247OjUIJhIxTGtvdGxpbngvc2VyaWFsaXphdGlvbi9qc29uL0pzb25PYmplY3QkQ29tcGFuaW9uOzo4CCcSNExrb3RsaW54L3NlcmlhbGl6YXRpb24vanNvbi9Kc29uUHJpbWl0aXZlJENvbXBhbmlvbjs6JwgoEiNMa290bGlueC9zZXJpYWxpemF0aW9uL0tTZXJpYWxpemVyOzpLCCkSR0xhbmRyb2lkeC93aW5kb3cvbGF5b3V0L2FkYXB0ZXIvc2lkZWNhci9EaXN0aW5jdEVsZW1lbnRTaWRlY2FyQ2FsbGJhY2s7Ok4IKhJKTGFuZHJvaWR4L3dpbmRvdy9sYXlvdXQvYWRhcHRlci9zaWRlY2FyL1NpZGVjYXJDb21wYXQkVHJhbnNsYXRpbmdDYWxsYmFjazs6MAgrEixMYW5kcm9pZHgvd2luZG93L3NpZGVjYXIvU2lkZWNhckRldmljZVN0YXRlOzoFCCwSAVY6GAgtEhRMYW5kcm9pZC9vcy9JQmluZGVyOzo1CC4SMUxhbmRyb2lkeC93aW5kb3cvc2lkZWNhci9TaWRlY2FyV2luZG93TGF5b3V0SW5mbzs6VggvElJMY29tL2dvb2dsZS9zYW1wbGVzL2FwcHMvbm93aW5hbmRyb2lkL2NvcmUvbmV0d29yay9yZXRyb2ZpdC9SZXRyb2ZpdE5pYU5ldHdvcmtBcGk7OioIMBImTGFuZHJvaWR4L2ZyYWdtZW50L2FwcC9EaWFsb2dGcmFnbWVudDs6PggxEjpMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9jb21tb24vU3VwcG9ydEVycm9yRGlhbG9nRnJhZ21lbnQ7OjQIMhIwTGNvbS9nb29nbGUvYW5kcm9pZC9nbXMvY29tbW9uL2FwaS9pbnRlcm5hbC96emQ7OjwIMxI4TGNvbS9nb29nbGUvYW5kcm9pZC9kYXRhdHJhbnNwb3J0L2NjdC9DY3RCYWNrZW5kRmFjdG9yeTs6NAg0EjBMY29tL2dvb2dsZS9maXJlYmFzZS9GaXJlYmFzZUNvbW1vbkt0eFJlZ2lzdHJhcjs6NAg1EjBMY29tL2dvb2dsZS9maXJlYmFzZS9hYnQvY29tcG9uZW50L0FidFJlZ2lzdHJhcjs6Ugg2Ek5MY29tL2dvb2dsZS9maXJlYmFzZS9hbmFseXRpY3MvY29ubmVjdG9yL2ludGVybmFsL0FuYWx5dGljc0Nvbm5lY3RvclJlZ2lzdHJhcjs6RQg3EkFMY29tL2dvb2dsZS9maXJlYmFzZS9jcmFzaGx5dGljcy9GaXJlYmFzZUNyYXNobHl0aWNzS3R4UmVnaXN0cmFyOzpJCDgSRUxjb20vZ29vZ2xlL2ZpcmViYXNlL2NyYXNobHl0aWNzL2t0eC9GaXJlYmFzZUNyYXNobHl0aWNzS3R4UmVnaXN0cmFyOzo6CDkSNkxjb20vZ29vZ2xlL2ZpcmViYXNlL2RhdGF0cmFuc3BvcnQvVHJhbnNwb3J0UmVnaXN0cmFyOzpGCDoSQkxjb20vZ29vZ2xlL2ZpcmViYXNlL2luc3RhbGxhdGlvbnMvRmlyZWJhc2VJbnN0YWxsYXRpb25zUmVnaXN0cmFyOzo4CDsSNExjb20vZ29vZ2xlL2ZpcmViYXNlL2t0eC9GaXJlYmFzZUNvbW1vbkt0eFJlZ2lzdHJhcjs6Owg8EjdMY29tL2dvb2dsZS9maXJlYmFzZS9rdHgvRmlyZWJhc2VDb21tb25MZWdhY3lSZWdpc3RyYXI7Oj4IPRI6TGNvbS9nb29nbGUvZmlyZWJhc2UvbWVzc2FnaW5nL0ZpcmViYXNlTWVzc2FnaW5nUmVnaXN0cmFyOzo3CD4SM0xjb20vZ29vZ2xlL2ZpcmViYXNlL3BlcmYvRmlyZWJhc2VQZXJmS3R4UmVnaXN0cmFyOzo0CD8SMExjb20vZ29vZ2xlL2ZpcmViYXNlL3BlcmYvRmlyZWJhc2VQZXJmUmVnaXN0cmFyOzo5CEASNUxjb20vZ29vZ2xlL2ZpcmViYXNlL3BlcmYvY29uZmlnL1JlbW90ZUNvbmZpZ01hbmFnZXI7OjsIQRI3TGNvbS9nb29nbGUvZmlyZWJhc2UvcGVyZi9rdHgvRmlyZWJhc2VQZXJmS3R4UmVnaXN0cmFyOzo1CEISMUxjb20vZ29vZ2xlL2ZpcmViYXNlL3BlcmYvc2Vzc2lvbi9TZXNzaW9uTWFuYWdlcjs6OghDEjZMY29tL2dvb2dsZS9maXJlYmFzZS9wZXJmL3Nlc3Npb24vZ2F1Z2VzL0dhdWdlTWFuYWdlcjs6RwhEEkNMY29tL2dvb2dsZS9maXJlYmFzZS9yZW1vdGVjb25maWcvRmlyZWJhc2VSZW1vdGVDb25maWdLdHhSZWdpc3RyYXI7OjwIRRI4TGNvbS9nb29nbGUvZmlyZWJhc2UvcmVtb3RlY29uZmlnL1JlbW90ZUNvbmZpZ1JlZ2lzdHJhcjs6SwhGEkdMY29tL2dvb2dsZS9maXJlYmFzZS9yZW1vdGVjb25maWcva3R4L0ZpcmViYXNlUmVtb3RlQ29uZmlnS3R4UmVnaXN0cmFyOzo8CEcSOExjb20vZ29vZ2xlL2ZpcmViYXNlL3Nlc3Npb25zL0ZpcmViYXNlU2Vzc2lvbnNSZWdpc3RyYXI7OhYISBISTGphdmEvbGFuZy9TdHJpbmc7Ok8ISRJLTGNvbS9nb29nbGUvZmlyZWJhc2UvY3Jhc2hseXRpY3MvRmlyZWJhc2VDcmFzaGx5dGljc0t0eFJlZ2lzdHJhciRDb21wYW5pb247OlMIShJPTGNvbS9nb29nbGUvZmlyZWJhc2UvY3Jhc2hseXRpY3Mva3R4L0ZpcmViYXNlQ3Jhc2hseXRpY3NLdHhSZWdpc3RyYXIkQ29tcGFuaW9uOzpACEsSPExjb20vZ29vZ2xlL2ZpcmViYXNlL3BlcmYvYXBwbGljYXRpb24vQXBwU3RhdGVVcGRhdGVIYW5kbGVyOzohCEwSHUxqYXZhL2xhbmcvcmVmL1dlYWtSZWZlcmVuY2U7OjoITRI2TGNvbS9nb29nbGUvZmlyZWJhc2UvcGVyZi9hcHBsaWNhdGlvbi9BcHBTdGF0ZU1vbml0b3I7OjkIThI1TGNvbS9nb29nbGUvZmlyZWJhc2UvcGVyZi92MS9BcHBsaWNhdGlvblByb2Nlc3NTdGF0ZTs6BQhPEgFaOgUIUBIBSjoFCFESAUk6LAhSEihMamF2YS91dGlsL2NvbmN1cnJlbnQvQ29uY3VycmVudEhhc2hNYXA7OjgIUxI0TGNvbS9nb29nbGUvZmlyZWJhc2UvcGVyZi9jb25maWcvRGV2aWNlQ2FjaGVNYW5hZ2VyOzojCFQSH0xqYXZhL3V0aWwvY29uY3VycmVudC9FeGVjdXRvcjs6OwhVEjdMY29tL2dvb2dsZS9maXJlYmFzZS9yZW1vdGVjb25maWcvRmlyZWJhc2VSZW1vdGVDb25maWc7OikIVhIlTGNvbS9nb29nbGUvZmlyZWJhc2UvaW5qZWN0L1Byb3ZpZGVyOzo0CFcSMExjb20vZ29vZ2xlL2ZpcmViYXNlL3BlcmYvbG9nZ2luZy9BbmRyb2lkTG9nZ2VyOzoTCFgSD0xqYXZhL3V0aWwvU2V0OzoyCFkSLkxjb20vZ29vZ2xlL2ZpcmViYXNlL3BlcmYvc2Vzc2lvbi9QZXJmU2Vzc2lvbjs6IQhaEh1MamF2YS91dGlsL2NvbmN1cnJlbnQvRnV0dXJlOzo0CFsSMExjb20vZ29vZ2xlL2ZpcmViYXNlL3BlcmYvY29uZmlnL0NvbmZpZ1Jlc29sdmVyOzopCFwSJUxjb20vZ29vZ2xlL2ZpcmViYXNlL2NvbXBvbmVudHMvTGF6eTs6KghdEiZMamF2YS91dGlsL2NvbmN1cnJlbnQvU2NoZWR1bGVkRnV0dXJlOzpCCF4SPkxjb20vZ29vZ2xlL2ZpcmViYXNlL3BlcmYvc2Vzc2lvbi9nYXVnZXMvR2F1Z2VNZXRhZGF0YU1hbmFnZXI7OjkIXxI1TGNvbS9nb29nbGUvZmlyZWJhc2UvcGVyZi90cmFuc3BvcnQvVHJhbnNwb3J0TWFuYWdlcjs6RghgEkJMY29tL2dvb2dsZS9maXJlYmFzZS9zZXNzaW9ucy9GaXJlYmFzZVNlc3Npb25zUmVnaXN0cmFyJENvbXBhbmlvbjs6LghhEipMY29tL2dvb2dsZS9maXJlYmFzZS9jb21wb25lbnRzL1F1YWxpZmllZDs6RwhiEkNMY29tL2dvb2dsZS9hbmRyb2lkL2RhdGF0cmFuc3BvcnQvcnVudGltZS9iYWNrZW5kcy9DcmVhdGlvbkNvbnRleHQ7OkgIYxJETGNvbS9nb29nbGUvYW5kcm9pZC9kYXRhdHJhbnNwb3J0L3J1bnRpbWUvYmFja2VuZHMvVHJhbnNwb3J0QmFja2VuZDs6FAhkEhBMamF2YS91dGlsL0xpc3Q7OjcIZRIzTGNvbS9nb29nbGUvZmlyZWJhc2UvY29tcG9uZW50cy9Db21wb25lbnRDb250YWluZXI7OjQIZhIwTGNvbS9nb29nbGUvZmlyZWJhc2UvYWJ0L2NvbXBvbmVudC9BYnRDb21wb25lbnQ7OkAIZxI8TGNvbS9nb29nbGUvZmlyZWJhc2UvYW5hbHl0aWNzL2Nvbm5lY3Rvci9BbmFseXRpY3NDb25uZWN0b3I7OjcIaBIzTGNvbS9nb29nbGUvYW5kcm9pZC9kYXRhdHJhbnNwb3J0L1RyYW5zcG9ydEZhY3Rvcnk7OkAIaRI8TGNvbS9nb29nbGUvZmlyZWJhc2UvaW5zdGFsbGF0aW9ucy9GaXJlYmFzZUluc3RhbGxhdGlvbnNBcGk7OjUIahIxTGNvbS9nb29nbGUvZmlyZWJhc2UvbWVzc2FnaW5nL0ZpcmViYXNlTWVzc2FnaW5nOzowCGsSLExjb20vZ29vZ2xlL2ZpcmViYXNlL3BlcmYvRmlyZWJhc2VQZXJmRWFybHk7OjIIbBIuTGNvbS9nb29nbGUvZmlyZWJhc2UvcGVyZi9GaXJlYmFzZVBlcmZvcm1hbmNlOzosCG0SKExjb20vZ29vZ2xlL2ZpcmViYXNlL3BlcmYvdXRpbC9PcHRpb25hbDs6QAhuEjxMY29tL2dvb2dsZS9maXJlYmFzZS9yZW1vdGVjb25maWcvRmlyZWJhc2VSZW1vdGVDb25maWdWYWx1ZTs6FghvEhJMamF2YS9sYW5nL09iamVjdDs6HQhwEhlMYW5kcm9pZC9jb250ZW50L0NvbnRleHQ7OhcIcRITTGphdmEvbGFuZy9Cb29sZWFuOzoZCHISFUxqYXZhL2xhbmcvRXhjZXB0aW9uOzoTCHMSD0xqYXZhL3V0aWwvTWFwOzo/CHQSO0xjb20vZ29vZ2xlL2ZpcmViYXNlL3BlcmYvc2Vzc2lvbi9nYXVnZXMvQ3B1R2F1Z2VDb2xsZWN0b3I7OkIIdRI+TGNvbS9nb29nbGUvZmlyZWJhc2UvcGVyZi9zZXNzaW9uL2dhdWdlcy9NZW1vcnlHYXVnZUNvbGxlY3Rvcjs6KQh2EiVMY29tL2dvb2dsZS9maXJlYmFzZS9wZXJmL3V0aWwvVGltZXI7Oi8IdxIrTGNvbS9nb29nbGUvZmlyZWJhc2UvcGVyZi92MS9HYXVnZU1ldGFkYXRhOzo8CHgSOExjb20vZ29vZ2xlL2ZpcmViYXNlL3JlbW90ZWNvbmZpZy9SZW1vdGVDb25maWdDb21wb25lbnQ7OjMIeRIvTGNvbS9nb29nbGUvZmlyZWJhc2Uvc2Vzc2lvbnMvRmlyZWJhc2VTZXNzaW9uczs6Mwh6Ei9MY29tL2dvb2dsZS9maXJlYmFzZS9zZXNzaW9ucy9TZXNzaW9uR2VuZXJhdG9yOzo6CHsSNkxjb20vZ29vZ2xlL2ZpcmViYXNlL3Nlc3Npb25zL1Nlc3Npb25GaXJlbG9nUHVibGlzaGVyOzo8CHwSOExjb20vZ29vZ2xlL2ZpcmViYXNlL3Nlc3Npb25zL3NldHRpbmdzL1Nlc3Npb25zU2V0dGluZ3M7OjMIfRIvTGNvbS9nb29nbGUvZmlyZWJhc2Uvc2Vzc2lvbnMvU2Vzc2lvbkRhdGFzdG9yZTs6QAh+EjxMY29tL2dvb2dsZS9maXJlYmFzZS9zZXNzaW9ucy9TZXNzaW9uTGlmZWN5Y2xlU2VydmljZUJpbmRlcjs6Tgh/EkpMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9keW5hbWl0ZS9EeW5hbWl0ZU1vZHVsZSREeW5hbWl0ZUxvYWRlckNsYXNzTG9hZGVyOzpvCIABEmpMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9keW5hbWl0ZS9kZXNjcmlwdG9ycy9jb20vZ29vZ2xlL2FuZHJvaWQvZ21zL21lYXN1cmVtZW50L2R5bmFtaXRlL01vZHVsZURlc2NyaXB0b3I7OlAIgQESS0xjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL21lYXN1cmVtZW50L2ludGVybmFsL0FwcE1lYXN1cmVtZW50RHluYW1pdGVTZXJ2aWNlOzocCIIBEhdMamF2YS9sYW5nL0NsYXNzTG9hZGVyOzo3CIMBEjJMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9pbnRlcm5hbC9tZWFzdXJlbWVudC96emJ4OzoYCIQBEhNMYW5kcm9pZC9vcy9QYXJjZWw7OjcIhQESMkxjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL2ludGVybmFsL21lYXN1cmVtZW50L3p6ZG07OjcIhgESMkxjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL2ludGVybmFsL21lYXN1cmVtZW50L3p6ZGo7OhgIhwESE0xhbmRyb2lkL29zL0J1bmRsZTs6NwiIARIyTGNvbS9nb29nbGUvYW5kcm9pZC9nbXMvaW50ZXJuYWwvbWVhc3VyZW1lbnQvenpkbzs6NAiJARIvTGNvbS9nb29nbGUvYW5kcm9pZC9nbXMvZHluYW1pYy9JT2JqZWN0V3JhcHBlcjs6NwiKARIyTGNvbS9nb29nbGUvYW5kcm9pZC9nbXMvaW50ZXJuYWwvbWVhc3VyZW1lbnQvenpkdzs6NwiLARIyTGNvbS9nb29nbGUvYW5kcm9pZC9nbXMvaW50ZXJuYWwvbWVhc3VyZW1lbnQvenpkcDs6NwiMARIyTGNvbS9nb29nbGUvYW5kcm9pZC9nbXMvaW50ZXJuYWwvbWVhc3VyZW1lbnQvenpkdTs6HQiNARIYTGFuZHJvaWQvY29udGVudC9JbnRlbnQ7Oh8IjgESGkxhbmRyb2lkeC9hbm5vdGF0aW9uL0tlZXA7OjgIjwESM0xjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL2NvbW1vbi9hbm5vdGF0aW9uL0tlZXBOYW1lOzo1CJABEjBMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9jb21tb24vdXRpbC9EeW5hbWl0ZUFwaTs6JgiRARIhTGFuZHJvaWR4L3dvcmsvaW1wbC9Xb3JrRGF0YWJhc2U7OisIkgESJkxhbmRyb2lkeC93b3JrL2ltcGwvV29ya0RhdGFiYXNlX0ltcGw7OkUIkwESQExjb20vZ29vZ2xlL3NhbXBsZXMvYXBwcy9ub3dpbmFuZHJvaWQvY29yZS9kYXRhYmFzZS9OaWFEYXRhYmFzZTs6SgiUARJFTGNvbS9nb29nbGUvc2FtcGxlcy9hcHBzL25vd2luYW5kcm9pZC9jb3JlL2RhdGFiYXNlL05pYURhdGFiYXNlX0ltcGw7OkEIlQESPExhbmRyb2lkeC9jb21wb3NlL3J1bnRpbWUvdHJhY2luZy9Db21wb3NlVHJhY2luZ0luaXRpYWxpemVyOzoyCJYBEi1MYW5kcm9pZHgvZW1vamkyL3RleHQvRW1vamlDb21wYXRJbml0aWFsaXplcjs6NQiXARIwTGFuZHJvaWR4L2xpZmVjeWNsZS9Qcm9jZXNzTGlmZWN5Y2xlSW5pdGlhbGl6ZXI7OjwImAESN0xhbmRyb2lkeC9wcm9maWxlaW5zdGFsbGVyL1Byb2ZpbGVJbnN0YWxsZXJJbml0aWFsaXplcjs6OgiZARI1TGFuZHJvaWR4L3RyYWNpbmcvcGVyZmV0dG8vU3RhcnR1cFRyYWNpbmdJbml0aWFsaXplcjs6KwiaARImTGFuZHJvaWR4L3dvcmsvV29ya01hbmFnZXJJbml0aWFsaXplcjs6KwibARImTGFuZHJvaWR4L2NvcmUvYXBwL1JlbW90ZUFjdGlvbkNvbXBhdDs6MQicARIsTGFuZHJvaWR4L2NvcmUvZ3JhcGhpY3MvZHJhd2FibGUvSWNvbkNvbXBhdDs6PQidARI4TGFuZHJvaWR4L3ZlcnNpb25lZHBhcmNlbGFibGUvQ3VzdG9tVmVyc2lvbmVkUGFyY2VsYWJsZTs6MgieARItTGNvbS9nb29nbGUvZmlyZWJhc2UvRmlyZWJhc2VDb21tb25SZWdpc3RyYXI7OjgInwESM0xjb20vZ29vZ2xlL2ZpcmViYXNlL2NvbmN1cnJlbnQvRXhlY3V0b3JzUmVnaXN0cmFyOzo7CKABEjZMY29tL2dvb2dsZS9maXJlYmFzZS9jcmFzaGx5dGljcy9DcmFzaGx5dGljc1JlZ2lzdHJhcjs6SgihARJFTGNvbS9nb29nbGUvZmlyZWJhc2UvaW5zdGFsbGF0aW9ucy9GaXJlYmFzZUluc3RhbGxhdGlvbnNLdHhSZWdpc3RyYXI7Ok4IogESSUxjb20vZ29vZ2xlL2ZpcmViYXNlL2luc3RhbGxhdGlvbnMva3R4L0ZpcmViYXNlSW5zdGFsbGF0aW9uc0t0eFJlZ2lzdHJhcjs6QgijARI9TGNvbS9nb29nbGUvZmlyZWJhc2UvbWVzc2FnaW5nL0ZpcmViYXNlTWVzc2FnaW5nS3R4UmVnaXN0cmFyOzpGCKQBEkFMY29tL2dvb2dsZS9maXJlYmFzZS9tZXNzYWdpbmcva3R4L0ZpcmViYXNlTWVzc2FnaW5nS3R4UmVnaXN0cmFyOzolCKUBEiBMYW5kcm9pZHgvd29yay9Xb3JrZXJQYXJhbWV0ZXJzOzpBCKYBEjxMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9jb21tb24vaW50ZXJuYWwvUmVmbGVjdGVkUGFyY2VsYWJsZTs6VwinARJSTGFuZHJvaWR4L3dpbmRvdy9hcmVhL3JlZmxlY3Rpb25ndWFyZC9FeHRlbnNpb25XaW5kb3dBcmVhUHJlc2VudGF0aW9uUmVxdWlyZW1lbnRzOzpRCKgBEkxMYW5kcm9pZHgvd2luZG93L2FyZWEvcmVmbGVjdGlvbmd1YXJkL0V4dGVuc2lvbldpbmRvd0FyZWFTdGF0dXNSZXF1aXJlbWVudHM7Ok8IqQESSkxhbmRyb2lkeC93aW5kb3cvYXJlYS9yZWZsZWN0aW9uZ3VhcmQvV2luZG93QXJlYUNvbXBvbmVudEFwaTNSZXF1aXJlbWVudHM7OhgIqgESE0xhbmRyb2lkL3ZpZXcvVmlldzs6IgirARIdTGFuZHJvaWQvdXRpbC9EaXNwbGF5TWV0cmljczs6PQisARI4TGFuZHJvaWR4L3dpbmRvdy9leHRlbnNpb25zL2NvcmUvdXRpbC9mdW5jdGlvbi9Db25zdW1lcjs6RgitARJBTGFuZHJvaWR4L3dpbmRvdy9leHRlbnNpb25zL2FyZWEvRXh0ZW5zaW9uV2luZG93QXJlYVByZXNlbnRhdGlvbjs6GwiuARIWTGFuZHJvaWQvYXBwL0FjdGl2aXR5OzorCK8BEiZMYW5kcm9pZHgvd2luZG93L3JlZmxlY3Rpb24vQ29uc3VtZXIyOzosCLABEidMYW5kcm9pZHgvd2luZG93L3JlZmxlY3Rpb24vSkZ1bmN0aW9uMjs6LAixARInTGFuZHJvaWR4L3dpbmRvdy9yZWZsZWN0aW9uL1ByZWRpY2F0ZTI7OjoIsgESNUxhbmRyb2lkL3N1cHBvcnQvdjQvYXBwL1JlbW90ZUFjdGlvbkNvbXBhdFBhcmNlbGl6ZXI7OkAIswESO0xhbmRyb2lkL3N1cHBvcnQvdjQvZ3JhcGhpY3MvZHJhd2FibGUvSWNvbkNvbXBhdFBhcmNlbGl6ZXI7OjMItAESLkxhbmRyb2lkeC92ZXJzaW9uZWRwYXJjZWxhYmxlL1ZlcnNpb25lZFBhcmNlbDs6NQi1ARIwTGFuZHJvaWR4L2NvcmUvYXBwL1JlbW90ZUFjdGlvbkNvbXBhdFBhcmNlbGl6ZXI7OjsItgESNkxhbmRyb2lkeC9jb3JlL2dyYXBoaWNzL2RyYXdhYmxlL0ljb25Db21wYXRQYXJjZWxpemVyOzouCLcBEilMYW5kcm9pZHgvdmVyc2lvbmVkcGFyY2VsYWJsZS9QYXJjZWxJbXBsOzpUCLgBEk9MY29tL2dvb2dsZS9zYW1wbGVzL2FwcHMvbm93aW5hbmRyb2lkL3N5bmMvd29ya2Vycy9IaWx0V29ya2VyRmFjdG9yeUVudHJ5UG9pbnQ7OloIuQESVUxkYWdnZXIvaGlsdC9hbmRyb2lkL2ludGVybmFsL2xpZmVjeWNsZS9EZWZhdWx0Vmlld01vZGVsRmFjdG9yaWVzJEFjdGl2aXR5RW50cnlQb2ludDs6XAi6ARJXTGRhZ2dlci9oaWx0L2FuZHJvaWQvaW50ZXJuYWwvbGlmZWN5Y2xlL0hpbHRWaWV3TW9kZWxGYWN0b3J5JEFjdGl2aXR5Q3JlYXRvckVudHJ5UG9pbnQ7Ol8IuwESWkxkYWdnZXIvaGlsdC9hbmRyb2lkL2ludGVybmFsL2xpZmVjeWNsZS9IaWx0Vmlld01vZGVsRmFjdG9yeSRWaWV3TW9kZWxGYWN0b3JpZXNFbnRyeVBvaW50OzpoCLwBEmNMZGFnZ2VyL2hpbHQvYW5kcm9pZC9pbnRlcm5hbC9saWZlY3ljbGUvSGlsdFdyYXBwZXJfSGlsdFZpZXdNb2RlbEZhY3RvcnlfQWN0aXZpdHlDcmVhdG9yRW50cnlQb2ludDs6aAi9ARJjTGRhZ2dlci9oaWx0L2FuZHJvaWQvaW50ZXJuYWwvbWFuYWdlcnMvQWN0aXZpdHlDb21wb25lbnRNYW5hZ2VyJEFjdGl2aXR5Q29tcG9uZW50QnVpbGRlckVudHJ5UG9pbnQ7OngIvgESc0xkYWdnZXIvaGlsdC9hbmRyb2lkL2ludGVybmFsL21hbmFnZXJzL0FjdGl2aXR5UmV0YWluZWRDb21wb25lbnRNYW5hZ2VyJEFjdGl2aXR5UmV0YWluZWRDb21wb25lbnRCdWlsZGVyRW50cnlQb2ludDs6cQi/ARJsTGRhZ2dlci9oaWx0L2FuZHJvaWQvaW50ZXJuYWwvbWFuYWdlcnMvQWN0aXZpdHlSZXRhaW5lZENvbXBvbmVudE1hbmFnZXIkQWN0aXZpdHlSZXRhaW5lZExpZmVjeWNsZUVudHJ5UG9pbnQ7OmYIwAESYUxkYWdnZXIvaGlsdC9hbmRyb2lkL2ludGVybmFsL21hbmFnZXJzL1NlcnZpY2VDb21wb25lbnRNYW5hZ2VyJFNlcnZpY2VDb21wb25lbnRCdWlsZGVyRW50cnlQb2ludDs6SgjBARJFTGNvbS9nb29nbGUvc2FtcGxlcy9hcHBzL25vd2luYW5kcm9pZC9NYWluQWN0aXZpdHlfR2VuZXJhdGVkSW5qZWN0b3I7OkwIwgESR0xjb20vZ29vZ2xlL3NhbXBsZXMvYXBwcy9ub3dpbmFuZHJvaWQvTmlhQXBwbGljYXRpb25fR2VuZXJhdGVkSW5qZWN0b3I7OmQIwwESX0xjb20vZ29vZ2xlL3NhbXBsZXMvYXBwcy9ub3dpbmFuZHJvaWQvc3luYy9zZXJ2aWNlcy9TeW5jTm90aWZpY2F0aW9uc1NlcnZpY2VfR2VuZXJhdGVkSW5qZWN0b3I7OlgIxAESU0xhbmRyb2lkeC9jb21wb3NlL2FuaW1hdGlvbi9BbmltYXRlZENvbnRlbnRUcmFuc2l0aW9uU2NvcGVJbXBsJFNpemVNb2RpZmllckVsZW1lbnQ7OjwIxQESN0xhbmRyb2lkeC9jb21wb3NlL2FuaW1hdGlvbi9FbnRlckV4aXRUcmFuc2l0aW9uRWxlbWVudDs6NAjGARIvTGFuZHJvaWR4L2NvbXBvc2UvZm91bmRhdGlvbi9CYWNrZ3JvdW5kRWxlbWVudDs6PAjHARI3TGFuZHJvaWR4L2NvbXBvc2UvZm91bmRhdGlvbi9Cb3JkZXJNb2RpZmllck5vZGVFbGVtZW50OzozCMgBEi5MYW5kcm9pZHgvY29tcG9zZS9mb3VuZGF0aW9uL0NsaWNrYWJsZUVsZW1lbnQ7OjsIyQESNkxhbmRyb2lkeC9jb21wb3NlL2ZvdW5kYXRpb24vQ29tYmluZWRDbGlja2FibGVFbGVtZW50Ozo0CMoBEi9MYW5kcm9pZHgvY29tcG9zZS9mb3VuZGF0aW9uL0ZvY3VzR3JvdXBFbGVtZW50OzozCMsBEi5MYW5kcm9pZHgvY29tcG9zZS9mb3VuZGF0aW9uL0ZvY3VzYWJsZUVsZW1lbnQ7OjMIzAESLkxhbmRyb2lkeC9jb21wb3NlL2ZvdW5kYXRpb24vSG92ZXJhYmxlRWxlbWVudDs6PAjNARI3TGFuZHJvaWR4L2NvbXBvc2UvZm91bmRhdGlvbi9JbmRpY2F0aW9uTW9kaWZpZXJFbGVtZW50OzozCM4BEi5MYW5kcm9pZHgvY29tcG9zZS9mb3VuZGF0aW9uL01hZ25pZmllckVsZW1lbnQ7OjgIzwESM0xhbmRyb2lkeC9jb21wb3NlL2ZvdW5kYXRpb24vU2Nyb2xsYWJsZUFyZWFFbGVtZW50Ozo5CNABEjRMYW5kcm9pZHgvY29tcG9zZS9mb3VuZGF0aW9uL1Njcm9sbGluZ0xheW91dEVsZW1lbnQ7OlgI0QESU0xhbmRyb2lkeC9jb21wb3NlL2ZvdW5kYXRpb24vZHJhZ2FuZGRyb3AvRHJhZ0FuZERyb3BTb3VyY2VXaXRoRGVmYXVsdFNoYWRvd0VsZW1lbnQ7OjwI0gESN0xhbmRyb2lkeC9jb21wb3NlL2ZvdW5kYXRpb24vZ2VzdHVyZXMvRHJhZ2dhYmxlRWxlbWVudDs6PQjTARI4TGFuZHJvaWR4L2NvbXBvc2UvZm91bmRhdGlvbi9nZXN0dXJlcy9TY3JvbGxhYmxlRWxlbWVudDs6RgjUARJBTGFuZHJvaWR4L2NvbXBvc2UvZm91bmRhdGlvbi9sYXlvdXQvQWxpZ25tZW50TGluZU9mZnNldERwRWxlbWVudDs6PQjVARI4TGFuZHJvaWR4L2NvbXBvc2UvZm91bmRhdGlvbi9sYXlvdXQvQm94Q2hpbGREYXRhRWxlbWVudDs6RwjWARJCTGFuZHJvaWR4L2NvbXBvc2UvZm91bmRhdGlvbi9sYXlvdXQvQ29uc3VtZWRJbnNldHNNb2RpZmllckVsZW1lbnQ7OkYI1wESQUxhbmRyb2lkeC9jb21wb3NlL2ZvdW5kYXRpb24vbGF5b3V0L0Rlcml2ZWRIZWlnaHRNb2RpZmllckVsZW1lbnQ7OjUI2AESMExhbmRyb2lkeC9jb21wb3NlL2ZvdW5kYXRpb24vbGF5b3V0L0ZpbGxFbGVtZW50OzpACNkBEjtMYW5kcm9pZHgvY29tcG9zZS9mb3VuZGF0aW9uL2xheW91dC9Ib3Jpem9udGFsQWxpZ25FbGVtZW50OzpGCNoBEkFMYW5kcm9pZHgvY29tcG9zZS9mb3VuZGF0aW9uL2xheW91dC9JbnNldHNQYWRkaW5nTW9kaWZpZXJFbGVtZW50Ozo/CNsBEjpMYW5kcm9pZHgvY29tcG9zZS9mb3VuZGF0aW9uL2xheW91dC9JbnRyaW5zaWNXaWR0aEVsZW1lbnQ7Oj0I3AESOExhbmRyb2lkeC9jb21wb3NlL2ZvdW5kYXRpb24vbGF5b3V0L0xheW91dFdlaWdodEVsZW1lbnQ7OjgI3QESM0xhbmRyb2lkeC9jb21wb3NlL2ZvdW5kYXRpb24vbGF5b3V0L1BhZGRpbmdFbGVtZW50OzpPCN4BEkpMYW5kcm9pZHgvY29tcG9zZS9mb3VuZGF0aW9uL2xheW91dC9QYWRkaW5nVmFsdWVzQ29uc3VtaW5nTW9kaWZpZXJFbGVtZW50Ozo+CN8BEjlMYW5kcm9pZHgvY29tcG9zZS9mb3VuZGF0aW9uL2xheW91dC9QYWRkaW5nVmFsdWVzRWxlbWVudDs6NQjgARIwTGFuZHJvaWR4L2NvbXBvc2UvZm91bmRhdGlvbi9sYXlvdXQvU2l6ZUVsZW1lbnQ7Ok0I4QESSExhbmRyb2lkeC9jb21wb3NlL2ZvdW5kYXRpb24vbGF5b3V0L1VuaW9uSW5zZXRzQ29uc3VtaW5nTW9kaWZpZXJFbGVtZW50OzpHCOIBEkJMYW5kcm9pZHgvY29tcG9zZS9mb3VuZGF0aW9uL2xheW91dC9VbnNwZWNpZmllZENvbnN0cmFpbnRzRWxlbWVudDs6PAjjARI3TGFuZHJvaWR4L2NvbXBvc2UvZm91bmRhdGlvbi9sYXlvdXQvV3JhcENvbnRlbnRFbGVtZW50OzpLCOQBEkZMYW5kcm9pZHgvY29tcG9zZS9mb3VuZGF0aW9uL2xhenkvbGF5b3V0L0xhenlMYXlvdXRBbmltYXRlSXRlbUVsZW1lbnQ7OlQI5QEST0xhbmRyb2lkeC9jb21wb3NlL2ZvdW5kYXRpb24vbGF6eS9sYXlvdXQvTGF6eUxheW91dEJleW9uZEJvdW5kc01vZGlmaWVyRWxlbWVudDs6aAjmARJjTGFuZHJvaWR4L2NvbXBvc2UvZm91bmRhdGlvbi9sYXp5L2xheW91dC9MYXp5TGF5b3V0SXRlbUFuaW1hdG9yJERpc3BsYXlpbmdEaXNhcHBlYXJpbmdJdGVtc0VsZW1lbnQ7OkoI5wESRUxhbmRyb2lkeC9jb21wb3NlL2ZvdW5kYXRpb24vbGF6eS9sYXlvdXQvTGF6eUxheW91dFNlbWFudGljc01vZGlmaWVyOzpWCOgBElFMYW5kcm9pZHgvY29tcG9zZS9mb3VuZGF0aW9uL2xhenkvbGF5b3V0L1RyYXZlcnNhYmxlUHJlZmV0Y2hTdGF0ZU1vZGlmaWVyRWxlbWVudDs6SwjpARJGTGFuZHJvaWR4L2NvbXBvc2UvZm91bmRhdGlvbi9yZWxvY2F0aW9uL0JyaW5nSW50b1ZpZXdSZXF1ZXN0ZXJFbGVtZW50Ozo+COoBEjlMYW5kcm9pZHgvY29tcG9zZS9mb3VuZGF0aW9uL3NlbGVjdGlvbi9TZWxlY3RhYmxlRWxlbWVudDs6PgjrARI5TGFuZHJvaWR4L2NvbXBvc2UvZm91bmRhdGlvbi9zZWxlY3Rpb24vVG9nZ2xlYWJsZUVsZW1lbnQ7Om8I7AESakxhbmRyb2lkeC9jb21wb3NlL2ZvdW5kYXRpb24vdGV4dC9jb250ZXh0bWVudS9tb2RpZmllci9BZGRUZXh0Q29udGV4dE1lbnVEYXRhQ29tcG9uZW50c1dpdGhDb250ZXh0RWxlbWVudDs6WgjtARJVTGFuZHJvaWR4L2NvbXBvc2UvZm91bmRhdGlvbi90ZXh0L2NvbnRleHRtZW51L21vZGlmaWVyL1RleHRDb250ZXh0TWVudUdlc3R1cmVFbGVtZW50OzphCO4BElxMYW5kcm9pZHgvY29tcG9zZS9mb3VuZGF0aW9uL3RleHQvY29udGV4dG1lbnUvbW9kaWZpZXIvVGV4dENvbnRleHRNZW51VG9vbGJhckhhbmRsZXJFbGVtZW50OzpMCO8BEkdMYW5kcm9pZHgvY29tcG9zZS9mb3VuZGF0aW9uL3RleHQvaGFuZHdyaXRpbmcvU3R5bHVzSGFuZHdyaXRpbmdFbGVtZW50OzpVCPABElBMYW5kcm9pZHgvY29tcG9zZS9mb3VuZGF0aW9uL3RleHQvaW5wdXQvaW50ZXJuYWwvQ29yZVRleHRGaWVsZFNlbWFudGljc01vZGlmaWVyOzpeCPEBEllMYW5kcm9pZHgvY29tcG9zZS9mb3VuZGF0aW9uL3RleHQvaW5wdXQvaW50ZXJuYWwvTGVnYWN5QWRhcHRpbmdQbGF0Zm9ybVRleHRJbnB1dE1vZGlmaWVyOzpWCPIBElFMYW5kcm9pZHgvY29tcG9zZS9mb3VuZGF0aW9uL3RleHQvbW9kaWZpZXJzL1NlbGVjdGFibGVUZXh0QW5ub3RhdGVkU3RyaW5nRWxlbWVudDs6TAjzARJHTGFuZHJvaWR4L2NvbXBvc2UvZm91bmRhdGlvbi90ZXh0L21vZGlmaWVycy9UZXh0QW5ub3RhdGVkU3RyaW5nRWxlbWVudDs6SQj0ARJETGFuZHJvaWR4L2NvbXBvc2UvZm91bmRhdGlvbi90ZXh0L21vZGlmaWVycy9UZXh0U3RyaW5nU2ltcGxlRWxlbWVudDs6Ngj1ARIxTGFuZHJvaWR4L2NvbXBvc2UvbWF0ZXJpYWwzL0luZGljYXRvckxpbmVFbGVtZW50Ozo8CPYBEjdMYW5kcm9pZHgvY29tcG9zZS9tYXRlcmlhbDMvTWluaW11bUludGVyYWN0aXZlTW9kaWZpZXI7OkYI9wESQUxhbmRyb2lkeC9jb21wb3NlL21hdGVyaWFsMy9hZGFwdGl2ZS9sYXlvdXQvQW5pbWF0ZUJvdW5kc0VsZW1lbnQ7OkUI+AESQExhbmRyb2lkeC9jb21wb3NlL21hdGVyaWFsMy9hZGFwdGl2ZS9sYXlvdXQvQW5pbWF0ZWRQYW5lRWxlbWVudDs6RAj5ARI/TGFuZHJvaWR4L2NvbXBvc2UvbWF0ZXJpYWwzL2FkYXB0aXZlL2xheW91dC9QYW5lTWFyZ2luc0VsZW1lbnQ7OkgI+gESQ0xhbmRyb2lkeC9jb21wb3NlL21hdGVyaWFsMy9hZGFwdGl2ZS9sYXlvdXQvUHJlZmVycmVkSGVpZ2h0RWxlbWVudDs6Rwj7ARJCTGFuZHJvaWR4L2NvbXBvc2UvbWF0ZXJpYWwzL2FkYXB0aXZlL2xheW91dC9QcmVmZXJyZWRXaWR0aEVsZW1lbnQ7OlQI/AEST0xhbmRyb2lkeC9jb21wb3NlL21hdGVyaWFsMy9hZGFwdGl2ZS9sYXlvdXQvaW50ZXJuYWwvRGVsZWdhYmxlU2VtYW50aWNzRWxlbWVudDs6RAj9ARI/TGFuZHJvaWR4L2NvbXBvc2UvbWF0ZXJpYWwzL2ludGVybmFsL0NoaWxkU2VtYW50aWNzTm9kZUVsZW1lbnQ7OkUI/gESQExhbmRyb2lkeC9jb21wb3NlL21hdGVyaWFsMy9pbnRlcm5hbC9QYXJlbnRTZW1hbnRpY3NOb2RlRWxlbWVudDs6Swj/ARJGTGFuZHJvaWR4L2NvbXBvc2UvdWkvZHJhZ2FuZGRyb3AvQW5kcm9pZERyYWdBbmREcm9wTWFuYWdlciRtb2RpZmllciQxOzoxCIACEixMYW5kcm9pZHgvY29tcG9zZS91aS9kcmF3L0RyYXdCZWhpbmRFbGVtZW50Ozo0CIECEi9MYW5kcm9pZHgvY29tcG9zZS91aS9kcmF3L0RyYXdXaXRoQ2FjaGVFbGVtZW50Ozo2CIICEjFMYW5kcm9pZHgvY29tcG9zZS91aS9kcmF3L0RyYXdXaXRoQ29udGVudEVsZW1lbnQ7Oi4IgwISKUxhbmRyb2lkeC9jb21wb3NlL3VpL2RyYXcvUGFpbnRlckVsZW1lbnQ7OjoIhAISNUxhbmRyb2lkeC9jb21wb3NlL3VpL2RyYXcvU2hhZG93R3JhcGhpY3NMYXllckVsZW1lbnQ7OjQIhQISL0xhbmRyb2lkeC9jb21wb3NlL3VpL2ZvY3VzL0ZvY3VzQ2hhbmdlZEVsZW1lbnQ7OjoIhgISNUxhbmRyb2lkeC9jb21wb3NlL3VpL2ZvY3VzL0ZvY3VzT3duZXJJbXBsJG1vZGlmaWVyJDE7OjcIhwISMkxhbmRyb2lkeC9jb21wb3NlL3VpL2ZvY3VzL0ZvY3VzUHJvcGVydGllc0VsZW1lbnQ7OjYIiAISMUxhbmRyb2lkeC9jb21wb3NlL3VpL2ZvY3VzL0ZvY3VzUmVxdWVzdGVyRWxlbWVudDs6PQiJAhI4TGFuZHJvaWR4L2NvbXBvc2UvdWkvZ3JhcGhpY3MvQmxvY2tHcmFwaGljc0xheWVyRWxlbWVudDs6OAiKAhIzTGFuZHJvaWR4L2NvbXBvc2UvdWkvZ3JhcGhpY3MvR3JhcGhpY3NMYXllckVsZW1lbnQ7OjQIiwISL0xhbmRyb2lkeC9jb21wb3NlL3VpL2lucHV0L2tleS9LZXlJbnB1dEVsZW1lbnQ7OkgIjAISQ0xhbmRyb2lkeC9jb21wb3NlL3VpL2lucHV0L3BvaW50ZXIvUG9pbnRlckhvdmVySWNvbk1vZGlmaWVyRWxlbWVudDs6RwiNAhJCTGFuZHJvaWR4L2NvbXBvc2UvdWkvaW5wdXQvcG9pbnRlci9TdHlsdXNIb3Zlckljb25Nb2RpZmllckVsZW1lbnQ7OkMIjgISPkxhbmRyb2lkeC9jb21wb3NlL3VpL2lucHV0L3BvaW50ZXIvU3VzcGVuZFBvaW50ZXJJbnB1dEVsZW1lbnQ7Oi8IjwISKkxhbmRyb2lkeC9jb21wb3NlL3VpL2xheW91dC9MYXlvdXRFbGVtZW50OzoxCJACEixMYW5kcm9pZHgvY29tcG9zZS91aS9sYXlvdXQvTGF5b3V0SWRFbGVtZW50Ozo9CJECEjhMYW5kcm9pZHgvY29tcG9zZS91aS9sYXlvdXQvT25HbG9iYWxseVBvc2l0aW9uZWRFbGVtZW50Ozo3CJICEjJMYW5kcm9pZHgvY29tcG9zZS91aS9sYXlvdXQvT25TaXplQ2hhbmdlZE1vZGlmaWVyOzo/CJMCEjpMYW5kcm9pZHgvY29tcG9zZS91aS9wbGF0Zm9ybS9BbmRyb2lkQ29tcG9zZVZpZXckcm9vdCQxJDE7OjIIlAISLUxhbmRyb2lkeC9jb21wb3NlL3VpL3BsYXRmb3JtL1Rlc3RUYWdFbGVtZW50Ozo9CJUCEjhMYW5kcm9pZHgvY29tcG9zZS91aS9zZW1hbnRpY3MvQXBwZW5kZWRTZW1hbnRpY3NFbGVtZW50OzpACJYCEjtMYW5kcm9pZHgvY29tcG9zZS91aS9zZW1hbnRpY3MvQ2xlYXJBbmRTZXRTZW1hbnRpY3NFbGVtZW50OzpkCJcCEl9MY29tL2dvb2dsZS9zYW1wbGVzL2FwcHMvbm93aW5hbmRyb2lkL2NvcmUvZGVzaWduc3lzdGVtL2NvbXBvbmVudC9zY3JvbGxiYXIvU2Nyb2xsVGh1bWJFbGVtZW50OzpBCJgCEjxMY29tL2dvb2dsZS9zYW1wbGVzL2FwcHMvbm93aW5hbmRyb2lkL01haW5BY3Rpdml0eVZpZXdNb2RlbDs6VQiZAhJQTGNvbS9nb29nbGUvc2FtcGxlcy9hcHBzL25vd2luYW5kcm9pZC9mZWF0dXJlL2Jvb2ttYXJrcy9pbXBsL0Jvb2ttYXJrc1ZpZXdNb2RlbDs6TwiaAhJKTGNvbS9nb29nbGUvc2FtcGxlcy9hcHBzL25vd2luYW5kcm9pZC9mZWF0dXJlL2ZvcnlvdS9pbXBsL0ZvcllvdVZpZXdNb2RlbDs6VQibAhJQTGNvbS9nb29nbGUvc2FtcGxlcy9hcHBzL25vd2luYW5kcm9pZC9mZWF0dXJlL2ludGVyZXN0cy9pbXBsL0ludGVyZXN0c1ZpZXdNb2RlbDs6TwicAhJKTGNvbS9nb29nbGUvc2FtcGxlcy9hcHBzL25vd2luYW5kcm9pZC9mZWF0dXJlL3NlYXJjaC9pbXBsL1NlYXJjaFZpZXdNb2RlbDs6UwidAhJOTGNvbS9nb29nbGUvc2FtcGxlcy9hcHBzL25vd2luYW5kcm9pZC9mZWF0dXJlL3NldHRpbmdzL2ltcGwvU2V0dGluZ3NWaWV3TW9kZWw7Ok0IngISSExjb20vZ29vZ2xlL3NhbXBsZXMvYXBwcy9ub3dpbmFuZHJvaWQvZmVhdHVyZS90b3BpYy9pbXBsL1RvcGljVmlld01vZGVsOzolCJ8CEiBMa290bGluL2Nvcm91dGluZXMvQ29udGludWF0aW9uOzoZCKACEhRMcmV0cm9maXQyL1Jlc3BvbnNlOzpCCKECEj1MYW5kcm9pZHgvd2luZG93L2xheW91dC9hZGFwdGVyL2V4dGVuc2lvbnMvTXVsdGljYXN0Q29uc3VtZXI7OjkIogISNExhbmRyb2lkeC93aW5kb3cvZXh0ZW5zaW9ucy9sYXlvdXQvV2luZG93TGF5b3V0SW5mbzs6OAijAhIzTGNvbS9nb29nbGUvZmlyZWJhc2UvY29tcG9uZW50cy9Db21wb25lbnRSZWdpc3RyYXI7OiwIpAISJ0xhbmRyb2lkeC9ncmFwaGljcy9wYXRoL0NvbmljQ29udmVydGVyOzo2CKUCEjFMYW5kcm9pZHgvZ3JhcGhpY3MvcGF0aC9QYXRoSXRlcmF0b3JQcmVBcGkzNEltcGw7OjMIpgISLkxhbmRyb2lkeC90cmFjaW5nL3BlcmZldHRvL2puaS9QZXJmZXR0b05hdGl2ZTs6BwinAhICW0Y6BgioAhIBRjocCKkCEhdMYW5kcm9pZC9ncmFwaGljcy9QYXRoOzpQCKoCEktMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9tZWFzdXJlbWVudC9BcHBNZWFzdXJlbWVudCRDb25kaXRpb25hbFVzZXJQcm9wZXJ0eTs6LQirAhIoTGNvbS9nb29nbGUvZmlyZWJhc2UvcGVyZi9tZXRyaWNzL1RyYWNlOzokCKwCEh9MYW5kcm9pZC9vcy9QYXJjZWxhYmxlJENyZWF0b3I7OkMIrQISPkxjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL2NvbW1vbi9hcGkvaW50ZXJuYWwvTGlmZWN5Y2xlQ2FsbGJhY2s7OjgIrgISM0xjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL21lYXN1cmVtZW50L0FwcE1lYXN1cmVtZW50Ozo2CK8CEjFMY29tL2dvb2dsZS9maXJlYmFzZS9hbmFseXRpY3MvRmlyZWJhc2VBbmFseXRpY3M7OjUIsAISMExjb20vZ29vZ2xlL2ZpcmViYXNlL3BlcmYvbWV0cmljcy9BcHBTdGFydFRyYWNlOzo+CLECEjlMY29tL2dvb2dsZS9maXJlYmFzZS9wZXJmL25ldHdvcmsvRmlyZWJhc2VQZXJmSHR0cENsaWVudDs6QAiyAhI7TGNvbS9nb29nbGUvZmlyZWJhc2UvcGVyZi9uZXR3b3JrL0ZpcmViYXNlUGVyZk9rSHR0cENsaWVudDs6QQizAhI8TGNvbS9nb29nbGUvZmlyZWJhc2UvcGVyZi9uZXR3b3JrL0ZpcmViYXNlUGVyZlVybENvbm5lY3Rpb247OkYItAISQUxjb20vZ29vZ2xlL2ZpcmViYXNlL3JlbW90ZWNvbmZpZy9pbnRlcm5hbC9Db25maWdGZXRjaEh0dHBDbGllbnQ7OkMItQISPkxjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL2NvbW1vbi9hcGkvaW50ZXJuYWwvTGlmZWN5Y2xlQWN0aXZpdHk7OkMItgISPkxjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL2NvbW1vbi9hcGkvaW50ZXJuYWwvTGlmZWN5Y2xlRnJhZ21lbnQ7OjcItwISMkxjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL21lYXN1cmVtZW50L2ludGVybmFsL3p6bGI7OiYIuAISIUxjb20vZ29vZ2xlL2ZpcmViYXNlL0ZpcmViYXNlQXBwOzooCLkCEiNMb3JnL2FwYWNoZS9odHRwL2NsaWVudC9IdHRwQ2xpZW50OzofCLoCEhpMb3JnL2FwYWNoZS9odHRwL0h0dHBIb3N0OzoiCLsCEh1Mb3JnL2FwYWNoZS9odHRwL0h0dHBSZXF1ZXN0OzotCLwCEihMb3JnL2FwYWNoZS9odHRwL2NsaWVudC9SZXNwb25zZUhhbmRsZXI7OisIvQISJkxvcmcvYXBhY2hlL2h0dHAvcHJvdG9jb2wvSHR0cENvbnRleHQ7OjQIvgISL0xvcmcvYXBhY2hlL2h0dHAvY2xpZW50L21ldGhvZHMvSHR0cFVyaVJlcXVlc3Q7OiMIvwISHkxvcmcvYXBhY2hlL2h0dHAvSHR0cFJlc3BvbnNlOzoTCMACEg5Mb2todHRwMy9DYWxsOzoXCMECEhJMb2todHRwMy9DYWxsYmFjazs6FwjCAhISTG9raHR0cDMvUmVzcG9uc2U7OhMIwwISDkxqYXZhL25ldC9VUkw7OhcIxAISEltMamF2YS9sYW5nL0NsYXNzOzoaCMUCEhVMamF2YS9pby9JbnB1dFN0cmVhbTs6IQjGAhIcTGphdmEvbmV0L0h0dHBVUkxDb25uZWN0aW9uOzoVCMcCEhBMamF2YS9sYW5nL0xvbmc7OhUIyAISEExqYXZhL3V0aWwvRGF0ZTs6UQjJAhJMTGNvbS9nb29nbGUvZmlyZWJhc2UvcmVtb3RlY29uZmlnL2ludGVybmFsL0NvbmZpZ0ZldGNoSGFuZGxlciRGZXRjaFJlc3BvbnNlOzooCMoCEiNMYW5kcm9pZHgvbGlmZWN5Y2xlL1JlcG9ydEZyYWdtZW50OzpHCMsCEkJMYW5kcm9pZHgvYXBwY29tcGF0L3dpZGdldC9BcHBDb21wYXRUZXh0Vmlld0F1dG9TaXplSGVscGVyJEltcGwyMzs6KAjMAhIjTGFuZHJvaWQvdGV4dC9TdGF0aWNMYXlvdXQkQnVpbGRlcjs6HgjNAhIZTGFuZHJvaWQvd2lkZ2V0L1RleHRWaWV3OzpHCM4CEkJMYW5kcm9pZHgvYXBwY29tcGF0L3dpZGdldC9BcHBDb21wYXRUZXh0Vmlld0F1dG9TaXplSGVscGVyJEltcGwyOTs6RQjPAhJATGFuZHJvaWR4L2FwcGNvbXBhdC93aWRnZXQvQXBwQ29tcGF0VGV4dFZpZXdBdXRvU2l6ZUhlbHBlciRJbXBsOzpFCNACEkBMYW5kcm9pZHgvY29yZS9hcHAvTm90aWZpY2F0aW9uQ29tcGF0JEJpZ1BpY3R1cmVTdHlsZSRBcGkyM0ltcGw7Oi8I0QISKkxhbmRyb2lkL2FwcC9Ob3RpZmljYXRpb24kQmlnUGljdHVyZVN0eWxlOzolCNICEiBMYW5kcm9pZC9ncmFwaGljcy9kcmF3YWJsZS9JY29uOzpFCNMCEkBMYW5kcm9pZHgvY29yZS9hcHAvTm90aWZpY2F0aW9uQ29tcGF0JEJpZ1BpY3R1cmVTdHlsZSRBcGkzMUltcGw7Oh0I1AISGExqYXZhL2xhbmcvQ2hhclNlcXVlbmNlOzpECNUCEj9MYW5kcm9pZHgvY29yZS9hcHAvTm90aWZpY2F0aW9uQ29tcGF0JEJ1YmJsZU1ldGFkYXRhJEFwaTI5SW1wbDs6OgjWAhI1TGFuZHJvaWR4L2NvcmUvYXBwL05vdGlmaWNhdGlvbkNvbXBhdCRCdWJibGVNZXRhZGF0YTs6LgjXAhIpTGFuZHJvaWQvYXBwL05vdGlmaWNhdGlvbiRCdWJibGVNZXRhZGF0YTs6RAjYAhI/TGFuZHJvaWR4L2NvcmUvYXBwL05vdGlmaWNhdGlvbkNvbXBhdCRCdWJibGVNZXRhZGF0YSRBcGkzMEltcGw7Oj0I2QISOExhbmRyb2lkeC9jb3JlL2FwcC9Ob3RpZmljYXRpb25Db21wYXQkQnVpbGRlciRBcGkyMUltcGw7OiwI2gISJ0xhbmRyb2lkL21lZGlhL0F1ZGlvQXR0cmlidXRlcyRCdWlsZGVyOzokCNsCEh9MYW5kcm9pZC9tZWRpYS9BdWRpb0F0dHJpYnV0ZXM7Oi4I3AISKUxhbmRyb2lkeC9jb3JlL3ZpZXcvVmlld0NvbXBhdCRBcGkyMEltcGw7OiAI3QISG0xhbmRyb2lkL3ZpZXcvV2luZG93SW5zZXRzOzowCN4CEitMYW5kcm9pZHgvY29yZS92aWV3L1ZpZXdDb21wYXQkQXBpMjFJbXBsJDE7OjUI3wISMExhbmRyb2lkeC9jb3JlL3ZpZXcvT25BcHBseVdpbmRvd0luc2V0c0xpc3RlbmVyOzouCOACEilMYW5kcm9pZHgvY29yZS92aWV3L1ZpZXdDb21wYXQkQXBpMjFJbXBsOzosCOECEidMYW5kcm9pZHgvY29yZS92aWV3L1dpbmRvd0luc2V0c0NvbXBhdDs6HAjiAhIXTGFuZHJvaWQvZ3JhcGhpY3MvUmVjdDs6KQjjAhIkTGFuZHJvaWQvY29udGVudC9yZXMvQ29sb3JTdGF0ZUxpc3Q7OicI5AISIkxhbmRyb2lkL2dyYXBoaWNzL1BvcnRlckR1ZmYkTW9kZTs6LgjlAhIpTGFuZHJvaWR4L2NvcmUvdmlldy9WaWV3Q29tcGF0JEFwaTIzSW1wbDs6LgjmAhIpTGFuZHJvaWR4L2NvcmUvdmlldy9WaWV3Q29tcGF0JEFwaTI4SW1wbDs6LgjnAhIpTGFuZHJvaWR4L2NvcmUvdmlldy9WaWV3Q29tcGF0JEFwaTI5SW1wbDs6LgjoAhIpTGFuZHJvaWQvdmlldy9WaWV3JEFjY2Vzc2liaWxpdHlEZWxlZ2F0ZTs6BwjpAhICW0k6IAjqAhIbTGFuZHJvaWQvdXRpbC9BdHRyaWJ1dGVTZXQ7OiUI6wISIExhbmRyb2lkL2NvbnRlbnQvcmVzL1R5cGVkQXJyYXk7Oi4I7AISKUxhbmRyb2lkeC9jb3JlL3ZpZXcvVmlld0NvbXBhdCRBcGkzMEltcGw7Oi4I7QISKUxhbmRyb2lkeC9jb3JlL3ZpZXcvVmlld0NvbXBhdCRBcGkzMUltcGw7OhgI7gISE1tMamF2YS9sYW5nL1N0cmluZzs6KwjvAhImTGFuZHJvaWR4L2NvcmUvdmlldy9Db250ZW50SW5mb0NvbXBhdDs6OgjwAhI1TGFuZHJvaWR4L2NvcmUvdmlldy9XaW5kb3dJbnNldHNDb21wYXQkQnVpbGRlckltcGwyMDs6JAjxAhIfTGFuZHJvaWR4L2NvcmUvZ3JhcGhpY3MvSW5zZXRzOzo6CPICEjVMYW5kcm9pZHgvY29yZS92aWV3L1dpbmRvd0luc2V0c0NvbXBhdCRCdWlsZGVySW1wbDI5Ozo6CPMCEjVMYW5kcm9pZHgvY29yZS92aWV3L1dpbmRvd0luc2V0c0NvbXBhdCRCdWlsZGVySW1wbDMwOzo6CPQCEjVMYW5kcm9pZHgvY29yZS92aWV3L1dpbmRvd0luc2V0c0NvbXBhdCRCdWlsZGVySW1wbDM0Ozo4CPUCEjNMYW5kcm9pZHgvY29yZS92aWV3L1dpbmRvd0luc2V0c0NvbXBhdCRCdWlsZGVySW1wbDs6Mwj2AhIuTGFuZHJvaWR4L2NvcmUvdmlldy9XaW5kb3dJbnNldHNDb21wYXQkSW1wbDIwOzolCPcCEiBbTGFuZHJvaWR4L2NvcmUvZ3JhcGhpY3MvSW5zZXRzOzozCPgCEi5MYW5kcm9pZHgvY29yZS92aWV3L1dpbmRvd0luc2V0c0NvbXBhdCRJbXBsMjE7OjMI+QISLkxhbmRyb2lkeC9jb3JlL3ZpZXcvV2luZG93SW5zZXRzQ29tcGF0JEltcGwyODs6LQj6AhIoTGFuZHJvaWR4L2NvcmUvdmlldy9EaXNwbGF5Q3V0b3V0Q29tcGF0OzozCPsCEi5MYW5kcm9pZHgvY29yZS92aWV3L1dpbmRvd0luc2V0c0NvbXBhdCRJbXBsMjk7OjMI/AISLkxhbmRyb2lkeC9jb3JlL3ZpZXcvV2luZG93SW5zZXRzQ29tcGF0JEltcGwzMDs6Mwj9AhIuTGFuZHJvaWR4L2NvcmUvdmlldy9XaW5kb3dJbnNldHNDb21wYXQkSW1wbDM0OzoxCP4CEixMYW5kcm9pZHgvY29yZS92aWV3L1dpbmRvd0luc2V0c0NvbXBhdCRJbXBsOzo3CP8CEjJMYW5kcm9pZHgvY29yZS92aWV3L1dpbmRvd0luc2V0c0NvbXBhdCRUeXBlSW1wbDMwOzo3CIADEjJMYW5kcm9pZHgvY29yZS92aWV3L1dpbmRvd0luc2V0c0NvbXBhdCRUeXBlSW1wbDM0Ozo2CIEDEjFMYW5kcm9pZHgvY29yZS93aWRnZXQvRWRnZUVmZmVjdENvbXBhdCRBcGkyMUltcGw7OiAIggMSG0xhbmRyb2lkL3dpZGdldC9FZGdlRWZmZWN0Ozo2CIMDEjFMYW5kcm9pZHgvY29yZS93aWRnZXQvRWRnZUVmZmVjdENvbXBhdCRBcGkzMUltcGw7OioIhAMSJUxhbmRyb2lkeC9hY3Rpdml0eS9Db21wb25lbnRBY3Rpdml0eTs6LwiFAxIqTGFuZHJvaWR4L2FwcGNvbXBhdC9hcHAvQXBwQ29tcGF0QWN0aXZpdHk7OkQIhgMSP0xhbmRyb2lkeC9kYXRhc3RvcmUvcHJlZmVyZW5jZXMvUHJlZmVyZW5jZXNQcm90byRQcmVmZXJlbmNlTWFwOzo1CIcDEjBMYW5kcm9pZHgvZGF0YXN0b3JlL3ByZWZlcmVuY2VzL3Byb3RvYnVmL1BhcnNlcjs6OwiIAxI2TGFuZHJvaWR4L2RhdGFzdG9yZS9wcmVmZXJlbmNlcy9wcm90b2J1Zi9NYXBGaWVsZExpdGU7OkAIiQMSO0xhbmRyb2lkeC9kYXRhc3RvcmUvcHJlZmVyZW5jZXMvUHJlZmVyZW5jZXNQcm90byRTdHJpbmdTZXQ7OkQIigMSP0xhbmRyb2lkeC9kYXRhc3RvcmUvcHJlZmVyZW5jZXMvcHJvdG9idWYvSW50ZXJuYWwkUHJvdG9idWZMaXN0Ozo8CIsDEjdMYW5kcm9pZHgvZGF0YXN0b3JlL3ByZWZlcmVuY2VzL1ByZWZlcmVuY2VzUHJvdG8kVmFsdWU7OkIIjAMSPUxhbmRyb2lkeC9kYXRhc3RvcmUvcHJlZmVyZW5jZXMvcHJvdG9idWYvQWJzdHJhY3RNZXNzYWdlTGl0ZTs6QwiNAxI+TGFuZHJvaWR4L2RhdGFzdG9yZS9wcmVmZXJlbmNlcy9wcm90b2J1Zi9HZW5lcmF0ZWRNZXNzYWdlTGl0ZTs6QgiOAxI9TGFuZHJvaWR4L2RhdGFzdG9yZS9wcmVmZXJlbmNlcy9wcm90b2J1Zi9Vbmtub3duRmllbGRTZXRMaXRlOzpPCI8DEkpMYW5kcm9pZHgvbGlmZWN5Y2xlL1Byb2Nlc3NMaWZlY3ljbGVPd25lciRhdHRhY2gkMSRvbkFjdGl2aXR5UHJlQ3JlYXRlZCQxOzovCJADEipMYW5kcm9pZHgvbGlmZWN5Y2xlL1Byb2Nlc3NMaWZlY3ljbGVPd25lcjs6OAiRAxIzTGFuZHJvaWR4L2xpZmVjeWNsZS9Qcm9jZXNzTGlmZWN5Y2xlT3duZXIkYXR0YWNoJDE7OjkIkgMSNExhbmRyb2lkeC9saWZlY3ljbGUvRW1wdHlBY3Rpdml0eUxpZmVjeWNsZUNhbGxiYWNrczs6SAiTAxJDTGFuZHJvaWR4L2xpZmVjeWNsZS9MaWZlY3ljbGVEaXNwYXRjaGVyJERpc3BhdGNoZXJBY3Rpdml0eUNhbGxiYWNrOzorCJQDEiZMYW5kcm9pZHgvd29yay9PdmVyd3JpdGluZ0lucHV0TWVyZ2VyOzo7CJUDEjZMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9pbnRlcm5hbC9tZWFzdXJlbWVudC96emZvJHp6YTs6NwiWAxIyTGNvbS9nb29nbGUvYW5kcm9pZC9nbXMvaW50ZXJuYWwvbWVhc3VyZW1lbnQvenpsbDs6NwiXAxIyTGNvbS9nb29nbGUvYW5kcm9pZC9nbXMvaW50ZXJuYWwvbWVhc3VyZW1lbnQvenprYzs6OwiYAxI2TGNvbS9nb29nbGUvYW5kcm9pZC9nbXMvaW50ZXJuYWwvbWVhc3VyZW1lbnQvenpmbyR6emI7OjsImQMSNkxjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL2ludGVybmFsL21lYXN1cmVtZW50L3p6Zm8kenpkOzo7CJoDEjZMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9pbnRlcm5hbC9tZWFzdXJlbWVudC96emZvJHp6Yzs6OwibAxI2TGNvbS9nb29nbGUvYW5kcm9pZC9nbXMvaW50ZXJuYWwvbWVhc3VyZW1lbnQvenpmbyR6emY7OjsInAMSNkxjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL2ludGVybmFsL21lYXN1cmVtZW50L3p6Zm8kenplOzo/CJ0DEjpMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9pbnRlcm5hbC9tZWFzdXJlbWVudC96emZyJHp6YSR6emE7Oj8IngMSOkxjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL2ludGVybmFsL21lYXN1cmVtZW50L3p6ZnIkenphJHp6Yzs6PwifAxI6TGNvbS9nb29nbGUvYW5kcm9pZC9nbXMvaW50ZXJuYWwvbWVhc3VyZW1lbnQvenpmciR6emEkenpmOzo7CKADEjZMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9pbnRlcm5hbC9tZWFzdXJlbWVudC96emZyJHp6YTs6OwihAxI2TGNvbS9nb29nbGUvYW5kcm9pZC9nbXMvaW50ZXJuYWwvbWVhc3VyZW1lbnQvenpmciR6emI7OjsIogMSNkxjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL2ludGVybmFsL21lYXN1cmVtZW50L3p6ZnIkenpjOzo7CKMDEjZMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9pbnRlcm5hbC9tZWFzdXJlbWVudC96emZyJHp6ZDs6OwikAxI2TGNvbS9nb29nbGUvYW5kcm9pZC9nbXMvaW50ZXJuYWwvbWVhc3VyZW1lbnQvenpmciR6emY7OjsIpQMSNkxjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL2ludGVybmFsL21lYXN1cmVtZW50L3p6ZnIkenppOzo7CKYDEjZMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9pbnRlcm5hbC9tZWFzdXJlbWVudC96emZyJHp6Zzs6OwinAxI2TGNvbS9nb29nbGUvYW5kcm9pZC9nbXMvaW50ZXJuYWwvbWVhc3VyZW1lbnQvenpmciR6emU7OjsIqAMSNkxjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL2ludGVybmFsL21lYXN1cmVtZW50L3p6ZnIkenpoOzo7CKkDEjZMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9pbnRlcm5hbC9tZWFzdXJlbWVudC96emZ5JHp6YTs6OwiqAxI2TGNvbS9nb29nbGUvYW5kcm9pZC9nbXMvaW50ZXJuYWwvbWVhc3VyZW1lbnQvenpmeSR6emI7OjsIqwMSNkxjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL2ludGVybmFsL21lYXN1cmVtZW50L3p6ZnkkenpjOzo7CKwDEjZMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9pbnRlcm5hbC9tZWFzdXJlbWVudC96emZ5JHp6ZDs6OwitAxI2TGNvbS9nb29nbGUvYW5kcm9pZC9nbXMvaW50ZXJuYWwvbWVhc3VyZW1lbnQvenpmeSR6em07OjsIrgMSNkxjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL2ludGVybmFsL21lYXN1cmVtZW50L3p6ZnkkenplOzo7CK8DEjZMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9pbnRlcm5hbC9tZWFzdXJlbWVudC96emZ5JHp6Zjs6OwiwAxI2TGNvbS9nb29nbGUvYW5kcm9pZC9nbXMvaW50ZXJuYWwvbWVhc3VyZW1lbnQvenpmeSR6emc7OjsIsQMSNkxjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL2ludGVybmFsL21lYXN1cmVtZW50L3p6ZnkkenpoOzoGCLIDEgFEOjsIswMSNkxjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL2ludGVybmFsL21lYXN1cmVtZW50L3p6ZnkkenppOzo7CLQDEjZMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9pbnRlcm5hbC9tZWFzdXJlbWVudC96emZ5JHp6ajs6Owi1AxI2TGNvbS9nb29nbGUvYW5kcm9pZC9nbXMvaW50ZXJuYWwvbWVhc3VyZW1lbnQvenpmeSR6ems7OjsItgMSNkxjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL2ludGVybmFsL21lYXN1cmVtZW50L3p6ZnkkenpsOzo3CLcDEjJMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9pbnRlcm5hbC9tZWFzdXJlbWVudC96emthOzo3CLgDEjJMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9pbnRlcm5hbC9tZWFzdXJlbWVudC96emp6Ozo7CLkDEjZMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9pbnRlcm5hbC9tZWFzdXJlbWVudC96emZ5JHp6bjs6Owi6AxI2TGNvbS9nb29nbGUvYW5kcm9pZC9nbXMvaW50ZXJuYWwvbWVhc3VyZW1lbnQvenpmeSR6em87OjsIuwMSNkxjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL2ludGVybmFsL21lYXN1cmVtZW50L3p6Z2QkenphOzo7CLwDEjZMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9pbnRlcm5hbC9tZWFzdXJlbWVudC96emdkJHp6Yjs6Owi9AxI2TGNvbS9nb29nbGUvYW5kcm9pZC9nbXMvaW50ZXJuYWwvbWVhc3VyZW1lbnQvenpnZCR6emM7OjsIvgMSNkxjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL2ludGVybmFsL21lYXN1cmVtZW50L3p6Z2QkenpkOzo3CL8DEjJMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9pbnRlcm5hbC9tZWFzdXJlbWVudC96emliOzo3CMADEjJMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9pbnRlcm5hbC9tZWFzdXJlbWVudC96emp0Ozo3CMEDEjJMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9pbnRlcm5hbC9tZWFzdXJlbWVudC96em1qOzo5CMIDEjRMY29tL2dvb2dsZS9maXJlYmFzZS9wZXJmL3YxL0FuZHJvaWRBcHBsaWNhdGlvbkluZm87OiEIwwMSHExjb20vZ29vZ2xlL3Byb3RvYnVmL1BhcnNlcjs6NwjEAxIyTGNvbS9nb29nbGUvZmlyZWJhc2UvcGVyZi92MS9BbmRyb2lkTWVtb3J5UmVhZGluZzs6MgjFAxItTGNvbS9nb29nbGUvZmlyZWJhc2UvcGVyZi92MS9BcHBsaWNhdGlvbkluZm87OicIxgMSIkxjb20vZ29vZ2xlL3Byb3RvYnVmL01hcEZpZWxkTGl0ZTs6MwjHAxIuTGNvbS9nb29nbGUvZmlyZWJhc2UvcGVyZi92MS9DcHVNZXRyaWNSZWFkaW5nOzouCMgDEilMY29tL2dvb2dsZS9maXJlYmFzZS9wZXJmL3YxL0dhdWdlTWV0cmljOzowCMkDEitMY29tL2dvb2dsZS9wcm90b2J1Zi9JbnRlcm5hbCRQcm90b2J1Zkxpc3Q7OjcIygMSMkxjb20vZ29vZ2xlL2ZpcmViYXNlL3BlcmYvdjEvTmV0d29ya1JlcXVlc3RNZXRyaWM7Oi0IywMSKExjb20vZ29vZ2xlL2ZpcmViYXNlL3BlcmYvdjEvUGVyZk1ldHJpYzs6LgjMAxIpTGNvbS9nb29nbGUvZmlyZWJhc2UvcGVyZi92MS9UcmFjZU1ldHJpYzs6MAjNAxIrTGNvbS9nb29nbGUvZmlyZWJhc2UvcGVyZi92MS9UcmFuc3BvcnRJbmZvOzouCM4DEilMY29tL2dvb2dsZS9maXJlYmFzZS9wZXJmL3YxL1BlcmZTZXNzaW9uOzorCM8DEiZMY29tL2dvb2dsZS9wcm90b2J1Zi9JbnRlcm5hbCRJbnRMaXN0Ozo5CNADEjRMY29tL2dvb2dsZS9wcm90b2J1Zi9JbnRlcm5hbCRMaXN0QWRhcHRlciRDb252ZXJ0ZXI7Oi4I0QMSKUxjb20vZ29vZ2xlL3Byb3RvYnVmL0Fic3RyYWN0TWVzc2FnZUxpdGU7OjcI0gMSMkxjb20vZ29vZ2xlL3Byb3RvYnVmL0dlbmVyYXRlZE1lc3NhZ2VMaXRlJEJ1aWxkZXI7Oi8I0wMSKkxjb20vZ29vZ2xlL3Byb3RvYnVmL0dlbmVyYXRlZE1lc3NhZ2VMaXRlOzouCNQDEilMY29tL2dvb2dsZS9wcm90b2J1Zi9Vbmtub3duRmllbGRTZXRMaXRlOzpKCNUDEkVMY29tL2dvb2dsZS9zYW1wbGVzL2FwcHMvbm93aW5hbmRyb2lkL2NvcmUvZGF0YXN0b3JlL1VzZXJQcmVmZXJlbmNlczs6LgjWAxIpTGFuZHJvaWR4L2FjdGl2aXR5L3Jlc3VsdC9BY3Rpdml0eVJlc3VsdDs6MwjXAxIuTGFuZHJvaWR4L2FjdGl2aXR5L3Jlc3VsdC9JbnRlbnRTZW5kZXJSZXF1ZXN0Ozo8CNgDEjdMYW5kcm9pZHgvYXBwY29tcGF0L3dpZGdldC9BcHBDb21wYXRTcGlubmVyJFNhdmVkU3RhdGU7OjMI2QMSLkxhbmRyb2lkeC9hcHBjb21wYXQvd2lkZ2V0L1Rvb2xiYXIkU2F2ZWRTdGF0ZTs6PQjaAxI4TGFuZHJvaWR4L2NvbXBvc2UvZm91bmRhdGlvbi9sYXp5L2xheW91dC9EZWZhdWx0TGF6eUtleTs6QwjbAxI+TGFuZHJvaWR4L2NvbXBvc2UvcnVudGltZS9QYXJjZWxhYmxlU25hcHNob3RNdXRhYmxlRmxvYXRTdGF0ZTs6QQjcAxI8TGFuZHJvaWR4L2NvbXBvc2UvcnVudGltZS9QYXJjZWxhYmxlU25hcHNob3RNdXRhYmxlSW50U3RhdGU7OkII3QMSPUxhbmRyb2lkeC9jb21wb3NlL3J1bnRpbWUvUGFyY2VsYWJsZVNuYXBzaG90TXV0YWJsZUxvbmdTdGF0ZTs6PgjeAxI5TGFuZHJvaWR4L2NvbXBvc2UvcnVudGltZS9QYXJjZWxhYmxlU25hcHNob3RNdXRhYmxlU3RhdGU7OjsI3wMSNkxhbmRyb2lkeC9jb21wb3NlL3J1bnRpbWUvc25hcHNob3RzL1NuYXBzaG90U3RhdGVMaXN0Ozo3COADEjJMYW5kcm9pZHgvY29yZS93aWRnZXQvTmVzdGVkU2Nyb2xsVmlldyRTYXZlZFN0YXRlOzotCOEDEihMYW5kcm9pZHgvY3VzdG9tdmlldy92aWV3L0Fic1NhdmVkU3RhdGU7OjEI4gMSLExhbmRyb2lkeC9mcmFnbWVudC9hcHAvQmFja1N0YWNrUmVjb3JkU3RhdGU7OisI4wMSJkxhbmRyb2lkeC9mcmFnbWVudC9hcHAvQmFja1N0YWNrU3RhdGU7OkEI5AMSPExhbmRyb2lkeC9mcmFnbWVudC9hcHAvRnJhZ21lbnRNYW5hZ2VyJExhdW5jaGVkRnJhZ21lbnRJbmZvOzoxCOUDEixMYW5kcm9pZHgvZnJhZ21lbnQvYXBwL0ZyYWdtZW50TWFuYWdlclN0YXRlOzoqCOYDEiVMYW5kcm9pZHgvZnJhZ21lbnQvYXBwL0ZyYWdtZW50U3RhdGU7OiII5wMSHUxjb2lsL21lbW9yeS9NZW1vcnlDYWNoZSRLZXk7OkEI6AMSPExjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL2F1dGgvYXBpL3NpZ25pbi9Hb29nbGVTaWduSW5BY2NvdW50Ozo5COkDEjRMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9jbG91ZG1lc3NhZ2luZy9DbG91ZE1lc3NhZ2U7OjAI6gMSK0xjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL2Nsb3VkbWVzc2FnaW5nL3p6ZDs6NQjrAxIwTGNvbS9nb29nbGUvYW5kcm9pZC9nbXMvY29tbW9uL0Nvbm5lY3Rpb25SZXN1bHQ7OiwI7AMSJ0xjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL2NvbW1vbi9GZWF0dXJlOzouCO0DEilMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9jb21tb24vYXBpL1Njb3BlOzovCO4DEipMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9jb21tb24vYXBpL1N0YXR1czs6TgjvAxJJTGNvbS9nb29nbGUvYW5kcm9pZC9nbXMvY29tbW9uL2ludGVybmFsL0Nvbm5lY3Rpb25UZWxlbWV0cnlDb25maWd1cmF0aW9uOzo/CPADEjpMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9jb21tb24vaW50ZXJuYWwvR2V0U2VydmljZVJlcXVlc3Q7Oj4I8QMSOUxjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL2NvbW1vbi9pbnRlcm5hbC9NZXRob2RJbnZvY2F0aW9uOzpICPIDEkNMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9jb21tb24vaW50ZXJuYWwvUm9vdFRlbGVtZXRyeUNvbmZpZ3VyYXRpb247OjsI8wMSNkxjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL2NvbW1vbi9pbnRlcm5hbC9UZWxlbWV0cnlEYXRhOzoxCPQDEixMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9jb21tb24vaW50ZXJuYWwvemF0OzoxCPUDEixMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9jb21tb24vaW50ZXJuYWwvemF2OzoxCPYDEixMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9jb21tb24vaW50ZXJuYWwvenprOzooCPcDEiNMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9jb21tb24venpvOzooCPgDEiNMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9jb21tb24venpxOzooCPkDEiNMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9jb21tb24venpzOzo3CPoDEjJMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9pbnRlcm5hbC9vc3NfbGljZW5zZXMvenplOzo3CPsDEjJMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9tZWFzdXJlbWVudC9pbnRlcm5hbC96emFlOzo3CPwDEjJMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9tZWFzdXJlbWVudC9pbnRlcm5hbC96emFqOzo3CP0DEjJMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9tZWFzdXJlbWVudC9pbnRlcm5hbC96emJlOzo3CP4DEjJMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9tZWFzdXJlbWVudC9pbnRlcm5hbC96emJmOzo3CP8DEjJMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9tZWFzdXJlbWVudC9pbnRlcm5hbC96em5vOzo2CIAEEjFMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9tZWFzdXJlbWVudC9pbnRlcm5hbC96em87OjcIgQQSMkxjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL21lYXN1cmVtZW50L2ludGVybmFsL3p6b247OjEIggQSLExjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL3NpZ25pbi9pbnRlcm5hbC96YWE7OjEIgwQSLExjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL3NpZ25pbi9pbnRlcm5hbC96YWc7OjEIhAQSLExjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL3NpZ25pbi9pbnRlcm5hbC96YWk7OjEIhQQSLExjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL3NpZ25pbi9pbnRlcm5hbC96YWs7OjIIhgQSLUxjb20vZ29vZ2xlL2ZpcmViYXNlL21lc3NhZ2luZy9SZW1vdGVNZXNzYWdlOzovCIcEEipMY29tL2dvb2dsZS9maXJlYmFzZS9wZXJmL21ldHJpY3MvQ291bnRlcjs6QQiIBBI8TGFuZHJvaWR4L2NvbXBvc2UvdWkvZ3JhcGhpY3MvbGF5ZXIvdmlldy9WaWV3TGF5ZXJDb250YWluZXI7OjYIiQQSMUxhbmRyb2lkeC9jb21wb3NlL3VpL3BsYXRmb3JtL0FuZHJvaWRDb21wb3NlVmlldzs6OwiKBBI2TGFuZHJvaWR4L2xpZmVjeWNsZS9SZXBvcnRGcmFnbWVudCRMaWZlY3ljbGVDYWxsYmFja3M7OkUIiwQSQExhbmRyb2lkeC9saWZlY3ljbGUvUmVwb3J0RnJhZ21lbnQkTGlmZWN5Y2xlQ2FsbGJhY2tzJENvbXBhbmlvbjs6KQiMBBIkTGFuZHJvaWR4L3RyYW5zaXRpb24vQ2hhbmdlQm91bmRzJDY7OjIIjQQSLUxhbmRyb2lkeC90cmFuc2l0aW9uL0NoYW5nZUJvdW5kcyRWaWV3Qm91bmRzOzpPCI4EEkpMYW5kcm9pZHgvdmVjdG9yZHJhd2FibGUvZ3JhcGhpY3MvZHJhd2FibGUvVmVjdG9yRHJhd2FibGVDb21wYXQkVkZ1bGxQYXRoOzpMCI8EEkdMYW5kcm9pZHgvdmVjdG9yZHJhd2FibGUvZ3JhcGhpY3MvZHJhd2FibGUvVmVjdG9yRHJhd2FibGVDb21wYXQkVkdyb3VwOzoeCJAEEhlMYW5kcm9pZC9ncmFwaGljcy9NYXRyaXg7OksIkQQSRkxhbmRyb2lkeC92ZWN0b3JkcmF3YWJsZS9ncmFwaGljcy9kcmF3YWJsZS9WZWN0b3JEcmF3YWJsZUNvbXBhdCRWUGF0aDs6NgiSBBIxW0xhbmRyb2lkeC9jb3JlL2dyYXBoaWNzL1BhdGhQYXJzZXIkUGF0aERhdGFOb2RlOzpTCJMEEk5MYW5kcm9pZHgvdmVjdG9yZHJhd2FibGUvZ3JhcGhpY3MvZHJhd2FibGUvVmVjdG9yRHJhd2FibGVDb21wYXQkVlBhdGhSZW5kZXJlcjs6XwiUBBJaTGFuZHJvaWR4L3ZlY3RvcmRyYXdhYmxlL2dyYXBoaWNzL2RyYXdhYmxlL1ZlY3RvckRyYXdhYmxlQ29tcGF0JFZlY3RvckRyYXdhYmxlQ29tcGF0U3RhdGU7OmEIlQQSXExhbmRyb2lkeC92ZWN0b3JkcmF3YWJsZS9ncmFwaGljcy9kcmF3YWJsZS9WZWN0b3JEcmF3YWJsZUNvbXBhdCRWZWN0b3JEcmF3YWJsZURlbGVnYXRlU3RhdGU7OikIlgQSJExrb3RsaW4vY29yb3V0aW5lcy9TYWZlQ29udGludWF0aW9uOzovCJcEEipMa290bGlueC9jb3JvdXRpbmVzL0F3YWl0QWxsJEF3YWl0QWxsTm9kZTs6IgiYBBIdTGtvdGxpbngvY29yb3V0aW5lcy9Bd2FpdEFsbDs6NQiZBBIwTGtvdGxpbngvY29yb3V0aW5lcy9DYW5jZWxsYWJsZUNvbnRpbnVhdGlvbkltcGw7Oi8ImgQSKkxrb3RsaW54L2Nvcm91dGluZXMvQ2FuY2VsbGVkQ29udGludWF0aW9uOzowCJsEEitMa290bGlueC9jb3JvdXRpbmVzL0NvbXBsZXRlZEV4Y2VwdGlvbmFsbHk7OikInAQSJExrb3RsaW54L2Nvcm91dGluZXMvRGVmYXVsdEV4ZWN1dG9yOzoXCJ0EEhJMamF2YS9sYW5nL1RocmVhZDs6LQieBBIoTGtvdGxpbngvY29yb3V0aW5lcy9EaXNwYXRjaGVkQ29yb3V0aW5lOzo3CJ8EEjJMa290bGlueC9jb3JvdXRpbmVzL0V2ZW50TG9vcEltcGxCYXNlJERlbGF5ZWRUYXNrOzorCKAEEiZMa290bGlueC9jb3JvdXRpbmVzL0V2ZW50TG9vcEltcGxCYXNlOzosCKEEEidMa290bGlueC9jb3JvdXRpbmVzL0ludm9rZU9uQ2FuY2VsbGluZzs6LgiiBBIpTGtvdGxpbngvY29yb3V0aW5lcy9Kb2JTdXBwb3J0JEZpbmlzaGluZzs6JAijBBIfTGtvdGxpbngvY29yb3V0aW5lcy9Kb2JTdXBwb3J0OzolCKQEEiBMa290bGlueC9jb3JvdXRpbmVzL1RocmVhZFN0YXRlOzovCKUEEipMa290bGlueC9jb3JvdXRpbmVzL1VuZGlzcGF0Y2hlZENvcm91dGluZTs6PAimBBI3TGtvdGxpbngvY29yb3V0aW5lcy9hbmRyb2lkL0FuZHJvaWRFeGNlcHRpb25QcmVIYW5kbGVyOzo1CKcEEjBMa290bGlueC9jb3JvdXRpbmVzL2FuZHJvaWQvSGFuZGxlckRpc3BhdGNoZXJLdDs6IQioBBIcTGFuZHJvaWQvdmlldy9DaG9yZW9ncmFwaGVyOzoyCKkEEi1Ma290bGlueC9jb3JvdXRpbmVzL2NoYW5uZWxzL0J1ZmZlcmVkQ2hhbm5lbDs6LAiqBBInTGtvdGxpbngvY29yb3V0aW5lcy9mbG93L1N0YXRlRmxvd0ltcGw7OjsIqwQSNkxrb3RsaW54L2Nvcm91dGluZXMvaW50ZXJuYWwvQ29uY3VycmVudExpbmtlZExpc3ROb2RlOzo5CKwEEjRMa290bGlueC9jb3JvdXRpbmVzL2ludGVybmFsL0Rpc3BhdGNoZWRDb250aW51YXRpb247OjQIrQQSL0xrb3RsaW54L2Nvcm91dGluZXMvaW50ZXJuYWwvTGltaXRlZERpc3BhdGNoZXI7OjkIrgQSNExrb3RsaW54L2Nvcm91dGluZXMvaW50ZXJuYWwvTG9ja0ZyZWVMaW5rZWRMaXN0Tm9kZTs6NAivBBIvTGtvdGxpbngvY29yb3V0aW5lcy9pbnRlcm5hbC9Mb2NrRnJlZVRhc2tRdWV1ZTs6OAiwBBIzTGtvdGxpbngvY29yb3V0aW5lcy9pbnRlcm5hbC9Mb2NrRnJlZVRhc2tRdWV1ZUNvcmU7OjcIsQQSMkxrb3RsaW54L2Nvcm91dGluZXMvaW50ZXJuYWwvUmVzaXphYmxlQXRvbWljQXJyYXk7OjcIsgQSMkxqYXZhL3V0aWwvY29uY3VycmVudC9hdG9taWMvQXRvbWljUmVmZXJlbmNlQXJyYXk7OioIswQSJUxrb3RsaW54L2Nvcm91dGluZXMvaW50ZXJuYWwvU2VnbWVudDs6MQi0BBIsTGtvdGxpbngvY29yb3V0aW5lcy9pbnRlcm5hbC9UaHJlYWRTYWZlSGVhcDs6Pgi1BBI5TGtvdGxpbngvY29yb3V0aW5lcy9zY2hlZHVsaW5nL0Nvcm91dGluZVNjaGVkdWxlciRXb3JrZXI7OjcItgQSMkxrb3RsaW54L2Nvcm91dGluZXMvc2NoZWR1bGluZy9Db3JvdXRpbmVTY2hlZHVsZXI7Oi4ItwQSKUxrb3RsaW54L2Nvcm91dGluZXMvc2NoZWR1bGluZy9Xb3JrUXVldWU7OigIuAQSI0xrb3RsaW54L2Nvcm91dGluZXMvc3luYy9NdXRleEltcGw7OjQIuQQSL0xrb3RsaW54L2Nvcm91dGluZXMvc3luYy9TZW1hcGhvcmVBbmRNdXRleEltcGw7OjAIugQSK0xhbmRyb2lkeC9jb21wb3NlL2FuaW1hdGlvbi9FbnRlckV4aXRTdGF0ZTs6MQi7BBIsW0xhbmRyb2lkeC9jb21wb3NlL2FuaW1hdGlvbi9FbnRlckV4aXRTdGF0ZTs6OQi8BBI0TGFuZHJvaWR4L2NvbXBvc2UvYW5pbWF0aW9uL2NvcmUvQW5pbWF0aW9uRW5kUmVhc29uOzo6CL0EEjVbTGFuZHJvaWR4L2NvbXBvc2UvYW5pbWF0aW9uL2NvcmUvQW5pbWF0aW9uRW5kUmVhc29uOzo1CL4EEjBMYW5kcm9pZHgvY29tcG9zZS9hbmltYXRpb24vY29yZS9NdXRhdGVQcmlvcml0eTs6Ngi/BBIxW0xhbmRyb2lkeC9jb21wb3NlL2FuaW1hdGlvbi9jb3JlL011dGF0ZVByaW9yaXR5OzoxCMAEEixMYW5kcm9pZHgvY29tcG9zZS9hbmltYXRpb24vY29yZS9SZXBlYXRNb2RlOzoyCMEEEi1bTGFuZHJvaWR4L2NvbXBvc2UvYW5pbWF0aW9uL2NvcmUvUmVwZWF0TW9kZTs6MQjCBBIsTGFuZHJvaWR4L2NvbXBvc2UvZm91bmRhdGlvbi9NdXRhdGVQcmlvcml0eTs6MgjDBBItW0xhbmRyb2lkeC9jb21wb3NlL2ZvdW5kYXRpb24vTXV0YXRlUHJpb3JpdHk7OlcIxAQSUkxhbmRyb2lkeC9jb21wb3NlL2ZvdW5kYXRpb24vZ2VzdHVyZXMvRHJhZ0RldGVjdGlvblN0YXRlJEF3YWl0RG93biRBd2FpdFRvdWNoU2xvcDs6WAjFBBJTW0xhbmRyb2lkeC9jb21wb3NlL2ZvdW5kYXRpb24vZ2VzdHVyZXMvRHJhZ0RldGVjdGlvblN0YXRlJEF3YWl0RG93biRBd2FpdFRvdWNoU2xvcDs6fQjGBBJ4TGFuZHJvaWR4L2NvbXBvc2UvZm91bmRhdGlvbi9nZXN0dXJlcy9JbmRpcmVjdFBvaW50ZXJJbnB1dERyYWdDeWNsZURldGVjdG9yJERyYWdEZXRlY3Rpb25TdGF0ZSRBd2FpdERvd24kQXdhaXRUb3VjaFNsb3A7On4IxwQSeVtMYW5kcm9pZHgvY29tcG9zZS9mb3VuZGF0aW9uL2dlc3R1cmVzL0luZGlyZWN0UG9pbnRlcklucHV0RHJhZ0N5Y2xlRGV0ZWN0b3IkRHJhZ0RldGVjdGlvblN0YXRlJEF3YWl0RG93biRBd2FpdFRvdWNoU2xvcDs6NwjIBBIyTGFuZHJvaWR4L2NvbXBvc2UvZm91bmRhdGlvbi9nZXN0dXJlcy9PcmllbnRhdGlvbjs6OAjJBBIzW0xhbmRyb2lkeC9jb21wb3NlL2ZvdW5kYXRpb24vZ2VzdHVyZXMvT3JpZW50YXRpb247OjMIygQSLkxhbmRyb2lkeC9jb21wb3NlL2ZvdW5kYXRpb24vbGF5b3V0L0RpcmVjdGlvbjs6NAjLBBIvW0xhbmRyb2lkeC9jb21wb3NlL2ZvdW5kYXRpb24vbGF5b3V0L0RpcmVjdGlvbjs6SQjMBBJETGFuZHJvaWR4L2NvbXBvc2UvZm91bmRhdGlvbi9sYXlvdXQvRmxvd0xheW91dE92ZXJmbG93JE92ZXJmbG93VHlwZTs6SgjNBBJFW0xhbmRyb2lkeC9jb21wb3NlL2ZvdW5kYXRpb24vbGF5b3V0L0Zsb3dMYXlvdXRPdmVyZmxvdyRPdmVyZmxvd1R5cGU7OjcIzgQSMkxhbmRyb2lkeC9jb21wb3NlL2ZvdW5kYXRpb24vbGF5b3V0L0ludHJpbnNpY1NpemU7OjgIzwQSM1tMYW5kcm9pZHgvY29tcG9zZS9mb3VuZGF0aW9uL2xheW91dC9JbnRyaW5zaWNTaXplOzo7CNAEEjZMYW5kcm9pZHgvY29tcG9zZS9mb3VuZGF0aW9uL2xheW91dC9MYXlvdXRPcmllbnRhdGlvbjs6PAjRBBI3W0xhbmRyb2lkeC9jb21wb3NlL2ZvdW5kYXRpb24vbGF5b3V0L0xheW91dE9yaWVudGF0aW9uOzouCNIEEilMYW5kcm9pZHgvY29tcG9zZS9mb3VuZGF0aW9uL3RleHQvSGFuZGxlOzovCNMEEipbTGFuZHJvaWR4L2NvbXBvc2UvZm91bmRhdGlvbi90ZXh0L0hhbmRsZTs6MwjUBBIuTGFuZHJvaWR4L2NvbXBvc2UvZm91bmRhdGlvbi90ZXh0L0hhbmRsZVN0YXRlOzo0CNUEEi9bTGFuZHJvaWR4L2NvbXBvc2UvZm91bmRhdGlvbi90ZXh0L0hhbmRsZVN0YXRlOzoyCNYEEi1MYW5kcm9pZHgvY29tcG9zZS9mb3VuZGF0aW9uL3RleHQvS2V5Q29tbWFuZDs6MwjXBBIuW0xhbmRyb2lkeC9jb21wb3NlL2ZvdW5kYXRpb24vdGV4dC9LZXlDb21tYW5kOzo8CNgEEjdMYW5kcm9pZHgvY29tcG9zZS9mb3VuZGF0aW9uL3RleHQvVGV4dENvbnRleHRNZW51SXRlbXM7Oj0I2QQSOFtMYW5kcm9pZHgvY29tcG9zZS9mb3VuZGF0aW9uL3RleHQvVGV4dENvbnRleHRNZW51SXRlbXM7OlAI2gQSS0xhbmRyb2lkeC9jb21wb3NlL2ZvdW5kYXRpb24vdGV4dC9jb250ZXh0bWVudS9tb2RpZmllci9Ub29sYmFySGFuZGxlclN0YXRlOzpRCNsEEkxbTGFuZHJvaWR4L2NvbXBvc2UvZm91bmRhdGlvbi90ZXh0L2NvbnRleHRtZW51L21vZGlmaWVyL1Rvb2xiYXJIYW5kbGVyU3RhdGU7Oj0I3AQSOExhbmRyb2lkeC9jb21wb3NlL2ZvdW5kYXRpb24vdGV4dC9zZWxlY3Rpb24vQ3Jvc3NTdGF0dXM7Oj4I3QQSOVtMYW5kcm9pZHgvY29tcG9zZS9mb3VuZGF0aW9uL3RleHQvc2VsZWN0aW9uL0Nyb3NzU3RhdHVzOzpACN4EEjtMYW5kcm9pZHgvY29tcG9zZS9mb3VuZGF0aW9uL3RleHQvc2VsZWN0aW9uL0Rvd25SZXNvbHV0aW9uOzpBCN8EEjxbTGFuZHJvaWR4L2NvbXBvc2UvZm91bmRhdGlvbi90ZXh0L3NlbGVjdGlvbi9Eb3duUmVzb2x1dGlvbjs6QgjgBBI9TGFuZHJvaWR4L2NvbXBvc2UvZm91bmRhdGlvbi90ZXh0L3NlbGVjdGlvbi9TZWxlY3RlZFRleHRUeXBlOzpDCOEEEj5bTGFuZHJvaWR4L2NvbXBvc2UvZm91bmRhdGlvbi90ZXh0L3NlbGVjdGlvbi9TZWxlY3RlZFRleHRUeXBlOzpHCOIEEkJMYW5kcm9pZHgvY29tcG9zZS9mb3VuZGF0aW9uL3RleHQvc2VsZWN0aW9uL1NlbGVjdGlvbkhhbmRsZUFuY2hvcjs6SAjjBBJDW0xhbmRyb2lkeC9jb21wb3NlL2ZvdW5kYXRpb24vdGV4dC9zZWxlY3Rpb24vU2VsZWN0aW9uSGFuZGxlQW5jaG9yOzo3COQEEjJMYW5kcm9pZHgvY29tcG9zZS9tYXRlcmlhbDMvU2NhZmZvbGRMYXlvdXRDb250ZW50Ozo4COUEEjNbTGFuZHJvaWR4L2NvbXBvc2UvbWF0ZXJpYWwzL1NjYWZmb2xkTGF5b3V0Q29udGVudDs6MgjmBBItTGFuZHJvaWR4L2NvbXBvc2UvbWF0ZXJpYWwzL1NuYWNrYmFyRHVyYXRpb247OjMI5wQSLltMYW5kcm9pZHgvY29tcG9zZS9tYXRlcmlhbDMvU25hY2tiYXJEdXJhdGlvbjs6MAjoBBIrTGFuZHJvaWR4L2NvbXBvc2UvbWF0ZXJpYWwzL1NuYWNrYmFyUmVzdWx0OzoxCOkEEixbTGFuZHJvaWR4L2NvbXBvc2UvbWF0ZXJpYWwzL1NuYWNrYmFyUmVzdWx0Ozo5COoEEjRMYW5kcm9pZHgvY29tcG9zZS9tYXRlcmlhbDMvV2lkZU5hdmlnYXRpb25SYWlsVmFsdWU7OjoI6wQSNVtMYW5kcm9pZHgvY29tcG9zZS9tYXRlcmlhbDMvV2lkZU5hdmlnYXRpb25SYWlsVmFsdWU7OjwI7AQSN0xhbmRyb2lkeC9jb21wb3NlL21hdGVyaWFsMy9hZGFwdGl2ZS9sYXlvdXQvRG9ja2VkRWRnZTs6PQjtBBI4W0xhbmRyb2lkeC9jb21wb3NlL21hdGVyaWFsMy9hZGFwdGl2ZS9sYXlvdXQvRG9ja2VkRWRnZTs6SQjuBBJETGFuZHJvaWR4L2NvbXBvc2UvbWF0ZXJpYWwzL2FkYXB0aXZlL2xheW91dC9EcmFnVG9SZXNpemVTdGF0ZSRTdGF0ZTs6SgjvBBJFW0xhbmRyb2lkeC9jb21wb3NlL21hdGVyaWFsMy9hZGFwdGl2ZS9sYXlvdXQvRHJhZ1RvUmVzaXplU3RhdGUkU3RhdGU7OkcI8AQSQkxhbmRyb2lkeC9jb21wb3NlL21hdGVyaWFsMy9hZGFwdGl2ZS9sYXlvdXQvVGhyZWVQYW5lU2NhZmZvbGRSb2xlOzpICPEEEkNbTGFuZHJvaWR4L2NvbXBvc2UvbWF0ZXJpYWwzL2FkYXB0aXZlL2xheW91dC9UaHJlZVBhbmVTY2FmZm9sZFJvbGU7OlcI8gQSUkxhbmRyb2lkeC9jb21wb3NlL21hdGVyaWFsMy9hZGFwdGl2ZS9uYXZpZ2F0aW9uc3VpdGUvTmF2aWdhdGlvblN1aXRlU2NhZmZvbGRWYWx1ZTs6WAjzBBJTW0xhbmRyb2lkeC9jb21wb3NlL21hdGVyaWFsMy9hZGFwdGl2ZS9uYXZpZ2F0aW9uc3VpdGUvTmF2aWdhdGlvblN1aXRlU2NhZmZvbGRWYWx1ZTs6NQj0BBIwTGFuZHJvaWR4L2NvbXBvc2UvbWF0ZXJpYWwzL2ludGVybmFsL0lucHV0UGhhc2U7OjYI9QQSMVtMYW5kcm9pZHgvY29tcG9zZS9tYXRlcmlhbDMvaW50ZXJuYWwvSW5wdXRQaGFzZTs6OAj2BBIzTGFuZHJvaWR4L2NvbXBvc2UvbWF0ZXJpYWwzL2ludGVybmFsL1RleHRGaWVsZFR5cGU7OjkI9wQSNFtMYW5kcm9pZHgvY29tcG9zZS9tYXRlcmlhbDMvaW50ZXJuYWwvVGV4dEZpZWxkVHlwZTs6PQj4BBI4TGFuZHJvaWR4L2NvbXBvc2UvbWF0ZXJpYWwzL3Rva2Vucy9Db2xvclNjaGVtZUtleVRva2Vuczs6Pgj5BBI5W0xhbmRyb2lkeC9jb21wb3NlL21hdGVyaWFsMy90b2tlbnMvQ29sb3JTY2hlbWVLZXlUb2tlbnM7Oj4I+gQSOUxhbmRyb2lkeC9jb21wb3NlL21hdGVyaWFsMy90b2tlbnMvTW90aW9uU2NoZW1lS2V5VG9rZW5zOzo/CPsEEjpbTGFuZHJvaWR4L2NvbXBvc2UvbWF0ZXJpYWwzL3Rva2Vucy9Nb3Rpb25TY2hlbWVLZXlUb2tlbnM7OjcI/AQSMkxhbmRyb2lkeC9jb21wb3NlL21hdGVyaWFsMy90b2tlbnMvU2hhcGVLZXlUb2tlbnM7OjgI/QQSM1tMYW5kcm9pZHgvY29tcG9zZS9tYXRlcmlhbDMvdG9rZW5zL1NoYXBlS2V5VG9rZW5zOzo8CP4EEjdMYW5kcm9pZHgvY29tcG9zZS9tYXRlcmlhbDMvdG9rZW5zL1R5cG9ncmFwaHlLZXlUb2tlbnM7Oj0I/wQSOFtMYW5kcm9pZHgvY29tcG9zZS9tYXRlcmlhbDMvdG9rZW5zL1R5cG9ncmFwaHlLZXlUb2tlbnM7OjIIgAUSLUxhbmRyb2lkeC9jb21wb3NlL3J1bnRpbWUvSW52YWxpZGF0aW9uUmVzdWx0OzozCIEFEi5bTGFuZHJvaWR4L2NvbXBvc2UvcnVudGltZS9JbnZhbGlkYXRpb25SZXN1bHQ7OjYIggUSMUxhbmRyb2lkeC9jb21wb3NlL3J1bnRpbWUvUGF1c2VkQ29tcG9zaXRpb25TdGF0ZTs6NwiDBRIyW0xhbmRyb2lkeC9jb21wb3NlL3J1bnRpbWUvUGF1c2VkQ29tcG9zaXRpb25TdGF0ZTs6MAiEBRIrTGFuZHJvaWR4L2NvbXBvc2UvcnVudGltZS9SZWNvbXBvc2VyJFN0YXRlOzoxCIUFEixbTGFuZHJvaWR4L2NvbXBvc2UvcnVudGltZS9SZWNvbXBvc2VyJFN0YXRlOzowCIYFEitMYW5kcm9pZHgvY29tcG9zZS91aS9hdXRvZmlsbC9BdXRvZmlsbFR5cGU7OjEIhwUSLFtMYW5kcm9pZHgvY29tcG9zZS91aS9hdXRvZmlsbC9BdXRvZmlsbFR5cGU7OlYIiAUSUUxhbmRyb2lkeC9jb21wb3NlL3VpL2NvbnRlbnRjYXB0dXJlL0FuZHJvaWRDb250ZW50Q2FwdHVyZU1hbmFnZXIkVHJhbnNsYXRlU3RhdHVzOzpXCIkFElJbTGFuZHJvaWR4L2NvbXBvc2UvdWkvY29udGVudGNhcHR1cmUvQW5kcm9pZENvbnRlbnRDYXB0dXJlTWFuYWdlciRUcmFuc2xhdGVTdGF0dXM7OkEIigUSPExhbmRyb2lkeC9jb21wb3NlL3VpL2NvbnRlbnRjYXB0dXJlL0NvbnRlbnRDYXB0dXJlRXZlbnRUeXBlOzpCCIsFEj1bTGFuZHJvaWR4L2NvbXBvc2UvdWkvY29udGVudGNhcHR1cmUvQ29udGVudENhcHR1cmVFdmVudFR5cGU7OjgIjAUSM0xhbmRyb2lkeC9jb21wb3NlL3VpL2ZvY3VzL0N1c3RvbURlc3RpbmF0aW9uUmVzdWx0Ozo5CI0FEjRbTGFuZHJvaWR4L2NvbXBvc2UvdWkvZm9jdXMvQ3VzdG9tRGVzdGluYXRpb25SZXN1bHQ7Oi8IjgUSKkxhbmRyb2lkeC9jb21wb3NlL3VpL2ZvY3VzL0ZvY3VzU3RhdGVJbXBsOzowCI8FEitbTGFuZHJvaWR4L2NvbXBvc2UvdWkvZm9jdXMvRm9jdXNTdGF0ZUltcGw7OjIIkAUSLUxhbmRyb2lkeC9jb21wb3NlL3VpL2dyYXBoaWNzL1BhdGgkRGlyZWN0aW9uOzozCJEFEi5bTGFuZHJvaWR4L2NvbXBvc2UvdWkvZ3JhcGhpY3MvUGF0aCREaXJlY3Rpb247OjkIkgUSNExhbmRyb2lkeC9jb21wb3NlL3VpL2lucHV0L3BvaW50ZXIvUG9pbnRlckV2ZW50UGFzczs6OgiTBRI1W0xhbmRyb2lkeC9jb21wb3NlL3VpL2lucHV0L3BvaW50ZXIvUG9pbnRlckV2ZW50UGFzczs6SAiUBRJDTGFuZHJvaWR4L2NvbXBvc2UvdWkvaW5wdXQvcG9pbnRlci91dGlsL1ZlbG9jaXR5VHJhY2tlcjFEJFN0cmF0ZWd5OzpJCJUFEkRbTGFuZHJvaWR4L2NvbXBvc2UvdWkvaW5wdXQvcG9pbnRlci91dGlsL1ZlbG9jaXR5VHJhY2tlcjFEJFN0cmF0ZWd5OzoxCJYFEixMYW5kcm9pZHgvY29tcG9zZS91aS9sYXlvdXQvSW50cmluc2ljTWluTWF4OzoyCJcFEi1bTGFuZHJvaWR4L2NvbXBvc2UvdWkvbGF5b3V0L0ludHJpbnNpY01pbk1heDs6NgiYBRIxTGFuZHJvaWR4L2NvbXBvc2UvdWkvbGF5b3V0L0ludHJpbnNpY1dpZHRoSGVpZ2h0Ozo3CJkFEjJbTGFuZHJvaWR4L2NvbXBvc2UvdWkvbGF5b3V0L0ludHJpbnNpY1dpZHRoSGVpZ2h0OzpFCJoFEkBMYW5kcm9pZHgvY29tcG9zZS91aS9sYXlvdXQvTWVhc3VyaW5nSW50cmluc2ljcyRJbnRyaW5zaWNNaW5NYXg7OkYImwUSQVtMYW5kcm9pZHgvY29tcG9zZS91aS9sYXlvdXQvTWVhc3VyaW5nSW50cmluc2ljcyRJbnRyaW5zaWNNaW5NYXg7OkoInAUSRUxhbmRyb2lkeC9jb21wb3NlL3VpL2xheW91dC9NZWFzdXJpbmdJbnRyaW5zaWNzJEludHJpbnNpY1dpZHRoSGVpZ2h0OzpLCJ0FEkZbTGFuZHJvaWR4L2NvbXBvc2UvdWkvbGF5b3V0L01lYXN1cmluZ0ludHJpbnNpY3MkSW50cmluc2ljV2lkdGhIZWlnaHQ7OiwIngUSJ0xhbmRyb2lkeC9jb21wb3NlL3VpL25vZGUvSW52YWxpZGF0aW9uOzotCJ8FEihbTGFuZHJvaWR4L2NvbXBvc2UvdWkvbm9kZS9JbnZhbGlkYXRpb247OjYIoAUSMUxhbmRyb2lkeC9jb21wb3NlL3VpL25vZGUvTGF5b3V0Tm9kZSRMYXlvdXRTdGF0ZTs6NwihBRIyW0xhbmRyb2lkeC9jb21wb3NlL3VpL25vZGUvTGF5b3V0Tm9kZSRMYXlvdXRTdGF0ZTs6OAiiBRIzTGFuZHJvaWR4L2NvbXBvc2UvdWkvbm9kZS9MYXlvdXROb2RlJFVzYWdlQnlQYXJlbnQ7OjkIowUSNFtMYW5kcm9pZHgvY29tcG9zZS91aS9ub2RlL0xheW91dE5vZGUkVXNhZ2VCeVBhcmVudDs6QQikBRI8TGFuZHJvaWR4L2NvbXBvc2UvdWkvbm9kZS9Mb29rYWhlYWRQYXNzRGVsZWdhdGUkUGxhY2VkU3RhdGU7OkIIpQUSPVtMYW5kcm9pZHgvY29tcG9zZS91aS9ub2RlL0xvb2thaGVhZFBhc3NEZWxlZ2F0ZSRQbGFjZWRTdGF0ZTs6RwimBRJCTGFuZHJvaWR4L2NvbXBvc2UvdWkvbm9kZS9Ob2RlTWVhc3VyaW5nSW50cmluc2ljcyRJbnRyaW5zaWNNaW5NYXg7OkgIpwUSQ1tMYW5kcm9pZHgvY29tcG9zZS91aS9ub2RlL05vZGVNZWFzdXJpbmdJbnRyaW5zaWNzJEludHJpbnNpY01pbk1heDs6TAioBRJHTGFuZHJvaWR4L2NvbXBvc2UvdWkvbm9kZS9Ob2RlTWVhc3VyaW5nSW50cmluc2ljcyRJbnRyaW5zaWNXaWR0aEhlaWdodDs6TQipBRJIW0xhbmRyb2lkeC9jb21wb3NlL3VpL25vZGUvTm9kZU1lYXN1cmluZ0ludHJpbnNpY3MkSW50cmluc2ljV2lkdGhIZWlnaHQ7OlMIqgUSTkxhbmRyb2lkeC9jb21wb3NlL3VpL25vZGUvVHJhdmVyc2FibGVOb2RlJENvbXBhbmlvbiRUcmF2ZXJzZURlc2NlbmRhbnRzQWN0aW9uOzpUCKsFEk9bTGFuZHJvaWR4L2NvbXBvc2UvdWkvbm9kZS9UcmF2ZXJzYWJsZU5vZGUkQ29tcGFuaW9uJFRyYXZlcnNlRGVzY2VuZGFudHNBY3Rpb247OjUIrAUSMExhbmRyb2lkeC9jb21wb3NlL3VpL3BsYXRmb3JtL1RleHRUb29sYmFyU3RhdHVzOzo2CK0FEjFbTGFuZHJvaWR4L2NvbXBvc2UvdWkvcGxhdGZvcm0vVGV4dFRvb2xiYXJTdGF0dXM7OkUIrgUSQExhbmRyb2lkeC9jb21wb3NlL3VpL3BsYXRmb3JtL2FjdGlvbm1vZGVjYWxsYmFjay9NZW51SXRlbU9wdGlvbjs6RgivBRJBW0xhbmRyb2lkeC9jb21wb3NlL3VpL3BsYXRmb3JtL2FjdGlvbm1vZGVjYWxsYmFjay9NZW51SXRlbU9wdGlvbjs6MAiwBRIrTGFuZHJvaWR4L2NvbXBvc2UvdWkvc3RhdGUvVG9nZ2xlYWJsZVN0YXRlOzoxCLEFEixbTGFuZHJvaWR4L2NvbXBvc2UvdWkvc3RhdGUvVG9nZ2xlYWJsZVN0YXRlOzouCLIFEilMYW5kcm9pZHgvY29tcG9zZS91aS90ZXh0L0Fubm90YXRpb25UeXBlOzovCLMFEipbTGFuZHJvaWR4L2NvbXBvc2UvdWkvdGV4dC9Bbm5vdGF0aW9uVHlwZTs6Tgi0BRJJTGFuZHJvaWR4L2NvbXBvc2UvdWkvdGV4dC9pbnB1dC9UZXh0SW5wdXRTZXJ2aWNlQW5kcm9pZCRUZXh0SW5wdXRDb21tYW5kOzpPCLUFEkpbTGFuZHJvaWR4L2NvbXBvc2UvdWkvdGV4dC9pbnB1dC9UZXh0SW5wdXRTZXJ2aWNlQW5kcm9pZCRUZXh0SW5wdXRDb21tYW5kOzo7CLYFEjZMYW5kcm9pZHgvY29tcG9zZS91aS90ZXh0L3N0eWxlL1Jlc29sdmVkVGV4dERpcmVjdGlvbjs6PAi3BRI3W0xhbmRyb2lkeC9jb21wb3NlL3VpL3RleHQvc3R5bGUvUmVzb2x2ZWRUZXh0RGlyZWN0aW9uOzovCLgFEipMYW5kcm9pZHgvY29tcG9zZS91aS91bml0L0xheW91dERpcmVjdGlvbjs6MAi5BRIrW0xhbmRyb2lkeC9jb21wb3NlL3VpL3VuaXQvTGF5b3V0RGlyZWN0aW9uOzoyCLoFEi1MYW5kcm9pZHgvY29tcG9zZS91aS93aW5kb3cvU2VjdXJlRmxhZ1BvbGljeTs6Mwi7BRIuW0xhbmRyb2lkeC9jb21wb3NlL3VpL3dpbmRvdy9TZWN1cmVGbGFnUG9saWN5OzoxCLwFEixMYW5kcm9pZHgvY29uY3VycmVudC9mdXR1cmVzL0RpcmVjdEV4ZWN1dG9yOzoyCL0FEi1bTGFuZHJvaWR4L2NvbmN1cnJlbnQvZnV0dXJlcy9EaXJlY3RFeGVjdXRvcjs6Rgi+BRJBTGFuZHJvaWR4L2RhdGFzdG9yZS9wcmVmZXJlbmNlcy9QcmVmZXJlbmNlc1Byb3RvJFZhbHVlJFZhbHVlQ2FzZTs6Rwi/BRJCW0xhbmRyb2lkeC9kYXRhc3RvcmUvcHJlZmVyZW5jZXMvUHJlZmVyZW5jZXNQcm90byRWYWx1ZSRWYWx1ZUNhc2U7OkMIwAUSPkxhbmRyb2lkeC9kYXRhc3RvcmUvcHJlZmVyZW5jZXMvcHJvdG9idWYvRmllbGRUeXBlJENvbGxlY3Rpb247OkQIwQUSP1tMYW5kcm9pZHgvZGF0YXN0b3JlL3ByZWZlcmVuY2VzL3Byb3RvYnVmL0ZpZWxkVHlwZSRDb2xsZWN0aW9uOzo4CMIFEjNMYW5kcm9pZHgvZGF0YXN0b3JlL3ByZWZlcmVuY2VzL3Byb3RvYnVmL0ZpZWxkVHlwZTs6OQjDBRI0W0xhbmRyb2lkeC9kYXRhc3RvcmUvcHJlZmVyZW5jZXMvcHJvdG9idWYvRmllbGRUeXBlOzpSCMQFEk1MYW5kcm9pZHgvZGF0YXN0b3JlL3ByZWZlcmVuY2VzL3Byb3RvYnVmL0dlbmVyYXRlZE1lc3NhZ2VMaXRlJE1ldGhvZFRvSW52b2tlOzpTCMUFEk5bTGFuZHJvaWR4L2RhdGFzdG9yZS9wcmVmZXJlbmNlcy9wcm90b2J1Zi9HZW5lcmF0ZWRNZXNzYWdlTGl0ZSRNZXRob2RUb0ludm9rZTs6NwjGBRIyTGFuZHJvaWR4L2RhdGFzdG9yZS9wcmVmZXJlbmNlcy9wcm90b2J1Zi9KYXZhVHlwZTs6OAjHBRIzW0xhbmRyb2lkeC9kYXRhc3RvcmUvcHJlZmVyZW5jZXMvcHJvdG9idWYvSmF2YVR5cGU7OjoIyAUSNUxhbmRyb2lkeC9kYXRhc3RvcmUvcHJlZmVyZW5jZXMvcHJvdG9idWYvUHJvdG9TeW50YXg7OjsIyQUSNltMYW5kcm9pZHgvZGF0YXN0b3JlL3ByZWZlcmVuY2VzL3Byb3RvYnVmL1Byb3RvU3ludGF4OzpDCMoFEj5MYW5kcm9pZHgvZGF0YXN0b3JlL3ByZWZlcmVuY2VzL3Byb3RvYnVmL1dpcmVGb3JtYXQkRmllbGRUeXBlOzpECMsFEj9bTGFuZHJvaWR4L2RhdGFzdG9yZS9wcmVmZXJlbmNlcy9wcm90b2J1Zi9XaXJlRm9ybWF0JEZpZWxkVHlwZTs6QgjMBRI9TGFuZHJvaWR4L2RhdGFzdG9yZS9wcmVmZXJlbmNlcy9wcm90b2J1Zi9XaXJlRm9ybWF0JEphdmFUeXBlOzpDCM0FEj5bTGFuZHJvaWR4L2RhdGFzdG9yZS9wcmVmZXJlbmNlcy9wcm90b2J1Zi9XaXJlRm9ybWF0JEphdmFUeXBlOzpACM4FEjtMYW5kcm9pZHgvZGF0YXN0b3JlL3ByZWZlcmVuY2VzL3Byb3RvYnVmL1dyaXRlciRGaWVsZE9yZGVyOzpBCM8FEjxbTGFuZHJvaWR4L2RhdGFzdG9yZS9wcmVmZXJlbmNlcy9wcm90b2J1Zi9Xcml0ZXIkRmllbGRPcmRlcjs6TwjQBRJKTGFuZHJvaWR4L2ZyYWdtZW50L2FwcC9TcGVjaWFsRWZmZWN0c0NvbnRyb2xsZXIkT3BlcmF0aW9uJExpZmVjeWNsZUltcGFjdDs6UAjRBRJLW0xhbmRyb2lkeC9mcmFnbWVudC9hcHAvU3BlY2lhbEVmZmVjdHNDb250cm9sbGVyJE9wZXJhdGlvbiRMaWZlY3ljbGVJbXBhY3Q7OkUI0gUSQExhbmRyb2lkeC9mcmFnbWVudC9hcHAvU3BlY2lhbEVmZmVjdHNDb250cm9sbGVyJE9wZXJhdGlvbiRTdGF0ZTs6RgjTBRJBW0xhbmRyb2lkeC9mcmFnbWVudC9hcHAvU3BlY2lhbEVmZmVjdHNDb250cm9sbGVyJE9wZXJhdGlvbiRTdGF0ZTs6PwjUBRI6TGFuZHJvaWR4L2ZyYWdtZW50L2FwcC9zdHJpY3Rtb2RlL0ZyYWdtZW50U3RyaWN0TW9kZSRGbGFnOzpACNUFEjtbTGFuZHJvaWR4L2ZyYWdtZW50L2FwcC9zdHJpY3Rtb2RlL0ZyYWdtZW50U3RyaWN0TW9kZSRGbGFnOzopCNYFEiRMYW5kcm9pZHgvbGlmZWN5Y2xlL0xpZmVjeWNsZSRFdmVudDs6KgjXBRIlW0xhbmRyb2lkeC9saWZlY3ljbGUvTGlmZWN5Y2xlJEV2ZW50OzopCNgFEiRMYW5kcm9pZHgvbGlmZWN5Y2xlL0xpZmVjeWNsZSRTdGF0ZTs6KgjZBRIlW0xhbmRyb2lkeC9saWZlY3ljbGUvTGlmZWN5Y2xlJFN0YXRlOzo1CNoFEjBMYW5kcm9pZHgvbG9hZGVyL2NvbnRlbnQvTW9kZXJuQXN5bmNUYXNrJFN0YXR1czs6NgjbBRIxW0xhbmRyb2lkeC9sb2FkZXIvY29udGVudC9Nb2Rlcm5Bc3luY1Rhc2skU3RhdHVzOzowCNwFEitMYW5kcm9pZHgvcHJvZmlsZWluc3RhbGxlci9GaWxlU2VjdGlvblR5cGU7OjEI3QUSLFtMYW5kcm9pZHgvcHJvZmlsZWluc3RhbGxlci9GaWxlU2VjdGlvblR5cGU7OjII3gUSLUxhbmRyb2lkeC9yb29tL09ic2VydmVkVGFibGVTdGF0ZXMkT2JzZXJ2ZU9wOzozCN8FEi5bTGFuZHJvaWR4L3Jvb20vT2JzZXJ2ZWRUYWJsZVN0YXRlcyRPYnNlcnZlT3A7Oi0I4AUSKExhbmRyb2lkeC9yb29tL1Jvb21EYXRhYmFzZSRKb3VybmFsTW9kZTs6LgjhBRIpW0xhbmRyb2lkeC9yb29tL1Jvb21EYXRhYmFzZSRKb3VybmFsTW9kZTs6NQjiBRIwTGFuZHJvaWR4L3Jvb20vVHJhbnNhY3RvciRTUUxpdGVUcmFuc2FjdGlvblR5cGU7OjYI4wUSMVtMYW5kcm9pZHgvcm9vbS9UcmFuc2FjdG9yJFNRTGl0ZVRyYW5zYWN0aW9uVHlwZTs6VQjkBRJQTGFuZHJvaWR4L3NxbGl0ZS9kYi9mcmFtZXdvcmsvRnJhbWV3b3JrU1FMaXRlT3BlbkhlbHBlciRPcGVuSGVscGVyJENhbGxiYWNrTmFtZTs6VgjlBRJRW0xhbmRyb2lkeC9zcWxpdGUvZGIvZnJhbWV3b3JrL0ZyYW1ld29ya1NRTGl0ZU9wZW5IZWxwZXIkT3BlbkhlbHBlciRDYWxsYmFja05hbWU7OlMI5gUSTkxhbmRyb2lkeC9zcWxpdGUvZHJpdmVyL1N1cHBvcnRTUUxpdGVTdGF0ZW1lbnQkQ29tcGFuaW9uJFRyYW5zYWN0aW9uT3BlcmF0aW9uOzpUCOcFEk9bTGFuZHJvaWR4L3NxbGl0ZS9kcml2ZXIvU3VwcG9ydFNRTGl0ZVN0YXRlbWVudCRDb21wYW5pb24kVHJhbnNhY3Rpb25PcGVyYXRpb247OiwI6AUSJ0xhbmRyb2lkeC93aW5kb3cvY29yZS9WZXJpZmljYXRpb25Nb2RlOzotCOkFEihbTGFuZHJvaWR4L3dpbmRvdy9jb3JlL1ZlcmlmaWNhdGlvbk1vZGU7OiII6gUSHUxhbmRyb2lkeC93b3JrL0JhY2tvZmZQb2xpY3k7OiMI6wUSHltMYW5kcm9pZHgvd29yay9CYWNrb2ZmUG9saWN5OzojCOwFEh5MYW5kcm9pZHgvd29yay9EaXJlY3RFeGVjdXRvcjs6JAjtBRIfW0xhbmRyb2lkeC93b3JrL0RpcmVjdEV4ZWN1dG9yOzonCO4FEiJMYW5kcm9pZHgvd29yay9FeGlzdGluZ1dvcmtQb2xpY3k7OigI7wUSI1tMYW5kcm9pZHgvd29yay9FeGlzdGluZ1dvcmtQb2xpY3k7OiAI8AUSG0xhbmRyb2lkeC93b3JrL05ldHdvcmtUeXBlOzohCPEFEhxbTGFuZHJvaWR4L3dvcmsvTmV0d29ya1R5cGU7OiUI8gUSIExhbmRyb2lkeC93b3JrL091dE9mUXVvdGFQb2xpY3k7OiYI8wUSIVtMYW5kcm9pZHgvd29yay9PdXRPZlF1b3RhUG9saWN5OzojCPQFEh5MYW5kcm9pZHgvd29yay9Xb3JrSW5mbyRTdGF0ZTs6JAj1BRIfW0xhbmRyb2lkeC93b3JrL1dvcmtJbmZvJFN0YXRlOzodCPYFEhhMY29pbC9kZWNvZGUvRGF0YVNvdXJjZTs6Hgj3BRIZW0xjb2lsL2RlY29kZS9EYXRhU291cmNlOzooCPgFEiNMY29pbC9kZWNvZGUvRXhpZk9yaWVudGF0aW9uUG9saWN5OzopCPkFEiRbTGNvaWwvZGVjb2RlL0V4aWZPcmllbnRhdGlvblBvbGljeTs6Hwj6BRIaTGNvaWwvcmVxdWVzdC9DYWNoZVBvbGljeTs6IAj7BRIbW0xjb2lsL3JlcXVlc3QvQ2FjaGVQb2xpY3k7OhoI/AUSFUxjb2lsL3NpemUvUHJlY2lzaW9uOzobCP0FEhZbTGNvaWwvc2l6ZS9QcmVjaXNpb247OhYI/gUSEUxjb2lsL3NpemUvU2NhbGU7OhcI/wUSEltMY29pbC9zaXplL1NjYWxlOzowCIAGEitMY29tL2dvb2dsZS9hbmRyb2lkL2RhdGF0cmFuc3BvcnQvUHJpb3JpdHk7OjEIgQYSLFtMY29tL2dvb2dsZS9hbmRyb2lkL2RhdGF0cmFuc3BvcnQvUHJpb3JpdHk7OkoIggYSRUxjb20vZ29vZ2xlL2FuZHJvaWQvZGF0YXRyYW5zcG9ydC9jY3QvaW50ZXJuYWwvQ2xpZW50SW5mbyRDbGllbnRUeXBlOzpLCIMGEkZbTGNvbS9nb29nbGUvYW5kcm9pZC9kYXRhdHJhbnNwb3J0L2NjdC9pbnRlcm5hbC9DbGllbnRJbmZvJENsaWVudFR5cGU7OlMIhAYSTkxjb20vZ29vZ2xlL2FuZHJvaWQvZGF0YXRyYW5zcG9ydC9jY3QvaW50ZXJuYWwvQ29tcGxpYW5jZURhdGEkUHJvZHVjdElkT3JpZ2luOzpUCIUGEk9bTGNvbS9nb29nbGUvYW5kcm9pZC9kYXRhdHJhbnNwb3J0L2NjdC9pbnRlcm5hbC9Db21wbGlhbmNlRGF0YSRQcm9kdWN0SWRPcmlnaW47OlgIhgYSU0xjb20vZ29vZ2xlL2FuZHJvaWQvZGF0YXRyYW5zcG9ydC9jY3QvaW50ZXJuYWwvTmV0d29ya0Nvbm5lY3Rpb25JbmZvJE1vYmlsZVN1YnR5cGU7OlkIhwYSVFtMY29tL2dvb2dsZS9hbmRyb2lkL2RhdGF0cmFuc3BvcnQvY2N0L2ludGVybmFsL05ldHdvcmtDb25uZWN0aW9uSW5mbyRNb2JpbGVTdWJ0eXBlOzpWCIgGElFMY29tL2dvb2dsZS9hbmRyb2lkL2RhdGF0cmFuc3BvcnQvY2N0L2ludGVybmFsL05ldHdvcmtDb25uZWN0aW9uSW5mbyROZXR3b3JrVHlwZTs6VwiJBhJSW0xjb20vZ29vZ2xlL2FuZHJvaWQvZGF0YXRyYW5zcG9ydC9jY3QvaW50ZXJuYWwvTmV0d29ya0Nvbm5lY3Rpb25JbmZvJE5ldHdvcmtUeXBlOzo8CIoGEjdMY29tL2dvb2dsZS9hbmRyb2lkL2RhdGF0cmFuc3BvcnQvY2N0L2ludGVybmFsL1Fvc1RpZXI7Oj0IiwYSOFtMY29tL2dvb2dsZS9hbmRyb2lkL2RhdGF0cmFuc3BvcnQvY2N0L2ludGVybmFsL1Fvc1RpZXI7Ok8IjAYSSkxjb20vZ29vZ2xlL2FuZHJvaWQvZGF0YXRyYW5zcG9ydC9ydW50aW1lL2JhY2tlbmRzL0JhY2tlbmRSZXNwb25zZSRTdGF0dXM7OlAIjQYSS1tMY29tL2dvb2dsZS9hbmRyb2lkL2RhdGF0cmFuc3BvcnQvcnVudGltZS9iYWNrZW5kcy9CYWNrZW5kUmVzcG9uc2UkU3RhdHVzOzpZCI4GElRMY29tL2dvb2dsZS9hbmRyb2lkL2RhdGF0cmFuc3BvcnQvcnVudGltZS9maXJlYmFzZS90cmFuc3BvcnQvTG9nRXZlbnREcm9wcGVkJFJlYXNvbjs6WgiPBhJVW0xjb20vZ29vZ2xlL2FuZHJvaWQvZGF0YXRyYW5zcG9ydC9ydW50aW1lL2ZpcmViYXNlL3RyYW5zcG9ydC9Mb2dFdmVudERyb3BwZWQkUmVhc29uOzpdCJAGElhMY29tL2dvb2dsZS9hbmRyb2lkL2RhdGF0cmFuc3BvcnQvcnVudGltZS9zY2hlZHVsaW5nL2pvYnNjaGVkdWxpbmcvU2NoZWR1bGVyQ29uZmlnJEZsYWc7Ol4IkQYSWVtMY29tL2dvb2dsZS9hbmRyb2lkL2RhdGF0cmFuc3BvcnQvcnVudGltZS9zY2hlZHVsaW5nL2pvYnNjaGVkdWxpbmcvU2NoZWR1bGVyQ29uZmlnJEZsYWc7OjcIkgYSMkxjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL2ludGVybmFsL21lYXN1cmVtZW50L3p6YnY7OjgIkwYSM1tMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9pbnRlcm5hbC9tZWFzdXJlbWVudC96emJ2Ozo3CJQGEjJMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9pbnRlcm5hbC9tZWFzdXJlbWVudC96emNqOzo4CJUGEjNbTGNvbS9nb29nbGUvYW5kcm9pZC9nbXMvaW50ZXJuYWwvbWVhc3VyZW1lbnQvenpjajs6NwiWBhIyTGNvbS9nb29nbGUvYW5kcm9pZC9nbXMvaW50ZXJuYWwvbWVhc3VyZW1lbnQvenpjbjs6OAiXBhIzW0xjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL2ludGVybmFsL21lYXN1cmVtZW50L3p6Y247OjcImAYSMkxjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL2ludGVybmFsL21lYXN1cmVtZW50L3p6Y287OjgImQYSM1tMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9pbnRlcm5hbC9tZWFzdXJlbWVudC96emNvOzo/CJoGEjpMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9pbnRlcm5hbC9tZWFzdXJlbWVudC96emZvJHp6ZCR6emI7OkAImwYSO1tMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9pbnRlcm5hbC9tZWFzdXJlbWVudC96emZvJHp6ZCR6emI7Oj8InAYSOkxjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL2ludGVybmFsL21lYXN1cmVtZW50L3p6Zm8kenpmJHp6Yjs6QAidBhI7W0xjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL2ludGVybmFsL21lYXN1cmVtZW50L3p6Zm8kenpmJHp6Yjs6PwieBhI6TGNvbS9nb29nbGUvYW5kcm9pZC9nbXMvaW50ZXJuYWwvbWVhc3VyZW1lbnQvenpmciR6emEkenpkOzpACJ8GEjtbTGNvbS9nb29nbGUvYW5kcm9pZC9nbXMvaW50ZXJuYWwvbWVhc3VyZW1lbnQvenpmciR6emEkenpkOzo/CKAGEjpMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9pbnRlcm5hbC9tZWFzdXJlbWVudC96emZyJHp6YSR6emU7OkAIoQYSO1tMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9pbnRlcm5hbC9tZWFzdXJlbWVudC96emZyJHp6YSR6emU7Oj8IogYSOkxjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL2ludGVybmFsL21lYXN1cmVtZW50L3p6ZnkkenpqJHp6Yjs6QAijBhI7W0xjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL2ludGVybmFsL21lYXN1cmVtZW50L3p6ZnkkenpqJHp6Yjs6PwikBhI6TGNvbS9nb29nbGUvYW5kcm9pZC9nbXMvaW50ZXJuYWwvbWVhc3VyZW1lbnQvenpmeSR6emwkenpiOzpACKUGEjtbTGNvbS9nb29nbGUvYW5kcm9pZC9nbXMvaW50ZXJuYWwvbWVhc3VyZW1lbnQvenpmeSR6emwkenpiOzo3CKYGEjJMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9pbnRlcm5hbC9tZWFzdXJlbWVudC96emdhOzo4CKcGEjNbTGNvbS9nb29nbGUvYW5kcm9pZC9nbXMvaW50ZXJuYWwvbWVhc3VyZW1lbnQvenpnYTs6PwioBhI6TGNvbS9nb29nbGUvYW5kcm9pZC9nbXMvaW50ZXJuYWwvbWVhc3VyZW1lbnQvenpnZCR6emQkenphOzpACKkGEjtbTGNvbS9nb29nbGUvYW5kcm9pZC9nbXMvaW50ZXJuYWwvbWVhc3VyZW1lbnQvenpnZCR6emQkenphOzo3CKoGEjJMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9pbnRlcm5hbC9tZWFzdXJlbWVudC96empuOzo4CKsGEjNbTGNvbS9nb29nbGUvYW5kcm9pZC9nbXMvaW50ZXJuYWwvbWVhc3VyZW1lbnQvenpqbjs6NwisBhIyTGNvbS9nb29nbGUvYW5kcm9pZC9nbXMvaW50ZXJuYWwvbWVhc3VyZW1lbnQvenpqcDs6OAitBhIzW0xjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL2ludGVybmFsL21lYXN1cmVtZW50L3p6anA7OjcIrgYSMkxjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL2ludGVybmFsL21lYXN1cmVtZW50L3p6a2Q7OjgIrwYSM1tMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9pbnRlcm5hbC9tZWFzdXJlbWVudC96emtkOzo3CLAGEjJMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9pbnRlcm5hbC9tZWFzdXJlbWVudC96emxuOzo4CLEGEjNbTGNvbS9nb29nbGUvYW5kcm9pZC9nbXMvaW50ZXJuYWwvbWVhc3VyZW1lbnQvenpsbjs6NwiyBhIyTGNvbS9nb29nbGUvYW5kcm9pZC9nbXMvaW50ZXJuYWwvbWVhc3VyZW1lbnQvenptczs6OAizBhIzW0xjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL2ludGVybmFsL21lYXN1cmVtZW50L3p6bXM7OjcItAYSMkxjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL2ludGVybmFsL21lYXN1cmVtZW50L3p6bXo7OjgItQYSM1tMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9pbnRlcm5hbC9tZWFzdXJlbWVudC96em16Ozo2CLYGEjFMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9pbnRlcm5hbC9tZWFzdXJlbWVudC96enM7OjcItwYSMltMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9pbnRlcm5hbC9tZWFzdXJlbWVudC96enM7OjcIuAYSMkxjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL21lYXN1cmVtZW50L2ludGVybmFsL3p6YWs7OjgIuQYSM1tMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9tZWFzdXJlbWVudC9pbnRlcm5hbC96emFrOzo7CLoGEjZMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9tZWFzdXJlbWVudC9pbnRlcm5hbC96emplJHp6YTs6PAi7BhI3W0xjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL21lYXN1cmVtZW50L2ludGVybmFsL3p6amUkenphOzo3CLwGEjJMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9tZWFzdXJlbWVudC9pbnRlcm5hbC96empnOzo4CL0GEjNbTGNvbS9nb29nbGUvYW5kcm9pZC9nbXMvbWVhc3VyZW1lbnQvaW50ZXJuYWwvenpqZzs6Nwi+BhIyTGNvbS9nb29nbGUvYW5kcm9pZC9nbXMvbWVhc3VyZW1lbnQvaW50ZXJuYWwvenpqaDs6OAi/BhIzW0xjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL21lYXN1cmVtZW50L2ludGVybmFsL3p6amg7OjcIwAYSMkxjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL21lYXN1cmVtZW50L2ludGVybmFsL3p6bnQ7OjgIwQYSM1tMY29tL2dvb2dsZS9hbmRyb2lkL2dtcy9tZWFzdXJlbWVudC9pbnRlcm5hbC96em50Ozo3CMIGEjJMY29tL2dvb2dsZS9jb21tb24vY29sbGVjdC9BYnN0cmFjdEl0ZXJhdG9yJFN0YXRlOzo4CMMGEjNbTGNvbS9nb29nbGUvY29tbW9uL2NvbGxlY3QvQWJzdHJhY3RJdGVyYXRvciRTdGF0ZTs6MwjEBhIuTGNvbS9nb29nbGUvY29tbW9uL2NvbGxlY3QvTWFwcyRFbnRyeUZ1bmN0aW9uOzo0CMUGEi9bTGNvbS9nb29nbGUvY29tbW9uL2NvbGxlY3QvTWFwcyRFbnRyeUZ1bmN0aW9uOzo3CMYGEjJMY29tL2dvb2dsZS9jb21tb24vdXRpbC9jb25jdXJyZW50L0RpcmVjdEV4ZWN1dG9yOzo4CMcGEjNbTGNvbS9nb29nbGUvY29tbW9uL3V0aWwvY29uY3VycmVudC9EaXJlY3RFeGVjdXRvcjs6RgjIBhJBTGNvbS9nb29nbGUvZmlyZWJhc2UvY29uY3VycmVudC9GaXJlYmFzZUV4ZWN1dG9ycyREaXJlY3RFeGVjdXRvcjs6RwjJBhJCW0xjb20vZ29vZ2xlL2ZpcmViYXNlL2NvbmN1cnJlbnQvRmlyZWJhc2VFeGVjdXRvcnMkRGlyZWN0RXhlY3V0b3I7OksIygYSRkxjb20vZ29vZ2xlL2ZpcmViYXNlL2NvbmN1cnJlbnQvU2VxdWVudGlhbEV4ZWN1dG9yJFdvcmtlclJ1bm5pbmdTdGF0ZTs6TAjLBhJHW0xjb20vZ29vZ2xlL2ZpcmViYXNlL2NvbmN1cnJlbnQvU2VxdWVudGlhbEV4ZWN1dG9yJFdvcmtlclJ1bm5pbmdTdGF0ZTs6MAjMBhIrTGNvbS9nb29nbGUvZmlyZWJhc2UvY29uY3VycmVudC9VaUV4ZWN1dG9yOzoxCM0GEixbTGNvbS9nb29nbGUvZmlyZWJhc2UvY29uY3VycmVudC9VaUV4ZWN1dG9yOzpPCM4GEkpMY29tL2dvb2dsZS9maXJlYmFzZS9jcmFzaGx5dGljcy9pbnRlcm5hbC9jb21tb24vQ29tbW9uVXRpbHMkQXJjaGl0ZWN0dXJlOzpQCM8GEktbTGNvbS9nb29nbGUvZmlyZWJhc2UvY3Jhc2hseXRpY3MvaW50ZXJuYWwvY29tbW9uL0NvbW1vblV0aWxzJEFyY2hpdGVjdHVyZTs6SAjQBhJDTGNvbS9nb29nbGUvZmlyZWJhc2UvY3Jhc2hseXRpY3MvaW50ZXJuYWwvY29tbW9uL0RlbGl2ZXJ5TWVjaGFuaXNtOzpJCNEGEkRbTGNvbS9nb29nbGUvZmlyZWJhc2UvY3Jhc2hseXRpY3MvaW50ZXJuYWwvY29tbW9uL0RlbGl2ZXJ5TWVjaGFuaXNtOzpOCNIGEklMY29tL2dvb2dsZS9maXJlYmFzZS9jcmFzaGx5dGljcy9pbnRlcm5hbC9zZXR0aW5ncy9TZXR0aW5nc0NhY2hlQmVoYXZpb3I7Ok8I0wYSSltMY29tL2dvb2dsZS9maXJlYmFzZS9jcmFzaGx5dGljcy9pbnRlcm5hbC9zZXR0aW5ncy9TZXR0aW5nc0NhY2hlQmVoYXZpb3I7Oj4I1AYSOUxjb20vZ29vZ2xlL2ZpcmViYXNlL2VuY29kZXJzL3Byb3RvL1Byb3RvYnVmJEludEVuY29kaW5nOzo/CNUGEjpbTGNvbS9nb29nbGUvZmlyZWJhc2UvZW5jb2RlcnMvcHJvdG8vUHJvdG9idWYkSW50RW5jb2Rpbmc7OkAI1gYSO0xjb20vZ29vZ2xlL2ZpcmViYXNlL2hlYXJ0YmVhdGluZm8vSGVhcnRCZWF0SW5mbyRIZWFydEJlYXQ7OkEI1wYSPFtMY29tL2dvb2dsZS9maXJlYmFzZS9oZWFydGJlYXRpbmZvL0hlYXJ0QmVhdEluZm8kSGVhcnRCZWF0OzpOCNgGEklMY29tL2dvb2dsZS9maXJlYmFzZS9pbnN0YWxsYXRpb25zL0ZpcmViYXNlSW5zdGFsbGF0aW9uc0V4Y2VwdGlvbiRTdGF0dXM7Ok8I2QYSSltMY29tL2dvb2dsZS9maXJlYmFzZS9pbnN0YWxsYXRpb25zL0ZpcmViYXNlSW5zdGFsbGF0aW9uc0V4Y2VwdGlvbiRTdGF0dXM7OlcI2gYSUkxjb20vZ29vZ2xlL2ZpcmViYXNlL2luc3RhbGxhdGlvbnMvbG9jYWwvUGVyc2lzdGVkSW5zdGFsbGF0aW9uJFJlZ2lzdHJhdGlvblN0YXR1czs6WAjbBhJTW0xjb20vZ29vZ2xlL2ZpcmViYXNlL2luc3RhbGxhdGlvbnMvbG9jYWwvUGVyc2lzdGVkSW5zdGFsbGF0aW9uJFJlZ2lzdHJhdGlvblN0YXR1czs6UQjcBhJMTGNvbS9nb29nbGUvZmlyZWJhc2UvaW5zdGFsbGF0aW9ucy9yZW1vdGUvSW5zdGFsbGF0aW9uUmVzcG9uc2UkUmVzcG9uc2VDb2RlOzpSCN0GEk1bTGNvbS9nb29nbGUvZmlyZWJhc2UvaW5zdGFsbGF0aW9ucy9yZW1vdGUvSW5zdGFsbGF0aW9uUmVzcG9uc2UkUmVzcG9uc2VDb2RlOzpICN4GEkNMY29tL2dvb2dsZS9maXJlYmFzZS9pbnN0YWxsYXRpb25zL3JlbW90ZS9Ub2tlblJlc3VsdCRSZXNwb25zZUNvZGU7OkkI3wYSRFtMY29tL2dvb2dsZS9maXJlYmFzZS9pbnN0YWxsYXRpb25zL3JlbW90ZS9Ub2tlblJlc3VsdCRSZXNwb25zZUNvZGU7OkkI4AYSRExjb20vZ29vZ2xlL2ZpcmViYXNlL21lc3NhZ2luZy9yZXBvcnRpbmcvTWVzc2FnaW5nQ2xpZW50RXZlbnQkRXZlbnQ7OkoI4QYSRVtMY29tL2dvb2dsZS9maXJlYmFzZS9tZXNzYWdpbmcvcmVwb3J0aW5nL01lc3NhZ2luZ0NsaWVudEV2ZW50JEV2ZW50OzpPCOIGEkpMY29tL2dvb2dsZS9maXJlYmFzZS9tZXNzYWdpbmcvcmVwb3J0aW5nL01lc3NhZ2luZ0NsaWVudEV2ZW50JE1lc3NhZ2VUeXBlOzpQCOMGEktbTGNvbS9nb29nbGUvZmlyZWJhc2UvbWVzc2FnaW5nL3JlcG9ydGluZy9NZXNzYWdpbmdDbGllbnRFdmVudCRNZXNzYWdlVHlwZTs6TwjkBhJKTGNvbS9nb29nbGUvZmlyZWJhc2UvbWVzc2FnaW5nL3JlcG9ydGluZy9NZXNzYWdpbmdDbGllbnRFdmVudCRTREtQbGF0Zm9ybTs6UAjlBhJLW0xjb20vZ29vZ2xlL2ZpcmViYXNlL21lc3NhZ2luZy9yZXBvcnRpbmcvTWVzc2FnaW5nQ2xpZW50RXZlbnQkU0RLUGxhdGZvcm07OjsI5gYSNkxjb20vZ29vZ2xlL2ZpcmViYXNlL21lc3NhZ2luZy90aHJlYWRzL1RocmVhZFByaW9yaXR5Ozo8COcGEjdbTGNvbS9nb29nbGUvZmlyZWJhc2UvbWVzc2FnaW5nL3RocmVhZHMvVGhyZWFkUHJpb3JpdHk7OjsI6AYSNkxjb20vZ29vZ2xlL2ZpcmViYXNlL3BlcmYvdXRpbC9Db25zdGFudHMkQ291bnRlck5hbWVzOzo8COkGEjdbTGNvbS9nb29nbGUvZmlyZWJhc2UvcGVyZi91dGlsL0NvbnN0YW50cyRDb3VudGVyTmFtZXM7OjkI6gYSNExjb20vZ29vZ2xlL2ZpcmViYXNlL3BlcmYvdXRpbC9Db25zdGFudHMkVHJhY2VOYW1lczs6OgjrBhI1W0xjb20vZ29vZ2xlL2ZpcmViYXNlL3BlcmYvdXRpbC9Db25zdGFudHMkVHJhY2VOYW1lczs6MAjsBhIrTGNvbS9nb29nbGUvZmlyZWJhc2UvcGVyZi91dGlsL1N0b3JhZ2VVbml0OzoxCO0GEixbTGNvbS9nb29nbGUvZmlyZWJhc2UvcGVyZi91dGlsL1N0b3JhZ2VVbml0Ozo7CO4GEjZbTGNvbS9nb29nbGUvZmlyZWJhc2UvcGVyZi92MS9BcHBsaWNhdGlvblByb2Nlc3NTdGF0ZTs6QgjvBhI9TGNvbS9nb29nbGUvZmlyZWJhc2UvcGVyZi92MS9OZXR3b3JrUmVxdWVzdE1ldHJpYyRIdHRwTWV0aG9kOzpDCPAGEj5bTGNvbS9nb29nbGUvZmlyZWJhc2UvcGVyZi92MS9OZXR3b3JrUmVxdWVzdE1ldHJpYyRIdHRwTWV0aG9kOzpQCPEGEktMY29tL2dvb2dsZS9maXJlYmFzZS9wZXJmL3YxL05ldHdvcmtSZXF1ZXN0TWV0cmljJE5ldHdvcmtDbGllbnRFcnJvclJlYXNvbjs6UQjyBhJMW0xjb20vZ29vZ2xlL2ZpcmViYXNlL3BlcmYvdjEvTmV0d29ya1JlcXVlc3RNZXRyaWMkTmV0d29ya0NsaWVudEVycm9yUmVhc29uOzozCPMGEi5MY29tL2dvb2dsZS9maXJlYmFzZS9wZXJmL3YxL1Nlc3Npb25WZXJib3NpdHk7OjQI9AYSL1tMY29tL2dvb2dsZS9maXJlYmFzZS9wZXJmL3YxL1Nlc3Npb25WZXJib3NpdHk7OkQI9QYSP0xjb20vZ29vZ2xlL2ZpcmViYXNlL3BlcmYvdjEvVHJhbnNwb3J0SW5mbyREaXNwYXRjaERlc3RpbmF0aW9uOzpFCPYGEkBbTGNvbS9nb29nbGUvZmlyZWJhc2UvcGVyZi92MS9UcmFuc3BvcnRJbmZvJERpc3BhdGNoRGVzdGluYXRpb247OkoI9wYSRUxjb20vZ29vZ2xlL2ZpcmViYXNlL3JlbW90ZWNvbmZpZy9GaXJlYmFzZVJlbW90ZUNvbmZpZ0V4Y2VwdGlvbiRDb2RlOzpLCPgGEkZbTGNvbS9nb29nbGUvZmlyZWJhc2UvcmVtb3RlY29uZmlnL0ZpcmViYXNlUmVtb3RlQ29uZmlnRXhjZXB0aW9uJENvZGU7Ok0I+QYSSExjb20vZ29vZ2xlL2ZpcmViYXNlL3JlbW90ZWNvbmZpZy9pbnRlcm5hbC9Db25maWdGZXRjaEhhbmRsZXIkRmV0Y2hUeXBlOzpOCPoGEklbTGNvbS9nb29nbGUvZmlyZWJhc2UvcmVtb3RlY29uZmlnL2ludGVybmFsL0NvbmZpZ0ZldGNoSGFuZGxlciRGZXRjaFR5cGU7OjcI+wYSMkxjb20vZ29vZ2xlL2ZpcmViYXNlL3Nlc3Npb25zL0RhdGFDb2xsZWN0aW9uU3RhdGU7OjgI/AYSM1tMY29tL2dvb2dsZS9maXJlYmFzZS9zZXNzaW9ucy9EYXRhQ29sbGVjdGlvblN0YXRlOzotCP0GEihMY29tL2dvb2dsZS9maXJlYmFzZS9zZXNzaW9ucy9FdmVudFR5cGU7Oi4I/gYSKVtMY29tL2dvb2dsZS9maXJlYmFzZS9zZXNzaW9ucy9FdmVudFR5cGU7OjII/wYSLUxjb20vZ29vZ2xlL2ZpcmViYXNlL3Nlc3Npb25zL0xvZ0Vudmlyb25tZW50OzozCIAHEi5bTGNvbS9nb29nbGUvZmlyZWJhc2Uvc2Vzc2lvbnMvTG9nRW52aXJvbm1lbnQ7Oj4IgQcSOUxjb20vZ29vZ2xlL2ZpcmViYXNlL3Nlc3Npb25zL2FwaS9TZXNzaW9uU3Vic2NyaWJlciROYW1lOzo/CIIHEjpbTGNvbS9nb29nbGUvZmlyZWJhc2Uvc2Vzc2lvbnMvYXBpL1Nlc3Npb25TdWJzY3JpYmVyJE5hbWU7Oi8IgwcSKkxjb20vZ29vZ2xlL3Byb3RvYnVmL0ZpZWxkVHlwZSRDb2xsZWN0aW9uOzowCIQHEitbTGNvbS9nb29nbGUvcHJvdG9idWYvRmllbGRUeXBlJENvbGxlY3Rpb247OiQIhQcSH0xjb20vZ29vZ2xlL3Byb3RvYnVmL0ZpZWxkVHlwZTs6JQiGBxIgW0xjb20vZ29vZ2xlL3Byb3RvYnVmL0ZpZWxkVHlwZTs6PgiHBxI5TGNvbS9nb29nbGUvcHJvdG9idWYvR2VuZXJhdGVkTWVzc2FnZUxpdGUkTWV0aG9kVG9JbnZva2U7Oj8IiAcSOltMY29tL2dvb2dsZS9wcm90b2J1Zi9HZW5lcmF0ZWRNZXNzYWdlTGl0ZSRNZXRob2RUb0ludm9rZTs6IwiJBxIeTGNvbS9nb29nbGUvcHJvdG9idWYvSmF2YVR5cGU7OiQIigcSH1tMY29tL2dvb2dsZS9wcm90b2J1Zi9KYXZhVHlwZTs6JgiLBxIhTGNvbS9nb29nbGUvcHJvdG9idWYvUHJvdG9TeW50YXg7OicIjAcSIltMY29tL2dvb2dsZS9wcm90b2J1Zi9Qcm90b1N5bnRheDs6LwiNBxIqTGNvbS9nb29nbGUvcHJvdG9idWYvV2lyZUZvcm1hdCRGaWVsZFR5cGU7OjAIjgcSK1tMY29tL2dvb2dsZS9wcm90b2J1Zi9XaXJlRm9ybWF0JEZpZWxkVHlwZTs6LgiPBxIpTGNvbS9nb29nbGUvcHJvdG9idWYvV2lyZUZvcm1hdCRKYXZhVHlwZTs6LwiQBxIqW0xjb20vZ29vZ2xlL3Byb3RvYnVmL1dpcmVGb3JtYXQkSmF2YVR5cGU7OiwIkQcSJ0xjb20vZ29vZ2xlL3Byb3RvYnVmL1dyaXRlciRGaWVsZE9yZGVyOzotCJIHEihbTGNvbS9nb29nbGUvcHJvdG9idWYvV3JpdGVyJEZpZWxkT3JkZXI7Ok8IkwcSSkxjb20vZ29vZ2xlL3NhbXBsZXMvYXBwcy9ub3dpbmFuZHJvaWQvY29yZS9kYXRhc3RvcmUvRGFya1RoZW1lQ29uZmlnUHJvdG87OlAIlAcSS1tMY29tL2dvb2dsZS9zYW1wbGVzL2FwcHMvbm93aW5hbmRyb2lkL2NvcmUvZGF0YXN0b3JlL0RhcmtUaGVtZUNvbmZpZ1Byb3RvOzpKCJUHEkVMY29tL2dvb2dsZS9zYW1wbGVzL2FwcHMvbm93aW5hbmRyb2lkL2NvcmUvZGF0YXN0b3JlL1RoZW1lQnJhbmRQcm90bzs6SwiWBxJGW0xjb20vZ29vZ2xlL3NhbXBsZXMvYXBwcy9ub3dpbmFuZHJvaWQvY29yZS9kYXRhc3RvcmUvVGhlbWVCcmFuZFByb3RvOzpcCJcHEldMY29tL2dvb2dsZS9zYW1wbGVzL2FwcHMvbm93aW5hbmRyb2lkL2NvcmUvZGVzaWduc3lzdGVtL2NvbXBvbmVudC9zY3JvbGxiYXIvVGh1bWJTdGF0ZTs6XQiYBxJYW0xjb20vZ29vZ2xlL3NhbXBsZXMvYXBwcy9ub3dpbmFuZHJvaWQvY29yZS9kZXNpZ25zeXN0ZW0vY29tcG9uZW50L3Njcm9sbGJhci9UaHVtYlN0YXRlOzpGCJkHEkFMY29tL2dvb2dsZS9zYW1wbGVzL2FwcHMvbm93aW5hbmRyb2lkL2NvcmUvZG9tYWluL1RvcGljU29ydEZpZWxkOzpHCJoHEkJbTGNvbS9nb29nbGUvc2FtcGxlcy9hcHBzL25vd2luYW5kcm9pZC9jb3JlL2RvbWFpbi9Ub3BpY1NvcnRGaWVsZDs6SwibBxJGTGNvbS9nb29nbGUvc2FtcGxlcy9hcHBzL25vd2luYW5kcm9pZC9jb3JlL21vZGVsL2RhdGEvRGFya1RoZW1lQ29uZmlnOzpMCJwHEkdbTGNvbS9nb29nbGUvc2FtcGxlcy9hcHBzL25vd2luYW5kcm9pZC9jb3JlL21vZGVsL2RhdGEvRGFya1RoZW1lQ29uZmlnOzpGCJ0HEkFMY29tL2dvb2dsZS9zYW1wbGVzL2FwcHMvbm93aW5hbmRyb2lkL2NvcmUvbW9kZWwvZGF0YS9UaGVtZUJyYW5kOzpHCJ4HEkJbTGNvbS9nb29nbGUvc2FtcGxlcy9hcHBzL25vd2luYW5kcm9pZC9jb3JlL21vZGVsL2RhdGEvVGhlbWVCcmFuZDs6HgifBxIZTGtvdGxpbi9EZXByZWNhdGlvbkxldmVsOzofCKAHEhpbTGtvdGxpbi9EZXByZWNhdGlvbkxldmVsOzoiCKEHEh1Ma290bGluL0xhenlUaHJlYWRTYWZldHlNb2RlOzojCKIHEh5bTGtvdGxpbi9MYXp5VGhyZWFkU2FmZXR5TW9kZTs6NwijBxIyTGtvdGxpbi9jb3JvdXRpbmVzL2ludHJpbnNpY3MvQ29yb3V0aW5lU2luZ2xldG9uczs6OAikBxIzW0xrb3RsaW4vY29yb3V0aW5lcy9pbnRyaW5zaWNzL0Nvcm91dGluZVNpbmdsZXRvbnM7Oh8IpQcSGkxrb3RsaW4vdGltZS9EdXJhdGlvblVuaXQ7OiAIpgcSG1tMa290bGluL3RpbWUvRHVyYXRpb25Vbml0OzooCKcHEiNMa290bGlueC9jb3JvdXRpbmVzL0Nvcm91dGluZVN0YXJ0OzopCKgHEiRbTGtvdGxpbngvY29yb3V0aW5lcy9Db3JvdXRpbmVTdGFydDs6MQipBxIsTGtvdGxpbngvY29yb3V0aW5lcy9jaGFubmVscy9CdWZmZXJPdmVyZmxvdzs6MgiqBxItW0xrb3RsaW54L2Nvcm91dGluZXMvY2hhbm5lbHMvQnVmZmVyT3ZlcmZsb3c7Oi0IqwcSKExrb3RsaW54L2Nvcm91dGluZXMvZmxvdy9TaGFyaW5nQ29tbWFuZDs6LgisBxIpW0xrb3RsaW54L2Nvcm91dGluZXMvZmxvdy9TaGFyaW5nQ29tbWFuZDs6QwitBxI+TGtvdGxpbngvY29yb3V0aW5lcy9zY2hlZHVsaW5nL0Nvcm91dGluZVNjaGVkdWxlciRXb3JrZXJTdGF0ZTs6RAiuBxI/W0xrb3RsaW54L2Nvcm91dGluZXMvc2NoZWR1bGluZy9Db3JvdXRpbmVTY2hlZHVsZXIkV29ya2VyU3RhdGU7OjkIrwcSNExrb3RsaW54L2Nvcm91dGluZXMvc2VsZWN0cy9UcnlTZWxlY3REZXRhaWxlZFJlc3VsdDs6OgiwBxI1W0xrb3RsaW54L2Nvcm91dGluZXMvc2VsZWN0cy9UcnlTZWxlY3REZXRhaWxlZFJlc3VsdDs6KQixBxIkTGtvdGxpbngvZGF0ZXRpbWUvZm9ybWF0L0FtUG1NYXJrZXI7OioIsgcSJVtMa290bGlueC9kYXRldGltZS9mb3JtYXQvQW1QbU1hcmtlcjs6JgizBxIhTGtvdGxpbngvZGF0ZXRpbWUvZm9ybWF0L1BhZGRpbmc7OicItAcSIltMa290bGlueC9kYXRldGltZS9mb3JtYXQvUGFkZGluZzs6OAi1BxIzTGtvdGxpbngvc2VyaWFsaXphdGlvbi9qc29uL0NsYXNzRGlzY3JpbWluYXRvck1vZGU7OjkItgcSNFtMa290bGlueC9zZXJpYWxpemF0aW9uL2pzb24vQ2xhc3NEaXNjcmltaW5hdG9yTW9kZTs6NAi3BxIvTGtvdGxpbngvc2VyaWFsaXphdGlvbi9qc29uL2ludGVybmFsL1dyaXRlTW9kZTs6NQi4BxIwW0xrb3RsaW54L3NlcmlhbGl6YXRpb24vanNvbi9pbnRlcm5hbC9Xcml0ZU1vZGU7OhcIuQcSEkxva2h0dHAzL1Byb3RvY29sOzoYCLoHEhNbTG9raHR0cDMvUHJvdG9jb2w7OhkIuwcSFExva2h0dHAzL1Rsc1ZlcnNpb247OhoIvAcSFVtMb2todHRwMy9UbHNWZXJzaW9uOzonCL0HEiJMb2todHRwMy9pbnRlcm5hbC9odHRwMi9FcnJvckNvZGU7OigIvgcSI1tMb2todHRwMy9pbnRlcm5hbC9odHRwMi9FcnJvckNvZGU7OjMIvwcSLkxva2h0dHAzL2xvZ2dpbmcvSHR0cExvZ2dpbmdJbnRlcmNlcHRvciRMZXZlbDs6NAjABxIvW0xva2h0dHAzL2xvZ2dpbmcvSHR0cExvZ2dpbmdJbnRlcmNlcHRvciRMZXZlbDs6HwjBBxIaTGtvdGxpbi9lbnVtcy9FbnVtRW50cmllczs6MwjCBxIuTGFuZHJvaWR4L2xpZmVjeWNsZS9MaWZlY3ljbGUkRXZlbnQkQ29tcGFuaW9uOzo2CMMHEjFMYW5kcm9pZHgvYXBwY29tcGF0L3ZpZXcvbWVudS9BY3Rpb25NZW51SXRlbVZpZXc7OjAIxAcSK0xhbmRyb2lkeC9hcHBjb21wYXQvdmlldy9tZW51L01lbnVJdGVtSW1wbDs6KQjFBxIkTGFuZHJvaWQvZ3JhcGhpY3MvZHJhd2FibGUvRHJhd2FibGU7OjsIxgcSNkxhbmRyb2lkeC9hcHBjb21wYXQvdmlldy9tZW51L01lbnVCdWlsZGVyJEl0ZW1JbnZva2VyOzpECMcHEj9MYW5kcm9pZHgvYXBwY29tcGF0L3ZpZXcvbWVudS9BY3Rpb25NZW51SXRlbVZpZXckUG9wdXBDYWxsYmFjazs6NAjIBxIvTGFuZHJvaWR4L2FwcGNvbXBhdC92aWV3L21lbnUvRXhwYW5kZWRNZW51Vmlldzs6NAjJBxIvTGFuZHJvaWR4L2FwcGNvbXBhdC92aWV3L21lbnUvTGlzdE1lbnVJdGVtVmlldzs6IgjKBxIdTGFuZHJvaWQvdmlldy9MYXlvdXRJbmZsYXRlcjs6MwjLBxIuTGFuZHJvaWR4L2FwcGNvbXBhdC93aWRnZXQvQWN0aW9uQmFyQ29udGFpbmVyOzo6CMwHEjVMYW5kcm9pZHgvYXBwY29tcGF0L3dpZGdldC9TY3JvbGxpbmdUYWJDb250YWluZXJWaWV3Ozo1CM0HEjBMYW5kcm9pZHgvYXBwY29tcGF0L3dpZGdldC9BY3Rpb25CYXJDb250ZXh0Vmlldzs6NwjOBxIyTGFuZHJvaWR4L2FwcGNvbXBhdC93aWRnZXQvQWN0aW9uQmFyT3ZlcmxheUxheW91dDs6UwjPBxJOTGFuZHJvaWR4L2FwcGNvbXBhdC93aWRnZXQvQWN0aW9uQmFyT3ZlcmxheUxheW91dCRBY3Rpb25CYXJWaXNpYmlsaXR5Q2FsbGJhY2s7OiMI0AcSHkxhbmRyb2lkL3ZpZXcvV2luZG93JENhbGxiYWNrOzovCNEHEipMYW5kcm9pZHgvYXBwY29tcGF0L3dpZGdldC9BY3Rpb25NZW51Vmlldzs6GAjSBxITTGFuZHJvaWQvdmlldy9NZW51OzpHCNMHEkJMYW5kcm9pZHgvYXBwY29tcGF0L3dpZGdldC9BY3Rpb25NZW51VmlldyRPbk1lbnVJdGVtQ2xpY2tMaXN0ZW5lcjs6NAjUBxIvTGFuZHJvaWR4L2FwcGNvbXBhdC93aWRnZXQvQWN0aW9uTWVudVByZXNlbnRlcjs6PgjVBxI5TGFuZHJvaWR4L2FwcGNvbXBhdC93aWRnZXQvQXBwQ29tcGF0QXV0b0NvbXBsZXRlVGV4dFZpZXc7OicI1gcSIkxhbmRyb2lkL3ZpZXcvQWN0aW9uTW9kZSRDYWxsYmFjazs6JgjXBxIhTGFuZHJvaWQvdGV4dC9tZXRob2QvS2V5TGlzdGVuZXI7OjAI2AcSK0xhbmRyb2lkeC9hcHBjb21wYXQvd2lkZ2V0L0FwcENvbXBhdEJ1dHRvbjs6OQjZBxI0TGFuZHJvaWR4L2FwcGNvbXBhdC93aWRnZXQvQXBwQ29tcGF0RW1vamlUZXh0SGVscGVyOzogCNoHEhtbTGFuZHJvaWQvdGV4dC9JbnB1dEZpbHRlcjs6MgjbBxItTGFuZHJvaWR4L2FwcGNvbXBhdC93aWRnZXQvQXBwQ29tcGF0Q2hlY2tCb3g7OjkI3AcSNExhbmRyb2lkeC9hcHBjb21wYXQvd2lkZ2V0L0FwcENvbXBhdENoZWNrZWRUZXh0Vmlldzs6MgjdBxItTGFuZHJvaWR4L2FwcGNvbXBhdC93aWRnZXQvQXBwQ29tcGF0RWRpdFRleHQ7Oj4I3gcSOUxhbmRyb2lkeC9hcHBjb21wYXQvd2lkZ2V0L0FwcENvbXBhdEVkaXRUZXh0JFN1cGVyQ2FsbGVyOzocCN8HEhdMYW5kcm9pZC90ZXh0L0VkaXRhYmxlOzoxCOAHEixMYW5kcm9pZC92aWV3L3RleHRjbGFzc2lmaWVyL1RleHRDbGFzc2lmaWVyOzo1COEHEjBMYW5kcm9pZHgvYXBwY29tcGF0L3dpZGdldC9BcHBDb21wYXRJbWFnZUJ1dHRvbjs6HgjiBxIZTGFuZHJvaWQvZ3JhcGhpY3MvQml0bWFwOzoWCOMHEhFMYW5kcm9pZC9uZXQvVXJpOzozCOQHEi5MYW5kcm9pZHgvYXBwY29tcGF0L3dpZGdldC9BcHBDb21wYXRJbWFnZVZpZXc7OkMI5QcSPkxhbmRyb2lkeC9hcHBjb21wYXQvd2lkZ2V0L0FwcENvbXBhdE11bHRpQXV0b0NvbXBsZXRlVGV4dFZpZXc7OjUI5gcSMExhbmRyb2lkeC9hcHBjb21wYXQvd2lkZ2V0L0FwcENvbXBhdFJhZGlvQnV0dG9uOzoxCOcHEixMYW5kcm9pZHgvYXBwY29tcGF0L3dpZGdldC9BcHBDb21wYXRTcGlubmVyOzo+COgHEjlMYW5kcm9pZHgvYXBwY29tcGF0L3dpZGdldC9BcHBDb21wYXRTcGlubmVyJFNwaW5uZXJQb3B1cDs6HQjpBxIYTGFuZHJvaWQvd2lkZ2V0L0FkYXB0ZXI7OiQI6gcSH0xhbmRyb2lkL3dpZGdldC9TcGlubmVyQWRhcHRlcjs6MgjrBxItTGFuZHJvaWR4L2FwcGNvbXBhdC93aWRnZXQvQXBwQ29tcGF0VGV4dFZpZXc7Oj4I7AcSOUxhbmRyb2lkeC9hcHBjb21wYXQvd2lkZ2V0L0FwcENvbXBhdFRleHRWaWV3JFN1cGVyQ2FsbGVyOzo2CO0HEjFMYW5kcm9pZHgvY29yZS90ZXh0L1ByZWNvbXB1dGVkVGV4dENvbXBhdCRQYXJhbXM7Oi8I7gcSKkxhbmRyb2lkeC9jb3JlL3RleHQvUHJlY29tcHV0ZWRUZXh0Q29tcGF0Ozo2CO8HEjFMYW5kcm9pZHgvYXBwY29tcGF0L3dpZGdldC9BcHBDb21wYXRUb2dnbGVCdXR0b247OjAI8AcSK0xhbmRyb2lkeC9hcHBjb21wYXQvd2lkZ2V0L0J1dHRvbkJhckxheW91dDs6MwjxBxIuTGFuZHJvaWR4L2FwcGNvbXBhdC93aWRnZXQvQ29udGVudEZyYW1lTGF5b3V0OzoeCPIHEhlMYW5kcm9pZC91dGlsL1R5cGVkVmFsdWU7OkQI8wcSP0xhbmRyb2lkeC9hcHBjb21wYXQvd2lkZ2V0L0NvbnRlbnRGcmFtZUxheW91dCRPbkF0dGFjaExpc3RlbmVyOzoxCPQHEixMYW5kcm9pZHgvYXBwY29tcGF0L3dpZGdldC9Ecm9wRG93bkxpc3RWaWV3Ozo2CPUHEjFMYW5kcm9pZHgvYXBwY29tcGF0L3dpZGdldC9GaXRXaW5kb3dzRnJhbWVMYXlvdXQ7Ok8I9gcSSkxhbmRyb2lkeC9hcHBjb21wYXQvd2lkZ2V0L0ZpdFdpbmRvd3NWaWV3R3JvdXAkT25GaXRTeXN0ZW1XaW5kb3dzTGlzdGVuZXI7OjcI9wcSMkxhbmRyb2lkeC9hcHBjb21wYXQvd2lkZ2V0L0ZpdFdpbmRvd3NMaW5lYXJMYXlvdXQ7OjMI+AcSLkxhbmRyb2lkeC9hcHBjb21wYXQvd2lkZ2V0L0xpbmVhckxheW91dENvbXBhdDs6RQj5BxJATGFuZHJvaWR4L2FwcGNvbXBhdC93aWRnZXQvTWVudVBvcHVwV2luZG93JE1lbnVEcm9wRG93bkxpc3RWaWV3Ozo2CPoHEjFMYW5kcm9pZHgvYXBwY29tcGF0L3dpZGdldC9NZW51SXRlbUhvdmVyTGlzdGVuZXI7Oj4I+wcSOUxhbmRyb2lkeC9hcHBjb21wYXQvd2lkZ2V0L1NlYXJjaFZpZXckU2VhcmNoQXV0b0NvbXBsZXRlOzorCPwHEiZMYW5kcm9pZHgvYXBwY29tcGF0L3dpZGdldC9TZWFyY2hWaWV3OzooCP0HEiNMYW5kcm9pZHgvYXBwY29tcGF0L3dpZGdldC9Ub29sYmFyOzoaCP4HEhVMamF2YS91dGlsL0FycmF5TGlzdDs6IAj/BxIbTGFuZHJvaWQvdmlldy9NZW51SW5mbGF0ZXI7Oi0IgAgSKExhbmRyb2lkeC9hcHBjb21wYXQvd2lkZ2V0L0RlY29yVG9vbGJhcjs6KAiBCBIjTGFuZHJvaWQvdmlldy9WaWV3JE9uQ2xpY2tMaXN0ZW5lcjs6QAiCCBI7TGFuZHJvaWR4L2FwcGNvbXBhdC93aWRnZXQvVG9vbGJhciRPbk1lbnVJdGVtQ2xpY2tMaXN0ZW5lcjs6LwiDCBIqTGFuZHJvaWR4L2FwcGNvbXBhdC93aWRnZXQvVmlld1N0dWJDb21wYXQ7OkEIhAgSPExhbmRyb2lkeC9hcHBjb21wYXQvd2lkZ2V0L1ZpZXdTdHViQ29tcGF0JE9uSW5mbGF0ZUxpc3RlbmVyOzo2CIUIEjFMYW5kcm9pZHgvY29tcG9zZS9tYXRlcmlhbC9yaXBwbGUvUmlwcGxlSG9zdFZpZXc7OjMIhggSLkxhbmRyb2lkeC9jb21wb3NlL3VpL2dyYXBoaWNzL2xheWVyL1ZpZXdMYXllcjs6MAiHCBIrTGFuZHJvaWR4L2NvbXBvc2UvdWkvZ3JhcGhpY3MvQ2FudmFzSG9sZGVyOzpBCIgIEjxMYW5kcm9pZHgvY29tcG9zZS91aS9ncmFwaGljcy9sYXllci92aWV3L0RyYXdDaGlsZENvbnRhaW5lcjs6NwiJCBIyTGFuZHJvaWR4L2NvbXBvc2UvdWkvcGxhdGZvcm0vQWJzdHJhY3RDb21wb3NlVmlldzs6MgiKCBItTGFuZHJvaWR4L2NvbXBvc2UvcnVudGltZS9Db21wb3NpdGlvbkNvbnRleHQ7OjsIiwgSNkxhbmRyb2lkeC9jb21wb3NlL3VpL3BsYXRmb3JtL1ZpZXdDb21wb3NpdGlvblN0cmF0ZWd5Ozo4CIwIEjNMYW5kcm9pZHgvY29tcG9zZS91aS9wbGF0Zm9ybS9BY2Nlc3NpYmlsaXR5TWFuYWdlcjs6PwiNCBI6TGFuZHJvaWR4L2NvbXBvc2UvdWkvcGxhdGZvcm0vQW5kcm9pZEFjY2Vzc2liaWxpdHlNYW5hZ2VyOzo3CI4IEjJMYW5kcm9pZHgvY29tcG9zZS91aS9wbGF0Zm9ybS9BbmRyb2lkVmlld3NIYW5kbGVyOzosCI8IEidMYW5kcm9pZHgvY29tcG9zZS91aS9hdXRvZmlsbC9BdXRvZmlsbDs6MwiQCBIuTGFuZHJvaWR4L2NvbXBvc2UvdWkvYXV0b2ZpbGwvQXV0b2ZpbGxNYW5hZ2VyOzowCJEIEitMYW5kcm9pZHgvY29tcG9zZS91aS9hdXRvZmlsbC9BdXRvZmlsbFRyZWU7OjQIkggSL0xhbmRyb2lkeC9jb21wb3NlL3VpL3BsYXRmb3JtL0FuZHJvaWRDbGlwYm9hcmQ7Oi0IkwgSKExhbmRyb2lkeC9jb21wb3NlL3VpL3BsYXRmb3JtL0NsaXBib2FyZDs6OwiUCBI2TGFuZHJvaWR4L2NvbXBvc2UvdWkvcGxhdGZvcm0vQW5kcm9pZENsaXBib2FyZE1hbmFnZXI7OjQIlQgSL0xhbmRyb2lkeC9jb21wb3NlL3VpL3BsYXRmb3JtL0NsaXBib2FyZE1hbmFnZXI7OigIlggSI0xhbmRyb2lkL2NvbnRlbnQvcmVzL0NvbmZpZ3VyYXRpb247OkYIlwgSQUxhbmRyb2lkeC9jb21wb3NlL3VpL2NvbnRlbnRjYXB0dXJlL0FuZHJvaWRDb250ZW50Q2FwdHVyZU1hbmFnZXI7OikImAgSJExrb3RsaW4vY29yb3V0aW5lcy9Db3JvdXRpbmVDb250ZXh0OzonCJkIEiJMYW5kcm9pZHgvY29tcG9zZS91aS91bml0L0RlbnNpdHk7OkAImggSO0xhbmRyb2lkeC9jb21wb3NlL3VpL2RyYWdhbmRkcm9wL0FuZHJvaWREcmFnQW5kRHJvcE1hbmFnZXI7OjkImwgSNExhbmRyb2lkeC9jb21wb3NlL3VpL2RyYWdhbmRkcm9wL0RyYWdBbmREcm9wTWFuYWdlcjs6KAicCBIjTGFuZHJvaWR4L2NvbXBvc2UvdWkvZ2VvbWV0cnkvUmVjdDs6KwidCBImTGFuZHJvaWR4L2NvbXBvc2UvdWkvZm9jdXMvRm9jdXNPd25lcjs6OAieCBIzTGFuZHJvaWR4L2NvbXBvc2UvdWkvdGV4dC9mb250L0ZvbnRGYW1pbHkkUmVzb2x2ZXI7OjgInwgSM0xhbmRyb2lkeC9jb21wb3NlL3VpL3RleHQvZm9udC9Gb250JFJlc291cmNlTG9hZGVyOzpXCKAIElJMYW5kcm9pZHgvY29tcG9zZS91aS9wbGF0Zm9ybS9MaWZlY3ljbGVSZXRhaW5lZFZhbHVlc1N0b3JlT3duZXIkRnJhbWVFbmRTY2hlZHVsZXI7OjMIoQgSLkxhbmRyb2lkeC9jb21wb3NlL3VpL2dyYXBoaWNzL0dyYXBoaWNzQ29udGV4dDs6OAiiCBIzTGFuZHJvaWR4L2NvbXBvc2UvdWkvaGFwdGljZmVlZGJhY2svSGFwdGljRmVlZGJhY2s7OjEIowgSLExhbmRyb2lkeC9jb21wb3NlL3VpL2lucHV0L0lucHV0TW9kZU1hbmFnZXI7OjAIpAgSK0xhbmRyb2lkeC9jb21wb3NlL3VpL2xheW91dC9JbnNldHNMaXN0ZW5lcjs6JwilCBIiTGFuZHJvaWR4L2NvbGxlY3Rpb24vSW50T2JqZWN0TWFwOzouCKYIEilMYW5kcm9pZHgvY29sbGVjdGlvbi9NdXRhYmxlSW50T2JqZWN0TWFwOzo4CKcIEjNMYW5kcm9pZHgvY29tcG9zZS91aS9tb2RpZmllci9Nb2RpZmllckxvY2FsTWFuYWdlcjs6MgioCBItTGFuZHJvaWR4L2NvbXBvc2UvdWkvbm9kZS9PdXRPZkZyYW1lRXhlY3V0b3I7OjoIqQgSNUxhbmRyb2lkeC9jb21wb3NlL3VpL2xheW91dC9QbGFjZWFibGUkUGxhY2VtZW50U2NvcGU7OjsIqggSNkxhbmRyb2lkeC9jb21wb3NlL3VpL2lucHV0L3BvaW50ZXIvUG9pbnRlckljb25TZXJ2aWNlOzpaCKsIElVMYW5kcm9pZHgvY29tcG9zZS91aS9pbnB1dC9pbmRpcmVjdC9JbmRpcmVjdFBvaW50ZXJFdmVudFByaW1hcnlEaXJlY3Rpb25hbE1vdGlvbkF4aXM7Oi4IrAgSKUxhbmRyb2lkeC9jb21wb3NlL3VpL3NwYXRpYWwvUmVjdE1hbmFnZXI7OjoIrQgSNUxhbmRyb2lkeC9jb21wb3NlL3J1bnRpbWUvcmV0YWluL1JldGFpbmVkVmFsdWVzU3RvcmU7OioIrggSJUxhbmRyb2lkeC9jb21wb3NlL3VpL25vZGUvTGF5b3V0Tm9kZTs6KwivCBImTGFuZHJvaWR4L2NvbXBvc2UvdWkvbm9kZS9Sb290Rm9yVGVzdDs6MwiwCBIuTGFuZHJvaWR4L2NvbXBvc2UvdWkvc2VtYW50aWNzL1NlbWFudGljc093bmVyOzozCLEIEi5MYW5kcm9pZHgvY29tcG9zZS91aS9ub2RlL0xheW91dE5vZGVEcmF3U2NvcGU7OjUIsggSMExhbmRyb2lkeC9jb21wb3NlL3VpL25vZGUvT3duZXJTbmFwc2hvdE9ic2VydmVyOzo+CLMIEjlMYW5kcm9pZHgvY29tcG9zZS91aS9wbGF0Zm9ybS9Tb2Z0d2FyZUtleWJvYXJkQ29udHJvbGxlcjs6Ngi0CBIxTGFuZHJvaWR4L2NvbXBvc2UvdWkvdGV4dC9pbnB1dC9UZXh0SW5wdXRTZXJ2aWNlOzovCLUIEipMYW5kcm9pZHgvY29tcG9zZS91aS9wbGF0Zm9ybS9UZXh0VG9vbGJhcjs6RAi2CBI/TGFuZHJvaWR4L2NvbXBvc2UvdWkvbm9kZS9Sb290Rm9yVGVzdCRVbmNhdWdodEV4Y2VwdGlvbkhhbmRsZXI7OjUItwgSMExhbmRyb2lkeC9jb21wb3NlL3VpL3BsYXRmb3JtL1ZpZXdDb25maWd1cmF0aW9uOzpFCLgIEkBMYW5kcm9pZHgvY29tcG9zZS91aS9wbGF0Zm9ybS9BbmRyb2lkQ29tcG9zZVZpZXckVmlld1RyZWVPd25lcnM7Oi4IuQgSKUxhbmRyb2lkeC9jb21wb3NlL3VpL3BsYXRmb3JtL1dpbmRvd0luZm87OjoIuggSNUxhbmRyb2lkeC9jb21wb3NlL3VpL2F1dG9maWxsL0FuZHJvaWRBdXRvZmlsbE1hbmFnZXI7OiUIuwgSIExrb3RsaW4vanZtL2Z1bmN0aW9ucy9GdW5jdGlvbjE7OhgIvAgSE0xqYXZhL3V0aWwvSGFzaE1hcDs6Lwi9CBIqTGFuZHJvaWR4L2NvbXBvc2UvdWkvcGxhdGZvcm0vQ29tcG9zZVZpZXc7OiUIvggSIExrb3RsaW4vanZtL2Z1bmN0aW9ucy9GdW5jdGlvbjI7Oi0IvwgSKExhbmRyb2lkeC9jb21wb3NlL3VpL3dpbmRvdy9Qb3B1cExheW91dDs6LgjACBIpTGFuZHJvaWQvdmlldy9XaW5kb3dNYW5hZ2VyJExheW91dFBhcmFtczs6MwjBCBIuTGFuZHJvaWR4L2NvbXBvc2UvdWkvbGF5b3V0L0xheW91dENvb3JkaW5hdGVzOzonCMIIEiJMYW5kcm9pZHgvY29tcG9zZS91aS91bml0L0ludFNpemU7OjcIwwgSMkxhbmRyb2lkeC9jb21wb3NlL3VpL3dpbmRvdy9Qb3B1cFBvc2l0aW9uUHJvdmlkZXI7OicIxAgSIkxhbmRyb2lkeC9jb21wb3NlL3VpL3VuaXQvSW50UmVjdDs6MQjFCBIsTGFuZHJvaWR4L2NvcmUvdmlldy9pbnNldHMvUHJvdGVjdGlvbkxheW91dDs6NgjGCBIxTGFuZHJvaWR4L2NvcmUvdmlldy9pbnNldHMvU3lzdGVtQmFyU3RhdGVNb25pdG9yOzosCMcIEidMYW5kcm9pZHgvY29yZS93aWRnZXQvTmVzdGVkU2Nyb2xsVmlldzs6NgjICBIxTGFuZHJvaWR4L2NvcmUvdmlldy9TY3JvbGxGZWVkYmFja1Byb3ZpZGVyQ29tcGF0OzpDCMkIEj5MYW5kcm9pZHgvY29yZS93aWRnZXQvTmVzdGVkU2Nyb2xsVmlldyRPblNjcm9sbENoYW5nZUxpc3RlbmVyOzoyCMoIEi1MYW5kcm9pZHgvZnJhZ21lbnQvYXBwL0ZyYWdtZW50Q29udGFpbmVyVmlldzs6JQjLCBIgTGFuZHJvaWR4L2ZyYWdtZW50L2FwcC9GcmFnbWVudDs6KQjMCBIkTGFuZHJvaWQvYW5pbWF0aW9uL0xheW91dFRyYW5zaXRpb247OjQIzQgSL0xhbmRyb2lkL3ZpZXcvVmlldyRPbkFwcGx5V2luZG93SW5zZXRzTGlzdGVuZXI7OiQIzggSH0xhbmRyb2lkeC93b3JrL0Nvcm91dGluZVdvcmtlcjs6GwjPCBIWTGFuZHJvaWR4L3dvcmsvV29ya2VyOzo6CNAIEjVMYW5kcm9pZHgvd29yay9pbXBsL3dvcmtlcnMvQ29uc3RyYWludFRyYWNraW5nV29ya2VyOzozCNEIEi5MYW5kcm9pZHgvd29yay9pbXBsL3dvcmtlcnMvRGlhZ25vc3RpY3NXb3JrZXI7OkkI0ggSRExjb20vZ29vZ2xlL3NhbXBsZXMvYXBwcy9ub3dpbmFuZHJvaWQvc3luYy93b3JrZXJzL0RlbGVnYXRpbmdXb3JrZXI7OkMI0wgSPkxjb20vZ29vZ2xlL3NhbXBsZXMvYXBwcy9ub3dpbmFuZHJvaWQvc3luYy93b3JrZXJzL1N5bmNXb3JrZXI7OlMI1AgSTkxjb20vZ29vZ2xlL3NhbXBsZXMvYXBwcy9ub3dpbmFuZHJvaWQvY29yZS9kYXRhc3RvcmUvTmlhUHJlZmVyZW5jZXNEYXRhU291cmNlOzpRCNUIEkxMY29tL2dvb2dsZS9zYW1wbGVzL2FwcHMvbm93aW5hbmRyb2lkL2NvcmUvZGF0YS9yZXBvc2l0b3J5L1RvcGljc1JlcG9zaXRvcnk7Ok8I1ggSSkxjb20vZ29vZ2xlL3NhbXBsZXMvYXBwcy9ub3dpbmFuZHJvaWQvY29yZS9kYXRhL3JlcG9zaXRvcnkvTmV3c1JlcG9zaXRvcnk7OlkI1wgSVExjb20vZ29vZ2xlL3NhbXBsZXMvYXBwcy9ub3dpbmFuZHJvaWQvY29yZS9kYXRhL3JlcG9zaXRvcnkvU2VhcmNoQ29udGVudHNSZXBvc2l0b3J5OzotCNgIEihMa290bGlueC9jb3JvdXRpbmVzL0Nvcm91dGluZURpc3BhdGNoZXI7OkoI2QgSRUxjb20vZ29vZ2xlL3NhbXBsZXMvYXBwcy9ub3dpbmFuZHJvaWQvY29yZS9hbmFseXRpY3MvQW5hbHl0aWNzSGVscGVyOzpGCNoIEkFMY29tL2dvb2dsZS9zYW1wbGVzL2FwcHMvbm93aW5hbmRyb2lkL3N5bmMvc3RhdHVzL1N5bmNTdWJzY3JpYmVyOzprCNsIEmZMYW5kcm9pZHgvc2F2ZWRzdGF0ZS9zZXJpYWxpemF0aW9uL3NlcmlhbGl6ZXJzL1NwYXJzZUFycmF5U2VyaWFsaXplciRTcGFyc2VBcnJheVN1cnJvZ2F0ZSQkc2VyaWFsaXplcjs6OQjcCBI0TGtvdGxpbngvc2VyaWFsaXphdGlvbi9kZXNjcmlwdG9ycy9TZXJpYWxEZXNjcmlwdG9yOzpcCN0IEldMY29tL2dvb2dsZS9zYW1wbGVzL2FwcHMvbm93aW5hbmRyb2lkL2NvcmUvbmV0d29yay9tb2RlbC9OZXR3b3JrQ2hhbmdlTGlzdCQkc2VyaWFsaXplcjs6XgjeCBJZTGNvbS9nb29nbGUvc2FtcGxlcy9hcHBzL25vd2luYW5kcm9pZC9jb3JlL25ldHdvcmsvbW9kZWwvTmV0d29ya05ld3NSZXNvdXJjZSQkc2VyaWFsaXplcjs6VwjfCBJSTGNvbS9nb29nbGUvc2FtcGxlcy9hcHBzL25vd2luYW5kcm9pZC9jb3JlL25ldHdvcmsvbW9kZWwvTmV0d29ya1RvcGljJCRzZXJpYWxpemVyOzpdCOAIElhMY29tL2dvb2dsZS9zYW1wbGVzL2FwcHMvbm93aW5hbmRyb2lkL2NvcmUvbmV0d29yay9yZXRyb2ZpdC9OZXR3b3JrUmVzcG9uc2UkJHNlcmlhbGl6ZXI7OmgI4QgSY0xjb20vZ29vZ2xlL3NhbXBsZXMvYXBwcy9ub3dpbmFuZHJvaWQvZmVhdHVyZS9pbnRlcmVzdHMvYXBpL25hdmlnYXRpb24vSW50ZXJlc3RzTmF2S2V5JCRzZXJpYWxpemVyOzpgCOIIEltMY29tL2dvb2dsZS9zYW1wbGVzL2FwcHMvbm93aW5hbmRyb2lkL2ZlYXR1cmUvdG9waWMvYXBpL25hdmlnYXRpb24vVG9waWNOYXZLZXkkJHNlcmlhbGl6ZXI7OkUI4wgSQExhbmRyb2lkeC9jb21wb3NlL3VpL3BsYXRmb3JtL0xpZmVjeWNsZVJldGFpbmVkVmFsdWVzU3RvcmVPd25lcjs6LQjkCBIoTGFuZHJvaWR4L2xpZmVjeWNsZS9TYXZlZFN0YXRlSGFuZGxlc1ZNOzo+COUIEjlMYW5kcm9pZHgvbGlmZWN5Y2xlL3ZpZXdtb2RlbC9uYXZpZ2F0aW9uMy9FbnRyeVZpZXdNb2RlbDs6PAjmCBI3TGFuZHJvaWR4L2xvYWRlci9hcHAvTG9hZGVyTWFuYWdlckltcGwkTG9hZGVyVmlld01vZGVsOzpHCOcIEkJMYW5kcm9pZHgvbGlmZWN5Y2xlL0xlZ2FjeVNhdmVkU3RhdGVIYW5kbGVDb250cm9sbGVyJE9uUmVjcmVhdGlvbjs6KAjoCBIjTGFuZHJvaWR4L2FjdGl2aXR5L0VkZ2VUb0VkZ2VBcGkyMzs6JwjpCBIiTGFuZHJvaWR4L2FjdGl2aXR5L1N5c3RlbUJhclN0eWxlOzoaCOoIEhVMYW5kcm9pZC92aWV3L1dpbmRvdzs6KAjrCBIjTGFuZHJvaWR4L2FjdGl2aXR5L0VkZ2VUb0VkZ2VBcGkyNjs6KAjsCBIjTGFuZHJvaWR4L2FjdGl2aXR5L0VkZ2VUb0VkZ2VBcGkyODs6KAjtCBIjTGFuZHJvaWR4L2FjdGl2aXR5L0VkZ2VUb0VkZ2VBcGkyOTs6KAjuCBIjTGFuZHJvaWR4L2FjdGl2aXR5L0VkZ2VUb0VkZ2VBcGkzMDs6KAjvCBIjTGFuZHJvaWR4L2FjdGl2aXR5L0VkZ2VUb0VkZ2VBcGkzNTs6OQjwCBI0TGFuZHJvaWR4L2FwcGNvbXBhdC9hcHAvQXBwQ29tcGF0RGVsZWdhdGUkQXBpMjRJbXBsOzocCPEIEhdMYW5kcm9pZC9vcy9Mb2NhbGVMaXN0Ozo5CPIIEjRMYW5kcm9pZHgvYXBwY29tcGF0L2FwcC9BcHBDb21wYXREZWxlZ2F0ZSRBcGkzM0ltcGw7Oj0I8wgSOExhbmRyb2lkeC9hcHBjb21wYXQvYXBwL0FwcENvbXBhdERlbGVnYXRlSW1wbCRBcGkyMUltcGw7Oh4I9AgSGUxhbmRyb2lkL29zL1Bvd2VyTWFuYWdlcjs6Fwj1CBISTGphdmEvdXRpbC9Mb2NhbGU7Oj0I9ggSOExhbmRyb2lkeC9hcHBjb21wYXQvYXBwL0FwcENvbXBhdERlbGVnYXRlSW1wbCRBcGkyNEltcGw7OigI9wgSI0xhbmRyb2lkeC9jb3JlL29zL0xvY2FsZUxpc3RDb21wYXQ7Oj0I+AgSOExhbmRyb2lkeC9hcHBjb21wYXQvYXBwL0FwcENvbXBhdERlbGVnYXRlSW1wbCRBcGkzM0ltcGw7Oi0I+QgSKExhbmRyb2lkL3dpbmRvdy9PbkJhY2tJbnZva2VkRGlzcGF0Y2hlcjs6Mwj6CBIuTGFuZHJvaWR4L2FwcGNvbXBhdC9hcHAvQXBwQ29tcGF0RGVsZWdhdGVJbXBsOzorCPsIEiZMYW5kcm9pZC93aW5kb3cvT25CYWNrSW52b2tlZENhbGxiYWNrOzpHCPwIEkJMYW5kcm9pZHgvYXBwY29tcGF0L2FwcC9BcHBMb2NhbGVzTWV0YWRhdGFIb2xkZXJTZXJ2aWNlJEFwaTI0SW1wbDs6Owj9CBI2TGFuZHJvaWR4L2FwcGNvbXBhdC9yZXNvdXJjZXMvQ29tcGF0aWJpbGl0eSRBcGkyMUltcGw7OiQI/ggSH0xhbmRyb2lkL2NvbnRlbnQvcmVzL1Jlc291cmNlczs6Iwj/CBIeTG9yZy94bWxwdWxsL3YxL1htbFB1bGxQYXJzZXI7OioIgAkSJUxhbmRyb2lkL2NvbnRlbnQvcmVzL1Jlc291cmNlcyRUaGVtZTs6PgiBCRI5TGFuZHJvaWR4L2FwcGNvbXBhdC92aWV3L1dpbmRvd0NhbGxiYWNrV3JhcHBlciRBcGkyM0ltcGw7Oh8IggkSGkxhbmRyb2lkL3ZpZXcvU2VhcmNoRXZlbnQ7Oh4IgwkSGUxhbmRyb2lkL3ZpZXcvQWN0aW9uTW9kZTs6PgiECRI5TGFuZHJvaWR4L2FwcGNvbXBhdC92aWV3L1dpbmRvd0NhbGxiYWNrV3JhcHBlciRBcGkyNEltcGw7Oj4IhQkSOUxhbmRyb2lkeC9hcHBjb21wYXQvdmlldy9XaW5kb3dDYWxsYmFja1dyYXBwZXIkQXBpMjZJbXBsOzpOCIYJEklMYW5kcm9pZHgvYXBwY29tcGF0L3dpZGdldC9BcHBDb21wYXRSZWNlaXZlQ29udGVudEhlbHBlciRPbkRyb3BBcGkyNEltcGw7Oh0IhwkSGExhbmRyb2lkL3ZpZXcvRHJhZ0V2ZW50Ozo7CIgJEjZMYW5kcm9pZHgvYXBwY29tcGF0L3dpZGdldC9BcHBDb21wYXRTcGlubmVyJEFwaTIzSW1wbDs6KgiJCRIlTGFuZHJvaWQvd2lkZ2V0L1RoZW1lZFNwaW5uZXJBZGFwdGVyOzpICIoJEkNMYW5kcm9pZHgvYXBwY29tcGF0L3dpZGdldC9BcHBDb21wYXRUZXh0Q2xhc3NpZmllckhlbHBlciRBcGkyNkltcGw7Oj4IiwkSOUxhbmRyb2lkeC9hcHBjb21wYXQvd2lkZ2V0L0FwcENvbXBhdFRleHRIZWxwZXIkQXBpMjFJbXBsOzo+CIwJEjlMYW5kcm9pZHgvYXBwY29tcGF0L3dpZGdldC9BcHBDb21wYXRUZXh0SGVscGVyJEFwaTI0SW1wbDs6PgiNCRI5TGFuZHJvaWR4L2FwcGNvbXBhdC93aWRnZXQvQXBwQ29tcGF0VGV4dEhlbHBlciRBcGkyNkltcGw7Oj4IjgkSOUxhbmRyb2lkeC9hcHBjb21wYXQvd2lkZ2V0L0FwcENvbXBhdFRleHRIZWxwZXIkQXBpMjhJbXBsOzogCI8JEhtMYW5kcm9pZC9ncmFwaGljcy9UeXBlZmFjZTs6SgiQCRJFTGFuZHJvaWR4L2FwcGNvbXBhdC93aWRnZXQvQXBwQ29tcGF0VGV4dFZpZXdBdXRvU2l6ZUhlbHBlciRBcGkyM0ltcGw7OiQIkQkSH0xhbmRyb2lkL3RleHQvTGF5b3V0JEFsaWdubWVudDs6HQiSCRIYTGFuZHJvaWQvdGV4dC9UZXh0UGFpbnQ7OiAIkwkSG0xhbmRyb2lkL3RleHQvU3RhdGljTGF5b3V0Ozo7CJQJEjZMYW5kcm9pZHgvYXBwY29tcGF0L3dpZGdldC9Ecm9wRG93bkxpc3RWaWV3JEFwaTIxSW1wbDs6OwiVCRI2TGFuZHJvaWR4L2FwcGNvbXBhdC93aWRnZXQvRHJvcERvd25MaXN0VmlldyRBcGkzM0ltcGw7OiEIlgkSHExhbmRyb2lkL3dpZGdldC9BYnNMaXN0Vmlldzs6OgiXCRI1TGFuZHJvaWR4L2FwcGNvbXBhdC93aWRnZXQvTGlzdFBvcHVwV2luZG93JEFwaTI0SW1wbDs6IQiYCRIcTGFuZHJvaWQvd2lkZ2V0L1BvcHVwV2luZG93Ozo6CJkJEjVMYW5kcm9pZHgvYXBwY29tcGF0L3dpZGdldC9MaXN0UG9wdXBXaW5kb3ckQXBpMjlJbXBsOzo6CJoJEjVMYW5kcm9pZHgvYXBwY29tcGF0L3dpZGdldC9NZW51UG9wdXBXaW5kb3ckQXBpMjNJbXBsOzokCJsJEh9MYW5kcm9pZC90cmFuc2l0aW9uL1RyYW5zaXRpb247OjoInAkSNUxhbmRyb2lkeC9hcHBjb21wYXQvd2lkZ2V0L01lbnVQb3B1cFdpbmRvdyRBcGkyOUltcGw7OjUInQkSMExhbmRyb2lkeC9hcHBjb21wYXQvd2lkZ2V0L1NlYXJjaFZpZXckQXBpMjlJbXBsOzoqCJ4JEiVMYW5kcm9pZC93aWRnZXQvQXV0b0NvbXBsZXRlVGV4dFZpZXc7OjIInwkSLUxhbmRyb2lkeC9hcHBjb21wYXQvd2lkZ2V0L1Rvb2xiYXIkQXBpMzNJbXBsOzoZCKAJEhRMamF2YS9sYW5nL1J1bm5hYmxlOzo4CKEJEjNMYW5kcm9pZHgvYXBwY29tcGF0L3dpZGdldC9Ub29sdGlwQ29tcGF0JEFwaTI2SW1wbDs6NAiiCRIvTGFuZHJvaWR4L2FwcGNvbXBhdC93aWRnZXQvVmlld1V0aWxzJEFwaTI5SW1wbDs6PQijCRI4TGFuZHJvaWR4L2Jyb3dzZXIvY3VzdG9tdGFicy9DdXN0b21UYWJzSW50ZW50JEFwaTIzSW1wbDs6IgikCRIdTGFuZHJvaWQvYXBwL0FjdGl2aXR5T3B0aW9uczs6PQilCRI4TGFuZHJvaWR4L2Jyb3dzZXIvY3VzdG9tdGFicy9DdXN0b21UYWJzSW50ZW50JEFwaTI0SW1wbDs6PQimCRI4TGFuZHJvaWR4L2Jyb3dzZXIvY3VzdG9tdGFicy9DdXN0b21UYWJzSW50ZW50JEFwaTM0SW1wbDs6SginCRJFTGFuZHJvaWR4L2NvbXBvc2UvdWkvcGxhdGZvcm0vQW5kcm9pZENvbXBvc2VWaWV3QXNzaXN0SGVscGVyTWV0aG9kc087OiEIqAkSHExhbmRyb2lkL3ZpZXcvVmlld1N0cnVjdHVyZTs6RAipCRI/TGFuZHJvaWR4L2NvbXBvc2UvdWkvcGxhdGZvcm0vQW5kcm9pZENvbXBvc2VWaWV3Rm9yY2VEYXJrTW9kZVE7OkcIqgkSQkxhbmRyb2lkeC9jb21wb3NlL3VpL3BsYXRmb3JtL0FuZHJvaWRDb21wb3NlVmlld1N0YXJ0RHJhZ0FuZERyb3BOOzo+CKsJEjlMYW5kcm9pZHgvY29tcG9zZS91aS9kcmFnYW5kZHJvcC9EcmFnQW5kRHJvcFRyYW5zZmVyRGF0YTs6PwisCRI6TGFuZHJvaWR4L2NvbXBvc2UvdWkvZHJhZ2FuZGRyb3AvQ29tcG9zZURyYWdTaGFkb3dCdWlsZGVyOzpKCK0JEkVMYW5kcm9pZHgvY29tcG9zZS91aS9wbGF0Zm9ybS9BbmRyb2lkQ29tcG9zZVZpZXdUcmFuc2xhdGlvbkNhbGxiYWNrUzs6UAiuCRJLTGFuZHJvaWR4L2NvbXBvc2UvdWkvcGxhdGZvcm0vQW5kcm9pZENvbXBvc2VWaWV3VmVyaWZpY2F0aW9uSGVscGVyTWV0aG9kc047OjQIrwkSL0xhbmRyb2lkeC9jb21wb3NlL3VpL2lucHV0L3BvaW50ZXIvUG9pbnRlckljb247OlAIsAkSS0xhbmRyb2lkeC9jb21wb3NlL3VpL3BsYXRmb3JtL0FuZHJvaWRDb21wb3NlVmlld1ZlcmlmaWNhdGlvbkhlbHBlck1ldGhvZHNPOzotCLEJEihMYW5kcm9pZHgvY29tcG9zZS91aS9wbGF0Zm9ybS9BcGkzMEltcGw7Oi0IsgkSKExhbmRyb2lkeC9jb21wb3NlL3VpL3BsYXRmb3JtL0FwaTM1SW1wbDs6QAizCRI7TGFuZHJvaWR4L2NvbXBvc2UvdWkvcGxhdGZvcm0vQ2FsY3VsYXRlTWF0cml4VG9XaW5kb3dBcGkyOTs6PAi0CRI3TGFuZHJvaWR4L2NvbXBvc2UvdWkvcGxhdGZvcm0vTW90aW9uRXZlbnRWZXJpZmllckFwaTI5OzofCLUJEhpMYW5kcm9pZC92aWV3L01vdGlvbkV2ZW50OzpECLYJEj9MYW5kcm9pZHgvY29tcG9zZS91aS90ZXh0L2ZvbnQvRm9udFdlaWdodEFkanVzdG1lbnRIZWxwZXJBcGkzMTs6Kwi3CRImTGFuZHJvaWR4L2NvbXBvc2UvdWkvd2luZG93L0FwaTIxSW1wbDs6Kwi4CRImTGFuZHJvaWR4L2NvbXBvc2UvdWkvd2luZG93L0FwaTI4SW1wbDs6Kwi5CRImTGFuZHJvaWR4L2NvbXBvc2UvdWkvd2luZG93L0FwaTMwSW1wbDs6PAi6CRI3TGFuZHJvaWR4L2Vtb2ppMi90ZXh0L0NvbmN1cnJlbmN5SGVscGVycyRIYW5kbGVyMjhJbXBsOzoYCLsJEhNMYW5kcm9pZC9vcy9Mb29wZXI7OhkIvAkSFExhbmRyb2lkL29zL0hhbmRsZXI7OkEIvQkSPExhbmRyb2lkeC9lbW9qaTIvdGV4dC9FbW9qaUV4Y2x1c2lvbnMkRW1vamlFeGNsdXNpb25zX0FwaTM0OzpACL4JEjtMYW5kcm9pZHgvZXhpZmludGVyZmFjZS9tZWRpYS9FeGlmSW50ZXJmYWNlVXRpbHMkQXBpMjFJbXBsOzodCL8JEhhMamF2YS9pby9GaWxlRGVzY3JpcHRvcjs6QAjACRI7TGFuZHJvaWR4L2V4aWZpbnRlcmZhY2UvbWVkaWEvRXhpZkludGVyZmFjZVV0aWxzJEFwaTIzSW1wbDs6KwjBCRImTGFuZHJvaWQvbWVkaWEvTWVkaWFNZXRhZGF0YVJldHJpZXZlcjs6JAjCCRIfTGFuZHJvaWQvbWVkaWEvTWVkaWFEYXRhU291cmNlOzpWCMMJElFMYW5kcm9pZHgvcHJpdmFjeXNhbmRib3gvYWRzL2Fkc2VydmljZXMvaW50ZXJuYWwvQWRTZXJ2aWNlc0luZm8kRXh0ZW5zaW9uczMwSW1wbDs6agjECRJlTGFuZHJvaWR4L3ByaXZhY3lzYW5kYm94L2Fkcy9hZHNlcnZpY2VzL2phdmEvbWVhc3VyZW1lbnQvTWVhc3VyZW1lbnRNYW5hZ2VyRnV0dXJlcyRBcGkzM0V4dDVKYXZhSW1wbDs6SQjFCRJETGFuZHJvaWR4L3ByaXZhY3lzYW5kYm94L2Fkcy9hZHNlcnZpY2VzL21lYXN1cmVtZW50L0RlbGV0aW9uUmVxdWVzdDs6OQjGCRI0TGNvbS9nb29nbGUvY29tbW9uL3V0aWwvY29uY3VycmVudC9MaXN0ZW5hYmxlRnV0dXJlOzoeCMcJEhlMYW5kcm9pZC92aWV3L0lucHV0RXZlbnQ7OlYIyAkSUUxhbmRyb2lkeC9wcml2YWN5c2FuZGJveC9hZHMvYWRzZXJ2aWNlcy9tZWFzdXJlbWVudC9XZWJTb3VyY2VSZWdpc3RyYXRpb25SZXF1ZXN0OzpXCMkJElJMYW5kcm9pZHgvcHJpdmFjeXNhbmRib3gvYWRzL2Fkc2VydmljZXMvbWVhc3VyZW1lbnQvV2ViVHJpZ2dlclJlZ2lzdHJhdGlvblJlcXVlc3Q7OloIygkSVUxhbmRyb2lkeC9wcml2YWN5c2FuZGJveC9hZHMvYWRzZXJ2aWNlcy9tZWFzdXJlbWVudC9NZWFzdXJlbWVudE1hbmFnZXIkQXBpMzNFeHQ1SW1wbDs6JgjLCRIhTGFuZHJvaWR4L3RyYWNpbmcvVHJhY2VBcGkyOUltcGw7OjYIzAkSMUxhbmRyb2lkeC9jb21wb3NlL2FuaW1hdGlvbi9jb3JlL1ByZWNvbmRpdGlvbnNLdDs6PwjNCRI6TGFuZHJvaWR4L2NvbXBvc2UvZm91bmRhdGlvbi9pbnRlcm5hbC9JbmxpbmVDbGFzc0hlbHBlckt0OzpGCM4JEkFMYW5kcm9pZHgvY29tcG9zZS9mb3VuZGF0aW9uL2xheW91dC9pbnRlcm5hbC9JbmxpbmVDbGFzc0hlbHBlckt0OzovCM8JEipMYW5kcm9pZHgvY29tcG9zZS9ydW50aW1lL1ByZWNvbmRpdGlvbnNLdDs6KwjQCRImTGFuZHJvaWR4L2NvbXBvc2UvcnVudGltZS9TbG90VGFibGVLdDs6OgjRCRI1TGFuZHJvaWR4L2NvbXBvc2UvcnVudGltZS9jb2xsZWN0aW9uL011dGFibGVWZWN0b3JLdDs6OwjSCRI2TGFuZHJvaWR4L2NvbXBvc2UvcnVudGltZS9yZXRhaW4vaW1wbC9QcmVjb25kaXRpb25zS3Q7OjkI0wkSNExhbmRyb2lkeC9jb21wb3NlL3VpL2dyYXBoaWNzL0FuZHJvaWRQYXRoX2FuZHJvaWRLdDs6NwjUCRIyTGFuZHJvaWR4L2NvbXBvc2UvdWkvZ3JhcGhpY3MvSW5saW5lQ2xhc3NIZWxwZXJLdDs6NwjVCRIyTGFuZHJvaWR4L2NvbXBvc2UvdWkvaW50ZXJuYWwvSW5saW5lQ2xhc3NIZWxwZXJLdDs6PAjWCRI3TGFuZHJvaWR4L2NvbXBvc2UvdWkvdGV4dC9pbnRlcm5hbC9JbmxpbmVDbGFzc0hlbHBlckt0OzotCNcJEihMYW5kcm9pZHgvY29tcG9zZS91aS91bml0L0NvbnN0cmFpbnRzS3Q7OhUI2AkSEExqYXZhL2xhbmcvVm9pZDs6MwjZCRIuTGFuZHJvaWR4L2NvbXBvc2UvdWkvdW5pdC9JbmxpbmVDbGFzc0hlbHBlckt0OzorCNoJEiZMYW5kcm9pZHgvY29tcG9zZS91aS91dGlsL0xpc3RVdGlsc0t0OzoqCNsJEiVMYW5kcm9pZHgvY29tcG9zZS9ydW50aW1lL0NvbXBvc2VyS3Q7OhgI3AkSE0xqYXZhL2xhbmcvSW50ZWdlcjs6VgjdCRJRTGNvbS9nb29nbGUvYW5kcm9pZC9nbXMvY29tbW9uL0dvb2dsZVBsYXlTZXJ2aWNlc0luY29ycmVjdE1hbmlmZXN0VmFsdWVFeGNlcHRpb247OkgI3gkSQ0xjb20vZ29vZ2xlL2FuZHJvaWQvZ21zL2NvbW1vbi9Hb29nbGVQbGF5U2VydmljZXNNYW5p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AukHQgcIlQESAuoHQgcIlgESAu4HQgYIlwESAVpCBwiYARIC7QdCBwiZARIC8wdCBwiaARIC9gdCBwibARIC+gdCBwicARIC/AdCBwidARICgQhCBwieARICgghCBwifARICygdCBwigARIChAhCBwihARIChQhCBwiiARICighCBwijARICiwhCBwikARIClghCBwilARIClwhCBwimARICmAhCBwinARICmQhCBwioARICnghCBwipARICoAhCBwiqARICuAVCBwirARICuwhCBwisARICqwhCBwitARICtghCBwiuARICuAhCBwivARICvghCBwiwARICwQhCBwixARICwghCBwiyARICwwhCBgizARIBZEIHCLQBEgLJCEIHCLUBEgLMCEIHCLYBEgLNCEIICLcBEgNwpQFCFgi4ARIRcKUB1AjVCNYI1wjYCNkI2ghCDwi5ARIK6QjpCOoIqgFPT0IHCLoBEgLqCEIICLsBEgNv8QhCBwi8ARIC9AhCBwi9ARIC9QhCCwi+ARIGlgiWCJYIQgcIvwESAvcIQgkIwAESBJYI9whCCAjBARIDb/oIQgcIwgESAm9vQg0IwwESCP4I/wjqAoAJQgcIxAESAusCQg8IxQESCsUH/gj/COoCgAlCCQjGARIE0AeCCUIKCMcBEgXQB9YHUUILCMgBEgbQB2TSB1FCCAjJARID0AdPQgsIygESBocJzQKuAUILCMsBEgaHCaoBrgFCCQjMARIEiQmACUIJCM0BEgTNAvEIQgsIzgESBs0CUVFRUUIKCM8BEgXNAukCUUIICNABEgPNAkhCCQjRARIEjwlRT0IRCNIBEgzUApEJUVHNApIJzwJCCwjTARIGqgGoAqgCQgcI1AESApYJQggI1QESA5YJT0ILCNYBEgaYCaoBUU9CCQjXARIEmAniAkIICNgBEgOYCU9CCQjZARIEmAmbCUIHCNoBEgKeCUIICNsBEgP7B1FCBwjcARICoAlCCwjdARIGqgHiAuICQggI3gESA6QJT0IJCN8BEgSoCaoBQgsI4AESBqoBqwmsCUIJCOEBEgSqAa8JQgkI4gESBKoBUU9CCQjjARIEqgGnAkIICOQBEgO1CVFCBwjlARICwAhCCAjmARIDwAhRQgcI5wESArsJQgcI6AESAr8JQgkI6QESBL8JUFFCCQjqARIEwQnCCUIHCOsBEgLFCUIJCOwBEgTjB8cJQgcI7QESAsgJQgcI7gESAskJQgkI7wESBMUJnwJCBwjwARICnwJCCwjxARIG4wfHCZ8CQgkI8gESBOMHnwJCCQjzARIEyAmfAkIJCPQBEgTJCZ8CQgcI9QESAq4IQggI9gESA2SfAkIJCPcBEgTcCZ8CQgkI+AESBOMJnwJKAyIBAEoJCAEQARgBIgEASgkIAhACGAIiAQBKCQgDEAMYAiIBAEoJCAQQBBgCIgEASgkIBRAFGAIiAQBKCQgGEAYYAyIBAEoJCAcQBxgEIgEASgkICBAIGAUiAQBKCQgJEAkYBiIBAEoJCAoQChgHIgEASgkICxALGAgiAQBKCQgMEAwYCCIBAEoJCA0QDRgIIgEASgkIDhAOGAgiAQBKCQgPEA8YCCIBAEoJCBAQEBgIIgEASgkIERARGAkiAQBKCQgSEBIYCSIBAEoJCBMQExgJIgEASgkIFBAUGAkiAQBKCQgVEBUYCSIBAEoJCBYQKRgMIgEESgkIFxAqGAwiAQRKCQgYEC8YAiIBBkoJCBkQMBgPIgEISgkIGhAxGBAiAQhKCQgbEDIYESIBCEoKCBwQMxgWIgIMDUoLCB0QNBgXIgMMDRhKCwgeEDUYGCIDDA0YSgwIHxA2GBkiBAwNGD5KCwggEDcYGiIDDA0YSgsIIRA4GBoiAwwNGEoLCCIQORgbIgMMDRhKCwgjEDoYHCIDDA0YSgsIJBA7GBciAwwNGEoLCCUQPBgdIgMMDRhKDAgmED0YHiIEDA0YPkoLCCcQPhgfIgMMDRhKDAgoED8YHyIEDA0YPkoKCCkQQBgfIgIMDUoLCCoQQRgfIgMMDRhKCggrEEIYHyICDA1KCggsEEMYHyICDA1KCwgtEEQYICIDDA0YSgsILhBFGCAiAwwNGEoLCC8QRhggIgMMDRhKCwgwEEcYISIDDA0YSgkIMRB/GBEiAQ5KCggyEIABGCQiAQ5KCggzEIEBGCQiAQ5KCwg0EI4BGCYiAhAmSgoINRCPARgRIgERSgoINhCQARgRIgESSgoINxCRARgnIgETSgoIOBCSARgnIgETSgoIORCTARgoIgETSgoIOhCUARgoIgETSgsIOxCVARgqIgIUcUoLCDwQlgEYKyICFHFKCwg9EJcBGCwiAhRxSgsIPhCYARgtIgIUcUoLCD8QmQEYLiICFHFKCwhAEJoBGCciAhRxSgoIQRCbARgxIgEWSgoIQhCcARgxIgEWSgoIQxCdARgyIgEWSgoIRBCeARgXIgEYSgoIRRCfARgXIgEYSgoIRhCgARgaIgEYSgoIRxChARgcIgEYSgoISBCiARgcIgEYSgoISRCjARgeIgEYSgoIShCkARgeIgEYSgoISxClARgnIgEaSgoITBCmARgRIgEbSgoITRCnARgMIgEcSgoIThCoARgMIgEcSgoITxCpARgMIgEcSgoIUBCvARgMIgEdSgoIURCwARgMIgEeSgoIUhCxARgMIgEfSgoIUxCyARgxIgEgSgoIVBCzARgxIgEgSgoIVRC1ARgxIgEhSgoIVhC2ARgxIgEhSgoIVxC3ARgyIgEiSgoIWBC4ARg3IgEnSgoIWRC5ARg4IgEnSgoIWhC6ARg4IgEnSgoIWxC7ARg4IgEnSgoIXBC8ARg4IgEnSgoIXRC9ARg4IgEnSgoIXhC+ARg4IgEnSgoIXxC/ARg4IgEnSgoIYBDAARg4IgEnSgoIYRDBARg6IgEqSgoIYhDCARg7IgEqSgoIYxDDARg3IgEqSgoIZBDEARg8IgErSgoIZRDFARg8IgErSgoIZhDGARg9IgErSgoIZxDHARg9IgErSgoIaBDIARg9IgErSgoIaRDJARg9IgErSgoIahDKARg9IgErSgoIaxDLARg9IgErSgoIbBDMARg9IgErSgoIbRDNARg9IgErSgoIbhDOARg9IgErSgoIbxDPARg9IgErSgoIcBDQARg9IgErSgoIcRDRARg9IgErSgoIchDSARg9IgErSgoIcxDTARg9IgErSgoIdBDUARg+IgErSgoIdRDVARg+IgErSgoIdhDWARg+IgErSgoIdxDXARg+IgErSgoIeBDYARg+IgErSgoIeRDZARg+IgErSgoIehDaARg+IgErSgoIexDbARg+IgErSgoIfBDcARg+IgErSgoIfRDdARg+IgErSgoIfhDeARg+IgErSgoIfxDfARg+IgErSgsIgAEQ4AEYPiIBK0oLCIEBEOEBGD4iAStKCwiCARDiARg+IgErSgsIgwEQ4wEYPiIBK0oLCIQBEOQBGD0iAStKCwiFARDlARg9IgErSgsIhgEQ5gEYPSIBK0oLCIcBEOcBGD0iAStKCwiIARDoARg9IgErSgsIiQEQ6QEYPSIBK0oLCIoBEOoBGD0iAStKCwiLARDrARg9IgErSgsIjAEQ7AEYPSIBK0oLCI0BEO0BGD0iAStKCwiOARDuARg9IgErSgsIjwEQ7wEYPSIBK0oLCJABEPABGD0iAStKCwiRARDxARg9IgErSgsIkgEQ8gEYPSIBK0oLCJMBEPMBGD0iAStKCwiUARD0ARg9IgErSgsIlQEQ9QEYPyIBK0oLCJYBEPYBGD8iAStKCwiXARD3ARhAIgErSgsImAEQ+AEYQCIBK0oLCJkBEPkBGEAiAStKCwiaARD6ARhAIgErSgsImwEQ+wEYQCIBK0oLCJwBEPwBGEAiAStKCwidARD9ARg/IgErSgsIngEQ/gEYPyIBK0oLCJ8BEP8BGEEiAStKCwigARCAAhhBIgErSgsIoQEQgQIYQSIBK0oLCKIBEIICGEEiAStKCwijARCDAhhBIgErSgsIpAEQhAIYQSIBK0oLCKUBEIUCGEEiAStKCwimARCGAhhBIgErSgsIpwEQhwIYQSIBK0oLCKgBEIgCGEEiAStKCwipARCJAhhBIgErSgsIqgEQigIYQSIBK0oLCKsBEIsCGEEiAStKCwisARCMAhhBIgErSgsIrQEQjQIYQSIBK0oLCK4BEI4CGEEiAStKCwivARCPAhhBIgErSgsIsAEQkAIYQSIBK0oLCLEBEJECGEEiAStKCwiyARCSAhhBIgErSgsIswEQkwIYQSIBK0oLCLQBEJQCGEEiAStKCwi1ARCVAhhBIgErSgsItgEQlgIYQSIBK0oLCLcBEJcCGEIiAStKCwi4ARCYAhhEIgEsSgsIuQEQmQIYRiIBLUoLCLoBEJoCGEgiAS5KCwi7ARCbAhhKIgEvSgsIvAEQnAIYTCIBMEoLCL0BEJ0CGE4iATFKCwi+ARCeAhhQIgEySgsIvwEQnwIYUiIBM0oLCMABEKACGFMiATRKCwjBARChAhgMIgE1SgsIwgEQowIYVCIBNkoMCMMBEKQCGFUiAjc/SgwIxAEQpQIYVSICNz9KCwjFARCmAhguIgE3SgsIxgEQqgIYVyIBPUoMCMcBEKsCGB8iAj0+SgsIyAEQrQIYESIBPkoLCMkBEK4CGFciAT5KCwjKARCvAhgZIgE+SgoIywEQahgeIgE+SgsIzAEQsAIYHyIBPkoLCM0BELECGB8iAT5KCwjOARCyAhgfIgE+SgsIzwEQswIYHyIBPkoLCNABELQCGCAiAT5KCwjRARDKAhhZIgFASgwI0gEQ0wgYNyICb3NKCwjTARDdCRgRIgFwSgsI1AEQ3gkYESIBcEoLCNUBEN8JGBEiAXBKCwjWARDgCRgQIgFwSgsI1wEQ4QkYECIBcEoLCNgBEJQDGCciAXJKCwjZARDOCBgnIgFzSgsI2gEQzwgYJyIBc0oLCNsBENAIGCciAXNKCwjcARDRCBgnIgFzSgsI3QEQ0ggYNyIBc0oLCN4BEOgDGBAiAXRKCwjfARDtAxgRIgF0SgsI4AEQ7gMYESIBdEoLCOEBEOIJGEEiAXVKDAjiARDkCRiGASIBdlIDIgEBUgkIARABGAEiAQFSCQgCEAIYAiIBAVIJCAMQAxgCIgEBUgkIBBAEGAIiAQFSCQgFEAUYAiIBAVIJCAYQBhgFIgEBUgkIBxAHGAciAQFSCQgIEAgYCCIBAVIJCAkQCRgIIgEBUgkIChAKGAgiAQFSCQgLEAsYCCIBAVIJCAwQDBgIIgEBUgkIDRANGAgiAQFSCQgOEA4YCSIBAVIJCA8QDxgJIgEBUgkIEBAQGAkiAQFSCQgREBEYCSIBAVIKCBIQEhgDIgICSFIKCBMQExgEIgICSFIKCBQQFBgGIgICSFIKCBUQFRgJIgICSFIJCBYQFhgYIgENUgkIFxAXGBoiAQ1SCQgYEBgYGiIBDVIJCBkQGRgbIgENUgkIGhAaGBwiAQ1SCQgbEBsYHiIBDVIJCBwQHBgfIgENUgkIHRAdGB8iAQ1SCQgeEB4YHyIBDVIJCB8QHxgfIgENUgkIIBAgGB8iAQ1SCQghECEYHyIBDVIJCCIQIhgfIgENUgkIIxAjGB8iAQ1SCQgkECQYHyIBDVIJCCUQJRgfIgENUgkIJhAmGB8iAQ1SCQgnECcYHyIBDVIJCCgQKBgfIgENUgkIKRApGB8iAQ1SCQgqECoYHyIBDVIJCCsQKxgfIgENUgkILBAsGB8iAQ1SCQgtEC0YHyIBDVIJCC4QLhgfIgENUgkILxAvGB8iAQ1SCQgwEDAYHyIBDVIJCDEQMRgfIgENUgkIMhAyGB8iAQ1SCQgzEDMYHyIBDVIJCDQQNBgfIgENUgkINRA1GB8iAQ1SCQg2EDYYHyIBDVIJCDcQNxgfIgENUgkIOBA4GB8iAQ1SCQg5EDkYHyIBDVIJCDoQOhgfIgENUgkIOxA7GB8iAQ1SCQg8EDwYHyIBDVIJCD0QPRgfIgENUgkIPhA+GB8iAQ1SCQg/ED8YHyIBDVIJCEAQQBgfIgENUgkIQRBBGB8iAQ1SCQhCEEIYHyIBDVIJCEMQQxgfIgENUgkIRBBEGB8iAQ1SCQhFEEUYICIBDVIJCEYQRhghIgENUgkIRxBHGCEiAQ1SCQhIEEgYISIBDVIJCEkQSRghIgENUgkIShBKGCEiAQ1SCQhLEEsYISIBDVIJCEwQTBghIgENUgkITRBNGCEiAQ1SCQhOEE4YISIBDVIJCE8QTxgRIgEOUgkIUBBQGCQiAQ5SCQhREFEYJCIBDlIJCFIQUhhXIgE9UgkIUxBTGFciAT1SCQhUEFQYVyIBPVIJCFUQVRhXIgE9UgkIVhBWGFciAT1SCQhXEFcYVyIBPVIJCFgQWBhXIgE9UgkIWRBZGFciAT1SCQhaEFoYVyIBPVIJCFsQWxhXIgE9UgkIXBBcGFciAT1SCQhdEF0YVyIBPVIJCF4QXhhXIgE9UgkIXxBfGFciAT1SCQhgEGAYVyIBPVIJCGEQYRhXIgE9UgsIYhBiGB8iAz1PUFIJCGMQYxheIgFKUgkIZBBkGF4iAUpSCQhlEGUYXiIBSlIJCGYQZhheIgFKUgkIZxBnGF4iAUpSCQhoEGgYXiIBSlIJCGkQaRheIgFKUgkIahBqGF4iAUpSCQhrEGsYXiIBSlIJCGwQbBheIgFKUgkIbRBtGF4iAUpSCQhuEG4YXiIBSlIJCG8QbxheIgFKUgkIcBBwGF4iAUpSCQhxEHEYXiIBSlIJCHIQchheIgFKUgkIcxBzGF4iAUpSCQh0EHQYXiIBSlIJCHUQdRheIgFKUgkIdhB2GF4iAUpSCQh3EHcYXyIBSlIJCHgQeBhfIgFKUgkIeRB5GF8iAUpSCQh6EHoYXyIBSlIJCHsQexhfIgFKUgkIfBB8GF8iAUpSCQh9EH0YXyIBSlIJCH4QfhhfIgFKUgkIfxB/GCwiAUtSCwiAARCAARgsIgFLUgsIgQEQgQEYYiIBTVILCIIBEIIBGGIiAU1SCwiDARCDARhiIgFNUgsIhAEQhAEYYiIBTVILCIUBEIUBGGIiAU1SCwiGARCGARhiIgFNUgsIhwEQhwEYYiIBTVILCIgBEIgBGGIiAU1SCwiJARCJARhiIgFNUgsIigEQigEYYiIBTVILCIsBEIsBGGIiAU1SCwiMARCMARhiIgFNUgsIjQEQjQEYYiIBTVILCI4BEI4BGGIiAU1SCwiPARCPARhiIgFNUgsIkAEQkAEYYiIBTVILCJEBEJEBGGIiAU1SCwiSARCSARhiIgFNUgsIkwEQkwEYYiIBTVILCJQBEJQBGGIiAU1SCwiVARCVARhiIgFNUgsIlgEQlgEYYiIBTVILCJcBEJcBGGIiAU1SCwiYARCYARhiIgFNUgsImQEQmQEYYiIBTVILCJoBEJoBGGIiAU1SCwibARCbARhiIgFNUgsInAEQnAEYYiIBTVILCJ0BEJ0BGGIiAU1SCwieARCeARhiIgFNUgsInwEQnwEYYiIBTVILCKABEKABGGIiAU1SCwihARChARhiIgFNUgsIogEQogEYYiIBTVILCKMBEKMBGGIiAU1SCwikARCkARhiIgFNUgsIpQEQpQEYYiIBTVILCKYBEKYBGGIiAU1SCwinARCnARhiIgFNUgsIqAEQqAEYYiIBTVILCKkBEKkBGGIiAU1SCwiqARCqARhiIgFNUgsIqwEQqwEYYiIBTVILCKwBEKwBGGIiAU1SCwitARCtARhiIgFNUgsIrgEQrgEYYiIBTVILCK8BEK8BGGIiAU1SCwiwARCwARhiIgFNUgsIsQEQsQEYYiIBTVILCLIBELIBGGIiAU1SCwizARCzARhiIgFNUgsItAEQtAEYYiIBTVILCLUBELUBGGIiAU1SCwi2ARC2ARhiIgFNUgsItwEQtwEYYiIBTVILCLgBELgBGGIiAU1SCwi5ARC5ARhiIgFNUgsIugEQugEYYiIBTVILCLsBELsBGGIiAU1SCwi8ARC8ARhiIgFNUgsIvQEQvQEYYiIBTVILCL4BEL4BGGIiAU1SCwi/ARC/ARhiIgFNUgsIwAEQwAEYYiIBTVILCMEBEMEBGGIiAU1SCwjCARDCARhiIgFNUgsIwwEQwwEYYiIBTVILCMQBEMQBGGIiAU1SCwjFARDFARhiIgFNUgsIxgEQxgEYYiIBTVILCMcBEMcBGGIiAU1SCwjIARDIARhiIgFNUgsIyQEQyQEYYiIBTVILCMoBEMoBGGIiAU1SCwjLARDLARhiIgFNUgsIzAEQzAEYYiIBTVILCM0BEM0BGGIiAU1SCwjOARDOARhiIgFNUgsIzwEQzwEYYiIBTVILCNABENABGGIiAU1SCwjRARDRARhiIgFNUgsI0gEQ0gEYYiIBTVILCNMBENMBGGIiAU1SCwjUARDUARhiIgFNUgsI1QEQ1QEYYiIBTVILCNYBENYBGGIiAU1SCwjXARDXARhiIgFNUgsI2AEQ2AEYYiIBTVILCNkBENkBGGIiAU1SCwjaARDaARhiIgFNUgsI2wEQ2wEYYiIBTVILCNwBENwBGGIiAU1SCwjdARDdARhiIgFNUgsI3gEQ3gEYYiIBTVILCN8BEN8BGGIiAU1SCwjgARDgARhiIgFNUgsI4QEQ4QEYYiIBTVILCOIBEOIBGGIiAU1SCwjjARDjARhiIgFNUgsI5AEQ5AEYYiIBTVILCOUBEOUBGGIiAU1SCwjmARDmARhiIgFNUgsI5wEQ5wEYYiIBTVILCOgBEOgBGGIiAU1SCwjpARDpARhiIgFNUgsI6gEQ6gEYYiIBTVILCOsBEOsBGGIiAU1SCwjsARDsARhiIgFNUgsI7QEQ7QEYYiIBTVILCO4BEO4BGGIiAU1SCwjvARDvARhiIgFNUgsI8AEQ8AEYYiIBTVILCPEBEPEBGGIiAU1SCwjyARDyARhiIgFNUgsI8wEQ8wEYYiIBTVILCPQBEPQBGGIiAU1SCwj1ARD1ARhiIgFNUgsI9gEQ9gEYYiIBTVILCPcBEPcBGGIiAU1SCwj4ARD4ARhiIgFNUgsI+QEQ+QEYYiIBTVILCPoBEPoBGGIiAU1SCwj7ARD7ARhiIgFNUgsI/AEQ/AEYYiIBTVILCP0BEP0BGGIiAU1SCwj+ARD+ARhiIgFNUgsI/wEQ/wEYYiIBTVILCIACEIACGGIiAU1SCwiBAhCBAhhiIgFNUgsIggIQggIYYiIBTVILCIMCEIMCGGIiAU1SCwiEAhCEAhhiIgFNUgsIhQIQhQIYYiIBTVILCIYCEIYCGGIiAU1SCwiHAhCHAhhiIgFNUgsIiAIQiAIYYiIBTVILCIkCEIkCGGIiAU1SCwiKAhCKAhhiIgFNUgsIiwIQiwIYYiIBTVILCIwCEIwCGGIiAU1SCwiNAhCNAhhiIgFNUgsIjgIQjgIYYiIBTVILCI8CEI8CGGIiAU1SCwiQAhCQAhhiIgFNUgsIkQIQkQIYYiIBTVILCJICEJICGGIiAU1SCwiTAhCTAhhiIgFNUgsIlAIQlAIYYiIBTVILCJUCEJUCGGIiAU1SCwiWAhCWAhhiIgFNUgsIlwIQlwIYYiIBTVILCJgCEJgCGGIiAU1SCwiZAhCZAhhiIgFNUgsImgIQmgIYYiIBTVILCJsCEJsCGGIiAU1SCwicAhCcAhhiIgFNUgsInQIQnQIYYiIBTVILCJ4CEJ4CGGIiAU1SCwifAhCfAhhiIgFNUgsIoAIQoAIYYiIBTVILCKECEKECGGIiAU1SCwiiAhCiAhhiIgFNUgsIowIQowIYYiIBTVILCKQCEKQCGGIiAU1SCwilAhClAhhiIgFNUgsIpgIQpgIYYiIBTVILCKcCEKcCGGIiAU1SCwioAhCoAhhiIgFNUgsIqQIQqQIYYiIBTVILCKoCEKoCGGIiAU1SCwirAhCrAhhiIgFNUgsIrAIQrAIYYiIBTVILCK0CEK0CGGIiAU1SCwiuAhCuAhhiIgFNUgsIrwIQrwIYYiIBTVILCLACELACGGIiAU1SCwixAhCxAhhiIgFNUgsIsgIQsgIYYiIBTVILCLMCELMCGGIiAU1SCwi0AhC0AhhiIgFNUgsItQIQtQIYYiIBTVILCLYCELYCGGIiAU1SCwi3AhC3AhhiIgFNUgsIuAIQuAIYYiIBTVILCLkCELkCGGIiAU1SCwi6AhC6AhhiIgFNUgsIuwIQuwIYYiIBTVILCLwCELwCGGIiAU1SCwi9AhC9AhhiIgFNUgsIvgIQvgIYYiIBTVILCL8CEL8CGGIiAU1SCwjAAhDAAhhiIgFNUgsIwQIQwQIYYiIBTVILCMICEMICGGIiAU1SCwjDAhDDAhhiIgFNUgsIxAIQxAIYYiIBTVILCMUCEMUCGGIiAU1SCwjGAhDGAhhiIgFNUgsIxwIQxwIYYiIBTVILCMgCEMgCGGIiAU1SCwjJAhDJAhhiIgFNUgsIygIQygIYYiIBTVILCMsCEMsCGGIiAU1SCwjMAhDMAhhiIgFNUgsIzQIQzQIYYiIBTVILCM4CEM4CGGIiAU1SCwjPAhDPAhhiIgFNUgsI0AIQ0AIYYiIBTVILCNECENECGGIiAU1SCwjSAhDSAhhiIgFNUgsI0wIQ0wIYYiIBTVILCNQCENQCGGIiAU1SCwjVAhDVAhhiIgFNUgsI1gIQ1gIYYiIBTVILCNcCENcCGGIiAU1SCwjYAhDYAhhiIgFNUgsI2QIQ2QIYYiIBTVILCNoCENoCGGIiAU1SCwjbAhDbAhhiIgFNUgsI3AIQ3AIYYiIBTVILCN0CEN0CGGIiAU1SCwjeAhDeAhhiIgFNUgsI3wIQ3wIYYiIBTVILCOACEOACGGIiAU1SCwjhAhDhAhhiIgFNUgsI4gIQ4gIYYiIBTVILCOMCEOMCGGIiAU1SCwjkAhDkAhhiIgFNUgsI5QIQ5QIYYiIBTVILCOYCEOYCGGIiAU1SCwjnAhDnAhhiIgFNUgsI6AIQ6AIYYiIBTVILCOkCEOkCGGIiAU1SCwjqAhDqAhhiIgFNUgsI6wIQ6wIYYiIBTVILCOwCEOwCGGIiAU1SCwjtAhDtAhhiIgFNUgsI7gIQ7gIYYiIBTVILCO8CEO8CGGIiAU1SCwjwAhDwAhhiIgFNUgsI8QIQ8QIYYiIBTVILCPICEPICGGIiAU1SCwjzAhDzAhhiIgFNUgsI9AIQ9AIYYiIBTVILCPUCEPUCGGIiAU1SCwj2AhD2AhhiIgFNUgsI9wIQ9wIYYiIBTVILCPgCEPgCGGIiAU1SCwj5AhD5AhhiIgFNUgsI+gIQ+gIYYiIBTVILCPsCEPsCGGIiAU1SCwj8AhD8AhhiIgFNUgsI/QIQ/QIYYiIBTVILCP4CEP4CGGIiAU1SCwj/AhD/AhhiIgFNUgsIgAMQgAMYYiIBTVILCIEDEIEDGGIiAU1SCwiCAxCCAxhiIgFNUgsIgwMQgwMYYiIBTVILCIQDEIQDGGIiAU1SCwiFAxCFAxhiIgFNUgsIhgMQhgMYYiIBTVILCIcDEIcDGGIiAU1SCwiIAxCIAxhiIgFNUgsIiQMQiQMYYiIBTVILCIoDEIoDGGIiAU1SCwiLAxCLAxhiIgFNUgsIjAMQjAMYYiIBTVILCI0DEI0DGGIiAU1SCwiOAxCOAxhiIgFNUgsIjwMQjwMYYiIBTVILCJADEJADGGIiAU1SCwiRAxCRAxhiIgFNUgsIkgMQkgMYYiIBTVILCJMDEJMDGGIiAU1SCwiUAxCUAxhiIgFNUgsIlQMQlQMYYiIBTVILCJYDEJYDGGIiAU1SCwiXAxCXAxhiIgFNUgsImAMQmAMYYiIBTVILCJkDEJkDGGIiAU1SCwiaAxCaAxhiIgFNUgsImwMQmwMYYiIBTVILCJwDEJwDGGIiAU1SCwidAxCdAxhiIgFNUgsIngMQngMYYiIBTVILCJ8DEJ8DGGIiAU1SCwigAxCgAxhiIgFNUgsIoQMQoQMYYiIBTVILCKIDEKIDGGIiAU1SCwijAxCjAxhiIgFNUgsIpAMQpAMYYiIBTVILCKUDEKUDGGIiAU1SCwimAxCmAxhiIgFNUgsIpwMQpwMYYiIBTVILCKgDEKgDGGIiAU1SCwipAxCpAxhiIgFNUgsIqgMQqgMYYiIBTVILCKsDEKsDGGIiAU1SCwisAxCsAxhiIgFNUgsIrQMQrQMYYiIBTVILCK4DEK4DGGIiAU1SCwivAxCvAxhiIgFNUgsIsAMQsAMYYiIBTVILCLEDELEDGGIiAU1SCwiyAxCyAxhiIgFNUgsIswMQswMYYiIBTVILCLQDELQDGGIiAU1SCwi1AxC1AxhiIgFNUgsItgMQtgMYYiIBTVILCLcDELcDGGIiAU1SCwi4AxC4AxhiIgFNUgsIuQMQuQMYYiIBTVILCLoDELoDGGIiAU1SCwi7AxC7AxhiIgFNUgsIvAMQvAMYYiIBTVILCL0DEL0DGGIiAU1SCwi+AxC+AxhiIgFNUgsIvwMQvwMYYiIBTVILCMADEMADGGIiAU1SCwjBAxDBAxhiIgFNUgsIwgMQwgMYYiIBTVILCMMDEMMDGGIiAU1SCwjEAxDEAxhiIgFNUgsIxQMQxQMYJSIBTVILCMYDEMYDGCUiAU1SCwjHAxDHAxglIgFNUgsIyAMQyAMYJSIBTVILCMkDEMkDGB8iAU5SCwjKAxDKAxgfIgFOUgsIywMQywMYHyIBTlILCMwDEMwDGB8iAU5SCwjNAxDNAxgfIgFOUgsIzgMQzgMYHyIBTlILCM8DEM8DGB8iAU5SCwjQAxDQAxgfIgFOUgsI0QMQ0QMYHyIBTlILCNIDENIDGB8iAU5SCwjTAxDTAxgfIgFOUgsI1AMQ1AMYHyIBTlILCNUDENUDGB8iAU5SCwjWAxDWAxgfIgFOUgsI1wMQ1wMYHyIBTlILCNgDENgDGB8iAU5SCwjZAxDZAxgfIgFOUgsI2gMQ2gMYHyIBTlILCNsDENsDGB8iAU5SCwjcAxDcAxgfIgFOUgsI3QMQ3QMYHyIBTlILCN4DEN4DGB8iAU5SCwjfAxDfAxgfIgFOUgsI4AMQ4AMYHyIBTlILCOEDEOEDGB8iAU5SCwjiAxDiAxgfIgFOUgsI4wMQ4wMYHyIBTlILCOQDEOQDGB8iAU5SCwjlAxDlAxgfIgFOUgsI5gMQ5gMYHyIBTlILCOcDEOcDGB8iAU5SCwjoAxDoAxgfIgFOUgsI6QMQ6QMYHyIBTlILCOoDEOoDGB8iAU5SCwjrAxDrAxgfIgFOUgsI7AMQ7AMYHyIBTlILCO0DEO0DGB8iAU5SCwjuAxDuAxgfIgFOUgsI7wMQ7wMYHyIBTlILCPADEPADGB8iAU5SCwjxAxDxAxgfIgFOUgsI8gMQ8gMYHyIBTlILCPMDEPMDGB8iAU5SCwj0AxD0AxgfIgFOUgsI9QMQ9QMYHyIBTlILCPYDEPYDGB8iAU5SCwj3AxD3AxgfIgFOUgsI+AMQ+AMYHyIBTlILCPkDEPkDGB8iAU5SCwj6AxD6AxgfIgFOUgsI+wMQ+wMYHyIBTlILCPwDEPwDGB8iAU5SCwj9AxD9AxgfIgFOUgsI/gMQ/gMYHyIBTlILCP8DEP8DGB8iAU5SCwiABBCABBgfIgFOUgsIgQQQgQQYHyIBTlILCIIEEIIEGB8iAU5SCwiDBBCDBBgfIgFOUgsIhAQQhAQYHyIBTlILCIUEEIUEGB8iAU5SCwiGBBCGBBgfIgFOUgsIhwQQhwQYHyIBTlILCIgEEIgEGB8iAU5SCwiJBBCJBBgfIgFOUgsIigQQigQYHyIBTlILCIsEEIsEGB8iAU5SCwiMBBCMBBgfIgFOUgsIjQQQjQQYHyIBTlILCI4EEI4EGB8iAU5SCwiPBBCPBBgfIgFOUgsIkAQQkAQYHyIBTlILCJEEEJEEGB8iAU5SCwiSBBCSBBgfIgFOUgsIkwQQkwQYHyIBTlILCJQEEJQEGB8iAU5SCwiVBBCVBBgfIgFOUgsIlgQQlgQYHyIBTlILCJcEEJcEGB8iAU5SCwiYBBCYBBgfIgFOUgsImQQQmQQYHyIBTlILCJoEEJoEGB8iAU5SCwibBBCbBBgfIgFOUgsInAQQnAQYHyIBTlILCJ0EEJ0EGB8iAU5SCwieBBCeBBgfIgFOUgsInwQQnwQYHyIBTlILCKAEEKAEGB8iAU5SCwihBBChBBgfIgFOUgsIogQQogQYHyIBTlILCKMEEKMEGB8iAU5SCwikBBCkBBgfIgFOUgsIpQQQpQQYHyIBTlILCKYEEKYEGB8iAU5SCwinBBCnBBgfIgFOUgsIqAQQqAQYHyIBTlILCKkEEKkEGB8iAU5SCwiqBBCqBBgfIgFOUgsIqwQQqwQYHyIBTlILCKwEEKwEGB8iAU5SCwitBBCtBBgfIgFOUgsIrgQQrgQYHyIBTlILCK8EEK8EGB8iAU5SCwiwBBCwBBgfIgFOUgsIsQQQsQQYHyIBTlILCLIEELIEGB8iAU5SCwizBBCzBBgfIgFOUgsItAQQtAQYHyIBTlILCLUEELUEGB8iAU5SCwi2BBC2BBgfIgFOUgsItwQQtwQYHyIBTlILCLgEELgEGB8iAU5SCwi5BBC5BBgfIgFOUgsIugQQugQYHyIBTlILCLsEELsEGB8iAU5SCwi8BBC8BBgfIgFOUgsIvQQQvQQYHyIBTlILCL4EEL4EGB8iAU5SCwi/BBC/BBgfIgFOUgsIwAQQwAQYHyIBTlILCMEEEMEEGB8iAU5SCwjCBBDCBBgfIgFOUgsIwwQQwwQYHyIBTlILCMQEEMQEGB8iAU5SCwjFBBDFBBgfIgFOUgsIxgQQxgQYHyIBTlILCMcEEMcEGB8iAU5SCwjIBBDIBBgfIgFOUgsIyQQQyQQYHyIBTlILCMoEEMoEGB8iAU5SCwjLBBDLBBgfIgFOUgsIzAQQzAQYHyIBTlILCM0EEM0EGB8iAU5SCwjOBBDOBBgfIgFOUgsIzwQQzwQYHyIBTlILCNAEENAEGB8iAU5SCwjRBBDRBBgfIgFOUgsI0gQQ0gQYHyIBTlILCNMEENMEGGQiAU5SCwjUBBDUBBhkIgFOUgsI1QQQ1QQYZCIBTlILCNYEENYEGGQiAU5SCwjXBBDXBBhkIgFOUgsI2AQQ2AQYZCIBTlILCNkEENkEGGQiAU5SCwjaBBDaBBhkIgFOUgsI2wQQ2wQYZCIBTlILCNwEENwEGGQiAU5SCwjdBBDdBBhlIgFOUgsI3gQQ3gQYZSIBTlILCN8EEN8EGGUiAU5SCwjgBBDgBBhlIgFOUgsI4QQQ4QQYZSIBTlILCOIEEOIEGGUiAU5SCwjjBBDjBBhlIgFOUgsI5AQQ5AQYZSIBTlILCOUEEOUEGGUiAU5SCwjmBBDmBBhlIgFOUgsI5wQQ5wQYZSIBTlILCOgEEOgEGGUiAU5SCwjpBBDpBBhlIgFOUgsI6gQQ6gQYZSIBTlILCOsEEOsEGGUiAU5SCwjsBBDsBBhlIgFOUgsI7QQQ7QQYZSIBTlILCO4EEO4EGGUiAU5SCwjvBBDvBBhlIgFOUgsI8AQQ8AQYZSIBTlILCPEEEPEEGGUiAU5SCwjyBBDyBBhlIgFOUgsI8wQQ8wQYZSIBTlILCPQEEPQEGGUiAU5SCwj1BBD1BBhlIgFOUgsI9gQQ9gQYZSIBTlILCPcEEPcEGGUiAU5SCwj4BBD4BBhlIgFOUgsI+QQQ+QQYZSIBTlILCPoEEPoEGGUiAU5SCwj7BBD7BBhlIgFOUgsI/AQQ/AQYZSIBTlILCP0EEP0EGGUiAU5SCwj+BBD+BBhlIgFOUgsI/wQQ/wQYZSIBTlILCIAFEIAFGGUiAU5SCwiBBRCBBRhlIgFOUgsIggUQggUYZSIBTlILCIMFEIMFGGUiAU5SCwiEBRCEBRhlIgFOUgwIhQUQhQUYXSICT1BSDAiGBRCGBRhdIgJPUFIMCIcFEIcFGFoiAk9QUgwIiAUQiAUYWiICT1BSDAiJBRCJBRg9IgJPUFIMCIoFEIoFGGciAk9QUgwIiwUQiwUYZyICT1BSDAiMBRCMBRhnIgJPUFIMCI0FEI0FGGciAk9QUgwIjgUQjgUYZyICT1BSDAiPBRCPBRgxIgJPUFIMCJAFEJAFGGgiAk9QUgwIkQUQkQUYDyICT1BSDAiSBRCSBRgPIgJPUFIMCJMFEJMFGA8iAk9QUgwIlAUQlAUYDyICT1BSDAiVBRCVBRgPIgJPUFIMCJYFEJYFGDIiAk9QUgwIlwUQlwUYaSICT1BSDAiYBRCYBRgQIgJPUFIMCJkFEJkFGGoiAk9QUgwImgUQmgUYaiICT1BSDAibBRCbBRgRIgJPUFIMCJwFEJwFGBEiAk9QUgwInQUQnQUYESICT1BSDAieBRCeBRgRIgJPUFIMCJ8FEJ8FGBEiAk9QUgwIoAUQoAUYESICT1BSDAihBRChBRgQIgJPUFIMCKIFEKIFGBEiAk9QUgwIowUQowUYECICT1BSDAikBRCkBRgQIgJPUFIMCKUFEKUFGBAiAk9QUgwIpgUQpgUYESICT1BSDAinBRCnBRgRIgJPUFIMCKgFEKgFGBEiAk9QUgwIqQUQqQUYESICT1BSDAiqBRCqBRglIgJPUFIMCKsFEKsFGGsiAk9QUgwIrAUQrAUYVyICT1BSDAitBRCtBRhXIgJPUFIMCK4FEK4FGFciAk9QUgwIrwUQrwUYVyICT1BSDAiwBRCwBRhXIgJPUFIMCLEFELEFGFciAk9QUgwIsgUQsgUYVyICT1BSDAizBRCzBRgQIgJPUFIMCLQFELQFGBAiAk9QUgwItQUQtQUYECICT1BSDAi2BRC2BRgQIgJPUFIMCLcFELcFGB4iAk9QUgwIuAUQuAUYHyICT1BSDAi5BRC5BRgfIgJPUFIMCLoFELoFGB8iAk9QUgsIuwUQuwUYWSIBV1ILCLwFELwFGG8iAVlSCwi9BRC9BRhSIgFcUgsIvgUQvgUYdSIBXVILCL8FEL8FGHUiAV1SCwjABRDABRh1IgFdUgsIwQUQwQUYdSIBXVILCMIFEMIFGHUiAV1SCwjDBRDDBRh1IgFdUgsIxAUQxAUYdSIBXVILCMUFEMUFGHUiAV1SCwjGBRDGBRh1IgFdUgsIxwUQxwUYdSIBXVILCMgFEMgFGHUiAV1SCwjJBRDJBRh1IgFdUgsIygUQygUYdSIBXVILCMsFEMsFGHUiAV1SCwjMBRDMBRh1IgFdUgsIzQUQzQUYdSIBXVILCM4FEM4FGHUiAV1SCwjPBRDPBRh1IgFdUgsI0AUQ0AUYdSIBXVILCNEFENEFGHUiAV1SCwjSBRDSBRh1IgFdUgsI0wUQ0wUYdSIBXVILCNQFENQFGHYiAV1SCwjVBRDVBRh2IgFdUgsI1gUQ1gUYdSIBXVILCNcFENcFGHUiAV1SCwjYBRDYBRh1IgFdUgsI2QUQ2QUYdSIBXVILCNoFENoFGHUiAV1SCwjbBRDbBRh1IgFdUgsI3AUQ3AUYdSIBXVILCN0FEN0FGHUiAV1SCwjeBRDeBRh1IgFdUgsI3wUQ3wUYdSIBXVILCOAFEOAFGHUiAV1SCwjhBRDhBRh1IgFdUgsI4gUQ4gUYdSIBXVILCOMFEOMFGHUiAV1SCwjkBRDkBRh1IgFdUgsI5QUQ5QUYdSIBXVILCOYFEOYFGHUiAV1SCwjnBRDnBRh1IgFdUgsI6AUQ6AUYdSIBXVILCOkFEOkFGHUiAV1SCwjqBRDqBRh1IgFdUgsI6wUQ6wUYdSIBXVILCOwFEOwFGHUiAV1SCwjtBRDtBRh1IgFdUgsI7gUQ7gUYdSIBXVILCO8FEO8FGHUiAV1SCwjwBRDwBRh1IgFdUgsI8QUQ8QUYdSIBXVILCPIFEPIFGHUiAV1SCwjzBRDzBRh1IgFdUgsI9AUQ9AUYdSIBXVILCPUFEPUFGHUiAV1SCwj2BRD2BRh1IgFdUgsI9wUQ9wUYdSIBXVILCPgFEPgFGHUiAV1SCwj5BRD5BRh1IgFdUgsI+gUQ+gUYdSIBXVILCPsFEPsFGHUiAV1SCwj8BRD8BRh1IgFdUgsI/QUQ/QUYfCIBX1ILCP4FEP4FGHwiAV9SCwj/BRD/BRh8IgFfUgsIgAYQgAYYfCIBX1ILCIEGEIEGGHwiAV9SCwiCBhCCBhh8IgFfUgsIgwYQgwYYfCIBX1ILCIQGEIQGGHwiAV9SCwiFBhCFBhh8IgFfUgsIhgYQhgYYfCIBX1ILCIcGEIcGGAEiAWJSCwiIBhCIBhgCIgFiUgsIiQYQiQYYAiIBYlILCIoGEIoGGAIiAWJSCwiLBhCLBhgCIgFiUgsIjAYQjAYYBSIBYlILCI0GEI0GGAciAWJaBhgDIgICSFoKCAEQARgEIgICSFoKCAIQAhgGIgICSFoKCAMQAxgJIgICSFoHCAQQBCIBA1oJCAUQBRgBIgEDWgkIBhAGGAIiAQNaCQgHEAcYAiIBA1oJCAgQCBgCIgEDWgkICRAJGAIiAQNaCQgKEAoYBSIBA1oJCAsQCxgHIgEDWgkIDBAMGAgiAQNaCQgNEA0YCCIBA1oJCA4QDhgIIgEDWgkIDxAPGAgiAQNaCQgQEBAYCCIBA1oJCBEQERgIIgEDWgkIEhASGAkiAQNaCQgTEBMYCSIBA1oJCBQQFBgJIgEDWgkIFRAVGAkiAQNaCQgWEBYYDCIBBFoJCBcQFxgMIgEEWgkIGBAYGAwiAQRaCQgZEBkYDCIBBFoJCBoQGhgPIgEIWgkIGxAbGBAiAQhaCQgcEBwYESIBCFoJCB0QHRgWIgENWgkIHhAeGBYiAQ1aCQgfEB8YFyIBDVoJCCAQIBgXIgENWgkIIRAhGBgiAQ1aCQgiECIYGCIBDVoJCCMQIxgYIgENWgkIJBAkGBkiAQ1aCgglECUYGSICDT5aCQgmECYYGSIBDVoJCCcQJxgaIgENWgkIKBAoGBoiAQ1aCQgpECkYGiIBDVoJCCoQKhgaIgENWgkIKxArGBsiAQ1aCQgsECwYGyIBDVoJCC0QLRgbIgENWgkILhAuGBsiAQ1aCQgvEC8YGyIBDVoJCDAQMBgcIgENWgkIMRAxGBwiAQ1aCQgyEDIYHCIBDVoJCDMQMxgXIgENWgkINBA0GBciAQ1aCQg1EDUYHSIBDVoJCDYQNhgdIgENWgkINxA3GB4iAQ1aCgg4EDgYHiICDT5aCQg5EDkYHiIBDVoJCDoQOhgfIgENWgkIOxA7GB8iAQ1aCQg8EDwYHyIBDVoKCD0QPRgfIgINPloJCD4QPhgfIgENWgkIPxA/GB8iAQ1aCQhAEEAYHyIBDVoJCEEQQRgfIgENWgkIQhBCGB8iAQ1aCQhDEEMYHyIBDVoJCEQQRBgfIgENWgkIRRBFGB8iAQ1aCQhGEEYYHyIBDVoJCEcQRxgfIgENWgkISBBIGB8iAQ1aCQhJEEkYHyIBDVoJCEoQShgfIgENWgkISxBLGB8iAQ1aCQhMEEwYHyIBDVoJCE0QTRgfIgENWgkIThBOGB8iAQ1aCQhPEE8YHyIBDVoJCFAQUBgfIgENWgkIURBRGB8iAQ1aCQhSEFIYHyIBDVoJCFMQUxgfIgENWgkIVBBUGB8iAQ1aCQhVEFUYHyIBDVoJCFYQVhgfIgENWgkIVxBXGB8iAQ1aCQhYEFgYHyIBDVoJCFkQWRgfIgENWgkIWhBaGB8iAQ1aCQhbEFsYHyIBDVoJCFwQXBgfIgENWgkIXRBdGB8iAQ1aCQheEF4YHyIBDVoJCF8QXxgfIgENWgkIYBBgGB8iAQ1aCQhhEGEYHyIBDVoJCGIQYhgfIgENWgkIYxBjGB8iAQ1aCQhkEGQYHyIBDVoJCGUQZRgfIgENWgkIZhBmGB8iAQ1aCQhnEGcYHyIBDVoJCGgQaBgfIgENWgkIaRBpGB8iAQ1aCQhqEGoYHyIBDVoJCGsQaxgfIgENWgkIbBBsGB8iAQ1aCQhtEG0YHyIBDVoJCG4QbhgfIgENWgkIbxBvGB8iAQ1aCQhwEHAYHyIBDVoJCHEQcRgfIgENWgkIchByGB8iAQ1aCQhzEHMYHyIBDVoJCHQQdBgfIgENWgkIdRB1GB8iAQ1aCQh2EHYYHyIBDVoJCHcQdxgfIgENWgkIeBB4GB8iAQ1aCQh5EHkYHyIBDVoJCHoQehgfIgENWgkIexB7GB8iAQ1aCQh8EHwYHyIBDVoJCH0QfRgfIgENWgkIfhB+GB8iAQ1aCQh/EH8YHyIBDVoLCIABEIABGB8iAQ1aCwiBARCBARgfIgENWgsIggEQggEYICIBDVoLCIMBEIMBGCAiAQ1aCwiEARCEARggIgENWgsIhQEQhQEYICIBDVoLCIYBEIYBGCAiAQ1aCwiHARCHARggIgENWgsIiAEQiAEYICIBDVoLCIkBEIkBGCEiAQ1aCwiKARCKARghIgENWgsIiwEQiwEYISIBDVoLCIwBEIwBGCEiAQ1aCwiNARCNARghIgENWgsIjgEQjgEYISIBDVoLCI8BEI8BGCEiAQ1aCwiQARCQARghIgENWgsIkQEQkQEYESIBDloLCJIBEJIBGCQiAQ5aCwiTARCTARglIgEOWgsIlAEQlAEYJSIBDloLCJUBEJUBGCUiAQ5aCwiWARCWARgkIgEOWgsIlwEQlwEYJCIBDloLCJgBEJgBGCQiAQ5aCwiZARCZARgkIgEOWgsImgEQmgEYJCIBDloLCJsBEJsBGCQiAQ5aCwicARCcARgkIgEOWgsInQEQnQEYJCIBDloLCJ4BEJ4BGCQiAQ5aCwifARCfARgkIgEOWgsIoAEQoAEYJCIBDloLCKEBEKEBGCQiAQ5aCwiiARCiARgkIgEOWgsIowEQowEYJCIBDloLCKQBEKQBGCQiAQ5aCwilARClARgkIgEOWgsIpgEQpgEYJCIBDloLCKcBEKcBGCQiAQ5aCwioARCoARgkIgEOWgsIqQEQqQEYJCIBDloLCKoBEKoBGCQiAQ5aCwirARCrARgkIgEOWgsIrAEQrAEYJCIBDloLCK0BEK0BGCQiAQ5aCwiuARCuARgkIgEOWgsIrwEQrwEYJCIBDloLCLABELABGCQiAQ5aCwixARCxARgkIgEOWgsIsgEQsgEYJCIBDloLCLMBELMBGCQiAQ5aCwi0ARC0ARgkIgEOWgsItQEQtQEYJCIBDloLCLYBELYBGCQiAQ5aCwi3ARC3ARgkIgEOWgsIuAEQuAEYJCIBDloLCLkBELkBGCQiAQ5aCwi6ARC6ARgkIgEOWgsIuwEQuwEYJCIBDloLCLwBELwBGCQiAQ5aCwi9ARC9ARgkIgEOWgsIvgEQvgEYJCIBDloLCL8BEL8BGCQiAQ5aCwjAARDAARgkIgEOWgsIwQEQwQEYJCIBDloLCMIBEMIBGCQiAQ5aCwjDARDDARgkIgEOWgsIxAEQxAEYJCIBDloLCMUBEMUBGCciARNaCwjGARDGARgnIgETWgsIxwEQxwEYKCIBE1oLCMgBEMgBGCgiARNaCwjJARDJARgqIgEUWgsIygEQygEYKyIBFFoLCMsBEMsBGCwiARRaCwjMARDMARgtIgEUWgsIzQEQzQEYLiIBFFoLCM4BEM4BGCciARRaCwjPARDPARgMIgEcWgsI0AEQ0AEYDCIBHFoLCNEBENEBGAwiARxaCwjSARDSARgMIgEcWgsI0wEQ0wEYDCIBHFoLCNQBENQBGAwiARxaCwjVARDVARgMIgEcWgsI1gEQ1gEYDCIBHFoLCNcBENcBGAwiARxaCwjYARDYARgMIgEcWgsI2QEQ2QEYDCIBHFoLCNoBENoBGAwiARxaCwjbARDbARgMIgEcWgsI3AEQ3AEYDCIBHFoLCN0BEN0BGAwiAR1aCwjeARDeARgMIgEeWgsI3wEQ3wEYDCIBH1oLCOABEOABGDEiASBaCwjhARDhARgxIgEgWgsI4gEQ4gEYMSIBIFoLCOMBEOMBGDEiASBaCwjkARDkARgxIgEgWgsI5QEQ5QEYMSIBIFoLCOYBEOYBGDEiASFaCwjnARDnARgxIgEhWgsI6AEQ6AEYMSIBIVoLCOkBEOkBGDEiASFaCwjqARDqARgxIgEhWgsI6wEQ6wEYMSIBIVoLCOwBEOwBGAwiATVaDAjtARDtARhVIgI3P1oMCO4BEO4BGFUiAjc/WgwI7wEQ7wEYVSICNz9aDAjwARDwARhVIgI3P1oMCPEBEPEBGFUiAjc/WgwI8gEQ8gEYVSICNz9aDAjzARDzARhVIgI3P1oMCPQBEPQBGFUiAjc/WgwI9QEQ9QEYLiICN1haDAj2ARD2ARguIgI3WFoMCPcBEPcBGC4iAjdYWgwI+AEQ+AEYLiICN1haCwj5ARD5ARgRIgE+WgsI+gEQ+gEYVyIBPloLCPsBEPsBGFciAT5aCwj8ARD8ARhXIgE+WgsI/QEQ/QEYVyIBPloLCP4BEP4BGFciAT5aCwj/ARD/ARhXIgE+WgsIgAIQgAIYVyIBPloLCIECEIECGFciAT5aCwiCAhCCAhhXIgE+WgsIgwIQgwIYVyIBPloLCIQCEIQCGFciAT5aCwiFAhCFAhhXIgE+WgsIhgIQhgIYVyIBPloLCIcCEIcCGFciAT5aCwiIAhCIAhgZIgE+WgsIiQIQiQIYGSIBPloLCIoCEIoCGBkiAT5aCwiLAhCLAhgZIgE+WgsIjAIQjAIYHiIBPloMCI0CEI0CGB8iAj5SWgwIjgIQjgIYHyICPlJaCwiPAhCPAhgfIgE+WgsIkAIQkAIYHyIBPloLCJECEJECGB8iAT5aCwiSAhCSAhgfIgE+WgsIkwIQkwIYHyIBPloLCJQCEJQCGB8iAT5aCwiVAhCVAhgfIgE+WgsIlgIQlgIYHyIBPloLCJcCEJcCGB8iAT5aCwiYAhCYAhgfIgE+WgsImQIQmQIYHyIBPloLCJoCEJoCGB8iAT5aCwibAhCbAhgfIgE+WgsInAIQnAIYHyIBPloLCJ0CEJ0CGB8iAT5aCwieAhCeAhgfIgE+WgsInwIQnwIYHyIBPloLCKACEKACGB8iAT5aCwihAhChAhgfIgE+WgsIogIQogIYHyIBPloLCKMCEKMCGB8iAT5aCwikAhCkAhgfIgE+WgsIpQIQpQIYHyIBPloLCKYCEKYCGB8iAT5aCwinAhCnAhgfIgE+WgsIqAIQqAIYHyIBPloLCKkCEKkCGB8iAT5aCwiqAhCqAhgfIgE+WgsIqwIQqwIYICIBPloLCKwCEKwCGFkiAUBaCwitAhCtAhhaIgFCWgsIrgIQrgIYWiIBQloLCK8CEK8CGFoiAUJaCwiwAhCwAhhaIgFCWgsIsQIQsQIYWiIBQloLCLICELICGFoiAUJaCwizAhCzAhhaIgFCWgsItAIQtAIYWiIBQloLCLUCELUCGDEiAUNaCwi2AhC2AhgxIgFDWgsItwIQtwIYMSIBQ1oLCLgCELgCGDEiAUNaCwi5AhC5AhgxIgFDWgsIugIQugIYMSIBQ1oLCLsCELsCGDEiAUNaCwi8AhC8AhgxIgFDWgsIvQIQvQIYMSIBQ1oLCL4CEL4CGDEiAUNaCwi/AhC/AhgxIgFFWgsIwAIQwAIYMSIBRVoLCMECEMECGDEiAUVaCwjCAhDCAhgxIgFFWgsIwwIQwwIYMSIBRVoLCMQCEMQCGDEiAUVaCwjFAhDFAhgxIgFFWgsIxgIQxgIYMSIBRVoLCMcCEMcCGDEiAUVaCwjIAhDIAhgxIgFFWgsIyQIQyQIYMSIBRVoLCMoCEMoCGDEiAUVaCwjLAhDLAhgxIgFFWgsIzAIQzAIYMSIBRVoLCM0CEM0CGDEiAUVaCwjOAhDOAhgxIgFFWgsIzwIQzwIYMSIBRVoLCNACENACGDEiAUVaCwjRAhDRAhgxIgFFWgsI0gIQ0gIYMSIBRVoLCNMCENMCGDEiAUVaCwjUAhDUAhgxIgFFWgsI1QIQ1QIYMSIBRVoLCNYCENYCGDEiAUVaCwjXAhDXAhgxIgFFWgsI2AIQ2AIYMSIBRVoLCNkCENkCGDEiAUVaCwjaAhDaAhgxIgFFWgsI2wIQ2wIYMSIBRVoLCNwCENwCGDEiAUVaCwjdAhDdAhgxIgFFWgsI3gIQ3gIYMSIBRloLCN8CEN8CGDEiAUZaCwjgAhDgAhgxIgFGWgsI4QIQ4QIYMSIBRloLCOICEOICGDEiAUZaCwjjAhDjAhgxIgFGWgsI5AIQ5AIYMSIBRloLCOUCEOUCGDEiAUZaCwjmAhDmAhgxIgFGWgsI5wIQ5wIYMSIBRloLCOgCEOgCGDEiAUZaCwjpAhDpAhgxIgFGWgsI6gIQ6gIYMSIBRloLCOsCEOsCGDEiAUZaCwjsAhDsAhgxIgFGWgsI7QIQ7QIYMSIBRloLCO4CEO4CGDEiAUZaCwjvAhDvAhgxIgFGWgsI8AIQ8AIYMSIBRloLCPECEPECGDEiAUZaCwjyAhDyAhgxIgFGWgsI8wIQ8wIYMSIBRloLCPQCEPQCGDEiAUZaCwj1AhD1AhgxIgFGWgsI9gIQ9gIYMSIBRloLCPcCEPcCGDEiAUZaCwj4AhD4AhgxIgFGWgsI+QIQ+QIYMSIBRloLCPoCEPoCGDEiAUZaCwj7AhD7AhgxIgFGWgsI/AIQ/AIYMSIBRloLCP0CEP0CGDEiAUZaCwj+AhD+AhgxIgFGWgsI/wIQ/wIYMSIBRloLCIADEIADGDEiAUZaCwiBAxCBAxgxIgFGWgsIggMQggMYMSIBRloLCIMDEIMDGDEiAUZaCwiEAxCEAxgxIgFGWgsIhQMQhQMYMSIBRloLCIYDEIYDGDEiAUZaCwiHAxCHAxgxIgFGWgsIiAMQiAMYMSIBRloLCIkDEIkDGDEiAUZaCwiKAxCKAxgxIgFGWgsIiwMQiwMYMSIBRloLCIwDEIwDGDEiAUZaCwiNAxCNAxgxIgFGWgsIjgMQjgMYMSIBRloLCI8DEI8DGDEiAUZaCwiQAxCQAxgxIgFGWgsIkQMQkQMYMSIBRloLCJIDEJIDGDEiAUZaCwiTAxCTAxgxIgFGWgsIlAMQlAMYMSIBRloLCJUDEJUDGDEiAUZaCwiWAxCWAxgxIgFGWgsIlwMQlwMYMSIBRloLCJgDEJgDGDEiAUZaCwiZAxCZAxgxIgFGWgsImgMQmgMYMSIBRloLCJsDEJsDGDEiAUZaCwicAxCcAxgxIgFGWgsInQMQnQMYMSIBRloLCJ4DEJ4DGDEiAUZaCwifAxCfAxgxIgFGWgsIoAMQoAMYMSIBRloLCKEDEKEDGDEiAUZaCwiiAxCiAxgxIgFGWgsIowMQowMYMSIBRloLCKQDEKQDGDEiAUZaCwilAxClAxgxIgFGWgsIpgMQpgMYMSIBRloLCKcDEKcDGDEiAUZaCwioAxCoAxgxIgFGWgsIqQMQqQMYMSIBRloLCKoDEKoDGDEiAUZaCwirAxCrAxgxIgFGWgsIrAMQrAMYMSIBRloLCK0DEK0DGDEiAUZaCwiuAxCuAxgxIgFGWgsIrwMQrwMYMSIBRloLCLADELADGDEiAUZaCwixAxCxAxgxIgFGWgsIsgMQsgMYMSIBRloLCLMDELMDGDEiAUZaCwi0AxC0AxgxIgFGWgsItQMQtQMYMSIBRloLCLYDELYDGDEiAUZaCwi3AxC3AxgxIgFGWgsIuAMQuAMYMSIBRloLCLkDELkDGDEiAUZaCwi6AxC6AxgxIgFGWgsIuwMQuwMYMSIBRloLCLwDELwDGDEiAUZaCwi9AxC9AxgxIgFGWgsIvgMQvgMYMSIBRloLCL8DEL8DGDEiAUZaCwjAAxDAAxgxIgFGWgsIwQMQwQMYMSIBRloLCMIDEMIDGDEiAUZaCwjDAxDDAxgxIgFGWgsIxAMQxAMYMSIBRloLCMUDEMUDGDEiAUZaCwjGAxDGAxgxIgFGWgsIxwMQxwMYMSIBRloLCMgDEMgDGDEiAUZaCwjJAxDJAxgxIgFGWgsIygMQygMYMSIBRloLCMsDEMsDGDEiAUZaCwjMAxDMAxgxIgFHWgsIzQMQzQMYMSIBR1oLCM4DEM4DGDEiAUdaCwjPAxDPAxgxIgFHWgsI0AMQ0AMYXSIBSVoLCNEDENEDGFoiAUlaCwjSAxDSAxgsIgFLWgsI0wMQ0wMYLCIBS1oLCNQDENQDGCwiAUtaCwjVAxDVAxgsIgFLWgsI1gMQ1gMYLCIBS1oLCNcDENcDGCwiAUtaCwjYAxDYAxgsIgFLWgsI2QMQ2QMYLCIBS1oLCNoDENoDGCwiAUtaCwjbAxDbAxgsIgFLWgsI3AMQ3AMYLCIBS1oLCN0DEN0DGCwiAUtaCwjeAxDeAxgsIgFLWgsI3wMQ3wMYLCIBS1oLCOADEOADGCwiAUtaCwjhAxDhAxgsIgFLWgsI4gMQ4gMYLCIBS1oLCOMDEOMDGCciAUxaCwjkAxDkAxhtIgFUWgsI5QMQ5QMYQSIBVVoLCOYDEOYDGFkiAVdaCwjnAxDnAxhZIgFXWgsI6AMQ6AMYWSIBV1oLCOkDEOkDGFkiAVdaCwjqAxDqAxhZIgFXWgsI6wMQ6wMYWSIBV1oLCOwDEOwDGFkiAVdaCwjtAxDtAxhZIgFXWgsI7gMQ7gMYWSIBV1oLCO8DEO8DGFkiAVdaCwjwAxDwAxhZIgFXWgsI8QMQ8QMYWSIBV1oLCPIDEPIDGFkiAVdaCwjzAxDzAxhZIgFXWgsI9AMQ9AMYWSIBV1oLCPUDEPUDGHEiAVpaCwj2AxD2AxhxIgFaWgsI9wMQ9wMYcSIBWloLCPgDEPgDGHEiAVpaCwj5AxD5AxhxIgFaWgsI+gMQ+gMYcSIBWloLCPsDEPsDGHEiAVpaCwj8AxD8AxhxIgFaWgsI/QMQ/QMYcSIBWloLCP4DEP4DGHEiAVpaCwj/AxD/AxhxIgFaWgsIgAQQgAQYcSIBWloLCIEEEIEEGHEiAVpaCwiCBBCCBBhxIgFaWgsIgwQQgwQYcSIBWloLCIQEEIQEGHEiAVpaCwiFBBCFBBhxIgFaWgsIhgQQhgQYcSIBWloLCIcEEIcEGHEiAVpaCwiIBBCIBBhxIgFaWgsIiQQQiQQYcSIBWloLCIoEEIoEGHEiAVpaCwiLBBCLBBhxIgFaWgsIjAQQjAQYcSIBWloLCI0EEI0EGHEiAVpaCwiOBBCOBBhxIgFaWgsIjwQQjwQYcSIBWloLCJAEEJAEGHEiAVpaCwiRBBCRBBhxIgFaWgsIkgQQkgQYcSIBWloLCJMEEJMEGHEiAVpaCwiUBBCUBBhxIgFaWgsIlQQQlQQYcSIBWloLCJYEEJYEGHEiAVpaCwiXBBCXBBhxIgFaWgsImAQQmAQYcSIBWloLCJkEEJkEGHEiAVpaCwiaBBCaBBhxIgFaWgsImwQQmwQYcSIBWloLCJwEEJwEGHEiAVpaCwidBBCdBBhxIgFaWgsIngQQngQYPCIBXloLCJ8EEJ8EGDwiAV5aCwigBBCgBBh3IgFeWgsIoQQQoQQYdyIBXloLCKIEEKIEGHciAV5aCwijBBCjBBh3IgFeWgsIpAQQpAQYdyIBXloLCKUEEKUEGHciAV5aCwimBBCmBBg9IgFeWgsIpwQQpwQYPSIBXloLCKgEEKgEGD0iAV5aCwipBBCpBBg9IgFeWgsIqgQQqgQYPSIBXloLCKsEEKsEGD0iAV5aCwisBBCsBBg9IgFeWgsIrQQQrQQYPSIBXloLCK4EEK4EGD4iAV5aCwivBBCvBBg+IgFeWgsIsAQQsAQYPiIBXloLCLEEELEEGD4iAV5aCwiyBBCyBBg+IgFeWgsIswQQswQYPiIBXloLCLQEELQEGD4iAV5aCwi1BBC1BBg+IgFeWgsItgQQtgQYPSIBXloLCLcEELcEGD0iAV5aCwi4BBC4BBg9IgFeWgsIuQQQuQQYPSIBXloLCLoEELoEGD0iAV5aCwi7BBC7BBg9IgFeWgsIvAQQvAQYPSIBXloLCL0EEL0EGD0iAV5aCwi+BBC+BBg9IgFeWgsIvwQQvwQYPSIBXloLCMAEEMAEGD0iAV5aCwjBBBDBBBg9IgFeWgsIwgQQwgQYPSIBXloLCMMEEMMEGD0iAV5aCwjEBBDEBBg9IgFeWgsIxQQQxQQYPSIBXloLCMYEEMYEGD0iAV5aCwjHBBDHBBg9IgFeWgsIyAQQyAQYPyIBXloLCMkEEMkEGD8iAV5aCwjKBBDKBBg/IgFeWgsIywQQywQYPyIBXloLCMwEEMwEGD8iAV5aCwjNBBDNBBg/IgFeWgsIzgQQzgQYPyIBXloLCM8EEM8EGD8iAV5aCwjQBBDQBBhAIgFeWgsI0QQQ0QQYQCIBXloLCNIEENIEGEAiAV5aCwjTBBDTBBhAIgFeWgsI1AQQ1AQYQCIBXloLCNUEENUEGEAiAV5aCwjWBBDWBBh4IgFeWgsI1wQQ1wQYeCIBXloLCNgEENgEGD8iAV5aCwjZBBDZBBg/IgFeWgsI2gQQ2gQYPyIBXloLCNsEENsEGD8iAV5aCwjcBBDcBBg/IgFeWgsI3QQQ3QQYPyIBXloLCN4EEN4EGD8iAV5aCwjfBBDfBBg/IgFeWgsI4AQQ4AQYPyIBXloLCOEEEOEEGD8iAV5aCwjiBBDiBBg/IgFeWgsI4wQQ4wQYPyIBXloLCOQEEOQEGGciAV5aCwjlBBDlBBhnIgFeWgsI5gQQ5gQYZyIBXloLCOcEEOcEGGciAV5aCwjoBBDoBBhnIgFeWgsI6QQQ6QQYZyIBXloLCOoEEOoEGEEiAV5aCwjrBBDrBBhBIgFeWgsI7AQQ7AQYQSIBXloLCO0EEO0EGEEiAV5aCwjuBBDuBBhBIgFeWgsI7wQQ7wQYQSIBXloLCPAEEPAEGEEiAV5aCwjxBBDxBBhBIgFeWgsI8gQQ8gQYQSIBXloLCPMEEPMEGEEiAV5aCwj0BBD0BBhtIgFeWgsI9QQQ9QQYbSIBXloLCPYEEPYEGEEiAV5aCwj3BBD3BBhBIgFeWgsI+AQQ+AQYQSIBXloLCPkEEPkEGEEiAV5aCwj6BBD6BBhBIgFeWgsI+wQQ+wQYQSIBXloLCPwEEPwEGEEiAV5aCwj9BBD9BBhBIgFeWgsI/gQQ/gQYQSIBXloLCP8EEP8EGEEiAV5aCwiABRCABRhBIgFeWgsIgQUQgQUYQSIBXloLCIIFEIIFGEEiAV5aCwiDBRCDBRhBIgFeWgsIhAUQhAUYQSIBXloLCIUFEIUFGEEiAV5aCwiGBRCGBRhBIgFeWgsIhwUQhwUYQSIBXloLCIgFEIgFGEEiAV5aCwiJBRCJBRhBIgFeWgsIigUQigUYQSIBXloLCIsFEIsFGEEiAV5aCwiMBRCMBRhBIgFeWgsIjQUQjQUYQSIBXloLCI4FEI4FGEEiAV5aCwiPBRCPBRhBIgFeWgsIkAUQkAUYQSIBXloLCJEFEJEFGEEiAV5aCwiSBRCSBRhBIgFeWgsIkwUQkwUYQSIBXloLCJQFEJQFGEEiAV5aCwiVBRCVBRhBIgFeWgsIlgUQlgUYeSIBXloLCJcFEJcFGHkiAV5aCwiYBRCYBRhBIgFeWgsImQUQmQUYQSIBXloLCJoFEJoFGHkiAV5aCwibBRCbBRh5IgFeWgsInAUQnAUYeiIBXloLCJ0FEJ0FGHoiAV5aCwieBRCeBRhBIgFeWgsInwUQnwUYQSIBXloLCKAFEKAFGHsiAV5aCwihBRChBRh7IgFeWgsIogUQogUYXiIBXloLCKMFEKMFGF4iAV5aCwikBRCkBRhfIgFeWgsIpQUQpQUYXyIBXloLCKYFEKYFGF8iAV5aCwinBRCnBRhfIgFeWgsIqAUQqAUYXyIBXloLCKkFEKkFGF8iAV5aCwiqBRCqBRhfIgFeWgsIqwUQqwUYXyIBXloLCKwFEKwFGF8iAV5aCwitBRCtBRhfIgFeWgsIrgUQrgUYXyIBXloLCK8FEK8FGF8iAV5aCwiwBRCwBRhfIgFeWgsIsQUQsQUYXyIBXloLCLIFELIFGF8iAV5aCwizBRCzBRhfIgFeWgsItAUQtAUYDyIBXloLCLUFELUFGA8iAV5aCwi2BRC2BRgPIgFeWgsItwUQtwUYDyIBXloLCLgFELgFGA8iAV5aCwi5BRC5BRgPIgFeWgsIugUQugUYfCIBXloLCLsFELsFGHwiAV5aCwi8BRC8BRh8IgFeWgsIvQUQvQUYfCIBXloLCL4FEL4FGH0iAV5aCwi/BRC/BRh9IgFeWgsIwAUQwAUYLSIBXloLCMEFEMEFGC0iAV5aCwjCBRDCBRh+IgFeWgsIwwUQwwUYfiIBXloLCMQFEMQFGH4iAV5aCwjFBRDFBRh+IgFeWgsIxgUQxgUYfiIBXloLCMcFEMcFGH4iAV5aCwjIBRDIBRh/IgFeWgsIyQUQyQUYfyIBXloLCMoFEMoFGH8iAV5aCwjLBRDLBRh/IgFeWgsIzAUQzAUYDCIBXloLCM0FEM0FGAwiAV5aCwjOBRDOBRgnIgFeWgsIzwUQzwUYJyIBXloLCNAFENAFGCciAV5aCwjRBRDRBRgnIgFeWgsI0gUQ0gUYJyIBXloLCNMFENMFGCciAV5aCwjUBRDUBRgnIgFeWgsI1QUQ1QUYJyIBXloLCNYFENYFGCciAV5aCwjXBRDXBRgnIgFeWgsI2AUQ2AUYJyIBXloLCNkFENkFGCciAV5aCwjaBRDaBRhpIgFeWgsI2wUQ2wUYaSIBXloLCNwFENwFGGkiAV5aCwjdBRDdBRhpIgFeWgsI3gUQ3gUYaSIBXloLCN8FEN8FGGkiAV5aCwjgBRDgBRhpIgFeWgsI4QUQ4QUYaSIBXloLCOIFEOIFGGkiAV5aCwjjBRDjBRhpIgFeWgwI5AUQ5AUYgAEiAV5aDAjlBRDlBRiAASIBXloLCOYFEOYFGBYiAV5aCwjnBRDnBRgWIgFeWgsI6AUQ6AUYFiIBXloLCOkFEOkFGBYiAV5aCwjqBRDqBRgWIgFeWgsI6wUQ6wUYFiIBXloLCOwFEOwFGBYiAV5aCwjtBRDtBRgWIgFeWgsI7gUQ7gUYFiIBXloLCO8FEO8FGBYiAV5aDAjwBRDwBRiBASIBXloMCPEFEPEFGIEBIgFeWgwI8gUQ8gUYgQEiAV5aDAjzBRDzBRiBASIBXloMCPQFEPQFGIEBIgFeWgwI9QUQ9QUYgQEiAV5aCwj2BRD2BRhiIgFeWgsI9wUQ9wUYVyIBXloLCPgFEPgFGFciAV5aCwj5BRD5BRhXIgFeWgsI+gUQ+gUYYiIBXloLCPsFEPsFGGIiAV5aCwj8BRD8BRhiIgFeWgsI/QUQ/QUYYiIBXloLCP4FEP4FGGIiAV5aCwj/BRD/BRhiIgFeWgsIgAYQgAYYYiIBXloLCIEGEIEGGGIiAV5aCwiCBhCCBhglIgFeWgsIgwYQgwYYJSIBXloLCIQGEIQGGCUiAV5aCwiFBhCFBhglIgFeWgsIhgYQhgYYJSIBXloLCIcGEIcGGCUiAV5aCwiIBhCIBhhiIgFeWgsIiQYQiQYYYiIBXloLCIoGEIoGGFciAV5aCwiLBhCLBhhXIgFeWgsIjAYQjAYYVyIBXloLCI0GEI0GGGIiAV5aDAiOBhCOBhiCASIBXloMCI8GEI8GGIIBIgFeWgwIkAYQkAYYggEiAV5aDAiRBhCRBhiCASIBXloMCJIGEJIGGIIBIgFeWgwIkwYQkwYYggEiAV5aCwiUBhCUBhgXIgFeWgsIlQYQlQYYFyIBXloLCJYGEJYGGBciAV5aCwiXBhCXBhgXIgFeWgsImAYQmAYYFyIBXloLCJkGEJkGGBciAV5aCwiaBhCaBhgaIgFeWgsImwYQmwYYGiIBXloLCJwGEJwGGBoiAV5aCwidBhCdBhgaIgFeWgsIngYQngYYGiIBXloLCJ8GEJ8GGBoiAV5aDAigBhCgBhiDASIBXloMCKEGEKEGGIMBIgFeWgsIogYQogYYFyIBXloLCKMGEKMGGBciAV5aCwikBhCkBhgcIgFeWgsIpQYQpQYYHCIBXloLCKYGEKYGGBwiAV5aCwinBhCnBhgcIgFeWgsIqAYQqAYYHCIBXloLCKkGEKkGGBwiAV5aCwiqBhCqBhgcIgFeWgsIqwYQqwYYHCIBXloLCKwGEKwGGB4iAV5aCwitBhCtBhgeIgFeWgsIrgYQrgYYHiIBXloLCK8GEK8GGB4iAV5aCwiwBhCwBhgeIgFeWgsIsQYQsQYYHiIBXloLCLIGELIGGB4iAV5aCwizBhCzBhgeIgFeWgsItAYQtAYYHyIBXloLCLUGELUGGB8iAV5aCwi2BhC2BhgfIgFeWgsItwYQtwYYHyIBXloLCLgGELgGGB8iAV5aCwi5BhC5BhgfIgFeWgsIugYQugYYHyIBXloLCLsGELsGGB8iAV5aCwi8BhC8BhgfIgFeWgsIvQYQvQYYHyIBXloLCL4GEL4GGB8iAV5aCwi/BhC/BhgfIgFeWgsIwAYQwAYYHyIBXloLCMEGEMEGGB8iAV5aCwjCBhDCBhgfIgFeWgsIwwYQwwYYHyIBXloLCMQGEMQGGCAiAV5aCwjFBhDFBhggIgFeWgsIxgYQxgYYICIBXloLCMcGEMcGGCAiAV5aCwjIBhDIBhghIgFeWgsIyQYQyQYYISIBXloLCMoGEMoGGCEiAV5aCwjLBhDLBhghIgFeWgsIzAYQzAYYISIBXloLCM0GEM0GGCEiAV5aCwjOBhDOBhghIgFeWgsIzwYQzwYYISIBXloLCNAGENAGGGQiAV5aCwjRBhDRBhhkIgFeWgsI0gYQ0gYYZCIBXloLCNMGENMGGGQiAV5aCwjUBhDUBhhkIgFeWgsI1QYQ1QYYZCIBXloLCNYGENYGGGQiAV5aCwjXBhDXBhhkIgFeWgsI2AYQ2AYYZCIBXloLCNkGENkGGGQiAV5aCwjaBhDaBhhkIgFeWgsI2wYQ2wYYZCIBXloLCNwGENwGGGQiAV5aCwjdBhDdBhhkIgFeWgsI3gYQ3gYYZCIBXloLCN8GEN8GGGQiAV5aCwjgBhDgBhhlIgFeWgsI4QYQ4QYYZSIBXloLCOIGEOIGGGUiAV5aCwjjBhDjBhhlIgFeWgsI5AYQ5AYYQiIBXloLCOUGEOUGGEIiAV5aDAjmBhDmBhiEASIBXloMCOcGEOcGGIQBIgFeWgwI6AYQ6AYYhQEiAV5aDAjpBhDpBhiFASIBXloMCOoGEOoGGIUBIgFeWgwI6wYQ6wYYhQEiAV5aCwjsBhDsBhhSIgFeWgsI7QYQ7QYYUiIBXloLCO4GEO4GGFIiAV5aCwjvBhDvBhhSIgFeWgsI8AYQ8AYYUiIBXloLCPEGEPEGGFIiAV5aCwjyBhDyBhhSIgFeWgsI8wYQ8wYYUiIBXloLCPQGEPQGGHUiAV5aCwj1BhD1Bhh1IgFeWgsI9gYQ9gYYdSIBXloLCPcGEPcGGHUiAV5aCwj4BhD4Bhh1IgFeWgsI+QYQ+QYYdSIBXloLCPoGEPoGGHUiAV5aCwj7BhD7Bhh1IgFeWgsI/AYQ/AYYdSIBXloLCP0GEP0GGHUiAV5aCwj+BhD+BhgIIgFeWgsI/wYQ/wYYCCIBXloLCIAHEIAHGAgiAV5aCwiBBxCBBxgIIgFeWgsIggcQggcYCSIBXloLCIMHEIMHGAkiAV5aCwiEBxCEBxgJIgFeWgsIhQcQhQcYCSIBXloMCIYHEIYHGIYBIgFeWgwIhwcQhwcYhgEiAV5aDAiIBxCIBxiGASIBXloMCIkHEIkHGIYBIgFeWgwIigcQigcYhgEiAV5aDAiLBxCLBxiGASIBXloMCIwHEIwHGIcBIgFeWgwIjQcQjQcYhwEiAV5aCwiOBxCOBxhaIgFgWgsIjwcQjwcYWiIBYFoLCJAHEJAHGFoiAWBaCwiRBxCRBxhaIgFgWgsIkgcQkgcYWiIBYFoLCJMHEJMHGFoiAWBaCwiUBxCUBxhaIgFgWgsIlQcQlQcYWiIBYFoLCJYHEJYHGFoiAWBaCwiXBxCXBxhaIgFgWgsImAcQmAcYWiIBYFoLCJkHEJkHGFoiAWBaCwiaBxCaBxhaIgFgWgsImwcQmwcYWiIBYFoLCJwHEJwHGFoiAWBaCwidBxCdBxhaIgFgWgsIngcQngcYWiIBYFoLCJ8HEJ8HGFoiAWBaCwigBxCgBxhaIgFgWgsIoQcQoQcYWiIBYFoLCKIHEKIHGFoiAWBaCwijBxCjBxhaIgFgWgsIpAcQpAcYWiIBYFoLCKUHEKUHGFoiAWBaCwimBxCmBxhaIgFgWgsIpwcQpwcYWiIBYFoLCKgHEKgHGFoiAWBaCwipBxCpBxhaIgFgWgsIqgcQqgcYWiIBYFoLCKsHEKsHGFoiAWBaCwisBxCsBxhaIgFgWgsIrQcQrQcYWiIBYFoLCK4HEK4HGFoiAWBaCwivBxCvBxhaIgFgWgsIsAcQsAcYWiIBYFoLCLEHELEHGFoiAWBaCwiyBxCyBxhaIgFgWgsIswcQswcYWiIBYFoLCLQHELQHGFoiAWBaCwi1BxC1BxhaIgFgWgsItgcQtgcYWiIBYFoLCLcHELcHGFoiAWBaCwi4BxC4BxhaIgFgWgsIuQcQuQcYWiIBYFoLCLoHELoHGFoiAWBaCwi7BxC7BxhaIgFgWgsIvAcQvAcYWiIBYFoLCL0HEL0HGFoiAWBaCwi+BxC+BxhaIgFgWgsIvwcQvwcYWiIBYFoLCMAHEMAHGFoiAWBaCwjBBxDBBxhaIgFgWgsIwgcQwgcYWiIBYFoLCMMHEMMHGFoiAWBaCwjEBxDEBxhaIgFgWgsIxQcQxQcYWiIBYFoLCMYHEMYHGFoiAWBaCwjHBxDHBxhaIgFgWgsIyAcQyAcYWiIBYFoLCMkHEMkHGFoiAWBaCwjKBxDKBxhaIgFgWgsIywcQywcYWiIBYFoLCMwHEMwHGFoiAWBaCwjNBxDNBxhaIgFgWgsIzgcQzgcYWiIBYFoLCM8HEM8HGFoiAWBaCwjQBxDQBxhaIgFgWgsI0QcQ0QcYWiIBYFoLCNIHENIHGFoiAWBaCwjTBxDTBxhaIgFgWgsI1AcQ1AcYWiIBYFoLCNUHENUHGFoiAWBaCwjWBxDWBxhaIgFgWgsI1wcQ1wcYWiIBYFoLCNgHENgHGFoiAWBaCwjZBxDZBxhaIgFgWgsI2gcQ2gcYWiIBYFoLCNsHENsHGFoiAWBaCwjcBxDcBxhaIgFgWgsI3QcQ3QcYWiIBYFoLCN4HEN4HGFoiAWBaCwjfBxDfBxhaIgFgWgsI4AcQ4AcYWiIBYFoLCOEHEOEHGFoiAWBaCwjiBxDiBxhaIgFgWgsI4wcQ4wcYWiIBYFoLCOQHEOQHGFoiAWBaCwjlBxDlBxhaIgFgWgsI5gcQ5gcYWiIBYFoLCOcHEOcHGFoiAWBaCwjoBxDoBxhaIgFgWgsI6QcQ6QcYWiIBYFoLCOoHEOoHGFoiAWBaCwjrBxDrBxhaIgFgWgsI7AcQ7AcYWiIBYFoLCO0HEO0HGFoiAWBaCwjuBxDuBxhaIgFgWgsI7wcQ7wcYWiIBYFoLCPAHEPAHGFoiAWBaCwjxBxDxBxhaIgFgWgsI8gcQ8gcYWiIBYFoLCPMHEPMHGFoiAWBaCwj0BxD0BxhaIgFgWgsI9QcQ9QcYWiIBYFoLCPYHEPYHGFoiAWBaCwj3BxD3BxhaIgFgWgsI+AcQ+AcYWiIBYFoLCPkHEPkHGFoiAWBaCwj6BxD6BxhaIgFgWgsI+wcQ+wcYWiIBYFoLCPwHEPwHGFoiAWBaCwj9BxD9BxhaIgFgWgsI/gcQ/gcYWiIBYFoLCP8HEP8HGFoiAWBaCwiACBCACBhaIgFgWgsIgQgQgQgYWiIBYFoLCIIIEIIIGFoiAWBaCwiDCBCDCBhaIgFgWgsIhAgQhAgYWiIBYFoLCIUIEIUIGFoiAWBaCwiGCBCGCBhaIgFgWgsIhwgQhwgYWiIBYFoLCIgIEIgIGFoiAWBaCwiJCBCJCBhaIgFgWgsIiggQiggYWiIBYFoLCIsIEIsIGFoiAWBaCwiMCBCMCBhaIgFgWgsIjQgQjQgYWiIBYFoLCI4IEI4IGFoiAWBaCwiPCBCPCBhaIgFgWgsIkAgQkAgYWiIBYFoLCJEIEJEIGFoiAWBaCwiSCBCSCBhaIgFgWgsIkwgQkwgYWiIBYFoLCJQIEJQIGFoiAWBaCwiVCBCVCBhaIgFgWgsIlggQlggYWiIBYFoLCJcIEJcIGFoiAWBaCwiYCBCYCBhaIgFgWgsImQgQmQgYWiIBYFoLCJoIEJoIGFoiAWBaCwibCBCbCBhaIgFgWgsInAgQnAgYWiIBYFoLCJ0IEJ0IGFoiAWBaCwieCBCeCBhaIgFgWgsInwgQnwgYWiIBYFoLCKAIEKAIGFoiAWBaCwihCBChCBhaIgFgWgsIoggQoggYWiIBYFoLCKMIEKMIGFoiAWBaCwikCBCkCBhaIgFgWgsIpQgQpQgYWiIBYFoLCKYIEKYIGFoiAWBaCwinCBCnCBhaIgFgWgsIqAgQqAgYWiIBYFoLCKkIEKkIGFoiAWBaCwiqCBCqCBhaIgFgWgsIqwgQqwgYWiIBYFoLCKwIEKwIGFoiAWBaCwitCBCtCBhaIgFgWgsIrggQrggYWiIBYFoLCK8IEK8IGFoiAWBaCwiwCBCwCBhaIgFgWgsIsQgQsQgYWiIBYFoLCLIIELIIGFoiAWBaCwizCBCzCBhaIgFgWgsItAgQtAgYWiIBYFoLCLUIELUIGFoiAWBaCwi2CBC2CBhaIgFgWgsItwgQtwgYWiIBYFoLCLgIELgIGFoiAWBaCwi5CBC5CBhaIgFgWgsIuggQuggYWiIBYFoLCLsIELsIGFoiAWBaCwi8CBC8CBhaIgFgWgsIvQgQvQgYWiIBYFoLCL4IEL4IGFoiAWBaCwi/CBC/CBhaIgFgWgsIwAgQwAgYWiIBYFoLCMEIEMEIGFoiAWBaCwjCCBDCCBhaIgFgWgsIwwgQwwgYWiIBYFoLCMQIEMQIGFoiAWBaCwjFCBDFCBhaIgFgWgsIxggQxggYWiIBYFoLCMcIEMcIGFoiAWBaCwjICBDICBhaIgFgWgsIyQgQyQgYWiIBYFoLCMoIEMoIGFoiAWBaCwjLCBDLCBhaIgFgWgsIzAgQzAgYWiIBYFoLCM0IEM0IGFoiAWBaCwjOCBDOCBhaIgFgWgsIzwgQzwgYWiIBYFoLCNAIENAIGFoiAWBaCwjRCBDRCBhaIgFgWgsI0ggQ0ggYWiIBYFoLCNMIENMIGFoiAWBaCwjUCBDUCBhaIgFgWgsI1QgQ1QgYWiIBYFoLCNYIENYIGFoiAWBaCwjXCBDXCBhaIgFgWgsI2AgQ2AgYWiIBYFoLCNkIENkIGFoiAWBaCwjaCBDaCBhaIgFgWgsI2wgQ2wgYWiIBYFoLCNwIENwIGFoiAWBaCwjdCBDdCBhaIgFgWgsI3ggQ3ggYWiIBYFoLCN8IEN8IGFoiAWBaCwjgCBDgCBhaIgFgWgsI4QgQ4QgYWiIBYFoLCOIIEOIIGFoiAWBaCwjjCBDjCBhaIgFgWgsI5AgQ5AgYWiIBYFoLCOUIEOUIGFoiAWBaCwjmCBDmCBhaIgFgWgsI5wgQ5wgYWiIBYFoLCOgIEOgIGFoiAWBaCwjpCBDpCBhaIgFgWgsI6ggQ6ggYWiIBYFoLCOsIEOsIGFoiAWBaCwjsCBDsCBhaIgFgWgsI7QgQ7QgYWiIBYFoLCO4IEO4IGFoiAWBaCwjvCBDvCBhaIgFgWgsI8AgQ8AgYWiIBYFoLCPEIEPEIGFoiAWBaCwjyCBDyCBhaIgFgWgsI8wgQ8wgYWiIBYFoLCPQIEPQIGFoiAWBaCwj1CBD1CBhaIgFgWgsI9ggQ9ggYWiIBYFoLCPcIEPcIGFoiAWBaCwj4CBD4CBhaIgFgWgsI+QgQ+QgYWiIBYFoLCPoIEPoIGFoiAWBaCwj7CBD7CBhaIgFgWgsI/AgQ/AgYWiIBYFoLCP0IEP0IGFoiAWBaCwj+CBD+CBhaIgFgWgsI/wgQ/wgYWiIBYFoLCIAJEIAJGFoiAWBaCwiBCRCBCRhaIgFgWgsIggkQggkYWiIBYFoLCIMJEIMJGFoiAWBaCwiECRCECRhaIgFgWgsIhQkQhQkYWiIBYFoLCIYJEIYJGFoiAWBaCwiHCRCHCRhaIgFgWgsIiAkQiAkYWiIBYFoLCIkJEIkJGFoiAWBaCwiKCRCKCRhaIgFgWgsIiwkQiwkYWiIBYFoLCIwJEIwJGFoiAWBaCwiNCRCNCRhaIgFgWgsIjgkQjgkYWiIBYFoLCI8JEI8JGFoiAWBaCwiQCRCQCRhaIgFgWgsIkQkQkQkYWiIBYFoLCJIJEJIJGFoiAWBaCwiTCRCTCRhaIgFgWgsIlAkQlAkYWiIBYFoLCJUJEJUJGFoiAWBaCwiWCRCWCRhaIgFgWgsIlwkQlwkYWiIBYFoLCJgJEJgJGFoiAWBaCwiZCRCZCRhaIgFgWgsImgkQmgkYWiIBYFoLCJsJEJsJGFoiAWBaCwicCRCcCRhaIgFgWgsInQkQnQkYWiIBYFoLCJ4JEJ4JGFoiAWBaCwifCRCfCRhaIgFgWgsIoAkQoAkYWiIBYFoLCKEJEKEJGFoiAWBaCwiiCRCiCRhaIgFgWgsIowkQowkYWiIBYFoLCKQJEKQJGFoiAWBaCwilCRClCRhaIgFgWgsIpgkQpgkYWiIBYFoLCKcJEKcJGFoiAWBaCwioCRCoCRhaIgFgWgsIqQkQqQkYWiIBYFoLCKoJEKoJGFoiAWBaCwirCRCrCRhaIgFgWgsIrAkQrAkYWiIBYFoLCK0JEK0JGFoiAWBaCwiuCRCuCRhaIgFgWgsIrwkQrwkYWiIBYFoLCLAJELAJGFoiAWBaCwixCRCxCRhaIgFgWgsIsgkQsgkYWiIBYFoLCLMJELMJGFoiAWBaCwi0CRC0CRhaIgFgWgsItQkQtQkYWiIBYFoLCLYJELYJGFoiAWBaCwi3CRC3CRhaIgFgWgsIuAkQuAkYWiIBYFoLCLkJELkJGFoiAWBaCwi6CRC6CRhaIgFgWgsIuwkQuwkYWiIBYFoLCLwJELwJGFoiAWBaCwi9CRC9CRhaIgFgWgsIvgkQvgkYWiIBYFoLCL8JEL8JGFoiAWBaCwjACRDACRhaIgFgWgsIwQkQwQkYWiIBYFoLCMIJEMIJGFoiAWBaCwjDCRDDCRhaIgFgWgsIxAkQxAkYWiIBYFoLCMUJEMUJGFoiAWBaCwjGCRDGCRhaIgFgWgsIxwkQxwkYWiIBYFoLCMgJEMgJGFoiAWBaCwjJCRDJCRhaIgFgWgsIygkQygkYWiIBYFoLCMsJEMsJGFoiAWBaCwjMCRDMCRhaIgFgWgsIzQkQzQkYWiIBYFoLCM4JEM4JGFoiAWBaCwjPCRDPCRhaIgFgWgsI0AkQ0AkYWiIBYFoLCNEJENEJGFoiAWBaCwjSCRDSCRhaIgFgWgsI0wkQ0wkYWiIBYFoLCNQJENQJGFoiAWBaCwjVCRDVCRhaIgFgWgsI1gkQ1gkYWiIBYFoLCNcJENcJGFoiAWBaCwjYCRDYCRhaIgFgWgsI2QkQ2QkYWiIBYFoLCNoJENoJGFoiAWBaCwjbCRDbCRhaIgFgWgsI3AkQ3AkYWiIBYFoLCN0JEN0JGFoiAWBaCwjeCRDeCRhaIgFgWgsI3wkQ3wkYWiIBYFoLCOAJEOAJGFoiAWBaCwjhCRDhCRhaIgFgWgsI4gkQ4gkYWiIBYFoLCOMJEOMJGFoiAWBaCwjkCRDkCRhaIgFgWgsI5QkQ5QkYWiIBYFoLCOYJEOYJGFoiAWBaCwjnCRDnCRhaIgFgWgsI6AkQ6AkYWiIBYFoLCOkJEOkJGFoiAWBaCwjqCRDqCRhaIgFgWgsI6wkQ6wkYWiIBYFoLCOwJEOwJGFoiAWBaCwjtCRDtCRhaIgFgWgsI7gkQ7gkYWiIBYFoLCO8JEO8JGFoiAWBaCwjwCRDwCRhaIgFgWgsI8QkQ8QkYWiIBYFoLCPIJEPIJGFoiAWBaCwjzCRDzCRhaIgFgWgsI9AkQ9AkYWiIBYFoLCPUJEPUJGFoiAWBaCwj2CRD2CRhaIgFgWgsI9wkQ9wkYWiIBYFoLCPgJEPgJGFoiAWBaCwj5CRD5CRhaIgFgWgsI+gkQ+gkYWiIBYFoLCPsJEPsJGFoiAWBaCwj8CRD8CRhaIgFgWgsI/QkQ/QkYWiIBYFoLCP4JEP4JGFoiAWBaCwj/CRD/CRhaIgFgWgsIgAoQgAoYWiIBYFoLCIEKEIEKGFoiAWBaCwiCChCCChhaIgFgWgsIgwoQgwoYWiIBYFoLCIQKEIQKGFoiAWBaCwiFChCFChhaIgFgWgsIhgoQhgoYWiIBYFoLCIcKEIcKGFoiAWBaCwiIChCIChhaIgFgWgsIiQoQiQoYWiIBYFoLCIoKEIoKGFoiAWBaCwiLChCLChhaIgFgWgsIjAoQjAoYWiIBYFoLCI0KEI0KGFoiAWBaCwiOChCOChhaIgFgWgsIjwoQjwoYWiIBYFoLCJAKEJAKGFoiAWBaCwiRChCRChhaIgFgWgsIkgoQkgoYWiIBYFoLCJMKEJMKGFoiAWBaCwiUChCUChhaIgFgWgsIlQoQlQoYWiIBYFoLCJYKEJYKGFoiAWBaCwiXChCXChhaIgFgWgsImAoQmAoYWiIBYFoLCJkKEJkKGFoiAWBaCwiaChCaChhaIgFgWgsImwoQmwoYWiIBYFoLCJwKEJwKGFoiAWBaCwidChCdChhaIgFgWgsIngoQngoYWiIBYFoLCJ8KEJ8KGFoiAWBaCwigChCgChhaIgFgWgsIoQoQoQoYWiIBYFoMCKIKEKIKGIgBIgFgWgwIowoQowoYiAEiAWBaCwikChCkChhtIgFgWgsIpQoQpQoYbSIBYFoLCKYKEKYKGG0iAWBaCwinChCnChhtIgFgWgsIqAoQqAoYbSIBYFoLCKkKEKkKGG0iAWBaCwiqChCqChhBIgFgWgsIqwoQqwoYQSIBYFoLCKwKEKwKGEEiAWBaCwitChCtChhBIgFgWgsIrgoQrgoYQSIBYFoLCK8KEK8KGEEiAWBaCwiwChCwChhBIgFgWgsIsQoQsQoYQSIBYFoLCLIKELIKGEEiAWBaCwizChCzChhBIgFgWgsItAoQtAoYQSIBYFoLCLUKELUKGEEiAWBaCwi2ChC2ChhBIgFgWgsItwoQtwoYQSIBYFoLCLgKELgKGEEiAWBaCwi5ChC5ChhBIgFgWgsIugoQugoYQSIBYFoLCLsKELsKGEEiAWBaCwi8ChC8ChhBIgFgWgsIvQoQvQoYQSIBYFoLCL4KEL4KGEEiAWBaCwi/ChC/ChhBIgFgWgsIwAoQwAoYQSIBYFoLCMEKEMEKGEEiAWBaCwjCChDCChhBIgFgWgsIwwoQwwoYQSIBYFoLCMQKEMQKGEEiAWBaCwjFChDFChhBIgFgWgsIxgoQxgoYQSIBYFoLCMcKEMcKGEEiAWBaCwjIChDIChhBIgFgWgsIyQoQyQoYQSIBYFoLCMoKEMoKGEEiAWBaCwjLChDLChhBIgFgWgsIzAoQzAoYQSIBYFoLCM0KEM0KGEEiAWBaCwjOChDOChhBIgFgWgsIzwoQzwoYQSIBYFoLCNAKENAKGEEiAWBaCwjRChDRChhBIgFgWgsI0goQ0goYQSIBYFoLCNMKENMKGEEiAWBaCwjUChDUChhBIgFgWgsI1QoQ1QoYQSIBYFoLCNYKENYKGEEiAWBaCwjXChDXChhBIgFgWgsI2AoQ2AoYQSIBYFoLCNkKENkKGEEiAWBaCwjaChDaChhBIgFgWgsI2woQ2woYQSIBYFoLCNwKENwKGEEiAWBaCwjdChDdChhBIgFgWgsI3goQ3goYQSIBYFoLCN8KEN8KGEEiAWBaCwjgChDgChhBIgFgWgsI4QoQ4QoYQSIBYFoLCOIKEOIKGEEiAWBaCwjjChDjChhBIgFgWgsI5AoQ5AoYQSIBYFoLCOUKEOUKGEEiAWBaCwjmChDmChhBIgFgWgsI5woQ5woYQSIBYFoLCOgKEOgKGEEiAWBaCwjpChDpChhBIgFgWgsI6goQ6goYQSIBYFoLCOsKEOsKGEEiAWBaCwjsChDsChhBIgFgWgsI7QoQ7QoYQSIBYFoLCO4KEO4KGEEiAWBaCwjvChDvChhBIgFgWgsI8AoQ8AoYQSIBYFoLCPEKEPEKGEEiAWBaCwjyChDyChhBIgFgWgsI8woQ8woYQSIBYFoLCPQKEPQKGEEiAWBaCwj1ChD1ChhBIgFgWgsI9goQ9goYQSIBYFoLCPcKEPcKGEEiAWBaCwj4ChD4ChhBIgFgWgsI+QoQ+QoYQSIBYFoLCPoKEPoKGEEiAWBaCwj7ChD7ChhBIgFgWgsI/AoQ/AoYQSIBYFoLCP0KEP0KGEEiAWBaCwj+ChD+ChhBIgFgWgsI/woQ/woYQSIBYFoLCIALEIALGEEiAWBaCwiBCxCBCxhBIgFgWgsIggsQggsYQSIBYFoLCIMLEIMLGEEiAWBaCwiECxCECxhBIgFgWgsIhQsQhQsYQSIBYFoLCIYLEIYLGEEiAWBaCwiHCxCHCxhBIgFgWgsIiAsQiAsYQSIBYFoLCIkLEIkLGEEiAWBaCwiKCxCKCxhBIgFgWgsIiwsQiwsYQSIBYFoLCIwLEIwLGEEiAWBaCwiNCxCNCxhBIgFgWgsIjgsQjgsYQSIBYFoLCI8LEI8LGEEiAWBaCwiQCxCQCxhBIgFgWgsIkQsQkQsYQSIBYFoLCJILEJILGEEiAWBaCwiTCxCTCxhBIgFgWgsIlAsQlAsYQSIBYFoLCJULEJULGEEiAWBaCwiWCxCWCxhBIgFgWgsIlwsQlwsYQSIBYFoLCJgLEJgLGEEiAWBaCwiZCxCZCxhBIgFgWgsImgsQmgsYQSIBYFoLCJsLEJsLGEEiAWBaCwicCxCcCxhBIgFgWgsInQsQnQsYQSIBYFoLCJ4LEJ4LGEEiAWBaCwifCxCfCxgxIgFgWgsIoAsQoAsYMSIBYFoLCKELEKELGDEiAWBaCwiiCxCiCxgxIgFgWgsIowsQowsYMSIBYFoLCKQLEKQLGDEiAWBaCwilCxClCxgxIgFgWgsIpgsQpgsYMSIBYFoLCKcLEKcLGDEiAWBaCwioCxCoCxgxIgFgWgsIqQsQqQsYMSIBYFoLCKoLEKoLGDEiAWBaCwirCxCrCxgxIgFgWgsIrAsQrAsYDyIBYFoLCK0LEK0LGA8iAWBaCwiuCxCuCxgPIgFgWgsIrwsQrwsYDyIBYFoLCLALELALGCciAWFaCwixCxCxCxgnIgFhWgsIsgsQsgsYJyIBYVoLCLMLELMLGCciAWFaCwi0CxC0Cxg3IgFhWgsItQsQtQsYNyIBYVoLCLYLELYLGEEiAWZaDAi3CxC3CxiLASIBZloMCLgLELgLGIwBIgFmWgsIuQsQuQsYfSIBZloMCLoLELoLGIsBIgFoWgsIuwsQuwsYXSIBaVoLCLwLELwLGF0iAWlaCwi9CxC9CxhdIgFpWgsIvgsQvgsYXSIBaVoLCL8LEL8LGF0iAWlaCwjACxDACxhdIgFpWgsIwQsQwQsYWiIBaVoLCMILEMILGFoiAWlaCwjDCxDDCxhaIgFpWgsIxAsQxAsYWiIBaVoLCMULEMULGFoiAWlaCwjGCxDGCxhaIgFpWgsIxwsQxwsYWiIBaVoLCMgLEMgLGFoiAWlaCwjJCxDJCxhaIgFpWgsIygsQygsYWiIBaVoLCMsLEMsLGFoiAWlaCwjMCxDMCxhaIgFpWgsIzQsQzQsYWiIBaVoMCM4LEM4LGI4BIgFpWgwIzwsQzwsYjgEiAWlaDAjQCxDQCxiOASIBaVoLCNELENELGFoiAWlaCwjSCxDSCxhaIgFpWgsI0wsQ0wsYWiIBaVoLCNQLENQLGFoiAWlaCwjVCxDVCxhaIgFpWgsI1gsQ1gsYWiIBaVoLCNcLENcLGFoiAWlaCwjYCxDYCxhaIgFpWgsI2QsQ2QsYWiIBaVoLCNoLENoLGFoiAWlaCwjbCxDbCxhaIgFpWgsI3AsQ3AsYWiIBaVoLCN0LEN0LGFoiAWlaCwjeCxDeCxhaIgFpWgsI3wsQ3wsYWiIBaVoLCOALEOALGFoiAWlaCwjhCxDhCxhaIgFpWgsI4gsQ4gsYWiIBaVoLCOMLEOMLGFoiAWlaCwjkCxDkCxhaIgFpWgsI5QsQ5QsYWiIBaVoLCOYLEOYLGFoiAWlaCwjnCxDnCxhaIgFpWgsI6AsQ6AsYWiIBaVoLCOkLEOkLGFoiAWlaCwjqCxDqCxhaIgFpWgsI6wsQ6wsYWiIBaVoLCOwLEOwLGFoiAWlaCwjtCxDtCxhaIgFpWgsI7gsQ7gsYWiIBaVoLCO8LEO8LGFoiAWlaCwjwCxDwCxhaIgFpWgsI8QsQ8QsYWiIBaVoLCPILEPILGFoiAWlaDAjzCxDzCxiPASIBaVoMCPQLEPQLGI8BIgFpWgwI9QsQ9QsYjwEiAWlaCwj2CxD2CxhBIgFpWgsI9wsQ9wsYQSIBaVoLCPgLEPgLGEEiAWlaCwj5CxD5CxhBIgFpWgsI+gsQ+gsYQSIBaVoLCPsLEPsLGEEiAWlaCwj8CxD8CxhBIgFpWgsI/QsQ/QsYQSIBaVoLCP4LEP4LGEEiAWlaCwj/CxD/CxhBIgFpWgsIgAwQgAwYQSIBaVoLCIEMEIEMGHkiAWlaCwiCDBCCDBhBIgFpWgsIgwwQgwwYQSIBaVoLCIQMEIQMGEEiAWlaCwiFDBCFDBhBIgFpWgsIhgwQhgwYQSIBaVoLCIcMEIcMGCsiAWlaCwiIDBCIDBgrIgFpWgwIiQwQiQwYkAEiAWlaDAiKDBCKDBiQASIBaVoMCIsMEIsMGJABIgFpWgwIjAwQjAwYkAEiAWlaDAiNDBCNDBiRASIBaVoMCI4MEI4MGJIBIgFpWgwIjwwQjwwYkgEiAWlaDAiQDBCQDBiSASIBaVoMCJEMEJEMGJIBIgFpWgwIkgwQkgwYkgEiAWlaDAiTDBCTDBiSASIBaVoMCJQMEJQMGJEBIgFpWgwIlQwQlQwYkQEiAWlaDAiWDBCWDBiRASIBaVoMCJcMEJcMGJEBIgFpWgwImAwQmAwYkQEiAWlaDAiZDBCZDBiRASIBaVoMCJoMEJoMGJMBIgFpWg0ImwwQmwwYdyIDamtsWg0InAwQnAwYdyIDamtsWg0InQwQnQwYPSIDamtsWg0IngwQngwYPSIDamtsWg0InwwQnwwYPSIDamtsWg0IoAwQoAwYPiIDamtsWg0IoQwQoQwYPiIDamtsWg4IogwQogwYZyIEamtsbVoOCKMMEKMMGGciBGprbG1aDgikDBCkDBhnIgRqa2xtWg4IpQwQpQwYZyIEamtsbVoOCKYMEKYMGGciBGprbG1aDginDBCnDBhnIgRqa2xtWg4IqAwQqAwYZyIEamtsbVoPCKkMEKkMGJQBIgRqa2xtWg0IqgwQqgwYbSIDamtsWg0IqwwQqwwYbSIDamtsWg0IrAwQrAwYQSIDamtsWg0IrQwQrQwYQSIDamtsWg0IrgwQrgwYQSIDamtsWg0IrwwQrwwYeSIDamtsWg0IsAwQsAwYeSIDamtsWg0IsQwQsQwYeiIDamtsWg0IsgwQsgwYeiIDamtsWg0IswwQswwYeiIDamtsWg0ItAwQtAwYeiIDamtsWg4ItQwQtQwYlQEiA2prbFoOCLYMELYMGJUBIgNqa2xaDAi3DBC3DBg9IgJrbFoMCLgMELgMGD0iAmtsWgwIuQwQuQwYQSICa2xaDAi6DBC6DBhBIgJrbFoLCLsMELsMGEEiAWtaDAi8DBC8DBh5IgJrbFoMCL0MEL0MGHkiAmtsWgsIvgwQvgwYZyIBbVoLCL8MEL8MGGciAW1aCwjADBDADBgCIgFuWgsIwQwQwQwYAiIBbloLCMIMEMIMGAIiAW5aCwjDDBDDDBgCIgFuWgsIxAwQxAwYQSIBdWIAYgcIARIDAAECYgYIAhICAQJiBQgDEgEBYgYIBBICAAFqtAESjwEtaWYgQGtvdGxpbnguc2VyaWFsaXphdGlvbi5TZXJpYWxpemFibGUgY2xhc3MgKioKIC1rZWVwLCBhbGxvd3Nocmlua2luZywgYWxsb3dvcHRpbWl6YXRpb24sIGFsbG93b2JmdXNjYXRpb24sIGFsbG93YWNjZXNzbW9kaWZpY2F0aW9uIGNsYXNzIDwxPiIGCAoQCxgCKhgSFgABAgMEBQYHCAkKCwwNDg8QERITFBVqmAEIARJ0LWlmIEBrb3RsaW54LnNlcmlhbGl6YXRpb24uU2VyaWFsaXphYmxlIGNsYXNzICoqCi1rZWVwY2xhc3NtZW1iZXJzIGNsYXNzIDwxPiB7CiAgICBzdGF0aWMgPDE+JENvbXBhbmlvbiBDb21wYW5pb247Cn0YASIGCAsQAxgBKhQaEgABAgMEBQYHCAkKCwwNDg8QEWrqAQgCEsoBLWlmIEBrb3RsaW54LnNlcmlhbGl6YXRpb24uU2VyaWFsaXphYmxlIGNsYXNzICoqIHsKICAgIHB1YmxpYyBzdGF0aWMgKiogSU5TVEFOQ0U7Cn0KLWtlZXBjbGFzc21lbWJlcnMgY2xhc3MgPDE+IHsKICAgIHB1YmxpYyBzdGF0aWMgPDE+IElOU1RBTkNFOwogICAga290bGlueC5zZXJpYWxpemF0aW9uLktTZXJpYWxpemVyIHNlcmlhbGl6ZXIoLi4uKTsKfRgBIgYICxARGAEqDwoBSBoEEhMUFSIEAAECA2rHAQgDEqIBLWlmIEBrb3RsaW54LnNlcmlhbGl6YXRpb24uU2VyaWFsaXphYmxlIGNsYXNzICoqIHsKICAgIHN0YXRpYyAqKiQqICo7Cn0KLWtlZXBjbGFzc21lbWJlcnMgY2xhc3MgPDI+JDwzPiB7CiAgICBrb3RsaW54LnNlcmlhbGl6YXRpb24uS1NlcmlhbGl6ZXIgc2VyaWFsaXplciguLi4pOwp9GAEiBggLEAkYASoUIhIEBQYHCAkKCwwNDg8QERITFBVqtQQIBBKaBC1pZiBjbGFzcyBhbmRyb2lkeC53aW5kb3cubGF5b3V0LmFkYXB0ZXIuc2lkZWNhci5TaWRlY2FyQ29tcGF0IHsKICBwdWJsaWMgKioqIHNldEV4dGVuc2lvbkNhbGxiYWNrKGFuZHJvaWR4LndpbmRvdy5sYXlvdXQuYWRhcHRlci5zaWRlY2FyLkV4dGVuc2lvbkludGVyZmFjZUNvbXBhdCRFeHRlbnNpb25DYWxsYmFja0ludGVyZmFjZSk7Cn0KLWtlZXAgY2xhc3MgYW5kcm9pZHgud2luZG93LmxheW91dC5hZGFwdGVyLnNpZGVjYXIuU2lkZWNhckNvbXBhdCRUcmFuc2xhdGluZ0NhbGxiYWNrLAogYW5kcm9pZHgud2luZG93LmxheW91dC5hZGFwdGVyLnNpZGVjYXIuRGlzdGluY3RFbGVtZW50U2lkZWNhckNhbGxiYWNrIHsKICBwdWJsaWMgKioqIG9uRGV2aWNlU3RhdGVDaGFuZ2VkKGFuZHJvaWR4LndpbmRvdy5zaWRlY2FyLlNpZGVjYXJEZXZpY2VTdGF0ZSk7CiAgcHVibGljICoqKiBvbldpbmRvd0xheW91dENoYW5nZWQoYW5kcm9pZC5vcy5JQmluZGVyLCBhbmRyb2lkeC53aW5kb3cuc2lkZWNhci5TaWRlY2FyV2luZG93TGF5b3V0SW5mbyk7Cn0YASIGCA0QEhgBKgoSAhYXIgQWFxgZam8IBRJfLWlmIGludGVyZmFjZSAqIHsgQHJldHJvZml0Mi5odHRwLiogPG1ldGhvZHM+OyB9Ci1rZWVwLGFsbG93b2JmdXNjYXRpb24gaW50ZXJmYWNlICogZXh0ZW5kcyA8MT4YAiIGCA4QIxgBKgBqaAgGElUtaWYgaW50ZXJmYWNlICogeyBAcmV0cm9maXQyLmh0dHAuKiA8bWV0aG9kcz47IH0KLWtlZXAsYWxsb3dvYmZ1c2NhdGlvbiBpbnRlcmZhY2UgPDE+GAIiBggOEB8YASoDEgEYaogBCAcSei1pZiBpbnRlcmZhY2UgKiB7IEByZXRyb2ZpdDIuaHR0cC4qIHB1YmxpYyAqKiogKiguLi4pOyB9Ci1rZWVwLGFsbG93b3B0aW1pemF0aW9uLGFsbG93c2hyaW5raW5nLGFsbG93b2JmdXNjYXRpb24gY2xhc3MgPDM+IgYIDhAsGAEqAGqoAQgIEo0BLWlmIHB1YmxpYyBjbGFzcyAqKiBleHRlbmRzIGFuZHJvaWR4LmZyYWdtZW50LmFwcC5GcmFnbWVudAota2VlcGNsYXNzZXN3aXRobWVtYmVycyxhbGxvd29iZnVzY2F0aW9uIHB1YmxpYyBjbGFzcyA8MT4gewogICAgcHVibGljIDxpbml0PigpOwp9GAIiBggSEBAYASoKEgMZGhsiAxobHGqcAggJEosCLWlmIHB1YmxpYyBjbGFzcyBhbmRyb2lkeC5jb21wb3NlLnVpLnBsYXRmb3JtLkFuZHJvaWRDb21wb3NpdGlvbkxvY2Fsc19hbmRyb2lkS3QgewogICAgcHVibGljIHN0YXRpYyAqKiogZ2V0TG9jYWxMaWZlY3ljbGVPd25lcigpOwp9Ci1rZWVwIHB1YmxpYyBjbGFzcyBhbmRyb2lkeC5jb21wb3NlLnVpLnBsYXRmb3JtLkFuZHJvaWRDb21wb3NpdGlvbkxvY2Fsc19hbmRyb2lkS3QgewogICAgcHVibGljIHN0YXRpYyAqKiogZ2V0TG9jYWxMaWZlY3ljbGVPd25lcigpOwp9GAEiBggTEA0YASoAaq4CCAoSnQItaWYgcHVibGljIGNsYXNzIGFuZHJvaWR4LmNvbXBvc2UudWkucGxhdGZvcm0uQW5kcm9pZENvbXBvc2l0aW9uTG9jYWxzX2FuZHJvaWRLdCB7CiAgICBwdWJsaWMgc3RhdGljICoqKiBnZXRMb2NhbFNhdmVkU3RhdGVSZWdpc3RyeU93bmVyKCk7Cn0KLWtlZXAgcHVibGljIGNsYXNzIGFuZHJvaWR4LmNvbXBvc2UudWkucGxhdGZvcm0uQW5kcm9pZENvbXBvc2l0aW9uTG9jYWxzX2FuZHJvaWRLdCB7CiAgICBwdWJsaWMgc3RhdGljICoqKiBnZXRMb2NhbFNhdmVkU3RhdGVSZWdpc3RyeU93bmVyKCk7Cn0YASIGCBQQDRgBKgBqQwgLEjMta2VlcCBAYW5kcm9pZC5zdXBwb3J0LmFubm90YXRpb24uS2VlcCBjbGFzcyAqIHsqO30YASIGCBUQRhgBKgBqUQgMEicta2VlcCBAYW5kcm9pZHguYW5ub3RhdGlvbi5LZWVwIGNsYXNzICoYASIGCCIQLBgBKhoKAQ0SFRwdHh8gISIjJCUmJygpKissLS4vMGqXAggNEiwta2VlcCBAYW5kcm9pZHguYW5ub3RhdGlvbi5LZWVwIGNsYXNzICogeyo7fRgBIgYIIxACGAEq2gESFRwdHh8gISIjJCUmJygpKissLS4vMBo5FhcYGRobHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2Nzg5Ojs8PT4/QEFCQ0RFRkdISUpLTE1OIoUBHR4fICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj9AQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVpbXF1eX2BhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ent8fX5/gAGBAYIBgwGEAYUBhgGHAYgBiQGKAYsBjAGNAY4BjwGQAWrzAQgOEm8ta2VlcCBAY29tLmdvb2dsZS5hbmRyb2lkLmdtcy5jb21tb24udXRpbC5EeW5hbWl0ZUFwaSBwdWJsaWMgY2xhc3MgKiB7CiAgcHVibGljIDxmaWVsZHM+OwogIHB1YmxpYyA8bWV0aG9kcz47Cn0YASIGCCIQRxgBKnQSAzEyMxoDT1BRImiRAZIBkwGUAZUBlgGXAZgBmQGaAZsBnAGdAZ4BnwGgAaEBogGjAaQBpQGmAacBqAGpAaoBqwGsAa0BrgGvAbABsQGyAbMBtAG1AbYBtwG4AbkBugG7AbwBvQG+Ab8BwAHBAcIBwwHEAWpACA8SMC1rZWVwIEBpbnRlcmZhY2UgYW5kcm9pZC5zdXBwb3J0LmFubm90YXRpb24uS2VlcBgBIgYIIhArGAEqAGo8CBASKS1rZWVwIEBpbnRlcmZhY2UgYW5kcm9pZHguYW5ub3RhdGlvbi5LZWVwGAEiBggiEDUYASoDEgE0alUIERJCLWtlZXAgQGludGVyZmFjZSBjb20uZ29vZ2xlLmFuZHJvaWQuZ21zLmNvbW1vbi5hbm5vdGF0aW9uLktlZXBOYW1lGAEiBggiED8YASoDEgE1alIIEhI/LWtlZXAgQGludGVyZmFjZSBjb20uZ29vZ2xlLmFuZHJvaWQuZ21zLmNvbW1vbi51dGlsLkR5bmFtaXRlQXBpGAEiBggiEEYYASoDEgE2amMIExJDLWtlZXAgY2xhc3MgKiBleHRlbmRzIGFuZHJvaWR4LnJvb20uUm9vbURhdGFiYXNlIHsgdm9pZCA8aW5pdD4oKTsgfRgBIgYIKRABGAEqEBIENzg5OiIIxQHGAccByAFqxwEIFBKgAS1rZWVwIGNsYXNzICogZXh0ZW5kcyBhbmRyb2lkeC5zdGFydHVwLkluaXRpYWxpemVyIHsKICAgICMgS2VlcCB0aGUgcHVibGljIG5vLWFyZ3VtZW50IGNvbnN0cnVjdG9yIHdoaWxlIGFsbG93aW5nIG90aGVyIG1ldGhvZHMgdG8gYmUgb3B0aW1pemVkLgogICAgPGluaXQ+KCk7Cn0YASIGCC8QBxgBKhYSBjs8PT4/QCIMyQHKAcsBzAHNAc4BamEIFRJRLWtlZXAgY2xhc3MgKiBpbXBsZW1lbnRzIGFuZHJvaWR4LmxpZmVjeWNsZS5HZW5lcmF0ZWRBZGFwdGVyIHsKICAgIDxpbml0PiguLi4pOwp9GAEiBggwEAoYASoAal4IFhJJLWtlZXAgY2xhc3MgKiBpbXBsZW1lbnRzIGFuZHJvaWR4LnZlcnNpb25lZHBhcmNlbGFibGUuVmVyc2lvbmVkUGFyY2VsYWJsZRgBIgYIMxABGAEqBRIDQUJDalkIFxJJLWtlZXAgY2xhc3MgKiBpbXBsZW1lbnRzIGNvbS5leGFtcGxlLm15bGlicmFyeS5TdGFydHVwVGFzayB7ICA8aW5pdD4oKTsgfRgBIgYINBADGAEqAGp0CBgSSi1rZWVwIGNsYXNzICogaW1wbGVtZW50cyBjb20uZ29vZ2xlLmZpcmViYXNlLmNvbXBvbmVudHMuQ29tcG9uZW50UmVnaXN0cmFyGAEiBgg1EAQYASoaEhgdRB4fRUYgISJHI0gkJUkmSicoKi0uLzBqOwgZEista2VlcCBjbGFzcyBhbmRyb2lkLnN1cHBvcnQuYW5ub3RhdGlvbi5LZWVwGAEiBggVEEQYASoAaj0IGhIqLWtlZXAgY2xhc3MgYW5kcm9pZHgud29yay5Xb3JrZXJQYXJhbWV0ZXJzGAEiBgg2EAoYASoDEgFLalkIGxJGLWtlZXAgY2xhc3MgY29tLmdvb2dsZS5hbmRyb2lkLmdtcy5jb21tb24uaW50ZXJuYWwuUmVmbGVjdGVkUGFyY2VsYWJsZRgBIgYIIhAkGAEqAxIBTGpxCBwSOy1rZWVwIGludGVyZmFjZSBhbmRyb2lkeC53aW5kb3cuYXJlYS5yZWZsZWN0aW9uZ3VhcmQuKiB7Kjt9GAEiBggNEBsYASojEgNNTk8iHM8B0AHRAdIB0wHUAdUB1gHXAdgB2QHaAdsB3AEyAQBqaQgdElIta2VlcCBpbnRlcmZhY2UgYW5kcm9pZHgud2luZG93LnJlZmxlY3Rpb24uQ29uc3VtZXIyIHsKICBwdWJsaWMgKioqIGFjY2VwdCgqKiopOwp9GAEiBggNECAYASoHEgFQIgLdAWppCB4SUi1rZWVwIGludGVyZmFjZSBhbmRyb2lkeC53aW5kb3cucmVmbGVjdGlvbi5KRnVuY3Rpb24yIHsKICBwdWJsaWMgKioqIGFwcGx5KCoqKik7Cn0YASIGCA0QJhgBKgcSAVEiAt4BamgIHxJRLWtlZXAgaW50ZXJmYWNlIGFuZHJvaWR4LndpbmRvdy5yZWZsZWN0aW9uLlByZWRpY2F0ZTIgewogIHB1YmxpYyAqKiogdGVzdCgqKiopOwp9GAEiBggNECMYASoHEgFSIgLfAWpYCCASNi1rZWVwIHB1YmxpYyBjbGFzcyBhbmRyb2lkLnN1cHBvcnQuKipQYXJjZWxpemVyIHsgKjsgfRgBIgYIMxACGAEqEhICU1QiDOAB4QHiAeMB5AHlAWpRCCESLy1rZWVwIHB1YmxpYyBjbGFzcyBhbmRyb2lkeC4qKlBhcmNlbGl6ZXIgeyAqOyB9GAEiBggzEAMYASoSEgJVViIM5gHnAegB6QHqAesBak0IIhI6LWtlZXAgcHVibGljIGNsYXNzIGFuZHJvaWR4LnZlcnNpb25lZHBhcmNlbGFibGUuUGFyY2VsSW1wbBgBIgYIMxAEGAEqAxIBV2pSCCMSQi1rZWVwIHB1YmxpYyBjbGFzcyBjb20uYW5kcm9pZC52ZW5kaW5nLmxpY2Vuc2luZy5JTGljZW5zaW5nU2VydmljZRgBIgYIFRAWGAEqAGpZCCQSSS1rZWVwIHB1YmxpYyBjbGFzcyBjb20uZ29vZ2xlLmFuZHJvaWQudmVuZGluZy5saWNlbnNpbmcuSUxpY2Vuc2luZ1NlcnZpY2UYASIGCBUQFxgBKgBqUQglEkEta2VlcCBwdWJsaWMgY2xhc3MgY29tLmdvb2dsZS52ZW5kaW5nLmxpY2Vuc2luZy5JTGljZW5zaW5nU2VydmljZRgBIgYIFRAVGAEqAGpNCCYSOi1rZWVwLGFsbG93b2JmdXNjYXRpb24gQGludGVyZmFjZSBhbmRyb2lkeC5hbm5vdGF0aW9uLktlZXAYAiIGCCMQARgBKgMSATRqYAgnEkUta2VlcCxhbGxvd29iZnVzY2F0aW9uLGFsbG93c2hyaW5raW5nIEBkYWdnZXIuaGlsdC5FbnRyeVBvaW50IGNsYXNzICoYAyIGCDkQAxgBKgsSCVhZWltcXV5fYGpiCCgSUi1rZWVwLGFsbG93b2JmdXNjYXRpb24sYWxsb3dzaHJpbmtpbmcgQGRhZ2dlci5oaWx0LmFuZHJvaWQuRWFybHlFbnRyeVBvaW50IGNsYXNzICoYAyIGCDkQBxgBKgBqZwgpElcta2VlcCxhbGxvd29iZnVzY2F0aW9uLGFsbG93c2hyaW5raW5nIEBkYWdnZXIuaGlsdC5pbnRlcm5hbC5Db21wb25lbnRFbnRyeVBvaW50IGNsYXNzICoYAyIGCDkQBRgBKgBqbAgqElcta2VlcCxhbGxvd29iZnVzY2F0aW9uLGFsbG93c2hyaW5raW5nIEBkYWdnZXIuaGlsdC5pbnRlcm5hbC5HZW5lcmF0ZWRFbnRyeVBvaW50IGNsYXNzICoYAyIGCDkQBhgBKgUSA2FiY2qCAggrEmIta2VlcCxhbGxvd29iZnVzY2F0aW9uLGFsbG93c2hyaW5raW5nIGNsYXNzICogZXh0ZW5kcyBhbmRyb2lkeC5jb21wb3NlLnVpLm5vZGUuTW9kaWZpZXJOb2RlRWxlbWVudBgDIgYIQxAhGAEqjwESjAFkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ent8fX5/gAGBAYIBgwGEAYUBhgGHAYgBiQGKAYsBjAGNAY4BjwGQAZEBkgGTAZQBlQGWAZcBmAGZAZoBmwGcAZ0BngGfAaABoQGiAaMBpAGlAaYBpwGoAakBqgGrAawBrQGuAa8BsAGxAbIBswG0AbUBtgG3AWp6CCwSZi1rZWVwLGFsbG93b2JmdXNjYXRpb24sYWxsb3dzaHJpbmtpbmcgY2xhc3MgY29tLmdvb2dsZS5zYW1wbGVzLmFwcHMubm93aW5hbmRyb2lkLk1haW5BY3Rpdml0eVZpZXdNb2RlbBgDIgYIRRABGAEqBBICuAFqjgEILRJ6LWtlZXAsYWxsb3dvYmZ1c2NhdGlvbixhbGxvd3Nocmlua2luZyBjbGFzcyBjb20uZ29vZ2xlLnNhbXBsZXMuYXBwcy5ub3dpbmFuZHJvaWQuZmVhdHVyZS5ib29rbWFya3MuaW1wbC5Cb29rbWFya3NWaWV3TW9kZWwYAyIGCEcQARgBKgQSArkBaogBCC4SdC1rZWVwLGFsbG93b2JmdXNjYXRpb24sYWxsb3dzaHJpbmtpbmcgY2xhc3MgY29tLmdvb2dsZS5zYW1wbGVzLmFwcHMubm93aW5hbmRyb2lkLmZlYXR1cmUuZm9yeW91LmltcGwuRm9yWW91Vmlld01vZGVsGAMiBghJEAEYASoEEgK6AWqOAQgvEnota2VlcCxhbGxvd29iZnVzY2F0aW9uLGFsbG93c2hyaW5raW5nIGNsYXNzIGNvbS5nb29nbGUuc2FtcGxlcy5hcHBzLm5vd2luYW5kcm9pZC5mZWF0dXJlLmludGVyZXN0cy5pbXBsLkludGVyZXN0c1ZpZXdNb2RlbBgDIgYISxABGAEqBBICuwFqiAEIMBJ0LWtlZXAsYWxsb3dvYmZ1c2NhdGlvbixhbGxvd3Nocmlua2luZyBjbGFzcyBjb20uZ29vZ2xlLnNhbXBsZXMuYXBwcy5ub3dpbmFuZHJvaWQuZmVhdHVyZS5zZWFyY2guaW1wbC5TZWFyY2hWaWV3TW9kZWwYAyIGCE0QARgBKgQSArwBaowBCDESeC1rZWVwLGFsbG93b2JmdXNjYXRpb24sYWxsb3dzaHJpbmtpbmcgY2xhc3MgY29tLmdvb2dsZS5zYW1wbGVzLmFwcHMubm93aW5hbmRyb2lkLmZlYXR1cmUuc2V0dGluZ3MuaW1wbC5TZXR0aW5nc1ZpZXdNb2RlbBgDIgYITxABGAEqBBICvQFqhgEIMhJyLWtlZXAsYWxsb3dvYmZ1c2NhdGlvbixhbGxvd3Nocmlua2luZyBjbGFzcyBjb20uZ29vZ2xlLnNhbXBsZXMuYXBwcy5ub3dpbmFuZHJvaWQuZmVhdHVyZS50b3BpYy5pbXBsLlRvcGljVmlld01vZGVsGAMiBghREAEYASoEEgK+AWpeCDMSSi1rZWVwLGFsbG93b2JmdXNjYXRpb24sYWxsb3dzaHJpbmtpbmcgY2xhc3Mga290bGluLmNvcm91dGluZXMuQ29udGludWF0aW9uGAMiBggOECkYASoEEgK/AWpSCDQSPi1rZWVwLGFsbG93b2JmdXNjYXRpb24sYWxsb3dzaHJpbmtpbmcgY2xhc3MgcmV0cm9maXQyLlJlc3BvbnNlGAMiBggOEDAYASoEEgLAAWq2AQg1Ep0BLWtlZXAsYWxsb3dzaHJpbmtpbmcgY2xhc3MgYW5kcm9pZHgud2luZG93LmxheW91dC5hZGFwdGVyLmV4dGVuc2lvbnMuTXVsdGljYXN0Q29uc3VtZXIgewogIHZvaWQgYWNjZXB0KGFuZHJvaWR4LndpbmRvdy5leHRlbnNpb25zLmxheW91dC5XaW5kb3dMYXlvdXRJbmZvKTsKfRgEIgYIDRAdGAEqCBICwQEiAuwBamQINhJQLWtlZXAsYWxsb3dzaHJpbmtpbmcgaW50ZXJmYWNlIGNvbS5nb29nbGUuZmlyZWJhc2UuY29tcG9uZW50cy5Db21wb25lbnRSZWdpc3RyYXIYBCIGCDUQBRgBKgQSAsIBaogBCDcSVi1rZWVwY2xhc3Nlc3dpdGhtZW1iZXJuYW1lcyxpbmNsdWRlZGVzY3JpcHRvcmNsYXNzZXMgY2xhc3MgKiB7CiAgICBuYXRpdmUgPG1ldGhvZHM+Owp9GAQiBggVEB0YASoiEgbDAcQBxQEiGO0B7gHvAfAB8QHyAfMB9AH1AfYB9wH4AWqRAQg4EoABLWtlZXBjbGFzc2Vzd2l0aG1lbWJlcm5hbWVzLGluY2x1ZGVkZXNjcmlwdG9yY2xhc3NlcyBjbGFzcyBhbmRyb2lkeC5kYXRhc3RvcmUuY29yZS5OYXRpdmVTaGFyZWRDb3VudGVyIHsKICAgIG5hdGl2ZSA8bWV0aG9kcz47Cn0YBCIGCFYQBxgBKgBqYgg5ElIta2VlcGNsYXNzZXN3aXRobWVtYmVycyBjbGFzcyAqIHsKICAgIEBhbmRyb2lkLnN1cHBvcnQuYW5ub3RhdGlvbi5LZWVwIDxmaWVsZHM+Owp9GAEiBggVEEwYASoAamUIOhJVLWtlZXBjbGFzc2Vzd2l0aG1lbWJlcnMgY2xhc3MgKiB7CiAgICBAYW5kcm9pZC5zdXBwb3J0LmFubm90YXRpb24uS2VlcCA8aW5pdD4oLi4uKTsKfRgBIgYIFRBQGAEqAGpjCDsSUy1rZWVwY2xhc3Nlc3dpdGhtZW1iZXJzIGNsYXNzICogewogICAgQGFuZHJvaWQuc3VwcG9ydC5hbm5vdGF0aW9uLktlZXAgPG1ldGhvZHM+Owp9GAEiBggVEEgYASoAal4IPBJOLWtlZXBjbGFzc2Vzd2l0aG1lbWJlcnMgY2xhc3MgKiB7CiAgICBAYW5kcm9pZHguYW5ub3RhdGlvbi5LZWVwIDxpbml0PiguLi4pOwp9GAEiBggjEAwYASoAanIIPRJJLWtlZXBjbGFzc2Vzd2l0aG1lbWJlcnMgY2xhc3MgKiB7CiAgQGFuZHJvaWR4LmFubm90YXRpb24uS2VlcCA8ZmllbGRzPjsKfRgBIgYIIhAtGAEqGRIExgHHARoRUlNUVVZXWFlaW1xdXl9gYWJq3wEIPhJKLWtlZXBjbGFzc2Vzd2l0aG1lbWJlcnMgY2xhc3MgKiB7CiAgQGFuZHJvaWR4LmFubm90YXRpb24uS2VlcCA8bWV0aG9kcz47Cn0YASIGCCIQMBgBKoQBEhfIAckBygEfywEmKMwBxwHNAc4BzwHQASJp+QH6AfsB/AH9Af4B/wGAAoECggKDAoQChQKGAocCiAKJAooCiwIljAI4PY0CjgKPApACkQKSApMClAKVApYClwKYApkCmgKbApwCnQKeAp8CoAKhAqICowKkAqUCpgKnAqgCqQKqAqsCanwIPxJRLWtlZXBjbGFzc2Vzd2l0aG1lbWJlcnMgY2xhc3MgYW5kcm9pZHguZ3JhcGhpY3MucGF0aC4qKiB7CiAgICBuYXRpdmUgPG1ldGhvZHM+Owp9GAEiBghYEAEYASoYEgTDAcQBIhDtAe4B7wHwAfEB8gHzAfQBMgEAaogBCEAScC1rZWVwY2xhc3Nlc3dpdGhtZW1iZXJzLGFsbG93b2JmdXNjYXRpb24gcHVibGljIGNsYXNzIGFuZHJvaWR4LmxpZmVjeWNsZS5SZXBvcnRGcmFnbWVudCB7CiAgICBwdWJsaWMgPGluaXQ+KCk7Cn0YAiIGCDAQFBgBKggSAtEBIgKsAmppCEESWS1rZWVwY2xhc3NtZW1iZXJuYW1lcyBjbGFzcyAqIHsKICBAY29tLmdvb2dsZS5hbmRyb2lkLmdtcy5jb21tb24uYW5ub3RhdGlvbi5LZWVwTmFtZSAqOwp9GAQiBggiEEEYASoAaq8BCEISjAEta2VlcGNsYXNzbWVtYmVybmFtZXMsYWxsb3dvYmZ1c2NhdGlvbixhbGxvd3Nocmlua2luZyBjbGFzcyBhbmRyb2lkeC5hcHBjb21wYXQud2lkZ2V0LkFwcENvbXBhdFRleHRWaWV3QXV0b1NpemVIZWxwZXIkSW1wbCogewogIDxtZXRob2RzPjsKfRgDIgYIWxAQGAEqEiIQrQKuAq8CsAKxArICswK0AmqiAQhDEnwta2VlcGNsYXNzbWVtYmVybmFtZXMsYWxsb3dvYmZ1c2NhdGlvbixhbGxvd3Nocmlua2luZyBjbGFzcyBhbmRyb2lkeC5jb3JlLmFwcC5Ob3RpZmljYXRpb25Db21wYXQkKiRBcGkqSW1wbCB7CiAgPG1ldGhvZHM+Owp9GAMiBghcEAgYASoWIhS1ArYCtwK4ArkCugK7ArwCvQK+AmqHAQhEEncta2VlcGNsYXNzbWVtYmVybmFtZXMsYWxsb3dvYmZ1c2NhdGlvbixhbGxvd3Nocmlua2luZyBjbGFzcyBhbmRyb2lkeC5jb3JlLm9zLlVzZXJIYW5kbGVDb21wYXQkQXBpKkltcGwgewogIDxtZXRob2RzPjsKfRgDIgYIXBALGAEqAGq/AQhFEm8ta2VlcGNsYXNzbWVtYmVybmFtZXMsYWxsb3dvYmZ1c2NhdGlvbixhbGxvd3Nocmlua2luZyBjbGFzcyBhbmRyb2lkeC5jb3JlLnZpZXcuVmlld0NvbXBh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QVRPUjsKfRgBIgYIFRAyGAEqcgoBUBpthQWGBYcFiAWJBYoFiwWMBY0FjgWPBZAFkQWSBZMFlAWVBZYFlwWYBZkFmgWbBZwFnQWeBZ8FoAWhBaIFowWkBaUFpgWnBagFqQWqBasFrAWtBa4FrwWwBbEFsgWzBbQFtQW2BbcFuAViuQW6BWrjAQhQEmEta2VlcGNsYXNzbWVtYmVycyBjbGFzcyAqIGltcGxlbWVudHMgYW5kcm9pZC5vcy5QYXJjZWxhYmxlIHsKICBwdWJsaWMgc3RhdGljIGZpbmFsICoqKiBDUkVBVE9SOwp9GAEiBggiECYYASpyCgFPGm2FBYYFhwWIBYkFigWLBYwFjQWOBY8FkAWRBZIFkwWUBZUFlgWXBZgFmQWaBZsFnAWdBZ4FnwWgBaEFogWjBaQFpQWmBacFqAWpBaoFqwWsBa0FrgWvBbAFsQWyBbMFtAW1BbYFtwW4BWK5BboFamAIURJQLWtlZXBjbGFzc21lbWJlcnMgY2xhc3MgKiB7CiAgICBAYW5kcm9pZC53ZWJraXQuSmF2YXNjcmlwdEludGVyZmFjZSA8bWV0aG9kcz47Cn0YASIGCBUQNxgBKgBqYwhSEkota2VlcGNsYXNzbWVtYmVycyBjbGFzcyAqKiB7CiAgICBAYW5kcm9pZHgubGlmZWN5Y2xlLk9uTGlmZWN5Y2xlRXZlbnQgKjsKfRgBIgYIMBAOGAEqCQoBPiIEjQKOAmq+AQhTEq0BLWtlZXBjbGFzc21lbWJlcnMgY2xhc3MgYW5kcm9pZHguY29tcG9zZS51aS5ncmFwaGljcy5sYXllci52aWV3LlBsYWNlaG9sZGVySGFyZHdhcmVDYW52YXMgewogICAgcHVibGljIGludCBkcmF3UmVuZGVyTm9kZSguLi4pOwogICAgcHVibGljIGJvb2xlYW4gaXNIYXJkd2FyZUFjY2VsZXJhdGVkKCk7Cn0YASIGCGwQHBgBKgBqmAEIVBKDAS1rZWVwY2xhc3NtZW1iZXJzIGNsYXNzIGFuZHJvaWR4LmNvbXBvc2UudWkuZ3JhcGhpY3MubGF5ZXIudmlldy5WaWV3TGF5ZXJDb250YWluZXIgewogICAgcHJvdGVjdGVkIHZvaWQgZGlzcGF0Y2hHZXREaXNwbGF5TGlzdCgpOwp9GAEiBghsEBkYASoEIgLkA2qfAQhVEooBLWtlZXBjbGFzc21lbWJlcnMgY2xhc3MgYW5kcm9pZHguY29tcG9zZS51aS5wbGF0Zm9ybS5BbmRyb2lkQ29tcG9zZVZpZXcgewogICAgYW5kcm9pZC52aWV3LlZpZXcgZmluZFZpZXdCeUFjY2Vzc2liaWxpdHlJZFRyYXZlcnNhbChpbnQpOwp9GAEiBghDEBoYASoEIgLlA2qIAQhWEngta2VlcGNsYXNzbWVtYmVycyBjbGFzcyBhbmRyb2lkeC5jb21wb3NlLnVpLnBsYXRmb3JtLlZpZXdMYXllckNvbnRhaW5lciB7CiAgICBwcm90ZWN0ZWQgdm9pZCBkaXNwYXRjaEdldERpc3BsYXlMaXN0KCk7Cn0YASIGCEMQFhgBKgBqhwEIVxJTLWtlZXBjbGFzc21lbWJlcnMgY2xhc3MgYW5kcm9pZHgubGlmZWN5Y2xlLlJlcG9ydEZyYWdtZW50JExpZmVjeWNsZUNhbGxiYWNrcyB7ICo7IH0YASIGCDAQGhgBKiQaArsFIh7mA+cD6APpA+oD6wPsA+0D7gPvA/AD8QPyA/MD9ANqhwIIWBLsAS1rZWVwY2xhc3NtZW1iZXJzIGNsYXNzIGFuZHJvaWR4LnRyYWNpbmcucGVyZmV0dG8uam5pLlBlcmZldHRvTmF0aXZlIHsKICAgIGphdmEubGFuZy5TdHJpbmcgbmF0aXZlVmVyc2lvbigpOwogICAgdm9pZCBuYXRpdmVSZWdpc3RlcldpdGhQZXJmZXR0bygpOwogICAgdm9pZCBuYXRpdmVUcmFjZUV2ZW50QmVnaW4oaW50LCBqYXZhLmxhbmcuU3RyaW5nKTsKICAgIHZvaWQgbmF0aXZlVHJhY2VFdmVudEVuZCgpOwp9GAEiBghuEAIYASoKIgj1AfYB9wH4AWrAAQhZEqsBLWtlZXBjbGFzc21lbWJlcnMgY2xhc3MgYW5kcm9pZHgudHJhbnNpdGlvbi5DaGFuZ2VCb3VuZHMkKiBleHRlbmRzIGFuZHJvaWQuYW5pbWF0aW9uLkFuaW1hdG9yTGlzdGVuZXJBZGFwdGVyIHsKICBhbmRyb2lkeC50cmFuc2l0aW9uLkNoYW5nZUJvdW5kcyRWaWV3Qm91bmRzIG1WaWV3Qm91bmRzOwp9GAEiBghwEBAYASoEGgK8BWriAQhaEn4ta2VlcGNsYXNzbWVtYmVycyBjbGFzcyBhbmRyb2lkeC52ZWN0b3JkcmF3YWJsZS5ncmFwaGljcy5kcmF3YWJsZS5WZWN0b3JEcmF3YWJsZUNvbXBhdCQqIHsKICAgdm9pZCBzZXQqKCoqKik7CiAgICoqKiBnZXQqKCk7Cn0YASIGCHIQEBgBKlQiUvUD9gP3A/gD+QP6A/sD/AP9A/4D/wOABIEEggSDBIQEhQSGBIcEiASJBIoEiwSMBI0EjgSPBJAEkQSSBJMElASVBJYElwSYBJkEmgSbBJwEnQRq0gEIWxLBAS1rZWVwY2xhc3NtZW1iZXJzIGNsYXNzIGNvbS5nb29nbGUuYW5kcm9pZC5nbXMuY29tbW9uLmFwaS5pbnRlcm5hbC5CYXNlUGVuZGluZ1Jlc3VsdCB7CiAgY29tLmdvb2dsZS5hbmRyb2lkLmdtcy5jb21tb24uYXBpLmludGVybmFsLkJhc2VQZW5kaW5nUmVzdWx0JFJlbGVhc2FibGVSZXN1bHRHdWFyZGlhbiBtUmVzdWx0R3VhcmRpYW47Cn0YASIGCHMQAhgBKgBqaQhcElUta2VlcGNsYXNzbWVtYmVycyBjbGFzcyBrb3RsaW4uY29yb3V0aW5lcy5TYWZlQ29udGludWF0aW9uIHsKICAgIHZvbGF0aWxlIDxmaWVsZHM+Owp9GAEiBgh0EAsYASoEGgK9BWrcAQhdEkgta2VlcGNsYXNzbWVtYmVycyBjbGFzcyBrb3RsaW54LmNvcm91dGluZXMuKiogewogICAgdm9sYXRpbGUgPGZpZWxkcz47Cn0YASIGCHQQBhgBKoABGn6+Bb8FwAXBBcIFwwXEBcUFxgXHBcgFyQXKBcsFzAXNBc4FzwXQBdEF0gXTBdQF1QXWBdcF2AXZBdoF2wXcBd0F3gXfBeAF4QXiBeMF5AXlBeYF5wXoBekF6gXrBewF7QXuBe8F8AXxBfIF8wX0BfUF9gX3BfgF+QX6BfsF/AUyAQBq4QYIXhJtLWtlZXBjbGFzc21lbWJlcnMgZW51bSAqIHsKICAgIHB1YmxpYyBzdGF0aWMgKipbXSB2YWx1ZXMoKTsKICAgIHB1YmxpYyBzdGF0aWMgKiogdmFsdWVPZihqYXZhLmxhbmcuU3RyaW5nKTsKfRgBIgYIFRAtGAEq4wUi4AWeBJ8EoAShBKIEowSkBKUEpgSnBKgEqQSqBKsErAStBK4ErwSwBLEEsgSzBLQEtQS2BLcEuAS5BLoEuwS8BL0EvgS/BMAEwQTCBMMExATFBMYExwTIBMkEygTLBMwEzQTOBM8E0ATRBNIE0wTUBNUE1gTXBNgE2QTaBNsE3ATdBN4E3wTgBOEE4gTjBOQE5QTmBOcE6ATpBOoE6wTsBO0E7gTvBPAE8QTyBPME9AT1BPYE9wT4BPkE+gT7BPwE/QT+BP8EgAWBBYIFgwWEBYUFhgWHBYgFiQWKBYsFjAWNBY4FjwWQBZEFkgWTBZQFlQWWBZcFmAWZBZoFmwWcBZ0FngWfBaAFoQWiBaMFpAWlBaYFpwWoBakFqgWrBawFrQWuBa8FsAWxBbIFswW0BbUFtgW3BbgFuQW6BbsFvAW9Bb4FvwXABcEFwgXDBcQFxQXGBccFyAXJBcoFywXMBc0FzgXPBdAF0QXSBdMF1AXVBdYF1wXYBdkF2gXbBdwF3QXeBd8F4AXhBeIF4wXkBeUF5gXnBegF6QXqBesF7AXtBe4F7wXwBfEF8gXzBfQF9QX2BfcF+AX5BfoF+wX8Bf0F/gX/BYAGgQaCBoMGhAaFBoYGhwaIBokGigaLBowGjQaOBo8GkAaRBpIGkwaUBpUGlgaXBpgGmQaaBpsGnAadBp4GnwagBqEGogajBqQGpQamBqcGqAapBqoGqwasBq0GrgavBrAGsQayBrMGtAa1BrYGtwa4BrkGuga7BrwGvQa+Br8GwAbBBsIGwwbEBsUGxgbHBsgGyQbKBssGzAbNBs4GzwbQBtEG0gbTBtQG1QbWBtcG2AbZBtoG2wbcBt0G3gbfBuAG4QbiBuMG5AblBuYG5wboBukG6gbrBuwG7QbuBu8G8AbxBvIG8wb0BvUG9gb3BvgG+Qb6BvsG/Ab9Bv4G/waAB4EHggeDB4QHhQeGB4cHiAeJB4oHiweMB40HanEIXxJLLWtlZXBjbGFzc21lbWJlcnMgZW51bSBhbmRyb2lkeC5saWZlY3ljbGUuTGlmZWN5Y2xlJEV2ZW50IHsKICAgIDxmaWVsZHM+Owp9GAEiBggwEAYYASoWGhT9Bf4F/wWABoEGggaDBoQGhQaGBmq6CQhgEmIta2VlcGNsYXNzbWVtYmVycyBwdWJsaWMgY2xhc3MgKiBleHRlbmRzIGFuZHJvaWQudmlldy5WaWV3IHsKICAgIHZvaWQgc2V0KigqKiopOwogICAgKioqIGdldCooKTsKfRgBIgYIFRAiGAEqxwgixAiOB48HkAeRB5IHkweUB5UHlgeXB5gHmQeaB5sHnAedB54HnwegB6EHogejB6QHpQemB6cHqAepB6oHqwesB60HrgevB7AHsQeyB7MHtAe1B7YHtwe4B7kHuge7B7wHvQe+B78HwAfBB8IHwwfEB8UHxgfHB8gHyQfKB8sHzAfNB84HzwfQB9EH0gfTB9QH1QfWB9cH2AfZB9oH2wfcB90H3gffB+AH4QfiB+MH5AflB+YH5wfoB+kH6gfrB+wH7QfuB+8H8AfxB/IH8wf0B/UH9gf3B/gH+Qf6B/sH/Af9B/4H/weACIEIggiDCIQIhQiGCIcIiAiJCIoIiwiMCI0IjgiPCJAIkQiSCJMIlAiVCJYIlwiYCJkImgibCJwInQieCJ8IoAihCKIIowikCKUIpginCKgIqQiqCKsIrAitCK4IrwiwCLEIsgizCLQItQi2CLcIuAi5CLoIuwi8CL0Ivgi/CMAIwQjCCMMIxAjFCMYIxwjICMkIygjLCMwIzQjOCM8I0AjRCNII0wjUCNUI1gjXCNgI2QjaCNsI3AjdCN4I3wjgCOEI4gjjCOQI5QjmCOcI6AjpCOoI6wjsCO0I7gjvCPAI8QjyCPMI9Aj1CPYI9wj4CPkI+gj7CPwI/Qj+CP8IgAmBCYIJgwmECYUJhgmHCYgJiQmKCYsJjAmNCY4JjwmQCZEJkgmTCZQJlQmWCZcJmAmZCZoJmwmcCZ0JngmfCaAJoQmiCaMJpAmlCaYJpwmoCakJqgmrCawJrQmuCa8JsAmxCbIJswm0CbUJtgm3CbgJuQm6CbsJvAm9Cb4JvwnACcEJwgnDCcQJxQnGCccJyAnJCcoJywnMCc0JzgnPCdAJ0QnSCdMJ1AnVCdYJ1wnYCdkJ2gnbCdwJ3QneCd8J4AnhCeIJ4wnkCeUJ5gnnCegJ6QnqCesJ7AntCe4J7wnwCfEJ8gnzCfQJ9Qn2CfcJ+An5CfoJ+wn8Cf0J/gn/CYAKgQqCCoMKhAqFCoYKhwqICokKigqLCowKjQqOCo8KkAqRCpIKkwqUCpUKlgqXCpgKmQqaCpsKnAqdCp4KnwqgCqEKogqjCqQKpQqmCqcKqAqpCqoKqwqsCq0KrgqvCrAKsQqyCrMKtAq1CrYKtwq4CrkKugq7CrwKvQq+Cr8KwArBCsIKwwrECsUKxgrHCsgKyQrKCssKzArNCs4KzwrQCtEK0grTCtQK1QrWCtcK2ArZCtoK2wrcCt0K3grfCuAK4QriCuMK5ArlCuYK5wroCukK6grrCuwK7QruCu8K8ArxCvIK8wr0CvUK9gr3CvgK+Qr6CvsK/Ar9Cv4K/wqAC4ELgguDC4QLhQuGC4cLiAuJC4oLiwuMC40LjguPC5ALkQuSC5MLlAuVC5YLlwuYC5kLmgubC5wLnQueC58LoAuhC6ILowukC6ULpgunC6gLqQuqC6sLrAutC64LrwtqgQEIYRJjLWtlZXBjbGFzc21lbWJlcnMgcHVibGljIGNsYXNzICogZXh0ZW5kcyBhbmRyb2lkeC53b3JrLkxpc3RlbmFibGVXb3JrZXIgewogICAgcHVibGljIDxpbml0PiguLi4pOwp9GAEiBgg2EAQYASoOIgywC7ELsguzC7QLtQtqbAhiEkwta2VlcGNsYXNzbWVtYmVycyBwdWJsaWMgY2xhc3MgKiokJHNlcmlhbGl6ZXIgewogICAgcHJpdmF0ZSAqKiBkZXNjcmlwdG9yOwp9GAEiBggLECcYASoQGg6HBogGiQaKBosGjAaNBmqWAQhjEoUBLWtlZXBjbGFzc21lbWJlcnMgcHVibGljIGNsYXNzIGNvbS5nb29nbGUuYW5kcm9pZC5nbXMuY29tbW9uLmludGVybmFsLnNhZmVwYXJjZWwuU2FmZVBhcmNlbGFibGUgewogICAgcHVibGljIHN0YXRpYyBmaW5hbCAqKiogTlVMTDsKfRgBIgYIIhAeGAEqAGqQAQhkEn8ta2VlcGNsYXNzbWVtYmVycyxhbGxvd29iZnVzY2F0aW9uIGNsYXNzICogZXh0ZW5kcyBhbmRyb2lkeC5saWZlY3ljbGUuQW5kcm9pZFZpZXdNb2RlbCB7CiAgICA8aW5pdD4oYW5kcm9pZC5hcHAuQXBwbGljYXRpb24pOwp9GAIiBwiJARAFGAEqAGq1AQhlEqMBLWtlZXBjbGFzc21lbWJlcnMsYWxsb3dvYmZ1c2NhdGlvbiBjbGFzcyAqIGV4dGVuZHMgYW5kcm9pZHgubGlmZWN5Y2xlLkFuZHJvaWRWaWV3TW9kZWwgewogICAgPGluaXQ+KGFuZHJvaWQuYXBwLkFwcGxpY2F0aW9uLGFuZHJvaWR4LmxpZmVjeWNsZS5TYXZlZFN0YXRlSGFuZGxlKTsKfRgCIgcIigEQBRgBKgBqfAhmEmEta2VlcGNsYXNzbWVtYmVycyxhbGxvd29iZnVzY2F0aW9uIGNsYXNzICogZXh0ZW5kcyBhbmRyb2lkeC5saWZlY3ljbGUuVmlld01vZGVsIHsKICAgIDxpbml0PigpOwp9GAIiBwiJARABGAEqCiIItgu3C7gLuQtqlgEIZxKEAS1rZWVwY2xhc3NtZW1iZXJzLGFsbG93b2JmdXNjYXRpb24gY2xhc3MgKiBleHRlbmRzIGFuZHJvaWR4LmxpZmVjeWNsZS5WaWV3TW9kZWwgewogICAgPGluaXQ+KGFuZHJvaWR4LmxpZmVjeWNsZS5TYXZlZFN0YXRlSGFuZGxlKTsKfRgCIgcIigEQARgBKgBqkQEIaBJ8LWtlZXBjbGFzc21lbWJlcnMsYWxsb3dvYmZ1c2NhdGlvbiBjbGFzcyAqIGltcGxlbWVudHMgYW5kcm9pZHguc2F2ZWRzdGF0ZS5TYXZlZFN0YXRlUmVnaXN0cnkkQXV0b1JlY3JlYXRlZCB7CiAgICA8aW5pdD4oKTsKfRgCIgcIjQEQDxgBKgQiAroLarACCGkSXC1rZWVwY2xhc3NtZW1iZXJzLGFsbG93b2JmdXNjYXRpb24gY2xhc3MgKiB7CiAgQGFuZHJvaWR4LmFubm90YXRpb24uRG9Ob3RJbmxpbmUgPG1ldGhvZHM+Owp9GAIiBggjEBAYASrDASLAAbsLvAu9C74LvwvAC8ELwgvDC8QLxQvGC8cLyAvJC8oLywvMC80LzgvPC9AL0QvSC9ML1AvVC9YL1wvYC9kL2gvbC9wL3QveC98L4AvhC+IL4wvkC+UL5gvnC+gL6QvqC+sL7AvtC+4L7wvwC/EL8gvzC/QL9Qv2C/cL+Av5C/oL+wv8C/0L/gv/C4AMgQyCDIMMhAyFDIYMhwyIDIkMigyLDIwMjQyODI8MkAyRDJIMkwyUDJUMlgyXDJgMmQyaDGqbAghqEssBLWtlZXBjbGFzc21lbWJlcnMsYWxsb3dzaHJpbmtpbmcsYWxsb3dvYmZ1c2NhdGlvbiBjbGFzcyBhbmRyb2lkeC5jb21wb3NlLioqLiogewogICAgc3RhdGljIHZvaWQgdGhyb3cqRXhjZXB0aW9uKC4uLik7CiAgICAjIEZvciBtZXRob2RzIHJldHVybmluZyBOb3RoaW5nCiAgICBzdGF0aWMgamF2YS5sYW5nLlZvaWQgdGhyb3cqRXhjZXB0aW9uKC4uLik7Cn0YAyIHCJYBEBIYASo+CgJrbCI4mwycDJ0MngyfDKAMoQyiDKMMpAylDKYMpwyoDKkMqgyrDKwMrQyuDK8MsAyxDLIMswy0DLUMtgxqoQQIaxLIAy1rZWVwY2xhc3NtZW1iZXJzLGFsbG93c2hyaW5raW5nLGFsbG93b2JmdXNjYXRpb24gY2xhc3MgYW5kcm9pZHguY29tcG9zZS4qKi4qIHsKICAgIHN0YXRpYyB2b2lkIHRocm93KkV4Y2VwdGlvbiguLi4pOwogICAgc3RhdGljIHZvaWQgdGhyb3cqRXhjZXB0aW9uRm9yTnVsbENoZWNrKC4uLik7CiAgICAjIEZvciBtZXRob2RzIHJldHVybmluZyBOb3RoaW5nCiAgICBzdGF0aWMgamF2YS5sYW5nLlZvaWQgdGhyb3cqRXhjZXB0aW9uKC4uLik7CiAgICBzdGF0aWMgamF2YS5sYW5nLlZvaWQgdGhyb3cqRXhjZXB0aW9uRm9yTnVsbENoZWNrKC4uLik7CiAgICAjIEZvciBmdW5jdGlvbnMgZ2VuZXJhdGluZyBlcnJvciBtZXNzYWdlcwogICAgc3RhdGljIGphdmEubGFuZy5TdHJpbmcgZXhjZXB0aW9uTWVzc2FnZSooLi4uKTsKICAgIGphdmEubGFuZy5TdHJpbmcgZXhjZXB0aW9uTWVzc2FnZSooLi4uKTsKfRgDIgYIQxAmGAEqSCJGmwycDJ0MtwyeDLgMnwygDKEMogyjDKQMpQymDKcMqAypDKoMqwysDLkMrQy6DK4MuwyvDLwMsAy9DLEMsgyzDLQMtQy2DGqUAwhsErkCLWtlZXBjbGFzc21lbWJlcnMsYWxsb3dzaHJpbmtpbmcsYWxsb3dvYmZ1c2NhdGlvbiBjbGFzcyBhbmRyb2lkeC5jb21wb3NlLioqLiogewogICAgc3RhdGljIHZvaWQgdGhyb3cqRXhjZXB0aW9uKC4uLik7CiAgICBzdGF0aWMgdm9pZCB0aHJvdypFeGNlcHRpb25Gb3JOdWxsQ2hlY2soLi4uKTsKICAgICMgRm9yIG1ldGhvZHMgcmV0dXJuaW5nIE5vdGhpbmcKICAgIHN0YXRpYyBqYXZhLmxhbmcuVm9pZCB0aHJvdypFeGNlcHRpb24oLi4uKTsKICAgIHN0YXRpYyBqYXZhLmxhbmcuVm9pZCB0aHJvdypFeGNlcHRpb25Gb3JOdWxsQ2hlY2soLi4uKTsKfRgDIgcIlwEQEhgBKkkKAWsiRJsMnAydDLcMngy4DJ8MoAyhDKIMowykDKUMpgynDKgMqQyqDKsMrAy5DK0MugyuDK8MvAywDL0MsQyyDLMMtAy1DLYMaugECG0SwAQta2VlcGNsYXNzbWVtYmVycyxhbGxvd3Nocmlua2luZyxhbGxvd29iZnVzY2F0aW9uIGNsYXNzIGFuZHJvaWR4LmNvbXBvc2UucnVudGltZS4qKiB7CiAgICAjIGphdmEubGFuZy5Wb2lkID09IG1ldGhvZHMgdGhhdCByZXR1cm4gTm90aGluZwogICAgc3RhdGljIHZvaWQgdGhyb3cqRXhjZXB0aW9uKC4uLik7CiAgICBzdGF0aWMgdm9pZCB0aHJvdypFeGNlcHRpb25Gb3JOdWxsQ2hlY2soLi4uKTsKICAgIHN0YXRpYyBqYXZhLmxhbmcuVm9pZCB0aHJvdypFeGNlcHRpb24oLi4uKTsKICAgIHN0YXRpYyBqYXZhLmxhbmcuVm9pZCB0aHJvdypFeGNlcHRpb25Gb3JOdWxsQ2hlY2soLi4uKTsKCiAgICAjIEZvciBmdW5jdGlvbnMgZ2VuZXJhdGluZyBlcnJvciBtZXNzYWdlcwogICAgc3RhdGljIGphdmEubGFuZy5TdHJpbmcgZXhjZXB0aW9uTWVzc2FnZSooLi4uKTsKICAgIGphdmEubGFuZy5TdHJpbmcgZXhjZXB0aW9uTWVzc2FnZSooLi4uKTsKCiAgICBzdGF0aWMgdm9pZCBjb21wb3NlKlJ1bnRpbWVFcnJvciguLi4pOwogICAgc3RhdGljIGphdmEubGFuZy5Wb2lkIGNvbXBvc2UqUnVudGltZUVycm9yKC4uLik7Cn0YAyIHCJgBEBQYASoWIhS+DL8MogyjDKQMpQymDKcMqAypDGp8CG4SYi1rZWVwY2xhc3NtZW1iZXJzLGFsbG93c2hyaW5raW5nLGFsbG93b2JmdXNjYXRpb24gaW50ZXJmYWNlICogewogICAgQHJldHJvZml0Mi5odHRwLiogPG1ldGhvZHM+Owp9GAMiBggOEAwYASoKIgjADMEMwgzDDGpwCG8SWC1rZWVwbmFtZXMgQGFuZHJvaWR4LmhpbHQud29yay5IaWx0V29ya2VyIGNsYXNzICogZXh0ZW5kcyBhbmRyb2lkeC53b3JrLkxpc3RlbmFibGVXb3JrZXIYBCIHCJkBEAIYASoHCgFzEgLSAWphCHASRS1rZWVwbmFtZXMgQGNvbS5nb29nbGUuYW5kcm9pZC5nbXMuY29tbW9uLmFubm90YXRpb24uS2VlcE5hbWUgY2xhc3MgKhgEIgYIIhBAGAEqDBIK0wHUAdUB1gHXAWpPCHESNy1rZWVwbmFtZXMgY2xhc3MgKiBleHRlbmRzIGFuZHJvaWR4LnN0YXJ0dXAuSW5pdGlhbGl6ZXIYBCIGCC8QAhgBKggSBjs8PT4/QGpICHISNC1rZWVwbmFtZXMgY2xhc3MgKiBleHRlbmRzIGFuZHJvaWR4LndvcmsuSW5wdXRNZXJnZXIYBCIGCDYQDRgBKgQSAtgBalcIcxI5LWtlZXBuYW1lcyBjbGFzcyAqIGV4dGVuZHMgYW5kcm9pZHgud29yay5MaXN0ZW5hYmxlV29ya2VyGAQiBgg2EAIYASoOEgzZAdoB2wHcAd0B0gFqcAh0Elgta2VlcG5hbWVzIGNsYXNzICogaW1wbGVtZW50cyBjb20uZ29vZ2xlLmFuZHJvaWQuZ21zLmNvbW1vbi5pbnRlcm5hbC5SZWZsZWN0ZWRQYXJjZWxhYmxlGAQiBggiECUYASoIEgbeAd8B4AFqbgh1ElYta2VlcG5hbWVzIGNsYXNzIGFuZHJvaWR4LmNvbXBvc2UudWkuaW5wdXQucG9pbnRlci5Qb2ludGVySW5wdXRFdmVudEhhbmRsZXIgewogICAgKjsKfRgEIgYIQxA0GAEqCBIC4QEiAsQMalgIdhJDLWtlZXBuYW1lcyBjbGFzcyBva2h0dHAzLmludGVybmFsLnB1YmxpY3N1ZmZpeC5QdWJsaWNTdWZmaXhEYXRhYmFzZRgEIgcImgEQBRgBKgQSAuIBehcIv6wCEMX9BBikig0gnXoo2YMCMLWWBQ==</script>
|
|
|
<script>// Copyright (c) 2026, the R8 project authors. Please see the AUTHORS file
|
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
/* ==========================================================================
|
|
|
APPLICATION LOGIC
|
|
|
==========================================================================
|
|
|
This script handles the interactive features of the Report.
|
|
|
It is divided into:
|
|
|
1. Constants & Configuration
|
|
|
2. UI Utilities (DOM helpers)
|
|
|
3. Main App Controller (Router)
|
|
|
4. ReportApp (The main table/grid view)
|
|
|
========================================================================== */
|
|
|
/**
|
|
|
* Global Constants used throughout the application.
|
|
|
*/
|
|
|
const CONSTANTS = {
|
|
|
VIEWS: {
|
|
|
MODULES: "modules",
|
|
|
PACKAGES: "packages",
|
|
|
DETAILS: "details",
|
|
|
FILE_DETAILS: "file-details"
|
|
|
},
|
|
|
DEFAULTS: {
|
|
|
AGGREGATED: "Aggregated"
|
|
|
},
|
|
|
};
|
|
|
/**
|
|
|
* UI Utilities
|
|
|
* Collection of helper functions for DOM manipulation and common UI patterns.
|
|
|
*/
|
|
|
const UIUtils = {
|
|
|
/**
|
|
|
* Returns the CSS class for score percentage coloring.
|
|
|
* @param {number|string} percentage - The score percentage (0-100 or "--").
|
|
|
* @returns {string} CSS class name.
|
|
|
*/
|
|
|
getScoreClass(percentage) {
|
|
|
if (percentage === "--") return "text-gray-500";
|
|
|
if (percentage >= 80) return "text-green-600";
|
|
|
if (percentage >= 60) return "text-yellow-600";
|
|
|
return "text-red-600";
|
|
|
},
|
|
|
getMatchClass(percentage) {
|
|
|
if (percentage === "--") return "text-gray-500";
|
|
|
if (percentage < 10) return "text-green-600";
|
|
|
if (percentage < 20) return "text-orange-600";
|
|
|
return "text-red-600";
|
|
|
},
|
|
|
/**
|
|
|
* Toggles the visibility of a DOM element.
|
|
|
* @param {HTMLElement} element - The element to toggle.
|
|
|
* @param {boolean} show - Whether to show or hide.
|
|
|
*/
|
|
|
toggleVisibility(element, show) {
|
|
|
if (!element) return;
|
|
|
if (show) {
|
|
|
element.classList.remove("hidden");
|
|
|
// Restore appropriate display type
|
|
|
if (element.id === "ts-selected-state") {
|
|
|
element.style.display = "flex";
|
|
|
} else {
|
|
|
element.style.display = "";
|
|
|
}
|
|
|
} else {
|
|
|
element.classList.add("hidden");
|
|
|
element.style.display = "none";
|
|
|
}
|
|
|
},
|
|
|
/**
|
|
|
* Builds a multi-select dropdown with "Select All" / "Clear" actions (Zone A)
|
|
|
* and a scrollable list of options (Zone B).
|
|
|
*
|
|
|
* @param {string} containerId - ID of the dropdown container.
|
|
|
* @param {Array} options - List of options {name, value}.
|
|
|
* @param {Array} selectedStateArr - Array storing currently selected values.
|
|
|
* @param {Function} onSelectionChange - Callback when selection changes.
|
|
|
* @param {boolean} searchable - Whether to include a search box.
|
|
|
* @param {boolean} multiSelect - Whether to allow multiple selections.
|
|
|
*/
|
|
|
buildActionDropdown(containerId, options, selectedStateArr,
|
|
|
onSelectionChange, searchable = true, multiSelect = true, totalCount =
|
|
|
null, itemName = "items", searchCallback = null) {
|
|
|
const container = document.getElementById(containerId);
|
|
|
if (!container) return;
|
|
|
// Container config
|
|
|
container.innerHTML = "";
|
|
|
container.style.padding = "0";
|
|
|
container.style.overflow = "hidden"; // Clip corners
|
|
|
// --- ZONE 0: Search (Top Level) ---
|
|
|
let searchInput = null;
|
|
|
if (searchable) {
|
|
|
const searchContainer = document.createElement("div");
|
|
|
searchContainer.className = "dropdown-search-zone";
|
|
|
searchContainer.style.padding = "0.5rem";
|
|
|
searchContainer.style.borderBottom = "1px solid var(--border-color)";
|
|
|
searchContainer.style.background = "var(--bg-surface)";
|
|
|
searchInput = document.createElement("input");
|
|
|
searchInput.type = "text";
|
|
|
searchInput.className = "popover-search";
|
|
|
searchInput.style.width = "100%";
|
|
|
searchInput.placeholder = "Search...";
|
|
|
searchContainer.appendChild(searchInput);
|
|
|
container.appendChild(searchContainer);
|
|
|
}
|
|
|
// --- ZONE B: Option List ---
|
|
|
const listZone = document.createElement("div");
|
|
|
listZone.className = "dropdown-scroll-zone";
|
|
|
container.appendChild(listZone);
|
|
|
// Render List Logic
|
|
|
const renderList = (optionsToRender) => {
|
|
|
listZone.innerHTML = "";
|
|
|
if (optionsToRender.length === 0) {
|
|
|
listZone.innerHTML =
|
|
|
`<div class="p-4 text-xs text-gray-400 text-center">No options available</div>`;
|
|
|
return;
|
|
|
}
|
|
|
optionsToRender.forEach(opt => {
|
|
|
// SKIP "All" options if they exist in the passed options list.
|
|
|
if (opt.value === "all") return;
|
|
|
const isChecked = selectedStateArr.includes(opt.value);
|
|
|
const item = document.createElement(multiSelect ? "label" :
|
|
|
"div");
|
|
|
item.className = "popover-item" + (isChecked && !multiSelect ?
|
|
|
" active-item" : "");
|
|
|
let checkbox = null;
|
|
|
if (multiSelect) {
|
|
|
checkbox = document.createElement("input");
|
|
|
checkbox.type = "checkbox";
|
|
|
checkbox.className = "popover-checkbox";
|
|
|
checkbox.checked = isChecked;
|
|
|
item.appendChild(checkbox);
|
|
|
}
|
|
|
const label = document.createElement("span");
|
|
|
label.innerHTML = opt.name;
|
|
|
item.appendChild(label);
|
|
|
// Interaction: Toggle Individual
|
|
|
const handleSelect = (e) => {
|
|
|
if (multiSelect) {
|
|
|
if (checkbox.checked) {
|
|
|
if (!selectedStateArr.includes(opt.value))
|
|
|
selectedStateArr.push(opt.value);
|
|
|
} else {
|
|
|
const idx = selectedStateArr.indexOf(opt.value);
|
|
|
if (idx > -1) selectedStateArr.splice(idx, 1);
|
|
|
}
|
|
|
} else {
|
|
|
selectedStateArr.length = 0;
|
|
|
selectedStateArr.push(opt.value);
|
|
|
}
|
|
|
if (!multiSelect) {
|
|
|
renderList(optionsToRender);
|
|
|
}
|
|
|
onSelectionChange();
|
|
|
};
|
|
|
if (multiSelect) {
|
|
|
item.addEventListener("change", (e) => {
|
|
|
e.stopPropagation();
|
|
|
handleSelect(e);
|
|
|
});
|
|
|
} else {
|
|
|
item.addEventListener("click", (e) => {
|
|
|
e.stopPropagation();
|
|
|
handleSelect(e);
|
|
|
});
|
|
|
}
|
|
|
listZone.appendChild(item);
|
|
|
});
|
|
|
};
|
|
|
renderList(options);
|
|
|
// --- ZONE C: Footer ---
|
|
|
let footer = null;
|
|
|
if (totalCount !== null) {
|
|
|
footer = document.createElement("div");
|
|
|
footer.className = "dropdown-footer";
|
|
|
footer.style.padding = "0.5rem 1rem";
|
|
|
footer.style.fontSize = "0.75rem";
|
|
|
footer.style.color = "var(--text-gray-400)";
|
|
|
footer.style.borderTop = "1px solid var(--border-color)";
|
|
|
footer.style.background = "var(--bg-subtle)";
|
|
|
footer.textContent =
|
|
|
`Showing ${options.length} out of ${totalCount} ${itemName}`;
|
|
|
container.appendChild(footer);
|
|
|
}
|
|
|
// --- Search Logic ---
|
|
|
if (searchInput) {
|
|
|
searchInput.addEventListener("input", (e) => {
|
|
|
const term = e.target.value.toLowerCase();
|
|
|
if (searchCallback) {
|
|
|
const {
|
|
|
options: filteredOptions,
|
|
|
total: mCount
|
|
|
} = searchCallback(term);
|
|
|
renderList(filteredOptions);
|
|
|
if (footer) {
|
|
|
footer.textContent =
|
|
|
`Showing ${filteredOptions.length} out of ${mCount} ${itemName}`;
|
|
|
}
|
|
|
} else {
|
|
|
const items = listZone.querySelectorAll(".popover-item");
|
|
|
let visibleCount = 0;
|
|
|
items.forEach(item => {
|
|
|
const label = item.querySelector("span").textContent
|
|
|
.toLowerCase();
|
|
|
const isVisible = label.includes(term);
|
|
|
item.style.display = isVisible ? "flex" : "none";
|
|
|
if (isVisible) visibleCount++;
|
|
|
});
|
|
|
if (footer && totalCount !== null) {
|
|
|
footer.textContent =
|
|
|
`Showing ${visibleCount} out of ${totalCount} ${itemName}`;
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
},
|
|
|
/**
|
|
|
* Renders the text on the filter chip (e.g., "Module: All" or "Module: :core:network (+2)").
|
|
|
*/
|
|
|
renderChipText(element, label, type, isMulti = false) {
|
|
|
if (!element) return;
|
|
|
// Logic for displaying close button: ALWAYS show if 'type' is present (meaning removable)
|
|
|
// The user specifically requested option to remove filter when all items are selected.
|
|
|
const showClose = !!type;
|
|
|
if (!showClose) {
|
|
|
element.innerHTML = `<span class="filter-text">${label}</span>`;
|
|
|
} else {
|
|
|
element.innerHTML = `
|
|
|
<span class="filter-text">${label}</span>
|
|
|
<span class="chip-close" data-clear="${type}">
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" width="14" height="14">
|
|
|
<path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"/>
|
|
|
</svg>
|
|
|
</span>`;
|
|
|
}
|
|
|
},
|
|
|
getFilterLabel(prefix, selectedArr, totalCount, options = []) {
|
|
|
if (selectedArr.length === 0 || (totalCount > 0 && selectedArr.length ===
|
|
|
totalCount)) return `${prefix}: All`;
|
|
|
if (selectedArr.length === 1) {
|
|
|
const val = selectedArr[0];
|
|
|
const opt = options.find(o => String(o.value) === String(val));
|
|
|
const name = opt ? opt.name : val;
|
|
|
// Strip HTML tags if any (like in keepRuleOptions)
|
|
|
const cleanName = name.replace(/<[^>]*>/g, "");
|
|
|
return `${prefix}: ${cleanName}`;
|
|
|
}
|
|
|
return `${prefix}: ${selectedArr.length} Selected`;
|
|
|
},
|
|
|
/**
|
|
|
* Finds the common prefix among an array of strings.
|
|
|
* @param {string[]} strings - Array of strings to analyze.
|
|
|
* @returns {string} The common prefix.
|
|
|
*/
|
|
|
findCommonPrefix(strings) {
|
|
|
if (!strings || strings.length === 0) return "";
|
|
|
let prefix = strings[0];
|
|
|
for (let i = 1; i < strings.length; i++) {
|
|
|
if (strings[i].startsWith("Android Gradle plugin")) {
|
|
|
continue;
|
|
|
}
|
|
|
while (strings[i].indexOf(prefix) !== 0) {
|
|
|
prefix = prefix.substring(0, prefix.length - 1);
|
|
|
if (prefix === "") return "";
|
|
|
}
|
|
|
}
|
|
|
// Ensure we only strip up to the last slash to keep the filename.
|
|
|
const lastSlash = prefix.lastIndexOf('/');
|
|
|
if (lastSlash !== -1) {
|
|
|
return prefix.substring(0, lastSlash + 1);
|
|
|
}
|
|
|
return "";
|
|
|
}
|
|
|
};
|
|
|
/* ==========================================================================
|
|
|
MAIN APP CONTROLLER
|
|
|
========================================================================== */
|
|
|
const App = {
|
|
|
keepRadiusData: null,
|
|
|
lookups: {},
|
|
|
detailsState: {
|
|
|
ruleId: null,
|
|
|
classQuery: "",
|
|
|
fieldQuery: "",
|
|
|
methodQuery: ""
|
|
|
},
|
|
|
init() {
|
|
|
// Initialize Report (Main Grid)
|
|
|
ReportApp.init();
|
|
|
// Load Protobuf Data in the Background
|
|
|
this.loadProtoData();
|
|
|
|
|
|
const headerLink = document.getElementById("header-link");
|
|
|
if (headerLink) {
|
|
|
headerLink.addEventListener("click", (e) => {
|
|
|
e.preventDefault();
|
|
|
this.showReportView();
|
|
|
});
|
|
|
}
|
|
|
|
|
|
// Setup Kept Lists Search listeners
|
|
|
const setupListSearch = (type, stateKey) => {
|
|
|
const toggleBtn = document.querySelector(`.search-toggle-btn[data-target="${type}"]`);
|
|
|
const container = document.getElementById(`${type}-search-container`);
|
|
|
const input = document.getElementById(`${type}-search-input`);
|
|
|
|
|
|
if (toggleBtn && container && input) {
|
|
|
toggleBtn.addEventListener("click", () => {
|
|
|
const isHidden = container.style.display === "none";
|
|
|
container.style.display = isHidden ? "block" : "none";
|
|
|
toggleBtn.classList.toggle("active", isHidden);
|
|
|
if (isHidden) {
|
|
|
input.focus();
|
|
|
} else {
|
|
|
// Clear query when closing search
|
|
|
input.value = "";
|
|
|
App.detailsState[stateKey] = "";
|
|
|
const rule = App.keepRadiusData?.keepRuleKeepRadiusTable.find(r => r.id === parseInt(App.detailsState.ruleId));
|
|
|
if (rule) App.renderKeptLists(rule, type);
|
|
|
}
|
|
|
});
|
|
|
|
|
|
input.addEventListener("input", (e) => {
|
|
|
App.detailsState[stateKey] = e.target.value;
|
|
|
const rule = App.keepRadiusData?.keepRuleKeepRadiusTable.find(r => r.id === parseInt(App.detailsState.ruleId));
|
|
|
if (rule) App.renderKeptLists(rule, type);
|
|
|
});
|
|
|
}
|
|
|
};
|
|
|
|
|
|
setupListSearch("classes", "classQuery");
|
|
|
setupListSearch("fields", "fieldQuery");
|
|
|
setupListSearch("methods", "methodQuery");
|
|
|
},
|
|
|
showDetailsView(ruleId) {
|
|
|
this.detailsState.ruleId = ruleId;
|
|
|
this.detailsState.classQuery = "";
|
|
|
this.detailsState.fieldQuery = "";
|
|
|
this.detailsState.methodQuery = "";
|
|
|
ReportApp.state.currentView = CONSTANTS.VIEWS.DETAILS;
|
|
|
document.getElementById("report-view").style.display = "none";
|
|
|
document.getElementById("file-details-view").style.display = "none";
|
|
|
document.getElementById("report-view-controls").style.display = "none";
|
|
|
document.getElementById("details-view").style.display = "flex";
|
|
|
const ruleContainer = document.getElementById("details-rule-container");
|
|
|
const impactContainer = document.getElementById("details-impact-container");
|
|
|
const identicalRulesBody = document.getElementById(
|
|
|
"details-identical-rules-body");
|
|
|
const identicalRulesHeader = document.getElementById(
|
|
|
"details-identical-rules-header");
|
|
|
const identicalRulesTitle = document.getElementById(
|
|
|
"details-identical-rules-title");
|
|
|
const subsumedByBody = document.getElementById(
|
|
|
"details-subsumed-by-body");
|
|
|
const subsumedByHeader = document.getElementById(
|
|
|
"details-subsumed-by-header");
|
|
|
const subsumedByTitle = document.getElementById(
|
|
|
"details-subsumed-by-title");
|
|
|
const impactHeader = document.getElementById(
|
|
|
"details-rule-impact-header");
|
|
|
const classesContent = document.getElementById("details-classes-content");
|
|
|
const methodsContent = document.getElementById("details-methods-content");
|
|
|
const fieldsContent = document.getElementById("details-fields-content");
|
|
|
let rule = this.keepRadiusData?.keepRuleKeepRadiusTable.find(r => r.id === parseInt(ruleId));
|
|
|
let isGlobal = false;
|
|
|
if (!rule) {
|
|
|
rule = this.keepRadiusData?.globalKeepRuleKeepRadiusTable.find(r => r.id === parseInt(ruleId));
|
|
|
isGlobal = true;
|
|
|
}
|
|
|
|
|
|
if (rule) {
|
|
|
const fileOriginId = rule?.origin?.fileOriginId;
|
|
|
const fileOrigin = this.keepRadiusData?.fileOriginTable.find(f => f
|
|
|
.id === fileOriginId);
|
|
|
let originStr = "";
|
|
|
if (fileOrigin) {
|
|
|
const mavenName = formatMavenCoordinate(fileOrigin.mavenCoordinate);
|
|
|
originStr =
|
|
|
`${mavenName || fileOrigin.filename}:${rule.origin?.lineNumber || 1}`;
|
|
|
if (mavenName) {
|
|
|
originStr += ` (${fileOrigin.filename})`;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (ruleContainer) {
|
|
|
const highlightedSource = highlightRule(rule.source);
|
|
|
|
|
|
ruleContainer.innerHTML = `
|
|
|
${originStr ? `<div style="font-size: 0.75rem; color: var(--text-gray-500); margin-bottom: 0.5rem; font-family: var(--font-family-mono);">${escapeHTML(originStr)}</div>` : ""}
|
|
|
<div style="background-color: var(--bg-body); border: 1px solid var(--border-color); border-radius: 4px; padding: 0.75rem;">
|
|
|
<pre style="white-space: pre-wrap; font-family: var(--font-family-mono); font-size: 0.8125rem; margin: 0; color: var(--text-main);">${highlightedSource}</pre>
|
|
|
</div>
|
|
|
`;
|
|
|
}
|
|
|
|
|
|
const impactContainer = document.getElementById("details-impact-container");
|
|
|
const relatedRulesContainer = document.getElementById("related-rules-container");
|
|
|
const gridContainer = document.getElementById("details-classes-content")?.parentElement?.parentElement;
|
|
|
|
|
|
if (isGlobal) {
|
|
|
if (impactContainer) impactContainer.parentElement.style.display = "none";
|
|
|
if (relatedRulesContainer) relatedRulesContainer.style.display = "none";
|
|
|
if (gridContainer) gridContainer.style.display = "none";
|
|
|
} else {
|
|
|
if (impactContainer) impactContainer.parentElement.style.display = "";
|
|
|
if (relatedRulesContainer) relatedRulesContainer.style.display = "";
|
|
|
if (gridContainer) gridContainer.style.display = "grid";
|
|
|
|
|
|
const constraintsMap = getConstraintsMap(this.keepRadiusData);
|
|
|
const constraints = constraintsMap.get(rule.constraintsId) || [];
|
|
|
const getTag = (c, label) => {
|
|
|
const isRestricted = constraints.includes(c);
|
|
|
if (!isRestricted) return "";
|
|
|
const color = "oklch(0.446 0.043 257.281)";
|
|
|
const bgColor = "oklch(0.984 0.003 247.858)";
|
|
|
const borderColor = "oklch(0.929 0.013 255.508)";
|
|
|
return `<span class="impact-tag" style="display: inline-block; color: ${color}; background-color: ${bgColor}; border: 1px solid ${borderColor}; border-radius: 4px; padding: 2px 8px; font-size: 10px; font-weight: 400; height: 21px; line-height: 15px; text-transform: uppercase; letter-spacing: 0.25px; box-sizing: border-box; text-align: center;">${label}</span>`;
|
|
|
};
|
|
|
const impactTagsHtml = `
|
|
|
<div class="impact-container">
|
|
|
${getTag('DONT_OBFUSCATE', 'OBFUSCATE')}
|
|
|
${getTag('DONT_OPTIMIZE', 'OPTIMIZE')}
|
|
|
${getTag('DONT_SHRINK', 'SHRINK')}
|
|
|
</div>
|
|
|
`;
|
|
|
|
|
|
const br = rule.keepRadius || {};
|
|
|
const classIds = br.classKeepRadius || [];
|
|
|
const fieldIds = br.fieldKeepRadius || [];
|
|
|
const methodIds = br.methodKeepRadius || [];
|
|
|
const matchedTotal = classIds.length + fieldIds.length + methodIds
|
|
|
.length;
|
|
|
const totalLive = getLiveItemCount(this.keepRadiusData);
|
|
|
const liveClasses = this.keepRadiusData?.buildInfo?.liveClassCount ||
|
|
|
0;
|
|
|
const liveFields = this.keepRadiusData?.buildInfo?.liveFieldCount || 0;
|
|
|
const liveMethods = this.keepRadiusData?.buildInfo?.liveMethodCount ||
|
|
|
0;
|
|
|
const renderMatchCell = (count, total, borderLeft = true) => {
|
|
|
const perc = total > 0 ? (count / total * 100) : 0;
|
|
|
const colorClass = UIUtils.getMatchClass(perc);
|
|
|
const bl = borderLeft ? "border-l border-gray-200" : "";
|
|
|
return `
|
|
|
<td class="text-center ${bl}" style="padding: 1rem; width: 100px; min-width: 100px;">
|
|
|
<div style="display: flex; flex-direction: column; align-items: center; justify-content: center;">
|
|
|
<span class="font-medium ${colorClass}">${perc.toFixed(1)}%</span>
|
|
|
<span class="text-xs text-gray-500 mt-1">${count}</span>
|
|
|
</div>
|
|
|
</td>
|
|
|
`;
|
|
|
};
|
|
|
if (impactContainer) {
|
|
|
const getPerc = (count, total) => total > 0 ? (count / total * 100) : 0;
|
|
|
const classPerc = getPerc(classIds.length, liveClasses);
|
|
|
const fieldPerc = getPerc(fieldIds.length, liveFields);
|
|
|
const methodPerc = getPerc(methodIds.length, liveMethods);
|
|
|
|
|
|
impactContainer.innerHTML = `
|
|
|
<div style="display: grid; grid-template-columns: 1fr 1fr 1fr auto; gap: 2rem; padding: 0; align-items: start;">
|
|
|
<!-- Kept Classes -->
|
|
|
<div>
|
|
|
<div style="color: var(--text-gray-500); font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 0.5rem;">Kept Classes</div>
|
|
|
<div style="display: flex; align-items: baseline; gap: 0.5rem; margin-bottom: 0.5rem;">
|
|
|
<span style="color: oklch(0.505 0.213 27.518); font-size: 1.25rem; font-weight: 500;">${classPerc.toFixed(1)}%</span>
|
|
|
<span style="color: var(--text-gray-500); font-size: 0.75rem;">${classIds.length} / ${liveClasses}</span>
|
|
|
</div>
|
|
|
<div style="height: 4px; background-color: var(--bg-hover); border-radius: 2px; width: 100%;">
|
|
|
<div style="height: 100%; background-color: oklch(0.505 0.213 27.518); border-radius: 2px; width: ${classPerc}%;"></div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<!-- Kept Fields -->
|
|
|
<div>
|
|
|
<div style="color: var(--text-gray-500); font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 0.5rem;">Kept Fields</div>
|
|
|
<div style="display: flex; align-items: baseline; gap: 0.5rem; margin-bottom: 0.5rem;">
|
|
|
<span style="color: oklch(0.505 0.213 27.518); font-size: 1.25rem; font-weight: 500;">${fieldPerc.toFixed(1)}%</span>
|
|
|
<span style="color: var(--text-gray-500); font-size: 0.75rem;">${fieldIds.length} / ${liveFields}</span>
|
|
|
</div>
|
|
|
<div style="height: 4px; background-color: var(--bg-hover); border-radius: 2px; width: 100%;">
|
|
|
<div style="height: 100%; background-color: oklch(0.505 0.213 27.518); border-radius: 2px; width: ${fieldPerc}%;"></div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<!-- Kept Methods -->
|
|
|
<div>
|
|
|
<div style="color: var(--text-gray-500); font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 0.5rem;">Kept Methods</div>
|
|
|
<div style="display: flex; align-items: baseline; gap: 0.5rem; margin-bottom: 0.5rem;">
|
|
|
<span style="color: oklch(0.505 0.213 27.518); font-size: 1.25rem; font-weight: 500;">${methodPerc.toFixed(1)}%</span>
|
|
|
<span style="color: var(--text-gray-500); font-size: 0.75rem;">${methodIds.length} / ${liveMethods}</span>
|
|
|
</div>
|
|
|
<div style="height: 4px; background-color: var(--bg-hover); border-radius: 2px; width: 100%;">
|
|
|
<div style="height: 100%; background-color: oklch(0.505 0.213 27.518); border-radius: 2px; width: ${methodPerc}%;"></div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<!-- Blocked by Rule -->
|
|
|
<div>
|
|
|
<div style="color: var(--text-gray-500); font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: .80rem;">Blocked by Rule</div>
|
|
|
<div style="display: flex; align-items: center; gap: 0.5rem;">
|
|
|
${impactTagsHtml}
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
`;
|
|
|
}
|
|
|
|
|
|
const allRules = this.keepRadiusData?.keepRuleKeepRadiusTable || [];
|
|
|
const subsumingIds = br.subsumedBy || [];
|
|
|
const identicalRules = [];
|
|
|
const subsumedByRules = [];
|
|
|
|
|
|
subsumingIds.forEach(id => {
|
|
|
const otherRule = allRules.find(r => r.id === id);
|
|
|
if (otherRule) {
|
|
|
const otherSubsumedBy = otherRule.keepRadius?.subsumedBy || [];
|
|
|
if (otherSubsumedBy.includes(rule.id)) {
|
|
|
identicalRules.push(otherRule);
|
|
|
} else {
|
|
|
subsumedByRules.push(otherRule);
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
|
|
|
if (relatedRulesContainer) {
|
|
|
const hasIdentical = identicalRules.length > 0;
|
|
|
const hasSubsumed = subsumedByRules.length > 0;
|
|
|
|
|
|
const renderDetailRuleRow = (r) => {
|
|
|
const rBr = r.keepRadius || {};
|
|
|
const rClassIds = rBr.classKeepRadius || [];
|
|
|
const rFieldIds = rBr.fieldKeepRadius || [];
|
|
|
const rMethodIds = rBr.methodKeepRadius || [];
|
|
|
|
|
|
const totalLive = getLiveItemCount(this.keepRadiusData);
|
|
|
const liveClasses = this.keepRadiusData?.buildInfo?.liveClassCount || 0;
|
|
|
const liveFields = this.keepRadiusData?.buildInfo?.liveFieldCount || 0;
|
|
|
const liveMethods = this.keepRadiusData?.buildInfo?.liveMethodCount || 0;
|
|
|
|
|
|
const renderMatchCell = (count, total) => {
|
|
|
const perc = total > 0 ? (count / total * 100) : 0;
|
|
|
return `
|
|
|
<td class="text-center" style="padding: 0.5rem; border-left: 1px solid var(--border-color);">
|
|
|
<div style="display: flex; flex-direction: column; align-items: center;">
|
|
|
<span style="color: var(--text-red-600); font-weight: 500;">${perc.toFixed(1)}%</span>
|
|
|
<span class="text-xs text-gray-500">${count}</span>
|
|
|
</div>
|
|
|
</td>
|
|
|
`;
|
|
|
};
|
|
|
|
|
|
const constraintsMap = getConstraintsMap(this.keepRadiusData);
|
|
|
const rConstraints = constraintsMap.get(r.constraintsId) || [];
|
|
|
|
|
|
const getTag = (c, label) => {
|
|
|
const isRestricted = rConstraints.includes(c);
|
|
|
const color = isRestricted ? "oklch(0.446 0.043 257.281)" : "#cbd5e1";
|
|
|
const bgColor = isRestricted ? "oklch(0.984 0.003 247.858)" : "#f8fafc";
|
|
|
const borderColor = isRestricted ? "oklch(0.929 0.013 255.508)" : "#e2e8f0";
|
|
|
return `<span class="impact-tag" style="display: inline-block; color: ${color}; background-color: ${bgColor}; border: 1px solid ${borderColor}; border-radius: 4px; padding: 2px 8px; font-size: 10px; font-weight: 400; height: 21px; line-height: 15px; text-transform: uppercase; letter-spacing: 0.25px; box-sizing: border-box; text-align: center;">${label}</span>`;
|
|
|
};
|
|
|
|
|
|
const impactCell = `
|
|
|
<td style="padding: 1rem; border-left: 1px solid var(--border-color);">
|
|
|
<div class="flex justify-start" style="gap: 0.5rem;">
|
|
|
${getTag('DONT_OBFUSCATE', 'OBFUSCATE')}
|
|
|
${getTag('DONT_OPTIMIZE', 'OPTIMIZE')}
|
|
|
${getTag('DONT_SHRINK', 'SHRINK')}
|
|
|
</div>
|
|
|
</td>
|
|
|
`;
|
|
|
|
|
|
return `
|
|
|
<tr class="table-row border-t border-gray-200 hover:bg-gray-50 cursor-pointer" onclick="App.showDetailsView('${r.id}')">
|
|
|
<td style="padding: 0.5rem; width: 40%;">
|
|
|
<pre style="white-space: pre-wrap; font-family: var(--font-family-mono); font-size: 0.8125rem; margin: 0;">${highlightRule(r.source)}</pre>
|
|
|
</td>
|
|
|
${renderMatchCell(rClassIds.length + rFieldIds.length + rMethodIds.length, totalLive)}
|
|
|
${renderMatchCell(rClassIds.length, liveClasses)}
|
|
|
${renderMatchCell(rFieldIds.length, liveFields)}
|
|
|
${renderMatchCell(rMethodIds.length, liveMethods)}
|
|
|
${impactCell}
|
|
|
</tr>
|
|
|
`;
|
|
|
};
|
|
|
|
|
|
const renderSection = (title, rules, explainer) => {
|
|
|
const hasRules = rules.length > 0;
|
|
|
let sectionHtml = `
|
|
|
<div class="table-container" style="display: flex; flex-direction: column;">
|
|
|
<div style="padding: 0.75rem 1rem; border-bottom: 1px solid var(--border-color); background-color: var(--bg-subtle); display: flex; justify-content: space-between; align-items: center;">
|
|
|
<div>
|
|
|
<span style="font-size: 0.875rem; font-weight: 600;">${title}</span>
|
|
|
<span style="color: var(--text-gray-500); font-size: 0.75rem; margin-left: 0.25rem;">· ${hasRules ? rules.length : 'None'}</span>
|
|
|
</div>
|
|
|
${hasRules ? `<span style="color: var(--text-gray-500); font-size: 0.75rem;">${explainer}</span>` : ''}
|
|
|
</div>
|
|
|
`;
|
|
|
|
|
|
if (hasRules) {
|
|
|
sectionHtml += `
|
|
|
<table style="width: 100%; border-collapse: collapse;">
|
|
|
<thead>
|
|
|
<tr>
|
|
|
<th rowspan="2" class="text-left bg-gray-50" style="padding: 0 1rem; width: 40%;">RULE</th>
|
|
|
<th colspan="4" class="text-center bg-gray-50" style="padding: .25rem 1rem; width: 40%; border-left: 1px solid var(--border-color);">KEPT ITEMS <span style="color: var(--text-muted);text-transform: none;font-weight: 500;">Higher is worse</span> <span class="tooltip-icon" data-tooltip="Items retained in the app due to this rule">?</span></th>
|
|
|
<th rowspan="2" class="text-left bg-gray-50" style="padding: 0 1rem; width: 20%; border-left: 1px solid var(--border-color);">BLOCKED BY RULE <span class="tooltip-icon" data-tooltip="Specific actions blocked by this rule">?</span></th>
|
|
|
</tr>
|
|
|
<tr>
|
|
|
<th class="text-center text-xs font-medium text-gray-500" style="padding: .15rem 1rem; width: 10%; border-left: 1px solid var(--border-color);">Total</th>
|
|
|
<th class="text-center text-xs font-medium text-gray-500" style="padding: .15rem 1rem; width: 10%; border-left: 1px solid var(--border-color);">Classes</th>
|
|
|
<th class="text-center text-xs font-medium text-gray-500" style="padding: .15rem 1rem; width: 10%; border-left: 1px solid var(--border-color);">Fields</th>
|
|
|
<th class="text-center text-xs font-medium text-gray-500" style="padding: .15rem 1rem; width: 10%; border-left: 1px solid var(--border-color);">Methods</th>
|
|
|
</tr>
|
|
|
</thead>
|
|
|
<tbody>
|
|
|
${rules.map(r => renderDetailRuleRow(r)).join('')}
|
|
|
</tbody>
|
|
|
</table>
|
|
|
`;
|
|
|
}
|
|
|
|
|
|
sectionHtml += `</div>`;
|
|
|
return sectionHtml;
|
|
|
};
|
|
|
|
|
|
if (!hasIdentical && !hasSubsumed) {
|
|
|
relatedRulesContainer.innerHTML = `
|
|
|
<div class="table-container" style="padding: 0.75rem 1rem; font-size: 0.875rem; display: flex; gap: 2rem; align-items: center;">
|
|
|
<span style="font-weight: 600; color: var(--text-gray-900);">Related rules:</span>
|
|
|
<span style="color: var(--text-gray-500);">Identical · None</span>
|
|
|
<span style="color: var(--text-gray-500);">Subsumed by · None</span>
|
|
|
</div>
|
|
|
`;
|
|
|
} else {
|
|
|
let html = '<div style="display: flex; flex-direction: column; gap: 1.5rem;">';
|
|
|
html += renderSection("Identical Rules", identicalRules, "Same matchers, can be deduplicated");
|
|
|
html += renderSection("Subsumed By", subsumedByRules, "Already covered by a broader rule");
|
|
|
html += '</div>';
|
|
|
relatedRulesContainer.innerHTML = html;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// Reset search inputs UI
|
|
|
const resetSearchUI = (type) => {
|
|
|
const container = document.getElementById(`${type}-search-container`);
|
|
|
const input = document.getElementById(`${type}-search-input`);
|
|
|
const toggleBtn = document.querySelector(`.search-toggle-btn[data-target="${type}"]`);
|
|
|
if (container && input && toggleBtn) {
|
|
|
container.style.display = "none";
|
|
|
input.value = "";
|
|
|
toggleBtn.classList.remove("active");
|
|
|
}
|
|
|
};
|
|
|
resetSearchUI("classes");
|
|
|
resetSearchUI("fields");
|
|
|
resetSearchUI("methods");
|
|
|
|
|
|
// Initial render of kept lists
|
|
|
this.renderKeptLists(rule);
|
|
|
}
|
|
|
} else {
|
|
|
ruleBody.innerHTML =
|
|
|
'<tr><td colspan="2" style="padding: 1rem;">Rule not found.</td></tr>';
|
|
|
classesContent.innerHTML = "";
|
|
|
methodsContent.innerHTML = "";
|
|
|
fieldsContent.innerHTML = "";
|
|
|
}
|
|
|
const fileOrigin = this.keepRadiusData?.fileOriginTable.find(f => f
|
|
|
.id === rule?.origin?.fileOriginId);
|
|
|
const fileOriginName = formatMavenCoordinate(fileOrigin
|
|
|
?.mavenCoordinate) || fileOrigin?.filename;
|
|
|
this.updateDetailsBreadcrumbs(fileOriginName, fileOrigin?.id);
|
|
|
},
|
|
|
renderKeptLists(rule, targetType = null) {
|
|
|
const br = rule.keepRadius || {};
|
|
|
|
|
|
const typeRefMap = App.lookups.typeReference;
|
|
|
|
|
|
const renderList = (ids, getLabel) => {
|
|
|
if (ids.length === 0)
|
|
|
return '<div style="padding: 0.5rem; color: var(--text-gray-500); font-size: 0.8125rem;">None</div>';
|
|
|
|
|
|
const formatSleekItem = (fullName) => {
|
|
|
const firstParen = fullName.indexOf('(');
|
|
|
const searchString = firstParen === -1 ? fullName : fullName.substring(0, firstParen);
|
|
|
const lastDot = searchString.lastIndexOf('.');
|
|
|
|
|
|
if (lastDot === -1) {
|
|
|
return `<span style="color: var(--text-gray-900); font-weight: 500;">${escapeHTML(fullName)}</span>`;
|
|
|
}
|
|
|
|
|
|
const pkg = fullName.substring(0, lastDot + 1);
|
|
|
const name = fullName.substring(lastDot + 1);
|
|
|
return `<span style="color: var(--text-gray-500);">${escapeHTML(pkg)}</span><span style="color: var(--text-gray-900); font-weight: 500;">${escapeHTML(name)}</span>`;
|
|
|
};
|
|
|
|
|
|
const limit = 1000;
|
|
|
const toRender = ids.slice(0, limit);
|
|
|
const listHtml = toRender.map(id => `
|
|
|
<div style="padding: 0.375rem 0.5rem; border-bottom: 1px solid #f1f5f9; font-family: var(--font-family-mono); font-size: 0.8125rem;" class="hover-bg-gray-100">
|
|
|
${formatSleekItem(getLabel(id))}
|
|
|
</div>
|
|
|
`).join("");
|
|
|
if (ids.length > limit) {
|
|
|
return listHtml + `
|
|
|
<div style="padding: 0.5rem; color: var(--text-gray-500); font-size: 0.8125rem; font-style: italic;">
|
|
|
... and ${ids.length - limit} more items
|
|
|
</div>`;
|
|
|
}
|
|
|
return listHtml;
|
|
|
};
|
|
|
|
|
|
// 1. CLASSES COLUMN
|
|
|
if (!targetType || targetType === "classes") {
|
|
|
const classIds = br.classKeepRadius || [];
|
|
|
const classesContent = document.getElementById("details-classes-content");
|
|
|
const filteredClassIds = classIds.filter(id => {
|
|
|
const info = App.lookups.keptClassInfo.get(id);
|
|
|
const name = formatDescriptor(typeRefMap.get(info?.classReferenceId));
|
|
|
return name.toLowerCase().includes(this.detailsState.classQuery.toLowerCase());
|
|
|
});
|
|
|
document.getElementById("details-classes-count").textContent = `· ${filteredClassIds.length}`;
|
|
|
classesContent.innerHTML = renderList(filteredClassIds, (id) => {
|
|
|
const info = App.lookups.keptClassInfo.get(id);
|
|
|
return formatDescriptor(typeRefMap.get(info?.classReferenceId));
|
|
|
});
|
|
|
}
|
|
|
|
|
|
// 2. FIELDS COLUMN
|
|
|
if (!targetType || targetType === "fields") {
|
|
|
const fieldIds = br.fieldKeepRadius || [];
|
|
|
const fieldsContent = document.getElementById("details-fields-content");
|
|
|
const filteredFieldIds = fieldIds.filter(id => {
|
|
|
const info = App.lookups.keptFieldInfo.get(id);
|
|
|
const ref = App.lookups.fieldReference.get(info?.fieldReferenceId);
|
|
|
const name = formatFieldName(ref, App.lookups);
|
|
|
return name.toLowerCase().includes(this.detailsState.fieldQuery.toLowerCase());
|
|
|
});
|
|
|
document.getElementById("details-fields-count").textContent = `· ${filteredFieldIds.length}`;
|
|
|
fieldsContent.innerHTML = renderList(filteredFieldIds, (id) => {
|
|
|
const info = App.lookups.keptFieldInfo.get(id);
|
|
|
const ref = App.lookups.fieldReference.get(info?.fieldReferenceId);
|
|
|
return formatFieldName(ref, App.lookups);
|
|
|
});
|
|
|
}
|
|
|
|
|
|
// 3. METHODS COLUMN
|
|
|
if (!targetType || targetType === "methods") {
|
|
|
const methodIds = br.methodKeepRadius || [];
|
|
|
const methodsContent = document.getElementById("details-methods-content");
|
|
|
const filteredMethodIds = methodIds.filter(id => {
|
|
|
const info = App.lookups.keptMethodInfo.get(id);
|
|
|
const ref = App.lookups.methodReference.get(info?.methodReferenceId);
|
|
|
const name = formatMethodName(ref, App.lookups);
|
|
|
return name.toLowerCase().includes(this.detailsState.methodQuery.toLowerCase());
|
|
|
});
|
|
|
document.getElementById("details-methods-count").textContent = `· ${filteredMethodIds.length}`;
|
|
|
methodsContent.innerHTML = renderList(filteredMethodIds, (id) => {
|
|
|
const info = App.lookups.keptMethodInfo.get(id);
|
|
|
const ref = App.lookups.methodReference.get(info?.methodReferenceId);
|
|
|
return formatMethodName(ref, App.lookups);
|
|
|
});
|
|
|
}
|
|
|
},
|
|
|
showReportView() {
|
|
|
ReportApp.state.currentView = CONSTANTS.VIEWS.MODULES;
|
|
|
document.getElementById("details-view").style.display = "none";
|
|
|
document.getElementById("file-details-view").style.display = "none";
|
|
|
document.getElementById("report-view-controls").style.display = "flex";
|
|
|
document.getElementById("report-view").style.display = "flex";
|
|
|
ReportApp.render();
|
|
|
},
|
|
|
showFileDetailsView(fileOriginId) {
|
|
|
ReportApp.state.currentView = CONSTANTS.VIEWS.FILE_DETAILS;
|
|
|
ReportApp.state.drillContext.fileOriginId = fileOriginId;
|
|
|
this.renderFileDetailsView(fileOriginId);
|
|
|
},
|
|
|
renderFileDetailsView(fileOriginId) {
|
|
|
document.getElementById("report-view").style.display = "none";
|
|
|
document.getElementById("details-view").style.display = "none";
|
|
|
document.getElementById("report-view-controls").style.display = "none";
|
|
|
document.getElementById("file-details-view").style.display = "flex";
|
|
|
const impactBody = document.getElementById("file-details-impact-body");
|
|
|
const rulesBody = document.getElementById("file-details-rules-body");
|
|
|
const rulesHeader = document.getElementById("file-details-rules-header");
|
|
|
const fileOrigin = this.keepRadiusData?.fileOriginTable.find(f => f
|
|
|
.id === parseInt(fileOriginId));
|
|
|
if (!fileOrigin) return;
|
|
|
const fileRules = this.keepRadiusData.keepRuleKeepRadiusTable
|
|
|
.filter(r => r.origin?.fileOriginId === fileOrigin.id);
|
|
|
|
|
|
const globalRules = [];
|
|
|
if (this.keepRadiusData.globalKeepRuleKeepRadiusTable) {
|
|
|
const totalClasses = this.keepRadiusData?.buildInfo?.liveClassCount || 0;
|
|
|
const totalFields = this.keepRadiusData?.buildInfo?.liveFieldCount || 0;
|
|
|
const totalMethods = this.keepRadiusData?.buildInfo?.liveMethodCount || 0;
|
|
|
|
|
|
this.keepRadiusData.globalKeepRuleKeepRadiusTable.forEach(rule => {
|
|
|
if (rule.source === '-dontoptimize' || rule.source === '-dontshrink' || rule.source === '-dontobfuscate') {
|
|
|
if (rule.origin?.fileOriginId === fileOrigin.id) {
|
|
|
globalRules.push({
|
|
|
id: rule.id,
|
|
|
source: rule.source,
|
|
|
constraintsId: rule.constraintsId,
|
|
|
isGlobal: true,
|
|
|
keepRadius: {
|
|
|
classKeepRadius: new Array(totalClasses),
|
|
|
fieldKeepRadius: new Array(totalFields),
|
|
|
methodKeepRadius: new Array(totalMethods),
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
|
|
|
const allRulesForFile = [...globalRules, ...fileRules];
|
|
|
let rules = allRulesForFile;
|
|
|
const lens = ReportApp.state.filters.keepRules[0];
|
|
|
if (lens) {
|
|
|
rules = ReportApp.applyKeepRuleLens(rules, lens);
|
|
|
}
|
|
|
const isIdenticalLens = lens === "Identical";
|
|
|
const isSubsumedLens = lens === "Subsumed";
|
|
|
if (isIdenticalLens || isSubsumedLens) {
|
|
|
rulesHeader.innerHTML = `
|
|
|
<tr>
|
|
|
<th class="text-left bg-gray-50 z-30" style="padding: 1rem; width: 600px; min-width: 600px; border-bottom: 1px solid var(--border-color);">Rule</th>
|
|
|
<th class="text-left bg-gray-50 border-l border-gray-200" style="padding: 1rem; width: 100%; border-bottom: 1px solid var(--border-color);">${isIdenticalLens ? 'Identical Rules' : 'Subsumed By'}</th>
|
|
|
</tr>
|
|
|
`;
|
|
|
} else {
|
|
|
rulesHeader.innerHTML = `
|
|
|
<tr>
|
|
|
<th rowspan="2" class="text-left bg-gray-50" style="padding: 1rem; width: 40%; border-bottom: 1px solid var(--border-color);">Rule</th>
|
|
|
<th colspan="4" class="text-center bg-gray-50" style="padding: 0.5rem; width: 40%; border-left: 1px solid var(--border-color); border-bottom: 1px solid var(--border-color);">Kept Items <span style="color: var(--text-muted);text-transform: none;font-weight: 500;">Higher is worse</span></th>
|
|
|
<th rowspan="2" class="text-left bg-gray-50" style="padding: 0.5rem; width: 20%; border-left: 1px solid var(--border-color); border-bottom: 1px solid var(--border-color);">Blocked by Rule</th>
|
|
|
</tr>
|
|
|
<tr>
|
|
|
<th class="text-center text-xs font-medium text-gray-500" style="padding: 0.5rem; width: 10%; border-left: 1px solid var(--border-color); border-bottom: 1px solid var(--border-color);">Total</th>
|
|
|
<th class="text-center text-xs font-medium text-gray-500" style="padding: 0.5rem; width: 10%; border-left: 1px solid var(--border-color); border-bottom: 1px solid var(--border-color);">Classes</th>
|
|
|
<th class="text-center text-xs font-medium text-gray-500" style="padding: 0.5rem; width: 10%; border-left: 1px solid var(--border-color); border-bottom: 1px solid var(--border-color);">Fields</th>
|
|
|
<th class="text-center text-xs font-medium text-gray-500" style="padding: 0.5rem; width: 10%; border-left: 1px solid var(--border-color); border-bottom: 1px solid var(--border-color);">Methods</th>
|
|
|
</tr>
|
|
|
`;
|
|
|
}
|
|
|
const liveClasses = this.keepRadiusData?.buildInfo?.liveClassCount || 0;
|
|
|
const liveFields = this.keepRadiusData?.buildInfo?.liveFieldCount || 0;
|
|
|
const liveMethods = this.keepRadiusData?.buildInfo?.liveMethodCount || 0;
|
|
|
const matchedClasses = new Set();
|
|
|
const matchedFields = new Set();
|
|
|
const matchedMethods = new Set();
|
|
|
allRulesForFile.forEach(rule => {
|
|
|
const br = rule.keepRadius || {};
|
|
|
(br.classKeepRadius || []).forEach(id => matchedClasses.add(id));
|
|
|
(br.fieldKeepRadius || []).forEach(id => matchedFields.add(id));
|
|
|
(br.methodKeepRadius || []).forEach(id => matchedMethods.add(id));
|
|
|
});
|
|
|
const renderMatchCell = (count, total, borderLeft = true) => {
|
|
|
const perc = total > 0 ? (count / total * 100) : 0;
|
|
|
const colorClass = UIUtils.getMatchClass(perc);
|
|
|
const bl = borderLeft ? "border-l border-gray-200" : "";
|
|
|
return `
|
|
|
<td class="text-center ${bl}" style="padding: 1rem;">
|
|
|
<div style="display: flex; flex-direction: column; align-items: center; justify-content: center;">
|
|
|
<span class="font-medium ${colorClass}">${perc.toFixed(1)}%</span>
|
|
|
<span class="text-xs text-gray-500 mt-1">${count}</span>
|
|
|
</div>
|
|
|
</td>
|
|
|
`;
|
|
|
};
|
|
|
impactBody.innerHTML = `
|
|
|
<tr class="border-t border-gray-200">
|
|
|
${renderMatchCell(matchedClasses.size, liveClasses, false)}
|
|
|
${renderMatchCell(matchedFields.size, liveFields)}
|
|
|
${renderMatchCell(matchedMethods.size, liveMethods)}
|
|
|
</tr>
|
|
|
`;
|
|
|
rulesBody.innerHTML = rules.map(rule => {
|
|
|
if (isIdenticalLens || isSubsumedLens) {
|
|
|
const list = isIdenticalLens ? rule.identicalRules : rule
|
|
|
.subsumedByRules;
|
|
|
const otherRulesHtml = (list || []).map(other => `
|
|
|
<div class="text-xs text-blue-600 hover:underline cursor-pointer mb-1" onclick="event.stopPropagation(); App.showDetailsView('${other.id}')">
|
|
|
<pre style="white-space: pre-wrap; margin: 0; font-family: var(--font-family-mono);">${escapeHTML(other.source)}</pre>
|
|
|
</div>
|
|
|
`).join("");
|
|
|
return `
|
|
|
<tr class="border-t border-gray-200 hover:bg-gray-50 cursor-pointer" onclick="App.showDetailsView('${rule.id}')">
|
|
|
<td class="sticky-name font-medium text-blue-600 hover:underline" title="${escapeHTML(rule.source)}" style="padding: 1rem; width: 600px; min-width: 600px;">
|
|
|
<pre style="white-space: pre-wrap; font-family: var(--font-family-mono); font-size: 0.8125rem; margin: 0; pointer-events: none;">${escapeHTML(rule.source)}</pre>
|
|
|
</td>
|
|
|
<td class="border-l border-gray-200" style="padding: 1rem; width: 100%;">
|
|
|
${otherRulesHtml || '<span class="text-gray-400 italic">None</span>'}
|
|
|
</td>
|
|
|
</tr>
|
|
|
`;
|
|
|
}
|
|
|
const br = rule.keepRadius || {};
|
|
|
const c = (br.classKeepRadius || []).length;
|
|
|
const f = (br.fieldKeepRadius || []).length;
|
|
|
const m = (br.methodKeepRadius || []).length;
|
|
|
const constraintsMap = getConstraintsMap(this.keepRadiusData);
|
|
|
let constraints = [...(constraintsMap.get(rule.constraintsId) || [])];
|
|
|
if (rule.isGlobal) {
|
|
|
if (rule.source === '-dontobfuscate' && !constraints.includes('DONT_OBFUSCATE')) {
|
|
|
constraints.push('DONT_OBFUSCATE');
|
|
|
}
|
|
|
if (rule.source === '-dontoptimize' && !constraints.includes('DONT_OPTIMIZE')) {
|
|
|
constraints.push('DONT_OPTIMIZE');
|
|
|
}
|
|
|
if (rule.source === '-dontshrink' && !constraints.includes('DONT_SHRINK')) {
|
|
|
constraints.push('DONT_SHRINK');
|
|
|
}
|
|
|
}
|
|
|
const getTag = (c, label) => {
|
|
|
const isRestricted = constraints.includes(c);
|
|
|
const color = isRestricted ? "oklch(0.446 0.043 257.281)" : "#cbd5e1";
|
|
|
const bgColor = isRestricted ? "oklch(0.984 0.003 247.858)" : "#f8fafc";
|
|
|
const borderColor = isRestricted ? "oklch(0.929 0.013 255.508)" : "#e2e8f0";
|
|
|
return `<span class="impact-tag" style="display: inline-block; color: ${color}; background-color: ${bgColor}; border: 1px solid ${borderColor}; border-radius: 4px; padding: 2px 8px; font-size: 10px; font-weight: 400; height: 21px; line-height: 15px; text-transform: uppercase; letter-spacing: 0.25px; box-sizing: border-box; text-align: center;">${label}</span>`;
|
|
|
};
|
|
|
|
|
|
const impactCell = `
|
|
|
<td style="padding: 0.5rem; border-left: 1px solid var(--border-color);">
|
|
|
<div class="flex justify-start" style="gap: 0.5rem;">
|
|
|
${getTag('DONT_OBFUSCATE', 'OBFUSCATE')}
|
|
|
${getTag('DONT_OPTIMIZE', 'OPTIMIZE')}
|
|
|
${getTag('DONT_SHRINK', 'SHRINK')}
|
|
|
</div>
|
|
|
</td>
|
|
|
`;
|
|
|
|
|
|
const renderMatchCell = (count, total, borderLeft = true) => {
|
|
|
const perc = total > 0 ? (count / total * 100) : 0;
|
|
|
const colorClass = UIUtils.getMatchClass(perc);
|
|
|
const bl = borderLeft ? "border-left: 1px solid var(--border-color);" : "";
|
|
|
return `
|
|
|
<td class="text-center" style="padding: 1rem; ${bl}">
|
|
|
<div style="display: flex; flex-direction: column; align-items: center; justify-content: center;">
|
|
|
<span class="font-medium ${colorClass}">${perc.toFixed(1)}%</span>
|
|
|
<span class="text-xs text-gray-500 mt-1">${count}</span>
|
|
|
</div>
|
|
|
</td>
|
|
|
`;
|
|
|
};
|
|
|
|
|
|
const totalLive = getLiveItemCount(this.keepRadiusData);
|
|
|
const liveClasses = this.keepRadiusData?.buildInfo?.liveClassCount || 0;
|
|
|
const liveFields = this.keepRadiusData?.buildInfo?.liveFieldCount || 0;
|
|
|
const liveMethods = this.keepRadiusData?.buildInfo?.liveMethodCount || 0;
|
|
|
|
|
|
const highlightedSource = highlightRule(rule.source);
|
|
|
|
|
|
return `
|
|
|
<tr class="border-t border-gray-200 hover:bg-gray-50 cursor-pointer" onclick="App.showDetailsView('${rule.id}')">
|
|
|
<td style="padding: 0.5rem; width: 40%;">
|
|
|
<pre style="white-space: pre-wrap; font-family: var(--font-family-mono); font-size: 0.8125rem; margin: 0;">${highlightedSource}</pre>
|
|
|
</td>
|
|
|
${renderMatchCell(c + f + m, totalLive, true)}
|
|
|
${renderMatchCell(c, liveClasses)}
|
|
|
${renderMatchCell(f, liveFields)}
|
|
|
${renderMatchCell(m, liveMethods)}
|
|
|
${impactCell}
|
|
|
</tr>
|
|
|
`;
|
|
|
}).join("");
|
|
|
const fileOriginName = formatMavenCoordinate(fileOrigin
|
|
|
.mavenCoordinate) || fileOrigin.filename;
|
|
|
this.updateFileDetailsBreadcrumbs(fileOriginName);
|
|
|
},
|
|
|
updateFileDetailsBreadcrumbs(filename) {
|
|
|
const bc = document.getElementById("file-details-breadcrumbs");
|
|
|
if (!bc) return;
|
|
|
const linkClass = "breadcrumb-pill";
|
|
|
const textClass = "breadcrumb-text";
|
|
|
const sep = '<span class="text-gray-300 mx-1">/</span>';
|
|
|
bc.innerHTML = `
|
|
|
<span class="${linkClass}" id="file-details-back-to-summary">Project</span>
|
|
|
${sep}
|
|
|
<span class="${textClass}">${escapeHTML(filename)}</span>
|
|
|
`;
|
|
|
document.getElementById("file-details-back-to-summary").addEventListener(
|
|
|
"click", () => {
|
|
|
this.showReportView();
|
|
|
});
|
|
|
},
|
|
|
updateDetailsBreadcrumbs(filename, fileOriginId) {
|
|
|
const bc = document.getElementById("details-breadcrumbs");
|
|
|
if (!bc) return;
|
|
|
const linkClass = "breadcrumb-pill";
|
|
|
const textClass = "breadcrumb-text";
|
|
|
const sep = '<span class="text-gray-300 mx-1">/</span>';
|
|
|
let html = `
|
|
|
<span class="${linkClass}" id="details-back-to-summary">Project</span>
|
|
|
${sep}`;
|
|
|
if (filename && fileOriginId !== undefined) {
|
|
|
html += `
|
|
|
<span class="${linkClass}" id="details-back-to-file">${escapeHTML(filename)}</span>
|
|
|
${sep}`;
|
|
|
}
|
|
|
html += `<span class="${textClass}">Keep Rule Details</span>`;
|
|
|
bc.innerHTML = html;
|
|
|
document.getElementById("details-back-to-summary").addEventListener(
|
|
|
"click", () => {
|
|
|
this.showReportView();
|
|
|
});
|
|
|
if (filename && fileOriginId !== undefined) {
|
|
|
document.getElementById("details-back-to-file").addEventListener(
|
|
|
"click", () => {
|
|
|
this.showFileDetailsView(fileOriginId);
|
|
|
});
|
|
|
}
|
|
|
},
|
|
|
async loadProtoData() {
|
|
|
const embeddedProtoSchemaSource = document.getElementById('keepradius-proto');
|
|
|
const embeddedProtoDataSource = document.getElementById('keepradius-data');
|
|
|
try {
|
|
|
const root = protobuf.parse(embeddedProtoSchemaSource.textContent).root;
|
|
|
const data = embeddedProtoDataSource.textContent.trim();
|
|
|
const bytes = Uint8Array.from(atob(data), c => c.charCodeAt(0));
|
|
|
const KeepRadiusContainer = root.lookupType(
|
|
|
"com.android.tools.r8.keepradius.proto.KeepRadiusContainer");
|
|
|
const message = KeepRadiusContainer.decode(bytes);
|
|
|
this.keepRadiusData = KeepRadiusContainer.toObject(message, {
|
|
|
longs: String,
|
|
|
enums: String,
|
|
|
bytes: String,
|
|
|
defaults: true,
|
|
|
arrays: true,
|
|
|
objects: true,
|
|
|
oneofs: true
|
|
|
});
|
|
|
// Extract and strip common prefix from file names
|
|
|
if (this.keepRadiusData.fileOriginTable) {
|
|
|
const filenames = this.keepRadiusData.fileOriginTable.map(f => f
|
|
|
.filename).filter(Boolean);
|
|
|
const commonPrefix = UIUtils.findCommonPrefix(filenames);
|
|
|
if (commonPrefix) {
|
|
|
this.keepRadiusData.fileOriginTable.forEach(f => {
|
|
|
if (f.filename && f.filename.startsWith(commonPrefix)) {
|
|
|
f.filename = f.filename.substring(commonPrefix.length);
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// Build highly optimized O(1) lookup Maps for details and filtering views
|
|
|
App.lookups = {
|
|
|
keptClassInfo: new Map((this.keepRadiusData.keptClassInfoTable || []).map(c => [c.id, c])),
|
|
|
keptFieldInfo: new Map((this.keepRadiusData.keptFieldInfoTable || []).map(f => [f.id, f])),
|
|
|
keptMethodInfo: new Map((this.keepRadiusData.keptMethodInfoTable || []).map(m => [m.id, m])),
|
|
|
fieldReference: new Map((this.keepRadiusData.fieldReferenceTable || []).map(r => [r.id, r])),
|
|
|
methodReference: new Map((this.keepRadiusData.methodReferenceTable || []).map(r => [r.id, r])),
|
|
|
protoReference: new Map((this.keepRadiusData.protoReferenceTable || []).map(p => [p.id, p])),
|
|
|
typeReferenceList: new Map((this.keepRadiusData.typeReferenceListTable || []).map(l => [l.id, l])),
|
|
|
typeReference: new Map((this.keepRadiusData.typeReferenceTable || []).map(t => [t.id, t.javaDescriptor]))
|
|
|
};
|
|
|
|
|
|
console.log("Protobuf data loaded successfully:", this
|
|
|
.keepRadiusData);
|
|
|
// Trigger re-render now that data is available
|
|
|
ReportApp.render();
|
|
|
} catch (err) {
|
|
|
console.error("Failed to load protobuf data:", err);
|
|
|
}
|
|
|
},
|
|
|
};
|
|
|
/* ==========================================================================
|
|
|
REPORT APP (Grid/List View)
|
|
|
========================================================================== */
|
|
|
const ReportApp = {
|
|
|
state: {
|
|
|
currentView: CONSTANTS.VIEWS.MODULES,
|
|
|
filters: {
|
|
|
keepRules: [],
|
|
|
classes: [],
|
|
|
fields: [],
|
|
|
methods: []
|
|
|
},
|
|
|
activeFilterChips: [],
|
|
|
sort: {
|
|
|
by: "matches.total",
|
|
|
order: "desc"
|
|
|
},
|
|
|
drillContext: {
|
|
|
module: null,
|
|
|
pkg: null,
|
|
|
fileOriginId: null
|
|
|
}, // Navigation path
|
|
|
statsVisible: true,
|
|
|
searchTerm: "",
|
|
|
showBlockedByRule: true
|
|
|
},
|
|
|
elements: {},
|
|
|
init() {
|
|
|
this.cacheDOMElements();
|
|
|
this.populateHeaderInfo();
|
|
|
this.populateFilters();
|
|
|
this.bindEvents();
|
|
|
this.render();
|
|
|
},
|
|
|
cacheDOMElements() {
|
|
|
const getById = (id) => document.getElementById(id);
|
|
|
this.elements = {
|
|
|
|
|
|
clsChip: getById("cls-chip-container"),
|
|
|
clsBtn: getById("cls-filter-btn"),
|
|
|
clsDropdown: getById("cls-dropdown"),
|
|
|
clsText: getById("cls-filter-text"),
|
|
|
fieldChip: getById("field-chip-container"),
|
|
|
fieldBtn: getById("field-filter-btn"),
|
|
|
fieldDropdown: getById("field-dropdown"),
|
|
|
fieldText: getById("field-filter-text"),
|
|
|
methodChip: getById("method-chip-container"),
|
|
|
methodBtn: getById("method-filter-btn"),
|
|
|
methodDropdown: getById("method-dropdown"),
|
|
|
methodText: getById("method-filter-text"),
|
|
|
addFilterContainer: getById("add-filter-container"),
|
|
|
addFilterBtn: getById("add-filter-btn"),
|
|
|
addFilterDropdown: getById("add-filter-dropdown"),
|
|
|
addFilterList: getById("add-filter-list"),
|
|
|
|
|
|
grpBtn: getById("group-by-btn"),
|
|
|
grpDropdown: getById("group-by-dropdown"),
|
|
|
grpText: getById("group-by-text"),
|
|
|
grpContainer: getById("group-by-container"),
|
|
|
grpList: getById("group-by-list"),
|
|
|
tableHeaders: getById("table-headers"),
|
|
|
tableData: getById("table-data"),
|
|
|
statsTableHeaders: getById("stats-table-headers"),
|
|
|
statsTableData: getById("stats-table-data"),
|
|
|
statsContainer: getById("stats-container"),
|
|
|
mainTable: getById("main-table"),
|
|
|
totalObfuscation: getById("total-obfuscation"),
|
|
|
totalOptimization: getById("total-optimization"),
|
|
|
totalShrinking: getById("total-shrinking"),
|
|
|
searchInput: getById("search-input"),
|
|
|
clearSearchBtn: getById("clear-search-btn"),
|
|
|
searchContainer: getById("search-container"),
|
|
|
searchIconBtn: getById("search-icon-btn"),
|
|
|
toggleColumnsBtn: getById("toggle-columns-btn"),
|
|
|
columnsDropdown: getById("columns-dropdown"),
|
|
|
toggleBlockedByRuleCb: getById("toggle-blocked-by-rule-cb"),
|
|
|
};
|
|
|
},
|
|
|
populateHeaderInfo() { },
|
|
|
/**
|
|
|
* Initializes all filters (Variants, Modules, etc.)
|
|
|
*/
|
|
|
populateFilters() {
|
|
|
// --- 1. Dynamic Filters (Modules/Packages/Classes) ---
|
|
|
this.updateDynamicFilters();
|
|
|
},
|
|
|
/**
|
|
|
* Updates the available options in Module/Package/Class dropdowns based on dependencies.
|
|
|
* e.g., Selecting "Module A" filters the Package options to only those in Module A.
|
|
|
*/
|
|
|
updateDynamicFilters() {
|
|
|
const {
|
|
|
keepRules,
|
|
|
classes,
|
|
|
fields,
|
|
|
methods
|
|
|
} = this.state.filters;
|
|
|
const chips = this.state.activeFilterChips;
|
|
|
// --- 1. Keep Rules Lens ---
|
|
|
const keepRuleOptions = [{
|
|
|
name: "<b>Identical:</b> Show rules that match the same items as other rules",
|
|
|
value: "Identical"
|
|
|
},
|
|
|
{
|
|
|
name: "<b>Subsumed:</b> Show rules that match a subset of the items matched by another rule",
|
|
|
value: "Subsumed"
|
|
|
},
|
|
|
{
|
|
|
name: "<b>Unused:</b> Show rules that don't match anything",
|
|
|
value: "Unused"
|
|
|
},
|
|
|
];
|
|
|
const lens = this.state.filters.keepRules[0] || "All";
|
|
|
const tabsContainer = document.getElementById("lens-tabs");
|
|
|
if (tabsContainer) {
|
|
|
tabsContainer.querySelectorAll(".segment-btn").forEach(btn => {
|
|
|
if (btn.dataset.lens === lens) {
|
|
|
btn.classList.add("active");
|
|
|
} else {
|
|
|
btn.classList.remove("active");
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
// --- 2. Classes Filter ---
|
|
|
const {
|
|
|
options: classOptions,
|
|
|
total: totalClasses
|
|
|
} = this.getKeptClasses();
|
|
|
UIUtils.buildActionDropdown("cls-dropdown", classOptions, classes, () => {
|
|
|
this.updateDynamicFilters();
|
|
|
this.render();
|
|
|
}, true, true, totalClasses, "classes", (term) => {
|
|
|
const brData = App.keepRadiusData;
|
|
|
if (!brData || !brData.keptClassInfoTable) return {
|
|
|
options: [],
|
|
|
total: 0
|
|
|
};
|
|
|
const typeRefMap = new Map();
|
|
|
brData.typeReferenceTable.forEach(t => typeRefMap.set(t.id, t
|
|
|
.javaDescriptor));
|
|
|
const filtered = brData.keptClassInfoTable.filter(c => {
|
|
|
const name = formatDescriptor(typeRefMap.get(c
|
|
|
.classReferenceId));
|
|
|
return name.toLowerCase().includes(term);
|
|
|
});
|
|
|
const results = filtered.slice(0, 1000).map(c => {
|
|
|
const name = escapeHTML(formatDescriptor(typeRefMap.get(c
|
|
|
.classReferenceId)));
|
|
|
return {
|
|
|
name,
|
|
|
value: c.id
|
|
|
};
|
|
|
});
|
|
|
return {
|
|
|
options: results,
|
|
|
total: filtered.length
|
|
|
};
|
|
|
});
|
|
|
UIUtils.renderChipText(this.elements.clsText, UIUtils.getFilterLabel(
|
|
|
"Classes", classes, totalClasses, classOptions), "class", true);
|
|
|
UIUtils.toggleVisibility(this.elements.clsChip, chips.includes("class"));
|
|
|
// --- 3. Fields Filter ---
|
|
|
const {
|
|
|
options: fieldOptions,
|
|
|
total: totalFields
|
|
|
} = this.getKeptFields();
|
|
|
UIUtils.buildActionDropdown("field-dropdown", fieldOptions, fields,
|
|
|
() => {
|
|
|
this.updateDynamicFilters();
|
|
|
this.render();
|
|
|
}, true, true, totalFields, "fields", (term) => {
|
|
|
const brData = App.keepRadiusData;
|
|
|
if (!brData || !brData.keptFieldInfoTable) return {
|
|
|
options: [],
|
|
|
total: 0
|
|
|
};
|
|
|
const typeRefMap = new Map();
|
|
|
brData.typeReferenceTable.forEach(t => typeRefMap.set(t.id, t
|
|
|
.javaDescriptor));
|
|
|
const fieldRefMap = new Map();
|
|
|
brData.fieldReferenceTable.forEach(f => fieldRefMap.set(f.id, f));
|
|
|
const filtered = brData.keptFieldInfoTable.filter(f => {
|
|
|
const fieldRef = fieldRefMap.get(f.fieldReferenceId);
|
|
|
const name = formatFieldName(fieldRef, brData, typeRefMap);
|
|
|
return name.toLowerCase().includes(term);
|
|
|
});
|
|
|
const results = filtered.slice(0, 1000).map(f => {
|
|
|
const fieldRef = fieldRefMap.get(f.fieldReferenceId);
|
|
|
const name = escapeHTML(formatFieldName(fieldRef, brData,
|
|
|
typeRefMap));
|
|
|
return {
|
|
|
name,
|
|
|
value: f.id
|
|
|
};
|
|
|
});
|
|
|
return {
|
|
|
options: results,
|
|
|
total: filtered.length
|
|
|
};
|
|
|
});
|
|
|
UIUtils.renderChipText(this.elements.fieldText, UIUtils.getFilterLabel(
|
|
|
"Fields", fields, totalFields, fieldOptions), "field", true);
|
|
|
UIUtils.toggleVisibility(this.elements.fieldChip, chips.includes(
|
|
|
"field"));
|
|
|
// --- 4. Methods Filter ---
|
|
|
const {
|
|
|
options: methodOptions,
|
|
|
total: totalMethods
|
|
|
} = this.getKeptMethods();
|
|
|
UIUtils.buildActionDropdown("method-dropdown", methodOptions, methods,
|
|
|
() => {
|
|
|
this.updateDynamicFilters();
|
|
|
this.render();
|
|
|
}, true, true, totalMethods, "methods", (term) => {
|
|
|
const brData = App.keepRadiusData;
|
|
|
if (!brData || !brData.keptMethodInfoTable) return {
|
|
|
options: [],
|
|
|
total: 0
|
|
|
};
|
|
|
const typeRefMap = new Map();
|
|
|
brData.typeReferenceTable.forEach(t => typeRefMap.set(t.id, t
|
|
|
.javaDescriptor));
|
|
|
const methodRefMap = new Map();
|
|
|
brData.methodReferenceTable.forEach(m => methodRefMap.set(m.id, m));
|
|
|
const filtered = brData.keptMethodInfoTable.filter(m => {
|
|
|
const methodRef = methodRefMap.get(m.methodReferenceId);
|
|
|
const name = formatMethodName(methodRef, brData, typeRefMap);
|
|
|
return name.toLowerCase().includes(term);
|
|
|
});
|
|
|
const results = filtered.slice(0, 1000).map(m => {
|
|
|
const methodRef = methodRefMap.get(m.methodReferenceId);
|
|
|
const name = escapeHTML(formatMethodName(methodRef, brData,
|
|
|
typeRefMap));
|
|
|
return {
|
|
|
name,
|
|
|
value: m.id
|
|
|
};
|
|
|
});
|
|
|
return {
|
|
|
options: results,
|
|
|
total: filtered.length
|
|
|
};
|
|
|
});
|
|
|
UIUtils.renderChipText(this.elements.methodText, UIUtils.getFilterLabel(
|
|
|
"Methods", methods, totalMethods, methodOptions), "method", true);
|
|
|
UIUtils.toggleVisibility(this.elements.methodChip, chips.includes(
|
|
|
"method"));
|
|
|
// --- Add Filter Button Logic ---
|
|
|
const availableFilters = [];
|
|
|
if (!chips.includes("class")) availableFilters.push({
|
|
|
name: "Classes",
|
|
|
value: "class",
|
|
|
options: classOptions,
|
|
|
total: totalClasses,
|
|
|
state: classes
|
|
|
});
|
|
|
if (!chips.includes("field")) availableFilters.push({
|
|
|
name: "Fields",
|
|
|
value: "field",
|
|
|
options: fieldOptions,
|
|
|
total: totalFields,
|
|
|
state: fields
|
|
|
});
|
|
|
if (!chips.includes("method")) availableFilters.push({
|
|
|
name: "Methods",
|
|
|
value: "method",
|
|
|
options: methodOptions,
|
|
|
total: totalMethods,
|
|
|
state: methods
|
|
|
});
|
|
|
if (availableFilters.length > 0) {
|
|
|
this.elements.addFilterContainer.classList.remove("hidden");
|
|
|
this.elements.addFilterList.innerHTML = availableFilters
|
|
|
.map(f =>
|
|
|
`<a href="#" class="dropdown-item add-filter-option" data-value="${f.value}">${f.name}</a>`
|
|
|
)
|
|
|
.join("");
|
|
|
this.elements.addFilterList.querySelectorAll(".add-filter-option")
|
|
|
.forEach(item => {
|
|
|
item.addEventListener("click", (e) => {
|
|
|
e.preventDefault();
|
|
|
e.stopPropagation();
|
|
|
const val = item.dataset.value;
|
|
|
if (!this.state.activeFilterChips.includes(val)) {
|
|
|
this.state.activeFilterChips.push(val);
|
|
|
}
|
|
|
// Close the "Add filter" dropdown
|
|
|
this.elements.addFilterDropdown.classList.add("hidden");
|
|
|
this.elements.addFilterBtn.classList.remove("bg-gray-200");
|
|
|
this.updateDynamicFilters();
|
|
|
this.render();
|
|
|
// Auto-open newly added dropdown
|
|
|
setTimeout(() => {
|
|
|
if (val === "class") this.toggleDropdown(this.elements
|
|
|
.clsDropdown, this.elements.clsBtn);
|
|
|
if (val === "field") this.toggleDropdown(this.elements
|
|
|
.fieldDropdown, this.elements.fieldBtn);
|
|
|
if (val === "method") this.toggleDropdown(this
|
|
|
.elements.methodDropdown, this.elements.methodBtn);
|
|
|
}, 0);
|
|
|
});
|
|
|
});
|
|
|
} else {
|
|
|
this.elements.addFilterContainer.classList.add("hidden");
|
|
|
}
|
|
|
},
|
|
|
getKeptClasses() {
|
|
|
const brData = App.keepRadiusData;
|
|
|
if (!brData || !brData.keptClassInfoTable) return {
|
|
|
options: [],
|
|
|
total: 0
|
|
|
};
|
|
|
const typeRefMap = new Map();
|
|
|
brData.typeReferenceTable.forEach(t => typeRefMap.set(t.id, t
|
|
|
.javaDescriptor));
|
|
|
const options = brData.keptClassInfoTable.slice(0, 1000).map(c => {
|
|
|
const name = escapeHTML(formatDescriptor(typeRefMap.get(c
|
|
|
.classReferenceId)));
|
|
|
return {
|
|
|
name,
|
|
|
value: c.id
|
|
|
};
|
|
|
});
|
|
|
return {
|
|
|
options,
|
|
|
total: brData.keptClassInfoTable.length
|
|
|
};
|
|
|
},
|
|
|
getKeptFields() {
|
|
|
const brData = App.keepRadiusData;
|
|
|
if (!brData || !brData.keptFieldInfoTable) return {
|
|
|
options: [],
|
|
|
total: 0
|
|
|
};
|
|
|
const typeRefMap = new Map();
|
|
|
brData.typeReferenceTable.forEach(t => typeRefMap.set(t.id, t
|
|
|
.javaDescriptor));
|
|
|
const fieldRefMap = new Map();
|
|
|
brData.fieldReferenceTable.forEach(f => fieldRefMap.set(f.id, f));
|
|
|
const options = brData.keptFieldInfoTable.slice(0, 1000).map(f => {
|
|
|
const fieldRef = fieldRefMap.get(f.fieldReferenceId);
|
|
|
const name = escapeHTML(formatFieldName(fieldRef, brData,
|
|
|
typeRefMap));
|
|
|
return {
|
|
|
name,
|
|
|
value: f.id
|
|
|
};
|
|
|
});
|
|
|
return {
|
|
|
options,
|
|
|
total: brData.keptFieldInfoTable.length
|
|
|
};
|
|
|
},
|
|
|
getKeptMethods() {
|
|
|
const brData = App.keepRadiusData;
|
|
|
if (!brData || !brData.keptMethodInfoTable) return {
|
|
|
options: [],
|
|
|
total: 0
|
|
|
};
|
|
|
const typeRefMap = new Map();
|
|
|
brData.typeReferenceTable.forEach(t => typeRefMap.set(t.id, t
|
|
|
.javaDescriptor));
|
|
|
const methodRefMap = new Map();
|
|
|
brData.methodReferenceTable.forEach(m => methodRefMap.set(m.id, m));
|
|
|
const options = brData.keptMethodInfoTable.slice(0, 1000).map(m => {
|
|
|
const methodRef = methodRefMap.get(m.methodReferenceId);
|
|
|
const name = escapeHTML(formatMethodName(methodRef, brData,
|
|
|
typeRefMap));
|
|
|
return {
|
|
|
name,
|
|
|
value: m.id
|
|
|
};
|
|
|
});
|
|
|
return {
|
|
|
options,
|
|
|
total: brData.keptMethodInfoTable.length
|
|
|
};
|
|
|
},
|
|
|
toggleDropdown(dropdown, triggerBtn = null) {
|
|
|
const allHelpers = [{
|
|
|
dd: this.elements.grpDropdown,
|
|
|
btn: this.elements.grpBtn
|
|
|
},
|
|
|
{
|
|
|
dd: this.elements.clsDropdown,
|
|
|
btn: this.elements.clsBtn
|
|
|
},
|
|
|
{
|
|
|
dd: this.elements.fieldDropdown,
|
|
|
btn: this.elements.fieldBtn
|
|
|
},
|
|
|
{
|
|
|
dd: this.elements.methodDropdown,
|
|
|
btn: this.elements.methodBtn
|
|
|
},
|
|
|
{
|
|
|
dd: this.elements.addFilterDropdown,
|
|
|
btn: this.elements.addFilterBtn
|
|
|
},
|
|
|
{
|
|
|
dd: this.elements.columnsDropdown,
|
|
|
btn: this.elements.toggleColumnsBtn
|
|
|
},
|
|
|
];
|
|
|
const isOpening = dropdown.classList.contains("hidden");
|
|
|
// Close all others first
|
|
|
allHelpers.forEach(({
|
|
|
dd,
|
|
|
btn
|
|
|
}) => {
|
|
|
if (dd !== dropdown) {
|
|
|
if (dd) dd.classList.add("hidden");
|
|
|
if (btn) btn.classList.remove("bg-gray-200");
|
|
|
}
|
|
|
});
|
|
|
if (isOpening) {
|
|
|
dropdown.classList.remove("hidden");
|
|
|
if (triggerBtn) triggerBtn.classList.add("bg-gray-200");
|
|
|
} else {
|
|
|
dropdown.classList.add("hidden");
|
|
|
if (triggerBtn) triggerBtn.classList.remove("bg-gray-200");
|
|
|
}
|
|
|
},
|
|
|
bindEvents() {
|
|
|
// --- Dropdown Management ---
|
|
|
const map = [{
|
|
|
btn: this.elements.grpBtn,
|
|
|
dd: this.elements.grpDropdown
|
|
|
},
|
|
|
{
|
|
|
btn: this.elements.clsBtn,
|
|
|
dd: this.elements.clsDropdown
|
|
|
},
|
|
|
{
|
|
|
btn: this.elements.fieldBtn,
|
|
|
dd: this.elements.fieldDropdown
|
|
|
},
|
|
|
{
|
|
|
btn: this.elements.methodBtn,
|
|
|
dd: this.elements.methodDropdown
|
|
|
},
|
|
|
{
|
|
|
btn: this.elements.addFilterBtn,
|
|
|
dd: this.elements.addFilterDropdown
|
|
|
},
|
|
|
{
|
|
|
btn: this.elements.toggleColumnsBtn,
|
|
|
dd: this.elements.columnsDropdown
|
|
|
},
|
|
|
];
|
|
|
map.forEach(({
|
|
|
btn,
|
|
|
dd
|
|
|
}) => {
|
|
|
if (btn && dd) {
|
|
|
btn.addEventListener("click", (e) => {
|
|
|
if (e.target.closest(".chip-close")) return;
|
|
|
e.stopPropagation();
|
|
|
this.toggleDropdown(dd, btn);
|
|
|
this.updateDynamicFilters();
|
|
|
});
|
|
|
}
|
|
|
});
|
|
|
|
|
|
// --- Column Toggle ---
|
|
|
if (this.elements.toggleBlockedByRuleCb) {
|
|
|
this.elements.toggleBlockedByRuleCb.addEventListener("change", (e) => {
|
|
|
this.state.showBlockedByRule = e.target.checked;
|
|
|
this.render();
|
|
|
});
|
|
|
}
|
|
|
const tabsContainer = document.getElementById("lens-tabs");
|
|
|
if (tabsContainer) {
|
|
|
tabsContainer.addEventListener("click", (e) => {
|
|
|
const btn = e.target.closest(".segment-btn");
|
|
|
if (!btn) return;
|
|
|
const lens = btn.dataset.lens;
|
|
|
this.state.filters.keepRules = lens === "All" ? [] : [lens];
|
|
|
this.updateDynamicFilters();
|
|
|
this.render();
|
|
|
});
|
|
|
}
|
|
|
|
|
|
// Global click listener to close dropdowns
|
|
|
document.addEventListener("click", (e) => {
|
|
|
let anyClosed = false;
|
|
|
map.forEach(({
|
|
|
dd,
|
|
|
btn
|
|
|
}) => {
|
|
|
if (dd && !dd.contains(e.target) && (!btn || !btn.contains(e
|
|
|
.target))) {
|
|
|
if (!dd.classList.contains("hidden")) {
|
|
|
dd.classList.add("hidden");
|
|
|
if (btn) btn.classList.remove("bg-gray-200");
|
|
|
anyClosed = true;
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
if (anyClosed) {
|
|
|
this.updateDynamicFilters();
|
|
|
}
|
|
|
// Close search bar if clicked outside
|
|
|
if (this.elements.searchContainer && !this.elements.searchContainer.contains(e.target)) {
|
|
|
this.elements.searchContainer.classList.remove("active");
|
|
|
}
|
|
|
});
|
|
|
// Chip removals
|
|
|
document.getElementById("filter-chips-container").addEventListener(
|
|
|
"click", (e) => {
|
|
|
const closeBtn = e.target.closest(".chip-close");
|
|
|
if (closeBtn) {
|
|
|
e.stopPropagation();
|
|
|
const type = closeBtn.dataset.clear;
|
|
|
if (type === "module") {
|
|
|
this.state.filters.keepRules = [];
|
|
|
this.state.activeFilterChips = this.state.activeFilterChips
|
|
|
.filter(c => c !== "module");
|
|
|
} else if (type === "class") {
|
|
|
this.state.filters.classes = [];
|
|
|
this.state.activeFilterChips = this.state.activeFilterChips
|
|
|
.filter(c => c !== "class");
|
|
|
} else if (type === "field") {
|
|
|
this.state.filters.fields = [];
|
|
|
this.state.activeFilterChips = this.state.activeFilterChips
|
|
|
.filter(c => c !== "field");
|
|
|
} else if (type === "method") {
|
|
|
this.state.filters.methods = [];
|
|
|
this.state.activeFilterChips = this.state.activeFilterChips
|
|
|
.filter(c => c !== "method");
|
|
|
}
|
|
|
this.updateDynamicFilters();
|
|
|
this.render();
|
|
|
}
|
|
|
});
|
|
|
// --- Group By Dropdown ---
|
|
|
this.elements.grpDropdown.addEventListener("click", (e) => {
|
|
|
const item = e.target.closest(".dropdown-item");
|
|
|
if (!item) return;
|
|
|
e.preventDefault();
|
|
|
this.state.currentView = item.dataset.value;
|
|
|
this.state.drillContext = {
|
|
|
module: null,
|
|
|
pkg: null
|
|
|
}; // Reset Drill-Down
|
|
|
// Reset default sort based on view
|
|
|
if (this.state.currentView === CONSTANTS.VIEWS.CLASSES ||
|
|
|
this.state.currentView === CONSTANTS.VIEWS.FIELDS ||
|
|
|
this.state.currentView === CONSTANTS.VIEWS.METHODS) {
|
|
|
this.state.sort = {
|
|
|
by: "name",
|
|
|
order: "asc"
|
|
|
};
|
|
|
} else {
|
|
|
this.state.sort = {
|
|
|
by: "matches.total",
|
|
|
order: "desc"
|
|
|
};
|
|
|
}
|
|
|
this.toggleDropdown(this.elements.grpDropdown, this.elements
|
|
|
.grpBtn);
|
|
|
this.render();
|
|
|
});
|
|
|
// --- Table Sorting ---
|
|
|
this.elements.tableHeaders.addEventListener("click", (e) => {
|
|
|
const th = e.target.closest("[data-sort-by]");
|
|
|
if (!th) return;
|
|
|
const newSortBy = th.dataset.sortBy;
|
|
|
if (this.state.sort.by === newSortBy)
|
|
|
this.state.sort.order = this.state.sort.order === "asc" ? "desc" :
|
|
|
"asc";
|
|
|
else {
|
|
|
this.state.sort.by = newSortBy;
|
|
|
this.state.sort.order = "desc";
|
|
|
}
|
|
|
this.render();
|
|
|
});
|
|
|
// --- Table Row Interaction (Manual Drill-Down) ---
|
|
|
this.elements.tableData.addEventListener("click", (e) => {
|
|
|
const ruleTd = e.target.closest("td[data-rule-id]");
|
|
|
if (ruleTd) {
|
|
|
e.preventDefault();
|
|
|
App.showDetailsView(ruleTd.dataset.ruleId);
|
|
|
return;
|
|
|
}
|
|
|
const fileTd = e.target.closest("td[data-file-origin-id]");
|
|
|
if (fileTd) {
|
|
|
e.preventDefault();
|
|
|
App.showFileDetailsView(fileTd.dataset.fileOriginId);
|
|
|
return;
|
|
|
}
|
|
|
const td = e.target.closest("td[data-name]");
|
|
|
if (!td) return;
|
|
|
const {
|
|
|
name,
|
|
|
type,
|
|
|
moduleName
|
|
|
} = td.dataset;
|
|
|
// Update Drill-Context (Silent)
|
|
|
if (type === "module") {
|
|
|
this.state.drillContext.module = name;
|
|
|
this.state.drillContext.pkg = null;
|
|
|
} else if (type === "package") {
|
|
|
this.state.drillContext.module = moduleName || this.state
|
|
|
.drillContext.module;
|
|
|
this.state.drillContext.pkg = name;
|
|
|
}
|
|
|
this.updateBreadcrumbs();
|
|
|
this.render();
|
|
|
});
|
|
|
|
|
|
// --- Search Icon Toggle ---
|
|
|
if (this.elements.searchIconBtn) {
|
|
|
this.elements.searchIconBtn.addEventListener("click", (e) => {
|
|
|
e.stopPropagation();
|
|
|
this.elements.searchContainer.classList.toggle("active");
|
|
|
if (this.elements.searchContainer.classList.contains("active")) {
|
|
|
this.elements.searchInput.focus();
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
|
|
|
// --- Search Input ---
|
|
|
if (this.elements.searchInput) {
|
|
|
this.elements.searchInput.addEventListener("input", (e) => {
|
|
|
this.state.searchTerm = e.target.value;
|
|
|
if (this.state.searchTerm) {
|
|
|
this.elements.clearSearchBtn.classList.remove("hidden");
|
|
|
} else {
|
|
|
this.elements.clearSearchBtn.classList.add("hidden");
|
|
|
}
|
|
|
this.render();
|
|
|
});
|
|
|
}
|
|
|
if (this.elements.clearSearchBtn) {
|
|
|
this.elements.clearSearchBtn.addEventListener("click", () => {
|
|
|
this.elements.searchInput.value = "";
|
|
|
this.state.searchTerm = "";
|
|
|
this.elements.clearSearchBtn.classList.add("hidden");
|
|
|
this.render();
|
|
|
});
|
|
|
}
|
|
|
|
|
|
// --- Help Hub Events ---
|
|
|
const helpHubFab = document.getElementById("help-hub-fab");
|
|
|
const helpHubPanel = document.getElementById("help-hub-panel");
|
|
|
const closeHelpHubBtn = document.getElementById("close-help-hub");
|
|
|
const helpHubSearchInput = document.querySelector("#help-hub-panel .search-input");
|
|
|
|
|
|
if (helpHubFab && helpHubPanel) {
|
|
|
helpHubFab.addEventListener("click", (e) => {
|
|
|
e.stopPropagation();
|
|
|
helpHubPanel.classList.toggle("open");
|
|
|
});
|
|
|
}
|
|
|
|
|
|
if (closeHelpHubBtn && helpHubPanel) {
|
|
|
closeHelpHubBtn.addEventListener("click", (e) => {
|
|
|
e.stopPropagation();
|
|
|
helpHubPanel.classList.remove("open");
|
|
|
});
|
|
|
}
|
|
|
|
|
|
// Close help hub when clicking outside
|
|
|
document.addEventListener("click", (e) => {
|
|
|
if (helpHubPanel && !helpHubPanel.contains(e.target) && !helpHubFab.contains(e.target)) {
|
|
|
helpHubPanel.classList.remove("open");
|
|
|
}
|
|
|
});
|
|
|
|
|
|
|
|
|
// Help Hub Accordion
|
|
|
if (helpHubPanel) {
|
|
|
const legendItems = helpHubPanel.querySelectorAll(".legend-item");
|
|
|
legendItems.forEach(item => {
|
|
|
const header = item.querySelector(".legend-item-header");
|
|
|
if (header) {
|
|
|
header.addEventListener("click", () => {
|
|
|
// Close all other items
|
|
|
legendItems.forEach(other => {
|
|
|
if (other !== item) {
|
|
|
other.classList.remove("open");
|
|
|
}
|
|
|
});
|
|
|
// Toggle current item
|
|
|
item.classList.toggle("open");
|
|
|
});
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
},
|
|
|
/**
|
|
|
* Core Data Pipeline: Filters and Flattens data based on current View Mode and Filters.
|
|
|
*/
|
|
|
applyKeepRuleLens(rules, lens) {
|
|
|
const brData = App.keepRadiusData;
|
|
|
if (!lens || !brData) return rules;
|
|
|
const ruleMap = new Map();
|
|
|
brData.keepRuleKeepRadiusTable.forEach(r => {
|
|
|
ruleMap.set(r.id, r);
|
|
|
});
|
|
|
return rules.filter(r => {
|
|
|
const getSubsumedBy = (rule) => rule.subsumedBy || (rule
|
|
|
.keepRadius && rule.keepRadius.subsumedBy) || [];
|
|
|
const getMatchesTotal = (rule) => {
|
|
|
if (rule.matches && rule.matches.total !== undefined)
|
|
|
return rule.matches.total;
|
|
|
const b = rule.keepRadius || {};
|
|
|
return (b.classKeepRadius || []).length + (b
|
|
|
.fieldKeepRadius || []).length + (b.methodKeepRadius ||
|
|
|
[]).length;
|
|
|
};
|
|
|
const subsumedBy = getSubsumedBy(r);
|
|
|
if (lens === "Identical") {
|
|
|
const identical = subsumedBy.filter(otherId => {
|
|
|
const other = ruleMap.get(otherId);
|
|
|
return other && (other.keepRadius?.subsumedBy || [])
|
|
|
.includes(r.id);
|
|
|
}).map(otherId => ruleMap.get(otherId));
|
|
|
if (identical.length > 0) {
|
|
|
r.identicalRules = identical;
|
|
|
return true;
|
|
|
}
|
|
|
return false;
|
|
|
} else if (lens === "Subsumed") {
|
|
|
if (subsumedBy.length > 0) {
|
|
|
r.subsumedByRules = subsumedBy.map(id => ruleMap.get(id));
|
|
|
return true;
|
|
|
}
|
|
|
return false;
|
|
|
} else if (lens === "Unused") {
|
|
|
return getMatchesTotal(r) === 0;
|
|
|
}
|
|
|
return true;
|
|
|
});
|
|
|
},
|
|
|
getFilteredData() {
|
|
|
const {
|
|
|
currentView,
|
|
|
filters
|
|
|
} = this.state;
|
|
|
const brData = App.keepRadiusData;
|
|
|
if (!brData) return [];
|
|
|
let data = [];
|
|
|
if (currentView === CONSTANTS.VIEWS.PACKAGES) {
|
|
|
data = getRuleFiles(brData).filter(f => f.matches.total > 0);
|
|
|
} else {
|
|
|
data = getRules(brData);
|
|
|
// If lens is 'Residual', 'All', or default, show only rules with matches > 0.
|
|
|
// If lens is 'Unused', show only rules with matches === 0.
|
|
|
const lens = filters.keepRules[0];
|
|
|
if (lens === "Residual" || lens === "All" || !lens) {
|
|
|
data = data.filter(r => r.matches.total > 0);
|
|
|
} else if (lens === "Unused") {
|
|
|
data = data.filter(r => r.matches.total === 0);
|
|
|
}
|
|
|
}
|
|
|
// Apply Keep Rules Lens (Filtering)
|
|
|
if (currentView === CONSTANTS.VIEWS.MODULES && filters.keepRules.length >
|
|
|
0) {
|
|
|
data = this.applyKeepRuleLens(data, filters.keepRules[0]);
|
|
|
}
|
|
|
// Apply Class/Field/Method filters
|
|
|
if (filters.classes.length > 0 || filters.fields.length > 0 || filters
|
|
|
.methods.length > 0) {
|
|
|
const matchedRuleIds = new Set();
|
|
|
if (filters.classes.length > 0) {
|
|
|
brData.keptClassInfoTable.forEach(c => {
|
|
|
if (filters.classes.includes(c.id)) {
|
|
|
(c.keptBy || []).forEach(rid => matchedRuleIds.add(rid));
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
if (filters.fields.length > 0) {
|
|
|
brData.keptFieldInfoTable.forEach(f => {
|
|
|
if (filters.fields.includes(f.id)) {
|
|
|
(f.keptBy || []).forEach(rid => matchedRuleIds.add(rid));
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
if (filters.methods.length > 0) {
|
|
|
brData.keptMethodInfoTable.forEach(m => {
|
|
|
if (filters.methods.includes(m.id)) {
|
|
|
(m.keptBy || []).forEach(rid => matchedRuleIds.add(rid));
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
data = data.filter(r => matchedRuleIds.has(r.id));
|
|
|
}
|
|
|
if (this.state.searchTerm) {
|
|
|
const term = this.state.searchTerm.toLowerCase();
|
|
|
data = data.filter(item => item.name.toLowerCase().includes(term));
|
|
|
}
|
|
|
return data;
|
|
|
},
|
|
|
getSortedData(data) {
|
|
|
const {
|
|
|
by,
|
|
|
order
|
|
|
} = this.state.sort;
|
|
|
if (!by) return data;
|
|
|
const getVal = (obj, path) => {
|
|
|
return path.split('.').reduce((o, key) => (o && o[key] !==
|
|
|
undefined) ? o[key] : 0, obj);
|
|
|
};
|
|
|
return [...data].sort((a, b) => {
|
|
|
const vA = getVal(a, by);
|
|
|
const vB = getVal(b, by);
|
|
|
if (typeof vA === "string")
|
|
|
return order === "asc" ? vA.localeCompare(vB) : vB.localeCompare(
|
|
|
vA);
|
|
|
return order === "asc" ? (vA || 0) - (vB || 0) : (vB || 0) - (vA ||
|
|
|
0);
|
|
|
});
|
|
|
},
|
|
|
updateBreadcrumbs() {
|
|
|
const bc = document.getElementById("flat-breadcrumbs");
|
|
|
if (!bc) return;
|
|
|
const linkClass = "breadcrumb-pill";
|
|
|
const textClass = "breadcrumb-text";
|
|
|
const sep = '<span class="text-gray-300 mx-1">/</span>';
|
|
|
let html = "";
|
|
|
const {
|
|
|
module,
|
|
|
pkg: pkg
|
|
|
} = this.state.drillContext;
|
|
|
const toggleText = this.state.statsVisible ? "Hide" :
|
|
|
"Show";
|
|
|
const toggleHtml = `
|
|
|
<button class="dropdown-btn" data-action="toggle-stats" style="border: none; background: transparent; padding: 0.25rem 0.5rem; display: flex; align-items: center; border-radius: 4px; margin-left: auto; cursor: pointer;">
|
|
|
<span style="font-weight: 500; color: var(--text-gray-400);">${toggleText}</span>
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 24 24"
|
|
|
stroke="currentColor" style="margin-left: 0.25rem; color: var(--text-gray-500); transform: ${this.state.statsVisible ? 'rotate(180deg)' : 'rotate(0deg)'}; transition: transform 0.2s;">
|
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
|
|
|
</svg>
|
|
|
</button>
|
|
|
`;
|
|
|
if (module) {
|
|
|
// Drilled Down Path
|
|
|
html += `<span class="${linkClass}" data-action="reset">R8 Optimization Levels</span>`;
|
|
|
html += sep;
|
|
|
if (pkg) {
|
|
|
html +=
|
|
|
`<span class="${linkClass}" data-action="module" data-val="${escapeHTML(module)}">${escapeHTML(module)}</span>`;
|
|
|
html += sep;
|
|
|
html += `<span class="${textClass}">${escapeHTML(pkg)}</span>`;
|
|
|
} else {
|
|
|
html += `<span class="${textClass}">${escapeHTML(module)}</span>`;
|
|
|
}
|
|
|
} else {
|
|
|
// Global View
|
|
|
html = `<span class="${textClass}">R8 Optimization Levels</span>`;
|
|
|
}
|
|
|
|
|
|
const subtextHtml = `
|
|
|
<div style="font-size: 0.75rem; color: var(--text-gray-500); font-weight: 400; margin-top: 0.25rem; text-transform: none; letter-spacing: normal; padding: 0rem 0.5rem;">
|
|
|
The percentage of your app’s codebase that R8 successfully shrinks, optimizes, and obfuscates. Achieving a higher percentage indicates a leaner, more performant application.
|
|
|
</div>
|
|
|
`;
|
|
|
|
|
|
bc.style.display = "flex";
|
|
|
bc.style.alignItems = "center";
|
|
|
bc.style.width = "100%";
|
|
|
bc.innerHTML = `
|
|
|
<div style="display: flex; flex-direction: column; align-items: start;">
|
|
|
<div style="display: flex; align-items: center;">
|
|
|
${html}
|
|
|
</div>
|
|
|
${this.state.statsVisible ? subtextHtml : ''}
|
|
|
</div>
|
|
|
${toggleHtml}
|
|
|
`;
|
|
|
// Breadcrumb Click Handlers
|
|
|
bc.querySelectorAll("[data-action]").forEach((el) => {
|
|
|
el.addEventListener("click", (e) => {
|
|
|
const action = el.dataset.action;
|
|
|
if (action === "reset") {
|
|
|
this.state.drillContext = {
|
|
|
module: null,
|
|
|
pkg: null
|
|
|
};
|
|
|
this.render();
|
|
|
} else if (action === "module") {
|
|
|
this.state.drillContext.pkg = null;
|
|
|
this.render();
|
|
|
} else if (action === "toggle-stats") {
|
|
|
this.state.statsVisible = !this.state.statsVisible;
|
|
|
this.render();
|
|
|
}
|
|
|
});
|
|
|
});
|
|
|
},
|
|
|
render() {
|
|
|
this.updateBreadcrumbs();
|
|
|
if (this.state.currentView === CONSTANTS.VIEWS.FILE_DETAILS) {
|
|
|
App.renderFileDetailsView(this.state.drillContext.fileOriginId);
|
|
|
return;
|
|
|
}
|
|
|
if (this.state.currentView === CONSTANTS.VIEWS.DETAILS) {
|
|
|
return;
|
|
|
}
|
|
|
// Update Label of Group Dropdown
|
|
|
const currentView = this.state.currentView;
|
|
|
const viewLabels = {
|
|
|
modules: "Keep Rules",
|
|
|
packages: "Keep Rule Files"
|
|
|
};
|
|
|
this.elements.grpText.textContent = viewLabels[currentView] || (
|
|
|
currentView.charAt(0).toUpperCase() + currentView.slice(1));
|
|
|
if (this.elements.grpList) {
|
|
|
this.elements.grpList.querySelectorAll(".dropdown-item").forEach((
|
|
|
el) => {
|
|
|
if (el.dataset.value === currentView)
|
|
|
el.classList.add("bg-gray-100", "text-gray-900",
|
|
|
"font-semibold");
|
|
|
else el.classList.remove("bg-gray-100", "text-gray-900",
|
|
|
"font-semibold");
|
|
|
});
|
|
|
}
|
|
|
// Process Data
|
|
|
let data = this.getFilteredData();
|
|
|
data = this.getSortedData(data);
|
|
|
// Update Summary Counts
|
|
|
let relevantClasses = [],
|
|
|
modCount = 0;
|
|
|
if (currentView === CONSTANTS.VIEWS.PACKAGES) {
|
|
|
relevantClasses = data.flatMap((p) => p.classes || []);
|
|
|
modCount = new Set(data.map((p) => p.moduleName)).size;
|
|
|
} else {
|
|
|
relevantClasses = data.flatMap((m) => (m.packages || []).flatMap((p) =>
|
|
|
p.classes || []));
|
|
|
modCount = data.length;
|
|
|
}
|
|
|
// Stats table visibility
|
|
|
if (this.elements.statsContainer) {
|
|
|
this.elements.statsContainer.style.display = this.state.statsVisible ?
|
|
|
"flex" : "none";
|
|
|
this.elements.statsContainer.style.marginBottom = this.state
|
|
|
.statsVisible ? "2rem" : "0";
|
|
|
}
|
|
|
const brData = App.keepRadiusData;
|
|
|
const totalLive = getLiveItemCount(brData);
|
|
|
const formatPerc = (disallowCount) => totalLive > 0 ? (100 - (
|
|
|
disallowCount / totalLive * 100)).toFixed(1) + '%' : '--';
|
|
|
const getPerc = (disallowCount) => totalLive > 0 ? (100 - (disallowCount /
|
|
|
totalLive * 100)) : '--';
|
|
|
const setStatValue = (element, disallowCount) => {
|
|
|
if (!brData) {
|
|
|
element.textContent = '--';
|
|
|
element.className = 'stat-value ' + UIUtils.getScoreClass('--');
|
|
|
return;
|
|
|
}
|
|
|
const perc = getPerc(disallowCount);
|
|
|
element.textContent = formatPerc(disallowCount);
|
|
|
element.className = 'stat-value ' + UIUtils.getScoreClass(perc);
|
|
|
};
|
|
|
setStatValue(this.elements.totalObfuscation, getDisallowObfuscationCount(
|
|
|
brData));
|
|
|
setStatValue(this.elements.totalOptimization,
|
|
|
getDisallowOptimizationCount(brData));
|
|
|
setStatValue(this.elements.totalShrinking, getDisallowShrinkingCount(
|
|
|
brData));
|
|
|
// Render Tables
|
|
|
this.renderHeaders();
|
|
|
this.renderFlatRows(data);
|
|
|
this.renderStatsTable();
|
|
|
},
|
|
|
renderStatsTable() {
|
|
|
const brData = App.keepRadiusData;
|
|
|
if (!brData) return;
|
|
|
|
|
|
const stats = getDetailedStats(brData);
|
|
|
if (!stats) return;
|
|
|
|
|
|
const updateCard = (key) => {
|
|
|
const setStat = (id, disallowCount, total) => {
|
|
|
const el = document.getElementById(id);
|
|
|
const perc = total > 0 ? (100 - (disallowCount / total * 100)) : 100;
|
|
|
if (el) {
|
|
|
el.textContent = perc.toFixed(1) + '%';
|
|
|
}
|
|
|
return perc;
|
|
|
};
|
|
|
|
|
|
const totalPerc = setStat(`card-total-${key}`, stats.overall[key], stats.overall.total);
|
|
|
|
|
|
const updateItem = (type) => {
|
|
|
const bar = document.getElementById(`card-${key}-${type}-bar`);
|
|
|
const val = document.getElementById(`card-${key}-${type}-val`);
|
|
|
if (bar && val) {
|
|
|
const disallow = stats[type][key];
|
|
|
const total = stats[type].total;
|
|
|
const perc = total > 0 ? (100 - (disallow / total * 100)) : 100;
|
|
|
bar.style.width = `${perc}%`;
|
|
|
val.textContent = `${perc.toFixed(1)}%`;
|
|
|
|
|
|
const colorClass = UIUtils.getScoreClass(perc);
|
|
|
if (colorClass.includes('green')) {
|
|
|
bar.style.background = 'var(--text-green-600)';
|
|
|
} else if (colorClass.includes('yellow')) {
|
|
|
bar.style.background = 'var(--text-yellow-600)';
|
|
|
} else if (colorClass.includes('red')) {
|
|
|
bar.style.background = 'var(--text-red-600)';
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
|
|
|
updateItem("classes");
|
|
|
updateItem("fields");
|
|
|
updateItem("methods");
|
|
|
};
|
|
|
|
|
|
updateCard("obfuscation");
|
|
|
updateCard("optimization");
|
|
|
updateCard("shrinking");
|
|
|
},
|
|
|
renderHeaders() {
|
|
|
const {
|
|
|
currentView,
|
|
|
sort
|
|
|
} = this.state;
|
|
|
const topHeader = document.createElement("tr");
|
|
|
const subHeader = document.createElement("tr");
|
|
|
const viewLabels = {
|
|
|
modules: "RULE",
|
|
|
packages: "KEEP RULE FILES"
|
|
|
};
|
|
|
const title = viewLabels[currentView];
|
|
|
const ind = (key) => {
|
|
|
if (sort.by !== key) return "";
|
|
|
return sort.order === "asc" ?
|
|
|
`<span class="sort-icon text-blue-600 ml-1">▲</span>` :
|
|
|
`<span class="sort-icon text-blue-600 ml-1">▼</span>`;
|
|
|
};
|
|
|
if (currentView === CONSTANTS.VIEWS.PACKAGES) {
|
|
|
topHeader.innerHTML = `
|
|
|
<th rowspan="2" class="text-left sticky-name bg-gray-50 z-30" data-sort-by="name" style="width: 40%; min-width: 300px;">
|
|
|
<div class="flex items-center cursor-pointer hover:text-blue-600" style="padding: 1rem;">
|
|
|
${title}${ind("name")}
|
|
|
</div>
|
|
|
</th>
|
|
|
<th rowspan="2" class="text-center bg-gray-50 border-l border-gray-200 cursor-pointer hover:bg-gray-100" data-sort-by="keepRules" style="padding: 1rem; width: 12%;">Keep Rules${ind("keepRules")}</th>
|
|
|
<th rowspan="2" class="text-center border-l border-gray-200 bg-gray-50 cursor-pointer hover:bg-gray-100" data-sort-by="matches.total" style="padding: 0.5rem; width: 12%;">Kept Items${ind("matches.total")}</th>
|
|
|
<th rowspan="2" class="text-center text-xs font-medium text-gray-500 border-l border-gray-200 cursor-pointer hover:bg-gray-100" data-sort-by="impact.obfuscation" style="padding: 0.5rem; width: 12%;">Obfuscation Score${ind("impact.obfuscation")}</th>
|
|
|
<th rowspan="2" class="text-center text-xs font-medium text-gray-500 border-l border-gray-200 cursor-pointer hover:bg-gray-100" data-sort-by="impact.optimization" style="padding: 0.5rem; width: 12%;">Optimization Score${ind("impact.optimization")}</th>
|
|
|
<th rowspan="2" class="text-center text-xs font-medium text-gray-500 border-l border-gray-200 cursor-pointer hover:bg-gray-100" data-sort-by="impact.shrinking" style="padding: 0.5rem; width: 12%;">Shrinking Score${ind("impact.shrinking")}</th>
|
|
|
`;
|
|
|
subHeader.innerHTML = ``;
|
|
|
} else {
|
|
|
const lens = this.state.filters.keepRules[0];
|
|
|
const isIdenticalLens = currentView === CONSTANTS.VIEWS.MODULES &&
|
|
|
lens === "Identical";
|
|
|
const isSubsumedLens = currentView === CONSTANTS.VIEWS.MODULES &&
|
|
|
lens === "Subsumed";
|
|
|
const isUnusedLens = currentView === CONSTANTS.VIEWS.MODULES &&
|
|
|
lens === "Unused";
|
|
|
if (this.elements.mainTable) {
|
|
|
if (isIdenticalLens || isSubsumedLens || isUnusedLens) {
|
|
|
this.elements.mainTable.style.tableLayout = "fixed";
|
|
|
} else {
|
|
|
this.elements.mainTable.style.tableLayout = "";
|
|
|
}
|
|
|
}
|
|
|
if (isIdenticalLens || isSubsumedLens) {
|
|
|
topHeader.innerHTML = `
|
|
|
<th rowspan="2" class="text-left sticky-name bg-gray-50 z-30" data-sort-by="name" style="width: 50%; min-width: 300px;">
|
|
|
<div class="flex items-center cursor-pointer hover:text-blue-600" style="padding: 1rem;">
|
|
|
${title}${ind("name")}
|
|
|
</div>
|
|
|
</th>
|
|
|
<th rowspan="2" class="text-left bg-gray-50 border-l border-gray-200" style="padding: 1rem; width: 50%;">${isIdenticalLens ? 'Identical Rules' : 'Subsumed By'}</th>
|
|
|
`;
|
|
|
subHeader.innerHTML = '';
|
|
|
} else if (isUnusedLens) {
|
|
|
topHeader.innerHTML = `
|
|
|
<th rowspan="2" class="text-left sticky-name bg-gray-50 z-30" data-sort-by="name" style="width: 50%; min-width: 300px;">
|
|
|
<div class="flex items-center cursor-pointer hover:text-blue-600" style="padding: 1rem;">
|
|
|
${title}${ind("name")}
|
|
|
</div>
|
|
|
</th>
|
|
|
<th rowspan="2" class="text-left bg-gray-50 border-l border-gray-200" style="padding: 1rem; width: 50%;">Origin</th>
|
|
|
`;
|
|
|
subHeader.innerHTML = '';
|
|
|
} else {
|
|
|
topHeader.innerHTML = `
|
|
|
<th rowspan="2" class="text-left sticky-name bg-gray-50 z-30" data-sort-by="name" style="width: 40%; min-width: 300px;">
|
|
|
<div class="flex items-center cursor-pointer hover:text-blue-600" style="padding: 1rem;">
|
|
|
${title}${ind("name")}
|
|
|
</div>
|
|
|
</th>
|
|
|
<th colspan="4" class="text-center border-l border-gray-200 bg-gray-50" style="padding: 0.5rem; width: 40%;">KEPT ITEMS <span style="color: var(--text-muted);text-transform: none;font-weight: 500;">Higher is worse</span> <span class="tooltip-icon" data-tooltip="Items retained in the app due to this rule">?</span></th>
|
|
|
${this.state.showBlockedByRule ? `
|
|
|
<th rowspan="2" class="text-left bg-gray-50" style="padding: 1rem; width: 20%; border-left: 1px solid var(--border-color);">BLOCKED BY RULE <span class="tooltip-icon" data-tooltip="Specific actions blocked by this rule">?</span></th>
|
|
|
` : ''}
|
|
|
`;
|
|
|
subHeader.innerHTML = `
|
|
|
<th class="text-center text-xs font-medium text-gray-500 border-l border-gray-200 cursor-pointer hover:bg-gray-100" data-sort-by="matches.total" style="padding: 0.5rem; width: 100px; min-width: 100px;">Total${ind("matches.total")}</th>
|
|
|
<th class="text-center text-xs font-medium text-gray-500 border-l border-gray-200 cursor-pointer hover:bg-gray-100" data-sort-by="matches.classes" style="padding: 0.5rem; width: 100px; min-width: 100px;">Classes${ind("matches.classes")}</th>
|
|
|
<th class="text-center text-xs font-medium text-gray-500 border-l border-gray-200 cursor-pointer hover:bg-gray-100" data-sort-by="matches.fields" style="padding: 0.5rem; width: 100px; min-width: 100px;">Fields${ind("matches.fields")}</th>
|
|
|
<th class="text-center text-xs font-medium text-gray-500 border-l border-gray-200 cursor-pointer hover:bg-gray-100" data-sort-by="matches.methods" style="padding: 0.5rem; width: 100px; min-width: 100px;">Methods${ind("matches.methods")}</th>
|
|
|
`;
|
|
|
}
|
|
|
}
|
|
|
this.elements.tableHeaders.innerHTML = "";
|
|
|
this.elements.tableHeaders.append(topHeader, subHeader);
|
|
|
},
|
|
|
renderFlatRows(data) {
|
|
|
const {
|
|
|
currentView
|
|
|
} = this.state;
|
|
|
if (!data.length) {
|
|
|
this.elements.tableData.innerHTML =
|
|
|
`<tr><td colspan="10" class="text-center py-8 text-gray-500">No results found.</td></tr>`;
|
|
|
return;
|
|
|
}
|
|
|
const brData = App.keepRadiusData;
|
|
|
const build = brData?.buildInfo || {};
|
|
|
const totalLive = getLiveItemCount(brData);
|
|
|
const renderMatchCell = (count, total) => {
|
|
|
const perc = total > 0 ? (count / total * 100) : 0;
|
|
|
const colorClass = UIUtils.getMatchClass(perc);
|
|
|
return `
|
|
|
<td class="text-center border-l border-gray-200" style="padding: 1rem; width: 12%;">
|
|
|
<div style="display: flex; flex-direction: column; align-items: center; justify-content: center;">
|
|
|
<span class="font-medium ${colorClass}">${perc.toFixed(1)}%</span>
|
|
|
<span class="text-xs text-gray-500 mt-1">${count}</span>
|
|
|
</div>
|
|
|
</td>
|
|
|
`;
|
|
|
};
|
|
|
const renderScoreCell = (disallowCount, total) => {
|
|
|
const perc = total > 0 ? (100 - (disallowCount / total * 100)) : 100;
|
|
|
const colorClass = UIUtils.getScoreClass(perc);
|
|
|
return `
|
|
|
<td class="text-center border-l border-gray-200" style="padding: 1rem; width: 12%;">
|
|
|
<div style="display: flex; flex-direction: column; align-items: center; justify-content: center;">
|
|
|
<span class="font-medium ${colorClass}">${perc.toFixed(1)}%</span>
|
|
|
<span class="text-xs text-gray-500 mt-1">${total - disallowCount}/${total}</span>
|
|
|
</div>
|
|
|
</td>
|
|
|
`;
|
|
|
};
|
|
|
this.elements.tableData.innerHTML = data.map((item) => {
|
|
|
const cleanedName = item.name.trim();
|
|
|
const escapedName = escapeHTML(cleanedName);
|
|
|
let nameCell = "";
|
|
|
if (currentView === CONSTANTS.VIEWS.MODULES) {
|
|
|
const highlightedName = highlightRule(cleanedName);
|
|
|
nameCell = `<td class="sticky-name font-medium hover:underline cursor-pointer" title="${escapedName}" style="padding: 1rem; width: 40%; min-width: 300px; font-family: var(--font-family-mono);" data-rule-id="${item.id}">
|
|
|
<pre style="white-space: pre-wrap; font-family: var(--font-family-mono); font-size: 0.8125rem; margin: 0; pointer-events: none;">${highlightedName}</pre>
|
|
|
</td>`;
|
|
|
} else if (currentView === CONSTANTS.VIEWS.PACKAGES) {
|
|
|
nameCell = `<td class="sticky-name font-medium text-blue-600 hover:underline cursor-pointer" title="${escapedName}" style="padding: 1rem; width: 40%; min-width: 300px;" data-file-origin-id="${item.id}">
|
|
|
<pre style="white-space: pre-wrap; font-family: var(--font-family-mono); font-size: 0.8125rem; margin: 0; pointer-events: none;">${escapedName}</pre>
|
|
|
</td>`;
|
|
|
} else {
|
|
|
nameCell =
|
|
|
`<td class="sticky-name font-medium text-gray-900" title="${escapedName}" style="padding: 1rem; width: 40%; min-width: 300px;"><pre style="white-space: pre-wrap; font-family: var(--font-family-mono); font-size: 0.8125rem; margin: 0;">${escapedName}</pre></td>`;
|
|
|
}
|
|
|
if (currentView === CONSTANTS.VIEWS.PACKAGES) {
|
|
|
const keepRulesCell =
|
|
|
`<td class="text-center border-l border-gray-200 text-sm font-semibold" style="padding: 1rem; width: 12%;">${item.keepRules}</td>`;
|
|
|
const totalKeptCell = renderMatchCell(item.matches.total,
|
|
|
totalLive);
|
|
|
const impactCells = `
|
|
|
${renderScoreCell(item.impact.obfuscation, totalLive)}
|
|
|
${renderScoreCell(item.impact.optimization, totalLive)}
|
|
|
${renderScoreCell(item.impact.shrinking, totalLive)}
|
|
|
`;
|
|
|
return `<tr class="table-row border-b border-gray-200 hover:bg-gray-50">${nameCell}${keepRulesCell}${totalKeptCell}${impactCells}</tr>`;
|
|
|
} else {
|
|
|
const lens = this.state.filters.keepRules[0];
|
|
|
const isIdenticalLens = currentView === CONSTANTS.VIEWS.MODULES &&
|
|
|
lens === "Identical";
|
|
|
const isSubsumedLens = currentView === CONSTANTS.VIEWS.MODULES &&
|
|
|
lens === "Subsumed";
|
|
|
const isUnusedLens = currentView === CONSTANTS.VIEWS.MODULES &&
|
|
|
lens === "Unused";
|
|
|
const customNameCell = `<td class="sticky-name font-medium hover:underline cursor-pointer" title="${escapedName}" style="padding: 1rem; width: 50%; min-width: 300px; font-family: var(--font-family-mono);" data-rule-id="${item.id}">
|
|
|
<pre style="white-space: pre-wrap; font-family: var(--font-family-mono); font-size: 0.8125rem; margin: 0; pointer-events: none;">${highlightRule(cleanedName)}</pre>
|
|
|
</td>`;
|
|
|
|
|
|
if (isIdenticalLens || isSubsumedLens) {
|
|
|
const rules = isIdenticalLens ? item.identicalRules : item
|
|
|
.subsumedByRules;
|
|
|
const rulesHtml = (rules || []).map(r => `
|
|
|
<div style="font-family: var(--font-family-mono); font-size: 0.8125rem; margin-bottom: 0.25rem;">
|
|
|
<pre style="white-space: pre-wrap; margin: 0; color: var(--text-main);">${highlightRule(r.source)}</pre>
|
|
|
</div>
|
|
|
`).join("");
|
|
|
|
|
|
return `<tr class="table-row border-b border-gray-200 hover:bg-gray-50">${customNameCell}<td class="border-l border-gray-200" style="padding: 1rem; vertical-align: top; width: 50%; font-family: var(--font-family-mono);">${rulesHtml}</td></tr>`;
|
|
|
} else if (isUnusedLens) {
|
|
|
const rule = brData.keepRuleKeepRadiusTable.find(r => r.id === item.id) || brData.globalKeepRuleKeepRadiusTable.find(r => r.id === item.id);
|
|
|
const fileOrigin = brData.fileOriginTable.find(f => f.id === rule?.origin?.fileOriginId);
|
|
|
let originStr = "Unknown";
|
|
|
if (fileOrigin) {
|
|
|
const mavenName = formatMavenCoordinate(fileOrigin.mavenCoordinate);
|
|
|
originStr = `${mavenName || fileOrigin.filename}:${rule.origin?.lineNumber || 1}`;
|
|
|
}
|
|
|
return `<tr class="table-row border-b border-gray-200 hover:bg-gray-50">${customNameCell}<td class="border-l border-gray-200" style="padding: 1rem; width: 50%; font-family: var(--font-family-mono);">${escapeHTML(originStr)}</td></tr>`;
|
|
|
}
|
|
|
const impact = item.impact || [];
|
|
|
const getTag = (c, label) => {
|
|
|
const isRestricted = impact.includes(c);
|
|
|
const color = isRestricted ? "oklch(0.446 0.043 257.281)" : "#cbd5e1";
|
|
|
const bgColor = isRestricted ? "oklch(0.984 0.003 247.858)" : "#f8fafc";
|
|
|
const borderColor = isRestricted ? "oklch(0.929 0.013 255.508)" : "#e2e8f0";
|
|
|
return `<span class="impact-tag" style="display: inline-block; color: ${color}; background-color: ${bgColor}; border: 1px solid ${borderColor}; border-radius: 4px; padding: 2px 8px; font-size: 10px; font-weight: 400; height: 21px; line-height: 15px; text-transform: uppercase; letter-spacing: 0.25px; box-sizing: border-box; text-align: center;">${label}</span>`;
|
|
|
};
|
|
|
const impactCell = `
|
|
|
<td style="padding: 1rem; border-left: 1px solid var(--border-color);">
|
|
|
<div class="flex justify-start" style="gap: 0.5rem;">
|
|
|
${getTag('DONT_OBFUSCATE', 'OBFUSCATE')}
|
|
|
${getTag('DONT_OPTIMIZE', 'OPTIMIZE')}
|
|
|
${getTag('DONT_SHRINK', 'SHRINK')}
|
|
|
</div>
|
|
|
</td>
|
|
|
`;
|
|
|
const matchesCells = `
|
|
|
${renderMatchCell(item.matches.total, totalLive)}
|
|
|
${renderMatchCell(item.matches.classes, build.liveClassCount || 0)}
|
|
|
${renderMatchCell(item.matches.fields, build.liveFieldCount || 0)}
|
|
|
${renderMatchCell(item.matches.methods, build.liveMethodCount || 0)}
|
|
|
`;
|
|
|
return `<tr class="table-row border-b border-gray-200 hover:bg-gray-50">${nameCell}${matchesCells}${this.state.showBlockedByRule ? impactCell : ''}</tr>`;
|
|
|
}
|
|
|
}).join("");
|
|
|
},
|
|
|
};
|
|
|
|
|
|
document.addEventListener("DOMContentLoaded", () => {
|
|
|
App.init();
|
|
|
});
|
|
|
</script>
|
|
|
<script>// Copyright (c) 2026, the R8 project authors. Please see the AUTHORS file
|
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
/**
|
|
|
* Utility functions for analyzing keep radius data.
|
|
|
*/
|
|
|
function hasGlobalRule(data, ruleName) {
|
|
|
if (!data || !data.globalKeepRuleKeepRadiusTable) return false;
|
|
|
return data.globalKeepRuleKeepRadiusTable.some(r => r.source === ruleName);
|
|
|
}
|
|
|
|
|
|
function getDisallowObfuscationCount(data) {
|
|
|
if (hasGlobalRule(data, '-dontobfuscate')) {
|
|
|
return getLiveItemCount(data);
|
|
|
}
|
|
|
return getScore(data, 'DONT_OBFUSCATE');
|
|
|
}
|
|
|
function getDisallowOptimizationCount(data) {
|
|
|
if (hasGlobalRule(data, '-dontoptimize')) {
|
|
|
return getLiveItemCount(data);
|
|
|
}
|
|
|
return getScore(data, 'DONT_OPTIMIZE');
|
|
|
}
|
|
|
function getDisallowShrinkingCount(data) {
|
|
|
if (hasGlobalRule(data, '-dontshrink')) {
|
|
|
return getLiveItemCount(data);
|
|
|
}
|
|
|
return getScore(data, 'DONT_SHRINK');
|
|
|
}
|
|
|
function getLiveItemCount(data) {
|
|
|
if (!data || !data.buildInfo) return 0;
|
|
|
return (data.buildInfo.liveClassCount || 0) +
|
|
|
(data.buildInfo.liveFieldCount || 0) +
|
|
|
(data.buildInfo.liveMethodCount || 0);
|
|
|
}
|
|
|
/**
|
|
|
* Returns detailed counts for the stats table.
|
|
|
*/
|
|
|
function getDetailedStats(data) {
|
|
|
if (!data) return null;
|
|
|
const build = data.buildInfo || {};
|
|
|
const stats = {
|
|
|
classes: { total: build.liveClassCount || 0, obfuscation: 0, optimization: 0, shrinking: 0 },
|
|
|
fields: { total: build.liveFieldCount || 0, obfuscation: 0, optimization: 0, shrinking: 0 },
|
|
|
methods: { total: build.liveMethodCount || 0, obfuscation: 0, optimization: 0, shrinking: 0 },
|
|
|
overall: { total: getLiveItemCount(data), obfuscation: 0, optimization: 0, shrinking: 0 }
|
|
|
};
|
|
|
|
|
|
const constraintsMap = getConstraintsMap(data);
|
|
|
const rulesMap = getRulesConstraintsMap(data);
|
|
|
|
|
|
const hasObfuscate = hasGlobalRule(data, '-dontobfuscate');
|
|
|
const hasOptimize = hasGlobalRule(data, '-dontoptimize');
|
|
|
const hasShrink = hasGlobalRule(data, '-dontshrink');
|
|
|
|
|
|
const processTable = (table, key, forcedObfuscation, forcedOptimization, forcedShrinking) => {
|
|
|
if (forcedObfuscation) {
|
|
|
stats[key].obfuscation = stats[key].total;
|
|
|
}
|
|
|
if (forcedOptimization) {
|
|
|
stats[key].optimization = stats[key].total;
|
|
|
}
|
|
|
if (forcedShrinking) {
|
|
|
stats[key].shrinking = stats[key].total;
|
|
|
}
|
|
|
|
|
|
if (!forcedObfuscation || !forcedOptimization || !forcedShrinking) {
|
|
|
if (!table) return;
|
|
|
table.forEach(item => {
|
|
|
const keptBy = item.keptBy || [];
|
|
|
const constraints = keptBy.flatMap(ruleId => constraintsMap.get(rulesMap.get(ruleId)) || []);
|
|
|
|
|
|
if (!forcedObfuscation && constraints.includes('DONT_OBFUSCATE')) stats[key].obfuscation++;
|
|
|
if (!forcedOptimization && constraints.includes('DONT_OPTIMIZE')) stats[key].optimization++;
|
|
|
if (!forcedShrinking && constraints.includes('DONT_SHRINK')) stats[key].shrinking++;
|
|
|
});
|
|
|
}
|
|
|
};
|
|
|
|
|
|
processTable(data.keptClassInfoTable, 'classes', hasObfuscate, hasOptimize, hasShrink);
|
|
|
processTable(data.keptFieldInfoTable, 'fields', hasObfuscate, hasOptimize, hasShrink);
|
|
|
processTable(data.keptMethodInfoTable, 'methods', hasObfuscate, hasOptimize, hasShrink);
|
|
|
|
|
|
stats.overall.obfuscation = stats.classes.obfuscation + stats.fields.obfuscation + stats.methods.obfuscation;
|
|
|
stats.overall.optimization = stats.classes.optimization + stats.fields.optimization + stats.methods.optimization;
|
|
|
stats.overall.shrinking = stats.classes.shrinking + stats.fields.shrinking + stats.methods.shrinking;
|
|
|
return stats;
|
|
|
}
|
|
|
function getConstraintsMap(data) {
|
|
|
const constraintsMap = new Map();
|
|
|
if (data.keepConstraintsTable) {
|
|
|
data.keepConstraintsTable.forEach(c => {
|
|
|
constraintsMap.set(c.id, c.constraints || []);
|
|
|
});
|
|
|
}
|
|
|
return constraintsMap;
|
|
|
}
|
|
|
function getRulesConstraintsMap(data) {
|
|
|
const rulesMap = new Map();
|
|
|
if (data.keepRuleKeepRadiusTable) {
|
|
|
data.keepRuleKeepRadiusTable.forEach(r => {
|
|
|
rulesMap.set(r.id, r.constraintsId);
|
|
|
});
|
|
|
}
|
|
|
return rulesMap;
|
|
|
}
|
|
|
function getImpactArray(constraints) {
|
|
|
if (!constraints) return [];
|
|
|
return constraints;
|
|
|
}
|
|
|
/**
|
|
|
* Returns formatted rules for the table.
|
|
|
*/
|
|
|
function getRules(data) {
|
|
|
if (!data || !data.keepRuleKeepRadiusTable) return [];
|
|
|
const constraintsMap = getConstraintsMap(data);
|
|
|
const rules = data.keepRuleKeepRadiusTable.map(rule => {
|
|
|
const constraints = constraintsMap.get(rule.constraintsId);
|
|
|
const br = rule.keepRadius || {};
|
|
|
const classes = (br.classKeepRadius || []).length;
|
|
|
const fields = (br.fieldKeepRadius || []).length;
|
|
|
const methods = (br.methodKeepRadius || []).length;
|
|
|
return {
|
|
|
id: rule.id,
|
|
|
name: rule.source,
|
|
|
impact: getImpactArray(constraints),
|
|
|
matches: {
|
|
|
classes,
|
|
|
fields,
|
|
|
methods,
|
|
|
total: classes + fields + methods
|
|
|
},
|
|
|
subsumedBy: br.subsumedBy || []
|
|
|
};
|
|
|
});
|
|
|
|
|
|
if (data.globalKeepRuleKeepRadiusTable) {
|
|
|
const totalClasses = data.buildInfo?.liveClassCount || 0;
|
|
|
const totalFields = data.buildInfo?.liveFieldCount || 0;
|
|
|
const totalMethods = data.buildInfo?.liveMethodCount || 0;
|
|
|
const totalLive = totalClasses + totalFields + totalMethods;
|
|
|
|
|
|
data.globalKeepRuleKeepRadiusTable.forEach(rule => {
|
|
|
if (rule.source === '-dontoptimize' || rule.source === '-dontshrink' || rule.source === '-dontobfuscate') {
|
|
|
const constraints = [...(constraintsMap.get(rule.constraintsId) || [])];
|
|
|
if (rule.source === '-dontobfuscate' && !constraints.includes('DONT_OBFUSCATE')) {
|
|
|
constraints.push('DONT_OBFUSCATE');
|
|
|
}
|
|
|
if (rule.source === '-dontoptimize' && !constraints.includes('DONT_OPTIMIZE')) {
|
|
|
constraints.push('DONT_OPTIMIZE');
|
|
|
}
|
|
|
if (rule.source === '-dontshrink' && !constraints.includes('DONT_SHRINK')) {
|
|
|
constraints.push('DONT_SHRINK');
|
|
|
}
|
|
|
rules.push({
|
|
|
id: rule.id,
|
|
|
name: rule.source,
|
|
|
impact: getImpactArray(constraints),
|
|
|
matches: {
|
|
|
classes: totalClasses,
|
|
|
fields: totalFields,
|
|
|
methods: totalMethods,
|
|
|
total: totalLive
|
|
|
},
|
|
|
subsumedBy: []
|
|
|
});
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
return rules;
|
|
|
}
|
|
|
/**
|
|
|
* Returns formatted files (origins) for the table.
|
|
|
*/
|
|
|
function getRuleFiles(data) {
|
|
|
if (!data || !data.fileOriginTable || !data.keepRuleKeepRadiusTable) return [];
|
|
|
const fileMap = new Map();
|
|
|
const constraintsMap = getConstraintsMap(data);
|
|
|
data.fileOriginTable.forEach(f => {
|
|
|
const mavenName = formatMavenCoordinate(f.mavenCoordinate);
|
|
|
fileMap.set(f.id, {
|
|
|
id: f.id,
|
|
|
name: mavenName || f.filename,
|
|
|
keepRules: 0,
|
|
|
matches: { classes: new Set(), fields: new Set(), methods: new Set() },
|
|
|
impact: {
|
|
|
obfuscation: new Set(),
|
|
|
optimization: new Set(),
|
|
|
shrinking: new Set()
|
|
|
}
|
|
|
});
|
|
|
});
|
|
|
data.keepRuleKeepRadiusTable.forEach(rule => {
|
|
|
const fileId = rule.origin?.fileOriginId;
|
|
|
const fileEntry = fileMap.get(fileId);
|
|
|
if (fileEntry) {
|
|
|
fileEntry.keepRules++;
|
|
|
const br = rule.keepRadius || {};
|
|
|
const c = br.classKeepRadius || [];
|
|
|
const f = br.fieldKeepRadius || [];
|
|
|
const m = br.methodKeepRadius || [];
|
|
|
c.forEach(id => fileEntry.matches.classes.add(id));
|
|
|
f.forEach(id => fileEntry.matches.fields.add(id));
|
|
|
m.forEach(id => fileEntry.matches.methods.add(id));
|
|
|
const constraints = constraintsMap.get(rule.constraintsId) || [];
|
|
|
if (constraints.includes('DONT_OBFUSCATE')) {
|
|
|
c.forEach(id => fileEntry.impact.obfuscation.add('c' + id));
|
|
|
f.forEach(id => fileEntry.impact.obfuscation.add('f' + id));
|
|
|
m.forEach(id => fileEntry.impact.obfuscation.add('m' + id));
|
|
|
}
|
|
|
if (constraints.includes('DONT_OPTIMIZE')) {
|
|
|
c.forEach(id => fileEntry.impact.optimization.add('c' + id));
|
|
|
f.forEach(id => fileEntry.impact.optimization.add('f' + id));
|
|
|
m.forEach(id => fileEntry.impact.optimization.add('m' + id));
|
|
|
}
|
|
|
if (constraints.includes('DONT_SHRINK')) {
|
|
|
c.forEach(id => fileEntry.impact.shrinking.add('c' + id));
|
|
|
f.forEach(id => fileEntry.impact.shrinking.add('f' + id));
|
|
|
m.forEach(id => fileEntry.impact.shrinking.add('m' + id));
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
if (data.globalKeepRuleKeepRadiusTable) {
|
|
|
data.globalKeepRuleKeepRadiusTable.forEach(rule => {
|
|
|
const fileId = rule.origin?.fileOriginId;
|
|
|
const fileEntry = fileMap.get(fileId);
|
|
|
if (fileEntry) {
|
|
|
fileEntry.keepRules++;
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
return Array.from(fileMap.values()).map(f => ({
|
|
|
id: f.id,
|
|
|
name: f.name,
|
|
|
keepRules: f.keepRules,
|
|
|
matches: {
|
|
|
classes: f.matches.classes.size,
|
|
|
fields: f.matches.fields.size,
|
|
|
methods: f.matches.methods.size,
|
|
|
total: f.matches.classes.size + f.matches.fields.size + f.matches.methods.size
|
|
|
},
|
|
|
impact: {
|
|
|
obfuscation: f.impact.obfuscation.size,
|
|
|
optimization: f.impact.optimization.size,
|
|
|
shrinking: f.impact.shrinking.size
|
|
|
}
|
|
|
}));
|
|
|
}
|
|
|
function formatDescriptor(desc) {
|
|
|
if (!desc) return "Unknown";
|
|
|
let dimensions = 0;
|
|
|
while (desc[dimensions] === '[') {
|
|
|
dimensions++;
|
|
|
}
|
|
|
let base = desc.substring(dimensions);
|
|
|
let res = "";
|
|
|
if (base.startsWith('L') && base.endsWith(';')) {
|
|
|
res = base.substring(1, base.length - 1).replace(/\//g, '.');
|
|
|
} else if (base.length === 1) {
|
|
|
switch (base[0]) {
|
|
|
case 'V':
|
|
|
res = "void";
|
|
|
break;
|
|
|
case 'Z':
|
|
|
res = "boolean";
|
|
|
break;
|
|
|
case 'B':
|
|
|
res = "byte";
|
|
|
break;
|
|
|
case 'S':
|
|
|
res = "short";
|
|
|
break;
|
|
|
case 'C':
|
|
|
res = "char";
|
|
|
break;
|
|
|
case 'I':
|
|
|
res = "int";
|
|
|
break;
|
|
|
case 'J':
|
|
|
res = "long";
|
|
|
break;
|
|
|
case 'F':
|
|
|
res = "float";
|
|
|
break;
|
|
|
case 'D':
|
|
|
res = "double";
|
|
|
break;
|
|
|
default:
|
|
|
res = base;
|
|
|
}
|
|
|
} else {
|
|
|
res = base;
|
|
|
}
|
|
|
for (let i = 0; i < dimensions; i++) {
|
|
|
res += "[]";
|
|
|
}
|
|
|
return res;
|
|
|
}
|
|
|
function formatMethodName(methodRef, dataOrLookups, typeRefMap) {
|
|
|
if (!methodRef) return "Unknown method";
|
|
|
|
|
|
if (dataOrLookups && dataOrLookups.typeReference) {
|
|
|
const lookups = dataOrLookups;
|
|
|
const className = formatDescriptor(lookups.typeReference.get(methodRef.classReferenceId));
|
|
|
const proto = lookups.protoReference.get(methodRef.protoReferenceId);
|
|
|
let params = "";
|
|
|
if (proto && proto.parametersId) {
|
|
|
const list = lookups.typeReferenceList.get(proto.parametersId);
|
|
|
if (list && list.typeReferenceIds) {
|
|
|
params = list.typeReferenceIds.map(id => formatDescriptor(lookups.typeReference.get(id))).join(', ');
|
|
|
}
|
|
|
}
|
|
|
return `${className}.${methodRef.name}(${params})`;
|
|
|
}
|
|
|
|
|
|
const data = dataOrLookups;
|
|
|
const className = formatDescriptor(typeRefMap.get(methodRef.classReferenceId));
|
|
|
const proto = (data.protoReferenceTable || []).find(p => p.id === methodRef.protoReferenceId);
|
|
|
let params = "";
|
|
|
if (proto && proto.parametersId) {
|
|
|
const list = (data.typeReferenceListTable || []).find(l => l.id === proto.parametersId);
|
|
|
if (list && list.typeReferenceIds) {
|
|
|
params = list.typeReferenceIds.map(id => formatDescriptor(typeRefMap.get(id))).join(', ');
|
|
|
}
|
|
|
}
|
|
|
return `${className}.${methodRef.name}(${params})`;
|
|
|
}
|
|
|
function formatFieldName(fieldRef, dataOrLookups, typeRefMap) {
|
|
|
if (!fieldRef) return "Unknown field";
|
|
|
|
|
|
if (dataOrLookups && dataOrLookups.typeReference) {
|
|
|
const lookups = dataOrLookups;
|
|
|
const className = formatDescriptor(lookups.typeReference.get(fieldRef.classReferenceId));
|
|
|
return `${className}.${fieldRef.name}`;
|
|
|
}
|
|
|
|
|
|
const className = formatDescriptor(typeRefMap.get(fieldRef.classReferenceId));
|
|
|
return `${className}.${fieldRef.name}`;
|
|
|
}
|
|
|
function formatMavenCoordinate(m) {
|
|
|
if (!m || !m.groupId) return null;
|
|
|
return `${m.groupId}:${m.artifactId}:${m.version}`;
|
|
|
}
|
|
|
function escapeHTML(str) {
|
|
|
if (!str) return "";
|
|
|
return str.replace(/[&<>"']/g, function (m) {
|
|
|
return {
|
|
|
'&': '&',
|
|
|
'<': '<',
|
|
|
'>': '>',
|
|
|
'"': '"',
|
|
|
"'": '''
|
|
|
}[m];
|
|
|
});
|
|
|
}
|
|
|
function highlightRule(source) {
|
|
|
if (!source) return "";
|
|
|
const escapedSource = escapeHTML(source);
|
|
|
// Highlight semicolon FIRST with negative lookbehind so we don't match inside subsequently inserted HTML tags or existing HTML entities
|
|
|
return escapedSource
|
|
|
.replace(/(?<!&[a-zA-Z0-9#]+);/g, '<span style="color: #ca8a04;">;</span>')
|
|
|
.replace(/([{}*])/g, '<span style="color: #ca8a04;">$1</span>')
|
|
|
.replace(/(-keep[a-z]*|-dontoptimize|-dontshrink|-dontobfuscate)/g, '<span style="color: #dc2626;">$1</span>')
|
|
|
.replace(/\b(class|interface|enum)\b/g, '<span style="color: #2563eb;">$1</span>');
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Shared helper to count kept items that have a specific constraint.
|
|
|
* An item is counted if ANY of the keep rules that keep it has the specified constraint.
|
|
|
*/
|
|
|
function getScore(data, constraintName) {
|
|
|
if (!data) return 0;
|
|
|
const constraintsMap = getConstraintsMap(data);
|
|
|
const rulesMap = getRulesConstraintsMap(data);
|
|
|
let count = 0;
|
|
|
const tables = [
|
|
|
data.keptClassInfoTable,
|
|
|
data.keptFieldInfoTable,
|
|
|
data.keptMethodInfoTable
|
|
|
];
|
|
|
tables.forEach(table => {
|
|
|
if (table) {
|
|
|
table.forEach(item => {
|
|
|
const hasRuleWithConstraint = (item.keptBy || []).some(ruleId => {
|
|
|
const constraintsId = rulesMap.get(ruleId);
|
|
|
const constraints = constraintsMap.get(constraintsId);
|
|
|
return constraints && constraints.includes(constraintName);
|
|
|
});
|
|
|
if (hasRuleWithConstraint) {
|
|
|
count++;
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
});
|
|
|
return count;
|
|
|
}</script>
|
|
|
|
|
|
<!-- Help Hub FAB -->
|
|
|
<button id="help-hub-fab" class="fab">
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="none" viewBox="0 0 24 24"
|
|
|
stroke="currentColor">
|
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
|
d="M8.228 9c.549-1.165 2.03-2 3.772-2 2.21 0 4 1.343 4 3 0 1.4-1.278 2.575-3.006 2.907-.542.104-.994.54-.994 1.093m0 3h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
|
</svg>
|
|
|
<span>Help</span>
|
|
|
</button>
|
|
|
|
|
|
<!-- Help Hub Side Panel -->
|
|
|
<div id="help-hub-panel" class="side-panel">
|
|
|
<div class="side-panel-header">
|
|
|
<div class="header-left">
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"
|
|
|
stroke="currentColor">
|
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
|
d="M8.228 9c.549-1.165 2.03-2 3.772-2 2.21 0 4 1.343 4 3 0 1.4-1.278 2.575-3.006 2.907-.542.104-.994.54-.994 1.093m0 3h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
|
</svg>
|
|
|
<h2>Help</h2>
|
|
|
</div>
|
|
|
<button id="close-help-hub" class="icon-btn">
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="none" viewBox="0 0 24 24"
|
|
|
stroke="currentColor">
|
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
|
|
|
</svg>
|
|
|
</button>
|
|
|
</div>
|
|
|
<div class="side-panel-content">
|
|
|
<!-- Introduction -->
|
|
|
<div class="help-section">
|
|
|
<div class="help-section-title">Introduction to Table Data</div>
|
|
|
<p>R8 is Android's code shrinker, optimizer, and obfuscator. This report shows how your keep rules constrain R8
|
|
|
— every kept item is one R8 couldn't shrink, optimize, or obfuscate. Higher percentages mean more of your app
|
|
|
is locked in place.</p>
|
|
|
</div>
|
|
|
|
|
|
<div class="divider"></div>
|
|
|
<!-- Legend -->
|
|
|
<div class="help-section">
|
|
|
<div class="help-section-title">Legend</div>
|
|
|
<div class="legend-list">
|
|
|
<!-- Obfuscation Score -->
|
|
|
<div class="legend-item" data-topic="obfuscation-score">
|
|
|
<div class="legend-item-header">
|
|
|
<span class="legend-item-title">Obfuscation Score</span>
|
|
|
<svg class="legend-item-arrow" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none"
|
|
|
viewBox="0 0 24 24" stroke="currentColor">
|
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
|
|
|
</svg>
|
|
|
</div>
|
|
|
<div class="legend-item-content">
|
|
|
% of classes/fields/methods R8 was free to rename. Higher = better.
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- Optimization Score -->
|
|
|
<div class="legend-item" data-topic="optimization-score">
|
|
|
<div class="legend-item-header">
|
|
|
<span class="legend-item-title">Optimization Score</span>
|
|
|
<svg class="legend-item-arrow" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none"
|
|
|
viewBox="0 0 24 24" stroke="currentColor">
|
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
|
|
|
</svg>
|
|
|
</div>
|
|
|
<div class="legend-item-content">
|
|
|
% of classes/fields/methods R8 was free to optimize. Higher = better.
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- Shrinking Score -->
|
|
|
<div class="legend-item" data-topic="shrinking-score">
|
|
|
<div class="legend-item-header">
|
|
|
<span class="legend-item-title">Shrinking Score</span>
|
|
|
<svg class="legend-item-arrow" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none"
|
|
|
viewBox="0 0 24 24" stroke="currentColor">
|
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
|
|
|
</svg>
|
|
|
</div>
|
|
|
<div class="legend-item-content">
|
|
|
% of classes/fields/methods R8 was free to remove. Higher = better.
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- Kept Items -->
|
|
|
<div class="legend-item" data-topic="kept-items">
|
|
|
<div class="legend-item-header">
|
|
|
<span class="legend-item-title">Kept Items (higher is worse)</span>
|
|
|
<svg class="legend-item-arrow" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none"
|
|
|
viewBox="0 0 24 24" stroke="currentColor">
|
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
|
|
|
</svg>
|
|
|
</div>
|
|
|
<div class="legend-item-content">
|
|
|
Total number of items kept by this rule. Higher numbers indicate a larger impact on APK size.
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- Blocked By Rule -->
|
|
|
<div class="legend-item" data-topic="blocked-by-rule">
|
|
|
<div class="legend-item-header">
|
|
|
<span class="legend-item-title">Blocked By Rule</span>
|
|
|
<svg class="legend-item-arrow" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none"
|
|
|
viewBox="0 0 24 24" stroke="currentColor">
|
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
|
|
|
</svg>
|
|
|
</div>
|
|
|
<div class="legend-item-content">
|
|
|
Specific actions blocked by this rule (e.g., Optimization, Shrinking).
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- Identical Rules -->
|
|
|
<div class="legend-item" data-topic="identical-rules">
|
|
|
<div class="legend-item-header">
|
|
|
<span class="legend-item-title">Identical Rules</span>
|
|
|
<svg class="legend-item-arrow" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none"
|
|
|
viewBox="0 0 24 24" stroke="currentColor">
|
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
|
|
|
</svg>
|
|
|
</div>
|
|
|
<div class="legend-item-content">
|
|
|
Rules that match the exact same set of items.
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- Subsumed By -->
|
|
|
<div class="legend-item" data-topic="subsumed-by">
|
|
|
<div class="legend-item-header">
|
|
|
<span class="legend-item-title">Subsumed By</span>
|
|
|
<svg class="legend-item-arrow" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none"
|
|
|
viewBox="0 0 24 24" stroke="currentColor">
|
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
|
|
|
</svg>
|
|
|
</div>
|
|
|
<div class="legend-item-content">
|
|
|
Rules that are covered by a broader rule.
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- Unused Rules -->
|
|
|
<div class="legend-item" data-topic="unused-rules">
|
|
|
<div class="legend-item-header">
|
|
|
<span class="legend-item-title">Unused Rules</span>
|
|
|
<svg class="legend-item-arrow" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none"
|
|
|
viewBox="0 0 24 24" stroke="currentColor">
|
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
|
|
|
</svg>
|
|
|
</div>
|
|
|
<div class="legend-item-content">
|
|
|
Rules that do not match any items in the application.
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- Lenses -->
|
|
|
<div class="legend-item" data-topic="lenses">
|
|
|
<div class="legend-item-header">
|
|
|
<span class="legend-item-title">Lenses (All / Identical / Subsumed / Unused)</span>
|
|
|
<svg class="legend-item-arrow" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none"
|
|
|
viewBox="0 0 24 24" stroke="currentColor">
|
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
|
|
|
</svg>
|
|
|
</div>
|
|
|
<div class="legend-item-content">
|
|
|
Different perspectives to view the rules.
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<div class="divider"></div>
|
|
|
<!-- Documentation -->
|
|
|
<div class="help-section">
|
|
|
<div class="help-section-title">Documentation</div>
|
|
|
<div class="doc-list">
|
|
|
<a href="https://r8.googlesource.com/r8/" target="_blank" class="doc-card">
|
|
|
<div class="doc-card-info">
|
|
|
<span class="doc-card-title">R8 keep rule reference</span>
|
|
|
<span class="doc-card-domain">developer.android.com</span>
|
|
|
<span class="doc-card-desc">Official guide to shrinking, obfuscation, and optimization with R8.</span>
|
|
|
</div>
|
|
|
<svg class="doc-card-icon" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none"
|
|
|
viewBox="0 0 24 24" stroke="currentColor">
|
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
|
d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" />
|
|
|
</svg>
|
|
|
</a>
|
|
|
|
|
|
<a href="https://developer.android.com/studio/build/shrink-code" target="_blank" class="doc-card">
|
|
|
<div class="doc-card-info">
|
|
|
<span class="doc-card-title">Reduce APK size</span>
|
|
|
<span class="doc-card-domain">developer.android.com</span>
|
|
|
<span class="doc-card-desc">Patterns and tools for minimizing the footprint of your release build.</span>
|
|
|
</div>
|
|
|
<svg class="doc-card-icon" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none"
|
|
|
viewBox="0 0 24 24" stroke="currentColor">
|
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
|
d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" />
|
|
|
</svg>
|
|
|
</a>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</body>
|
|
|
</html>
|