Pakate importe
require(dplyr)
require(broom)
require(ggplot2)
require(ggdendro)
require(cluster)
Einlesen der Datei
#library(readxl)
#Clusteranalyse <- read_excel("python_webseite/Clusteranalyse/Clusteranalyse.xlsx")
#View(Clusteranalyse)
Clusteranalyse$KlassenBudget <- as.numeric(Clusteranalyse$KlassenBudget)
Clusteranalyse$digitaler_Ausstattungsscore <- as.numeric(Clusteranalyse$digitaler_Ausstattungsscore)
rownames(Clusteranalyse) <- make.unique(as.character(Clusteranalyse$Schule))
1. Voraussetzungen der Clusteranalyse
✓ Damit verlässliche Aussagen über die Grundgesamtheit möglich sind,
sollte die Stichprobe ausreichend groß sein – auch wenn in der Praxis
häufig kleinere Stichproben verwendet werden.
✓ Fehlende Werte müssen vor der Durchführung einer Clusteranalyse
bereinigt werden. Dazu stehen verschiedene Methoden zur Verfügung, etwa
das Entfernen unvollständiger Fälle, das Ersetzen fehlender Werte durch
Mittelwerte oder die Imputation.
✓ Alle Variablen, die in die Clusteranalyse einfließen, sollten
möglichst dasselbe Skalenniveau aufweisen. Falls dies nicht gegeben ist,
kann eine Angleichung auf ein gemeinsames (meist niedrigeres)
Skalenniveau erforderlich sein.
✓ Unterscheiden sich die Variablen stark in ihrem Wertebereich, ist
eine Standardisierung – beispielsweise durch z-Transformation –
sinnvoll, um Verzerrungen in der Clusterbildung zu vermeiden.
2. Grundlegende Konzepte
Die Clusteranalyse ist ein Verfahren der multivariaten Statistik, das
dazu dient, Objekte (zum Beispiel Personen, Unternehmen oder – wie in
deinem Fall – Schulen) anhand ihrer Merkmale in Gruppen (sogenannte
Cluster) einzuteilen. Ziel ist es, dass die Objekte innerhalb eines
Clusters möglichst ähnlich sind, während sich die Cluster untereinander
möglichst stark unterscheiden. Dabei weiß man zu Beginn meist nicht, wie
viele Cluster es geben wird – dies ergibt sich aus den Daten selbst. Die
Clusteranalyse kommt häufig in den Sozialwissenschaften, im Marketing
oder der Biologie zum Einsatz, um verborgene Muster und Strukturen in
großen Datensätzen zu entdecken. Typische Schritte bei einer
Clusteranalyse sind die Auswahl relevanter Variablen, das Bereinigen der
Daten (z.B. Umgang mit fehlenden Werten), eventuell eine
Standardisierung der Merkmale sowie die Anwendung eines Algorithmus (wie
K-Means oder hierarchisches Clustering). Die Ergebnisse der Analyse
helfen dabei, Gruppen mit ähnlichen Eigenschaften zu identifizieren und
diese anschließend zu interpretieren und weiterzuverwenden.
3. Deskriptive Statistiken
describe(Clusteranalyse)
library(dplyr)
Clusteranalyse %>%
summarise(
Mittelwert_KlassenBudget = mean(KlassenBudget),
Mittelwert_DigitalScore = mean(digitaler_Ausstattungsscore),
n = n()
)
4. Prüfung der Voraussetzung
✓ Damit verlässliche Aussagen über die Grundgesamtheit möglich sind,
sollte die Stichprobe ausreichend groß sein – auch wenn in der Praxis
häufig kleinere Stichproben verwendet werden.
N ist mit größer 30
✓ Alle Variablen, die in die Clusteranalyse einfließen, sollten
möglichst dasselbe Skalenniveau aufweisen. Falls dies nicht gegeben ist,
kann eine Angleichung auf ein gemeinsames (meist niedrigeres)
Skalenniveau erforderlich sein.
Beide Spalten sind metrisch.
✓ Fehlende Werte müssen vor der Durchführung einer Clusteranalyse
bereinigt werden. Dazu stehen verschiedene Methoden zur Verfügung, etwa
das Entfernen unvollständiger Fälle, das Ersetzen fehlender Werte durch
Mittelwerte oder die Imputation.
missing_value <- sum(as.numeric(is.na(Clusteranalyse)))
sprintf("Fehlende Werte: %.2f", missing_value)
[1] "Fehlende Werte: 0.00"
✓ Unterscheiden sich die Variablen stark in ihrem Wertebereich, ist
eine Standardisierung – beispielsweise durch z-Transformation –
sinnvoll, um Verzerrungen in der Clusterbildung zu vermeiden.
daten <- Clusteranalyse[, 2:3]
# # 3. Labels (Schulnamen)
labels <- Clusteranalyse$Schule
rownames(daten) <- labels
Warnung: Setting row names on a tibble is deprecated.
# Standardisierung (z-Transformation)
daten_scaled <- scale(daten)
Da sich die Variablen in ihrem Wertebereich deutlich unterscheiden,
wurden die Daten vor der Clusteranalyse mittels z-Transformation
standardisiert. So wird sichergestellt, dass beide Merkmale gleich
gewichtet in die Distanzberechnung und Clusterbildung eingehen und keine
Verzerrungen entstehen.
4. Prozess der Clusterbildung
Bevor mit der eigentlichen Clusterbildung begonnen werden kann, ist
die Erstellung einer Distanzmatrix ein zentraler erster Schritt. Sie
liefert die Grundlage, um objektiv zu bestimmen, wie ähnlich oder
verschieden die einzelnen Fälle im Datensatz zueinander sind und bildet
damit die Basis für alle weiteren Schritte der Clusteranalyse.
# Distanzmatrix (euklidisch)
distanz <- dist(daten_scaled, method = "euclidean")
# Quadrierte Distanzen (wie im Beispiel)
naeherungsmatrix <- as.matrix(distanz)^2
# Runden für bessere Lesbarkeit
naeherungsmatrix <- round(naeherungsmatrix, 3)
# Spalten- und Zeilennamen setzen (Überschriften)
colnames(naeherungsmatrix) <- labels
rownames(naeherungsmatrix) <- labels
# Matrix anzeigen
print(naeherungsmatrix)
AEG AFS EvTG EKG EAO FSR GSS GG HHG HR MMS MLS PS SSG TSG
AEG 0.000 0.391 0.219 2.471 6.715 1.554 10.357 7.313 3.339 8.061 7.733 7.385 7.756 6.690 25.739
AFS 0.391 0.000 0.539 0.910 3.988 0.407 6.813 4.353 1.477 4.923 4.673 4.422 4.736 4.021 20.232
EvTG 0.219 0.539 0.000 2.684 7.305 1.443 10.844 7.566 3.072 8.246 7.319 6.897 7.141 5.855 23.688
EKG 2.471 0.910 2.684 0.000 1.140 0.261 2.754 1.283 0.297 1.606 1.717 1.641 1.921 1.830 14.176
EAO 6.715 3.988 7.305 1.140 0.000 2.423 0.427 0.150 1.495 0.265 1.170 1.330 1.664 2.377 11.561
FSR 1.554 0.407 1.443 0.261 2.423 0.000 4.447 2.426 0.338 2.800 2.360 2.164 2.372 1.883 14.930
GSS 10.357 6.813 10.844 2.754 0.427 4.447 0.000 0.315 2.766 0.240 1.189 1.444 1.711 2.774 8.935
GG 7.313 4.353 7.566 1.283 0.150 2.426 0.315 0.000 1.216 0.024 0.508 0.636 0.864 1.496 9.135
HHG 3.339 1.477 3.072 0.297 1.495 0.338 2.766 1.216 0.000 1.416 0.918 0.793 0.924 0.701 10.944
HR 8.061 4.923 8.246 1.606 0.265 2.800 0.240 0.024 1.416 0.000 0.430 0.570 0.770 1.452 8.327
MMS 7.733 4.673 7.319 1.717 1.170 2.360 1.189 0.508 0.918 0.430 0.000 0.014 0.049 0.340 6.154
MLS 7.385 4.422 6.897 1.641 1.330 2.164 1.444 0.636 0.793 0.570 0.014 0.000 0.019 0.218 6.196
PS 7.756 4.736 7.141 1.921 1.664 2.372 1.711 0.864 0.924 0.770 0.049 0.019 0.000 0.152 5.660
SSG 6.690 4.021 5.855 1.830 2.377 1.883 2.774 1.496 0.701 1.452 0.340 0.218 0.152 0.000 6.214
TSG 25.739 20.232 23.688 14.176 11.561 14.930 8.935 9.135 10.944 8.327 6.154 6.196 5.660 6.214 0.000
Bei der Durchführung einer Clusteranalyse wird zunächst eine
sogenannte Näherungsmatrix (Distanzmatrix) erstellt. Diese Matrix
enthält die quadrierten euklidischen Distanzen für sämtliche
Kombinationen von Fällen (hier: Schulen) im Datensatz. Für jedes
Wertepaar lässt sich daraus direkt ablesen, wie groß der Abstand
zwischen den einzelnen Fällen im Merkmalsraum ist. Die Werte geben
jeweils die quadrierte Entfernung zwischen zwei Schulen an.
Beispielsweise beträgt der Abstand zwischen „AEG“ und „AFS“ exakt
0,391 Einheiten, was auf eine hohe Ähnlichkeit dieser beiden Schulen
bezüglich der untersuchten Merkmale hindeutet. Im Gegensatz dazu zeigt
der Wert von 25,739 für das Paar „AEG“ und „TSG“ eine sehr große
Verschiedenheit.
Besonders niedrige Werte in der Matrix deuten darauf hin, dass diese
Fälle sich hinsichtlich ihrer Merkmalsausprägungen besonders ähnlich
sind und somit bei der Clusterbildung früh zusammengefasst werden. Hohe
Distanzwerte zeigen dagegen besonders unterschiedliche Fälle an, die
erst in späten Schritten des Clustering-Prozesses gemeinsam einem
Cluster zugeordnet werden.
Die Näherungsmatrix bildet somit die Basis für das hierarchische
Clustering, da in jedem Schritt stets die jeweils ähnlichsten Fälle bzw.
Cluster zusammengefasst werden.
# Hierarchisches Clustering (Ward)
hc <- hclust(dist(daten_scaled), method = "ward.D2")
# Tabelle für die Zuordnungsübersicht bauen
zuordnung <- data.frame(
Schritt = 1:length(hc$height),
Cluster_1 = hc$merge[,1],
Cluster_2 = hc$merge[,2],
Koeffizient = round(hc$height^2, 3)) # quadrierte Distanz
zuordnung$Cluster_1_ID <- ifelse(zuordnung$Cluster_1 < 0, -zuordnung$Cluster_1, zuordnung$Cluster_1)
zuordnung$Cluster_2_ID <- ifelse(zuordnung$Cluster_2 < 0, -zuordnung$Cluster_2, zuordnung$Cluster_2)
colnames(zuordnung) <- c("Schritt", "Cluster 1 (intern)", "Cluster 2 (intern)", "Koeffizienten", "Cluster 1", "Cluster 2")
zuordnung_tab <- zuordnung[,c("Schritt", "Cluster 1", "Cluster 2", "Koeffizienten")]
print(zuordnung_tab)
View(zuordnung_tab)
Im weiteren Verlauf der Analyse wird in der sogenannten
Zuordnungsübersicht detailliert aufgezeigt, wie die einzelnen Schritte
der Clusterbildung ablaufen. Zu Beginn der Analyse bildet jeder Fall ein
eigenes Cluster. In jedem Schritt werden dann die beiden Cluster
zusammengeführt, die den jeweils geringsten Abstand zueinander aufweisen
– dies ist in der Spalte „Koeffizienten“ an den kleinsten Werten zu
erkennen.
So zeigt die Übersicht beispielsweise, dass im ersten Schritt
(Schritt 14) die Cluster 1 und 14 miteinander verschmolzen werden, da
sie den minimalen Abstand zueinander aufweisen (Koeffizient: 0.014). Im
darauf folgenden Schritt (Schritt 12) wird dieses neu gebildete Cluster
(1/14) direkt mit Cluster 11 zusammengeführt (Koeffizient: 0.019).
Dadurch entsteht ein größeres Cluster (1, 11, 14). Parallel dazu werden
auch weitere Fälle mit geringer Distanz zusammengefasst, zum Beispiel
Cluster 3 und 5 (Schritt 8, Koeffizient: 0.041).
Mit jedem weiteren Schritt in der Tabelle werden jeweils die aktuell
ähnlichsten Clusterpaare vereinigt, was sich daran zeigt, dass die
jeweiligen Koeffizienten weiterhin eher klein bleiben (z.B. 0.024,
0.219, 0.261 usw.), bevor mit zunehmender Clustergröße die Werte
deutlich ansteigen. Am Ende des Prozesses (Schritt 14 und Schritt 13)
werden schließlich die größten, verbliebenen Cluster zusammengeführt,
wobei die Koeffizienten nun deutlich größer sind (z.B. 13.190 oder
30.693). Dies zeigt, dass in den letzten Schritten auch weniger ähnliche
Gruppen zu einem Gesamtcluster verschmolzen werden.
Die Koeffizienten-Spalte dokumentiert dabei die jeweils aktuelle
Heterogenität beim Zusammenführen der Cluster – kleine Werte stehen für
sehr ähnliche Gruppen, große Werte für die Vereinigung sehr
unterschiedlicher Cluster. Die Tabelle macht somit transparent, wie der
Algorithmus Schritt für Schritt immer größere, aber auch immer weniger
homogene Gruppen bildet, bis alle Fälle in einem einzigen Gesamtcluster
vereint sind.
6. Bestimmen der Anzahl Cluster
Zu Beginn eines Clusteranalyse-Verfahrens wird jeder einzelne Fall
als eigenständiges Cluster betrachtet. Im Verlauf des Analyseprozesses
werden diese Einzelfälle schrittweise zu immer größeren Gruppen
zusammengeführt, bis schließlich alle Fälle in einem einzigen,
umfassenden Cluster vereint sind. Die zentrale Frage, die sich dabei
stellt, ist: Wie viele Cluster sind für die Interpretation der
Daten sinnvoll? Das heißt, wo zwischen der maximalen Anzahl von
Clustern (bei 15 Fällen: 15 Cluster) und nur einem einzigen Cluster
liegt die optimale Lösung?
Um diese Entscheidung zu treffen, wird häufig sowohl auf inhaltliche
Überlegungen (also die Sinnhaftigkeit bestimmter Gruppenzahlen für das
Untersuchungsziel) als auch auf grafische Hilfsmittel wie das sogenannte
Dendrogramm zurückgegriffen.
# Dendrogramm plotten
plot(hc, main = "Dendrogramm mit Ward-Verknüpfung", xlab = "", sub = "")
# Rote Markierung für optimale Cluster-Anzahl (hier: 2-Cluster-Lösung)
rect.hclust(hc, k = 2, border = "red")

Alternative
ggdendro::ggdendrogram(hc, labels = T, rotate = T)

Das oben dargestellte Dendrogramm visualisiert den gesamten
Clusterbildungsprozess in Form einer Baumstruktur. Am Anfang steht jede
Schule als eigenständiger Punkt ganz unten in dieser Baumstruktur. Mit
jedem Schritt werden jeweils die beiden ähnlichsten Schulen oder Cluster
zu einem gemeinsamen Ast zusammengefasst – dies ist an den vertikalen
Linien der Baumstruktur erkennbar. Je höher die Verbindung in der
Baumstruktur angesetzt ist, desto größer ist die Unterschiedlichkeit
(Heterogenität) der zusammengeführten Cluster.
Die vertikale Achse (“Height”) gibt die Distanz an, mit der jeweils
zwei Cluster fusionieren. Ein besonders großer Sprung auf dieser Achse
signalisiert, dass an dieser Stelle zwei Gruppen zusammengelegt werden,
die sich bereits deutlich voneinander unterscheiden.
In diesem Beispiel ist klar zu erkennen, dass sich eine
Zwei-Cluster-Lösung anbietet. Die beiden roten Kästen markieren die
Cluster, die nach dem größten Sprung in der Baumstruktur entstehen:
Der linke Cluster enthält die Schulen HHG, EKG, FSR, AFS, AEG
und EvTG,
der rechte Cluster fasst die übrigen Schulen zusammen (TSG,
SSG, PS, MMS, MLS, GSS, EAO, GG, HR).
Die Wahl der optimalen Clusterzahl orientiert sich an dem Punkt, an
dem in der Baumstruktur der größte Abstand (“Height”) zwischen zwei
Verbindungen auftritt. Dadurch werden zwei Gruppen gebildet, die intern
möglichst ähnlich und untereinander möglichst unterschiedlich sind.
Diese Darstellung in Baumstruktur-Form macht den Prozess der
Clusterbildung besonders anschaulich und erleichtert die
nachvollziehbare Einteilung der betrachteten Schulen in sinnvolle
Gruppen.
7. Beschreibung der Cluster
Die Tabelle zur Cluster-Zugehörigkeit zeigt, welche Fälle jeweils
demselben Cluster zugeordnet sind. In diesem Beispiel wurde eine
Zwei-Cluster-Lösung gewählt, sodass das Hauptaugenmerk auf der Spalte
liegt, die die Zugehörigkeit zu den beiden Clustern angibt. Dabei wird
deutlich, dass die Fälle 1, 2, 3, 4, 5, 10, 11, 12 und 14 das erste
Cluster bilden, während die Fälle 6, 7, 8, 9, 13 und 15 dem zweiten
Cluster zugeordnet werden.
# Clusterzugehörigkeiten für 5, 4, 3, 2 Cluster berechnen
clusters <- data.frame(
Fall = labels,
`5 Cluster` = cutree(hc, k = 5),
`4 Cluster` = cutree(hc, k = 4),
`3 Cluster` = cutree(hc, k = 3),
`2 Cluster` = cutree(hc, k = 2)
)
# Ausgabe wie im SPSS-Beispiel
print(clusters)
Um die optimale Anzahl an Clustern für das k-Means-Verfahren
festzulegen, wird häufig das sogenannte Elbow-Kriterium
(Kniepunkt-Kriterium) herangezogen. Dazu wird für verschiedene Werte von
k (Anzahl der Cluster) die gesamte innerhalb der Cluster liegende
Quadratsumme („Total Within-Cluster Sum of Squares“, tot.withinss)
berechnet und grafisch dargestellt. Der daraus entstehende Elbow-Plot
zeigt, wie stark die Heterogenität innerhalb der Cluster mit steigender
Clusterzahl abnimmt.
Das Ziel dieses Ansatzes ist es, den Punkt zu identifizieren, an dem
eine weitere Erhöhung der Clusteranzahl zu keiner wesentlichen
Verbesserung mehr führt. Dieser Punkt – der sogenannte „Knick“ oder
„Elbow“ – gibt einen Hinweis darauf, wie viele Cluster die vorhandene
Struktur der Daten am besten beschreiben. Auf diese Weise lässt sich
eine ausgewogene Balance zwischen zu grober und zu feiner Gruppierung
finden.
multi.clust <- data.frame(k = 1:4) %>% group_by(k) %>% do(clust = kmeans(Clusteranalyse, .$k))
sumsq.clust <- multi.clust %>% group_by(k) %>% do(glance(.$clust[[1]]))
ggplot(sumsq.clust, aes(k, tot.withinss)) + geom_line() + geom_point()

Die Grafik zeigt den Verlauf der gesamten innerhalb der Cluster
liegenden Quadratsumme (tot.withinss) in Abhängigkeit von der gewählten
Clusteranzahl (k). Man erkennt deutlich, dass der Wert für tot.withinss
beim Wechsel von einem auf zwei Cluster stark abnimmt. Dieser starke
Rückgang bedeutet, dass durch die Aufteilung in zwei Cluster ein
Großteil der Heterogenität innerhalb der Gruppen bereits erklärt
wird.
Mit jeder weiteren Erhöhung von k sinkt die tot.withinss zwar weiter,
der Zugewinn an Homogenität fällt jedoch zunehmend geringer aus.
Besonders auffällig ist der „Knick“ zwischen k = 2 und k = 3, ab dem
sich die Kurve abflacht. Dies deutet darauf hin, dass die Wahl von zwei
Clustern eine sinnvolle Lösung darstellt, da zusätzliche Cluster nur
noch einen vergleichsweise geringen Mehrwert bringen.
Zusammenfassend lässt sich festhalten, dass das Elbow-Kriterium hier
klar für eine Zwei-Cluster-Lösung spricht, weil an dieser Stelle der
größte relative Zugewinn an Homogenität erzielt wird und die Daten somit
effizient und sinnvoll gruppiert werden.
weitere Klärung
Zur grafischen Darstellung der Cluster eignet sich ein Streudiagramm
(Scatterplot), bei dem die Fälle entsprechend ihrer Clusterzugehörigkeit
farblich unterschieden werden. Dabei werden die beiden ausgewählten
Merkmale auf den Achsen abgetragen, und die Datenpunkte erhalten
unterschiedliche Farben oder Symbole, je nachdem, zu welchem Cluster sie
gehören. Die Gruppenzugehörigkeit wird dabei durch die Variable
dargestellt, die die Clusterzuordnung enthält. Auf diese Weise lässt
sich die Verteilung der Cluster visuell leicht nachvollziehen.
Vorbereitung
Clusteranalyse$Schule <- NULL
row.names(Clusteranalyse)<- clusters$Fall
Warnung: Setting row names on a tibble is deprecated.
View(Clusteranalyse)
p.cluster <- Clusteranalyse %>% kmeans(., 2)
p.cluster$cluster <- as.factor(p.cluster$cluster)
ggplot(Clusteranalyse, aes(KlassenBudget, digitaler_Ausstattungsscore, label = rownames(Clusteranalyse))) +
scale_fill_discrete(name = "Cluster") +
geom_label(aes(fill = p.cluster$cluster), colour = "white",
fontface = "bold", size=2)

Das Streudiagramm zeigt anschaulich, wie die einzelnen Datenpunkte
den Clustern zugeordnet sind. Dabei fällt auf, dass der Wert für „CEO“
möglicherweise einen Ausreißer darstellt. Obwohl dieser Fall dennoch
einem der beiden Cluster zugeordnet wurde, könnte man alternativ auch
überlegen, ihn als eigenes Cluster zu behandeln (z. B. durch eine
Drei-Cluster-Lösung) oder ihn ganz aus der Analyse auszuschließen.
Cluster 1 umfasst Schulen mit niedrigem
Klassenbudget und geringem digitalen Ausstattungs-Score. Diese Gruppe
besteht meist aus kleineren oder finanziell schwächer ausgestatteten
Schulen mit Nachholbedarf bei der Digitalisierung.
Cluster 2 beinhaltet Schulen mit hohem Budget und
fortschrittlicher digitaler Ausstattung. Hierzu zählen häufig größere
oder besser geförderte Schulen, die bereits umfassender in moderne
Technologien investiert haben.
alle
multi.clust <- data.frame(k = 1:5) %>% group_by(k) %>% do(clust = kmeans(Clusteranalyse, .$k))
multi.k <- multi.clust %>% group_by(k) %>% do(augment(.$clust[[1]], Clusteranalyse))
ggplot(multi.k, aes(KlassenBudget, digitaler_Ausstattungsscore,)) + geom_point(aes(color = .cluster)) +
facet_wrap(~k)

Für die Interpretation und Beschreibung der gefundenen Cluster werden
häufig deskriptive Statistiken genutzt. Dazu teilt man den Datensatz
entsprechend der Clusterzugehörigkeit auf und berechnet für jedes
Cluster beispielsweise Mittelwerte oder Häufigkeiten wichtiger Merkmale.
So lässt sich die Zusammensetzung der Cluster gezielt vergleichen und
charakterisieren.
Clusteranalyse$Cluster2 <- as.factor(cutree(hc, k = 2))
# 9. Clusterbeschreibung (Mittelwerte je Cluster)
cluster_summary <- Clusteranalyse %>%
group_by(Cluster2) %>%
summarise(
Mittelwert_KlassenBudget = mean(KlassenBudget),
Mittelwert_DigitalScore = mean(digitaler_Ausstattungsscore),
Anzahl = n()
)
print(cluster_summary)
# 10. (Optional) t-Test zum Clustervergleich
t.test(KlassenBudget ~ Cluster2, data = Clusteranalyse)
Welch Two Sample t-test
data: KlassenBudget by Cluster2
t = -3.2603, df = 11.787, p-value = 0.006975
alternative hypothesis: true difference in means between group 1 and group 2 is not equal to 0
95 percent confidence interval:
-52.04893 -10.29885
sample estimates:
mean in group 1 mean in group 2
36.58167 67.75556
t.test(digitaler_Ausstattungsscore ~ Cluster2, data = Clusteranalyse)
Welch Two Sample t-test
data: digitaler_Ausstattungsscore by Cluster2
t = -5.2889, df = 8.0922, p-value = 0.000711
alternative hypothesis: true difference in means between group 1 and group 2 is not equal to 0
95 percent confidence interval:
-155.30066 -61.12489
sample estimates:
mean in group 1 mean in group 2
131.0250 239.2378
Zur Überprüfung, ob sich die Cluster hinsichtlich des Klassenbudgets
und des digitalen Ausstattungsscores signifikant unterscheiden, wurden
unabhängige Stichproben-t-Tests durchgeführt.
Für das Klassenbudget ergab der Test einen signifikanten Unterschied
zwischen den beiden Clustern, t(11.79) = -3.26, p = .007. Die mittleren
Klassenbudgets lagen bei Cluster 1 bei M = 36.58 und bei Cluster 2 bei M
= 67.76. Das 95%-Konfidenzintervall für die Mittelwertsdifferenz lag
zwischen -52.05 und -10.30.
Auch für den digitalen Ausstattungsscore zeigte sich ein
hochsignifikanter Unterschied zwischen den Clustern, t(8.09) = -5.29, p
< .001. Der Mittelwert im ersten Cluster betrug M = 131.03, im
zweiten Cluster M = 239.24. Das 95%-Konfidenzintervall für die
Mittelwertsdifferenz reichte von -155.30 bis -61.12.
Interpretation: Die Ergebnisse zeigen, dass sich die beiden
identifizierten Cluster sowohl im Klassenbudget als auch im digitalen
Ausstattungsgrad signifikant unterscheiden.
8. Eine Aussage
Im Rahmen der vorliegenden Untersuchung wurde eine hierarchische
Clusteranalyse unter Anwendung der Ward-Methode und auf Basis der
quadrierten euklidischen Distanz durchgeführt. Ziel war es, die
untersuchten Schulen anhand der Merkmale „Klassenbudget“ und „digitaler
Ausstattungs-Score“ in möglichst homogene Gruppen einzuteilen und so
verborgene Strukturen innerhalb des Datensatzes sichtbar zu machen.
Die Auswertung des zugehörigen Dendrogramms und die Anwendung des
Elbow-Kriteriums (vgl. Abbildung X) deuten darauf hin, dass eine
Zwei-Cluster-Lösung die vorhandene Heterogenität in den Daten am besten
abbildet. Der markanteste Anstieg der Fusionsdistanzen im Dendrogramm
legt nahe, dass die Zusammenfassung auf zwei Gruppen sowohl statistisch
sinnvoll als auch aus inhaltlicher Perspektive plausibel ist.
Zur Überprüfung der Unterschiede zwischen den Clustern wurden
unabhängige Stichproben-t-Tests durchgeführt. Die Ergebnisse zeigen,
dass sich die beiden Cluster signifikant sowohl im Klassenbudget
(t(11.79) = -3.26, p = .007, 95%-CI [-52.05; -10.30]) als auch im
digitalen Ausstattungs-Score (t(8.09) = -5.29, p < .001, 95%-CI
[-155.30; -61.12]) unterscheiden. Die Mittelwerte in den beiden Clustern
liegen beim Klassenbudget bei M₁ = 36.58 (SD nicht ausgewiesen) und M₂ =
67.76, beim Ausstattungs-Score bei M₁ = 131.03 und M₂ = 239.24. Die
Differenzen sind somit sowohl statistisch signifikant als auch praktisch
bedeutsam.
Interpretation der Clusterstruktur: Cluster 1 umfasst jene Schulen,
die sowohl über ein unterdurchschnittliches Klassenbudget als auch über
einen vergleichsweise niedrigen digitalen Ausstattungs-Score verfügen.
Typischerweise gehören zu dieser Gruppe beispielsweise kleinere oder
finanziell weniger stark ausgestattete Schulen, die möglicherweise im
Bereich der digitalen Infrastruktur noch Entwicklungsbedarf
aufweisen.
Cluster 2 hingegen setzt sich aus Schulen zusammen, die sowohl ein
deutlich höheres Budget als auch eine fortschrittlichere digitale
Ausstattung aufweisen. Diese Gruppe könnte zum Beispiel Gymnasien oder
Schulen in wohlhabenderen Regionen umfassen, bei denen mehr Mittel für
moderne Ausstattung zur Verfügung stehen und die tendenziell auch von
gezielten Digitalisierungsinitiativen profitiert haben.
Die grafische Darstellung der Cluster in der Baumstruktur des
Dendrogramms zeigt deutlich, dass innerhalb der beiden Gruppen eine hohe
Ähnlichkeit hinsichtlich der betrachteten Merkmale besteht, während sich
die Gruppen untereinander klar voneinander abgrenzen. Diese Befunde
werden durch die Ergebnisse der t-Tests weiter untermauert.
Zusammenfassend lässt sich festhalten: Die durchgeführte
Clusteranalyse bestätigt, dass Schulen anhand der beiden untersuchten
Merkmale zuverlässig in zwei unterschiedliche Typen eingeteilt werden
können. Die Zugehörigkeit zu einem der beiden Cluster ist dabei eng mit
den jeweiligen Ausprägungen in Budget und Digitalisierung verknüpft. Die
Analyse bietet somit eine belastbare Grundlage für eine gezielte Förder-
oder Interventionsstrategie, etwa indem Schulen mit niedrigerem Budget
und Ausstattungsgrad gezielt in ihrer digitalen Entwicklung unterstützt
werden.
LS0tCnRpdGxlOiAiQ2x1c3RlcmFuYWx5c2UiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCiMgUGFrYXRlIGltcG9ydGUKYGBge3J9CmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoYnJvb20pCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShnZ2RlbmRybykKbGlicmFyeShjbHVzdGVyKQpsaWJyYXJ5KHJlYWR4bCkKYGBgCgojIEVpbmxlc2VuIGRlciBEYXRlaQoKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KI2xpYnJhcnkocmVhZHhsKQojQ2x1c3RlcmFuYWx5c2UgPC0gcmVhZF9leGNlbCgicHl0aG9uX3dlYnNlaXRlL0NsdXN0ZXJhbmFseXNlL0NsdXN0ZXJhbmFseXNlLnhsc3giKQojVmlldyhDbHVzdGVyYW5hbHlzZSkKQ2x1c3RlcmFuYWx5c2UkS2xhc3NlbkJ1ZGdldCA8LSBhcy5udW1lcmljKENsdXN0ZXJhbmFseXNlJEtsYXNzZW5CdWRnZXQpCkNsdXN0ZXJhbmFseXNlJGRpZ2l0YWxlcl9BdXNzdGF0dHVuZ3NzY29yZSA8LSBhcy5udW1lcmljKENsdXN0ZXJhbmFseXNlJGRpZ2l0YWxlcl9BdXNzdGF0dHVuZ3NzY29yZSkKcm93bmFtZXMoQ2x1c3RlcmFuYWx5c2UpIDwtIG1ha2UudW5pcXVlKGFzLmNoYXJhY3RlcihDbHVzdGVyYW5hbHlzZSRTY2h1bGUpKQpgYGAKCgojIDEuCVZvcmF1c3NldHp1bmdlbiBkZXIgQ2x1c3RlcmFuYWx5c2UKCuKckyBEYW1pdCB2ZXJsw6Rzc2xpY2hlIEF1c3NhZ2VuIMO8YmVyIGRpZSBHcnVuZGdlc2FtdGhlaXQgbcO2Z2xpY2ggc2luZCwgc29sbHRlIGRpZSBTdGljaHByb2JlIGF1c3JlaWNoZW5kIGdyb8OfIHNlaW4g4oCTIGF1Y2ggd2VubiBpbiBkZXIgUHJheGlzIGjDpHVmaWcga2xlaW5lcmUgU3RpY2hwcm9iZW4gdmVyd2VuZGV0IHdlcmRlbi4KCuKckyBGZWhsZW5kZSBXZXJ0ZSBtw7xzc2VuIHZvciBkZXIgRHVyY2hmw7xocnVuZyBlaW5lciBDbHVzdGVyYW5hbHlzZSBiZXJlaW5pZ3Qgd2VyZGVuLiBEYXp1IHN0ZWhlbiB2ZXJzY2hpZWRlbmUgTWV0aG9kZW4genVyIFZlcmbDvGd1bmcsIGV0d2EgZGFzIEVudGZlcm5lbiB1bnZvbGxzdMOkbmRpZ2VyIEbDpGxsZSwgZGFzIEVyc2V0emVuIGZlaGxlbmRlciBXZXJ0ZSBkdXJjaCBNaXR0ZWx3ZXJ0ZSBvZGVyIGRpZSBJbXB1dGF0aW9uLgoK4pyTIEFsbGUgVmFyaWFibGVuLCBkaWUgaW4gZGllIENsdXN0ZXJhbmFseXNlIGVpbmZsaWXDn2VuLCBzb2xsdGVuIG3DtmdsaWNoc3QgZGFzc2VsYmUgU2thbGVubml2ZWF1IGF1ZndlaXNlbi4gRmFsbHMgZGllcyBuaWNodCBnZWdlYmVuIGlzdCwga2FubiBlaW5lIEFuZ2xlaWNodW5nIGF1ZiBlaW4gZ2VtZWluc2FtZXMgKG1laXN0IG5pZWRyaWdlcmVzKSBTa2FsZW5uaXZlYXUgZXJmb3JkZXJsaWNoIHNlaW4uCgrinJMgVW50ZXJzY2hlaWRlbiBzaWNoIGRpZSBWYXJpYWJsZW4gc3RhcmsgaW4gaWhyZW0gV2VydGViZXJlaWNoLCBpc3QgZWluZSBTdGFuZGFyZGlzaWVydW5nIOKAkyBiZWlzcGllbHN3ZWlzZSBkdXJjaCB6LVRyYW5zZm9ybWF0aW9uIOKAkyBzaW5udm9sbCwgdW0gVmVyemVycnVuZ2VuIGluIGRlciBDbHVzdGVyYmlsZHVuZyB6dSB2ZXJtZWlkZW4uCgoKCgojIDIuCUdydW5kbGVnZW5kZSBLb256ZXB0ZQoKRGllIENsdXN0ZXJhbmFseXNlIGlzdCBlaW4gVmVyZmFocmVuIGRlciBtdWx0aXZhcmlhdGVuIFN0YXRpc3RpaywgZGFzIGRhenUgZGllbnQsIE9iamVrdGUgKHp1bSBCZWlzcGllbCBQZXJzb25lbiwgVW50ZXJuZWhtZW4gb2RlciDigJMgd2llIGluIGRlaW5lbSBGYWxsIOKAkyBTY2h1bGVuKSBhbmhhbmQgaWhyZXIgTWVya21hbGUgaW4gR3J1cHBlbiAoc29nZW5hbm50ZSBDbHVzdGVyKSBlaW56dXRlaWxlbi4gWmllbCBpc3QgZXMsIGRhc3MgZGllIE9iamVrdGUgaW5uZXJoYWxiIGVpbmVzIENsdXN0ZXJzIG3DtmdsaWNoc3Qgw6RobmxpY2ggc2luZCwgd8OkaHJlbmQgc2ljaCBkaWUgQ2x1c3RlciB1bnRlcmVpbmFuZGVyIG3DtmdsaWNoc3Qgc3RhcmsgdW50ZXJzY2hlaWRlbi4gRGFiZWkgd2Vpw58gbWFuIHp1IEJlZ2lubiBtZWlzdCBuaWNodCwgd2llIHZpZWxlIENsdXN0ZXIgZXMgZ2ViZW4gd2lyZCDigJMgZGllcyBlcmdpYnQgc2ljaCBhdXMgZGVuIERhdGVuIHNlbGJzdC4gRGllIENsdXN0ZXJhbmFseXNlIGtvbW10IGjDpHVmaWcgaW4gZGVuIFNvemlhbHdpc3NlbnNjaGFmdGVuLCBpbSBNYXJrZXRpbmcgb2RlciBkZXIgQmlvbG9naWUgenVtIEVpbnNhdHosIHVtIHZlcmJvcmdlbmUgTXVzdGVyIHVuZCBTdHJ1a3R1cmVuIGluIGdyb8OfZW4gRGF0ZW5zw6R0emVuIHp1IGVudGRlY2tlbi4gVHlwaXNjaGUgU2Nocml0dGUgYmVpIGVpbmVyIENsdXN0ZXJhbmFseXNlIHNpbmQgZGllIEF1c3dhaGwgcmVsZXZhbnRlciBWYXJpYWJsZW4sIGRhcyBCZXJlaW5pZ2VuIGRlciBEYXRlbiAoei5CLiBVbWdhbmcgbWl0IGZlaGxlbmRlbiBXZXJ0ZW4pLCBldmVudHVlbGwgZWluZSBTdGFuZGFyZGlzaWVydW5nIGRlciBNZXJrbWFsZSBzb3dpZSBkaWUgQW53ZW5kdW5nIGVpbmVzIEFsZ29yaXRobXVzICh3aWUgSy1NZWFucyBvZGVyIGhpZXJhcmNoaXNjaGVzIENsdXN0ZXJpbmcpLiBEaWUgRXJnZWJuaXNzZSBkZXIgQW5hbHlzZSBoZWxmZW4gZGFiZWksIEdydXBwZW4gbWl0IMOkaG5saWNoZW4gRWlnZW5zY2hhZnRlbiB6dSBpZGVudGlmaXppZXJlbiB1bmQgZGllc2UgYW5zY2hsaWXDn2VuZCB6dSBpbnRlcnByZXRpZXJlbiB1bmQgd2VpdGVyenV2ZXJ3ZW5kZW4uCgojIDMuCURlc2tyaXB0aXZlIFN0YXRpc3Rpa2VuCgpgYGB7cn0KZGVzY3JpYmUoQ2x1c3RlcmFuYWx5c2UpCmBgYApgYGB7cn0KbGlicmFyeShkcGx5cikKQ2x1c3RlcmFuYWx5c2UgJT4lCiAgc3VtbWFyaXNlKAogICAgTWl0dGVsd2VydF9LbGFzc2VuQnVkZ2V0ID0gbWVhbihLbGFzc2VuQnVkZ2V0KSwKICAgIE1pdHRlbHdlcnRfRGlnaXRhbFNjb3JlID0gbWVhbihkaWdpdGFsZXJfQXVzc3RhdHR1bmdzc2NvcmUpLAogICAgbiA9IG4oKQogICkKYGBgCgoKCiMgNC4gUHLDvGZ1bmcgZGVyIFZvcmF1c3NldHp1bmcKCuKckyBEYW1pdCB2ZXJsw6Rzc2xpY2hlIEF1c3NhZ2VuIMO8YmVyIGRpZSBHcnVuZGdlc2FtdGhlaXQgbcO2Z2xpY2ggc2luZCwgc29sbHRlIGRpZSBTdGljaHByb2JlIGF1c3JlaWNoZW5kIGdyb8OfIHNlaW4g4oCTIGF1Y2ggd2VubiBpbiBkZXIgUHJheGlzIGjDpHVmaWcga2xlaW5lcmUgU3RpY2hwcm9iZW4gdmVyd2VuZGV0IHdlcmRlbi4KCiAqKk4qKiBpc3QgbWl0IGdyw7bDn2VyICoqMzAqKgoKCuKckyBBbGxlIFZhcmlhYmxlbiwgZGllIGluIGRpZSBDbHVzdGVyYW5hbHlzZSBlaW5mbGllw59lbiwgc29sbHRlbiBtw7ZnbGljaHN0IGRhc3NlbGJlIFNrYWxlbm5pdmVhdSBhdWZ3ZWlzZW4uIEZhbGxzIGRpZXMgbmljaHQgZ2VnZWJlbiBpc3QsIGthbm4gZWluZSBBbmdsZWljaHVuZyBhdWYgZWluIGdlbWVpbnNhbWVzIChtZWlzdCBuaWVkcmlnZXJlcykgU2thbGVubml2ZWF1IGVyZm9yZGVybGljaCBzZWluLgoKKipCZWlkZSBTcGFsdGVuIHNpbmQgbWV0cmlzY2guKioKCgrinJMgRmVobGVuZGUgV2VydGUgbcO8c3NlbiB2b3IgZGVyIER1cmNoZsO8aHJ1bmcgZWluZXIgQ2x1c3RlcmFuYWx5c2UgYmVyZWluaWd0IHdlcmRlbi4gRGF6dSBzdGVoZW4gdmVyc2NoaWVkZW5lIE1ldGhvZGVuIHp1ciBWZXJmw7xndW5nLCBldHdhIGRhcyBFbnRmZXJuZW4gdW52b2xsc3TDpG5kaWdlciBGw6RsbGUsIGRhcyBFcnNldHplbiBmZWhsZW5kZXIgV2VydGUgZHVyY2ggTWl0dGVsd2VydGUgb2RlciBkaWUgSW1wdXRhdGlvbi4KCmBgYHtyfQptaXNzaW5nX3ZhbHVlIDwtIHN1bShhcy5udW1lcmljKGlzLm5hKENsdXN0ZXJhbmFseXNlKSkpCnNwcmludGYoIkZlaGxlbmRlIFdlcnRlOiAlLjJmIiwgbWlzc2luZ192YWx1ZSkKYGBgCgoK4pyTIFVudGVyc2NoZWlkZW4gc2ljaCBkaWUgVmFyaWFibGVuIHN0YXJrIGluIGlocmVtIFdlcnRlYmVyZWljaCwgaXN0IGVpbmUgU3RhbmRhcmRpc2llcnVuZyDigJMgYmVpc3BpZWxzd2Vpc2UgZHVyY2ggei1UcmFuc2Zvcm1hdGlvbiDigJMgc2lubnZvbGwsIHVtIFZlcnplcnJ1bmdlbiBpbiBkZXIgQ2x1c3RlcmJpbGR1bmcgenUgdmVybWVpZGVuLgoKYGBge3J9CmRhdGVuIDwtIENsdXN0ZXJhbmFseXNlWywgMjozXQoKIyAjIDMuIExhYmVscyAoU2NodWxuYW1lbikKbGFiZWxzIDwtIENsdXN0ZXJhbmFseXNlJFNjaHVsZQoKcm93bmFtZXMoZGF0ZW4pIDwtIGxhYmVscwoKIyBTdGFuZGFyZGlzaWVydW5nICh6LVRyYW5zZm9ybWF0aW9uKQpkYXRlbl9zY2FsZWQgPC0gc2NhbGUoZGF0ZW4pCmBgYAoKRGEgc2ljaCBkaWUgVmFyaWFibGVuIGluIGlocmVtIFdlcnRlYmVyZWljaCBkZXV0bGljaCB1bnRlcnNjaGVpZGVuLCB3dXJkZW4gZGllIERhdGVuIHZvciBkZXIgQ2x1c3RlcmFuYWx5c2UgbWl0dGVscyB6LVRyYW5zZm9ybWF0aW9uIHN0YW5kYXJkaXNpZXJ0LiBTbyB3aXJkIHNpY2hlcmdlc3RlbGx0LCBkYXNzIGJlaWRlIE1lcmttYWxlIGdsZWljaCBnZXdpY2h0ZXQgaW4gZGllIERpc3RhbnpiZXJlY2hudW5nIHVuZCBDbHVzdGVyYmlsZHVuZyBlaW5nZWhlbiB1bmQga2VpbmUgVmVyemVycnVuZ2VuIGVudHN0ZWhlbi4KCgoKCiMgNC4JUHJvemVzcyBkZXIgQ2x1c3RlcmJpbGR1bmcKCkJldm9yIG1pdCBkZXIgZWlnZW50bGljaGVuIENsdXN0ZXJiaWxkdW5nIGJlZ29ubmVuIHdlcmRlbiBrYW5uLCBpc3QgZGllIEVyc3RlbGx1bmcgZWluZXIgRGlzdGFuem1hdHJpeCBlaW4gemVudHJhbGVyIGVyc3RlciBTY2hyaXR0LiBTaWUgbGllZmVydCBkaWUgR3J1bmRsYWdlLCB1bSBvYmpla3RpdiB6dSBiZXN0aW1tZW4sIHdpZSDDpGhubGljaCBvZGVyIHZlcnNjaGllZGVuIGRpZSBlaW56ZWxuZW4gRsOkbGxlIGltIERhdGVuc2F0eiB6dWVpbmFuZGVyIHNpbmQgdW5kIGJpbGRldCBkYW1pdCBkaWUgQmFzaXMgZsO8ciBhbGxlIHdlaXRlcmVuIFNjaHJpdHRlIGRlciBDbHVzdGVyYW5hbHlzZS4KCmBgYHtyfQojIERpc3RhbnptYXRyaXggKGV1a2xpZGlzY2gpCmRpc3RhbnogPC0gZGlzdChkYXRlbl9zY2FsZWQsIG1ldGhvZCA9ICJldWNsaWRlYW4iKQoKIyBRdWFkcmllcnRlIERpc3RhbnplbiAod2llIGltIEJlaXNwaWVsKQpuYWVoZXJ1bmdzbWF0cml4IDwtIGFzLm1hdHJpeChkaXN0YW56KV4yCgojIFJ1bmRlbiBmw7xyIGJlc3NlcmUgTGVzYmFya2VpdApuYWVoZXJ1bmdzbWF0cml4IDwtIHJvdW5kKG5hZWhlcnVuZ3NtYXRyaXgsIDMpCgojIFNwYWx0ZW4tIHVuZCBaZWlsZW5uYW1lbiBzZXR6ZW4gKMOcYmVyc2NocmlmdGVuKQpjb2xuYW1lcyhuYWVoZXJ1bmdzbWF0cml4KSA8LSBsYWJlbHMKcm93bmFtZXMobmFlaGVydW5nc21hdHJpeCkgPC0gbGFiZWxzCgojIE1hdHJpeCBhbnplaWdlbgpwcmludChuYWVoZXJ1bmdzbWF0cml4KQoKYGBgCgpCZWkgZGVyIER1cmNoZsO8aHJ1bmcgZWluZXIgQ2x1c3RlcmFuYWx5c2Ugd2lyZCB6dW7DpGNoc3QgZWluZSBzb2dlbmFubnRlIE7DpGhlcnVuZ3NtYXRyaXggKERpc3RhbnptYXRyaXgpIGVyc3RlbGx0LiBEaWVzZSBNYXRyaXggZW50aMOkbHQgZGllIHF1YWRyaWVydGVuIGV1a2xpZGlzY2hlbiBEaXN0YW56ZW4gZsO8ciBzw6RtdGxpY2hlIEtvbWJpbmF0aW9uZW4gdm9uIEbDpGxsZW4gKGhpZXI6IFNjaHVsZW4pIGltIERhdGVuc2F0ei4gRsO8ciBqZWRlcyBXZXJ0ZXBhYXIgbMOkc3N0IHNpY2ggZGFyYXVzIGRpcmVrdCBhYmxlc2VuLCB3aWUgZ3Jvw58gZGVyIEFic3RhbmQgendpc2NoZW4gZGVuIGVpbnplbG5lbiBGw6RsbGVuIGltIE1lcmttYWxzcmF1bSBpc3QuIERpZSBXZXJ0ZSBnZWJlbiBqZXdlaWxzIGRpZSBxdWFkcmllcnRlIEVudGZlcm51bmcgendpc2NoZW4gendlaSBTY2h1bGVuIGFuLgoKQmVpc3BpZWxzd2Vpc2UgYmV0csOkZ3QgZGVyIEFic3RhbmQgendpc2NoZW4g4oCeQUVH4oCcIHVuZCDigJ5BRlPigJwgZXhha3QgMCwzOTEgRWluaGVpdGVuLCB3YXMgYXVmIGVpbmUgaG9oZSDDhGhubGljaGtlaXQgZGllc2VyIGJlaWRlbiBTY2h1bGVuIGJlesO8Z2xpY2ggZGVyIHVudGVyc3VjaHRlbiBNZXJrbWFsZSBoaW5kZXV0ZXQuIEltIEdlZ2Vuc2F0eiBkYXp1IHplaWd0IGRlciBXZXJ0IHZvbiAyNSw3MzkgZsO8ciBkYXMgUGFhciDigJ5BRUfigJwgdW5kIOKAnlRTR+KAnCBlaW5lIHNlaHIgZ3Jvw59lIFZlcnNjaGllZGVuaGVpdC4KCkJlc29uZGVycyBuaWVkcmlnZSBXZXJ0ZSBpbiBkZXIgTWF0cml4IGRldXRlbiBkYXJhdWYgaGluLCBkYXNzIGRpZXNlIEbDpGxsZSBzaWNoIGhpbnNpY2h0bGljaCBpaHJlciBNZXJrbWFsc2F1c3Byw6RndW5nZW4gYmVzb25kZXJzIMOkaG5saWNoIHNpbmQgdW5kIHNvbWl0IGJlaSBkZXIgQ2x1c3RlcmJpbGR1bmcgZnLDvGggenVzYW1tZW5nZWZhc3N0IHdlcmRlbi4gSG9oZSBEaXN0YW56d2VydGUgemVpZ2VuIGRhZ2VnZW4gYmVzb25kZXJzIHVudGVyc2NoaWVkbGljaGUgRsOkbGxlIGFuLCBkaWUgZXJzdCBpbiBzcMOkdGVuIFNjaHJpdHRlbiBkZXMgQ2x1c3RlcmluZy1Qcm96ZXNzZXMgZ2VtZWluc2FtIGVpbmVtIENsdXN0ZXIgenVnZW9yZG5ldCB3ZXJkZW4uCgpEaWUgTsOkaGVydW5nc21hdHJpeCBiaWxkZXQgc29taXQgZGllIEJhc2lzIGbDvHIgZGFzIGhpZXJhcmNoaXNjaGUgQ2x1c3RlcmluZywgZGEgaW4gamVkZW0gU2Nocml0dCBzdGV0cyBkaWUgamV3ZWlscyDDpGhubGljaHN0ZW4gRsOkbGxlIGJ6dy4gQ2x1c3RlciB6dXNhbW1lbmdlZmFzc3Qgd2VyZGVuLgoKCmBgYHtyfQojIEhpZXJhcmNoaXNjaGVzIENsdXN0ZXJpbmcgKFdhcmQpCmhjIDwtIGhjbHVzdChkaXN0KGRhdGVuX3NjYWxlZCksIG1ldGhvZCA9ICJ3YXJkLkQyIikKYGBgCgoKYGBge3J9CgojIFRhYmVsbGUgZsO8ciBkaWUgWnVvcmRudW5nc8O8YmVyc2ljaHQgYmF1ZW4KenVvcmRudW5nIDwtIGRhdGEuZnJhbWUoCiAgU2Nocml0dCA9IDE6bGVuZ3RoKGhjJGhlaWdodCksCiAgQ2x1c3Rlcl8xID0gaGMkbWVyZ2VbLDFdLAogIENsdXN0ZXJfMiA9IGhjJG1lcmdlWywyXSwKICBLb2VmZml6aWVudCA9IHJvdW5kKGhjJGhlaWdodF4yLCAzKSkgIyBxdWFkcmllcnRlIERpc3RhbnogCgp6dW9yZG51bmckQ2x1c3Rlcl8xX0lEIDwtIGlmZWxzZSh6dW9yZG51bmckQ2x1c3Rlcl8xIDwgMCwgLXp1b3JkbnVuZyRDbHVzdGVyXzEsIHp1b3JkbnVuZyRDbHVzdGVyXzEpCnp1b3JkbnVuZyRDbHVzdGVyXzJfSUQgPC0gaWZlbHNlKHp1b3JkbnVuZyRDbHVzdGVyXzIgPCAwLCAtenVvcmRudW5nJENsdXN0ZXJfMiwgenVvcmRudW5nJENsdXN0ZXJfMikKCmNvbG5hbWVzKHp1b3JkbnVuZykgPC0gYygiU2Nocml0dCIsICJDbHVzdGVyIDEgKGludGVybikiLCAiQ2x1c3RlciAyIChpbnRlcm4pIiwgIktvZWZmaXppZW50ZW4iLCAiQ2x1c3RlciAxIiwgIkNsdXN0ZXIgMiIpCgoKenVvcmRudW5nX3RhYiA8LSB6dW9yZG51bmdbLGMoIlNjaHJpdHQiLCAiQ2x1c3RlciAxIiwgIkNsdXN0ZXIgMiIsICJLb2VmZml6aWVudGVuIildCnByaW50KHp1b3JkbnVuZ190YWIpCmBgYAoKCgpJbSB3ZWl0ZXJlbiBWZXJsYXVmIGRlciBBbmFseXNlIHdpcmQgaW4gZGVyIHNvZ2VuYW5udGVuIFp1b3JkbnVuZ3PDvGJlcnNpY2h0IGRldGFpbGxpZXJ0IGF1ZmdlemVpZ3QsIHdpZSBkaWUgZWluemVsbmVuIFNjaHJpdHRlIGRlciBDbHVzdGVyYmlsZHVuZyBhYmxhdWZlbi4gWnUgQmVnaW5uIGRlciBBbmFseXNlIGJpbGRldCBqZWRlciBGYWxsIGVpbiBlaWdlbmVzIENsdXN0ZXIuIEluIGplZGVtIFNjaHJpdHQgd2VyZGVuIGRhbm4gZGllIGJlaWRlbiBDbHVzdGVyIHp1c2FtbWVuZ2Vmw7xocnQsIGRpZSBkZW4gamV3ZWlscyBnZXJpbmdzdGVuIEFic3RhbmQgenVlaW5hbmRlciBhdWZ3ZWlzZW4g4oCTIGRpZXMgaXN0IGluIGRlciBTcGFsdGUg4oCeS29lZmZpemllbnRlbuKAnCBhbiBkZW4ga2xlaW5zdGVuIFdlcnRlbiB6dSBlcmtlbm5lbi4KClNvIHplaWd0IGRpZSDDnGJlcnNpY2h0IGJlaXNwaWVsc3dlaXNlLCBkYXNzIGltIGVyc3RlbiBTY2hyaXR0IChTY2hyaXR0IDE0KSBkaWUgQ2x1c3RlciAxIHVuZCAxNCBtaXRlaW5hbmRlciB2ZXJzY2htb2x6ZW4gd2VyZGVuLCBkYSBzaWUgZGVuIG1pbmltYWxlbiBBYnN0YW5kIHp1ZWluYW5kZXIgYXVmd2Vpc2VuIChLb2VmZml6aWVudDogMC4wMTQpLiBJbSBkYXJhdWYgZm9sZ2VuZGVuIFNjaHJpdHQgKFNjaHJpdHQgMTIpIHdpcmQgZGllc2VzIG5ldSBnZWJpbGRldGUgQ2x1c3RlciAoMS8xNCkgZGlyZWt0IG1pdCBDbHVzdGVyIDExIHp1c2FtbWVuZ2Vmw7xocnQgKEtvZWZmaXppZW50OiAwLjAxOSkuIERhZHVyY2ggZW50c3RlaHQgZWluIGdyw7bDn2VyZXMgQ2x1c3RlciAoMSwgMTEsIDE0KS4gUGFyYWxsZWwgZGF6dSB3ZXJkZW4gYXVjaCB3ZWl0ZXJlIEbDpGxsZSBtaXQgZ2VyaW5nZXIgRGlzdGFueiB6dXNhbW1lbmdlZmFzc3QsIHp1bSBCZWlzcGllbCBDbHVzdGVyIDMgdW5kIDUgKFNjaHJpdHQgOCwgS29lZmZpemllbnQ6IDAuMDQxKS4KCk1pdCBqZWRlbSB3ZWl0ZXJlbiBTY2hyaXR0IGluIGRlciBUYWJlbGxlIHdlcmRlbiBqZXdlaWxzIGRpZSBha3R1ZWxsIMOkaG5saWNoc3RlbiBDbHVzdGVycGFhcmUgdmVyZWluaWd0LCB3YXMgc2ljaCBkYXJhbiB6ZWlndCwgZGFzcyBkaWUgamV3ZWlsaWdlbiBLb2VmZml6aWVudGVuIHdlaXRlcmhpbiBlaGVyIGtsZWluIGJsZWliZW4gKHouQi4gMC4wMjQsIDAuMjE5LCAwLjI2MSB1c3cuKSwgYmV2b3IgbWl0IHp1bmVobWVuZGVyIENsdXN0ZXJncsO2w59lIGRpZSBXZXJ0ZSBkZXV0bGljaCBhbnN0ZWlnZW4uIEFtIEVuZGUgZGVzIFByb3plc3NlcyAoU2Nocml0dCAxNCB1bmQgU2Nocml0dCAxMykgd2VyZGVuIHNjaGxpZcOfbGljaCBkaWUgZ3LDtsOfdGVuLCB2ZXJibGllYmVuZW4gQ2x1c3RlciB6dXNhbW1lbmdlZsO8aHJ0LCB3b2JlaSBkaWUgS29lZmZpemllbnRlbiBudW4gZGV1dGxpY2ggZ3LDtsOfZXIgc2luZCAoei5CLiAxMy4xOTAgb2RlciAzMC42OTMpLiBEaWVzIHplaWd0LCBkYXNzIGluIGRlbiBsZXR6dGVuIFNjaHJpdHRlbiBhdWNoIHdlbmlnZXIgw6RobmxpY2hlIEdydXBwZW4genUgZWluZW0gR2VzYW10Y2x1c3RlciB2ZXJzY2htb2x6ZW4gd2VyZGVuLgoKRGllIEtvZWZmaXppZW50ZW4tU3BhbHRlIGRva3VtZW50aWVydCBkYWJlaSBkaWUgamV3ZWlscyBha3R1ZWxsZSBIZXRlcm9nZW5pdMOkdCBiZWltIFp1c2FtbWVuZsO8aHJlbiBkZXIgQ2x1c3RlciDigJMga2xlaW5lIFdlcnRlIHN0ZWhlbiBmw7xyIHNlaHIgw6RobmxpY2hlIEdydXBwZW4sIGdyb8OfZSBXZXJ0ZSBmw7xyIGRpZSBWZXJlaW5pZ3VuZyBzZWhyIHVudGVyc2NoaWVkbGljaGVyIENsdXN0ZXIuIERpZSBUYWJlbGxlIG1hY2h0IHNvbWl0IHRyYW5zcGFyZW50LCB3aWUgZGVyIEFsZ29yaXRobXVzIFNjaHJpdHQgZsO8ciBTY2hyaXR0IGltbWVyIGdyw7bDn2VyZSwgYWJlciBhdWNoIGltbWVyIHdlbmlnZXIgaG9tb2dlbmUgR3J1cHBlbiBiaWxkZXQsIGJpcyBhbGxlIEbDpGxsZSBpbiBlaW5lbSBlaW56aWdlbiBHZXNhbXRjbHVzdGVyIHZlcmVpbnQgc2luZC4KCgoKCiMgNi4JQmVzdGltbWVuIGRlciBBbnphaGwgQ2x1c3RlcgoKClp1IEJlZ2lubiBlaW5lcyBDbHVzdGVyYW5hbHlzZS1WZXJmYWhyZW5zIHdpcmQgamVkZXIgZWluemVsbmUgRmFsbCBhbHMgZWlnZW5zdMOkbmRpZ2VzIENsdXN0ZXIgYmV0cmFjaHRldC4gSW0gVmVybGF1ZiBkZXMgQW5hbHlzZXByb3plc3NlcyB3ZXJkZW4gZGllc2UgRWluemVsZsOkbGxlIHNjaHJpdHR3ZWlzZSB6dSBpbW1lciBncsO2w59lcmVuIEdydXBwZW4genVzYW1tZW5nZWbDvGhydCwgYmlzIHNjaGxpZcOfbGljaCBhbGxlIEbDpGxsZSBpbiBlaW5lbSBlaW56aWdlbiwgdW1mYXNzZW5kZW4gQ2x1c3RlciB2ZXJlaW50IHNpbmQuIERpZSB6ZW50cmFsZSBGcmFnZSwgZGllIHNpY2ggZGFiZWkgc3RlbGx0LCBpc3Q6ICoqV2llIHZpZWxlIENsdXN0ZXIgc2luZCBmw7xyIGRpZSBJbnRlcnByZXRhdGlvbiBkZXIgRGF0ZW4gc2lubnZvbGw/KiogRGFzIGhlacOfdCwgd28gendpc2NoZW4gZGVyIG1heGltYWxlbiBBbnphaGwgdm9uIENsdXN0ZXJuIChiZWkgMTUgRsOkbGxlbjogMTUgQ2x1c3RlcikgdW5kIG51ciBlaW5lbSBlaW56aWdlbiBDbHVzdGVyIGxpZWd0IGRpZSBvcHRpbWFsZSBMw7ZzdW5nPwoKVW0gZGllc2UgRW50c2NoZWlkdW5nIHp1IHRyZWZmZW4sIHdpcmQgaMOkdWZpZyBzb3dvaGwgYXVmIGluaGFsdGxpY2hlIMOcYmVybGVndW5nZW4gKGFsc28gZGllIFNpbm5oYWZ0aWdrZWl0IGJlc3RpbW10ZXIgR3J1cHBlbnphaGxlbiBmw7xyIGRhcyBVbnRlcnN1Y2h1bmdzemllbCkgYWxzIGF1Y2ggYXVmIGdyYWZpc2NoZSBIaWxmc21pdHRlbCB3aWUgZGFzIHNvZ2VuYW5udGUgKkRlbmRyb2dyYW1tKiB6dXLDvGNrZ2VncmlmZmVuLgoKYGBge3J9CiMgRGVuZHJvZ3JhbW0gcGxvdHRlbgpwbG90KGhjLCBtYWluID0gIkRlbmRyb2dyYW1tIG1pdCBXYXJkLVZlcmtuw7xwZnVuZyIsIHhsYWIgPSAiIiwgc3ViID0gIiIpCgojIFJvdGUgTWFya2llcnVuZyBmw7xyIG9wdGltYWxlIENsdXN0ZXItQW56YWhsIChoaWVyOiAyLUNsdXN0ZXItTMO2c3VuZykKcmVjdC5oY2x1c3QoaGMsIGsgPSAyLCBib3JkZXIgPSAicmVkIikKCmBgYAoKKipBbHRlcm5hdGl2ZSoqCgoKYGBge3J9CmdnZGVuZHJvOjpnZ2RlbmRyb2dyYW0oaGMsIGxhYmVscyA9IFQsIHJvdGF0ZSA9ICBUKQpgYGAKCkRhcyBvYmVuIGRhcmdlc3RlbGx0ZSBEZW5kcm9ncmFtbSB2aXN1YWxpc2llcnQgZGVuIGdlc2FtdGVuIENsdXN0ZXJiaWxkdW5nc3Byb3plc3MgaW4gRm9ybSBlaW5lciBCYXVtc3RydWt0dXIuIEFtIEFuZmFuZyBzdGVodCBqZWRlIFNjaHVsZSBhbHMgZWlnZW5zdMOkbmRpZ2VyIFB1bmt0IGdhbnogdW50ZW4gaW4gZGllc2VyIEJhdW1zdHJ1a3R1ci4gTWl0IGplZGVtIFNjaHJpdHQgd2VyZGVuIGpld2VpbHMgZGllIGJlaWRlbiDDpGhubGljaHN0ZW4gU2NodWxlbiBvZGVyIENsdXN0ZXIgenUgZWluZW0gZ2VtZWluc2FtZW4gQXN0IHp1c2FtbWVuZ2VmYXNzdCDigJMgZGllcyBpc3QgYW4gZGVuIHZlcnRpa2FsZW4gTGluaWVuIGRlciBCYXVtc3RydWt0dXIgZXJrZW5uYmFyLiBKZSBow7ZoZXIgZGllIFZlcmJpbmR1bmcgaW4gZGVyIEJhdW1zdHJ1a3R1ciBhbmdlc2V0enQgaXN0LCBkZXN0byBncsO2w59lciBpc3QgZGllIFVudGVyc2NoaWVkbGljaGtlaXQgKEhldGVyb2dlbml0w6R0KSBkZXIgenVzYW1tZW5nZWbDvGhydGVuIENsdXN0ZXIuCgpEaWUgdmVydGlrYWxlIEFjaHNlICgiSGVpZ2h0IikgZ2lidCBkaWUgRGlzdGFueiBhbiwgbWl0IGRlciBqZXdlaWxzIHp3ZWkgQ2x1c3RlciBmdXNpb25pZXJlbi4gRWluIGJlc29uZGVycyBncm/Dn2VyIFNwcnVuZyBhdWYgZGllc2VyIEFjaHNlIHNpZ25hbGlzaWVydCwgZGFzcyBhbiBkaWVzZXIgU3RlbGxlIHp3ZWkgR3J1cHBlbiB6dXNhbW1lbmdlbGVndCB3ZXJkZW4sIGRpZSBzaWNoIGJlcmVpdHMgZGV1dGxpY2ggdm9uZWluYW5kZXIgdW50ZXJzY2hlaWRlbi4KCkluIGRpZXNlbSBCZWlzcGllbCBpc3Qga2xhciB6dSBlcmtlbm5lbiwgZGFzcyBzaWNoIGVpbmUgWndlaS1DbHVzdGVyLUzDtnN1bmcgYW5iaWV0ZXQuIERpZSBiZWlkZW4gcm90ZW4gS8Okc3RlbiBtYXJraWVyZW4gZGllIENsdXN0ZXIsIGRpZSBuYWNoIGRlbSBncsO2w590ZW4gU3BydW5nIGluIGRlciBCYXVtc3RydWt0dXIgZW50c3RlaGVuOgoKKipEZXIgbGlua2UgQ2x1c3RlciBlbnRow6RsdCBkaWUgU2NodWxlbiBISEcsIEVLRywgRlNSLCBBRlMsIEFFRyB1bmQgRXZURywqKgoKKipkZXIgcmVjaHRlIENsdXN0ZXIgZmFzc3QgZGllIMO8YnJpZ2VuIFNjaHVsZW4genVzYW1tZW4gKFRTRywgU1NHLCBQUywgTU1TLCBNTFMsIEdTUywgRUFPLCBHRywgSFIpLioqCgpEaWUgV2FobCBkZXIgb3B0aW1hbGVuIENsdXN0ZXJ6YWhsIG9yaWVudGllcnQgc2ljaCBhbiBkZW0gUHVua3QsIGFuIGRlbSBpbiBkZXIgQmF1bXN0cnVrdHVyIGRlciBncsO2w590ZSBBYnN0YW5kICgiSGVpZ2h0Iikgendpc2NoZW4gendlaSBWZXJiaW5kdW5nZW4gYXVmdHJpdHQuIERhZHVyY2ggd2VyZGVuIHp3ZWkgR3J1cHBlbiBnZWJpbGRldCwgZGllIGludGVybiBtw7ZnbGljaHN0IMOkaG5saWNoIHVuZCB1bnRlcmVpbmFuZGVyIG3DtmdsaWNoc3QgdW50ZXJzY2hpZWRsaWNoIHNpbmQuCgpEaWVzZSBEYXJzdGVsbHVuZyBpbiBCYXVtc3RydWt0dXItRm9ybSBtYWNodCBkZW4gUHJvemVzcyBkZXIgQ2x1c3RlcmJpbGR1bmcgYmVzb25kZXJzIGFuc2NoYXVsaWNoIHVuZCBlcmxlaWNodGVydCBkaWUgbmFjaHZvbGx6aWVoYmFyZSBFaW50ZWlsdW5nIGRlciBiZXRyYWNodGV0ZW4gU2NodWxlbiBpbiBzaW5udm9sbGUgR3J1cHBlbi4KCgojIDcuCUJlc2NocmVpYnVuZyBkZXIgQ2x1c3RlcgoKRGllIFRhYmVsbGUgenVyIENsdXN0ZXItWnVnZWjDtnJpZ2tlaXQgemVpZ3QsIHdlbGNoZSBGw6RsbGUgamV3ZWlscyBkZW1zZWxiZW4gQ2x1c3RlciB6dWdlb3JkbmV0IHNpbmQuIEluIGRpZXNlbSBCZWlzcGllbCB3dXJkZSBlaW5lIFp3ZWktQ2x1c3Rlci1Mw7ZzdW5nIGdld8OkaGx0LCBzb2Rhc3MgZGFzIEhhdXB0YXVnZW5tZXJrIGF1ZiBkZXIgU3BhbHRlIGxpZWd0LCBkaWUgZGllIFp1Z2Vow7ZyaWdrZWl0IHp1IGRlbiBiZWlkZW4gQ2x1c3Rlcm4gYW5naWJ0LiBEYWJlaSB3aXJkIGRldXRsaWNoLCBkYXNzIGRpZSBGw6RsbGUgMSwgMiwgMywgNCwgNSwgMTAsIDExLCAxMiB1bmQgMTQgZGFzIGVyc3RlIENsdXN0ZXIgYmlsZGVuLCB3w6RocmVuZCBkaWUgRsOkbGxlIDYsIDcsIDgsIDksIDEzIHVuZCAxNSBkZW0gendlaXRlbiBDbHVzdGVyIHp1Z2VvcmRuZXQgd2VyZGVuLgoKCmBgYHtyfQoKIyBDbHVzdGVyenVnZWjDtnJpZ2tlaXRlbiBmw7xyIDUsIDQsIDMsIDIgQ2x1c3RlciBiZXJlY2huZW4KY2x1c3RlcnMgPC0gZGF0YS5mcmFtZSgKICBGYWxsID0gbGFiZWxzLAogIGA1IENsdXN0ZXJgID0gY3V0cmVlKGhjLCBrID0gNSksCiAgYDQgQ2x1c3RlcmAgPSBjdXRyZWUoaGMsIGsgPSA0KSwKICBgMyBDbHVzdGVyYCA9IGN1dHJlZShoYywgayA9IDMpLAogIGAyIENsdXN0ZXJgID0gY3V0cmVlKGhjLCBrID0gMikKKQoKIyBBdXNnYWJlIHdpZSBpbSBTUFNTLUJlaXNwaWVsCnByaW50KGNsdXN0ZXJzKQpgYGAKClVtIGRpZSBvcHRpbWFsZSBBbnphaGwgYW4gQ2x1c3Rlcm4gZsO8ciBkYXMgay1NZWFucy1WZXJmYWhyZW4gZmVzdHp1bGVnZW4sIHdpcmQgaMOkdWZpZyBkYXMgc29nZW5hbm50ZSBFbGJvdy1Lcml0ZXJpdW0gKEtuaWVwdW5rdC1Lcml0ZXJpdW0pIGhlcmFuZ2V6b2dlbi4gRGF6dSB3aXJkIGbDvHIgdmVyc2NoaWVkZW5lIFdlcnRlIHZvbiBrIChBbnphaGwgZGVyIENsdXN0ZXIpIGRpZSBnZXNhbXRlIGlubmVyaGFsYiBkZXIgQ2x1c3RlciBsaWVnZW5kZSBRdWFkcmF0c3VtbWUgKOKAnlRvdGFsIFdpdGhpbi1DbHVzdGVyIFN1bSBvZiBTcXVhcmVz4oCcLCB0b3Qud2l0aGluc3MpIGJlcmVjaG5ldCB1bmQgZ3JhZmlzY2ggZGFyZ2VzdGVsbHQuIERlciBkYXJhdXMgZW50c3RlaGVuZGUgRWxib3ctUGxvdCB6ZWlndCwgd2llIHN0YXJrIGRpZSBIZXRlcm9nZW5pdMOkdCBpbm5lcmhhbGIgZGVyIENsdXN0ZXIgbWl0IHN0ZWlnZW5kZXIgQ2x1c3RlcnphaGwgYWJuaW1tdC4KCkRhcyBaaWVsIGRpZXNlcyBBbnNhdHplcyBpc3QgZXMsIGRlbiBQdW5rdCB6dSBpZGVudGlmaXppZXJlbiwgYW4gZGVtIGVpbmUgd2VpdGVyZSBFcmjDtmh1bmcgZGVyIENsdXN0ZXJhbnphaGwgenUga2VpbmVyIHdlc2VudGxpY2hlbiBWZXJiZXNzZXJ1bmcgbWVociBmw7xocnQuIERpZXNlciBQdW5rdCDigJMgZGVyIHNvZ2VuYW5udGUg4oCeS25pY2vigJwgb2RlciDigJ5FbGJvd+KAnCDigJMgZ2lidCBlaW5lbiBIaW53ZWlzIGRhcmF1Ziwgd2llIHZpZWxlIENsdXN0ZXIgZGllIHZvcmhhbmRlbmUgU3RydWt0dXIgZGVyIERhdGVuIGFtIGJlc3RlbiBiZXNjaHJlaWJlbi4gQXVmIGRpZXNlIFdlaXNlIGzDpHNzdCBzaWNoIGVpbmUgYXVzZ2V3b2dlbmUgQmFsYW5jZSB6d2lzY2hlbiB6dSBncm9iZXIgdW5kIHp1IGZlaW5lciBHcnVwcGllcnVuZyBmaW5kZW4uCgoKYGBge3J9Cm11bHRpLmNsdXN0IDwtIGRhdGEuZnJhbWUoayA9IDE6NCkgJT4lIGdyb3VwX2J5KGspICU+JSBkbyhjbHVzdCA9IGttZWFucyhDbHVzdGVyYW5hbHlzZSwgLiRrKSkKc3Vtc3EuY2x1c3QgPC0gbXVsdGkuY2x1c3QgJT4lIGdyb3VwX2J5KGspICU+JSBkbyhnbGFuY2UoLiRjbHVzdFtbMV1dKSkKCmdncGxvdChzdW1zcS5jbHVzdCwgYWVzKGssIHRvdC53aXRoaW5zcykpICsgZ2VvbV9saW5lKCkgKyBnZW9tX3BvaW50KCkKYGBgCgpEaWUgR3JhZmlrIHplaWd0IGRlbiBWZXJsYXVmIGRlciBnZXNhbXRlbiBpbm5lcmhhbGIgZGVyIENsdXN0ZXIgbGllZ2VuZGVuIFF1YWRyYXRzdW1tZSAodG90LndpdGhpbnNzKSBpbiBBYmjDpG5naWdrZWl0IHZvbiBkZXIgZ2V3w6RobHRlbiBDbHVzdGVyYW56YWhsIChrKS4gTWFuIGVya2VubnQgZGV1dGxpY2gsIGRhc3MgZGVyIFdlcnQgZsO8ciB0b3Qud2l0aGluc3MgYmVpbSBXZWNoc2VsIHZvbiBlaW5lbSBhdWYgendlaSBDbHVzdGVyIHN0YXJrIGFibmltbXQuIERpZXNlciBzdGFya2UgUsO8Y2tnYW5nIGJlZGV1dGV0LCBkYXNzIGR1cmNoIGRpZSBBdWZ0ZWlsdW5nIGluIHp3ZWkgQ2x1c3RlciBlaW4gR3Jvw590ZWlsIGRlciBIZXRlcm9nZW5pdMOkdCBpbm5lcmhhbGIgZGVyIEdydXBwZW4gYmVyZWl0cyBlcmtsw6RydCB3aXJkLgoKTWl0IGplZGVyIHdlaXRlcmVuIEVyaMO2aHVuZyB2b24gayBzaW5rdCBkaWUgdG90LndpdGhpbnNzIHp3YXIgd2VpdGVyLCBkZXIgWnVnZXdpbm4gYW4gSG9tb2dlbml0w6R0IGbDpGxsdCBqZWRvY2ggenVuZWhtZW5kIGdlcmluZ2VyIGF1cy4gQmVzb25kZXJzIGF1ZmbDpGxsaWcgaXN0IGRlciDigJ5Lbmlja+KAnCB6d2lzY2hlbiBrID0gMiB1bmQgayA9IDMsIGFiIGRlbSBzaWNoIGRpZSBLdXJ2ZSBhYmZsYWNodC4gRGllcyBkZXV0ZXQgZGFyYXVmIGhpbiwgZGFzcyBkaWUgV2FobCB2b24gendlaSBDbHVzdGVybiBlaW5lIHNpbm52b2xsZSBMw7ZzdW5nIGRhcnN0ZWxsdCwgZGEgenVzw6R0emxpY2hlIENsdXN0ZXIgbnVyIG5vY2ggZWluZW4gdmVyZ2xlaWNoc3dlaXNlIGdlcmluZ2VuIE1laHJ3ZXJ0IGJyaW5nZW4uCgpadXNhbW1lbmZhc3NlbmQgbMOkc3N0IHNpY2ggZmVzdGhhbHRlbiwgZGFzcyBkYXMgRWxib3ctS3JpdGVyaXVtIGhpZXIga2xhciBmw7xyIGVpbmUgWndlaS1DbHVzdGVyLUzDtnN1bmcgc3ByaWNodCwgd2VpbCBhbiBkaWVzZXIgU3RlbGxlIGRlciBncsO2w590ZSByZWxhdGl2ZSBadWdld2lubiBhbiBIb21vZ2VuaXTDpHQgZXJ6aWVsdCB3aXJkIHVuZCBkaWUgRGF0ZW4gc29taXQgZWZmaXppZW50IHVuZCBzaW5udm9sbCBncnVwcGllcnQgd2VyZGVuLgoKKip3ZWl0ZXJlIEtsw6RydW5nKioKClp1ciBncmFmaXNjaGVuIERhcnN0ZWxsdW5nIGRlciBDbHVzdGVyIGVpZ25ldCBzaWNoIGVpbiBTdHJldWRpYWdyYW1tIChTY2F0dGVycGxvdCksIGJlaSBkZW0gZGllIEbDpGxsZSBlbnRzcHJlY2hlbmQgaWhyZXIgQ2x1c3Rlcnp1Z2Vow7ZyaWdrZWl0IGZhcmJsaWNoIHVudGVyc2NoaWVkZW4gd2VyZGVuLiBEYWJlaSB3ZXJkZW4gZGllIGJlaWRlbiBhdXNnZXfDpGhsdGVuIE1lcmttYWxlIGF1ZiBkZW4gQWNoc2VuIGFiZ2V0cmFnZW4sIHVuZCBkaWUgRGF0ZW5wdW5rdGUgZXJoYWx0ZW4gdW50ZXJzY2hpZWRsaWNoZSBGYXJiZW4gb2RlciBTeW1ib2xlLCBqZSBuYWNoZGVtLCB6dSB3ZWxjaGVtIENsdXN0ZXIgc2llIGdlaMO2cmVuLiBEaWUgR3J1cHBlbnp1Z2Vow7ZyaWdrZWl0IHdpcmQgZGFiZWkgZHVyY2ggZGllIFZhcmlhYmxlIGRhcmdlc3RlbGx0LCBkaWUgZGllIENsdXN0ZXJ6dW9yZG51bmcgZW50aMOkbHQuIEF1ZiBkaWVzZSBXZWlzZSBsw6Rzc3Qgc2ljaCBkaWUgVmVydGVpbHVuZyBkZXIgQ2x1c3RlciB2aXN1ZWxsIGxlaWNodCBuYWNodm9sbHppZWhlbi4KCgoKCioqVm9yYmVyZWl0dW5nKioKYGBge3J9CkNsdXN0ZXJhbmFseXNlJFNjaHVsZSA8LSBOVUxMCnJvdy5uYW1lcyhDbHVzdGVyYW5hbHlzZSk8LSBjbHVzdGVycyRGYWxsClZpZXcoQ2x1c3RlcmFuYWx5c2UpCmBgYAoKCmBgYHtyfQpwLmNsdXN0ZXIgPC0gQ2x1c3RlcmFuYWx5c2UgJT4lIGttZWFucyguLCAyKQpwLmNsdXN0ZXIkY2x1c3RlciA8LSBhcy5mYWN0b3IocC5jbHVzdGVyJGNsdXN0ZXIpCmdncGxvdChDbHVzdGVyYW5hbHlzZSwgYWVzKEtsYXNzZW5CdWRnZXQsIGRpZ2l0YWxlcl9BdXNzdGF0dHVuZ3NzY29yZSwgbGFiZWwgPSByb3duYW1lcyhDbHVzdGVyYW5hbHlzZSkpKSArIAogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZSA9ICJDbHVzdGVyIikgICsKICBnZW9tX2xhYmVsKGFlcyhmaWxsID0gcC5jbHVzdGVyJGNsdXN0ZXIpLCBjb2xvdXIgPSAid2hpdGUiLCAKICBmb250ZmFjZSA9ICJib2xkIiwgc2l6ZT0yKQpgYGAKCgpEYXMgU3RyZXVkaWFncmFtbSB6ZWlndCBhbnNjaGF1bGljaCwgd2llIGRpZSBlaW56ZWxuZW4gRGF0ZW5wdW5rdGUgZGVuIENsdXN0ZXJuIHp1Z2VvcmRuZXQgc2luZC4gRGFiZWkgZsOkbGx0IGF1ZiwgZGFzcyBkZXIgV2VydCBmw7xyIOKAnkNFT+KAnCBtw7ZnbGljaGVyd2Vpc2UgZWluZW4gQXVzcmVpw59lciBkYXJzdGVsbHQuIE9id29obCBkaWVzZXIgRmFsbCBkZW5ub2NoIGVpbmVtIGRlciBiZWlkZW4gQ2x1c3RlciB6dWdlb3JkbmV0IHd1cmRlLCBrw7ZubnRlIG1hbiBhbHRlcm5hdGl2IGF1Y2ggw7xiZXJsZWdlbiwgaWhuIGFscyBlaWdlbmVzIENsdXN0ZXIgenUgYmVoYW5kZWxuICh6LuKAr0IuIGR1cmNoIGVpbmUgRHJlaS1DbHVzdGVyLUzDtnN1bmcpIG9kZXIgaWhuIGdhbnogYXVzIGRlciBBbmFseXNlIGF1c3p1c2NobGllw59lbi4KCgoKKipDbHVzdGVyIDEqKiB1bWZhc3N0IFNjaHVsZW4gbWl0IG5pZWRyaWdlbSBLbGFzc2VuYnVkZ2V0IHVuZCBnZXJpbmdlbSBkaWdpdGFsZW4gQXVzc3RhdHR1bmdzLVNjb3JlLiBEaWVzZSBHcnVwcGUgYmVzdGVodCBtZWlzdCBhdXMga2xlaW5lcmVuIG9kZXIgZmluYW56aWVsbCBzY2h3w6RjaGVyIGF1c2dlc3RhdHRldGVuIFNjaHVsZW4gbWl0IE5hY2hob2xiZWRhcmYgYmVpIGRlciBEaWdpdGFsaXNpZXJ1bmcuCgoqKkNsdXN0ZXIgMioqIGJlaW5oYWx0ZXQgU2NodWxlbiBtaXQgaG9oZW0gQnVkZ2V0IHVuZCBmb3J0c2Nocml0dGxpY2hlciBkaWdpdGFsZXIgQXVzc3RhdHR1bmcuIEhpZXJ6dSB6w6RobGVuIGjDpHVmaWcgZ3LDtsOfZXJlIG9kZXIgYmVzc2VyIGdlZsO2cmRlcnRlIFNjaHVsZW4sIGRpZSBiZXJlaXRzIHVtZmFzc2VuZGVyIGluIG1vZGVybmUgVGVjaG5vbG9naWVuIGludmVzdGllcnQgaGFiZW4uCgoKCiphbGxlICoKCgoKYGBge3J9Cm11bHRpLmNsdXN0IDwtIGRhdGEuZnJhbWUoayA9IDE6NSkgJT4lIGdyb3VwX2J5KGspICU+JSBkbyhjbHVzdCA9IGttZWFucyhDbHVzdGVyYW5hbHlzZSwgLiRrKSkKbXVsdGkuayA8LSBtdWx0aS5jbHVzdCAlPiUgZ3JvdXBfYnkoaykgJT4lIGRvKGF1Z21lbnQoLiRjbHVzdFtbMV1dLCBDbHVzdGVyYW5hbHlzZSkpCgpnZ3Bsb3QobXVsdGkuaywgYWVzKEtsYXNzZW5CdWRnZXQsIGRpZ2l0YWxlcl9BdXNzdGF0dHVuZ3NzY29yZSwpKSArIGdlb21fcG9pbnQoYWVzKGNvbG9yID0gLmNsdXN0ZXIpKSArIAogIGZhY2V0X3dyYXAofmspCmBgYAoKRsO8ciBkaWUgSW50ZXJwcmV0YXRpb24gdW5kIEJlc2NocmVpYnVuZyBkZXIgZ2VmdW5kZW5lbiBDbHVzdGVyIHdlcmRlbiBow6R1ZmlnIGRlc2tyaXB0aXZlIFN0YXRpc3Rpa2VuIGdlbnV0enQuIERhenUgdGVpbHQgbWFuIGRlbiBEYXRlbnNhdHogZW50c3ByZWNoZW5kIGRlciBDbHVzdGVyenVnZWjDtnJpZ2tlaXQgYXVmIHVuZCBiZXJlY2huZXQgZsO8ciBqZWRlcyBDbHVzdGVyIGJlaXNwaWVsc3dlaXNlIE1pdHRlbHdlcnRlIG9kZXIgSMOkdWZpZ2tlaXRlbiB3aWNodGlnZXIgTWVya21hbGUuIFNvIGzDpHNzdCBzaWNoIGRpZSBadXNhbW1lbnNldHp1bmcgZGVyIENsdXN0ZXIgZ2V6aWVsdCB2ZXJnbGVpY2hlbiB1bmQgY2hhcmFrdGVyaXNpZXJlbi4KCgpgYGB7cn0KQ2x1c3RlcmFuYWx5c2UkQ2x1c3RlcjIgPC0gYXMuZmFjdG9yKGN1dHJlZShoYywgayA9IDIpKQoKIyA5LiBDbHVzdGVyYmVzY2hyZWlidW5nIChNaXR0ZWx3ZXJ0ZSBqZSBDbHVzdGVyKQpjbHVzdGVyX3N1bW1hcnkgPC0gQ2x1c3RlcmFuYWx5c2UgJT4lCiAgZ3JvdXBfYnkoQ2x1c3RlcjIpICU+JQogIHN1bW1hcmlzZSgKICAgIE1pdHRlbHdlcnRfS2xhc3NlbkJ1ZGdldCA9IG1lYW4oS2xhc3NlbkJ1ZGdldCksCiAgICBNaXR0ZWx3ZXJ0X0RpZ2l0YWxTY29yZSA9IG1lYW4oZGlnaXRhbGVyX0F1c3N0YXR0dW5nc3Njb3JlKSwKICAgIEFuemFobCA9IG4oKQogICkKcHJpbnQoY2x1c3Rlcl9zdW1tYXJ5KQoKIyAxMC4gKE9wdGlvbmFsKSB0LVRlc3QgenVtIENsdXN0ZXJ2ZXJnbGVpY2gKdC50ZXN0KEtsYXNzZW5CdWRnZXQgfiBDbHVzdGVyMiwgZGF0YSA9IENsdXN0ZXJhbmFseXNlKQp0LnRlc3QoZGlnaXRhbGVyX0F1c3N0YXR0dW5nc3Njb3JlIH4gQ2x1c3RlcjIsIGRhdGEgPSBDbHVzdGVyYW5hbHlzZSkKYGBgCgoKWnVyIMOcYmVycHLDvGZ1bmcsIG9iIHNpY2ggZGllIENsdXN0ZXIgaGluc2ljaHRsaWNoIGRlcyBLbGFzc2VuYnVkZ2V0cyB1bmQgZGVzIGRpZ2l0YWxlbiBBdXNzdGF0dHVuZ3PCrXNjb3JlcyBzaWduaWZpa2FudCB1bnRlcnNjaGVpZGVuLCB3dXJkZW4gdW5hYmjDpG5naWdlIFN0aWNocHJvYmVuLXQtVGVzdHMgZHVyY2hnZWbDvGhydC4KCkbDvHIgZGFzIEtsYXNzZW5idWRnZXQgZXJnYWIgZGVyIFRlc3QgZWluZW4gc2lnbmlmaWthbnRlbiBVbnRlcnNjaGllZCB6d2lzY2hlbiBkZW4gYmVpZGVuIENsdXN0ZXJuLCB0KDExLjc5KSA9IC0zLjI2LCBwID0gLjAwNy4gRGllIG1pdHRsZXJlbiBLbGFzc2VuYnVkZ2V0cyBsYWdlbiBiZWkgQ2x1c3RlciAxIGJlaSBNID0gMzYuNTggdW5kIGJlaSBDbHVzdGVyIDIgYmVpIE0gPSA2Ny43Ni4gRGFzIDk1JS1Lb25maWRlbnppbnRlcnZhbGwgZsO8ciBkaWUgTWl0dGVsd2VydHNkaWZmZXJlbnogbGFnIHp3aXNjaGVuIC01Mi4wNSB1bmQgLTEwLjMwLgoKQXVjaCBmw7xyIGRlbiBkaWdpdGFsZW4gQXVzc3RhdHR1bmdzc2NvcmUgemVpZ3RlIHNpY2ggZWluIGhvY2hzaWduaWZpa2FudGVyIFVudGVyc2NoaWVkIHp3aXNjaGVuIGRlbiBDbHVzdGVybiwgdCg4LjA5KSA9IC01LjI5LCBwIDwgLjAwMS4gRGVyIE1pdHRlbHdlcnQgaW0gZXJzdGVuIENsdXN0ZXIgYmV0cnVnIE0gPSAxMzEuMDMsIGltIHp3ZWl0ZW4gQ2x1c3RlciBNID0gMjM5LjI0LiBEYXMgOTUlLUtvbmZpZGVuemludGVydmFsbCBmw7xyIGRpZSBNaXR0ZWx3ZXJ0c2RpZmZlcmVueiByZWljaHRlIHZvbiAtMTU1LjMwIGJpcyAtNjEuMTIuCgpJbnRlcnByZXRhdGlvbjoKRGllIEVyZ2Vibmlzc2UgemVpZ2VuLCBkYXNzIHNpY2ggZGllIGJlaWRlbiBpZGVudGlmaXppZXJ0ZW4gQ2x1c3RlciBzb3dvaGwgaW0gS2xhc3NlbmJ1ZGdldCBhbHMgYXVjaCBpbSBkaWdpdGFsZW4gQXVzc3RhdHR1bmdzZ3JhZCBzaWduaWZpa2FudCB1bnRlcnNjaGVpZGVuLgoKCgoKIyA4LglFaW5lIEF1c3NhZ2UKSW0gUmFobWVuIGRlciB2b3JsaWVnZW5kZW4gVW50ZXJzdWNodW5nIHd1cmRlIGVpbmUgaGllcmFyY2hpc2NoZSBDbHVzdGVyYW5hbHlzZSB1bnRlciBBbndlbmR1bmcgZGVyIFdhcmQtTWV0aG9kZSB1bmQgYXVmIEJhc2lzIGRlciBxdWFkcmllcnRlbiBldWtsaWRpc2NoZW4gRGlzdGFueiBkdXJjaGdlZsO8aHJ0LiBaaWVsIHdhciBlcywgZGllIHVudGVyc3VjaHRlbiBTY2h1bGVuIGFuaGFuZCBkZXIgTWVya21hbGUg4oCeS2xhc3NlbmJ1ZGdldOKAnCB1bmQg4oCeZGlnaXRhbGVyIEF1c3N0YXR0dW5ncy1TY29yZeKAnCBpbiBtw7ZnbGljaHN0IGhvbW9nZW5lIEdydXBwZW4gZWluenV0ZWlsZW4gdW5kIHNvIHZlcmJvcmdlbmUgU3RydWt0dXJlbiBpbm5lcmhhbGIgZGVzIERhdGVuc2F0emVzIHNpY2h0YmFyIHp1IG1hY2hlbi4KCkRpZSBBdXN3ZXJ0dW5nIGRlcyB6dWdlaMO2cmlnZW4gRGVuZHJvZ3JhbW1zIHVuZCBkaWUgQW53ZW5kdW5nIGRlcyBFbGJvdy1Lcml0ZXJpdW1zICh2Z2wuIEFiYmlsZHVuZyBYKSBkZXV0ZW4gZGFyYXVmIGhpbiwgZGFzcyBlaW5lIFp3ZWktQ2x1c3Rlci1Mw7ZzdW5nIGRpZSB2b3JoYW5kZW5lIEhldGVyb2dlbml0w6R0IGluIGRlbiBEYXRlbiBhbSBiZXN0ZW4gYWJiaWxkZXQuIERlciBtYXJrYW50ZXN0ZSBBbnN0aWVnIGRlciBGdXNpb25zZGlzdGFuemVuIGltIERlbmRyb2dyYW1tIGxlZ3QgbmFoZSwgZGFzcyBkaWUgWnVzYW1tZW5mYXNzdW5nIGF1ZiB6d2VpIEdydXBwZW4gc293b2hsIHN0YXRpc3Rpc2NoIHNpbm52b2xsIGFscyBhdWNoIGF1cyBpbmhhbHRsaWNoZXIgUGVyc3Bla3RpdmUgcGxhdXNpYmVsIGlzdC4KClp1ciDDnGJlcnByw7xmdW5nIGRlciBVbnRlcnNjaGllZGUgendpc2NoZW4gZGVuIENsdXN0ZXJuIHd1cmRlbiB1bmFiaMOkbmdpZ2UgU3RpY2hwcm9iZW4tdC1UZXN0cyBkdXJjaGdlZsO8aHJ0LiBEaWUgRXJnZWJuaXNzZSB6ZWlnZW4sIGRhc3Mgc2ljaCBkaWUgYmVpZGVuIENsdXN0ZXIgc2lnbmlmaWthbnQgc293b2hsIGltIEtsYXNzZW5idWRnZXQgKHQoMTEuNzkpID0gLTMuMjYsIHAgPSAuMDA3LCA5NSUtQ0kgWy01Mi4wNTsgLTEwLjMwXSkgYWxzIGF1Y2ggaW0gZGlnaXRhbGVuIEF1c3N0YXR0dW5ncy1TY29yZSAodCg4LjA5KSA9IC01LjI5LCBwIDwgLjAwMSwgOTUlLUNJIFstMTU1LjMwOyAtNjEuMTJdKSB1bnRlcnNjaGVpZGVuLiBEaWUgTWl0dGVsd2VydGUgaW4gZGVuIGJlaWRlbiBDbHVzdGVybiBsaWVnZW4gYmVpbSBLbGFzc2VuYnVkZ2V0IGJlaSBN4oKBID0gMzYuNTggKFNEIG5pY2h0IGF1c2dld2llc2VuKSB1bmQgTeKCgiA9IDY3Ljc2LCBiZWltIEF1c3N0YXR0dW5ncy1TY29yZSBiZWkgTeKCgSA9IDEzMS4wMyB1bmQgTeKCgiA9IDIzOS4yNC4gRGllIERpZmZlcmVuemVuIHNpbmQgc29taXQgc293b2hsIHN0YXRpc3Rpc2NoIHNpZ25pZmlrYW50IGFscyBhdWNoIHByYWt0aXNjaCBiZWRldXRzYW0uCgpJbnRlcnByZXRhdGlvbiBkZXIgQ2x1c3RlcnN0cnVrdHVyOgpDbHVzdGVyIDEgdW1mYXNzdCBqZW5lIFNjaHVsZW4sIGRpZSBzb3dvaGwgw7xiZXIgZWluIHVudGVyZHVyY2hzY2huaXR0bGljaGVzIEtsYXNzZW5idWRnZXQgYWxzIGF1Y2ggw7xiZXIgZWluZW4gdmVyZ2xlaWNoc3dlaXNlIG5pZWRyaWdlbiBkaWdpdGFsZW4gQXVzc3RhdHR1bmdzLVNjb3JlIHZlcmbDvGdlbi4gVHlwaXNjaGVyd2Vpc2UgZ2Vow7ZyZW4genUgZGllc2VyIEdydXBwZSBiZWlzcGllbHN3ZWlzZSBrbGVpbmVyZSBvZGVyIGZpbmFuemllbGwgd2VuaWdlciBzdGFyayBhdXNnZXN0YXR0ZXRlIFNjaHVsZW4sIGRpZSBtw7ZnbGljaGVyd2Vpc2UgaW0gQmVyZWljaCBkZXIgZGlnaXRhbGVuIEluZnJhc3RydWt0dXIgbm9jaCBFbnR3aWNrbHVuZ3NiZWRhcmYgYXVmd2Vpc2VuLgoKQ2x1c3RlciAyIGhpbmdlZ2VuIHNldHp0IHNpY2ggYXVzIFNjaHVsZW4genVzYW1tZW4sIGRpZSBzb3dvaGwgZWluIGRldXRsaWNoIGjDtmhlcmVzIEJ1ZGdldCBhbHMgYXVjaCBlaW5lIGZvcnRzY2hyaXR0bGljaGVyZSBkaWdpdGFsZSBBdXNzdGF0dHVuZyBhdWZ3ZWlzZW4uIERpZXNlIEdydXBwZSBrw7ZubnRlIHp1bSBCZWlzcGllbCBHeW1uYXNpZW4gb2RlciBTY2h1bGVuIGluIHdvaGxoYWJlbmRlcmVuIFJlZ2lvbmVuIHVtZmFzc2VuLCBiZWkgZGVuZW4gbWVociBNaXR0ZWwgZsO8ciBtb2Rlcm5lIEF1c3N0YXR0dW5nIHp1ciBWZXJmw7xndW5nIHN0ZWhlbiB1bmQgZGllIHRlbmRlbnppZWxsIGF1Y2ggdm9uIGdlemllbHRlbiBEaWdpdGFsaXNpZXJ1bmdzaW5pdGlhdGl2ZW4gcHJvZml0aWVydCBoYWJlbi4KCkRpZSBncmFmaXNjaGUgRGFyc3RlbGx1bmcgZGVyIENsdXN0ZXIgaW4gZGVyIEJhdW1zdHJ1a3R1ciBkZXMgRGVuZHJvZ3JhbW1zIHplaWd0IGRldXRsaWNoLCBkYXNzIGlubmVyaGFsYiBkZXIgYmVpZGVuIEdydXBwZW4gZWluZSBob2hlIMOEaG5saWNoa2VpdCBoaW5zaWNodGxpY2ggZGVyIGJldHJhY2h0ZXRlbiBNZXJrbWFsZSBiZXN0ZWh0LCB3w6RocmVuZCBzaWNoIGRpZSBHcnVwcGVuIHVudGVyZWluYW5kZXIga2xhciB2b25laW5hbmRlciBhYmdyZW56ZW4uIERpZXNlIEJlZnVuZGUgd2VyZGVuIGR1cmNoIGRpZSBFcmdlYm5pc3NlIGRlciB0LVRlc3RzIHdlaXRlciB1bnRlcm1hdWVydC4KClp1c2FtbWVuZmFzc2VuZCBsw6Rzc3Qgc2ljaCBmZXN0aGFsdGVuOgpEaWUgZHVyY2hnZWbDvGhydGUgQ2x1c3RlcmFuYWx5c2UgYmVzdMOkdGlndCwgZGFzcyBTY2h1bGVuIGFuaGFuZCBkZXIgYmVpZGVuIHVudGVyc3VjaHRlbiBNZXJrbWFsZSB6dXZlcmzDpHNzaWcgaW4gendlaSB1bnRlcnNjaGllZGxpY2hlIFR5cGVuIGVpbmdldGVpbHQgd2VyZGVuIGvDtm5uZW4uIERpZSBadWdlaMO2cmlna2VpdCB6dSBlaW5lbSBkZXIgYmVpZGVuIENsdXN0ZXIgaXN0IGRhYmVpIGVuZyBtaXQgZGVuIGpld2VpbGlnZW4gQXVzcHLDpGd1bmdlbiBpbiBCdWRnZXQgdW5kIERpZ2l0YWxpc2llcnVuZyB2ZXJrbsO8cGZ0LiBEaWUgQW5hbHlzZSBiaWV0ZXQgc29taXQgZWluZSBiZWxhc3RiYXJlIEdydW5kbGFnZSBmw7xyIGVpbmUgZ2V6aWVsdGUgRsO2cmRlci0gb2RlciBJbnRlcnZlbnRpb25zc3RyYXRlZ2llLCBldHdhIGluZGVtIFNjaHVsZW4gbWl0IG5pZWRyaWdlcmVtIEJ1ZGdldCB1bmQgQXVzc3RhdHR1bmdzZ3JhZCBnZXppZWx0IGluIGlocmVyIGRpZ2l0YWxlbiBFbnR3aWNrbHVuZyB1bnRlcnN0w7x0enQgd2VyZGVuLgoKCgoKCgo=