text: ﻿/* 
   * WinJS Contrib v2.1.0.6
   * licensed under MIT license (see http://opensource.org/licenses/MIT)
   * sources available at https://github.com/gleborgne/winjscontrib
   */
  
  var WinJSContrib=WinJSContrib||{};WinJSContrib.BgDownloads=WinJSContrib.BgDownloads||{},function(){"use strict";var e=Windows.Storage.ApplicationData.current.localFolder,n="downloadeditems.json",t=WinJS.Binding.define({download:null,status:null,progress:0}),r=WinJSContrib.Logs.getLogger("WinJSContrib.BgDownloadTracker"),o={waiting:"waiting",downloading:"downloading",downloaded:"downloaded",error:"error",completed:"completed"},i=WinJS.Binding.define({nbPendings:0});WinJSContrib.BgDownloads.Tracker=WinJS.Class.mix(WinJS.Class.define(function(e,n){var t=this;t.name=e,n=n||{},t.state=new i,this.tempExtension=".download",this.saveItemsPromise=WinJS.Promise.wrap(),this.downloadsStart=WinJS.Promise.wrap(),this.folder=n.folder,this.retryOnError=n.retryOnError,this.handleItemProperties=n.handleItemProperties,this.maxConcurrentDownloads=n.maxConcurrentDownloads||300,this.debouncedCheck=_.debounce(function(){t.checkDownloads()},1e3,!1),this.debouncedVerif=_.debounce(function(){t.verifyItems()},200,!1),this.debouncedSave=_.throttle(function(){t.saveItems()},200,!1),n.getFolder&&(this.getFolder=n.getFolder),n.createFolder&&(this.createFolder=n.createFolder),this.items=new WinJS.Binding.List,this.defaultFolderPromise=t._getFolder(!0),this.refreshInterval=null,t.ready=!1},{_getFolder:function(e){return this.folder?WinJS.Promise.wrap(this.folder):e?this.createFolder():this.getFolder()},getFolder:function(){return e.getFolderAsync("bgdownloads\\"+this.name,Windows.Storage.CreationCollisionOption.openIfExists)},createFolder:function(n){return e.createFolderAsync("bgdownloads\\"+this.name,Windows.Storage.CreationCollisionOption.openIfExists)},_loadItemsFile:function(){var e=this;return e._getFolder(!1).then(function(e){return e?e.getFileAsync(n).then(function(e){return Windows.Storage.FileIO.readTextAsync(e).then(function(e){var n=e?JSON.parse(e):{};return n})}):void 0},function(e){return r.error("internal error loading items",e),[]})},verifyItems:function(){var e=this,n=[];return e.items.length?(e.items.forEach(function(t){n.push(t.status==o.downloading&&t.downloadid&&!t.download?e._swapTempFile(t).then(function(){return e._checkItem(t)}):e._checkItem(t))}),WinJS.Promise.join(n).then(function(){return e.saveItems()}).then(function(){e.debouncedCheck()})):WinJS.Promise.wrap()},startLoop:function(){var e=this;e.refreshInterval||(e.items.length>0||WinJSContrib.BgDownloads.currentDownloads.length>0)&&(e.refreshInterval=setInterval(function(){e.debouncedCheck()},6e4))},loadItems:function(){var e=this,n=function(n){return e.items.splice(0,e.items.length),e._loadItemsFile().then(function(t){if(t&&t.items&&t.items.length){var r=[];return t.items.forEach(function(t){if(t){var i=e._wrap(t,n);e.items.push(i),r.push(i.status==o.downloading&&i.downloadid&&!i.download?e._swapTempFile(i).then(function(){return e._checkItem(i)}):e._checkItem(i))}}),WinJS.Promise.join(r).then(function(){e.items.length&&e.startLoop(),e.debouncedSave(),e.ready=!0})}e.ready=!0,e.debouncedSave()},function(n){r.error("error loading items",n),e.ready=!0})};return WinJSContrib.BgDownloads.initDownloads().then(function(e){return n(e)},function(e){return n([])}).then(function(){return e.checkDownloads()},function(e){return r.error("tracker error",e),WinJS.Promise.wrap()})},saveItems:function(e){var t=this;return t.saveItemsPromise.then(function(){var o=t.items.map(t._unwrap),i=t.defaultFolderPromise.then(function(e){return e.createFileAsync(n,Windows.Storage.CreationCollisionOption.replaceExisting).then(function(e){return Windows.Storage.FileIO.writeTextAsync(e,JSON.stringify({items:o})).then(function(){r.verbose("items saved")})})}).then(null,function(n){return r.warn("error saving bgdownload tracker items",n),e=e||0,2>e?WinJS.Promise.timeout(20).then(function(){return t.saveItemsPromise=WinJS.Promise.wrap(),t.saveItems(e+1),t.saveItemsPromise}):void r.error("error saving bgdownload tracker items",n)});return i.then(function(){t.saveItemsPromise==i&&(r.verbose("refresh save promise"),t.saveItemsPromise=WinJS.Promise.wrap())}),t.saveItemsPromise=i,t.saveItemsPromise})},attach:function(e,n){var t=this;n.oncomplete=function(){e.download=null,e.status=o.downloaded,t._swapTempFile(e).then(function(){return t._checkItem(e)},function(e){return r.error("error swapping temp file",e),WinJS.Promise.wrap()}).then(function(){t.debouncedSave(),e.errorMessage?r.debug("bgdownload complete with errors",{data:e.data,message:e.errorMessage}):r.debug("bgdownload complete",{data:e.data,message:e.errorMessage}),t.debouncedCheck(),t.dispatchEvent("downloadcomplete",{data:e.data})},function(e){return r.error("error removing item",e),WinJS.Promise.wrap()})},n.onerror=function(n){e.status=o.error,e.download=null,e.downloadid=null,e.errorMessage=n.message;var i=WinJS.Promise.wrap();n.asyncOpType&&"Windows.Foundation.IAsyncOperationWithProgress`2<Windows.Networking.BackgroundTransfer.DownloadOperation,Windows.Networking.BackgroundTransfer.DownloadOperation>"==n.asyncOpType&&(n.message&&n.message.indexOf("(404)")>0?(e.status=o.downloaded,r.warn("remote item not found, skipping item "+e.itemid),i=t._checkItem(e,!0)):n.message&&n.message.indexOf("(500)")>0&&(e.status=o.downloaded,r.warn("server error, skipping item "+e.itemid),i=t._checkItem(e,!0))),i.then(function(){return WinJS.Promise.timeout(5)}).then(function(){return t.removeFile(e)}).then(function(){e.filepath=null}).then(function(){t.debouncedSave(),t.debouncedCheck()},function(e){return r.error("error removing file on error",e),WinJS.Promise.wrap()}),n.item=e.data,r.debug("bgdownload error",{error:n,data:e.data}),t.dispatchEvent("downloaderror",{data:e.data,error:n})},n.onprogress=function(n){e.progress=n}},_wrap:function(e,n){var r=this,o=new t;if(o.data=e.data,o.itemid=e.itemid,o.folderpath=e.folderpath,o.uri=e.uri,o.filename=e.filename,o.filepath=e.filepath,o.status=e.status,o.downloadid=e.downloadid,o.downloadid&&n&&n.length){var n=n.filter(function(e){return e.download.guid==o.downloadid});n&&n.length&&(o.download=n[0],r.attach(o,n[0]))}return o},_checkItem:function(e,n){var t=this;return e.itemCheckPromise||(e.itemCheckPromise=WinJS.Promise.wrap()),e.itemCheckPromise.then(function(){var i=function(){if(e.status!=o.completed){if(e.status=o.downloaded,t.remove(e),t.handleItemProperties)return WinJS.Promise.as(t.handleItemProperties(e.data,file)).then(function(){e.status=o.completed},function(e){return r.error("error handling tracker items properties",e),WinJS.Promise.wrap()});e.status=o.completed}};return e.status===o.downloading&&e.downloadid||e.status===o.waiting?WinJS.Promise.wrap():e.status===o.error?WinJS.Promise.wrap():(e.itemCheckPromise=Windows.Storage.StorageFile.getFileFromPathAsync(e.filepath).then(function(e){return e?i():void 0},function(t){return n?i():(e.status=o.error,WinJS.Promise.wrap())}),e.itemCheckPromise)})},_swapTempFile:function(e){var n=this.tempExtension;return e.filepath.indexOf(n)>0?Windows.Storage.StorageFile.getFileFromPathAsync(e.filepath).then(function(n){return n?n.renameAsync(e.filename,Windows.Storage.NameCollisionOption.replaceExisting).then(function(t){e.status=o.downloaded,e.filepath=n.path}):void 0},function(n){return r.error("internal error swapping temp file",n),e.status=o.error,WinJS.Promise.wrap()}):(r.error("invalid temp file"),e.status=o.error,WinJS.Promise.wrap())},_unwrap:function(e){var n={itemid:e.itemid,data:e.data,uri:e.uri,folderpath:e.folderpath,filename:e.filename,filepath:e.filepath,downloadid:e.downloadid,status:e.status};return n},add:function(e,n,r,i,a,s){var d=this,l=d.items.filter(function(e){return e.itemid==n});if(l&&l.length)return WinJS.Promise.wrap(l[0]);var u=new t;return u.itemid=n,u.data=e,u.folderpath=r,u.filename=i,u.uri=a,u.status=o.waiting,d.items.push(u),d.debouncedSave(),s?this.startDownloads([u]).then(function(e){return e&&e.length?e[0]:void 0}):(d.debouncedCheck(),WinJS.Promise.wrap(u))},startDownloads:function(e){var n=this;return e.forEach(function(e){e.status=o.downloading}),n.downloadsStart.then(function(){var t=[];e.forEach(function(e){var i=null;if(e){i=e.folderpath?Windows.Storage.StorageFolder.getFolderFromPathAsync(e.folderpath):n.defaultFolderPromise;var a=i.then(function(t){if(WinJSContrib.BgDownloads.currentDownloads.length>n.maxConcurrentDownloads)return e.status=o.waiting,r.debug("too much pendings dl "+WinJSContrib.BgDownloads.currentDownloads.length+" / "+n.maxConcurrentDownloads+" "+n.items.length),WinJS.Promise.wrap(null);var i=new WinJSContrib.BgDownloads.Download,a=encodeURIComponent(e.filename),s=new Windows.Foundation.Uri(e.uri),d=i.start(s,a+n.tempExtension,t,Windows.Storage.CreationCollisionOption.replaceExisting).then(function(t){return r.debug("bgdownload start "+WinJSContrib.BgDownloads.currentDownloads.length+" / "+n.maxConcurrentDownloads+" "+n.items.length),e.status=o.downloading,e.download=t,e.downloadid=t.download.guid,e.filepath=t.file,n.attach(e,t),e}).then(null,function(n){return r.error("download start error "+n),e.status=o.error,e.download=null,e.downloadid=null,e});return d});t.push(a)}});var i=WinJS.Promise.join(t);return i=i.then(function(e){return e},function(e){return r.error("error starting dowloads",e),WinJS.Promise.wrap()}),n.downloadsStart=i,i.then(function(){return n.downloadsStart==i&&(r.verbose("refresh start downloads promise"),n.downloadsStart=WinJS.Promise.wrap()),n.debouncedSave()},function(e){r.warn("error saving bgdownload items ",e)}),n.downloadsStart})},checkDownloads:function(){var e=this;return e.startLoop(),WinJSContrib.BgDownloads.currentDownloads.length>e.maxConcurrentDownloads?(r.debug("checking download, too much pendings "+WinJSContrib.BgDownloads.currentDownloads.length+" / "+e.maxConcurrentDownloads+" "+e.items.length),WinJS.Promise.wrap()):e.downloadsStart.then(function(){var n=e.checkState();if(r.debug("checking download "+n.length+" files to download "+WinJSContrib.BgDownloads.currentDownloads.length+" / "+e.maxConcurrentDownloads+" "+e.items.length),n.length){var t=WinJSContrib.BgDownloads.currentDownloads.length;if(WinJSContrib.BgDownloads.currentDownloads.length<e.maxConcurrentDownloads){var o=n.slice(0,e.maxConcurrentDownloads-t);return e.startDownloads(o)}}return WinJS.Promise.wrap()}).then(function(){e.checkState()})},checkState:function(){var e=this,n=e.items.filter(function(e){return e.status==o.waiting||e.status==o.error});return e.state.nbPendings=n.length+WinJSContrib.BgDownloads.currentDownloads.length,0===e.state.nbPendings&&e.debouncedVerif(),e.refreshInterval&&0==e.items.length&&0==WinJSContrib.BgDownloads.currentDownloads.length&&(clearInterval(e.refreshInterval),e.refreshInterval=null),n},removeFile:function(e){var n=this;return new WinJS.Promise(function(t,o){r.verbose("remove item file for "+e.itemid);var i=n.items.indexOf(e);i>=0?(r.verbose("remove item file for "+e.itemid+" "+e.filepath),Windows.Storage.StorageFile.getFileFromPathAsync(e.filepath).then(function(e){e?e.deleteAsync().then(t,o):t()},function(n){r.debug("file not found for deletion "+e.filepath,n),t()})):t()})},remove:function(e){var n=this,t=n.items.indexOf(e);return t>=0?(r.verbose("remove item from list "+e.itemid),n.items.splice(t,1),Windows.Storage.StorageFile.getFileFromPathAsync(e.filepath).then(function(e){var t=n.tempExtension;return e.path.indexOf(t)==e.path.length-t.length?e.deleteAsync():void 0},function(e){return r.debug("file not found",e),WinJS.Promise.wrap()}).then(function(){n.debouncedSave()})):(r.warn("item "+e.itemid+" not found"),WinJS.Promise.wrap())},exists:function(e){var n=this,t=n.items.filter(function(n){return n.itemid==e});return t.length>0},get:function(e){var n=this,t=n.items.filter(function(n){return n.itemid==e});return t&&t.length?t[0]:null}}),WinJS.Utilities.eventMixin,WinJS.Utilities.createEventProperties(["downloadcomplete","downloaderror"]))}();