oracle 데이터를 Rstudio로 가져오는 방법
myJDBC <- JDBC("oracle.jdbc.driver.OracleDriver",
"C:\\oraclexeapp\\oracle\\product\\11.2.0\\server\\jdbc\\lib\\ojdbc6.jar")
conn <- dbConnect(myJDBC,
"jdbc:oracle:thin:@localhost:1521:xe",
"hr",
"oracle"
)
tab <- dbGetQuery(conn, "SELECT * FROM TAB")
head(tab)
tab
dplyr
filterm select, arrange, mutate,
summarise, group_by, left_join, bind_rows
tab <- data.frame(tab)
View(tab)
tname <- tab$TNAME
tname <- as.vector(tname)
tname
[1] “COUNTRIES” cnt
[2] “DEPARTMENTS” dep
[3] “EMPLOYEES” emp
[4] “EMP_DETAILS_VIEW” empd
[5] “JOBS” job
[6] “JOB_HISTORY” jobh
[7] “LOCATIONS” loc
[8] “REGIONS” reg
cnt <- data.frame(dbGetQuery(conn, "SELECT * FROM COUNTRIES"))
dep <- data.frame(dbGetQuery(conn, "SELECT * FROM DEPARTMENTS"))
emp <- data.frame(dbGetQuery(conn, "SELECT * FROM EMPLOYEES"))
empd <- data.frame(dbGetQuery(conn, "SELECT * FROM EMP_DETAILS_VIEW"))
job <- data.frame(dbGetQuery(conn, "SELECT * FROM JOBS"))
jobh <- data.frame(dbGetQuery(conn, "SELECT * FROM JOB_HISTORY"))
loc <- data.frame(dbGetQuery(conn, "SELECT * FROM LOCATIONS"))
reg <- data.frame(dbGetQuery(conn, "SELECT * FROM REGIONS"))
head(cnt)
cnt 의 컬럼명을 한글로 전환하시오. (3.5.1)
str(cnt)
# COUNTRY_ID 국가아이디,
# COUNTRY_NAME 국가명,
# REGION_ID 지역아이디
cnt <- cnt %>%
dplyr::rename(국가아이디 = COUNTRY_ID,
국가명 = COUNTRY_NAME,
지역아이디 = REGION_ID)
str(cnt)
dep 의 컬럼명 전환
str(dep)
# DEPARTMENT_ID 부서아이디,
# DEPARTMENT_NAME 부서명,
# MANAGER_ID 매니저아이디,
# LOCATION_ID 위치아이디
dep <- dep %>%
dplyr::rename(부서아이디 = DEPARTMENT_ID,
부서명 = DEPARTMENT_NAME,
매니저아이디 = MANAGER_ID,
위치아이디 = LOCATION_ID)
str(dep)
emp 의 컬럼명을 한글로 전환하시오.
그리고 First Name 과 Last Name 을
붙여서 이름 으로 된 컬럼을 추가하시오
단, 이름 간격은 띄울것. ex) James Dean
직원아이디 = EMPLOYEE_ID
이메일 = EMAIL
전화번호 = PHONE_NUMBER
채용일 = HIRE_DATE
업무아이디 = JOB_ID
연봉 = SALARY
커미션비율 = COMMISSION_PCT
매니저아이디 = MANAGER_ID
부서아이디 = DEPARTMENT_ID
str(emp)
emp <- emp %>%
dplyr::rename(직원아이디 = EMPLOYEE_ID,
이메일 = EMAIL,
전화번호 = PHONE_NUMBER,
채용일 = HIRE_DATE,
업무아이디 = JOB_ID,
연봉 = SALARY,
커미션비율 = COMMISSION_PCT,
매니저아이디 = MANAGER_ID,
부서아이디 = DEPARTMENT_ID) %>%
mutate(이름 = paste(FIRST_NAME, LAST_NAME))
View(head(emp))
필요없는 변수 삭제하기
emp <- subset(emp,select = -c(FIRST_NAME, LAST_NAME))
View(head(emp))
매달 지급하는 월급여 (연봉/12)를 보여주는 월급이라는 컬럼(변수)를 추가시키시오.
0단위 이하는 절삭
emp <- emp %>%
dplyr::mutate(월급 = 연봉 %/% 12)
emp %>% head
연봉이 10000불 이상인 사원(emp)의 목록을 이름, 직원아이디, 연봉만 구하되,
연봉 내림차순으로 보여주시오.
emp %>%
left_join(dep,by="부서아이디") %>%
filter(연봉 >= 10000) %>%
select(이름, 직원아이디, 연봉, 부서명) %>%
arrange(desc(연봉))
연봉이 3000 미만인 사원에게 보너스로 급여를 1%를 지급하겠다고 합니다.
대상자의 목록을 이름, 직원아이디, 연봉, 보너스를 기재하고
아이디 오름차순으로 보여주시오.
단, 보너스는 이번 달만 주는 것이므로
emp DF에 저장하지 않고 1회용 임시 DF를 따로 생성해서 저장하고, 기한이 지나면 폐기하시오.
보너스지급명세서<- emp %>%
filter(연봉 < 3000) %>%
dplyr::mutate(보너스 = 연봉 * 0.01) %>%
select(이름, 직원아이디, 연봉, 보너스) %>%
arrange(직원아이디)
View(보너스지급명세서)
rm(보너스지급명세서)
View(dep)
연봉이 10000 이 넘는 직원의 부서명, 이름, 연봉을 출력(get)하시오.
emp %>%
left_join(dep,by="부서아이디") %>%
filter(연봉 >= 10000) %>%
select(부서명, 이름, 연봉)
부서별로 연봉 평균을 구하시오.
dep %>%
left_join(emp,by="부서아이디") %>%
group_by(부서명, 부서아이디) %>%
dplyr::summarise(연봉평균=mean(연봉,na.rm=T)) %>%
arrange(desc(연봉평균)) %>%
View
이 회사의 부서의 수를 구하시오.
dep %>%
dplyr::distinct(부서명) %>%#distinct는 중복을 제거함.
count
연봉이 12000 이 넘는 직원의 부서명, 이름, 연봉, 직책 을 기재하시오.
job <- job %>%
rename(업무아이디 = JOB_ID,
직책 = JOB_TITLE,
최소연봉 = MIN_SALARY,
최대연봉 = MAX_SALARY
)
job %>% View
dep %>%
left_join(emp,by="부서아이디") %>%
left_join(job,by="업무아이디") %>%
filter(연봉 > 12000) %>%
select(부서명, 이름, 연봉, 직책)
emp %>%
left_join(dep,by="부서아이디") %>%
left_join(job,by="업무아이디") %>%
filter(연봉 > 12000) %>%
select(부서명, 이름, 연봉, 직책)
부서별로 가장 높은 연봉을 받는 부서아이디, 부서명, 최대연봉을 구하시오.
emp %>%
left_join(dep,by="부서아이디") %>%
left_join(job,by="업무아이디") %>%
group_by(부서아이디, 부서명) %>%
summarise(max(연봉))
부서아이디를 발급 받지 않으면 신입입니다.
신입의 이름과 연봉을 구하시오.
emp %>%
filter(is.na(emp %>% select(부서아이디))) %>%
select(이름, 연봉, 부서아이디)
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KIyMjIG9yYWNsZSDrjbDsnbTthLDrpbwgUnN0dWRpb+uhnCDqsIDsoLjsmKTripQg67Cp67KVDQoNCmBgYHtyfQ0KbXlKREJDIDwtIEpEQkMoIm9yYWNsZS5qZGJjLmRyaXZlci5PcmFjbGVEcml2ZXIiLA0KICAgICAgICAgICAgICAgIkM6XFxvcmFjbGV4ZWFwcFxcb3JhY2xlXFxwcm9kdWN0XFwxMS4yLjBcXHNlcnZlclxcamRiY1xcbGliXFxvamRiYzYuamFyIikNCmNvbm4gPC0gZGJDb25uZWN0KG15SkRCQywNCiAgICAgICAgICAgICAgICAgICJqZGJjOm9yYWNsZTp0aGluOkBsb2NhbGhvc3Q6MTUyMTp4ZSIsDQogICAgICAgICAgICAgICAgICAiaHIiLA0KICAgICAgICAgICAgICAgICAgIm9yYWNsZSINCikNCnRhYiA8LSBkYkdldFF1ZXJ5KGNvbm4sICJTRUxFQ1QgKiBGUk9NIFRBQiIpDQpoZWFkKHRhYikNCnRhYg0KYGBgDQoNCg0KDQojIyBkcGx5cg0KIyMgZmlsdGVybSBzZWxlY3QsIGFycmFuZ2UsIG11dGF0ZSwNCiMjIHN1bW1hcmlzZSwgZ3JvdXBfYnksIGxlZnRfam9pbiwgYmluZF9yb3dzDQpgYGB7cn0NCnRhYiA8LSBkYXRhLmZyYW1lKHRhYikNClZpZXcodGFiKQ0KdG5hbWUgPC0gdGFiJFROQU1FDQp0bmFtZSA8LSBhcy52ZWN0b3IodG5hbWUpDQp0bmFtZQ0KYGBgDQoNCg0KDQojIyBbMV0gIkNPVU5UUklFUyIgY250DQojIyBbMl0gIkRFUEFSVE1FTlRTIiAgZGVwDQojIyBbM10gIkVNUExPWUVFUyIgIGVtcCANCiMjIFs0XSAiRU1QX0RFVEFJTFNfVklFVyIgIGVtcGQNCiMjIFs1XSAiSk9CUyIgICAgam9iDQojIyBbNl0gIkpPQl9ISVNUT1JZIiAgam9iaA0KIyMgWzddICJMT0NBVElPTlMiICBsb2MgDQojIyBbOF0gIlJFR0lPTlMiICByZWcNCg0KYGBge3J9DQoNCmNudCA8LSBkYXRhLmZyYW1lKGRiR2V0UXVlcnkoY29ubiwgIlNFTEVDVCAqIEZST00gQ09VTlRSSUVTIikpDQpkZXAgPC0gZGF0YS5mcmFtZShkYkdldFF1ZXJ5KGNvbm4sICJTRUxFQ1QgKiBGUk9NIERFUEFSVE1FTlRTIikpDQplbXAgPC0gZGF0YS5mcmFtZShkYkdldFF1ZXJ5KGNvbm4sICJTRUxFQ1QgKiBGUk9NIEVNUExPWUVFUyIpKQ0KZW1wZCA8LSBkYXRhLmZyYW1lKGRiR2V0UXVlcnkoY29ubiwgIlNFTEVDVCAqIEZST00gRU1QX0RFVEFJTFNfVklFVyIpKQ0Kam9iIDwtIGRhdGEuZnJhbWUoZGJHZXRRdWVyeShjb25uLCAiU0VMRUNUICogRlJPTSBKT0JTIikpDQpqb2JoIDwtIGRhdGEuZnJhbWUoZGJHZXRRdWVyeShjb25uLCAiU0VMRUNUICogRlJPTSBKT0JfSElTVE9SWSIpKQ0KbG9jIDwtIGRhdGEuZnJhbWUoZGJHZXRRdWVyeShjb25uLCAiU0VMRUNUICogRlJPTSBMT0NBVElPTlMiKSkNCnJlZyA8LSBkYXRhLmZyYW1lKGRiR2V0UXVlcnkoY29ubiwgIlNFTEVDVCAqIEZST00gUkVHSU9OUyIpKQ0KaGVhZChjbnQpDQpgYGANCg0KDQojIyBjbnQg7J2YIOy7rOufvOuqheydhCDtlZzquIDroZwg7KCE7ZmY7ZWY7Iuc7JikLiAoMy41LjEpDQoNCmBgYHtyfQ0KDQpzdHIoY250KQ0KIyBDT1VOVFJZX0lEIOq1reqwgOyVhOydtOuUlCwNCiMgQ09VTlRSWV9OQU1FIOq1reqwgOuqhSwNCiMgUkVHSU9OX0lEIOyngOyXreyVhOydtOuUlA0KY250IDwtIGNudCAlPiUNCiAgZHBseXI6OnJlbmFtZSjqta3qsIDslYTsnbTrlJQgPSBDT1VOVFJZX0lELA0KICAgICAgICAgICAgICAgICAgICAg6rWt6rCA66qFID0gQ09VTlRSWV9OQU1FLA0KICAgICAgICAgICAgICAgICAgICAg7KeA7Jet7JWE7J2065SUID0gUkVHSU9OX0lEKQ0Kc3RyKGNudCkNCmBgYA0KDQoNCiMjIGRlcCDsnZgg7Lus65+866qFIOyghO2ZmA0KDQpgYGB7cn0NCnN0cihkZXApDQojIERFUEFSVE1FTlRfSUQg67aA7ISc7JWE7J2065SULA0KIyBERVBBUlRNRU5UX05BTUUg67aA7ISc66qFLA0KIyBNQU5BR0VSX0lEIOunpOuLiOyggOyVhOydtOuUlCwNCiMgTE9DQVRJT05fSUQg7JyE7LmY7JWE7J2065SUDQpkZXAgPC0gZGVwICU+JSANCiAgZHBseXI6OnJlbmFtZSjrtoDshJzslYTsnbTrlJQgPSBERVBBUlRNRU5UX0lELA0KICAgICAgICAgICAgICAgICAgICAg67aA7ISc66qFID0gREVQQVJUTUVOVF9OQU1FLA0KICAgICAgICAgICAgICAgICAgICAg66ek64uI7KCA7JWE7J2065SUID0gTUFOQUdFUl9JRCwNCiAgICAgICAgICAgICAgICAgICAgIOychOy5mOyVhOydtOuUlCA9IExPQ0FUSU9OX0lEKQ0Kc3RyKGRlcCkNCg0KDQpgYGANCg0KIyMgZW1wIOydmCDsu6zrn7zrqoXsnYQg7ZWc6riA66GcIOyghO2ZmO2VmOyLnOyYpC4NCiMjIOq3uOumrOqzoCBGaXJzdCBOYW1lIOqzvCBMYXN0IE5hbWUg7J2EDQojIyDrtpnsl6zshJwg7J2066aEIOycvOuhnCDrkJwg7Lus65+87J2EIOy2lOqwgO2VmOyLnOyYpA0KIyMg64uoLCDsnbTrpoQg6rCE6rKp7J2AIOudhOyauOqygy4gZXgpIEphbWVzIERlYW4NCiMjIOyngeybkOyVhOydtOuUlCA9IEVNUExPWUVFX0lEDQojIyDsnbTrqZTsnbwgPSBFTUFJTA0KIyMg7KCE7ZmU67KI7Zi4ID0gUEhPTkVfTlVNQkVSDQojIyDssYTsmqnsnbwgPSBISVJFX0RBVEUNCiMjIOyXheustOyVhOydtOuUlCA9IEpPQl9JRA0KIyMg7Jew67SJID0gU0FMQVJZDQojIyDsu6Trr7jshZjruYTsnKggPSBDT01NSVNTSU9OX1BDVA0KIyMg66ek64uI7KCA7JWE7J2065SUID0gTUFOQUdFUl9JRA0KIyMg67aA7ISc7JWE7J2065SUID0gREVQQVJUTUVOVF9JRA0KDQpgYGB7cn0NCnN0cihlbXApDQplbXAgPC0gZW1wICU+JQ0KICBkcGx5cjo6cmVuYW1lKOyngeybkOyVhOydtOuUlCA9IEVNUExPWUVFX0lELA0KICAgICAgICAgICAgICAgICAgICAg7J2066mU7J28ID0gRU1BSUwsDQogICAgICAgICAgICAgICAgICAgICDsoITtmZTrsojtmLggPSBQSE9ORV9OVU1CRVIsDQogICAgICAgICAgICAgICAgICAgICDssYTsmqnsnbwgPSBISVJFX0RBVEUsDQogICAgICAgICAgICAgICAgICAgICDsl4XrrLTslYTsnbTrlJQgPSBKT0JfSUQsDQogICAgICAgICAgICAgICAgICAgICDsl7DrtIkgPSBTQUxBUlksDQogICAgICAgICAgICAgICAgICAgICDsu6Trr7jshZjruYTsnKggPSBDT01NSVNTSU9OX1BDVCwNCiAgICAgICAgICAgICAgICAgICAgIOunpOuLiOyggOyVhOydtOuUlCA9IE1BTkFHRVJfSUQsDQogICAgICAgICAgICAgICAgICAgICDrtoDshJzslYTsnbTrlJQgPSBERVBBUlRNRU5UX0lEKSAlPiUNCiAgbXV0YXRlKOydtOumhCA9IHBhc3RlKEZJUlNUX05BTUUsIExBU1RfTkFNRSkpDQpWaWV3KGhlYWQoZW1wKSkNCmBgYA0KDQojIO2VhOyalOyXhuuKlCDrs4DsiJgg7IKt7KCc7ZWY6riwDQoNCg0KYGBge3J9DQplbXAgPC0gc3Vic2V0KGVtcCxzZWxlY3QgPSAtYyhGSVJTVF9OQU1FLCBMQVNUX05BTUUpKQ0KVmlldyhoZWFkKGVtcCkpIA0KYGBgDQoNCiMg66ek64usIOyngOq4ie2VmOuKlCDsm5TquInsl6wgKOyXsOu0iS8xMinrpbwg67O07Jes7KO864qUIOyblOq4ieydtOudvOuKlCDsu6zrn7wo67OA7IiYKeulvCDstpTqsIDsi5ztgqTsi5zsmKQuDQojIDDri6jsnIQg7J207ZWY64qUIOygiOyCrQ0KDQpgYGB7cn0NCg0KZW1wIDwtIGVtcCAlPiUgDQogIGRwbHlyOjptdXRhdGUo7JuU6riJID0g7Jew67SJICUvJSAxMikNCmVtcCAlPiUgaGVhZA0KDQpgYGANCg0KIyDsl7DrtInsnbQgMTAwMDDrtogg7J207IOB7J24IOyCrOybkChlbXAp7J2YIOuqqeuhneydhCDsnbTrpoQsIOyngeybkOyVhOydtOuUlCwg7Jew67SJ66eMIOq1rO2VmOuQmCwNCiMg7Jew67SJIOuCtOumvOywqOyInOycvOuhnCDrs7Tsl6zso7zsi5zsmKQuDQoNCmBgYHtyfQ0KZW1wICU+JSANCiAgbGVmdF9qb2luKGRlcCxieT0i67aA7ISc7JWE7J2065SUIikgJT4lIA0KICBmaWx0ZXIo7Jew67SJID49IDEwMDAwKSAlPiUgDQogIHNlbGVjdCjsnbTrpoQsIOyngeybkOyVhOydtOuUlCwg7Jew67SJLCDrtoDshJzrqoUpICU+JSANCiAgYXJyYW5nZShkZXNjKOyXsOu0iSkpDQpgYGANCg0KIyDsl7DrtInsnbQgMzAwMCDrr7jrp4zsnbgg7IKs7JuQ7JeQ6rKMIOuztOuEiOyKpOuhnCDquInsl6zrpbwgMSXrpbwg7KeA6riJ7ZWY6rKg64uk6rOgIO2VqeuLiOuLpC4NCiMg64yA7IOB7J6Q7J2YIOuqqeuhneydhCDsnbTrpoQsIOyngeybkOyVhOydtOuUlCwg7Jew67SJLCDrs7TrhIjsiqTrpbwg6riw7J6s7ZWY6rOgDQojIOyVhOydtOuUlCDsmKTrpoTssKjsiJzsnLzroZwg67O07Jes7KO87Iuc7JikLg0KIyDri6gsIOuztOuEiOyKpOuKlCDsnbTrsogg64us66eMIOyjvOuKlCDqsoPsnbTrr4DroZwNCiMgZW1wIERG7JeQIOyggOyepe2VmOyngCDslYrqs6AgMe2ajOyaqSDsnoTsi5wgREbrpbwg65Sw66GcIOyDneyEse2VtOyEnCDsoIDsnqXtlZjqs6AsIOq4sO2VnOydtCDsp4DrgpjrqbQg7Y+Q6riw7ZWY7Iuc7JikLg0KDQpgYGB7cn0NCuuztOuEiOyKpOyngOq4ieuqheyEuOyEnDwtIGVtcCAlPiUgDQogIGZpbHRlcijsl7DrtIkgPCAzMDAwKSAlPiUgDQogIGRwbHlyOjptdXRhdGUo67O064SI7IqkID0g7Jew67SJICogMC4wMSkgJT4lIA0KICBzZWxlY3Qo7J2066aELCDsp4Hsm5DslYTsnbTrlJQsIOyXsOu0iSwg67O064SI7IqkKSAlPiUgDQogIGFycmFuZ2Uo7KeB7JuQ7JWE7J2065SUKQ0KVmlldyjrs7TrhIjsiqTsp4DquInrqoXshLjshJwpDQpybSjrs7TrhIjsiqTsp4DquInrqoXshLjshJwpDQpWaWV3KGRlcCkNCmBgYA0KIyDsl7DrtInsnbQgMTAwMDAg7J20IOuEmOuKlCDsp4Hsm5DsnZgg67aA7ISc66qFLCDsnbTrpoQsIOyXsOu0ieydhCDstpzroKUoZ2V0Ke2VmOyLnOyYpC4NCg0KDQpgYGB7cn0NCmVtcCAlPiUNCiAgbGVmdF9qb2luKGRlcCxieT0i67aA7ISc7JWE7J2065SUIikgJT4lIA0KICBmaWx0ZXIo7Jew67SJID49IDEwMDAwKSAlPiUNCiAgc2VsZWN0KOu2gOyEnOuqhSwg7J2066aELCDsl7DrtIkpDQoNCmBgYA0KDQojIOu2gOyEnOuzhOuhnCDsl7DrtIkg7Y+J6reg7J2EIOq1rO2VmOyLnOyYpC4NCg0KYGBge3J9DQpkZXAgJT4lDQogIGxlZnRfam9pbihlbXAsYnk9Iuu2gOyEnOyVhOydtOuUlCIpICU+JQ0KICBncm91cF9ieSjrtoDshJzrqoUsIOu2gOyEnOyVhOydtOuUlCkgJT4lDQogIGRwbHlyOjpzdW1tYXJpc2Uo7Jew67SJ7Y+J6regPW1lYW4o7Jew67SJLG5hLnJtPVQpKSAlPiUgDQogIGFycmFuZ2UoZGVzYyjsl7DrtIntj4nqt6ApKSAlPiUgDQogIFZpZXcNCg0KYGBgDQojIOydtCDtmozsgqzsnZgg67aA7ISc7J2YIOyImOulvCDqtaztlZjsi5zsmKQuDQoNCmBgYHtyfQ0KZGVwICU+JQ0KICBkcGx5cjo6ZGlzdGluY3Qo67aA7ISc66qFKSAlPiUjZGlzdGluY3TripQg7KSR67O17J2EIOygnOqxsO2VqC4NCiAgY291bnQNCg0KYGBgDQoNCiMg7Jew67SJ7J20IDEyMDAwIOydtCDrhJjripQg7KeB7JuQ7J2YIOu2gOyEnOuqhSwg7J2066aELCDsl7DrtIksIOyngeyxhSDsnYQg6riw7J6s7ZWY7Iuc7JikLg0KDQpgYGB7cn0NCmpvYiA8LSBqb2IgJT4lIA0KICByZW5hbWUo7JeF66y07JWE7J2065SUID0gSk9CX0lELA0KICAgICAgICAgICAgICDsp4HssYUgPSBKT0JfVElUTEUsDQogICAgICAgICAgICAgIOy1nOyGjOyXsOu0iSA9IE1JTl9TQUxBUlksDQogICAgICAgICAgICAgIOy1nOuMgOyXsOu0iSA9IE1BWF9TQUxBUlkNCiAgKQ0Kam9iICU+JSBWaWV3DQoNCmRlcCAlPiUgDQogIGxlZnRfam9pbihlbXAsYnk9Iuu2gOyEnOyVhOydtOuUlCIpICU+JSANCiAgbGVmdF9qb2luKGpvYixieT0i7JeF66y07JWE7J2065SUIikgJT4lIA0KICBmaWx0ZXIo7Jew67SJID4gMTIwMDApICU+JSANCiAgc2VsZWN0KOu2gOyEnOuqhSwg7J2066aELCDsl7DrtIksIOyngeyxhSkNCg0KZW1wICU+JQ0KICBsZWZ0X2pvaW4oZGVwLGJ5PSLrtoDshJzslYTsnbTrlJQiKSAlPiUNCiAgbGVmdF9qb2luKGpvYixieT0i7JeF66y07JWE7J2065SUIikgJT4lDQogIGZpbHRlcijsl7DrtIkgPiAxMjAwMCkgJT4lIA0KICBzZWxlY3Qo67aA7ISc66qFLCDsnbTrpoQsIOyXsOu0iSwg7KeB7LGFKQ0KDQpgYGANCg0KDQojIOu2gOyEnOuzhOuhnCDqsIDsnqUg64aS7J2AIOyXsOu0ieydhCDrsJvripQg67aA7ISc7JWE7J2065SULCDrtoDshJzrqoUsIOy1nOuMgOyXsOu0ieydhCDqtaztlZjsi5zsmKQuDQoNCmBgYHtyfQ0KZW1wICU+JQ0KICBsZWZ0X2pvaW4oZGVwLGJ5PSLrtoDshJzslYTsnbTrlJQiKSAlPiUNCiAgbGVmdF9qb2luKGpvYixieT0i7JeF66y07JWE7J2065SUIikgJT4lDQogIGdyb3VwX2J5KOu2gOyEnOyVhOydtOuUlCwg67aA7ISc66qFKSAlPiUgDQogIHN1bW1hcmlzZShtYXgo7Jew67SJKSkNCmBgYA0KDQoNCiMg67aA7ISc7JWE7J2065SU66W8IOuwnOq4iSDrsJvsp4Ag7JWK7Jy866m0IOyLoOyeheyeheuLiOuLpC4NCiMg7Iug7J6F7J2YIOydtOumhOqzvCDsl7DrtInsnYQg6rWs7ZWY7Iuc7JikLg0KDQoNCmBgYHtyfQ0KZW1wICU+JSANCiAgZmlsdGVyKGlzLm5hKGVtcCAlPiUgc2VsZWN0KOu2gOyEnOyVhOydtOuUlCkpKSAlPiUgDQogIHNlbGVjdCjsnbTrpoQsIOyXsOu0iSwg67aA7ISc7JWE7J2065SUKQ0KDQpgYGANCg0K