This project tries to answer which state and induatry is the best place to work in America, by analyzing working hours and wage data by states and industries. It mainly can be divided into 3 part.
1.General Analysis
What’s the working environment in America? Data analysis and visualization of the average working hours and wage by different states. In this part, we are going to explore which state provides the best environment for working speaking of wages, working hours and thereby the hour salary.
2.Occupations and Industries Analysis
Which job or industry is the best to work for? To find the best occupation and industry to work on. In this part, we are going to study the attributions of each occupation. Does the job require high education? How long people of the job work? How is the salary? Is the job a popular choice?
3.Computer and Mathmatical Occupations Analysis
If I stay with what I learnt, where should I go? From the former part, it turns outh that CMM(Computer and Mathmatical Occupations) looks like the best occupation for us to do. So in this part we going forward to focusing on the computer and Mathmatical Occupations and research on the working hours and wage by different states, in order to find the best place for us to go.
Set up the Bench
library(readr)
library(dplyr)
library(maps)
library(leaflet)
library(rbokeh)
library(fmsb)
Read Data
setwd("C:/Users/Administrator/Desktop/ADS/Proj 1/Data")
The working directory was changed to C:/Users/Administrator/Desktop/ADS/Proj 1/Data inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the the working directory for notebook chunks.
load(".RData")
#a14=read_csv("ss14pusa.csv")
#b14=read_csv("ss14pusb.csv")
#all14=rbind(a14,b14)
#rm(a14);rm(b14)
#gc();Sys.sleep(10);gc() #To make sure clean all memory in case of crash
ST_name=read.csv("statenames.csv") #The redundant space in abbr column has been removed in Excel
occupa=read.csv("OCCP.csv")
Clean Dataset
#selct=select(all14,OCCP,ST,WAGP,AGEP,JWMNP,ESR,SCHL,SEX,WKHP,NAICSP,PWGTP,POWSP,POWPUMA)%>%
# na.omit()%>%
# mutate(WAGP=as.numeric(WAGP),
# AGEP=as.numeric(AGEP),
# WKHP=as.numeric(WKHP),
# JWMNP=as.numeric(JWMNP),
# PWGTP=as.numeric(PWGTP),
# ST=as.integer(ST),
# SCHL=as.integer(SCHL),
# SEX=as.integer(SEX),
# OCCP=as.integer(OCCP))%>%
# merge(occupa,by="OCCP")
group_ST=group_by(selct,ST)
sumrz_ST=summarise(group_ST,
Meanwage=weighted.mean(WAGP,w=PWGTP),
MeanAGEP=weighted.mean(AGEP,w=PWGTP),
MeanWKHP=weighted.mean(WKHP,w=PWGTP),
MeanJWMNP=weighted.mean(JWMNP,w=PWGTP)
)%>%
mutate(ST.map=match((ST_name$abbr[-52]),state.fips$abb,nomatch=99))%>%
#use the cleaned statename.csv file or will crash here, also OCCP.csv must be correct
mutate(abb=state.fips$abb[ST.map])%>%
arrange(ST.map)
map.data=merge(state.fips,sumrz_ST,by="abb",all=T)%>%
arrange(ST.map)
Data Analysis and Visualization
1.General Analysis: What’s the working environment in America?
Average Annual Wage by States
Figure 1.Map for Average Wage
This graph shows the distribution of the average wage of different states. The darker the color is, the higher the average wage is. Generally speaking, coast region has a higher wage. As it shows, The Northeast region has a higher salaries than the rest part of the contries. The west coast also shows higher wage tendency. Colorado, Minnesota and Illinois also stand out from the middle. Colorado has a reputation on its aerospace and aviation industry. Apart from agriculture, Minnesota has a strong root of bioscience, is one of the biggest cribs of medical profesionals. Chicago as the third biggest city in USA definitely contributes on the deeper color of Illinois in this graph.
In this graph, it seems that better to work in coast area. But wait! What about the working hour? If you have to work all days long to earn a relatively high wage, it will be a silly decision. So we need to go further and see the working hour.
Average Working Hours per week by States
Figure 2.Map for Average Working Hour
This Graph shows the average working hours by different state. The darker the color is, the longer one have to work in this state. The states which shows longer averagely working hours are most likely depends on agriculture industry. Surprisingly, New York people is not the most hard working people among the country.
What!? The lower wage areas have longer working hour? That is crazy. Too unfair. But for us, just let it be and see what we can utilize from this funny fact.
The idea is simple, just look at hour salary, that is, salary earned per hour.(Indeed it doesn’t have to be “per hour”, it could be per minute or per 37 seconds. We just need to compare them in the same scale and done.)
Work Life balance Ratio by States
Figure 3.Map for Hour Salary
In the graph, the darker the color is, the higher hour salary the state earns.
Laziness is human nature. Don’t you want a job which pays tons of money and only requireds you show up at work for an hour on Friday before you head out? We calculated work life balance ratio by working hours and wage. Apparently, people who works “in the office” and have higher education generally have a sweeter life. But the problem is the data shows smaller diversities of working hours among the states, so this graph’s data is mainly dominant by the wage differences.
From this graph, it shows we shall definitely choose the northeast coast and second west coast. But is it too simple? Yes! Alghough the analysis above does provide some key insight in the general working environment and answer the question that is it a busy poor state, which one should concern for his generally welfare, we forget the occupation per se. There are some job we cannot do due to our present education background. So let take a detour and choose a nice job which we can apply now.
2.Occupations and Industries Analysis: Which job or industry is the best to work for?
Regroup Data by Occupations and Industries
group_OCCPABB=group_by(selct,OCCABB)
sumrz_OCCPABB=summarise(group_OCCPABB,
Meanwage=weighted.mean(WAGP,w=PWGTP),
MeanAGEP=weighted.mean(AGEP,w=PWGTP),
MeanWKHP=weighted.mean(WKHP,w=PWGTP),
MeanJWMNP=weighted.mean(JWMNP,w=PWGTP),
MeanSCHL=weighted.mean(SCHL,w=PWGTP),
MeanSEX=weighted.mean(SEX,w=PWGTP),
Count=sum(PWGTP),
JOBNAME=NOTE[1]
)
group_OCCP=group_by(selct,OCCP)
sumrz_OCCP=summarise(group_OCCP,
Meanwage=weighted.mean(WAGP,w=PWGTP),
MeanAGEP=weighted.mean(AGEP,w=PWGTP),
MeanWKHP=weighted.mean(WKHP,w=PWGTP),
MeanJWMNP=weighted.mean(JWMNP,w=PWGTP),
MeanSCHL=weighted.mean(SCHL,w=PWGTP),
MeanSEX=weighted.mean(SEX,w=PWGTP),
Count=sum(PWGTP),
JOBNAME=OCCUPATION[1]
)
Occupations and Industries Working Conditions Comparison
n <- nrow(sumrz_OCCP)
ramp <- colorNumeric(
palette = "Blues",
domain = sumrz_OCCP$MeanSCHL
)
options(viewer = NULL)
figure() %>%
ly_points(x=Meanwage,y=MeanWKHP, hover=JOBNAME,color = ramp(sumrz_OCCP$MeanSCHL), size = 30*Count/max(Count),data=sumrz_OCCP) %>%
tool_box_select() %>%
tool_lasso_select()%>%
x_axis("Average Wage",number_formatter = "numeral", format = "0,000")%>%
y_axis("Average Working Hour",number_formatter = "numeral", format = "0,000")
Figure 4. Occupation Attribution (By Occupation)
The color stands for education level, darker means higher level. Size indicates the amount of people doing this job.
Physicians and surgens won the best paid occupation without a doubt, and their wage is way higher than other occupations. All other managing and legal related occupations appear a lead speaking of wage. But we cannot do that since we learn only data science. Maybe it will be more helpful to categorize the jobs and look at them in a broader view.
figure() %>%
ly_points(x=Meanwage,y=MeanWKHP, hover=JOBNAME,color = ramp(sumrz_OCCPABB$MeanSCHL), size = Count/min(Count),data=sumrz_OCCPABB) %>%
tool_box_select() %>%
tool_lasso_select()%>%
x_axis("Average Wage",number_formatter = "numeral", format = "0,000")%>%
y_axis("Average Working Hour",number_formatter = "numeral", format = "0,000")
Figure 5. Occupation Attribution (By Category)
The color stands for education level, darker means higher level. Size indicates the amount of people doing this job.
Among all the occupations, legal occupations won the best paid occupation. Business and Managing occupations have the best work life balance. Finance, engineering and computer mathmatical occupations are pretty close to managing roles speaking of working hours and wages. In general, the graph illustrates the old saying, no pain no gain.
So now where we stand? From the graph, the rightest dot which we can choose turns out to be CMM(Computer and Mathmatical Occupations) after a while of examination. So now let’s focus on CMM and repeat the job we have done in PART 1.
3.Where can WE(statistician) choose?
Figure 6. Map for Average Wage (Occupation Category: CMM-Computer and Mathematical Occupations)
According to the map, Northeast including New York City, California and Washiton’s computer and mathematical occupaitions are the best place for data scientists, programmer or statistians to work where provides the best work life balance. Since most of tech companies who requires more computer and mathmatical profesionals are located in northeat cities and the west coasts. Contrast with part 1, WA pops out as the best salary state for CMM.
Figure 7. Map for Average Working Hour (Occupation Category: CMM-Computer and Mathematical Occupations)
Nice enough, WA does not lie in the most tiring class. Let’s also see the hour salary.
Figure 8.Map for Hour Salary (Occupation Category: CMM-Computer and Mathematical Occupations)
According to the map, Northeast including New York City, California and Washiton’s computer and mathematical occupaitions are the best place for data scientists, programmer or statistians to work where provides the best work life balance. Since most of tech companies who requires more computer and mathmatical profesionals are located in northeat cities and the west coasts.
So, finally we can learn something: Definitely go to WA if you can. If not, NJ or CA also seem pretty good. But now after reading this, obsolutely don’t go to NV, AR and WY.
The end.
LS0tDQp0aXRsZTogIldoZXJlIHRvIEZpbmQgdGhlIEJlc3QgSm9iPyINCm91dHB1dDoNCiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdA0KICBodG1sX2RvY3VtZW50OiBkZWZhdWx0DQogIHBkZl9kb2N1bWVudDogZGVmYXVsdA0KLS0tDQpUaGlzIHByb2plY3QgdHJpZXMgdG8gYW5zd2VyIHdoaWNoIHN0YXRlIGFuZCBpbmR1YXRyeSBpcyB0aGUgYmVzdCBwbGFjZSB0byB3b3JrIGluIEFtZXJpY2EsIGJ5IGFuYWx5emluZyB3b3JraW5nIGhvdXJzIGFuZCB3YWdlIGRhdGEgYnkgc3RhdGVzIGFuZCBpbmR1c3RyaWVzLiBJdCBtYWlubHkgY2FuIGJlIGRpdmlkZWQgaW50byAzIHBhcnQuDQoNCiMjIyMxLkdlbmVyYWwgQW5hbHlzaXMgICAgICAgICAgICAgICAgDQoqV2hhdCdzIHRoZSB3b3JraW5nIGVudmlyb25tZW50IGluIEFtZXJpY2E/KiBEYXRhIGFuYWx5c2lzIGFuZCB2aXN1YWxpemF0aW9uIG9mIHRoZSBhdmVyYWdlIHdvcmtpbmcgaG91cnMgYW5kIHdhZ2UgYnkgZGlmZmVyZW50IHN0YXRlcy4gSW4gdGhpcyBwYXJ0LCB3ZSBhcmUgZ29pbmcgdG8gZXhwbG9yZSB3aGljaCBzdGF0ZSBwcm92aWRlcyB0aGUgYmVzdCBlbnZpcm9ubWVudCBmb3Igd29ya2luZyBzcGVha2luZyBvZiB3YWdlcywgd29ya2luZyBob3VycyBhbmQgdGhlcmVieSB0aGUgaG91ciBzYWxhcnkuDQogICAgICAgDQojIyMjMi5PY2N1cGF0aW9ucyBhbmQgSW5kdXN0cmllcyBBbmFseXNpcyAgICAgDQoqV2hpY2ggam9iIG9yIGluZHVzdHJ5IGlzIHRoZSBiZXN0IHRvIHdvcmsgZm9yPyogVG8gZmluZCB0aGUgYmVzdCBvY2N1cGF0aW9uIGFuZCBpbmR1c3RyeSB0byB3b3JrIG9uLiBJbiB0aGlzIHBhcnQsIHdlIGFyZSBnb2luZyB0byBzdHVkeSB0aGUgYXR0cmlidXRpb25zIG9mIGVhY2ggb2NjdXBhdGlvbi4gRG9lcyB0aGUgam9iIHJlcXVpcmUgaGlnaCBlZHVjYXRpb24/IEhvdyBsb25nIHBlb3BsZSBvZiB0aGUgam9iIHdvcms/IEhvdyBpcyB0aGUgc2FsYXJ5PyBJcyB0aGUgam9iIGEgcG9wdWxhciBjaG9pY2U/DQogICAgICAgICAgDQojIyMjMy5Db21wdXRlciBhbmQgTWF0aG1hdGljYWwgT2NjdXBhdGlvbnMgQW5hbHlzaXMNCipJZiBJIHN0YXkgd2l0aCB3aGF0IEkgbGVhcm50LCB3aGVyZSBzaG91bGQgSSBnbz8qIEZyb20gdGhlIGZvcm1lciBwYXJ0LCBpdCB0dXJucyBvdXRoIHRoYXQgQ01NKENvbXB1dGVyIGFuZCBNYXRobWF0aWNhbCBPY2N1cGF0aW9ucykgbG9va3MgbGlrZSB0aGUgYmVzdCBvY2N1cGF0aW9uIGZvciB1cyB0byBkby4gU28gaW4gdGhpcyBwYXJ0IHdlIGdvaW5nIGZvcndhcmQgdG8gZm9jdXNpbmcgb24gdGhlIGNvbXB1dGVyIGFuZCBNYXRobWF0aWNhbCBPY2N1cGF0aW9ucyBhbmQgcmVzZWFyY2ggb24gdGhlIHdvcmtpbmcgaG91cnMgYW5kIHdhZ2UgYnkgZGlmZmVyZW50IHN0YXRlcywgaW4gb3JkZXIgdG8gZmluZCB0aGUgYmVzdCBwbGFjZSBmb3IgdXMgdG8gZ28uDQoNCiAgICAgICANCiMjU2V0IHVwIHRoZSBCZW5jaA0KDQpgYGB7ciBsaWIsbWVzc2FnZT1GQUxTRX0NCmxpYnJhcnkocmVhZHIpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShtYXBzKQ0KbGlicmFyeShsZWFmbGV0KQ0KbGlicmFyeShyYm9rZWgpDQpsaWJyYXJ5KGZtc2IpDQpgYGANCg0KIyNSZWFkIERhdGENCg0KYGBge3IgdG9sb2FkLG1lc3NhZ2U9RkFMU0V9DQpzZXR3ZCgiQzovVXNlcnMvQWRtaW5pc3RyYXRvci9EZXNrdG9wL0FEUy9Qcm9qIDEvRGF0YSIpDQpsb2FkKCIuUkRhdGEiKQ0KI2ExND1yZWFkX2Nzdigic3MxNHB1c2EuY3N2IikNCiNiMTQ9cmVhZF9jc3YoInNzMTRwdXNiLmNzdiIpDQojYWxsMTQ9cmJpbmQoYTE0LGIxNCkNCiNybShhMTQpO3JtKGIxNCkNCiNnYygpO1N5cy5zbGVlcCgxMCk7Z2MoKSAjVG8gbWFrZSBzdXJlIGNsZWFuIGFsbCBtZW1vcnkgaW4gY2FzZSBvZiBjcmFzaA0KU1RfbmFtZT1yZWFkLmNzdigic3RhdGVuYW1lcy5jc3YiKSAjVGhlIHJlZHVuZGFudCBzcGFjZSBpbiBhYmJyIGNvbHVtbiBoYXMgYmVlbiByZW1vdmVkIGluIEV4Y2VsDQpvY2N1cGE9cmVhZC5jc3YoIk9DQ1AuY3N2IikNCmBgYA0KDQojI0NsZWFuIERhdGFzZXQNCg0KYGBge3J9DQojc2VsY3Q9c2VsZWN0KGFsbDE0LE9DQ1AsU1QsV0FHUCxBR0VQLEpXTU5QLEVTUixTQ0hMLFNFWCxXS0hQLE5BSUNTUCxQV0dUUCxQT1dTUCxQT1dQVU1BKSU+JQ0KIyAgICAgIG5hLm9taXQoKSU+JQ0KIyAgICAgIG11dGF0ZShXQUdQPWFzLm51bWVyaWMoV0FHUCksDQojICAgICAgICAgICAgIEFHRVA9YXMubnVtZXJpYyhBR0VQKSwNCiMgICAgICAgICAgICAgV0tIUD1hcy5udW1lcmljKFdLSFApLA0KIyAgICAgICAgICAgICBKV01OUD1hcy5udW1lcmljKEpXTU5QKSwNCiMgICAgICAgICAgICAgUFdHVFA9YXMubnVtZXJpYyhQV0dUUCksDQojICAgICAgICAgICAgIFNUPWFzLmludGVnZXIoU1QpLA0KIyAgICAgICAgICAgICBTQ0hMPWFzLmludGVnZXIoU0NITCksDQojICAgICAgICAgICAgIFNFWD1hcy5pbnRlZ2VyKFNFWCksDQojICAgICAgICAgICAgIE9DQ1A9YXMuaW50ZWdlcihPQ0NQKSklPiUNCiMgICAgICAgbWVyZ2Uob2NjdXBhLGJ5PSJPQ0NQIikNCmdyb3VwX1NUPWdyb3VwX2J5KHNlbGN0LFNUKQ0Kc3VtcnpfU1Q9c3VtbWFyaXNlKGdyb3VwX1NULA0KICAgICAgICAgICAgICAgICAgIE1lYW53YWdlPXdlaWdodGVkLm1lYW4oV0FHUCx3PVBXR1RQKSwNCiAgICAgICAgICAgICAgICAgICBNZWFuQUdFUD13ZWlnaHRlZC5tZWFuKEFHRVAsdz1QV0dUUCksDQogICAgICAgICAgICAgICAgICAgTWVhbldLSFA9d2VpZ2h0ZWQubWVhbihXS0hQLHc9UFdHVFApLA0KICAgICAgICAgICAgICAgICAgIE1lYW5KV01OUD13ZWlnaHRlZC5tZWFuKEpXTU5QLHc9UFdHVFApDQogICAgICAgICAgICAgICAgICAgICklPiUNCiAgICAgICAgICBtdXRhdGUoU1QubWFwPW1hdGNoKChTVF9uYW1lJGFiYnJbLTUyXSksc3RhdGUuZmlwcyRhYmIsbm9tYXRjaD05OSkpJT4lIA0KICAgICAgICAgICN1c2UgdGhlIGNsZWFuZWQgc3RhdGVuYW1lLmNzdiBmaWxlIG9yIHdpbGwgY3Jhc2ggaGVyZSwgYWxzbyBPQ0NQLmNzdiBtdXN0IGJlIGNvcnJlY3QNCiAgICAgICAgICBtdXRhdGUoYWJiPXN0YXRlLmZpcHMkYWJiW1NULm1hcF0pJT4lDQogICAgICAgICAgYXJyYW5nZShTVC5tYXApDQptYXAuZGF0YT1tZXJnZShzdGF0ZS5maXBzLHN1bXJ6X1NULGJ5PSJhYmIiLGFsbD1UKSU+JQ0KICAgICAgICAgYXJyYW5nZShTVC5tYXApDQpgYGANCg0KIyNEYXRhIEFuYWx5c2lzIGFuZCBWaXN1YWxpemF0aW9uDQoNCiMjIzEuR2VuZXJhbCBBbmFseXNpczogV2hhdCdzIHRoZSB3b3JraW5nIGVudmlyb25tZW50IGluIEFtZXJpY2E/DQoNCiMjIyNBdmVyYWdlIEFubnVhbCBXYWdlIGJ5IFN0YXRlcw0KDQpbRmlndXJlIDEuTWFwIGZvciBBdmVyYWdlIFdhZ2VdKGh0dHA6Ly9ycHVicy5jb20vRGF0YUtpbmcvTWFwMSkNCg0KVGhpcyBncmFwaCBzaG93cyB0aGUgZGlzdHJpYnV0aW9uIG9mIHRoZSBhdmVyYWdlIHdhZ2Ugb2YgZGlmZmVyZW50IHN0YXRlcy4gVGhlIGRhcmtlciB0aGUgY29sb3IgaXMsIHRoZSBoaWdoZXIgdGhlIGF2ZXJhZ2Ugd2FnZSBpcy4gR2VuZXJhbGx5IHNwZWFraW5nLCBfY29hc3QgcmVnaW9uXyBoYXMgYSBoaWdoZXIgd2FnZS4gQXMgaXQgc2hvd3MsIF9UaGUgTm9ydGhlYXN0IHJlZ2lvbl8gIGhhcyBhIGhpZ2hlciBzYWxhcmllcyB0aGFuIHRoZSByZXN0IHBhcnQgb2YgdGhlIGNvbnRyaWVzLiBfVGhlIHdlc3QgY29hc3RfIGFsc28gc2hvd3MgaGlnaGVyIHdhZ2UgdGVuZGVuY3kuIF9Db2xvcmFkbywgTWlubmVzb3RhIGFuZCBJbGxpbm9pc18gYWxzbyBzdGFuZCBvdXQgZnJvbSB0aGUgbWlkZGxlLiBDb2xvcmFkbyBoYXMgYSByZXB1dGF0aW9uIG9uIGl0cyBhZXJvc3BhY2UgYW5kIGF2aWF0aW9uIGluZHVzdHJ5LiBBcGFydCBmcm9tIGFncmljdWx0dXJlLCBNaW5uZXNvdGEgaGFzIGEgc3Ryb25nIHJvb3Qgb2YgYmlvc2NpZW5jZSwgaXMgb25lIG9mIHRoZSBiaWdnZXN0IGNyaWJzIG9mIG1lZGljYWwgcHJvZmVzaW9uYWxzLiBDaGljYWdvIGFzIHRoZSB0aGlyZCBiaWdnZXN0IGNpdHkgaW4gVVNBIGRlZmluaXRlbHkgY29udHJpYnV0ZXMgb24gdGhlIGRlZXBlciBjb2xvciBvZiBJbGxpbm9pcyBpbiB0aGlzIGdyYXBoLiANCg0KSW4gdGhpcyBncmFwaCwgaXQgc2VlbXMgdGhhdCBiZXR0ZXIgdG8gd29yayBpbiBjb2FzdCBhcmVhLiBCdXQgd2FpdCEgV2hhdCBhYm91dCB0aGUgd29ya2luZyBob3VyPyBJZiB5b3UgaGF2ZSB0byB3b3JrIGFsbCBkYXlzIGxvbmcgdG8gZWFybiBhIHJlbGF0aXZlbHkgaGlnaCB3YWdlLCBpdCB3aWxsIGJlIGEgc2lsbHkgZGVjaXNpb24uIFNvIHdlIG5lZWQgdG8gZ28gZnVydGhlciBhbmQgc2VlIHRoZSB3b3JraW5nIGhvdXIuDQoNCiMjIyNBdmVyYWdlIFdvcmtpbmcgSG91cnMgcGVyIHdlZWsgYnkgU3RhdGVzDQoNCltGaWd1cmUgMi5NYXAgZm9yIEF2ZXJhZ2UgV29ya2luZyBIb3VyXShodHRwOi8vcnB1YnMuY29tL0RhdGFLaW5nL01hcDIpDQoNClRoaXMgR3JhcGggc2hvd3MgdGhlIGF2ZXJhZ2Ugd29ya2luZyBob3VycyBieSBkaWZmZXJlbnQgc3RhdGUuIFRoZSBkYXJrZXIgdGhlIGNvbG9yIGlzLCB0aGUgbG9uZ2VyIG9uZSBoYXZlIHRvIHdvcmsgaW4gdGhpcyBzdGF0ZS4gVGhlIHN0YXRlcyB3aGljaCBzaG93cyBsb25nZXIgYXZlcmFnZWx5IHdvcmtpbmcgaG91cnMgYXJlIG1vc3QgbGlrZWx5IGRlcGVuZHMgb24gYWdyaWN1bHR1cmUgaW5kdXN0cnkuIFN1cnByaXNpbmdseSwgTmV3IFlvcmsgcGVvcGxlIGlzIG5vdCB0aGUgbW9zdCBoYXJkIHdvcmtpbmcgcGVvcGxlIGFtb25nIHRoZSBjb3VudHJ5Lg0KDQpXaGF0IT8gVGhlIGxvd2VyIHdhZ2UgYXJlYXMgaGF2ZSBsb25nZXIgd29ya2luZyBob3VyPyBUaGF0IGlzIGNyYXp5LiBUb28gdW5mYWlyLiBCdXQgZm9yIHVzLCBqdXN0IGxldCBpdCBiZSBhbmQgc2VlIHdoYXQgd2UgY2FuIHV0aWxpemUgZnJvbSB0aGlzIGZ1bm55IGZhY3QuDQoNClRoZSBpZGVhIGlzIHNpbXBsZSwganVzdCBsb29rIGF0IGhvdXIgc2FsYXJ5LCB0aGF0IGlzLCBzYWxhcnkgZWFybmVkIHBlciBob3VyLihJbmRlZWQgaXQgZG9lc24ndCBoYXZlIHRvIGJlICJwZXIgaG91ciIsIGl0IGNvdWxkIGJlIHBlciBtaW51dGUgb3IgcGVyIDM3IHNlY29uZHMuIFdlIGp1c3QgbmVlZCB0byBjb21wYXJlIHRoZW0gaW4gdGhlIHNhbWUgc2NhbGUgYW5kIGRvbmUuKQ0KDQoNCiMjIyNXb3JrIExpZmUgYmFsYW5jZSBSYXRpbyBieSBTdGF0ZXMNCg0KW0ZpZ3VyZSAzLk1hcCBmb3IgSG91ciBTYWxhcnldKGh0dHA6Ly9ycHVicy5jb20vRGF0YUtpbmcvTWFwMykNCg0KSW4gdGhlIGdyYXBoLCB0aGUgZGFya2VyIHRoZSBjb2xvciBpcywgdGhlIGhpZ2hlciBob3VyIHNhbGFyeSB0aGUgc3RhdGUgZWFybnMuDQoNCkxhemluZXNzIGlzIGh1bWFuIG5hdHVyZS4gRG9uJ3QgeW91IHdhbnQgYSBqb2Igd2hpY2ggcGF5cyB0b25zIG9mIG1vbmV5IGFuZCBvbmx5IHJlcXVpcmVkcyB5b3Ugc2hvdyB1cCBhdCB3b3JrIGZvciBhbiBob3VyIG9uIEZyaWRheSBiZWZvcmUgeW91IGhlYWQgb3V0PyBXZSBjYWxjdWxhdGVkIHdvcmsgbGlmZSBiYWxhbmNlIHJhdGlvIGJ5IHdvcmtpbmcgaG91cnMgYW5kIHdhZ2UuIEFwcGFyZW50bHksIHBlb3BsZSB3aG8gd29ya3MgImluIHRoZSBvZmZpY2UiIGFuZCBoYXZlIGhpZ2hlciBlZHVjYXRpb24gZ2VuZXJhbGx5IGhhdmUgYSBzd2VldGVyIGxpZmUuIEJ1dCB0aGUgcHJvYmxlbSBpcyB0aGUgZGF0YSBzaG93cyBzbWFsbGVyIGRpdmVyc2l0aWVzIG9mIHdvcmtpbmcgaG91cnMgYW1vbmcgdGhlIHN0YXRlcywgc28gdGhpcyBncmFwaCdzIGRhdGEgaXMgbWFpbmx5IGRvbWluYW50IGJ5IHRoZSB3YWdlIGRpZmZlcmVuY2VzLiANCg0KRnJvbSB0aGlzIGdyYXBoLCBpdCBzaG93cyB3ZSBzaGFsbCBkZWZpbml0ZWx5IGNob29zZSB0aGUgbm9ydGhlYXN0IGNvYXN0IGFuZCBzZWNvbmQgd2VzdCBjb2FzdC4gQnV0IGlzIGl0IHRvbyBzaW1wbGU/IFllcyEgQWxnaG91Z2ggdGhlIGFuYWx5c2lzIGFib3ZlIGRvZXMgcHJvdmlkZSBzb21lIGtleSBpbnNpZ2h0IGluIHRoZSBnZW5lcmFsIHdvcmtpbmcgZW52aXJvbm1lbnQgYW5kIGFuc3dlciB0aGUgcXVlc3Rpb24gdGhhdCBpcyBpdCBhIGJ1c3kgcG9vciBzdGF0ZSwgd2hpY2ggb25lIHNob3VsZCBjb25jZXJuIGZvciBoaXMgZ2VuZXJhbGx5IHdlbGZhcmUsIHdlIGZvcmdldCB0aGUgb2NjdXBhdGlvbiBwZXIgc2UuIFRoZXJlIGFyZSBzb21lIGpvYiB3ZSBjYW5ub3QgZG8gZHVlIHRvIG91ciBwcmVzZW50IGVkdWNhdGlvbiBiYWNrZ3JvdW5kLiBTbyBsZXQgdGFrZSBhIGRldG91ciBhbmQgY2hvb3NlIGEgbmljZSBqb2Igd2hpY2ggd2UgY2FuIGFwcGx5IG5vdy4NCg0KIyMjMi5PY2N1cGF0aW9ucyBhbmQgSW5kdXN0cmllcyBBbmFseXNpczogV2hpY2ggam9iIG9yIGluZHVzdHJ5IGlzIHRoZSBiZXN0IHRvIHdvcmsgZm9yPyANCg0KIyMjI1JlZ3JvdXAgRGF0YSBieSBPY2N1cGF0aW9ucyBhbmQgSW5kdXN0cmllcw0KYGBge3J9DQpncm91cF9PQ0NQQUJCPWdyb3VwX2J5KHNlbGN0LE9DQ0FCQikNCnN1bXJ6X09DQ1BBQkI9c3VtbWFyaXNlKGdyb3VwX09DQ1BBQkIsDQogICAgICAgICAgICAgICAgICAgTWVhbndhZ2U9d2VpZ2h0ZWQubWVhbihXQUdQLHc9UFdHVFApLA0KICAgICAgICAgICAgICAgICAgIE1lYW5BR0VQPXdlaWdodGVkLm1lYW4oQUdFUCx3PVBXR1RQKSwNCiAgICAgICAgICAgICAgICAgICBNZWFuV0tIUD13ZWlnaHRlZC5tZWFuKFdLSFAsdz1QV0dUUCksDQogICAgICAgICAgICAgICAgICAgTWVhbkpXTU5QPXdlaWdodGVkLm1lYW4oSldNTlAsdz1QV0dUUCksDQogICAgICAgICAgICAgICAgICAgTWVhblNDSEw9d2VpZ2h0ZWQubWVhbihTQ0hMLHc9UFdHVFApLA0KICAgICAgICAgICAgICAgICAgIE1lYW5TRVg9d2VpZ2h0ZWQubWVhbihTRVgsdz1QV0dUUCksDQogICAgICAgICAgICAgICAgICAgQ291bnQ9c3VtKFBXR1RQKSwNCiAgICAgICAgICAgICAgICAgICBKT0JOQU1FPU5PVEVbMV0NCikNCg0KZ3JvdXBfT0NDUD1ncm91cF9ieShzZWxjdCxPQ0NQKQ0Kc3VtcnpfT0NDUD1zdW1tYXJpc2UoZ3JvdXBfT0NDUCwNCiAgICAgICAgICAgICAgICAgICAgICAgIE1lYW53YWdlPXdlaWdodGVkLm1lYW4oV0FHUCx3PVBXR1RQKSwNCiAgICAgICAgICAgICAgICAgICAgICAgIE1lYW5BR0VQPXdlaWdodGVkLm1lYW4oQUdFUCx3PVBXR1RQKSwNCiAgICAgICAgICAgICAgICAgICAgICAgIE1lYW5XS0hQPXdlaWdodGVkLm1lYW4oV0tIUCx3PVBXR1RQKSwNCiAgICAgICAgICAgICAgICAgICAgICAgIE1lYW5KV01OUD13ZWlnaHRlZC5tZWFuKEpXTU5QLHc9UFdHVFApLA0KICAgICAgICAgICAgICAgICAgICAgICAgTWVhblNDSEw9d2VpZ2h0ZWQubWVhbihTQ0hMLHc9UFdHVFApLA0KICAgICAgICAgICAgICAgICAgICAgICAgTWVhblNFWD13ZWlnaHRlZC5tZWFuKFNFWCx3PVBXR1RQKSwNCiAgICAgICAgICAgICAgICAgICAgICAgIENvdW50PXN1bShQV0dUUCksDQogICAgICAgICAgICAgICAgICAgICAgICBKT0JOQU1FPU9DQ1VQQVRJT05bMV0NCikNCg0KYGBgDQoNCiMjIyNPY2N1cGF0aW9ucyBhbmQgSW5kdXN0cmllcyBXb3JraW5nIENvbmRpdGlvbnMgQ29tcGFyaXNvbg0KDQpgYGB7cn0NCm4gPC0gbnJvdyhzdW1yel9PQ0NQKQ0KcmFtcCA8LSBjb2xvck51bWVyaWMoDQogIHBhbGV0dGUgPSAiQmx1ZXMiLA0KICBkb21haW4gPSBzdW1yel9PQ0NQJE1lYW5TQ0hMDQopDQpvcHRpb25zKHZpZXdlciA9IE5VTEwpDQpgYGANCmBgYHtyfQ0KZmlndXJlKCkgJT4lDQogIGx5X3BvaW50cyh4PU1lYW53YWdlLHk9TWVhbldLSFAsIGhvdmVyPUpPQk5BTUUsY29sb3IgPSByYW1wKHN1bXJ6X09DQ1AkTWVhblNDSEwpLCBzaXplID0gMzAqQ291bnQvbWF4KENvdW50KSxkYXRhPXN1bXJ6X09DQ1ApICU+JQ0KICB0b29sX2JveF9zZWxlY3QoKSAlPiUNCiAgdG9vbF9sYXNzb19zZWxlY3QoKSU+JQ0KICB4X2F4aXMoIkF2ZXJhZ2UgV2FnZSIsbnVtYmVyX2Zvcm1hdHRlciA9ICJudW1lcmFsIiwgZm9ybWF0ID0gIjAsMDAwIiklPiUNCiAgeV9heGlzKCJBdmVyYWdlIFdvcmtpbmcgSG91ciIsbnVtYmVyX2Zvcm1hdHRlciA9ICJudW1lcmFsIiwgZm9ybWF0ID0gIjAsMDAwIikNCmBgYA0KDQpGaWd1cmUgNC4gT2NjdXBhdGlvbiBBdHRyaWJ1dGlvbiAoQnkgT2NjdXBhdGlvbikNCg0KVGhlIGNvbG9yIHN0YW5kcyBmb3IgZWR1Y2F0aW9uIGxldmVsLCBkYXJrZXIgbWVhbnMgaGlnaGVyIGxldmVsLiBTaXplIGluZGljYXRlcyB0aGUgYW1vdW50IG9mIHBlb3BsZSBkb2luZyB0aGlzIGpvYi4NCg0KUGh5c2ljaWFucyBhbmQgc3VyZ2VucyB3b24gdGhlIGJlc3QgcGFpZCBvY2N1cGF0aW9uIHdpdGhvdXQgYSBkb3VidCwgYW5kIHRoZWlyIHdhZ2UgaXMgd2F5IGhpZ2hlciB0aGFuIG90aGVyIG9jY3VwYXRpb25zLiBBbGwgb3RoZXIgbWFuYWdpbmcgYW5kIGxlZ2FsIHJlbGF0ZWQgb2NjdXBhdGlvbnMgYXBwZWFyIGEgbGVhZCBzcGVha2luZyBvZiB3YWdlLiBCdXQgd2UgY2Fubm90IGRvIHRoYXQgc2luY2Ugd2UgbGVhcm4gb25seSBkYXRhIHNjaWVuY2UuIE1heWJlIGl0IHdpbGwgYmUgbW9yZSBoZWxwZnVsIHRvIGNhdGVnb3JpemUgdGhlIGpvYnMgYW5kIGxvb2sgYXQgdGhlbSBpbiBhIGJyb2FkZXIgdmlldy4NCg0KDQoNCmBgYHtyfQ0KZmlndXJlKCkgJT4lDQogIGx5X3BvaW50cyh4PU1lYW53YWdlLHk9TWVhbldLSFAsIGhvdmVyPUpPQk5BTUUsY29sb3IgPSByYW1wKHN1bXJ6X09DQ1BBQkIkTWVhblNDSEwpLCBzaXplID0gQ291bnQvbWluKENvdW50KSxkYXRhPXN1bXJ6X09DQ1BBQkIpICU+JQ0KICB0b29sX2JveF9zZWxlY3QoKSAlPiUNCiAgdG9vbF9sYXNzb19zZWxlY3QoKSU+JQ0KICB4X2F4aXMoIkF2ZXJhZ2UgV2FnZSIsbnVtYmVyX2Zvcm1hdHRlciA9ICJudW1lcmFsIiwgZm9ybWF0ID0gIjAsMDAwIiklPiUNCiAgeV9heGlzKCJBdmVyYWdlIFdvcmtpbmcgSG91ciIsbnVtYmVyX2Zvcm1hdHRlciA9ICJudW1lcmFsIiwgZm9ybWF0ID0gIjAsMDAwIikNCg0KYGBgDQoNCkZpZ3VyZSA1LiBPY2N1cGF0aW9uIEF0dHJpYnV0aW9uIChCeSBDYXRlZ29yeSkNCg0KVGhlIGNvbG9yIHN0YW5kcyBmb3IgZWR1Y2F0aW9uIGxldmVsLCBkYXJrZXIgbWVhbnMgaGlnaGVyIGxldmVsLiBTaXplIGluZGljYXRlcyB0aGUgYW1vdW50IG9mIHBlb3BsZSBkb2luZyB0aGlzIGpvYi4NCg0KQW1vbmcgYWxsIHRoZSBvY2N1cGF0aW9ucywgbGVnYWwgb2NjdXBhdGlvbnMgd29uIHRoZSBiZXN0IHBhaWQgb2NjdXBhdGlvbi4gQnVzaW5lc3MgYW5kIE1hbmFnaW5nIG9jY3VwYXRpb25zIGhhdmUgdGhlIGJlc3Qgd29yayBsaWZlIGJhbGFuY2UuIEZpbmFuY2UsIGVuZ2luZWVyaW5nIGFuZCBjb21wdXRlciBtYXRobWF0aWNhbCBvY2N1cGF0aW9ucyBhcmUgcHJldHR5IGNsb3NlIHRvIG1hbmFnaW5nIHJvbGVzIHNwZWFraW5nIG9mIHdvcmtpbmcgaG91cnMgYW5kIHdhZ2VzLiBJbiBnZW5lcmFsLCB0aGUgZ3JhcGggaWxsdXN0cmF0ZXMgdGhlIG9sZCBzYXlpbmcsIG5vIHBhaW4gbm8gZ2Fpbi4NCg0KU28gbm93IHdoZXJlIHdlIHN0YW5kPyBGcm9tIHRoZSBncmFwaCwgdGhlIHJpZ2h0ZXN0IGRvdCB3aGljaCB3ZSBjYW4gY2hvb3NlIHR1cm5zIG91dCB0byBiZSBDTU0oQ29tcHV0ZXIgYW5kIE1hdGhtYXRpY2FsIE9jY3VwYXRpb25zKSBhZnRlciBhIHdoaWxlIG9mIGV4YW1pbmF0aW9uLiBTbyBub3cgbGV0J3MgZm9jdXMgb24gQ01NIGFuZCByZXBlYXQgdGhlIGpvYiB3ZSBoYXZlIGRvbmUgaW4gUEFSVCAxLg0KDQojIyMzLldoZXJlIGNhbiBXRShzdGF0aXN0aWNpYW4pIGNob29zZT8NCg0KW0ZpZ3VyZSA2LiBNYXAgZm9yIEF2ZXJhZ2UgV2FnZSAoT2NjdXBhdGlvbiBDYXRlZ29yeTogQ01NLUNvbXB1dGVyIGFuZCBNYXRoZW1hdGljYWwgT2NjdXBhdGlvbnMpXShodHRwOi8vcnB1YnMuY29tL0RhdGFLaW5nL01hcDQpDQoNCkFjY29yZGluZyB0byB0aGUgbWFwLCBOb3J0aGVhc3QgaW5jbHVkaW5nIE5ldyBZb3JrIENpdHksIENhbGlmb3JuaWEgYW5kIFdhc2hpdG9uJ3MgY29tcHV0ZXIgYW5kIG1hdGhlbWF0aWNhbCBvY2N1cGFpdGlvbnMgYXJlIHRoZSBiZXN0IHBsYWNlIGZvciBkYXRhIHNjaWVudGlzdHMsIHByb2dyYW1tZXIgb3Igc3RhdGlzdGlhbnMgdG8gd29yayB3aGVyZSBwcm92aWRlcyB0aGUgYmVzdCB3b3JrIGxpZmUgYmFsYW5jZS4gU2luY2UgbW9zdCBvZiB0ZWNoIGNvbXBhbmllcyB3aG8gcmVxdWlyZXMgbW9yZSBjb21wdXRlciBhbmQgbWF0aG1hdGljYWwgcHJvZmVzaW9uYWxzIGFyZSBsb2NhdGVkIGluIG5vcnRoZWF0IGNpdGllcyBhbmQgdGhlIHdlc3QgY29hc3RzLiBDb250cmFzdCB3aXRoIHBhcnQgMSwgV0EgcG9wcyBvdXQgYXMgdGhlIGJlc3Qgc2FsYXJ5IHN0YXRlIGZvciBDTU0uDQoNCltGaWd1cmUgNy4gTWFwIGZvciBBdmVyYWdlIFdvcmtpbmcgSG91ciAoT2NjdXBhdGlvbiBDYXRlZ29yeTogQ01NLUNvbXB1dGVyIGFuZCBNYXRoZW1hdGljYWwgT2NjdXBhdGlvbnMpXShodHRwOi8vcnB1YnMuY29tL0RhdGFLaW5nL01hcDUpDQoNCk5pY2UgZW5vdWdoLCBXQSBkb2VzIG5vdCBsaWUgaW4gdGhlIG1vc3QgdGlyaW5nIGNsYXNzLiBMZXQncyBhbHNvIHNlZSB0aGUgaG91ciBzYWxhcnkuDQoNCg0KW0ZpZ3VyZSA4Lk1hcCBmb3IgSG91ciBTYWxhcnkgKE9jY3VwYXRpb24gQ2F0ZWdvcnk6IENNTS1Db21wdXRlciBhbmQgTWF0aGVtYXRpY2FsIE9jY3VwYXRpb25zKV0oaHR0cDovL3JwdWJzLmNvbS9EYXRhS2luZy9NYXA2KQ0KDQpBY2NvcmRpbmcgdG8gdGhlIG1hcCwgTm9ydGhlYXN0IGluY2x1ZGluZyBOZXcgWW9yayBDaXR5LCBDYWxpZm9ybmlhIGFuZCBXYXNoaXRvbidzIGNvbXB1dGVyIGFuZCBtYXRoZW1hdGljYWwgb2NjdXBhaXRpb25zIGFyZSB0aGUgYmVzdCBwbGFjZSBmb3IgZGF0YSBzY2llbnRpc3RzLCBwcm9ncmFtbWVyIG9yIHN0YXRpc3RpYW5zIHRvIHdvcmsgd2hlcmUgcHJvdmlkZXMgdGhlIGJlc3Qgd29yayBsaWZlIGJhbGFuY2UuIFNpbmNlIG1vc3Qgb2YgdGVjaCBjb21wYW5pZXMgd2hvIHJlcXVpcmVzIG1vcmUgY29tcHV0ZXIgYW5kIG1hdGhtYXRpY2FsIHByb2Zlc2lvbmFscyBhcmUgbG9jYXRlZCBpbiBub3J0aGVhdCBjaXRpZXMgYW5kIHRoZSB3ZXN0IGNvYXN0cy4NCg0KU28sIGZpbmFsbHkgd2UgY2FuIGxlYXJuIHNvbWV0aGluZzogRGVmaW5pdGVseSBnbyB0byBXQSBpZiB5b3UgY2FuLiBJZiBub3QsIE5KIG9yIENBIGFsc28gc2VlbSBwcmV0dHkgZ29vZC4gQnV0IG5vdyBhZnRlciByZWFkaW5nIHRoaXMsIG9ic29sdXRlbHkgZG9uJ3QgZ28gdG8gTlYsIEFSIGFuZCBXWS4NCg0KVGhlIGVuZC4=