Введение

Подключаем библиотеки:

library(dplyr)
library(ggplot2)
library(phonR)
library(vowels)
library(readr)
library(lingtypology)

Рутульский язык (Нахско-дагестанские > Лезгинские > Западно-лезгинские)

Кининский диалект рутульского:

(простите, я не научился центрировать карту в нужном месте)

map.feature(languages = vcol$language,
            features = vcol$language,
            color = vcol$color,
            latitude = vcol$lat,
            longitude = vcol$lon,
            label = vcol$eng
            )

Чего мы хотим?

Узнать что-то про рутульскую редукцию гласных!

Подходы к ударению и редукции:

На самом деле cловами “spectral tilt” называют примерно тысячу вещей:

Нам потенциально подходит мера A1-A2:

Спойлер: мне не удалось нормально вытащить A1-A2, так что в этот раз обойдемся без него.

Итак, у нас осталось 3 меры.

Данные

Общие штуки

  • Записаны 30 июня и 1 июля сего года

  • 5 информант_ок 1971-1982 г. р.

  • Техника:
  • Диктофон TASCAM DR-40
  • Хэдсет Shure WH20XLR
  • Параметры: Моно, .wav 24-bit, ЧД 44100 Гц.

  • На данный момент размечено 4 записи (одна оказалась с проблемами, поэтому было решено её отложить до выяснения)

  • Скрипт для вытаскивания данных из данных взят отсюда: [Washington 2018]

Я немного его модифицировал

Стимулы

Ударение выделено акутом, желтой подсветкой – интересующий нас гласный.

Проблемы со стимулами:

  • ! Повсюду плавные (в правом контексте)

  • сложная морфология (причастия, рефактив) вводила в замешательство, люди старались избавиться от нее, несмотря на мои уговоры

  • Чудовищная вариативность косвенных форм (но тут уж ничего не поделать)

  • В одном случае пришлось взять клитизованную связку, потому что другой заударный контекст для ки* мне отказались придумывать

  • Иней – плохая идея ленивого человека.

  • Разное количество рядов стимулов на группу – столько осталось после выбраковки

Разметка

Про сегментацию есть умная книжка: [Machač, Skarnitzl 2009].

  • Плохая новость №1 - она есть в интернете только кусками.

  • Плохая новость №2 - там в основном только про интервокальные штуки, хотя нечто общетеоретическое там тоже есть.

Для меня было важным, что они предлагают ставить границы между формантными колонками (formant columns) (сразу перед или после)

Итак:

  • Размечался кусок гласного по следующим правилам:
  • Начальная граница (startpoint) помечалась сразу после двух отчетливо заметных формантных колонок
  • Конечная граница (endpoint) помечалась сразу перед последней отчетливо заметной формантной колонкой

Что кодировалось?

  1. Гласный

  2. Позиция относительно ударения (ударный, предударный, заударный)

  3. Тип произнесения (1, 2, 3, контекстное произнесение)

  4. Слово

  5. Спикер

  • Понятное дело, на этом месте возникли проблемы с нашими любимыми плавными.

  • Их я размечал скорее импрессионистически, ориентируясь на степень зачернения колонок и на гомогенность колонок по всему спектру

Что вышло

Данные:

data

Скрипт позволяет доставать форманты в более “sophisticated” формате, но я пока не додумался как это можно использовать.

Но он очень тяжелый, поэтому пруфов не будет.

Разделим данные на изолированные и контекстные произнесения:

iso = filter(data, type %in% c("1","2","3"))
ctxt = filter(data, type == "CP")

Длительность

Посмотрим, что у нас с длительностью:

ggplot2::ggplot(iso, aes(x = vowel, y = duration, color = position)) +
  geom_boxplot() + 
  theme_classic()

stpu = filter(iso, position != "ZU")
t.test(stpu$duration~stpu$position)

    Welch Two Sample t-test

data:  stpu$duration by stpu$position
t = -18.419, df = 286.34, p-value < 2.2e-16
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -0.07695864 -0.06209903
sample estimates:
mean in group PU mean in group ST 
      0.07016941       0.13969825 
stzu = filter(iso, position != "PU")
t.test(stzu$duration~stzu$position)

    Welch Two Sample t-test

data:  stzu$duration by stzu$position
t = 12.374, df = 285.45, p-value < 2.2e-16
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 0.03918263 0.05400535
sample estimates:
mean in group ST mean in group ZU 
      0.13969825       0.09310426 
puzu = filter(iso, position != "ST")
t.test(puzu$duration~puzu$position)

    Welch Two Sample t-test

data:  puzu$duration by puzu$position
t = -7.1763, df = 297.99, p-value = 5.717e-12
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -0.02922430 -0.01664538
sample estimates:
mean in group PU mean in group ZU 
      0.07016941       0.09310426 
ggplot2::ggplot(ctxt, aes(x = vowel, y = duration, color = position)) +
  geom_boxplot() + 
  theme_classic()

stpuc = filter(ctxt, position != "ZU")
t.test(stpuc$duration~stpuc$position)

    Welch Two Sample t-test

data:  stpuc$duration by stpuc$position
t = -5.1745, df = 87.398, p-value = 1.44e-06
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -0.04947632 -0.02201636
sample estimates:
mean in group PU mean in group ST 
      0.05405204       0.08979837 
stzuc = filter(ctxt, position != "PU")
t.test(stzuc$duration~stzuc$position)

    Welch Two Sample t-test

data:  stzuc$duration by stzuc$position
t = 3.7782, df = 83.362, p-value = 0.0002955
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 0.01207073 0.03890313
sample estimates:
mean in group ST mean in group ZU 
      0.08979837       0.06431144 
puzuc = filter(ctxt, position != "ST")
t.test(puzuc$duration~puzuc$position)

    Welch Two Sample t-test

data:  puzuc$duration by puzuc$position
t = -2.0041, df = 100.11, p-value = 0.04776
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -0.0204157157 -0.0001030983
sample estimates:
mean in group PU mean in group ZU 
      0.05405204       0.06431144 

Интенсивность

Пробуем провернуть тот же трюк:

Интенсивность определилась не для всего, так что:

intens_flt = filter(iso, intensity != "NA")
intens_flt_ctxt = filter(ctxt, intensity != "NA")
ggplot2::ggplot(intens_flt, aes(x = vowel, y = intensity, color = position)) +
  geom_boxplot() + 
  theme_classic()

stpu_intens = filter(intens_flt, position != "ZU")
t.test(stpu_intens$intensity~stpu_intens$position)

    Welch Two Sample t-test

data:  stpu_intens$intensity by stpu_intens$position
t = -4.7999, df = 304.43, p-value = 2.492e-06
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -2.566735 -1.074107
sample estimates:
mean in group PU mean in group ST 
        60.58536         62.40578 
stzu_intens = filter(intens_flt, position != "PU")
t.test(stzu_intens$intensity~stzu_intens$position)

    Welch Two Sample t-test

data:  stzu_intens$intensity by stzu_intens$position
t = 6.3512, df = 216.69, p-value = 1.238e-09
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 2.179721 4.141339
sample estimates:
mean in group ST mean in group ZU 
        62.53475         59.37422 
puzu_intens = filter(intens_flt, position != "ST")
t.test(puzu_intens$intensity~puzu_intens$position)

    Welch Two Sample t-test

data:  puzu_intens$intensity by puzu_intens$position
t = 5.0551, df = 272.79, p-value = 7.896e-07
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 1.417276 3.225305
sample estimates:
mean in group PU mean in group ZU 
        60.58536         58.26407 

С контекстными слишком мало данных, подозреваю, что там слишком короткие сегменты были.

Формантное пространство

Форманты от четверти и от половины длительности:

with(iso, plotVowels(sf1, sf2, vowel, pretty = TRUE, alpha.tokens = 0.2, col = "red", 
    col.axis = "red", xlim = c(3500, 500), ylim = c(1200, 200)))
par(new = TRUE)
with(iso, plotVowels(qf1, qf2, vowel, pretty = TRUE, alpha.tokens = 0.2, xlim = c(3500, 
    500), ylim = c(1200, 200)))

Для начала просто нарисуем:

with(iso, plotVowels(sf1, sf2, vowel, plot.tokens = TRUE, pch.tokens = vowel, 
    cex.tokens = 1.2, alpha.tokens = 0.4, plot.means = TRUE, pch.means = vowel, 
    cex.means = 4, var.col.by = vowel, family = "Brill", pretty = TRUE))

Нормализация:

fornorm = subset(iso, select = c(speaker, vowel, word, sf1, sf2, sf3))
fornorm[,"gl.F1"] <- NA
fornorm[,"gl.F2"] <- NA
fornorm[,"gl.F3"] <- NA
names(fornorm)[names(fornorm) == "vowel"] <- "vowel.frame"
names(fornorm)[names(fornorm) == "word"] <- "context"
fornorm <- as.data.frame(fornorm)
normed = vowels::norm.lobanov(fornorm)
normedn = vowels::norm.nearey(fornorm)
names(normed)[names(normed) == "F*1"] <- "sf1"
names(normed)[names(normed) == "F*2"] <- "sf2"
names(normed)[names(normed) == "Vowel"] <- "vowel"
with(normed, plotVowels(sf1, sf2, vowel, plot.tokens = TRUE, pch.tokens = vowel, 
    cex.tokens = 1.2, alpha.tokens = 0.4, plot.means = TRUE, pch.means = vowel, 
    cex.means = 4, var.col.by = vowel, family = "Brill", pretty = TRUE))

names(normedn)[names(normedn) == "F*1"] <- "sf1"
names(normedn)[names(normedn) == "F*2"] <- "sf2"
names(normedn)[names(normedn) == "Vowel"] <- "vowel"
with(normedn, plotVowels(sf1, sf2, vowel, plot.tokens = TRUE, pch.tokens = vowel, 
    cex.tokens = 1.2, alpha.tokens = 0.4, plot.means = TRUE, pch.means = vowel, 
    cex.means = 4, var.col.by = vowel, family = "Brill", pretty = TRUE))

with(iso, plotVowels(sf1, sf2, vowel, plot.tokens = TRUE, pch.tokens = vowel, 
    cex.tokens = 1.2, alpha.tokens = 1, plot.means = FALSE, pch.means = vowel, 
    cex.means = 4, var.col.by = position, pretty = TRUE, family = "Brill", legend.kwd = "bottomright"))

#pos = select(iso, position)
#normedn = mutate(normedn, position = iso$position)
with(iso, plotVowels(sf1, sf2, vowel, group = position, plot.tokens = FALSE, plot.means = TRUE, 
    pch.means = vowel, cex.means = 2, var.col.by = position, var.sty.by = position, ellipse.fill = TRUE, 
    poly.line = TRUE, poly.order = c("i", "e", "a", "u", "ɨ"), pretty = TRUE))

nnred = mutate(iso, nred = ifelse(position == "ST", "ST", "NST"))
with(nnred, plotVowels(sf1, sf2, vowel, group = nred, plot.tokens = FALSE, plot.means = TRUE, 
    pch.means = vowel, cex.means = 2, var.col.by = nred, var.sty.by = nred, ellipse.fill = TRUE, 
    poly.line = TRUE, poly.order = c("i", "e", "a", "u", "ɨ"), pretty = TRUE, legend.kwd = "bottomright"))

LS0tCnRpdGxlOiAiUnV0dWwgdm93ZWwgcmVkdWN0aW9uIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCiMjIyDQktCy0LXQtNC10L3QuNC1CtCf0L7QtNC60LvRjtGH0LDQtdC8INCx0LjQsdC70LjQvtGC0LXQutC4OgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkocGhvblIpCmxpYnJhcnkodm93ZWxzKQpsaWJyYXJ5KHJlYWRyKQpsaWJyYXJ5KGxpbmd0eXBvbG9neSkKYGBgCtCg0YPRgtGD0LvRjNGB0LrQuNC5INGP0LfRi9C6ICjQndCw0YXRgdC60L4t0LTQsNCz0LXRgdGC0LDQvdGB0LrQuNC1ID4g0JvQtdC30LPQuNC90YHQutC40LUgPiDQl9Cw0L/QsNC00L3Qvi3Qu9C10LfQs9C40L3RgdC60LjQtSkKCtCa0LjQvdC40L3RgdC60LjQuSDQtNC40LDQu9C10LrRgiDRgNGD0YLRg9C70YzRgdC60L7Qs9C+OgoKKNC/0YDQvtGB0YLQuNGC0LUsINGPINC90LUg0L3QsNGD0YfQuNC70YHRjyDRhtC10L3RgtGA0LjRgNC+0LLQsNGC0Ywg0LrQsNGA0YLRgyDQsiDQvdGD0LbQvdC+0Lwg0LzQtdGB0YLQtSkKYGBge3IgaW5jbHVkZT1GQUxTRX0KdmNvbCA9IHJlYWRfdHN2KCIvVXNlcnMvdHJpb2xvL0RvY3VtZW50cy9ydXR1bF9zdHJlc3Mvcl9zdHJlc3MvZm9yYXVkL3Zjb2xfdmlsbGFnZXMudHN2IikKdmNvbCA9IGZpbHRlcih2Y29sLCBsYXQgIT0iTkEiKQp2Y29sID0gZmlsdGVyKHZjb2wsIGVuZyAhPSJOQSIpCmBgYApgYGB7cn0KbWFwLmZlYXR1cmUobGFuZ3VhZ2VzID0gdmNvbCRsYW5ndWFnZSwKICAgICAgICAgICAgZmVhdHVyZXMgPSB2Y29sJGxhbmd1YWdlLAogICAgICAgICAgICBjb2xvciA9IHZjb2wkY29sb3IsCiAgICAgICAgICAgIGxhdGl0dWRlID0gdmNvbCRsYXQsCiAgICAgICAgICAgIGxvbmdpdHVkZSA9IHZjb2wkbG9uLAogICAgICAgICAgICBsYWJlbCA9IHZjb2wkZW5nCiAgICAgICAgICAgICkKYGBgCiMjIyDQp9C10LPQviDQvNGLINGF0L7RgtC40Lw/CtCj0LfQvdCw0YLRjCDRh9GC0L4t0YLQviDQv9GA0L4g0YDRg9GC0YPQu9GM0YHQutGD0Y4g0YDQtdC00YPQutGG0LjRjiDQs9C70LDRgdC90YvRhSEKCtCf0L7QtNGF0L7QtNGLINC6INGD0LTQsNGA0LXQvdC40Y4g0Lgg0YDQtdC00YPQutGG0LjQuDoKCiog0LTQvtC70LPQvtGC0LAg0LPQu9Cw0YHQvdC+0LPQviAoZHVyYXRpb24pCgoqINC10YHQu9C4INGA0LXQtNGD0LrRhtC40Y8g0LrQsNGH0LXRgdGC0LLQtdC90L3QsNGPLCDRgtC+INGA0LDQt9C90LjRhtCwINCyIEYxINC4IEYyCgoqINC40L3RgtC10L3RgdC40LLQvdC+0YHRgtGMIChpbnRlbnNpdHkpCgoqINGB0L/QtdC60YLRgNCw0LvRjNC90YvQuSDRgdC60L7RgSAoc3BlY3RyYWwgdGlsdCkKCtCd0LAg0YHQsNC80L7QvCDQtNC10LvQtSBj0LvQvtCy0LDQvNC4ICJzcGVjdHJhbCB0aWx0IiDQvdCw0LfRi9Cy0LDRjtGCINC/0YDQuNC80LXRgNC90L4g0YLRi9GB0Y/Rh9GDINCy0LXRidC10Lk6CgoqIEgxLUgyCgoqIEgxLUExCgoqIEgxLUEyCgoqIEgxLUEzCtC4INC00LDQttC1CiogW2staW5kZXhdKGh0dHBzOi8vd3d3LmludGVybmF0aW9uYWxwaG9uZXRpY2Fzc29jaWF0aW9uLm9yZy9pY3Bocy1wcm9jZWVkaW5ncy9JQ1BoUzIwMDMvcGFwZXJzL3AxNV8yMjAxLnBkZikKCtCd0LDQvCDQv9C+0YLQtdC90YbQuNCw0LvRjNC90L4g0L/QvtC00YXQvtC00LjRgiDQvNC10YDQsCBBMS1BMjoKIVtdKC9Vc2Vycy90cmlvbG8vRG9jdW1lbnRzL3J1dHVsX3N0cmVzcy9hMWEyLnBuZykKIVtdKC9Vc2Vycy90cmlvbG8vRG9jdW1lbnRzL3J1dHVsX3N0cmVzcy9hc3BlY3RydW0ucG5nKQoK0KHQv9C+0LnQu9C10YA6INC80L3QtSDQvdC1INGD0LTQsNC70L7RgdGMINC90L7RgNC80LDQu9GM0L3QviDQstGL0YLQsNGJ0LjRgtGMIEExLUEyLCDRgtCw0Log0YfRgtC+INCyINGN0YLQvtGCINGA0LDQtyDQvtCx0L7QudC00LXQvNGB0Y8g0LHQtdC3INC90LXQs9C+LgoK0JjRgtCw0LosINGDINC90LDRgSDQvtGB0YLQsNC70L7RgdGMIDMg0LzQtdGA0YsuCgojIyMg0JTQsNC90L3Ri9C1CiMjIyMg0J7QsdGJ0LjQtSDRiNGC0YPQutC4Ciog0JfQsNC/0LjRgdCw0L3RiyAzMCDQuNGO0L3RjyDQuCAxINC40Y7Qu9GPINGB0LXQs9C+INCz0L7QtNCwCgoqIDUg0LjQvdGE0L7RgNC80LDQvdGCX9C+0LogMTk3MS0xOTgyINCzLiDRgC4KCiog0KLQtdGF0L3QuNC60LA6CiAgKyDQlNC40LrRgtC+0YTQvtC9IFRBU0NBTSBEUi00MAogICsg0KXRjdC00YHQtdGCIFNodXJlIFdIMjBYTFIKICArINCf0LDRgNCw0LzQtdGC0YDRizog0JzQvtC90L4sIC53YXYgMjQtYml0LCDQp9CUIDQ0MTAwINCT0YYuCgoqINCd0LAg0LTQsNC90L3Ri9C5INC80L7QvNC10L3RgiDRgNCw0LfQvNC10YfQtdC90L4gNCDQt9Cw0L/QuNGB0LggKNC+0LTQvdCwINC+0LrQsNC30LDQu9Cw0YHRjCAq0YEg0L/RgNC+0LHQu9C10LzQsNC80LgqLCDQv9C+0Y3RgtC+0LzRgyDQsdGL0LvQviDRgNC10YjQtdC90L4g0LXRkSDQvtGC0LvQvtC20LjRgtGMINC00L4g0LLRi9GP0YHQvdC10L3QuNGPKQoKKiDQodC60YDQuNC/0YIg0LTQu9GPINCy0YvRgtCw0YHQutC40LLQsNC90LjRjyDQtNCw0L3QvdGL0YUg0LjQtyDQtNCw0L3QvdGL0YUg0LLQt9GP0YIg0L7RgtGB0Y7QtNCwOiBbW1dhc2hpbmd0b24gMjAxOF1dKGh0dHBzOi8vZ2l0aHViLmNvbS9qb25vcnRod2FzaC9wcmFhdC1zY3JpcHRzL2Jsb2IvbWFzdGVyL2NvbGxlY3RfZHVyYXRpb25zX2YwX2Zvcm1hbnRzX2ludGVuc2l0eV9hbmRfZmllbGRzX3Rocm91Z2hvdXRfdm93ZWxzLnByYWF0KQoK0K8g0L3QtdC80L3QvtCz0L4g0LXQs9C+IFvQvNC+0LTQuNGE0LjRhtC40YDQvtCy0LDQu10oaHR0cHM6Ly9naXRodWIuY29tL3RyaW9sby9ydXR1bF92b3dlbF9yZWR1Y3Rpb24vYmxvYi9tYXN0ZXIvbW9kaWZpZWRfc2NyaXB0LnR4dCkKCiMjIyMg0KHRgtC40LzRg9C70YsKCtCj0LTQsNGA0LXQvdC40LUg0LLRi9C00LXQu9C10L3QviDQsNC60YPRgtC+0LwsINC20LXQu9GC0L7QuSDQv9C+0LTRgdCy0LXRgtC60L7QuSAtLSAg0LjQvdGC0LXRgNC10YHRg9GO0YnQuNC5INC90LDRgSDQs9C70LDRgdC90YvQuS4KCiFbXSgvVXNlcnMvdHJpb2xvL0RvY3VtZW50cy9ydXR1bF9zdHJlc3Mvc3RpbXVsaS5wbmcpCtCf0YDQvtCx0LvQtdC80Ysg0YHQviDRgdGC0LjQvNGD0LvQsNC80Lg6CgoqICEg0J/QvtCy0YHRjtC00YMg0L/Qu9Cw0LLQvdGL0LUgKNCyINC/0YDQsNCy0L7QvCDQutC+0L3RgtC10LrRgdGC0LUpCgoqINGB0LvQvtC20L3QsNGPINC80L7RgNGE0L7Qu9C+0LPQuNGPICjQv9GA0LjRh9Cw0YHRgtC40Y8sINGA0LXRhNCw0LrRgtC40LIpINCy0LLQvtC00LjQu9CwINCyINC30LDQvNC10YjQsNGC0LXQu9GM0YHRgtCy0L4sINC70Y7QtNC4INGB0YLQsNGA0LDQu9C40YHRjCDQuNC30LHQsNCy0LjRgtGM0YHRjyDQvtGCINC90LXQtSwg0L3QtdGB0LzQvtGC0YDRjyDQvdCwINC80L7QuCDRg9Cz0L7QstC+0YDRiwoKKiDQp9GD0LTQvtCy0LjRidC90LDRjyDQstCw0YDQuNCw0YLQuNCy0L3QvtGB0YLRjCDQutC+0YHQstC10L3QvdGL0YUg0YTQvtGA0LwgKNC90L4g0YLRg9GCINGD0LYg0L3QuNGH0LXQs9C+INC90LUg0L/QvtC00LXQu9Cw0YLRjCkKCiog0JIg0L7QtNC90L7QvCDRgdC70YPRh9Cw0LUg0L/RgNC40YjQu9C+0YHRjCDQstC30Y/RgtGMINC60LvQuNGC0LjQt9C+0LLQsNC90L3Rg9GOINGB0LLRj9C30LrRgywg0L/QvtGC0L7QvNGDINGH0YLQviDQtNGA0YPQs9C+0Lkg0LfQsNGD0LTQsNGA0L3Ri9C5INC60L7QvdGC0LXQutGB0YIg0LTQu9GPINC60LgqINC80L3QtSDQvtGC0LrQsNC30LDQu9C40YHRjCDQv9GA0LjQtNGD0LzRi9Cy0LDRgtGMCgoqINCY0L3QtdC5IC0tINC/0LvQvtGF0LDRjyDQuNC00LXRjyDQu9C10L3QuNCy0L7Qs9C+INGH0LXQu9C+0LLQtdC60LAuCgoqINCg0LDQt9C90L7QtSDQutC+0LvQuNGH0LXRgdGC0LLQviDRgNGP0LTQvtCyINGB0YLQuNC80YPQu9C+0LIg0L3QsCDQs9GA0YPQv9C/0YMgLS0g0YHRgtC+0LvRjNC60L4g0L7RgdGC0LDQu9C+0YHRjCDQv9C+0YHQu9C1INCy0YvQsdGA0LDQutC+0LLQutC4CgojIyMjINCg0LDQt9C80LXRgtC60LAKCtCf0YDQviDRgdC10LPQvNC10L3RgtCw0YbQuNGOINC10YHRgtGMINGD0LzQvdCw0Y8g0LrQvdC40LbQutCwOiBbTWFjaGHEjSwgU2thcm5pdHpsIDIwMDldLgoKKiDQn9C70L7RhdCw0Y8g0L3QvtCy0L7RgdGC0Ywg4oSWMSAtINC+0L3QsCDQtdGB0YLRjCDQsiDQuNC90YLQtdGA0L3QtdGC0LUg0YLQvtC70YzQutC+INC60YPRgdC60LDQvNC4LgoKKiDQn9C70L7RhdCw0Y8g0L3QvtCy0L7RgdGC0Ywg4oSWMiAtINGC0LDQvCDQsiDQvtGB0L3QvtCy0L3QvtC8INGC0L7Qu9GM0LrQviDQv9GA0L4g0LjQvdGC0LXRgNCy0L7QutCw0LvRjNC90YvQtSDRiNGC0YPQutC4LCDRhdC+0YLRjyDQvdC10YfRgtC+INC+0LHRidC10YLQtdC+0YDQtdGC0LjRh9C10YHQutC+0LUg0YLQsNC8INGC0L7QttC1INC10YHRgtGMLgoK0JTQu9GPINC80LXQvdGPINCx0YvQu9C+INCy0LDQttC90YvQvCwg0YfRgtC+INC+0L3QuCDQv9GA0LXQtNC70LDQs9Cw0Y7RgiDRgdGC0LDQstC40YLRjCDQs9GA0LDQvdC40YbRiyDQvNC10LbQtNGDINGE0L7RgNC80LDQvdGC0L3Ri9C80Lgg0LrQvtC70L7QvdC60LDQvNC4IChmb3JtYW50IGNvbHVtbnMpICjRgdGA0LDQt9GDINC/0LXRgNC10LQg0LjQu9C4INC/0L7RgdC70LUpCgrQmNGC0LDQujoKCiog0KDQsNC30LzQtdGH0LDQu9GB0Y8g0LrRg9GB0L7QuiDQs9C70LDRgdC90L7Qs9C+INC/0L4g0YHQu9C10LTRg9GO0YnQuNC8INC/0YDQsNCy0LjQu9Cw0Lw6CiAgKyDQndCw0YfQsNC70YzQvdCw0Y8g0LPRgNCw0L3QuNGG0LAgKHN0YXJ0cG9pbnQpINC/0L7QvNC10YfQsNC70LDRgdGMINGB0YDQsNC30YMg0L/QvtGB0LvQtSDQtNCy0YPRhSDQvtGC0YfQtdGC0LvQuNCy0L4g0LfQsNC80LXRgtC90YvRhSDRhNC+0YDQvNCw0L3RgtC90YvRhSDQutC+0LvQvtC90L7QugogICsg0JrQvtC90LXRh9C90LDRjyDQs9GA0LDQvdC40YbQsCAoZW5kcG9pbnQpINC/0L7QvNC10YfQsNC70LDRgdGMINGB0YDQsNC30YMg0L/QtdGA0LXQtCDQv9C+0YHQu9C10LTQvdC10Lkg0L7RgtGH0LXRgtC70LjQstC+INC30LDQvNC10YLQvdC+0Lkg0YTQvtGA0LzQsNC90YLQvdC+0Lkg0LrQvtC70L7QvdC60L7QuQohW10oL1VzZXJzL3RyaW9sby9Eb2N1bWVudHMvcnV0dWxfc3RyZXNzL3Jhem0ucG5nKQoK0KfRgtC+INC60L7QtNC40YDQvtCy0LDQu9C+0YHRjD8KCjEuINCT0LvQsNGB0L3Ri9C5CgoyLiDQn9C+0LfQuNGG0LjRjyDQvtGC0L3QvtGB0LjRgtC10LvRjNC90L4g0YPQtNCw0YDQtdC90LjRjyAo0YPQtNCw0YDQvdGL0LksINC/0YDQtdC00YPQtNCw0YDQvdGL0LksINC30LDRg9C00LDRgNC90YvQuSkKCjMuINCi0LjQvyDQv9GA0L7QuNC30L3QtdGB0LXQvdC40Y8gKDEsIDIsIDMsINC60L7QvdGC0LXQutGB0YLQvdC+0LUg0L/RgNC+0LjQt9C90LXRgdC10L3QuNC1KQoKNC4g0KHQu9C+0LLQvgoKNS4g0KHQv9C40LrQtdGACgoqINCf0L7QvdGP0YLQvdC+0LUg0LTQtdC70L4sINC90LAg0Y3RgtC+0Lwg0LzQtdGB0YLQtSDQstC+0LfQvdC40LrQu9C4INC/0YDQvtCx0LvQtdC80Ysg0YEg0L3QsNGI0LjQvNC4INC70Y7QsdC40LzRi9C80Lgg0L/Qu9Cw0LLQvdGL0LzQuC4KCiog0JjRhSDRjyDRgNCw0LfQvNC10YfQsNC7INGB0LrQvtGA0LXQtSDQuNC80L/RgNC10YHRgdC40L7QvdC40YHRgtC40YfQtdGB0LrQuCwg0L7RgNC40LXQvdGC0LjRgNGD0Y/RgdGMINC90LAg0YHRgtC10L/QtdC90Ywg0LfQsNGH0LXRgNC90LXQvdC40Y8g0LrQvtC70L7QvdC+0Log0Lgg0L3QsCDQs9C+0LzQvtCz0LXQvdC90L7RgdGC0Ywg0LrQvtC70L7QvdC+0Log0L/QviDQstGB0LXQvNGDINGB0L/QtdC60YLRgNGDCiFbXSgvVXNlcnMvdHJpb2xvL0RvY3VtZW50cy9ydXR1bF9zdHJlc3MvZmxpcXVpZHMucG5nKQoKCiMjIyDQp9GC0L4g0LLRi9GI0LvQvgoK0JTQsNC90L3Ri9C1OgpgYGB7ciBpbmNsdWRlPUZBTFNFfQpkYXRhIDwtIHJlYWRyOjpyZWFkX3RzdigiL1VzZXJzL3RyaW9sby9Eb2N1bWVudHMvcnV0dWxfc3RyZXNzL3Rlc3RfZGF0YS9kYXRhLnRzdiIpCmBgYAoKYGBge3J9CmRhdGEKYGBgCtCh0LrRgNC40L/RgiDQv9C+0LfQstC+0LvRj9C10YIg0LTQvtGB0YLQsNCy0LDRgtGMINGE0L7RgNC80LDQvdGC0Ysg0LIg0LHQvtC70LXQtSAic29waGlzdGljYXRlZCIg0YTQvtGA0LzQsNGC0LUsINC90L4g0Y8g0L/QvtC60LAg0L3QtSDQtNC+0LTRg9C80LDQu9GB0Y8g0LrQsNC6INGN0YLQviDQvNC+0LbQvdC+INC40YHQv9C+0LvRjNC30L7QstCw0YLRjC4KCtCd0L4g0L7QvSDQvtGH0LXQvdGMINGC0Y/QttC10LvRi9C5LCDQv9C+0Y3RgtC+0LzRgyDQv9GA0YPRhNC+0LIg0L3QtSDQsdGD0LTQtdGCLgoK0KDQsNC30LTQtdC70LjQvCDQtNCw0L3QvdGL0LUg0L3QsCDQuNC30L7Qu9C40YDQvtCy0LDQvdC90YvQtSDQuCDQutC+0L3RgtC10LrRgdGC0L3Ri9C1INC/0YDQvtC40LfQvdC10YHQtdC90LjRjzoKCmBgYHtyfQppc28gPSBmaWx0ZXIoZGF0YSwgdHlwZSAlaW4lIGMoIjEiLCIyIiwiMyIpKQpjdHh0ID0gZmlsdGVyKGRhdGEsIHR5cGUgPT0gIkNQIikKYGBgCgoKIyMjIyDQlNC70LjRgtC10LvRjNC90L7RgdGC0YwKCtCf0L7RgdC80L7RgtGA0LjQvCwg0YfRgtC+INGDINC90LDRgSDRgSDQtNC70LjRgtC10LvRjNC90L7RgdGC0YzRjjoKYGBge3J9CmdncGxvdDI6OmdncGxvdChpc28sIGFlcyh4ID0gdm93ZWwsIHkgPSBkdXJhdGlvbiwgY29sb3IgPSBwb3NpdGlvbikpICsKICBnZW9tX2JveHBsb3QoKSArIAogIHRoZW1lX2NsYXNzaWMoKQpgYGAKCmBgYHtyfQpzdHB1ID0gZmlsdGVyKGlzbywgcG9zaXRpb24gIT0gIlpVIikKdC50ZXN0KHN0cHUkZHVyYXRpb25+c3RwdSRwb3NpdGlvbikKYGBgCgpgYGB7cn0Kc3R6dSA9IGZpbHRlcihpc28sIHBvc2l0aW9uICE9ICJQVSIpCnQudGVzdChzdHp1JGR1cmF0aW9ufnN0enUkcG9zaXRpb24pCmBgYAoKYGBge3J9CnB1enUgPSBmaWx0ZXIoaXNvLCBwb3NpdGlvbiAhPSAiU1QiKQp0LnRlc3QocHV6dSRkdXJhdGlvbn5wdXp1JHBvc2l0aW9uKQpgYGAKCgpgYGB7cn0KZ2dwbG90Mjo6Z2dwbG90KGN0eHQsIGFlcyh4ID0gdm93ZWwsIHkgPSBkdXJhdGlvbiwgY29sb3IgPSBwb3NpdGlvbikpICsKICBnZW9tX2JveHBsb3QoKSArIAogIHRoZW1lX2NsYXNzaWMoKQpgYGAKCmBgYHtyfQpzdHB1YyA9IGZpbHRlcihjdHh0LCBwb3NpdGlvbiAhPSAiWlUiKQp0LnRlc3Qoc3RwdWMkZHVyYXRpb25+c3RwdWMkcG9zaXRpb24pCmBgYAoKYGBge3J9CnN0enVjID0gZmlsdGVyKGN0eHQsIHBvc2l0aW9uICE9ICJQVSIpCnQudGVzdChzdHp1YyRkdXJhdGlvbn5zdHp1YyRwb3NpdGlvbikKYGBgCmBgYHtyfQpwdXp1YyA9IGZpbHRlcihjdHh0LCBwb3NpdGlvbiAhPSAiU1QiKQp0LnRlc3QocHV6dWMkZHVyYXRpb25+cHV6dWMkcG9zaXRpb24pCmBgYAoKCiMjIyMg0JjQvdGC0LXQvdGB0LjQstC90L7RgdGC0YwKCtCf0YDQvtCx0YPQtdC8INC/0YDQvtCy0LXRgNC90YPRgtGMINGC0L7RgiDQttC1INGC0YDRjtC6OgoK0JjQvdGC0LXQvdGB0LjQstC90L7RgdGC0Ywg0L7Qv9GA0LXQtNC10LvQuNC70LDRgdGMINC90LUg0LTQu9GPINCy0YHQtdCz0L4sINGC0LDQuiDRh9GC0L46CgpgYGB7cn0KaW50ZW5zX2ZsdCA9IGZpbHRlcihpc28sIGludGVuc2l0eSAhPSAiTkEiKQppbnRlbnNfZmx0X2N0eHQgPSBmaWx0ZXIoY3R4dCwgaW50ZW5zaXR5ICE9ICJOQSIpCmBgYAoKCmBgYHtyfQpnZ3Bsb3QyOjpnZ3Bsb3QoaW50ZW5zX2ZsdCwgYWVzKHggPSB2b3dlbCwgeSA9IGludGVuc2l0eSwgY29sb3IgPSBwb3NpdGlvbikpICsKICBnZW9tX2JveHBsb3QoKSArIAogIHRoZW1lX2NsYXNzaWMoKQpgYGAKCmBgYHtyfQpzdHB1X2ludGVucyA9IGZpbHRlcihpbnRlbnNfZmx0LCBwb3NpdGlvbiAhPSAiWlUiKQp0LnRlc3Qoc3RwdV9pbnRlbnMkaW50ZW5zaXR5fnN0cHVfaW50ZW5zJHBvc2l0aW9uKQpgYGAKCmBgYHtyfQpzdHp1X2ludGVucyA9IGZpbHRlcihpbnRlbnNfZmx0LCBwb3NpdGlvbiAhPSAiUFUiKQp0LnRlc3Qoc3R6dV9pbnRlbnMkaW50ZW5zaXR5fnN0enVfaW50ZW5zJHBvc2l0aW9uKQpgYGAKYGBge3J9CnB1enVfaW50ZW5zID0gZmlsdGVyKGludGVuc19mbHQsIHBvc2l0aW9uICE9ICJTVCIpCnQudGVzdChwdXp1X2ludGVucyRpbnRlbnNpdHl+cHV6dV9pbnRlbnMkcG9zaXRpb24pCmBgYAoK0KEg0LrQvtC90YLQtdC60YHRgtC90YvQvNC4INGB0LvQuNGI0LrQvtC8INC80LDQu9C+INC00LDQvdC90YvRhSwg0L/QvtC00L7Qt9GA0LXQstCw0Y4sINGH0YLQviDRgtCw0Lwg0YHQu9C40YjQutC+0Lwg0LrQvtGA0L7RgtC60LjQtSDRgdC10LPQvNC10L3RgtGLINCx0YvQu9C4LgoKIyMjIyDQpNC+0YDQvNCw0L3RgtC90L7QtSDQv9GA0L7RgdGC0YDQsNC90YHRgtCy0L4KCtCk0L7RgNC80LDQvdGC0Ysg0L7RgiDRh9C10YLQstC10YDRgtC4INC4INC+0YIg0L/QvtC70L7QstC40L3RiyDQtNC70LjRgtC10LvRjNC90L7RgdGC0Lg6CmBgYHtyfQp3aXRoKGlzbywgcGxvdFZvd2VscyhzZjEsIHNmMiwgdm93ZWwsIHByZXR0eSA9IFRSVUUsIGFscGhhLnRva2VucyA9IDAuMiwgY29sID0gInJlZCIsIAogICAgY29sLmF4aXMgPSAicmVkIiwgeGxpbSA9IGMoMzUwMCwgNTAwKSwgeWxpbSA9IGMoMTIwMCwgMjAwKSkpCnBhcihuZXcgPSBUUlVFKQp3aXRoKGlzbywgcGxvdFZvd2VscyhxZjEsIHFmMiwgdm93ZWwsIHByZXR0eSA9IFRSVUUsIGFscGhhLnRva2VucyA9IDAuMiwgeGxpbSA9IGMoMzUwMCwgCiAgICA1MDApLCB5bGltID0gYygxMjAwLCAyMDApKSkKYGBgCgoKCtCU0LvRjyDQvdCw0YfQsNC70LAg0L/RgNC+0YHRgtC+INC90LDRgNC40YHRg9C10Lw6CgpgYGB7cn0Kd2l0aChpc28sIHBsb3RWb3dlbHMoc2YxLCBzZjIsIHZvd2VsLCBwbG90LnRva2VucyA9IFRSVUUsIHBjaC50b2tlbnMgPSB2b3dlbCwgCiAgICBjZXgudG9rZW5zID0gMS4yLCBhbHBoYS50b2tlbnMgPSAwLjQsIHBsb3QubWVhbnMgPSBUUlVFLCBwY2gubWVhbnMgPSB2b3dlbCwgCiAgICBjZXgubWVhbnMgPSA0LCB2YXIuY29sLmJ5ID0gdm93ZWwsIGZhbWlseSA9ICJCcmlsbCIsIHByZXR0eSA9IFRSVUUpKQpgYGAK0J3QvtGA0LzQsNC70LjQt9Cw0YbQuNGPOgpgYGB7cn0KZm9ybm9ybSA9IHN1YnNldChpc28sIHNlbGVjdCA9IGMoc3BlYWtlciwgdm93ZWwsIHdvcmQsIHNmMSwgc2YyLCBzZjMpKQpmb3Jub3JtWywiZ2wuRjEiXSA8LSBOQQpmb3Jub3JtWywiZ2wuRjIiXSA8LSBOQQpmb3Jub3JtWywiZ2wuRjMiXSA8LSBOQQpuYW1lcyhmb3Jub3JtKVtuYW1lcyhmb3Jub3JtKSA9PSAidm93ZWwiXSA8LSAidm93ZWwuZnJhbWUiCm5hbWVzKGZvcm5vcm0pW25hbWVzKGZvcm5vcm0pID09ICJ3b3JkIl0gPC0gImNvbnRleHQiCmZvcm5vcm0gPC0gYXMuZGF0YS5mcmFtZShmb3Jub3JtKQpub3JtZWQgPSB2b3dlbHM6Om5vcm0ubG9iYW5vdihmb3Jub3JtKQpub3JtZWRuID0gdm93ZWxzOjpub3JtLm5lYXJleShmb3Jub3JtKQpgYGAKCgpgYGB7cn0KbmFtZXMobm9ybWVkKVtuYW1lcyhub3JtZWQpID09ICJGKjEiXSA8LSAic2YxIgpuYW1lcyhub3JtZWQpW25hbWVzKG5vcm1lZCkgPT0gIkYqMiJdIDwtICJzZjIiCm5hbWVzKG5vcm1lZClbbmFtZXMobm9ybWVkKSA9PSAiVm93ZWwiXSA8LSAidm93ZWwiCndpdGgobm9ybWVkLCBwbG90Vm93ZWxzKHNmMSwgc2YyLCB2b3dlbCwgcGxvdC50b2tlbnMgPSBUUlVFLCBwY2gudG9rZW5zID0gdm93ZWwsIAogICAgY2V4LnRva2VucyA9IDEuMiwgYWxwaGEudG9rZW5zID0gMC40LCBwbG90Lm1lYW5zID0gVFJVRSwgcGNoLm1lYW5zID0gdm93ZWwsIAogICAgY2V4Lm1lYW5zID0gNCwgdmFyLmNvbC5ieSA9IHZvd2VsLCBmYW1pbHkgPSAiQnJpbGwiLCBwcmV0dHkgPSBUUlVFKSkKYGBgCmBgYHtyfQpuYW1lcyhub3JtZWRuKVtuYW1lcyhub3JtZWRuKSA9PSAiRioxIl0gPC0gInNmMSIKbmFtZXMobm9ybWVkbilbbmFtZXMobm9ybWVkbikgPT0gIkYqMiJdIDwtICJzZjIiCm5hbWVzKG5vcm1lZG4pW25hbWVzKG5vcm1lZG4pID09ICJWb3dlbCJdIDwtICJ2b3dlbCIKd2l0aChub3JtZWRuLCBwbG90Vm93ZWxzKHNmMSwgc2YyLCB2b3dlbCwgcGxvdC50b2tlbnMgPSBUUlVFLCBwY2gudG9rZW5zID0gdm93ZWwsIAogICAgY2V4LnRva2VucyA9IDEuMiwgYWxwaGEudG9rZW5zID0gMC40LCBwbG90Lm1lYW5zID0gVFJVRSwgcGNoLm1lYW5zID0gdm93ZWwsIAogICAgY2V4Lm1lYW5zID0gNCwgdmFyLmNvbC5ieSA9IHZvd2VsLCBmYW1pbHkgPSAiQnJpbGwiLCBwcmV0dHkgPSBUUlVFKSkKYGBgCmBgYHtyfQp3aXRoKGlzbywgcGxvdFZvd2VscyhzZjEsIHNmMiwgdm93ZWwsIHBsb3QudG9rZW5zID0gVFJVRSwgcGNoLnRva2VucyA9IHZvd2VsLCAKICAgIGNleC50b2tlbnMgPSAxLjIsIGFscGhhLnRva2VucyA9IDEsIHBsb3QubWVhbnMgPSBGQUxTRSwgcGNoLm1lYW5zID0gdm93ZWwsIAogICAgY2V4Lm1lYW5zID0gNCwgdmFyLmNvbC5ieSA9IHBvc2l0aW9uLCBwcmV0dHkgPSBUUlVFLCBmYW1pbHkgPSAiQnJpbGwiLCBsZWdlbmQua3dkID0gImJvdHRvbXJpZ2h0IikpCmBgYAoKYGBge3J9CiNwb3MgPSBzZWxlY3QoaXNvLCBwb3NpdGlvbikKI25vcm1lZG4gPSBtdXRhdGUobm9ybWVkbiwgcG9zaXRpb24gPSBpc28kcG9zaXRpb24pCndpdGgoaXNvLCBwbG90Vm93ZWxzKHNmMSwgc2YyLCB2b3dlbCwgZ3JvdXAgPSBwb3NpdGlvbiwgcGxvdC50b2tlbnMgPSBGQUxTRSwgcGxvdC5tZWFucyA9IFRSVUUsIAogICAgcGNoLm1lYW5zID0gdm93ZWwsIGNleC5tZWFucyA9IDIsIHZhci5jb2wuYnkgPSBwb3NpdGlvbiwgdmFyLnN0eS5ieSA9IHBvc2l0aW9uLCBlbGxpcHNlLmZpbGwgPSBUUlVFLCAKICAgIHBvbHkubGluZSA9IFRSVUUsIHBvbHkub3JkZXIgPSBjKCJpIiwgImUiLCAiYSIsICJ1IiwgIsmoIiksIHByZXR0eSA9IFRSVUUpKQpgYGAKYGBge3J9Cm5ucmVkID0gbXV0YXRlKGlzbywgbnJlZCA9IGlmZWxzZShwb3NpdGlvbiA9PSAiU1QiLCAiU1QiLCAiTlNUIikpCmBgYApgYGB7cn0Kd2l0aChubnJlZCwgcGxvdFZvd2VscyhzZjEsIHNmMiwgdm93ZWwsIGdyb3VwID0gbnJlZCwgcGxvdC50b2tlbnMgPSBGQUxTRSwgcGxvdC5tZWFucyA9IFRSVUUsIAogICAgcGNoLm1lYW5zID0gdm93ZWwsIGNleC5tZWFucyA9IDIsIHZhci5jb2wuYnkgPSBucmVkLCB2YXIuc3R5LmJ5ID0gbnJlZCwgZWxsaXBzZS5maWxsID0gVFJVRSwgCiAgICBwb2x5LmxpbmUgPSBUUlVFLCBwb2x5Lm9yZGVyID0gYygiaSIsICJlIiwgImEiLCAidSIsICLJqCIpLCBwcmV0dHkgPSBUUlVFLCBsZWdlbmQua3dkID0gImJvdHRvbXJpZ2h0IikpCmBgYAoKCg==