diff --git a/.gitignore b/.gitignore
index 237de09242727825c182d3cb3e1d799a904c25ce..430120a229a113fe54a8b1711706b97707fded24 100644
--- a/.gitignore
+++ b/.gitignore
@@ -66,3 +66,4 @@ Python/build/*
 **/src/Python/build/*
 leversc/src/Python/dist/*
 matlab/Yannick_oracle/001.png
+!matlab/cacheReferenceLoG.mat
\ No newline at end of file
diff --git a/elever/main.js b/elever/main.js
index 3a93b5aade3a40d37e7d9eaf544a18e89dd02c72..ef57995d73f699f14a9f2c1c25efc11f7f36059b 100644
--- a/elever/main.js
+++ b/elever/main.js
@@ -5,7 +5,6 @@ const app = electron.app
 
 // Module to create native browser window.
 const BrowserWindow = electron.BrowserWindow
-
 const path = require('path')
 const url = require('url')
 const {ipcMain} = require('electron');
@@ -24,7 +23,9 @@ function createWindow ()
   // Create the browser window.
   mainWindow = new BrowserWindow({width: 800, height: 600, icon:path.join(__dirname,'..','leverjs/leverjs.ico'), 
     webPreferences: {
-      nodeIntegration: true
+      nodeIntegration: true,
+      contextIsolation: false,
+      enableRemoteModule: true
     } 
   });
  
diff --git a/leverjs/ImageWindowBuilder.js b/leverjs/ImageWindowBuilder.js
index e71de6acbb6793f4b305087f683cfba53e25837d..2c9cf23767bde48a14b6f0323001cf42f86edeb2 100644
--- a/leverjs/ImageWindowBuilder.js
+++ b/leverjs/ImageWindowBuilder.js
@@ -41,7 +41,8 @@ var miniMapmousedrag = false;
 // database is read only
 var gbReadOnlyDB=false;
 
-const IS_NODE = typeof module !== 'undefined' && module.exports;
+// const IS_NODE = typeof module !== 'undefined' && module.exports;
+var IS_NODE = navigator.userAgent.indexOf('Electron') >= 0
 
 // set to tell render.js (reDraw) not to kick off a multires if we're in the experiment window
 var gbExperimentRender=false;
@@ -144,6 +145,8 @@ function setLeverscUI()
     document.getElementById('sbtabAlgorithms').style.display='none';
     document.getElementById('sbtabWrangle').style.display='none';
     document.getElementById('playPause').style.display='none';
+    document.getElementById('toolbarClip').style.display="";
+
     sbtabClick('View');
 }
 // Runs when the window is first open
@@ -169,7 +172,7 @@ window.onload = function () {
             ROOT=params[1].slice('ROOT='.length)
             title=params[2].slice('TITLE='.length)
             
-            console.log('lever figure window found :: port='+port+" :: root="+root)
+            console.log('lever figure window found :: port='+port+" :: root="+ROOT)
             uiServer.init(port,window)
             document.title='leversc '+title
             setLeverscUI()
diff --git a/leverjs/uiServer.js b/leverjs/uiServer.js
index 036218d703079b1e56e25988c23eaa16e4f10e2d..74e81027a7a4c6bdc07f71ff81c2f9090be07a4f 100644
--- a/leverjs/uiServer.js
+++ b/leverjs/uiServer.js
@@ -77,7 +77,6 @@ app.post('/loadfig', fig_upload, function (req, res)
                 cx.renderParams=gWindow.gRenderParams;
             gWindow.CONSTANTS=cx;
             gWindow.initWebGL();
-            gWindow.setToolUI(cx);
             gWindow.UpdateTime();  
             gWindow.populateViewTab();          
         });
@@ -223,8 +222,9 @@ app.get('/uiParams', function (req, res) {
     var logoDiv=gWindow.document.getElementById('logoDiv');
     var clockButton=gWindow.document.getElementById('clockButton');
     var time=document.getElementById('imageTimeDiv').innerHTML;
+    var scalebar = gWindow.gbScalebar;
     var ui={sidebar:sidebar.style.display,webToolbar:webToolbar.children[1].style.display,logoDiv:logoDiv.style.display,
-        clockButton:clockButton.style.display,time:time};
+        clockButton:clockButton.style.display,time:time,scalebar:scalebar};
     res.send(ui);
 });
 
@@ -235,14 +235,17 @@ app.post('/uiParams', jsonParser,function (req, res) {
     var logoDiv=gWindow.document.getElementById('logoDiv');
     var lineageControls=gWindow.document.getElementById('divLineageControls');
 
+    if (gWindow.gbScalebar != ui.scalebar)
+        drawScalebar(true);
+
     lineageControls.style.display=ui.webToolbar;
     sidebar.style.display=ui.sidebar;
     // webToolbar.style.display=ui.webToolbar;
     logoDiv.style.display=ui.logoDiv;
 
     for (var i=0;i<webToolbar.children.length;i++) {
-        if (webToolbar.children[i].id=='clockButton')
-            continue;
+        // if (webToolbar.children[i].id=='clockButton')
+        //     continue;
         webToolbar.children[i].style.display=ui.webToolbar;
     }
     document.getElementById('imageTimeDiv').innerHTML=ui.time;
diff --git a/leversc/src/MATLAB/@leversc/getProperty.m b/leversc/src/MATLAB/@leversc/getProperty.m
index 516afc64e3b3d3f9d4e4de64484544d3eaecb94e..094a36b9675c42bf347ece2572ebe64d6d11dfa8 100644
--- a/leversc/src/MATLAB/@leversc/getProperty.m
+++ b/leversc/src/MATLAB/@leversc/getProperty.m
@@ -1,5 +1,7 @@
 function rval=getProperty(obj,propertyName)
 
+rval = [];
+
 if isempty(obj.check_server())
     return;
 end
diff --git a/leversc/src/MATLAB/@leversc/leversc.m b/leversc/src/MATLAB/@leversc/leversc.m
index 35ed034c9eb5ccf9bf815a7c9882ac72089aefe9..73a002abf3a6bcba691c3a09746de4fc5178f51a 100644
--- a/leversc/src/MATLAB/@leversc/leversc.m
+++ b/leversc/src/MATLAB/@leversc/leversc.m
@@ -30,6 +30,7 @@ classdef leversc <handle
                 optional_figNumber=1;
             end
             [im,imD,figNumber]=parseArgs(optional_im,optional_imD,optional_figNumber);
+            im = imPad4(im);
             obj.figNumber=figNumber;
             if isfield(imD,'imageData')
                 CONSTANTS=imD;
@@ -122,3 +123,19 @@ end
 
 end
 
+function im = imPad4(im)
+
+pad = [0,0,0];
+for d = 1:3
+    if 0~=mod(size(im,d),4)
+        pad(d) = size(im,d) + 4-mod(size(im,d),4);
+    end
+end
+if any(pad)
+    sz = size(im);
+    sz = sz(1:3);
+    pad = max(pad,sz);
+    im(pad(1),pad(2),pad(3),:) = 0;
+end
+
+end
\ No newline at end of file
diff --git a/leversc/src/MATLAB/@leversc/loadImage.m b/leversc/src/MATLAB/@leversc/loadImage.m
index 511a935ace771fcf7eee31644aa95ad947678b39..dbdde44d01af0e7195d22999188ab9cb0f00e8f7 100644
--- a/leversc/src/MATLAB/@leversc/loadImage.m
+++ b/leversc/src/MATLAB/@leversc/loadImage.m
@@ -16,7 +16,7 @@ sz(1)=sz(2);
 sz(2)=temp;
 sz(4)=length(channels);
 sz(5)=length(time);
-targetFile=strrep(strDB,'.LEVER','.h5');
+targetFile=[fullfile(CONSTANTS.imageData.imageDir,CONSTANTS.imageData.DatasetName) '.h5'];
 im=h5read(targetFile,'/Images/Original',[1,1,1,channels(1),time(1)],sz);
 % im=mat2gray(im);
 end
diff --git a/leversc/src/MATLAB/@leversc/show.m b/leversc/src/MATLAB/@leversc/show.m
index e6a01af93108cc582559f8e6e017a0793bcaf918..2ad1d3bec242fb393e668cc2f3708f2d0a6cd036 100644
--- a/leversc/src/MATLAB/@leversc/show.m
+++ b/leversc/src/MATLAB/@leversc/show.m
@@ -106,9 +106,19 @@ end
 
 function launch_electron_posix(port,fignum,workdir, leverpath,strDB)
 elec_cmd = 'leverjs';
+px = getenv('PATH');
 if ( ~isempty(leverpath) )
-    elec_path = fullfile(leverpath,'node_modules','.bin','electron');
-    elec_cmd = [elec_path ' ' fullfile(leverpath,'elever','main.js')];
+        % first try NVM
+        nvm_path = getenv('NVM_DIR');
+        if ~isempty(nvm_path)
+            [ret,elec_path] = system('source ~/.nvm/nvm.sh;which electron');  
+            elec_path = replace(elec_path,newline,'');
+            nodePath = fileparts(elec_path);            
+            px = [px ':' nodePath];
+        else
+            elec_path = fullfile(leverpath,'node_modules','.bin','electron');            
+        end
+        elec_cmd = [elec_path ' ' fullfile(leverpath,'elever','main.js')];
 else
     [status,~] = system(['which ' elec_cmd]);
     if ( status ~= 0 )
@@ -118,8 +128,8 @@ end
 if exist('strDB','var') && ~isempty(strDB)
     elec_cmd = [elec_cmd ' --leverFile=' strDB ' '];
 end
-cmd = [elec_cmd ' --port=' num2str(port) ' --title="figure ' num2str(fignum) '"' ' &'];
-system(cmd);
+cmd = [elec_cmd ' --port=' num2str(port) ' --title="figure ' num2str(fignum) '"' ' &']
+system(cmd,'PATH',px);
 end
 
 function launch_electron_windows(port,fignum,workdir, leverpath, strDB)
diff --git a/leversc/src/MATLAB/ssf_kymo.m b/leversc/src/MATLAB/ssf_kymo.m
new file mode 100644
index 0000000000000000000000000000000000000000..91f062504be7dc25d16f6138f69b9c424350211a
--- /dev/null
+++ b/leversc/src/MATLAB/ssf_kymo.m
@@ -0,0 +1,104 @@
+%
+function ssf_kymo(bPreview)
+
+lsc = leversc();
+
+    %% Disable most UI elements
+    lsc.uiParams.time='none';
+    lsc.uiParams.sidebar='none';
+    lsc.uiParams.clockButton='none';
+    lsc.uiParams.webToolbar='none';
+    
+    %% Reset view parameters (also set background to black)
+    lsc.viewParams.clipMode = 0;
+    lsc.viewParams.worldRot = reshape([1,0,0,0; 0,1,0,0; 0,0,1,0; 0,0,0,1], 16,1);
+    lsc.viewParams.zoom = 0;
+    lsc.viewParams.bgColor = [0,0,0];
+    
+    if ( ~bPreview )
+        movieFile='pos3_erk_ssf.avi';
+        vidWrite=VideoWriter(movieFile,'Motion JPEG AVI');
+        vidWrite.FrameRate=10;
+        open(vidWrite)
+    end
+    
+%     %% Quick zoom from 0 to 0.4 (1 sec = 10 frames)
+%     zlevels = linspace(0,0.4, 10);
+%     for i=1:length(zlevels)
+%         lsc.viewParams.zoom=zlevels(i);
+%         
+%         imCap = get_rendered_frame(lsc);
+%         if ( bPreview )
+%             imagesc(imCap);
+%             axis image;
+%             drawnow();
+%         else
+%             writeVideo(vidWrite,imCap);
+%         end
+%     end
+%     
+%     % Padding for 0.2 sec
+%     if ( ~bPreview )
+%         writeVideo(vidWrite,imCap);
+%         writeVideo(vidWrite,imCap);
+%     end
+    
+    
+    %% Rotate 1/3 way around in 5sec
+    angles = linspace(0,360,200);
+    for i=2:length(angles)
+        ry=[cosd(angles(i)), 0, sind(angles(i)),0;
+            0,1,0,0;
+            -sind(angles(i)),0,cosd(angles(i)),0;
+            0,0,0,1];
+
+        worldRot=ry;
+        lsc.viewParams.worldRot=worldRot(:);
+        
+        imCap = get_rendered_frame(lsc);
+        if ( bPreview )
+            imagesc(imCap);
+            axis image;
+            drawnow();
+        else
+            writeVideo(vidWrite,imCap);
+        end
+    end
+%     % Padding for 0.2 sec
+%     if ( ~bPreview )
+%         writeVideo(vidWrite,imCap);
+%         writeVideo(vidWrite,imCap);
+%     end
+%     angles = linspace(120,0,50);
+%     for i=2:length(angles)
+%         ry=[cosd(angles(i)), 0, sind(angles(i)),0;
+%             0,1,0,0;
+%             -sind(angles(i)),0,cosd(angles(i)),0;
+%             0,0,0,1];
+% 
+%         worldRot=ry;
+%         lsc.viewParams.worldRot=worldRot(:);
+%         
+%         imCap = get_rendered_frame(lsc);
+%         if ( bPreview )
+%             imagesc(imCap);
+%             axis image;
+%             drawnow();
+%         else
+%             writeVideo(vidWrite,imCap);
+%         end
+%     end
+  
+    if ( ~bPreview )
+        close(vidWrite)
+    end
+end
+
+function im = get_rendered_frame(lsc)
+    % We need to poll for draw-complete in order to avoid timeouts
+    while ~lsc.drawComplete()
+        pause(0.1);
+    end
+    im=lsc.captureImage();
+end
+
diff --git a/matlab/+AutoParam/imRadius.m b/matlab/+AutoParam/imRadius.m
index 8b9cecba1ff986f901366ae226e8005ac619b61a..25164deae9003626ad741287b2f7951572925ab4 100644
--- a/matlab/+AutoParam/imRadius.m
+++ b/matlab/+AutoParam/imRadius.m
@@ -2,24 +2,32 @@ function [radius,area]=imRadius(im,CONSTANTS)
 
 radius=[];
 area=[];
-bwp=bwperim(im);
 for i=1:max(im(:))
-    rx=[];
-    idx=find(im==i & bwp);
+    idx=find(im==i);
     if isempty(idx)
         continue
     end
+    sz=CONSTANTS.imageData.PixelPhysicalSize;
     if is3D(im)
-        [r,c,z]=ind2sub(size(im),idx);           
+        [r,c,z]=ind2sub(size(im),idx);
+        iRadius= (std([r,c,z])) .* sqrt(3);
     else
         [r,c]=ind2sub(size(im),idx);
-        z=[];
+        iRadius = (std([r,c])) .* sqrt(2);
+        sz = sz(1:2);
     end
-    rx = getRadius(CONSTANTS,r,c,z);        
-    radius=[radius;median(rx)];
-
-    idxArea=find(im==i);
-    area=[area;length(idxArea)];
+    if any(r==1) || any(c==1) || any(r==size(im,1)) || any(c==size(im,2))
+        continue;
+    end
+    if is3D(im) && (any(z==1) || any(z==size(im,3)))
+        continue
+    end
+    iRadius = norm(iRadius .* sz);
+    if iRadius<1
+        4;
+    end
+    radius=[radius;iRadius];
+    area=[area;length(idx)];
 end
 4;
     
diff --git a/matlab/+Batch/batchProc.m b/matlab/+Batch/batchProc.m
new file mode 100644
index 0000000000000000000000000000000000000000..a2ddcb3fbf776dcac79f64bdbe8184999aca1497
--- /dev/null
+++ b/matlab/+Batch/batchProc.m
@@ -0,0 +1,14 @@
+
+function batchProc(ROOT,nproc,nthread)
+
+ljsStartParallel(nproc);
+
+flist = dir(fullfile(ROOT,'*.LEVER'));
+parfor ff=1:length(flist)
+    strDB = fullfile(flist(ff).folder,flist(ff).name);
+    cmd = ['matlab -batch "Batch.processMovie(''' strDB ''',0,'  num2str(nthread) ')"'];
+    tx = tic();
+    [s,o] = system(cmd)
+    tElapsed = toc(tx);
+    ljsLog(['fini process ' strDB ' : tElapsed = ' num2str(tElapsed,'%0.0f')],0);
+end
\ No newline at end of file
diff --git a/matlab/+Batch/buildCompositeCache.m b/matlab/+Batch/buildCompositeCache.m
index 970bb6710857de1ed244a5566cd28f07f12c5eac..7e1e74a3cfe693f87af9edfd970a331816e14f0f 100644
--- a/matlab/+Batch/buildCompositeCache.m
+++ b/matlab/+Batch/buildCompositeCache.m
@@ -1,7 +1,5 @@
 % cache imLoG here -- keeps spmd procs from using CUDA and burning the
-% ~ 500MB per process CUDA vram overhead. We keep im while we're here
-% to cut down the disk read too. store in composite so we don't
-% duplicate memory on every client
+% ~ 500MB per process CUDA vram overhead. 
 function imCompCache=buildCompositeCache(imCompCache,commandList, ...
     idxCommandList,segParams,CONSTANTS,medianMask,tExistingSeg)
 
@@ -9,33 +7,40 @@ if ~exist('imCompCache','var')
     imCompCache=Composite();
 end
 
-for ix=1:length(imCompCache)
-    icc=[];
-    if ix+idxCommandList>size(commandList,1)
-        continue
+imWorkingCache = Composite();
+GPU_THREADS = 4;
+nPass = ceil(length(imCompCache) / GPU_THREADS);
+for n = 1 : nPass
+    spmd
+        if labindex<=GPU_THREADS      
+            icc=[];
+            workerindex = labindex + (n-1)*GPU_THREADS;
+            if workerindex+idxCommandList<=size(commandList,1)
+                t=commandList(workerindex+idxCommandList,1);
+                icc.t=t;
+            end
+            if t<=0 || t>CONSTANTS.imageData.NumberOfFrames || ~isempty(intersect(t,tExistingSeg))
+                icc.im=[];
+                icc.imLoG=[];
+                icc.sp = [];
+                icc.imnChannel = [];
+                imWorkingCache =icc;
+            else
+                sp=segParams;
+                sp.minimumRadius_um=commandList(workerindex+idxCommandList,2);
+                % copy the previous compCache entry if the t's match so we don't reload                
+                icc.im = DenoiseCache.readImages(t,CONSTANTS,sp,medianMask);                
+                [icc.imLoG, ~, ~] = LoG.getCompositeLoG(icc.im,CONSTANTS,sp);
+                icc.caChannelLoG = Segment.getChannelLoG(CONSTANTS, t, segParams);
+                icc.minimumRadius_um = sp.minimumRadius_um;
+                imWorkingCache =icc;
+            end
+        end
     end
-    t=commandList(ix+idxCommandList,1);
-    icc.t=t;
-    if t<=0 || t>CONSTANTS.imageData.NumberOfFrames || ~isempty(intersect(t,tExistingSeg))
-        icc.im=[];
-        icc.imLoG=[];
-        imCompCache{ix}=icc;
-        continue
-    end
-    sp=segParams;
-    sp.minimumRadius_um=commandList(ix+idxCommandList,2);
-    % copy the previous compCache entry if the t's match so we don't reload
-    if ix>1
-        imM1=imCompCache{ix-1};
-    else
-        imM1.t=-1;
-    end
-    if imM1.t==t
-        icc.im=imM1.im;
-    else
-        icc.im=DenoiseCache.readImages(t,CONSTANTS,sp,medianMask);
-    end
-    icc.imLoG=Segment.getLoG(icc.im,CONSTANTS,sp);
-    imCompCache{ix}=icc;
+    % only use gpu on working cache, first GPU_THREADS procs
+    % then copy results to full cache. Only a few procs can touch GPU
+    % without killing vram
+    imCompCache( (n-1)*GPU_THREADS + 1 : n*GPU_THREADS) = imWorkingCache(1:GPU_THREADS);
 end
-4;
\ No newline at end of file
+4;
+
diff --git a/matlab/+Batch/goProcess.m b/matlab/+Batch/goProcess.m
index 09e16dfbbc44718b0d9ec8037b6e56a9e1a2aecb..e933d62efbfee90708a079fe8fc5c946d39a5abf 100644
--- a/matlab/+Batch/goProcess.m
+++ b/matlab/+Batch/goProcess.m
@@ -6,13 +6,12 @@ end
 if ~exist('bForceSegment','var')
     bForceSegment=false;
 end
-processInfo=[];
 [~,~,ext]=fileparts(strDB);
 if strcmp(ext,'.LEVER')
     processInfo=Batch.processMovie(strDB,bForceSegment,nProcessors);
 else
     folderName=strDB;
-    flist=dir(fullfile(folderName,'**/*.LEVER'));        
+    flist=dir(fullfile(folderName,'*.LEVER'));        
     % denoise first - this keeps our cuda work separate. cuda charges a
     % sick overhead for each process    
     targetFolder=unique({flist.folder});
@@ -20,7 +19,7 @@ else
         DenoiseCache.denoiseFolder(targetFolder{tt});
     end
     for ff=1:length(flist)        
-        strDB=fullfile(flist(ff).folder,flist(ff).name);            
-        processInfo=[processInfo;Batch.processMovie(strDB,bForceSegment,nProcessors)];
+        strDB=fullfile(flist(ff).folder,flist(ff).name);  
+        processInfo = Batch.processMovie(strDB,bForceSegment,nProcessors);
     end
 end
\ No newline at end of file
diff --git a/matlab/+Batch/processMovie.m b/matlab/+Batch/processMovie.m
index bcf947a33d920f08302b2c93ec08601f7e52ae51..8bbce04fe7dfb4215df267d69c2cc6739b83af35 100644
--- a/matlab/+Batch/processMovie.m
+++ b/matlab/+Batch/processMovie.m
@@ -48,7 +48,9 @@ Smooth.Patch.patchOcclusion(conn);
 processInfo.tPatch=getElapsed(tx);
 
 tx=tic();
-nMerged = Smooth.Merge.goMerge(conn,CONSTANTS,segParams,nProcessors);
+% nMerged = Smooth.Merge.goMerge(conn,CONSTANTS,segParams,nProcessors);
+% nMerged = Smooth.Merge.goMerge2(conn, CONSTANTS, segParams);
+nMerged = -1;
 processInfo.tMerge=getElapsed(tx);
 
 tx=tic();
@@ -57,7 +59,9 @@ Smooth.extFamily(conn);
 processInfo.tClassify=getElapsed(tx);
 
 tx=tic();
-Batch.batchFeatures(conn,CONSTANTS,nProcessors);
+% batch features needs LoG in every frame...clip # procs to placate cuda
+nBatchProcessors = min(nProcessors,12); % 
+Batch.batchFeatures(conn,CONSTANTS,nBatchProcessors);
 processInfo.tFeatures=getElapsed(tx);
 
 processInfo.nMerged = nMerged;
@@ -74,6 +78,10 @@ ljsLog(sz,0);
 
 close(conn)
 
+if batchStartupOptionUsed
+    quit(0,'force')
+end
+
 function tElapsed=getElapsed(timerID)
 tElapsed=toc(timerID);
 tElapsed=round(tElapsed,2);
diff --git a/matlab/+CellFeatures/channelLoG.m b/matlab/+CellFeatures/channelLoG.m
index 343ee156baa5534744aee2f8d2896443e0d64a29..7db1f3217fa270daeebb7ba773a1a51d50054ccb 100644
--- a/matlab/+CellFeatures/channelLoG.m
+++ b/matlab/+CellFeatures/channelLoG.m
@@ -22,30 +22,44 @@ im = MicroscopeData.Reader('imageData',CONSTANTS.imageData, 'chanList',...
 if all(isnan(im(:)))
     return;
 end
+im = Segment.denoise(im,segParams,false);
 im=mat2gray(im);
 
-rCell = cellfun(@(x) std(x),{cellList.pts},'UniformOutput',false);
-rCell = median(vertcat(rCell{:}));
-rCell = mean(rCell);
-rCell_um = rCell .* CONSTANTS.imageData.PixelPhysicalSize(1);
-
-segParams.minimumRadius_um=rCell_um;
-imLoG = Segment.getLoG(im,CONSTANTS,segParams);
+imp = [];
+imn = []; % h2b wants imn
+if is3D(im)
+    rdim = 4;
+else
+    rdim = 3;
+end
 
-% keep only positive imLoG - e.g. darker blob against bright boundary 
-% or bright blob on dark boundary in complement
-% imLoG(imLoG<0)=0;
+rTarget_um = Ensemble.getEnsembleRadius(segParams.minimumRadius_um);
+for rr=1:length(rTarget_um)
+    sp = segParams;
+    sp.minimumRadius_um = rTarget_um(rr);
+    [~,imp_rr,imn_rr] = LoG.getCompositeLoG(im,CONSTANTS,sp);     
+    imp = cat(rdim,imp,imp_rr);
+%     imn = cat(rdim,imn,imn_rr);
+end
+% for now, we take dark nucleus against bright cytoplasm or nuclear rim.
+% this is for e. g. ERK or Oracle. This will show up on the positive LoG
+% response. 
+imp_max = max(imp,[],3);
+% 
+% imn_max = max(imn,[],3);
 
 cellFeatures=[];
 for i=1:length(cellList)   
-    bw=0*im;
-    bw(cellList(i).idxPts)=1;
-    bwd=bwdist(~bw);
-    thresh=prctile(bwd(find(bwd)),95);
-    bwd(bwd<thresh)=0;
-    channelLoG = imLoG(find(bwd));
-    channelLoG(channelLoG<=0)=0;
-    channelLoG=median(channelLoG);
+%     bw=0*im;
+%     bw(cellList(i).idxPts)=1;
+%     bwd=bwdist(~bw);
+%     thresh=prctile(bwd(find(bwd)),95);
+%     bwd(bwd<thresh)=0;
+%     channelLoG = imn_max(find(bwd));    
+%     channelLoG=median(channelLoG);
+    
+    center = round(cellList(i).centroid);
+    channelLoG = imp_max(center(2),center(1));
     cellFeatures=[cellFeatures;cellList(i).cellID,channelLoG]; 
 end
 tblCellFeatures.cellID=cellFeatures(:,1);
diff --git a/matlab/+DenoiseCache/denoiseFolder.m b/matlab/+DenoiseCache/denoiseFolder.m
index 4bba6216fae32826fc3d4050ddd1a8e757d3f6f8..0d12c85aa0b395a4fd28c82d2aeb6201361ec179 100644
--- a/matlab/+DenoiseCache/denoiseFolder.m
+++ b/matlab/+DenoiseCache/denoiseFolder.m
@@ -8,6 +8,8 @@ if 2==length(nProcessors)
     nProcessors=nProcessors(2);
 end
 
+nProcessors = min(nProcessors,8);
+
 flist=dir(fullfile(folderName,'*.h5'));
 if 0==length(flist)
     fprintf(2,'no lever files found to denoise\n');
diff --git a/matlab/+DenoiseCache/readImages.m b/matlab/+DenoiseCache/readImages.m
index 006b2026f24a4dc88f5f2e8df5025e3d2b1030ad..861e0a4af7a6aefed0c0f9fe9ac7bd0141c2e1e1 100644
--- a/matlab/+DenoiseCache/readImages.m
+++ b/matlab/+DenoiseCache/readImages.m
@@ -1,8 +1,7 @@
-function [im,imLog]=readImages(t,CONSTANTS,segParams,medianMask)
+function im = readImages(t,CONSTANTS,segParams,medianMask)
 
 if t>CONSTANTS.imageData.NumberOfFrames
     im=[];
-    imLog=[];
     return
 end
 
@@ -14,11 +13,7 @@ end
 targetFile=fullfile(CONSTANTS.imageData.imageDir,'cacheDenoise',...
         [CONSTANTS.imageData.DatasetName '.h5']);    
 if ~segParams.denoise || ~exist(targetFile,'file')
-    if 1==nargout
-        im=Segment.getImages(CONSTANTS,t,segParams.channels(1),segParams,medianMask);
-    else
-        [im,imLog]=Segment.getImages(CONSTANTS,t,segParams.channels(1),segParams,medianMask);
-    end
+    im=Segment.getImages(CONSTANTS,t,segParams.channels(1),segParams,medianMask);
     return;
 end
 
@@ -32,7 +27,7 @@ if size(nlm,1)~=1
     nlm=nlm';
 end
 if length(nlm)~=length(segParams.NLM) || any(segParams.NLM~=nlm)
-    [im,imLog]=Segment.getImages(CONSTANTS,t,segParams.channels(1),segParams,medianMask);
+    im=Segment.getImages(CONSTANTS,t,segParams.channels(1),segParams,medianMask);
     return;
 end
 
@@ -47,13 +42,5 @@ if 1==segParams.wellRadius && exist('medianMask','var') && ~isempty(medianMask)
     im=im-medianMask;
     im=mat2gray(im);
 end
-if 2==nargout
-    % try to grab imLog
-    logTarget=['/Images/LoG/' num2str(segParams.minimumRadius_um)];
-    try
-        imLog=h5read(targetFile,logTarget,[1,1,1,1,t],sz);
-    catch
-        imLog=Segment.getLoG(im,CONSTANTS,segParams);    
-    end
-end
+
 4;
diff --git a/matlab/+Ensemble/processEnsemble.m b/matlab/+Ensemble/processEnsemble.m
index 19c8881d37e89e2cf0d75b08d83673143002c54e..b58cf9c18bc33358b9dfd637a68dea64ca6f0b5e 100644
--- a/matlab/+Ensemble/processEnsemble.m
+++ b/matlab/+Ensemble/processEnsemble.m
@@ -76,6 +76,7 @@ ljsLog(sprintf('ensembleSegment: time=%d, found %d cells, elapsedTime=%2.3f ',..
 
 function areaStats=getCellSizeStats(conn,CONSTANTS)
 areaStats=[];
+return;
 cmd='select area from tblCells';
 q=ljsFetch(conn,cmd);
 if length(q)<100
@@ -98,7 +99,7 @@ function score=ScoreCell(areaStats,cell)
 cd=cell.ensemble.area/cell.ensemble.convexArea;
 logEff=sum(cell.ensemble.logEfficiency);
 score=cd+cell.ensemble.circularity + logEff + cell.ensemble.backgroundEfficiency;
-
+score = score + -1 * cell.LoG;
 
 % for each bucket (nestedCells{i}) of overlapping cells, we evaluate the
 % best subsets of cell combinations
@@ -150,7 +151,6 @@ for j=1:length(nestedCells{ic})
     % question of combining function -- min,max,mean,etc. relates to
     % cluster structure function. empirically chose min.
     % and on Dec 13 2019 tried max and mean as well. chose mean for now..:)
-%     scoreJ(j)=max([nestedCells{ic}(cellsJ{j}).score]);
     scoreJ(j)=mean([nestedCells{ic}(cellsJ{j}).score]);
     nestedCells{ic}(j).nest.score=scoreJ(j);
 end
diff --git a/matlab/+Ensemble/setCellEfficiency.m b/matlab/+Ensemble/setCellEfficiency.m
index 040acfb167a8056efc17ae5c590f1888532c0841..b33e9a04669bb33470565935bcd2badd0faa5627 100644
--- a/matlab/+Ensemble/setCellEfficiency.m
+++ b/matlab/+Ensemble/setCellEfficiency.m
@@ -16,10 +16,11 @@ idxPts=vertcat(Cells.idxPts);
 spx=segParams;
 spx.minimumRadius_um=0;
 % get foreground pixels with no minimum size
-[bw,bwLoG]=Segment.thresholdImages(im,imLoG,spx, 0,0,medianMask);
-bgEfficiency=length(idxPts)/length(find(bw));
-bgEfficiency=min(bgEfficiency,1);
+% [bw,bwLoG]=Segment.thresholdImages(im,imLoG,spx, 0,0,medianMask);
+% bgEfficiency=length(idxPts)/length(find(bw));
+% bgEfficiency=min(bgEfficiency,1);
 % 
+bgEfficiency = 0;
 
 imLoG_p=imLoG;
 imLoG_p(imLoG_p<0)=0;
diff --git a/matlab/+Ensemble/set_LoG_score.m b/matlab/+Ensemble/set_LoG_score.m
index eef0c58f794b80c14e914ca4dd6d6458d1415751..4dbf088fa71193e431e126fc420e31962d96ce01 100644
--- a/matlab/+Ensemble/set_LoG_score.m
+++ b/matlab/+Ensemble/set_LoG_score.m
@@ -1,12 +1,18 @@
-function cellList = set_LoG_score(cellList,CONSTANTS,im,segParams)
+function cellList = set_LoG_score(cellList,CONSTANTS,im,imLoG,segParams)
 
 cellList = Read.setCellsIdxPts(cellList,CONSTANTS);
+load('cacheReferenceLoG.mat');
 
 % figure;imagesc(im);hold on
-for i=1:length(cellList)
-    
-    cellList(i).log_score = LoG.referenceLoG(im,CONSTANTS,cellList(i),segParams);
-%     center = round(cellList(i).centroid);
-%     text(center(1),center(2),num2str(cellList(i).log_score,4),'color','k','BackgroundColor','w');
+for i=1:length(cellList)    
+    [log_score] = LoG.referenceLoG(im,imLoG,CONSTANTS,cellList(i),cacheReferenceLoG);
+    % bright nucleus on dark background - take negative response
+    cellList(i).log_score = log_score;
+%     if 1 || log_score > 0.5
+%         center = cellList(i).surface(1,:);
+%         text(center(1),center(2),[num2str(log_score,2)],'color','k','BackgroundColor','w');
+%     end
 end
 
+%cellList([cellList.log_score]>0.995)=[];
+4;
\ No newline at end of file
diff --git a/matlab/+Helpers/buildWrangleFile.m b/matlab/+Helpers/buildWrangleFile.m
index 01cdd3a35547e0c0e6493aa6a671f440767d2fe0..9d3cf4f801277cf671763c4a528e57c25fc742c4 100644
--- a/matlab/+Helpers/buildWrangleFile.m
+++ b/matlab/+Helpers/buildWrangleFile.m
@@ -1,5 +1,8 @@
 function strTarget=buildWrangleFile(strDB,outfolder,dsName,segParams)
 
+if ~exist(outfolder,'dir')
+    mkdir(outfolder);
+end
 strTarget=fullfile(outfolder,[dsName '.LEVER']);
 if exist(strTarget,'file')
     delete([strTarget '*']);
diff --git a/matlab/+Helpers/cellEccentricity.m b/matlab/+Helpers/cellEccentricity.m
new file mode 100644
index 0000000000000000000000000000000000000000..0f76c5e048e30167a23d4dcded626b238925212d
--- /dev/null
+++ b/matlab/+Helpers/cellEccentricity.m
@@ -0,0 +1,4 @@
+function ecc = cellEccentricity(cx)
+
+evals = eig(cov(cx.pts));
+ecc = min(evals)/max(evals);
\ No newline at end of file
diff --git a/matlab/+Helpers/drawSeg.m b/matlab/+Helpers/drawSeg.m
new file mode 100644
index 0000000000000000000000000000000000000000..2c0985219ed65bb62ac1357fb27a3003d4f7113b
--- /dev/null
+++ b/matlab/+Helpers/drawSeg.m
@@ -0,0 +1,7 @@
+function drawSeg(cellList)
+
+hold on
+for i=1:length(cellList)
+    ccc = Read.getTrackColor(conn,cellList(i).cellID);
+    plot(cellList(i).surface(:,1),cellList(i).surface(:,2),'Color',ccc);
+end
\ No newline at end of file
diff --git a/matlab/+Helpers/imMod4.m b/matlab/+Helpers/imMod4.m
new file mode 100644
index 0000000000000000000000000000000000000000..029fb3c30191fb710fc162c2d6199eae2c69730c
--- /dev/null
+++ b/matlab/+Helpers/imMod4.m
@@ -0,0 +1,9 @@
+function im=imMod4(im)
+
+d1 = mod(size(im,1) ,4);
+d2 = mod(size(im,2) ,4);
+
+if 0~=d1,d1=4-d1;end
+if 0~=d2,d2=4-d2;end
+
+im(size(im,1)+d1,size(im,2)+d2,end,end,end)=0;
\ No newline at end of file
diff --git a/matlab/+Helpers/imTransfer.m b/matlab/+Helpers/imTransfer.m
new file mode 100644
index 0000000000000000000000000000000000000000..1c2f99ce26a21fd0974970df2fe48970a2bd4665
--- /dev/null
+++ b/matlab/+Helpers/imTransfer.m
@@ -0,0 +1,44 @@
+% transfer is [dark, medium, bright] as in leverjs transfer function
+function imScale = imTransfer(im,transfer)
+x_min = transfer(1); % dark
+y_mid = transfer(2); % medium
+x_max = transfer(3); % bright
+x_mid = (x_max+x_min)/2;
+
+tm = [  x_min.^2, x_min, 1, 0;
+    x_mid.^2, x_mid, 1, 0;
+    x_max.^2, x_max, 1, 0;
+    0, 0, 0, 1]';
+tm = tm^-1;
+
+y_mid = max(y_mid,0.01);
+y_mid = min(y_mid,0.99);
+
+yVal  = [0, y_mid, 1, 1];
+
+coeffs = yVal * tm;
+a=coeffs(1);
+b=coeffs(2);
+c=coeffs(3);
+
+% so we now have a,b,c for ax^2+bx+c the actual transfer function
+% we want to find when the slope, 2ax+b of the transfer function goes negative
+% and make the range (minRange,maxRange) so that never happens
+if (a>0)
+    minRange = max(-b/(2*a),x_min);
+    maxRange = x_max;
+elseif (0==a)
+    minRange = x_min;
+    maxRange = x_max;
+else
+    minRange = x_min;
+    maxRange = min(-b/(2*a),x_max);
+end
+
+idx0 = find(im<minRange);
+idx1 = find(im>maxRange);
+imScale = a .* im.^2 + b .* im + c;
+imScale(idx0)=0;
+imScale(idx1)=1;
+imScale = max(imScale,0);
+imScale = min(imScale,1);
diff --git a/matlab/+Helpers/scaleBar.m b/matlab/+Helpers/scaleBar.m
index bfbf2ca2dbf4808c97283ee139e74a7808a2835a..83aab422f44cfc28b7b5545dc16f4c4672ccff1e 100644
--- a/matlab/+Helpers/scaleBar.m
+++ b/matlab/+Helpers/scaleBar.m
@@ -1,4 +1,4 @@
-function [nPixels,microns] = scaleBar(CONSTANTS,targetPixels)
+function [nPixels,microns] = scaleBar(CONSTANTS,targetPixels,szim)
 
 if ~exist('targetPixels','var')
     targetPixels = 100;
@@ -9,3 +9,10 @@ microns = targetPixels .* microns_per_pixel;
 microns = 5 * round(microns/5);
 nPixels = round(microns / microns_per_pixel);
 
+% rectangle('Position',[szim(2)-100,25,nPixels,10],'facecolor','w')
+% text(szim(2)-100+nPixels/2,25,'30um','color','w','HorizontalAlignment','center', ...
+%     'VerticalAlignment','bottom')
+
+rectangle('Position',[szim(2)-30-nPixels,40,nPixels,15],'FaceColor','w');
+% text(szim(2)-30-nPixels,15,[num2str(microns) '\mum'],'color','w','VerticalAlignment','top','fontsize',12)
+text(szim(2)-30-nPixels,5,[num2str(microns) '\mum'],'color','w','VerticalAlignment','top','fontsize',12)
diff --git a/matlab/+Helpers/swapXY.m b/matlab/+Helpers/swapXY.m
new file mode 100644
index 0000000000000000000000000000000000000000..d84c083fdb37a867d19eea8d105ada2fefc4775e
--- /dev/null
+++ b/matlab/+Helpers/swapXY.m
@@ -0,0 +1,5 @@
+function pts = swapXY(pts)
+
+tmp = pts(:,1);
+pts(:,1) = pts(:,2);
+pts(:,2) = tmp;
diff --git a/matlab/+Helpers/volumeSize.m b/matlab/+Helpers/volumeSize.m
new file mode 100644
index 0000000000000000000000000000000000000000..d68ec1efe305893ea40df836b4a4ccb9d8794cfa
--- /dev/null
+++ b/matlab/+Helpers/volumeSize.m
@@ -0,0 +1,5 @@
+% returns sz in bytes
+function sz = volumeSize (CONSTANTS)
+
+sz =[CONSTANTS.imageData.Dimensions, CONSTANTS.imageData.NumberOfChannels, CONSTANTS.imageData.NumberOfFrames];
+sz=[sz(2) sz(1) sz(3:end)];
diff --git a/matlab/+Import/prepareH5.m b/matlab/+Import/prepareH5.m
index 8096f0d20f05b9d48baa61d4965cde2a0bf8f570..dddace62f09c8b3b55afed21ddfdc9698acdc90a 100644
--- a/matlab/+Import/prepareH5.m
+++ b/matlab/+Import/prepareH5.m
@@ -4,6 +4,8 @@
 %
 % imageData=MicroscopeData.MakeMetadataFromImage(imx);
 %       remember to set imageData.NumberOfFrames and imageData.
+% IMPORTANT -- datasetName is e.g. Original, Denoise, etc., not your actual
+% datasetname
 function prepareH5(h5File,imageData,datasetName,szChunk)
 
 if ~exist('datasetName','var')
diff --git a/matlab/+Lineage/eraseLineage.m b/matlab/+Lineage/eraseLineage.m
new file mode 100644
index 0000000000000000000000000000000000000000..79116adb6bbfe7c6db1479c2034302740ac3621f
--- /dev/null
+++ b/matlab/+Lineage/eraseLineage.m
@@ -0,0 +1,9 @@
+function eraseLineage(conn)
+
+exec(conn,'delete from tblFamilies;delete from uiExtFamilies');
+strDB = conn.DataSource;
+Batch.batchTrack(strDB);
+Smooth.Patch.patch11(conn);
+Smooth.Patch.patch12(conn);
+Smooth.Patch.patch21(conn);
+Smooth.Patch.patchOcclusion(conn);
\ No newline at end of file
diff --git a/matlab/+LoG/+Reference/generateReferenceLoG.m b/matlab/+LoG/+Reference/generateReferenceLoG.m
new file mode 100644
index 0000000000000000000000000000000000000000..0aa752aa50286c0e56426af841fbe3eb70a1e4c0
--- /dev/null
+++ b/matlab/+LoG/+Reference/generateReferenceLoG.m
@@ -0,0 +1,43 @@
+function cacheReferenceLoG = generateReferenceLoG()
+
+b3D = false;
+
+if ~exist('szImage','var')
+    sz = [200,200];
+end
+if ~exist('rgRadius_pixels','var')
+    rgRadius = [1:0.5:20];
+end
+center=round(sz/2);
+cacheReferenceLoG = [];
+
+for xRadius = 1:length(rgRadius)
+    for yRadius = xRadius:length(rgRadius)
+        im = zeros(sz(1),sz(2));
+        rProjected = [rgRadius(xRadius),rgRadius(yRadius),0];
+        imref_small = HIP.MakeEllipsoidMask(rProjected);
+        refCenterSmall = size(imref_small)/2;
+        if b3D
+            idxRef = find(imref_small);
+            [r,c,z] = ind2sub(size(imref_small),idxRef);
+            idxRef = sub2ind(size(im),round(r+refCenter(1)-refCenterSmall(1)),...
+                round(c+refCenter(2)-refCenterSmall(2)),...
+                round(z+refCenter(3)-refCenterSmall(3)));
+            im(idxRef)=1;
+            d=3;
+        else
+            [r,c] = find(imref_small);
+            idxRef = sub2ind(size(im),round(r+center(1)-refCenterSmall(1)),...
+                round(c+center(2)-refCenterSmall(2)));
+            im(idxRef)=1;
+            d=2;
+        end
+        sigma = 1/sqrt(d) .* rProjected;
+        lr.imf = HIP.LoG(im,sigma,[]);
+        lr.radius = rProjected;
+        lr.maxResponse = max(abs(lr.imf(:)));
+        cacheReferenceLoG = [cacheReferenceLoG,lr];
+    end
+end
+save('cacheReferenceLoG.mat','cacheReferenceLoG');
+4;
\ No newline at end of file
diff --git a/matlab/+LoG/channelLoG_separate.m b/matlab/+LoG/channelLoG_separate.m
new file mode 100644
index 0000000000000000000000000000000000000000..8cc4a69d88aa2ae4f4408d30061fdae477de5321
--- /dev/null
+++ b/matlab/+LoG/channelLoG_separate.m
@@ -0,0 +1,18 @@
+function imOut = channelLoG_separate(caChannelLoG, bw, min_radius_pixels)
+
+bwd = bwdist(~bw);
+if is3D(bw)
+    bw = bw & (bwd > min(min_radius_pixels));
+else
+    bw = bw & (bwd > min_radius_pixels(1));
+end
+imOut = [];
+for cc=1:length(length(caChannelLoG))
+    [~,imp,imn] = LoG.separateLoG(caChannelLoG{cc});
+    if isempty(imOut)
+        imOut = max(imn.*bw, imp.*bw);
+    else
+        imOut = imOut + max(imn.*bw, imp.*bw);
+    end    
+end
+4;
diff --git a/matlab/+LoG/cleanLoG.m b/matlab/+LoG/cleanLoG.m
new file mode 100644
index 0000000000000000000000000000000000000000..023ee70e3f12a99304381d0e37c3fad0d1562001
--- /dev/null
+++ b/matlab/+LoG/cleanLoG.m
@@ -0,0 +1,85 @@
+% remove spurious LoG noise
+function [bwLoG,bwLoG_gradient]=cleanLoG(bwLoG_pos,bwLoG_neg,min_area_pixels,min_radius_pixels)
+
+% bright cell, dark bg
+% LoG+ is gradiants
+% LoG- is blobs
+% hint - see LoG.separateLoG, imc is [imp,imn,0] -> (r,g,b)
+
+if 1 == length(min_radius_pixels)
+    nhood = HIP.MakeEllipsoidMask(ceil([min_radius_pixels,min_radius_pixels,0]));
+else
+    nhood = HIP.MakeEllipsoidMask(ceil(min_radius_pixels));
+end
+
+if min(min_radius_pixels)/max(min_radius_pixels) < 0.25
+    baniso = true;
+else
+    % isotropic - use faster approximations for dilate/erode at cell scale
+    baniso = false;
+end
+
+baniso = false;
+
+
+defConn = conndef(ndims(bwLoG_pos),'minimal');
+
+bwLoG_neg = bwareaopen(bwLoG_neg,min_area_pixels,defConn);
+% distance from blob voxels to bg
+bwd_neg = bwdist(~bwLoG_neg);
+bwd_pos = bwdist(~bwLoG_pos);
+
+% blob must go 1 radius deep
+bwd_blob = bwd_neg;
+if baniso    
+    bwd_neg = imdilate(bwd_neg,nhood);
+    % pixels must be within 1 diameter (2 radii) of a pixel with
+    % depth>=min_radius
+    bwd_blob(bwd_neg<0.75*min(min_radius_pixels)) = 0;
+else
+    % imdilate with big 3-D nhood is toooo sloooooww
+    % so instead use distance tranform. lose anisotropy to gain speed
+    bwd_blob_deep = bwd_neg;
+    bwd_blob_deep(bwd_blob_deep<0.75*min(min_radius_pixels))=0;
+    bwd_deep_blob = bwdist(bwd_blob_deep);
+    % pixels must be within 1 diameter (2 radii) of a pixel with
+    % depth>=min_radius
+    bwd_blob(bwd_deep_blob>min(min_radius_pixels)) = 0;
+end
+% valid gradient must be adjacent to blobs 
+bwLoG_gradient = bwLoG_pos;
+bwd_gradient_to_blob = bwdist(bwd_blob);
+bwLoG_gradient(bwd_gradient_to_blob > min_radius_pixels(1)) = 0;
+bwLoG_gradient = bwareaopen(bwLoG_gradient,ceil(pi * min(min_radius_pixels)),defConn);
+
+% % ACK - controversial! gradient should have diameter of blob?
+if baniso
+    bwd_pos=imdilate(bwd_pos,nhood);
+    bwLoG_gradient(bwd_pos<min(min_radius_pixels))=0;
+else
+    % dilate too slow! use istropic distance instead as above
+    bwd_deep_gradient = bwd_pos;
+    bwd_deep_gradient(bwd_deep_gradient<min(min_radius_pixels)) = 0;
+    bwd_gradient_to_deep_gradient = bwdist(bwd_deep_gradient);
+    bwLoG_gradient(bwd_gradient_to_deep_gradient>min(min_radius_pixels))=0;
+end
+
+% blobs have to be adjacent to gradient
+bwd_blob_to_gradient = bwdist(bwLoG_gradient);
+if baniso
+    bwd_blob_to_gradient = imerode(bwd_blob_to_gradient,nhood);
+    % as above, pixels must be within 1 diameter of a gradient pixel
+    bwd_blob(bwd_blob_to_gradient > min_radius_pixels(1)) = 0;
+else
+    % imerode too slow! use anisotropic instead
+    bwd_blob_to_gradient(bwd_blob_to_gradient>max(min_radius_pixels))=0;
+    bwd_blob_to_gradient = bwdist(bwd_blob_to_gradient);
+    bwd_blob(bwd_blob_to_gradient > max(min_radius_pixels(1))) = 0;
+end
+
+bwLoG = logical(bwd_blob) ;
+bwLoG = imfill(bwLoG,'holes');
+bwLoG = Segment.aiAreaOpen(bwLoG,min_radius_pixels,defConn);
+
+4;
+
diff --git a/matlab/+LoG/drawCellScores.m b/matlab/+LoG/drawCellScores.m
index 6a201eb57d946122d6257e81b15dd7061a1d2f8e..e5a7115075f7fa919bc84e519e351b94d3c523ee 100644
--- a/matlab/+LoG/drawCellScores.m
+++ b/matlab/+LoG/drawCellScores.m
@@ -1,17 +1,6 @@
-
-strDB='/f/leverjs/Olivier/Yannick/20210924/20210924_pos3.LEVER';
-[conn,CONSTANTS,segParams]=openDB(strDB);
-
-t=300;
-cellList = Read.getCellsTime(conn,t);
-[imLoG,imc] = LoG.getCombinedLoG(conn,CONSTANTS,segParams,t,[1,6]);
-
-im = DenoiseCache.readImages(t,CONSTANTS,segParams);
-imagesc(im);colormap(gray);hold on;
-for i=1:length(cellList)
-    score = CellFeatures.sampleLoG(cellList(i),imLoG,CONSTANTS);
-    ccc = Read.getTrackColor(conn,cellList(i).trackID);
-    plot(cellList(i).surface(:,1),cellList(i).surface(:,2),'color',ccc);
-    text(max(cellList(i).surface(:,1)),cellList(i).centroid(2),num2str(score(2),2),'color','k','BackgroundColor','w','FontSize',8);
+function drawCellScores(cellList)
+for i=1:length(cellList)    
+    score = cellList(i).LoG;
+    text(max(cellList(i).surface(:,1)),cellList(i).centroid(2),num2str(score,2),'color','k','BackgroundColor','w','FontSize',8);
 end
 
diff --git a/matlab/+LoG/evalLoG2.m b/matlab/+LoG/evalLoG2.m
new file mode 100644
index 0000000000000000000000000000000000000000..9781e2f915655995094552180dafa2ea6ae6e69a
--- /dev/null
+++ b/matlab/+LoG/evalLoG2.m
@@ -0,0 +1,65 @@
+% strDB='/f/leverjs/g/ctc2021_wrangle/Fluo-N2DL-HeLa_training_02.LEVER';
+% strDB = '/f/leverjs/Parsons/MCF7_ERK_KTR_29April22/mcf7 erk ktrsora hoescht33324 trial run_mcf7_withH_1.LEVER'
+% strDB = '/g/leverjs/ctc2021_manual/2d/Fluo-N2DL-HeLa_training_01.LEVER'
+% [conn,CONSTANTS,segParams]=openDB(strDB);
+cellList = Segment.frameSegment(conn,1,CONSTANTS,segParams)
+r=[1:0.5:12];
+res=[];
+
+t=1;
+res={};
+imLoG = [];
+parfor ir = 1:length(r)
+
+    res{ir} = [];
+    sp=segParams;
+    rr = r(ir);
+    sp.minimumRadius_um=rr;
+    [im,imf] = DenoiseCache.readImages(t,CONSTANTS,sp);
+    cx=Segment.frameSegment(conn,t,CONSTANTS,sp);
+
+    for i=1:length(cellList)
+        % find any cx that overlaps cellList(i)
+        targetPoint = cellList(i).centroid;
+        if ~is3D(im)
+            targetPoint = targetPoint(1:2);
+        end
+
+        [cx1,dmin,idxMin] = Segment.findNearestSegmentation(cx,targetPoint);
+        if dmin>2
+            % this cell did not get a segmentation at this radius
+            continue
+        end
+        %             [cellScore,refVal] = LoG.referenceLoG(im,imf,CONSTANTS,cx(i),segParams);
+        %             cx(i).cellScore = cellScore;
+        res{ir}=vertcat(res{ir},[r(ir),i,idxMin,cx1.LoG]);
+    
+    end
+end
+
+cellRadii={};
+choice1=[];
+resR = vertcat(res{:});
+for i=1:length(cellList)
+    idx = find(resR(:,3)==i);
+    res1 = resR(idx,:);
+    res1 = sortrows(res1,4,'ascend');
+    cellRadii{i}=res1(:,1);
+    choice1(i)=res1(1,1);
+end
+
+
+% resR = vertcat(res{:});
+% resBest = [];
+% rHist = unique(resR(:,1))
+% histMap = containers.Map(rHist,repmat(0.0,size(rHist)));
+% for i=1:length(cellList)
+%     idx = find(resR(:,3)==i);
+%     for j=1:length(idx)
+%         histMap(resR(idx(j),1)) = histMap(resR(idx(j),1)) + 1;
+%     end
+% end
+%
+for i=1:length(cellList)
+    text(cellList(i).centroid(1),cellList(i).centroid(2),[num2str(i) ',' num2str(choice1(i),2)],'color','k','BackgroundColor','w');
+end
\ No newline at end of file
diff --git a/matlab/+LoG/getCombinedGradients.m b/matlab/+LoG/getCombinedGradients.m
new file mode 100644
index 0000000000000000000000000000000000000000..8795652327069e6fc6ce45a60d41ff71fcb94d7b
--- /dev/null
+++ b/matlab/+LoG/getCombinedGradients.m
@@ -0,0 +1,9 @@
+function imf = getCombinedGradients(im,CONSTANTS,rEval)
+
+imf = 0*im;
+for rr=1:length(rEval);
+    sp = Segment.getDefaultSegParams();
+    sp.minimumRadius_um = rEval(rr);
+    imf = Segment.getLoG(im,CONSTANTS,sp);
+end
+4;
\ No newline at end of file
diff --git a/matlab/+LoG/getCompositeLoG.m b/matlab/+LoG/getCompositeLoG.m
new file mode 100644
index 0000000000000000000000000000000000000000..bbf52b9348444c5b2b397d019bd16c2f7e08f4e9
--- /dev/null
+++ b/matlab/+LoG/getCompositeLoG.m
@@ -0,0 +1,38 @@
+function [imLoG, imp, imn] = getCompositeLoG(im,CONSTANTS,segParams)
+
+
+if is3D(im)
+    ndim = 4;
+    sampleSize = 10;
+else
+    ndim = 3;
+    sampleSize = 20;
+end
+
+if length(segParams.minimumRadius_um)>1
+    rgRadius = Ensemble.getEnsembleRadius(segParams.minimumRadius_um);
+else
+    rgRadius = linspace(0.75*segParams.minimumRadius_um,1.25*segParams.minimumRadius_um,sampleSize);
+end
+
+imLoG = [];
+
+for ir = 1:length(rgRadius)
+
+    sp=segParams;
+    rr = rgRadius(ir);
+    sp.minimumRadius_um=rr;
+
+    imf = Segment.getLoG(im,CONSTANTS,sp);
+    
+    imLoG = cat(ndim,imLoG,imf);
+
+end
+imn = min(imLoG,[],ndim);
+imn(imn>0) = 0;
+imn=abs(imn);
+
+imp = max(imLoG,[],ndim);
+imp(imp<0) = 0;
+imCombine = imp>imn;
+imLoG = imCombine.*imp + -1.*~imCombine.*imn;
diff --git a/matlab/+LoG/getRadiusPixels.m b/matlab/+LoG/getRadiusPixels.m
index 45a15b1c6dddf4721971906f2d326edd2a541a74..7bbd364227a7c897f0d9329339f71c6a5ee05a1b 100644
--- a/matlab/+LoG/getRadiusPixels.m
+++ b/matlab/+LoG/getRadiusPixels.m
@@ -1,10 +1,10 @@
 function radiusPixels = getRadiusPixels(CONSTANTS,segParams)
 
 
-radiusPixels = segParams.minimumRadius_um(1) .* CONSTANTS.imageData.PixelPhysicalSize;
+radiusPixels = segParams.minimumRadius_um(1) ./ CONSTANTS.imageData.PixelPhysicalSize;
 if is3D(CONSTANTS)
-    radiusPixels = radiusPixels ./ (1/sqrt(3));
+    radiusPixels = radiusPixels .* (1/sqrt(3));
 else
-    radiusPixels = radiusPixels ./ (1/sqrt(2));
+    radiusPixels = radiusPixels .* (1/sqrt(2));
     radiusPixels(3) = 0;
 end
diff --git a/matlab/+LoG/get_5d.m b/matlab/+LoG/get_5d.m
new file mode 100644
index 0000000000000000000000000000000000000000..647dfc91daf671887919f58231fd257512402cd6
--- /dev/null
+++ b/matlab/+LoG/get_5d.m
@@ -0,0 +1,19 @@
+% write a 5d lever file for this image
+strDB = '/f/leverjs/Parsons/MCF7_ERK_KTR_29April22/mcf7 erk ktrsora hoescht33324 trial run_mcf7_withH_2.LEVER'
+[conn,CONSTANTS,segParams] = openDB(strDB);
+rEval = [0.5:0.1:4];
+
+ljsStartParallel(24);
+for t = 1 : 1 %CONSTANTS.imageData.NumberOfFrames
+    logStack = [];    
+    imp=[];
+    imn=[];
+    parfor rr = 1:length(rEval)
+        sp = segParams;
+        sp.minimumRadius_um=rEval(rr);
+        [im,imLoG] = DenoiseCache.readImages(t,CONSTANTS,sp);
+        [~, imp(:,:,rr), imn(:,:,rr)] = LoG.separateLoG(imLoG);
+    end
+    logStack(:,:,:,1,1) = imp;
+    logStack(:,:,:,2,1) = imn;
+end
diff --git a/matlab/+LoG/logStudy_perCell.m b/matlab/+LoG/logStudy_perCell.m
new file mode 100644
index 0000000000000000000000000000000000000000..89cc6cbeecd57a5593829408f3a94f696aba1682
--- /dev/null
+++ b/matlab/+LoG/logStudy_perCell.m
@@ -0,0 +1,146 @@
+% strDB ='/f/leverjs/Olivier/wrangle/20210924_pos3.LEVER'
+% H2B = 1;
+% ERK = 2;
+% Oracle = 3;
+% 
+% strDB = '/g/leverjs/Olivier/Yannick/April_12_2021/20210129_20x_SD_LI2_HEO_3d_10s10t/20210129_20x_SD_LI2_HEO_3d_10s10t_s20.LEVER'
+% H2B = 3;
+% ERK = 2;
+% Oracle = 1;
+
+
+strDB = '/f/leverjs/Olivier/Yannick/April_12_2021/20210129_20x_SD_LI2_HEO_3d_10s10t/20210129_20x_SD_LI2_HEO_3d_10s10t_s02.LEVER'
+H2B = 3;
+ERK = 2;
+
+targetChannel = ERK;
+
+[conn,CONSTANTS,segParams]=openDB(strDB);
+[~,dsName,~] = fileparts(strDB); 
+dsName = [dsName '_erk'];
+% need better naming convention! ACK
+outfolder = ['./tiffs_' dsName];
+prefix = 'erk_log_';
+if ~exist(outfolder,'dir')
+    mkdir(outfolder) 
+   
+end
+
+% clip limits
+im = MicroscopeData.Reader('imageData',CONSTANTS.imageData, 'chanList',...
+    targetChannel,'timeRange',[1,1], 'outType',CONSTANTS.imageData.PixelFormat,'prompt',false);
+clipMax = double(max(im(:)));
+clipMin = double(min(im(:)));
+
+for t=1:CONSTANTS.imageData.NumberOfFrames
+    
+    cx=openDB(strDB);
+    cellList = Read.getCellsTime(cx,t,H2B,CONSTANTS);  
+    close(cx);
+
+    if ~is3D(CONSTANTS)
+        d = 2;
+        sz_um = CONSTANTS.imageData.PixelPhysicalSize(1:2);
+    else
+        d=3;
+        sz_um = CONSTANTS.imageData.PixelPhysicalSize;
+    end
+    rCell_pixels = cellfun(@(x) (sqrt(d) .* std(double(x))),{cellList.pts},'UniformOutput',false);   
+    rCell_um = cellfun(@(x) norm(x .* sz_um),rCell_pixels);
+    aCell_pixels = cellfun(@length,{cellList.pts});
+
+%     r0 = segParams.minimumRadius_um(1); %min(rCell_um);
+%     r1 = segParams.minimumRadius_um(3); %median(rCell_um);
+    r0 = min(rCell_um);
+    r1 = median(rCell_um);
+
+    rTarget_um = linspace(r0,r1,20);
+    rTarget_um = linspace(r0,r1,20);
+
+%     if ~is3D(CONSTANTS)
+%         d = 2;
+%         sz_um = CONSTANTS.imageData.PixelPhysicalSize(1:2);
+%     else
+%         d=3;
+%         sz_um = CONSTANTS.imageData.PixelPhysicalSize;
+%     end
+%     rCell_pixels = cellfun(@(x) (sqrt(d) .* std(double(x))),{cellList.pts},'UniformOutput',false);   
+%     rCell_um = cellfun(@(x) norm(x .* sz_um),rCell_pixels);
+%     aCell_pixels = cellfun(@length,{cellList.pts});
+        
+    r0 = min(rCell_um);
+    r1 = median(rCell_um);
+    rTarget_um = linspace(r0,r1,20);
+
+    %     rTarget_um = [min(rTarget_um),mean(diff(rTarget_um)),max(rTarget_um)];
+    im = MicroscopeData.Reader('imageData',CONSTANTS.imageData, 'chanList',...
+        targetChannel,'timeRange',[t t], 'outType',CONSTANTS.imageData.PixelFormat,'prompt',false);
+    im = double(im);
+    im = (im-clipMin)./(clipMax-clipMin);
+    im = im - median(im(:));
+    im = max(im,0);
+    im = min(im,1);
+    im = Segment.denoise(im,segParams,false);
+
+    imp = [];
+    if is3D(im)
+        rdim = 4;
+    else
+        rdim = 3;
+    end
+    imn = []; % h2b wants imn
+    for rr=1:length(rTarget_um)
+        sp = segParams;
+        sp.minimumRadius_um = rTarget_um(rr);
+        [~,imp_rr,imn_rr] = LoG.getCompositeLoG(im,CONSTANTS,sp);
+        imp = cat(rdim,imp,imp_rr);
+        imn = cat(rdim,imn,imn_rr);
+    end
+    imp_max = max(imp,[],rdim);
+    imn_max = max(imn,[],rdim);
+
+    if H2B == targetChannel
+        imp_max = imn_max; % capture h2b
+    end
+
+
+    im_segLoG = 0 * im;
+    for i=1:length(cellList)
+        im_segLoG(cellList(i).idxPts) = imp_max(cellList(i).idxPts);
+    end
+
+    im_segLoG = mat2gray(im_segLoG);
+    vbar = 0.33 * ones(size(im,1),5,3);
+
+    if H2B == targetChannel
+        imcx = Helpers.imTransfer(mat2gray(im),[0,1,0.5]);
+    else
+        imcx = im; %
+    end
+    imc = [];
+    imc(:,:,1)=0*im;
+    imc(:,:,2)=mat2gray(imcx);
+    imc(:,:,3)=imc(:,:,2);
+        
+    if H2B == targetChannel
+        imlx = Helpers.imTransfer(mat2gray(im_segLoG),[0,1,0.5]);
+    else
+        imlx = im_segLoG; %
+    end
+    imlc = [];
+    imlc(:,:,1)=imlx;
+    imlc(:,:,2)=imlx;
+    imlc(:,:,3)=imlx;
+    
+    imOut = [imc,vbar,imlc];
+    
+
+%     imOut = mat2gray([im,vbar,im_segLoG]);
+       
+%     figure(1);imagesc(imOut);axis image
+%     title(num2str(t))
+%     drawnow
+
+    fname = fullfile(outfolder,[prefix num2str(t) '.tif']);
+    imwrite(imOut,fname);
+end
diff --git a/matlab/+LoG/logStudy_perCell_3d_vis.m b/matlab/+LoG/logStudy_perCell_3d_vis.m
new file mode 100644
index 0000000000000000000000000000000000000000..85561cccfab52a01074cc481edca24f3db6b32de
--- /dev/null
+++ b/matlab/+LoG/logStudy_perCell_3d_vis.m
@@ -0,0 +1,168 @@
+% strDB ='/f/leverjs/Olivier/wrangle/20210924_pos3.LEVER'
+% H2B = 1;
+% ERK = 2;
+% Oracle = 3;
+% 
+% strDB = '/g/leverjs/Olivier/Yannick/April_12_2021/20210129_20x_SD_LI2_HEO_3d_10s10t/20210129_20x_SD_LI2_HEO_3d_10s10t_s20.LEVER'
+% H2B = 3;
+% ERK = 2;
+% Oracle = 1;
+
+
+strDB = '/g/leverjs/Olivier/mcf10a_3d_LoG/190827_wt_stage_1_00_movieS1.LEVER';
+H2B = 1;
+ERK = 2;
+
+bPreview = false;
+if ( ~bPreview )
+    movieFile='190827_wt_stage_1_00_movieS1_erk_ssf.avi';
+    vidWrite=VideoWriter(movieFile,'Motion JPEG AVI');
+    vidWrite.FrameRate=10;
+    open(vidWrite)
+end
+
+targetChannel = ERK;
+
+[conn,CONSTANTS,segParams]=openDB(strDB);
+
+% clip limits
+im = MicroscopeData.Reader('imageData',CONSTANTS.imageData, 'chanList',...
+    targetChannel,'timeRange',[1,1], 'outType',CONSTANTS.imageData.PixelFormat,'prompt',false);
+clipMax = double(max(im(:)));
+clipMin = double(min(im(:)));
+
+angles = linspace(0,360,CONSTANTS.imageData.NumberOfFrames);
+for t=1:CONSTANTS.imageData.NumberOfFrames
+    
+    cx=openDB(strDB);
+    cellList = Read.getCellsTime(cx,t,H2B,CONSTANTS);  
+    close(cx);
+
+%     r0 = segParams.minimumRadius_um(1); %min(rCell_um);
+%     r1 = segParams.minimumRadius_um(3); %median(rCell_um);
+%     rTarget_um = linspace(r0,r1,20);
+
+    if ~is3D(CONSTANTS)
+        d = 2;
+        sz_um = CONSTANTS.imageData.PixelPhysicalSize(1:2);
+    else
+        d=3;
+        sz_um = CONSTANTS.imageData.PixelPhysicalSize;
+    end
+    rCell_pixels = cellfun(@(x) (sqrt(d) .* std(double(x))),{cellList.pts},'UniformOutput',false);   
+    rCell_um = cellfun(@(x) norm(x .* sz_um),rCell_pixels);
+    aCell_pixels = cellfun(@length,{cellList.pts});
+%     r0 = min(rCell_um);
+%     r1 = median(rCell_um);
+r0=3;
+r1=5;
+    rTarget_um = linspace(r0,r1,20);
+
+    %     rTarget_um = [min(rTarget_um),mean(diff(rTarget_um)),max(rTarget_um)];
+    im = MicroscopeData.Reader('imageData',CONSTANTS.imageData, 'chanList',...
+        targetChannel,'timeRange',[t t], 'outType',CONSTANTS.imageData.PixelFormat,'prompt',false);
+    im = double(im);
+    im = (im-clipMin)./(clipMax-clipMin);
+    im = im - median(im(:));
+    im = max(im,0);
+    im = min(im,1);
+    im = Segment.denoise(im,segParams,false);
+    if (all(0==im(:)))
+        continue
+    end
+    imp = [];
+    if is3D(im)
+        rdim = 4;
+    else
+        rdim = 3;
+    end
+    imn = []; % h2b wants imn
+    for rr=1:length(rTarget_um)
+        sp = segParams;
+        sp.minimumRadius_um = rTarget_um(rr);
+        [~,imp_rr,imn_rr] = LoG.getCompositeLoG(im,CONSTANTS,sp);
+        imp = cat(rdim,imp,imp_rr);
+        imn = cat(rdim,imn,imn_rr);
+    end
+    imp_max = max(imp,[],rdim);
+    imn_max = max(imn,[],rdim);
+
+    if H2B == targetChannel
+        imp_max = imn_max; % capture h2b
+    end
+
+
+    im_segLoG = 0 * im;
+    for i=1:length(cellList)
+        im_segLoG(cellList(i).idxPts) = imp_max(cellList(i).idxPts);
+    end
+
+    im_segLoG = mat2gray(im_segLoG);
+    
+    
+    
+    % use leversc for [im,im_segLoG]
+    % setup original
+    if 1==t
+%         imd = CONSTANTS.imageData;
+%         imd.NumberOfChannels=1;
+%         lsc = leversc(im,imd);
+        %% Disable most UI elements
+              
+        imd = MicroscopeData.MakeMetadataFromImage(im);
+        imd.PixelPhysicalSize = [0.3700 0.3700 0.6000];
+        lsc = leversc(im,imd);
+        %% Reset view parameters (also set background to black)
+        lsc.viewParams.clipMode = 0;
+        lsc.viewParams.worldRot = reshape([1,0,0,0; 0,1,0,0; 0,0,1,0; 0,0,0,1], 16,1);
+        lsc.viewParams.zoom = 0;
+%         
+    end
+    leversc(im,imd);
+    lsc.viewParams.bgColor = [0,0,0];
+    lsc.uiParams.sidebar='none';  
+    lsc.uiParams.scalebar=false;    
+    lsc.renderParams.color=[0,1,0];
+    lsc.uiParams.webToolbar='none';
+    lsc.uiParams.clockButton='';
+    lsc.uiParams.logoDiv='';
+    lsc.uiParams.time=num2str(t);
+    lsc.renderParams.alpha=0.1;
+    % first ,im
+    while ~lsc.drawComplete()
+        pause(0.1);
+    end
+    imRawCap=lsc.captureImage();
+
+    lsc.show(im_segLoG);
+    lsc.uiParams.clockButton='none';
+    lsc.uiParams.logoDiv='none';
+    lsc.renderParams.color=[1,1,1];
+    lsc.uiParams.scalebar=true;
+    lsc.uiParams.webToolbar='none';
+    lsc.renderParams.alpha=1;
+
+    while ~lsc.drawComplete()
+        pause(0.1);
+    end
+    imLoGcap=lsc.captureImage();
+    imCap = [imRawCap,64*ones(size(imLoGcap,1),5,3),imLoGcap];
+
+%     ry=[cosd(angles(t)), 0, sind(angles(t)),0;
+%             0,1,0,0;
+%             -sind(angles(t)),0,cosd(angles(t)),0;
+%             0,0,0,1];
+% 
+%     worldRot=ry;
+%     lsc.viewParams.worldRot=worldRot(:);
+
+    
+    if ( bPreview )
+        imagesc(imCap);
+        axis image;
+        drawnow();
+    else
+        writeVideo(vidWrite,imCap);
+    end
+end
+close(vidWrite)
\ No newline at end of file
diff --git a/matlab/+LoG/logStudy_perCell_kymo.m b/matlab/+LoG/logStudy_perCell_kymo.m
new file mode 100644
index 0000000000000000000000000000000000000000..11d56e2268b5da09b8dd9a924e7c9404e04b7323
--- /dev/null
+++ b/matlab/+LoG/logStudy_perCell_kymo.m
@@ -0,0 +1,77 @@
+strDB ='/g/leverjs/Olivier/pos3/20210924_pos3.LEVER'
+H2B = 1;
+ERK = 2;
+Oracle = 3;
+
+% strDB = '/g/leverjs/Olivier/Yannick/April_12_2021/20210129_20x_SD_LI2_HEO_3d_10s10t/20210129_20x_SD_LI2_HEO_3d_10s10t_s20.LEVER'
+% H2B = 3;
+% ERK = 2;
+% Oracle = 1;
+
+targetChannel = ERK;
+
+imKymo = [];
+
+[conn,CONSTANTS,segParams]=openDB(strDB);
+
+% clip limits
+im = MicroscopeData.Reader('imageData',CONSTANTS.imageData, 'chanList',...
+    targetChannel,'timeRange',[1,1], 'outType','uint16','prompt',false);
+clipMax = double(max(im(:)));
+clipMin = double(min(im(:)));
+
+
+parfor t=1:CONSTANTS.imageData.NumberOfFrames
+    
+    imt = [];
+
+    cx=openDB(strDB);
+    cellList = Read.getCellsTime(cx,t,H2B,CONSTANTS);  
+    close(cx);
+
+    rCell_pixels = cellfun(@(x) std(double(x)),{cellList.pts},'UniformOutput',false);
+    rCell_um = mean(vertcat(rCell_pixels{:}),2) .* CONSTANTS.imageData.PixelPhysicalSize(1);
+    
+    r0 = prctile(mean(vertcat(rCell_pixels{:}),2),2.5);
+    r1 = prctile(mean(vertcat(rCell_pixels{:}),2),97.5);
+    rTarget_um = linspace(r0,r1,20);
+%     rTarget_um = [min(rTarget_um),mean(diff(rTarget_um)),max(rTarget_um)];
+    im = MicroscopeData.Reader('imageData',CONSTANTS.imageData, 'chanList',...
+        targetChannel,'timeRange',[t t], 'outType','uint16','prompt',false);
+    im = double(im);
+    im = (im-clipMin)./(clipMax-clipMin);
+    im = im - median(im(:));
+    im = max(im,0);
+    im = min(im,1);
+    im = Segment.denoise(im,segParams,false);
+
+    imp = [];
+    if is3D(im)
+        rdim = 4;
+    else
+        rdim = 3;
+    end
+    imn = []; % h2b wants imn
+    for rr=1:length(rTarget_um)
+        sp = segParams;
+        sp.minimumRadius_um = rTarget_um(rr);
+        [~,imp_rr,imn_rr] = LoG.getCompositeLoG(im,CONSTANTS,sp);
+        imp = cat(rdim,imp,imp_rr);
+        imn = cat(rdim,imn,imn_rr);
+    end
+    imp_max = max(imp,[],3);
+    imn_max = max(imn,[],3);
+
+    if H2B == targetChannel
+        imp_max = imn_max; % capture h2b
+    end
+
+
+    im_segLoG = 0 * im;
+    for i=1:length(cellList)
+        im_segLoG(cellList(i).idxPts) = imp_max(cellList(i).idxPts);
+    end
+
+%     im_segLoG = mat2gray(im_segLoG);
+    imKymo(:,:,t) = im_segLoG;
+end
diff --git a/matlab/+LoG/logStudy_perCell_sparse.m b/matlab/+LoG/logStudy_perCell_sparse.m
new file mode 100644
index 0000000000000000000000000000000000000000..2a35d711b65d40ca03cc24d8b7394b8c6603173e
--- /dev/null
+++ b/matlab/+LoG/logStudy_perCell_sparse.m
@@ -0,0 +1,143 @@
+% strDB ='/f/leverjs/Olivier/wrangle/20210924_pos3.LEVER'
+% H2B = 1;
+% ERK = 2;
+% Oracle = 3;
+
+% strDB = '/f/leverjs/Olivier/Yannick/April_12_2021/20210129_20x_SD_LI2_HEO_3d_10s10t/20210129_20x_SD_LI2_HEO_3d_10s10t_s01.LEVER'
+% H2B = 3;
+% ERK = 2;
+% Oracle = 1;
+
+
+strDB = '/f/leverjs/Parsons/May17_2022/mcf7 erk ktr on/mcf7 erk ktr on_s01.LEVER'
+ERK = 1;
+H2B = 2;
+targetChannel = ERK;
+
+[conn,CONSTANTS,segParams]=openDB(strDB);
+[~,dsName,~] = fileparts(strDB); 
+dsName = [dsName '_erk'];
+% need better naming convention! ACK
+outfolder = ['./tiffs_' dsName];
+prefix = 'erk_log_';
+if ~exist(outfolder,'dir')
+    mkdir(outfolder)
+end
+
+% clip limits
+im = MicroscopeData.Reader('imageData',CONSTANTS.imageData, 'chanList',...
+    targetChannel,'timeRange',[1,1], 'outType','uint16','prompt',false);
+clipMax = double(max(im(:)));
+clipMin = double(min(im(:)));
+
+
+parfor t=1:CONSTANTS.imageData.NumberOfFrames
+    
+    cx=openDB(strDB);
+    cellList = Read.getCellsTime(cx,t,H2B,CONSTANTS);  
+    close(cx);
+
+    if ~is3D(CONSTANTS)
+        d = 2;
+        sz_um = CONSTANTS.imageData.PixelPhysicalSize(1:2);
+    else
+        d=3;
+        sz_um = CONSTANTS.imageData.PixelPhysicalSize;
+    end
+    rCell_pixels = cellfun(@(x) (sqrt(d) .* std(double(x))),{cellList.pts},'UniformOutput',false);   
+    rCell_um = cellfun(@(x) norm(x .* sz_um),rCell_pixels);
+    aCell_pixels = cellfun(@length,{cellList.pts});
+        
+    r0 = segParams.minimumRadius_um(1); %min(rCell_um);
+    r1 = segParams.minimumRadius_um(3); %median(rCell_um);
+    rTarget_um = linspace(r0,r1,20);
+    im = MicroscopeData.Reader('imageData',CONSTANTS.imageData, 'chanList',...
+        targetChannel,'timeRange',[t t], 'outType','uint16','prompt',false);
+    im = double(im);
+    im = (im-clipMin)./(clipMax-clipMin);
+    im = im - median(im(:));
+    im = max(im,0);
+    im = min(im,1);
+    im = Segment.denoise(im,segParams,false);
+    bw = imbinarize(im,'adaptive');
+    bw = imfill(bw,'holes');
+
+    imp = [];
+    if is3D(im)
+        rdim = 4;
+    else
+        rdim = 3;
+    end
+    imn = []; % h2b wants imn
+    bwp = [];
+    for rr=1:length(rTarget_um)
+        sp = segParams;
+        sp.minimumRadius_um = rTarget_um(rr);
+        [~,imp_rr,imn_rr] = LoG.getCompositeLoG(im,CONSTANTS,sp);
+        imp = cat(rdim,imp,imp_rr);
+        imn = cat(rdim,imn,imn_rr);       
+    end
+    imp_max = max(imp,[],3);
+    imn_max = max(imn,[],3);
+   
+    if H2B == targetChannel
+        imp_max = imn_max; % capture h2b
+    end
+
+
+    im_segLoG = 0 * im;
+    for i=1:length(cellList)
+%         if length(find(bw(cellList(i).idxPts))) < 0.5*length(cellList(i).idxPts)
+%             continue;
+%         end
+        if sum(imp_max(cellList(i).idxPts)) < sum(imn_max(cellList(i).idxPts))
+            continue
+        end
+        im_segLoG(cellList(i).idxPts) = imp_max(cellList(i).idxPts);        
+    end
+    rp = regionprops(logical(im_segLoG),'MajorAxisLength','MinorAxisLength','PixelIdxList','Area','ConvexArea');
+    ecc = [rp.MinorAxisLength]./[rp.MajorAxisLength];
+    cd = [rp.Area]./[rp.ConvexArea];
+    idxReset = find(ecc<0.25 | cd<0.5);
+    if ~isempty(idxReset)
+        pixelIdxReset=vertcat(rp(idxReset).PixelIdxList);
+        %     [r,c] = ind2sub(size(im),pixelIdxReset);
+        %     hold on;plot(c,r,'.r')
+        im_segLoG(pixelIdxReset)=0;
+    end
+    im_segLoG = mat2gray(im_segLoG);
+    vbar = 0.33 * ones(size(im,1),5,3);
+
+    if H2B == targetChannel
+        imcx = Helpers.imTransfer(mat2gray(im),[0,1,0.5]);
+    else
+        imcx = im; %
+    end
+    imc = [];
+    imc(:,:,1)=0*im;
+    imc(:,:,2)=mat2gray(imcx);
+    imc(:,:,3)=imc(:,:,2);
+    
+    if H2B == targetChannel
+        imlx = Helpers.imTransfer(mat2gray(im_segLoG),[0,1,0.5]);
+    else
+        imlx = im_segLoG; %
+    end
+%     imlc = [];
+%     imlc(:,:,1)=imlx;
+%     imlc(:,:,2)=imlx;
+%     imlc(:,:,3)=imlx;
+    imlc = ind2rgb(gray2ind(imlx,255),hot(255));
+    
+    imOut = [imc,vbar,imlc];
+    
+
+%     imOut = mat2gray([im,vbar,im_segLoG]);
+       
+%     figure(1);imagesc(imOut);axis image
+%     title(num2str(t))
+%     drawnow
+
+    fname = fullfile(outfolder,[prefix num2str(t) '.tif']);
+    imwrite(imOut,fname);
+end
diff --git a/matlab/+LoG/principalEllipse.m b/matlab/+LoG/principalEllipse.m
new file mode 100644
index 0000000000000000000000000000000000000000..30872627d84c853f6433d7013707274cd9d401a1
--- /dev/null
+++ b/matlab/+LoG/principalEllipse.m
@@ -0,0 +1,41 @@
+function [rcz, imref, idxRef, rProjected] = principalEllipse(projectedPts)
+
+% compute axes in SVD space
+rProjected = (max(projectedPts)-min(projectedPts)) / 2;
+
+if size(projectedPts,2)==2    
+    b3D = false;
+    rProjected(3) = 0;
+else
+    b3D = true;    
+end
+imref_small = HIP.MakeEllipsoidMask(rProjected);
+refCenterSmall = size(imref_small)/2;
+sz = 6.*ceil(rProjected);
+
+if b3D
+    idxRef = find(imref_small);
+    [r,c,z] = ind2sub(size(imref_small),idxRef);
+else
+    [r,c] = find(imref_small);
+    sz(3)=[];
+end
+
+refCenter = sz/2;
+imref = zeros(sz);
+
+if b3D
+    idxRef = sub2ind(size(imref),round(r+refCenter(1)-refCenterSmall(1)),...
+        round(c+refCenter(2)-refCenterSmall(2)),...
+        round(z+refCenter(3)-refCenterSmall(3)));
+    imref(idxRef)=1;
+    [r,c,z] = ind2sub(size(imref),idxRef);
+    rcz = [r,c,z];
+else
+    idxRef = sub2ind(size(imref),round(r+refCenter(1)-refCenterSmall(1)),...
+        round(c+refCenter(2)-refCenterSmall(2)));
+    imref(idxRef)=1;
+    [r,c] = ind2sub(size(imref),idxRef);
+    rcz = [r,c];
+end
+rcz = rcz - size(imref)./2 - 1;
diff --git a/matlab/+LoG/referenceLoG.m b/matlab/+LoG/referenceLoG.m
index dacd10bc1b862c2e2346ff4ea57846fbebaf9858..1ab3a99c5dc7c5edb02f376d749127f78ec41a5f 100644
--- a/matlab/+LoG/referenceLoG.m
+++ b/matlab/+LoG/referenceLoG.m
@@ -1,53 +1,33 @@
-function cellScore = referenceLoG(im,CONSTANTS,targetCell,segParams)
+function [cellScore] = referenceLoG(im,imLoG,CONSTANTS,targetCell,cacheReferenceLoG)
 
 cellScore = 0;
 
-% targetRadius = std(targetCell.pts);
-targetRadius = max(segParams.minimumRadius_um);
-targetRadius = repmat(targetRadius,[1,3]);
-sz=5*ceil(max(targetCell.maxRadius,targetRadius));
-refCenter=round(sz/2);
-
-if is3D(im)
-    targetRadius = 1/sqrt(3) * targetRadius;
-    imref=zeros(sz);
-    targetCentroid = targetCell.centroid;
+targetPts = double(targetCell.pts);
+targetPts = targetPts - mean(targetPts);
+[U,S,V] = svd(targetPts,'econ');
+projectedPts = targetPts * V;
+rProjected = (max(projectedPts)-min(projectedPts)) / 2;
+if size(projectedPts,2)==2    
+    b3D = false;    
+    rProjected = [min(rProjected),max(rProjected),0];
 else
-    imref=zeros(sz(1:2));
-    targetRadius = 1/sqrt(2) * targetRadius;
-    targetRadius(3) = 0;
-    refCenter = refCenter(1:2);
-    targetCentroid = targetCell.centroid(1:2);
-end
-targetCell = Read.setCellsIdxPts(targetCell,CONSTANTS);
-for y=1:size(imref,1)
-    for x=1:size(imref,2)
-        d = sqrt((y-refCenter(1))^2 + (x-refCenter(2))^2);
-        if d<targetRadius(1) % ACK -- get a super-ellipse!
-            imref(y,x)=1;
-        end
-    end
+    b3D = true;
+    % yikes TODO
 end
 
-imRefLoG = HIP.LoG(imref,targetRadius,[]);
-imLoG = HIP.LoG(im,targetRadius,[]);
-
-% match smaller ref image to full size imLoG
-targetCentroid = repmat(targetCentroid,[size(targetCell.pts,1),1]);
-refOffset = targetCell.pts - targetCentroid + refCenter;
-refOffset = round(refOffset);
-srcIdx = sub2ind(size(imRefLoG),refOffset(:,1),refOffset(:,2));
-
-% cell score is NOT sum of square difference - 'cause...
-% ACK check for idx out of range...
-sourceStats = [mean(imLoG(targetCell.idxPts)), std(imLoG(targetCell.idxPts))];
-refStats = [mean(imRefLoG(srcIdx )), std(imRefLoG(srcIdx ))];
-
-% % use Fisher Discrim Dist
-% d =  (sourceStats(1) - refStats(1)).^2 / (sourceStats(2) + refStats(2));
-% cellScore = 1-d;
+d = pdist2(vertcat(cacheReferenceLoG.radius),rProjected);
+[~,idx] = min(d);
+imref = cacheReferenceLoG(idx).imf;
+% projected points on reference image
+refProjectedPts = round(projectedPts + size(imref)./2);
+if is3D(CONSTANTS)
+    idxRefProjected  = sub2ind(size(imref),refProjectedPts(:,1),refProjectedPts(:,2),refProjectedPts(:,3));
+else
+    idxRefProjected  = sub2ind(size(imref),refProjectedPts(:,1),refProjectedPts(:,2));
+end
+imref = imref .* mean(im(targetCell.idxPts));
+% compute MAD
+cellScore = 1- mean( abs( imLoG(targetCell.idxPts) - imref(idxRefProjected) ) );
+4;
 
-% ok maybe it is MAD
-cellScore = 1- mean(abs(imLoG(targetCell.idxPts) - imRefLoG(srcIdx)));
 
-4;
\ No newline at end of file
diff --git a/matlab/+LoG/sampleCell.m b/matlab/+LoG/sampleCell.m
new file mode 100644
index 0000000000000000000000000000000000000000..626561c0fd339bfffc09c948d0b2769c613f80e3
--- /dev/null
+++ b/matlab/+LoG/sampleCell.m
@@ -0,0 +1,13 @@
+function cval = sampleCell(newCell,CONSTANTS,imLoG)
+center = round(newCell.centroid);
+
+if is3D(imLoG)
+    center = min(center,CONSTANTS.imageData.Dimensions);
+    center = max(center, [1,1,1]);
+    cval = imLoG(center(2),center(1),center(3));
+else
+    center = center(1:2);
+    center = min(center,CONSTANTS.imageData.Dimensions(1:2));
+    center = max(center, [1,1]);
+    cval = imLoG(center(2),center(1));
+end
diff --git a/matlab/+LoG/separateLoG.m b/matlab/+LoG/separateLoG.m
index 5f7d1a664f236aa2d3f735c74fdd1ac16aa30ebb..9b7516c07fb9e38d0e7f844d2858cb48e8195d6f 100644
--- a/matlab/+LoG/separateLoG.m
+++ b/matlab/+LoG/separateLoG.m
@@ -1,19 +1,24 @@
-function [imc, imp, imn] = separateLoG(imf)
+% returns color separated LoG
+% imc is scaled, as with leverjs transfer function [dark,medium,bright]
+function [imc, imp, imn] = separateLoG(imf,transfer)
 
+if ~exist('transfer','var')
+    transfer = [0,1,0.125];
+end
 imp=imf;
 imp(imp<0)=0;
 imn=imf;
 imn(imn>0)=0;
 imn=abs(imn);
 
-imp1=mat2gray(imp);
-imn1=mat2gray(imn);
+imp1=Helpers.imTransfer(imp,transfer);
+imn1=Helpers.imTransfer(imn,transfer);
 
 if is3D(imf)
     imc(:,:,:,1)=imp1;
     imc(:,:,:,2)=imn1;
-    imc(:,:,:,3)=0*imf;
 else
+    % 3 channels - pack to rgb 2-D
     imc(:,:,1)=imp1;
     imc(:,:,2)=imn1;
     imc(:,:,3)=0*imf;
diff --git a/matlab/+LoG/show5d.m b/matlab/+LoG/show5d.m
new file mode 100644
index 0000000000000000000000000000000000000000..f04c2eec40babb564f3704f9dc83b4ef576b2dcd
--- /dev/null
+++ b/matlab/+LoG/show5d.m
@@ -0,0 +1,31 @@
+% write a 5d lever file for this image
+
+strDB = '/f/leverjs/Olivier/Yannick/20210924/20210924_pos3.LEVER';
+[conn,CONSTANTS,segParams] = openDB(strDB);
+rEval = [0.5:0.25:6];
+[~,dsName,~] = fileparts(strDB);
+datasetName = [dsName '_LoG_' mat2str([rEval(1),length(rEval),rEval(end)])];
+datasetName = strrep(datasetName,' ','_');
+datasetName = strrep(datasetName,'[','');
+datasetName = strrep(datasetName,']','');
+
+outfolder = '/f/leverjs/andy';
+if ~exist(outfolder,'dir')
+    mkdir(outfolder);
+end
+h5file = [fullfile(outfolder,datasetName) '.h5'];
+t = CONSTANTS.imageData.NumberOfFrames
+logStack = [];
+for rr = 1:length(rEval)
+    segParams.minimumRadius_um=rEval(rr);
+    [im,imLoG] = DenoiseCache.readImages(t,CONSTANTS,segParams);
+
+    [~, imp, imn] = LoG.separateLoG(imLoG);
+    logStack(:,:,rr,1,1) = imp;
+    logStack(:,:,rr,2,1) = imn;
+end
+imd = Import.makeMetaData(logStack);
+imd.ChannelNames={'LoG+','LoG-'};
+
+leversc(im,imd)
+
diff --git a/matlab/+LoG/write_5d.m b/matlab/+LoG/write_5d.m
new file mode 100644
index 0000000000000000000000000000000000000000..bac38575fbe1aca67c919f33ca53a46976b30035
--- /dev/null
+++ b/matlab/+LoG/write_5d.m
@@ -0,0 +1,41 @@
+% write a 5d lever file for this image
+
+% strDB = '/f/leverjs/Olivier/Yannick/20210924/20210924_pos3.LEVER';
+% [conn,CONSTANTS,segParams] = openDB(strDB);
+rEval = [1:0.25:4];
+[~,dsName,~] = fileparts(strDB);
+datasetName = [dsName '_h2b__LoG_' mat2str([rEval(1),length(rEval),rEval(end)])];
+datasetName = strrep(datasetName,' ','_');
+datasetName = strrep(datasetName,'[','');
+datasetName = strrep(datasetName,']','');
+datasetName = strrep(datasetName,'.','x');
+
+outfolder = '/f/leverjs/andy';
+if ~exist(outfolder,'dir')
+    mkdir(outfolder);
+end
+ljsStartParallel(24);
+h5file = [fullfile(outfolder,datasetName) '.h5'];
+for t = 1 : 1 %CONSTANTS.imageData.NumberOfFrames
+    logStack = [];    
+    imp=[];
+    imn=[];
+    parfor rr = 1:length(rEval)
+        sp = segParams;
+        sp.minimumRadius_um=rEval(rr);
+        [im,imLoG] = DenoiseCache.readImages(t,CONSTANTS,sp);
+        [~, imp(:,:,rr), imn(:,:,rr)] = LoG.separateLoG(imLoG);
+    end
+    logStack(:,:,:,1,1) = imp;
+    logStack(:,:,:,2,1) = imn;
+
+    if 1==t
+        imageData = Import.makeMetaData(logStack);
+        imageData.DatasetName = datasetName;
+        imageData.ChannelNames = {'LoG+','LoG-'};
+        imageData.NumberOfFrames = CONSTANTS.imageData.NumberOfFrames;
+        Import.prepareH5(h5file,imageData);
+    end
+    Import.appendH5Frame(h5file,logStack,t);
+end
+Import.leverImport('',outfolder);
\ No newline at end of file
diff --git a/matlab/+MovieMaker/goFigureAnimation.m b/matlab/+MovieMaker/goFigureAnimation.m
index 7a6c8ad7a49e49f3f2d21a2421096653a218a950..cdf3798843e633a891c9d5badf6a6c94d5c25a7e 100644
--- a/matlab/+MovieMaker/goFigureAnimation.m
+++ b/matlab/+MovieMaker/goFigureAnimation.m
@@ -3,7 +3,7 @@
 % periodicity toggle? if true remove final frame
 % changing number of inbetweens to speed up or slow down the animation
 
-fileName = 'coralGraph';                 % name of movie generated
+fileName = 'ssfClustering';              % name of movie generated
 frameRate = 30;                          % desired frame rate
 duration = 30;                           % desired length of movie in seconds
 azimuthList = [-20,-110,-190,-290,-380]; % camera pan angle at key frames
@@ -46,4 +46,4 @@ for frame = 1:size(angleList,1)
     writeVideo(v,getframe(gcf));
 end
 
-close(v);
\ No newline at end of file
+close(v);
diff --git a/matlab/+MovieMaker/printLoG.m b/matlab/+MovieMaker/printLoG.m
new file mode 100644
index 0000000000000000000000000000000000000000..5c9e4d3c136d3fa3e48fba776dd003e1d16ca770
--- /dev/null
+++ b/matlab/+MovieMaker/printLoG.m
@@ -0,0 +1,41 @@
+% strDB ='/f/leverjs/Olivier/Yannick/20210924/20210924_pos2.LEVER'
+strDB = '/f/leverjs/Olivier/Yannick/April_12_2021/20210129_20x_SD_LI2_HEO_3d_10s10t*20210129_20x_SD_LI2_HEO_3d_10s10t_s01.LEVER'
+[conn,CONSTANTS,segParams]=openDB(strDB);
+rEval = [1,0.2,4];
+
+[~,dsName,~] = fileparts(strDB); 
+outfolder = ['./tiffs_' dsName];
+
+if ~exist(outfolder,'dir')
+    mkdir(outfolder)
+end
+
+H2B_CHANNEL = 3;
+ERK_CHANNEL = 2;
+Oracle_CHANNEL = 1;
+
+prefix = '';
+for t=1:CONSTANTS.imageData.NumberOfFrames
+    % ACK !!! denoise?
+    [im,CONSTANTS] = leversc.loadImage(strDB,t,H2B_CHANNEL);
+    im = leversc.loadImage(strDB,t,H2B_CHANNEL);
+    im = mat2gray(im);
+    imLoG = LoG.getCombinedGradients(im,CONSTANTS,rEval);
+    imc_H2B = LoG.separateLoG(imLoG);
+
+    [im,CONSTANTS] = leversc.loadImage(strDB,t,ERK_CHANNEL);
+    im = mat2gray(im);
+    imLoG = LoG.getCombinedGradients(im,CONSTANTS,rEval);
+    imc_ERK = LoG.separateLoG(imLoG);
+
+    [im,CONSTANTS] = leversc.loadImage(strDB,t,Oracle_CHANNEL);
+    im = mat2gray(im);
+    imLoG = LoG.getCombinedGradients(im,CONSTANTS,rEval);
+    imc_Oracle = LoG.separateLoG(imLoG);
+
+    vbar = 0.33* ones(size(im,1),5,3);
+    imc = double([imc_H2B,vbar,imc_ERK,vbar,imc_Oracle]);
+    
+    fname = fullfile(outfolder,[prefix num2str(t) '.tif']);
+    imwrite(imc,fname);
+end
diff --git a/matlab/+MovieMaker/ssfMovie1.m b/matlab/+MovieMaker/ssfMovie1.m
new file mode 100644
index 0000000000000000000000000000000000000000..87cea0b80da17d901b371e372d38215d4de861be
--- /dev/null
+++ b/matlab/+MovieMaker/ssfMovie1.m
@@ -0,0 +1,127 @@
+% called from breakpoint on Segment.frameSegment after cleanLoG
+% strDB = '/g/leverjs/Olivier/mcf10a_3d_LoG/190827_wt_stage_1_00_movieS1.LEVER';
+function ssfMovie1(im,bwLoG_pos,bwLoG_neg)
+
+bPreview = false
+
+bwx = bwLoG_pos;
+bwx(:,:,:,2) = bwLoG_neg;
+imd = MicroscopeData.MakeMetadataFromImage(bwx);
+imd.PixelPhysicalSize = [0.3700 0.3700 0.6000];
+lsc = leversc(bwx,imd);
+
+
+
+    %% Set up pre-selected render properties
+    %% Disable most UI elements
+    lsc.uiParams.time='none';
+    lsc.uiParams.sidebar='none';
+    lsc.uiParams.clockButton='none';
+    lsc.uiParams.webToolbar='none';
+    
+    %% Reset view parameters (also set background to black)
+    lsc.viewParams.clipMode = 0;
+    lsc.viewParams.worldRot = reshape([1,0,0,0; 0,1,0,0; 0,0,1,0; 0,0,0,1], 16,1);
+    lsc.viewParams.zoom = 0;
+    lsc.viewParams.bgColor = [0,0,0];
+    
+    if ( ~bPreview )
+        movieFile='h2b_ssf_movie1.avi';
+        vidWrite=VideoWriter(movieFile,'Motion JPEG AVI');
+        vidWrite.FrameRate=10;
+        open(vidWrite)
+    end
+    
+    %% Rotate 360 around in 15sec
+    angles = linspace(0,360,150);
+    for i=2:length(angles)
+        ry=[cosd(angles(i)), 0, sind(angles(i)),0;
+            0,1,0,0;
+            -sind(angles(i)),0,cosd(angles(i)),0;
+            0,0,0,1];
+
+        worldRot=ry;        
+        lsc.viewParams.worldRot=worldRot(:);
+
+        lsc.renderParams(1).alpha=1;
+        lsc.uiParams.logoDiv='';
+        lsc.uiParams.scalebar=false;
+        lsc.renderParams(1).medium=1;
+        lsc.show(im);
+        imRaw = get_rendered_frame(lsc);
+
+        lsc.renderParams(1).alpha=0.02;
+        lsc.uiParams.logoDiv='none';
+        lsc.uiParams.scalebar=true;
+        lsc.renderParams(1).medium=0.5;
+        lsc.show(bwx);
+        imX = get_rendered_frame(lsc);
+        
+        imCap = [imRaw,128*ones(size(imRaw,1),5,3),imX];
+        if ( bPreview )
+            imagesc(imCap);
+            axis image;
+            drawnow();
+        else
+            writeVideo(vidWrite,imCap);
+        end
+    end
+    
+    % Padding for 0.2 sec
+    if ( ~bPreview )
+        writeVideo(vidWrite,imCap);
+        writeVideo(vidWrite,imCap);
+    end
+    
+    %% Put sample plane at the back of the volume and set to planar clipping mode,
+    %% then animate plane movement into just back from center
+    % in 10 seconds
+    planeZs = linspace(0,35, 100);
+    lsc.viewParams.planeCenter(3) = planeZs(1);
+    lsc.viewParams.clipMode = 1; % Plane-clipping mode
+    for i=1:length(planeZs)
+        lsc.viewParams.planeCenter(3) = planeZs(i);
+
+        lsc.uiParams.logoDiv='';
+        lsc.uiParams.scalebar=false;
+        lsc.renderParams(1).medium=1;
+        lsc.renderParams(1).alpha=1;
+        lsc.show(im);
+        imRaw = get_rendered_frame(lsc);
+
+        lsc.uiParams.logoDiv='none';
+        lsc.uiParams.scalebar=true;
+        lsc.renderParams(1).medium=0.5;
+        lsc.renderParams(1).alpha=0.02;
+        lsc.show(bwx);
+        imX = get_rendered_frame(lsc);
+
+        imCap = [imRaw,128*ones(size(imRaw,1),5,3),imX];
+        if ( bPreview )
+            imagesc(imCap);
+            axis image;
+            drawnow();
+        else
+            writeVideo(vidWrite,imCap);
+        end
+    end
+    
+    % Padding for 0.2 sec
+    if ( ~bPreview )
+        writeVideo(vidWrite,imCap);
+        writeVideo(vidWrite,imCap);
+    end
+    
+    if ( ~bPreview )
+        close(vidWrite)
+    end
+end
+
+function im = get_rendered_frame(lsc)
+    % We need to poll for draw-complete in order to avoid timeouts
+    while ~lsc.drawComplete()
+        pause(0.1);
+    end
+    im=lsc.captureImage();
+end
+
diff --git a/matlab/+MovieMaker/ssfMovie_erk.m b/matlab/+MovieMaker/ssfMovie_erk.m
new file mode 100644
index 0000000000000000000000000000000000000000..7b850a4a63f18275100ecfa88c7c70371e62c495
--- /dev/null
+++ b/matlab/+MovieMaker/ssfMovie_erk.m
@@ -0,0 +1,128 @@
+% called from breakpoint on Segment.frameSegment after cleanLoG
+% strDB = '/g/leverjs/Olivier/mcf10a_3d_LoG/190827_wt_stage_1_00_movieS1.LEVER';
+function ssfMovie1(strDB)
+
+bPreview = true
+
+
+bwx = bwLoG_pos;
+bwx(:,:,:,2) = bwLoG_neg;
+imd = MicroscopeData.MakeMetadataFromImage(bwx);
+imd.PixelPhysicalSize = [0.3700 0.3700 0.6000];
+lsc = leversc(bwx,imd);
+
+
+
+    %% Set up pre-selected render properties
+    %% Disable most UI elements
+    lsc.uiParams.time='none';
+    lsc.uiParams.sidebar='none';
+    lsc.uiParams.clockButton='none';
+    lsc.uiParams.webToolbar='none';
+    
+    %% Reset view parameters (also set background to black)
+    lsc.viewParams.clipMode = 0;
+    lsc.viewParams.worldRot = reshape([1,0,0,0; 0,1,0,0; 0,0,1,0; 0,0,0,1], 16,1);
+    lsc.viewParams.zoom = 0;
+    lsc.viewParams.bgColor = [0,0,0];
+    
+    if ( ~bPreview )
+        movieFile='h2b_ssf_movie1.avi';
+        vidWrite=VideoWriter(movieFile,'Motion JPEG AVI');
+        vidWrite.FrameRate=10;
+        open(vidWrite)
+    end
+    
+    %% Rotate 360 around in 15sec
+    angles = linspace(0,360,150);
+    for i=2:length(angles)
+        ry=[cosd(angles(i)), 0, sind(angles(i)),0;
+            0,1,0,0;
+            -sind(angles(i)),0,cosd(angles(i)),0;
+            0,0,0,1];
+
+        worldRot=ry;        
+        lsc.viewParams.worldRot=worldRot(:);
+
+        lsc.renderParams(1).alpha=1;
+        lsc.uiParams.logoDiv='';
+        lsc.uiParams.scalebar=false;
+        lsc.renderParams(1).medium=1;
+        lsc.show(im);
+        imRaw = get_rendered_frame(lsc);
+
+        lsc.renderParams(1).alpha=0.02;
+        lsc.uiParams.logoDiv='none';
+        lsc.uiParams.scalebar=true;
+        lsc.renderParams(1).medium=0.5;
+        lsc.show(bwx);
+        imX = get_rendered_frame(lsc);
+        
+        imCap = [imRaw,128*ones(size(imRaw,1),5,3),imX];
+        if ( bPreview )
+            imagesc(imCap);
+            axis image;
+            drawnow();
+        else
+            writeVideo(vidWrite,imCap);
+        end
+    end
+    
+    % Padding for 0.2 sec
+    if ( ~bPreview )
+        writeVideo(vidWrite,imCap);
+        writeVideo(vidWrite,imCap);
+    end
+    
+    %% Put sample plane at the back of the volume and set to planar clipping mode,
+    %% then animate plane movement into just back from center
+    % in 10 seconds
+    planeZs = linspace(0,35, 100);
+    lsc.viewParams.planeCenter(3) = planeZs(1);
+    lsc.viewParams.clipMode = 1; % Plane-clipping mode
+    for i=1:length(planeZs)
+        lsc.viewParams.planeCenter(3) = planeZs(i);
+
+        lsc.uiParams.logoDiv='';
+        lsc.uiParams.scalebar=false;
+        lsc.renderParams(1).medium=1;
+        lsc.renderParams(1).alpha=1;
+        lsc.show(im);
+        imRaw = get_rendered_frame(lsc);
+
+        lsc.uiParams.logoDiv='none';
+        lsc.uiParams.scalebar=true;
+        lsc.renderParams(1).medium=0.5;
+        lsc.renderParams(1).alpha=0.02;
+        lsc.show(bwx);
+        imX = get_rendered_frame(lsc);
+
+        imCap = [imRaw,128*ones(size(imRaw,1),5,3),imX];
+        if ( bPreview )
+            imagesc(imCap);
+            axis image;
+            drawnow();
+        else
+            writeVideo(vidWrite,imCap);
+        end
+    end
+    
+    % Padding for 0.2 sec
+    if ( ~bPreview )
+        writeVideo(vidWrite,imCap);
+        writeVideo(vidWrite,imCap);
+    end
+    
+    if ( ~bPreview )
+        close(vidWrite)
+    end
+end
+
+function im = get_rendered_frame(lsc)
+    % We need to poll for draw-complete in order to avoid timeouts
+    while ~lsc.drawComplete()
+        pause(0.1);
+    end
+    im=lsc.captureImage();
+end
+
diff --git a/matlab/+MovieMaker/ssfRatio.m b/matlab/+MovieMaker/ssfRatio.m
new file mode 100644
index 0000000000000000000000000000000000000000..3e95c3df505e03e7988234b3afaab24cab8d6b54
--- /dev/null
+++ b/matlab/+MovieMaker/ssfRatio.m
@@ -0,0 +1,43 @@
+strDB = '/f/leverjs/Olivier/Yannick/April_12_2021/20210129_20x_SD_LI2_HEO_3d_10s10t/20210129_20x_SD_LI2_HEO_3d_10s10t_s01.LEVER';
+[conn,CONSTANTS,segParams]=openDB(strDB);
+outfolder = './tiffs/';
+if ~exist(outfolder,'dir')
+    mkdir(outfolder)
+end
+
+cmd = 'select max(erkRatio) as erk_max,min(erkRatio) as erk_min from tblCellFeatures';
+q = fetch(conn,cmd);
+erk_max = q.erk_max;
+erk_min = q.erk_min;
+
+erk_min = 1.0;
+erk_max = 2.5;
+
+erk_channel = 2;
+for t=1:CONSTANTS.imageData.NumberOfFrames
+    im = MicroscopeData.Reader('imageData',CONSTANTS.imageData, 'chanList',erk_channel,'timeRange',[t t], 'outType','double','prompt',false);
+    im = Segment.denoise(im,segParams,false);
+    cellList = Read.getCellsTime(conn,t,segParams.channels(1),CONSTANTS);
+    imBlob = 0*im;
+    
+    ids = Helpers.sqlEncodeVector([cellList.cellID]);
+    cmd = ['select cellID,erkRatio from tblCellFeatures where cellID in ' ids];
+    q=fetch(conn,cmd);
+
+    for i=1:length(cellList)
+        idx = find(q.cellID == cellList(i).cellID);
+        fval = q.erkRatio(idx);
+        fval = min(fval,erk_max);
+        fval = max(fval,erk_min);
+        fval = (fval - erk_min) / (erk_max - erk_min);
+        imBlob(cellList(i).idxPts) = fval;
+    end
+    outname = fullfile(outfolder,['ratio_' num2str(t),'.tiff']);
+    imBlob = double(imBlob);
+    imwrite(imBlob,outname);
+
+%     outname = fullfile(outfolder,['raw_' num2str(t),'.tiff']);
+%     imwrite(im,outname);
+    t
+end
+close(v)
\ No newline at end of file
diff --git a/matlab/+MovieMaker/ssf_2d_movie.m b/matlab/+MovieMaker/ssf_2d_movie.m
new file mode 100644
index 0000000000000000000000000000000000000000..9a8226fc45574aa4db91a2a1909cd22b0885a520
--- /dev/null
+++ b/matlab/+MovieMaker/ssf_2d_movie.m
@@ -0,0 +1,45 @@
+% strDB = '/f/leverjs/Olivier/Yannick/April_12_2021/20210129_20x_SD_LI2_HEO_3d_10s10t/20210129_20x_SD_LI2_HEO_3d_10s10t_s01.LEVER';
+strDB = '/f/leverjs/Olivier/Agne/2022-06-04_ibidi-insert-setup1/2022-06-04_ibidi-insert-setup1_37.LEVER'
+[conn,CONSTANTS,segParams]=openDB(strDB);
+outfolder = './tiffs/';
+if ~exist(outfolder,'dir')
+    mkdir(outfolder)
+end
+
+refMax = 0.7; % from cacheReferenceLoG
+erk_channel = 1;
+h2b_channel = 3;
+for t=1:CONSTANTS.imageData.NumberOfFrames
+    im = MicroscopeData.Reader('imageData',CONSTANTS.imageData, 'chanList',erk_channel,'timeRange',[t t], 'outType','uint16','prompt',false);
+    im = Segment.denoise(im,segParams,false);
+    im = double(im)./2^16;
+    [imLoG, imp, imn] = LoG.getCompositeLoG(im,CONSTANTS,segParams);
+    imMax = max(im(:));
+    cellList = Read.getCellsTime(conn,t,segParams.channels(1),CONSTANTS);
+    imBlob = 0*im;
+    for i=1:length(cellList)
+        cx = round(cellList(i).centroid);
+        val = imp(cx(2),cx(1));
+        % 0 nucleus against 1 cytoplasm for erk activation
+        % so use complement of intensity in scaling ref
+        refVal = (imMax-max(im(cellList(i).idxPts))).*refMax;
+        refVal = min(refVal,1);
+        refVal = max(refVal,0);
+        imBlob(cellList(i).idxPts) = val./refVal;
+    end
+
+    imBlob = gray2ind(imBlob,256);
+    imBlob = ind2rgb(imBlob,parula(256));
+    im = gray2ind(im,256);
+    im = ind2rgb(im,gray(256));
+    
+    im_h2b = MicroscopeData.Reader('imageData',CONSTANTS.imageData, 'chanList',h2b_channel,'timeRange',[t t], 'outType','uint16','prompt',false);
+    im_h2b = double(im_h2b)./2^16;
+    im(:,:,2) = im(:,:,2) + im_h2b;
+    im(:,:,3) = im(:,:,3) + im_h2b;
+    im = min(im,1);
+    imOut = [im,ones(size(im,1),5,3),imBlob];
+    outname = fullfile(outfolder,[num2str(t),'.tiff']);
+    imwrite(imOut,outname)
+    t
+end
diff --git a/matlab/+MovieMaker/tiffs2movie.m b/matlab/+MovieMaker/tiffs2movie.m
new file mode 100644
index 0000000000000000000000000000000000000000..1bdba4d5587b3a25b11562240a90a1c07ad2f7c3
--- /dev/null
+++ b/matlab/+MovieMaker/tiffs2movie.m
@@ -0,0 +1,34 @@
+
+strDB = '/f/leverjs/Olivier/Yannick/April_12_2021/20210129_20x_SD_LI2_HEO_3d_10s10t/20210129_20x_SD_LI2_HEO_3d_10s10t_s01.LEVER';
+[conn,CONSTANTS,segParams]=openDB(strDB);
+outfolder = './tiffs/';
+
+v = VideoWriter('20210129_20x_SD_LI2_HEO_3d_10s10t_erk_ssf_nlm.avi');
+open(v);
+
+for t=1:CONSTANTS.imageData.NumberOfFrames
+    fname = fullfile(outfolder,[num2str(t),'.tiff']);
+    if ~exist(fname,'file')
+        break
+    end
+    im = imread(fname);
+    hold off;imshow(im); hold on; axis image;axis off; colormap default
+    % scale bar
+    [nPixels,microns] = Helpers.scaleBar(CONSTANTS);
+    rectangle('Position',[size(im,2)-50-nPixels,50,nPixels,25],'FaceColor','w');
+    text(size(im,2)-50-nPixels,75,[num2str(microns) '\mum'],'color','w','VerticalAlignment','top','fontsize',8)
+    % time
+    % time
+    tout = t - 1;
+    hours = floor(tout / 12);
+    minutes = mod(tout, 12)*5;
+    text(50,50,[num2str(hours) ' : ' num2str(minutes)],'color','w','fontsize',8);
+    drawnow
+    
+    f = getframe()
+    writeVideo(v,f);
+    
+    
+end
+
+close(v)
\ No newline at end of file
diff --git a/matlab/+Read/findImageFolder.m b/matlab/+Read/findImageFolder.m
index 7c77d95bca10871e33666766a195b1325a6b1d0e..095c95256764feef690e5baef9c3b5acfcf0bebe 100644
--- a/matlab/+Read/findImageFolder.m
+++ b/matlab/+Read/findImageFolder.m
@@ -42,7 +42,7 @@ if ~exist(ljs,'file')
 end
 [fid,message]=fopen(fullfile(leverFolder,'lever.json'));
 if (fid<=0)
-    fprintf(1,'ERROR -- getConstants.m -- image path invalid and no lever.json ROOT override (message=%s)\n',message);
+    fprintf(1,'ERROR %s -- getConstants.m -- image path invalid and no lever.json ROOT override (message=%s)\n',CONSTANTS.imageData.DatasetName,message);
     return;
 end
 
diff --git a/matlab/+Read/getCell.m b/matlab/+Read/getCell.m
index 863eee99192a3e809fdefb9830f1a19080e65ea6..72e20413e3ab5dbb8e7d1d5f55b96588ec07e52c 100644
--- a/matlab/+Read/getCell.m
+++ b/matlab/+Read/getCell.m
@@ -1,13 +1,21 @@
-function Cell=getCell(conn,cellID)
+function Cell=getCell(conn,cellID,CONSTANTS)
 
 Cell=[];
-
+qTable=fetch(conn,'pragma table_info(tblCells)');
+bLoG = any(cellfun(@length,(strfind(qTable.name,'LoG'))));
 try
-    cmd=['SELECT cellID,time,trackID,centroid,u16pixels,maxRadius,channel,area,surface,segCC '...
-        ' FROM tblCells WHERE cellID=' num2str(cellID)];
+    cmd=['SELECT cellID,time,trackID,centroid,u16pixels,maxRadius,channel,area,surface,segCC '];
+    if bLoG
+        cmd = [cmd ' ,LoG '];
+    end
+    cmd =[cmd ' FROM tblCells WHERE cellID=' num2str(cellID)];
     Q=ljsFetch(conn,cmd);
 catch
-    Cell=Read.getCell3D(conn,cellID);
+    try
+        Cell=Read.getCell3D(conn,cellID);
+    catch
+        fprintf(2,'unable to read cell from %s\n',CONSTANTS.imageData.DatasetName);
+    end
     return
 end
 if isempty(Q)
@@ -28,3 +36,10 @@ Cell.area=Q{8};
 Cell.surface=jsondecode(Q{9});
 Cell.segCC=Q{10};
 
+if bLoG
+    Cell.LoG = Q{11};
+end
+if exist('CONSTANTS','var')
+    Cell = Read.setCellsIdxPts(Cell,CONSTANTS);
+end
+
diff --git a/matlab/+Read/getCell3D.m b/matlab/+Read/getCell3D.m
index c8d9b0b2919572c970b2b12b8a97fd08aee12e27..7ade71dea7999ec240c7d9df7a07f64cb5fd3126 100644
--- a/matlab/+Read/getCell3D.m
+++ b/matlab/+Read/getCell3D.m
@@ -1,8 +1,15 @@
-function Cell=getCell3D(conn,cellID)
+function Cell=getCell3D(conn,cellID,CONSTANTS)
 
 Cell=[];
 
-cmd=['SELECT time,trackID,centroid,channel,area,maxRadius,verts,faces,edges,normals,u16pixels FROM tblCells WHERE cellID=' num2str(cellID)];
+qTable=fetch(conn,'pragma table_info(tblCells)');
+bLoG = any(cellfun(@length,(strfind(qTable.name,'LoG'))));
+
+cmd=['SELECT time,trackID,centroid,channel,area,maxRadius,verts,faces,edges,normals,u16pixels '];
+if bLoG
+    cmd = [cmd ',LoG '];
+end
+cmd = [cmd ' FROM tblCells WHERE cellID=' num2str(cellID)];
 Q=ljsFetch(conn,cmd);
 % cellid time trackID centroid channel area, maxRadius,
 % verts,edges,normals,faces,u16pixels
@@ -27,12 +34,15 @@ Cell.edges=reshape(Cell.edges,2,[])';
 Cell.normals=typecast(Q{10},'single');
 Cell.normals=reshape(Cell.normals,3,[])';
 
-
 points=Q{11};
 points = typecast(points,'uint16');
 points=reshape(points,3,[])'; 
 Cell.pts=points;
 
+if exist('CONSTANTS','var')
+    Cell = Read.setCellsIdxPts(Cell,CONSTANTS);
+end
+
 
 
 
diff --git a/matlab/+SSF/catKymographs.m b/matlab/+SSF/catKymographs.m
new file mode 100644
index 0000000000000000000000000000000000000000..dbc4f2d70f775cd11f7a9f6532e2595af19f3ca5
--- /dev/null
+++ b/matlab/+SSF/catKymographs.m
@@ -0,0 +1,26 @@
+% pads time between images
+function i12 = catKymographs(i1,i2,dim)
+[i1,i2] = padIm(i1,i2);
+i12 = cat(dim,i1,i2);
+4;
+
+function [i1,i2] = padIm(i1,i2)
+
+if size(i1,3)>size(i2,3)
+    i2(:,:,end:size(i1,3),:)=0;
+else
+    i1(:,:,end:size(i2,3),:)=0;
+end
+
+if size(i1,2)>size(i2,2)
+    i2(:,end:size(i1,2),:,:)=0;
+else
+    i1(:,end:size(i2,2),:,:)=0;
+end
+
+if size(i1,1)>size(i2,1)
+    i2(end:size(i1,1),:,:,:)=0;
+else
+    i1(end:size(i2,1),:,:,:)=0;
+end
+
diff --git a/matlab/+SSF/cropKymo.m b/matlab/+SSF/cropKymo.m
new file mode 100644
index 0000000000000000000000000000000000000000..c86c14812892d6bd762924e73d6f8b84ce784d1e
--- /dev/null
+++ b/matlab/+SSF/cropKymo.m
@@ -0,0 +1,22 @@
+function im_crop = cropKymo(imSrc,idxPixels)
+
+% first copy over target pixels
+im = 0 * imSrc;
+im(idxPixels) = imSrc(idxPixels);
+
+[r,c,z]=ind2sub(size(im),idxPixels);
+
+r = cropDim(r,size(im,1));
+c = cropDim(c,size(im,2));
+z = cropDim(z,size(im,3));
+
+im_crop = im(min(r):max(r),min(c):max(c),min(z):max(z),:);
+
+
+function y = cropDim(x,sz)
+
+y = [min(x)-1:max(x)+1];
+y = min(y,sz);
+y = max(y,1);
+
+
diff --git a/matlab/+SSF/drawMitoticSSFtracks.m b/matlab/+SSF/drawMitoticSSFtracks.m
new file mode 100644
index 0000000000000000000000000000000000000000..d852790910a56a878784506820612d26d6e40fd7
--- /dev/null
+++ b/matlab/+SSF/drawMitoticSSFtracks.m
@@ -0,0 +1,57 @@
+% erk1D = Y(:,1);
+% [~,idxSort] = sort(erk1D);
+% qMitoSorted = qMitotic(idxSort,:);
+% 
+function imx = drawMitoticSSFtracks(qMitotic,erkClipLimits,bDraw)
+
+if ~exist('bDraw','var')
+    bDraw = false;
+end
+
+for i = 1:height(qMitotic)
+    if ~isa(qMitotic.erk{i},'uint8')
+        qMitotic.erk{i} = SSF.quantize8(qMitotic.erk{i},erkClipLimits);
+    end
+end
+
+tmax = max(cellfun(@length,qMitotic.erk));
+imx = zeros(2*height(qMitotic),tmax);
+for i = 1:height(qMitotic)
+    erk_i = qMitotic.erk{i};
+    imx(2*i,end-length(erk_i)+1:end) = erk_i;
+end
+
+if ~bDraw
+    return
+end
+
+
+cmPos = colormap('parula');
+cmNeg = colormap('cool');
+cm = [cmNeg(1:2:end,:);cmPos(1:2:end,:)];
+cm(1,:) = [1,1,1];
+
+
+figure;imagesc(imx);colormap(cm);
+c = colorbar();
+clim = [min(c.Ticks),max(c.Ticks)];
+cticks = [clim(1), mean([clim(1),mean(clim)]), mean(clim), mean([clim(2),mean(clim)]),clim(2)];
+c.Ticks = cticks;
+c.TickLabels = {'BG','-0.5','0','0.5','1'}
+c.Label.String = 'Erk SSF';
+
+% close all
+
+% cm = colormap('parula');
+% cm(1:13,:)=repmat([1,1,1],13,1);
+% % c = colorbar('ticks',round(linspace(double(erkLimits(1)),double(erkLimits(2)),10)));
+% c = colorbar
+% c.Label.String = 'Erk SSF (8 bit, clipped to 95%)'
+% 
+% xx = round(linspace(50,size(imx,2),5));
+% set(gca,'XTickLabel',arrayfun(@(y) num2str((y-308),xx,'UniformOutput',false))
+% xlabel('frames before mitosis');
+% ylabel('mitotic parent track sorted by NCD principal component')
+% yy = yticks();
+% set(gca,'YTickLabel',arrayfun(@(y) num2str(y/2),yticks()))
+% 4;
diff --git a/matlab/+SSF/drawSSFclusters.m b/matlab/+SSF/drawSSFclusters.m
new file mode 100644
index 0000000000000000000000000000000000000000..2e71a714a664dab1a0852ce74a93214d0ab0a191
--- /dev/null
+++ b/matlab/+SSF/drawSSFclusters.m
@@ -0,0 +1,68 @@
+% erk1D = Y(:,1);
+% [~,idxSort] = sort(erk1D);
+% qMitoSorted = qMitotic(idxSort,:);
+% 
+% function imx = drawSSFtracks(qMitotic,idx,bDraw)
+
+% if ~exist('bDraw','var')
+%     bDraw = false;
+% end
+tmax = max(cellfun(@length,qMitotic.erk));
+imx = [];
+imxH = 1;
+clusterPts = [];
+for k = 1:max(idx)
+    idxk = find(idx==k);
+    qk = qMitotic(idxk,:);
+    qk.yk = Y(idxk,1);
+    qk = sortrows(qk,'yk');
+    for i = 1:height(qk)
+        erk_i = qk.erk{i};
+        imx(imxH,tmax-length(erk_i)+1:tmax) = erk_i;
+        imxH = imxH+2;
+    end
+    imxH = imxH + 2;
+    clusterPts=[clusterPts,imxH];
+    imxH = imxH + 4;
+
+end
+
+
+
+% if ~bDraw
+%     return
+% end
+
+
+close all
+
+cm = colormap('parula');
+cm(1,:) = [1,1,1];
+
+figure;imagesc(imx);colormap(cm);hold on
+c = colorbar('ticks',[2,64,128,192,255], 'ticklabels',{'-1.0','-0.5','0','0.5','1'});
+c.Label.String = 'Erk SSF';
+for p = 1:length(clusterPts)
+    plot([1,size(imx,2)],[clusterPts(p),clusterPts(p)],'-..k')
+end
+
+% 
+
+% cm = colormap('parula');
+% cm(1:13,:)=repmat([1,1,1],13,1);
+% % c = colorbar('ticks',round(linspace(double(erkLimits(1)),double(erkLimits(2)),10)));
+% c = colorbar
+% c.Label.String = 'Erk SSF (8 bit, clipped to 95%)'
+% 
+xx = round(linspace(50,size(imx,2),5));
+set(gca,'XTick',xx);
+set(gca,'XTickLabel',arrayfun(@(y) num2str(y-308),xx,'UniformOutput',false))
+xlabel('frames before mitosis');
+ylabel('mitotic parent track sorted by cluster and NCD principal component')
+yy = yticks();
+set(gca,'YTickLabel',arrayfun(@(y) num2str(y/2),yticks(),'uniformOutput',false))
+% h=gca; h.YAxis.TickLength = [0 0];
+yticks([])
+% 4;
+set(gcf,'color','w')
+% exportgraphics(gcf,'erk ssf heat map tracks NCD sorted cluster FLIF1d.pdf','Resolution',600,'contenttype','image')
diff --git a/matlab/+SSF/drawSSFtracks.m b/matlab/+SSF/drawSSFtracks.m
new file mode 100644
index 0000000000000000000000000000000000000000..1578eb1ffe731c9d7b4c7fdc167cf34188d461c4
--- /dev/null
+++ b/matlab/+SSF/drawSSFtracks.m
@@ -0,0 +1,85 @@
+% strDB = '/g/leverjs/Olivier/Agne/march_2023_20x/2022-04-05_steady_state_48h_deprived_13_ori.LEVER';
+
+function drawSSFtracks(ROOT,cache, kymo_channel, channel_description,fnames)
+
+[~,dsName,ext] = fileparts(ROOT);
+if ~exist('fnames','var')
+    fnames = [];
+end
+
+outfile = [dsName ' ' channel_description ' SSF projection_y_t.pdf'];
+if isempty(ext)
+    flist = dir(fullfile(ROOT,'*.LEVER'));
+else
+    flist = dir(ROOT);
+end
+f=figure(1);
+f.WindowState = 'maximized';
+pause(1)
+
+kymoPixels = {};
+for ff=1:length(flist)
+    strDB = fullfile(flist(ff).folder,flist(ff).name);
+    [ROOT,lf] = fileparts(strDB);
+    strKymoDB = fullfile(ROOT,cache,[lf '.LEVER_ssf_cache.LEVER']);
+    if ~exist(strKymoDB,'file')
+        continue
+    end
+    imKymo = SSF.loadImage(strKymoDB,kymo_channel);
+    kymoPixels{ff} = imKymo(find(imKymo));
+end 
+kymoPixels = vertcat(kymoPixels{:});
+erkClipLimits = [prctile(kymoPixels,2.5),prctile(kymoPixels,97.5)];
+
+for ff = 1:length(flist)
+    strDB = fullfile(flist(ff).folder,flist(ff).name);
+    [ROOT,lf] = fileparts(strDB);
+    strKymoDB = fullfile(ROOT,cache,[lf '.LEVER_ssf_cache.LEVER']);
+    if ~exist(strKymoDB,'file')
+        continue
+    end
+    imKymo = SSF.loadImage(strKymoDB,kymo_channel);
+    % 
+    imp = squeeze(max(imKymo,[],2));
+    imn = squeeze(min(imKymo,[],2));
+    imn = abs(imn);
+    idx = find(imn>imp);
+    imp(idx) = -1 .* imn(idx);
+%     imp(imp<-0.5) = 0;
+    impq = SSF.quantize8(imp,erkClipLimits);
+%     impq(imp==0 & imn==0) = 0;
+    
+%     % keep just [0,1] SSF
+%     imp = squeeze(max(imKymo,[],2));
+%     erkClipLimits = [0,prctile(kymoPixels,99.9)];
+%     impq = SSF.quantize8(imp,erkClipLimits);
+%     impq(imp==0) = 0; % set the background
+%     
+    
+    clf;imagesc(impq)
+    cm = colormap('parula');
+    cm(1,:) = [1,1,1]; % make the background white!
+    colormap(cm)
+    c = colorbar();
+    clim = [min(impq(:)),max(impq(:))];
+    cticks = [clim(1)+1, mean([clim(1),mean(clim)]), mean(clim), mean([clim(2),mean(clim)]),clim(2)];
+    c.Ticks = cticks;
+    % c.TickLabels = {'-1','-0.5','0','0.5','1'}
+
+    ticksSSF = linspace(erkClipLimits(1),erkClipLimits(2),5);
+    ticksSSF = arrayfun(@(x) num2str(x,2),ticksSSF,'UniformOutput',false);
+    c.TickLabels = ticksSSF;
+    c.Label.String = [channel_description ' SSF (dataset reference)'];
+    if ~isempty(fnames)
+        lf = fnames{ff};
+    end
+    hold on
+    yl = ylim();
+    plot([62,62],[yl(1),yl(2)],'--r','linewidth',2)
+    title([lf ' ' channel_description ' SSF projection to (Y/2,time)'],'interpreter','none')
+    xlabel('time (frames)')
+    ylabel('Y (max intensity projection along X)')
+    bAppend = ff>1;
+    exportgraphics(gcf,outfile,'Resolution',600,'contenttype','image','append',bAppend);
+    
+end
\ No newline at end of file
diff --git a/matlab/+SSF/drawSubsets.m b/matlab/+SSF/drawSubsets.m
new file mode 100644
index 0000000000000000000000000000000000000000..eb058607c103b3357a896ddfc05cd19126c4e130
--- /dev/null
+++ b/matlab/+SSF/drawSubsets.m
@@ -0,0 +1,78 @@
+% andy and layton. jul 3 2023. very preliminary.
+kROOT = '/g/leverjs/Olivier/Agne/2022-06-03_48h-depr-transcr-drugs/kymo_combined_downsize_steady_state';
+flist = dir(fullfile(kROOT,'*.LEVER'));
+transcr_class = readtable('expDescr-2022-06-03.xlsx');
+steady_state_class = load('../agne_20x_classMap.mat');
+
+className = {};
+for ff = 1:length(flist)
+    cn = regexp(flist(ff).name,'(\d+-\d+-\d+)_.*(\d\d)_ori*','tokens');
+    if isempty(cn)
+        re = regexp(flist(ff).name,'^(\d+)_.*(\d).LEVER','tokens');
+        idx = str2double(re{1}{1});
+        part = str2double(re{1}{2});
+        if part == 1
+            className{ff} = ['pre_' transcr_class.Cell_Type{idx}];
+        else 
+            className{ff} = ['post_' transcr_class.Cell_Type{idx}];
+        end
+    else
+        cn = [cn{1}{1} '_' cn{1}{2}];
+        className{ff} = steady_state_class.classMap(cn);
+    end
+end
+
+ssClassList = unique(steady_state_class.classMap.values);
+idx = contains(ssClassList,'E17K');
+ssClassList(idx) = [];
+idx = contains(ssClassList,'E545K');
+ssClassList(idx) = [];
+ssClassList(end+1) = {'pre_ErbB2_overexpr'};
+
+idx = cellfun(@(x) any(contains(ssClassList,x)),className,'UniformOutput',false);
+idx = find([idx{:}]);
+
+d2 = d(idx,idx);
+className = className(idx);
+
+A = d2;
+K=3;
+
+
+
+[idx,Y] = Cluster.SpectralCluster(A,K);
+% Y = tsne(Y,'Algorithm','exact','NumDimensions',3);
+clf;hold off;
+% if size(Y,2) == 3
+%     plot3(Y(:,1),Y(:,2),Y(:,3),'.')
+% else
+%     plot(Y(:,1),Y(:,2),'.')
+% end
+sym = {'ko','cv','m^','r*','gx','<k','b>','gs','bd'};
+
+
+classList = unique(className);
+hx = zeros(size(classList));
+hold on
+
+for ff=1:size(Y,1)
+    
+    idxSym = find(strcmp(classList,className{ff}));
+    if K==3
+        h1 = plot3(Y(ff,1),Y(ff,2),Y(ff,3),sym{idxSym});
+    else
+        h1 = plot(Y(ff,1),Y(ff,2),sym{idxSym},'UserData',ff);
+    end
+    if ~hx(idxSym)
+        hx(idxSym) = h1;
+    end
+    %     if size(Y,2) == 3
+    %         text(Y(i,1),Y(i,2),Y(i,3),num2str(i),'FontSize',12)
+    %
+    %     else
+    %         text(Y(i,1),Y(i,2),num2str(i),'FontSize',12)
+    %     end
+end
+set(gcf,'color','w')
+xlabel('u1');ylabel('u2'),zlabel('u3')
+legend(hx(find(hx)),classList(find(hx)),'interpreter','none');
\ No newline at end of file
diff --git a/matlab/+SSF/draw_ssf_ncd.m b/matlab/+SSF/draw_ssf_ncd.m
new file mode 100644
index 0000000000000000000000000000000000000000..4c4acb5b8ef8caf077c51efbc45355a800b9dbcc
--- /dev/null
+++ b/matlab/+SSF/draw_ssf_ncd.m
@@ -0,0 +1,55 @@
+% load('agne_72_8bpp.mat')
+flist = dir(fullfile(ROOT,'*.LEVER'));
+
+% className = {};
+% for ff=1:length(flist)
+%     cn = regexp(flist(ff).name,'(\d+-\d+-\d+)_.*(\d\d)_ori*','tokens');
+%     cn = [cn{1}{1} '_' cn{1}{2}];
+%     className{ff} = classMap(cn);
+% end
+% targetClass = {'AKT1_E17K','WT','PIK3CA_E545K'}
+% idx = find(cellfun(@(x) ~isempty(find(strcmp(targetClass,x))),className));
+% A=d(idx,idx);
+% className = className(idx);
+
+A = d;
+K=3;
+
+
+
+[idx,Y] = Cluster.SpectralCluster(A,K);
+% Y = tsne(Y,'Algorithm','exact','NumDimensions',3);
+clf;hold off;
+% if size(Y,2) == 3
+%     plot3(Y(:,1),Y(:,2),Y(:,3),'.')
+% else
+%     plot(Y(:,1),Y(:,2),'.')
+% end
+sym = {'ko','cv','m^','r*','gx','<k','b>','gs','bd'};
+
+
+classList = unique(className);
+hx = zeros(size(classList));
+hold on
+
+for ff=1:size(Y,1)
+    
+    idxSym = find(strcmp(classList,className{ff}));
+    if K==3
+        h1 = plot3(Y(ff,1),Y(ff,2),Y(ff,3),sym{idxSym});
+    else
+        h1 = plot(Y(ff,1),Y(ff,2),sym{idxSym},'UserData',ff);
+    end
+    if ~hx(idxSym)
+        hx(idxSym) = h1;
+    end
+    %     if size(Y,2) == 3
+    %         text(Y(i,1),Y(i,2),Y(i,3),num2str(i),'FontSize',12)
+    %
+    %     else
+    %         text(Y(i,1),Y(i,2),num2str(i),'FontSize',12)
+    %     end
+end
+set(gcf,'color','w')
+xlabel('u1');ylabel('u2'),zlabel('u3')
+legend(hx(find(hx)),classList(find(hx)),'interpreter','none');
\ No newline at end of file
diff --git a/matlab/+SSF/erkTrackingGraph.m b/matlab/+SSF/erkTrackingGraph.m
new file mode 100644
index 0000000000000000000000000000000000000000..e58da9ff71ed4b427c164a51dc721929d5160376
--- /dev/null
+++ b/matlab/+SSF/erkTrackingGraph.m
@@ -0,0 +1,38 @@
+ROOT = '/g/leverjs/Olivier/Agne/2022-06-04_ibidi-insert-setup1/';
+cacheFolder = fullfile(ROOT,'logCache2');
+
+strDB = '/g/leverjs/Olivier/Agne/2022-06-04_ibidi-insert-setup1/2022-06-04_ibidi-insert-setup1_37.LEVER';
+[conn,CONSTANTS,segParams]=openDB(strDB);
+
+str_imd = strrep(strDB,'.LEVER','.json');
+imd = MicroscopeData.ReadMetadata(str_imd,false);
+imLoG = MicroscopeData.Reader('imageData',imd);
+cmd = ['select A.cellID as cid_src,A.time as t_src,A.centroid as cx_src, '...
+    'B.cellID as cid_dst,B.time as t_dst,B.centroid as cx_dst FROM tblDistCC '...
+	'inner join tblCells as A on A.cellID = cellID_src '...
+	'inner join tblCells as B on B.cellID = cellID_dst'];
+q = fetch(conn,cmd);
+
+erkCost = [];
+parfor i = 1:length(q.cid_src)        
+    cx_src = jsondecode(q.cx_src{i});
+    cx_src(3) = q.t_src(i)
+    cx_src = round(cx_src);
+    val_src = imLoG(cx_src(2),cx_src(1),cx_src(3));
+
+    cx_dst = jsondecode(q.cx_src{i});
+    cx_dst(3) = q.t_dst(i)
+    cx_dst = round(cx_dst);
+    val_dst = imLoG(cx_dst(2),cx_dst(1),cx_dst(3));
+    logCost = abs(val_src-val_dst);
+    erkCost(i,:) = [q.cid_src(i),q.cid_dst(i),logCost] ;  
+end
+
+tblErkDstCC = table();
+tblErkDstCC.cellID_src = erkCost(:,1);
+tblErkDstCC.cellID_dst = erkCost(:,2);
+tblErkDstCC.cost = erkCost(:,3);
+
+exec(conn,'drop table if exists tblErkDstCC;create table tblErkDstCC(cellID_src,cellID_dst,cost)');
+insert(conn,'tblErkDstCC',{'cellID_src','cellID_dst','cost'},tblErkDstCC);
+close(conn)
diff --git a/matlab/+SSF/gen_SSF_kymo.m b/matlab/+SSF/gen_SSF_kymo.m
new file mode 100644
index 0000000000000000000000000000000000000000..0c01c39bee3f2dfc285b3308ee41b4df9f9fc3c1
--- /dev/null
+++ b/matlab/+SSF/gen_SSF_kymo.m
@@ -0,0 +1,59 @@
+
+% BE CAREFUL HERE! BE DRAGONS! GET THESE target names & numbers RIGHT OR PERISH
+% targetChannelNames = {'Erk SSF'; 'Akt SSF' ; 'DHB SSF'; 'H2B SSF'; 'velocity SSF'}; % channel names in the kymo
+% targetChannelNames = {'Erk SSF'; 'Oct4 SSF' ;  'H2B SSF'; 'velocity SSF'}; % channel names in the kymo
+% targetChannelNumbers = [2, 3, -1]; % maps image channel names to kymo channel names
+function gen_SSF_kymo(strDB,targetChannelNames,targetChannelNumbers,outfolder,bDownscale, startFrame)
+
+if ~exist('bDownscale','var')
+    bDownscale = false;
+end
+if ~exist('startFrame','var')
+    startFrame = 1;
+end
+
+[fx,nx,ext]=fileparts(strDB);
+if strcmp(ext,'.LEVER')
+    flist = dir(strDB);
+    ROOT = fx;
+else
+    ROOT = strDB;
+    flist = dir(fullfile(strDB,'*.LEVER'));
+end
+L = length(flist);
+
+
+if ~exist(outfolder,'dir')
+    mkdir(outfolder);
+end
+
+imd={};
+nGPU = HIP.Cuda.DeviceCount();
+p = ljsStartParallel(8*nGPU);
+
+parfor ff=1:L
+% for ff=1:L    
+    str_ff = fullfile(flist(ff).folder,flist(ff).name);     
+    if exist(fullfile(outfolder,[flist(ff).name '_ssf_cache.json']),'file')
+        fprintf(1,'genKymo skipping %s kymo exists\n',str_ff);
+        continue
+    end
+    t0 = tic();
+    imVolume = SSF.ssf_volume(str_ff,targetChannelNumbers, bDownscale);
+    if isempty(imVolume)
+        continue
+    end
+    if contains(targetChannelNames{end},'velocity ssf','IgnoreCase',true)
+        imVolume(:,:,:,length(targetChannelNumbers)+1) = SSF.velocity_kymo(str_ff,bDownscale);
+    end
+    imVolume = imVolume(:,:,startFrame:end,:); % trim off first 30 frames
+    imd{ff}=MicroscopeData.MakeMetadataFromImage(imVolume);
+    imd{ff}.DatasetName=[flist(ff).name '_ssf_cache'];
+    imd{ff}.imageDir = outfolder;
+    imd{ff}.ChannelNames = targetChannelNames;
+    MicroscopeData.WriterH5(imVolume,'imageData',imd{ff},'path',outfolder);  
+
+    tElapsed = toc(t0);
+    fprintf(1,'ssf_volume %d tElapsed=%0.2f\n',ff,tElapsed);
+end
+Import.leverImport('',outfolder);
\ No newline at end of file
diff --git a/matlab/+SSF/goErkCN.m b/matlab/+SSF/goErkCN.m
new file mode 100644
index 0000000000000000000000000000000000000000..1c7ae124eb937c61971f4571c2c873fe3c298117
--- /dev/null
+++ b/matlab/+SSF/goErkCN.m
@@ -0,0 +1,42 @@
+% strDB = '/f/leverjs/Olivier/Yannick/20210924/20210924_pos3.LEVER';
+% tblCN = goErkCN(strDB,174279)
+% tblCN = goErkCN(strDB,224589)
+function tblCN = goErkCN(strDB,targetTrack)
+
+[conn,CONSTANTS,segParams]=openDB(strDB);
+[ROOT,lf] = fileparts(strDB);
+strKymo = fullfile(ROOT,'kymoV',[lf '.LEVER_ssf_cache.LEVER']);
+imKymo = leversc.loadImage(strKymo,1,1);
+
+cmd = ['select cellID,trackID,centroid,time,LoG from tblCells where trackID = '...
+    num2str(targetTrack)];
+q=fetch(conn,cmd);
+
+erkSSF = [];
+for i = 1:height(q)
+    centroid = jsondecode(q.centroid{i});
+    centroid = [round(centroid(1:2))', q.time(i)];
+    sample_value = SSF.ssf_sample(imKymo,centroid);
+    erkSSF(i) = sample_value;
+end
+
+featureParams.channel = 2;
+featureParams.name='CytoToNuclearRatio';
+featureParams.color="#00ffff";
+tblCN = table();
+for i = 1:height(q)
+    t = q.time(i);
+    cellList = Read.getCellsTime(conn,t,segParams.channels(1),CONSTANTS);
+    nt = SSF.cytoToNuclearRatio(cellList,q.cellID(i),t,CONSTANTS,featureParams,segParams);
+    nt.erkSSF = erkSSF(i);
+    tblCN = [tblCN;nt]
+end
+ee = imKymo(find(imKymo));
+erkClipLimits = [prctile(ee,2.5), prctile(ee,97.5)];
+
+erk = tblCN.erkSSF;
+erk = SSF.quantize8(erk,erkClipLimits);
+erk = 2 * (double(erk) / 255) -1;
+figure;plot(erk)
+hold on
+plot(tblCN.cnRatio)
\ No newline at end of file
diff --git a/matlab/+SSF/goTrackSSFkymo.m b/matlab/+SSF/goTrackSSFkymo.m
new file mode 100644
index 0000000000000000000000000000000000000000..6461c99111f6b7e7ace956edf4da2fbd94be7224
--- /dev/null
+++ b/matlab/+SSF/goTrackSSFkymo.m
@@ -0,0 +1,117 @@
+
+ROOT = '/f/leverjs/Olivier/Yannick/20210924/';
+flist = dir(fullfile(ROOT,'*.LEVER'));
+
+cxKymo = {};
+qMitotic = {};
+
+for ff = 1:length(flist)
+    strDB = fullfile(flist(ff).folder,flist(ff).name);
+    [ROOT,lf] = fileparts(strDB);
+    strKymoDB = fullfile(ROOT,'kymoV',[lf '.LEVER_ssf_cache.LEVER']);
+    cxKymo{ff} = SSF.loadImage(strKymoDB,1);
+    [conn,CONSTANTS,segParams]=openDB(strDB);    
+    imErk = cxKymo{ff}(:,:,:,1);
+    qm = fetch(conn,'select * from (select cellID,trackID,count(time) as nt from tblCells where trackID in (select trackID from tblCells inner join tblFamilies on cellID_parent=cellID) group by trackID) where nt>23');
+    for i = 1:length(qm.trackID)
+        qcx = fetch(conn,['select centroid,time from tblCells where trackID = ' num2str(qm.trackID(i))]);
+        centroids = cellfun(@jsondecode,qcx.centroid,'UniformOutput',false);
+        centroids = reshape(vertcat(centroids{:}),3,[])';
+        centroids = round(centroids);  
+        qm.centroids{i} = [centroids(:,1:2),qcx.time];
+        qm.idxCentroids{i} = sub2ind(size(cxKymo{ff}),centroids(:,2),centroids(:,1),qcx.time);        
+        qm.movieID(i) = ff;
+        qm.erk{i} = SSF.ssf_sample_idx(imErk,qm.idxCentroids{i});
+        qm.isEmpty(i) = all(0==qm.erk{i});       
+    end
+    qm(qm.isEmpty,:)=[];
+    qMitotic = [qMitotic;qm];
+end
+% qMitotic.erk is the signal. quantize it to 8 bit now
+erkCombined =[qMitotic.erk{:}]' ;
+erkClipLimits = [prctile(erkCombined,2.5), prctile(erkCombined,97.5)];
+for c = 1:length(cxKymo)
+    cxKymo{c} = SSF.quantize8(cxKymo{c},erkClipLimits);
+end
+% % a bit slow, but steady. find distancefrom each mitotis
+for i = 1:height(qMitotic)
+
+    strDB = fullfile(flist(qMitotic.movieID(i)).folder,flist(qMitotic.movieID(i)).name);
+    [conn,CONSTANTS,segParams]=openDB(strDB);
+    q1 = fetch(conn,['select centroid,time from tblCells where cellID = ' num2str(qMitotic.cellID(i))]);
+    colony = Read.getCellsTime(conn,q1.time,4,CONSTANTS);
+    for c = 1:length(colony)
+        bw = zeros(CONSTANTS.imageData.Dimensions(2),CONSTANTS.imageData.Dimensions(1));
+        bw(colony(c).idxPts) = 1;
+        centroid1 = round(jsondecode(q1.centroid{1}));
+        if ~bw(centroid1(2),centroid1(1))
+            continue
+        end
+        bwd = bwdist(~bw);
+        bwd = bwd./max(bwd(:));
+        qMitotic.dNormalized(i) = bwd(centroid1(2),centroid1(1));
+        qMitotic.time(i) = q1.time;
+    end
+end
+
+
+
+for i = 1:height(qMitotic)    
+    erk_i = medfilt1(qMitotic.erk{i}, 5);
+    erk_i = SSF.quantize8(erk_i, erkClipLimits);
+    qMitotic.erk{i} = erk_i;
+end
+
+d = [];
+L = height(qMitotic);
+parfor i = 1:L
+%     im_i = SSF.cropKymo(cxKymo{qMitotic.movieID(i)},qMitotic.idxCentroids{i});
+    for j = 1:L
+%         im_j = SSF.cropKymo(cxKymo{qMitotic.movieID(j)},qMitotic.idxCentroids{j});
+        erk_j = medfilt1(qMitotic.erk{j},5)
+        im_j = SSF.quantize8(erk_j,erkClipLimits);
+        d(i,j) = SSF.ncd_ssf_volume(im_i,im_j);
+    end
+end
+
+% for i = 1:length(d)
+%     for j = 1 : length(d)
+%         d(i,j)=max(d(i,j),d(j,i));
+%     end
+%     d(i,i) = max(d(i,i),0);
+% end
+
+close all
+A = d;
+K=3;
+[idx,Y] = Cluster.SpectralCluster(A,K);
+% Y(:,3) = [erkMitotic.d];
+figure;hold on
+hred = [];
+hgreen = [];
+for i = 1 : height(qMitotic)    
+    if qMitotic.dNormalized(i)<.2929
+        hred = [hred,plot3(Y(i,1),Y(i,2),Y(i,3),'.r')];        
+    else
+        hgreen = [hgreen,plot3(Y(i,1),Y(i,2),Y(i,3),'.g')];        
+    end
+end
+xlabel('u1')
+ylabel('u2')
+zlabel('u3')
+legend([hred(1),hgreen(1)],'d_{normalized} < 0.29','d_{normalized} \geq .2929')
+
+set(gcf,'color','w')
+figure;hold on
+for i = 1 : height(qMitotic)
+    if qMitotic.dNormalized(i)<.2929
+        plot(Y(i,1),Y(i,2),'.r');
+    else
+        plot(Y(i,1),Y(i,2),'.g');
+    end
+end
+xlabel('u1')
+ylabel('u2')
+legend({'d_{normalized}>.2929','d_{normalized}<.2929'})
+set(gcf,'color','w')
+% exportgraphics(gcf,'erkMitoticParentTracksEmbedding_medfilt.pdf','Resolution',300,'contenttype','image')
\ No newline at end of file
diff --git a/matlab/+SSF/go_ssf_ncd.m b/matlab/+SSF/go_ssf_ncd.m
new file mode 100644
index 0000000000000000000000000000000000000000..f6dd59cc9741d5c09589aa4788ff92b16d8d9784
--- /dev/null
+++ b/matlab/+SSF/go_ssf_ncd.m
@@ -0,0 +1,90 @@
+% ROOT = '/g/leverjs/Olivier/Agne/2022-06-04_ibidi-insert-setup1/kymo3/';
+% % ROOT  = '/g/leverjs/Olivier/Agne/2022-04-05_steady_state_48h_deprived/kymo3';
+% ERK_CHANNEL = 1; % ERK is channel 1 on kymograph
+% AKT_CHANNEL = 2;
+% H2B_CHANNEL = 3;
+% targetChannels = [ERK_CHANNEL,AKT_CHANNEL];
+function d=go_ssf_ncd(kROOT,targetChannels)
+
+tStart = tic();
+
+flist = dir(fullfile(kROOT,'*.LEVER'));
+d = zeros(length(flist));
+kymoPixels = {};
+ 
+p = ljsStartParallel();
+% 
+parfor ff=1:length(flist)
+    strDB_ff = fullfile(flist(ff).folder,flist(ff).name);
+    im_ff = SSF.loadImage(strDB_ff,targetChannels);
+    kp = im_ff(find(im_ff));
+    kymoPixels{ff} = kp;
+end 
+kymoPixels = vertcat(kymoPixels{:});
+% erkClipLimits = [prctile(kymoPixels,2.5),prctile(kymoPixels,97.5)]
+erkClipLimits = [0,prctile(kymoPixels,99)];
+% erkClipLimits = [-1,1];
+
+%
+cmdList = NCD.dParallelCommandList(ones(length(flist)),p.NumWorkers);
+W = size(cmdList,2); % for slicing j in parfor
+H = size(cmdList,1);
+dxx = zeros(H,W);
+parfor i=1:H
+    str_ff_prev = '';
+    im_ff = [];
+
+    for j = 1:W
+        t0 = tic();
+        ff = cmdList(i,j,2); % ff is the row var -- repeats
+        gg = cmdList(i,j,1);
+        if 0 == ff || 0 == gg
+            continue
+        end
+        strDB_ff = fullfile(flist(ff).folder,flist(ff).name);
+        if ~strcmp(strDB_ff,str_ff_prev)
+            im_ff = SSF.loadImage(strDB_ff,targetChannels);
+            im_ff = SSF.quantize8(im_ff,erkClipLimits);
+            str_ff_prev = strDB_ff;
+        end
+
+        if ff == gg
+            d1 = SSF.ncd_ssf_volume(im_ff,im_ff);
+            dxx(i,j) = d1;
+        else
+            strDB_gg = fullfile(flist(gg).folder,flist(gg).name);
+            im_gg = SSF.loadImage(strDB_gg,targetChannels);
+            im_gg = SSF.quantize8(im_gg,erkClipLimits);
+
+            d1 = SSF.ncd_ssf_volume(im_ff,im_gg);
+            d2 = SSF.ncd_ssf_volume(im_gg,im_ff);
+
+
+            dxx(i,j) = min(d1,d2);
+        end
+        tElapsed = toc(t0);
+        fprintf('%s tElapsed = %0.2f\n',mat2str([ff,gg,dxx(i,j)]),tElapsed);
+    end
+end
+% convert dxx to distance matrix d
+d = [];
+for i = 1 : size(dxx,1)
+    for j = 1 : size(dxx,2)
+        c = cmdList(i,j,1);
+        r = cmdList(i,j,2);
+        if 0 == r || 0 == c
+            continue
+        end
+        d(r,c) = dxx(i,j);
+    end
+end
+
+for i = 1 : size(d,1)
+    for j = 1 : size(d,2)
+        if 0 == d(i,j)
+            d(i,j) = d(j,i);
+        end
+    end
+end
+tElapsed = toc(tStart);
+fprintf('total time tElapsed = %0.2f\n',tElapsed);
diff --git a/matlab/+SSF/loadImage.m b/matlab/+SSF/loadImage.m
new file mode 100644
index 0000000000000000000000000000000000000000..9e149c8d140985dc9473b36273bbf4483b2c4841
--- /dev/null
+++ b/matlab/+SSF/loadImage.m
@@ -0,0 +1,11 @@
+
+function im = loadImage(strDB,channelList)
+
+if ~exist('bDouble','var')
+    bDouble = false;
+end
+im = [];
+time = 1; % kymo is single time point
+for c=1:length(channelList)
+    im(:,:,:,c) = leversc.loadImage(strDB,time,channelList(c));  
+end
diff --git a/matlab/+SSF/mapCentroids.m b/matlab/+SSF/mapCentroids.m
new file mode 100644
index 0000000000000000000000000000000000000000..db3605526f40a56e60ea5b57dc01a745f8a6df2d
--- /dev/null
+++ b/matlab/+SSF/mapCentroids.m
@@ -0,0 +1,22 @@
+function centroidMap = mapCentroids(conn,CONSTANTS)
+
+q = fetch(conn,'select cellID,centroid,time from tblCells');
+cx = cellfun(@jsondecode,q.centroid,'UniformOutput',false);
+cx = [cx{:}]';
+
+d = squareform(pdist(cx));
+[~,u123] = Cluster.SpectralCluster(d,2);
+
+
+for dim=1:2
+    % normalize to [0,1]
+    u123(:,dim) = (max(u123(:,dim)) - u123(:,dim))./(max(u123(:,dim)) - min(u123(:,dim)));
+    % scale to image range
+    u123(:,dim) = (u123(:,dim) .* (max(cx(:,dim))-min(cx(:,dim))) + min(cx(:,dim)) ) ;    
+end
+
+u123 = round(u123);
+u123 = max(u123,1);
+u123 = min(u123,[CONSTANTS.imageData.Dimensions(1:2)]);
+u123 = mat2cell(u123,ones(length(u123),1));
+centroidMap = containers.Map([q.cellID],u123);
diff --git a/matlab/+SSF/ncd_ssf_volume.m b/matlab/+SSF/ncd_ssf_volume.m
new file mode 100644
index 0000000000000000000000000000000000000000..0c3427a496154cf7e7ca3f8e62c3e5f32c32eb74
--- /dev/null
+++ b/matlab/+SSF/ncd_ssf_volume.m
@@ -0,0 +1,24 @@
+% i1 and i2 are signal kymos (x,y,t,c)outdir
+% we want images {t}(x,y,c)
+% package to cell array by t and then pass to in memory FLI%F compressor
+function ncd = ncd_ssf_volume(i1,i2)
+
+im12 = SSF.catKymographs(i1,i2,1);
+im12 = squeeze(num2cell(im12,[1,2,4]));
+s12 = NCD.flifPress(im12);
+
+im21 = SSF.catKymographs(i1,i2,2);
+im21 = squeeze(num2cell(im21,[1,2,4]));
+s21 = NCD.flifPress(im21);
+
+s12 = min(s12,s21);
+
+i1 = squeeze(num2cell(i1,[1,2,4]));
+i2 = squeeze(num2cell(i2,[1,2,4]));
+
+s1 = NCD.flifPress(i1);
+s2 = NCD.flifPress(i2);
+
+ncd = ( s12-min(s1,s2)) / (max(s1,s2));
+
+4;
diff --git a/matlab/+SSF/quantize8.m b/matlab/+SSF/quantize8.m
new file mode 100644
index 0000000000000000000000000000000000000000..1a2a0f119da3e86867c2433fc4da199bb0480fd6
--- /dev/null
+++ b/matlab/+SSF/quantize8.m
@@ -0,0 +1,14 @@
+% clipLimits = [minVal,maxVal];
+function im = quantize8(im,clipLimits)
+
+if isa(im,'uint8')
+    return
+end
+im = max(im,clipLimits(1));
+im = min(im,clipLimits(2));
+
+im = (im - clipLimits(1)) ./ (clipLimits(2) - clipLimits(1));
+
+im = im2uint8(im);
+im = max(im,1); % exclude 0 -- only for background
+im(1,1) = 0; % make sure at least 1 pixel hits background
\ No newline at end of file
diff --git a/matlab/+SSF/ssfTracks.m b/matlab/+SSF/ssfTracks.m
new file mode 100644
index 0000000000000000000000000000000000000000..0b3e0ba13879f64cf17353818c81430654c44bf5
--- /dev/null
+++ b/matlab/+SSF/ssfTracks.m
@@ -0,0 +1,38 @@
+% function ssfTracks(strDB)
+
+ROOT = '/g/leverjs/Olivier/Agne/2022-02-19_1h_starved_steady_state_exp1/';
+ERK_CHANNEL = 2;
+DHB_CHANNEL = 3;
+ref_max = 0.7;
+movie_tracks = {};
+
+flist = dir(fullfile(ROOT,'*.LEVER'));
+for ff=1:length(flist)
+    strDB = fullfile(flist(ff).folder,flist(ff).name);
+    [conn,CONSTANTS,segParams] = openDB(strDB);
+
+    ssf_tracks = containers.Map('KeyType','double','ValueType','any');
+
+    for t = 1:CONSTANTS.imageData.NumberOfFrames
+        cellList = Read.getCellsTime(conn,t,1,CONSTANTS);
+        imSSF = SSF.ssf_channel(cellList,CONSTANTS,DHB_CHANNEL,t,ref_max,segParams,[]);
+        
+        for i = 1:length(cellList)
+            cx = round(cellList(i).centroid);
+            cx = [cx(2),cx(1)]; % [y,x]
+            cxSSF = imSSF(cx(1),cx(2));
+            trackID = cellList(i).trackID;
+            if isKey(ssf_tracks,trackID)
+                ssf_vals = ssf_tracks(trackID);
+                ssf_vals = [ssf_vals, [cxSSF ; t]];
+                ssf_tracks(trackID) = ssf_vals;
+            else
+                ssf_tracks(trackID) = [cxSSF ; t];
+            end
+        end
+        4;
+    end
+    close(conn);
+    movie_tracks{ff} = ssf_tracks;
+end
+
diff --git a/matlab/+SSF/ssf_channel.m b/matlab/+SSF/ssf_channel.m
new file mode 100644
index 0000000000000000000000000000000000000000..70e0970e191a7a460837eb3a8e2865a4bf566767
--- /dev/null
+++ b/matlab/+SSF/ssf_channel.m
@@ -0,0 +1,64 @@
+function imSSF = ssf_channel(cellList,CONSTANTS,channel,t,refMax,segParams,centroidMap,bDownscale)
+
+im = MicroscopeData.Reader('imageData',CONSTANTS.imageData, 'chanList',abs(channel),'timeRange',[t t], 'outType','uint16','prompt',false);
+im = Segment.denoise(im,segParams,false);
+im = double(im)./2^16;
+% scale refMax by actual image statistics. median estimates background,
+% 99.99% represents max foreground intensity.
+ %refMax * ( prctile(im(:),99.99) -  median(im(:)));
+
+[imLoG, imp, imn] = LoG.getCompositeLoG(im,CONSTANTS,segParams);
+
+bw = logical(0*imp);
+for i=1:length(cellList)
+    bw(cellList(i).idxPts)=1;
+end
+d = bwdist(~bw);
+imp(d<3)=0;
+imn(d<3)=0;
+
+szim = ceil(size(imp));
+if bDownscale
+    szim = szim ./ 2;
+end
+imSSF = zeros(szim(1),szim(2));
+for i=1:length(cellList)
+    if is3D(CONSTANTS)
+        cx = centroidMap(cellList(i).cellID);        
+    else
+        cx = round(cellList(i).centroid);
+        cx = [cx(2),cx(1)]; % [y,x]
+    end
+    if bDownscale
+        cx = round(cx/2);
+    end
+    val_Pos = max(imp(cellList(i).idxPts));
+    val_Neg = max(imn(cellList(i).idxPts));
+    if val_Pos > val_Neg
+        % dark nucleus, bright cytoplasm
+        % ssf sign is in direction of intensity gradient
+        val = val_Pos;
+    else
+        % bright nucleus, dark cytoplasm
+        val = -1 * val_Neg;
+    end
+    ratio = val./refMax;
+    ratio  = min(ratio,1);
+    ratio  = max(ratio,-1);
+    
+    imSSF(cx(1),cx(2)) = ratio;
+
+end
+
+% if channel < 0
+%     % negative channel, keep negative LoG response
+%     imSSF(imSSF>0) = 0;
+%     imSSF = abs(imSSF);
+% else
+%     % positive channel, keep positive LoG response
+%     imSSF(imSSF<0) = 0;
+% end
+
+% imSSF = max(imSSF,0);
+% imSSF = min(imSSF,1);
+4;
diff --git a/matlab/+SSF/ssf_sample.m b/matlab/+SSF/ssf_sample.m
new file mode 100644
index 0000000000000000000000000000000000000000..d39f114804581513bda4597295cc072da8592ca4
--- /dev/null
+++ b/matlab/+SSF/ssf_sample.m
@@ -0,0 +1,10 @@
+% check the neighborhood around centeroid in imkymo. used to eliminate
+% round off errors in kymo / cell centroid
+function sample_value = ssf_sample(imKymo,centroid,idxCentroid)
+
+sample_value = imKymo(centroid(1)-1:centroid(1)+1,centroid(2)-1:centroid(2)+1,centroid(3));
+if length(find(sample_value))>1
+    fprintf(2,'ack SSF kymo ack more than one ssf sample found at centroid. send help.\n');
+end
+sample_value = sample_value(find(sample_value));
+sample_value = sample_value(1);
\ No newline at end of file
diff --git a/matlab/+SSF/ssf_sample_idx.m b/matlab/+SSF/ssf_sample_idx.m
new file mode 100644
index 0000000000000000000000000000000000000000..0d3d500c518a55f21dd3e67f132852220bbd33af
--- /dev/null
+++ b/matlab/+SSF/ssf_sample_idx.m
@@ -0,0 +1,17 @@
+% check the neighborhood around centeroid in imkymo. used to eliminate
+% round off errors in kymo / cell centroid
+function sampleList = ssf_sample_idx(imKymo,idxCentroid)
+sampleList = [];
+for i = 1:length(idxCentroid)
+    [centroid(1),centroid(2),centroid(3)] = ind2sub(size(imKymo),idxCentroid(i));
+    sv = imKymo(centroid(1)-1:centroid(1)+1,centroid(2)-1:centroid(2)+1,centroid(3));
+    if length(find(sv))>1
+        fprintf(2,'ack SSF kymo ack more than one ssf sample found at centroid. send help.\n');
+    end
+    sv = sv(find(sv));
+    if isempty(sv)
+        sv = 0;
+    end
+    sv = sv(1);
+    sampleList(i) = sv;
+end
\ No newline at end of file
diff --git a/matlab/+SSF/ssf_volume.m b/matlab/+SSF/ssf_volume.m
new file mode 100644
index 0000000000000000000000000000000000000000..7e2927ea01a46987baed927ab1d189cf7dd9c757
--- /dev/null
+++ b/matlab/+SSF/ssf_volume.m
@@ -0,0 +1,42 @@
+function im_ssf = ssf_volume(strDB,targetChannelNumbers, bDownscale)
+
+refMax = 0.7; % from cacheReferenceLoG
+
+[connx,CONSTANTS,segParams]=openDB(strDB);
+if isempty(CONSTANTS)
+    im_ssf = [];
+    return
+end
+cmd = ['select count(cellID) as nCells from tblCells where time =' num2str(CONSTANTS.imageData.NumberOfFrames)];
+q=fetch(connx,cmd);
+if 0==q.nCells
+    fprintf(2,'genKymo::ssf_volume skipping %s no segmentations in final frame\n',strDB);
+    close(connx);
+    im_ssf = [];
+    return
+end
+% x,y,1,c,t -> x,y,t,c,1
+xyzct_size = Helpers.volumeSize(CONSTANTS);
+% FUN NOTE :: if you compute kymo_size wrong here, then when we iterate
+% below you will propagate that mistake exponentially and run out of memory
+kymo_size = [xyzct_size(1:2) xyzct_size(5) xyzct_size(4) 1];
+if bDownscale
+    kymo_size(1:2) = ceil(kymo_size(1:2) ./ 2);
+end
+if is3D(CONSTANTS)
+    centroidMap = SSF.mapCentroids(connx,CONSTANTS);
+else
+    centroidMap = [];
+end
+
+
+im_ssf = zeros(kymo_size);
+
+for t=1:CONSTANTS.imageData.NumberOfFrames
+    cellList = Read.getCellsTime(connx,t,segParams.channels(1),CONSTANTS);
+    for c=1:length(targetChannelNumbers)
+        % 5-D x,y,1,c,t -> 3-D x,y,t(z),c
+        im_ssf(:,:,t,c) = SSF.ssf_channel(cellList,CONSTANTS,targetChannelNumbers(c),t,refMax,segParams,centroidMap,bDownscale); 
+    end
+end
+close(connx);
\ No newline at end of file
diff --git a/matlab/+SSF/trackDistance.m b/matlab/+SSF/trackDistance.m
new file mode 100644
index 0000000000000000000000000000000000000000..4f018e942bae2444aafe3a2dc62234220edd76fd
--- /dev/null
+++ b/matlab/+SSF/trackDistance.m
@@ -0,0 +1,18 @@
+function d = trackDistance(ci,cj)
+tOverlap = intersect(ci(:,3),cj(:,3));
+if isempty(tOverlap)
+    d = Inf;
+    return
+end
+idxDel = find(arrayfun(@(x) isempty(intersect(x,tOverlap)),ci(:,3)));
+ci(idxDel,:) = [];
+idxDel = find(arrayfun(@(x) isempty(intersect(x,tOverlap)),cj(:,3)));
+cj(idxDel,:) = [];
+
+
+if isempty(ci) || isempty(cj)
+    d = Inf;
+    return
+end
+dx = sqrt( (ci(:,1) - cj(:,1)).^2 + (ci(:,2)-cj(:,2)).^2);
+d = median(dx);
\ No newline at end of file
diff --git a/matlab/+SSF/velocity_kymo.m b/matlab/+SSF/velocity_kymo.m
new file mode 100644
index 0000000000000000000000000000000000000000..cf5dd267069bfd9269829ea0a00a3d9045580442
--- /dev/null
+++ b/matlab/+SSF/velocity_kymo.m
@@ -0,0 +1,42 @@
+function im_v_kymo = velocity_kymo(strDB,bDownscale)
+[conn,CONSTANTS,segParams]=openDB(strDB);
+
+szIm = Helpers.volumeSize(CONSTANTS);
+% kymo is (x,y,t)
+if bDownscale
+    szIm(1:2) = round(szIm(1:2) ./ 2);
+end
+im_v_kymo = zeros([szIm(2),szIm(1),szIm(5)]);
+
+for time = 1:CONSTANTS.imageData.NumberOfFrames
+    cmd = ['select srcCell.centroid as src_centroid,srcCell.time src_time, srcCell.maxRadius as src_maxRadius, '...
+        'dstCell.centroid as dst_centroid,dstCell.time as dst_time,dstCell.maxRadius as dst_maxRadius, CC.* from '...
+        '(select * from (select tblCells.centroid,tblCells.maxRadius,cellID_src,cellID,time,min(cost) from tblCells '...
+        ' inner join tblDistCC on cellID=cellID_dst where time =  ' num2str(time)...
+        ' group by cellID) as src inner join'...
+        '(select cellID_dst,cellID,time,min(cost) from tblCells  '...
+        ' inner join tblDistCC on cellID=cellID_src where time = ' num2str(time)...
+        ' group by cellID) as dst on src.cellID=dst.cellID) as CC' ...
+        ' inner join tblCells as srcCell on CC.cellID_src = srcCell.cellID '...
+        ' inner join tblCells as dstCell on CC.cellID_dst = dstCell.cellID'];
+    q=fetch(conn,cmd);
+%     
+    for i = 1:height(q)
+        csrc = jsondecode(q.src_centroid{i});
+        cdst = jsondecode(q.dst_centroid{i});
+        cx = jsondecode(q.centroid{i});
+        vsrc = norm(cx-csrc); % in velocity
+        vdst = norm(cdst-cx); % out velocity
+        v = (vsrc+vdst)/2.0; % average in velocity and out velocity
+        maxRadius = max([q.maxRadius(i),q.dst_maxRadius(i),q.src_maxRadius(i)]);
+        v = v / (3*maxRadius); % 3*maxRadius is the velocity gate
+        if bDownscale
+            cx = cx ./2;
+        end
+        cx = round(cx);
+        
+        im_v_kymo(cx(2),cx(1),time) = v;
+    end
+end
+close(conn);
+% 
\ No newline at end of file
diff --git a/matlab/+SSF/write_ssf_tracks.m b/matlab/+SSF/write_ssf_tracks.m
new file mode 100644
index 0000000000000000000000000000000000000000..e72523a058e4b8ad430748313a5e2eade1325762
--- /dev/null
+++ b/matlab/+SSF/write_ssf_tracks.m
@@ -0,0 +1,31 @@
+
+% classList = unique(classMap.values);
+for ff = 1:1 %length(flist)
+    strDB = fullfile(flist(ff).folder,flist(ff).name);
+    [conn,CONSTANTS,segParams]=openDB(strDB);
+
+    cmd = 'select trackID from tblCells inner join tblFamilies on cellID = cellID_parent';
+    q = fetch(conn,cmd);
+    close(conn);
+
+    ssf_tracks = movie_tracks{ff};
+    tids = ssf_tracks.keys;
+    tids = [tids{:}];
+    tids = intersect(tids,q.trackID);
+    tblSSF = table();
+    for i = 1:length(tids)        
+        ssf = ssf_tracks(tids(i));
+        
+        if size(ssf,2) <= 10 || all(0==ssf(1,:))
+            continue
+        end
+        x=zeros(1,CONSTANTS.imageData.NumberOfFrames);
+        x(ssf(2,:)) = ssf(1,:);
+        nt = table();
+        nt.trackID = tids(i);
+        nt.SSF = {x};
+        tblSSF = [tblSSF ; nt];
+    end
+end
+[~,fname,~] = fileparts(flist(ff).name);
+writetable(tblSSF,[fname '_dhb_full.csv'])
\ No newline at end of file
diff --git a/matlab/+Segment/aiAreaOpen.m b/matlab/+Segment/aiAreaOpen.m
index d2d04ce2436a2f58ab9c59e4a034efc899f221a1..6aed349bc36e64ca48f04da8fed93fff6dbb50fc 100644
--- a/matlab/+Segment/aiAreaOpen.m
+++ b/matlab/+Segment/aiAreaOpen.m
@@ -1,19 +1,22 @@
 function bw=aiAreaOpen(bw,min_radius_pixels,bFill)
 
-if numel(bw)>25e6 % && ~is3D(bw) 
-    % 2d huge image - use pi*r^2 approximation for speed
-    radius=min_radius_pixels(1);
-    area = radius^2 * pi;
-    area=round(area);
-    bw=bwareaopen(bw,area);
+if min(min_radius_pixels)/max(min_radius_pixels) < 0.25
+    baniso = true;
+else
+    % isotropic - use faster approximation bwareaopen
+    baniso = false;
+end
+if ~baniso 
+    min_area_pixels = Segment.getPixelArea(min_radius_pixels,is3D(bw));
+    bw=bwareaopen(bw,min_area_pixels);
     return;
 end
 
 if ~exist('bFill','var')
     bFill=false;
 end
-% maskRadius=0.5*min_radius_pixels;
-maskRadius=min_radius_pixels;
+maskRadius=floor(min_radius_pixels);
+% maskRadius=ceil(min_radius_pixels);
 maskRadius=max(maskRadius,[1,1,1]);
 if ~is3D(bw)
     maskRadius(3)=0;
diff --git a/matlab/+Segment/allocateShake.m b/matlab/+Segment/allocateShake.m
deleted file mode 100644
index 22a7c4728870aaa48c7f89d6a17699a9807ae66b..0000000000000000000000000000000000000000
--- a/matlab/+Segment/allocateShake.m
+++ /dev/null
@@ -1,33 +0,0 @@
-function [L,num,bwBoundary]=allocateShake(bw,bw2,min_radius_pixels,segParams)
-
-bwBoundary=assignShake(bw,bw2,true);
-bwReduce=Segment.aiAreaOpen(bwBoundary,min_radius_pixels);
-% any components that were not big enough?
-if find(bwBoundary & ~bwReduce,1,'first')
-    % "re-absorb" components too small to exist on their own
-    % allow disconnected components in case whole CC was removed
-    bwBoundary=assignShake(bwReduce,bw2,false);
-    bwBoundary=Segment.aiAreaOpen(bwBoundary,min_radius_pixels);
-end
-bwBoundary=imfill(bwBoundary,'holes');
-% now, the boundary has been resent, label that and done
-[L,num]=bwlabeln(bwBoundary);
-return
-
-function bwBoundary=assignShake(bw,bw2,bNoDisconnected)
-d=bwdist(bw);
-L=watershed(d);
-L(~bw2)=0;
-bwBoundary=logical(L); % cell image with boundaries set to 0
-% don't allow disconnected components
-if bNoDisconnected
-    [LX,nx]=bwlabeln(bwBoundary);
-    idx=unique(LX(bw));
-    % the boundary image, remove the connected components not from bw (e.g.
-    % bw2 only)
-    bwBoundary=bwBoundary&ismember(LX,idx);
-end
-bwBoundary=bwBoundary|bw;
-
-
-
diff --git a/matlab/+Segment/denoise.m b/matlab/+Segment/denoise.m
new file mode 100644
index 0000000000000000000000000000000000000000..e8aad9605f3799ca8abe7e897e2c3974eb5fd8c7
--- /dev/null
+++ b/matlab/+Segment/denoise.m
@@ -0,0 +1,55 @@
+function im=denoise(im,segParams,bNorm)
+
+if ~exist('bNorm','var')
+    bNorm=true;
+end
+ 
+if false==segParams.denoise
+    im=im2single(mat2gray(im));
+    return
+end
+
+bUseCuda=segParams.useCuda&&~ismac && HIP.Cuda.DeviceCount>0;
+if 4~=length(segParams.NLM)
+    bUseCuda=false;
+else
+    nlm_h=segParams.NLM(1);
+    nlm_sw_radius=segParams.NLM(2);
+    nlm_nh_radius=segParams.NLM(3);
+    nlm_hpf=segParams.NLM(4);
+    szFilter=size(im).*nlm_hpf;
+end
+if is3D(im)
+    % 3D
+    if bUseCuda
+        targetDevice = getCudaTarget();
+        imx=HIP.Cuda.NLMeans(im,nlm_h,nlm_sw_radius,nlm_nh_radius,targetDevice);
+        if nlm_hpf
+            imx=imx-HIP.Cuda.Gaussian(im,szFilter,1,targetDevice);
+        end
+    else
+        imx = medfilt3(im);
+        for i=1:30
+            imx=medfilt3(imx);
+        end
+    end
+else
+    % 2D
+    if bUseCuda     
+        targetDevice = getCudaTarget();
+        imx=HIP.Cuda.NLMeans(im,nlm_h,nlm_sw_radius,nlm_nh_radius,targetDevice);
+        if nlm_hpf
+            imx=imx-HIP.Cuda.Gaussian(im,[szFilter,1],1,targetDevice);
+        end
+    else
+        imx=imnlmfilt(im);
+    end
+end
+
+if bNorm
+    im = im2single(mat2gray(imx));
+else
+    im = imx; 
+end
+    
+
diff --git a/matlab/+Segment/findNearestSegmentation.m b/matlab/+Segment/findNearestSegmentation.m
index 4775ce061e7f492850d572192468700c6feb4449..e989ba10bf2aec31ce8123d54752e29c82ef7202 100644
--- a/matlab/+Segment/findNearestSegmentation.m
+++ b/matlab/+Segment/findNearestSegmentation.m
@@ -1,9 +1,10 @@
-function cxCell = findNearestSegmentation(cellList,targetPoint)
-
+function [cxCell,dMin,idxMin] = findNearestSegmentation(cellList,targetPoint)
 
+dMin = 0;
 for i=1:length(cellList)
     if intersect(cellList(i).pts,targetPoint,'rows')
         cxCell = cellList(i);
+        idxMin = i;
         return
     end
 end
@@ -13,5 +14,5 @@ if length(targetPoint)==2
     targetPoint(3)=0;
 end
 dd = pdist2(vertcat(cellList.centroid),targetPoint);
-[~,idx] = min(dd);
-cxCell = cellList(idx);
+[dMin,idxMin] = min(dd);
+cxCell = cellList(idxMin);
diff --git a/matlab/+Segment/frameSegment.m b/matlab/+Segment/frameSegment.m
index 055b7cca86234dc195349463375bed9b6247f0a2..58756230a73dbb0f87c25dd2734cd0cc6728d7bf 100644
--- a/matlab/+Segment/frameSegment.m
+++ b/matlab/+Segment/frameSegment.m
@@ -14,11 +14,6 @@ if isdeployed()
     segParams.draw=false;
 end
    
-if prod(CONSTANTS.imageData.Dimensions*8)>1e9
-    % huge image -- force cuda to use the mutex
-%     setenv('HYDRA_ENABLE_MUTEX','1');
-end
-
 global DRAW
 DRAW=segParams.draw;
 
@@ -44,26 +39,23 @@ min_radius_pixels = segParams.minimumRadius_um ./ resolution_um;
 
 chan=segParams.channels(1); % default channel
 if exist('imCompCache','var')
-    im=imCompCache.im;
-    imLoG=imCompCache.imLoG;
+    im = imCompCache.im;
+    imLoG = imCompCache.imLoG;
+    caChannelLoG = imCompCache.caChannelLoG;
 else
-    [im,imLoG]=DenoiseCache.readImages(t,CONSTANTS,segParams,medianMask);
+    im = DenoiseCache.readImages(t,CONSTANTS,segParams,medianMask);    
+    [imLoG, ~, ~] = LoG.getCompositeLoG(im,CONSTANTS,segParams);
+    caChannelLoG = Segment.getChannelLoG(CONSTANTS, t, segParams);
 end
 if isempty(im) || all(im(:)==0)
     ljsLog(sprintf('frameSegment: empty image at time=%d -- skipping\n',t));
     return;
 end
 
-if is3D(im)
-    min_area_pixels = 4/3*pi* mean(min_radius_pixels)^3;
-else
-    min_radius_pixels=min_radius_pixels(1);
-    min_area_pixels = min_radius_pixels^2 * pi;
-end
+[min_area_pixels,min_radius_pixels] = Segment.getPixelArea(min_radius_pixels,is3D(CONSTANTS));
 if segParams.bCytoplasmic
     min_area_pixels=min_area_pixels*4;
 end
-min_area_pixels = ceil(min_area_pixels);
 
 if DRAW
     imRaw=MicroscopeData.Reader('imageData',CONSTANTS.imageData, 'chanList',segParams.channels(1),'timeRange',[t t], 'outType','single','prompt',false);
@@ -78,41 +70,35 @@ if DRAW
     drawnow
 end
 
-[bw,bwLog]=Segment.thresholdImages(im,imLoG,segParams, min_radius_pixels,min_area_pixels,...
-    medianMask);
+[bw, bwLoG_pos, imn, imp] = Segment.thresholdLoG_negative(imLoG,segParams);
+bw = bwareaopen(bw,ceil(min_area_pixels));
+
+bwLoG_pos = bwareaopen(bwLoG_pos,ceil(min_area_pixels));
 
-if segParams.membraneChannel>0
-    bwMembrane=Segment.getMembrane(CONSTANTS,segParams.membraneChannel,t);
-    if ~isempty(bwMembrane)
-        bwLog=bwLog|bwMembrane;
-    end
-end
 
-bwChannelLoG=Segment.getChannelLoG(segParams,CONSTANTS,t);
-if ~isempty(bwChannelLoG)
-    bwLog=bwLog|bwChannelLoG;
+% [bw, bwLoG_pos] = LoG.cleanLoG(bwLoG_pos, bw, min_area_pixels, min_radius_pixels);
+if all(0==bw(:))
+    return
 end
 
-% bw2 is all the pixels in our foreground image. after we mask, some
-% of those pixels will be discarded in resolving the underlying cells.
-% allocateShake (below) assigns each discarded pixel to it's closest
-% touching segmentation using a morphological region fill
-bw2=bw;
+% % bw2 is all the pixels in our foreground image. after we mask, some
+% % of those pixels will be discarded in resolving the underlying cells.
+% % allocateShake (below) assigns each discarded pixel to it's closest
+% % touching segmentation using a morphological region fill
+bw2 = bw;
 
-bw=Segment.segReduce(bw,bwLog,segParams,min_radius_pixels);
-if is3D(bw)
-    % fill on a slice by slice basis
-    for z=1:CONSTANTS.imageData.Dimensions(3)
-        bw(:,:,z)=bw(:,:,z)|imfill(bw(:,:,z),'holes');
-    end
-else
-    if ~segParams.isPhase
-        bw=bw|imfill(bw,'holes');
-    end
+% combine blob image from non-seg channels if specified
+if ~isempty(caChannelLoG)
+    imChannel_LoG = LoG.channelLoG_separate(caChannelLoG, bw, min_radius_pixels);
+    imn = imn+imChannel_LoG;
 end
 
-[L,num,bwBoundary]=Segment.allocateShake(bw,bw2,min_radius_pixels,segParams);
-[L2]=bwlabeln(bw2); % used to mark original cc for segCC field
+L = Segment.segReduce(bw, imn, min_area_pixels);
+[L2] = bwlabeln(bw2); % used to mark original cc for segCC field
+
+if ~is3D(CONSTANTS)
+    [bounds,L] = bwboundaries(L);
+end
 
 if bEnsemble
     if size(bw,3)>1
@@ -124,24 +110,27 @@ else
     rp=[];
 end
 
-% final CC pass
-if ~is3D(im)
-    bounds=bwboundaries(bwBoundary,'noholes');
-    if length(bounds)~=num
-        fprintf(2,'ACK frameSegment: boundaries and num components !=\n');
-    end
-end
-CC=bwconncomp(L);
-for n=1:num
-    idx=CC.PixelIdxList{n};  
-    if length(idx)<3
+
+for n=1:max(L(:))
+
+    idx=find(L==n);  
+    if length(idx)<min_area_pixels
         continue
     end
     if is3D(im)
         newCell=Segment.frameSegment_create_3D(idx,size(bw),chan,t);
     else        
-        newCell=Segment.frameSegment_create(idx,size(bw),chan,t,[],[],bounds(n));
+        if isempty(bounds{n})
+            ljsLog(' ACK!! empty bounds! tough to repro! find me!!!\n',0);
+            continue
+        end
+        newCell=Segment.frameSegment_create(idx,size(bw),chan,t,[],[],bounds(n));        
+        if isempty(intersect(newCell.surface,newCell.pts,'rows'))
+            fprintf('bad surface, n=%d,r=%d\n',n,segParams.minimumRadius_um);
+        end
     end
+    newCell.idxPts = idx;
+    newCell.n = n;
     segL=unique(L2(idx));
     segL(0==segL)=[];
     if length(segL)>1
@@ -151,30 +140,53 @@ for n=1:num
     if bEnsemble
         newCell=Ensemble.setCellFeatures(newCell,rp,n,segParams);
     end
-        
-    if DRAW && ~is3D(im)
-        for i=1:length(newCell)
-            nc=newCell(i);
-            cmap=hsv(255);
-            cidx=1+round(rand()*254);
-            plot(nc.surface(:,1),nc.surface(:,2),'color',cmap(cidx,:),'linewidth',1);
-%             drawnow
-        end
+    newCell.LoG = LoG.sampleCell(newCell,CONSTANTS,imLoG);
+
+    % check ecc
+    v = eig(cov(newCell.pts));
+    ecc = max(v)/min(v);
+    if ecc>50 
+        continue
     end
+%     if is3D(imLoG)
+%         threshLoG = -1e-2;
+%     else
+%         threshLoG = -1e-3;
+%     end
+%     if (newCell.LoG >threshLoG) 
+%         % disallow segmentation based on centroid LoG thresholding
+%         continue
+%     end
+
     Cells=[Cells newCell];
 end
+if ~isempty(Cells)
+    threshLoG = mean([Cells.LoG])/10;
+    idx = find([Cells.LoG]>threshLoG); % use > since LoG is negative on nuclear channel
+%     Cells(idx) = [];
+    % % on ensembleSeg
+    if 1 || bEnsemble         
+        Cells=Ensemble.setCellEfficiency(Cells,CONSTANTS,im,imLoG,segParams,medianMask);   
+    %     Cells = Ensemble.set_LoG_score(Cells,CONSTANTS,im,imLoG,segParams);
+    end 
+end
+
+if DRAW && ~is3D(im)
+    for i=1:length(Cells)
+        nc=Cells(i);
+        cmap=hsv(255);
+        cidx=1+round(rand()*254);
+        plot(nc.surface(:,1),nc.surface(:,2),'color',cmap(cidx,:),'linewidth',1);
+%             drawnow
+    end
+end
 
-% % on ensembleSeg
-if bEnsemble
-    Cells=Ensemble.setCellEfficiency(Cells,CONSTANTS,im,imLoG,segParams,medianMask);
-    Cells = Ensemble.set_LoG_score(Cells,CONSTANTS,imLoG,segParams);
-end 
 tElapsed=toc;
 
 sz=sprintf('segmented frame %d found %d hulls, minRadius=%f time=%0.0f\n',t,length(Cells),segParams.minimumRadius_um,tElapsed);
 ljsLog(sz,3);
 if DRAW
-    title([num2str(tElapsed,'%0.0f') 'seconds']);
+    title([num2str(segParams.minimumRadius_um) 'um']);
     drawnow
 end
 4;
diff --git a/matlab/+Segment/frameSegment_create.m b/matlab/+Segment/frameSegment_create.m
index a7157dc0cdb8d375ed20f4974a36ae4d4b20e726..a15abb9b47568efede00e3eebe67ebe3bd6ce0d4 100644
--- a/matlab/+Segment/frameSegment_create.m
+++ b/matlab/+Segment/frameSegment_create.m
@@ -7,14 +7,20 @@ function newCell=frameSegment_create(idxPixels, imSize, channel, time, ...
         return;
     end
     
-    if ~exist('bounds','var')
+    if ~exist('bounds','var') || isempty(bounds)
         bw=logical(zeros(imSize));
         bw(idxPixels)=1;
         bounds=bwboundaries(bw);
     end
     
     newCell=[];
-    newCell.surface=[bounds{1}(:,2),bounds{1}(:,1)];   
+    if isempty(bounds) || length(bounds{1})<2
+        fprintf(2,'ACK!');
+        newCell
+        newCell.surface = newCell.centroid;
+    else
+        newCell.surface=[bounds{1}(:,2),bounds{1}(:,1)];   
+    end
     [r,c]=ind2sub(imSize,idxPixels);
     
     
diff --git a/matlab/+Segment/frameSegment_create_3D.m b/matlab/+Segment/frameSegment_create_3D.m
index 53c0162f64f17321c7a0a24b0a5bddef03c3852e..cb516ff8e4520b2872a1bf3f219a43691584675b 100644
--- a/matlab/+Segment/frameSegment_create_3D.m
+++ b/matlab/+Segment/frameSegment_create_3D.m
@@ -46,15 +46,11 @@ szCrop=[max(r)+PAD,max(c)+PAD,max(z)+PAD];
 bwCrop=zeros(szCrop);
 idxScale=sub2ind(szCrop,round(r),round(c),round(z));
 bwCrop(idxScale)=1;
-bwResize=imresize3(bwCrop,scaleFactor);
-[faces,verts]=isosurface(bwResize,graythresh(bwResize));
-norms = isonormals(bwResize,verts);
-
-% put verts back into image space
-verts=verts-0.25;
-% first unscale
-unscale=szCrop./size(bwResize);
-verts=verts.*unscale;
+
+[faces,verts] = isosurface(bwCrop,graythresh(bwCrop));
+[faces,verts] = reducepatch(faces,verts,scaleFactor);
+norms = isonormals(bwCrop,verts);
+
 % now uncrop
 verts=verts+[cl,rl,zl]-PAD;
 
diff --git a/matlab/+Segment/getChannelLoG.m b/matlab/+Segment/getChannelLoG.m
index 050e1fad99f299fd59f048ceb39dddb68c33e1b8..55657b93f507117dff083cdf36a65686b509e94a 100644
--- a/matlab/+Segment/getChannelLoG.m
+++ b/matlab/+Segment/getChannelLoG.m
@@ -1,38 +1,16 @@
-function [bwLoG,imc]=getChannelLoG(segParams,CONSTANTS,t)
-bwLoG=[];
-if isempty(segParams.logChannels)
+% returns a cell array of LoG images, 1 per channel
+function caChannelLoG = getChannelLoG(CONSTANTS, t, segParams)
+
+caChannelLoG = [];
+logChannels=segParams.logChannels;
+if isempty(logChannels)
     return
 end
-logChannels=segParams.logChannels;
+
 for cc=1:length(logChannels)
     channel=abs(logChannels(cc));
-    im = MicroscopeData.Reader('imageData',CONSTANTS.imageData, 'chanList',channel,...
-        'timeRange',[t t], 'outType','single','prompt',false);
-    if isempty(im) || all(im(:)==0)
-        return;
-    end
-    imf = 0*im;
-    for rr=1:0.1:1.4
-        radiusPixels = rr .* LoG.getRadiusPixels(CONSTANTS,segParams);
-        imf = imf + HIP.LoG(im,radiusPixels,[]);
-    end
-    imp=imf;
-    imp(imp<0)=0;
-    imn=imf;
-    imn(imn>0)=0;
-    imn=abs(imn);
-    imc(:,:,1)=mat2gray(imp);
-    imc(:,:,2)=mat2gray(imn);
-    imc(:,:,3)=0*imn;
-    
-    if logChannels(cc)>0
-        % nuclear channel - bright blob - use + side
-%         continue
-        bwLoG=imbinarize(imp);
-    else
-        bwLoG=imbinarize(imn);
-    end
+    im = Segment.getImages(CONSTANTS,t,channel,segParams);
     
-    % 
+    [caChannelLoG{cc}, ~, ~ ] = LoG.getCompositeLoG(im,CONSTANTS,segParams);
 end
 4;
\ No newline at end of file
diff --git a/matlab/+Segment/getDefaultSegParams.m b/matlab/+Segment/getDefaultSegParams.m
index 4aa13f496417083891c076f0a754bd2cbd037635..ccb992553cf363734f70a16fcdacc749564a800a 100644
--- a/matlab/+Segment/getDefaultSegParams.m
+++ b/matlab/+Segment/getDefaultSegParams.m
@@ -1,7 +1,7 @@
 function segParams=getDefaultSegParams()
 segParams=[];
 segParams.draw=false;
-segParams.minimumRadius_um=[1.5,0.25,2.5];
+segParams.minimumRadius_um=5;
 segParams.channels=1;
 segParams.colonyChannel=-1;
 segParams.logChannels=[];
@@ -11,7 +11,7 @@ segParams.wellRadius=-1;
 segParams.useCuda=true;
 segParams.nCores=feature('numcores'); % for ensemble seg only
 segParams.storeEnsemble=true;
-segParams.sensitivity=0.5;
+segParams.sensitivity=0;
 segParams.denoise=true;
 segParams.bCytoplasmic=false;
 segParams.bCircular=false;
diff --git a/matlab/+Segment/getImages.m b/matlab/+Segment/getImages.m
index 8da11624437087cab3f1f4814bb8b6f35a5f7f6a..562998b4d3489fccad5928325b17aa480c3d0ac5 100644
--- a/matlab/+Segment/getImages.m
+++ b/matlab/+Segment/getImages.m
@@ -9,55 +9,10 @@ if 1==segParams.wellRadius && exist('medianMask','var') && ~isempty(medianMask)
     im=im-medianMask;
     im=mat2gray(im);
 end
-im=denoise(im,segParams);
+im=Segment.denoise(im,segParams);
 if 1==nargout
     return
 end
 imLog=Segment.getLoG(im,CONSTANTS,segParams);
 4;
 
-function im=denoise(im,segParams)
- 
-if false==segParams.denoise
-    im=im2single(mat2gray(im));
-    return
-end
-
-bUseCuda=segParams.useCuda&&~ismac && HIP.Cuda.DeviceCount>0;
-if 4~=length(segParams.NLM)
-    bUseCuda=false;
-else
-    nlm_h=segParams.NLM(1);
-    nlm_sw_radius=segParams.NLM(2);
-    nlm_nh_radius=segParams.NLM(3);
-    nlm_hpf=segParams.NLM(4);
-    szFilter=size(im).*nlm_hpf;
-end
-if is3D(im)
-    % 3D
-    if bUseCuda
-        imx=HIP.Cuda.NLMeans(im,nlm_h,nlm_sw_radius,nlm_nh_radius,[]);
-        if nlm_hpf
-            imx=imx-HIP.Cuda.Gaussian(im,szFilter,1,[]);
-        end
-    else
-        imx = medfilt3(im);
-        for i=1:30
-            imx=medfilt3(imx);
-        end
-    end
-else
-    % 2D
-    if bUseCuda        
-        imx=HIP.Cuda.NLMeans(im,nlm_h,nlm_sw_radius,nlm_nh_radius,[]);
-        if nlm_hpf
-            imx=imx-HIP.Cuda.Gaussian(im,[szFilter,1],1,[]);
-        end
-    else
-        imx=imnlmfilt(im);
-    end
-end
-
-im=im2single(mat2gray(imx));
-    
-
diff --git a/matlab/+Segment/getLoG.m b/matlab/+Segment/getLoG.m
index accff54d53b0b82ac1d96a38b296700df43ec9c1..e45ff5562082dd47aa8c25bb31b45b705d539225 100644
--- a/matlab/+Segment/getLoG.m
+++ b/matlab/+Segment/getLoG.m
@@ -14,7 +14,7 @@ if isempty(im)
     return;
 end
 
-bUseCuda=segParams.useCuda&&~ismac && HIP.Cuda.DeviceCount>0;
+bUseCuda=true; 
 
 resolution_um=CONSTANTS.imageData.PixelPhysicalSize; % um per pixel
 min_radius_pixels = segParams.minimumRadius_um ./ resolution_um;
@@ -50,6 +50,7 @@ else
     logRadius=((1/sqrt(2)).*min_radius_pixels);
 end
 
-imLoG=HIP.LoG(im,logRadius,[]); 
+targetDevice = getCudaTarget();
+imLoG=HIP.LoG(im,logRadius,targetDevice); 
 
 4;
diff --git a/matlab/+Segment/getPixelArea.m b/matlab/+Segment/getPixelArea.m
new file mode 100644
index 0000000000000000000000000000000000000000..b5e962464468a4c8c7d1c8d142cbae7a13ac8c62
--- /dev/null
+++ b/matlab/+Segment/getPixelArea.m
@@ -0,0 +1,10 @@
+function [min_area_pixels,min_radius_pixels] = getPixelArea(min_radius_pixels,b3D)
+
+if b3D
+    min_area_pixels = 4/3*pi* min(min_radius_pixels)^3;
+else
+    min_radius_pixels=min_radius_pixels(1);
+    min_area_pixels = (min_radius_pixels)^2 * pi;
+end
+min_area_pixels = ceil(min_area_pixels);
+
diff --git a/matlab/+Segment/label2boundary.m b/matlab/+Segment/label2boundary.m
new file mode 100644
index 0000000000000000000000000000000000000000..d681bc99ae582646f55dcc2afe52c2511b1cc073
--- /dev/null
+++ b/matlab/+Segment/label2boundary.m
@@ -0,0 +1,49 @@
+function boundsL = label2boundary(L)
+warning('off','images:bwfilt:tie');
+boundsL={};
+lmask = L.*boundarymask(L);
+for i=1:max(lmask(:))    
+    bw = (lmask==i);
+    % if a segmentation has multiple CCs, keep only the largest
+    bw = bwareafilt(bw,1);
+    [r,c] = find(bw,1,'first');    
+%     bi = bwboundaries(bw);
+    bi = bwtraceboundary(bw,[r,c],'N');
+    if length(bi)>1
+%         [~,idxMax] = max(cellfun(@length,bi));        
+%         bi = bi(idxMax);
+    end
+%   plot(bi(:,2),bi(:,1),'-r')
+    boundsL{i} = bi;
+end
+4;
+% 
+% 
+% lx = L.*~boundarymask(L);
+% bounds = bwboundaries(lx);
+% boundsKey=cell(max(L(:)),1);
+% for i=1:length(bounds)
+%     idx = sub2ind(size(L),bounds{i}(:,1),bounds{i}(:,2));
+%     lkey = unique(L(idx));
+%     boundsKey{lkey}=[boundsKey{lkey},i];
+% end
+% % if there are >1 boundary component, take the one with the most pixels
+% for i=1:length(boundsKey)
+%     if 1==length(boundsKey{i})
+%         continue
+%     end
+%     lx = arrayfun(@(x) length(find(L==x)), boundsKey{i});
+%     [~,idxMax]=max(lx);
+%     boundsKey{i} = [boundsKey{i}(idxMax)];
+% end
+% 
+% boundsL = cell(max(L(:)),1);
+% for i=1:max(L(:))
+%     if isempty(boundsKey{i})
+%         ljsLog('ack! empty boundary label : %d\n',2);
+%         continue
+%     end
+%     boundsL(i) = bounds(boundsKey{i}(1));
+% end
+% 4;
+% 
diff --git a/matlab/+Segment/segReduce.m b/matlab/+Segment/segReduce.m
index 001af6cb25768159c73512e7b325dc1ae321bf66..654da8f96e0c52d15a57230ffb19fe0c7e64a27a 100644
--- a/matlab/+Segment/segReduce.m
+++ b/matlab/+Segment/segReduce.m
@@ -1,84 +1,32 @@
-
-function bwOut=segReduce(bw,bwLog,segParams,min_radius_pixels)
-% 
-% if segParams.isPhase
-%     bwOut=phaseReduce(bw,bwLog,min_radius_pixels);
-%     return;
-% end
-
-if is3D(bw)
-    % anisotropic dilater
-    % seZ dilates bwLoG in 3-D
-    seZ=strel('sphere',1);
-    seZ=seZ.Neighborhood;
-    % se dilates bwLoG in 2-D only
-    se=seZ;
-    se(:,:,1)=0;
-    se(:,:,3)=0;
-    % zDilate controls so we use seZ only every zDilate iterations
-    zDilate=round(min_radius_pixels(1)/min_radius_pixels(3));
-    zDilate=max(1,zDilate);
-else
-    se=strel('disk',1);
-end
-
-bwOut=bw;
-if segParams.isPhase
-    nIter=1;
-elseif segParams.bCytoplasmic 
-    nIter=3;
-else
-    nIter=ceil(pi*min_radius_pixels(1));
-    nIter=max(nIter,10);
-end
- 
-for nDilate=1:nIter
-    bwKernels=bwOut&~bwLog;
-    bwKernels=imfill(bwKernels,'holes');    
-%     bwKernels=Segment.aiAreaOpen(bwKernels,0.5*min_radius_pixels); 
-bwKernels=Segment.aiAreaOpen(bwKernels,min_radius_pixels); 
-    L=bwlabeln(bwKernels);
-    CC=bwconncomp(bwOut);
-    workingL=double(labelmatrix(CC));
-    % 3 things can happen: (0) CC s (1) CC disappears (2) CC splits
-    idxWL=vertcat(CC.PixelIdxList{:});
-    map=unique([workingL(idxWL),L(idxWL)],'rows');
-    if isempty(map)
-        break;
-    end
-    map(map(:,2)==0,:)=[];    
-    mapCounts=hist(map(:,1),[1:max(map(:,1))])';
-    idxChange=find(mapCounts>1);
-    for i=1:length(idxChange)
-        % copy over new objects to bwOut
-        idxMap=find(map(:,1)==idxChange(i),1,'first');
-        idx=CC.PixelIdxList{map(idxMap,1)};
-        bwOut(idx)=logical(L(idx));
-    end
-    
-    if isempty(find(bwKernels, 1))
-        break;
-    end
-    % dilate anisotropically
-    if is3D(bwLog) && 0==mod(nDilate,zDilate)
-        bwLog=imdilate(bwLog,seZ);
-    else
-        bwLog=imdilate(bwLog,se);   
-    end
-end
-4;
-
-function bwReduce=phaseReduce(bw,bwLog,min_radius_pixels)
-bwLogHoles=bwLog;
-bwLogHoles=imfill(bwLogHoles,'holes')&~bwLogHoles;
-bwReduce=bw&bwLogHoles;
-bwReduce=imfill(bwReduce,'holes');
-bwReduce=Segment.aiAreaOpen(bwReduce,min_radius_pixels);
-[L,num]=bwlabeln(bw);
-for n=1:num
-    idx=find(L==n);
-    if all(bwReduce(idx)==0)
-        bwReduce(idx)=1;
-    end
-end
-4;
\ No newline at end of file
+
+function L = segReduce(bw,imn,min_area_pixels)
+% use the LoG image instead of distance for watershed xform
+% empirical maxima surpression with first watershed
+hmax = 0.01;
+L = watershed(-1 * imhmax(imn,hmax));
+% % L=watershed(-1 * imn);
+L(~bw)=0;
+
+rp = regionprops(L,'Area','Centroid');
+% take the LoG response at the centroid of each region
+cx = round(vertcat(rp.Centroid));
+cx(isnan(cx))=1; % lost components have nan centroids and 0 area - removed below
+if is3D(bw)
+    cx_idx = sub2ind(size(bw),cx(:,2),cx(:,1),cx(:,3));
+else
+    cx_idx = sub2ind(size(bw),cx(:,2),cx(:,1));
+end
+% pick out segmentations that are large enough and high enough LoG response
+cx_LoG = imn(cx_idx);
+idx = find([rp.Area]' >= 1 * min_area_pixels & cx_LoG>1e-2);
+bwOut = ismember(L,idx);
+
+% use good segmentations as seeds for marker controlled watershed
+dLoG = imn .* bw;
+dLoG = -1 .* dLoG;
+dLoG2 = imimposemin(dLoG,bwOut); % marker controlled 
+L = watershed(dLoG2);
+L(~bw) = 0;
+
+L = bwlabeln(L); % make sure separate CCs are kept separate
+4;
diff --git a/matlab/+Segment/thresholdImages.m b/matlab/+Segment/thresholdImages.m
index bb7131fd0c9dbde257e97a19f4f87a1dbbf28142..8dac1f399aef3cace955c4e164b8d25a4c70ca85 100644
--- a/matlab/+Segment/thresholdImages.m
+++ b/matlab/+Segment/thresholdImages.m
@@ -46,7 +46,7 @@ else
 end
 % bwLog=Segment.aiAreaOpen(bwLog,2*min_radius_pixels,true);
 % bwLog=bwareaopen(bwLog,floor(2*pi*min_radius_pixels));
-bwLoG=cleanLoG(bwLoG);
+bwLoG=LoG.cleanLoG(logical(0*bwLoG), bwLoG, min_area_pixels,min_radius_pixels);
 bw=Segment.aiAreaOpen(bw,min_radius_pixels);
 4;
 
@@ -102,20 +102,3 @@ bwMask=bwareaopen(bwMask,500);
 bw=bw&~bwMask;
 bwLoG=bwLoG&~bwMask;
 
-% remove spurious LoG noise
-function bwLoG=cleanLoG(bwLoG)
-
-if is3D(bwLoG)
-    rp=regionprops3(bwLoG,'ConvexVolume','Volume','VoxelIdxList');
-    convDef=[rp.ConvexVolume]./[rp.Volume];
-    pixelIdxList=rp.VoxelIdxList;    
-else
-    rp=regionprops(bwLoG,'ConvexArea','Area','PixelIdxList');
-    convDef=[rp.ConvexArea]./[rp.Area];
-    pixelIdxList={rp.PixelIdxList};
-end
-idxReset=find(convDef<1.25);
-if ~isempty(idxReset)
-    pixelIdxReset=vertcat(pixelIdxList{idxReset});
-    bwLoG(pixelIdxReset)=0;
-end
diff --git a/matlab/+Segment/thresholdLoG_negative.m b/matlab/+Segment/thresholdLoG_negative.m
new file mode 100644
index 0000000000000000000000000000000000000000..29aa79124ee71827f938a801a954a8c2f6038a11
--- /dev/null
+++ b/matlab/+Segment/thresholdLoG_negative.m
@@ -0,0 +1,37 @@
+% threshold bright signal on dark background (e. g. H2B, etc.)
+% LoG response is negative (gradiant points down)
+% bwn is the blobs
+% bwp is the gradients
+function [bwn, bwp, imn, imp] = thresholdLoG_negative(imLoG,segParams)
+
+if ~exist('segParams','var') || ~isfield(segParams,'sensitivity')
+    sensitivity = 0.5;
+else
+    sensitivity = segParams.sensitivity;
+end
+
+% ACK! hardcode! ACK!
+sensitivity = 0;
+
+imn = imLoG;
+imn(imn>0)=0;
+imn=abs(imn);
+
+imp = imLoG;
+imp(imp<0) = 0;
+
+if 0== sensitivity
+    if is3D(imLoG)
+        % 3D generally stronger gradients -- more better dimensions
+        % this number is controversial! ACK! set it directly via reference
+        % distribution?
+        epsThresh = 0.05;
+    else
+        epsThresh = 1e-3;
+    end
+    bwn = logical(imn>epsThresh);
+    bwp = logical(imp>0);
+else
+    bwn = imbinarize(imn,'adaptive','sensitivity',sensitivity);
+    bwp = imbinarize(imp,'adaptive','sensitivity',sensitivity);
+end
diff --git a/matlab/+Smooth/+Classify/getMitosisFeatures.m b/matlab/+Smooth/+Classify/getMitosisFeatures.m
index e47ce7446ca54d136c91d425ae6eaa42a7548f73..204e9fcbc8cbe172bb28c634aa14dbced2fd37b5 100644
--- a/matlab/+Smooth/+Classify/getMitosisFeatures.m
+++ b/matlab/+Smooth/+Classify/getMitosisFeatures.m
@@ -44,15 +44,12 @@ centroids=cellfun(@jsondecode,q(:,3),'uniformoutput',false);
 centroids=reshape(cell2mat(centroids),3,[])';
 parentCandidates=[cell2mat(q(:,1:2)) centroids];
 
-d1=Read.getCell(conn,d1CellID);
+d1=Read.getCell(conn,d1CellID,CONSTANTS);
 costs=findD2Candidates(conn,parentCandidates,time,d1);
 if isempty(costs)
     return
 end
-[~,idx]=min([costs.ratioD1D2]);
-if costs(idx).ratioD1D2>25
-    return
-end
+[~,idx]=min(abs(1-[costs.ratioD1D2]));
 mitosisNode.ratioD1D2=costs(idx).ratioD1D2;
 
 % make sure daughter is not already in family tree. if density is high
@@ -70,20 +67,20 @@ end
 cmd=['select max(time) from tblCells where trackID IN(' num2str(costs(idx).parentDaughterTID(2)), ',' num2str(costs(idx).parentDaughterCID(2))  ') '];
 q=ljsFetch(conn,cmd);
 t1=q{1};
-if (t1-time)<5 && ~bDebug
-    return
-end
+% if (t1-time)<5 && ~bDebug
+%     return
+% end
 
 mitosisNode.parentCellID=costs(idx).parentDaughterCID(1);
 mitosisNode.siblingCellID=costs(idx).parentDaughterCID(2);
 mitosisNode.parentDaughterTID=costs(idx).parentDaughterTID;
 
-d2=Read.getCell(conn,mitosisNode.siblingCellID);
-p=Read.getCell(conn,mitosisNode.parentCellID);
+d2=Read.getCell(conn,mitosisNode.siblingCellID,CONSTANTS);
+p=Read.getCell(conn,mitosisNode.parentCellID,CONSTANTS);
 
-% for parent area, select max over last 3 frames
+% for parent area, select max over last 2 frames
 cmd=['select area from tblCells where trackID=' num2str(mitosisNode.parentDaughterTID(1))...
-    ' and time<' num2str(d1.time) ' and time>=' num2str(p.time-3)];
+    ' and time<' num2str(d1.time) ' and time>=' num2str(d1.time-2)];
 q=ljsFetch(conn,cmd);
 aparent=cell2mat(q);
 
@@ -95,40 +92,43 @@ else
     areaRatio=ar2;
 end
 mitosisNode.areaRatio=areaRatio;
-if areaRatio<minAreaRatio || areaRatio>2.5
-    return
-end
+
 
 bOcclusionEdge1=Mitosis.checkOcclusionEdge(conn,d1);
 bOcclusionEdge2=Mitosis.checkOcclusionEdge(conn,d2);
 if bOcclusionEdge1 || bOcclusionEdge2
+    % ???
+    mitosisNode.areaRatio = Inf;
     return
 end
 
 mitosisNode.sibAreaRatio=max([d1.area,d2.area])/min([d1.area,d2.area]);
 
+% parent LoG
+cmd=['select LoG from tblCells where trackID=' num2str(p.trackID)...
+    ' and time<' num2str(d1.time) ' and time>=' num2str(p.time-3)];
+q=ljsFetch(conn,cmd);
+parentLoG = min(cell2mat(q));
+% d1 LoG
+cmd=['select LoG from tblCells where trackID=' num2str(d1.trackID)...
+    ' and time>=' num2str(d1.time) ' and time<' num2str(d1.time+3)];
+q=ljsFetch(conn,cmd);
+d1LoG = min(cell2mat(q));
 
-segParams=Read.getSegmentationParams(conn);
-imCache=Mitosis.getImageCache(conn,CONSTANTS,time,segParams);
-if isempty(imCache)
-    return;
-end
+% d1 LoG
+cmd=['select LoG from tblCells where trackID=' num2str(d2.trackID)...
+    ' and time>=' num2str(d1.time) ' and time<' num2str(d2.time+3)];
+q=ljsFetch(conn,cmd);
+d2LoG = min(cell2mat(q));
 
-d1br=brightShape(d1,imCache.im);
-d2br=brightShape(d2,imCache.im);
-d1t1=getNextDaughter(conn,d1);
-if ~isempty(d1t1)
-    d1br=max([d1br,brightShape(d1t1,imCache.imP1)]);
-end
-d2t1=getNextDaughter(conn,d2);
-if ~isempty(d2t1)
-    d2br=max([d2br,brightShape(d2t1,imCache.imP1)]);
-end
+mitosisNode.pd1d2LoG = [parentLoG,d1LoG,d2LoG];
 
-pbr=getParentBR(conn,CONSTANTS,p,imCache);
-mitosisNode.brightRatio=[d1br,d2br,pbr];
-eccParent=getParentECC(conn,imCache,p);
-mitosisNode.eccParent=eccParent;
+mitosisNode.pd1d2Ecc = [Helpers.cellEccentricity(p),Helpers.cellEccentricity(d1),...
+    Helpers.cellEccentricity(d2)];
+
+o1 = length(intersect(p.idxPts,d1.idxPts))/min(length(p.idxPts),length(d1.idxPts));
+o2 = length(intersect(p.idxPts,d2.idxPts))/min(length(p.idxPts),length(d2.idxPts));
+mitosisNode.pd1d2overlap = [o1,o2];
 
 4;
 % end of find family
@@ -140,113 +140,41 @@ for i=1:size(parentCandidates,1)
     
 %     % target sibling 2 is the cell parent candidate tracked 2
     % parentCandidates are [cellID,trackID,centroid]  
-    [d2TrackID,d2CellID,d2Centroid]=getDaughter2(conn,parentCandidates(i,:),time,d1);
-    if isempty(d2TrackID)
+    d2 = getDaughter2(conn,parentCandidates(i,:),time,d1);
+    if isempty(d2)
         continue
     end
-    if d2CellID==d1.cellID
+    if d2.cellID==d1.cellID
         % need to come in via the other sibling!
         return
     end
-    
+    d1d2LoG = abs([d1.LoG,d2.LoG]);
+    d1d2LoG = min(d1d2LoG)/max(d1d2LoG);
+%     if  d1d2LoG < 0.5
+%         continue
+%     end
     pCentroid=parentCandidates(i,3:5);
     
     % midpoint of line between daughters -- this is where we'd like to see
     % the parent
-    pmid=(d2Centroid+d1.centroid)/2;
+    pmid=(d2.centroid+d1.centroid)/2;
     
     nc=[];
-    nc.parentDaughterCID=[parentCandidates(i,1),d2CellID,];
+    nc.parentDaughterCID=[parentCandidates(i,1),d2.cellID,];
     nc.parentToDaughterMidpoint=norm(pCentroid-pmid);
     nc.dParentD1=Mitosis.cellDistance(conn,d1.cellID,parentCandidates(i,1));
-    nc.dParentD2=Mitosis.cellDistance(conn,d2CellID,parentCandidates(i,1));
-    nc.parentDaughterTID=[parentCandidates(i,2),d2TrackID];
+    nc.dParentD2=Mitosis.cellDistance(conn,d2.cellID,parentCandidates(i,1));
+    nc.parentDaughterTID=[parentCandidates(i,2),d2.trackID];
+
+    ratioD1D2 = min(nc.dParentD1,nc.dParentD2) / max(nc.dParentD1,nc.dParentD2);
     nc.ratioD1D2=nc.dParentD1/nc.dParentD2;
+    nc.d1d2LoG = d1d2LoG;
     costs=[costs nc];
 end
 
-function eccParent=getParentECC(conn,imCache,p)
-eccParent=getEcc(size(imCache.im),p);
-cmd=['select cellID from tblCells where time=' num2str(p.time-1) ' and '...
-    ' trackID= ' num2str(p.trackID)];
-q=ljsFetch(conn,cmd);
-if isempty(q)
-    return
-end
-p1=Read.getCell(conn,q{1});
-eccParent1=getEcc(size(imCache.im),p1);
-eccParent=min([eccParent,eccParent1]);
-
-
-function pbr=getParentBR(conn,CONSTANTS,p,imCache)
-
-% parent needs to be in frame t-1
-pbr=brightShape(p,imCache.imM1);
-cmd=['select cellID from tblCells where time=' num2str(p.time-1) ' and '...
-    ' trackID= ' num2str(p.trackID)];
-q=ljsFetch(conn,cmd);
-if isempty(q)
-    return
-end
-p1=Read.getCell(conn,q{1});
-pbr1=brightShape(p1,imCache.imM2);
-pbr=max([pbr,pbr1]);
-
-function d=getNextDaughter(conn,cell)
-
-cmd=['select cellID from tblCells where trackID=' num2str(cell.trackID) ' and time=' num2str(cell.time)];
-q=ljsFetch(conn,cmd);
-if isempty(q)
-    d=[];
-    return;
-end
-nextID=q{1};
-d=Read.getCell(conn,nextID);
-
-% mse between distance transform and intensity profile
-function br=brightShape(cell,im)
-
-if isempty(im)
-    br=0;
-    return;
-end
-imx=0*im;
-if (size(im,3))>1
-    idx=sub2ind(size(im),cell.pts(:,2),cell.pts(:,1),cell.pts(:,3));
-else
-    idx=sub2ind(size(im),cell.pts(:,2),cell.pts(:,1));
-end
-imx(idx)=im(idx);
-if (0==max(imx(:)))
-    br=0;
-    return
-end
-
-bwd=bwdist(~imx);
-imx=imx.*max(bwd(:))/max(imx(:));
-br=sum(bwd(:)-imx(:))/length(find(bwd));
-
-function ecc=getEcc(szImage,cell)
-
-if length(szImage)>2 && szImage(3)>1
-    ecc=0;
-    return;
-end
-imx=zeros(szImage);
-idx=sub2ind(szImage,cell.pts(:,2),cell.pts(:,1));
-imx(idx)=1;
-if (0==max(imx(:)))
-    ecc=1;
-    return
-end
-rp=regionprops(imx,'Eccentricity');
-ecc=rp.Eccentricity;
-
-function [d2TrackID,d2CellID,d2Centroid]=getDaughter2(conn,parentCandidate,time,d1)
+function d2 = getDaughter2(conn,parentCandidate,time,d1)
 
-d2TrackID=[];
-d2CellID=[];
-d2Centroid=[];
+d2 = [];
 
 itid=parentCandidate(2); % trackID for parent/daughter 2
 % try to use parent trackID in time t-1 to find daughter in time t
@@ -257,9 +185,7 @@ if size(q,1)>1
     fprintf(2,'rut roh! duplicate track entries conn=%s time=%d\n',conn.DataSource,time);
 end
 if ~isempty(q)
-    d2TrackID=itid;
-    d2CellID=q{1};
-    d2Centroid=jsondecode(q{1,2})';
+    d2 = Read.getCell(conn,q{1});
 else
     % parent did not track to a d2
     % so, there first choice is still out there and is not d1 (since d1 is 
@@ -272,26 +198,24 @@ else
     %  to find a daughter that the parent wanted, but later the parent may
     %  get the track they actually wanted. pfad.
     %  for now, no go
-    return;
-    
-    cmd=['select * from tblDistCC where cellID_src=' num2str(parentCandidate(1)) ...
-        ' and cellID_dst in (select cellID  from (select cellID,trackID,min(time) ' ...
-        ' as tStart from tblCells group by trackID)) and cellID_dst<>' num2str(d1.cellID)];
-    q=fetch(conn,cmd);
-    if ~isempty(q)
-        % make sure d2 is not already in table
-        cmd=['select * from tblFamilies where cellID_child1=' num2str(q.cellID_dst(1))];
-        qfamily=fetch(conn,cmd);
-        if isempty(qfamily)
-            d2=Read.getCell(conn,q.cellID_dst(1));
-            if d2.time~=d1.time
-                return
-            end
-            d2TrackID=d2.trackID;
-            d2CellID=d2.cellID;
-            d2Centroid=d2.centroid;
+    cmd = ['select * from tblDistCC where cellID_src = ' num2str(parentCandidate(1)) ' order by cost asc'];
+    qp = fetch(conn,cmd);
+    cmd = ['select cellID,LoG from tblCells where cellID in ' Helpers.sqlEncodeVector(qp.cellID_dst)];
+    qd = fetch(conn,cmd);
+    qd(qd.LoG>-0.1,:) = [];
+    qd(qd.cellID == d1.cellID,:) = [];
+    i = 1;
+    while i <= length(qp.cellID_dst)
+        if isempty(intersect(qp.cellID_dst(i),qd.cellID))
+            qp(i,:) = [];
+        else
+            i = i+1;
         end
     end
+    if ~isempty(qp)
+        d2 = Read.getCell(conn,qp.cellID_dst(1));
+    end
+
 end
    
 
diff --git a/matlab/+Smooth/+Classify/goClassifyMitosis.m b/matlab/+Smooth/+Classify/goClassifyMitosis.m
index b1dd86c29e34ff999064fa38a9d0c29304627025..b2542ead4a500033e82d7f29cd2991f149e144cb 100644
--- a/matlab/+Smooth/+Classify/goClassifyMitosis.m
+++ b/matlab/+Smooth/+Classify/goClassifyMitosis.m
@@ -13,43 +13,23 @@ end
 if ~exist('nProcessors','var') || isempty(nProcessors)
     nProcessors=ljsNProcs();
 end
-p=ljsStartParallel(nProcessors);
+% p=ljsStartParallel(nProcessors);
 
 mParams=Read.getMitosisParams(conn);
+segParams = Read.getSegmentationParams(conn);
 targetTracks=Smooth.getTargetTracks(conn,5);
-strDB=conn.DataSource;
 
-mnode=Smooth.Classify.newMitosisNode(-1);
-cxComp=Composite();
-spmd
-    cxComp=openDB(strDB);
-end
-mnode=[];
-for i=1:ceil(size(targetTracks,1)/p.NumWorkers)
-    mx=[];
-    spmd
-        idx = ((i - 1) * numlabs) + labindex;
-        if idx<=size(targetTracks,1)
-            if targetTracks.t0(idx)==1
-                mx=Smooth.Classify.newMitosisNode(targetTracks.trackID(idx));
-            else            
-                mx=Smooth.Classify.getMitosisFeatures(cxComp,CONSTANTS,mParams,targetTracks.trackID(idx));
-            end
-        end
-    end
-    mres=[mx{:}]';
-    mnode=[mnode;mres];
-end
-spmd
-    close(cxComp);
-end
+mnode = [];
+
+for i = 1:length(targetTracks.trackID)
+    mn = Smooth.Classify.getMitosisFeatures(conn,CONSTANTS,mParams,targetTracks.trackID(i))  ;
 
-for i=1:length(mnode)
-    if Smooth.Classify.isValidMitosis(mnode(i),mParams)
-        c1=Read.getCell(conn,mnode(i).d1CellID);
-        c2=Read.getCell(conn,mnode(i).siblingCellID);
-        p=Read.getCell(conn,mnode(i).parentCellID);        
-        ljsLog('resegMitosis: adding new mitosis at child = %d\n',mnode(i).d1CellID);
-        Mitosis.addMitosis(conn,p,c1,c2);    
+    if Smooth.Classify.isValidMitosis(mn,mParams)
+        c1=Read.getCell(conn,mn.d1CellID);
+        c2=Read.getCell(conn,mn.siblingCellID);
+        p=Read.getCell(conn,mn.parentCellID);
+%         drawMitosis(conn.DataSource,p,c1,c2,segParams,mn);
+        ljsLog('resegMitosis: adding new mitosis at child = %d\n',mn.d1CellID);
+        Mitosis.addMitosis(conn,p,c1,c2);
     end
 end
\ No newline at end of file
diff --git a/matlab/+Smooth/+Classify/isValidMitosis.m b/matlab/+Smooth/+Classify/isValidMitosis.m
index 154d6d3b13ab94d8a7fbe3c12077310e11b74470..f2eb47765e065a8865d969c1263e9832354a48c9 100644
--- a/matlab/+Smooth/+Classify/isValidMitosis.m
+++ b/matlab/+Smooth/+Classify/isValidMitosis.m
@@ -3,19 +3,27 @@ bValid=false;
 if mnode.parentCellID<0
     return;
 end
-if any(isinf(mnode.brightRatio))
+threshLoG = [-0.05,-0.1,-0.35];
+if any(mnode.pd1d2LoG > threshLoG(1)) 
     return;
 end
-if ~isinf(mParams.brightThreshold)
-    if any(mnode.brightRatio<mParams.brightThreshold)
-        return;
-    end
+if any(mnode.pd1d2LoG < threshLoG(3)) 
+    return;
 end
-if ~isinf(mParams.eccentricityThreshold)
-    if mnode.eccParent>mParams.eccentricityThreshold
-        return;
+if ~any(mnode.pd1d2LoG < threshLoG(2))
+    return
+end
+if any(mnode.pd1d2overlap>0.25)
+    if ~all(mnode.pd1d2LoG<threshLoG(2))
+        return
     end
 end
+
+daughterLoG = abs(mnode.pd1d2LoG(2:3));
+dRatio = min(daughterLoG)/max(daughterLoG);
+if dRatio < 0.5
+    return
+end
 if ~isinf(mParams.parentDaughterAreaRatio)
     if mnode.areaRatio<mParams.parentDaughterAreaRatio
         return;
diff --git a/matlab/+Smooth/+Classify/newMitosisNode.m b/matlab/+Smooth/+Classify/newMitosisNode.m
index 599f7716a7fdeecf93f26e268363d45682122f7e..7ee0e1dc4030806221d5d86245ac6781cfd5e702 100644
--- a/matlab/+Smooth/+Classify/newMitosisNode.m
+++ b/matlab/+Smooth/+Classify/newMitosisNode.m
@@ -6,7 +6,8 @@ mitosisNode.parentCellID=-1;
 mitosisNode.siblingCellID=-1;
 mitosisNode.parentDaughterTID=[-1,d1CellID];
 mitosisNode.areaRatio=0;
-mitosisNode.brightRatio=[-Inf,-Inf,-Inf];
+mitosisNode.pd1d2LoG=[-Inf,-Inf,-Inf];
 mitosisNode.sibAreaRatio=0;
-mitosisNode.eccParent=2;
+mitosisNode.pd1d2Ecc=[-Inf,-Inf,-Inf];
 mitosisNode.d1CellID=d1CellID;
+mitosisNode.pd1d2overlap = [-Inf,-Inf];
diff --git a/matlab/+Smooth/+Merge/goMerge.m b/matlab/+Smooth/+Merge/goMerge.m
index 173baa8e000ab2ca8d8d6dba1874b9cdf050b7c1..98e2482c60da6d9931a74054119ceed8c0bcbd74 100644
--- a/matlab/+Smooth/+Merge/goMerge.m
+++ b/matlab/+Smooth/+Merge/goMerge.m
@@ -1,6 +1,7 @@
 
 function nMerged = goMerge(conn,CONSTANTS,segParams,nProcessors)
 nMerged=0;
+
 r=Ensemble.getEnsembleRadius(segParams.minimumRadius_um);
 if 1==length(r)
     % ensemble merge uses ensemble results. if no ensemble, no results.
@@ -20,7 +21,7 @@ fragmentTracks = Smooth.Merge.getTargetFragments(conn,10);
 tx={};
 strDB=conn.DataSource;
 p=ljsStartParallel(nProcessors);
-parfor i=1:length(fragmentTracks.trackID)
+for i=1:length(fragmentTracks.trackID)
     
     cx=openDB(strDB);
     mergeTarget = Smooth.Merge.getMergeTarget(cx,fragmentTracks.trackID(i),CONSTANTS);
@@ -57,7 +58,7 @@ srcCellIDs=vertcat(targets.srcCellID{:});
 % find the unique destCellIDs in the targets table
 targetCIDs=unique(destCellIDs);
 mergeQ=table();
-parfor i=1:length(targetCIDs)
+for i=1:length(targetCIDs)
     idx=find(destCellIDs==targetCIDs(i));
     mergeList=[targetCIDs(i);srcCellIDs(idx)];
     cx=openDB(strDB);
diff --git a/matlab/+Smooth/+Merge/goMerge2.m b/matlab/+Smooth/+Merge/goMerge2.m
new file mode 100644
index 0000000000000000000000000000000000000000..b9c1569f132202a5cd3151e9858b926b7dd4733e
--- /dev/null
+++ b/matlab/+Smooth/+Merge/goMerge2.m
@@ -0,0 +1,91 @@
+
+% strDB = '/g/leverjs/ctc2022/2d_Fluo-N2DL-HeLa_training_02.LEVER';
+% [conn,CONSTANTS,segParams]=openDB(strDB);
+
+function nMerge = goMerge2(conn,CONSTANTS, segParams)
+
+nMerge = 0;
+if 1 == CONSTANTS.imageData.NumberOfFrames
+    return
+end
+
+warning('off','images:bwfilt:tie');
+q = fetch(conn,'select trackID,count(trackID) as lifespan from tblCells group by trackID');
+
+MIN_LIFESPAN = 5;
+imSize = [CONSTANTS.imageData.Dimensions(2),CONSTANTS.imageData.Dimensions(1),CONSTANTS.imageData.Dimensions(3)];
+for t=1:CONSTANTS.imageData.NumberOfFrames
+
+    cellList = Read.getCellsTime(conn,t,segParams.channels,CONSTANTS);
+    if isempty(cellList)
+        continue
+    end
+    [tTracks,idxtTracks] = intersect(q.trackID,[cellList.trackID],'stable');
+    qt = q(idxtTracks,:);
+
+    labelIm = zeros(imSize);
+    qtFragments = table();
+    for i=1:height(qt)
+        if qt.lifespan(i)<MIN_LIFESPAN
+            qtFragments = [qtFragments;qt(i,:)];            
+        else
+            cx = cellList(find([cellList.trackID] == qt.trackID(i)));
+            labelIm(horzcat(cx.idxPts)) = cx.trackID;
+        end
+    end
+    % go through each merge-able track iteratively. every time one gets
+    % absorbed, we need to check all again
+    bMergedIteration = true;
+    while bMergedIteration
+        bMergedIteration = false;
+        [d,idxd] = bwdist(labelIm);
+        for i=1:height(qtFragments)
+            if qtFragments.lifespan(i)>=MIN_LIFESPAN
+                continue
+
+            end
+            cx = cellList(find([cellList.trackID] == qtFragments.trackID(i)));
+            if isempty(cx)
+                continue
+            end
+            dx = [d(cx.idxPts),labelIm(idxd(cx.idxPts))];
+            dx(dx(:,1)>2,:) = [];
+            if isempty(dx)
+                continue
+            end
+            % take smallest distance
+            dx(dx(:,1)>min(dx(:,1)),:)=[];
+            % merge cells
+            bMergedIteration = true;
+            qtFragments(i,:) = [];
+            mergeTarget = mode(dx(:,2));
+            cxTarget = cellList(find([cellList.trackID] == mergeTarget));
+            cxTarget.pts = [cxTarget.pts;cx.pts];
+            cxTarget.idxPts = [cxTarget.idxPts;cx.idxPts];
+            cxTarget.centroid = mean(cxTarget.pts);
+            if is3D(CONSTANTS)                                
+                newCell = Segment.frameSegment_create_3D(cxTarget.idxPts, imSize, segParams.channels(1), cxTarget.time);
+                cxTarget.edges = newCell.edges;
+                cxTarget.faces = newCell.faces;
+                cxTarget.verts = newCell.verts;
+                cxTarget.normals = newCell.normals;
+            else
+                bx = logical(0*labelIm);
+                bx(cxTarget.idxPts) = 1;   
+                bx = bwareafilt(bx,1);
+                bounds = bwboundaries(bx);
+                cxTarget.surface = [bounds{1}(:,2),bounds{1}(:,1)];
+                cxTarget.centroid(3)=0;
+            end
+            % update cxTarget in cellList
+            cellList(find([cellList.trackID] == mergeTarget)) = cxTarget;
+            labelIm(cx.idxPts) = mergeTarget;
+            [d,idxd] = bwdist(labelIm);
+            Write.ReplaceCell(conn,cxTarget,cxTarget.cellID,cxTarget.trackID);
+            exec(conn,['delete from tblCells where cellID=',num2str(cx.cellID)]);
+            nMerge = nMerge + 1;
+            break; % start over, allowing cx+cxTarget to absorb other fragments
+        end
+    end
+end
+ljsLog(['goMerge2 :: nMerged = ', num2str(nMerge)],0);
diff --git a/matlab/+Smooth/getTargetTracks.m b/matlab/+Smooth/getTargetTracks.m
index de010390f3c6b8a40e1f160880e1af4167d26e5c..bbdf4640e4bd55b9017c81420f127b1910fea5e7 100644
--- a/matlab/+Smooth/getTargetTracks.m
+++ b/matlab/+Smooth/getTargetTracks.m
@@ -1,9 +1,16 @@
 
 function targetTracks=getTargetTracks(conn,nFrames)
 
-cmd=['select * from (select trackID,min(time) as t0,max(time) as t1,count(time) as lifespan '...
-    ' from tblCells group by trackID) where lifespan>' num2str(nFrames)];    
-targetTracks=fetch(conn,cmd);
+% cmd=['select * from (select trackID,min(time) as t0,max(time) as t1,count(time) as lifespan '...
+%     ' from tblCells group by trackID) where lifespan>' num2str(nFrames)];    
+% targetTracks=fetch(conn,cmd);
 
+cmd = ['select tblCells.trackID,tblCells.time,tblCells.LoG from tblCells '...
+    ' inner join (select trackID,count(time) as nt '...
+    ' from tblCells group by trackID) as qx on tblCells.trackID = qx.trackID '...
+    ' where nt>5 and tblCells.cellID=tblCells.trackID and tblCells.time>1 and '...
+    ' tblCells.LoG<-0.05 order by tblCells.LoG asc'];
+
+targetTracks = fetch(conn,cmd);
 
 
diff --git a/matlab/+UI/channelExtFamily.m b/matlab/+UI/channelExtFamily.m
index 316061a28ee2fbfcbe6f13ac46547da50eabcae9..913e724de955985089a08f094a01b46bd398abfb 100644
--- a/matlab/+UI/channelExtFamily.m
+++ b/matlab/+UI/channelExtFamily.m
@@ -16,7 +16,9 @@ for ff=1:length(flist)
     bw=imbinarize(im);
 
     cellList = Read.getCellsTime(conn,1,channelSeg,CONSTANTS);
-
+    if isempty(cellList)
+        continue
+    end
     exec(conn,'delete from uiExtFamilies');
     extFamily=[];
     for i=1:length(cellList)
diff --git a/matlab/+UI/lifsepanExtFamily.m b/matlab/+UI/lifsepanExtFamily.m
index b7eaa120c44f0ff152cfd9ee54dec91c8f6ac74d..6f0b2e5a714ce43d2383fe5bdd4f66a249d8eb71 100644
--- a/matlab/+UI/lifsepanExtFamily.m
+++ b/matlab/+UI/lifsepanExtFamily.m
@@ -7,6 +7,7 @@ cmd=['select trackID,min(time) as t0,max(time) as t1 from tblCells group by trac
 q=fetch(conn,cmd);
 q.ls=q.t1-q.t0+1;
 q=sortrows(q,'ls','descend');
-
+idx=find(q.ls<tmin);
+q(idx,:)=[];
 exec(conn,'delete from uiExtFamilies');
-insert(conn,'uiExtFamilies','trackID',q.trackID(1:tmin));
\ No newline at end of file
+insert(conn,'uiExtFamilies','trackID',q.trackID);
\ No newline at end of file
diff --git a/matlab/+Write/CreateCells.m b/matlab/+Write/CreateCells.m
index 94eb5644662538dbb3ae71a2599b22514b4b37c0..221f409341693f376d3d21df6a5baba3d2049a5a 100644
--- a/matlab/+Write/CreateCells.m
+++ b/matlab/+Write/CreateCells.m
@@ -9,16 +9,27 @@ if isempty(Cells)
 end
 
 [~,tblFields]=Write.prepareCell([],Cells(1));
+qTable=fetch(conn,'pragma table_info(tblCells)');
 if isfield(Cells,'nest')
-    tblFields.iNest=max(tblFields{1,:})+1;
-    q=fetch(conn,'pragma table_info(tblCells)');
-    if ~any(cellfun(@length,(strfind(q.name,'iNest'))))
+    tblFields.iNest=max(tblFields{1,:})+1;    
+    if ~any(cellfun(@length,(strfind(qTable.name,'iNest'))))
         cmd = ['ALTER TABLE tblCells ADD COLUMN iNest INTEGER default -1'];
         exec(conn,cmd);
         cmd = ['ALTER TABLE tblZombies ADD COLUMN iNest INTEGER'];
         exec(conn,cmd);
     end
 end
+
+if isfield(Cells,'LoG')
+    tblFields.LoG=max(tblFields{1,:})+1;    
+    if ~any(cellfun(@length,(strfind(qTable.name,'LoG'))))
+        cmd = ['ALTER TABLE tblCells ADD COLUMN LoG REAL'];
+        exec(conn,cmd);
+        cmd = ['ALTER TABLE tblZombies ADD COLUMN LoG REAL'];
+        exec(conn,cmd);
+    end
+end
+
 cmd=Write.buildPreparedStatement(tblFields,'tblCells');
 insertCells = conn.handle.prepareStatement(cmd);
 
@@ -33,6 +44,11 @@ for i=1:length(Cells)
             insertCells.setInt(tblFields.iNest,-1);
         end
     end
+    if isfield(Cells,'LoG')
+        if ~isempty(Cells(i).nest)
+            insertCells.setDouble(tblFields.LoG,Cells(i).LoG);
+        end
+    end
     Write.tryUpdateDB(insertCells);
 end
 
diff --git a/matlab/+Write/setSegParamsFolder.m b/matlab/+Write/setSegParamsFolder.m
index 570c301e79f3d6c3aa50d74820b4b322ca446e5f..c8ace14465d3f66d3e9b3b5a2e4dc89133a74554 100644
--- a/matlab/+Write/setSegParamsFolder.m
+++ b/matlab/+Write/setSegParamsFolder.m
@@ -4,7 +4,7 @@ flist=dir(fullfile(folder,'*.LEVER'));
 for ff=1:length(flist)
     strDB=fullfile(flist(ff).folder,flist(ff).name);
     conn = database(strDB, '','', 'org.sqlite.JDBC', 'jdbc:sqlite:');
-    setSegParams(conn,segParams);
+    Write.setSegParams(conn,segParams);
     close(conn);
 end
     
diff --git a/matlab/+im2lever/im2lever.m b/matlab/+im2lever/im2lever.m
new file mode 100644
index 0000000000000000000000000000000000000000..a548c92355ced9338f4d5e60cf3038eef6a99dd9
--- /dev/null
+++ b/matlab/+im2lever/im2lever.m
@@ -0,0 +1,4 @@
+function im2lever(im,CONSTANTS,outdir)
+
+imageData = MicroscopeData.MakeMetadataFromImage(im);
+MicroscopeData.WriterH5(im,CONSTANTS.imageData);
\ No newline at end of file
diff --git a/matlab/.gitattributes b/matlab/.gitattributes
new file mode 100644
index 0000000000000000000000000000000000000000..f0ff11a66ed781b66edf41fa3b97a142bdada0e0
--- /dev/null
+++ b/matlab/.gitattributes
@@ -0,0 +1 @@
+cacheReferenceLoG.mat filter=lfs diff=lfs merge=lfs -text
diff --git a/matlab/batchMitosis.m b/matlab/batchMitosis.m
new file mode 100644
index 0000000000000000000000000000000000000000..227c4b05daf0db332e4dea3b2a6ab22d40bf8f96
--- /dev/null
+++ b/matlab/batchMitosis.m
@@ -0,0 +1,13 @@
+ROOT =  '/g/leverjs/Olivier/Agne/2022-02-19_1h_starved_steady_state_exp1/';
+
+flist = dir(fullfile(ROOT,'*.LEVER'));
+nProcessors = 128;
+
+for ff=1:length(flist)
+    strDB = fullfile(flist(ff).folder,flist(ff).name);
+    [conn,CONSTANTS,segParams]=openDB(strDB);
+
+    Smooth.Classify.goClassifyMitosis(conn,CONSTANTS,nProcessors);
+
+    close(conn);
+end
diff --git a/matlab/cacheReferenceLoG.mat b/matlab/cacheReferenceLoG.mat
new file mode 100644
index 0000000000000000000000000000000000000000..552dab96604fc508ade65f3057d47505916548e4
--- /dev/null
+++ b/matlab/cacheReferenceLoG.mat
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a5ed0553e0c15ea60c2f5f909ee0445086c4c4f45fe6ee9add6bb46787aee704
+size 20274469
diff --git a/matlab/getCudaTarget.m b/matlab/getCudaTarget.m
new file mode 100644
index 0000000000000000000000000000000000000000..db83991b8c4337ecfcdf7086579982a79f1d6361
--- /dev/null
+++ b/matlab/getCudaTarget.m
@@ -0,0 +1,26 @@
+function targetGPU = getCudaTarget()
+persistent nGPU
+targetGPU = [];
+if ~isempty(nGPU)
+    if nGPU > 1
+        targetGPU = randi(nGPU)-1;
+    end
+    return 
+end
+
+nGPU = length(HIP.Cuda.DeviceStats);
+if nGPU<=1
+    return
+end
+% if more than 1 GPU, enable multiGPU use via environment variable
+% NOTE - tested only on Ubuntu 20.04, not windows yet! AC Jan 10 2023.
+
+gpuStr = '';
+for i=0:nGPU-1
+    gpuStr = [gpuStr num2str(i) ','];
+end
+gpuStr(end) = [];
+
+setenv('CUDA_VISIBLE_DEVICE',gpuStr);
+
+targetGPU = randi(nGPU)-1;
\ No newline at end of file
diff --git a/matlab/logStudy2.m b/matlab/logStudy2.m
new file mode 100644
index 0000000000000000000000000000000000000000..ec6b9c6bb001cdd866bcf4d3818a2f56f0191787
--- /dev/null
+++ b/matlab/logStudy2.m
@@ -0,0 +1,46 @@
+% strDB ='/f/leverjs/Olivier/wrangle/20210924_pos3.LEVER'
+% [conn,CONSTANTS,segParams]=openDB(strDB);
+[~,dsName,~] = fileparts(strDB); 
+outfolder = ['./tiffs_' dsName];
+prefix = '';
+if ~exist(outfolder,'dir')
+    mkdir(outfolder)
+end
+
+H2B = 1;
+ERK = 2;
+Oracle = 3;
+for t=1:CONSTANTS.imageData.NumberOfFrames
+    
+    cellList = Read.getCellsTime(conn,t,H2B,CONSTANTS);  
+
+    rCell = cellfun(@(x) std(double(x)),{cellList.pts},'UniformOutput',false);
+    rCell = median(vertcat(rCell{:}));
+    rCell = mean(rCell);
+    rCell_um = rCell .* CONSTANTS.imageData.PixelPhysicalSize(1);
+
+    im = MicroscopeData.Reader('imageData',CONSTANTS.imageData, 'chanList',...
+        ERK,'timeRange',[t t], 'outType','single','prompt',false);
+    if all(isnan(im(:)))
+        return;
+    end
+    
+    sp = segParams;
+    sp.minimumRadius_um = rCell_um;
+    imLoG = Segment.getLoG(im,CONSTANTS,sp);
+    
+    imp = imLoG;
+    imp(imp<0)=0;
+    imp = mat2gray(imp);
+    imSegment = 0*im;
+    imSegment(vertcat(cellList.idxPts)) = 1;
+    im_erkLoG = imSegment .* imp;
+    vbar = 0.33 * ones(size(im,1),5);
+    imOut = mat2gray([im,vbar,im_erkLoG]);
+    
+    figure(1);imagesc(imOut);axis image
+    title(num2str(t))
+    drawnow
+    fname = fullfile(outfolder,[prefix num2str(t) '.tif']);
+    imwrite(imOut,fname);
+end
diff --git a/package-lock.json b/package-lock.json
index cd633b34241451f2a2217d009e66774391285c95..37d82ac109c3a80e999b30b9dfa7eb3ac1d4ca33 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,23 +10,23 @@
       "hasInstallScript": true,
       "license": "UNLICENSED",
       "dependencies": {
-        "auth0-lock": "^11.30.0",
+        "auth0-lock": "^11.31.0",
         "electron-log": "^3.0.8",
         "electron-updater": "^4.3.9",
         "express-jwt": "^5.3.3",
         "express.js": "^1.0.0",
         "http-parser": "^1.0.3",
         "jwks-rsa": "^1.12.3",
-        "keypair": "^1.0.3",
+        "keypair": "^1.0.4",
         "minimist": "^1.2.5",
-        "multer": "^1.4.2",
+        "multer": "^1.4.3",
         "semver": "^6.3.0",
-        "sqlite3": "^4.1.1",
+        "sqlite3": "^5.1.6",
         "xlsx": "^0.15.6"
       },
       "devDependencies": {
         "electron": "^6.1.12",
-        "electron-builder": "^22.11.3",
+        "electron-builder": "^22.13.1",
         "sync-package-pom": "^1.0.1"
       }
     },
@@ -72,9 +72,9 @@
       }
     },
     "node_modules/@electron/universal/node_modules/debug": {
-      "version": "4.3.1",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
-      "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+      "version": "4.3.4",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+      "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
       "dev": true,
       "dependencies": {
         "ms": "2.1.2"
@@ -130,6 +130,12 @@
         "node": ">= 10.0.0"
       }
     },
+    "node_modules/@gar/promisify": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz",
+      "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==",
+      "optional": true
+    },
     "node_modules/@malept/cross-spawn-promise": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz",
@@ -168,9 +174,9 @@
       }
     },
     "node_modules/@malept/flatpak-bundler/node_modules/debug": {
-      "version": "4.3.1",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
-      "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+      "version": "4.3.4",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+      "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
       "dev": true,
       "dependencies": {
         "ms": "2.1.2"
@@ -226,6 +232,109 @@
         "node": ">= 10.0.0"
       }
     },
+    "node_modules/@mapbox/node-pre-gyp": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz",
+      "integrity": "sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA==",
+      "dependencies": {
+        "detect-libc": "^2.0.0",
+        "https-proxy-agent": "^5.0.0",
+        "make-dir": "^3.1.0",
+        "node-fetch": "^2.6.7",
+        "nopt": "^5.0.0",
+        "npmlog": "^5.0.1",
+        "rimraf": "^3.0.2",
+        "semver": "^7.3.5",
+        "tar": "^6.1.11"
+      },
+      "bin": {
+        "node-pre-gyp": "bin/node-pre-gyp"
+      }
+    },
+    "node_modules/@mapbox/node-pre-gyp/node_modules/node-fetch": {
+      "version": "2.6.11",
+      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz",
+      "integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==",
+      "dependencies": {
+        "whatwg-url": "^5.0.0"
+      },
+      "engines": {
+        "node": "4.x || >=6.0.0"
+      },
+      "peerDependencies": {
+        "encoding": "^0.1.0"
+      },
+      "peerDependenciesMeta": {
+        "encoding": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@mapbox/node-pre-gyp/node_modules/semver": {
+      "version": "7.5.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
+      "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
+      "dependencies": {
+        "lru-cache": "^6.0.0"
+      },
+      "bin": {
+        "semver": "bin/semver.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/@npmcli/fs": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz",
+      "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==",
+      "optional": true,
+      "dependencies": {
+        "@gar/promisify": "^1.0.1",
+        "semver": "^7.3.5"
+      }
+    },
+    "node_modules/@npmcli/fs/node_modules/semver": {
+      "version": "7.5.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
+      "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
+      "optional": true,
+      "dependencies": {
+        "lru-cache": "^6.0.0"
+      },
+      "bin": {
+        "semver": "bin/semver.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/@npmcli/move-file": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz",
+      "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==",
+      "deprecated": "This functionality has been moved to @npmcli/fs",
+      "optional": true,
+      "dependencies": {
+        "mkdirp": "^1.0.4",
+        "rimraf": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/@npmcli/move-file/node_modules/mkdirp": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+      "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+      "optional": true,
+      "bin": {
+        "mkdirp": "bin/cmd.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
     "node_modules/@sindresorhus/is": {
       "version": "0.14.0",
       "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
@@ -273,10 +382,13 @@
       }
     },
     "node_modules/@types/debug": {
-      "version": "4.1.5",
-      "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.5.tgz",
-      "integrity": "sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ==",
-      "dev": true
+      "version": "4.1.7",
+      "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz",
+      "integrity": "sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==",
+      "dev": true,
+      "dependencies": {
+        "@types/ms": "*"
+      }
     },
     "node_modules/@types/express": {
       "version": "4.17.11",
@@ -317,18 +429,18 @@
       }
     },
     "node_modules/@types/fs-extra": {
-      "version": "9.0.11",
-      "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.11.tgz",
-      "integrity": "sha512-mZsifGG4QeQ7hlkhO56u7zt/ycBgGxSVsFI/6lGTU34VtwkiqrrSDgw0+ygs8kFGWcXnFQWMrzF2h7TtDFNixA==",
+      "version": "9.0.13",
+      "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz",
+      "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==",
       "dev": true,
       "dependencies": {
         "@types/node": "*"
       }
     },
     "node_modules/@types/glob": {
-      "version": "7.1.3",
-      "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz",
-      "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==",
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz",
+      "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==",
       "dev": true,
       "optional": true,
       "dependencies": {
@@ -342,12 +454,18 @@
       "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw=="
     },
     "node_modules/@types/minimatch": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.4.tgz",
-      "integrity": "sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA==",
+      "version": "3.0.5",
+      "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz",
+      "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==",
       "dev": true,
       "optional": true
     },
+    "node_modules/@types/ms": {
+      "version": "0.7.31",
+      "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz",
+      "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==",
+      "dev": true
+    },
     "node_modules/@types/node": {
       "version": "10.17.50",
       "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.50.tgz",
@@ -389,25 +507,25 @@
       }
     },
     "node_modules/@types/verror": {
-      "version": "1.10.4",
-      "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.4.tgz",
-      "integrity": "sha512-OjJdqx6QlbyZw9LShPwRW+Kmiegeg3eWNI41MQQKaG3vjdU2L9SRElntM51HmHBY1cu7izxQJ1lMYioQh3XMBg==",
+      "version": "1.10.5",
+      "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.5.tgz",
+      "integrity": "sha512-9UjMCHK5GPgQRoNbqdLIAvAy0EInuiqbW0PBMtVP6B5B2HQJlvoJHM+KodPZMEjOa5VkSc+5LH7xy+cUzQdmHw==",
       "dev": true,
       "optional": true
     },
     "node_modules/@types/yargs": {
-      "version": "16.0.1",
-      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.1.tgz",
-      "integrity": "sha512-x4HABGLyzr5hKUzBC9dvjciOTm11WVH1NWonNjGgxapnTHu5SWUqyqn0zQ6Re0yQU0lsQ6ztLCoMAKDGZflyxA==",
+      "version": "17.0.10",
+      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz",
+      "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==",
       "dev": true,
       "dependencies": {
         "@types/yargs-parser": "*"
       }
     },
     "node_modules/@types/yargs-parser": {
-      "version": "20.2.0",
-      "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.0.tgz",
-      "integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==",
+      "version": "21.0.0",
+      "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz",
+      "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==",
       "dev": true
     },
     "node_modules/7zip-bin": {
@@ -480,6 +598,74 @@
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
       "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
     },
+    "node_modules/agentkeepalive": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.3.0.tgz",
+      "integrity": "sha512-7Epl1Blf4Sy37j4v9f9FjICCh4+KAQOyXgHEwlyBiAQLbhKdq/i2QQU3amQalS/wPhdPzDXPL5DMR5bkn+YeWg==",
+      "optional": true,
+      "dependencies": {
+        "debug": "^4.1.0",
+        "depd": "^2.0.0",
+        "humanize-ms": "^1.2.1"
+      },
+      "engines": {
+        "node": ">= 8.0.0"
+      }
+    },
+    "node_modules/agentkeepalive/node_modules/debug": {
+      "version": "4.3.4",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+      "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+      "optional": true,
+      "dependencies": {
+        "ms": "2.1.2"
+      },
+      "engines": {
+        "node": ">=6.0"
+      },
+      "peerDependenciesMeta": {
+        "supports-color": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/agentkeepalive/node_modules/depd": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+      "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+      "optional": true,
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/agentkeepalive/node_modules/ms": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+      "optional": true
+    },
+    "node_modules/aggregate-error": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
+      "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
+      "optional": true,
+      "dependencies": {
+        "clean-stack": "^2.0.0",
+        "indent-string": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/aggregate-error/node_modules/indent-string": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+      "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
+      "optional": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/ajv": {
       "version": "6.12.6",
       "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
@@ -582,15 +768,15 @@
       }
     },
     "node_modules/app-builder-bin": {
-      "version": "3.5.13",
-      "resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-3.5.13.tgz",
-      "integrity": "sha512-ighVe9G+bT1ENGdp9ecO1P+94vv/f+FUwaI+XkNzeg9bYF8Oi3BQ+mJuxS00UgyHs8luuOzjzC+qnAtdb43Mpg==",
+      "version": "3.7.1",
+      "resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-3.7.1.tgz",
+      "integrity": "sha512-ql93vEUq6WsstGXD+SBLSIQw6SNnhbDEM0swzgugytMxLp3rT24Ag/jcC80ZHxiPRTdew1niuR7P3/FCrDqIjw==",
       "dev": true
     },
     "node_modules/app-builder-lib": {
-      "version": "22.11.3",
-      "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-22.11.3.tgz",
-      "integrity": "sha512-u40ESAF/wPVlRPkS0hRjtClzUcS0PQ61bb5ZN8+d039cmwtS7myRVYucck58c9GOyXfvyO1hHaJii5I+QrBtdA==",
+      "version": "22.14.13",
+      "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-22.14.13.tgz",
+      "integrity": "sha512-SufmrtxU+D0Tn948fjEwAOlCN9757UXLkzzTWXMwZKR/5hisvgqeeBepWfphMIE6OkDGz0fbzEhL1P2Pty4XMg==",
       "dev": true,
       "dependencies": {
         "@develar/schema-utils": "~2.6.5",
@@ -599,32 +785,47 @@
         "7zip-bin": "~5.1.1",
         "async-exit-hook": "^2.0.1",
         "bluebird-lst": "^1.0.9",
-        "builder-util": "22.11.3",
-        "builder-util-runtime": "8.7.5",
+        "builder-util": "22.14.13",
+        "builder-util-runtime": "8.9.2",
         "chromium-pickle-js": "^0.2.0",
         "debug": "^4.3.2",
         "ejs": "^3.1.6",
-        "electron-publish": "22.11.2",
+        "electron-osx-sign": "^0.5.0",
+        "electron-publish": "22.14.13",
+        "form-data": "^4.0.0",
         "fs-extra": "^10.0.0",
         "hosted-git-info": "^4.0.2",
         "is-ci": "^3.0.0",
         "isbinaryfile": "^4.0.8",
         "js-yaml": "^4.1.0",
-        "lazy-val": "^1.0.4",
+        "lazy-val": "^1.0.5",
         "minimatch": "^3.0.4",
         "read-config-file": "6.2.0",
         "sanitize-filename": "^1.6.3",
         "semver": "^7.3.5",
         "temp-file": "^3.4.0"
       },
+      "engines": {
+        "node": ">=14.0.0"
+      }
+    },
+    "node_modules/app-builder-lib/node_modules/builder-util-runtime": {
+      "version": "8.9.2",
+      "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.9.2.tgz",
+      "integrity": "sha512-rhuKm5vh7E0aAmT6i8aoSfEjxzdYEFX7zDApK+eNgOhjofnWb74d9SRJv0H/8nsgOkos0TZ4zxW0P8J4N7xQ2A==",
+      "dev": true,
+      "dependencies": {
+        "debug": "^4.3.2",
+        "sax": "^1.2.4"
+      },
       "engines": {
         "node": ">=12.0.0"
       }
     },
     "node_modules/app-builder-lib/node_modules/debug": {
-      "version": "4.3.2",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
-      "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+      "version": "4.3.4",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+      "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
       "dev": true,
       "dependencies": {
         "ms": "2.1.2"
@@ -639,9 +840,9 @@
       }
     },
     "node_modules/app-builder-lib/node_modules/fs-extra": {
-      "version": "10.0.0",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz",
-      "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==",
+      "version": "10.1.0",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
+      "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
       "dev": true,
       "dependencies": {
         "graceful-fs": "^4.2.0",
@@ -653,9 +854,9 @@
       }
     },
     "node_modules/app-builder-lib/node_modules/hosted-git-info": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz",
-      "integrity": "sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==",
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
+      "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==",
       "dev": true,
       "dependencies": {
         "lru-cache": "^6.0.0"
@@ -683,9 +884,9 @@
       "dev": true
     },
     "node_modules/app-builder-lib/node_modules/semver": {
-      "version": "7.3.5",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
-      "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+      "version": "7.3.7",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
+      "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
       "dev": true,
       "dependencies": {
         "lru-cache": "^6.0.0"
@@ -712,17 +913,33 @@
       "integrity": "sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY="
     },
     "node_modules/aproba": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
-      "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw=="
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz",
+      "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ=="
     },
     "node_modules/are-we-there-yet": {
-      "version": "1.1.5",
-      "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
-      "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz",
+      "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==",
       "dependencies": {
         "delegates": "^1.0.0",
-        "readable-stream": "^2.0.6"
+        "readable-stream": "^3.6.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/are-we-there-yet/node_modules/readable-stream": {
+      "version": "3.6.2",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+      "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "string_decoder": "^1.1.1",
+        "util-deprecate": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
       }
     },
     "node_modules/argparse": {
@@ -750,9 +967,9 @@
       "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
     },
     "node_modules/asar": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/asar/-/asar-3.0.3.tgz",
-      "integrity": "sha512-k7zd+KoR+n8pl71PvgElcoKHrVNiSXtw7odKbyNpmgKe7EGRF9Pnu3uLOukD37EvavKwVFxOUpqXTIZC5B5Pmw==",
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/asar/-/asar-3.1.0.tgz",
+      "integrity": "sha512-vyxPxP5arcAqN4F/ebHd/HhwnAiZtwhglvdmc7BR2f0ywbVNTOpSeyhLDbGXtE/y58hv1oC75TaNIXutnsOZsQ==",
       "dev": true,
       "dependencies": {
         "chromium-pickle-js": "^0.2.0",
@@ -797,6 +1014,16 @@
         "node": ">=0.8"
       }
     },
+    "node_modules/astral-regex": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
+      "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/async": {
       "version": "1.5.2",
       "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
@@ -826,14 +1053,14 @@
       }
     },
     "node_modules/auth0-js": {
-      "version": "9.16.0",
-      "resolved": "https://registry.npmjs.org/auth0-js/-/auth0-js-9.16.0.tgz",
-      "integrity": "sha512-I9jECErKZviVPVg0hKfG7URiGV/woyd0JOnh1SKH7Vy4/9n+AkJXgZqF7ayGV5W8sHKJl2aZ3ve3fc50LfR07g==",
+      "version": "9.19.0",
+      "resolved": "https://registry.npmjs.org/auth0-js/-/auth0-js-9.19.0.tgz",
+      "integrity": "sha512-PbzzGqtcfUZj3jnPqEcJYoWH+YNMmHI9woRYBY1VZn+GaU5NIWR1H/2ZAx5ZERZXvte6qQsu2FDNB8V+1N9Ahg==",
       "dependencies": {
-        "base64-js": "^1.3.0",
-        "idtoken-verifier": "^2.0.3",
+        "base64-js": "^1.5.1",
+        "idtoken-verifier": "^2.2.2",
         "js-cookie": "^2.2.0",
-        "qs": "^6.7.0",
+        "qs": "^6.10.1",
         "superagent": "^5.3.1",
         "url-join": "^4.0.1",
         "winchan": "^0.2.2"
@@ -845,24 +1072,46 @@
       "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA=="
     },
     "node_modules/auth0-lock": {
-      "version": "11.30.0",
-      "resolved": "https://registry.npmjs.org/auth0-lock/-/auth0-lock-11.30.0.tgz",
-      "integrity": "sha512-s+a4KT0wtKiUL3g33V5O38hZJEKJcic4cyKz75PXZufHtOVqs1AQXthzrhmSf9mHhpp15NWVJ5RRq2TIj+wNUg==",
+      "version": "11.33.1",
+      "resolved": "https://registry.npmjs.org/auth0-lock/-/auth0-lock-11.33.1.tgz",
+      "integrity": "sha512-eKQtN8GjO25vyYVUzJ7BEHZDZLcA3aj3CN8OeGcmC7/gZe41nkGTSiVO8BTMMvjUQ8zA6S9znFla/AkXslAsYw==",
       "dependencies": {
-        "auth0-js": "^9.13.3",
+        "auth0-js": "^9.19.0",
         "auth0-password-policies": "^1.0.2",
-        "blueimp-md5": "2.3.1",
+        "blueimp-md5": "^2.19.0",
+        "classnames": "^2.3.1",
+        "dompurify": "^2.3.7",
         "immutable": "^3.7.3",
         "jsonp": "^0.2.1",
-        "password-sheriff": "^1.1.0",
-        "prop-types": "^15.6.0",
-        "qs": "^6.7.0",
+        "node-fetch": "^2.6.7",
+        "password-sheriff": "^1.1.1",
+        "prop-types": "^15.8.0",
+        "qs": "^6.10.3",
         "react": "^15.6.2",
         "react-dom": "^15.6.2",
         "react-transition-group": "^2.2.1",
-        "trim": "1.0.0",
+        "trim": "^1.0.1",
         "url-join": "^1.1.0",
-        "validator": "^13.1.1"
+        "validator": "^13.6.0"
+      }
+    },
+    "node_modules/auth0-lock/node_modules/node-fetch": {
+      "version": "2.6.7",
+      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
+      "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
+      "dependencies": {
+        "whatwg-url": "^5.0.0"
+      },
+      "engines": {
+        "node": "4.x || >=6.0.0"
+      },
+      "peerDependencies": {
+        "encoding": "^0.1.0"
+      },
+      "peerDependenciesMeta": {
+        "encoding": {
+          "optional": true
+        }
       }
     },
     "node_modules/auth0-password-policies": {
@@ -945,9 +1194,9 @@
       }
     },
     "node_modules/blueimp-md5": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.3.1.tgz",
-      "integrity": "sha1-mSpnN3M7naHt1kFVDcOsqy6c/Fo="
+      "version": "2.19.0",
+      "resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.19.0.tgz",
+      "integrity": "sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w=="
     },
     "node_modules/body-parser": {
       "version": "1.19.0",
@@ -1103,6 +1352,22 @@
         "ieee754": "^1.1.13"
       }
     },
+    "node_modules/buffer-alloc": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz",
+      "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==",
+      "dev": true,
+      "dependencies": {
+        "buffer-alloc-unsafe": "^1.1.0",
+        "buffer-fill": "^1.0.0"
+      }
+    },
+    "node_modules/buffer-alloc-unsafe": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz",
+      "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==",
+      "dev": true
+    },
     "node_modules/buffer-crc32": {
       "version": "0.2.13",
       "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
@@ -1115,7 +1380,7 @@
     "node_modules/buffer-equal": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz",
-      "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=",
+      "integrity": "sha512-tcBWO2Dl4e7Asr9hTGcpVrCe+F7DubpmqWCTbj4FHLmjqO2hIaC383acQubWtRJhdceqs5uBHs6Es+Sk//RKiQ==",
       "dev": true,
       "engines": {
         "node": ">=0.4.0"
@@ -1126,6 +1391,12 @@
       "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
       "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk="
     },
+    "node_modules/buffer-fill": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz",
+      "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==",
+      "dev": true
+    },
     "node_modules/buffer-from": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
@@ -1137,20 +1408,23 @@
       "integrity": "sha1-83FR2DzYLZCtyvHAUSj2NYM4374="
     },
     "node_modules/builder-util": {
-      "version": "22.11.3",
-      "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-22.11.3.tgz",
-      "integrity": "sha512-az4s7iyf1ZPXaSVgCY+YoUcBVNspHz/f2lZSXTeXpPUjiKcbV+jzewWdw8yPWFUZ9UDArI5AVhW2bQfyBRjgVQ==",
+      "version": "22.14.13",
+      "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-22.14.13.tgz",
+      "integrity": "sha512-oePC/qrrUuerhmH5iaCJzPRAKlSBylrhzuAJmRQClTyWnZUv6jbaHh+VoHMbEiE661wrj2S2aV7/bQh12cj1OA==",
       "dev": true,
       "dependencies": {
-        "@types/debug": "^4.1.5",
+        "@types/debug": "^4.1.6",
         "@types/fs-extra": "^9.0.11",
         "7zip-bin": "~5.1.1",
-        "app-builder-bin": "3.5.13",
+        "app-builder-bin": "3.7.1",
         "bluebird-lst": "^1.0.9",
-        "builder-util-runtime": "8.7.5",
+        "builder-util-runtime": "8.9.2",
         "chalk": "^4.1.1",
+        "cross-spawn": "^7.0.3",
         "debug": "^4.3.2",
         "fs-extra": "^10.0.0",
+        "http-proxy-agent": "^5.0.0",
+        "https-proxy-agent": "^5.0.0",
         "is-ci": "^3.0.0",
         "js-yaml": "^4.1.0",
         "source-map-support": "^0.5.19",
@@ -1191,16 +1465,38 @@
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
       "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
     },
-    "node_modules/builder-util/node_modules/debug": {
-      "version": "4.3.2",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
-      "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+    "node_modules/builder-util/node_modules/@tootallnate/once": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
+      "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==",
+      "dev": true,
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/builder-util/node_modules/builder-util-runtime": {
+      "version": "8.9.2",
+      "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.9.2.tgz",
+      "integrity": "sha512-rhuKm5vh7E0aAmT6i8aoSfEjxzdYEFX7zDApK+eNgOhjofnWb74d9SRJv0H/8nsgOkos0TZ4zxW0P8J4N7xQ2A==",
       "dev": true,
       "dependencies": {
-        "ms": "2.1.2"
+        "debug": "^4.3.2",
+        "sax": "^1.2.4"
       },
       "engines": {
-        "node": ">=6.0"
+        "node": ">=12.0.0"
+      }
+    },
+    "node_modules/builder-util/node_modules/debug": {
+      "version": "4.3.4",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+      "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.1.2"
+      },
+      "engines": {
+        "node": ">=6.0"
       },
       "peerDependenciesMeta": {
         "supports-color": {
@@ -1209,9 +1505,9 @@
       }
     },
     "node_modules/builder-util/node_modules/fs-extra": {
-      "version": "10.0.0",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz",
-      "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==",
+      "version": "10.1.0",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
+      "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
       "dev": true,
       "dependencies": {
         "graceful-fs": "^4.2.0",
@@ -1222,6 +1518,20 @@
         "node": ">=12"
       }
     },
+    "node_modules/builder-util/node_modules/http-proxy-agent": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
+      "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==",
+      "dev": true,
+      "dependencies": {
+        "@tootallnate/once": "2",
+        "agent-base": "6",
+        "debug": "4"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
     "node_modules/builder-util/node_modules/jsonfile": {
       "version": "6.1.0",
       "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
@@ -1290,6 +1600,47 @@
         "node": ">= 0.8"
       }
     },
+    "node_modules/cacache": {
+      "version": "15.3.0",
+      "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz",
+      "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==",
+      "optional": true,
+      "dependencies": {
+        "@npmcli/fs": "^1.0.0",
+        "@npmcli/move-file": "^1.0.1",
+        "chownr": "^2.0.0",
+        "fs-minipass": "^2.0.0",
+        "glob": "^7.1.4",
+        "infer-owner": "^1.0.4",
+        "lru-cache": "^6.0.0",
+        "minipass": "^3.1.1",
+        "minipass-collect": "^1.0.2",
+        "minipass-flush": "^1.0.5",
+        "minipass-pipeline": "^1.2.2",
+        "mkdirp": "^1.0.3",
+        "p-map": "^4.0.0",
+        "promise-inflight": "^1.0.1",
+        "rimraf": "^3.0.2",
+        "ssri": "^8.0.1",
+        "tar": "^6.0.2",
+        "unique-filename": "^1.1.1"
+      },
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/cacache/node_modules/mkdirp": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+      "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+      "optional": true,
+      "bin": {
+        "mkdirp": "bin/cmd.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
     "node_modules/cacheable-request": {
       "version": "6.1.0",
       "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz",
@@ -1402,22 +1753,39 @@
       }
     },
     "node_modules/chownr": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
-      "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
+      "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
+      "engines": {
+        "node": ">=10"
+      }
     },
     "node_modules/chromium-pickle-js": {
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz",
-      "integrity": "sha1-BKEGZywYsIWrd02YPfo+oTjyIgU=",
+      "integrity": "sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==",
       "dev": true
     },
     "node_modules/ci-info": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.1.1.tgz",
-      "integrity": "sha512-kdRWLBIJwdsYJWYJFtAFFYxybguqeF91qpZaggjG5Nf8QKdizFG2hjqvaTXbxFIcYbSaD74KpAXv6BSm17DHEQ==",
+      "version": "3.3.2",
+      "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.2.tgz",
+      "integrity": "sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg==",
       "dev": true
     },
+    "node_modules/classnames": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz",
+      "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA=="
+    },
+    "node_modules/clean-stack": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
+      "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
+      "optional": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/cli-boxes": {
       "version": "2.2.1",
       "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz",
@@ -1431,64 +1799,75 @@
       }
     },
     "node_modules/cli-truncate": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-1.1.0.tgz",
-      "integrity": "sha512-bAtZo0u82gCfaAGfSNxUdTI9mNyza7D8w4CVCcaOsy7sgwDzvx6ekr6cuWJqY3UGzgnQ1+4wgENup5eIhgxEYA==",
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz",
+      "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==",
       "dev": true,
       "optional": true,
       "dependencies": {
-        "slice-ansi": "^1.0.0",
-        "string-width": "^2.0.0"
+        "slice-ansi": "^3.0.0",
+        "string-width": "^4.2.0"
       },
       "engines": {
-        "node": ">=4"
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
     "node_modules/cli-truncate/node_modules/ansi-regex": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
-      "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
       "dev": true,
       "optional": true,
       "engines": {
-        "node": ">=4"
+        "node": ">=8"
       }
     },
+    "node_modules/cli-truncate/node_modules/emoji-regex": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+      "dev": true,
+      "optional": true
+    },
     "node_modules/cli-truncate/node_modules/is-fullwidth-code-point": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
-      "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
       "dev": true,
       "optional": true,
       "engines": {
-        "node": ">=4"
+        "node": ">=8"
       }
     },
     "node_modules/cli-truncate/node_modules/string-width": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
-      "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+      "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
       "dev": true,
       "optional": true,
       "dependencies": {
-        "is-fullwidth-code-point": "^2.0.0",
-        "strip-ansi": "^4.0.0"
+        "emoji-regex": "^8.0.0",
+        "is-fullwidth-code-point": "^3.0.0",
+        "strip-ansi": "^6.0.1"
       },
       "engines": {
-        "node": ">=4"
+        "node": ">=8"
       }
     },
     "node_modules/cli-truncate/node_modules/strip-ansi": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
-      "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
       "dev": true,
       "optional": true,
       "dependencies": {
-        "ansi-regex": "^3.0.0"
+        "ansi-regex": "^5.0.1"
       },
       "engines": {
-        "node": ">=4"
+        "node": ">=8"
       }
     },
     "node_modules/cliui": {
@@ -1607,10 +1986,18 @@
       "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
       "dev": true
     },
+    "node_modules/color-support": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
+      "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
+      "bin": {
+        "color-support": "bin.js"
+      }
+    },
     "node_modules/colors": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz",
-      "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=",
+      "integrity": "sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==",
       "dev": true,
       "engines": {
         "node": ">=0.1.90"
@@ -1632,6 +2019,15 @@
       "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz",
       "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg=="
     },
+    "node_modules/compare-version": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz",
+      "integrity": "sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/component-emitter": {
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
@@ -1676,7 +2072,7 @@
     "node_modules/console-control-strings": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
-      "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4="
+      "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ=="
     },
     "node_modules/content-disposition": {
       "version": "0.5.3",
@@ -1716,9 +2112,9 @@
       "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
     },
     "node_modules/cookiejar": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz",
-      "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA=="
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz",
+      "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ=="
     },
     "node_modules/core-js": {
       "version": "1.2.7",
@@ -1780,9 +2176,9 @@
       }
     },
     "node_modules/crypto-js": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.3.0.tgz",
-      "integrity": "sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q=="
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz",
+      "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw=="
     },
     "node_modules/crypto-random-string": {
       "version": "2.0.0",
@@ -1822,6 +2218,7 @@
       "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
       "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
       "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)",
+      "dev": true,
       "dependencies": {
         "ms": "^2.1.1"
       }
@@ -1829,7 +2226,8 @@
     "node_modules/debug/node_modules/ms": {
       "version": "2.1.2",
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
-      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+      "dev": true
     },
     "node_modules/decamelize": {
       "version": "1.2.0",
@@ -1856,6 +2254,7 @@
       "version": "0.6.0",
       "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
       "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
+      "dev": true,
       "engines": {
         "node": ">=4.0.0"
       }
@@ -1877,7 +2276,7 @@
     "node_modules/delegates": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
-      "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o="
+      "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ=="
     },
     "node_modules/depd": {
       "version": "1.1.2",
@@ -1893,14 +2292,11 @@
       "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
     },
     "node_modules/detect-libc": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
-      "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=",
-      "bin": {
-        "detect-libc": "bin/detect-libc.js"
-      },
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz",
+      "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==",
       "engines": {
-        "node": ">=0.10"
+        "node": ">=8"
       }
     },
     "node_modules/dicer": {
@@ -1954,7 +2350,7 @@
     "node_modules/dir-compare/node_modules/commander": {
       "version": "2.9.0",
       "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz",
-      "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=",
+      "integrity": "sha512-bmkUukX8wAOjHdN26xj5c4ctEV22TQ7dQYhSmuckKhToXrkUn0iIaolHdIxYYqD55nhpSPA9zPQ1yP57GdXP2A==",
       "dev": true,
       "dependencies": {
         "graceful-readlink": ">= 1.0.0"
@@ -1964,26 +2360,56 @@
       }
     },
     "node_modules/dmg-builder": {
-      "version": "22.11.3",
-      "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-22.11.3.tgz",
-      "integrity": "sha512-NGlorMQF2YGboVtHM8zP5EHxYhrxFGjtsnX6YCr9BV1bsjSPVyBJZpuxKnOOLj86zlYWYeiNGyj4NeUOLGgUCA==",
+      "version": "22.14.13",
+      "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-22.14.13.tgz",
+      "integrity": "sha512-xNOugB6AbIRETeU2uID15sUfjdZZcKdxK8xkFnwIggsM00PJ12JxpLNPTjcRoUnfwj3WrPjilrO64vRMwNItQg==",
       "dev": true,
       "dependencies": {
-        "app-builder-lib": "22.11.3",
-        "builder-util": "22.11.3",
-        "builder-util-runtime": "8.7.5",
+        "app-builder-lib": "22.14.13",
+        "builder-util": "22.14.13",
+        "builder-util-runtime": "8.9.2",
         "fs-extra": "^10.0.0",
         "iconv-lite": "^0.6.2",
         "js-yaml": "^4.1.0"
       },
       "optionalDependencies": {
-        "dmg-license": "^1.0.8"
+        "dmg-license": "^1.0.9"
+      }
+    },
+    "node_modules/dmg-builder/node_modules/builder-util-runtime": {
+      "version": "8.9.2",
+      "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.9.2.tgz",
+      "integrity": "sha512-rhuKm5vh7E0aAmT6i8aoSfEjxzdYEFX7zDApK+eNgOhjofnWb74d9SRJv0H/8nsgOkos0TZ4zxW0P8J4N7xQ2A==",
+      "dev": true,
+      "dependencies": {
+        "debug": "^4.3.2",
+        "sax": "^1.2.4"
+      },
+      "engines": {
+        "node": ">=12.0.0"
+      }
+    },
+    "node_modules/dmg-builder/node_modules/debug": {
+      "version": "4.3.4",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+      "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.1.2"
+      },
+      "engines": {
+        "node": ">=6.0"
+      },
+      "peerDependenciesMeta": {
+        "supports-color": {
+          "optional": true
+        }
       }
     },
     "node_modules/dmg-builder/node_modules/fs-extra": {
-      "version": "10.0.0",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz",
-      "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==",
+      "version": "10.1.0",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
+      "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
       "dev": true,
       "dependencies": {
         "graceful-fs": "^4.2.0",
@@ -1995,9 +2421,9 @@
       }
     },
     "node_modules/dmg-builder/node_modules/iconv-lite": {
-      "version": "0.6.2",
-      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz",
-      "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==",
+      "version": "0.6.3",
+      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+      "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
       "dev": true,
       "dependencies": {
         "safer-buffer": ">= 2.1.2 < 3.0.0"
@@ -2018,6 +2444,12 @@
         "graceful-fs": "^4.1.6"
       }
     },
+    "node_modules/dmg-builder/node_modules/ms": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+      "dev": true
+    },
     "node_modules/dmg-builder/node_modules/universalify": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
@@ -2028,9 +2460,10 @@
       }
     },
     "node_modules/dmg-license": {
-      "version": "1.0.8",
-      "resolved": "https://registry.npmjs.org/dmg-license/-/dmg-license-1.0.8.tgz",
-      "integrity": "sha512-47GOb6b4yVzpovXC34heXElpH++ICg9GuWBeOTaokUNLAoAdWpE4VehudYEEtu96j2jXsgQWYf78nW7r+0Y3eg==",
+      "version": "1.0.11",
+      "resolved": "https://registry.npmjs.org/dmg-license/-/dmg-license-1.0.11.tgz",
+      "integrity": "sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q==",
+      "deprecated": "Disk image license agreements are deprecated by Apple and will probably be removed in a future macOS release. Discussion at: https://github.com/argv-minus-one/dmg-license/issues/11",
       "dev": true,
       "optional": true,
       "os": [
@@ -2040,10 +2473,9 @@
         "@types/plist": "^3.0.1",
         "@types/verror": "^1.10.3",
         "ajv": "^6.10.0",
-        "cli-truncate": "^1.1.0",
         "crc": "^3.8.0",
-        "iconv-corefoundation": "^1.1.5",
-        "plist": "^3.0.1",
+        "iconv-corefoundation": "^1.1.7",
+        "plist": "^3.0.4",
         "smart-buffer": "^4.0.2",
         "verror": "^1.10.0"
       },
@@ -2062,6 +2494,11 @@
         "@babel/runtime": "^7.1.2"
       }
     },
+    "node_modules/dompurify": {
+      "version": "2.3.8",
+      "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.3.8.tgz",
+      "integrity": "sha512-eVhaWoVibIzqdGYjwsBWodIQIaXFSB+cKDf4cfxLMsK0xiud6SE+/WCVx/Xw/UwQsa4cS3T2eITcdtmTg2UKcw=="
+    },
     "node_modules/dot-prop": {
       "version": "5.3.0",
       "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz",
@@ -2125,12 +2562,12 @@
       "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
     },
     "node_modules/ejs": {
-      "version": "3.1.6",
-      "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.6.tgz",
-      "integrity": "sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==",
+      "version": "3.1.8",
+      "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz",
+      "integrity": "sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==",
       "dev": true,
       "dependencies": {
-        "jake": "^10.6.1"
+        "jake": "^10.8.5"
       },
       "bin": {
         "ejs": "bin/cli.js"
@@ -2158,20 +2595,20 @@
       }
     },
     "node_modules/electron-builder": {
-      "version": "22.11.3",
-      "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-22.11.3.tgz",
-      "integrity": "sha512-STv4uU3q00FzVgW9kMpRXSrhJxogzAZgIhFZl0mBZQC1VOAajNiEBsZPaU32jP23oxlgLQExj/ux6/frYk5vGA==",
+      "version": "22.14.13",
+      "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-22.14.13.tgz",
+      "integrity": "sha512-3fgLxqF2TXVKiUPeg74O4V3l0l3j7ERLazo8sUbRkApw0+4iVAf2BJkHsHMaXiigsgCoEzK/F4/rB5rne/VAnw==",
       "dev": true,
       "dependencies": {
-        "@types/yargs": "^16.0.1",
-        "app-builder-lib": "22.11.3",
-        "builder-util": "22.11.3",
-        "builder-util-runtime": "8.7.5",
+        "@types/yargs": "^17.0.1",
+        "app-builder-lib": "22.14.13",
+        "builder-util": "22.14.13",
+        "builder-util-runtime": "8.9.2",
         "chalk": "^4.1.1",
-        "dmg-builder": "22.11.3",
+        "dmg-builder": "22.14.13",
         "fs-extra": "^10.0.0",
         "is-ci": "^3.0.0",
-        "lazy-val": "^1.0.4",
+        "lazy-val": "^1.0.5",
         "read-config-file": "6.2.0",
         "update-notifier": "^5.1.0",
         "yargs": "^17.0.1"
@@ -2180,10 +2617,40 @@
         "electron-builder": "cli.js",
         "install-app-deps": "install-app-deps.js"
       },
+      "engines": {
+        "node": ">=14.0.0"
+      }
+    },
+    "node_modules/electron-builder/node_modules/builder-util-runtime": {
+      "version": "8.9.2",
+      "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.9.2.tgz",
+      "integrity": "sha512-rhuKm5vh7E0aAmT6i8aoSfEjxzdYEFX7zDApK+eNgOhjofnWb74d9SRJv0H/8nsgOkos0TZ4zxW0P8J4N7xQ2A==",
+      "dev": true,
+      "dependencies": {
+        "debug": "^4.3.2",
+        "sax": "^1.2.4"
+      },
       "engines": {
         "node": ">=12.0.0"
       }
     },
+    "node_modules/electron-builder/node_modules/debug": {
+      "version": "4.3.4",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+      "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.1.2"
+      },
+      "engines": {
+        "node": ">=6.0"
+      },
+      "peerDependenciesMeta": {
+        "supports-color": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/electron-builder/node_modules/fs-extra": {
       "version": "10.0.0",
       "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz",
@@ -2210,6 +2677,12 @@
         "graceful-fs": "^4.1.6"
       }
     },
+    "node_modules/electron-builder/node_modules/ms": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+      "dev": true
+    },
     "node_modules/electron-builder/node_modules/universalify": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
@@ -2256,47 +2729,67 @@
       "resolved": "https://registry.npmjs.org/electron-log/-/electron-log-3.0.9.tgz",
       "integrity": "sha512-kfV4riUqW8uooYLAfrlB3EJW66W29ePipJU4/Fm8UxQekVNcR2qHI/0tiJX3oWM79VdAUiiYqL9V49lhnSIO8g=="
     },
-    "node_modules/electron-publish": {
-      "version": "22.11.2",
-      "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-22.11.2.tgz",
-      "integrity": "sha512-RSrDyYL407QRryIN0QhQGJc5PjHK4gdCwTHYTH5Zl43753ZLVUMRmzW768H0Tb8hVM2VOymy8pNnQAHB5egoiQ==",
+    "node_modules/electron-osx-sign": {
+      "version": "0.5.0",
+      "resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.5.0.tgz",
+      "integrity": "sha512-icoRLHzFz/qxzDh/N4Pi2z4yVHurlsCAYQvsCSG7fCedJ4UJXBS6PoQyGH71IfcqKupcKeK7HX/NkyfG+v6vlQ==",
       "dev": true,
       "dependencies": {
-        "@types/fs-extra": "^9.0.7",
-        "builder-util": "22.11.2",
-        "builder-util-runtime": "8.7.4",
-        "chalk": "^4.1.0",
-        "fs-extra": "^9.1.0",
-        "lazy-val": "^1.0.4",
-        "mime": "^2.5.0"
+        "bluebird": "^3.5.0",
+        "compare-version": "^0.1.2",
+        "debug": "^2.6.8",
+        "isbinaryfile": "^3.0.2",
+        "minimist": "^1.2.0",
+        "plist": "^3.0.1"
+      },
+      "bin": {
+        "electron-osx-flat": "bin/electron-osx-flat.js",
+        "electron-osx-sign": "bin/electron-osx-sign.js"
+      },
+      "engines": {
+        "node": ">=4.0.0"
       }
     },
-    "node_modules/electron-publish/node_modules/builder-util": {
-      "version": "22.11.2",
-      "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-22.11.2.tgz",
-      "integrity": "sha512-n5QkoRcNKy7KrBO8trpk7WRgdpBnOu68KVm+roSbDtZaW1qAmBplyThxnczcvjByVwD+UrsKd62eNIARiz2jyw==",
+    "node_modules/electron-osx-sign/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
       "dev": true,
       "dependencies": {
-        "@types/debug": "^4.1.5",
-        "@types/fs-extra": "^9.0.7",
-        "7zip-bin": "~5.1.1",
-        "app-builder-bin": "3.5.13",
-        "bluebird-lst": "^1.0.9",
-        "builder-util-runtime": "8.7.4",
-        "chalk": "^4.1.0",
-        "debug": "^4.3.2",
-        "fs-extra": "^9.1.0",
-        "is-ci": "^3.0.0",
-        "js-yaml": "^4.0.0",
-        "source-map-support": "^0.5.19",
-        "stat-mode": "^1.0.0",
-        "temp-file": "^3.3.7"
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/electron-osx-sign/node_modules/isbinaryfile": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.3.tgz",
+      "integrity": "sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw==",
+      "dev": true,
+      "dependencies": {
+        "buffer-alloc": "^1.2.0"
+      },
+      "engines": {
+        "node": ">=0.6.0"
+      }
+    },
+    "node_modules/electron-publish": {
+      "version": "22.14.13",
+      "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-22.14.13.tgz",
+      "integrity": "sha512-0oP3QiNj3e8ewOaEpEJV/o6Zrmy2VarVvZ/bH7kyO/S/aJf9x8vQsKVWpsdmSiZ5DJEHgarFIXrnO0ZQf0P9iQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/fs-extra": "^9.0.11",
+        "builder-util": "22.14.13",
+        "builder-util-runtime": "8.9.2",
+        "chalk": "^4.1.1",
+        "fs-extra": "^10.0.0",
+        "lazy-val": "^1.0.5",
+        "mime": "^2.5.2"
       }
     },
     "node_modules/electron-publish/node_modules/builder-util-runtime": {
-      "version": "8.7.4",
-      "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.7.4.tgz",
-      "integrity": "sha512-2vDOwH0cyyCLQwW0Tsrg3RKKQpEcrV70KFun39E8RPzNFBOv9ds9juK8WUnO6ml+xJWKkKTjWLFdF3y+8GbPOw==",
+      "version": "8.9.2",
+      "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.9.2.tgz",
+      "integrity": "sha512-rhuKm5vh7E0aAmT6i8aoSfEjxzdYEFX7zDApK+eNgOhjofnWb74d9SRJv0H/8nsgOkos0TZ4zxW0P8J4N7xQ2A==",
       "dev": true,
       "dependencies": {
         "debug": "^4.3.2",
@@ -2307,9 +2800,9 @@
       }
     },
     "node_modules/electron-publish/node_modules/debug": {
-      "version": "4.3.2",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
-      "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+      "version": "4.3.4",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+      "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
       "dev": true,
       "dependencies": {
         "ms": "2.1.2"
@@ -2324,18 +2817,17 @@
       }
     },
     "node_modules/electron-publish/node_modules/fs-extra": {
-      "version": "9.1.0",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
-      "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
+      "version": "10.1.0",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
+      "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
       "dev": true,
       "dependencies": {
-        "at-least-node": "^1.0.0",
         "graceful-fs": "^4.2.0",
         "jsonfile": "^6.0.1",
         "universalify": "^2.0.0"
       },
       "engines": {
-        "node": ">=10"
+        "node": ">=12"
       }
     },
     "node_modules/electron-publish/node_modules/jsonfile": {
@@ -2351,9 +2843,9 @@
       }
     },
     "node_modules/electron-publish/node_modules/mime": {
-      "version": "2.5.2",
-      "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz",
-      "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==",
+      "version": "2.6.0",
+      "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
+      "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
       "dev": true,
       "bin": {
         "mime": "cli.js"
@@ -2489,6 +2981,12 @@
         "node": ">=4"
       }
     },
+    "node_modules/err-code": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz",
+      "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==",
+      "optional": true
+    },
     "node_modules/error-ex": {
       "version": "1.3.2",
       "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
@@ -2526,15 +3024,6 @@
       "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
       "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
     },
-    "node_modules/escape-string-regexp": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
-      "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.8.0"
-      }
-    },
     "node_modules/etag": {
       "version": "1.8.1",
       "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
@@ -2669,22 +3158,10 @@
         "ms": "2.0.0"
       }
     },
-    "node_modules/extract-zip/node_modules/mkdirp": {
-      "version": "0.5.5",
-      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
-      "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
-      "dev": true,
-      "dependencies": {
-        "minimist": "^1.2.5"
-      },
-      "bin": {
-        "mkdirp": "bin/cmd.js"
-      }
-    },
-    "node_modules/extsprintf": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
-      "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
+    "node_modules/extsprintf": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+      "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
       "dev": true,
       "engines": [
         "node >=0.6.0"
@@ -2703,9 +3180,9 @@
       "dev": true
     },
     "node_modules/fast-safe-stringify": {
-      "version": "2.0.7",
-      "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz",
-      "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA=="
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz",
+      "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA=="
     },
     "node_modules/fbjs": {
       "version": "0.8.17",
@@ -2731,12 +3208,33 @@
       }
     },
     "node_modules/filelist": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz",
-      "integrity": "sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ==",
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz",
+      "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==",
       "dev": true,
       "dependencies": {
-        "minimatch": "^3.0.4"
+        "minimatch": "^5.0.1"
+      }
+    },
+    "node_modules/filelist/node_modules/brace-expansion": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+      "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+      "dev": true,
+      "dependencies": {
+        "balanced-match": "^1.0.0"
+      }
+    },
+    "node_modules/filelist/node_modules/minimatch": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz",
+      "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==",
+      "dev": true,
+      "dependencies": {
+        "brace-expansion": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=10"
       }
     },
     "node_modules/finalhandler": {
@@ -2818,9 +3316,10 @@
       }
     },
     "node_modules/form-data": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
-      "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
+      "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+      "dev": true,
       "dependencies": {
         "asynckit": "^0.4.0",
         "combined-stream": "^1.0.8",
@@ -2831,9 +3330,9 @@
       }
     },
     "node_modules/formidable": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.2.tgz",
-      "integrity": "sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q==",
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.6.tgz",
+      "integrity": "sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ==",
       "deprecated": "Please upgrade to latest, formidable@v2 or formidable@v3! Check these notes: https://bit.ly/2ZEqIau",
       "funding": {
         "url": "https://ko-fi.com/tunnckoCore/commissions"
@@ -2875,11 +3374,14 @@
       }
     },
     "node_modules/fs-minipass": {
-      "version": "1.2.7",
-      "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz",
-      "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==",
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
+      "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
       "dependencies": {
-        "minipass": "^2.6.0"
+        "minipass": "^3.0.0"
+      },
+      "engines": {
+        "node": ">= 8"
       }
     },
     "node_modules/fs.realpath": {
@@ -2893,18 +3395,67 @@
       "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
     },
     "node_modules/gauge": {
-      "version": "2.7.4",
-      "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
-      "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz",
+      "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==",
       "dependencies": {
-        "aproba": "^1.0.3",
+        "aproba": "^1.0.3 || ^2.0.0",
+        "color-support": "^1.1.2",
         "console-control-strings": "^1.0.0",
-        "has-unicode": "^2.0.0",
-        "object-assign": "^4.1.0",
+        "has-unicode": "^2.0.1",
+        "object-assign": "^4.1.1",
         "signal-exit": "^3.0.0",
-        "string-width": "^1.0.1",
-        "strip-ansi": "^3.0.1",
-        "wide-align": "^1.1.0"
+        "string-width": "^4.2.3",
+        "strip-ansi": "^6.0.1",
+        "wide-align": "^1.1.2"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/gauge/node_modules/ansi-regex": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/gauge/node_modules/emoji-regex": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+    },
+    "node_modules/gauge/node_modules/is-fullwidth-code-point": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/gauge/node_modules/string-width": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+      "dependencies": {
+        "emoji-regex": "^8.0.0",
+        "is-fullwidth-code-point": "^3.0.0",
+        "strip-ansi": "^6.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/gauge/node_modules/strip-ansi": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+      "dependencies": {
+        "ansi-regex": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
       }
     },
     "node_modules/get-caller-file": {
@@ -2917,13 +3468,13 @@
       }
     },
     "node_modules/get-intrinsic": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
-      "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz",
+      "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==",
       "dependencies": {
         "function-bind": "^1.1.1",
         "has": "^1.0.3",
-        "has-symbols": "^1.0.1"
+        "has-symbols": "^1.0.3"
       },
       "funding": {
         "url": "https://github.com/sponsors/ljharb"
@@ -3025,14 +3576,14 @@
       }
     },
     "node_modules/graceful-fs": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz",
-      "integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg=="
+      "version": "4.2.11",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+      "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="
     },
     "node_modules/graceful-readlink": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz",
-      "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=",
+      "integrity": "sha512-8tLu60LgxF6XpdbK8OW3FA+IfTNBn1ZHGHKF4KQbEeSkajYw5PlYJcKluntgegDPTg8UkHjpet1T82vk6TQ68w==",
       "dev": true
     },
     "node_modules/har-schema": {
@@ -3058,28 +3609,6 @@
         "node": ">=6"
       }
     },
-    "node_modules/har-validator/node_modules/ajv": {
-      "version": "6.12.6",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
-      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
-      "dev": true,
-      "dependencies": {
-        "fast-deep-equal": "^3.1.1",
-        "fast-json-stable-stringify": "^2.0.0",
-        "json-schema-traverse": "^0.4.1",
-        "uri-js": "^4.2.2"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/epoberezkin"
-      }
-    },
-    "node_modules/har-validator/node_modules/fast-deep-equal": {
-      "version": "3.1.3",
-      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
-      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
-      "dev": true
-    },
     "node_modules/has": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
@@ -3101,9 +3630,9 @@
       }
     },
     "node_modules/has-symbols": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
-      "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==",
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+      "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
       "engines": {
         "node": ">= 0.4"
       },
@@ -3114,7 +3643,7 @@
     "node_modules/has-unicode": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
-      "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk="
+      "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ=="
     },
     "node_modules/has-yarn": {
       "version": "2.1.0",
@@ -3135,7 +3664,7 @@
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
       "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==",
-      "dev": true
+      "devOptional": true
     },
     "node_modules/http-errors": {
       "version": "1.7.2",
@@ -3242,17 +3771,26 @@
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
       "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
     },
+    "node_modules/humanize-ms": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
+      "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==",
+      "optional": true,
+      "dependencies": {
+        "ms": "^2.0.0"
+      }
+    },
     "node_modules/iconv-corefoundation": {
-      "version": "1.1.5",
-      "resolved": "https://registry.npmjs.org/iconv-corefoundation/-/iconv-corefoundation-1.1.5.tgz",
-      "integrity": "sha512-hI4m7udfV04OcjleOmDaR4gwXnH4xumxN+ZmywHDiKf2CmAzsT9SVYe7Y4pdnQbyZfXwAQyrElykbE5PrPRfmQ==",
+      "version": "1.1.7",
+      "resolved": "https://registry.npmjs.org/iconv-corefoundation/-/iconv-corefoundation-1.1.7.tgz",
+      "integrity": "sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ==",
       "dev": true,
       "optional": true,
       "os": [
         "darwin"
       ],
       "dependencies": {
-        "cli-truncate": "^1.1.0",
+        "cli-truncate": "^2.1.0",
         "node-addon-api": "^1.6.3"
       },
       "engines": {
@@ -3271,15 +3809,15 @@
       }
     },
     "node_modules/idtoken-verifier": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/idtoken-verifier/-/idtoken-verifier-2.1.0.tgz",
-      "integrity": "sha512-X0423UM4Rc5bFb39Ai0YHr35rcexlu4oakKdYzSGZxtoPy84P86hhAbzlpgbgomcLOFRgzgKRvhY7YjO5g8OPA==",
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/idtoken-verifier/-/idtoken-verifier-2.2.2.tgz",
+      "integrity": "sha512-PFNivtWIUKFt0B53FOACLAM2PaejEwB/wh6fPqlWoLGMWP05JKGJyKyMv/uS9kduevEfRhHaSVdoLYUnQ0YmsA==",
       "dependencies": {
-        "base64-js": "^1.3.0",
-        "crypto-js": "^3.2.1",
+        "base64-js": "^1.5.1",
+        "crypto-js": "^4.1.1",
         "es6-promise": "^4.2.8",
         "jsbn": "^1.1.0",
-        "unfetch": "^4.1.0",
+        "unfetch": "^4.2.0",
         "url-join": "^4.0.1"
       }
     },
@@ -3309,14 +3847,6 @@
       ],
       "optional": true
     },
-    "node_modules/ignore-walk": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz",
-      "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==",
-      "dependencies": {
-        "minimatch": "^3.0.4"
-      }
-    },
     "node_modules/immutable": {
       "version": "3.8.2",
       "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.2.tgz",
@@ -3338,7 +3868,7 @@
       "version": "0.1.4",
       "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
       "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
-      "dev": true,
+      "devOptional": true,
       "engines": {
         "node": ">=0.8.19"
       }
@@ -3355,6 +3885,12 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/infer-owner": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
+      "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==",
+      "optional": true
+    },
     "node_modules/inflight": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
@@ -3374,10 +3910,17 @@
       "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
       "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
       "deprecated": "Please update to ini >=1.3.6 to avoid a prototype pollution issue",
+      "dev": true,
       "engines": {
         "node": "*"
       }
     },
+    "node_modules/ip": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz",
+      "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==",
+      "optional": true
+    },
     "node_modules/ipaddr.js": {
       "version": "1.9.0",
       "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz",
@@ -3393,12 +3936,12 @@
       "dev": true
     },
     "node_modules/is-ci": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz",
-      "integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==",
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz",
+      "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==",
       "dev": true,
       "dependencies": {
-        "ci-info": "^3.1.1"
+        "ci-info": "^3.2.0"
       },
       "bin": {
         "is-ci": "bin.js"
@@ -3443,6 +3986,12 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/is-lambda": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz",
+      "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==",
+      "optional": true
+    },
     "node_modules/is-npm": {
       "version": "5.0.0",
       "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-5.0.0.tgz",
@@ -3505,9 +4054,9 @@
       "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
     },
     "node_modules/isbinaryfile": {
-      "version": "4.0.8",
-      "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.8.tgz",
-      "integrity": "sha512-53h6XFniq77YdW+spoRrebh0mnmTxRPTlcuIArO57lmMdq4uBKFKaeTjnb92oYWrSn/LVL+LT+Hap2tFQj8V+w==",
+      "version": "4.0.10",
+      "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz",
+      "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==",
       "dev": true,
       "engines": {
         "node": ">= 8.0.0"
@@ -3519,8 +4068,8 @@
     "node_modules/isexe": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
-      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
-      "dev": true
+      "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+      "devOptional": true
     },
     "node_modules/isomorphic-fetch": {
       "version": "2.2.1",
@@ -3538,13 +4087,13 @@
       "dev": true
     },
     "node_modules/jake": {
-      "version": "10.8.2",
-      "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.2.tgz",
-      "integrity": "sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==",
+      "version": "10.8.5",
+      "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz",
+      "integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==",
       "dev": true,
       "dependencies": {
-        "async": "0.9.x",
-        "chalk": "^2.4.2",
+        "async": "^3.2.3",
+        "chalk": "^4.0.2",
         "filelist": "^1.0.1",
         "minimatch": "^3.0.4"
       },
@@ -3552,77 +4101,15 @@
         "jake": "bin/cli.js"
       },
       "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/jake/node_modules/ansi-styles": {
-      "version": "3.2.1",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
-      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
-      "dev": true,
-      "dependencies": {
-        "color-convert": "^1.9.0"
-      },
-      "engines": {
-        "node": ">=4"
+        "node": ">=10"
       }
     },
     "node_modules/jake/node_modules/async": {
-      "version": "0.9.2",
-      "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
-      "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=",
-      "dev": true
-    },
-    "node_modules/jake/node_modules/chalk": {
-      "version": "2.4.2",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
-      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
-      "dev": true,
-      "dependencies": {
-        "ansi-styles": "^3.2.1",
-        "escape-string-regexp": "^1.0.5",
-        "supports-color": "^5.3.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/jake/node_modules/color-convert": {
-      "version": "1.9.3",
-      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
-      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
-      "dev": true,
-      "dependencies": {
-        "color-name": "1.1.3"
-      }
-    },
-    "node_modules/jake/node_modules/color-name": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+      "version": "3.2.4",
+      "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz",
+      "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==",
       "dev": true
     },
-    "node_modules/jake/node_modules/has-flag": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
-      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/jake/node_modules/supports-color": {
-      "version": "5.5.0",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
-      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
-      "dev": true,
-      "dependencies": {
-        "has-flag": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
     "node_modules/js-cookie": {
       "version": "2.2.1",
       "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz",
@@ -3647,7 +4134,7 @@
     "node_modules/jsbn": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz",
-      "integrity": "sha1-sBMHyym2GKHtJux56RH4A8TaAEA="
+      "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A=="
     },
     "node_modules/json-buffer": {
       "version": "3.0.0",
@@ -3674,13 +4161,10 @@
       "dev": true
     },
     "node_modules/json5": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
-      "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
+      "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
       "dev": true,
-      "dependencies": {
-        "minimist": "^1.2.5"
-      },
       "bin": {
         "json5": "lib/cli.js"
       },
@@ -3825,9 +4309,9 @@
       }
     },
     "node_modules/keypair": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/keypair/-/keypair-1.0.3.tgz",
-      "integrity": "sha512-0wjZ2z/SfZZq01+3/8jYLd8aEShSa+aat1zyPGQY3IuKoEAp6DJGvu2zt6snELrQU9jbCkIlCyNOD7RdQbHhkQ=="
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/keypair/-/keypair-1.0.4.tgz",
+      "integrity": "sha512-zwhgOhhniaL7oxMgUMKKw5219PWWABMO+dgMnzJOQ2/5L3XJtTJGhW2PEXlxXj9zaccdReZJZ83+4NPhVfNVDg=="
     },
     "node_modules/keyv": {
       "version": "3.1.0",
@@ -3851,9 +4335,9 @@
       }
     },
     "node_modules/lazy-val": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.4.tgz",
-      "integrity": "sha512-u93kb2fPbIrfzBuLjZE+w+fJbUUMhNDXxNmMfaqNgpfQf1CO5ZSe2LfsnBqVAk7i/2NF48OSoRj+Xe2VT+lE8Q=="
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz",
+      "integrity": "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q=="
     },
     "node_modules/limiter": {
       "version": "1.1.5",
@@ -4008,7 +4492,6 @@
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
       "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
-      "dev": true,
       "dependencies": {
         "semver": "^6.0.0"
       },
@@ -4019,6 +4502,33 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/make-fetch-happen": {
+      "version": "9.1.0",
+      "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz",
+      "integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==",
+      "optional": true,
+      "dependencies": {
+        "agentkeepalive": "^4.1.3",
+        "cacache": "^15.2.0",
+        "http-cache-semantics": "^4.1.0",
+        "http-proxy-agent": "^4.0.1",
+        "https-proxy-agent": "^5.0.0",
+        "is-lambda": "^1.0.1",
+        "lru-cache": "^6.0.0",
+        "minipass": "^3.1.3",
+        "minipass-collect": "^1.0.2",
+        "minipass-fetch": "^1.3.2",
+        "minipass-flush": "^1.0.5",
+        "minipass-pipeline": "^1.2.4",
+        "negotiator": "^0.6.2",
+        "promise-retry": "^2.0.1",
+        "socks-proxy-agent": "^6.0.0",
+        "ssri": "^8.0.0"
+      },
+      "engines": {
+        "node": ">= 10"
+      }
+    },
     "node_modules/map-obj": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
@@ -4121,82 +4631,124 @@
       }
     },
     "node_modules/minimist": {
-      "version": "1.2.5",
-      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
-      "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
+      "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
     },
     "node_modules/minipass": {
-      "version": "2.9.0",
-      "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz",
-      "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==",
+      "version": "3.3.6",
+      "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+      "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
       "dependencies": {
-        "safe-buffer": "^5.1.2",
-        "yallist": "^3.0.0"
+        "yallist": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
       }
     },
-    "node_modules/minipass/node_modules/safe-buffer": {
-      "version": "5.2.1",
-      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
-      "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ]
+    "node_modules/minipass-collect": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz",
+      "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==",
+      "optional": true,
+      "dependencies": {
+        "minipass": "^3.0.0"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
     },
-    "node_modules/minipass/node_modules/yallist": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
-      "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
+    "node_modules/minipass-fetch": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz",
+      "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==",
+      "optional": true,
+      "dependencies": {
+        "minipass": "^3.1.0",
+        "minipass-sized": "^1.0.3",
+        "minizlib": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "optionalDependencies": {
+        "encoding": "^0.1.12"
+      }
+    },
+    "node_modules/minipass-flush": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
+      "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
+      "optional": true,
+      "dependencies": {
+        "minipass": "^3.0.0"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/minipass-pipeline": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz",
+      "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==",
+      "optional": true,
+      "dependencies": {
+        "minipass": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/minipass-sized": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz",
+      "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==",
+      "optional": true,
+      "dependencies": {
+        "minipass": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
     },
     "node_modules/minizlib": {
-      "version": "1.3.3",
-      "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz",
-      "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==",
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
+      "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
       "dependencies": {
-        "minipass": "^2.9.0"
+        "minipass": "^3.0.0",
+        "yallist": "^4.0.0"
+      },
+      "engines": {
+        "node": ">= 8"
       }
     },
     "node_modules/mkdirp": {
-      "version": "0.5.1",
-      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
-      "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
-      "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)",
+      "version": "0.5.6",
+      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
+      "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
       "dependencies": {
-        "minimist": "0.0.8"
+        "minimist": "^1.2.6"
       },
       "bin": {
         "mkdirp": "bin/cmd.js"
       }
     },
-    "node_modules/mkdirp/node_modules/minimist": {
-      "version": "0.0.8",
-      "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
-      "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
-    },
     "node_modules/ms": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
       "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
     },
     "node_modules/multer": {
-      "version": "1.4.2",
-      "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.2.tgz",
-      "integrity": "sha512-xY8pX7V+ybyUpbYMxtjM9KAiD9ixtg5/JkeKUTD6xilfDv0vzzOFcCp4Ljb1UU3tSOM3VTZtKo63OmzOrGi3Cg==",
+      "version": "1.4.4",
+      "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.4.tgz",
+      "integrity": "sha512-2wY2+xD4udX612aMqMcB8Ws2Voq6NIUPEtD1be6m411T4uDH/VtL9i//xvcyFlTVfRdaBsk7hV5tgrGQqhuBiw==",
+      "deprecated": "Multer 1.x is affected by CVE-2022-24434. This is fixed in v1.4.4-lts.1 which drops support for versions of Node.js before 6. Please upgrade to at least Node.js 6 and version 1.4.4-lts.1 of Multer. If you need support for older versions of Node.js, we are open to accepting patches that would fix the CVE on the main 1.x release line, whilst maintaining compatibility with Node.js 0.10.",
       "dependencies": {
         "append-field": "^1.0.0",
         "busboy": "^0.2.11",
         "concat-stream": "^1.5.2",
-        "mkdirp": "^0.5.1",
+        "mkdirp": "^0.5.4",
         "object-assign": "^4.1.1",
         "on-finished": "^2.3.0",
         "type-is": "^1.6.4",
@@ -4214,27 +4766,6 @@
         "node": ">=0.4"
       }
     },
-    "node_modules/nan": {
-      "version": "2.14.2",
-      "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz",
-      "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ=="
-    },
-    "node_modules/needle": {
-      "version": "2.6.0",
-      "resolved": "https://registry.npmjs.org/needle/-/needle-2.6.0.tgz",
-      "integrity": "sha512-KKYdza4heMsEfSWD7VPUIz3zX2XDwOyX2d+geb4vrERZMT5RMU6ujjaD+I5Yr54uZxQ2w6XRTAhHBbSCyovZBg==",
-      "dependencies": {
-        "debug": "^3.2.6",
-        "iconv-lite": "^0.4.4",
-        "sax": "^1.2.4"
-      },
-      "bin": {
-        "needle": "bin/needle"
-      },
-      "engines": {
-        "node": ">= 4.4.x"
-      }
-    },
     "node_modules/negotiator": {
       "version": "0.6.2",
       "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
@@ -4259,54 +4790,186 @@
         "is-stream": "^1.0.1"
       }
     },
-    "node_modules/node-jsxml": {
-      "version": "0.9.0",
-      "resolved": "https://registry.npmjs.org/node-jsxml/-/node-jsxml-0.9.0.tgz",
-      "integrity": "sha1-Ca5p+9YJnfuGAoHaZv8nkPoAmVQ=",
-      "dev": true,
+    "node_modules/node-gyp": {
+      "version": "8.4.1",
+      "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-8.4.1.tgz",
+      "integrity": "sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==",
+      "optional": true,
+      "dependencies": {
+        "env-paths": "^2.2.0",
+        "glob": "^7.1.4",
+        "graceful-fs": "^4.2.6",
+        "make-fetch-happen": "^9.1.0",
+        "nopt": "^5.0.0",
+        "npmlog": "^6.0.0",
+        "rimraf": "^3.0.2",
+        "semver": "^7.3.5",
+        "tar": "^6.1.2",
+        "which": "^2.0.2"
+      },
+      "bin": {
+        "node-gyp": "bin/node-gyp.js"
+      },
       "engines": {
-        "node": ">=0.1.9"
+        "node": ">= 10.12.0"
       }
     },
-    "node_modules/node-pre-gyp": {
-      "version": "0.11.0",
-      "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz",
-      "integrity": "sha512-TwWAOZb0j7e9eGaf9esRx3ZcLaE5tQ2lvYy1pb5IAaG1a2e2Kv5Lms1Y4hpj+ciXJRofIxxlt5haeQ/2ANeE0Q==",
-      "deprecated": "Please upgrade to @mapbox/node-pre-gyp: the non-scoped node-pre-gyp package is deprecated and only the @mapbox scoped package will recieve updates in the future",
+    "node_modules/node-gyp/node_modules/ansi-regex": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+      "optional": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/node-gyp/node_modules/are-we-there-yet": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz",
+      "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==",
+      "optional": true,
       "dependencies": {
-        "detect-libc": "^1.0.2",
-        "mkdirp": "^0.5.1",
-        "needle": "^2.2.1",
-        "nopt": "^4.0.1",
-        "npm-packlist": "^1.1.6",
-        "npmlog": "^4.0.2",
-        "rc": "^1.2.7",
-        "rimraf": "^2.6.1",
-        "semver": "^5.3.0",
-        "tar": "^4"
+        "delegates": "^1.0.0",
+        "readable-stream": "^3.6.0"
       },
-      "bin": {
-        "node-pre-gyp": "bin/node-pre-gyp"
+      "engines": {
+        "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
       }
     },
-    "node_modules/node-pre-gyp/node_modules/semver": {
-      "version": "5.7.1",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+    "node_modules/node-gyp/node_modules/emoji-regex": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+      "optional": true
+    },
+    "node_modules/node-gyp/node_modules/env-paths": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
+      "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
+      "optional": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/node-gyp/node_modules/gauge": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz",
+      "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==",
+      "optional": true,
+      "dependencies": {
+        "aproba": "^1.0.3 || ^2.0.0",
+        "color-support": "^1.1.3",
+        "console-control-strings": "^1.1.0",
+        "has-unicode": "^2.0.1",
+        "signal-exit": "^3.0.7",
+        "string-width": "^4.2.3",
+        "strip-ansi": "^6.0.1",
+        "wide-align": "^1.1.5"
+      },
+      "engines": {
+        "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+      }
+    },
+    "node_modules/node-gyp/node_modules/is-fullwidth-code-point": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+      "optional": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/node-gyp/node_modules/npmlog": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz",
+      "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==",
+      "optional": true,
+      "dependencies": {
+        "are-we-there-yet": "^3.0.0",
+        "console-control-strings": "^1.1.0",
+        "gauge": "^4.0.3",
+        "set-blocking": "^2.0.0"
+      },
+      "engines": {
+        "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+      }
+    },
+    "node_modules/node-gyp/node_modules/readable-stream": {
+      "version": "3.6.2",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+      "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+      "optional": true,
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "string_decoder": "^1.1.1",
+        "util-deprecate": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/node-gyp/node_modules/semver": {
+      "version": "7.5.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
+      "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
+      "optional": true,
+      "dependencies": {
+        "lru-cache": "^6.0.0"
+      },
       "bin": {
-        "semver": "bin/semver"
+        "semver": "bin/semver.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/node-gyp/node_modules/string-width": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+      "optional": true,
+      "dependencies": {
+        "emoji-regex": "^8.0.0",
+        "is-fullwidth-code-point": "^3.0.0",
+        "strip-ansi": "^6.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/node-gyp/node_modules/strip-ansi": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+      "optional": true,
+      "dependencies": {
+        "ansi-regex": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/node-jsxml": {
+      "version": "0.9.0",
+      "resolved": "https://registry.npmjs.org/node-jsxml/-/node-jsxml-0.9.0.tgz",
+      "integrity": "sha1-Ca5p+9YJnfuGAoHaZv8nkPoAmVQ=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.1.9"
       }
     },
     "node_modules/nopt": {
-      "version": "4.0.3",
-      "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz",
-      "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==",
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
+      "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
       "dependencies": {
-        "abbrev": "1",
-        "osenv": "^0.1.4"
+        "abbrev": "1"
       },
       "bin": {
         "nopt": "bin/nopt.js"
+      },
+      "engines": {
+        "node": ">=6"
       }
     },
     "node_modules/normalize-package-data": {
@@ -4339,38 +5002,15 @@
         "node": ">=8"
       }
     },
-    "node_modules/npm-bundled": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.1.tgz",
-      "integrity": "sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==",
-      "dependencies": {
-        "npm-normalize-package-bin": "^1.0.1"
-      }
-    },
-    "node_modules/npm-normalize-package-bin": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz",
-      "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA=="
-    },
-    "node_modules/npm-packlist": {
-      "version": "1.4.8",
-      "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz",
-      "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==",
-      "dependencies": {
-        "ignore-walk": "^3.0.1",
-        "npm-bundled": "^1.0.1",
-        "npm-normalize-package-bin": "^1.0.1"
-      }
-    },
     "node_modules/npmlog": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
-      "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz",
+      "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==",
       "dependencies": {
-        "are-we-there-yet": "~1.1.2",
-        "console-control-strings": "~1.1.0",
-        "gauge": "~2.7.3",
-        "set-blocking": "~2.0.0"
+        "are-we-there-yet": "^2.0.0",
+        "console-control-strings": "^1.1.0",
+        "gauge": "^3.0.0",
+        "set-blocking": "^2.0.0"
       }
     },
     "node_modules/nugget": {
@@ -4426,9 +5066,9 @@
       }
     },
     "node_modules/object-inspect": {
-      "version": "1.10.3",
-      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz",
-      "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==",
+      "version": "1.12.2",
+      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
+      "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==",
       "funding": {
         "url": "https://github.com/sponsors/ljharb"
       }
@@ -4458,31 +5098,6 @@
         "wrappy": "1"
       }
     },
-    "node_modules/os-homedir": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
-      "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/os-tmpdir": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
-      "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/osenv": {
-      "version": "0.1.5",
-      "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
-      "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
-      "dependencies": {
-        "os-homedir": "^1.0.0",
-        "os-tmpdir": "^1.0.0"
-      }
-    },
     "node_modules/p-cancelable": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz",
@@ -4492,6 +5107,21 @@
         "node": ">=6"
       }
     },
+    "node_modules/p-map": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
+      "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
+      "optional": true,
+      "dependencies": {
+        "aggregate-error": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
     "node_modules/package-json": {
       "version": "6.5.0",
       "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz",
@@ -4528,9 +5158,9 @@
       }
     },
     "node_modules/password-sheriff": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/password-sheriff/-/password-sheriff-1.1.0.tgz",
-      "integrity": "sha1-/bPD2EWgo8kt5CKyrZNGzginFBM="
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/password-sheriff/-/password-sheriff-1.1.1.tgz",
+      "integrity": "sha512-bt0ptyUs97Fb2ZXUcdQP0RYrBFjzO6KhGTjq4RkmR388c6wcT3khG0U7Bvvqwq3DyShEZ9IACed9JMVyAxdaCA=="
     },
     "node_modules/path-exists": {
       "version": "3.0.0",
@@ -4626,15 +5256,13 @@
       }
     },
     "node_modules/plist": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.2.tgz",
-      "integrity": "sha512-MSrkwZBdQ6YapHy87/8hDU8MnIcyxBKjeF+McXnr5A9MtffPewTs7G3hlpodT5TacyfIyFTaJEhh3GGcmasTgQ==",
+      "version": "3.0.5",
+      "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.5.tgz",
+      "integrity": "sha512-83vX4eYdQp3vP9SxuYgEM/G/pJQqLUz/V/xzPrzruLs7fz7jxGQ1msZ/mg1nwZxUSuOp4sb+/bEIbRrbzZRxDA==",
       "dev": true,
-      "optional": true,
       "dependencies": {
         "base64-js": "^1.5.1",
-        "xmlbuilder": "^9.0.7",
-        "xmldom": "^0.5.0"
+        "xmlbuilder": "^9.0.7"
       },
       "engines": {
         "node": ">=6"
@@ -4643,9 +5271,8 @@
     "node_modules/plist/node_modules/xmlbuilder": {
       "version": "9.0.7",
       "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
-      "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=",
+      "integrity": "sha512-7YXTQc3P2l9+0rjaUbLwMKRhtmwg1M1eDf6nag7urC7pIPYLD9W/jmzQ4ptRSUbodw5S0jfoGTflLemQibSpeQ==",
       "dev": true,
-      "optional": true,
       "engines": {
         "node": ">=4.0"
       }
@@ -4709,14 +5336,33 @@
         "asap": "~2.0.3"
       }
     },
+    "node_modules/promise-inflight": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
+      "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==",
+      "optional": true
+    },
+    "node_modules/promise-retry": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz",
+      "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==",
+      "optional": true,
+      "dependencies": {
+        "err-code": "^2.0.2",
+        "retry": "^0.12.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
     "node_modules/prop-types": {
-      "version": "15.7.2",
-      "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz",
-      "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==",
+      "version": "15.8.1",
+      "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
+      "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
       "dependencies": {
         "loose-envify": "^1.4.0",
         "object-assign": "^4.1.1",
-        "react-is": "^16.8.1"
+        "react-is": "^16.13.1"
       }
     },
     "node_modules/proxy-addr": {
@@ -4779,9 +5425,9 @@
       }
     },
     "node_modules/qs": {
-      "version": "6.10.1",
-      "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz",
-      "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==",
+      "version": "6.10.5",
+      "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.5.tgz",
+      "integrity": "sha512-O5RlPh0VFtR78y79rgcgKK4wbAI0C5zGVLztOIdpWX6ep368q5Hv6XRxDvXuZ9q3C6v+e3n8UfZZJw7IIG27eQ==",
       "dependencies": {
         "side-channel": "^1.0.4"
       },
@@ -4818,6 +5464,7 @@
       "version": "1.2.8",
       "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
       "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
+      "dev": true,
       "dependencies": {
         "deep-extend": "^0.6.0",
         "ini": "~1.3.0",
@@ -5095,15 +5742,27 @@
         "lowercase-keys": "^1.0.0"
       }
     },
+    "node_modules/retry": {
+      "version": "0.12.0",
+      "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
+      "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==",
+      "optional": true,
+      "engines": {
+        "node": ">= 4"
+      }
+    },
     "node_modules/rimraf": {
-      "version": "2.7.1",
-      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
-      "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+      "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
       "dependencies": {
         "glob": "^7.1.3"
       },
       "bin": {
         "rimraf": "bin.js"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
       }
     },
     "node_modules/safe-buffer": {
@@ -5208,7 +5867,7 @@
     "node_modules/set-blocking": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
-      "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
+      "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="
     },
     "node_modules/setimmediate": {
       "version": "1.0.5",
@@ -5255,9 +5914,9 @@
       }
     },
     "node_modules/signal-exit": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
-      "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
+      "version": "3.0.7",
+      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+      "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
     },
     "node_modules/single-line-log": {
       "version": "1.1.2",
@@ -5269,39 +5928,91 @@
       }
     },
     "node_modules/slice-ansi": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz",
-      "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==",
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz",
+      "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==",
       "dev": true,
       "optional": true,
       "dependencies": {
-        "is-fullwidth-code-point": "^2.0.0"
+        "ansi-styles": "^4.0.0",
+        "astral-regex": "^2.0.0",
+        "is-fullwidth-code-point": "^3.0.0"
       },
       "engines": {
-        "node": ">=4"
+        "node": ">=8"
       }
     },
     "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
-      "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
       "dev": true,
       "optional": true,
       "engines": {
-        "node": ">=4"
+        "node": ">=8"
       }
     },
     "node_modules/smart-buffer": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.1.0.tgz",
-      "integrity": "sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw==",
-      "dev": true,
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
+      "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
       "optional": true,
       "engines": {
         "node": ">= 6.0.0",
         "npm": ">= 3.0.0"
       }
     },
+    "node_modules/socks": {
+      "version": "2.7.1",
+      "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz",
+      "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==",
+      "optional": true,
+      "dependencies": {
+        "ip": "^2.0.0",
+        "smart-buffer": "^4.2.0"
+      },
+      "engines": {
+        "node": ">= 10.13.0",
+        "npm": ">= 3.0.0"
+      }
+    },
+    "node_modules/socks-proxy-agent": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz",
+      "integrity": "sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==",
+      "optional": true,
+      "dependencies": {
+        "agent-base": "^6.0.2",
+        "debug": "^4.3.3",
+        "socks": "^2.6.2"
+      },
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/socks-proxy-agent/node_modules/debug": {
+      "version": "4.3.4",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+      "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+      "optional": true,
+      "dependencies": {
+        "ms": "2.1.2"
+      },
+      "engines": {
+        "node": ">=6.0"
+      },
+      "peerDependenciesMeta": {
+        "supports-color": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/socks-proxy-agent/node_modules/ms": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+      "optional": true
+    },
     "node_modules/source-map": {
       "version": "0.6.1",
       "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@@ -5312,9 +6023,9 @@
       }
     },
     "node_modules/source-map-support": {
-      "version": "0.5.19",
-      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
-      "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
+      "version": "0.5.21",
+      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
+      "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
       "dev": true,
       "dependencies": {
         "buffer-from": "^1.0.0",
@@ -5360,15 +6071,32 @@
       "dev": true
     },
     "node_modules/sqlite3": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-4.2.0.tgz",
-      "integrity": "sha512-roEOz41hxui2Q7uYnWsjMOTry6TcNUNmp8audCx18gF10P2NknwdpF+E+HKvz/F2NvPKGGBF4NGc+ZPQ+AABwg==",
+      "version": "5.1.6",
+      "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.1.6.tgz",
+      "integrity": "sha512-olYkWoKFVNSSSQNvxVUfjiVbz3YtBwTJj+mfV5zpHmqW3sELx2Cf4QCdirMelhM5Zh+KDVaKgQHqCxrqiWHybw==",
       "hasInstallScript": true,
       "dependencies": {
-        "nan": "^2.12.1",
-        "node-pre-gyp": "^0.11.0"
+        "@mapbox/node-pre-gyp": "^1.0.0",
+        "node-addon-api": "^4.2.0",
+        "tar": "^6.1.11"
+      },
+      "optionalDependencies": {
+        "node-gyp": "8.x"
+      },
+      "peerDependencies": {
+        "node-gyp": "8.x"
+      },
+      "peerDependenciesMeta": {
+        "node-gyp": {
+          "optional": true
+        }
       }
     },
+    "node_modules/sqlite3/node_modules/node-addon-api": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz",
+      "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ=="
+    },
     "node_modules/ssf": {
       "version": "0.10.3",
       "resolved": "https://registry.npmjs.org/ssf/-/ssf-0.10.3.tgz",
@@ -5414,6 +6142,18 @@
       "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
       "dev": true
     },
+    "node_modules/ssri": {
+      "version": "8.0.1",
+      "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz",
+      "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==",
+      "optional": true,
+      "dependencies": {
+        "minipass": "^3.1.1"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
     "node_modules/stat-mode": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-1.0.0.tgz",
@@ -5502,6 +6242,7 @@
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
       "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
+      "dev": true,
       "engines": {
         "node": ">=0.10.0"
       }
@@ -5531,6 +6272,7 @@
       "version": "5.3.1",
       "resolved": "https://registry.npmjs.org/superagent/-/superagent-5.3.1.tgz",
       "integrity": "sha512-wjJ/MoTid2/RuGCOFtlacyGNxN9QLMgcpYLDQlWFIhhdJ93kNscFonGvrpAHSCVjRVj++DGCglocF7Aej1KHvQ==",
+      "deprecated": "Please upgrade to v7.0.2+ of superagent.  We have fixed numerous issues with streams, form-data, attach(), filesystem errors not bubbling up (ENOENT on attach()), and all tests are now passing.  See the releases tab for more information at <https://github.com/visionmedia/superagent/releases>.",
       "dependencies": {
         "component-emitter": "^1.3.0",
         "cookiejar": "^2.1.2",
@@ -5549,9 +6291,9 @@
       }
     },
     "node_modules/superagent/node_modules/debug": {
-      "version": "4.3.1",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
-      "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+      "version": "4.3.4",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+      "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
       "dependencies": {
         "ms": "2.1.2"
       },
@@ -5564,10 +6306,23 @@
         }
       }
     },
+    "node_modules/superagent/node_modules/form-data": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
+      "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
+      "dependencies": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.8",
+        "mime-types": "^2.1.12"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
     "node_modules/superagent/node_modules/mime": {
-      "version": "2.5.2",
-      "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz",
-      "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==",
+      "version": "2.6.0",
+      "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
+      "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
       "bin": {
         "mime": "cli.js"
       },
@@ -5594,9 +6349,9 @@
       }
     },
     "node_modules/superagent/node_modules/semver": {
-      "version": "7.3.5",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
-      "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+      "version": "7.3.7",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
+      "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
       "dependencies": {
         "lru-cache": "^6.0.0"
       },
@@ -5635,45 +6390,39 @@
       }
     },
     "node_modules/tar": {
-      "version": "4.4.13",
-      "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz",
-      "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==",
-      "dependencies": {
-        "chownr": "^1.1.1",
-        "fs-minipass": "^1.2.5",
-        "minipass": "^2.8.6",
-        "minizlib": "^1.2.1",
-        "mkdirp": "^0.5.0",
-        "safe-buffer": "^5.1.2",
-        "yallist": "^3.0.3"
+      "version": "6.1.15",
+      "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.15.tgz",
+      "integrity": "sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==",
+      "dependencies": {
+        "chownr": "^2.0.0",
+        "fs-minipass": "^2.0.0",
+        "minipass": "^5.0.0",
+        "minizlib": "^2.1.1",
+        "mkdirp": "^1.0.3",
+        "yallist": "^4.0.0"
       },
       "engines": {
-        "node": ">=4.5"
+        "node": ">=10"
       }
     },
-    "node_modules/tar/node_modules/safe-buffer": {
-      "version": "5.2.1",
-      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
-      "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ]
+    "node_modules/tar/node_modules/minipass": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
+      "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
+      "engines": {
+        "node": ">=8"
+      }
     },
-    "node_modules/tar/node_modules/yallist": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
-      "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
+    "node_modules/tar/node_modules/mkdirp": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+      "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+      "bin": {
+        "mkdirp": "bin/cmd.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
     },
     "node_modules/temp-file": {
       "version": "3.4.0",
@@ -5686,9 +6435,9 @@
       }
     },
     "node_modules/temp-file/node_modules/fs-extra": {
-      "version": "10.0.0",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz",
-      "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==",
+      "version": "10.1.0",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
+      "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
       "dev": true,
       "dependencies": {
         "graceful-fs": "^4.2.0",
@@ -5773,29 +6522,14 @@
       }
     },
     "node_modules/tmp-promise": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.2.tgz",
-      "integrity": "sha512-OyCLAKU1HzBjL6Ev3gxUeraJNlbNingmi8IrHHEsYH8LTmEuhvYfqvhn2F/je+mjf4N58UmZ96OMEy1JanSCpA==",
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz",
+      "integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==",
       "dev": true,
       "dependencies": {
         "tmp": "^0.2.0"
       }
     },
-    "node_modules/tmp/node_modules/rimraf": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
-      "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
-      "dev": true,
-      "dependencies": {
-        "glob": "^7.1.3"
-      },
-      "bin": {
-        "rimraf": "bin.js"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
     "node_modules/to-readable-stream": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz",
@@ -5826,10 +6560,15 @@
         "node": ">=0.8"
       }
     },
+    "node_modules/tr46": {
+      "version": "0.0.3",
+      "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+      "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
+    },
     "node_modules/trim": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/trim/-/trim-1.0.0.tgz",
-      "integrity": "sha512-UgtES1lYpE+f4WiGY5lyJlHchuGhTa/xMPH96g/B7gc+pEQPiL41s6ECm7Ky3hkhARG/u1SHGFcleJodAvQOKQ=="
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/trim/-/trim-1.0.1.tgz",
+      "integrity": "sha512-3JVP2YVqITUisXblCDq/Bi4P9457G/sdEamInkyvCsjbTcXLXIiG7XCb4kGMFWh6JGXesS3TKxOPtrncN/xe8w=="
     },
     "node_modules/trim-newlines": {
       "version": "1.0.0",
@@ -5843,7 +6582,7 @@
     "node_modules/truncate-utf8-bytes": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz",
-      "integrity": "sha1-QFkjkJWS1W94pYGENLC3hInKXys=",
+      "integrity": "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==",
       "dev": true,
       "dependencies": {
         "utf8-byte-length": "^1.0.1"
@@ -5928,6 +6667,24 @@
       "resolved": "https://registry.npmjs.org/unfetch/-/unfetch-4.2.0.tgz",
       "integrity": "sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA=="
     },
+    "node_modules/unique-filename": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz",
+      "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==",
+      "optional": true,
+      "dependencies": {
+        "unique-slug": "^2.0.0"
+      }
+    },
+    "node_modules/unique-slug": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz",
+      "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==",
+      "optional": true,
+      "dependencies": {
+        "imurmurhash": "^0.1.4"
+      }
+    },
     "node_modules/unique-string": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz",
@@ -6056,7 +6813,7 @@
     "node_modules/utf8-byte-length": {
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz",
-      "integrity": "sha1-9F8VDExm7uloGGUFq5P8u4rWv2E=",
+      "integrity": "sha512-4+wkEYLBbWxqTahEsWrhxepcoVOJ+1z5PGIjPZxRkytcdSUaNjIjBM7Xn8E+pdSuV7SzvWovBFA54FO0JSoqhA==",
       "dev": true
     },
     "node_modules/util-deprecate": {
@@ -6122,16 +6879,30 @@
         "extsprintf": "^1.2.0"
       }
     },
+    "node_modules/webidl-conversions": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+      "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
+    },
     "node_modules/whatwg-fetch": {
       "version": "3.6.2",
       "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz",
       "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA=="
     },
+    "node_modules/whatwg-url": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+      "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+      "dependencies": {
+        "tr46": "~0.0.3",
+        "webidl-conversions": "^3.0.0"
+      }
+    },
     "node_modules/which": {
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
       "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
-      "dev": true,
+      "devOptional": true,
       "dependencies": {
         "isexe": "^2.0.0"
       },
@@ -6143,11 +6914,11 @@
       }
     },
     "node_modules/wide-align": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
-      "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
+      "version": "1.1.5",
+      "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
+      "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
       "dependencies": {
-        "string-width": "^1.0.2 || 2"
+        "string-width": "^1.0.2 || 2 || 3 || 4"
       }
     },
     "node_modules/widest-line": {
@@ -6349,16 +7120,6 @@
         "node": ">=8.0"
       }
     },
-    "node_modules/xmldom": {
-      "version": "0.5.0",
-      "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.5.0.tgz",
-      "integrity": "sha512-Foaj5FXVzgn7xFzsKeNIde9g6aFBxTPi37iwsno8QvApmtg7KYrr+OPyRHcJF7dud2a5nGRBXK3n0dL62Gf7PA==",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">=10.0.0"
-      }
-    },
     "node_modules/xtend": {
       "version": "2.1.2",
       "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz",
@@ -6475,9 +7236,9 @@
   },
   "dependencies": {
     "@babel/runtime": {
-      "version": "7.15.4",
-      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.4.tgz",
-      "integrity": "sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==",
+      "version": "7.14.0",
+      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.0.tgz",
+      "integrity": "sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA==",
       "requires": {
         "regenerator-runtime": "^0.13.4"
       }
@@ -6506,9 +7267,9 @@
       },
       "dependencies": {
         "debug": {
-          "version": "4.3.2",
-          "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
-          "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+          "version": "4.3.4",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+          "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
           "dev": true,
           "requires": {
             "ms": "2.1.2"
@@ -6550,6 +7311,12 @@
         }
       }
     },
+    "@gar/promisify": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz",
+      "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==",
+      "optional": true
+    },
     "@malept/cross-spawn-promise": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz",
@@ -6572,9 +7339,9 @@
       },
       "dependencies": {
         "debug": {
-          "version": "4.3.2",
-          "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
-          "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+          "version": "4.3.4",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+          "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
           "dev": true,
           "requires": {
             "ms": "2.1.2"
@@ -6601,18 +7368,91 @@
             "graceful-fs": "^4.1.6",
             "universalify": "^2.0.0"
           }
-        },
-        "ms": {
-          "version": "2.1.2",
-          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
-          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
-          "dev": true
-        },
-        "universalify": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
-          "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
-          "dev": true
+        },
+        "ms": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+          "dev": true
+        },
+        "universalify": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
+          "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
+          "dev": true
+        }
+      }
+    },
+    "@mapbox/node-pre-gyp": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz",
+      "integrity": "sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA==",
+      "requires": {
+        "detect-libc": "^2.0.0",
+        "https-proxy-agent": "^5.0.0",
+        "make-dir": "^3.1.0",
+        "node-fetch": "^2.6.7",
+        "nopt": "^5.0.0",
+        "npmlog": "^5.0.1",
+        "rimraf": "^3.0.2",
+        "semver": "^7.3.5",
+        "tar": "^6.1.11"
+      },
+      "dependencies": {
+        "node-fetch": {
+          "version": "2.6.11",
+          "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz",
+          "integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==",
+          "requires": {
+            "whatwg-url": "^5.0.0"
+          }
+        },
+        "semver": {
+          "version": "7.5.1",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
+          "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
+          "requires": {
+            "lru-cache": "^6.0.0"
+          }
+        }
+      }
+    },
+    "@npmcli/fs": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz",
+      "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==",
+      "optional": true,
+      "requires": {
+        "@gar/promisify": "^1.0.1",
+        "semver": "^7.3.5"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "7.5.1",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
+          "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
+          "optional": true,
+          "requires": {
+            "lru-cache": "^6.0.0"
+          }
+        }
+      }
+    },
+    "@npmcli/move-file": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz",
+      "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==",
+      "optional": true,
+      "requires": {
+        "mkdirp": "^1.0.4",
+        "rimraf": "^3.0.2"
+      },
+      "dependencies": {
+        "mkdirp": {
+          "version": "1.0.4",
+          "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+          "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+          "optional": true
         }
       }
     },
@@ -6710,9 +7550,9 @@
       }
     },
     "@types/glob": {
-      "version": "7.1.4",
-      "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.4.tgz",
-      "integrity": "sha512-w+LsMxKyYQm347Otw+IfBXOv9UWVjpHpCDdbBMt8Kz/xbvCYNjP+0qPh91Km3iKfSRLBB0P7fAMf0KHrPu+MyA==",
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz",
+      "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==",
       "dev": true,
       "optional": true,
       "requires": {
@@ -6752,15 +7592,6 @@
       "requires": {
         "@types/node": "*",
         "xmlbuilder": ">=11.0.1"
-      },
-      "dependencies": {
-        "xmlbuilder": {
-          "version": "15.1.1",
-          "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz",
-          "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==",
-          "dev": true,
-          "optional": true
-        }
       }
     },
     "@types/qs": {
@@ -6795,18 +7626,18 @@
       "optional": true
     },
     "@types/yargs": {
-      "version": "17.0.4",
-      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.4.tgz",
-      "integrity": "sha512-D/wihO9WFYqwsmJI0e0qS+U09wIQtYRSBJlXWjTFGjouEuOCy0BU4N/ZK5utb00S5lW/9LO7vOpvGDd8M06NvQ==",
+      "version": "17.0.10",
+      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz",
+      "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==",
       "dev": true,
       "requires": {
         "@types/yargs-parser": "*"
       }
     },
     "@types/yargs-parser": {
-      "version": "20.2.1",
-      "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz",
-      "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==",
+      "version": "21.0.0",
+      "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz",
+      "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==",
       "dev": true
     },
     "7zip-bin": {
@@ -6861,6 +7692,58 @@
         }
       }
     },
+    "agentkeepalive": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.3.0.tgz",
+      "integrity": "sha512-7Epl1Blf4Sy37j4v9f9FjICCh4+KAQOyXgHEwlyBiAQLbhKdq/i2QQU3amQalS/wPhdPzDXPL5DMR5bkn+YeWg==",
+      "optional": true,
+      "requires": {
+        "debug": "^4.1.0",
+        "depd": "^2.0.0",
+        "humanize-ms": "^1.2.1"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "4.3.4",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+          "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+          "optional": true,
+          "requires": {
+            "ms": "2.1.2"
+          }
+        },
+        "depd": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+          "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+          "optional": true
+        },
+        "ms": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+          "optional": true
+        }
+      }
+    },
+    "aggregate-error": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
+      "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
+      "optional": true,
+      "requires": {
+        "clean-stack": "^2.0.0",
+        "indent-string": "^4.0.0"
+      },
+      "dependencies": {
+        "indent-string": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+          "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
+          "optional": true
+        }
+      }
+    },
     "ajv": {
       "version": "6.12.6",
       "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
@@ -6881,44 +7764,44 @@
       "requires": {}
     },
     "ansi-align": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz",
-      "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==",
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz",
+      "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==",
       "dev": true,
       "requires": {
-        "string-width": "^4.1.0"
+        "string-width": "^3.0.0"
       },
       "dependencies": {
         "ansi-regex": {
-          "version": "5.0.1",
-          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
-          "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+          "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
           "dev": true
         },
         "is-fullwidth-code-point": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
-          "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+          "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
           "dev": true
         },
         "string-width": {
-          "version": "4.2.3",
-          "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
-          "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+          "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
           "dev": true,
           "requires": {
-            "emoji-regex": "^8.0.0",
-            "is-fullwidth-code-point": "^3.0.0",
-            "strip-ansi": "^6.0.1"
+            "emoji-regex": "^7.0.1",
+            "is-fullwidth-code-point": "^2.0.0",
+            "strip-ansi": "^5.1.0"
           }
         },
         "strip-ansi": {
-          "version": "6.0.1",
-          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
-          "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+          "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
           "dev": true,
           "requires": {
-            "ansi-regex": "^5.0.1"
+            "ansi-regex": "^4.1.0"
           }
         }
       }
@@ -6944,9 +7827,9 @@
       "dev": true
     },
     "app-builder-lib": {
-      "version": "22.13.1",
-      "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-22.13.1.tgz",
-      "integrity": "sha512-TsUe7gCdH1cnSknUcqwVRAAxsFxsxcU/BJvnKR8ASzjaZtePW7MU+AEaDVDUURycgYxQ9XeymGjmuQGS32jcbw==",
+      "version": "22.14.13",
+      "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-22.14.13.tgz",
+      "integrity": "sha512-SufmrtxU+D0Tn948fjEwAOlCN9757UXLkzzTWXMwZKR/5hisvgqeeBepWfphMIE6OkDGz0fbzEhL1P2Pty4XMg==",
       "dev": true,
       "requires": {
         "@develar/schema-utils": "~2.6.5",
@@ -6955,13 +7838,14 @@
         "7zip-bin": "~5.1.1",
         "async-exit-hook": "^2.0.1",
         "bluebird-lst": "^1.0.9",
-        "builder-util": "22.13.1",
-        "builder-util-runtime": "8.8.1",
+        "builder-util": "22.14.13",
+        "builder-util-runtime": "8.9.2",
         "chromium-pickle-js": "^0.2.0",
         "debug": "^4.3.2",
         "ejs": "^3.1.6",
         "electron-osx-sign": "^0.5.0",
-        "electron-publish": "22.13.1",
+        "electron-publish": "22.14.13",
+        "form-data": "^4.0.0",
         "fs-extra": "^10.0.0",
         "hosted-git-info": "^4.0.2",
         "is-ci": "^3.0.0",
@@ -6976,9 +7860,9 @@
       },
       "dependencies": {
         "builder-util-runtime": {
-          "version": "8.8.1",
-          "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.8.1.tgz",
-          "integrity": "sha512-xHxAzdsJmMV8m/N+INzYUKfyJASeKyKHnA1uGkY8Y8JKLI/c4BG+If+L0If2YETv96CiRASkvd02tIt2pvrchQ==",
+          "version": "8.9.2",
+          "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.9.2.tgz",
+          "integrity": "sha512-rhuKm5vh7E0aAmT6i8aoSfEjxzdYEFX7zDApK+eNgOhjofnWb74d9SRJv0H/8nsgOkos0TZ4zxW0P8J4N7xQ2A==",
           "dev": true,
           "requires": {
             "debug": "^4.3.2",
@@ -6986,18 +7870,18 @@
           }
         },
         "debug": {
-          "version": "4.3.2",
-          "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
-          "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+          "version": "4.3.4",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+          "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
           "dev": true,
           "requires": {
             "ms": "2.1.2"
           }
         },
         "fs-extra": {
-          "version": "10.0.0",
-          "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz",
-          "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==",
+          "version": "10.1.0",
+          "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
+          "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
           "dev": true,
           "requires": {
             "graceful-fs": "^4.2.0",
@@ -7006,9 +7890,9 @@
           }
         },
         "hosted-git-info": {
-          "version": "4.0.2",
-          "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz",
-          "integrity": "sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==",
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
+          "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==",
           "dev": true,
           "requires": {
             "lru-cache": "^6.0.0"
@@ -7024,12 +7908,6 @@
             "universalify": "^2.0.0"
           }
         },
-        "lazy-val": {
-          "version": "1.0.5",
-          "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz",
-          "integrity": "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==",
-          "dev": true
-        },
         "ms": {
           "version": "2.1.2",
           "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -7037,9 +7915,9 @@
           "dev": true
         },
         "semver": {
-          "version": "7.3.5",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
-          "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+          "version": "7.3.7",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
+          "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
           "dev": true,
           "requires": {
             "lru-cache": "^6.0.0"
@@ -7059,17 +7937,29 @@
       "integrity": "sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY="
     },
     "aproba": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
-      "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw=="
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz",
+      "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ=="
     },
     "are-we-there-yet": {
-      "version": "1.1.5",
-      "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
-      "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz",
+      "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==",
       "requires": {
         "delegates": "^1.0.0",
-        "readable-stream": "^2.0.6"
+        "readable-stream": "^3.6.0"
+      },
+      "dependencies": {
+        "readable-stream": {
+          "version": "3.6.2",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+          "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+          "requires": {
+            "inherits": "^2.0.3",
+            "string_decoder": "^1.1.1",
+            "util-deprecate": "^1.0.1"
+          }
+        }
       }
     },
     "argparse": {
@@ -7129,6 +8019,13 @@
       "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
       "dev": true
     },
+    "astral-regex": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
+      "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
+      "dev": true,
+      "optional": true
+    },
     "async": {
       "version": "1.5.2",
       "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
@@ -7152,9 +8049,9 @@
       "dev": true
     },
     "auth0-js": {
-      "version": "9.17.0",
-      "resolved": "https://registry.npmjs.org/auth0-js/-/auth0-js-9.17.0.tgz",
-      "integrity": "sha512-rqHhOq6ZgOaHwz0e46YywsGW4Y2wLF3Fu+y2wT94vbEFNAi5vyJHJYVyNAetAN7w7Ljhda/7SsUs/usuEMRBpQ==",
+      "version": "9.19.0",
+      "resolved": "https://registry.npmjs.org/auth0-js/-/auth0-js-9.19.0.tgz",
+      "integrity": "sha512-PbzzGqtcfUZj3jnPqEcJYoWH+YNMmHI9woRYBY1VZn+GaU5NIWR1H/2ZAx5ZERZXvte6qQsu2FDNB8V+1N9Ahg==",
       "requires": {
         "base64-js": "^1.5.1",
         "idtoken-verifier": "^2.2.2",
@@ -7173,27 +8070,37 @@
       }
     },
     "auth0-lock": {
-      "version": "11.31.0",
-      "resolved": "https://registry.npmjs.org/auth0-lock/-/auth0-lock-11.31.0.tgz",
-      "integrity": "sha512-UwKeqIK3syTyGz3/r9MNsH1BFIp0gw4ioXw+27Fw5OwApoyOFI91/MMWoKRabQa22pNAmOYtmRCgiACQ23pMpQ==",
+      "version": "11.33.1",
+      "resolved": "https://registry.npmjs.org/auth0-lock/-/auth0-lock-11.33.1.tgz",
+      "integrity": "sha512-eKQtN8GjO25vyYVUzJ7BEHZDZLcA3aj3CN8OeGcmC7/gZe41nkGTSiVO8BTMMvjUQ8zA6S9znFla/AkXslAsYw==",
       "requires": {
-        "auth0-js": "^9.16.4",
+        "auth0-js": "^9.19.0",
         "auth0-password-policies": "^1.0.2",
-        "blueimp-md5": "^2.18.0",
+        "blueimp-md5": "^2.19.0",
         "classnames": "^2.3.1",
-        "dompurify": "^2.2.8",
+        "dompurify": "^2.3.7",
         "immutable": "^3.7.3",
         "jsonp": "^0.2.1",
-        "node-fetch": "^2.6.1",
+        "node-fetch": "^2.6.7",
         "password-sheriff": "^1.1.1",
-        "prop-types": "^15.6.0",
-        "qs": "^6.7.0",
+        "prop-types": "^15.8.0",
+        "qs": "^6.10.3",
         "react": "^15.6.2",
         "react-dom": "^15.6.2",
         "react-transition-group": "^2.2.1",
         "trim": "^1.0.1",
         "url-join": "^1.1.0",
         "validator": "^13.6.0"
+      },
+      "dependencies": {
+        "node-fetch": {
+          "version": "2.6.7",
+          "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
+          "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
+          "requires": {
+            "whatwg-url": "^5.0.0"
+          }
+        }
       }
     },
     "auth0-password-policies": {
@@ -7296,25 +8203,25 @@
       }
     },
     "boxen": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz",
-      "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==",
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.0.1.tgz",
+      "integrity": "sha512-49VBlw+PrWEF51aCmy7QIteYPIFZxSpvqBdP/2itCPPlJ49kj9zg/XPRFrdkne2W+CfwXUls8exMvu1RysZpKA==",
       "dev": true,
       "requires": {
         "ansi-align": "^3.0.0",
         "camelcase": "^6.2.0",
         "chalk": "^4.1.0",
         "cli-boxes": "^2.2.1",
-        "string-width": "^4.2.2",
+        "string-width": "^4.2.0",
         "type-fest": "^0.20.2",
         "widest-line": "^3.1.0",
         "wrap-ansi": "^7.0.0"
       },
       "dependencies": {
         "ansi-regex": {
-          "version": "5.0.1",
-          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
-          "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+          "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
           "dev": true
         },
         "camelcase": {
@@ -7323,6 +8230,12 @@
           "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==",
           "dev": true
         },
+        "emoji-regex": {
+          "version": "8.0.0",
+          "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+          "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+          "dev": true
+        },
         "is-fullwidth-code-point": {
           "version": "3.0.0",
           "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
@@ -7330,23 +8243,23 @@
           "dev": true
         },
         "string-width": {
-          "version": "4.2.3",
-          "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
-          "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+          "version": "4.2.2",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
+          "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==",
           "dev": true,
           "requires": {
             "emoji-regex": "^8.0.0",
             "is-fullwidth-code-point": "^3.0.0",
-            "strip-ansi": "^6.0.1"
+            "strip-ansi": "^6.0.0"
           }
         },
         "strip-ansi": {
-          "version": "6.0.1",
-          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
-          "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+          "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
           "dev": true,
           "requires": {
-            "ansi-regex": "^5.0.1"
+            "ansi-regex": "^5.0.0"
           }
         }
       }
@@ -7396,7 +8309,7 @@
     "buffer-equal": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz",
-      "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=",
+      "integrity": "sha512-tcBWO2Dl4e7Asr9hTGcpVrCe+F7DubpmqWCTbj4FHLmjqO2hIaC383acQubWtRJhdceqs5uBHs6Es+Sk//RKiQ==",
       "dev": true
     },
     "buffer-equal-constant-time": {
@@ -7407,7 +8320,7 @@
     "buffer-fill": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz",
-      "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=",
+      "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==",
       "dev": true
     },
     "buffer-from": {
@@ -7421,21 +8334,23 @@
       "integrity": "sha1-83FR2DzYLZCtyvHAUSj2NYM4374="
     },
     "builder-util": {
-      "version": "22.13.1",
-      "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-22.13.1.tgz",
-      "integrity": "sha512-gMdoW9aQbWYxuQ4k4jT4An1BTo/hWzvsdv3pwNz18iNYnqn9j+xMllQOg9CHgfQYKSUd8VuMsZnbCvLO4NltYw==",
+      "version": "22.14.13",
+      "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-22.14.13.tgz",
+      "integrity": "sha512-oePC/qrrUuerhmH5iaCJzPRAKlSBylrhzuAJmRQClTyWnZUv6jbaHh+VoHMbEiE661wrj2S2aV7/bQh12cj1OA==",
       "dev": true,
       "requires": {
-        "@types/debug": "^4.1.5",
+        "@types/debug": "^4.1.6",
         "@types/fs-extra": "^9.0.11",
         "7zip-bin": "~5.1.1",
-        "app-builder-bin": "3.5.13",
+        "app-builder-bin": "3.7.1",
         "bluebird-lst": "^1.0.9",
-        "builder-util-runtime": "8.8.1",
+        "builder-util-runtime": "8.9.2",
         "chalk": "^4.1.1",
         "cross-spawn": "^7.0.3",
         "debug": "^4.3.2",
         "fs-extra": "^10.0.0",
+        "http-proxy-agent": "^5.0.0",
+        "https-proxy-agent": "^5.0.0",
         "is-ci": "^3.0.0",
         "js-yaml": "^4.1.0",
         "source-map-support": "^0.5.19",
@@ -7443,10 +8358,16 @@
         "temp-file": "^3.4.0"
       },
       "dependencies": {
+        "@tootallnate/once": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
+          "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==",
+          "dev": true
+        },
         "builder-util-runtime": {
-          "version": "8.8.1",
-          "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.8.1.tgz",
-          "integrity": "sha512-xHxAzdsJmMV8m/N+INzYUKfyJASeKyKHnA1uGkY8Y8JKLI/c4BG+If+L0If2YETv96CiRASkvd02tIt2pvrchQ==",
+          "version": "8.9.2",
+          "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.9.2.tgz",
+          "integrity": "sha512-rhuKm5vh7E0aAmT6i8aoSfEjxzdYEFX7zDApK+eNgOhjofnWb74d9SRJv0H/8nsgOkos0TZ4zxW0P8J4N7xQ2A==",
           "dev": true,
           "requires": {
             "debug": "^4.3.2",
@@ -7454,18 +8375,18 @@
           }
         },
         "debug": {
-          "version": "4.3.2",
-          "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
-          "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+          "version": "4.3.4",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+          "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
           "dev": true,
           "requires": {
             "ms": "2.1.2"
           }
         },
         "fs-extra": {
-          "version": "10.0.0",
-          "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz",
-          "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==",
+          "version": "10.1.0",
+          "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
+          "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
           "dev": true,
           "requires": {
             "graceful-fs": "^4.2.0",
@@ -7473,6 +8394,17 @@
             "universalify": "^2.0.0"
           }
         },
+        "http-proxy-agent": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
+          "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==",
+          "dev": true,
+          "requires": {
+            "@tootallnate/once": "2",
+            "agent-base": "6",
+            "debug": "4"
+          }
+        },
         "jsonfile": {
           "version": "6.1.0",
           "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
@@ -7558,6 +8490,40 @@
       "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
       "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg=="
     },
+    "cacache": {
+      "version": "15.3.0",
+      "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz",
+      "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==",
+      "optional": true,
+      "requires": {
+        "@npmcli/fs": "^1.0.0",
+        "@npmcli/move-file": "^1.0.1",
+        "chownr": "^2.0.0",
+        "fs-minipass": "^2.0.0",
+        "glob": "^7.1.4",
+        "infer-owner": "^1.0.4",
+        "lru-cache": "^6.0.0",
+        "minipass": "^3.1.1",
+        "minipass-collect": "^1.0.2",
+        "minipass-flush": "^1.0.5",
+        "minipass-pipeline": "^1.2.2",
+        "mkdirp": "^1.0.3",
+        "p-map": "^4.0.0",
+        "promise-inflight": "^1.0.1",
+        "rimraf": "^3.0.2",
+        "ssri": "^8.0.1",
+        "tar": "^6.0.2",
+        "unique-filename": "^1.1.1"
+      },
+      "dependencies": {
+        "mkdirp": {
+          "version": "1.0.4",
+          "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+          "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+          "optional": true
+        }
+      }
+    },
     "cacheable-request": {
       "version": "6.1.0",
       "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz",
@@ -7632,9 +8598,9 @@
       }
     },
     "chalk": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
-      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+      "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
       "dev": true,
       "requires": {
         "ansi-styles": "^4.1.0",
@@ -7642,20 +8608,20 @@
       }
     },
     "chownr": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
-      "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
+      "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="
     },
     "chromium-pickle-js": {
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz",
-      "integrity": "sha1-BKEGZywYsIWrd02YPfo+oTjyIgU=",
+      "integrity": "sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==",
       "dev": true
     },
     "ci-info": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz",
-      "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==",
+      "version": "3.3.2",
+      "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.2.tgz",
+      "integrity": "sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg==",
       "dev": true
     },
     "classnames": {
@@ -7663,6 +8629,12 @@
       "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz",
       "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA=="
     },
+    "clean-stack": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
+      "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
+      "optional": true
+    },
     "cli-boxes": {
       "version": "2.2.1",
       "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz",
@@ -7670,49 +8642,57 @@
       "dev": true
     },
     "cli-truncate": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-1.1.0.tgz",
-      "integrity": "sha512-bAtZo0u82gCfaAGfSNxUdTI9mNyza7D8w4CVCcaOsy7sgwDzvx6ekr6cuWJqY3UGzgnQ1+4wgENup5eIhgxEYA==",
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz",
+      "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==",
       "dev": true,
       "optional": true,
       "requires": {
-        "slice-ansi": "^1.0.0",
-        "string-width": "^2.0.0"
+        "slice-ansi": "^3.0.0",
+        "string-width": "^4.2.0"
       },
       "dependencies": {
         "ansi-regex": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
-          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+          "version": "5.0.1",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+          "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+          "dev": true,
+          "optional": true
+        },
+        "emoji-regex": {
+          "version": "8.0.0",
+          "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+          "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
           "dev": true,
           "optional": true
         },
         "is-fullwidth-code-point": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
-          "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+          "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
           "dev": true,
           "optional": true
         },
         "string-width": {
-          "version": "2.1.1",
-          "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
-          "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+          "version": "4.2.3",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+          "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
           "dev": true,
           "optional": true,
           "requires": {
-            "is-fullwidth-code-point": "^2.0.0",
-            "strip-ansi": "^4.0.0"
+            "emoji-regex": "^8.0.0",
+            "is-fullwidth-code-point": "^3.0.0",
+            "strip-ansi": "^6.0.1"
           }
         },
         "strip-ansi": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
-          "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+          "version": "6.0.1",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+          "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
           "dev": true,
           "optional": true,
           "requires": {
-            "ansi-regex": "^3.0.0"
+            "ansi-regex": "^5.0.1"
           }
         }
       }
@@ -7729,9 +8709,15 @@
       },
       "dependencies": {
         "ansi-regex": {
-          "version": "5.0.1",
-          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
-          "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+          "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
+          "dev": true
+        },
+        "emoji-regex": {
+          "version": "8.0.0",
+          "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+          "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
           "dev": true
         },
         "is-fullwidth-code-point": {
@@ -7741,23 +8727,23 @@
           "dev": true
         },
         "string-width": {
-          "version": "4.2.3",
-          "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
-          "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+          "version": "4.2.2",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
+          "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==",
           "dev": true,
           "requires": {
             "emoji-regex": "^8.0.0",
             "is-fullwidth-code-point": "^3.0.0",
-            "strip-ansi": "^6.0.1"
+            "strip-ansi": "^6.0.0"
           }
         },
         "strip-ansi": {
-          "version": "6.0.1",
-          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
-          "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+          "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
           "dev": true,
           "requires": {
-            "ansi-regex": "^5.0.1"
+            "ansi-regex": "^5.0.0"
           }
         }
       }
@@ -7807,10 +8793,15 @@
       "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
       "dev": true
     },
+    "color-support": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
+      "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg=="
+    },
     "colors": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz",
-      "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=",
+      "integrity": "sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==",
       "dev": true
     },
     "combined-stream": {
@@ -7829,7 +8820,7 @@
     "compare-version": {
       "version": "0.1.2",
       "resolved": "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz",
-      "integrity": "sha1-AWLsLZNR9d3VmpICy6k1NmpyUIA=",
+      "integrity": "sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==",
       "dev": true
     },
     "component-emitter": {
@@ -7870,7 +8861,7 @@
     "console-control-strings": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
-      "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4="
+      "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ=="
     },
     "content-disposition": {
       "version": "0.5.3",
@@ -7989,6 +8980,7 @@
       "version": "3.2.6",
       "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
       "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+      "dev": true,
       "requires": {
         "ms": "^2.1.1"
       },
@@ -7996,7 +8988,8 @@
         "ms": {
           "version": "2.1.2",
           "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
-          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+          "dev": true
         }
       }
     },
@@ -8018,7 +9011,8 @@
     "deep-extend": {
       "version": "0.6.0",
       "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
-      "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="
+      "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
+      "dev": true
     },
     "defer-to-connect": {
       "version": "1.1.3",
@@ -8034,7 +9028,7 @@
     "delegates": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
-      "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o="
+      "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ=="
     },
     "depd": {
       "version": "1.1.2",
@@ -8047,9 +9041,9 @@
       "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
     },
     "detect-libc": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
-      "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups="
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz",
+      "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w=="
     },
     "dicer": {
       "version": "0.2.5",
@@ -8098,7 +9092,7 @@
         "commander": {
           "version": "2.9.0",
           "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz",
-          "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=",
+          "integrity": "sha512-bmkUukX8wAOjHdN26xj5c4ctEV22TQ7dQYhSmuckKhToXrkUn0iIaolHdIxYYqD55nhpSPA9zPQ1yP57GdXP2A==",
           "dev": true,
           "requires": {
             "graceful-readlink": ">= 1.0.0"
@@ -8107,14 +9101,14 @@
       }
     },
     "dmg-builder": {
-      "version": "22.13.1",
-      "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-22.13.1.tgz",
-      "integrity": "sha512-qgfLN2fo4q2wIWNvbcKlZ71DLRDLvWIElOB7oxlSxUrMi6xhI+9v1Mh7E0FJ+r5UXhQzaQXaGuyMsQRbGgrSwg==",
+      "version": "22.14.13",
+      "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-22.14.13.tgz",
+      "integrity": "sha512-xNOugB6AbIRETeU2uID15sUfjdZZcKdxK8xkFnwIggsM00PJ12JxpLNPTjcRoUnfwj3WrPjilrO64vRMwNItQg==",
       "dev": true,
       "requires": {
-        "app-builder-lib": "22.13.1",
-        "builder-util": "22.13.1",
-        "builder-util-runtime": "8.8.1",
+        "app-builder-lib": "22.14.13",
+        "builder-util": "22.14.13",
+        "builder-util-runtime": "8.9.2",
         "dmg-license": "^1.0.9",
         "fs-extra": "^10.0.0",
         "iconv-lite": "^0.6.2",
@@ -8122,9 +9116,9 @@
       },
       "dependencies": {
         "builder-util-runtime": {
-          "version": "8.8.1",
-          "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.8.1.tgz",
-          "integrity": "sha512-xHxAzdsJmMV8m/N+INzYUKfyJASeKyKHnA1uGkY8Y8JKLI/c4BG+If+L0If2YETv96CiRASkvd02tIt2pvrchQ==",
+          "version": "8.9.2",
+          "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.9.2.tgz",
+          "integrity": "sha512-rhuKm5vh7E0aAmT6i8aoSfEjxzdYEFX7zDApK+eNgOhjofnWb74d9SRJv0H/8nsgOkos0TZ4zxW0P8J4N7xQ2A==",
           "dev": true,
           "requires": {
             "debug": "^4.3.2",
@@ -8132,18 +9126,18 @@
           }
         },
         "debug": {
-          "version": "4.3.2",
-          "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
-          "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+          "version": "4.3.4",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+          "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
           "dev": true,
           "requires": {
             "ms": "2.1.2"
           }
         },
         "fs-extra": {
-          "version": "10.0.0",
-          "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz",
-          "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==",
+          "version": "10.1.0",
+          "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
+          "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
           "dev": true,
           "requires": {
             "graceful-fs": "^4.2.0",
@@ -8185,19 +9179,18 @@
       }
     },
     "dmg-license": {
-      "version": "1.0.9",
-      "resolved": "https://registry.npmjs.org/dmg-license/-/dmg-license-1.0.9.tgz",
-      "integrity": "sha512-Rq6qMDaDou2+aPN2SYy0x7LDznoJ/XaG6oDcH5wXUp+WRWQMUYE6eM+F+nex+/LSXOp1uw4HLFoed0YbfU8R/Q==",
+      "version": "1.0.11",
+      "resolved": "https://registry.npmjs.org/dmg-license/-/dmg-license-1.0.11.tgz",
+      "integrity": "sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q==",
       "dev": true,
       "optional": true,
       "requires": {
         "@types/plist": "^3.0.1",
         "@types/verror": "^1.10.3",
         "ajv": "^6.10.0",
-        "cli-truncate": "^1.1.0",
         "crc": "^3.8.0",
-        "iconv-corefoundation": "^1.1.6",
-        "plist": "^3.0.1",
+        "iconv-corefoundation": "^1.1.7",
+        "plist": "^3.0.4",
         "smart-buffer": "^4.0.2",
         "verror": "^1.10.0"
       }
@@ -8211,9 +9204,9 @@
       }
     },
     "dompurify": {
-      "version": "2.3.3",
-      "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.3.3.tgz",
-      "integrity": "sha512-dqnqRkPMAjOZE0FogZ+ceJNM2dZ3V/yNOuFB7+39qpO93hHhfRpHw3heYQC7DPK9FqbQTfBKUJhiSfz4MvXYwg=="
+      "version": "2.3.8",
+      "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.3.8.tgz",
+      "integrity": "sha512-eVhaWoVibIzqdGYjwsBWodIQIaXFSB+cKDf4cfxLMsK0xiud6SE+/WCVx/Xw/UwQsa4cS3T2eITcdtmTg2UKcw=="
     },
     "dot-prop": {
       "version": "5.3.0",
@@ -8274,12 +9267,12 @@
       "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
     },
     "ejs": {
-      "version": "3.1.6",
-      "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.6.tgz",
-      "integrity": "sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==",
+      "version": "3.1.8",
+      "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz",
+      "integrity": "sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==",
       "dev": true,
       "requires": {
-        "jake": "^10.6.1"
+        "jake": "^10.8.5"
       }
     },
     "electron": {
@@ -8294,17 +9287,17 @@
       }
     },
     "electron-builder": {
-      "version": "22.13.1",
-      "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-22.13.1.tgz",
-      "integrity": "sha512-ajlI40L60qKBBxvpf770kcjxHAccMpEWpwsHAppytl3WmWgJfMut4Wz9VUFqyNtX/9a624QTatk6TqoxqewRug==",
+      "version": "22.14.13",
+      "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-22.14.13.tgz",
+      "integrity": "sha512-3fgLxqF2TXVKiUPeg74O4V3l0l3j7ERLazo8sUbRkApw0+4iVAf2BJkHsHMaXiigsgCoEzK/F4/rB5rne/VAnw==",
       "dev": true,
       "requires": {
         "@types/yargs": "^17.0.1",
-        "app-builder-lib": "22.13.1",
-        "builder-util": "22.13.1",
-        "builder-util-runtime": "8.8.1",
+        "app-builder-lib": "22.14.13",
+        "builder-util": "22.14.13",
+        "builder-util-runtime": "8.9.2",
         "chalk": "^4.1.1",
-        "dmg-builder": "22.13.1",
+        "dmg-builder": "22.14.13",
         "fs-extra": "^10.0.0",
         "is-ci": "^3.0.0",
         "lazy-val": "^1.0.5",
@@ -8314,9 +9307,9 @@
       },
       "dependencies": {
         "builder-util-runtime": {
-          "version": "8.8.1",
-          "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.8.1.tgz",
-          "integrity": "sha512-xHxAzdsJmMV8m/N+INzYUKfyJASeKyKHnA1uGkY8Y8JKLI/c4BG+If+L0If2YETv96CiRASkvd02tIt2pvrchQ==",
+          "version": "8.9.2",
+          "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.9.2.tgz",
+          "integrity": "sha512-rhuKm5vh7E0aAmT6i8aoSfEjxzdYEFX7zDApK+eNgOhjofnWb74d9SRJv0H/8nsgOkos0TZ4zxW0P8J4N7xQ2A==",
           "dev": true,
           "requires": {
             "debug": "^4.3.2",
@@ -8324,9 +9317,9 @@
           }
         },
         "debug": {
-          "version": "4.3.2",
-          "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
-          "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+          "version": "4.3.4",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+          "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
           "dev": true,
           "requires": {
             "ms": "2.1.2"
@@ -8353,12 +9346,6 @@
             "universalify": "^2.0.0"
           }
         },
-        "lazy-val": {
-          "version": "1.0.5",
-          "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz",
-          "integrity": "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==",
-          "dev": true
-        },
         "ms": {
           "version": "2.1.2",
           "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -8423,20 +9410,7 @@
           "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
           "dev": true,
           "requires": {
-            "@types/debug": "^4.1.5",
-            "@types/fs-extra": "^9.0.7",
-            "7zip-bin": "~5.1.1",
-            "app-builder-bin": "3.5.13",
-            "bluebird-lst": "^1.0.9",
-            "builder-util-runtime": "8.7.4",
-            "chalk": "^4.1.0",
-            "debug": "^4.3.2",
-            "fs-extra": "^9.1.0",
-            "is-ci": "^3.0.0",
-            "js-yaml": "^4.0.0",
-            "source-map-support": "^0.5.19",
-            "stat-mode": "^1.0.0",
-            "temp-file": "^3.3.7"
+            "ms": "2.0.0"
           }
         },
         "isbinaryfile": {
@@ -8451,14 +9425,14 @@
       }
     },
     "electron-publish": {
-      "version": "22.13.1",
-      "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-22.13.1.tgz",
-      "integrity": "sha512-5nCXhnsqrRxP5NsZxUKjiMkcFmQglXp7i/YY4rp3h1s1psg3utOIkM29Z93YTSXicZJU1J+8811eo5HX1vpoKg==",
+      "version": "22.14.13",
+      "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-22.14.13.tgz",
+      "integrity": "sha512-0oP3QiNj3e8ewOaEpEJV/o6Zrmy2VarVvZ/bH7kyO/S/aJf9x8vQsKVWpsdmSiZ5DJEHgarFIXrnO0ZQf0P9iQ==",
       "dev": true,
       "requires": {
         "@types/fs-extra": "^9.0.11",
-        "builder-util": "22.13.1",
-        "builder-util-runtime": "8.8.1",
+        "builder-util": "22.14.13",
+        "builder-util-runtime": "8.9.2",
         "chalk": "^4.1.1",
         "fs-extra": "^10.0.0",
         "lazy-val": "^1.0.5",
@@ -8466,9 +9440,9 @@
       },
       "dependencies": {
         "builder-util-runtime": {
-          "version": "8.8.1",
-          "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.8.1.tgz",
-          "integrity": "sha512-xHxAzdsJmMV8m/N+INzYUKfyJASeKyKHnA1uGkY8Y8JKLI/c4BG+If+L0If2YETv96CiRASkvd02tIt2pvrchQ==",
+          "version": "8.9.2",
+          "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.9.2.tgz",
+          "integrity": "sha512-rhuKm5vh7E0aAmT6i8aoSfEjxzdYEFX7zDApK+eNgOhjofnWb74d9SRJv0H/8nsgOkos0TZ4zxW0P8J4N7xQ2A==",
           "dev": true,
           "requires": {
             "debug": "^4.3.2",
@@ -8476,18 +9450,18 @@
           }
         },
         "debug": {
-          "version": "4.3.2",
-          "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
-          "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+          "version": "4.3.4",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+          "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
           "dev": true,
           "requires": {
             "ms": "2.1.2"
           }
         },
         "fs-extra": {
-          "version": "10.0.0",
-          "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz",
-          "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==",
+          "version": "10.1.0",
+          "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
+          "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
           "dev": true,
           "requires": {
             "graceful-fs": "^4.2.0",
@@ -8505,16 +9479,10 @@
             "universalify": "^2.0.0"
           }
         },
-        "lazy-val": {
-          "version": "1.0.5",
-          "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz",
-          "integrity": "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==",
-          "dev": true
-        },
         "mime": {
-          "version": "2.5.2",
-          "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz",
-          "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==",
+          "version": "2.6.0",
+          "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
+          "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
           "dev": true
         },
         "ms": {
@@ -8581,9 +9549,9 @@
       }
     },
     "emoji-regex": {
-      "version": "8.0.0",
-      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
-      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+      "version": "7.0.3",
+      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+      "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
       "dev": true
     },
     "encodeurl": {
@@ -8600,9 +9568,9 @@
       },
       "dependencies": {
         "iconv-lite": {
-          "version": "0.6.3",
-          "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
-          "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+          "version": "0.6.2",
+          "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz",
+          "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==",
           "requires": {
             "safer-buffer": ">= 2.1.2 < 3.0.0"
           }
@@ -8624,6 +9592,12 @@
       "integrity": "sha1-QWgTO0K7BcOKNbGuQ5fIKYqzaeA=",
       "dev": true
     },
+    "err-code": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz",
+      "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==",
+      "optional": true
+    },
     "error-ex": {
       "version": "1.3.2",
       "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
@@ -8655,12 +9629,6 @@
       "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
       "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
     },
-    "escape-string-regexp": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
-      "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
-      "dev": true
-    },
     "etag": {
       "version": "1.8.1",
       "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
@@ -8778,15 +9746,6 @@
           "requires": {
             "ms": "2.0.0"
           }
-        },
-        "mkdirp": {
-          "version": "0.5.5",
-          "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
-          "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
-          "dev": true,
-          "requires": {
-            "minimist": "^1.2.5"
-          }
         }
       }
     },
@@ -8837,12 +9796,32 @@
       }
     },
     "filelist": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz",
-      "integrity": "sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ==",
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz",
+      "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==",
       "dev": true,
       "requires": {
-        "minimatch": "^3.0.4"
+        "minimatch": "^5.0.1"
+      },
+      "dependencies": {
+        "brace-expansion": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+          "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+          "dev": true,
+          "requires": {
+            "balanced-match": "^1.0.0"
+          }
+        },
+        "minimatch": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz",
+          "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==",
+          "dev": true,
+          "requires": {
+            "brace-expansion": "^2.0.1"
+          }
+        }
       }
     },
     "finalhandler": {
@@ -8902,9 +9881,10 @@
       "dev": true
     },
     "form-data": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
-      "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
+      "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+      "dev": true,
       "requires": {
         "asynckit": "^0.4.0",
         "combined-stream": "^1.0.8",
@@ -8912,9 +9892,9 @@
       }
     },
     "formidable": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.2.tgz",
-      "integrity": "sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q=="
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.6.tgz",
+      "integrity": "sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ=="
     },
     "forwarded": {
       "version": "0.1.2",
@@ -8943,11 +9923,11 @@
       }
     },
     "fs-minipass": {
-      "version": "1.2.7",
-      "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz",
-      "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==",
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
+      "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
       "requires": {
-        "minipass": "^2.6.0"
+        "minipass": "^3.0.0"
       }
     },
     "fs.realpath": {
@@ -8961,18 +9941,54 @@
       "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
     },
     "gauge": {
-      "version": "2.7.4",
-      "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
-      "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz",
+      "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==",
       "requires": {
-        "aproba": "^1.0.3",
+        "aproba": "^1.0.3 || ^2.0.0",
+        "color-support": "^1.1.2",
         "console-control-strings": "^1.0.0",
-        "has-unicode": "^2.0.0",
-        "object-assign": "^4.1.0",
+        "has-unicode": "^2.0.1",
+        "object-assign": "^4.1.1",
         "signal-exit": "^3.0.0",
-        "string-width": "^1.0.1",
-        "strip-ansi": "^3.0.1",
-        "wide-align": "^1.1.0"
+        "string-width": "^4.2.3",
+        "strip-ansi": "^6.0.1",
+        "wide-align": "^1.1.2"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "5.0.1",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+          "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
+        },
+        "emoji-regex": {
+          "version": "8.0.0",
+          "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+          "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+        },
+        "is-fullwidth-code-point": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+          "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
+        },
+        "string-width": {
+          "version": "4.2.3",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+          "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+          "requires": {
+            "emoji-regex": "^8.0.0",
+            "is-fullwidth-code-point": "^3.0.0",
+            "strip-ansi": "^6.0.1"
+          }
+        },
+        "strip-ansi": {
+          "version": "6.0.1",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+          "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+          "requires": {
+            "ansi-regex": "^5.0.1"
+          }
+        }
       }
     },
     "get-caller-file": {
@@ -8982,13 +9998,13 @@
       "dev": true
     },
     "get-intrinsic": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
-      "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz",
+      "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==",
       "requires": {
         "function-bind": "^1.1.1",
         "has": "^1.0.3",
-        "has-symbols": "^1.0.1"
+        "has-symbols": "^1.0.3"
       }
     },
     "get-stdin": {
@@ -9065,14 +10081,14 @@
       }
     },
     "graceful-fs": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz",
-      "integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg=="
+      "version": "4.2.11",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+      "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="
     },
     "graceful-readlink": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz",
-      "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=",
+      "integrity": "sha512-8tLu60LgxF6XpdbK8OW3FA+IfTNBn1ZHGHKF4KQbEeSkajYw5PlYJcKluntgegDPTg8UkHjpet1T82vk6TQ68w==",
       "dev": true
     },
     "har-schema": {
@@ -9089,26 +10105,6 @@
       "requires": {
         "ajv": "^6.12.3",
         "har-schema": "^2.0.0"
-      },
-      "dependencies": {
-        "ajv": {
-          "version": "6.12.6",
-          "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
-          "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
-          "dev": true,
-          "requires": {
-            "fast-deep-equal": "^3.1.1",
-            "fast-json-stable-stringify": "^2.0.0",
-            "json-schema-traverse": "^0.4.1",
-            "uri-js": "^4.2.2"
-          }
-        },
-        "fast-deep-equal": {
-          "version": "3.1.3",
-          "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
-          "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
-          "dev": true
-        }
       }
     },
     "has": {
@@ -9126,14 +10122,14 @@
       "dev": true
     },
     "has-symbols": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
-      "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw=="
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+      "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
     },
     "has-unicode": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
-      "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk="
+      "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ=="
     },
     "has-yarn": {
       "version": "2.1.0",
@@ -9151,7 +10147,7 @@
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
       "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==",
-      "dev": true
+      "devOptional": true
     },
     "http-errors": {
       "version": "1.7.2",
@@ -9233,14 +10229,24 @@
         }
       }
     },
+    "humanize-ms": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
+      "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==",
+      "optional": true,
+      "requires": {
+        "ms": "^2.0.0"
+      }
+    },
     "iconv-corefoundation": {
-      "version": "1.1.6",
-      "resolved": "https://registry.npmjs.org/iconv-corefoundation/-/iconv-corefoundation-1.1.6.tgz",
-      "integrity": "sha512-1NBe55C75bKGZaY9UHxvXG3G0gEp0ziht7quhuFrW3SPgZDw9HI6qvYXRSV5M/Eupyu8ljuJ6Cba+ec15PZ4Xw==",
+      "version": "1.1.7",
+      "resolved": "https://registry.npmjs.org/iconv-corefoundation/-/iconv-corefoundation-1.1.7.tgz",
+      "integrity": "sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ==",
       "dev": true,
       "optional": true,
       "requires": {
-        "cli-truncate": "^1.1.0"
+        "cli-truncate": "^2.1.0",
+        "node-addon-api": "^1.6.3"
       }
     },
     "iconv-lite": {
@@ -9278,14 +10284,6 @@
       "dev": true,
       "optional": true
     },
-    "ignore-walk": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz",
-      "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==",
-      "requires": {
-        "minimatch": "^3.0.4"
-      }
-    },
     "immutable": {
       "version": "3.8.2",
       "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.2.tgz",
@@ -9301,7 +10299,7 @@
       "version": "0.1.4",
       "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
       "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
-      "dev": true
+      "devOptional": true
     },
     "indent-string": {
       "version": "2.1.0",
@@ -9312,6 +10310,12 @@
         "repeating": "^2.0.0"
       }
     },
+    "infer-owner": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
+      "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==",
+      "optional": true
+    },
     "inflight": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
@@ -9329,7 +10333,14 @@
     "ini": {
       "version": "1.3.5",
       "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
-      "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
+      "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
+      "dev": true
+    },
+    "ip": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz",
+      "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==",
+      "optional": true
     },
     "ipaddr.js": {
       "version": "1.9.0",
@@ -9343,12 +10354,12 @@
       "dev": true
     },
     "is-ci": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz",
-      "integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==",
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz",
+      "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==",
       "dev": true,
       "requires": {
-        "ci-info": "^3.1.1"
+        "ci-info": "^3.2.0"
       }
     },
     "is-finite": {
@@ -9375,6 +10386,12 @@
         "is-path-inside": "^3.0.2"
       }
     },
+    "is-lambda": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz",
+      "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==",
+      "optional": true
+    },
     "is-npm": {
       "version": "5.0.0",
       "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-5.0.0.tgz",
@@ -9422,16 +10439,16 @@
       "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
     },
     "isbinaryfile": {
-      "version": "4.0.8",
-      "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.8.tgz",
-      "integrity": "sha512-53h6XFniq77YdW+spoRrebh0mnmTxRPTlcuIArO57lmMdq4uBKFKaeTjnb92oYWrSn/LVL+LT+Hap2tFQj8V+w==",
+      "version": "4.0.10",
+      "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz",
+      "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==",
       "dev": true
     },
     "isexe": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
-      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
-      "dev": true
+      "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+      "devOptional": true
     },
     "isomorphic-fetch": {
       "version": "2.2.1",
@@ -9440,17 +10457,6 @@
       "requires": {
         "node-fetch": "^1.0.1",
         "whatwg-fetch": ">=0.10.0"
-      },
-      "dependencies": {
-        "node-fetch": {
-          "version": "1.7.3",
-          "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
-          "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
-          "requires": {
-            "encoding": "^0.1.11",
-            "is-stream": "^1.0.1"
-          }
-        }
       }
     },
     "isstream": {
@@ -9460,72 +10466,22 @@
       "dev": true
     },
     "jake": {
-      "version": "10.8.2",
-      "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.2.tgz",
-      "integrity": "sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==",
+      "version": "10.8.5",
+      "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz",
+      "integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==",
       "dev": true,
       "requires": {
-        "async": "0.9.x",
-        "chalk": "^2.4.2",
+        "async": "^3.2.3",
+        "chalk": "^4.0.2",
         "filelist": "^1.0.1",
         "minimatch": "^3.0.4"
       },
       "dependencies": {
-        "ansi-styles": {
-          "version": "3.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
-          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
-          "dev": true,
-          "requires": {
-            "color-convert": "^1.9.0"
-          }
-        },
         "async": {
-          "version": "0.9.2",
-          "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
-          "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=",
-          "dev": true
-        },
-        "chalk": {
-          "version": "2.4.2",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
-          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^3.2.1",
-            "escape-string-regexp": "^1.0.5",
-            "supports-color": "^5.3.0"
-          }
-        },
-        "color-convert": {
-          "version": "1.9.3",
-          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
-          "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
-          "dev": true,
-          "requires": {
-            "color-name": "1.1.3"
-          }
-        },
-        "color-name": {
-          "version": "1.1.3",
-          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-          "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
-          "dev": true
-        },
-        "has-flag": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
-          "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+          "version": "3.2.4",
+          "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz",
+          "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==",
           "dev": true
-        },
-        "supports-color": {
-          "version": "5.5.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
-          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
-          "dev": true,
-          "requires": {
-            "has-flag": "^3.0.0"
-          }
         }
       }
     },
@@ -9550,7 +10506,7 @@
     "jsbn": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz",
-      "integrity": "sha1-sBMHyym2GKHtJux56RH4A8TaAEA="
+      "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A=="
     },
     "json-buffer": {
       "version": "3.0.0",
@@ -9577,13 +10533,10 @@
       "dev": true
     },
     "json5": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
-      "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
-      "dev": true,
-      "requires": {
-        "minimist": "^1.2.5"
-      }
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
+      "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
+      "dev": true
     },
     "jsonfile": {
       "version": "4.0.0",
@@ -9735,9 +10688,9 @@
       }
     },
     "lazy-val": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.4.tgz",
-      "integrity": "sha512-u93kb2fPbIrfzBuLjZE+w+fJbUUMhNDXxNmMfaqNgpfQf1CO5ZSe2LfsnBqVAk7i/2NF48OSoRj+Xe2VT+lE8Q=="
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz",
+      "integrity": "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q=="
     },
     "limiter": {
       "version": "1.1.5",
@@ -9879,11 +10832,34 @@
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
       "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
-      "dev": true,
       "requires": {
         "semver": "^6.0.0"
       }
     },
+    "make-fetch-happen": {
+      "version": "9.1.0",
+      "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz",
+      "integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==",
+      "optional": true,
+      "requires": {
+        "agentkeepalive": "^4.1.3",
+        "cacache": "^15.2.0",
+        "http-cache-semantics": "^4.1.0",
+        "http-proxy-agent": "^4.0.1",
+        "https-proxy-agent": "^5.0.0",
+        "is-lambda": "^1.0.1",
+        "lru-cache": "^6.0.0",
+        "minipass": "^3.1.3",
+        "minipass-collect": "^1.0.2",
+        "minipass-fetch": "^1.3.2",
+        "minipass-flush": "^1.0.5",
+        "minipass-pipeline": "^1.2.4",
+        "negotiator": "^0.6.2",
+        "promise-retry": "^2.0.1",
+        "socks-proxy-agent": "^6.0.0",
+        "ssri": "^8.0.0"
+      }
+    },
     "map-obj": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
@@ -9956,52 +10932,81 @@
       }
     },
     "minimist": {
-      "version": "1.2.5",
-      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
-      "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
+      "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
     },
     "minipass": {
-      "version": "2.9.0",
-      "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz",
-      "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==",
+      "version": "3.3.6",
+      "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+      "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
       "requires": {
-        "safe-buffer": "^5.1.2",
-        "yallist": "^3.0.0"
-      },
-      "dependencies": {
-        "safe-buffer": {
-          "version": "5.2.1",
-          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
-          "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
-        },
-        "yallist": {
-          "version": "3.1.1",
-          "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
-          "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
-        }
+        "yallist": "^4.0.0"
+      }
+    },
+    "minipass-collect": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz",
+      "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==",
+      "optional": true,
+      "requires": {
+        "minipass": "^3.0.0"
+      }
+    },
+    "minipass-fetch": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz",
+      "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==",
+      "optional": true,
+      "requires": {
+        "encoding": "^0.1.12",
+        "minipass": "^3.1.0",
+        "minipass-sized": "^1.0.3",
+        "minizlib": "^2.0.0"
+      }
+    },
+    "minipass-flush": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
+      "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
+      "optional": true,
+      "requires": {
+        "minipass": "^3.0.0"
+      }
+    },
+    "minipass-pipeline": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz",
+      "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==",
+      "optional": true,
+      "requires": {
+        "minipass": "^3.0.0"
+      }
+    },
+    "minipass-sized": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz",
+      "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==",
+      "optional": true,
+      "requires": {
+        "minipass": "^3.0.0"
       }
     },
     "minizlib": {
-      "version": "1.3.3",
-      "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz",
-      "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==",
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
+      "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
       "requires": {
-        "minipass": "^2.9.0"
+        "minipass": "^3.0.0",
+        "yallist": "^4.0.0"
       }
     },
     "mkdirp": {
-      "version": "0.5.1",
-      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
-      "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+      "version": "0.5.6",
+      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
+      "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
       "requires": {
-        "minimist": "0.0.8"
-      },
-      "dependencies": {
-        "minimist": {
-          "version": "0.0.8",
-          "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
-          "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
-        }
+        "minimist": "^1.2.6"
       }
     },
     "ms": {
@@ -10010,9 +11015,9 @@
       "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
     },
     "multer": {
-      "version": "1.4.3",
-      "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.3.tgz",
-      "integrity": "sha512-np0YLKncuZoTzufbkM6wEKp68EhWJXcU6fq6QqrSwkckd2LlMgd1UqhUJLj6NS/5sZ8dE8LYDWslsltJznnXlg==",
+      "version": "1.4.4",
+      "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.4.tgz",
+      "integrity": "sha512-2wY2+xD4udX612aMqMcB8Ws2Voq6NIUPEtD1be6m411T4uDH/VtL9i//xvcyFlTVfRdaBsk7hV5tgrGQqhuBiw==",
       "requires": {
         "append-field": "^1.0.0",
         "busboy": "^0.2.11",
@@ -10024,86 +11029,168 @@
         "xtend": "^4.0.0"
       },
       "dependencies": {
-        "mkdirp": {
-          "version": "0.5.5",
-          "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
-          "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
+        "xtend": {
+          "version": "4.0.2",
+          "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+          "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="
+        }
+      }
+    },
+    "negotiator": {
+      "version": "0.6.2",
+      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
+      "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
+    },
+    "node-addon-api": {
+      "version": "1.7.2",
+      "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz",
+      "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==",
+      "dev": true,
+      "optional": true
+    },
+    "node-fetch": {
+      "version": "1.7.3",
+      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
+      "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
+      "requires": {
+        "encoding": "^0.1.11",
+        "is-stream": "^1.0.1"
+      }
+    },
+    "node-gyp": {
+      "version": "8.4.1",
+      "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-8.4.1.tgz",
+      "integrity": "sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==",
+      "optional": true,
+      "requires": {
+        "env-paths": "^2.2.0",
+        "glob": "^7.1.4",
+        "graceful-fs": "^4.2.6",
+        "make-fetch-happen": "^9.1.0",
+        "nopt": "^5.0.0",
+        "npmlog": "^6.0.0",
+        "rimraf": "^3.0.2",
+        "semver": "^7.3.5",
+        "tar": "^6.1.2",
+        "which": "^2.0.2"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "5.0.1",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+          "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+          "optional": true
+        },
+        "are-we-there-yet": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz",
+          "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==",
+          "optional": true,
+          "requires": {
+            "delegates": "^1.0.0",
+            "readable-stream": "^3.6.0"
+          }
+        },
+        "emoji-regex": {
+          "version": "8.0.0",
+          "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+          "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+          "optional": true
+        },
+        "env-paths": {
+          "version": "2.2.1",
+          "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
+          "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
+          "optional": true
+        },
+        "gauge": {
+          "version": "4.0.4",
+          "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz",
+          "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==",
+          "optional": true,
+          "requires": {
+            "aproba": "^1.0.3 || ^2.0.0",
+            "color-support": "^1.1.3",
+            "console-control-strings": "^1.1.0",
+            "has-unicode": "^2.0.1",
+            "signal-exit": "^3.0.7",
+            "string-width": "^4.2.3",
+            "strip-ansi": "^6.0.1",
+            "wide-align": "^1.1.5"
+          }
+        },
+        "is-fullwidth-code-point": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+          "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+          "optional": true
+        },
+        "npmlog": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz",
+          "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==",
+          "optional": true,
+          "requires": {
+            "are-we-there-yet": "^3.0.0",
+            "console-control-strings": "^1.1.0",
+            "gauge": "^4.0.3",
+            "set-blocking": "^2.0.0"
+          }
+        },
+        "readable-stream": {
+          "version": "3.6.2",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+          "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+          "optional": true,
           "requires": {
-            "minimist": "^1.2.5"
+            "inherits": "^2.0.3",
+            "string_decoder": "^1.1.1",
+            "util-deprecate": "^1.0.1"
           }
         },
-        "xtend": {
-          "version": "4.0.2",
-          "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
-          "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="
+        "semver": {
+          "version": "7.5.1",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
+          "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
+          "optional": true,
+          "requires": {
+            "lru-cache": "^6.0.0"
+          }
+        },
+        "string-width": {
+          "version": "4.2.3",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+          "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+          "optional": true,
+          "requires": {
+            "emoji-regex": "^8.0.0",
+            "is-fullwidth-code-point": "^3.0.0",
+            "strip-ansi": "^6.0.1"
+          }
+        },
+        "strip-ansi": {
+          "version": "6.0.1",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+          "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+          "optional": true,
+          "requires": {
+            "ansi-regex": "^5.0.1"
+          }
         }
       }
     },
-    "nan": {
-      "version": "2.14.2",
-      "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz",
-      "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ=="
-    },
-    "needle": {
-      "version": "2.6.0",
-      "resolved": "https://registry.npmjs.org/needle/-/needle-2.6.0.tgz",
-      "integrity": "sha512-KKYdza4heMsEfSWD7VPUIz3zX2XDwOyX2d+geb4vrERZMT5RMU6ujjaD+I5Yr54uZxQ2w6XRTAhHBbSCyovZBg==",
-      "requires": {
-        "debug": "^3.2.6",
-        "iconv-lite": "^0.4.4",
-        "sax": "^1.2.4"
-      }
-    },
-    "negotiator": {
-      "version": "0.6.2",
-      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
-      "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
-    },
-    "node-fetch": {
-      "version": "2.6.5",
-      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz",
-      "integrity": "sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==",
-      "requires": {
-        "whatwg-url": "^5.0.0"
-      }
-    },
     "node-jsxml": {
       "version": "0.9.0",
       "resolved": "https://registry.npmjs.org/node-jsxml/-/node-jsxml-0.9.0.tgz",
       "integrity": "sha1-Ca5p+9YJnfuGAoHaZv8nkPoAmVQ=",
       "dev": true
     },
-    "node-pre-gyp": {
-      "version": "0.11.0",
-      "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz",
-      "integrity": "sha512-TwWAOZb0j7e9eGaf9esRx3ZcLaE5tQ2lvYy1pb5IAaG1a2e2Kv5Lms1Y4hpj+ciXJRofIxxlt5haeQ/2ANeE0Q==",
-      "requires": {
-        "detect-libc": "^1.0.2",
-        "mkdirp": "^0.5.1",
-        "needle": "^2.2.1",
-        "nopt": "^4.0.1",
-        "npm-packlist": "^1.1.6",
-        "npmlog": "^4.0.2",
-        "rc": "^1.2.7",
-        "rimraf": "^2.6.1",
-        "semver": "^5.3.0",
-        "tar": "^4"
-      },
-      "dependencies": {
-        "semver": {
-          "version": "5.7.1",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-          "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
-        }
-      }
-    },
     "nopt": {
-      "version": "4.0.3",
-      "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz",
-      "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==",
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
+      "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
       "requires": {
-        "abbrev": "1",
-        "osenv": "^0.1.4"
+        "abbrev": "1"
       }
     },
     "normalize-package-data": {
@@ -10127,43 +11214,20 @@
       }
     },
     "normalize-url": {
-      "version": "4.5.1",
-      "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz",
-      "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==",
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz",
+      "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==",
       "dev": true
     },
-    "npm-bundled": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.1.tgz",
-      "integrity": "sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==",
-      "requires": {
-        "npm-normalize-package-bin": "^1.0.1"
-      }
-    },
-    "npm-normalize-package-bin": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz",
-      "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA=="
-    },
-    "npm-packlist": {
-      "version": "1.4.8",
-      "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz",
-      "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==",
-      "requires": {
-        "ignore-walk": "^3.0.1",
-        "npm-bundled": "^1.0.1",
-        "npm-normalize-package-bin": "^1.0.1"
-      }
-    },
     "npmlog": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
-      "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz",
+      "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==",
       "requires": {
-        "are-we-there-yet": "~1.1.2",
-        "console-control-strings": "~1.1.0",
-        "gauge": "~2.7.3",
-        "set-blocking": "~2.0.0"
+        "are-we-there-yet": "^2.0.0",
+        "console-control-strings": "^1.1.0",
+        "gauge": "^3.0.0",
+        "set-blocking": "^2.0.0"
       }
     },
     "nugget": {
@@ -10209,9 +11273,9 @@
       "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
     },
     "object-inspect": {
-      "version": "1.11.0",
-      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz",
-      "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg=="
+      "version": "1.12.2",
+      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
+      "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ=="
     },
     "object-keys": {
       "version": "0.4.0",
@@ -10235,31 +11299,21 @@
         "wrappy": "1"
       }
     },
-    "os-homedir": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
-      "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M="
-    },
-    "os-tmpdir": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
-      "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
-    },
-    "osenv": {
-      "version": "0.1.5",
-      "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
-      "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
-      "requires": {
-        "os-homedir": "^1.0.0",
-        "os-tmpdir": "^1.0.0"
-      }
-    },
     "p-cancelable": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz",
       "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==",
       "dev": true
     },
+    "p-map": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
+      "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
+      "optional": true,
+      "requires": {
+        "aggregate-error": "^3.0.0"
+      }
+    },
     "package-json": {
       "version": "6.5.0",
       "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz",
@@ -10364,13 +11418,21 @@
       }
     },
     "plist": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.4.tgz",
-      "integrity": "sha512-ksrr8y9+nXOxQB2osVNqrgvX/XQPOXaU4BQMKjYq8PvaY1U18mo+fKgBSwzK+luSyinOuPae956lSVcBwxlAMg==",
+      "version": "3.0.5",
+      "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.5.tgz",
+      "integrity": "sha512-83vX4eYdQp3vP9SxuYgEM/G/pJQqLUz/V/xzPrzruLs7fz7jxGQ1msZ/mg1nwZxUSuOp4sb+/bEIbRrbzZRxDA==",
       "dev": true,
       "requires": {
         "base64-js": "^1.5.1",
         "xmlbuilder": "^9.0.7"
+      },
+      "dependencies": {
+        "xmlbuilder": {
+          "version": "9.0.7",
+          "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
+          "integrity": "sha512-7YXTQc3P2l9+0rjaUbLwMKRhtmwg1M1eDf6nag7urC7pIPYLD9W/jmzQ4ptRSUbodw5S0jfoGTflLemQibSpeQ==",
+          "dev": true
+        }
       }
     },
     "prepend-http": {
@@ -10417,14 +11479,30 @@
         "asap": "~2.0.3"
       }
     },
+    "promise-inflight": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
+      "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==",
+      "optional": true
+    },
+    "promise-retry": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz",
+      "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==",
+      "optional": true,
+      "requires": {
+        "err-code": "^2.0.2",
+        "retry": "^0.12.0"
+      }
+    },
     "prop-types": {
-      "version": "15.7.2",
-      "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz",
-      "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==",
+      "version": "15.8.1",
+      "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
+      "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
       "requires": {
         "loose-envify": "^1.4.0",
         "object-assign": "^4.1.1",
-        "react-is": "^16.8.1"
+        "react-is": "^16.13.1"
       }
     },
     "proxy-addr": {
@@ -10478,9 +11556,9 @@
       }
     },
     "qs": {
-      "version": "6.10.1",
-      "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz",
-      "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==",
+      "version": "6.10.5",
+      "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.5.tgz",
+      "integrity": "sha512-O5RlPh0VFtR78y79rgcgKK4wbAI0C5zGVLztOIdpWX6ep368q5Hv6XRxDvXuZ9q3C6v+e3n8UfZZJw7IIG27eQ==",
       "requires": {
         "side-channel": "^1.0.4"
       }
@@ -10505,6 +11583,7 @@
       "version": "1.2.8",
       "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
       "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
+      "dev": true,
       "requires": {
         "deep-extend": "^0.6.0",
         "ini": "~1.3.0",
@@ -10615,9 +11694,9 @@
       }
     },
     "regenerator-runtime": {
-      "version": "0.13.9",
-      "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
-      "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
+      "version": "0.13.7",
+      "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
+      "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew=="
     },
     "registry-auth-token": {
       "version": "4.2.1",
@@ -10723,10 +11802,16 @@
         "lowercase-keys": "^1.0.0"
       }
     },
+    "retry": {
+      "version": "0.12.0",
+      "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
+      "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==",
+      "optional": true
+    },
     "rimraf": {
-      "version": "2.7.1",
-      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
-      "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+      "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
       "requires": {
         "glob": "^7.1.3"
       }
@@ -10825,7 +11910,7 @@
     "set-blocking": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
-      "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
+      "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="
     },
     "setimmediate": {
       "version": "1.0.5",
@@ -10863,9 +11948,9 @@
       }
     },
     "signal-exit": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
-      "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
+      "version": "3.0.7",
+      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+      "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
     },
     "single-line-log": {
       "version": "1.1.2",
@@ -10877,19 +11962,21 @@
       }
     },
     "slice-ansi": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz",
-      "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==",
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz",
+      "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==",
       "dev": true,
       "optional": true,
       "requires": {
-        "is-fullwidth-code-point": "^2.0.0"
+        "ansi-styles": "^4.0.0",
+        "astral-regex": "^2.0.0",
+        "is-fullwidth-code-point": "^3.0.0"
       },
       "dependencies": {
         "is-fullwidth-code-point": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
-          "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+          "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
           "dev": true,
           "optional": true
         }
@@ -10899,9 +11986,46 @@
       "version": "4.2.0",
       "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
       "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
-      "dev": true,
       "optional": true
     },
+    "socks": {
+      "version": "2.7.1",
+      "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz",
+      "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==",
+      "optional": true,
+      "requires": {
+        "ip": "^2.0.0",
+        "smart-buffer": "^4.2.0"
+      }
+    },
+    "socks-proxy-agent": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz",
+      "integrity": "sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==",
+      "optional": true,
+      "requires": {
+        "agent-base": "^6.0.2",
+        "debug": "^4.3.3",
+        "socks": "^2.6.2"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "4.3.4",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+          "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+          "optional": true,
+          "requires": {
+            "ms": "2.1.2"
+          }
+        },
+        "ms": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+          "optional": true
+        }
+      }
+    },
     "source-map": {
       "version": "0.6.1",
       "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@@ -10909,9 +12033,9 @@
       "dev": true
     },
     "source-map-support": {
-      "version": "0.5.20",
-      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz",
-      "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==",
+      "version": "0.5.21",
+      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
+      "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
       "dev": true,
       "requires": {
         "buffer-from": "^1.0.0",
@@ -10957,12 +12081,21 @@
       "dev": true
     },
     "sqlite3": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-4.2.0.tgz",
-      "integrity": "sha512-roEOz41hxui2Q7uYnWsjMOTry6TcNUNmp8audCx18gF10P2NknwdpF+E+HKvz/F2NvPKGGBF4NGc+ZPQ+AABwg==",
+      "version": "5.1.6",
+      "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.1.6.tgz",
+      "integrity": "sha512-olYkWoKFVNSSSQNvxVUfjiVbz3YtBwTJj+mfV5zpHmqW3sELx2Cf4QCdirMelhM5Zh+KDVaKgQHqCxrqiWHybw==",
       "requires": {
-        "nan": "^2.12.1",
-        "node-pre-gyp": "^0.11.0"
+        "@mapbox/node-pre-gyp": "^1.0.0",
+        "node-addon-api": "^4.2.0",
+        "node-gyp": "8.x",
+        "tar": "^6.1.11"
+      },
+      "dependencies": {
+        "node-addon-api": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz",
+          "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ=="
+        }
       }
     },
     "ssf": {
@@ -10998,6 +12131,15 @@
         }
       }
     },
+    "ssri": {
+      "version": "8.0.1",
+      "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz",
+      "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==",
+      "optional": true,
+      "requires": {
+        "minipass": "^3.1.1"
+      }
+    },
     "stat-mode": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-1.0.0.tgz",
@@ -11061,7 +12203,8 @@
     "strip-json-comments": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
-      "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo="
+      "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
+      "dev": true
     },
     "sumchecker": {
       "version": "2.0.2",
@@ -11102,17 +12245,27 @@
       },
       "dependencies": {
         "debug": {
-          "version": "4.3.2",
-          "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
-          "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+          "version": "4.3.4",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+          "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
           "requires": {
             "ms": "2.1.2"
           }
         },
+        "form-data": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
+          "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
+          "requires": {
+            "asynckit": "^0.4.0",
+            "combined-stream": "^1.0.8",
+            "mime-types": "^2.1.12"
+          }
+        },
         "mime": {
-          "version": "2.5.2",
-          "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz",
-          "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg=="
+          "version": "2.6.0",
+          "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
+          "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg=="
         },
         "ms": {
           "version": "2.1.2",
@@ -11130,9 +12283,9 @@
           }
         },
         "semver": {
-          "version": "7.3.5",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
-          "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+          "version": "7.3.7",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
+          "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
           "requires": {
             "lru-cache": "^6.0.0"
           }
@@ -11158,28 +12311,27 @@
       }
     },
     "tar": {
-      "version": "4.4.13",
-      "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz",
-      "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==",
-      "requires": {
-        "chownr": "^1.1.1",
-        "fs-minipass": "^1.2.5",
-        "minipass": "^2.8.6",
-        "minizlib": "^1.2.1",
-        "mkdirp": "^0.5.0",
-        "safe-buffer": "^5.1.2",
-        "yallist": "^3.0.3"
+      "version": "6.1.15",
+      "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.15.tgz",
+      "integrity": "sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==",
+      "requires": {
+        "chownr": "^2.0.0",
+        "fs-minipass": "^2.0.0",
+        "minipass": "^5.0.0",
+        "minizlib": "^2.1.1",
+        "mkdirp": "^1.0.3",
+        "yallist": "^4.0.0"
       },
       "dependencies": {
-        "safe-buffer": {
-          "version": "5.2.1",
-          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
-          "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
+        "minipass": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
+          "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ=="
         },
-        "yallist": {
-          "version": "3.1.1",
-          "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
-          "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
+        "mkdirp": {
+          "version": "1.0.4",
+          "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+          "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="
         }
       }
     },
@@ -11194,9 +12346,9 @@
       },
       "dependencies": {
         "fs-extra": {
-          "version": "10.0.0",
-          "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz",
-          "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==",
+          "version": "10.1.0",
+          "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
+          "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
           "dev": true,
           "requires": {
             "graceful-fs": "^4.2.0",
@@ -11271,23 +12423,12 @@
       "dev": true,
       "requires": {
         "rimraf": "^3.0.0"
-      },
-      "dependencies": {
-        "rimraf": {
-          "version": "3.0.2",
-          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
-          "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
-          "dev": true,
-          "requires": {
-            "glob": "^7.1.3"
-          }
-        }
       }
     },
     "tmp-promise": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.2.tgz",
-      "integrity": "sha512-OyCLAKU1HzBjL6Ev3gxUeraJNlbNingmi8IrHHEsYH8LTmEuhvYfqvhn2F/je+mjf4N58UmZ96OMEy1JanSCpA==",
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz",
+      "integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==",
       "dev": true,
       "requires": {
         "tmp": "^0.2.0"
@@ -11317,7 +12458,7 @@
     "tr46": {
       "version": "0.0.3",
       "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
-      "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
+      "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
     },
     "trim": {
       "version": "1.0.1",
@@ -11333,7 +12474,7 @@
     "truncate-utf8-bytes": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz",
-      "integrity": "sha1-QFkjkJWS1W94pYGENLC3hInKXys=",
+      "integrity": "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==",
       "dev": true,
       "requires": {
         "utf8-byte-length": "^1.0.1"
@@ -11393,6 +12534,24 @@
       "resolved": "https://registry.npmjs.org/unfetch/-/unfetch-4.2.0.tgz",
       "integrity": "sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA=="
     },
+    "unique-filename": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz",
+      "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==",
+      "optional": true,
+      "requires": {
+        "unique-slug": "^2.0.0"
+      }
+    },
+    "unique-slug": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz",
+      "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==",
+      "optional": true,
+      "requires": {
+        "imurmurhash": "^0.1.4"
+      }
+    },
     "unique-string": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz",
@@ -11495,7 +12654,7 @@
     "utf8-byte-length": {
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz",
-      "integrity": "sha1-9F8VDExm7uloGGUFq5P8u4rWv2E=",
+      "integrity": "sha512-4+wkEYLBbWxqTahEsWrhxepcoVOJ+1z5PGIjPZxRkytcdSUaNjIjBM7Xn8E+pdSuV7SzvWovBFA54FO0JSoqhA==",
       "dev": true
     },
     "util-deprecate": {
@@ -11548,7 +12707,7 @@
     "webidl-conversions": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
-      "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
+      "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
     },
     "whatwg-fetch": {
       "version": "3.6.2",
@@ -11558,7 +12717,7 @@
     "whatwg-url": {
       "version": "5.0.0",
       "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
-      "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
+      "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
       "requires": {
         "tr46": "~0.0.3",
         "webidl-conversions": "^3.0.0"
@@ -11568,17 +12727,17 @@
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
       "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
-      "dev": true,
+      "devOptional": true,
       "requires": {
         "isexe": "^2.0.0"
       }
     },
     "wide-align": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
-      "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
+      "version": "1.1.5",
+      "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
+      "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
       "requires": {
-        "string-width": "^1.0.2 || 2"
+        "string-width": "^1.0.2 || 2 || 3 || 4"
       }
     },
     "widest-line": {
@@ -11591,9 +12750,15 @@
       },
       "dependencies": {
         "ansi-regex": {
-          "version": "5.0.1",
-          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
-          "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+          "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
+          "dev": true
+        },
+        "emoji-regex": {
+          "version": "8.0.0",
+          "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+          "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
           "dev": true
         },
         "is-fullwidth-code-point": {
@@ -11603,23 +12768,23 @@
           "dev": true
         },
         "string-width": {
-          "version": "4.2.3",
-          "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
-          "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+          "version": "4.2.2",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
+          "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==",
           "dev": true,
           "requires": {
             "emoji-regex": "^8.0.0",
             "is-fullwidth-code-point": "^3.0.0",
-            "strip-ansi": "^6.0.1"
+            "strip-ansi": "^6.0.0"
           }
         },
         "strip-ansi": {
-          "version": "6.0.1",
-          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
-          "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+          "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
           "dev": true,
           "requires": {
-            "ansi-regex": "^5.0.1"
+            "ansi-regex": "^5.0.0"
           }
         }
       }
@@ -11646,9 +12811,15 @@
       },
       "dependencies": {
         "ansi-regex": {
-          "version": "5.0.1",
-          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
-          "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+          "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
+          "dev": true
+        },
+        "emoji-regex": {
+          "version": "8.0.0",
+          "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+          "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
           "dev": true
         },
         "is-fullwidth-code-point": {
@@ -11658,23 +12829,23 @@
           "dev": true
         },
         "string-width": {
-          "version": "4.2.3",
-          "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
-          "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+          "version": "4.2.2",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
+          "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==",
           "dev": true,
           "requires": {
             "emoji-regex": "^8.0.0",
             "is-fullwidth-code-point": "^3.0.0",
-            "strip-ansi": "^6.0.1"
+            "strip-ansi": "^6.0.0"
           }
         },
         "strip-ansi": {
-          "version": "6.0.1",
-          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
-          "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+          "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
           "dev": true,
           "requires": {
-            "ansi-regex": "^5.0.1"
+            "ansi-regex": "^5.0.0"
           }
         }
       }
@@ -11718,10 +12889,11 @@
       }
     },
     "xmlbuilder": {
-      "version": "9.0.7",
-      "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
-      "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=",
-      "dev": true
+      "version": "15.1.1",
+      "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz",
+      "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==",
+      "dev": true,
+      "optional": true
     },
     "xtend": {
       "version": "2.1.2",
@@ -11744,9 +12916,9 @@
       "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
     },
     "yargs": {
-      "version": "17.2.1",
-      "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.2.1.tgz",
-      "integrity": "sha512-XfR8du6ua4K6uLGm5S6fA+FIJom/MdJcFNVY8geLlp2v8GYbOXD4EB1tPNZsRn4vBzKGMgb5DRZMeWuFc2GO8Q==",
+      "version": "17.0.1",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.0.1.tgz",
+      "integrity": "sha512-xBBulfCc8Y6gLFcrPvtqKz9hz8SO0l1Ni8GgDekvBX2ro0HRQImDGnikfc33cgzcYUSncapnNcZDjVFIH3f6KQ==",
       "dev": true,
       "requires": {
         "cliui": "^7.0.2",
@@ -11759,9 +12931,15 @@
       },
       "dependencies": {
         "ansi-regex": {
-          "version": "5.0.1",
-          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
-          "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+          "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
+          "dev": true
+        },
+        "emoji-regex": {
+          "version": "8.0.0",
+          "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+          "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
           "dev": true
         },
         "is-fullwidth-code-point": {
@@ -11771,31 +12949,31 @@
           "dev": true
         },
         "string-width": {
-          "version": "4.2.3",
-          "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
-          "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+          "version": "4.2.2",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
+          "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==",
           "dev": true,
           "requires": {
             "emoji-regex": "^8.0.0",
             "is-fullwidth-code-point": "^3.0.0",
-            "strip-ansi": "^6.0.1"
+            "strip-ansi": "^6.0.0"
           }
         },
         "strip-ansi": {
-          "version": "6.0.1",
-          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
-          "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+          "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
           "dev": true,
           "requires": {
-            "ansi-regex": "^5.0.1"
+            "ansi-regex": "^5.0.0"
           }
         }
       }
     },
     "yargs-parser": {
-      "version": "20.2.9",
-      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
-      "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
+      "version": "20.2.7",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz",
+      "integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==",
       "dev": true
     },
     "yauzl": {
diff --git a/package.json b/package.json
index 59d64bdd0d9d59fec0eb08c05532f40c2fa587e2..f5e43ff94b0bda9740506e31e107f45816e47de0 100644
--- a/package.json
+++ b/package.json
@@ -29,7 +29,7 @@
     "minimist": "^1.2.5",
     "multer": "^1.4.3",
     "semver": "^6.3.0",
-    "sqlite3": "^4.1.1",
+    "sqlite3": "^5.1.6",
     "xlsx": "^0.15.6"
   },
   "devDependencies": {