diff --git a/about.php b/about.php index 50b19a4a..86fa2af8 100644 --- a/about.php +++ b/about.php @@ -248,6 +248,16 @@
Your password is stored according to best practices, with a salted hash stored with 10,000 of PBKDF2. Your data is physically located on servers at UC Berkeley.
++ All personal information we collect about you, other than transient information like your last login IP address and time, is available from your personal profile page. If it's not visible on that page, we don't have that information about you. +
++ Your basic contact data is visible to others to the extent configured on your profile page, and is searchable when adding collaborators or filtering projects. +
++ Any new session irretrievably overwrites old transient data about you, and such transient data only reflects your current session (not historical). You may delete your account permanantly and irretrievably by visiting your dashboard, going to account settings, expanding the "more" button, and selecting "Remove Account". +
@@ -272,7 +282,7 @@
amphibiandisease.org has no regulatory authority, and submitting data to it does not constitute an official - pathogen-reporting record. + pathogen-reporting record.
diff --git a/admin-api.php b/admin-api.php index 5ed66fba..7b55ee6e 100644 --- a/admin-api.php +++ b/admin-api.php @@ -1208,7 +1208,7 @@ function mintBcid($projectLink, $datasetRelativeUri = null, $datasetTitle, $addT ))."\r\n", )); $ctx = stream_context_create($params); - $rawResponse = file_get_contents($fimsAuthUrl, false, $ctx); + $rawResponse = file_get_contents_curl($fimsAuthUrl, false, $ctx); if ($rawResponse === false) { throw(new Exception("Fatal FIMS communication error 001 (No Response)")); } @@ -1245,7 +1245,7 @@ function mintBcid($projectLink, $datasetRelativeUri = null, $datasetTitle, $addT $params['http']['header'] = $headers; $params['http']['content'] = http_build_query($fimsMintData); $ctx = stream_context_create($params); - $rawResponse = file_get_contents($fimsMintUrl, false, $ctx); + $rawResponse = file_get_contents_curl($fimsMintUrl, false, $ctx); if ($rawResponse === false) { throw(new Exception("Fatal FIMS communication error 002 (No Response)")); } @@ -1359,7 +1359,7 @@ function associateBcidsWithExpeditions($projectLink, $fimsAuthCookiesAsString = ))."\r\n", )); $ctx = stream_context_create($params); - $rawResponse = file_get_contents($fimsAuthUrl, false, $ctx); + $rawResponse = file_get_contents_curl($fimsAuthUrl, false, $ctx); if ($rawResponse === false) { throw(new Exception("Fatal FIMS communication error 003 (No Response)")); } @@ -1402,7 +1402,7 @@ function associateBcidsWithExpeditions($projectLink, $fimsAuthCookiesAsString = $tempAssociationData['bcid'] = $bcid; $params['http']['content'] = http_build_query($tempAssociationData); $ctx = stream_context_create($params); - $rawResponse = file_get_contents($fimsAssociateUrl, false, $ctx); + $rawResponse = file_get_contents_curl($fimsAssociateUrl, false, $ctx); if ($rawResponse === false) { throw(new Exception("Fatal FIMS communication error 004 (No Response)")); } @@ -1515,7 +1515,7 @@ function mintExpedition($projectLink, $projectTitle, $publicProject = false, $as 'header' => implode("\r\n", $fimsDefaultHeaders)."\r\n", )); $ctx = stream_context_create($params); - $rawResponse = file_get_contents($fimsAuthUrl, false, $ctx); + $rawResponse = file_get_contents_curl($fimsAuthUrl, false, $ctx); if ($rawResponse === false) { error_log("POST login failed!! Sent post:\n\tTarget URL:\t".$fimsAuthUrl."\n\tParameters:\t".print_r($params, true)."\n\tFull Context:\t".print_r($ctx, True)."\n\nResponse: ".print_r($rawResponse, true)); throw(new Exception("Fatal FIMS communication error 005 (No Response)")); @@ -1550,7 +1550,7 @@ function mintExpedition($projectLink, $projectTitle, $publicProject = false, $as $params['http']['header'] = $header; $params['http']['content'] = http_build_query($fimsMintData); $ctx = stream_context_create($params); - $rawResponse = file_get_contents($fimsMintUrl, false, $ctx); + $rawResponse = file_get_contents_curl($fimsMintUrl, false, $ctx); $resp = null; if ($rawResponse === false) { $errorOut = true; @@ -1583,7 +1583,7 @@ function mintExpedition($projectLink, $projectTitle, $publicProject = false, $as 'header' => implode("\r\n", $fimsDefaultHeaders)."\r\n", )); $ctx = stream_context_create($params); - $rawReauthResponse = file_get_contents($fimsAuthUrl, false, $ctx); + $rawReauthResponse = file_get_contents_curl($fimsAuthUrl, false, $ctx); if ($rawReauthResponse === false) { error_log("POST reauth failed!! Sent post:\n\tTarget URL:\t".$fimsAuthUrl."\n\tParameters:\t".print_r($params, true)."\n\tFull Context:\t".print_r($ctx, True)."\n\nResponse: ".print_r($rawReauthResponse, true)); throw(new Exception("Fatal FIMS communication error 009 (No Response)")); @@ -1667,7 +1667,7 @@ function mintExpedition($projectLink, $projectTitle, $publicProject = false, $as $params["http"]["method"] = "GET"; unset($params["http"]["content"]); $ctx = stream_context_create($params); - $rawResponse2 = file_get_contents($target, false, $ctx); + $rawResponse2 = file_get_contents_curl($target, false, $ctx); $resp = json_decode($rawResponse2, true); $rawResponse = array( "original_response" => $rawResponse, @@ -1748,11 +1748,11 @@ function validateDataset($dataPath, $projectLink, $fimsAuthCookiesAsString = nul )); $params['http']['header'] .= "Cookie: ".$cookiesString."\r\n"; $ctx = stream_context_create($params); - $rawResponse = file_get_contents($fimsStatusUrl, false, $ctx); + $rawResponse = file_get_contents_curl($fimsStatusUrl, false, $ctx); if ($rawResponse === false) { throw(new Exception("Fatal FIMS communication error 007 (No Response)")); } - $rawResponse2 = file_get_contents($fimsContinueUrl, false, $ctx); + $rawResponse2 = file_get_contents_curl($fimsContinueUrl, false, $ctx); $resp = json_decode($rawResponse, true); $resp2 = json_decode($rawResponse2, true); @@ -1829,7 +1829,7 @@ function validateDataset($dataPath, $projectLink, $fimsAuthCookiesAsString = nul ))."\r\n", )); $ctx = stream_context_create($params); - $rawResponse = file_get_contents($fimsAuthUrl, false, $ctx); + $rawResponse = file_get_contents_curl($fimsAuthUrl, false, $ctx); if ($rawResponse === false) { throw(new Exception("Fatal FIMS communication error 008 (No Response)")); } diff --git a/admin/core/core.php b/admin/core/core.php index daf47034..e3978716 100644 --- a/admin/core/core.php +++ b/admin/core/core.php @@ -1,5 +1,24 @@ siteKey; @@ -280,7 +280,7 @@ public function getUser($user_id = null) * @param string|array $user_id Either a column/value pair or an ID for the default column * @return array of the user result column ***/ - + if (empty($this->user) || !empty($user_id)) { $this->setUser($user_id); } elseif (empty($this->user)) { @@ -523,7 +523,7 @@ public function canSMS($strict = true, $throw = true) # If we're strict, the user only can SMS when the phone number is verified. # Otherwise, we just return the status of the phone number itself. $verified = $strict ? $userdata['phone_verified'] == true : self::isValidPhone($this->getPhone()); - + return $verified; } @@ -539,7 +539,7 @@ private static function cleanPhone($number) if (substr($number, 0, 1) == '1') { $number = substr($number, 1); } - + return $number; } @@ -695,7 +695,7 @@ public function makeTOTP($provider = null) /* $iphone32 = str_replace("=","",$secret_part[1]); */ /* $iphone_uri = $secret_part[0]."secret=".$iphone32; #still no good */ $retarr = self::generateQR($iphone_uri); - + # Let's get a human-readable secret $human_secret0 = str_replace('=', '', $secret); $i = 0; @@ -744,14 +744,14 @@ public function saveTOTP($code) if ($r === false) { $e = mysqli_error($l); mysqli_query($l, 'ROLLBACK'); - + return array('status' => false,'error' => $e,'human_error' => 'Could not save secret','username' => $this->username); } $r = mysqli_query($l, $query2); if ($r === false) { $e = mysqli_error($l); mysqli_query($l, 'ROLLBACK'); - + return array('status' => false,'error' => $e,'human_error' => 'Could not create backup code','username' => $this->username); } mysqli_query($l, 'COMMIT'); @@ -819,7 +819,7 @@ public function removeTOTP($username, $password, $code) if ($r === false) { return array('status' => false,'error' => mysqli_error($l),'human_error' => 'Server error verifying removal. Please try again.'); } - + return array('status' => true,'query' => $query,'username' => $this->getUsername()); } @@ -838,7 +838,7 @@ public function sendTOTPText() $totp->setDigest($this->getDigest()); $message = 'Your authentication code for '.$this->getSiteName().' is: '.$totp->now().' . It is valid for 30 seconds.'; $this->textUser($message); - + return true; } catch (Exception $e) { return false; @@ -894,7 +894,7 @@ public static function generateQR($uri, $data_path = null, $identifier_path = nu if (function_exists('ImageCreate')) { QRcode::png($uri, $filename, QR_ECLEVEL_H, 8, 1); } - $raw = base64_encode(file_get_contents($filename)); + $raw = base64_encode(file_get_contents_curl($filename)); $raw = 'data:image/png;base64,'.$raw; if (!$persistent) { unlink($filename); @@ -902,7 +902,7 @@ public static function generateQR($uri, $data_path = null, $identifier_path = nu # As a final option, get a URL fallback # https://developers.google.com/chart/infographics/docs/qr_codes?csw=1 $url = 'https://chart.googleapis.com/chart?cht=qr&chs=500x500&chld=H&chl='.$uri; - + return array('status' => true,'uri' => $uri,'svg' => $svg,'raw' => $raw,'url' => $url); } catch (Exception $e) { return array('status' => false,'human_error' => 'Unable to generate QR code','error' => $e->getMessage(),'uri' => $uri,'identifier' => $identifier,'persistent' => $persistent); @@ -1370,7 +1370,7 @@ public function sendEmailVerification($alternate = false) { } - public function mailSuperusers($subject, $body) + public function mailSuperusers($subject, $body) { /*** * Send an email to site superusers @@ -1402,8 +1402,8 @@ public function mailSuperusers($subject, $body) "error" => $error, ); } - - public function isVerified($alternate = false) + + public function isVerified($alternate = false) { $key = $alternate ? "alternate_email_verified" : "email_verified"; $colCheck = array( @@ -1690,7 +1690,7 @@ public function setImageAsUserPicture($image, $path = null) { $image = str_replace($path, "", $image); } $sourceImage = $path . $image; - $imageData = file_get_contents($sourceImage); + $imageData = file_get_contents_curl($sourceImage); $iParts = explode(".", $image); $extension = array_pop($iParts); $imgUri = $path.$this->getHardlink().'.'.$extension; diff --git a/api.php b/api.php index 12790802..fa4025ef 100644 --- a/api.php +++ b/api.php @@ -367,6 +367,7 @@ function doCartoSqlApiPush($get) "insert" => "EDIT", "insertinto" => "EDIT", "update" => "EDIT", + "ifexists(\nselect1\nfrominformation_schema.tables\nwhere\n)drop" => "EDIT", ); $unrestrictedActions = array( "create" => true, @@ -399,6 +400,7 @@ function doCartoSqlApiPush($get) $checkedTablePermissions[] = $cartoTable; $cartoTableJson = str_replace('_', '_', $cartoTable); $accessListLookupQuery = 'SELECT `project_id`, `author`, `access_data`, `public` FROM `'.$db->getTable()."` WHERE `carto_id` LIKE '%".$cartoTableJson."%' OR `carto_id` LIKE '%".$cartoTable."%'"; + //#' # Syntax highlight helper $l = $db->openDB(); $r = mysqli_query($l, $accessListLookupQuery); $row = mysqli_fetch_assoc($r); @@ -552,7 +554,7 @@ function doCartoSqlApiPush($get) ), ); $context = stream_context_create($opts); - $response = file_get_contents($cartoFullUrl, false, $context); + $response = file_get_contents_curl($cartoFullUrl, false, $context); $responses[] = $response; $decoded = json_decode($response, true); $decoded["query"] = $statement; @@ -575,7 +577,7 @@ function doCartoSqlApiPush($get) ), ); $context = stream_context_create($opts); - $response = file_get_contents($cartoFullUrl, false, $context); + $response = file_get_contents_curl($cartoFullUrl, false, $context); $responses[] = $response; $decoded = json_decode($response, true); $decoded["query"] = $sqlQuery; @@ -659,7 +661,7 @@ function doAWebValidate($get) # How old is our copy? if (filemtime($localAWebTarget) + $dayOffset < time()) { # Fetch a new copy - $aWebList = file_get_contents($amphibiaWebListTarget); + $aWebList = file_get_contents_curl($amphibiaWebListTarget); if (strlen($aWebList) > 0) { $h = fopen($localAWebTarget, 'w+'); $bytes = fwrite($h, $aWebList); @@ -674,7 +676,7 @@ function doAWebValidate($get) } $response['aweb_list_age'] = time() - filemtime($localAWebTarget); $response['aweb_list_max_age'] = $dayOffset; - //$aWebList = file_get_contents($localAWebTarget); + //$aWebList = file_get_contents_curl($localAWebTarget); $aWebListArray = array_map('tsvHelper', file($localAWebTarget)); /* * For a given row, we have this numeric key to real id mapping: diff --git a/coffee/admin-editor.coffee b/coffee/admin-editor.coffee index 100ffe32..a80c9d8e 100644 --- a/coffee/admin-editor.coffee +++ b/coffee/admin-editor.coffee @@ -1031,7 +1031,10 @@ showAddUserDialog = (refAccessList) -> for uid in toAddUids user = toAddEmails[i] console.info "Adding", user - userName = $(user).text() + try + userName = user.text() + catch + userName = $(user).text() ++i html = """\n The internet is a bit slow right now. We're still verifying your credentials.\n
\n",$("main #main-body").html("\n The internet is a bit slow right now. We're still verifying your credentials.\n
\nPlease be patient while the administrative interface loads.
\nThere was an error in the application. Please refresh and try again. If this persists, please contact administration.
\n Restricted accounts can't create projects.\n
\nThere's currently a server problem. Try back again soon.
\n This represents the approximate collection region for your samples.\n
\n \n The last thing you do (search, build a locality, or upload data) will be your dataset\'s canonical locality.\n .\n
\n You may also click on the map to outline a region of interest, then click "Build Map" below to calculate a locality.\n
\nDrag and drop as many files as you need below.
\n\n Please note that the data must have a header row,\n and the data must have the columns decimalLatitude
, decimalLongitude
, and coordinateUncertaintyInMeters
. Your project must also be titled before uploading data.\n
Samples
, as per FIMS.\n "+$.cookie("amphibiandisease_user")+"
>"},$.get(uri.urlString+"admin-api.php",buildArgs(o,"json")),$.get(uri.urlString+"recordMigrator.php"),stopLoad(),delay(1e3,function(){return loadEditor(_adp.projectId)}),toastStatusMessage("Data successfully saved to server")):(console.error(a.error.error),console.log(a),stopLoadError(a.human_error),bsAlert(a.human_error,"error"))}catch(e){b=e,stopLoadError("There was a verifying your save data");try{t=JSON.stringify(a)}catch(e){t="BAD_OBJECT"}try{bsAlert("There was a problem verifying your save data"+t+"
"+b.message+"
"+b.stack+"
","error")}catch(e){}console.error("JavaScript error in save data callback! FinalizeData said: "+b.message),console.warn(b.stack)}return!1}).fail(function(e,a){return stopLoadError("There was a problem saving your data. Please try again"),!1})},console.info("Checking locality ..."),null==geo.computedLocality&&dataFileParams.hasDataFile){if(dataFileParams.hasDataFile)return null==t&&(t=getMapCenter(geo.boundingBox)),console.info("Computing locality with reverse geocode from",t,geo.boundingBox),geo.reverseGeocode(t.lat,t.lng,geo.boundingBox,function(e){return console.info("Computed locality "+e),_adp.locality=e,j()});try{_adp.locality=p$("#locality-input").value}catch(e){_adp.locality=""}return console.warn("How did we get to this state? No locality precomputed, no data file"),j()}if(null!=geo.computedLocality)console.info("Already have locality"),_adp.locality=geo.computedLocality;else try{console.info("Took written locality"),_adp.locality=p$("#locality-input").value}catch(e){console.info("Can't figure out locality"),_adp.locality=""}return dataFileParams.hasDataFile?j():mintExpedition(_adp.projectId,null,function(){return j()})}catch(e){return b=e,stopLoadError("There was a problem with the application. Please try again later. (E-003)"),console.error("JavaScript error in saving data (E-003)! FinalizeData said: "+b.message),console.warn(b.stack)}})):(stopLoadError("Please fill out all required fields"),!1)}catch(e){t=e,stopLoadError("There was a problem with the application. Please try again later. (E-004)");try{bsAlert("There was a problem with the application. Please try again later. (E-004)"+t.message+"
"+t.stack+"
","error")}catch(e){}return console.error("JavaScript error in saving data (E-004)! FinalizeData said: "+t.message),console.warn(t.stack)}},resetForm=function(){return foo()},getTableCoordinates=function(e){return null==e&&(e="tdf0f1bc730325de59d48a5c80df45931_6d6d454828c05e8ceea03c99cc5f547e52fcb5fb"),!1},pointStringToLatLng=function(e,a){var t,o,n;return null==a&&(a=!1),e.search(!1)?(n=e.slice(6,-1).split(" "),o=1===(t=90\n Computed locality: '+a[0].formatted_address+'\n
\n\n This is your currently active locality. Entering points below will take priority over this.\n
\nlat, lng
, with one set on each line. Please press enter to insert a new line after your last coordinate.",a='\n Status:\n Sampled by "+c.samplemethod+", disease status "+c.diseasedetected+" for "+c.diseasetested+"\n
"},r.infoWindow=f,t.push(r),n.push(f)}if(dataAttrs.coords=t,dataAttrs.markerInfo=n,console.info("Calling back with",t,y),"function"==typeof w)return w(t,y)}).fail(function(e,a){return null!=(null!=dataAttrs?dataAttrs.coords:void 0)?w(dataAttrs.coords,y):(stopLoadError("Couldn't get bounding coordinates from data"),console.error("No valid coordinates accessible!"))})}).fail(function(e,a){return!1})}),!1},getUploadIdentifier=function(){var e,a,t;if(isNull(_adp.uploadIdentifier)){if(isNull(_adp.projectId)){if(e=$.cookie(adminParams.domain+"_link"),isNull(_adp.projectIdentifierString)){try{t=isNull(p$("#project-title").value)?randomString(16):p$("#project-title").value}catch(e){t=randomString(16)}a="t"+md5(t+e),_adp.projectIdentifierString=a}_adp.projectId=md5(""+a+e+Date.now())}_adp.uploadIdentifier=md5(""+user+_adp.projectId)}return _adp.uploadIdentifier},bootstrapUploader=function(e,a,t){var o,n;return null==e&&(e="file-uploader"),null==a&&(a="col-md-4"),n="#"+e,$.cookie(adminParams.domain+"_link"),getUploadIdentifier(),_adp.projectIdentifierString,$(n).exists()||(o='',$("main #uploader-container-section").append(o),console.info("Appended upload form"),$(n).submit(function(e){return e.preventDefault(),e.stopPropagation(),!1})),verifyLoginCredentials(function(){var e;return null==window.dropperParams&&(window.dropperParams={}),window.dropperParams.dropTargetSelector=n,window.dropperParams.uploadPath="uploaded/"+getUploadIdentifier()+"/",e=!0===window.dropperParams.hasInitialized,loadJS("helpers/js-dragdrop/client-upload.min.js",function(){if(console.info("Loaded drag drop helper"),e){console.info("Reinitialized dropper");try{window.dropperParams.initialize()}catch(e){console.warn("Couldn't reinitialize dropper!")}}if(window.dropperParams.postUploadHandler=function(e,a){var t,o,n,r,i,s,l,c;if(window.dropperParams.dropzone.removeAllFiles(),"object"!=typeof a)return console.error("Dropzone returned an error - "+a),toastStatusMessage("There was a problem with the server handling your image. Please try again."),!1;if(!0!==a.status)return null==a.human_error&&(a.human_error="There was a problem uploading your image."),toastStatusMessage(""+a.human_error),console.error("Error uploading!",a),!1;try{switch(console.info("Server returned the following result:",a),console.info("The script returned the following file information:",e),s="helpers/js-dragdrop/uploaded/"+getUploadIdentifier()+"/",o=a.full_path.split("/").pop(),c=a.wrote_thumb,i=a.mime_provided.split("/")[0],r=a.mime_provided.split("/")[1],n=e.size<5242880||"image"!==i?""+s+a.wrote_file:""+s+c,l=function(){switch(i){case"image":return'\n '+e.name+" -> "+o+'\n (\n Original Image\n )\n
\n\n '+e.name+" -> "+o+'\n (\n Original Media\n )\n
\n\n '+e.name+" -> "+o+'\n (\n Original Media\n )\n
\n'+e.name+" -> "+o+"
\n")+"
",bsAlert(y,"danger"),console.info("Missing: ",null!=S.decimalLatitude,null!=S.decimalLongitude,null!=S.coordinateUncertaintyInMeters),removeDataFile(),!1;if(!(isNumber(S.decimalLatitude)&&isNumber(S.decimalLongitude)&&isNumber(S.coordinateUncertaintyInMeters)))return toastStatusMessage("Data has invalid entries for geo columns. Please be sure they're all numeric and try again."),removeDataFile(),!1;D=Object.size(e);try{p$("#samplecount").value=D}catch(e){}if(isNull($("#project-disease").val()))try{p$("#project-disease").value=S.diseaseTested}catch(e){}j={},dataAttrs.coords=[],dataAttrs.coordsFull=[],dataAttrs.fimsData=[],u={},toastStatusMessage("Please wait, parsing your data"),$("#data-parsing").removeAttr("indeterminate");try{p$("#data-parsing").max=D}catch(e){}for(_ in Date.now(),N=[],d=[],e){for(n in P=e[_],k=toInt(_)+1,T={},O=[],P){if(M=P[n],n=n.trim(),0<=indexOf.call(O,n))return console.error("There was a duplicate column '"+n+"'",O),stopLoadBarsError(null,"You have at least one duplicate column '"+n+"'. Ensure all your columns are unique."),!1;switch(A=!1,n){case"ContactName":case"basisOfRecord":case"occurrenceID":case"institutionCode":case"collectionCode":case"labNumber":case"originalsource":case"datum":case"georeferenceSource":case"depth":case"Collector2":case"Collector3":case"verbatimLocality":case"Habitat":case"Test_Method":case"eventRemarks":case"quantityDetected":case"dilutionFactor":case"cycleTimeFirstDetection":if("string"==typeof M)try{M=(M=(M=M.replace(/;/gim,";")).replace(/'/gim,"'")).replace(/"/gim,""")}catch(e){console.warn("Couldn't replace quotes for this:",M)}u[n]=M,A=!0;break;case"specimenDisposition":n="sampleDisposition";break;case"sampleType":n="sampleMethod";break;case"elevation":n="alt";break;case"dateCollected":case"dateIdentified":if(n="dateIdentified",L=excelDateToUnixTime(M,!0),!isNumber(L))return console.error("This row (#"+k+") has a non-date value ! ("+M+" = "+L+")"),stopLoadBarsError(null,"Detected an invalid date '"+M+"' at row #"+k+". Check your dates!"),!1;if(s=new Date(L),L"+M+"
)"),!1;if("decimalLatitude"===n&&(M<-90||9090
and -90
."),!1;if("decimalLongitude"===n&&(M<-180||180180
and -180
."),!1;if("coordinateUncertaintyInMeters"===n&&M<=0)return stopLoadBarsError(null,"Coordinate uncertainty must be >= 0 at row "+k),!1;o=toFloat(M);break;case"diseaseDetected":if(isBool(M))o=M.toBool();else try{o="negative"!==M.trim().toLowerCase()&&("positive"===M.trim().toLowerCase()||"NO_CONFIDENCE")}catch(e){o="NO_CONFIDENCE"}break;case"sex":try{M="m"===(M=M.trim().toLowerCase()).slice(0,1)?"male":"f"===M.slice(0,1)?"female":"not determined"}catch(e){M="not determined"}break;case"sampleId":try{"n/a"===(I=M.trim()).toLowerCase()&&(I=""),o=I=I.replace(/^([a-zA-Z]+) (\d+)$/gm,"$1$2")}catch(e){o=M}indexOf.call(N,o)<0?N.push(o):indexOf.call(d,o)<0&&d.push(o);break;default:try{o=M.trim()}catch(e){o=M}}A||(T[n]=o)}r={lat:T.decimalLatitude,lng:T.decimalLongitude,alt:T.alt,uncertainty:T.coordinateUncertaintyMeters},i=new Point(r.lat,r.lng),dataAttrs.coords.push(i),dataAttrs.coordsFull.push(r),dataAttrs.fimsData.push(u);try{T.fimsExtra=JSON.stringify(u)}catch(e){console.warn("Couldn't store FIMS extra data",u)}j[_]=T,0===modulo(_,500)&&0<_&&(toastStatusMessage("Processed "+_+" rows ..."),console.log("Processed "+_+" rows ..."));try{p$("#data-parsing").value=_+1}catch(e){}}try{console.log("Basic validation passed"),isNull(d)||bsAlert("Warning: the following field IDs all had duplicates:"+d+"
We strongly recommend unique IDs.","warning")}catch(e){}isNull(_adp.projectIdentifierString)?(x="t"+md5(p$("#project-title").value+a+Date.now()),_adp.projectIdentifierString=x):x=_adp.projectIdentifierString;try{f={downloadFile:"cleaned-dataset-"+Date.now()+".csv",selector:"#download-server-parsed-data"},downloadCSVFile(j,f),window.parsedData=j,_adp.cleanedAndParsedData=j}catch(e){}for(b in h=function(){var e,a,t,o,n,r,i;for(t={},i="",o=a=0,n=(r=sortPoints(dataAttrs.coords)).length;o