#Матрицы и списки. Часть 1 Наследуют свойства векторов
МАТРИЦА
Двумерный массив данных одного типа
Работает такой же принцип приведения, как для веткоров
По сути - это вектор, уложенный по столбцам
Для создания матрица можно испольовать функци matrix
matrix(1:6, nrow = 2, ncol = 3)
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
Можно избавиться от избыточности
Можно указать только nrow или ncol, а второй будет вычислен автоматически, исxодя из длины вектора
matrix(1:6, nrow = 2)
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
Если хотим упаковать вектор не по столбцам, а по строчкам?
Используем аргумент byrow = TRUE
matrix(1:6, nrow = 2, byrow = TRUE)
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
Несоотвествие между длиной вектора и задаваемым размером?
А) Вектор короче размеров таблицы
Вектор переписывается и повторяется нужное число раз
matrix(7:8, nrow = 2, ncol = 5)
[,1] [,2] [,3] [,4] [,5]
[1,] 7 7 7 7 7
[2,] 8 8 8 8 8
Б) Если вектор длинее? Тестируем:
Получается, что используются только те значения вектора, которые помещаются в заданные размеры
matrix(1:10, nrow = 2, ncol = 2)
[,1] [,2]
[1,] 1 3
[2,] 2 4
Отличия матрицы от векторв
Единственное отличие состоит в том, что у матрицы есть специальный атрибут dim - отвечает за размерность
### Можно получить доступ к размерности, используя dim
n <- matrix(1:6, ncol = 3)
dim(n)
[1] 2 3
2 - это ряды
3 - это столбцы
Cпециальные функции nrow() и ncol() делают то же самое
nrow(n)
[1] 2
ncol(n)
[1] 3
Что будет, если нивелировать dim?
Матрица превращается в обычный вектор
dim(n) <- NULL
n
[1] 1 2 3 4 5 6
Если восстановить аттрибут, то матрица приобретет исходный вид
dim(n) <- c(2,3)
n
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
Вопрос: что будет, если вектору присвоить аттрибут dim?
Ожидаю, что вектор превратится в матрицу. Тестирую:
1. Cоздам вектор от 1 до 8
vec <- 1:8
vec
[1] 1 2 3 4 5 6 7 8
- Присвою аттрибут dim
dim(vec) <- c(2, 4)
vec
[,1] [,2] [,3] [,4]
[1,] 1 3 5 7
[2,] 2 4 6 8
Как и ожидалось вектор превратился в матрицу. Прикольно
Арифметические операции с матрицами
Действуют все те же правила, что и для веткоров.
Создадим две матрицы для проверки
n1 <- matrix(1:4, nrow = 2)
n2 <- matrix(c(1,2,2,3), nrow = 2)
n1
[,1] [,2]
[1,] 1 3
[2,] 2 4
n2
[,1] [,2]
[1,] 1 2
[2,] 2 3
Сложение
Теперь попробуем их сложить друг с другом. Сложение произойдет поэлементно
n1 + n2
[,1] [,2]
[1,] 2 5
[2,] 4 7
Правила переписывания
Правила работают так же, как на векторах, поэтому можем, например, к матрице добавить число (арифметика снова выполняется поэлементно)
n1
[,1] [,2]
[1,] 1 3
[2,] 2 4
n1 + 5
[,1] [,2]
[1,] 6 8
[2,] 7 9
Умножение
Так же будут выполняться поэлементно, как и все остальные арифметические операторы
n1 * 2
[,1] [,2]
[1,] 2 6
[2,] 4 8
n1 * n2
[,1] [,2]
[1,] 1 6
[2,] 4 12
Умножение в смысле линейной алгебры требует других операторов
Что такое линейное алгебра, я понятия не имею. Пишут, что умножение в линейной алгебре работает по "принципу строку на столбец
|a1 b1| |c1 d1|
| | * | |
|a2 b2| |c2 d2|
получется то же, что и
|a1c1 + b1c2 a1d1 + b1d2|
| |
|a2c1 + b2c2 a2d1 + b2d2|
n1 %*% n2
[,1] [,2]
[1,] 7 11
[2,] 10 16
Протестирую сложение с таким же доп оператором - такой функции нет
Функция sum()
Попробую применить к двум матрицам
n1
[,1] [,2]
[1,] 1 3
[2,] 2 4
n2
[,1] [,2]
[1,] 1 2
[2,] 2 3
sum(n1, n2)
[1] 18
Т.е. sum() возвращает сумму всех элементов всех матрица, а не поэлементную сумму
Индексирование матриц
Действуют те же правила, что и для векторов, но учитываются две размерности например, создадм матрицу
m <- matrix(1:10, ncol = 5)
m
[,1] [,2] [,3] [,4] [,5]
[1,] 1 3 5 7 9
[2,] 2 4 6 8 10
Получим доступ к элементу в первом ряду, в 3 столбце
m[1, 3]
[1] 5
Интересно, что если опустим один из аргументов при обращении к элементу, то получим доступ ко всей строке/ столбцу
#2-я строка
m[2, ]
[1] 2 4 6 8 10
#3-й столбец
m[ , 3]
[1] 5 6
Можно пользоваться такой аннотацией для замены элементов матрицы
Подставлять в элементы матрицы можно:
* вектора
* вектора единичной длины (скаляры)
* подматрицы
Обнулить всю первую строку
m[1, ] <- 0; m
[,1] [,2] [,3] [,4] [,5]
[1,] 0 0 0 0 0
[2,] 2 4 6 8 10
То же самое касается отрицательных индексов. Например, если хочу переприсвоить все значения кроме 5-го столбца
m[ , -5] <- 11:18; m
[,1] [,2] [,3] [,4] [,5]
[1,] 11 13 15 17 0
[2,] 12 14 16 18 10
Схлопывание размерности - особенность матриц
Допустим, возъмем ту же матрицу, что и раньше, но воспользуемся отдельным вектором, который будет указывать индексы столбцов
m <- matrix(1:10, ncol = 5)
ind <- c(1,3,5)
m
[,1] [,2] [,3] [,4] [,5]
[1,] 1 3 5 7 9
[2,] 2 4 6 8 10
Теперь обратимся к элементам, индексируемым в векторе ind. Получаем подматрицу из 3х столбцов
m[ , ind]
[,1] [,2] [,3]
[1,] 1 5 9
[2,] 2 6 10
Что будет, если длина индекса будет равна 1. Допустим, нас интересует только 3й столбец. Мы захотим получить подматрицу, состоящую из 3го столбца
ind <- 3
m[ , ind]
[1] 5 6
Мы видим, что происходит “схлопывание размерности” - т.е. резульатом обращения к матрице видим не матрицу, а вектор.
Чтобы избавиться от этого поведения, можно воспользоваться дополнительным аргументом drop
m[ , ind, drop = F]
[,1]
[1,] 5
[2,] 6
Получаем таким образом матрицу в 1 столбец, а не вектор
Именованные матрицы: rownames/colnames
У векторо могут быть имена, так же и у матриц.Возьмем матрицу и присвоим рядам этой матрицы название
m <- matrix(1:10, ncol = 5)
rownames(m) <- c("row1", "row2")
m
[,1] [,2] [,3] [,4] [,5]
row1 1 3 5 7 9
row2 2 4 6 8 10
Так же можно присвоить имена столбцам. Но, если не хочется вводить все имена вручную, то можно воспользоваться функцией paste0(), которая склеивает вводные аргументы в вектор из строк
colnames(m) <- paste0("column", 1:5)
m
column1 column2 column3 column4 column5
row1 1 3 5 7 9
row2 2 4 6 8 10
Получили матрицу, к которой теперь можно обращаться по именам
m["row1", c("column2", "column4"), drop = F]
column2 column4
row1 3 7
Что будет, если изменить порядок колонок? Изменится ли отображение в коде?
m["row1", c("column4", "column2"), drop = F]
column4 column2
row1 7 3
То есть порядок выстраивается в соответствии с кодом
В чем отличие paste() и paste0().
paste (…, sep = " ", collapse = NULL) paste0(…, collapse = NULL) Попробуем повторить аналогичную операцию. Пока разницы не вижу.
colnames(m) <- paste("col", 1:5)
m
col 1 col 2 col 3 col 4 col 5
row1 1 3 5 7 9
row2 2 4 6 8 10
Возможно, если подавать несколько векторов функции, то между ними можно строить некие раделители?
colnames(m) <- paste("col", 1:2, "sol", 3:5)
Error in dimnames(x) <- dn :
length of 'dimnames' [2] not equal to array extent
Короче пока какая-то непонятная функция.
Присоединение матриц: rbind/cbind
Что делать, если я хочу присоединить матрицу к матрице.
Для этого есть две функции:
* rbind - т.е. rowbind, т.е. присоединение по рядам
n1
[,1] [,2]
[1,] 1 3
[2,] 2 4
n2
[,1] [,2]
[1,] 1 2
[2,] 2 3
rbind(n1, n2)
[,1] [,2]
[1,] 1 3
[2,] 2 4
[3,] 1 2
[4,] 2 3
- cbind - т.е. columnbind, т.е. присоединение по колонкам
cbind(n1, n2)
[,1] [,2] [,3] [,4]
[1,] 1 3 1 2
[2,] 2 4 2 3
Что будет, если присоединить к матрице вектор по рядам?
vec <- 1:5
vec
[1] 1 2 3 4 5
rbind(n1, vec)
number of columns of result is not a multiple of vector length (arg 2)
[,1] [,2]
1 3
2 4
vec 1 2
cbind(n1, vec)
number of rows of result is not a multiple of vector length (arg 2)
vec
[1,] 1 3 1
[2,] 2 4 2
Вывод ошибки о том, что результирующий объект не кратен длине аргументе vec.
Попробую привести vec к соответсвующей длине.
length(n1)
[1] 4
length(vec)
[1] 5
Т.е. длина матрицы определяется количеством элементов в ней
vec <- 1:4
rbind(n1, vec)
number of columns of result is not a multiple of vector length (arg 2)
[,1] [,2]
1 3
2 4
vec 1 2
vec <- 1:2
rbind(n1, vec)
[,1] [,2]
1 3
2 4
vec 1 2
Выходит что-то мне пока не очень понятное.
Если почитать справку по rbind или cbind, то увидим, что аргументом функции служит “…” (ellipsis) - это значит, что функции можно передавать неограниченное число объектов.
Например, хочу вызвать функцию cbind на большом количестве векторов
cbind(n1, n2)
[,1] [,2] [,3] [,4]
[1,] 1 3 1 2
[2,] 2 4 2 3
cbind(n1, n2, 1:2)
[,1] [,2] [,3] [,4] [,5]
[1,] 1 3 1 2 1
[2,] 2 4 2 3 2
cbind(n1, n2, 1:2, c(5,3))
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 3 1 2 1 5
[2,] 2 4 2 3 2 3
cbind(n1, n2, 1:2, c(5,3), n2[ ,1])
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] 1 3 1 2 1 5 1
[2,] 2 4 2 3 2 3 2
# И так далее
cbind(n1, n2, 1:2, c(5,3), n2[ , 1], n1 + 3, cbind(n2, n1))
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13]
[1,] 1 3 1 2 1 5 1 4 6 1 2 1 3
[2,] 2 4 2 3 2 3 2 5 7 2 3 2 4
Таким образом будут работать и другие функции:
* с
* paste
* paste0
* sum
Функция семейства apply
Применение функций к матрице apply()
Часто возникает необходимость применить одну и ту же функцию к солбцам или строчкам. В других языках для этого можно было бы написать цикл for. В R тоже можно, но в этом нет необходимости.
Создадим матрицу
m <- matrix(1:25, 5)
m
[,1] [,2] [,3] [,4] [,5]
[1,] 1 6 11 16 21
[2,] 2 7 12 17 22
[3,] 3 8 13 18 23
[4,] 4 9 14 19 24
[5,] 5 10 15 20 25
N.B! У функции необзательно должно быть ключевое слово return. Если к концу функции return не встречается, то возврашается результат последней операции. Можно сокращать запись Создаем функцию с одной операцией
f <- function(x) sum(x^2)
Три аргумента функции apply:
- Массив (матрица)
- Индекс (1 - по строкам, 2 - по столбцам)
- Функция
# Применю функцию f к матрице m построчно
apply(m, 1, f)
[1] 855 970 1095 1230 1375
# Применю функцию по столбцам
apply(m, 2, f)
[1] 55 330 855 1630 2655
Переписывается ли матрица?
m
[,1] [,2] [,3] [,4] [,5]
[1,] 1 6 11 16 21
[2,] 2 7 12 17 22
[3,] 3 8 13 18 23
[4,] 4 9 14 19 24
[5,] 5 10 15 20 25
Не переписывается.
Применение функций к матрице: apply
Если хочу применить функцию ко всем элементам, то:
apply(m, 1:2, f)
[,1] [,2] [,3] [,4] [,5]
[1,] 1 36 121 256 441
[2,] 4 49 144 289 484
[3,] 9 64 169 324 529
[4,] 16 81 196 361 576
[5,] 25 100 225 400 625
Можно и задавать условия применения функции, например: если элемент больше 13, то оставляем элемент, а если меньше, то заменяем на 13
apply(m, 1:2, function(i) if (i > 13) i else 13)
[,1] [,2] [,3] [,4] [,5]
[1,] 13 13 13 16 21
[2,] 13 13 13 17 22
[3,] 13 13 13 18 23
[4,] 13 13 14 19 24
[5,] 13 13 15 20 25
Переписалась ли при этом матрица?
m
[,1] [,2] [,3] [,4] [,5]
[1,] 1 6 11 16 21
[2,] 2 7 12 17 22
[3,] 3 8 13 18 23
[4,] 4 9 14 19 24
[5,] 5 10 15 20 25
Нет.
Такая функция (не имеющая имени) называется анонимной - она прекращает свое существования сразу после того, как apply была выполнена. Ни в одном окружении ее не осталось. Это удобно для быстрых функций, для которых не хочется заводить переменную С точки зрения языка R - это лишняя работа. Можно было сделать то же с помощью логического индексирования
m[m <= 13] <- 13; m
[,1] [,2] [,3] [,4] [,5]
[1,] 13 13 13 16 21
[2,] 13 13 13 17 22
[3,] 13 13 13 18 23
[4,] 13 13 14 19 24
[5,] 13 13 15 20 25
Самые частые функции для матриц
Самые частые операции по строкам и столбцам - sum и mean
* rowSums - cумма по рядам
rowSums(m)
[1] 76 78 80 83 86
- rowMeans - среднее по рядам
rowMeans(m)
[1] 15.2 15.6 16.0 16.6 17.2
- colSums - cумма по колонкам
- colMeans - среднее по колонкам
Допустим, мы хотим удостовериться, что rowSums действительно считает сумму элементов по рядам. Можем написать свою собственную функцию, используя apply для этого
all.equal(rowSums(m),apply(m, 1, sum))
[1] TRUE
all.equal(colSums(m),apply(m, 2, sum))
[1] TRUE
Комментарии Stepik
Управляющие конструкции тоже работают с векторами и матрицами
Например,
t <- matrix(1:9, 3); t
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
y <- ifelse(t %% 2 == 0, 1, 0)
y
[,1] [,2] [,3]
[1,] 0 1 0
[2,] 1 0 1
[3,] 0 1 0
Но стоит учитывать, что ifelse хоть и векторизована, но не работает не очень быстро. В приведенном примере лучше опять же использовать индексирование. Например
m <- matrix(0, 3, 3); m
[,1] [,2] [,3]
[1,] 0 0 0
[2,] 0 0 0
[3,] 0 0 0
m[seq_along(m) %% 2 == 0] <- 1
m
[,1] [,2] [,3]
[1,] 0 1 0
[2,] 1 0 1
[3,] 0 1 0
Некоторые особенности матриц
Матрицы занимают меньший объем оперативной памяти, чем аналогичный dataframe
Скорость выполнения аналогичных функций на матрицах, выше чем на dataframe
В контексте работы с чем-то очень большим, используется наследник матрицы bigmatrix
Применение функции семейства apply не самая хорошая практика из-за нестабильности получаемого результата
Матрицы и Списки - часть 2
Допустим, есть две матрицы. Чтобы получить из них одну большую матрицу можно воспользоваться функциями rbind() или cbind().
Но, допустим, этого недостаточно. Например, хотим объединить их по диагонали так, чтобы m1 занимала левый верхний угол, m2 - правый нижний угол, а остальные элементы матрицы были заполнены какими-нибудь значеними
### Как написать функцию для решения такой задачи? Напишем функцию. Нам нужно ввести результирующую матрицу, мы знаем ее размер - это сумма количества рядов m1 и m2, то же самое верно и для столбцов.
1. Заполним m3 элементом fill, который будет заполнять пустые ячейки, а потом просто заполним левый верхний и правый нижний углы
bind_diag <- function(m1, m2, fill) {
m3 <- matrix(fill,
nrow = nrow(m1) + nrow(m2),
ncol = ncol(m1) + ncol(m2)
)
# Матрицы создана, теперь можно заполнить ее два куска
# Первый кусок - левый верхний угол m1
m3[1:nrow(m1), 1:ncol(m1)] <- m1
m3[nrow(m1) + 1:nrow(m2), ncol(m1) + 1:ncol(m2)] <- m2
m3
}
Вот функция и готова.
Можем ввести матрицы
m1 <- matrix(1:12, nrow = 3)
m2 <- matrix(10:15, ncol = 3)
m1; m2
[,1] [,2] [,3] [,4]
[1,] 1 4 7 10
[2,] 2 5 8 11
[3,] 3 6 9 12
[,1] [,2] [,3]
[1,] 10 12 14
[2,] 11 13 15
Применим функцию
bind_diag(m2, m1, fill = NA)
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] 10 12 14 NA NA NA NA
[2,] 11 13 15 NA NA NA NA
[3,] NA NA NA 1 4 7 10
[4,] NA NA NA 2 5 8 11
[5,] NA NA NA 3 6 9 12
bind_diag(m2, m1, fill = 0)
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] 10 12 14 0 0 0 0
[2,] 11 13 15 0 0 0 0
[3,] 0 0 0 1 4 7 10
[4,] 0 0 0 2 5 8 11
[5,] 0 0 0 3 6 9 12
bind_diag(m2, m1, fill = "fuck")
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] "10" "12" "14" "fuck" "fuck" "fuck" "fuck"
[2,] "11" "13" "15" "fuck" "fuck" "fuck" "fuck"
[3,] "fuck" "fuck" "fuck" "1" "4" "7" "10"
[4,] "fuck" "fuck" "fuck" "2" "5" "8" "11"
[5,] "fuck" "fuck" "fuck" "3" "6" "9" "12"
Записывается ли при этом переменная m3 в глобальное окружение или это одноразовый вывод?
m3
Error: object 'm3' not found
Не записывается, как и ожидалось
Тоже самое можно было и сделать через cbind и rbind
bind_diag2<-function(m1,m2,fill)
{
cbind(
rbind(m1,matrix(fill,nrow(m2),ncol(m1))),
rbind(matrix(fill,nrow(m1),ncol(m2)),m2))
}
Пробуем
bind_diag2(m1, m2, fill = 0)
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] 1 4 7 10 0 0 0
[2,] 2 5 8 11 0 0 0
[3,] 3 6 9 12 0 0 0
[4,] 0 0 0 0 10 12 14
[5,] 0 0 0 0 11 13 15
Задача, с которой я не справился
Напишите функцию, которая принимает одно целое число n, а возвращает “ступенчатую” матрицу, состоящую из n этажей. Этажи нумеруются с первого, ширина каждой ступеньки равна одной строке или столбцу.
Пример. Пусть n=4, тогда необходимо вернуть матрицу вида
1 1 1 1 1 1 1
1 2 2 2 2 2 1
1 2 3 3 3 2 1
1 2 3 4 3 2 1
1 2 3 3 3 2 1
1 2 2 2 2 2 1
1 1 1 1 1 1 1
Решения
1 - c циклом for
build_ziggurat2 <- function(n) {
m<-matrix(0,2*n-1,2*n-1)
b<-n*2-1
c<-b
for (i in 1:n) {
if (i==1) {
m1<-matrix(i,b,b)
m[i:b,i:b] <- m1
b <- b-1
} else {
c <- c-2
m1 <-matrix(i,c,c)
m[i:b,i:b] <-m1
b <- b-1
}
}
m
}
Через индексы
build_ziggurat <- function(n) {
#Выводим в отдельную матрицу со столбцами "row" и "col" все индексы матрицы размерности зиккурата
z <- which(matrix(1,n*2-1,n*2-1)==1, arr.ind = T)
#В каждой строке меняем значения, превышающее заданное число n
z <- ifelse(z>n,2*n-z,z)
#В каждой строке оставляем только наименьшее
z <- ifelse(z[,1]>=z[,2],z[,2],z[,1])
#Итоговый вектор превращаем в матрицу (зиккурат)
dim(z)<-c(2*n-1,2*n-1)
#Zиккурат
z
}
2 без циклов и рекурсий
build_ziggurat <- function(n) {
d <- n * 2 - 1
outer(1:d, 1:d, function(x,y) {
x <- n - abs(n - x)
y <- n - abs(n - y)
pmin(x,y)
})
}
3 - красивое решение без циклов
build_ziggurat <- function(n) {
d = n*2-1
# создадим 4 ступенчатые матрицы, направленные в разные стороны
m1 = matrix(1:d, d, d)
m2 = matrix(1:d, d, d, byrow = T)
m3 = matrix(d:1, d, d)
m4 = matrix(d:1, d, d, byrow = T)
# найдем минимум для каждой позиции из четырех матриц
pmin(m1, m2, m3, m4)
}
Геометрическое решение
build_ziggurat <- function(n) {
v <- c(1:(n-1), n, (n-1):1) # пример: 1 2 3 2 1
N <- 2*n-1
# матрица из повторяющихся векторов
mat1 <- matrix(rep(v, N), N, N)
# та же матрица в траспонированном ("повернутом") виде
mat2 <- matrix(rep(v, N), N, N, byrow=T)
# смешение матриц дает пирамиду
# модуль позволяет "убрать" избыточные диагональные элементы
return((mat1+mat2-abs(mat1-mat2))/2)
}
Важно, что код на R с циклом работает медленее
Функция на цикле
build_ziggurat_1 <- function(n) {
result_m <- matrix(0, nrow = 2n - 1, ncol = 2n - 1)
for(i in 1:(2n - 1)){
for(j in 1:(2n - 1)){
result_m[i,j] = -max(abs(i-n),abs(j-n))
}
}
return(result_m + n)
Функция без цикла
build_ziggurat_2 <- function(n) {
size <- n*2-1
temp <- matrix(NaN, size, size)
pmin(n-abs(n - row(temp)), n-abs(n-col(temp)))
Проверим скорость работы
system.time(build_ziggurat_1(1000))
пользователь система прошло 9.42 0.30 10.09
system.time(build_ziggurat_2(1000))
пользователь система прошло 0.71 0.04 0.75
LS0tDQp0aXRsZTogIk1hdHJpeCBhbmQgTGlzdHMiDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQNCiAgcGRmX2RvY3VtZW50OiBkZWZhdWx0DQotLS0NCg0KI9Cc0LDRgtGA0LjRhtGLINC4INGB0L/QuNGB0LrQuC4g0KfQsNGB0YLRjCAxDQrQndCw0YHQu9C10LTRg9GO0YIg0YHQstC+0LnRgdGC0LLQsCDQstC10LrRgtC+0YDQvtCyDQoNCiMg0JzQkNCi0KDQmNCm0JAgIA0KDQoqINCU0LLRg9C80LXRgNC90YvQuSDQvNCw0YHRgdC40LIg0LTQsNC90L3Ri9GFINC+0LTQvdC+0LPQviDRgtC40L/QsCAgDQoNCiog0KDQsNCx0L7RgtCw0LXRgiDRgtCw0LrQvtC5INC20LUg0L/RgNC40L3RhtC40L8g0L/RgNC40LLQtdC00LXQvdC40Y8sINC60LDQuiDQtNC70Y8g0LLQtdGC0LrQvtGA0L7QsiAgDQoNCiog0J/QviDRgdGD0YLQuCAtINGN0YLQviDQstC10LrRgtC+0YAsINGD0LvQvtC20LXQvdC90YvQuSDQv9C+INGB0YLQvtC70LHRhtCw0LwgIA0KDQoqINCU0LvRjyDRgdC+0LfQtNCw0L3QuNGPINC80LDRgtGA0LjRhtCwINC80L7QttC90L4g0LjRgdC/0L7Qu9GM0L7QstCw0YLRjCDRhNGD0L3QutGG0LggbWF0cml4ICANCg0KDQpgYGB7cn0NCm1hdHJpeCgxOjYsIG5yb3cgPSAyLCBuY29sID0gMykNCmBgYA0KDQojINCc0L7QttC90L4g0LjQt9Cx0LDQstC40YLRjNGB0Y8g0L7RgiDQuNC30LHRi9GC0L7Rh9C90L7RgdGC0LggIw0K0JzQvtC20L3QviDRg9C60LDQt9Cw0YLRjCDRgtC+0LvRjNC60L4gbnJvdyDQuNC70LggbmNvbCwg0LAg0LLRgtC+0YDQvtC5INCx0YPQtNC10YIg0LLRi9GH0LjRgdC70LXQvSDQsNCy0YLQvtC80LDRgtC40YfQtdGB0LrQuCwg0LjRgXjQvtC00Y8g0LjQtyDQtNC70LjQvdGLINCy0LXQutGC0L7RgNCwIA0KIA0KYGBge3J9DQptYXRyaXgoMTo2LCBucm93ID0gMikNCmBgYA0KDQojINCV0YHQu9C4INGF0L7RgtC40Lwg0YPQv9Cw0LrQvtCy0LDRgtGMINCy0LXQutGC0L7RgCDQvdC1INC/0L4g0YHRgtC+0LvQsdGG0LDQvCwg0LAg0L/QviDRgdGC0YDQvtGH0LrQsNC8PyAjDQrQmNGB0L/QvtC70YzQt9GD0LXQvCDQsNGA0LPRg9C80LXQvdGCIGJ5cm93ID0gVFJVRQ0KDQpgYGB7cn0NCm1hdHJpeCgxOjYsIG5yb3cgPSAyLCBieXJvdyA9IFRSVUUpDQpgYGANCg0KIyDQndC10YHQvtC+0YLQstC10YHRgtCy0LjQtSDQvNC10LbQtNGDINC00LvQuNC90L7QuSDQstC10LrRgtC+0YDQsCDQuCDQt9Cw0LTQsNCy0LDQtdC80YvQvCDRgNCw0LfQvNC10YDQvtC8PyAjDQojIyMg0JApINCS0LXQutGC0L7RgCDQutC+0YDQvtGH0LUg0YDQsNC30LzQtdGA0L7QsiDRgtCw0LHQu9C40YbRiyAgDQrQktC10LrRgtC+0YAg0L/QtdGA0LXQv9C40YHRi9Cy0LDQtdGC0YHRjyDQuCDQv9C+0LLRgtC+0YDRj9C10YLRgdGPINC90YPQttC90L7QtSDRh9C40YHQu9C+INGA0LDQtw0KYGBge3J9DQptYXRyaXgoNzo4LCBucm93ID0gMiwgbmNvbCA9IDUpDQpgYGANCiMjIyDQkSkg0JXRgdC70Lgg0LLQtdC60YLQvtGAINC00LvQuNC90LXQtT8g0KLQtdGB0YLQuNGA0YPQtdC8OiAgDQrQn9C+0LvRg9GH0LDQtdGC0YHRjywg0YfRgtC+INC40YHQv9C+0LvRjNC30YPRjtGC0YHRjyDRgtC+0LvRjNC60L4g0YLQtSDQt9C90LDRh9C10L3QuNGPINCy0LXQutGC0L7RgNCwLCDQutC+0YLQvtGA0YvQtSDQv9C+0LzQtdGJ0LDRjtGC0YHRjyDQsiDQt9Cw0LTQsNC90L3Ri9C1INGA0LDQt9C80LXRgNGLIA0KDQpgYGB7cn0NCm1hdHJpeCgxOjEwLCBucm93ID0gMiwgbmNvbCA9IDIpDQpgYGANCg0KIyDQntGC0LvQuNGH0LjRjyDQvNCw0YLRgNC40YbRiyDQvtGCINCy0LXQutGC0L7RgNCyICMNCtCV0LTQuNC90YHRgtCy0LXQvdC90L7QtSDQvtGC0LvQuNGH0LjQtSDRgdC+0YHRgtC+0LjRgiDQsiDRgtC+0LwsINGH0YLQviDRgyDQvNCw0YLRgNC40YbRiyDQtdGB0YLRjCDRgdC/0LXRhtC40LDQu9GM0L3Ri9C5INCw0YLRgNC40LHRg9GCIGRpbSAtINC+0YLQstC10YfQsNC10YIg0LfQsCDRgNCw0LfQvNC10YDQvdC+0YHRgtGMICANCiMjIyDQnNC+0LbQvdC+INC/0L7Qu9GD0YfQuNGC0Ywg0LTQvtGB0YLRg9C/INC6INGA0LDQt9C80LXRgNC90L7RgdGC0LgsINC40YHQv9C+0LvRjNC30YPRjyBkaW0gIA0KYGBge3J9DQpuIDwtIG1hdHJpeCgxOjYsIG5jb2wgPSAzKQ0KZGltKG4pDQpgYGANCjIgLSDRjdGC0L4g0YDRj9C00YsgIA0KMyAtINGN0YLQviDRgdGC0L7Qu9Cx0YbRiyAgDQoNCiMjIyBD0L/QtdGG0LjQsNC70YzQvdGL0LUg0YTRg9C90LrRhtC40LggbnJvdygpINC4IG5jb2woKSDQtNC10LvQsNGO0YIg0YLQviDQttC1INGB0LDQvNC+0LUNCmBgYHtyfQ0KbnJvdyhuKQ0KbmNvbChuKQ0KYGBgDQojIyMg0KfRgtC+INCx0YPQtNC10YIsINC10YHQu9C4INC90LjQstC10LvQuNGA0L7QstCw0YLRjCBkaW0/DQrQnNCw0YLRgNC40YbQsCDQv9GA0LXQstGA0LDRidCw0LXRgtGB0Y8g0LIg0L7QsdGL0YfQvdGL0Lkg0LLQtdC60YLQvtGADQpgYGB7cn0NCmRpbShuKSA8LSBOVUxMDQpuDQpgYGANCtCV0YHQu9C4INCy0L7RgdGB0YLQsNC90L7QstC40YLRjCDQsNGC0YLRgNC40LHRg9GCLCDRgtC+INC80LDRgtGA0LjRhtCwINC/0YDQuNC+0LHRgNC10YLQtdGCINC40YHRhdC+0LTQvdGL0Lkg0LLQuNC0DQpgYGB7cn0NCmRpbShuKSA8LSBjKDIsMykNCm4NCmBgYA0KIyMjINCS0L7Qv9GA0L7RgTog0YfRgtC+INCx0YPQtNC10YIsINC10YHQu9C4INCy0LXQutGC0L7RgNGDINC/0YDQuNGB0LLQvtC40YLRjCDQsNGC0YLRgNC40LHRg9GCIGRpbT8NCtCe0LbQuNC00LDRjiwg0YfRgtC+INCy0LXQutGC0L7RgCDQv9GA0LXQstGA0LDRgtC40YLRgdGPINCyINC80LDRgtGA0LjRhtGDLiDQotC10YHRgtC40YDRg9GOOiAgDQoxLiBD0L7Qt9C00LDQvCDQstC10LrRgtC+0YAg0L7RgiAxINC00L4gOA0KYGBge3J9DQp2ZWMgPC0gMTo4DQp2ZWMNCmBgYA0KMi4g0J/RgNC40YHQstC+0Y4g0LDRgtGC0YDQuNCx0YPRgiBkaW0NCmBgYHtyfQ0KZGltKHZlYykgPC0gYygyLCA0KQ0KdmVjDQpgYGANCtCa0LDQuiDQuCDQvtC20LjQtNCw0LvQvtGB0Ywg0LLQtdC60YLQvtGAINC/0YDQtdCy0YDQsNGC0LjQu9GB0Y8g0LIg0LzQsNGC0YDQuNGG0YMuINCf0YDQuNC60L7Qu9GM0L3QviANCg0KDQojINCQ0YDQuNGE0LzQtdGC0LjRh9C10YHQutC40LUg0L7Qv9C10YDQsNGG0LjQuCDRgSDQvNCw0YLRgNC40YbQsNC80LgNCtCU0LXQudGB0YLQstGD0Y7RgiDQstGB0LUg0YLQtSDQttC1INC/0YDQsNCy0LjQu9CwLCDRh9GC0L4g0Lgg0LTQu9GPINCy0LXRgtC60L7RgNC+0LIuICANCtCh0L7Qt9C00LDQtNC40Lwg0LTQstC1INC80LDRgtGA0LjRhtGLINC00LvRjyDQv9GA0L7QstC10YDQutC4DQpgYGB7cn0NCm4xIDwtIG1hdHJpeCgxOjQsIG5yb3cgPSAyKSAgDQpuMiA8LSBtYXRyaXgoYygxLDIsMiwzKSwgbnJvdyA9IDIpDQpuMQ0KbjINCmBgYA0KIyMjINCh0LvQvtC20LXQvdC40LUNCtCi0LXQv9C10YDRjCDQv9C+0L/RgNC+0LHRg9C10Lwg0LjRhSDRgdC70L7QttC40YLRjCDQtNGA0YPQsyDRgSDQtNGA0YPQs9C+0LwuINCh0LvQvtC20LXQvdC40LUg0L/RgNC+0LjQt9C+0LnQtNC10YIg0L/QvtGN0LvQtdC80LXQvdGC0L3Qvg0KYGBge3J9DQpuMSArIG4yIA0KYGBgDQojIyMg0J/RgNCw0LLQuNC70LAg0L/QtdGA0LXQv9C40YHRi9Cy0LDQvdC40Y8NCtCf0YDQsNCy0LjQu9CwINGA0LDQsdC+0YLQsNGO0YIg0YLQsNC6INC20LUsINC60LDQuiDQvdCwINCy0LXQutGC0L7RgNCw0YUsINC/0L7RjdGC0L7QvNGDINC80L7QttC10LwsINC90LDQv9GA0LjQvNC10YAsINC6INC80LDRgtGA0LjRhtC1INC00L7QsdCw0LLQuNGC0Ywg0YfQuNGB0LvQviAo0LDRgNC40YTQvNC10YLQuNC60LAg0YHQvdC+0LLQsCDQstGL0L/QvtC70L3Rj9C10YLRgdGPINC/0L7RjdC70LXQvNC10L3RgtC90L4pDQpgYGB7cn0NCm4xDQpuMSArIDUNCmBgYA0KIyMjINCj0LzQvdC+0LbQtdC90LjQtQ0K0KLQsNC6INC20LUg0LHRg9C00YPRgiDQstGL0L/QvtC70L3Rj9GC0YzRgdGPINC/0L7RjdC70LXQvNC10L3RgtC90L4sINC60LDQuiDQuCDQstGB0LUg0L7RgdGC0LDQu9GM0L3Ri9C1INCw0YDQuNGE0LzQtdGC0LjRh9C10YHQutC40LUg0L7Qv9C10YDQsNGC0L7RgNGLIA0KYGBge3J9DQpuMSAqIDINCmBgYA0KYGBge3J9DQpuMSAqIG4yDQpgYGANCiMjINCj0LzQvdC+0LbQtdC90LjQtSDQsiDRgdC80YvRgdC70LUg0LvQuNC90LXQudC90L7QuSDQsNC70LPQtdCx0YDRiyDRgtGA0LXQsdGD0LXRgiDQtNGA0YPQs9C40YUg0L7Qv9C10YDQsNGC0L7RgNC+0LINCtCn0YLQviDRgtCw0LrQvtC1INC70LjQvdC10LnQvdC+0LUg0LDQu9Cz0LXQsdGA0LAsINGPINC/0L7QvdGP0YLQuNGPINC90LUg0LjQvNC10Y4uINCf0LjRiNGD0YIsINGH0YLQviDRg9C80L3QvtC20LXQvdC40LUg0LIg0LvQuNC90LXQudC90L7QuSDQsNC70LPQtdCx0YDQtSDRgNCw0LHQvtGC0LDQtdGCINC/0L4gItC/0YDQuNC90YbQuNC/0YMg0YHRgtGA0L7QutGDINC90LAg0YHRgtC+0LvQsdC10YYgIA0KfGExICAgIGIxfCAgICAgICAgfGMxICAgIGQxfCAgDQp8ICAgICAgICB8ICAgKiAgICB8ICAgICAgICB8ICANCnxhMiAgICBiMnwgICAgICAgIHxjMiAgICBkMnwgIA0K0L/QvtC70YPRh9C10YLRgdGPINGC0L4g0LbQtSwg0YfRgtC+INC4ICANCnxhMWMxICsgYjFjMiAgICBhMWQxICsgYjFkMnwgIA0KfCAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgDQp8YTJjMSArIGIyYzIgICAgYTJkMSArIGIyZDJ8ICANCmBgYHtyfQ0KbjEgJSolIG4yDQpgYGANCtCf0YDQvtGC0LXRgdGC0LjRgNGD0Y4g0YHQu9C+0LbQtdC90LjQtSDRgSDRgtCw0LrQuNC8INC20LUg0LTQvtC/INC+0L/QtdGA0LDRgtC+0YDQvtC8IC0g0YLQsNC60L7QuSDRhNGD0L3QutGG0LjQuCDQvdC10YIgIA0KDQojINCk0YPQvdC60YbQuNGPIHN1bSgpDQrQn9C+0L/RgNC+0LHRg9GOINC/0YDQuNC80LXQvdC40YLRjCDQuiDQtNCy0YPQvCDQvNCw0YLRgNC40YbQsNC8DQpgYGB7cn0NCm4xDQpuMg0Kc3VtKG4xLCBuMikNCmBgYA0K0KIu0LUuIHN1bSgpINCy0L7Qt9Cy0YDQsNGJ0LDQtdGCINGB0YPQvNC80YMg0LLRgdC10YUg0Y3Qu9C10LzQtdC90YLQvtCyINCy0YHQtdGFINC80LDRgtGA0LjRhtCwLCDQsCDQvdC1INC/0L7RjdC70LXQvNC10L3RgtC90YPRjiDRgdGD0LzQvNGDIA0KDQojINCY0L3QtNC10LrRgdC40YDQvtCy0LDQvdC40LUg0LzQsNGC0YDQuNGGDQrQlNC10LnRgdGC0LLRg9GO0YIg0YLQtSDQttC1INC/0YDQsNCy0LjQu9CwLCDRh9GC0L4g0Lgg0LTQu9GPINCy0LXQutGC0L7RgNC+0LIsINC90L4g0YPRh9C40YLRi9Cy0LDRjtGC0YHRjyDQtNCy0LUg0YDQsNC30LzQtdGA0L3QvtGB0YLQuA0K0L3QsNC/0YDQuNC80LXRgCwg0YHQvtC30LTQsNC00Lwg0LzQsNGC0YDQuNGG0YMNCmBgYHtyfQ0KbSA8LSBtYXRyaXgoMToxMCwgbmNvbCA9IDUpDQptDQpgYGANCiMg0J/QvtC70YPRh9C40Lwg0LTQvtGB0YLRg9C/INC6INGN0LvQtdC80LXQvdGC0YMg0LIg0L/QtdGA0LLQvtC8INGA0Y/QtNGDLCDQsiAzINGB0YLQvtC70LHRhtC1IA0KYGBge3J9DQptWzEsIDNdDQpgYGANCtCY0L3RgtC10YDQtdGB0L3Qviwg0YfRgtC+INC10YHQu9C4INC+0L/Rg9GB0YLQuNC8INC+0LTQuNC9INC40Lcg0LDRgNCz0YPQvNC10L3RgtC+0LIg0L/RgNC4INC+0LHRgNCw0YnQtdC90LjQuCDQuiDRjdC70LXQvNC10L3RgtGDLCDRgtC+INC/0L7Qu9GD0YfQuNC8INC00L7RgdGC0YPQvyDQutC+INCy0YHQtdC5INGB0YLRgNC+0LrQtS8g0YHRgtC+0LvQsdGG0YMNCmBgYHtyfQ0KIzIt0Y8g0YHRgtGA0L7QutCwDQptWzIsIF0NCmBgYA0KYGBge3J9DQojMy3QuSDRgdGC0L7Qu9Cx0LXRhg0KbVsgLCAzXQ0KYGBgDQojIyDQnNC+0LbQvdC+INC/0L7Qu9GM0LfQvtCy0LDRgtGM0YHRjyDRgtCw0LrQvtC5INCw0L3QvdC+0YLQsNGG0LjQtdC5INC00LvRjyDQt9Cw0LzQtdC90Ysg0Y3Qu9C10LzQtdC90YLQvtCyINC80LDRgtGA0LjRhtGLDQrQn9C+0LTRgdGC0LDQstC70Y/RgtGMINCyINGN0LvQtdC80LXQvdGC0Ysg0LzQsNGC0YDQuNGG0Ysg0LzQvtC20L3QvjogIA0KKiDQstC10LrRgtC+0YDQsCAgDQoqINCy0LXQutGC0L7RgNCwINC10LTQuNC90LjRh9C90L7QuSDQtNC70LjQvdGLICjRgdC60LDQu9GP0YDRiykgIA0KKiDQv9C+0LTQvNCw0YLRgNC40YbRiyAgDQoNCiMjIyDQntCx0L3Rg9C70LjRgtGMINCy0YHRjiDQv9C10YDQstGD0Y4g0YHRgtGA0L7QutGDDQpgYGB7cn0NCm1bMSwgXSA8LSAwOyBtDQpgYGANCtCi0L4g0LbQtSDRgdCw0LzQvtC1INC60LDRgdCw0LXRgtGB0Y8g0L7RgtGA0LjRhtCw0YLQtdC70YzQvdGL0YUg0LjQvdC00LXQutGB0L7Qsi4g0J3QsNC/0YDQuNC80LXRgCwg0LXRgdC70Lgg0YXQvtGH0YMg0L/QtdGA0LXQv9GA0LjRgdCy0L7QuNGC0Ywg0LLRgdC1INC30L3QsNGH0LXQvdC40Y8g0LrRgNC+0LzQtSA1LdCz0L4g0YHRgtC+0LvQsdGG0LANCmBgYHtyfQ0KbVsgLCAtNV0gPC0gMTE6MTg7IG0NCmBgYA0KIyDQodGF0LvQvtC/0YvQstCw0L3QuNC1INGA0LDQt9C80LXRgNC90L7RgdGC0LggLSDQvtGB0L7QsdC10L3QvdC+0YHRgtGMINC80LDRgtGA0LjRhg0K0JTQvtC/0YPRgdGC0LjQvCwg0LLQvtC30YrQvNC10Lwg0YLRgyDQttC1INC80LDRgtGA0LjRhtGDLCDRh9GC0L4g0Lgg0YDQsNC90YzRiNC1LCDQvdC+INCy0L7RgdC/0L7Qu9GM0LfRg9C10LzRgdGPINC+0YLQtNC10LvRjNC90YvQvCDQstC10LrRgtC+0YDQvtC8LCDQutC+0YLQvtGA0YvQuSDQsdGD0LTQtdGCINGD0LrQsNC30YvQstCw0YLRjCDQuNC90LTQtdC60YHRiyDRgdGC0L7Qu9Cx0YbQvtCyDQpgYGB7cn0NCm0gPC0gbWF0cml4KDE6MTAsIG5jb2wgPSA1KQ0KaW5kIDwtIGMoMSwzLDUpDQptDQpgYGANCtCi0LXQv9C10YDRjCDQvtCx0YDQsNGC0LjQvNGB0Y8g0Log0Y3Qu9C10LzQtdC90YLQsNC8LCDQuNC90LTQtdC60YHQuNGA0YPQtdC80YvQvCDQsiDQstC10LrRgtC+0YDQtSBpbmQuINCf0L7Qu9GD0YfQsNC10Lwg0L/QvtC00LzQsNGC0YDQuNGG0YMg0LjQtyAz0YUg0YHRgtC+0LvQsdGG0L7QsiANCmBgYHtyfQ0KbVsgLCBpbmRdDQpgYGANCtCn0YLQviDQsdGD0LTQtdGCLCDQtdGB0LvQuCDQtNC70LjQvdCwINC40L3QtNC10LrRgdCwINCx0YPQtNC10YIg0YDQsNCy0L3QsCAxLiDQlNC+0L/Rg9GB0YLQuNC8LCDQvdCw0YEg0LjQvdGC0LXRgNC10YHRg9C10YIg0YLQvtC70YzQutC+IDPQuSDRgdGC0L7Qu9Cx0LXRhi4g0JzRiyDQt9Cw0YXQvtGC0LjQvCDQv9C+0LvRg9GH0LjRgtGMINC/0L7QtNC80LDRgtGA0LjRhtGDLCDRgdC+0YHRgtC+0Y/RidGD0Y4g0LjQtyAz0LPQviDRgdGC0L7Qu9Cx0YbQsCANCmBgYHtyfQ0KaW5kIDwtIDMNCm1bICwgaW5kXQ0KYGBgDQrQnNGLINCy0LjQtNC40LwsINGH0YLQviDQv9GA0L7QuNGB0YXQvtC00LjRgiAi0YHRhdC70L7Qv9GL0LLQsNC90LjQtSDRgNCw0LfQvNC10YDQvdC+0YHRgtC4IiAtINGCLtC1LiDRgNC10LfRg9C70YzQsNGC0L7QvCDQvtCx0YDQsNGJ0LXQvdC40Y8g0Log0LzQsNGC0YDQuNGG0LUg0LLQuNC00LjQvCDQvdC1INC80LDRgtGA0LjRhtGDLCDQsCDQstC10LrRgtC+0YAuICANCtCn0YLQvtCx0Ysg0LjQt9Cx0LDQstC40YLRjNGB0Y8g0L7RgiDRjdGC0L7Qs9C+INC/0L7QstC10LTQtdC90LjRjywg0LzQvtC20L3QviDQstC+0YHQv9C+0LvRjNC30L7QstCw0YLRjNGB0Y8g0LTQvtC/0L7Qu9C90LjRgtC10LvRjNC90YvQvCDQsNGA0LPRg9C80LXQvdGC0L7QvCBkcm9wDQpgYGB7cn0NCm1bICwgaW5kLCBkcm9wID0gRl0NCmBgYA0K0J/QvtC70YPRh9Cw0LXQvCDRgtCw0LrQuNC8INC+0LHRgNCw0LfQvtC8INC80LDRgtGA0LjRhtGDINCyIDEg0YHRgtC+0LvQsdC10YYsINCwINC90LUg0LLQtdC60YLQvtGAIA0KDQojINCY0LzQtdC90L7QstCw0L3QvdGL0LUg0LzQsNGC0YDQuNGG0Ys6IHJvd25hbWVzL2NvbG5hbWVzDQrQoyDQstC10LrRgtC+0YDQviDQvNC+0LPRg9GCINCx0YvRgtGMINC40LzQtdC90LAsINGC0LDQuiDQttC1INC4INGDINC80LDRgtGA0LjRhi7QktC+0LfRjNC80LXQvCDQvNCw0YLRgNC40YbRgyDQuCDQv9GA0LjRgdCy0L7QuNC8INGA0Y/QtNCw0Lwg0Y3RgtC+0Lkg0LzQsNGC0YDQuNGG0Ysg0L3QsNC30LLQsNC90LjQtSANCmBgYHtyfQ0KbSA8LSBtYXRyaXgoMToxMCwgbmNvbCA9IDUpDQpyb3duYW1lcyhtKSA8LSBjKCJyb3cxIiwgInJvdzIiKQ0KbQ0KYGBgDQrQotCw0Log0LbQtSDQvNC+0LbQvdC+INC/0YDQuNGB0LLQvtC40YLRjCDQuNC80LXQvdCwINGB0YLQvtC70LHRhtCw0LwuINCd0L4sINC10YHQu9C4INC90LUg0YXQvtGH0LXRgtGB0Y8g0LLQstC+0LTQuNGC0Ywg0LLRgdC1INC40LzQtdC90LAg0LLRgNGD0YfQvdGD0Y4sINGC0L4g0LzQvtC20L3QviDQstC+0YHQv9C+0LvRjNC30L7QstCw0YLRjNGB0Y8g0YTRg9C90LrRhtC40LXQuSBwYXN0ZTAoKSwg0LrQvtGC0L7RgNCw0Y8g0YHQutC70LXQuNCy0LDQtdGCINCy0LLQvtC00L3Ri9C1INCw0YDQs9GD0LzQtdC90YLRiyDQsiDQstC10LrRgtC+0YAg0LjQtyDRgdGC0YDQvtC6DQpgYGB7cn0NCmNvbG5hbWVzKG0pIDwtIHBhc3RlMCgiY29sdW1uIiwgMTo1KQ0KbQ0KYGBgDQoNCtCf0L7Qu9GD0YfQuNC70Lgg0LzQsNGC0YDQuNGG0YMsINC6INC60L7RgtC+0YDQvtC5INGC0LXQv9C10YDRjCDQvNC+0LbQvdC+INC+0LHRgNCw0YnQsNGC0YzRgdGPINC/0L4g0LjQvNC10L3QsNC8DQpgYGB7cn0NCm1bInJvdzEiLCBjKCJjb2x1bW4yIiwgImNvbHVtbjQiKSwgZHJvcCA9IEZdDQpgYGANCtCn0YLQviDQsdGD0LTQtdGCLCDQtdGB0LvQuCDQuNC30LzQtdC90LjRgtGMINC/0L7RgNGP0LTQvtC6INC60L7Qu9C+0L3QvtC6PyDQmNC30LzQtdC90LjRgtGB0Y8g0LvQuCDQvtGC0L7QsdGA0LDQttC10L3QuNC1INCyINC60L7QtNC1Pw0KYGBge3J9DQptWyJyb3cxIiwgYygiY29sdW1uNCIsICJjb2x1bW4yIiksIGRyb3AgPSBGXQ0KYGBgDQrQotC+INC10YHRgtGMINC/0L7RgNGP0LTQvtC6INCy0YvRgdGC0YDQsNC40LLQsNC10YLRgdGPINCyINGB0L7QvtGC0LLQtdGC0YHRgtCy0LjQuCDRgSDQutC+0LTQvtC8DQoNCtCSINGH0LXQvCDQvtGC0LvQuNGH0LjQtSBwYXN0ZSgpINC4IHBhc3RlMCgpLiAgDQpwYXN0ZSAoLi4uLCBzZXAgPSAiICIsIGNvbGxhcHNlID0gTlVMTCkNCnBhc3RlMCguLi4sIGNvbGxhcHNlID0gTlVMTCkNCtCf0L7Qv9GA0L7QsdGD0LXQvCDQv9C+0LLRgtC+0YDQuNGC0Ywg0LDQvdCw0LvQvtCz0LjRh9C90YPRjiDQvtC/0LXRgNCw0YbQuNGOLiDQn9C+0LrQsCDRgNCw0LfQvdC40YbRiyDQvdC1INCy0LjQttGDLiANCmBgYHtyfQ0KY29sbmFtZXMobSkgPC0gcGFzdGUoImNvbCIsIDE6NSkNCm0NCmBgYA0KDQrQktC+0LfQvNC+0LbQvdC+LCDQtdGB0LvQuCDQv9C+0LTQsNCy0LDRgtGMINC90LXRgdC60L7Qu9GM0LrQviDQstC10LrRgtC+0YDQvtCyINGE0YPQvdC60YbQuNC4LCDRgtC+INC80LXQttC00YMg0L3QuNC80Lgg0LzQvtC20L3QviDRgdGC0YDQvtC40YLRjCDQvdC10LrQuNC1INGA0LDQtNC10LvQuNGC0LXQu9C4Pw0KYGBge3J9DQpjb2xuYW1lcyhtKSA8LSBwYXN0ZSgiY29sIiwgMToyLCAic29sIiwgMzo1KQ0KbQ0KYGBgDQrQmtC+0YDQvtGH0LUg0L/QvtC60LAg0LrQsNC60LDRjy3RgtC+INC90LXQv9C+0L3Rj9GC0L3QsNGPINGE0YPQvdC60YbQuNGPLiANCg0KDQojINCf0YDQuNGB0L7QtdC00LjQvdC10L3QuNC1INC80LDRgtGA0LjRhjogcmJpbmQvY2JpbmQNCtCn0YLQviDQtNC10LvQsNGC0YwsINC10YHQu9C4INGPINGF0L7Rh9GDINC/0YDQuNGB0L7QtdC00LjQvdC40YLRjCDQvNCw0YLRgNC40YbRgyDQuiDQvNCw0YLRgNC40YbQtS4gIA0K0JTQu9GPINGN0YLQvtCz0L4g0LXRgdGC0Ywg0LTQstC1INGE0YPQvdC60YbQuNC4OiAgDQoqIHJiaW5kIC0g0YIu0LUuIHJvd2JpbmQsINGCLtC1LiDQv9GA0LjRgdC+0LXQtNC40L3QtdC90LjQtSDQv9C+INGA0Y/QtNCw0LwNCmBgYHtyfQ0KbjENCm4yDQpyYmluZChuMSwgbjIpDQpgYGANCiogY2JpbmQgLSDRgi7QtS4gY29sdW1uYmluZCwg0YIu0LUuINC/0YDQuNGB0L7QtdC00LjQvdC10L3QuNC1INC/0L4g0LrQvtC70L7QvdC60LDQvA0KYGBge3J9DQpjYmluZChuMSwgbjIpDQpgYGANCtCn0YLQviDQsdGD0LTQtdGCLCDQtdGB0LvQuCDQv9GA0LjRgdC+0LXQtNC40L3QuNGC0Ywg0Log0LzQsNGC0YDQuNGG0LUg0LLQtdC60YLQvtGAINC/0L4g0YDRj9C00LDQvD8NCmBgYHtyfQ0KdmVjIDwtIDE6NQ0KdmVjDQpyYmluZChuMSwgdmVjKQ0KY2JpbmQobjEsIHZlYykNCmBgYA0K0JLRi9Cy0L7QtCDQvtGI0LjQsdC60Lgg0L4g0YLQvtC8LCDRh9GC0L4g0YDQtdC30YPQu9GM0YLQuNGA0YPRjtGJ0LjQuSDQvtCx0YrQtdC60YIg0L3QtSDQutGA0LDRgtC10L0g0LTQu9C40L3QtSDQsNGA0LPRg9C80LXQvdGC0LUgdmVjLiAgDQrQn9C+0L/RgNC+0LHRg9GOINC/0YDQuNCy0LXRgdGC0LggdmVjINC6INGB0L7QvtGC0LLQtdGC0YHQstGD0Y7RidC10Lkg0LTQu9C40L3QtS4NCmBgYHtyfQ0KbGVuZ3RoKG4xKQ0KbGVuZ3RoKHZlYykNCmBgYA0K0KIu0LUuINC00LvQuNC90LAg0LzQsNGC0YDQuNGG0Ysg0L7Qv9GA0LXQtNC10LvRj9C10YLRgdGPINC60L7Qu9C40YfQtdGB0YLQstC+0Lwg0Y3Qu9C10LzQtdC90YLQvtCyINCyINC90LXQuSANCg0KYGBge3J9DQp2ZWMgPC0gMTo0DQpyYmluZChuMSwgdmVjKQ0KYGBgDQpgYGB7cn0NCnZlYyA8LSAxOjINCnJiaW5kKG4xLCB2ZWMpDQpgYGANCtCS0YvRhdC+0LTQuNGCINGH0YLQvi3RgtC+INC80L3QtSDQv9C+0LrQsCDQvdC1INC+0YfQtdC90Ywg0L/QvtC90Y/RgtC90L7QtS4gIA0K0JXRgdC70Lgg0L/QvtGH0LjRgtCw0YLRjCDRgdC/0YDQsNCy0LrRgyDQv9C+IHJiaW5kINC40LvQuCBjYmluZCwg0YLQviDRg9Cy0LjQtNC40LwsINGH0YLQviDQsNGA0LPRg9C80LXQvdGC0L7QvCDRhNGD0L3QutGG0LjQuCDRgdC70YPQttC40YIgIi4uLiIgKGVsbGlwc2lzKSAtINGN0YLQviDQt9C90LDRh9C40YIsINGH0YLQviDRhNGD0L3QutGG0LjQuCDQvNC+0LbQvdC+INC/0LXRgNC10LTQsNCy0LDRgtGMINC90LXQvtCz0YDQsNC90LjRh9C10L3QvdC+0LUg0YfQuNGB0LvQviDQvtCx0YrQtdC60YLQvtCyLiAgDQrQndCw0L/RgNC40LzQtdGALCDRhdC+0YfRgyDQstGL0LfQstCw0YLRjCDRhNGD0L3QutGG0LjRjiBjYmluZCDQvdCwINCx0L7Qu9GM0YjQvtC8INC60L7Qu9C40YfQtdGB0YLQstC1INCy0LXQutGC0L7RgNC+0LINCmBgYHtyfQ0KY2JpbmQobjEsIG4yKQ0KY2JpbmQobjEsIG4yLCAxOjIpDQpjYmluZChuMSwgbjIsIDE6MiwgYyg1LDMpKQ0KY2JpbmQobjEsIG4yLCAxOjIsIGMoNSwzKSwgbjJbICwxXSkNCiMg0Jgg0YLQsNC6INC00LDQu9C10LUNCmNiaW5kKG4xLCBuMiwgMToyLCBjKDUsMyksIG4yWyAsIDFdLCBuMSArIDMsIGNiaW5kKG4yLCBuMSkpDQpgYGANCtCi0LDQutC40Lwg0L7QsdGA0LDQt9C+0Lwg0LHRg9C00YPRgiDRgNCw0LHQvtGC0LDRgtGMINC4INC00YDRg9Cz0LjQtSDRhNGD0L3QutGG0LjQuDogIA0KKiDRgSAgDQoqIHBhc3RlICANCiogcGFzdGUwICANCiogc3VtICANCg0KIyDQpNGD0L3QutGG0LjRjyDRgdC10LzQtdC50YHRgtCy0LAgYXBwbHkNCiMjINCf0YDQuNC80LXQvdC10L3QuNC1INGE0YPQvdC60YbQuNC5INC6INC80LDRgtGA0LjRhtC1IGFwcGx5KCkNCtCn0LDRgdGC0L4g0LLQvtC30L3QuNC60LDQtdGCINC90LXQvtCx0YXQvtC00LjQvNC+0YHRgtGMINC/0YDQuNC80LXQvdC40YLRjCDQvtC00L3RgyDQuCDRgtGDINC20LUg0YTRg9C90LrRhtC40Y4g0Log0YHQvtC70LHRhtCw0Lwg0LjQu9C4INGB0YLRgNC+0YfQutCw0LwuINCSINC00YDRg9Cz0LjRhSDRj9C30YvQutCw0YUg0LTQu9GPINGN0YLQvtCz0L4g0LzQvtC20L3QviDQsdGL0LvQviDQsdGLINC90LDQv9C40YHQsNGC0Ywg0YbQuNC60LsgZm9yLiDQkiBSINGC0L7QttC1INC80L7QttC90L4sINC90L4g0LIg0Y3RgtC+0Lwg0L3QtdGCINC90LXQvtCx0YXQvtC00LjQvNC+0YHRgtC4LiAgDQrQodC+0LfQtNCw0LTQuNC8INC80LDRgtGA0LjRhtGDDQpgYGB7cn0NCm0gPC0gbWF0cml4KDE6MjUsIDUpDQptDQpgYGANCk4uQiEg0KMg0YTRg9C90LrRhtC40Lgg0L3QtdC+0LHQt9Cw0YLQtdC70YzQvdC+INC00L7Qu9C20L3QviDQsdGL0YLRjCDQutC70Y7Rh9C10LLQvtC1INGB0LvQvtCy0L4gcmV0dXJuLiDQldGB0LvQuCDQuiDQutC+0L3RhtGDINGE0YPQvdC60YbQuNC4IHJldHVybiDQvdC1INCy0YHRgtGA0LXRh9Cw0LXRgtGB0Y8sINGC0L4g0LLQvtC30LLRgNCw0YjQsNC10YLRgdGPINGA0LXQt9GD0LvRjNGC0LDRgiDQv9C+0YHQu9C10LTQvdC10Lkg0L7Qv9C10YDQsNGG0LjQuC4g0JzQvtC20L3QviDRgdC+0LrRgNCw0YnQsNGC0Ywg0LfQsNC/0LjRgdGMIA0K0KHQvtC30LTQsNC10Lwg0YTRg9C90LrRhtC40Y4g0YEg0L7QtNC90L7QuSDQvtC/0LXRgNCw0YbQuNC10LkNCmBgYHtyfQ0KZiA8LSBmdW5jdGlvbih4KSBzdW0oeF4yKQ0KYGBgDQoNCiMjINCi0YDQuCDQsNGA0LPRg9C80LXQvdGC0LAg0YTRg9C90LrRhtC40LggYXBwbHk6DQoqINCc0LDRgdGB0LjQsiAo0LzQsNGC0YDQuNGG0LApDQoqINCY0L3QtNC10LrRgSAoMSAtINC/0L4g0YHRgtGA0L7QutCw0LwsIDIgLSDQv9C+INGB0YLQvtC70LHRhtCw0LwpDQoqINCk0YPQvdC60YbQuNGPIA0KYGBge3J9DQojINCf0YDQuNC80LXQvdGOINGE0YPQvdC60YbQuNGOIGYg0Log0LzQsNGC0YDQuNGG0LUgbSDQv9C+0YHRgtGA0L7Rh9C90L4NCmFwcGx5KG0sIDEsIGYpDQpgYGANCmBgYHtyfQ0KIyDQn9GA0LjQvNC10L3RjiDRhNGD0L3QutGG0LjRjiDQv9C+INGB0YLQvtC70LHRhtCw0LwNCmFwcGx5KG0sIDIsIGYpDQpgYGANCtCf0LXRgNC10L/QuNGB0YvQstCw0LXRgtGB0Y8g0LvQuCDQvNCw0YLRgNC40YbQsD8NCmBgYHtyfQ0KbQ0KYGBgDQrQndC1INC/0LXRgNC10L/QuNGB0YvQstCw0LXRgtGB0Y8uICANCiAgDQojINCf0YDQuNC80LXQvdC10L3QuNC1INGE0YPQvdC60YbQuNC5INC6INC80LDRgtGA0LjRhtC1OiBhcHBseQ0K0JXRgdC70Lgg0YXQvtGH0YMg0L/RgNC40LzQtdC90LjRgtGMINGE0YPQvdC60YbQuNGOINC60L4g0LLRgdC10Lwg0Y3Qu9C10LzQtdC90YLQsNC8LCDRgtC+OiANCmBgYHtyfQ0KYXBwbHkobSwgMToyLCBmKQ0KYGBgDQrQnNC+0LbQvdC+INC4INC30LDQtNCw0LLQsNGC0Ywg0YPRgdC70L7QstC40Y8g0L/RgNC40LzQtdC90LXQvdC40Y8g0YTRg9C90LrRhtC40LgsINC90LDQv9GA0LjQvNC10YA6INC10YHQu9C4INGN0LvQtdC80LXQvdGCINCx0L7Qu9GM0YjQtSAxMywg0YLQviDQvtGB0YLQsNCy0LvRj9C10Lwg0Y3Qu9C10LzQtdC90YIsINCwINC10YHQu9C4INC80LXQvdGM0YjQtSwg0YLQviDQt9Cw0LzQtdC90Y/QtdC8INC90LAgMTMNCmBgYHtyfQ0KYXBwbHkobSwgMToyLCBmdW5jdGlvbihpKSBpZiAoaSA+IDEzKSBpIGVsc2UgMTMpDQpgYGANCtCf0LXRgNC10L/QuNGB0LDQu9Cw0YHRjCDQu9C4INC/0YDQuCDRjdGC0L7QvCDQvNCw0YLRgNC40YbQsD8NCmBgYHtyfQ0KbQ0KYGBgDQrQndC10YIuICANCiAgDQrQotCw0LrQsNGPINGE0YPQvdC60YbQuNGPICjQvdC1INC40LzQtdGO0YnQsNGPINC40LzQtdC90LgpINC90LDQt9GL0LLQsNC10YLRgdGPICrQsNC90L7QvdC40LzQvdC+0LkqIC0g0L7QvdCwINC/0YDQtdC60YDQsNGJ0LDQtdGCINGB0LLQvtC1INGB0YPRidC10YHRgtCy0L7QstCw0L3QuNGPINGB0YDQsNC30YMg0L/QvtGB0LvQtSDRgtC+0LPQviwg0LrQsNC6IGFwcGx5INCx0YvQu9CwINCy0YvQv9C+0LvQvdC10L3QsC4g0J3QuCDQsiDQvtC00L3QvtC8INC+0LrRgNGD0LbQtdC90LjQuCDQtdC1INC90LUg0L7RgdGC0LDQu9C+0YHRjC4g0K3RgtC+INGD0LTQvtCx0L3QviDQtNC70Y8g0LHRi9GB0YLRgNGL0YUg0YTRg9C90LrRhtC40LksINC00LvRjyDQutC+0YLQvtGA0YvRhSDQvdC1INGF0L7Rh9C10YLRgdGPINC30LDQstC+0LTQuNGC0Ywg0L/QtdGA0LXQvNC10L3QvdGD0Y4gDQrQoSDRgtC+0YfQutC4INC30YDQtdC90LjRjyDRj9C30YvQutCwIFIgLSDRjdGC0L4g0LvQuNGI0L3Rj9GPINGA0LDQsdC+0YLQsC4g0JzQvtC20L3QviDQsdGL0LvQviDRgdC00LXQu9Cw0YLRjCDRgtC+INC20LUg0YEg0L/QvtC80L7RidGM0Y4g0LvQvtCz0LjRh9C10YHQutC+0LPQviDQuNC90LTQtdC60YHQuNGA0L7QstCw0L3QuNGPDQpgYGB7cn0NCm1bbSA8PSAxM10gPC0gMTM7IG0NCmBgYA0KIyDQodCw0LzRi9C1INGH0LDRgdGC0YvQtSDRhNGD0L3QutGG0LjQuCDQtNC70Y8g0LzQsNGC0YDQuNGGDQrQodCw0LzRi9C1INGH0LDRgdGC0YvQtSDQvtC/0LXRgNCw0YbQuNC4INC/0L4g0YHRgtGA0L7QutCw0Lwg0Lgg0YHRgtC+0LvQsdGG0LDQvCAtIHN1bSDQuCBtZWFuICANCiogcm93U3VtcyAtIGPRg9C80LzQsCDQv9C+INGA0Y/QtNCw0LwgDQpgYGB7cn0NCnJvd1N1bXMobSkNCmBgYA0KKiByb3dNZWFucyAtINGB0YDQtdC00L3QtdC1INC/0L4g0YDRj9C00LDQvA0KYGBge3J9DQpyb3dNZWFucyhtKQ0KYGBgDQoqIGNvbFN1bXMgLSBj0YPQvNC80LAg0L/QviDQutC+0LvQvtC90LrQsNC8ICANCiogY29sTWVhbnMgLSDRgdGA0LXQtNC90LXQtSDQv9C+INC60L7Qu9C+0L3QutCw0LwgIA0KICANCtCU0L7Qv9GD0YHRgtC40LwsINC80Ysg0YXQvtGC0LjQvCDRg9C00L7RgdGC0L7QstC10YDQuNGC0YzRgdGPLCDRh9GC0L4gcm93U3VtcyDQtNC10LnRgdGC0LLQuNGC0LXQu9GM0L3QviDRgdGH0LjRgtCw0LXRgiDRgdGD0LzQvNGDINGN0LvQtdC80LXQvdGC0L7QsiDQv9C+INGA0Y/QtNCw0LwuINCc0L7QttC10Lwg0L3QsNC/0LjRgdCw0YLRjCDRgdCy0L7RjiDRgdC+0LHRgdGC0LLQtdC90L3Rg9GOINGE0YPQvdC60YbQuNGOLCDQuNGB0L/QvtC70YzQt9GD0Y8gYXBwbHkg0LTQu9GPINGN0YLQvtCz0L4gDQpgYGB7cn0NCmFsbC5lcXVhbChyb3dTdW1zKG0pLGFwcGx5KG0sIDEsIHN1bSkpDQpgYGANCmBgYHtyfQ0KYWxsLmVxdWFsKGNvbFN1bXMobSksYXBwbHkobSwgMiwgc3VtKSkNCmBgYA0KIyDQmtC+0LzQvNC10L3RgtCw0YDQuNC4IFN0ZXBpaw0KIyMg0KPQv9GA0LDQstC70Y/RjtGJ0LjQtSDQutC+0L3RgdGC0YDRg9C60YbQuNC4INGC0L7QttC1INGA0LDQsdC+0YLQsNGO0YIg0YEg0LLQtdC60YLQvtGA0LDQvNC4INC4INC80LDRgtGA0LjRhtCw0LzQuA0K0J3QsNC/0YDQuNC80LXRgCwNCmBgYHtyfQ0KdCA8LSBtYXRyaXgoMTo5LCAzKTsgdA0KeSA8LSAgaWZlbHNlKHQgJSUgMiA9PSAwLCAxLCAwKQ0KeQ0KYGBgDQrQndC+INGB0YLQvtC40YIg0YPRh9C40YLRi9Cy0LDRgtGMLCDRh9GC0L4gaWZlbHNlINGF0L7RgtGMINC4INCy0LXQutGC0L7RgNC40LfQvtCy0LDQvdCwLCDQvdC+INC90LUg0YDQsNCx0L7RgtCw0LXRgiDQvdC1INC+0YfQtdC90Ywg0LHRi9GB0YLRgNC+LiDQkiDQv9GA0LjQstC10LTQtdC90L3QvtC8INC/0YDQuNC80LXRgNC1INC70YPRh9GI0LUg0L7Qv9GP0YLRjCDQttC1INC40YHQv9C+0LvRjNC30L7QstCw0YLRjCDQuNC90LTQtdC60YHQuNGA0L7QstCw0L3QuNC1LiDQndCw0L/RgNC40LzQtdGADQpgYGB7cn0NCm0gPC0gIG1hdHJpeCgwLCAzLCAzKTsgbQ0KbVtzZXFfYWxvbmcobSkgJSUgMiA9PSAwXSA8LSAxDQptDQpgYGANCiMjINCd0LXQutC+0YLQvtGA0YvQtSDQvtGB0L7QsdC10L3QvdC+0YHRgtC4INC80LDRgtGA0LjRhg0KMSkg0JzQsNGC0YDQuNGG0Ysg0LfQsNC90LjQvNCw0Y7RgiDQvNC10L3RjNGI0LjQuSDQvtCx0YrQtdC8INC+0L/QtdGA0LDRgtC40LLQvdC+0Lkg0L/QsNC80Y/RgtC4LCDRh9C10Lwg0LDQvdCw0LvQvtCz0LjRh9C90YvQuSBkYXRhZnJhbWUgIA0KDQoyKSDQodC60L7RgNC+0YHRgtGMINCy0YvQv9C+0LvQvdC10L3QuNGPINCw0L3QsNC70L7Qs9C40YfQvdGL0YUg0YTRg9C90LrRhtC40Lkg0L3QsCDQvNCw0YLRgNC40YbQsNGFLCDQstGL0YjQtSDRh9C10Lwg0L3QsCBkYXRhZnJhbWUgIA0KDQozKSDQkiDQutC+0L3RgtC10LrRgdGC0LUg0YDQsNCx0L7RgtGLINGBINGH0LXQvC3RgtC+INC+0YfQtdC90Ywg0LHQvtC70YzRiNC40LwsINC40YHQv9C+0LvRjNC30YPQtdGC0YHRjyDQvdCw0YHQu9C10LTQvdC40Log0LzQsNGC0YDQuNGG0YsgYmlnbWF0cml4ICANCg0K0J/RgNC40LzQtdC90LXQvdC40LUg0YTRg9C90LrRhtC40Lgg0YHQtdC80LXQudGB0YLQstCwIGFwcGx5INC90LUg0YHQsNC80LDRjyDRhdC+0YDQvtGI0LDRjyDQv9GA0LDQutGC0LjQutCwINC40Lct0LfQsCDQvdC10YHRgtCw0LHQuNC70YzQvdC+0YHRgtC4INC/0L7Qu9GD0YfQsNC10LzQvtCz0L4g0YDQtdC30YPQu9GM0YLQsNGC0LANCg0KIyDQnNCw0YLRgNC40YbRiyDQuCDQodC/0LjRgdC60LggLSDRh9Cw0YHRgtGMIDIgIA0K0JTQvtC/0YPRgdGC0LjQvCwg0LXRgdGC0Ywg0LTQstC1INC80LDRgtGA0LjRhtGLLiDQp9GC0L7QsdGLINC/0L7Qu9GD0YfQuNGC0Ywg0LjQtyDQvdC40YUg0L7QtNC90YMg0LHQvtC70YzRiNGD0Y4g0LzQsNGC0YDQuNGG0YMg0LzQvtC20L3QviDQstC+0YHQv9C+0LvRjNC30L7QstCw0YLRjNGB0Y8g0YTRg9C90LrRhtC40Y/QvNC4ICpyYmluZCgpKiDQuNC70LggKmNiaW5kKCkqLiAgDQrQndC+LCDQtNC+0L/Rg9GB0YLQuNC8LCDRjdGC0L7Qs9C+INC90LXQtNC+0YHRgtCw0YLQvtGH0L3Qvi4g0J3QsNC/0YDQuNC80LXRgCwg0YXQvtGC0LjQvCDQvtCx0YrQtdC00LjQvdC40YLRjCDQuNGFINC/0L4g0LTQuNCw0LPQvtC90LDQu9C4INGC0LDQuiwg0YfRgtC+0LHRiyBtMSDQt9Cw0L3QuNC80LDQu9CwINC70LXQstGL0Lkg0LLQtdGA0YXQvdC40Lkg0YPQs9C+0LssIG0yIC0g0L/RgNCw0LLRi9C5INC90LjQttC90LjQuSDRg9Cz0L7Quywg0LAg0L7RgdGC0LDQu9GM0L3Ri9C1INGN0LvQtdC80LXQvdGC0Ysg0LzQsNGC0YDQuNGG0Ysg0LHRi9C70Lgg0LfQsNC/0L7Qu9C90LXQvdGLINC60LDQutC40LzQuC3QvdC40LHRg9C00Ywg0LfQvdCw0YfQtdC90LjQvNC4ICANCiMjIyDQmtCw0Log0L3QsNC/0LjRgdCw0YLRjCDRhNGD0L3QutGG0LjRjiDQtNC70Y8g0YDQtdGI0LXQvdC40Y8g0YLQsNC60L7QuSDQt9Cw0LTQsNGH0Lg/IA0K0J3QsNC/0LjRiNC10Lwg0YTRg9C90LrRhtC40Y4uINCd0LDQvCDQvdGD0LbQvdC+INCy0LLQtdGB0YLQuCDRgNC10LfRg9C70YzRgtC40YDRg9GO0YnRg9GOINC80LDRgtGA0LjRhtGDLCDQvNGLINC30L3QsNC10Lwg0LXQtSDRgNCw0LfQvNC10YAgLSDRjdGC0L4g0YHRg9C80LzQsCDQutC+0LvQuNGH0LXRgdGC0LLQsCDRgNGP0LTQvtCyIG0xINC4IG0yLCDRgtC+INC20LUg0YHQsNC80L7QtSDQstC10YDQvdC+INC4INC00LvRjyDRgdGC0L7Qu9Cx0YbQvtCyLiAgDQoxLiDQl9Cw0L/QvtC70L3QuNC8IG0zINGN0LvQtdC80LXQvdGC0L7QvCBmaWxsLCDQutC+0YLQvtGA0YvQuSDQsdGD0LTQtdGCINC30LDQv9C+0LvQvdGP0YLRjCDQv9GD0YHRgtGL0LUg0Y/Rh9C10LnQutC4LCDQsCDQv9C+0YLQvtC8INC/0YDQvtGB0YLQviDQt9Cw0L/QvtC70L3QuNC8INC70LXQstGL0Lkg0LLQtdGA0YXQvdC40Lkg0Lgg0L/RgNCw0LLRi9C5INC90LjQttC90LjQuSDRg9Cz0LvRiw0KYGBge3J9DQpiaW5kX2RpYWcgPC0gZnVuY3Rpb24obTEsIG0yLCBmaWxsKSB7DQogIG0zIDwtIG1hdHJpeChmaWxsLCANCiAgICAgICAgICAgICAgIG5yb3cgPSBucm93KG0xKSArIG5yb3cobTIpLA0KICAgICAgICAgICAgICAgbmNvbCA9IG5jb2wobTEpICsgbmNvbChtMikNCiAgICAgICAgICAgICAgICkNCiAgIyDQnNCw0YLRgNC40YbRiyDRgdC+0LfQtNCw0L3QsCwg0YLQtdC/0LXRgNGMINC80L7QttC90L4g0LfQsNC/0L7Qu9C90LjRgtGMINC10LUg0LTQstCwINC60YPRgdC60LANCiAgIyDQn9C10YDQstGL0Lkg0LrRg9GB0L7QuiAtINC70LXQstGL0Lkg0LLQtdGA0YXQvdC40Lkg0YPQs9C+0LsgbTENCiAgbTNbMTpucm93KG0xKSwgMTpuY29sKG0xKV0gPC0gbTENCiAgbTNbbnJvdyhtMSkgKyAxOm5yb3cobTIpLCBuY29sKG0xKSArIDE6bmNvbChtMildIDwtIG0yDQogIG0zDQp9DQpgYGANCtCS0L7RgiDRhNGD0L3QutGG0LjRjyDQuCDQs9C+0YLQvtCy0LAuICANCtCc0L7QttC10Lwg0LLQstC10YHRgtC4INC80LDRgtGA0LjRhtGLDQpgYGB7cn0NCm0xIDwtIG1hdHJpeCgxOjEyLCBucm93ID0gMykNCm0yIDwtIG1hdHJpeCgxMDoxNSwgbmNvbCA9IDMpDQptMTsgbTINCmBgYA0K0J/RgNC40LzQtdC90LjQvCDRhNGD0L3QutGG0LjRjg0KYGBge3J9DQpiaW5kX2RpYWcobTIsIG0xLCBmaWxsID0gTkEpDQpgYGANCmBgYHtyfQ0KYmluZF9kaWFnKG0yLCBtMSwgZmlsbCA9IDApDQpgYGANCmBgYHtyfQ0KYmluZF9kaWFnKG0yLCBtMSwgZmlsbCA9ICJmdWNrIikNCmBgYA0K0JfQsNC/0LjRgdGL0LLQsNC10YLRgdGPINC70Lgg0L/RgNC4INGN0YLQvtC8INC/0LXRgNC10LzQtdC90L3QsNGPIG0zINCyINCz0LvQvtCx0LDQu9GM0L3QvtC1INC+0LrRgNGD0LbQtdC90LjQtSDQuNC70Lgg0Y3RgtC+INC+0LTQvdC+0YDQsNC30L7QstGL0Lkg0LLRi9Cy0L7QtD8NCmBgYHtyfQ0KbTMNCmBgYA0K0J3QtSDQt9Cw0L/QuNGB0YvQstCw0LXRgtGB0Y8sINC60LDQuiDQuCDQvtC20LjQtNCw0LvQvtGB0YwgIA0KICANCtCi0L7QttC1INGB0LDQvNC+0LUg0LzQvtC20L3QviDQsdGL0LvQviDQuCDRgdC00LXQu9Cw0YLRjCDRh9C10YDQtdC3IGNiaW5kINC4IHJiaW5kDQpgYGB7cn0NCmJpbmRfZGlhZzI8LWZ1bmN0aW9uKG0xLG0yLGZpbGwpDQp7DQogIGNiaW5kKA0KICByYmluZChtMSxtYXRyaXgoZmlsbCxucm93KG0yKSxuY29sKG0xKSkpLA0KICByYmluZChtYXRyaXgoZmlsbCxucm93KG0xKSxuY29sKG0yKSksbTIpKQ0KfQ0KYGBgDQrQn9GA0L7QsdGD0LXQvA0KYGBge3J9DQpiaW5kX2RpYWcyKG0xLCBtMiwgZmlsbCA9IDApDQpgYGANCiMjINCX0LDQtNCw0YfQsCwg0YEg0LrQvtGC0L7RgNC+0Lkg0Y8g0L3QtSDRgdC/0YDQsNCy0LjQu9GB0Y8NCtCd0LDQv9C40YjQuNGC0LUg0YTRg9C90LrRhtC40Y4sINC60L7RgtC+0YDQsNGPINC/0YDQuNC90LjQvNCw0LXRgiDQvtC00L3QviDRhtC10LvQvtC1INGH0LjRgdC70L4gbiwg0LAg0LLQvtC30LLRgNCw0YnQsNC10YIg4oCc0YHRgtGD0L/QtdC90YfQsNGC0YPRjuKAnSDQvNCw0YLRgNC40YbRgywg0YHQvtGB0YLQvtGP0YnRg9GOINC40LcgbiDRjdGC0LDQttC10LkuINCt0YLQsNC20Lgg0L3Rg9C80LXRgNGD0Y7RgtGB0Y8g0YEg0L/QtdGA0LLQvtCz0L4sINGI0LjRgNC40L3QsCDQutCw0LbQtNC+0Lkg0YHRgtGD0L/QtdC90YzQutC4INGA0LDQstC90LAg0L7QtNC90L7QuSDRgdGC0YDQvtC60LUg0LjQu9C4INGB0YLQvtC70LHRhtGDLiAgDQoNCtCf0YDQuNC80LXRgC4g0J/Rg9GB0YLRjCBuPTQsINGC0L7Qs9C00LAg0L3QtdC+0LHRhdC+0LTQuNC80L4g0LLQtdGA0L3Rg9GC0Ywg0LzQsNGC0YDQuNGG0YMg0LLQuNC00LAgIA0KDQogIDEgICAxICAgMSAgIDEgICAxICAgMSAgIDEgIA0KICAxICAgMiAgIDIgICAyICAgMiAgIDIgICAxICANCiAgMSAgIDIgICAzICAgMyAgIDMgICAyICAgMSAgDQogIDEgICAyICAgMyAgIDQgICAzICAgMiAgIDEgIA0KICAxICAgMiAgIDMgICAzICAgMyAgIDIgICAxICANCiAgMSAgIDIgICAyICAgMiAgIDIgICAyICAgMSAgDQogIDEgICAxICAgMSAgIDEgICAxICAgMSAgIDEgIA0KICANCiMjIyDQoNC10YjQtdC90LjRjw0KIyMjIyAxIC0gYyDRhtC40LrQu9C+0LwgZm9yDQoNCmBgYHtyfQ0KYnVpbGRfemlnZ3VyYXQyIDwtIGZ1bmN0aW9uKG4pIHsNCiAgbTwtbWF0cml4KDAsMipuLTEsMipuLTEpDQogIGI8LW4qMi0xDQogIGM8LWINCiAgZm9yIChpIGluIDE6bikgew0KICAgIGlmIChpPT0xKSB7DQogICAgICBtMTwtbWF0cml4KGksYixiKQ0KICAgICAgbVtpOmIsaTpiXSA8LSBtMQ0KICAgICAgYiA8LSBiLTENCiAgICB9IGVsc2Ugew0KICAgICAgYyA8LSBjLTINCiAgICAgIG0xIDwtbWF0cml4KGksYyxjKQ0KICAgICAgbVtpOmIsaTpiXSA8LW0xDQogICAgICBiIDwtIGItMQ0KICAgIH0NCiAgfQ0KICBtDQp9ICANCmBgYA0KDQojIyMjINCn0LXRgNC10Lcg0LjQvdC00LXQutGB0YsNCmBgYHtyfQ0KYnVpbGRfemlnZ3VyYXQgPC0gZnVuY3Rpb24obikgew0KICAgICPQktGL0LLQvtC00LjQvCDQsiDQvtGC0LTQtdC70YzQvdGD0Y4g0LzQsNGC0YDQuNGG0YMg0YHQviDRgdGC0L7Qu9Cx0YbQsNC80LggInJvdyIg0LggImNvbCIg0LLRgdC1INC40L3QtNC10LrRgdGLINC80LDRgtGA0LjRhtGLINGA0LDQt9C80LXRgNC90L7RgdGC0Lgg0LfQuNC60LrRg9GA0LDRgtCwDQogICAgeiA8LSB3aGljaChtYXRyaXgoMSxuKjItMSxuKjItMSk9PTEsIGFyci5pbmQgPSBUKQ0KICAgICPQkiDQutCw0LbQtNC+0Lkg0YHRgtGA0L7QutC1INC80LXQvdGP0LXQvCDQt9C90LDRh9C10L3QuNGPLCDQv9GA0LXQstGL0YjQsNGO0YnQtdC1INC30LDQtNCw0L3QvdC+0LUg0YfQuNGB0LvQviBuDQogICAgeiA8LSBpZmVsc2Uoej5uLDIqbi16LHopDQogICAgI9CSINC60LDQttC00L7QuSDRgdGC0YDQvtC60LUg0L7RgdGC0LDQstC70Y/QtdC8INGC0L7Qu9GM0LrQviDQvdCw0LjQvNC10L3RjNGI0LXQtQ0KICAgIHogPC0gaWZlbHNlKHpbLDFdPj16WywyXSx6WywyXSx6WywxXSkNCiAgICAj0JjRgtC+0LPQvtCy0YvQuSDQstC10LrRgtC+0YAg0L/RgNC10LLRgNCw0YnQsNC10Lwg0LIg0LzQsNGC0YDQuNGG0YMgKNC30LjQutC60YPRgNCw0YIpDQogICAgZGltKHopPC1jKDIqbi0xLDIqbi0xKQ0KICAgICNa0LjQutC60YPRgNCw0YINCiAgICB6DQp9DQpgYGANCg0KDQojIyMjIDIg0LHQtdC3INGG0LjQutC70L7QsiDQuCDRgNC10LrRg9GA0YHQuNC5ICANCmBgYHtyfQ0KYnVpbGRfemlnZ3VyYXQgPC0gZnVuY3Rpb24obikgew0KICBkIDwtIG4gKiAyIC0gMQ0KICBvdXRlcigxOmQsIDE6ZCwgZnVuY3Rpb24oeCx5KSB7DQogICB4IDwtIG4gLSBhYnMobiAtIHgpDQogICB5IDwtIG4gLSBhYnMobiAtIHkpDQogICBwbWluKHgseSkNCiAgfSkNCn0gIA0KYGBgDQoNCg0KIyMjIyAzIC0g0LrRgNCw0YHQuNCy0L7QtSDRgNC10YjQtdC90LjQtSDQsdC10Lcg0YbQuNC60LvQvtCyDQoNCmBgYHtyfQ0KYnVpbGRfemlnZ3VyYXQgPC0gZnVuY3Rpb24obikgew0KICBkID0gbioyLTEgIA0KICAjINGB0L7Qt9C00LDQtNC40LwgNCDRgdGC0YPQv9C10L3Rh9Cw0YLRi9C1INC80LDRgtGA0LjRhtGLLCDQvdCw0L/RgNCw0LLQu9C10L3QvdGL0LUg0LIg0YDQsNC30L3Ri9C1INGB0YLQvtGA0L7QvdGLDQogIG0xID0gbWF0cml4KDE6ZCwgZCwgZCkNCiAgbTIgPSBtYXRyaXgoMTpkLCBkLCBkLCBieXJvdyA9IFQpDQogIG0zID0gbWF0cml4KGQ6MSwgZCwgZCkNCiAgbTQgPSBtYXRyaXgoZDoxLCBkLCBkLCBieXJvdyA9IFQpDQogICMg0L3QsNC50LTQtdC8INC80LjQvdC40LzRg9C8INC00LvRjyDQutCw0LbQtNC+0Lkg0L/QvtC30LjRhtC40Lgg0LjQtyDRh9C10YLRi9GA0LXRhSDQvNCw0YLRgNC40YYNCiAgcG1pbihtMSwgbTIsIG0zLCBtNCkNCn0NCmBgYA0KICANCiMjIyMg0JPQtdC+0LzQtdGC0YDQuNGH0LXRgdC60L7QtSDRgNC10YjQtdC90LjQtQ0KYGBge3J9DQpidWlsZF96aWdndXJhdCA8LSBmdW5jdGlvbihuKSB7DQogIHYgPC0gYygxOihuLTEpLCBuLCAobi0xKToxKSAgIyDQv9GA0LjQvNC10YA6IDEgMiAzIDIgMQ0KICBOIDwtIDIqbi0xDQogIA0KICAjINC80LDRgtGA0LjRhtCwINC40Lcg0L/QvtCy0YLQvtGA0Y/RjtGJ0LjRhdGB0Y8g0LLQtdC60YLQvtGA0L7Qsg0KICBtYXQxIDwtIG1hdHJpeChyZXAodiwgTiksIE4sIE4pDQogIA0KICAjINGC0LAg0LbQtSDQvNCw0YLRgNC40YbQsCDQsiDRgtGA0LDRgdC/0L7QvdC40YDQvtCy0LDQvdC90L7QvCAoItC/0L7QstC10YDQvdGD0YLQvtC8Iikg0LLQuNC00LUNCiAgbWF0MiA8LSBtYXRyaXgocmVwKHYsIE4pLCBOLCBOLCBieXJvdz1UKQ0KICANCiAgIyDRgdC80LXRiNC10L3QuNC1INC80LDRgtGA0LjRhiDQtNCw0LXRgiDQv9C40YDQsNC80LjQtNGDDQogICMg0LzQvtC00YPQu9GMINC/0L7Qt9Cy0L7Qu9GP0LXRgiAi0YPQsdGA0LDRgtGMIiDQuNC30LHRi9GC0L7Rh9C90YvQtSDQtNC40LDQs9C+0L3QsNC70YzQvdGL0LUg0Y3Qu9C10LzQtdC90YLRiw0KICByZXR1cm4oKG1hdDErbWF0Mi1hYnMobWF0MS1tYXQyKSkvMikNCn0NCmBgYA0KDQojIyMjINCS0LDQttC90L4sINGH0YLQviDQutC+0LQg0L3QsCBSINGBINGG0LjQutC70L7QvCDRgNCw0LHQvtGC0LDQtdGCINC80LXQtNC70LXQvdC10LUNCtCk0YPQvdC60YbQuNGPINC90LAg0YbQuNC60LvQtQ0KDQpidWlsZF96aWdndXJhdF8xIDwtIGZ1bmN0aW9uKG4pIHsgIA0KIHJlc3VsdF9tIDwtIG1hdHJpeCgwLCBucm93ID0gMipuIC0gMSwgbmNvbCA9IDIqbiAtIDEpICANCiAgZm9yKGkgaW4gMTooMipuIC0gMSkpeyAgDQogICBmb3IoaiBpbiAxOigyKm4gLSAxKSl7ICANCiAgICByZXN1bHRfbVtpLGpdID0gLW1heChhYnMoaS1uKSxhYnMoai1uKSkgIA0KICAgIH0gIA0KICB9ICANCnJldHVybihyZXN1bHRfbSArIG4pDQoNCiAgDQrQpNGD0L3QutGG0LjRjyDQsdC10Lcg0YbQuNC60LvQsA0KDQpidWlsZF96aWdndXJhdF8yIDwtIGZ1bmN0aW9uKG4pIHsgIA0KIHNpemUgPC0gbioyLTEgIA0KICB0ZW1wIDwtIG1hdHJpeChOYU4sIHNpemUsIHNpemUpICANCiAgcG1pbihuLWFicyhuIC0gcm93KHRlbXApKSwgbi1hYnMobi1jb2wodGVtcCkpKQ0KDQogIA0K0J/RgNC+0LLQtdGA0LjQvCDRgdC60L7RgNC+0YHRgtGMINGA0LDQsdC+0YLRiyANCmBgYHtyfQ0Kc3lzdGVtLnRpbWUoYnVpbGRfemlnZ3VyYXRfMSgxMDAwKSkNCmBgYA0K0L/QvtC70YzQt9C+0LLQsNGC0LXQu9GMICAgICAg0YHQuNGB0YLQtdC80LAgICAgICAg0L/RgNC+0YjQu9C+IA0KICAgICAgICA5LjQyICAgICAgICAgMC4zMCAgICAgICAgMTAuMDkgDQoNCmBgYHtyfQ0Kc3lzdGVtLnRpbWUoYnVpbGRfemlnZ3VyYXRfMigxMDAwKSkNCmBgYA0K0L/QvtC70YzQt9C+0LLQsNGC0LXQu9GMICAgICAg0YHQuNGB0YLQtdC80LAgICAgICAg0L/RgNC+0YjQu9C+IA0KICAgICAgICAwLjcxICAgICAgICAgMC4wNCAgICAgICAgIDAuNzUgDQoNCg0K