<?php
$page_title = 'Run temp analysis';
require('../directoryinfo.php');
include('../connect.php');
include('functions.php');
require_once('../header.html');
?>
<!-- Form For Executing Code -->
<form action="map_figure.php" method="post" name="file_select">
<fieldset>
<table align="left" cellspacing=15>
<tr><td colspan="2"><input type="checkbox" checked name="go" value="yes"><STRONG>draw map</STRONG></td></tr>
<tr><td colspan=2><input type="submit" name="submit" value="Submit"></td></tr>
</table>
</fieldset>
</form>
<?php
if(isset($_POST['go'])) {
$q_time_scale = "SELECT interval_name, age_bottom, age_top, intervals.id FROM intervals
WHERE interval_name IN ('Whiterock', 'Chazyan', 'Blackriverian', 'Shermanian', 'Richmondian', 'Hirnantian', 'Rhuddanian', 'Aeronian', 'Telychian', 'Wenlock')
ORDER BY age_bottom";
$time_scale = mysqli_query($connect_macrostrat, $q_time_scale);
if($row['interval_name'] == 'Blackriverian') {
$int_name[] = 'Blackriveran-Kirkfield';
$int_bottom[] = $row['age_bottom'];
$int_top[] = 457.0000;
} else if($row['interval_name'] == 'Shermanian') {
$int_name[] = 'Shermanian-Maysvillian';
$int_bottom[] = $row['age_bottom'];
$int_top[] = 450.0000;
} else {
$int_name[] = $row['interval_name'];
$int_bottom[] = $row['age_bottom'];
$int_top[] = $row['age_top'];
}
$int_id[] = $row['id'];
}
$n_int = count($int_name);
$base_ordovician = 488.3;
$study_max = max($int_bottom); $study_min = min($int_top);
//////////////
//
// Column data saved as columns.csv
//
//////////////
$q = "SELECT cols.id FROM cols
INNER JOIN col_groups ON col_groups.id=col_group_id
INNER JOIN projects ON projects.id=project_id
WHERE project LIKE 'North America' AND col_group NOT LIKE 'Mexico' AND cols.id NOT IN (34, 111, 139, 218, 586, 587) AND status_code='active'";
//////////////
//
// get packages
//
//////////////
$temp_pkg = split_packages('marine');
for($i=0; $i<count($temp_pkg); ++$i) { $q = "SELECT col_id, max(b.age_bottom) bottom, min(t.age_top) top, count(distinct units.id) n_unit FROM units
INNER JOIN intervals b ON b.id=FO
INNER JOIN intervals t ON t.id=LO
WHERE units.id IN ($temp_pkg[$i])";
if(in_array($row['col_id'], $my_cols)===TRUE && $row['bottom']>$study_min && $row['top']<$study_max) $my_pkg[] = $temp_pkg[$i]; }
//////////////
//
// units saved as O_S_units.csv
//
//////////////
$units_file = "O_S_units.csv";
$fh = fopen($units_file, 'w') or
die("can't open file"); chmod($units_file, 0777); $file_row = "unit_id, col_id, age_bottom, age_top, color\n";
$q = "SELECT units.id, col_id, b.age_bottom, t.age_top, color FROM units
INNER JOIN intervals b ON b.id=FO
INNER JOIN intervals t ON t.id=LO
WHERE units.id IN (".$all_units.") and b.age_bottom>$study_min AND t.age_top<$study_max"; //echo $q."<br>";
$file_row = $row['id'].",".$row['col_id'].",".$row['age_bottom'].",".$row['age_top'].",".$row['color']."\n";
}
echo 'File <a href="'.$units_file.'">'.$units_file.'</a> saved<BR>';
//////////////
//
// pbdb_collections saved as O_S_collections.csv
//
//////////////
$fh = fopen("collections.csv", "r"); $my_collections = fgetcsv($fh, 100000, ",") echo "There are ".count($data)." collections<br>";
$pbdb_file = "O_S_collections.csv";
$fh = fopen($pbdb_file, 'w') or
die("can't open file"); $file_row = "collection_no, unit_id, lat, lng\n";
$q = "SELECT collection_no, unit_id, lat, lng FROM pbdb_matches
WHERE collection_no IN (".implode(",",$my_collections).")"; $file_row = $row['collection_no'].",".$row['unit_id'].",".$row['lat'].",".$row['lng']."\n";
}
echo 'File <a href="'.$pbdb_file.'">'.$pbdb_file.'</a> saved<BR>';
//////////////
//
// draw map in R
//
//////////////
$r_file = "temp.r";
$fh = fopen($r_file, 'w') or
die("can't open file");
$r_script = "
source('myFunctions.r')
library(maps)
library(mapproj)
time.scale <- read.csv(file='time_scale.csv', header=TRUE); n.bins <- nrow(time.scale)
units <- read.csv(file='O_S_units.csv', header=TRUE)
polygons <- read.csv(file='column_polygons.csv', header=TRUE)
pbdb <- read.csv(file='O_S_collections.csv', header=TRUE)
## make maps
lon.limit <- c(-172,-50)
lat.limit <- c(25,83)
map.orient <- c(54,-103,0)
map.data <- map('world', c('USA', 'Canada'), xlim=lon.limit, ylim=lat.limit, proj='azequalarea',orient=map.orient, plot=FALSE, interior=FALSE)
map.color <- 'gray25' # solid dark gray
pbdb.color <- rgb(1,0,0,0.3) # transparent red
rock.colors <- matrix(NA, nrow=15, ncol=3)
rock.colors[,1] <- c('blue','gray light','tan','orange','yellow','blue green','pink','brown dark','green dark','brown','green light','brown light','blue dark','gray','green')
rock.colors[,2] <- c('#6BA1FF','#7C7C7C','#9A9469','#FF8400','#FFFF00','#00FFFF','#FF80A8','#55432F','#008800','#55432F','#008800','#55432F','#3838FF','#7C7C7C','#008800')
rock.colors[,3] <- c('carbonate','fine clastics','mixed clastics','coarse clastics','sands','chert','evaporite','metamorphic','plutonic','metamorphic','volcanic','metamorphic','mixed carb/clast','fine clastics','volcanics')
rock.colors <- rock.colors[order(rock.colors[,1]),]
top.units <- vector(mode='numeric', length=nrow(units)); counter <- 1
pdf(file='map_figure.pdf', height=20, width=50)
par(mfrow=c(2,5), mar=c(0,0,10,0)+0.1, pch=16, cex.main=7)
for(i in n.bins:1) {
unit.temp <- units[units[,3]>time.scale[i,3] & units[,4]<time.scale[i,2],]
cols.temp <- unique(unit.temp\$col_id)
pbdb.temp <- unique(pbdb[is.element(pbdb\$unit_id, unit.temp\$unit_id),3:4])
plot(map.data, main=time.scale[i,1], axes=FALSE, frame.plot=TRUE, type='n', xlab='', ylab='')
# plot macrostrat units
for(j in 1:length(cols.temp)) {
top.units[counter] <- unit.temp[unit.temp\$col_id==cols.temp[j],1][1]
color.temp <- rock.colors[match(unit.temp[unit.temp\$col_id==cols.temp[j],5][1], rock.colors[,1]),2]
poly.temp <- polygons[polygons[,1]==cols.temp[j],2:3]
poly.proj <- mapproject(list(x=poly.temp[,1], y=poly.temp[,2]))
polygon(poly.proj\$x, poly.proj\$y, col=paste(color.temp), border=paste(color.temp), lwd=0.5)
counter <- counter + 1
}
# plot pbdb
if(nrow(pbdb.temp) > 0) {
pbdb.proj <- mapproject(list(x=pbdb.temp[,2], y=pbdb.temp[,1]))
points(pbdb.proj\$x, pbdb.proj\$y, cex=3, col=pbdb.color)
}
lines(map.data\$x, map.data\$y, col=map.color)
}
dev.off()
top.units <- top.units[top.units>0]
rock.colors2 <- rock.colors[match(unique(units[is.element(units[,1], top.units), 5]),rock.colors[,1]),]
## make legend
pdf(file='map_legend.pdf', height=6, width=10)
layout(matrix(1:15, nrow=3, ncol=5, byrow=TRUE))
for(i in 1:nrow(rock.colors2)) {
par(mar=c(0.1,0.1,0.1,0.1))
plot(1:10, xlim=c(0,10), ylim=c(0,10), type='n', axes=FALSE, frame.plot=TRUE, xlab='', ylab='')
rect(1,1,9,4, col=paste(rock.colors2[i,2]))
text(5,8, labels=rock.colors2[i,1], cex=1.5)
text(5,6, labels=rock.colors2[i,3], cex=1.5)
}
dev.off()
";
$cmd = "echo 'rscript <- \"$r_file\"; source(rscript)' | " . "/usr/bin/R --slave 2>&1";
}
echo 'File <a href="map_figure.pdf" target="blank">map_figure.pdf</a> saved<BR>';
echo 'File <a href="map_legend.pdf" target="blank">map_legend.pdf</a> saved<BR>';
}
//////////////
//
// stuff at the end
//
//////////////
if(isset($_POST['submit'])) { $time_diff = $t1 - $t0;
if ($time_diff/60 < 1) {
$diff_seconds = round($time_diff, 3); echo "<br>This process took ".$diff_seconds." seconds";
} else if ($time_diff>=1 & $time_diff<3600) {
$diff_min = round($time_diff/60, 3); echo "<br>This process took ".$diff_min." minutes";
} else {
$diff_hour = round($time_diff/3600, 3); echo "<br>This process took ".$diff_hour." hours";
}
}
?>
<?php
require_once('../footer.html');
?>
PD9waHAKCSRwYWdlX3RpdGxlID0gJ1J1biB0ZW1wIGFuYWx5c2lzJzsKCXJlcXVpcmUoJy4uL2RpcmVjdG9yeWluZm8ucGhwJyk7CglpbmNsdWRlKCcuLi9jb25uZWN0LnBocCcpOwoJaW5jbHVkZSgnZnVuY3Rpb25zLnBocCcpOwoJcmVxdWlyZV9vbmNlKCcuLi9oZWFkZXIuaHRtbCcpOwo/PgoKPCEtLSBGb3JtIEZvciBFeGVjdXRpbmcgQ29kZSAtLT4KPGZvcm0gYWN0aW9uPSJtYXBfZmlndXJlLnBocCIgbWV0aG9kPSJwb3N0IiBuYW1lPSJmaWxlX3NlbGVjdCI+Cgk8ZmllbGRzZXQ+CgkKCTx0YWJsZSBhbGlnbj0ibGVmdCIgY2VsbHNwYWNpbmc9MTU+CgkJPHRyPjx0ZCBjb2xzcGFuPSIyIj48aW5wdXQgdHlwZT0iY2hlY2tib3giIGNoZWNrZWQgbmFtZT0iZ28iIHZhbHVlPSJ5ZXMiPjxTVFJPTkc+ZHJhdyBtYXA8L1NUUk9ORz48L3RkPjwvdHI+CgkJPHRyPjx0ZCBjb2xzcGFuPTI+PGlucHV0IHR5cGU9InN1Ym1pdCIgbmFtZT0ic3VibWl0IiB2YWx1ZT0iU3VibWl0Ij48L3RkPjwvdHI+Cgk8L3RhYmxlPgoJPC9maWVsZHNldD4KPC9mb3JtPgoKPD9waHAKCWVycm9yX3JlcG9ydGluZyhFX0FMTCk7CQoJaWYoaXNzZXQoJF9QT1NUWydnbyddKSkgewoJCSR0MCA9IG1pY3JvdGltZSh0cnVlKTsKCQkKCQkkcV90aW1lX3NjYWxlID0gIlNFTEVDVCBpbnRlcnZhbF9uYW1lLCBhZ2VfYm90dG9tLCBhZ2VfdG9wLCBpbnRlcnZhbHMuaWQgRlJPTSBpbnRlcnZhbHMgCgkJV0hFUkUgaW50ZXJ2YWxfbmFtZSBJTiAoJ1doaXRlcm9jaycsICdDaGF6eWFuJywgJ0JsYWNrcml2ZXJpYW4nLCAnU2hlcm1hbmlhbicsICdSaWNobW9uZGlhbicsICdIaXJuYW50aWFuJywgJ1JodWRkYW5pYW4nLCAnQWVyb25pYW4nLCAnVGVseWNoaWFuJywgJ1dlbmxvY2snKQoJCU9SREVSIEJZIGFnZV9ib3R0b20iOwoJCSR0aW1lX3NjYWxlID0gbXlzcWxpX3F1ZXJ5KCRjb25uZWN0X21hY3Jvc3RyYXQsICRxX3RpbWVfc2NhbGUpOyAgICAgICAgIAoJCSRuX2JpbiA9IG15c3FsaV9udW1fcm93cygkdGltZV9zY2FsZSk7CgkJCgkJd2hpbGUoJHJvdyA9IG15c3FsaV9mZXRjaF9hc3NvYygkdGltZV9zY2FsZSkpIHsJCQkKCQkJaWYoJHJvd1snaW50ZXJ2YWxfbmFtZSddID09ICdCbGFja3JpdmVyaWFuJykgewoJCQkJJGludF9uYW1lW10gPSAnQmxhY2tyaXZlcmFuLUtpcmtmaWVsZCc7CgkJCQkkaW50X2JvdHRvbVtdID0gJHJvd1snYWdlX2JvdHRvbSddOwoJCQkJJGludF90b3BbXSA9IDQ1Ny4wMDAwOwoJCQl9IGVsc2UgaWYoJHJvd1snaW50ZXJ2YWxfbmFtZSddID09ICdTaGVybWFuaWFuJykgewoJCQkJJGludF9uYW1lW10gPSAnU2hlcm1hbmlhbi1NYXlzdmlsbGlhbic7CgkJCQkkaW50X2JvdHRvbVtdID0gJHJvd1snYWdlX2JvdHRvbSddOwoJCQkJJGludF90b3BbXSA9IDQ1MC4wMDAwOwoJCQl9IGVsc2UgewoJCQkJJGludF9uYW1lW10gPSAkcm93WydpbnRlcnZhbF9uYW1lJ107CgkJCQkkaW50X2JvdHRvbVtdID0gJHJvd1snYWdlX2JvdHRvbSddOwoJCQkJJGludF90b3BbXSA9ICRyb3dbJ2FnZV90b3AnXTsKCQkJfQoJCQkkaW50X2lkW10gPSAkcm93WydpZCddOwoJCX0KCQlteXNxbGlfZnJlZV9yZXN1bHQoJHRpbWVfc2NhbGUpOwoJCSRuX2ludCA9IGNvdW50KCRpbnRfbmFtZSk7CgkJCgkJJGJhc2Vfb3Jkb3ZpY2lhbiA9IDQ4OC4zOwoJCSRzdHVkeV9tYXggPSBtYXgoJGludF9ib3R0b20pOwoJCSRzdHVkeV9taW4gPSBtaW4oJGludF90b3ApOwoJCQoJCQoJCS8vLy8vLy8vLy8vLy8vCgkJLy8KCQkvLyBDb2x1bW4gZGF0YSBzYXZlZCBhcyBjb2x1bW5zLmNzdgoJCS8vCgkJLy8vLy8vLy8vLy8vLy8KCQkkcSA9ICJTRUxFQ1QgY29scy5pZCBGUk9NIGNvbHMgCgkJSU5ORVIgSk9JTiBjb2xfZ3JvdXBzIE9OIGNvbF9ncm91cHMuaWQ9Y29sX2dyb3VwX2lkIAoJCUlOTkVSIEpPSU4gcHJvamVjdHMgT04gcHJvamVjdHMuaWQ9cHJvamVjdF9pZAoJCVdIRVJFIHByb2plY3QgTElLRSAnTm9ydGggQW1lcmljYScgQU5EIGNvbF9ncm91cCBOT1QgTElLRSAnTWV4aWNvJyBBTkQgY29scy5pZCBOT1QgSU4gKDM0LCAxMTEsIDEzOSwgMjE4LCA1ODYsIDU4NykgQU5EIHN0YXR1c19jb2RlPSdhY3RpdmUnIjsKCQkkY29sdW1ucyA9IG15c3FsaV9xdWVyeSgkY29ubmVjdF9tYWNyb3N0cmF0LCAkcSk7ICAgICAgIAkJCgkJd2hpbGUoJHJvdyA9IG15c3FsaV9mZXRjaF9hc3NvYygkY29sdW1ucykpICRteV9jb2xzW10gPSAkcm93WydpZCddOwoJCW15c3FsaV9mcmVlX3Jlc3VsdCgkY29sdW1ucyk7CgkJCgkJCgkJLy8vLy8vLy8vLy8vLy8KCQkvLwoJCS8vIGdldCBwYWNrYWdlcwkKCQkvLwoJCS8vLy8vLy8vLy8vLy8vCQkKCQkkdGVtcF9wa2cgPSBzcGxpdF9wYWNrYWdlcygnbWFyaW5lJyk7CQoJCWZvcigkaT0wOyAkaTxjb3VudCgkdGVtcF9wa2cpOyArKyRpKSB7CgkJCSRxID0gIlNFTEVDVCBjb2xfaWQsIG1heChiLmFnZV9ib3R0b20pIGJvdHRvbSwgbWluKHQuYWdlX3RvcCkgdG9wLCBjb3VudChkaXN0aW5jdCB1bml0cy5pZCkgbl91bml0IEZST00gdW5pdHMKCQkJSU5ORVIgSk9JTiBpbnRlcnZhbHMgYiBPTiBiLmlkPUZPCgkJCUlOTkVSIEpPSU4gaW50ZXJ2YWxzIHQgT04gdC5pZD1MTwoJCQlXSEVSRSB1bml0cy5pZCBJTiAoJHRlbXBfcGtnWyRpXSkiOwoJCQkkcmVzdWx0PW15c3FsaV9xdWVyeSgkY29ubmVjdF9tYWNyb3N0cmF0LCAkcSk7CgkJCSRyb3c9bXlzcWxpX2ZldGNoX2Fzc29jKCRyZXN1bHQpOwoJCQlpZihpbl9hcnJheSgkcm93Wydjb2xfaWQnXSwgJG15X2NvbHMpPT09VFJVRSAmJiAkcm93Wydib3R0b20nXT4kc3R1ZHlfbWluICYmICRyb3dbJ3RvcCddPCRzdHVkeV9tYXgpICRteV9wa2dbXSA9ICR0ZW1wX3BrZ1skaV07CQoJCQlteXNxbGlfZnJlZV9yZXN1bHQoJHJlc3VsdCk7CgkJfQoJCSRhbGxfdW5pdHMgPSBpbXBsb2RlKCIsIiwkbXlfcGtnKTsKCQkKCQkKCQkvLy8vLy8vLy8vLy8vLwoJCS8vCgkJLy8gdW5pdHMgc2F2ZWQgYXMgT19TX3VuaXRzLmNzdgoJCS8vCgkJLy8vLy8vLy8vLy8vLy8KCQkkdW5pdHNfZmlsZSA9ICJPX1NfdW5pdHMuY3N2IjsKCQkkZmggPSBmb3BlbigkdW5pdHNfZmlsZSwgJ3cnKSBvciBkaWUoImNhbid0IG9wZW4gZmlsZSIpOwoJCWNobW9kKCR1bml0c19maWxlLCAwNzc3KTsKCQkkZmlsZV9yb3cgPSAidW5pdF9pZCwgY29sX2lkLCBhZ2VfYm90dG9tLCBhZ2VfdG9wLCBjb2xvclxuIjsKCQlmd3JpdGUoJGZoLCAkZmlsZV9yb3cpOwoJCSRxID0gIlNFTEVDVCB1bml0cy5pZCwgY29sX2lkLCBiLmFnZV9ib3R0b20sIHQuYWdlX3RvcCwgY29sb3IgRlJPTSB1bml0cwoJCUlOTkVSIEpPSU4gaW50ZXJ2YWxzIGIgT04gYi5pZD1GTwoJCUlOTkVSIEpPSU4gaW50ZXJ2YWxzIHQgT04gdC5pZD1MTwoJCVdIRVJFIHVuaXRzLmlkIElOICgiLiRhbGxfdW5pdHMuIikgYW5kIGIuYWdlX2JvdHRvbT4kc3R1ZHlfbWluIEFORCB0LmFnZV90b3A8JHN0dWR5X21heCI7IC8vZWNobyAkcS4iPGJyPiI7CgkJJHJlc3VsdD1teXNxbGlfcXVlcnkoJGNvbm5lY3RfbWFjcm9zdHJhdCwgJHEpOwoJCXdoaWxlKCRyb3c9bXlzcWxpX2ZldGNoX2Fzc29jKCRyZXN1bHQpKSB7CgkJCSRmaWxlX3JvdyA9ICRyb3dbJ2lkJ10uIiwiLiRyb3dbJ2NvbF9pZCddLiIsIi4kcm93WydhZ2VfYm90dG9tJ10uIiwiLiRyb3dbJ2FnZV90b3AnXS4iLCIuJHJvd1snY29sb3InXS4iXG4iOwoJCQlmd3JpdGUoJGZoLCAkZmlsZV9yb3cpOwoJCX0KCQlmY2xvc2UoJGZoKTsKCQlteXNxbGlfZnJlZV9yZXN1bHQoJHJlc3VsdCk7CgkJZWNobyAnRmlsZSA8YSBocmVmPSInLiR1bml0c19maWxlLiciPicuJHVuaXRzX2ZpbGUuJzwvYT4gc2F2ZWQ8QlI+JzsKCQkKCQkKCQkvLy8vLy8vLy8vLy8vLwoJCS8vCgkJLy8gcGJkYl9jb2xsZWN0aW9ucyBzYXZlZCBhcyBPX1NfY29sbGVjdGlvbnMuY3N2CgkJLy8KCQkvLy8vLy8vLy8vLy8vLwoJCSRmaCA9IGZvcGVuKCJjb2xsZWN0aW9ucy5jc3YiLCAiciIpOwoJCSRteV9jb2xsZWN0aW9ucyA9IGZnZXRjc3YoJGZoLCAxMDAwMDAsICIsIikKCQllY2hvICJUaGVyZSBhcmUgIi5jb3VudCgkZGF0YSkuIiBjb2xsZWN0aW9uczxicj4iOwoJCWZjbG9zZSgkZmgpOyAKCQkKCQkkcGJkYl9maWxlID0gIk9fU19jb2xsZWN0aW9ucy5jc3YiOwoJCSRmaCA9IGZvcGVuKCRwYmRiX2ZpbGUsICd3Jykgb3IgZGllKCJjYW4ndCBvcGVuIGZpbGUiKTsKCQljaG1vZCgkcGJkYl9maWxlLCAwNzc3KTsKCQkkZmlsZV9yb3cgPSAiY29sbGVjdGlvbl9ubywgdW5pdF9pZCwgbGF0LCBsbmdcbiI7CgkJZndyaXRlKCRmaCwgJGZpbGVfcm93KTsKCQkkcSA9ICJTRUxFQ1QgY29sbGVjdGlvbl9ubywgdW5pdF9pZCwgbGF0LCBsbmcgRlJPTSBwYmRiX21hdGNoZXMKCQlXSEVSRSBjb2xsZWN0aW9uX25vIElOICgiLmltcGxvZGUoIiwiLCRteV9jb2xsZWN0aW9ucykuIikiOwoJCSRyZXN1bHQ9bXlzcWxpX3F1ZXJ5KCRjb25uZWN0X21hY3Jvc3RyYXQsICRxKTsKCQl3aGlsZSgkcm93PW15c3FsaV9mZXRjaF9hc3NvYygkcmVzdWx0KSkgewoJCQkkZmlsZV9yb3cgPSAkcm93Wydjb2xsZWN0aW9uX25vJ10uIiwiLiRyb3dbJ3VuaXRfaWQnXS4iLCIuJHJvd1snbGF0J10uIiwiLiRyb3dbJ2xuZyddLiJcbiI7CgkJCWZ3cml0ZSgkZmgsICRmaWxlX3Jvdyk7CgkJfQoJCWZjbG9zZSgkZmgpOwoJCW15c3FsaV9mcmVlX3Jlc3VsdCgkcmVzdWx0KTsKCQllY2hvICdGaWxlIDxhIGhyZWY9IicuJHBiZGJfZmlsZS4nIj4nLiRwYmRiX2ZpbGUuJzwvYT4gc2F2ZWQ8QlI+JzsKCgkJCgkJLy8vLy8vLy8vLy8vLy8KCQkvLwoJCS8vIGRyYXcgbWFwIGluIFIKCQkvLwoJCS8vLy8vLy8vLy8vLy8vCgkJCgkJJHJfZmlsZSA9ICJ0ZW1wLnIiOwoJCSRmaCA9IGZvcGVuKCRyX2ZpbGUsICd3Jykgb3IgZGllKCJjYW4ndCBvcGVuIGZpbGUiKTsKCQljaG1vZCgkcl9maWxlLCAwNzc3KTsKCQkKCQkkcl9zY3JpcHQgPSAiCgkJCXNvdXJjZSgnbXlGdW5jdGlvbnMucicpCgkJCWxpYnJhcnkobWFwcykKCQkJbGlicmFyeShtYXBwcm9qKQoJCQkKCQkJdGltZS5zY2FsZSA8LSByZWFkLmNzdihmaWxlPSd0aW1lX3NjYWxlLmNzdicsIGhlYWRlcj1UUlVFKTsgbi5iaW5zIDwtIG5yb3codGltZS5zY2FsZSkKCQkJdW5pdHMgPC0gcmVhZC5jc3YoZmlsZT0nT19TX3VuaXRzLmNzdicsIGhlYWRlcj1UUlVFKQoJCQlwb2x5Z29ucyA8LSByZWFkLmNzdihmaWxlPSdjb2x1bW5fcG9seWdvbnMuY3N2JywgaGVhZGVyPVRSVUUpCgkJCXBiZGIgPC0gcmVhZC5jc3YoZmlsZT0nT19TX2NvbGxlY3Rpb25zLmNzdicsIGhlYWRlcj1UUlVFKQoJCQkKCQkJIyMgbWFrZSBtYXBzCgkJCWxvbi5saW1pdCA8LSBjKC0xNzIsLTUwKQoJCQlsYXQubGltaXQgPC0gYygyNSw4MykKCQkJCgkJCW1hcC5vcmllbnQgPC0gYyg1NCwtMTAzLDApCgkJCQoJCQltYXAuZGF0YSA8LSBtYXAoJ3dvcmxkJywgYygnVVNBJywgJ0NhbmFkYScpLCB4bGltPWxvbi5saW1pdCwgeWxpbT1sYXQubGltaXQsIHByb2o9J2F6ZXF1YWxhcmVhJyxvcmllbnQ9bWFwLm9yaWVudCwgcGxvdD1GQUxTRSwgaW50ZXJpb3I9RkFMU0UpCgkJCQoJCQltYXAuY29sb3IgPC0gJ2dyYXkyNScgICMgc29saWQgZGFyayBncmF5CgkJCXBiZGIuY29sb3IgPC0gcmdiKDEsMCwwLDAuMykgICMgdHJhbnNwYXJlbnQgcmVkCgkJCQoJCQlyb2NrLmNvbG9ycyA8LSBtYXRyaXgoTkEsIG5yb3c9MTUsIG5jb2w9MykKCQkJcm9jay5jb2xvcnNbLDFdIDwtIGMoJ2JsdWUnLCdncmF5IGxpZ2h0JywndGFuJywnb3JhbmdlJywneWVsbG93JywnYmx1ZSBncmVlbicsJ3BpbmsnLCdicm93biBkYXJrJywnZ3JlZW4gZGFyaycsJ2Jyb3duJywnZ3JlZW4gbGlnaHQnLCdicm93biBsaWdodCcsJ2JsdWUgZGFyaycsJ2dyYXknLCdncmVlbicpCgkJCXJvY2suY29sb3JzWywyXSA8LSBjKCcjNkJBMUZGJywnIzdDN0M3QycsJyM5QTk0NjknLCcjRkY4NDAwJywnI0ZGRkYwMCcsJyMwMEZGRkYnLCcjRkY4MEE4JywnIzU1NDMyRicsJyMwMDg4MDAnLCcjNTU0MzJGJywnIzAwODgwMCcsJyM1NTQzMkYnLCcjMzgzOEZGJywnIzdDN0M3QycsJyMwMDg4MDAnKQoJCQlyb2NrLmNvbG9yc1ssM10gPC0gYygnY2FyYm9uYXRlJywnZmluZSBjbGFzdGljcycsJ21peGVkIGNsYXN0aWNzJywnY29hcnNlIGNsYXN0aWNzJywnc2FuZHMnLCdjaGVydCcsJ2V2YXBvcml0ZScsJ21ldGFtb3JwaGljJywncGx1dG9uaWMnLCdtZXRhbW9ycGhpYycsJ3ZvbGNhbmljJywnbWV0YW1vcnBoaWMnLCdtaXhlZCBjYXJiL2NsYXN0JywnZmluZSBjbGFzdGljcycsJ3ZvbGNhbmljcycpCgkJCXJvY2suY29sb3JzIDwtIHJvY2suY29sb3JzW29yZGVyKHJvY2suY29sb3JzWywxXSksXQoJCQkKCQkJdG9wLnVuaXRzIDwtIHZlY3Rvcihtb2RlPSdudW1lcmljJywgbGVuZ3RoPW5yb3codW5pdHMpKTsgY291bnRlciA8LSAxCgkJCXBkZihmaWxlPSdtYXBfZmlndXJlLnBkZicsIGhlaWdodD0yMCwgd2lkdGg9NTApCgkJCXBhcihtZnJvdz1jKDIsNSksIG1hcj1jKDAsMCwxMCwwKSswLjEsIHBjaD0xNiwgY2V4Lm1haW49NykJCQoJCQkKCQkJZm9yKGkgaW4gbi5iaW5zOjEpIHsKCQkJCXVuaXQudGVtcCA8LSB1bml0c1t1bml0c1ssM10+dGltZS5zY2FsZVtpLDNdICYgdW5pdHNbLDRdPHRpbWUuc2NhbGVbaSwyXSxdCgkJCQljb2xzLnRlbXAgPC0gdW5pcXVlKHVuaXQudGVtcFwkY29sX2lkKQoJCQkJcGJkYi50ZW1wIDwtIHVuaXF1ZShwYmRiW2lzLmVsZW1lbnQocGJkYlwkdW5pdF9pZCwgdW5pdC50ZW1wXCR1bml0X2lkKSwzOjRdKQoJCQkJCgkJCQlwbG90KG1hcC5kYXRhLCBtYWluPXRpbWUuc2NhbGVbaSwxXSwgYXhlcz1GQUxTRSwgZnJhbWUucGxvdD1UUlVFLCB0eXBlPSduJywgeGxhYj0nJywgeWxhYj0nJykKCQkJCQoJCQkJIyBwbG90IG1hY3Jvc3RyYXQgdW5pdHMKCQkJCWZvcihqIGluIDE6bGVuZ3RoKGNvbHMudGVtcCkpIHsKCQkJCQl0b3AudW5pdHNbY291bnRlcl0gPC0gdW5pdC50ZW1wW3VuaXQudGVtcFwkY29sX2lkPT1jb2xzLnRlbXBbal0sMV1bMV0KCQkJCQljb2xvci50ZW1wIDwtIHJvY2suY29sb3JzW21hdGNoKHVuaXQudGVtcFt1bml0LnRlbXBcJGNvbF9pZD09Y29scy50ZW1wW2pdLDVdWzFdLCByb2NrLmNvbG9yc1ssMV0pLDJdCgkJCQkJCgkJCQkJcG9seS50ZW1wIDwtIHBvbHlnb25zW3BvbHlnb25zWywxXT09Y29scy50ZW1wW2pdLDI6M10KCQkJCQlwb2x5LnByb2ogPC0gbWFwcHJvamVjdChsaXN0KHg9cG9seS50ZW1wWywxXSwgeT1wb2x5LnRlbXBbLDJdKSkKCQkJCQlwb2x5Z29uKHBvbHkucHJvalwkeCwgcG9seS5wcm9qXCR5LCBjb2w9cGFzdGUoY29sb3IudGVtcCksIGJvcmRlcj1wYXN0ZShjb2xvci50ZW1wKSwgbHdkPTAuNSkKCQkJCQljb3VudGVyIDwtIGNvdW50ZXIgKyAxCgkJCQl9CgkJCQkKCQkJCSMgcGxvdCBwYmRiCgkJCQlpZihucm93KHBiZGIudGVtcCkgPiAwKSB7CgkJCQkJcGJkYi5wcm9qIDwtIG1hcHByb2plY3QobGlzdCh4PXBiZGIudGVtcFssMl0sIHk9cGJkYi50ZW1wWywxXSkpCgkJCQkJcG9pbnRzKHBiZGIucHJvalwkeCwgcGJkYi5wcm9qXCR5LCBjZXg9MywgY29sPXBiZGIuY29sb3IpCgkJCQl9CgkJCQlsaW5lcyhtYXAuZGF0YVwkeCwgbWFwLmRhdGFcJHksIGNvbD1tYXAuY29sb3IpCgkJCX0KCQkJZGV2Lm9mZigpCgkJCQoJCQl0b3AudW5pdHMgPC0gdG9wLnVuaXRzW3RvcC51bml0cz4wXQoJCQlyb2NrLmNvbG9yczIgPC0gcm9jay5jb2xvcnNbbWF0Y2godW5pcXVlKHVuaXRzW2lzLmVsZW1lbnQodW5pdHNbLDFdLCB0b3AudW5pdHMpLCA1XSkscm9jay5jb2xvcnNbLDFdKSxdCgkJCQoJCQkjIyBtYWtlIGxlZ2VuZAoJCQlwZGYoZmlsZT0nbWFwX2xlZ2VuZC5wZGYnLCBoZWlnaHQ9Niwgd2lkdGg9MTApCgkJCWxheW91dChtYXRyaXgoMToxNSwgbnJvdz0zLCBuY29sPTUsIGJ5cm93PVRSVUUpKQoJCQlmb3IoaSBpbiAxOm5yb3cocm9jay5jb2xvcnMyKSkgewoJCQkJcGFyKG1hcj1jKDAuMSwwLjEsMC4xLDAuMSkpCgkJCQlwbG90KDE6MTAsIHhsaW09YygwLDEwKSwgeWxpbT1jKDAsMTApLCB0eXBlPSduJywgYXhlcz1GQUxTRSwgZnJhbWUucGxvdD1UUlVFLCB4bGFiPScnLCB5bGFiPScnKQoJCQkJcmVjdCgxLDEsOSw0LCBjb2w9cGFzdGUocm9jay5jb2xvcnMyW2ksMl0pKQoJCQkJdGV4dCg1LDgsIGxhYmVscz1yb2NrLmNvbG9yczJbaSwxXSwgY2V4PTEuNSkKCQkJCXRleHQoNSw2LCBsYWJlbHM9cm9jay5jb2xvcnMyW2ksM10sIGNleD0xLjUpCgkJCX0gCgkJCWRldi5vZmYoKQoJCQkiOwoJCQoJCWZ3cml0ZSgkZmgsICRyX3NjcmlwdCk7CgkJCgkJJGNtZCA9ICJlY2hvICdyc2NyaXB0IDwtIFwiJHJfZmlsZVwiOyBzb3VyY2UocnNjcmlwdCknIHwgIiAuICIvdXNyL2Jpbi9SIC0tc2xhdmUgMj4mMSI7CgkJZXhlYygkY21kLCAkcl9yYW4pOyAKCQlpZihjb3VudCgkcl9yYW4pPjApIHsKCQkJcHJpbnRfcigkcl9yYW4pOyBlY2hvICI8YnI+IjsKCQl9CgkJCgkJZWNobyAnRmlsZSA8YSBocmVmPSJtYXBfZmlndXJlLnBkZiIgdGFyZ2V0PSJibGFuayI+bWFwX2ZpZ3VyZS5wZGY8L2E+IHNhdmVkPEJSPic7CgkJZWNobyAnRmlsZSA8YSBocmVmPSJtYXBfbGVnZW5kLnBkZiIgdGFyZ2V0PSJibGFuayI+bWFwX2xlZ2VuZC5wZGY8L2E+IHNhdmVkPEJSPic7CgoJfQoKCgkvLy8vLy8vLy8vLy8vLwoJLy8KCS8vIHN0dWZmIGF0IHRoZSBlbmQKCS8vCgkvLy8vLy8vLy8vLy8vLwoJaWYoaXNzZXQoJF9QT1NUWydzdWJtaXQnXSkpIHsKCQkkdDEgPSBtaWNyb3RpbWUodHJ1ZSk7CgkJJHRpbWVfZGlmZiA9ICR0MSAtICR0MDsKCQlpZiAoJHRpbWVfZGlmZi82MCA8IDEpIHsKCQkJJGRpZmZfc2Vjb25kcyA9IHJvdW5kKCR0aW1lX2RpZmYsIDMpOwoJCQllY2hvICI8YnI+VGhpcyBwcm9jZXNzIHRvb2sgIi4kZGlmZl9zZWNvbmRzLiIgc2Vjb25kcyI7CgkJfSBlbHNlIGlmICgkdGltZV9kaWZmPj0xICYgJHRpbWVfZGlmZjwzNjAwKSB7CgkJCSRkaWZmX21pbiA9IHJvdW5kKCR0aW1lX2RpZmYvNjAsIDMpOwoJCQllY2hvICI8YnI+VGhpcyBwcm9jZXNzIHRvb2sgIi4kZGlmZl9taW4uIiBtaW51dGVzIjsKCQl9IGVsc2UgewoJCQkkZGlmZl9ob3VyID0gcm91bmQoJHRpbWVfZGlmZi8zNjAwLCAzKTsKCQkJZWNobyAiPGJyPlRoaXMgcHJvY2VzcyB0b29rICIuJGRpZmZfaG91ci4iIGhvdXJzIjsKCQl9Cgl9Cj8+CgoKCjw/cGhwIAoJcmVxdWlyZV9vbmNlKCcuLi9mb290ZXIuaHRtbCcpOwoJZXhpdCgpOwo/Pg==