]> _ Git - fluidbook-toolbox.git/commitdiff
wip #5661 @7
authorVincent Vanwaelscappel <vincent@cubedesigners.com>
Tue, 20 Dec 2022 17:53:30 +0000 (18:53 +0100)
committerVincent Vanwaelscappel <vincent@cubedesigners.com>
Tue, 20 Dec 2022 17:53:30 +0000 (18:53 +0100)
50 files changed:
.docker/docker-compose.yml
.docker/images/php/Dockerfile
.docker/images/php/startup
app/Fluidbook/Packager/Base.php
app/Fluidbook/Packager/ChromeOS.php
app/Fluidbook/Packager/MacOS.php
app/Fluidbook/Packager/OfflineHTML.php
app/Fluidbook/Packager/Online.php
app/Fluidbook/Packager/WindowsInstaller.php
app/Fluidbook/Packager/WindowsZIP.php
app/Jobs/FluidbookCompiler.php
app/Models/FluidbookPublication.php
app/Models/FluidbookTheme.php
composer.lock
resources/fluidbookpublication/favicon/fluidbook.icns [new file with mode: 0644]
resources/fluidbookpublication/favicon/fluidbook.ico [new file with mode: 0644]
resources/fluidbookpublication/favicon/fluidbook.png [new file with mode: 0644]
resources/fluidbookpublication/packager/_ffmpeg/libffmpeg.dylib
resources/fluidbookpublication/packager/_ffmpeg/win-ia32.dll [new file with mode: 0644]
resources/fluidbookpublication/packager/_ffmpeg/win-x64.dll [new file with mode: 0644]
resources/fluidbookpublication/packager/_ffmpeg/windows-x32-ffmpeg.dll [deleted file]
resources/fluidbookpublication/packager/_ffmpeg/windows-x64-ffmpeg.dll [deleted file]
resources/fluidbookpublication/packager/_node_modules_win/child_process/README.md [new file with mode: 0644]
resources/fluidbookpublication/packager/_node_modules_win/child_process/package.json [new file with mode: 0644]
resources/fluidbookpublication/packager/_node_modules_win/fs/README.md [new file with mode: 0644]
resources/fluidbookpublication/packager/_node_modules_win/fs/package.json [new file with mode: 0644]
resources/fluidbookpublication/packager/_node_modules_win/inherits/LICENSE [new file with mode: 0644]
resources/fluidbookpublication/packager/_node_modules_win/inherits/README.md [new file with mode: 0644]
resources/fluidbookpublication/packager/_node_modules_win/inherits/inherits.js [new file with mode: 0644]
resources/fluidbookpublication/packager/_node_modules_win/inherits/inherits_browser.js [new file with mode: 0644]
resources/fluidbookpublication/packager/_node_modules_win/inherits/package.json [new file with mode: 0644]
resources/fluidbookpublication/packager/_node_modules_win/path/.npmignore [new file with mode: 0644]
resources/fluidbookpublication/packager/_node_modules_win/path/LICENSE [new file with mode: 0644]
resources/fluidbookpublication/packager/_node_modules_win/path/README.md [new file with mode: 0644]
resources/fluidbookpublication/packager/_node_modules_win/path/package.json [new file with mode: 0644]
resources/fluidbookpublication/packager/_node_modules_win/path/path.js [new file with mode: 0644]
resources/fluidbookpublication/packager/_node_modules_win/process/.eslintrc [new file with mode: 0644]
resources/fluidbookpublication/packager/_node_modules_win/process/LICENSE [new file with mode: 0644]
resources/fluidbookpublication/packager/_node_modules_win/process/README.md [new file with mode: 0644]
resources/fluidbookpublication/packager/_node_modules_win/process/browser.js [new file with mode: 0644]
resources/fluidbookpublication/packager/_node_modules_win/process/index.js [new file with mode: 0644]
resources/fluidbookpublication/packager/_node_modules_win/process/package.json [new file with mode: 0644]
resources/fluidbookpublication/packager/_node_modules_win/process/test.js [new file with mode: 0644]
resources/fluidbookpublication/packager/_node_modules_win/util/LICENSE [new file with mode: 0644]
resources/fluidbookpublication/packager/_node_modules_win/util/README.md [new file with mode: 0644]
resources/fluidbookpublication/packager/_node_modules_win/util/package.json [new file with mode: 0644]
resources/fluidbookpublication/packager/_node_modules_win/util/support/isBuffer.js [new file with mode: 0644]
resources/fluidbookpublication/packager/_node_modules_win/util/support/isBufferBrowser.js [new file with mode: 0644]
resources/fluidbookpublication/packager/_node_modules_win/util/util.js [new file with mode: 0644]
resources/fluidbookpublication/packager/fluidbook.ico [deleted file]

index bb03e38cf91886d0ece2001943bd11fe1cce7c03..341ef9949851687130e242432ec99a2d0f6ab2e2 100644 (file)
@@ -69,7 +69,6 @@ services:
       - '/home/toolbox/www/.docker/config/php.ini:/etc/php/8.1/fpm/conf.d/99-overrides.ini'
       # Files
       - '/home/extranet/share:/application/share'
-      - '/mnt:/mnt'
       - '/home/toolbox/www:/application'
       - '/home/toolbox/www/storage/app/public/:/application/public/storage/'
       - '/mnt/sshfs/godzilla/data/fluidbook/docs/:/application/protected/fluidbookpublication/docs/'
@@ -77,9 +76,6 @@ services:
       - '/data/extranet/www/fluidbook/books/working/:/application/protected/fluidbookpublication/working/'
       - '/home/extranet:/home/extranet'
       - '/data/extranet:/data/extranet'
-    tmpfs:
-      - '/tmp:uid=1001,gid=33'
-      - '/application/storage/framework:uid=1001,gid=33'
     ports:
       - '58744:8123'
       - '58745:22'
index b6b804140209e7fd71662ef6691ce0c3f1c3ea10..af5556c2783933828b7d5abe181bac5c1818a954 100644 (file)
@@ -17,7 +17,7 @@ RUN apt update && apt -y --no-install-recommends install build-essential scons m
 RUN cd /root && curl -L https://master.dl.sourceforge.net/project/nsisbi/nsisbi3.08.1/nsis-code-7336-1-NSIS-trunk.zip -o /root/nsis.zip && unzip -o /root/nsis.zip && cd /root/nsis-code-7336-1-NSIS-trunk && scons SKIPUTILS="zip2exe","NSIS Menu" && scons install SKIPUTILS="zip2exe","NSIS Menu"
 
 # Add additional repositories
-RUN curl -fsSL https://deb.nodesource.com/setup_18.x | bash -
+RUN curl -fsSL https://deb.nodesource.com/setup_19.x | bash -
 RUN sh -c 'echo "deb [arch=amd64] https://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google-chrome.list'
 RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -
 RUN echo "deb http://ppa.launchpad.net/ondrej/php/ubuntu jammy main" > /etc/apt/sources.list.d/ondrej-php.list \
@@ -69,7 +69,7 @@ RUN apt-get -y --no-install-recommends install build-essential chrpath libssl-de
 RUN apt-get -y --no-install-recommends install libreoffice
 RUN apt-get -y --no-install-recommends install lftp
 RUN apt-get -y --no-install-recommends install sshfs python3 python3-pip
-RUN apt-get -y --no-install-recommends install openssh-server rsyslog
+RUN apt-get -y --no-install-recommends install openssh-server rsyslog wine64
 
 RUN apt-get -y --no-install-recommends install locales
 RUN sed -i '/fr_FR.UTF-8/s/^# //g' /etc/locale.gen && \
@@ -79,18 +79,18 @@ ENV LANGUAGE fr_FR:fr
 ENV LC_ALL fr_FR.UTF-8
 
 RUN cd /root;wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2;tar xvjf phantomjs-2.1.1-linux-x86_64.tar.bz2;mv phantomjs-2.1.1-linux-x86_64 /usr/local/share;ln -sf /usr/local/share/phantomjs-2.1.1-linux-x86_64/bin/phantomjs /usr/local/bin
-RUN cd /root;wget https://github.com/nwutils/Web2Executable/releases/download/v0.7.1b/Web2ExeLinux-CMD.zip;unzip Web2ExeLinux-CMD.zip;mv Web2ExeLinux-CMD /usr/local/web2exe
 RUN cd /root;wget https://github.com/RazrFalcon/svgcleaner/releases/download/v0.9.5/svgcleaner_linux_x86_64_0.9.5.tar.gz; tar xvzf svgcleaner_linux_x86_64_0.9.5.tar.gz;mv svgcleaner /usr/local/bin
 
 RUN curl -L https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp -o /usr/local/bin/yt-dlp
 
 RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/doc/*
 
-RUN groupadd sudo;useradd -d /application -g www-data -G sudo -s /bin/bash -u 1001 toolbox
 ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true
-RUN npm install --unsafe-perm --global uglify-js less sass puppeteer favicons nw-builder@3.5.7
+RUN npm install --unsafe-perm --global uglify-js less sass puppeteer favicons nw-builder@^4
 RUN pip3 install font-line
 
+RUN groupadd sudo;useradd -d /application -g 33 -G sudo -s /bin/bash -u 1001 toolbox
+
 # PHP-FPM packages need a nudge to make them docker-friendly
 COPY overrides.conf /etc/php/8.1/fpm/pool.d/z-overrides.conf
 
index ec00d2c195ef6987f71dbb52dda63adfa038ba10..494a93bd6c88f1809955c89396bb4a3f948ccc68 100644 (file)
@@ -1,7 +1,9 @@
 #!/bin/sh
+
 # Set file rights
 umask 0000
 chmod -R 777 /tmp
+
 chown -R root:root /etc/sudoers.d
 chown -R toolbox:www-data /application/storage/framework
 chmod 755 /etc/ssh/*.d
index 8d0f0f29b2c4dbe4e584b809a844d6ed6b80b68b..cc0e68b9d41dad3c000ab48f3e3d1e2e66f88d01 100644 (file)
@@ -29,12 +29,16 @@ class Base extends \App\Jobs\Base
     protected $zip;
     protected $workingDir;
     protected $_clean = true;
+    /**
+     * @var int
+     */
+    protected $_time = 0;
     protected $_compileOnConstruct = false;
     public $cleanOnDestruct = true;
 
     public $zipPackage = true;
 
-    public $type = 'base';
+    public $downloadExt='zip';
 
 
     public static function package($book_id, $type, $zipPackage = true, $cleanOnDestruct = true, $options = [])
@@ -94,6 +98,7 @@ class Base extends \App\Jobs\Base
     public function __construct($book_id, $vdir = null, $options = [])
     {
 
+        $this->_time = time();
         $this->_clean = (null === $vdir);
 
         $this->book_id = $book_id;
@@ -127,15 +132,18 @@ class Base extends \App\Jobs\Base
 
     protected function packager_path($path = '')
     {
-        return protected_path('/fluidbookpublication/packager/' . ltrim($path, '/'));
+        return protected_path('fluidbookpublication/packager/' . ltrim($path, '/'));
     }
 
 
     protected function resource_path($path)
     {
-        return resource_path('/fluidbookpublication/packager/' . ltrim($path, '/'));
+        return resource_path('fluidbookpublication/packager/' . ltrim($path, '/'));
     }
 
+    /**
+     * @throws Exception
+     */
     protected function compile($forceCompile = false)
     {
         $compiler = new FluidbookCompiler($this->book, $this->scormVariant);
@@ -149,7 +157,7 @@ class Base extends \App\Jobs\Base
 
     public function makePackage($zip)
     {
-        $this->preparePackage();
+        return $this->preparePackage();
     }
 
     protected function replaceContents($str, $toReplace)
@@ -167,7 +175,16 @@ class Base extends \App\Jobs\Base
 
     protected function getBaseFile()
     {
-        return $this->type . '-' . date('Ymdhis') . '-' . $this->escapeTitle();
+        return $this->type . '-' . date('Ymdhis', $this->_time) . '-' . $this->escapeTitle();
+    }
+
+    protected function getDownloadURL($ext = '')
+    {
+        $res = '/download/' . $this->getBaseFile();
+        if ($ext != '') {
+            $res .= '.' . $ext;
+        }
+        return url('packager' . $res);
     }
 
     protected function escapeTitle()
@@ -251,12 +268,16 @@ class Base extends \App\Jobs\Base
     /**
      * @throws Exception
      */
-    protected function _compileFluidbook( $book, $dest, $hybrid = false)
+    protected function _compileFluidbook($book, $dest = null, $hybrid = false)
     {
+        if (null === $dest) {
+            $dest = $this->vdir;
+        }
+
         $compiler = new FluidbookCompiler($book, $this->scormVariant, false, "latest", null, false, false, false, null, $hybrid);
         $compiler->handle();
 
-        $rsync = new CommandLine\Rsync(rtrim($compiler->getFinalPath(),'/'), $dest, true);
+        $rsync = new CommandLine\Rsync(rtrim($compiler->getFinalPath(), '/'), $dest, true);
         $rsync->execute();
 
         $htmlFiles = array('index');
index cafdabbcfd55b20b41102983ddacab6a9e6f7a60..d778c42cacd6ee820b3098209a8e52778b9abdf5 100644 (file)
@@ -10,11 +10,13 @@ class ChromeOS extends Online
     public $type='chormeos';
     public $cleanOnDestruct=true;
 
+    public $downloadExt='crx';
+
     protected function preparePackage()
     {
         parent::preparePackage();
         $manifest = ['name' => $this->book->parametres->offlineTitle == '' ? $this->book->parametres->title : $this->book->parametres->offlineTitle,
-            'version' => '1.0.' . time(),
+            'version' => '1.0.' . $this->_time,
             'manifest_version' => 3,
             //'default_locale' => $this->book->lang,
             //'icons' => [],
@@ -40,7 +42,5 @@ class ChromeOS extends Online
         $chrome->setArg(null, $this->vdir . '/m/');
         $chrome->execute();
         $chrome->debug();
-
-        return $this->getURLBase('crx');
     }
 }
index 1dcab8f2f7dddfdf900100af70bbe4115271c8c3..f73634f1485124fe18ac231ec469f6b6fc7d9979 100644 (file)
@@ -12,6 +12,7 @@ class MacOS extends OfflineHTML
     protected $exenameMaxlength = 28;
     public $type = 'mac_exe_html';
 
+
     public function makePackage($zip)
     {
         $this->preparePackage();
index 8744fe99a063e8fc8163f3e6b547d5ed05c5bcda..1d5e4d3a66580caeb200b7161355b2fe00150531 100644 (file)
@@ -7,6 +7,7 @@ class OfflineHTML extends Online
     protected $_allowNetworking = 'internal';
     public $type = 'win_html';
 
+
     protected function copyFluidbookFiles()
     {
         parent::copyFluidbookFiles();
index cde42b4d1b28e80c6bca1c2a4307855bf7a0e1f4..7d5c61e11fa45b029dea99ddec4a98c2d60fc585 100644 (file)
@@ -17,6 +17,7 @@ class Online extends Base
     protected $_compileOnConstruct = false;
 
 
+
     protected function preparePackage()
     {
         parent::preparePackage();
index 273d421222522b120a92ee7677bcb5e39169f29f..452e04a14a9a445bf42c11010d058f1cfbe5318d 100644 (file)
@@ -12,6 +12,7 @@ class WindowsInstaller extends WindowsZIP
     protected $nsifile = 'html';
 
     public $type = 'win_ins_html';
+    public $downloadExt = 'exe';
 
 
     protected function preparePackage()
@@ -23,10 +24,9 @@ class WindowsInstaller extends WindowsZIP
 
     protected function makeNSI()
     {
-
         $winvdir = $this->getFinalPackageDir();
 
-        $locale = $this->book->translations['nsis'];
+        $locale = $this->book->getDefaultTranslations()['nsis'];
         if ($locale === 'Arabic') {
             $locale = 'English';
         }
@@ -43,53 +43,23 @@ class WindowsInstaller extends WindowsZIP
         $nsi = str_replace('$nwplatform', $this->nwplatform, $nsi);
         $nsi = str_replace('$nsisdir', '/usr/local/share/nsis', $nsi);
         $nsi = str_replace('$output', $this->getPathBase('exe'), $nsi);
-        $nsi = str_replace('$favicon', $this->_favicon(), $nsi);
+        $nsi = str_replace('$favicon', $this->theme->favicon(), $nsi);
 
         $this->nsi = $nsi;
     }
 
-    protected function _favicon()
-    {
-        $favicon = $this->vdir . 'data/favicon.ico';
-        if ($this->theme->parametres->favicon == '') {
-            $this->copy($this->resource_path('/fluidbook.ico'), $favicon);
-        } else if (!file_exists($favicon)) {
-            $pngFile = $this->co->themeAsset('favicon', $this->theme->parametres->favicon);
-            $icoFile = WS_THEMES . '/' . $this->theme->theme_id . '/favicon.ico';
-            if (!file_exists($icoFile) || filemtime($icoFile) < filemtime($pngFile) || filemtime(__FILE__) > filemtime($icoFile)) {
-                $tmp = Files::tempnam() . '.png';
-                $convert = "convert $pngFile -resize 64x64^ -gravity center $tmp";
-                `$convert`;
-
-                $icotool = new CommandLine('icotool');
-                $icotool->setArg('c');
-                $icotool->setArg('o', $icoFile);
-                $icotool->setArg(null, $tmp);
-                $icotool->execute();
-
-                unlink($tmp);
-            }
-            $this->copy($icoFile, $favicon);
-            if (!file_exists($favicon)) {
-                $this->copy($this->resource_path('fluidbook.ico'), $favicon);
-            }
-        }
-        return $favicon;
-    }
-
     public function makePackage($zip)
     {
         $this->preparePackage();
 
-        $tmp = cubeFiles::tempnam() . '.nsi';
+        $tmp = Files::tempnam() . '.nsi';
         file_put_contents($tmp, $this->nsi);
         $makensis = new CommandLine('makensis');
         $makensis->setArg(null, '-V4');
         $makensis->setArg(null, $tmp);
         $makensis->execute();
-        $makensis->debug();
         if (!file_exists($this->getPathBase('exe'))) {
-            die('Error while building the installer  : ' . $this->getPathBase('exe') . ' // ' . $makensis->commande . ' // ' . $makensis->output);
+            die('Error while building the installer  : ' . $this->getPathBase('exe'));
         }
 
         $this->signInstaller();
@@ -97,13 +67,11 @@ class WindowsInstaller extends WindowsZIP
         if (!file_exists($this->getPathBase('exe'))) {
             die('Error during the signing process : ' . $this->getPathBase('exe'));
         }
-
-        return $this->getURLBase('exe');
     }
 
     public function signInstaller()
     {
-        $this->_sign($this->getPathBase('exe'));
+        $this->_sign($this->getPathBase('exe'), true);
     }
 
     public function __destruct()
index e617ce897bc3ffde9ae187a61032806bbbeeff42..9d236fc14ab92095aabc4491adf5e66a4ad7fc48 100644 (file)
@@ -12,28 +12,34 @@ class WindowsZIP extends Base
     protected $exeName;
     protected $appName;
     protected $buildPath;
-    protected $nwplatform = 'windows-x64';
-    protected $nwversion = '0.55.0';
+    protected $nwplatform = 'win';
+    protected $arch = 'x64';
+    protected $nwversion = '0.71.0';
     protected $appversion = '';
     protected $node_platform = 'win';
     protected $exenameMaxlength = 30;
     protected $_compileOnConstruct = true;
 
+    protected $_ext = 'html';
+
     public $type = 'win_exe_html';
 
     public function __construct($book_id, $vdir = null, $options = [])
     {
         parent::__construct($book_id, $vdir, $options);
         $this->appName = '';
-        $this->appversion = '1.0.' . time();
+        $this->appversion = '1.0.' . $this->_time;
         $this->_clean = false;
 
-        if ($this->book->parametres->offlineTitle == "") {
-            $this->exeName = $this->book->book_id . '-' . trim(cubeText::str2URL(mb_substr($this->book->parametres->title, 0, $this->exenameMaxlength - 6)), '-');
-            $this->appName = $this->book->parametres->title;
+        $offlineTitle = $this->book->getSettings()->get('offlineTitle', '');
+
+        if ($offlineTitle == "") {
+            $title = $this->book->title;
+            $this->exeName = $this->book->id . '-' . trim(Text::str2URL(mb_substr($title, 0, $this->exenameMaxlength - 6)), '-');
+            $this->appName = $title;
         } else {
-            $this->exeName = trim(Text::str2URL(mb_substr($this->book->parametres->offlineTitle, 0, $this->exenameMaxlength)), '-');
-            $this->appName = $this->book->parametres->offlineTitle;
+            $this->exeName = trim(Text::str2URL(mb_substr($offlineTitle, 0, $this->exenameMaxlength)), '-');
+            $this->appName = $offlineTitle;
         }
 
         if ($this->exeName === '') {
@@ -43,45 +49,28 @@ class WindowsZIP extends Base
 
     protected function preparePackage()
     {
-
         parent::preparePackage();
-
-        $this->copyFluidbookFiles();
         $this->makeJSON();
 
-        $this->buildPath = Files::mkdir($this->packager_path('/nwbuild/' . $this->version . '/' . $this->book_id));
-
-        `umask 0000;rm -rf $this->buildPath;mkdir -p 0777 $this->buildPath;chmod -R 777 $this->vdir;mkdir -p 0777 /application/tmp;chmod -R 777 /application/tmp`;
-
-        $cl = new CommandLine('/usr/local/web2exe/web2exe-linux');
-        $cl->setSudo(true);
-        $cl->setEnv('TMPDIR', '/application/tmp');
-        $cl->setLongArgumentSeparator(' ');
-        $cl->setArg('export-to', $this->nwplatform);
-        $cl->setArg('uncompressed-folder');
-        $cl->setArg('title', $this->appName);
-        $cl->setArg('output-dir', $this->buildPath);
-        $cl->setArg('nw-version', $this->nwversion);
-        //$cl->setArg('sdk-build');
-        $cl->setArg('main', 'index.html');
-        $cl->setArg('name', $this->exeName);
-        $cl->setArg('mac-icon', $this->vdir . 'icon.icns');
-        $cl->setArg('exe-icon', $this->vdir . 'icon.ico');
-        $cl->setArg('icon', $this->vdir . 'icon.png');
-        $cl->setArg('width', 1024);
-        $cl->setArg('height', 768);
-        $cl->setArg('app-name', $this->exeName);
-        $cl->setArg('version', $this->appversion);
-        $cl->setArg('id', 'com.fluidbook.' . $this->book_id);
-        $cl->setArg('verbose');
+        $this->buildPath = Files::mkdir($this->packager_path('/nwbuild/' . $this->type . '/' . $this->book_id));
+
+        `umask 0000;sudo rm -rf $this->buildPath;mkdir -p 0777 $this->buildPath;chmod -R 777 $this->vdir;mkdir -p 0777 /application/tmp;chmod -R 777 /application/tmp`;
+
+        $cl = new CommandLine('nwbuild');
+        $cl->setArg('platform', $this->nwplatform);
+        $cl->setArg('outDir', $this->buildPath);
+        $cl->setArg('flavour', "normal");
+        $cl->setArg('version', $this->nwversion);
+        $cl->setArg('arch', $this->arch);
+        $cl->setArg('winIco', $this->vdir . 'icon.ico');
+        $cl->setArg('macIcns', $this->vdir . 'icon.icns');
         $cl->setArg(null, $this->vdir);
         $cl->execute();
-        $cl->debug();
 
-        `sudo chown -R toolbox:www-data $this->buildPath`;
+        `sudo chown -R 1001:33 $this->buildPath`;
 
         if (!file_exists($this->buildPath)) {
-            die('Error while making exe : ' . $cl->commande . ' // ' . $cl->output);
+            throw new \Exception('Error while making exe : ' . $cl->commande . ' // ' . $cl->output);
         }
 
         $this->replaceFFMpeg();
@@ -91,65 +80,73 @@ class WindowsZIP extends Base
 
     function signExe()
     {
-        $exe = $this->buildPath . '/' . $this->exeName . '/' . $this->nwplatform . '/' . $this->exeName . '.exe';
+        $exe = $this->buildPath . $this->exeName . '.exe';
         $this->_sign($exe);
     }
 
-    function _sign($exe)
+    function _sign($source, $symbolicLink = false)
     {
-        $rand = 'sign-' . rand(1000000, 9999999) . '.exe';
-        copy($exe, '/mnt/sshfs/codesign/' . $rand);
-        $cli = new CommandLine('C:/Program Files (x86)/Windows Kits/10/bin/10.0.18362.0/x64/signtool.exe');
-        $cli->setManualArg("sign /f C:/Users/vince/Documents/Cubedesigners.cer /csp \"eToken Base Cryptographic Provider\" /k \"[SafeNet Token JC 0{{TYWjZacq%hAH98}}]=54C3F1B91759268A\" /tr http://timestamp.sectigo.com /td sha256 /fd sha256 /a C:/Sign/$rand");
-        $cli->execute(new SSH2('paris.cubedesigners.com', 'vince', 'Y@mUC9mY2DOYWXkN', '22422'));
-        $cli->debug();
-        sleep(2);
-        copy('/mnt/sshfs/codesign/' . $rand, $exe);
-        unlink('/mnt/sshfs/codesign/' . $rand);
+        $rand = 'sign-' . hash_file('sha256', $source) . '.exe';
+        $distant = '/mnt/sshfs/codesign/' . $rand;
+        $local = protected_path('signedexe/' . $rand);
+        if (!file_exists($local)) {
+            `mv $source $distant`;
+            $cli = new CommandLine('C:/Program Files (x86)/Windows Kits/10/bin/10.0.18362.0/x64/signtool.exe');
+            $cli->setManualArg("sign /f C:/Users/vince/Documents/Cubedesigners.cer /csp \"eToken Base Cryptographic Provider\" /k \"[SafeNet Token JC 0{{TYWjZacq%hAH98}}]=54C3F1B91759268A\" /tr http://timestamp.sectigo.com /td sha256 /fd sha256 /a C:/Sign/$rand");
+            $cli->execute(new SSH2('paris.cubedesigners.com', 'vince', 'Y@mUC9mY2DOYWXkN', '22422'));
+            if (!stristr($cli->getOutput(), 'Successfully signed')) {
+                unlink($distant);
+                throw new \Exception('Error while signing exe ' . $rand . ' : ' . $cli->getOutput());
+            }
+            copy($distant, $local);
+            unlink($distant);
+            sleep(2);
+        }
+        if ($symbolicLink) {
+            symlink($local, $source);
+        } else {
+            copy($local, $source);
+        }
     }
 
     function replaceFFMpeg()
     {
-        copy($this->resource_path('_ffmpeg/' . $this->nwplatform . '-ffmpeg.dll'), $this->getFinalPackageDir() . '/ffmpeg.dll');
+        copy($this->resource_path('_ffmpeg/' . $this->nwplatform . '-' . $this->arch . '.dll'), $this->getFinalPackageDir() . '/ffmpeg.dll');
     }
 
+    /**
+     * @throws \Exception
+     */
     function makeJSON()
     {
-        $data = ['app_name' => $this->appName, 'main' => 'index.html', 'name' => $this->exeName, 'version' => '1.0.' . time(),
+        $data = ['app_name' => $this->appName, 'main' => 'index.html', 'name' => $this->exeName, 'version' => '1.0.' . $this->_time,
             'webkit' => [],
-            'window' => ['height' => 768, 'width' => 1024, 'title' => $this->appName, 'id' => 'main', 'icon' => 'icon.png', 'mac_icon' => 'icon.icns'],
-            'dependencies' => ['child_process' => "^1.0.2",
-                'fs' => '0.0.1-security',
-                'path' => '^0.12.7'],
+            'window' => [
+                'height' => 768,
+                'width' => 1024,
+                'title' => $this->appName,
+                'id' => 'main',
+                'icon' => 'icon.png',
+                'mac_icon' => 'icon.icns'
+            ],
+            'dependencies' =>
+                [
+                    'child_process' => "^1.0.2",
+                    'fs' => '0.0.1-security',
+                    'path' => '^0.12.7'
+                ],
         ];
 
-        if ($this->book->parametres->offlineWindowsProfilePath != '') {
-            $datadir = str_replace('%title%', $this->exeName, $this->book->parametres->offlineWindowsProfilePath);
+        $offlineWindowsProfilePath = $this->book->getSettings()->get('offlineWindowsProfilePath', '');
+        if ($offlineWindowsProfilePath != '') {
+            $datadir = str_replace('%title%', $this->exeName, $offlineWindowsProfilePath);
             $data['chromium-args'] = '--crash-dumps-dir=\'' . $datadir . '\' --user-data-dir=\'' . $datadir . '\'';
         }
 
-
-        $pngIcon = $this->vdir . '/icon.png';
-        $winIcon = $this->vdir . '/icon.ico';
-
-        $png = WS_COMPILE_ASSETS . '/fluidbook.png';
-        $ico = WS_COMPILE_ASSETS . '/fluidbook.ico';
-
-        if ($this->theme->parametres->favicon != '') {
-            if (file_exists($this->vdir . '/data/favicon.png')) {
-                $png = $this->vdir . '/data/favicon.png';
-            }
-            if (file_exists($this->vdir . '/data/favicon.ico')) {
-                $ico = $this->vdir . '/data/favicon.ico';
-            }
+        foreach (['png', 'ico', 'icns'] as $format) {
+            $this->copy($this->theme->favicon($format), $this->vdir . '/icon.' . $format);
         }
 
-        $icns = $this->vdir . '/icon.icns';
-        $this->copy($png, $pngIcon);
-        $this->copy($ico, $winIcon);
-        commonTools::pngToIcns($png, $icns);
-
-
         file_put_contents($this->vdir . '/package.json', json_encode($data));
     }
 
@@ -163,57 +160,30 @@ class WindowsZIP extends Base
 
     public function getFinalPackageDir()
     {
-        return $this->buildPath . '/' . $this->exeName . '/' . $this->nwplatform;
+        return $this->buildPath;
     }
 
     protected function compile($forceCompile = false)
     {
+        $this->initTempDir();
         // For exe version, force to export only the html5 version
         // No need to export pages with texts for this version, we are certain that svg is supported if enabled
         if ($this->book->getSettings()->get('mobileVersion') == 'html5-desktop') {
-            $this->book->getSettings()->set('mobileVersion','html5');
+            $this->book->getSettings()->set('mobileVersion', 'html5');
         }
-        $this->book->getSettings()->set('seoVersion',false);
-        $this->_compileFluidbook($this->book,null,false);
-    }
-
-    protected function copyFluidbookFiles()
-    {
-        // Copie du FB vers un répertoire temporaire
-        $cp = new CommandLine('cp');
-        $cp->setArg('R');
-        $cp->setArg('p');
-        $cp->setArg(null, WS_BOOKS . '/html5/' . $this->book->book_id . '/*');
-        $cp->setArg(null, $this->vdir);
-        $cp->execute();
+        $this->book->getSettings()->set('seoVersion', false);
 
-        $this->copyExtras();
+        $this->_compileFluidbook($this->book);
         $this->copyNodeModules();
     }
 
-    protected function copyExtras()
-    {
-
-        if ($this->book->parametres->form == 'bourbon') {
-
-            $dest = $this->vdir . '/exe';
-            if (!file_exists($dest)) {
-                mkdir($dest, 0777, true);
-            }
-            $this->copy(WS_FILES . '/bourbon/sendemail.exe', $dest . '/sendemail.exe');
-        }
-    }
-
     protected function copyNodeModules()
     {
-        $dest = $this->vdir . '/node_modules';
-        if (!file_exists($dest)) {
-            mkdir($dest, 0777, true);
-        }
+        $dest = Files::mkdir($this->vdir . '/node_modules');
         $cp = new CommandLine('cp');
         $cp->setArg('R');
         $cp->setArg('p');
-        $cp->setArg(null, WS_COMPILE_ASSETS . '/_exehtml/_node_modules_' . $this->node_platform . '/*');
+        $cp->setArg(null, $this->resource_path('_node_modules_' . $this->node_platform . '/') . '*');
         $cp->setArg(null, $dest);
         $cp->execute();
     }
index e7a14b8c5d33cfff26ecbb811b01f9f99127b549..db914458f19abdda520f320e437ba82a8d7bda2d 100644 (file)
@@ -1756,14 +1756,11 @@ height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
             $this->log('Got index vars 3');
 
             $favicon = '';
-            $faviconAsset = $this->themeAsset('favicon');
-            if ($faviconAsset) {
-                $pngFile = $faviconAsset->getPathname();
-                $faviconDir = self::generateFavicons($pngFile);
-
-                $this->vdir->copy($faviconDir . '/favicon.ico', 'data/favicon.ico');
+            if ($this->theme->hasFavicon()) {
+                $pngFile = $this->theme->favicon('png');
+                $this->vdir->copy($this->theme->favicon('ico'), 'data/favicon.ico');
                 $this->vdir->copy($pngFile, 'data/favicon.png');
-                $this->vdir->copy($faviconDir . '/apple-touch-icon.png', 'data/apple-touch-icon.png');
+                $this->vdir->copy($pngFile, 'data/apple-touch-icon.png');
 
                 $datapng = 'data:image/png;base64,' . base64_encode(file_get_contents($pngFile));
 
@@ -2081,12 +2078,7 @@ height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
     {
         $this->config->defaultLang = $this->getFluidbook()->locale;
         $l10n = FluidbookTranslate::getCompiledTranslations();
-        $l10n['default'] = $l10n[$this->config->defaultLang];
-        if ($this->getFluidbook()->translations) {
-            foreach ($this->getFluidbook()->translations as $k => $v) {
-                $l10n['default'][$k] = $v;
-            }
-        }
+        $l10n['default'] = $this->getFluidbook()->getDefaultTranslations($l10n);
         $this->config->setRaw('l10n', $l10n);
 
 
index e978a62745bd3d9e8829fbb2fc62def0df72e036..406a623eed0cedbc55641e42a90027097fe2c172 100644 (file)
@@ -401,6 +401,25 @@ class FluidbookPublication extends ToolboxSettingsModel
         return Json::decode($this->chapters, true);
     }
 
+    /**
+     * @param $l10n array|null
+     * @return array
+     */
+    public function getDefaultTranslations($l10n = null)
+    {
+        $defaultLocale = $this->locale;
+        if (null === $l10n) {
+            $l10n = FluidbookTranslate::getCompiledTranslations();
+        }
+        $res = $l10n[$defaultLocale];
+        if ($this->translations) {
+            foreach ($this->translations as $k => $v) {
+                $res[$k] = $v;
+            }
+        }
+        return $res;
+    }
+
     public function allowsDelete()
     {
         if (!can('fluidbook-publication:admin')) {
index 623ff3330340b2e57a3b440e5d14bd631e896e40..cc720381468127dffd086a348311bd02752b079a 100644 (file)
@@ -11,6 +11,8 @@ use Cubist\Backpack\Magic\EntityData;
 use Cubist\Backpack\Magic\Fields\Color;
 use Cubist\Backpack\Magic\Fields\Files;
 use Cubist\Backpack\Magic\Fields\SelectFromModel;
+use Cubist\Util\CommandLine;
+use Cubist\Util\CommandLine\Imagemagick\Ico;
 
 class FluidbookTheme extends ToolboxSettingsModel
 {
@@ -536,7 +538,8 @@ class FluidbookTheme extends ToolboxSettingsModel
         $this->addField([
             'name' => 'favicon',
             'type' => FluidbookThemeImage::class,
-            'label' => __('Icone (pour favicon et CD-ROM)'),
+            'label' => __('Icone (pour favicon, apps et exe)'),
+            'mime_types' => ['image/png'],
             'hint' => __('Image PNG de 256x256'),
             'translatable' => false,
         ]);
@@ -846,6 +849,56 @@ class FluidbookTheme extends ToolboxSettingsModel
         return $res;
     }
 
+    /**
+     * @throws \Exception
+     */
+    public function favicon($format = 'ico')
+    {
+        $supported = ['ico', 'png', 'icns'];
+        if (!in_array($format, $supported)) {
+            throw new \Exception('Unsupported format ' . $format);
+        }
+        if (!$this->hasFavicon()) {
+            return resource_path('fluidbookpublication/favicon/fluidbook.' . $format);
+        }
+        $pngSource = $this->getFirstMediaInField('favicon')->getPath();
+
+        if ($format === 'png') {
+            return $pngSource;
+        }
+        $dest = $pngSource . '.' . $format;
+        if (file_exists($dest) && filemtime($dest) >= filemtime($pngSource)) {
+            return $dest;
+        }
+        if ($format === 'ico') {
+            $ico = new Ico();
+            $ico->setSrc($pngSource);
+            $ico->setDest($dest);
+            $ico->execute();
+            if (!file_exists($dest)) {
+                return resource_path('fluidbookpublication/favicon/fluidbook.' . $format);
+            }
+            return $dest;
+        }
+        if ($format === 'icns') {
+            $png2icns = new CommandLine('png2icns');
+            $png2icns->setArg(null, $dest);
+            $png2icns->setArg(null, $pngSource);
+            $png2icns->execute();
+            if (!file_exists($dest)) {
+                return resource_path('fluidbookpublication/favicon/fluidbook.' . $format);
+            }
+            return $dest;
+        }
+
+    }
+
+    public function hasFavicon()
+    {
+        $media=$this->getFirstMediaInField('favicon');
+        return !is_null($media) && !($this->getSettings()->get('favicon', '') == '') && file_exists($media->getPath());
+    }
+
     /**
      * @return EntityData
      */
index 8b82779baf1d87fe9243713b95b499c035d781be..4a3cbe850e3d22534a06ae2999cc176d509fcb1a 100644 (file)
             "source": {
                 "type": "git",
                 "url": "git://git.cubedesigners.com/cubist_util.git",
-                "reference": "b8380231a798e59ca386aaad9dc809287f719a5f"
+                "reference": "1df8a20be9fd6d50873388d776b9b5978f32c8ca"
             },
             "dist": {
                 "type": "tar",
-                "url": "https://composer.cubedesigners.com/dist/cubist/util/cubist-util-dev-master-753514.tar",
-                "reference": "b8380231a798e59ca386aaad9dc809287f719a5f",
-                "shasum": "bea91db9297f7e89a46511b9e70c2987d5a19c95"
+                "url": "https://composer.cubedesigners.com/dist/cubist/util/cubist-util-dev-master-e00b85.tar",
+                "reference": "1df8a20be9fd6d50873388d776b9b5978f32c8ca",
+                "shasum": "24d40bb3b892638319aac870397daf0249c611c2"
             },
             "require": {
                 "cubist/net": "dev-master",
                 }
             ],
             "description": "Utilities class",
-            "time": "2022-12-09T12:04:37+00:00"
+            "time": "2022-12-20T09:18:30+00:00"
         },
         {
             "name": "cviebrock/eloquent-sluggable",
         },
         {
             "name": "doctrine/dbal",
-            "version": "3.5.1",
+            "version": "3.5.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/doctrine/dbal.git",
-                "reference": "f38ee8aaca2d58ee88653cb34a6a3880c23f38a5"
+                "reference": "63e513cebbbaf96a6795e5c5ee34d205831bfc85"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/doctrine/dbal/zipball/f38ee8aaca2d58ee88653cb34a6a3880c23f38a5",
-                "reference": "f38ee8aaca2d58ee88653cb34a6a3880c23f38a5",
+                "url": "https://api.github.com/repos/doctrine/dbal/zipball/63e513cebbbaf96a6795e5c5ee34d205831bfc85",
+                "reference": "63e513cebbbaf96a6795e5c5ee34d205831bfc85",
                 "shasum": ""
             },
             "require": {
                 "psr/log": "^1|^2|^3"
             },
             "require-dev": {
-                "doctrine/coding-standard": "10.0.0",
-                "jetbrains/phpstorm-stubs": "2022.2",
-                "phpstan/phpstan": "1.8.10",
+                "doctrine/coding-standard": "11.0.0",
+                "jetbrains/phpstorm-stubs": "2022.3",
+                "phpstan/phpstan": "1.9.2",
                 "phpstan/phpstan-strict-rules": "^1.4",
-                "phpunit/phpunit": "9.5.25",
-                "psalm/plugin-phpunit": "0.17.0",
+                "phpunit/phpunit": "9.5.27",
+                "psalm/plugin-phpunit": "0.18.4",
                 "squizlabs/php_codesniffer": "3.7.1",
                 "symfony/cache": "^5.4|^6.0",
                 "symfony/console": "^4.4|^5.4|^6.0",
-                "vimeo/psalm": "4.29.0"
+                "vimeo/psalm": "4.30.0"
             },
             "suggest": {
                 "symfony/console": "For helpful console commands such as SQL execution and import of files."
             ],
             "support": {
                 "issues": "https://github.com/doctrine/dbal/issues",
-                "source": "https://github.com/doctrine/dbal/tree/3.5.1"
+                "source": "https://github.com/doctrine/dbal/tree/3.5.2"
             },
             "funding": [
                 {
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-10-24T07:26:18+00:00"
+            "time": "2022-12-19T08:17:34+00:00"
         },
         {
             "name": "doctrine/deprecations",
             "source": {
                 "type": "git",
                 "url": "git://git.cubedesigners.com/fluidbook_tools.git",
-                "reference": "666ca2acecc063ba33cfa955c61b0f50a88b93d9"
+                "reference": "3d3de0bab52a2f3f810bbd8701f7abb3a98292a8"
             },
             "dist": {
                 "type": "tar",
-                "url": "https://composer.cubedesigners.com/dist/fluidbook/tools/fluidbook-tools-dev-master-16252e.tar",
-                "reference": "666ca2acecc063ba33cfa955c61b0f50a88b93d9",
-                "shasum": "aec3dc3a7b94dda7f24e794378066b6ebe5c3d2e"
+                "url": "https://composer.cubedesigners.com/dist/fluidbook/tools/fluidbook-tools-dev-master-64af3b.tar",
+                "reference": "3d3de0bab52a2f3f810bbd8701f7abb3a98292a8",
+                "shasum": "82785b51a8581d2ef17ac0c183a45f3c35218923"
             },
             "require": {
                 "barryvdh/laravel-debugbar": "^3.6",
                 }
             ],
             "description": "Fluidbook Tools",
-            "time": "2022-12-14T19:23:54+00:00"
+            "time": "2022-12-20T07:33:32+00:00"
         },
         {
             "name": "genealabs/laravel-model-caching",
         },
         {
             "name": "ramsey/uuid",
-            "version": "4.6.0",
+            "version": "4.7.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/ramsey/uuid.git",
-                "reference": "ad63bc700e7d021039e30ce464eba384c4a1d40f"
+                "reference": "5ed9ad582647bbc3864ef78db34bdc1afdcf9b49"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/ramsey/uuid/zipball/ad63bc700e7d021039e30ce464eba384c4a1d40f",
-                "reference": "ad63bc700e7d021039e30ce464eba384c4a1d40f",
+                "url": "https://api.github.com/repos/ramsey/uuid/zipball/5ed9ad582647bbc3864ef78db34bdc1afdcf9b49",
+                "reference": "5ed9ad582647bbc3864ef78db34bdc1afdcf9b49",
                 "shasum": ""
             },
             "require": {
                 "brick/math": "^0.8.8 || ^0.9 || ^0.10",
                 "ext-json": "*",
                 "php": "^8.0",
-                "ramsey/collection": "^1.0"
+                "ramsey/collection": "^1.2"
             },
             "replace": {
                 "rhumsaa/uuid": "self.version"
             ],
             "support": {
                 "issues": "https://github.com/ramsey/uuid/issues",
-                "source": "https://github.com/ramsey/uuid/tree/4.6.0"
+                "source": "https://github.com/ramsey/uuid/tree/4.7.0"
             },
             "funding": [
                 {
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-11-05T23:03:38+00:00"
+            "time": "2022-12-19T22:30:49+00:00"
         },
         {
             "name": "react/promise",
         },
         {
             "name": "symfony/event-dispatcher",
-            "version": "v6.2.0",
+            "version": "v6.2.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/event-dispatcher.git",
-                "reference": "9efb1618fabee89515fe031314e8ed5625f85a53"
+                "reference": "3ffeb31139b49bf6ef0bc09d1db95eac053388d1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/9efb1618fabee89515fe031314e8ed5625f85a53",
-                "reference": "9efb1618fabee89515fe031314e8ed5625f85a53",
+                "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/3ffeb31139b49bf6ef0bc09d1db95eac053388d1",
+                "reference": "3ffeb31139b49bf6ef0bc09d1db95eac053388d1",
                 "shasum": ""
             },
             "require": {
             "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/event-dispatcher/tree/v6.2.0"
+                "source": "https://github.com/symfony/event-dispatcher/tree/v6.2.2"
             },
             "funding": [
                 {
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-11-02T09:08:04+00:00"
+            "time": "2022-12-14T16:11:27+00:00"
         },
         {
             "name": "symfony/event-dispatcher-contracts",
         },
         {
             "name": "symfony/http-client",
-            "version": "v6.2.0",
+            "version": "v6.2.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/http-client.git",
-                "reference": "153540b6ed72eecdcb42dc847f8d8cf2e2516e8e"
+                "reference": "7054ad466f836309aef511789b9c697bc986d8ce"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/http-client/zipball/153540b6ed72eecdcb42dc847f8d8cf2e2516e8e",
-                "reference": "153540b6ed72eecdcb42dc847f8d8cf2e2516e8e",
+                "url": "https://api.github.com/repos/symfony/http-client/zipball/7054ad466f836309aef511789b9c697bc986d8ce",
+                "reference": "7054ad466f836309aef511789b9c697bc986d8ce",
                 "shasum": ""
             },
             "require": {
             "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/http-client/tree/v6.2.0"
+                "source": "https://github.com/symfony/http-client/tree/v6.2.2"
             },
             "funding": [
                 {
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-11-14T10:13:36+00:00"
+            "time": "2022-12-14T16:11:27+00:00"
         },
         {
             "name": "symfony/http-client-contracts",
         },
         {
             "name": "symfony/serializer",
-            "version": "v6.2.1",
+            "version": "v6.2.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/serializer.git",
-                "reference": "e7655a4697c2af2416f0abc6c9f41189ae3eaf0e"
+                "reference": "2b6a60d084e08f1ea2090f4bf33c20721ee8b7ab"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/serializer/zipball/e7655a4697c2af2416f0abc6c9f41189ae3eaf0e",
-                "reference": "e7655a4697c2af2416f0abc6c9f41189ae3eaf0e",
+                "url": "https://api.github.com/repos/symfony/serializer/zipball/2b6a60d084e08f1ea2090f4bf33c20721ee8b7ab",
+                "reference": "2b6a60d084e08f1ea2090f4bf33c20721ee8b7ab",
                 "shasum": ""
             },
             "require": {
             "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/serializer/tree/v6.2.1"
+                "source": "https://github.com/symfony/serializer/tree/v6.2.2"
             },
             "funding": [
                 {
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-12-04T18:26:13+00:00"
+            "time": "2022-12-15T14:02:21+00:00"
         },
         {
             "name": "symfony/service-contracts",
         },
         {
             "name": "symfony/string",
-            "version": "v6.2.0",
+            "version": "v6.2.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/string.git",
-                "reference": "145702685e0d12f81d755c71127bfff7582fdd36"
+                "reference": "863219fd713fa41cbcd285a79723f94672faff4d"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/string/zipball/145702685e0d12f81d755c71127bfff7582fdd36",
-                "reference": "145702685e0d12f81d755c71127bfff7582fdd36",
+                "url": "https://api.github.com/repos/symfony/string/zipball/863219fd713fa41cbcd285a79723f94672faff4d",
+                "reference": "863219fd713fa41cbcd285a79723f94672faff4d",
                 "shasum": ""
             },
             "require": {
                 "utf8"
             ],
             "support": {
-                "source": "https://github.com/symfony/string/tree/v6.2.0"
+                "source": "https://github.com/symfony/string/tree/v6.2.2"
             },
             "funding": [
                 {
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-11-30T17:13:47+00:00"
+            "time": "2022-12-14T16:11:27+00:00"
         },
         {
             "name": "symfony/translation",
-            "version": "v6.2.0",
+            "version": "v6.2.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/translation.git",
-                "reference": "c08de62caead8357244efcb809d0b1a2584f2198"
+                "reference": "3294288c335b6267eab14964bf2c46015663d93f"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/translation/zipball/c08de62caead8357244efcb809d0b1a2584f2198",
-                "reference": "c08de62caead8357244efcb809d0b1a2584f2198",
+                "url": "https://api.github.com/repos/symfony/translation/zipball/3294288c335b6267eab14964bf2c46015663d93f",
+                "reference": "3294288c335b6267eab14964bf2c46015663d93f",
                 "shasum": ""
             },
             "require": {
             "description": "Provides tools to internationalize your application",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/translation/tree/v6.2.0"
+                "source": "https://github.com/symfony/translation/tree/v6.2.2"
             },
             "funding": [
                 {
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-11-02T09:08:04+00:00"
+            "time": "2022-12-13T18:04:17+00:00"
         },
         {
             "name": "symfony/translation-contracts",
         },
         {
             "name": "symfony/yaml",
-            "version": "v6.2.0",
+            "version": "v6.2.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/yaml.git",
-                "reference": "f2570f21bd4adc3589aa3133323273995109bae0"
+                "reference": "6ed8243aa5f2cb5a57009f826b5e7fb3c4200cf3"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/yaml/zipball/f2570f21bd4adc3589aa3133323273995109bae0",
-                "reference": "f2570f21bd4adc3589aa3133323273995109bae0",
+                "url": "https://api.github.com/repos/symfony/yaml/zipball/6ed8243aa5f2cb5a57009f826b5e7fb3c4200cf3",
+                "reference": "6ed8243aa5f2cb5a57009f826b5e7fb3c4200cf3",
                 "shasum": ""
             },
             "require": {
             "description": "Loads and dumps YAML files",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/yaml/tree/v6.2.0"
+                "source": "https://github.com/symfony/yaml/tree/v6.2.2"
             },
             "funding": [
                 {
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-11-25T19:00:27+00:00"
+            "time": "2022-12-14T16:11:27+00:00"
         },
         {
             "name": "tijsverkoyen/css-to-inline-styles",
diff --git a/resources/fluidbookpublication/favicon/fluidbook.icns b/resources/fluidbookpublication/favicon/fluidbook.icns
new file mode 100644 (file)
index 0000000..6439319
Binary files /dev/null and b/resources/fluidbookpublication/favicon/fluidbook.icns differ
diff --git a/resources/fluidbookpublication/favicon/fluidbook.ico b/resources/fluidbookpublication/favicon/fluidbook.ico
new file mode 100644 (file)
index 0000000..fdaa6af
Binary files /dev/null and b/resources/fluidbookpublication/favicon/fluidbook.ico differ
diff --git a/resources/fluidbookpublication/favicon/fluidbook.png b/resources/fluidbookpublication/favicon/fluidbook.png
new file mode 100644 (file)
index 0000000..983708a
Binary files /dev/null and b/resources/fluidbookpublication/favicon/fluidbook.png differ
index 03951a7b5f579809a95be3c3aee577d0c93d2693..032318caa56908bf1e0645604a9ed78352188213 100644 (file)
Binary files a/resources/fluidbookpublication/packager/_ffmpeg/libffmpeg.dylib and b/resources/fluidbookpublication/packager/_ffmpeg/libffmpeg.dylib differ
diff --git a/resources/fluidbookpublication/packager/_ffmpeg/win-ia32.dll b/resources/fluidbookpublication/packager/_ffmpeg/win-ia32.dll
new file mode 100644 (file)
index 0000000..483ed60
Binary files /dev/null and b/resources/fluidbookpublication/packager/_ffmpeg/win-ia32.dll differ
diff --git a/resources/fluidbookpublication/packager/_ffmpeg/win-x64.dll b/resources/fluidbookpublication/packager/_ffmpeg/win-x64.dll
new file mode 100644 (file)
index 0000000..2063601
Binary files /dev/null and b/resources/fluidbookpublication/packager/_ffmpeg/win-x64.dll differ
diff --git a/resources/fluidbookpublication/packager/_ffmpeg/windows-x32-ffmpeg.dll b/resources/fluidbookpublication/packager/_ffmpeg/windows-x32-ffmpeg.dll
deleted file mode 100644 (file)
index 4d335be..0000000
Binary files a/resources/fluidbookpublication/packager/_ffmpeg/windows-x32-ffmpeg.dll and /dev/null differ
diff --git a/resources/fluidbookpublication/packager/_ffmpeg/windows-x64-ffmpeg.dll b/resources/fluidbookpublication/packager/_ffmpeg/windows-x64-ffmpeg.dll
deleted file mode 100644 (file)
index faa1b7d..0000000
Binary files a/resources/fluidbookpublication/packager/_ffmpeg/windows-x64-ffmpeg.dll and /dev/null differ
diff --git a/resources/fluidbookpublication/packager/_node_modules_win/child_process/README.md b/resources/fluidbookpublication/packager/_node_modules_win/child_process/README.md
new file mode 100644 (file)
index 0000000..5e9a74c
--- /dev/null
@@ -0,0 +1,9 @@
+# Security holding package
+
+This package name is not currently in use, but was formerly occupied
+by another package. To avoid malicious use, npm is hanging on to the
+package name, but loosely, and we'll probably give it to you if you
+want it.
+
+You may adopt this package by contacting support@npmjs.com and
+requesting the name.
diff --git a/resources/fluidbookpublication/packager/_node_modules_win/child_process/package.json b/resources/fluidbookpublication/packager/_node_modules_win/child_process/package.json
new file mode 100644 (file)
index 0000000..2f3b1c6
--- /dev/null
@@ -0,0 +1,46 @@
+{
+  "_from": "child_process",
+  "_id": "child_process@1.0.2",
+  "_inBundle": false,
+  "_integrity": "sha1-sffn/HPSXn/R1FWtyU4UODAYK1o=",
+  "_location": "/child_process",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "tag",
+    "registry": true,
+    "raw": "child_process",
+    "name": "child_process",
+    "escapedName": "child_process",
+    "rawSpec": "",
+    "saveSpec": null,
+    "fetchSpec": "latest"
+  },
+  "_requiredBy": [
+    "#USER",
+    "/"
+  ],
+  "_resolved": "https://registry.npmjs.org/child_process/-/child_process-1.0.2.tgz",
+  "_shasum": "b1f7e7fc73d25e7fd1d455adc94e143830182b5a",
+  "_spec": "child_process",
+  "_where": "C:\\Users\\Vincent\\AppData\\Local\\Bourbon-SMS\\package.nw",
+  "author": "",
+  "bugs": {
+    "url": "https://github.com/npm/security-holder/issues"
+  },
+  "bundleDependencies": false,
+  "deprecated": false,
+  "description": "This package name is not currently in use, but was formerly occupied by another package. To avoid malicious use, npm is hanging on to the package name, but loosely, and we'll probably give it to you if you want it.",
+  "homepage": "https://github.com/npm/security-holder#readme",
+  "keywords": [],
+  "license": "ISC",
+  "main": "index.js",
+  "name": "child_process",
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/npm/security-holder.git"
+  },
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "version": "1.0.2"
+}
diff --git a/resources/fluidbookpublication/packager/_node_modules_win/fs/README.md b/resources/fluidbookpublication/packager/_node_modules_win/fs/README.md
new file mode 100644 (file)
index 0000000..5e9a74c
--- /dev/null
@@ -0,0 +1,9 @@
+# Security holding package
+
+This package name is not currently in use, but was formerly occupied
+by another package. To avoid malicious use, npm is hanging on to the
+package name, but loosely, and we'll probably give it to you if you
+want it.
+
+You may adopt this package by contacting support@npmjs.com and
+requesting the name.
diff --git a/resources/fluidbookpublication/packager/_node_modules_win/fs/package.json b/resources/fluidbookpublication/packager/_node_modules_win/fs/package.json
new file mode 100644 (file)
index 0000000..68e3c1c
--- /dev/null
@@ -0,0 +1,46 @@
+{
+  "_from": "fs",
+  "_id": "fs@0.0.1-security",
+  "_inBundle": false,
+  "_integrity": "sha1-invTcYa23d84E/I4WLV+yq9eQdQ=",
+  "_location": "/fs",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "tag",
+    "registry": true,
+    "raw": "fs",
+    "name": "fs",
+    "escapedName": "fs",
+    "rawSpec": "",
+    "saveSpec": null,
+    "fetchSpec": "latest"
+  },
+  "_requiredBy": [
+    "#USER",
+    "/"
+  ],
+  "_resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz",
+  "_shasum": "8a7bd37186b6dddf3813f23858b57ecaaf5e41d4",
+  "_spec": "fs",
+  "_where": "C:\\Users\\Vincent\\AppData\\Local\\Bourbon-SMS\\package.nw",
+  "author": "",
+  "bugs": {
+    "url": "https://github.com/npm/security-holder/issues"
+  },
+  "bundleDependencies": false,
+  "deprecated": false,
+  "description": "This package name is not currently in use, but was formerly occupied by another package. To avoid malicious use, npm is hanging on to the package name, but loosely, and we'll probably give it to you if you want it.",
+  "homepage": "https://github.com/npm/security-holder#readme",
+  "keywords": [],
+  "license": "ISC",
+  "main": "index.js",
+  "name": "fs",
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/npm/security-holder.git"
+  },
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "version": "0.0.1-security"
+}
diff --git a/resources/fluidbookpublication/packager/_node_modules_win/inherits/LICENSE b/resources/fluidbookpublication/packager/_node_modules_win/inherits/LICENSE
new file mode 100644 (file)
index 0000000..dea3013
--- /dev/null
@@ -0,0 +1,16 @@
+The ISC License
+
+Copyright (c) Isaac Z. Schlueter
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
diff --git a/resources/fluidbookpublication/packager/_node_modules_win/inherits/README.md b/resources/fluidbookpublication/packager/_node_modules_win/inherits/README.md
new file mode 100644 (file)
index 0000000..b1c5665
--- /dev/null
@@ -0,0 +1,42 @@
+Browser-friendly inheritance fully compatible with standard node.js
+[inherits](http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor).
+
+This package exports standard `inherits` from node.js `util` module in
+node environment, but also provides alternative browser-friendly
+implementation through [browser
+field](https://gist.github.com/shtylman/4339901). Alternative
+implementation is a literal copy of standard one located in standalone
+module to avoid requiring of `util`. It also has a shim for old
+browsers with no `Object.create` support.
+
+While keeping you sure you are using standard `inherits`
+implementation in node.js environment, it allows bundlers such as
+[browserify](https://github.com/substack/node-browserify) to not
+include full `util` package to your client code if all you need is
+just `inherits` function. It worth, because browser shim for `util`
+package is large and `inherits` is often the single function you need
+from it.
+
+It's recommended to use this package instead of
+`require('util').inherits` for any code that has chances to be used
+not only in node.js but in browser too.
+
+## usage
+
+```js
+var inherits = require('inherits');
+// then use exactly as the standard one
+```
+
+## note on version ~1.0
+
+Version ~1.0 had completely different motivation and is not compatible
+neither with 2.0 nor with standard node.js `inherits`.
+
+If you are using version ~1.0 and planning to switch to ~2.0, be
+careful:
+
+* new version uses `super_` instead of `super` for referencing
+  superclass
+* new version overwrites current prototype while old one preserves any
+  existing fields on it
diff --git a/resources/fluidbookpublication/packager/_node_modules_win/inherits/inherits.js b/resources/fluidbookpublication/packager/_node_modules_win/inherits/inherits.js
new file mode 100644 (file)
index 0000000..3b94763
--- /dev/null
@@ -0,0 +1,7 @@
+try {
+  var util = require('util');
+  if (typeof util.inherits !== 'function') throw '';
+  module.exports = util.inherits;
+} catch (e) {
+  module.exports = require('./inherits_browser.js');
+}
diff --git a/resources/fluidbookpublication/packager/_node_modules_win/inherits/inherits_browser.js b/resources/fluidbookpublication/packager/_node_modules_win/inherits/inherits_browser.js
new file mode 100644 (file)
index 0000000..c1e78a7
--- /dev/null
@@ -0,0 +1,23 @@
+if (typeof Object.create === 'function') {
+  // implementation from standard node.js 'util' module
+  module.exports = function inherits(ctor, superCtor) {
+    ctor.super_ = superCtor
+    ctor.prototype = Object.create(superCtor.prototype, {
+      constructor: {
+        value: ctor,
+        enumerable: false,
+        writable: true,
+        configurable: true
+      }
+    });
+  };
+} else {
+  // old school shim for old browsers
+  module.exports = function inherits(ctor, superCtor) {
+    ctor.super_ = superCtor
+    var TempCtor = function () {}
+    TempCtor.prototype = superCtor.prototype
+    ctor.prototype = new TempCtor()
+    ctor.prototype.constructor = ctor
+  }
+}
diff --git a/resources/fluidbookpublication/packager/_node_modules_win/inherits/package.json b/resources/fluidbookpublication/packager/_node_modules_win/inherits/package.json
new file mode 100644 (file)
index 0000000..053573d
--- /dev/null
@@ -0,0 +1,61 @@
+{
+  "_from": "inherits@2.0.3",
+  "_id": "inherits@2.0.3",
+  "_inBundle": false,
+  "_integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+  "_location": "/inherits",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "version",
+    "registry": true,
+    "raw": "inherits@2.0.3",
+    "name": "inherits",
+    "escapedName": "inherits",
+    "rawSpec": "2.0.3",
+    "saveSpec": null,
+    "fetchSpec": "2.0.3"
+  },
+  "_requiredBy": [
+    "/util"
+  ],
+  "_resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+  "_shasum": "633c2c83e3da42a502f52466022480f4208261de",
+  "_spec": "inherits@2.0.3",
+  "_where": "C:\\Users\\Vincent\\AppData\\Local\\Bourbon-SMS\\package.nw\\node_modules\\util",
+  "browser": "./inherits_browser.js",
+  "bugs": {
+    "url": "https://github.com/isaacs/inherits/issues"
+  },
+  "bundleDependencies": false,
+  "deprecated": false,
+  "description": "Browser-friendly inheritance fully compatible with standard node.js inherits()",
+  "devDependencies": {
+    "tap": "^7.1.0"
+  },
+  "files": [
+    "inherits.js",
+    "inherits_browser.js"
+  ],
+  "homepage": "https://github.com/isaacs/inherits#readme",
+  "keywords": [
+    "inheritance",
+    "class",
+    "klass",
+    "oop",
+    "object-oriented",
+    "inherits",
+    "browser",
+    "browserify"
+  ],
+  "license": "ISC",
+  "main": "./inherits.js",
+  "name": "inherits",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/isaacs/inherits.git"
+  },
+  "scripts": {
+    "test": "node test"
+  },
+  "version": "2.0.3"
+}
diff --git a/resources/fluidbookpublication/packager/_node_modules_win/path/.npmignore b/resources/fluidbookpublication/packager/_node_modules_win/path/.npmignore
new file mode 100644 (file)
index 0000000..b512c09
--- /dev/null
@@ -0,0 +1 @@
+node_modules
\ No newline at end of file
diff --git a/resources/fluidbookpublication/packager/_node_modules_win/path/LICENSE b/resources/fluidbookpublication/packager/_node_modules_win/path/LICENSE
new file mode 100644 (file)
index 0000000..e3d4e69
--- /dev/null
@@ -0,0 +1,18 @@
+Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
diff --git a/resources/fluidbookpublication/packager/_node_modules_win/path/README.md b/resources/fluidbookpublication/packager/_node_modules_win/path/README.md
new file mode 100644 (file)
index 0000000..f5227af
--- /dev/null
@@ -0,0 +1,15 @@
+# path
+
+This is an exact copy of the NodeJS â€™path’ module published to the NPM registry. 
+
+[Documentation](http://nodejs.org/docs/latest/api/path.html)
+
+## Install
+
+```sh
+$ npm install --save path
+```
+
+## License
+
+MIT
diff --git a/resources/fluidbookpublication/packager/_node_modules_win/path/package.json b/resources/fluidbookpublication/packager/_node_modules_win/path/package.json
new file mode 100644 (file)
index 0000000..7abb368
--- /dev/null
@@ -0,0 +1,53 @@
+{
+  "_from": "path",
+  "_id": "path@0.12.7",
+  "_inBundle": false,
+  "_integrity": "sha1-1NwqUGxM4hl+tIHr/NWzbAFAsQ8=",
+  "_location": "/path",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "tag",
+    "registry": true,
+    "raw": "path",
+    "name": "path",
+    "escapedName": "path",
+    "rawSpec": "",
+    "saveSpec": null,
+    "fetchSpec": "latest"
+  },
+  "_requiredBy": [
+    "#USER",
+    "/"
+  ],
+  "_resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz",
+  "_shasum": "d4dc2a506c4ce2197eb481ebfcd5b36c0140b10f",
+  "_spec": "path",
+  "_where": "C:\\Users\\Vincent\\AppData\\Local\\Bourbon-SMS\\package.nw",
+  "author": {
+    "name": "Joyent",
+    "url": "http://www.joyent.com"
+  },
+  "bugs": {
+    "url": "https://github.com/jinder/path/issues"
+  },
+  "bundleDependencies": false,
+  "dependencies": {
+    "process": "^0.11.1",
+    "util": "^0.10.3"
+  },
+  "deprecated": false,
+  "description": "Node.JS path module",
+  "homepage": "http://nodejs.org/docs/latest/api/path.html",
+  "keywords": [
+    "ender",
+    "path"
+  ],
+  "license": "MIT",
+  "main": "./path.js",
+  "name": "path",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/jinder/path.git"
+  },
+  "version": "0.12.7"
+}
diff --git a/resources/fluidbookpublication/packager/_node_modules_win/path/path.js b/resources/fluidbookpublication/packager/_node_modules_win/path/path.js
new file mode 100644 (file)
index 0000000..937bc79
--- /dev/null
@@ -0,0 +1,628 @@
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+'use strict';
+
+
+var isWindows = process.platform === 'win32';
+var util = require('util');
+
+
+// resolves . and .. elements in a path array with directory names there
+// must be no slashes or device names (c:\) in the array
+// (so also no leading and trailing slashes - it does not distinguish
+// relative and absolute paths)
+function normalizeArray(parts, allowAboveRoot) {
+  var res = [];
+  for (var i = 0; i < parts.length; i++) {
+    var p = parts[i];
+
+    // ignore empty parts
+    if (!p || p === '.')
+      continue;
+
+    if (p === '..') {
+      if (res.length && res[res.length - 1] !== '..') {
+        res.pop();
+      } else if (allowAboveRoot) {
+        res.push('..');
+      }
+    } else {
+      res.push(p);
+    }
+  }
+
+  return res;
+}
+
+// returns an array with empty elements removed from either end of the input
+// array or the original array if no elements need to be removed
+function trimArray(arr) {
+  var lastIndex = arr.length - 1;
+  var start = 0;
+  for (; start <= lastIndex; start++) {
+    if (arr[start])
+      break;
+  }
+
+  var end = lastIndex;
+  for (; end >= 0; end--) {
+    if (arr[end])
+      break;
+  }
+
+  if (start === 0 && end === lastIndex)
+    return arr;
+  if (start > end)
+    return [];
+  return arr.slice(start, end + 1);
+}
+
+// Regex to split a windows path into three parts: [*, device, slash,
+// tail] windows-only
+var splitDeviceRe =
+    /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/;
+
+// Regex to split the tail part of the above into [*, dir, basename, ext]
+var splitTailRe =
+    /^([\s\S]*?)((?:\.{1,2}|[^\\\/]+?|)(\.[^.\/\\]*|))(?:[\\\/]*)$/;
+
+var win32 = {};
+
+// Function to split a filename into [root, dir, basename, ext]
+function win32SplitPath(filename) {
+  // Separate device+slash from tail
+  var result = splitDeviceRe.exec(filename),
+      device = (result[1] || '') + (result[2] || ''),
+      tail = result[3] || '';
+  // Split the tail into dir, basename and extension
+  var result2 = splitTailRe.exec(tail),
+      dir = result2[1],
+      basename = result2[2],
+      ext = result2[3];
+  return [device, dir, basename, ext];
+}
+
+function win32StatPath(path) {
+  var result = splitDeviceRe.exec(path),
+      device = result[1] || '',
+      isUnc = !!device && device[1] !== ':';
+  return {
+    device: device,
+    isUnc: isUnc,
+    isAbsolute: isUnc || !!result[2], // UNC paths are always absolute
+    tail: result[3]
+  };
+}
+
+function normalizeUNCRoot(device) {
+  return '\\\\' + device.replace(/^[\\\/]+/, '').replace(/[\\\/]+/g, '\\');
+}
+
+// path.resolve([from ...], to)
+win32.resolve = function() {
+  var resolvedDevice = '',
+      resolvedTail = '',
+      resolvedAbsolute = false;
+
+  for (var i = arguments.length - 1; i >= -1; i--) {
+    var path;
+    if (i >= 0) {
+      path = arguments[i];
+    } else if (!resolvedDevice) {
+      path = process.cwd();
+    } else {
+      // Windows has the concept of drive-specific current working
+      // directories. If we've resolved a drive letter but not yet an
+      // absolute path, get cwd for that drive. We're sure the device is not
+      // an unc path at this points, because unc paths are always absolute.
+      path = process.env['=' + resolvedDevice];
+      // Verify that a drive-local cwd was found and that it actually points
+      // to our drive. If not, default to the drive's root.
+      if (!path || path.substr(0, 3).toLowerCase() !==
+          resolvedDevice.toLowerCase() + '\\') {
+        path = resolvedDevice + '\\';
+      }
+    }
+
+    // Skip empty and invalid entries
+    if (!util.isString(path)) {
+      throw new TypeError('Arguments to path.resolve must be strings');
+    } else if (!path) {
+      continue;
+    }
+
+    var result = win32StatPath(path),
+        device = result.device,
+        isUnc = result.isUnc,
+        isAbsolute = result.isAbsolute,
+        tail = result.tail;
+
+    if (device &&
+        resolvedDevice &&
+        device.toLowerCase() !== resolvedDevice.toLowerCase()) {
+      // This path points to another device so it is not applicable
+      continue;
+    }
+
+    if (!resolvedDevice) {
+      resolvedDevice = device;
+    }
+    if (!resolvedAbsolute) {
+      resolvedTail = tail + '\\' + resolvedTail;
+      resolvedAbsolute = isAbsolute;
+    }
+
+    if (resolvedDevice && resolvedAbsolute) {
+      break;
+    }
+  }
+
+  // Convert slashes to backslashes when `resolvedDevice` points to an UNC
+  // root. Also squash multiple slashes into a single one where appropriate.
+  if (isUnc) {
+    resolvedDevice = normalizeUNCRoot(resolvedDevice);
+  }
+
+  // At this point the path should be resolved to a full absolute path,
+  // but handle relative paths to be safe (might happen when process.cwd()
+  // fails)
+
+  // Normalize the tail path
+  resolvedTail = normalizeArray(resolvedTail.split(/[\\\/]+/),
+                                !resolvedAbsolute).join('\\');
+
+  return (resolvedDevice + (resolvedAbsolute ? '\\' : '') + resolvedTail) ||
+         '.';
+};
+
+
+win32.normalize = function(path) {
+  var result = win32StatPath(path),
+      device = result.device,
+      isUnc = result.isUnc,
+      isAbsolute = result.isAbsolute,
+      tail = result.tail,
+      trailingSlash = /[\\\/]$/.test(tail);
+
+  // Normalize the tail path
+  tail = normalizeArray(tail.split(/[\\\/]+/), !isAbsolute).join('\\');
+
+  if (!tail && !isAbsolute) {
+    tail = '.';
+  }
+  if (tail && trailingSlash) {
+    tail += '\\';
+  }
+
+  // Convert slashes to backslashes when `device` points to an UNC root.
+  // Also squash multiple slashes into a single one where appropriate.
+  if (isUnc) {
+    device = normalizeUNCRoot(device);
+  }
+
+  return device + (isAbsolute ? '\\' : '') + tail;
+};
+
+
+win32.isAbsolute = function(path) {
+  return win32StatPath(path).isAbsolute;
+};
+
+win32.join = function() {
+  var paths = [];
+  for (var i = 0; i < arguments.length; i++) {
+    var arg = arguments[i];
+    if (!util.isString(arg)) {
+      throw new TypeError('Arguments to path.join must be strings');
+    }
+    if (arg) {
+      paths.push(arg);
+    }
+  }
+
+  var joined = paths.join('\\');
+
+  // Make sure that the joined path doesn't start with two slashes, because
+  // normalize() will mistake it for an UNC path then.
+  //
+  // This step is skipped when it is very clear that the user actually
+  // intended to point at an UNC path. This is assumed when the first
+  // non-empty string arguments starts with exactly two slashes followed by
+  // at least one more non-slash character.
+  //
+  // Note that for normalize() to treat a path as an UNC path it needs to
+  // have at least 2 components, so we don't filter for that here.
+  // This means that the user can use join to construct UNC paths from
+  // a server name and a share name; for example:
+  //   path.join('//server', 'share') -> '\\\\server\\share\')
+  if (!/^[\\\/]{2}[^\\\/]/.test(paths[0])) {
+    joined = joined.replace(/^[\\\/]{2,}/, '\\');
+  }
+
+  return win32.normalize(joined);
+};
+
+
+// path.relative(from, to)
+// it will solve the relative path from 'from' to 'to', for instance:
+// from = 'C:\\orandea\\test\\aaa'
+// to = 'C:\\orandea\\impl\\bbb'
+// The output of the function should be: '..\\..\\impl\\bbb'
+win32.relative = function(from, to) {
+  from = win32.resolve(from);
+  to = win32.resolve(to);
+
+  // windows is not case sensitive
+  var lowerFrom = from.toLowerCase();
+  var lowerTo = to.toLowerCase();
+
+  var toParts = trimArray(to.split('\\'));
+
+  var lowerFromParts = trimArray(lowerFrom.split('\\'));
+  var lowerToParts = trimArray(lowerTo.split('\\'));
+
+  var length = Math.min(lowerFromParts.length, lowerToParts.length);
+  var samePartsLength = length;
+  for (var i = 0; i < length; i++) {
+    if (lowerFromParts[i] !== lowerToParts[i]) {
+      samePartsLength = i;
+      break;
+    }
+  }
+
+  if (samePartsLength == 0) {
+    return to;
+  }
+
+  var outputParts = [];
+  for (var i = samePartsLength; i < lowerFromParts.length; i++) {
+    outputParts.push('..');
+  }
+
+  outputParts = outputParts.concat(toParts.slice(samePartsLength));
+
+  return outputParts.join('\\');
+};
+
+
+win32._makeLong = function(path) {
+  // Note: this will *probably* throw somewhere.
+  if (!util.isString(path))
+    return path;
+
+  if (!path) {
+    return '';
+  }
+
+  var resolvedPath = win32.resolve(path);
+
+  if (/^[a-zA-Z]\:\\/.test(resolvedPath)) {
+    // path is local filesystem path, which needs to be converted
+    // to long UNC path.
+    return '\\\\?\\' + resolvedPath;
+  } else if (/^\\\\[^?.]/.test(resolvedPath)) {
+    // path is network UNC path, which needs to be converted
+    // to long UNC path.
+    return '\\\\?\\UNC\\' + resolvedPath.substring(2);
+  }
+
+  return path;
+};
+
+
+win32.dirname = function(path) {
+  var result = win32SplitPath(path),
+      root = result[0],
+      dir = result[1];
+
+  if (!root && !dir) {
+    // No dirname whatsoever
+    return '.';
+  }
+
+  if (dir) {
+    // It has a dirname, strip trailing slash
+    dir = dir.substr(0, dir.length - 1);
+  }
+
+  return root + dir;
+};
+
+
+win32.basename = function(path, ext) {
+  var f = win32SplitPath(path)[2];
+  // TODO: make this comparison case-insensitive on windows?
+  if (ext && f.substr(-1 * ext.length) === ext) {
+    f = f.substr(0, f.length - ext.length);
+  }
+  return f;
+};
+
+
+win32.extname = function(path) {
+  return win32SplitPath(path)[3];
+};
+
+
+win32.format = function(pathObject) {
+  if (!util.isObject(pathObject)) {
+    throw new TypeError(
+        "Parameter 'pathObject' must be an object, not " + typeof pathObject
+    );
+  }
+
+  var root = pathObject.root || '';
+
+  if (!util.isString(root)) {
+    throw new TypeError(
+        "'pathObject.root' must be a string or undefined, not " +
+        typeof pathObject.root
+    );
+  }
+
+  var dir = pathObject.dir;
+  var base = pathObject.base || '';
+  if (!dir) {
+    return base;
+  }
+  if (dir[dir.length - 1] === win32.sep) {
+    return dir + base;
+  }
+  return dir + win32.sep + base;
+};
+
+
+win32.parse = function(pathString) {
+  if (!util.isString(pathString)) {
+    throw new TypeError(
+        "Parameter 'pathString' must be a string, not " + typeof pathString
+    );
+  }
+  var allParts = win32SplitPath(pathString);
+  if (!allParts || allParts.length !== 4) {
+    throw new TypeError("Invalid path '" + pathString + "'");
+  }
+  return {
+    root: allParts[0],
+    dir: allParts[0] + allParts[1].slice(0, -1),
+    base: allParts[2],
+    ext: allParts[3],
+    name: allParts[2].slice(0, allParts[2].length - allParts[3].length)
+  };
+};
+
+
+win32.sep = '\\';
+win32.delimiter = ';';
+
+
+// Split a filename into [root, dir, basename, ext], unix version
+// 'root' is just a slash, or nothing.
+var splitPathRe =
+    /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
+var posix = {};
+
+
+function posixSplitPath(filename) {
+  return splitPathRe.exec(filename).slice(1);
+}
+
+
+// path.resolve([from ...], to)
+// posix version
+posix.resolve = function() {
+  var resolvedPath = '',
+      resolvedAbsolute = false;
+
+  for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
+    var path = (i >= 0) ? arguments[i] : process.cwd();
+
+    // Skip empty and invalid entries
+    if (!util.isString(path)) {
+      throw new TypeError('Arguments to path.resolve must be strings');
+    } else if (!path) {
+      continue;
+    }
+
+    resolvedPath = path + '/' + resolvedPath;
+    resolvedAbsolute = path[0] === '/';
+  }
+
+  // At this point the path should be resolved to a full absolute path, but
+  // handle relative paths to be safe (might happen when process.cwd() fails)
+
+  // Normalize the path
+  resolvedPath = normalizeArray(resolvedPath.split('/'),
+                                !resolvedAbsolute).join('/');
+
+  return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
+};
+
+// path.normalize(path)
+// posix version
+posix.normalize = function(path) {
+  var isAbsolute = posix.isAbsolute(path),
+      trailingSlash = path && path[path.length - 1] === '/';
+
+  // Normalize the path
+  path = normalizeArray(path.split('/'), !isAbsolute).join('/');
+
+  if (!path && !isAbsolute) {
+    path = '.';
+  }
+  if (path && trailingSlash) {
+    path += '/';
+  }
+
+  return (isAbsolute ? '/' : '') + path;
+};
+
+// posix version
+posix.isAbsolute = function(path) {
+  return path.charAt(0) === '/';
+};
+
+// posix version
+posix.join = function() {
+  var path = '';
+  for (var i = 0; i < arguments.length; i++) {
+    var segment = arguments[i];
+    if (!util.isString(segment)) {
+      throw new TypeError('Arguments to path.join must be strings');
+    }
+    if (segment) {
+      if (!path) {
+        path += segment;
+      } else {
+        path += '/' + segment;
+      }
+    }
+  }
+  return posix.normalize(path);
+};
+
+
+// path.relative(from, to)
+// posix version
+posix.relative = function(from, to) {
+  from = posix.resolve(from).substr(1);
+  to = posix.resolve(to).substr(1);
+
+  var fromParts = trimArray(from.split('/'));
+  var toParts = trimArray(to.split('/'));
+
+  var length = Math.min(fromParts.length, toParts.length);
+  var samePartsLength = length;
+  for (var i = 0; i < length; i++) {
+    if (fromParts[i] !== toParts[i]) {
+      samePartsLength = i;
+      break;
+    }
+  }
+
+  var outputParts = [];
+  for (var i = samePartsLength; i < fromParts.length; i++) {
+    outputParts.push('..');
+  }
+
+  outputParts = outputParts.concat(toParts.slice(samePartsLength));
+
+  return outputParts.join('/');
+};
+
+
+posix._makeLong = function(path) {
+  return path;
+};
+
+
+posix.dirname = function(path) {
+  var result = posixSplitPath(path),
+      root = result[0],
+      dir = result[1];
+
+  if (!root && !dir) {
+    // No dirname whatsoever
+    return '.';
+  }
+
+  if (dir) {
+    // It has a dirname, strip trailing slash
+    dir = dir.substr(0, dir.length - 1);
+  }
+
+  return root + dir;
+};
+
+
+posix.basename = function(path, ext) {
+  var f = posixSplitPath(path)[2];
+  // TODO: make this comparison case-insensitive on windows?
+  if (ext && f.substr(-1 * ext.length) === ext) {
+    f = f.substr(0, f.length - ext.length);
+  }
+  return f;
+};
+
+
+posix.extname = function(path) {
+  return posixSplitPath(path)[3];
+};
+
+
+posix.format = function(pathObject) {
+  if (!util.isObject(pathObject)) {
+    throw new TypeError(
+        "Parameter 'pathObject' must be an object, not " + typeof pathObject
+    );
+  }
+
+  var root = pathObject.root || '';
+
+  if (!util.isString(root)) {
+    throw new TypeError(
+        "'pathObject.root' must be a string or undefined, not " +
+        typeof pathObject.root
+    );
+  }
+
+  var dir = pathObject.dir ? pathObject.dir + posix.sep : '';
+  var base = pathObject.base || '';
+  return dir + base;
+};
+
+
+posix.parse = function(pathString) {
+  if (!util.isString(pathString)) {
+    throw new TypeError(
+        "Parameter 'pathString' must be a string, not " + typeof pathString
+    );
+  }
+  var allParts = posixSplitPath(pathString);
+  if (!allParts || allParts.length !== 4) {
+    throw new TypeError("Invalid path '" + pathString + "'");
+  }
+  allParts[1] = allParts[1] || '';
+  allParts[2] = allParts[2] || '';
+  allParts[3] = allParts[3] || '';
+
+  return {
+    root: allParts[0],
+    dir: allParts[0] + allParts[1].slice(0, -1),
+    base: allParts[2],
+    ext: allParts[3],
+    name: allParts[2].slice(0, allParts[2].length - allParts[3].length)
+  };
+};
+
+
+posix.sep = '/';
+posix.delimiter = ':';
+
+
+if (isWindows)
+  module.exports = win32;
+else /* posix */
+  module.exports = posix;
+
+module.exports.posix = posix;
+module.exports.win32 = win32;
diff --git a/resources/fluidbookpublication/packager/_node_modules_win/process/.eslintrc b/resources/fluidbookpublication/packager/_node_modules_win/process/.eslintrc
new file mode 100644 (file)
index 0000000..1e7aab7
--- /dev/null
@@ -0,0 +1,21 @@
+{
+extends: "eslint:recommended",
+  "env": {
+    "node": true,
+    "browser": true,
+    "es6" : true,
+    "mocha": true
+  },
+  "rules": {
+    "indent": [2, 4],
+    "brace-style": [2, "1tbs"],
+    "quotes": [2, "single"],
+    "no-console": 0,
+    "no-shadow": 0,
+    "no-use-before-define": [2, "nofunc"],
+    "no-underscore-dangle": 0,
+    "no-constant-condition": 0,
+    "space-after-function-name": 0,
+   "consistent-return": 0
+  }
+}
diff --git a/resources/fluidbookpublication/packager/_node_modules_win/process/LICENSE b/resources/fluidbookpublication/packager/_node_modules_win/process/LICENSE
new file mode 100644 (file)
index 0000000..b8c1246
--- /dev/null
@@ -0,0 +1,22 @@
+(The MIT License)
+
+Copyright (c) 2013 Roman Shtylman <shtylman@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/resources/fluidbookpublication/packager/_node_modules_win/process/README.md b/resources/fluidbookpublication/packager/_node_modules_win/process/README.md
new file mode 100644 (file)
index 0000000..6570729
--- /dev/null
@@ -0,0 +1,26 @@
+# process
+
+```require('process');``` just like any other module.
+
+Works in node.js and browsers via the browser.js shim provided with the module.
+
+## browser implementation
+
+The goal of this module is not to be a full-fledged alternative to the builtin process module. This module mostly exists to provide the nextTick functionality and little more. We keep this module lean because it will often be included by default by tools like browserify when it detects a module has used the `process` global.
+
+It also exposes a "browser" member (i.e. `process.browser`) which is `true` in this implementation but `undefined` in node. This can be used in isomorphic code that adjusts it's behavior depending on which environment it's running in. 
+
+If you are looking to provide other process methods, I suggest you monkey patch them onto the process global in your app. A list of user created patches is below.
+
+* [hrtime](https://github.com/kumavis/browser-process-hrtime)
+* [stdout](https://github.com/kumavis/browser-stdout)
+
+## package manager notes
+
+If you are writing a bundler to package modules for client side use, make sure you use the ```browser``` field hint in package.json.
+
+See https://gist.github.com/4339901 for details.
+
+The [browserify](https://github.com/substack/node-browserify) module will properly handle this field when bundling your files.
+
+
diff --git a/resources/fluidbookpublication/packager/_node_modules_win/process/browser.js b/resources/fluidbookpublication/packager/_node_modules_win/process/browser.js
new file mode 100644 (file)
index 0000000..d059362
--- /dev/null
@@ -0,0 +1,184 @@
+// shim for using process in browser
+var process = module.exports = {};
+
+// cached from whatever global is present so that test runners that stub it
+// don't break things.  But we need to wrap it in a try catch in case it is
+// wrapped in strict mode code which doesn't define any globals.  It's inside a
+// function because try/catches deoptimize in certain engines.
+
+var cachedSetTimeout;
+var cachedClearTimeout;
+
+function defaultSetTimout() {
+    throw new Error('setTimeout has not been defined');
+}
+function defaultClearTimeout () {
+    throw new Error('clearTimeout has not been defined');
+}
+(function () {
+    try {
+        if (typeof setTimeout === 'function') {
+            cachedSetTimeout = setTimeout;
+        } else {
+            cachedSetTimeout = defaultSetTimout;
+        }
+    } catch (e) {
+        cachedSetTimeout = defaultSetTimout;
+    }
+    try {
+        if (typeof clearTimeout === 'function') {
+            cachedClearTimeout = clearTimeout;
+        } else {
+            cachedClearTimeout = defaultClearTimeout;
+        }
+    } catch (e) {
+        cachedClearTimeout = defaultClearTimeout;
+    }
+} ())
+function runTimeout(fun) {
+    if (cachedSetTimeout === setTimeout) {
+        //normal enviroments in sane situations
+        return setTimeout(fun, 0);
+    }
+    // if setTimeout wasn't available but was latter defined
+    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
+        cachedSetTimeout = setTimeout;
+        return setTimeout(fun, 0);
+    }
+    try {
+        // when when somebody has screwed with setTimeout but no I.E. maddness
+        return cachedSetTimeout(fun, 0);
+    } catch(e){
+        try {
+            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
+            return cachedSetTimeout.call(null, fun, 0);
+        } catch(e){
+            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
+            return cachedSetTimeout.call(this, fun, 0);
+        }
+    }
+
+
+}
+function runClearTimeout(marker) {
+    if (cachedClearTimeout === clearTimeout) {
+        //normal enviroments in sane situations
+        return clearTimeout(marker);
+    }
+    // if clearTimeout wasn't available but was latter defined
+    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
+        cachedClearTimeout = clearTimeout;
+        return clearTimeout(marker);
+    }
+    try {
+        // when when somebody has screwed with setTimeout but no I.E. maddness
+        return cachedClearTimeout(marker);
+    } catch (e){
+        try {
+            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally
+            return cachedClearTimeout.call(null, marker);
+        } catch (e){
+            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
+            // Some versions of I.E. have different rules for clearTimeout vs setTimeout
+            return cachedClearTimeout.call(this, marker);
+        }
+    }
+
+
+
+}
+var queue = [];
+var draining = false;
+var currentQueue;
+var queueIndex = -1;
+
+function cleanUpNextTick() {
+    if (!draining || !currentQueue) {
+        return;
+    }
+    draining = false;
+    if (currentQueue.length) {
+        queue = currentQueue.concat(queue);
+    } else {
+        queueIndex = -1;
+    }
+    if (queue.length) {
+        drainQueue();
+    }
+}
+
+function drainQueue() {
+    if (draining) {
+        return;
+    }
+    var timeout = runTimeout(cleanUpNextTick);
+    draining = true;
+
+    var len = queue.length;
+    while(len) {
+        currentQueue = queue;
+        queue = [];
+        while (++queueIndex < len) {
+            if (currentQueue) {
+                currentQueue[queueIndex].run();
+            }
+        }
+        queueIndex = -1;
+        len = queue.length;
+    }
+    currentQueue = null;
+    draining = false;
+    runClearTimeout(timeout);
+}
+
+process.nextTick = function (fun) {
+    var args = new Array(arguments.length - 1);
+    if (arguments.length > 1) {
+        for (var i = 1; i < arguments.length; i++) {
+            args[i - 1] = arguments[i];
+        }
+    }
+    queue.push(new Item(fun, args));
+    if (queue.length === 1 && !draining) {
+        runTimeout(drainQueue);
+    }
+};
+
+// v8 likes predictible objects
+function Item(fun, array) {
+    this.fun = fun;
+    this.array = array;
+}
+Item.prototype.run = function () {
+    this.fun.apply(null, this.array);
+};
+process.title = 'browser';
+process.browser = true;
+process.env = {};
+process.argv = [];
+process.version = ''; // empty string to avoid regexp issues
+process.versions = {};
+
+function noop() {}
+
+process.on = noop;
+process.addListener = noop;
+process.once = noop;
+process.off = noop;
+process.removeListener = noop;
+process.removeAllListeners = noop;
+process.emit = noop;
+process.prependListener = noop;
+process.prependOnceListener = noop;
+
+process.listeners = function (name) { return [] }
+
+process.binding = function (name) {
+    throw new Error('process.binding is not supported');
+};
+
+process.cwd = function () { return '/' };
+process.chdir = function (dir) {
+    throw new Error('process.chdir is not supported');
+};
+process.umask = function() { return 0; };
diff --git a/resources/fluidbookpublication/packager/_node_modules_win/process/index.js b/resources/fluidbookpublication/packager/_node_modules_win/process/index.js
new file mode 100644 (file)
index 0000000..8d8ed7d
--- /dev/null
@@ -0,0 +1,2 @@
+// for now just expose the builtin process global from node.js
+module.exports = global.process;
diff --git a/resources/fluidbookpublication/packager/_node_modules_win/process/package.json b/resources/fluidbookpublication/packager/_node_modules_win/process/package.json
new file mode 100644 (file)
index 0000000..48de213
--- /dev/null
@@ -0,0 +1,59 @@
+{
+  "_from": "process@^0.11.1",
+  "_id": "process@0.11.10",
+  "_inBundle": false,
+  "_integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=",
+  "_location": "/process",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "range",
+    "registry": true,
+    "raw": "process@^0.11.1",
+    "name": "process",
+    "escapedName": "process",
+    "rawSpec": "^0.11.1",
+    "saveSpec": null,
+    "fetchSpec": "^0.11.1"
+  },
+  "_requiredBy": [
+    "/path"
+  ],
+  "_resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
+  "_shasum": "7332300e840161bda3e69a1d1d91a7d4bc16f182",
+  "_spec": "process@^0.11.1",
+  "_where": "C:\\Users\\Vincent\\AppData\\Local\\Bourbon-SMS\\package.nw\\node_modules\\path",
+  "author": {
+    "name": "Roman Shtylman",
+    "email": "shtylman@gmail.com"
+  },
+  "browser": "./browser.js",
+  "bugs": {
+    "url": "https://github.com/shtylman/node-process/issues"
+  },
+  "bundleDependencies": false,
+  "deprecated": false,
+  "description": "process information for node.js and browsers",
+  "devDependencies": {
+    "mocha": "2.2.1",
+    "zuul": "^3.10.3"
+  },
+  "engines": {
+    "node": ">= 0.6.0"
+  },
+  "homepage": "https://github.com/shtylman/node-process#readme",
+  "keywords": [
+    "process"
+  ],
+  "license": "MIT",
+  "main": "./index.js",
+  "name": "process",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/shtylman/node-process.git"
+  },
+  "scripts": {
+    "browser": "zuul --no-coverage --ui mocha-bdd --local 8080 -- test.js",
+    "test": "mocha test.js"
+  },
+  "version": "0.11.10"
+}
diff --git a/resources/fluidbookpublication/packager/_node_modules_win/process/test.js b/resources/fluidbookpublication/packager/_node_modules_win/process/test.js
new file mode 100644 (file)
index 0000000..8ba579c
--- /dev/null
@@ -0,0 +1,199 @@
+var assert = require('assert');
+var ourProcess = require('./browser');
+describe('test against our process', function () {
+    test(ourProcess);
+});
+if (!process.browser) {
+  describe('test against node', function () {
+    test(process);
+  });
+  vmtest();
+}
+function test (ourProcess) {
+    describe('test arguments', function () {
+        it ('works', function (done) {
+          var order = 0;
+
+
+          ourProcess.nextTick(function (num) {
+              assert.equal(num, order++, 'first one works');
+              ourProcess.nextTick(function (num) {
+                assert.equal(num, order++, 'recursive one is 4th');
+              }, 3);
+          }, 0);
+          ourProcess.nextTick(function (num) {
+              assert.equal(num, order++, 'second one starts');
+              ourProcess.nextTick(function (num) {
+                assert.equal(num, order++, 'this is third');
+                ourProcess.nextTick(function (num) {
+                    assert.equal(num, order++, 'this is last');
+                    done();
+                }, 5);
+            }, 4);
+          }, 1);
+          ourProcess.nextTick(function (num) {
+
+              assert.equal(num, order++, '3rd schedualed happens after the error');
+          }, 2);
+        });
+    });
+if (!process.browser) {
+    describe('test errors', function (t) {
+        it ('works', function (done) {
+        var order = 0;
+        process.removeAllListeners('uncaughtException');
+        process.once('uncaughtException', function(err) {
+            assert.equal(2, order++, 'error is third');
+            ourProcess.nextTick(function () {
+                assert.equal(5, order++, 'schedualed in error is last');
+                done();
+            });
+        });
+        ourProcess.nextTick(function () {
+            assert.equal(0, order++, 'first one works');
+            ourProcess.nextTick(function () {
+            assert.equal(4, order++, 'recursive one is 4th');
+            });
+        });
+        ourProcess.nextTick(function () {
+            assert.equal(1, order++, 'second one starts');
+            throw(new Error('an error is thrown'));
+        });
+        ourProcess.nextTick(function () {
+            assert.equal(3, order++, '3rd schedualed happens after the error');
+        });
+        });
+    });
+}
+    describe('rename globals', function (t) {
+      var oldTimeout = setTimeout;
+      var oldClear = clearTimeout;
+
+      it('clearTimeout', function (done){
+
+        var ok = true;
+        clearTimeout = function () {
+          ok = false;
+        }
+        var ran = false;
+        function cleanup() {
+          clearTimeout = oldClear;
+          var err;
+          try {
+            assert.ok(ok, 'fake clearTimeout ran');
+            assert.ok(ran, 'should have run');
+          } catch (e) {
+            err = e;
+          }
+          done(err);
+        }
+        setTimeout(cleanup, 1000);
+        ourProcess.nextTick(function () {
+          ran = true;
+        });
+      });
+      it('just setTimeout', function (done){
+
+
+        setTimeout = function () {
+          setTimeout = oldTimeout;
+          try {
+            assert.ok(false, 'fake setTimeout called')
+          } catch (e) {
+            done(e);
+          }
+
+        }
+
+        ourProcess.nextTick(function () {
+          setTimeout = oldTimeout;
+          done();
+        });
+      });
+    });
+}
+function vmtest() {
+  var vm = require('vm');
+  var fs = require('fs');
+  var process =  fs.readFileSync('./browser.js', {encoding: 'utf8'});
+
+
+  describe('should work in vm in strict mode with no globals', function () {
+    it('should parse', function (done) {
+      var str = '"use strict";var module = {exports:{}};';
+      str += process;
+      str += 'this.works = process.browser;';
+      var script = new vm.Script(str);
+      var context = {
+        works: false
+      };
+      script.runInNewContext(context);
+      assert.ok(context.works);
+      done();
+    });
+    it('setTimeout throws error', function (done) {
+      var str = '"use strict";var module = {exports:{}};';
+      str += process;
+      str += 'try {process.nextTick(function () {})} catch (e){this.works = e;}';
+      var script = new vm.Script(str);
+      var context = {
+        works: false
+      };
+      script.runInNewContext(context);
+      assert.ok(context.works);
+      done();
+    });
+    it('should generally work', function (done) {
+      var str = '"use strict";var module = {exports:{}};';
+      str += process;
+      str += 'process.nextTick(function () {assert.ok(true);done();})';
+      var script = new vm.Script(str);
+      var context = {
+        clearTimeout: clearTimeout,
+        setTimeout: setTimeout,
+        done: done,
+        assert: assert
+      };
+      script.runInNewContext(context);
+    });
+    it('late defs setTimeout', function (done) {
+      var str = '"use strict";var module = {exports:{}};';
+      str += process;
+      str += 'var setTimeout = hiddenSetTimeout;process.nextTick(function () {assert.ok(true);done();})';
+      var script = new vm.Script(str);
+      var context = {
+        clearTimeout: clearTimeout,
+        hiddenSetTimeout: setTimeout,
+        done: done,
+        assert: assert
+      };
+      script.runInNewContext(context);
+    });
+    it('late defs clearTimeout', function (done) {
+      var str = '"use strict";var module = {exports:{}};';
+      str += process;
+      str += 'var clearTimeout = hiddenClearTimeout;process.nextTick(function () {assert.ok(true);done();})';
+      var script = new vm.Script(str);
+      var context = {
+        hiddenClearTimeout: clearTimeout,
+        setTimeout: setTimeout,
+        done: done,
+        assert: assert
+      };
+      script.runInNewContext(context);
+    });
+    it('late defs setTimeout and then redefine', function (done) {
+      var str = '"use strict";var module = {exports:{}};';
+      str += process;
+      str += 'var setTimeout = hiddenSetTimeout;process.nextTick(function () {setTimeout = function (){throw new Error("foo")};hiddenSetTimeout(function(){process.nextTick(function (){assert.ok(true);done();});});});';
+      var script = new vm.Script(str);
+      var context = {
+        clearTimeout: clearTimeout,
+        hiddenSetTimeout: setTimeout,
+        done: done,
+        assert: assert
+      };
+      script.runInNewContext(context);
+    });
+  });
+}
diff --git a/resources/fluidbookpublication/packager/_node_modules_win/util/LICENSE b/resources/fluidbookpublication/packager/_node_modules_win/util/LICENSE
new file mode 100644 (file)
index 0000000..e3d4e69
--- /dev/null
@@ -0,0 +1,18 @@
+Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
diff --git a/resources/fluidbookpublication/packager/_node_modules_win/util/README.md b/resources/fluidbookpublication/packager/_node_modules_win/util/README.md
new file mode 100644 (file)
index 0000000..1c473d2
--- /dev/null
@@ -0,0 +1,15 @@
+# util
+
+[![Build Status](https://travis-ci.org/defunctzombie/node-util.png?branch=master)](https://travis-ci.org/defunctzombie/node-util)
+
+node.js [util](http://nodejs.org/api/util.html) module as a module
+
+## install via [npm](npmjs.org)
+
+```shell
+npm install util
+```
+
+## browser support
+
+This module also works in modern browsers. If you need legacy browser support you will need to polyfill ES5 features.
diff --git a/resources/fluidbookpublication/packager/_node_modules_win/util/package.json b/resources/fluidbookpublication/packager/_node_modules_win/util/package.json
new file mode 100644 (file)
index 0000000..70abc20
--- /dev/null
@@ -0,0 +1,63 @@
+{
+  "_from": "util@^0.10.3",
+  "_id": "util@0.10.4",
+  "_inBundle": false,
+  "_integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==",
+  "_location": "/util",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "range",
+    "registry": true,
+    "raw": "util@^0.10.3",
+    "name": "util",
+    "escapedName": "util",
+    "rawSpec": "^0.10.3",
+    "saveSpec": null,
+    "fetchSpec": "^0.10.3"
+  },
+  "_requiredBy": [
+    "/path"
+  ],
+  "_resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz",
+  "_shasum": "3aa0125bfe668a4672de58857d3ace27ecb76901",
+  "_spec": "util@^0.10.3",
+  "_where": "C:\\Users\\Vincent\\AppData\\Local\\Bourbon-SMS\\package.nw\\node_modules\\path",
+  "author": {
+    "name": "Joyent",
+    "url": "http://www.joyent.com"
+  },
+  "browser": {
+    "./support/isBuffer.js": "./support/isBufferBrowser.js"
+  },
+  "bugs": {
+    "url": "https://github.com/defunctzombie/node-util/issues"
+  },
+  "bundleDependencies": false,
+  "dependencies": {
+    "inherits": "2.0.3"
+  },
+  "deprecated": false,
+  "description": "Node.JS util module",
+  "devDependencies": {
+    "zuul": "~1.0.9"
+  },
+  "files": [
+    "util.js",
+    "support"
+  ],
+  "homepage": "https://github.com/defunctzombie/node-util",
+  "keywords": [
+    "util"
+  ],
+  "license": "MIT",
+  "main": "./util.js",
+  "name": "util",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/defunctzombie/node-util.git"
+  },
+  "scripts": {
+    "test": "node test/node/*.js && zuul test/browser/*.js"
+  },
+  "version": "0.10.4"
+}
diff --git a/resources/fluidbookpublication/packager/_node_modules_win/util/support/isBuffer.js b/resources/fluidbookpublication/packager/_node_modules_win/util/support/isBuffer.js
new file mode 100644 (file)
index 0000000..ace9ac0
--- /dev/null
@@ -0,0 +1,3 @@
+module.exports = function isBuffer(arg) {
+  return arg instanceof Buffer;
+}
diff --git a/resources/fluidbookpublication/packager/_node_modules_win/util/support/isBufferBrowser.js b/resources/fluidbookpublication/packager/_node_modules_win/util/support/isBufferBrowser.js
new file mode 100644 (file)
index 0000000..0e1bee1
--- /dev/null
@@ -0,0 +1,6 @@
+module.exports = function isBuffer(arg) {
+  return arg && typeof arg === 'object'
+    && typeof arg.copy === 'function'
+    && typeof arg.fill === 'function'
+    && typeof arg.readUInt8 === 'function';
+}
\ No newline at end of file
diff --git a/resources/fluidbookpublication/packager/_node_modules_win/util/util.js b/resources/fluidbookpublication/packager/_node_modules_win/util/util.js
new file mode 100644 (file)
index 0000000..e0ea321
--- /dev/null
@@ -0,0 +1,586 @@
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+var formatRegExp = /%[sdj%]/g;
+exports.format = function(f) {
+  if (!isString(f)) {
+    var objects = [];
+    for (var i = 0; i < arguments.length; i++) {
+      objects.push(inspect(arguments[i]));
+    }
+    return objects.join(' ');
+  }
+
+  var i = 1;
+  var args = arguments;
+  var len = args.length;
+  var str = String(f).replace(formatRegExp, function(x) {
+    if (x === '%%') return '%';
+    if (i >= len) return x;
+    switch (x) {
+      case '%s': return String(args[i++]);
+      case '%d': return Number(args[i++]);
+      case '%j':
+        try {
+          return JSON.stringify(args[i++]);
+        } catch (_) {
+          return '[Circular]';
+        }
+      default:
+        return x;
+    }
+  });
+  for (var x = args[i]; i < len; x = args[++i]) {
+    if (isNull(x) || !isObject(x)) {
+      str += ' ' + x;
+    } else {
+      str += ' ' + inspect(x);
+    }
+  }
+  return str;
+};
+
+
+// Mark that a method should not be used.
+// Returns a modified function which warns once by default.
+// If --no-deprecation is set, then it is a no-op.
+exports.deprecate = function(fn, msg) {
+  // Allow for deprecating things in the process of starting up.
+  if (isUndefined(global.process)) {
+    return function() {
+      return exports.deprecate(fn, msg).apply(this, arguments);
+    };
+  }
+
+  if (process.noDeprecation === true) {
+    return fn;
+  }
+
+  var warned = false;
+  function deprecated() {
+    if (!warned) {
+      if (process.throwDeprecation) {
+        throw new Error(msg);
+      } else if (process.traceDeprecation) {
+        console.trace(msg);
+      } else {
+        console.error(msg);
+      }
+      warned = true;
+    }
+    return fn.apply(this, arguments);
+  }
+
+  return deprecated;
+};
+
+
+var debugs = {};
+var debugEnviron;
+exports.debuglog = function(set) {
+  if (isUndefined(debugEnviron))
+    debugEnviron = process.env.NODE_DEBUG || '';
+  set = set.toUpperCase();
+  if (!debugs[set]) {
+    if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
+      var pid = process.pid;
+      debugs[set] = function() {
+        var msg = exports.format.apply(exports, arguments);
+        console.error('%s %d: %s', set, pid, msg);
+      };
+    } else {
+      debugs[set] = function() {};
+    }
+  }
+  return debugs[set];
+};
+
+
+/**
+ * Echos the value of a value. Trys to print the value out
+ * in the best way possible given the different types.
+ *
+ * @param {Object} obj The object to print out.
+ * @param {Object} opts Optional options object that alters the output.
+ */
+/* legacy: obj, showHidden, depth, colors*/
+function inspect(obj, opts) {
+  // default options
+  var ctx = {
+    seen: [],
+    stylize: stylizeNoColor
+  };
+  // legacy...
+  if (arguments.length >= 3) ctx.depth = arguments[2];
+  if (arguments.length >= 4) ctx.colors = arguments[3];
+  if (isBoolean(opts)) {
+    // legacy...
+    ctx.showHidden = opts;
+  } else if (opts) {
+    // got an "options" object
+    exports._extend(ctx, opts);
+  }
+  // set default options
+  if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
+  if (isUndefined(ctx.depth)) ctx.depth = 2;
+  if (isUndefined(ctx.colors)) ctx.colors = false;
+  if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
+  if (ctx.colors) ctx.stylize = stylizeWithColor;
+  return formatValue(ctx, obj, ctx.depth);
+}
+exports.inspect = inspect;
+
+
+// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
+inspect.colors = {
+  'bold' : [1, 22],
+  'italic' : [3, 23],
+  'underline' : [4, 24],
+  'inverse' : [7, 27],
+  'white' : [37, 39],
+  'grey' : [90, 39],
+  'black' : [30, 39],
+  'blue' : [34, 39],
+  'cyan' : [36, 39],
+  'green' : [32, 39],
+  'magenta' : [35, 39],
+  'red' : [31, 39],
+  'yellow' : [33, 39]
+};
+
+// Don't use 'blue' not visible on cmd.exe
+inspect.styles = {
+  'special': 'cyan',
+  'number': 'yellow',
+  'boolean': 'yellow',
+  'undefined': 'grey',
+  'null': 'bold',
+  'string': 'green',
+  'date': 'magenta',
+  // "name": intentionally not styling
+  'regexp': 'red'
+};
+
+
+function stylizeWithColor(str, styleType) {
+  var style = inspect.styles[styleType];
+
+  if (style) {
+    return '\u001b[' + inspect.colors[style][0] + 'm' + str +
+           '\u001b[' + inspect.colors[style][1] + 'm';
+  } else {
+    return str;
+  }
+}
+
+
+function stylizeNoColor(str, styleType) {
+  return str;
+}
+
+
+function arrayToHash(array) {
+  var hash = {};
+
+  array.forEach(function(val, idx) {
+    hash[val] = true;
+  });
+
+  return hash;
+}
+
+
+function formatValue(ctx, value, recurseTimes) {
+  // Provide a hook for user-specified inspect functions.
+  // Check that value is an object with an inspect function on it
+  if (ctx.customInspect &&
+      value &&
+      isFunction(value.inspect) &&
+      // Filter out the util module, it's inspect function is special
+      value.inspect !== exports.inspect &&
+      // Also filter out any prototype objects using the circular check.
+      !(value.constructor && value.constructor.prototype === value)) {
+    var ret = value.inspect(recurseTimes, ctx);
+    if (!isString(ret)) {
+      ret = formatValue(ctx, ret, recurseTimes);
+    }
+    return ret;
+  }
+
+  // Primitive types cannot have properties
+  var primitive = formatPrimitive(ctx, value);
+  if (primitive) {
+    return primitive;
+  }
+
+  // Look up the keys of the object.
+  var keys = Object.keys(value);
+  var visibleKeys = arrayToHash(keys);
+
+  if (ctx.showHidden) {
+    keys = Object.getOwnPropertyNames(value);
+  }
+
+  // IE doesn't make error fields non-enumerable
+  // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
+  if (isError(value)
+      && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
+    return formatError(value);
+  }
+
+  // Some type of object without properties can be shortcutted.
+  if (keys.length === 0) {
+    if (isFunction(value)) {
+      var name = value.name ? ': ' + value.name : '';
+      return ctx.stylize('[Function' + name + ']', 'special');
+    }
+    if (isRegExp(value)) {
+      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
+    }
+    if (isDate(value)) {
+      return ctx.stylize(Date.prototype.toString.call(value), 'date');
+    }
+    if (isError(value)) {
+      return formatError(value);
+    }
+  }
+
+  var base = '', array = false, braces = ['{', '}'];
+
+  // Make Array say that they are Array
+  if (isArray(value)) {
+    array = true;
+    braces = ['[', ']'];
+  }
+
+  // Make functions say that they are functions
+  if (isFunction(value)) {
+    var n = value.name ? ': ' + value.name : '';
+    base = ' [Function' + n + ']';
+  }
+
+  // Make RegExps say that they are RegExps
+  if (isRegExp(value)) {
+    base = ' ' + RegExp.prototype.toString.call(value);
+  }
+
+  // Make dates with properties first say the date
+  if (isDate(value)) {
+    base = ' ' + Date.prototype.toUTCString.call(value);
+  }
+
+  // Make error with message first say the error
+  if (isError(value)) {
+    base = ' ' + formatError(value);
+  }
+
+  if (keys.length === 0 && (!array || value.length == 0)) {
+    return braces[0] + base + braces[1];
+  }
+
+  if (recurseTimes < 0) {
+    if (isRegExp(value)) {
+      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
+    } else {
+      return ctx.stylize('[Object]', 'special');
+    }
+  }
+
+  ctx.seen.push(value);
+
+  var output;
+  if (array) {
+    output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
+  } else {
+    output = keys.map(function(key) {
+      return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
+    });
+  }
+
+  ctx.seen.pop();
+
+  return reduceToSingleString(output, base, braces);
+}
+
+
+function formatPrimitive(ctx, value) {
+  if (isUndefined(value))
+    return ctx.stylize('undefined', 'undefined');
+  if (isString(value)) {
+    var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
+                                             .replace(/'/g, "\\'")
+                                             .replace(/\\"/g, '"') + '\'';
+    return ctx.stylize(simple, 'string');
+  }
+  if (isNumber(value))
+    return ctx.stylize('' + value, 'number');
+  if (isBoolean(value))
+    return ctx.stylize('' + value, 'boolean');
+  // For some reason typeof null is "object", so special case here.
+  if (isNull(value))
+    return ctx.stylize('null', 'null');
+}
+
+
+function formatError(value) {
+  return '[' + Error.prototype.toString.call(value) + ']';
+}
+
+
+function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
+  var output = [];
+  for (var i = 0, l = value.length; i < l; ++i) {
+    if (hasOwnProperty(value, String(i))) {
+      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
+          String(i), true));
+    } else {
+      output.push('');
+    }
+  }
+  keys.forEach(function(key) {
+    if (!key.match(/^\d+$/)) {
+      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
+          key, true));
+    }
+  });
+  return output;
+}
+
+
+function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
+  var name, str, desc;
+  desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
+  if (desc.get) {
+    if (desc.set) {
+      str = ctx.stylize('[Getter/Setter]', 'special');
+    } else {
+      str = ctx.stylize('[Getter]', 'special');
+    }
+  } else {
+    if (desc.set) {
+      str = ctx.stylize('[Setter]', 'special');
+    }
+  }
+  if (!hasOwnProperty(visibleKeys, key)) {
+    name = '[' + key + ']';
+  }
+  if (!str) {
+    if (ctx.seen.indexOf(desc.value) < 0) {
+      if (isNull(recurseTimes)) {
+        str = formatValue(ctx, desc.value, null);
+      } else {
+        str = formatValue(ctx, desc.value, recurseTimes - 1);
+      }
+      if (str.indexOf('\n') > -1) {
+        if (array) {
+          str = str.split('\n').map(function(line) {
+            return '  ' + line;
+          }).join('\n').substr(2);
+        } else {
+          str = '\n' + str.split('\n').map(function(line) {
+            return '   ' + line;
+          }).join('\n');
+        }
+      }
+    } else {
+      str = ctx.stylize('[Circular]', 'special');
+    }
+  }
+  if (isUndefined(name)) {
+    if (array && key.match(/^\d+$/)) {
+      return str;
+    }
+    name = JSON.stringify('' + key);
+    if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
+      name = name.substr(1, name.length - 2);
+      name = ctx.stylize(name, 'name');
+    } else {
+      name = name.replace(/'/g, "\\'")
+                 .replace(/\\"/g, '"')
+                 .replace(/(^"|"$)/g, "'");
+      name = ctx.stylize(name, 'string');
+    }
+  }
+
+  return name + ': ' + str;
+}
+
+
+function reduceToSingleString(output, base, braces) {
+  var numLinesEst = 0;
+  var length = output.reduce(function(prev, cur) {
+    numLinesEst++;
+    if (cur.indexOf('\n') >= 0) numLinesEst++;
+    return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
+  }, 0);
+
+  if (length > 60) {
+    return braces[0] +
+           (base === '' ? '' : base + '\n ') +
+           ' ' +
+           output.join(',\n  ') +
+           ' ' +
+           braces[1];
+  }
+
+  return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
+}
+
+
+// NOTE: These type checking functions intentionally don't use `instanceof`
+// because it is fragile and can be easily faked with `Object.create()`.
+function isArray(ar) {
+  return Array.isArray(ar);
+}
+exports.isArray = isArray;
+
+function isBoolean(arg) {
+  return typeof arg === 'boolean';
+}
+exports.isBoolean = isBoolean;
+
+function isNull(arg) {
+  return arg === null;
+}
+exports.isNull = isNull;
+
+function isNullOrUndefined(arg) {
+  return arg == null;
+}
+exports.isNullOrUndefined = isNullOrUndefined;
+
+function isNumber(arg) {
+  return typeof arg === 'number';
+}
+exports.isNumber = isNumber;
+
+function isString(arg) {
+  return typeof arg === 'string';
+}
+exports.isString = isString;
+
+function isSymbol(arg) {
+  return typeof arg === 'symbol';
+}
+exports.isSymbol = isSymbol;
+
+function isUndefined(arg) {
+  return arg === void 0;
+}
+exports.isUndefined = isUndefined;
+
+function isRegExp(re) {
+  return isObject(re) && objectToString(re) === '[object RegExp]';
+}
+exports.isRegExp = isRegExp;
+
+function isObject(arg) {
+  return typeof arg === 'object' && arg !== null;
+}
+exports.isObject = isObject;
+
+function isDate(d) {
+  return isObject(d) && objectToString(d) === '[object Date]';
+}
+exports.isDate = isDate;
+
+function isError(e) {
+  return isObject(e) &&
+      (objectToString(e) === '[object Error]' || e instanceof Error);
+}
+exports.isError = isError;
+
+function isFunction(arg) {
+  return typeof arg === 'function';
+}
+exports.isFunction = isFunction;
+
+function isPrimitive(arg) {
+  return arg === null ||
+         typeof arg === 'boolean' ||
+         typeof arg === 'number' ||
+         typeof arg === 'string' ||
+         typeof arg === 'symbol' ||  // ES6 symbol
+         typeof arg === 'undefined';
+}
+exports.isPrimitive = isPrimitive;
+
+exports.isBuffer = require('./support/isBuffer');
+
+function objectToString(o) {
+  return Object.prototype.toString.call(o);
+}
+
+
+function pad(n) {
+  return n < 10 ? '0' + n.toString(10) : n.toString(10);
+}
+
+
+var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
+              'Oct', 'Nov', 'Dec'];
+
+// 26 Feb 16:19:34
+function timestamp() {
+  var d = new Date();
+  var time = [pad(d.getHours()),
+              pad(d.getMinutes()),
+              pad(d.getSeconds())].join(':');
+  return [d.getDate(), months[d.getMonth()], time].join(' ');
+}
+
+
+// log is just a thin wrapper to console.log that prepends a timestamp
+exports.log = function() {
+  console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
+};
+
+
+/**
+ * Inherit the prototype methods from one constructor into another.
+ *
+ * The Function.prototype.inherits from lang.js rewritten as a standalone
+ * function (not on Function.prototype). NOTE: If this file is to be loaded
+ * during bootstrapping this function needs to be rewritten using some native
+ * functions as prototype setup using normal JavaScript does not work as
+ * expected during bootstrapping (see mirror.js in r114903).
+ *
+ * @param {function} ctor Constructor function which needs to inherit the
+ *     prototype.
+ * @param {function} superCtor Constructor function to inherit prototype from.
+ */
+exports.inherits = require('inherits');
+
+exports._extend = function(origin, add) {
+  // Don't do anything if add isn't an object
+  if (!add || !isObject(add)) return origin;
+
+  var keys = Object.keys(add);
+  var i = keys.length;
+  while (i--) {
+    origin[keys[i]] = add[keys[i]];
+  }
+  return origin;
+};
+
+function hasOwnProperty(obj, prop) {
+  return Object.prototype.hasOwnProperty.call(obj, prop);
+}
diff --git a/resources/fluidbookpublication/packager/fluidbook.ico b/resources/fluidbookpublication/packager/fluidbook.ico
deleted file mode 100644 (file)
index fdaa6af..0000000
Binary files a/resources/fluidbookpublication/packager/fluidbook.ico and /dev/null differ