{"version":3,"sources":["webpack:///./build-targets/theme/packages/core/functionality/selectpicker.js","webpack:///./packages/core-asset/collections/assetConstituents_.js","webpack:///./packages/core-asset/models/assetConstituent_keyframe.js","webpack:///./packages/core-asset/models/assetConstituent_layer.js","webpack:///./packages/core-asset/models/assetConstituent_page.js","webpack:///./packages/core-asset/collections/assetConstituents.js","webpack:///./packages/core-asset/collections/assetConstituents_clips.js","webpack:///./packages/core-asset/collections/assetConstituents_keyframes.js","webpack:///./packages/core-asset/collections/assetConstituents_layers.js","webpack:///./packages/core-asset/collections/assetConstituents_pages.js","webpack:///./packages/core-asset/models/asset.js","webpack:///./packages/core-asset-expiration/utils/assetExpires.ts","webpack:///./packages/core-asset-expiration/utils/userInputToExpirationTime.ts","webpack:///./packages/core/lib/netx-moment.ts","webpack:///./packages/core-asset/models/assetConstituent.js","webpack:///./packages/core-asset/properties/asset.js","webpack:///./packages/core-asset/enablers.js","webpack:///./packages/core-share/properties/downloadOptions.js","webpack:///./build-targets/theme/packages/core-audio-editor/templates/editor.html","webpack:///./build-targets/theme/packages/core-audio-editor/templates/operationControls.html","webpack:///./build-targets/theme/packages/core-audio-editor/templates/operationControl.html","webpack:///./build-targets/theme/packages/core-audio-editor/templates/operationControl_dropdown.html","webpack:///./build-targets/theme/packages/core-audio-editor/templates/operationControl_trim.html","webpack:///./packages/core-asset-expiration/utils/assetExpirationToDateString.ts","webpack:///./packages/core-app/models/progress.js","webpack:///./packages/core-audio-editor/actions.js","webpack:///./packages/core-audio-editor/menus.js","webpack:///./packages/core-audio-editor/models/operation.js","webpack:///./packages/core-audio-editor/models/operation_format.js","webpack:///./packages/core-audio-editor/models/operation_trim.js","webpack:///./packages/core-audio-editor/config.js","webpack:///./packages/core-audio-editor/collections/operations.js","webpack:///./packages/core-audio-editor/collections/operationsStack.js","webpack:///./packages/core-audio-editor/models/audio.js","webpack:///./packages/core-audio-editor/views/operationControl.js","webpack:///./packages/core-audio-editor/views/operationControl_dropdown.js","webpack:///./build-targets/theme/packages/core-audio-editor/views/operationControl_dropdown.js","webpack:///./packages/core-audio-editor/views/operationControl_trim.js","webpack:///./build-targets/theme/packages/core-audio-editor/views/operationControl_trim.js","webpack:///./packages/core-audio-editor/views/operationControls.js","webpack:///./packages/core-audio-editor/views/editor.js","webpack:///./build-targets/theme/packages/core-audio-editor/views/editor.js","webpack:///./packages/core-audio-editor/routes.js","webpack:///./packages/core-audio-editor/controller.js","webpack:///./packages/core-audio-editor/index.js","webpack:///./build-targets/theme/packages/core/functionality/materialList.js","webpack:///./packages/core-asset/models/assetConstituent_clip.js","webpack:///./packages/core-share/collections/downloadOptions.js","webpack:///./packages/core-share/models/downloadOption.js","webpack:///./packages/core-app/views/appTabItemView.js","webpack:///./build-targets/theme/packages/core-app/views/appTabItemView.js","webpack:///./packages/core-app/views/appTabItemsView.js","webpack:///./build-targets/theme/packages/core-app/views/appTabItemsView.js","webpack:///./packages/core/lib/netx-tabView.js","webpack:///./packages/core-share/models/shareable.js","webpack:///./packages/core-asset/models/assetVersion.js","webpack:///./build-targets/theme/packages/core/functionality/resizable.js","webpack:///./packages/core-asset/properties/assetSets.js","webpack:///./node_modules/moment/locale sync ^\\.\\/.*$","webpack:///./packages/core-asset/models/assetSet.js","webpack:///./build-targets/theme/packages/core-app/templates/appTabItemsView.html","webpack:///./build-targets/theme/packages/core-app/templates/appTabItemView.html"],"names":["NAME","icons","faCaretDown","icon","html","Props","refreshSelectpicker","$el","this","Plugins","Update","target","hasFunctionality","extendFunctionality","addInitializer","instance","opts","Register","selectpicker","name","multiple","updateMethod","options","styleBase","doneButtonText","style","container","liveSearch","isMobile","noneSelectedText","i18n","t","noneResultsText","template","caret","on","Destroy","selectPickerOptions","Initialize","purgeEls","el","querySelectorAll","getExcludedViews","AssetConstituents_","Base","rpc","url","Netx","URL","api","xhrTrackProgress","methods","read","parsers","data","_","each","v","k","type","reset","ucfirst","slice","__name__","AssetConstituent_Keyframe","defaults","extend","super","AssetConstituent_Layer","AssetConstituent_Page","pageNumber","clientAttrs","constructor","attrs","title","get","split","length","attributes","page","ConsituentCollections","clips","models","model","Model","keyframes","layers","pages","searchPDFPages","str","filtered","assetId","idx","originalPages","map","d","clearSearch","AssetConstituents","subCollection","set","selected","findWhere","display","displayed","properties","constituentProps","types","thing","id","things","listenTo","collection","xhr","silent","trigger","resp","addSubCollection","Asset","idAttribute","titleAttribute","xhrExcludeProgress","alphaChannel","attributeIds","attributeNames","attributeValues","bitDepth","categories","categoryid","categoryPaths","checkout","checkoutUserLabel","colorProfile","constituentIds","constituentType","creationdate","description","dpi","duration","expirationDate","file","fileFormatFamily","fileheight","fileSize2","filetype","filetypelabel","filewidth","flvPreview","geoLocationLabel","importDate","importUserLabel","inCurrentCart","latitude","locationContext","locationid","longitude","moddate","moduserid","moduserlabel","metadataAvailable","path","permissionMatrix","previewHeight","previewUrl","previewWidth","proofAvailable","rating","readOnly","relatedAvailable","repurposeAvailability","reviewAvailable","statDeliveries","statPreviews","status","templatable","templateCustomizable","thumbUrl","versionIds","viewIds","viewNames","visible","zoomAvailable","imageid","metadata","attribute1","attribute2","attribute3","attribute4","attribute5","attribute6","attribute7","attribute8","attribute9","attribute10","attribute11","attribute12","attribute13","attribute14","attribute15","attribute16","attribute17","attribute18","attribute19","attribute20","hasChildren","parentId","activatingTemplate","deactivatingTemplate","audioUrl","videoUrl","zoomUrl","update","self","remove","expireAsset","importAsset","reserve","addCategory","$","Deferred","setAssetCategoryLink","link","then","response","resolveWith","reject","Error","promise","removeCategory","linkCategory","setCategory","setCategories","repurpose","manualRepurpose","repurposeOtherIds","repurposeMethods","repurposeValues","resync","assetInCurrentCart","_getCarts","cancelCheckout","checkPendingTasks","checkStatus","getConstituents","getProcessListForUser","recordViewed","makeZoomTiles","activateAdBuilderTemplate","deactivateAdBuilderTemplate","uuid","batchJob","trackBatchJob","undefined","completed","fetch","dispatcher","console","warn","cat","cats","join","linkCategories","log","ids","attr","deleteWait","importAttributes","collisionStrategy","fail","rename","messageType","objectContext","repurposeId","repurposeDownloadOverride","version","AssetVersionModel","addSubModel","setMediaUrls","setChecksum","progress","ProgressModel","constituents","AssetConstituentsCollection","clear","versions","creationDate","fileSize","fileTypeId","fileTypeLabel","userId","userLabel","oldAssetId","_previousAttributes","setupCustomThumbnailListeners","setupAssetTaskListeners","error","asset","m","cid","indexOf","has","progressMessage","complete","clip","isNew","add","setupAssetCheckinListeners","parse","omit","hasAudio","hasVideo","hasZoom","apply","concat","validate","isNumber","canZoom","isImage","getPreference","expire","dateStr","expirationTime","userInputToExpirationTime","ex","fetchConstituents","duplicateQueryPolicy","garbageCollect","getAttribute","templateId","attrModel","value","getSystemAttribute","format","parseInValue","getAttributeId","getAttributeValue","attrName","isArray","getTokenString","token","getToken","getWaveformJSON","getJSON","json","tokenStr","hasFormatFamily","contains","hasMultimedia","setAttribute","val","isString","isCSV","isTrueMultivalue","arrayToCsv","clone","attributePermissions","stopListening","delay","bind","newVersion","task","tempIconPattern","previewNow","match","patienceExhausted","timesPolled","pollUntil","realProgress","tasks","importTasks","eventPrefix","updating","pluploader","parseInt","percent","checksumEnabled","unexpire","setCombo","vals","getCombo","csvToArray","moveCategory","from","to","resolve","isNaN","Array","without","forEach","catId","isDocument","isPDF","includes","isLocked","lock","save","wait","toAssetSet","AssetSetModel","assetSetTypes","label","unlock","cacheBuster","prefix","dateFromAsset","getTime","Date","bumpModdate","date","dateToAsset","allows","perm","matrixIndex","matrixNames","cacheInMediaRich","Promise","mediarichCacheUrl","encodeURIComponent","session","ajax","responseJSON","responseText","jqXHR","assetExpires","moment","endOf","utc","tomorrow","valueOf","isValid","initialized","locale","language","AssetConstituent","lowresUrl","modDate","rebuildType","rebuildCount","ref","setDisplay","result","clipAttributes","getAttributesByObjectType","currentAsset","current","arguments","canCreateLink","canEmail","typeNames","AudioTask","FFFViewTask","INDDPageTask","IWorkPageTask","KeyframesTask","MetadataTask","OfficePageTask","PDFPageTask","PostImportTask","PreviewTask","RelatedAssetTask","SWFTask","ThumbnailTask","VideoPreviewTask","WatermarkTask","ZoomTask","renderableChanges","UNKNOWN","ONLINE","NEARLINE","OFFLINE","TEMP","CHECKOUT","IMPORT_IN_PROGRESS","attributeHistory","userLevel","enableTest","notMobile","constituents_keyframes","constituents_layers","constituents_pages","detail","matrix","fileinfo","index","links","overview","permissions","preview","projects","publicLinks","reviews","usage","views","assetCanRepurpose","getViewModel","supported","assetIsPresent","assetCanReview","assetExpirationEnabled","assetHasConstituents_clips","assetHasClips","assetHasConstituents_keyframes","size","assetHasConstituents_layers","assetHasConstituents_pages","assetHasDetail","assetHasLinks","assetHasMetadata","assetHasPreview","assetHasProjects","assetHasReviews","assetHasVersions","assetIsEditable","assetData","AssetModel","canEdit","assetHasViews","assetIsImage","stat","assetStatuses","assetNotCheckedOut","getViewCollection","at","assetNotPending","isUndefined","pending","assetRequestsEnabled","canCheckIn","checkedOutBy","getUserLevel","getUser","canCheckOut","canDeleteAttribute","canDownloadVersion","canEditAttribute","canLock","canManageVersions","canRemoveAssetFromCategory","canUnlock","canZoomAsset","semanticsEnabled","canUnexpire","contactSheet","defaultEngine","defaultTemplates","maxAttributes","ignoreDownloadWarningTypes","original","proxy","assetView","presetProcess","historical","thumb","templateCustomization","module","exports","obj","__t","__p","__j","prototype","print","call","escape","items","item","assetExpirationToDateString","local","Progress","message","active","destroy","GetDefaults","Operation","order","getValue","audio","hasChanged","Operation_Format","control","render","values","pulldownOptions","pulldownOption","pick","keys","toLowerCase","floor","Math","round","Operation_Trim","endTime","range","Infinity","startTime","convertValue","getTimeObject","seconds","time","hour","minute","second","millisecond","pretty","pad","Models","base","BaseOperationModel","FormatOperationModel","trim","TrimOperationModel","Operations","modelId","pluck","userOperations","additionalOptions","operations","compact","userOperation","toUpperCase","push","comparator","OperationsStack","audioOperations","AudioEditorOperationsCollection","operation","updateIndex","getClone","isObject","getData","isFunction","newOperation","amount","indexedOrder","unindexedOrder","oindex","nindex","zipped","zip","n","object","i","sortBy","op","sort","Audio","originalUrl","OperationsCollection","lastOperationsStack","OperationsStackCollection","operationStackArray","operationStackHistory","operationsStack","getOperation","key","alias","peaks","getManualRepurposeOptions","fetchOperations","displayedDownloadOptionTypes","downloadOptionTypes","updateOperations","changes","lastOp","currentOp","o","isEqual","removed","OperationControl","className","events","change","Template","updateValue","throttle","bindModelEvents","postRender","_items","checkBounds","e","$item","_val","max","min","$target","newValue","setValue","unbindModelEvents","OperationControl_Dropdown","Selectpicker","OperationControl_Trim","regionUpdating","sound","initVal","currentTrim","start","end","regionUpdated","event","args","isEmpty","changed","$startTime","$endTime","mediaReady","addToEndTime","totalTime","updateTrimTime","addToStartTime","enable","getDuration","isReady","region","subtractFromEndTime","subtractFromStartTime","initializeIcons","faMinus","faPlus","_ChildViews","OperationControlView","dropdown","DropdownOperationControlView","OperationControls","editor","media","childView","viewClass","addOperationControl","hasError","bindCollectionEvents","addedOperationControl","removedOperationControl","c","a","merge","preRender","templateVars","operationsSelected","preventDefault","currentTarget","$operations","swapControls","b","updateOperationControls","ChildViews","Editor","defaultTab","headerTitle","removeOnHide","displayCurrentTime","resize","debounce","seeking","skipBack","skipForward","mediaError","finish","mediaLoadProgress","pause","play","regionClicked","regionCreated","regionPlay","regionRemoved","updateTheme","wavesurfer","elementKey","autoCenter","backend","barWidth","closeAudioContext","minPxPerSec","normalize","progressColor","getStyleProperty","waveColor","plugins","MinimapPlugin","create","height","cursorColor","showRegions","RegionsPlugin","color","dragSelection","destroyMethod","pauseMedia","currentAjax","abort","initializeMethod","pluginObj","$pluginEl","initOpts","cb","WaveSurfer","load","$audio","fireEvent","operationControls","removeSubView","addClass","removeClass","$container","$currentTime","$durationTime","$errorMessage","$manualOperations","$mediaProgress","$selectionTime","$timeline","whenShown","injectAudio","displayDuration","tabs","OperationControlsView","viewOptions","submit","applyOperations","regions","regionList","list","regionKeys","addRegion","checkOverflow","drawer","overflown","width","wrapper","clientWidth","classList","toggle","setSeconds","displayTime","toISOString","substr","hasOperation","rendered","scrollParent","peaksUnavailable","hasMediaError","$waveContainer","toggleClass","msg","percentStr","find","css","defer","addPlugin","TimelinePlugin","notchPercentHeight","primaryColor","secondaryColor","primaryFontColor","secondaryFontColor","fontFamily","fontSize","initPlugin","isPlaying","playPause","stopPropagation","shiftKey","playLoop","onDrag","delta","total","updateSelectionTime","isShown","currentTime","getCurrentTime","playing","drawBuffer","minimap","renderRegions","seekTo","seekBack","seekForward","skipping","skip","startSkipBack","startSkipForward","stopSkipBack","stopSkipForward","togglePlay","setMilliseconds","setWaveColor","setProgressColor","faBackward","faChevronLeft","faChevronRight","faExclamationCircle","faForward","faPause","faPlay","faStepBackward","faStepForward","faTimes","resizeDragFrom","resizeMinWidth","resizeTargetSelector","Resizable","once","NS","audioEditor","customConfig","app","fsViews","AudioEditorView","showActions","window","Modernizr","webaudioapi","manualUserLevel","location","hash","router","navigate","AudioModel","ready","routeMatch","RegExp","isRouted","err","onConfirmed","onCancelled","exitRoute","assetSet","repurposeOptions","excludes","affected","filter","eventStr","defaultValue","toString","toRemove","added","routes","namespace","initialize","Actions","actions","addMenus","menus","controller","disabledListItemCheckboxPatch","MDCList","List","view","arrowNavigationPatch","materialRipples","listElements","listItemEl","MDCRipple","foundation_","setSingleSelection","wrapFocus","addEventListener","onClick","clicked","onAction","itemSelected","materialListItemSelected","setSelectedIndex","checkActive","replace","hashSplit","findIndex","all","href","hrefSplit","cleanUp","invoke","_ignoreItemSelection","setTimeout","removeEventListener","onListItemSelect","evt","MouseEvent","bubbles","cancelable","dispatchEvent","selectAll","adapter","adapter_","listElement","hasCheckboxAtIndex","setCheckedCheckboxOrRadioAtIndex","materialList","materialLists","setup","closest","getFocusedListItem","focusedItem","focusedItemIndex_","getActiveList","focusedList","childViews","AssetConstituent_Clip","keyframeReady","_prepareDownload","constituent","progressUuid","_data","downloadOptions","now","parseFloat","process","getPrettyRange","prettyRange","r","DownloadOptions","filterTypes","where","originalOption","proxyOptions","processOptions","metadataOptions","contactSheetOptions","vppOptions","getOption","hasManualRepurposeOptions","hasOption","parseSelectedDownloadOptions","selectedDownloadOptions","selectedDownloadOptionModels","organizeContentsBy","embedMetadata","addOptions","metadataMapping","manualRepurposeOption","proxyDownloadOption","viewDownloadOption","proxies","proxyName","viewName","processes","processId","isNumeric","sheetOption","unset","toPick","assetListSortField","assetListSortOrder","metadataOption","setId","historicalOption","setUserSelectedDownloadOptions","option","opt","DownloadOption","family","requiresApproval","requiresJustification","engine","exportOptions","Collection","templates","getPDFTemplateOptions","getOptions","lvbsToObject","setOptions","objectToLvbs","addObject","AppTabItemView","tabName","toCamelCase","click","iconOnly","viewSpec","addRelatedView","listenToOnce","toggleActive","toggleUnsavedChanges","relatedView","action","Find","Object","assign","hasTotal","$title","tabClicked","CustomEvent","updateCount","count","$count","requireSync","syncedOnce","getTotal","useList","role","tagName","querySelector","AppTabItemsView","ChildView","tabsChanged","tab","checkMaterialTabActive","tabBar","tabList_","root_","activateTab","setupMaterial","MDCTabBar","MaterialList","TabView","isTabView","__isTabView__","noRender","instantiateOnAdd","additionalViewClasses","automaticallySetTabs","showOnAdd","tabsViewOptions","tabsView","addSubView","viewCollection","showViewByName","enabled","activeView","getActiveView","showFirstEnabledView","newTab","oldTab","tabChanged","$tabs","setElement","beforeShowView","currentHeight","$childTargetEl","registerView","instantiateView","showView","showTab","viewChanging","canChange","lastTab","routedView","isMyOriginalCollection","Backbone","history","isRouting","isViewActionValid","back","viewInstantiated","removeOnSimpleHide","viewAfterShown","viewOnShowing","AppViewModel","performAction","Shareable","collections","getLabel","aType","cart","savedCart","savedSearch","AssetVersion","memoId","memoText","shortMemoText","reactivateAssetVersion","assetVersion","cleanUpResizable","resizeTargets","prepareResizable","startSize","resizableGetStartSize","startHeigh","startWidth","horizontal","resizeDirection","resizeUserPref","resizeStartWidth","resizeStartHeight","minSize","resizeMinHeight","resizeUsingPercent","test","resizeStart","resized","originalEvent","ui","setPreference","resizing","toggleResizable","resizable","resizeDisabled","dragresizestart","dragresizeend","dragresizing","dragresizereset","netxDragResize","direction","dragFrom","maxHeight","resizeMaxHeight","minHeight","maxWidth","resizeMaxWidth","minWidth","usePercent","attributeSet","category","organizeByTypes","none","fileType","folderPath","webpackContext","req","webpackContextResolve","__webpack_require__","code","AssetSet","recursive","assetCount","assetIds","getAssetIdsInSets","getDownloadWarnings","getDownloadOptions","prepareDownload","archiveName","justification","toCollection","DownloadOptionsCollection","results","Rpc","ParseError","downloadOption","warnings","messageCount","assetsUnavailableCount","unique","progressMessages","objectId","getCurrentCart","saved","search","toShareable","sType","ShareableModel"],"mappings":"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","file":"21.bundle.min.js?2.22.17.58a9f31f.1678743775824","sourcesContent":["const NAME = 'selectpicker';\n\nimport 'theme-libs/bootstrap-select';\nimport 'theme-libs/bootstrap-select-netx';\n\nimport {icon} from '@fortawesome/fontawesome-svg-core';\nimport {faCaretDown} from '@fortawesome/pro-solid-svg-icons';\nimport {purgeEls} from '@netx/core/lib/utils';\nimport {isMobile} from '@netx/core/lib/underscore-netx';\n\nconst icons = {\n\tfaCaretDown: icon(faCaretDown).html,\n};\n\nconst Props = {\n\t/** @method */\n\trefreshSelectpicker($el) {\n\t\tthis.Plugins.Update('selectpicker', $el);\n\t},\n};\n\nexport default function (target) {\n\tif (!target || target.hasFunctionality(NAME)) return target;\n\n\ttarget.extendFunctionality(Props);\n\n\ttarget.addInitializer((instance, opts = {}) => {\n\t\t// Selectpicker\n\t\tinstance.Plugins.Register({\n\t\t\tselectpicker: {\n\t\t\t\tname: 'selectpicker',\n\t\t\t\tmultiple: true,\n\t\t\t\tupdateMethod: 'refresh',\n\t\t\t\toptions: {\n\t\t\t\t\tstyleBase: 'mdc-button',\n\t\t\t\t\tdoneButtonText: instance.doneButtonText || 'done',\n\t\t\t\t\tstyle: '',\n\t\t\t\t\tcontainer: 'body',\n\t\t\t\t\tliveSearch: !isMobile(),\n\t\t\t\t\tnoneSelectedText: i18n.t('i18n.nothingSelected'),\n\t\t\t\t\t// This will be followed by \"search term\"\n\t\t\t\t\tnoneResultsText: i18n.t('i18n.noResultsMatchThing'),\n\t\t\t\t\ttemplate: {\n\t\t\t\t\t\tcaret: icons.faCaretDown,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t});\n\n\t\t// Hey, listen!\n\t\tinstance\n\t\t\t.on('preRenderHook', () => {\n\t\t\t\tinstance.Plugins.Destroy('selectpicker');\n\t\t\t})\n\t\t\t.on('postRenderHook', () => {\n\t\t\t\t// See if view wants to pass additional options at plugin init\n\t\t\t\tconst opts =\n\t\t\t\t\ttypeof instance.selectPickerOptions === 'function'\n\t\t\t\t\t\t? instance.selectPickerOptions()\n\t\t\t\t\t\t: instance.selectPickerOptions || {};\n\n\t\t\t\tinstance.Plugins.Initialize(\n\t\t\t\t\t'selectpicker',\n\t\t\t\t\tpurgeEls(\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t...instance.el.querySelectorAll(\n\t\t\t\t\t\t\t\t'.selectpicker:not([data-autocomplete])',\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t],\n\t\t\t\t\t\tinstance.getExcludedViews(),\n\t\t\t\t\t),\n\t\t\t\t\topts,\n\t\t\t\t);\n\t\t\t});\n\t}, NAME);\n\n\treturn target;\n}\n","/**\n * For when you want to just deal with a single type of constituent (like doc viewer)\n * @class\n */\nimport Base from '@netx/core/lib/netx-collection';\n\nexport default class AssetConstituents_ extends Base {\n\t/**\n\t * @type {Netx.Rpc}\n\t * @private\n\t */\n\tget rpc() {\n\t\treturn true;\n\t}\n\t/**\n\t * @type {Netx.URL}\n\t * @private\n\t */\n\tget url() {\n\t\treturn Netx.URL.api;\n\t}\n\n\t/** @type {boolean} */\n\tget xhrTrackProgress() {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @property {object} methods - Collection RPC methods\n\t * @property {method} methods.read - Fetch constituents\n\t */\n\tget methods() {\n\t\treturn {\n\t\t\t/** @method */\n\t\t\tread: ['getConstituentsForAsset', 'assetId'],\n\t\t};\n\t}\n\n\t/**\n\t * @property {object} parsers - Collection parsers\n\t * @property {function} parsers.read - Parse the results of fetch\n\t */\n\tget parsers() {\n\t\treturn {\n\t\t\t/**\n\t\t\t * @function\n\t\t\t * @param {array} data Data\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tread(data, opts) {\n\t\t\t\t// Where k could be\n\t\t\t\t// clips\n\t\t\t\t// keyframes\n\t\t\t\t// layers\n\t\t\t\t// pages\n\t\t\t\t_.each(data, (v, k) => {\n\t\t\t\t\tif (k === this.type) {\n\t\t\t\t\t\tthis.reset(v);\n\t\t\t\t\t\tthis['original' + _.ucfirst(k)] = v.slice();\n\t\t\t\t\t}\n\t\t\t\t\tdelete data[k];\n\t\t\t\t});\n\t\t\t\t// Return nothing - not doing so will result in rpc setting the return for us\n\t\t\t\treturn null;\n\t\t\t},\n\t\t};\n\t}\n\n\t/** @type {string} */\n\tstatic get __name__() {\n\t\treturn 'AssetConstituents_';\n\t}\n}\n","/**\n * @class\n */\nimport Base from './assetConstituent';\n\nexport default class AssetConstituent_Keyframe extends Base {\n\t/**\n\t * @property {object} defaults - The default attribute values\n\t * @property {number} defaults.type - Default type (1 = keyframe)\n\t */\n\tget defaults() {\n\t\treturn _.extend(super.defaults, {\n\t\t\ttype: 1,\n\t\t});\n\t}\n\n\t/** @type {string} */\n\tstatic get __name__() {\n\t\treturn 'AssetConstituent_Keyframe';\n\t}\n}\n","/**\n * @class\n */\nimport Base from './assetConstituent';\n\nexport default class AssetConstituent_Layer extends Base {\n\t/**\n\t * @property {object} defaults - The default attribute values\n\t * @property {number} defaults.type - Default type (2 = layer)\n\t */\n\tget defaults() {\n\t\treturn _.extend(super.defaults, {\n\t\t\ttype: 2,\n\t\t});\n\t}\n\n\t/** @type {string} */\n\tstatic get __name__() {\n\t\treturn 'AssetConstituent_Layer';\n\t}\n}\n","/**\n * @class\n */\nimport Base from './assetConstituent';\n\nexport default class AssetConstituent_Page extends Base {\n\t/**\n\t * @property {object} defaults - The default attribute values\n\t * @property {number} defaults.type - Default type (3 = page)\n\t * @property {number} defaults.pageNumber - The default page number (client side)\n\t */\n\tget defaults() {\n\t\treturn _.extend(super.defaults, {\n\t\t\ttype: 3,\n\t\t\t// Client attributes\n\t\t\tpageNumber: 0,\n\t\t});\n\t}\n\t/** @type {array} */\n\tget clientAttrs() {\n\t\treturn ['pageNumber'];\n\t}\n\n\t/**\n\t * @override\n\t * @param {object} attr Model attributes\n\t * @param {object} opts Model options\n\t */\n\tconstructor(attrs, opts) {\n\t\tsuper(attrs, opts);\n\n\t\t// Internationalize the title for pages\n\t\tvar title = this.get('title');\n\t\tif (title) {\n\t\t\t// \"Page n\"\n\t\t\ttitle = title.split(' ');\n\t\t\tif (title.length > 1) {\n\t\t\t\tthis.attributes.title = i18n.t('i18n.pageAndNumber', {\n\t\t\t\t\tpage: title[1],\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t/** @type {string} */\n\tstatic get __name__() {\n\t\treturn 'AssetConstituent_Page';\n\t}\n}\n","/**\n * AssetConstituents collection\n * We now get a return with objects - the key representing the constituent type.\n * There is currently no individual call to get the constituents of a type for an asset.\n * This collection makes the fetch and splits off the return into the appropriate constituent sub collection.\n * Each collection may need a different comparator and definitely needs its own model type (looking at you clips)\n * The alternative is that we get in a mess of declaring all these collections within a controller and then have a\n * specific call for each - why not just fetch here and get it all for free?\n * @class\n */\nimport Base from '@netx/core/lib/netx-collection';\nimport Model from '../models/assetConstituent';\n\nimport Clips from './assetConstituents_clips';\nimport Keyframes from './assetConstituents_keyframes';\nimport Layers from './assetConstituents_layers';\nimport Pages from './assetConstituents_pages';\n\nimport {constituents as constituentProps} from '../properties/asset';\n\nconst ConsituentCollections = {\n\tclips: Clips,\n\tkeyframes: Keyframes,\n\tlayers: Layers,\n\tpages: Pages,\n};\n\nexport default class AssetConstituents extends Base {\n\t/**\n\t * @type {Netx.Rpc}\n\t * @private\n\t */\n\tget rpc() {\n\t\treturn true;\n\t}\n\t/**\n\t * @type {Netx.URL}\n\t * @private\n\t */\n\tget url() {\n\t\treturn Netx.URL.api;\n\t}\n\n\t/** @type {boolean} */\n\tget xhrTrackProgress() {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @property {object} methods - Collection RPC methods\n\t * @property {method} methods.read - Fetch constituents\n\t */\n\tget methods() {\n\t\treturn {\n\t\t\tread: ['getConstituentsForAsset', 'assetId'],\n\t\t};\n\t}\n\n\t/**\n\t * @property {object} parsers - Collection parsers\n\t * @property {function} parsers.read - Parse the results of fetch\n\t */\n\tget parsers() {\n\t\treturn _.extend(super.parsers, {\n\t\t\t/**\n\t\t\t * @function\n\t\t\t * @param {array} data Data\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tread(data, opts) {\n\t\t\t\t// Where k could be\n\t\t\t\t// clips\n\t\t\t\t// keyframes\n\t\t\t\t// layers\n\t\t\t\t// pages\n\t\t\t\t_.each(data, (v, k) => {\n\t\t\t\t\tconst subCollection = this[k];\n\n\t\t\t\t\t// Set models for sub colelction\n\t\t\t\t\tsubCollection.set(v);\n\n\t\t\t\t\t// Check for selected constituent and store it\n\t\t\t\t\tconst selected = subCollection.findWhere({display: 1});\n\t\t\t\t\tif (selected) {\n\t\t\t\t\t\tthis.displayed = selected;\n\t\t\t\t\t}\n\n\t\t\t\t\tdelete data[k];\n\t\t\t\t});\n\n\t\t\t\treturn data;\n\t\t\t},\n\t\t});\n\t}\n\n\t/**\n\t * @override\n\t * @param {array} models An array of models or model attirbutes\n\t * @param {object} options Options\n\t */\n\tconstructor(models, opts = {}) {\n\t\topts.model = opts.model || Model;\n\n\t\tsuper(models, opts);\n\n\t\t/**\n\t\t * AssetId that the constituents reference\n\t\t * @type {Number}\n\t\t * @default\n\t\t */\n\t\tthis.assetId = opts.assetId || 0;\n\n\t\t/**\n\t\t * The currently selected constituent for display\n\t\t * @memberOf Netx.Collections.AssetConstituents\n\t\t * @alias displayed\n\t\t * @type {module:asset/models/assetConstituent}\n\t\t */\n\t\tthis.displayed = null;\n\n\t\t/**\n\t\t * @memberOf Netx.Collections.AssetConstituents\n\t\t * @alias properties\n\t\t * @type {object}\n\t\t */\n\t\tthis.properties = opts.properties || constituentProps;\n\n\t\t// Our clip types\n\t\t// this.clips = new Netx.Collections.AssetConstituents_clips\n\t\t// this.keyframes = new Netx.Collections.AssetConstituents_keyframes\n\t\t// this.layers = new Netx.Collections.AssetConstituents_layers\n\t\t// this.pages = new Netx.Collections.AssetConstituents_pages\n\t\t_.each(this.properties.types, (thing, id) => {\n\t\t\tconst things = new ConsituentCollections[`${thing}s`]([]);\n\n\t\t\tthings\n\t\t\t\t// The subcollections should mirror the read events of the parent collections, as they're all fetched as one:\n\t\t\t\t.listenTo(this, 'request:read', (collection, xhr, opts) => {\n\t\t\t\t\tif (collection !== this) return;\n\t\t\t\t\t!opts.silent && things.trigger('request:read', things, xhr, opts);\n\t\t\t\t})\n\t\t\t\t// When it syncs we sync\n\t\t\t\t.listenTo(this, 'sync', (collection, resp, opts) => {\n\t\t\t\t\tif (collection !== this) return;\n\t\t\t\t\t!opts.silent && things.trigger('sync', things, resp, opts);\n\t\t\t\t});\n\n\t\t\tthis.listenTo(things, 'sync', collection => {\n\t\t\t\tif (collection !== things) return;\n\t\t\t\tconst displayed = this.findWhere({display: 1});\n\t\t\t\tif (displayed) {\n\t\t\t\t\tthis.displayed = displayed;\n\t\t\t\t}\n\t\t\t}).listenTo(things, 'change:display', (model, display) => {\n\t\t\t\tif (display && this.displayed !== model) {\n\t\t\t\t\tthis.displayed && this.displayed.set('display', 0);\n\t\t\t\t\tthis.displayed = model;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tthis[thing + 's'] = things;\n\t\t\tthis.addSubCollection(things);\n\t\t});\n\t}\n\n\t/** @type {string} */\n\tstatic get __name__() {\n\t\treturn 'AssetConstituents';\n\t}\n}\n","/**\n * @class\n */\nimport Base from './assetConstituents_';\nimport Model from '../models/assetConstituent_clip';\n\nexport default class AssetConstituents_Clips extends Base {\n\t/** @type {string} */\n\tget type() {\n\t\treturn 'clips';\n\t}\n\n\t/** @override */\n\tconstructor(models, opts = {}) {\n\t\topts.model = opts.model || Model;\n\t\tsuper(models, opts);\n\t}\n\n\t/** @type {string} */\n\tstatic get __name__() {\n\t\treturn 'AssetConstituents_Clips';\n\t}\n}\n","/**\n * @class\n */\nimport Base from './assetConstituents_';\nimport Model from '../models/assetConstituent_keyframe';\n\nexport default class AssetConstituents_Keyframes extends Base {\n\t/** @type {string} */\n\tget type() {\n\t\treturn 'keyframes';\n\t}\n\n\t/** @override */\n\tconstructor(models, opts = {}) {\n\t\topts.model = opts.model || Model;\n\t\tsuper(models, opts);\n\t}\n\n\t/** @type {string} */\n\tstatic get __name__() {\n\t\treturn 'AssetConstituents_Keyframes';\n\t}\n}\n","/**\n * @class\n */\nimport Base from './assetConstituents_';\nimport Model from '../models/assetConstituent_layer';\n\nexport default class AssetConstituents_Layers extends Base {\n\t/** @type {string} */\n\tget type() {\n\t\treturn 'layers';\n\t}\n\n\t/** @override */\n\tconstructor(models, opts = {}) {\n\t\topts.model = opts.model || Model;\n\t\tsuper(models, opts);\n\t}\n\n\t/** @type {string} */\n\tstatic get __name__() {\n\t\treturn 'AssetConstituents_Layers';\n\t}\n}\n","/**\n * @class\n */\nimport Base from './assetConstituents_';\nimport Model from '../models/assetConstituent_page';\n\nexport default class AssetConstituents_Pages extends Base {\n\t/** @type {string} */\n\tget type() {\n\t\treturn 'pages';\n\t}\n\n\t/**\n\t * @property {object} methods - Collection RPC methods\n\t * @property {method} methods.read - Search pages\n\t */\n\tget methods() {\n\t\treturn _.extend(super.methods, {\n\t\t\t/**\n\t\t\t * @method\n\t\t\t * @param {string} str Search fragment\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tsearchPDFPages(str, opts) {\n\t\t\t\tthis.filtered = true;\n\t\t\t\treturn ['searchPDFPages', this.assetId, str];\n\t\t\t},\n\t\t});\n\t}\n\n\t/*\n\t * @property {object} parsers - Collection parsers\n\t * @property {function} parsers.read - Parse the results of fetch\n\t * @property {function} parsers.searchPDFPages - Parse the results of search\n\t */\n\tget parsers() {\n\t\treturn _.extend(super.parsers, {\n\t\t\t/**\n\t\t\t * @function\n\t\t\t * @param {array} data Data\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tread(data, opts) {\n\t\t\t\t// Set page number - cannot be certain of this with the ref/id\n\t\t\t\t_.each(data.pages, (page, idx) => {\n\t\t\t\t\tpage.pageNumber = idx + 1;\n\t\t\t\t});\n\t\t\t\tthis.originalPages = data.pages.slice();\n\t\t\t\treturn data.pages;\n\t\t\t},\n\t\t\t/**\n\t\t\t * @function\n\t\t\t * @param {array} data Data\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tsearchPDFPages(data, opts) {\n\t\t\t\tthis.reset(\n\t\t\t\t\t_.map(data, (d, idx) => {\n\t\t\t\t\t\td.pageNumber = idx + 1;\n\t\t\t\t\t\treturn d;\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t},\n\t\t});\n\t}\n\n\t/** @override */\n\tconstructor(models, opts = {}) {\n\t\topts.model = opts.model || Model;\n\t\tsuper(models, opts);\n\n\t\t/**\n\t\t * Store original pages (for search results)\n\t\t * @memberOf Netx.Collections.Pages\n\t\t * @alias originalPages\n\t\t * @type {array}\n\t\t */\n\t\tthis.originalPages = this.originalPages || [];\n\t}\n\n\t/**\n\t * Clear search\n\t * @method\n\t */\n\tclearSearch() {\n\t\t// No longer filtered\n\t\tthis.filtered = false;\n\t\tthis.reset(this.originalPages);\n\t}\n\n\t/** @type {string} */\n\tstatic get __name__() {\n\t\treturn 'AssetConstituents_Pages';\n\t}\n}\n","/**\n * Asset model.\n *\n * @classdesc This model is the client-side representation of the DAM 'assetBean' object, containing all DAM info on an asset.\n * It has a variety of RPC methods for operating on a single asset. The object is quite complete, and not all fields\n * are used for all assets.\n *\n * @class\n * @extends Netx.Model\n */\nimport Base from '@netx/core/lib/netx-model';\n\nimport {i18n} from '@netx/core/i18n';\n\nimport AssetConstituentsCollection from '../collections/assetConstituents';\nimport AssetVersionModel from './assetVersion';\nimport AssetSetModel from './assetSet';\nimport ProgressModel from '@netx/core-app/models/progress';\n\nimport {userInputToExpirationTime} from '@netx/core-asset-expiration/utils';\nimport {matrixNames} from '@netx/core-permissions/properties/assetPermissions';\nimport {importTasks} from '../properties/asset';\nimport {types as assetSetTypes} from '../properties/assetSets';\n\nimport Netx, {dispatcher} from '@netx/core/bootstrap';\n\nimport {checksumEnabled} from '../enablers';\n\nexport default class Asset extends Base {\n\t/**\n\t * @type {Netx.Rpc}\n\t * @private\n\t */\n\tget rpc() {\n\t\treturn true;\n\t}\n\t/**\n\t * @type {Netx.URL}\n\t * @private\n\t */\n\tget url() {\n\t\treturn Netx.URL.api;\n\t}\n\n\t/** @type {string} */\n\tget idAttribute() {\n\t\treturn 'assetId';\n\t}\n\n\tget titleAttribute() {\n\t\treturn 'name';\n\t}\n\n\t/** @type {boolean} */\n\tget xhrTrackProgress() {\n\t\treturn true;\n\t}\n\n\t/** @type {array} */\n\tget xhrExcludeProgress() {\n\t\treturn ['recordViewed'];\n\t}\n\n\t/**\n\t * @property {object} defaults - The default attribute values\n\t * @property {number} defaults.assetId - ID\n\t * @property {string} defaults.alphsChannel - Alpha channel\n\t * @property {array} defaults.attributeIds - Attribute IDs\n\t * @property {array} defaults.attributeNames - Attribute names\n\t * @property {array} defaults.attributeValues - Attribute values\n\t * @property {number} defaults.bitDepth - Bit depth\n\t * @property {array} defaults.categories - Category IDs\n\t * @property {number} defaults.categoryid - Primary category ID\n\t * @property {array} defaults.categoryPaths - Category paths\n\t * @property {number} defaults.checkout - If checked out, ID of user who checked it out\n\t * @property {string} defaults.checkoutUserLabel - Name of user that has this asset currently checked out\n\t * @property {string} defaults.colorProfile - Color profile\n\t * @property {array} defaults.constituentIds - Array of ids for all of the assets constituents\n\t * @property {string} defaults.constituentType - Type of constituent the asset has (keyframes, pages, layers)\n\t * @property {string} defaults.creationDate - Creation date (YYYY-MM-DD hh:mm:ss)\n\t * @property {string} defaults.description - Description\n\t * @property {number} defaults.dpi - DPI\n\t * @property {number} defaults.duration - Audio/video duration (seconds)\n\t * @property {number} defaults.expirationDate - Expiration date (Unix timestamp)\n\t * @property {string} defaults.file - Filename\n\t * @property {array} defaults.fileFormatFamily - File format families (types)\n\t * @property {number} defaults.fileheight - File height (pixels)\n\t * @property {number} defaults.filesize - Deprecated. See `fileSize2`\n\t * @property {number} defaults.fileSize2 - File size in bytes\n\t * @property {number} defaults.fileType - ID of file format type\n\t * @property {string} defaults.fileTypeLabel - File type name (usually the file extension)\n\t * @property {number} defaults.filewidth - File width (pixels)\n\t * @property {boolean} defaults.flvAvailable - FLV preview is available\n\t * @property {string} defaults.geoLocationLabel - Geo location label\n\t * @property {boolean} defaults.hasChildren - Deprecated\n\t * @property {number} defaults.hidden - Controls visibility of assets in search results if the asset is part of a group of related assets (this is a way to only show one asset from a group of related assets in search results)\n\t * @property {string} defaults.importDate - Import date (YYYY-MM-DD hh:mm:ss)\n\t * @property {string} defaults.importUserLabel - Name of user that imported this asset\n\t * @property {boolean} defaults.inCurrentCart - In current cart (selection)\n\t * @property {number} defaults.latitude - Latitude (gelocation)\n\t * @property {number} defaults.locationid - Storage location ID\n\t * @property {string} defaults.locationContext - Description of storage location\n\t * @property {number} defaults.longitude - Longitude (gelocation)\n\t * @property {boolean} defaults.metadataAvailable - Embedded metadata available (XMP, DC, ID3, etc)\n\t * @property {string} defaults.moddate - Modification date (YYYY-MM-DD hh:mm:ss)\n\t * @property {number} defaults.moduserid - ID of last user to modify the asset\n\t * @property {string} defaults.moduserlabel - Name of last user to modify the asset\n\t * @property {string} defaults.name - Name\n\t * @property {string} defaults.path - Path and filename of the asset in the repository\n\t * @property {number} defaults.parentId - Deprecated\n\t * @property {array} defaults.permissionMatrix - Assets permission matrix -- see {module:permissions/properties/assetPermissions#matrixNames} for the 6 permission types\n\t * @property {number} defaults.previewHeight - Preview height (pixels)\n\t * @property {string} defaults.previewUrl - Relative URL of preview image\n\t * @property {number} defaults.previewWidth - Preview width (pixels)\n\t * @property {boolean} defaults.proofAvailable - Proofs available for the asset\n\t * @property {number} defaults.rating - Rating (range is 1 - 100)\n\t * @property {boolean} defaults.readOnly - Flag indicating whether the asset is read only\n\t * @property {boolean} defaults.relatedAvailable - Related assets are available\n\t * @property {number} defaults.repurposeAvailability - Repurpose availability flag\n\t * @property {boolean} defaults.reviewAvailable - Reviews available for the asset\n\t * @property {number} defaults.statDeliveries - Number of times asset has been downloaded (as defined in Statistics Module)\n\t * @property {number} defaults.statPreviews - Number of times asset has been viewed (as defined in Statistics Module)\n\t * @property {number} defaults.status - Indicates availability of asset file\n\t * @property {string} defaults.thumbUrl - Relative URL of thumbnail image\n\t * @property {number} defaults.timeScale - Frames per second\n\t * @property {array} defaults.versionIds - An array of version ids, for any/all versions of the asset\n\t * @property {array} defaults.viewIds - Array of ids for all of the views belonging to the asset\n\t * @property {array} defaults.viewNames - Array of names of all of the views belonging to the asset\n\t * @property {number} defaults.visible - Visibility flag (1 indicates visible). If set to 0, the asset will only be seen by admins, regardless of permissions\n\t * @property {boolean} defaults.zoomAvailable - Zoom image is available\n\t *\n\t * @property {boolean} defaults.activatingTemplate - Activating template (adBuilder)\n\t * @property {string} defaults.audioUrl - If asset is of type audio, this is the url to the audio (client only)\n\t * @property {boolean} defaults.deactivatingTemplate - Deactivating template (adBuilder)\n\t * @property {boolean} defaults.templatable\t\t\t\t\t\t - Indicates whether asset can be activated as a template\n\t * @property {boolean} defaults.template - adBuilder template\n\t * @property {boolean} defaults.templateCustomizable - adBuilder template customizable\n\t * @property {string} defaults.videoUrl - Video URL (client only)\n\t * @property {string} defaults.zoomUrl - Zoom image (not to be mistaken for zoom tiles) (client only)\n\t */\n\tget defaults() {\n\t\treturn {\n\t\t\t// assetId: 0,\n\t\t\talphaChannel: '',\n\t\t\t// metadata is stored in these three parallel arrays\n\t\t\tattributeIds: [],\n\t\t\tattributeNames: [],\n\t\t\tattributeValues: [],\n\t\t\tbitDepth: 0,\n\t\t\tcategories: [],\n\t\t\tcategoryid: 0,\n\t\t\tcategoryPaths: [],\n\t\t\tcheckout: 0,\n\t\t\tcheckoutUserLabel: '',\n\t\t\tcolorProfile: '',\n\t\t\tconstituentIds: [],\n\t\t\tconstituentType: '',\n\t\t\tcreationdate: '',\n\t\t\tdescription: '',\n\t\t\tdpi: 0,\n\t\t\tduration: 0,\n\t\t\texpirationDate: 0,\n\t\t\tfile: '',\n\t\t\tfileFormatFamily: [],\n\t\t\tfileheight: 0,\n\t\t\tfileSize2: 0,\n\t\t\tfiletype: 0,\n\t\t\tfiletypelabel: '',\n\t\t\tfilewidth: 0,\n\t\t\tflvPreview: false,\n\t\t\tgeoLocationLabel: '',\n\t\t\timportDate: '',\n\t\t\timportUserLabel: '',\n\t\t\tinCurrentCart: false,\n\t\t\tlatitude: 0.0,\n\t\t\tlocationContext: '',\n\t\t\tlocationid: 0,\n\t\t\tlongitude: 0.0,\n\t\t\tmoddate: '',\n\t\t\tmoduserid: 0,\n\t\t\tmoduserlabel: '',\n\t\t\tmetadataAvailable: false,\n\t\t\tname: '',\n\t\t\tpath: '',\n\t\t\tpermissionMatrix: [1, 1, 1, 1, 1, 1],\n\t\t\tpreviewHeight: 0,\n\t\t\tpreviewUrl: '',\n\t\t\tpreviewWidth: 0,\n\t\t\tproofAvailable: false,\n\t\t\trating: 0,\n\t\t\treadOnly: 0,\n\t\t\trelatedAvailable: false,\n\t\t\trepurposeAvailability: 0,\n\t\t\treviewAvailable: false,\n\t\t\tstatDeliveries: 0,\n\t\t\tstatPreviews: 0,\n\t\t\tstatus: 0,\n\t\t\ttemplatable: false,\n\t\t\ttemplateCustomizable: false,\n\t\t\tthumbUrl: '',\n\t\t\tversionIds: [],\n\t\t\tviewIds: [],\n\t\t\tviewNames: [],\n\t\t\tvisible: 1,\n\t\t\tzoomAvailable: false,\n\n\t\t\t// Deprecated fields -- do not use!\n\t\t\timageid: 0,\n\t\t\tmetadata: '',\n\t\t\tattribute1: '',\n\t\t\tattribute2: '',\n\t\t\tattribute3: '',\n\t\t\tattribute4: '',\n\t\t\tattribute5: '',\n\t\t\tattribute6: '',\n\t\t\tattribute7: '',\n\t\t\tattribute8: '',\n\t\t\tattribute9: '',\n\t\t\tattribute10: '',\n\t\t\tattribute11: '',\n\t\t\tattribute12: '',\n\t\t\tattribute13: '',\n\t\t\tattribute14: '',\n\t\t\tattribute15: '',\n\t\t\tattribute16: '',\n\t\t\tattribute17: '',\n\t\t\tattribute18: '',\n\t\t\tattribute19: '',\n\t\t\tattribute20: '',\n\t\t\thasChildren: false,\n\t\t\tparentId: 0,\n\n\t\t\t// Client attributes\n\t\t\tactivatingTemplate: false,\n\t\t\tdeactivatingTemplate: false,\n\t\t\taudioUrl: '',\n\t\t\tvideoUrl: '',\n\t\t\tzoomUrl: '',\n\t\t};\n\t}\n\t/**\n\t * @type {array}\n\t */\n\tget clientAttrs() {\n\t\treturn [\n\t\t\t'activatingTemplate',\n\t\t\t'audioUrl',\n\t\t\t'customThumbnailFile',\n\t\t\t'progress',\n\t\t\t'thumbnailUpdating',\n\t\t\t'videoUrl',\n\t\t\t'zoomUrl',\n\t\t];\n\t}\n\n\t/**\n\t * The following RPC methods cause the DAM to operate on the asset described in the model.\n\t * All manipulation takes place in the DAM; the browser does not directly manipulate image\n\t * data, files or the database.\n\t * @rpcs\n\t */\n\tget methods() {\n\t\treturn {\n\t\t\t/**\n\t\t\t * fetch(): load the asset described by 'assetId' from the DAM\n\t\t\t * api method: getAssetBean\n\t\t\t * @method fetch\n\t\t\t */\n\t\t\tread: ['getAssetBean', 'assetId'],\n\t\t\t/**\n\t\t\t * @method\n\t\t\t * @param {Object} opts Backbone options object, passed to the internal persistence methods.\n\t\t\t */\n\t\t\tupdate(opts) {\n\t\t\t\treturn ['setAsset', this.self()];\n\t\t\t},\n\t\t\t/**\n\t\t\t * destroy(): delete this asset from the DAM.\n\t\t\t * api method: deleteAsset\n\t\t\t * @method destroy\n\t\t\t */\n\t\t\tremove: ['deleteAsset', 'assetId', 'deleteWait'],\n\t\t\t/**\n\t\t\t * This works for both expiring and unexpiring\n\t\t\t * Unexpireing just means setting 0 on expirationDate\n\t\t\t * @method\n\t\t\t */\n\t\t\texpireAsset: ['expireAsset', 'assetId', 'expirationDate'],\n\t\t\t/**\n\t\t\t * Import a previously uploaded asset to the DAM\n\t\t\t * @method\n\t\t\t */\n\t\t\timportAsset: [\n\t\t\t\t'importAsset2',\n\t\t\t\t'file',\n\t\t\t\t'categoryid',\n\t\t\t\t'locationid',\n\t\t\t\t'importAttributes',\n\t\t\t],\n\t\t\t/*\n\t\t\t * reserve: reserve an asset ID from the DAM for an asset to be imported.\n\t\t\t * api method: reserveAssetIds\n\t\t\t * NOTE: not tested. Use Netx.Collections.Assets.reserve() instead, to reserve N asset IDs at a time.\n\t\t\t * @private\n\t\t\t * @method\n\t\t\t */\n\t\t\treserve: ['reserveAssetIds', 1],\n\t\t\t/**\n\t\t\t * addCategory: add this asset to a DAM category.\n\t\t\t * api method: setAssetCategoryLink\n\t\t\t * @method\n\t\t\t * @todo We do not get back an error response, just a boolean\n\t\t\t */\n\t\t\taddCategory(opts) {\n\t\t\t\tconst d = new $.Deferred();\n\t\t\t\tthis.setAssetCategoryLink(_.extend({}, opts, {link: true})).then(\n\t\t\t\t\t(response) => {\n\t\t\t\t\t\tresponse\n\t\t\t\t\t\t\t? d.resolveWith(this, [response])\n\t\t\t\t\t\t\t: d.reject(new Error(i18n.t('assetAddToCategoryError')));\n\t\t\t\t\t},\n\t\t\t\t\td.reject,\n\t\t\t\t);\n\t\t\t\treturn d.promise();\n\t\t\t},\n\t\t\t/**\n\t\t\t * removeCategory: remove this asset from a DAM category.\n\t\t\t * api method: setAssetCategoryLink\n\t\t\t * @method\n\t\t\t * @todo We do not get back an error response, just a boolean\n\t\t\t */\n\t\t\tremoveCategory(opts) {\n\t\t\t\tconst d = new $.Deferred();\n\t\t\t\tthis.setAssetCategoryLink(_.extend({}, opts, {link: false})).then(\n\t\t\t\t\t(response) => {\n\t\t\t\t\t\tresponse\n\t\t\t\t\t\t\t? d.resolveWith(this, [response])\n\t\t\t\t\t\t\t: d.reject(new Error(i18n.t('assetRemoveFromCategoryError')));\n\t\t\t\t\t},\n\t\t\t\t\td.reject,\n\t\t\t\t);\n\t\t\t\treturn d.promise();\n\t\t\t},\n\t\t\t/**\n\t\t\t * setAssetCategoryLink: add/remove this asset to/from a DAM category.\n\t\t\t * api method: setAssetCategoryLink\n\t\t\t * @method\n\t\t\t * @todo determine & describe the default collision strategy here.\n\t\t\t * @todo explain what happens when you remove the last category from an asset\n\t\t\t * @todo We do not get back an error response, just a boolean\n\t\t\t */\n\t\t\tsetAssetCategoryLink(opts) {\n\t\t\t\treturn [\n\t\t\t\t\t'setAssetCategoryLink',\n\t\t\t\t\tthis.id,\n\t\t\t\t\tthis.linkCategory,\n\t\t\t\t\topts.link || false,\n\t\t\t\t];\n\t\t\t},\n\t\t\t/**\n\t\t\t * setCategory: place the asset in exactly one (specified) category, removing it from all others. (Alias of setCategories())\n\t\t\t * api method: setAssetCategories\n\t\t\t * @method\n\t\t\t */\n\t\t\tsetCategory(opts) {\n\t\t\t\treturn [\n\t\t\t\t\t'setAssetCategories',\n\t\t\t\t\tthis.id,\n\t\t\t\t\t[this.linkCategory],\n\t\t\t\t\t'collisionStrategy.rename',\n\t\t\t\t];\n\t\t\t},\n\t\t\t/**\n\t\t\t * setCategories: place the asset in exactly the specified list of categories, removing it from all others.\n\t\t\t * api method: setAssetCategories\n\t\t\t * @method\n\t\t\t */\n\t\t\tsetCategories: [\n\t\t\t\t'setAssetCategories',\n\t\t\t\t'assetId',\n\t\t\t\t'linkCategories',\n\t\t\t\t'collisionStrategy.rename',\n\t\t\t],\n\t\t\t/**\n\t\t\t * repurpose: run a preset repurposing algorithm on this asset. (When finished, use the Sharing architecture to get the result.)\n\t\t\t * api method: repurposeAssetsWithPresetProcess\n\t\t\t * @method\n\t\t\t */\n\t\t\trepurpose(opts) {\n\t\t\t\treturn [\n\t\t\t\t\t'repurposeAssetsWithPresetProcess',\n\t\t\t\t\t[this.id],\n\t\t\t\t\t'repurposeOtherIds',\n\t\t\t\t\t'repurposeId',\n\t\t\t\t\t'repurposeDownloadOverride',\n\t\t\t\t];\n\t\t\t},\n\t\t\t/**\n\t\t\t * @method\n\t\t\t */\n\t\t\tmanualRepurpose(opts) {\n\t\t\t\treturn [\n\t\t\t\t\t'repurposeAssets',\n\t\t\t\t\t[this.id],\n\t\t\t\t\tthis.repurposeOtherIds,\n\t\t\t\t\tthis.repurposeMethods,\n\t\t\t\t\tthis.repurposeValues,\n\t\t\t\t];\n\t\t\t},\n\t\t\t/**\n\t\t\t * resync: resync this asset in the DAM\n\t\t\t * DAM-5726\n\t\t\t * api method: batchResyncAssets\n\t\t\t * @method resync\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tresync(opts) {\n\t\t\t\t//rpc needs an *array* of ids (single in this case)\n\t\t\t\treturn ['batchResyncAssets', [this.id], 'all'];\n\t\t\t},\n\t\t\t/*\n\t\t\t * @deprecated\n\t\t\t * assetInCurrentCart: tests if this asset is in the current cart.\n\t\t\t * api method: assetsInCurrentCart\n\t\t\t * @method\n\t\t\t * @private\n\t\t\t *\n\t\t\t * @todo this method has no parser and appears unused, perhaps untested ... deprecate?\n\t\t\t * miniAssets have an inCurrentCart attribute from the DAM, which we use instead of this method.\n\t\t\t * We also flip it manually when adding items to the cart (or we should).\n\t\t\t * This method might actually have some purpose on a miniAsset, but it's here instead ... my bad, I'm sure ...\n\t\t\t */\n\t\t\tassetInCurrentCart(opts) {\n\t\t\t\treturn ['assetsInCurrentCart', [this.id]];\n\t\t\t},\n\t\t\t/**\n\t\t\t * getCarts: returns a set of savedCart objects representing the saved carts in the DAM which\n\t\t\t * contain this asset.\n\t\t\t * api method: getCartsForAsset\n\t\t\t * @deprecated\n\t\t\t * @method\n\t\t\t */\n\t\t\t_getCarts: ['getCartsForAsset', 'assetId'],\n\t\t\t/**\n\t\t\t * checkout: 'checks out' the asset, manipulating its state in various ways, and prepares a download of the asset file.\n\t\t\t * api method: checkoutAsset\n\t\t\t * @method\n\t\t\t */\n\t\t\tcheckout: ['checkoutAsset', 'assetId'],\n\t\t\t/**\n\t\t\t * cancelCheckout: checks-in without file\n\t\t\t * api method: checkinAsset\n\t\t\t * @method\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tcancelCheckout(opts) {\n\t\t\t\treturn ['checkinAsset', this.id, this.get('file'), '', true];\n\t\t\t},\n\t\t\t/**\n\t\t\t * checkPendingTasks: track the DAM tasks that fire on asset import\n\t\t\t * @method\n\t\t\t */\n\t\t\tcheckPendingTasks: ['getImportPendingTasks', 'assetId'],\n\t\t\t/**\n\t\t\t * checkStatus: check the status of various import tasks.\n\t\t\t */\n\t\t\tcheckStatus: ['getMessage', 'messageType', 'assetId', 'objectContext'],\n\n\t\t\t/** @todo this method does nothing, because it has no parser. Remove? The constituents are normally fetched by Netx.asset.current.constituents ... */\n\t\t\tgetConstituents: ['getConstituentObjectsForAsset', 'assetId'],\n\t\t\t/**\n\t\t\t * Gets the process list (repurpose) for this asset\n\t\t\t */\n\t\t\tgetProcessListForUser: ['getProcessListForUser', 'assetId'],\n\t\t\t/**\n\t\t\t * recordViewed: tell the DAM statistics package that this asset was viewed once.\n\t\t\t * api method: recordAssetView\n\t\t\t * @method\n\t\t\t */\n\t\t\trecordViewed: ['recordAssetView', 'assetId'],\n\t\t\t/**\n\t\t\t * makeZoomTiles: tell the DAM to begin making the set of image tiles needed by the asset zoom view.\n\t\t\t * Once begun, progress on the tile generation is reported by getProgressReport().\n\t\t\t * api method: generateZoomifyTiles\n\t\t\t * @method\n\t\t\t */\n\t\t\tmakeZoomTiles: ['generateZoomifyTiles', 'assetId'],\n\n\t\t\t/**\n\t\t\t * adBuilder template methods:\n\t\t\t * ingest a 'template' asset (an .indd file with specific script labels configured)\n\t\t\t * to become the framework of an adBuilder template.\n\t\t\t * @method\n\t\t\t */\n\t\t\tactivateAdBuilderTemplate: ['activateAdBuilderTemplate', 'id'],\n\t\t\tdeactivateAdBuilderTemplate: ['deactivateAdBuilderTemplate', 'id'],\n\t\t};\n\t}\n\t/** @type {object} */\n\tget parsers() {\n\t\treturn {\n\t\t\t/**\n\t\t\t * @function\n\t\t\t * @deprecated\n\t\t\t * @param {boolean} response Response\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tassetInCurrentCart(response, opts) {\n\t\t\t\tif (this.inCurrentCart !== response[0]) {\n\t\t\t\t\tthis.inCurrentCart = response[0];\n\t\t\t\t\tthis.set('inCurrentCart', this.inCurrentCart, opts);\n\t\t\t\t\t!opts.silent && this.trigger('sync', this, opts);\n\t\t\t\t}\n\t\t\t},\n\t\t\t/**\n\t\t\t * @function\n\t\t\t * @param {string} uuid UUID\n\t\t\t * @param {object} opts Request options\n\t\t\t * @todo We get back a UUID because technically we call checkinAsset and pass `true` to\n\t\t\t * checkin without a file. The checkin is immediate in this case and we should probably get\n\t\t\t * a call specifically for cancelling checkout so that we get back the updated bean instead\n\t\t\t * of tracking a UUID that is finished immediately.\n\t\t\t * Also, the fact we have to pass more than just our asset id to cancel a checkout is messy\n\t\t\t */\n\t\t\tcancelCheckout(uuid, opts) {\n\t\t\t\tif (!uuid) return false;\n\n\t\t\t\t// Custom events for resyncing\n\t\t\t\tthis.trigger('cancellingCheckOut', this);\n\n\t\t\t\t// Poll\n\t\t\t\tconst batchJob = this.trackBatchJob(uuid, undefined, 500);\n\n\t\t\t\t// When completed\n\t\t\t\tbatchJob.completed.then(() => {\n\t\t\t\t\tthis.trigger('cancelledCheckedOut', this);\n\t\t\t\t\tthis.fetch();\n\t\t\t\t});\n\n\t\t\t\treturn batchJob;\n\t\t\t},\n\t\t\t/**\n\t\t\t * @function\n\t\t\t * @param {string} uuid Response (we need to get full beans back as we refactor things)\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tcheckout(uuid, opts) {\n\t\t\t\tif (!uuid) return false;\n\n\t\t\t\t// Custom events for resyncing\n\t\t\t\tthis.trigger('checkingOut', this);\n\n\t\t\t\t// Poll\n\t\t\t\tconst batchJob = this.trackBatchJob(uuid, undefined, 500);\n\n\t\t\t\t// When completed\n\t\t\t\tbatchJob.completed.then(() => {\n\t\t\t\t\tthis.trigger('checkedOut', this);\n\t\t\t\t\tthis.fetch();\n\t\t\t\t});\n\n\t\t\t\treturn batchJob;\n\t\t\t},\n\t\t\t/**\n\t\t\t * @function\n\t\t\t * @param {number} assetId Asset id\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\timportAsset(assetId, opts) {\n\t\t\t\tif (!assetId) {\n\t\t\t\t\t// NOTE: there is an outstanding bug with this returning zero, which is never right.\n\t\t\t\t\tconsole.warn('importReservedAsset returned ' + assetId); // DEBUG;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tthis.set({assetId: assetId});\n\t\t\t\t// Tell category system that we added an asset.\n\t\t\t\t// TODO: the category system could just as easily respond to an 'asset:imported' event, which would be more generic & meaningful.\n\t\t\t\tdispatcher.trigger(\n\t\t\t\t\t'asset:category:added',\n\t\t\t\t\tthis.id,\n\t\t\t\t\tthis.get('categoryid'),\n\t\t\t\t\tthis,\n\t\t\t\t\t'import',\n\t\t\t\t);\n\n\t\t\t\treturn assetId;\n\t\t\t},\n\t\t\t/**\n\t\t\t * @function\n\t\t\t * @param {boolean} response Response\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tsetAssetCategoryLink(response, opts) {\n\t\t\t\tif (response != true) return;\n\n\t\t\t\tdispatcher.trigger(\n\t\t\t\t\t'asset:category:added',\n\t\t\t\t\tthis.id,\n\t\t\t\t\tthis.linkCategory,\n\t\t\t\t\tthis,\n\t\t\t\t\t'setLink',\n\t\t\t\t);\n\t\t\t\t// Track index tasks.\n\t\t\t\t// DAM-21440?: if just linking, no need to track (hopefully)\n\t\t\t\topts?.link == null && dispatcher.trigger('asset:tasks:track', this);\n\t\t\t},\n\t\t\t/**\n\t\t\t * @function\n\t\t\t * @param {boolean} response Response\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tremoveCategory(response, opts) {\n\t\t\t\tconst cat = this.linkCategory;\n\t\t\t\tdispatcher.trigger('asset:category:removed', this.id, cat, this);\n\t\t\t\tdispatcher.trigger('asset:tasks:track', this);\n\t\t\t},\n\t\t\t/**\n\t\t\t * @function\n\t\t\t * @param {array} cats Category IDs\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tsetCategories(cats, opts) {\n\t\t\t\t// server should have given us back the list of ids we gave it\n\t\t\t\tif (cats.join('') != this.linkCategories.join('')) {\n\t\t\t\t\tconsole.log('warning: setCategories failed to set categories');\n\t\t\t\t}\n\t\t\t},\n\t\t\t/**\n\t\t\t * @function\n\t\t\t * @param {array} ids Asset IDs\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\treserve(ids, opts) {\n\t\t\t\tthis.set('assetId', ids[0]);\n\t\t\t},\n\t\t\t/**\n\t\t\t * @function\n\t\t\t * @param {string} uuid UUID\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tresync(uuid, opts) {\n\t\t\t\tif (!uuid) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\t// Custom events for resyncing\n\t\t\t\tthis.trigger('resyncing', this);\n\n\t\t\t\t// Poll\n\t\t\t\tconst batchJob = this.trackBatchJob(uuid);\n\n\t\t\t\t// When completed\n\t\t\t\tbatchJob.completed.then(() => {\n\t\t\t\t\tthis.trigger('resynced', this);\n\t\t\t\t});\n\n\t\t\t\treturn batchJob;\n\t\t\t},\n\t\t};\n\t}\n\n\t/**\n\t * Internally, the Asset model uses another model, 'metadata', to store DAM metadata attributes.\n\t * (Backbone.Model uses the key 'attributes' in this object to store all other model data.)\n\t * We override the constructor to add that object when the model is created.\n\t * @override\n\t */\n\tconstructor(attr, opts = {}) {\n\t\tsuper(attr, opts);\n\n\t\t/**\n\t\t * Seperate from the asset model's attributes (which describe DAM data) are the following asset model properties\n\t\t * which inform the various RPC methods of this model.\n\t\t *\n\t\t * For remove():\n\t\t * deleteWait determines if deleteAsset() method will block until the DAM is done deleting.\n\t\t * @type {boolean}\n\t\t * @todo No we wont\n\t\t */\n\t\tthis.deleteWait = opts.deleteWait !== true;\n\n\t\t/**\n\t\t * importAttributes: an array of LabelValue objects to set as asset metadata attributes upon import\n\t\t * @type {Array}\n\t\t */\n\t\tthis.importAttributes = opts.importAttributes || [];\n\n\t\t/*\n\t\t * cache of our cart state; 'undefined' means we know nothing.\n\t\t *\n\t\t * @todo As of 7.6.0 assetBeans have inCurrentCart as a property\n\t\t * we need to deprecate all usage of the model property inCurrentCart\n\t\t * in favor of the model attribute inCurrentCart\n\t\t */\n\t\tthis.inCurrentCart = undefined;\n\n\t\t/**\n\t\t * For addCategory, removeCategory, setCategory:\n\t\t * linkCategory is the category ID these calls operate on.\n\t\t * @type {number}\n\t\t */\n\t\tthis.linkCategory = opts.linkCategory || 0;\n\n\t\t/**\n\t\t * for setAssetCategories:\n\t\t * linkCategories is a list of category Ids to set on the asset.\n\t\t * @type {array}\n\t\t */\n\t\tthis.linkCategories = opts.linkCategories || [];\n\t\t/*\n\t\t * collisionStrategy defines ways setAssetCategories can handle a filename collision.\n\t\t * Filenames must be unique within categories. A collision occurs when\n\t\t * we try to move an asset into a category where the asset's filename is already in use.\n\t\t * (Multiple uploads of the same asset are the most common example.) This integer argument to the\n\t\t * setCategoryAssets() API call specifies how to handle that. This object maps those\n\t\t * integers to meaningful labels, but we don't allow API users to change the default strategy,\n\t\t * which is collisionStrategy.rename .\n\t\t * @private\n\t\t */\n\t\tthis.collisionStrategy = _.extend(\n\t\t\t{\n\t\t\t\tfail: 0, // block the category change; leave the asset in its current category.\n\t\t\t\trename: 1, // rename the file we're recategorizing\n\t\t\t},\n\t\t\topts.collisionStrategy,\n\t\t);\n\n\t\t//\n\t\t// for getMessage, a nearly-but-not-quite-deprecated API call which we use to track reimports:\n\t\t// messageType: 4 = messages about asset reimport. Other values unknown.\n\t\t// objectContext: always null for us.\n\t\t// @private\n\t\t//\n\t\tthis.messageType = opts.messageType != null ? opts.messageType : 4;\n\t\t/** @type {string} */\n\t\tthis.objectContext = opts.objectContext || '';\n\n\t\t/**\n\t\t * for repurpose():\n\t\t * repurposeId is the ID of the preset repurposing process to apply with 'repurpose' method. (Netx.asset.processes contains the complete set of those processes, and is indexed by ID.)\n\t\t * @type {number}\n\t\t */\n\t\tthis.repurposeId = opts.repurposeId || 0;\n\n\t\t/**\n\t\t * repurposeOtherIds: meaning varies by process.\n\t\t * @type {array}\n\t\t */\n\t\tthis.repurposeOtherIds = opts.repurposeOtherIds || [];\n\t\tthis.repurposeMethods = opts.repurposeMethods || [];\n\t\tthis.repurposeValues = opts.repurposeValues || [];\n\n\t\t// according to FlexService.java, this field is 100% ignored.\n\t\tthis.repurposeDownloadOverride = opts.repurposeDownloadOverride || '';\n\n\t\t// Keep a model of the current version\n\t\tthis.version = new AssetVersionModel();\n\t\tthis.addSubModel(this.version);\n\n\t\tthis.setMediaUrls();\n\t\tthis.setChecksum();\n\n\t\t/**\n\t\t * @memberof module:asset/models/asset\n\t\t * @alias progress\n\t\t * @type {module:app/models/progress}\n\t\t */\n\t\tthis.progress = new ProgressModel();\n\t\tthis.addSubModel(this.progress);\n\n\t\t/**\n\t\t * @memberof module:asset/models/asset\n\t\t * @alias constituents\n\t\t * @type {module:asset/collections/assetConstituents}\n\t\t */\n\t\tthis.constituents = new AssetConstituentsCollection([]);\n\t\tthis.addSubCollection(this.constituents);\n\n\t\t// Hey, listen!\n\t\tthis\n\t\t\t// Make necessary updates when the id changes\n\t\t\t.listenTo(this, 'change:assetId', (model, assetId, options) => {\n\t\t\t\t// Update this.version when the asset changes id - sync doesn't work in most of our cases as the data is being\n\t\t\t\t// set by the cursor change in the controller with data from an asset collection\n\t\t\t\t// TODO: the asset mimics a sync now when we put it on the cursor - see if this is all still necessary\n\t\t\t\t// and if there may be a better place to put it\n\t\t\t\tthis.version.clear();\n\t\t\t\tif (this.id) {\n\t\t\t\t\tconst versions = this.get('versionIds');\n\t\t\t\t\tif (versions && versions.length > 1) {\n\t\t\t\t\t\tthis.version.set('versionId', versions[0]);\n\t\t\t\t\t\tthis.version.fetch();\n\t\t\t\t\t} else if (versions) {\n\t\t\t\t\t\t// Fake it 'til they make it\n\t\t\t\t\t\tthis.version.set({\n\t\t\t\t\t\t\tcreationDate: this.get('creationdate'),\n\t\t\t\t\t\t\tfileSize: this.get('fileSize2'),\n\t\t\t\t\t\t\tfileTypeId: this.get('filetype'),\n\t\t\t\t\t\t\tfileTypeLabel: this.get('filetypelabel'),\n\t\t\t\t\t\t\tassetId: this.get('imageid'),\n\t\t\t\t\t\t\tuserId: this.get('moduserid'),\n\t\t\t\t\t\t\tuserLabel: this.get('moduserlabel'),\n\t\t\t\t\t\t});\n\t\t\t\t\t\t// Mimic a sync\n\t\t\t\t\t\tthis.version.trigger('sync', this.version);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Custom thumbnail progress listeners\n\t\t\t\tconst oldAssetId = this._previousAttributes.assetId;\n\t\t\t\tthis.setupCustomThumbnailListeners(oldAssetId);\n\t\t\t\tthis.setupAssetTaskListeners(oldAssetId);\n\t\t\t\tthis.setMediaUrls();\n\t\t\t\tthis.setChecksum();\n\t\t\t})\n\t\t\t////////////////////////////\n\t\t\t// ADBUILDER\n\t\t\t////////////////////////////\n\t\t\t.listenTo(\n\t\t\t\tdispatcher,\n\t\t\t\t'adBuilder:activate:asset:error',\n\t\t\t\t(error, asset) => {\n\t\t\t\t\tasset &&\n\t\t\t\t\t\tasset.id === this.id &&\n\t\t\t\t\t\tthis.set({\n\t\t\t\t\t\t\tactivatingTemplate: false,\n\t\t\t\t\t\t\ttemplate: false,\n\t\t\t\t\t\t\ttemplateCustomizable: false,\n\t\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t)\n\t\t\t.listenTo(dispatcher, 'adBuilder:activate:asset:start', (asset) => {\n\t\t\t\tasset &&\n\t\t\t\t\tasset.id === this.id &&\n\t\t\t\t\tthis.set({\n\t\t\t\t\t\tactivatingTemplate: true,\n\t\t\t\t\t\tdeactivatingTemplate: false,\n\t\t\t\t\t});\n\t\t\t})\n\t\t\t.listenTo(dispatcher, 'adBuilder:activate:asset:succeeded', (asset) => {\n\t\t\t\tasset &&\n\t\t\t\t\tasset.id === this.id &&\n\t\t\t\t\tthis.set({\n\t\t\t\t\t\tactivatingTemplate: false,\n\t\t\t\t\t\ttemplate: true,\n\t\t\t\t\t});\n\t\t\t})\n\t\t\t.listenTo(\n\t\t\t\tdispatcher,\n\t\t\t\t'adBuilder:deactivate:asset:error',\n\t\t\t\t(error, asset) => {\n\t\t\t\t\tasset &&\n\t\t\t\t\t\tasset.id === this.id &&\n\t\t\t\t\t\tthis.set({\n\t\t\t\t\t\t\tdeactivatingTemplate: false,\n\t\t\t\t\t\t\ttemplate: true,\n\t\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t)\n\t\t\t.listenTo(dispatcher, 'adBuilder:deactivate:asset:start', (asset) => {\n\t\t\t\tasset &&\n\t\t\t\t\tasset.id === this.id &&\n\t\t\t\t\tthis.set({\n\t\t\t\t\t\tactivatingTemplate: false,\n\t\t\t\t\t\tdeactivatingTemplate: true,\n\t\t\t\t\t});\n\t\t\t})\n\t\t\t.listenTo(dispatcher, 'adBuilder:deactivate:asset:succeeded', (asset) => {\n\t\t\t\tasset &&\n\t\t\t\t\tasset.id === this.id &&\n\t\t\t\t\tthis.set({\n\t\t\t\t\t\tdeactivatingTemplate: false,\n\t\t\t\t\t\ttemplate: false,\n\t\t\t\t\t\ttemplateCustomizable: false,\n\t\t\t\t\t});\n\t\t\t})\n\t\t\t////////////////////////////\n\t\t\t// !ADBUILDER\n\t\t\t////////////////////////////\n\n\t\t\t////////////////////////////\n\t\t\t// ATTRIBUTES (METADATA)\n\t\t\t////////////////////////////\n\t\t\t.listenTo(\n\t\t\t\tdispatcher,\n\t\t\t\t'asset:submit:save asset:info:edit:success asset:attributes:submit:success',\n\t\t\t\t(m) => {\n\t\t\t\t\tif (m.cid !== this.cid && m.id === this.id) {\n\t\t\t\t\t\tthis.set(m.attributes);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t)\n\t\t\t////////////////////////////\n\t\t\t// !ATTRIBUTES (METADATA)\n\t\t\t////////////////////////////\n\n\t\t\t////////////////////////////////\n\t\t\t// CART STATUS\n\t\t\t////////////////////////////////\n\t\t\t// Tracking whether we're in the current cart:\n\t\t\t// If we are added to the cart, we know we're in it\n\t\t\t.listenTo(dispatcher, 'cart:added', (ids) => {\n\t\t\t\tif (ids.indexOf(this.id) < 0) return;\n\n\t\t\t\tif (this.has('inCurrentCart')) {\n\t\t\t\t\tthis.set('inCurrentCart', true);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tthis.inCurrentCart = true;\n\t\t\t\tthis.trigger('change');\n\t\t\t})\n\t\t\t// If we are removed, we know we're not in it\n\t\t\t.listenTo(dispatcher, 'cart:removed', (ids) => {\n\t\t\t\tif (ids.indexOf(this.id) < 0) return;\n\n\t\t\t\tif (this.has('inCurrentCart')) {\n\t\t\t\t\tthis.set('inCurrentCart', false);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tthis.inCurrentCart = false;\n\t\t\t\tthis.trigger('change');\n\t\t\t})\n\t\t\t// If the cart is cleared, we know we're not in it.\n\t\t\t.listenTo(dispatcher, 'cart:cleared', () => {\n\t\t\t\tif (this.has('inCurrentCart')) {\n\t\t\t\t\tthis.set('inCurrentCart', false);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tthis.inCurrentCart = false;\n\t\t\t\tthis.trigger('change');\n\t\t\t})\n\t\t\t////////////////////////////////\n\t\t\t// !CART STATUS\n\t\t\t////////////////////////////////\n\n\t\t\t// When a checkout & checkin happens, update our status & checked-out-ness\n\t\t\t.listenTo(\n\t\t\t\tdispatcher,\n\t\t\t\t'asset:checkout:success asset:checkout:cancel:success',\n\t\t\t\t(asset) => {\n\t\t\t\t\t// we are us!\n\t\t\t\t\t// we are not a duplicate model for the same DAM asset\n\t\t\t\t\tif (asset === this || asset.id !== this.id) return;\n\n\t\t\t\t\tthis.set({\n\t\t\t\t\t\tstatus: asset.get('status'),\n\t\t\t\t\t\tcheckout: asset.get('checkout'),\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t)\n\t\t\t// Batch jobs\n\t\t\t.listenTo(this, 'progress', (model, batchJob, progress) => {\n\t\t\t\tconst progressMessage = (batchJob && batchJob.get('details')) || '';\n\t\t\t\tthis.progress.update(progress, progressMessage);\n\t\t\t})\n\t\t\t.listenTo(this, 'complete', (model, batchJob) => {\n\t\t\t\tthis.progress.complete();\n\t\t\t})\n\t\t\t// When asset sybcs\n\t\t\t.listenTo(this, 'sync', (model) => {\n\t\t\t\tif (model !== this) return;\n\t\t\t\tthis.progress.reset();\n\t\t\t})\n\t\t\t// When a clip is created/updated\n\t\t\t.listenTo(\n\t\t\t\tdispatcher,\n\t\t\t\t'asset:constituent:clip:edit:success',\n\t\t\t\t(asset, clip, isNew) => {\n\t\t\t\t\tif (asset.id !== this.id) return;\n\n\t\t\t\t\tthis.constituents.clips.add(clip);\n\t\t\t\t},\n\t\t\t);\n\n\t\t// Custom thumbnail progress listeners\n\t\tthis.setupCustomThumbnailListeners();\n\t\tthis.setupAssetTaskListeners();\n\t\tthis.setupAssetCheckinListeners();\n\t}\n\n\t/**\n\t * The parse() method converts the contents of the AssetBean's attributeNames & attributeValues arrays\n\t * into the internal metadata model.\n\t * @override\n\t * @param {object} resp Asset bean\n\t * @param {object} opts Request options\n\t * @return {object} the unmodified attributes. (The internal attribute* arrays will still be updated from this data.)\n\t */\n\tparse(resp, opts) {\n\t\t// Set media urls\n\t\treturn _.extend(_.omit(resp, 'validationData', 'id'), {\n\t\t\taudioUrl: this.hasAudio(resp) || '',\n\t\t\tvideoUrl: this.hasVideo(resp) || '',\n\t\t\tzoomUrl: this.hasZoom(resp) || '',\n\t\t});\n\t}\n\n\t/**\n\t * the self() method translates the metadata object back into arrays,\n\t * being careful to preserve the same order as the attributeNames array.\n\t * @override\n\t * @return {object}\n\t */\n\tself() {\n\t\treturn _.omit.apply(\n\t\t\t_,\n\t\t\t[\n\t\t\t\tthis.attributes,\n\t\t\t\t'attributeValues',\n\t\t\t\t'attributeNames',\n\t\t\t\t'attributeIds',\n\t\t\t].concat(this.clientAttrs),\n\t\t);\n\t}\n\n\t/** @method */\n\tvalidate(attrs) {\n\t\tif (!_.isNumber(attrs.assetId)) {\n\t\t\treturn 'Must pass a number';\n\t\t}\n\t}\n\n\t/**\n\t * @method\n\t * @return {boolean} Can zoom\n\t */\n\tcanZoom() {\n\t\treturn (\n\t\t\tthis.isImage() &&\n\t\t\tthis.get('filewidth') > 0 &&\n\t\t\tthis.get('fileheight') > 0 &&\n\t\t\tthis.get('zoomAvailable') &&\n\t\t\t(Netx.getPreference('zoom.tiles.enabled', true) ||\n\t\t\t\t(Netx.getPreference('equilibrium.enabled', true) &&\n\t\t\t\t\tNetx.getPreference('equilibrium.zoomEnabled', true)))\n\t\t);\n\t}\n\n\t/**\n\t * @method\n\t * @param {string} dateStr Date (yyyy-mm-dd)\n\t */\n\texpire(dateStr) {\n\t\ttry {\n\t\t\tconst expirationTime = userInputToExpirationTime(dateStr);\n\t\t\treturn this.set('expirationDate', expirationTime).expireAsset();\n\t\t} catch (ex) {\n\t\t\treturn new $.Deferred().reject(ex);\n\t\t}\n\t}\n\n\t/**\n\t * @method\n\t * @param {object} opts Request options\n\t */\n\tfetchConstituents(opts) {\n\t\tvar constituents = this.constituents;\n\n\t\tif (constituents.assetId === this.id) {\n\t\t\treturn new $.Deferred().resolveWith(constituents);\n\t\t}\n\n\t\tconstituents.assetId = this.id;\n\t\treturn constituents.fetch(\n\t\t\t_.extend(\n\t\t\t\t{\n\t\t\t\t\tduplicateQueryPolicy: 'abort',\n\t\t\t\t\treset: true,\n\t\t\t\t},\n\t\t\t\topts,\n\t\t\t),\n\t\t);\n\t}\n\n\tgarbageCollect() {\n\t\tsuper.garbageCollect();\n\t\tdelete this.progress;\n\t\tdelete this.version;\n\t\tdelete this.constituents;\n\t}\n\n\t/**\n\t * getAttribute() and setAttribute() are the preferred interface to the DAM's internal representation of asset attributes.\n\t * @method\n\t * @param {number} templateId Template id\n\t * @param {string} name Template name\n\t * @param {object} opts Options\n\t * @return {mixed}\n\t */\n\tgetAttribute(templateId, name, opts = {}) {\n\t\tconst attrModel = Netx.getAttribute(templateId, name);\n\t\tlet value;\n\n\t\tif (attrModel) {\n\t\t\tvalue =\n\t\t\t\tattrModel.get('system') &&\n\t\t\t\tattrModel.id !== -119 && // Smart labels\n\t\t\t\tattrModel.id !== -120 // dimensions\n\t\t\t\t\t? this.getSystemAttribute(attrModel.id)\n\t\t\t\t\t: this.get('attributeValues')[\n\t\t\t\t\t\t\t_.indexOf(this.get('attributeIds'), attrModel.id)\n\t\t\t\t\t ];\n\n\t\t\tvalue = opts.format\n\t\t\t\t? attrModel.format(value, opts)\n\t\t\t\t: attrModel.parseInValue(value);\n\t\t}\n\n\t\treturn value != null ? value : '';\n\t}\n\n\t/**\n\t * Get attribute template id by name\n\t * @param {string} name Attribute name\n\t * @return {number}\n\t */\n\tgetAttributeId(name) {\n\t\treturn Netx.getAttributeId(name);\n\t}\n\n\t/**\n\t * @method\n\t * @param {number} templateId Template id\n\t * @param {object} opts Options\n\t * @return {mixed}\n\t * @deprecated see `this.getAttribute`\n\t */\n\tgetAttributeValue(templateId, opts) {\n\t\treturn this.getAttribute(templateId, null, opts);\n\t}\n\n\t/**\n\t * @method\n\t * @param {number} templateId Attribute template id\n\t * @return {mixed}\n\t */\n\tgetSystemAttribute(templateId, name) {\n\t\tconst attrModel = Netx.getAttribute(templateId, name);\n\n\t\tlet value;\n\t\tif (attrModel) {\n\t\t\tvar attrName = attrModel.get('name');\n\t\t\t// Normalize\n\t\t\tswitch (attrModel.get('name')) {\n\t\t\t\tcase 'creationDate':\n\t\t\t\t\tattrName = 'creationdate';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'expireDate':\n\t\t\t\t\tattrName = 'expirationDate';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'fileSize':\n\t\t\t\t\tattrName = 'fileSize2';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'fileType':\n\t\t\t\t\tattrName = 'filetypelabel';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'folderPath':\n\t\t\t\t\tattrName = 'categoryPaths';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'height':\n\t\t\t\t\tattrName = 'fileheight';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'modDate':\n\t\t\t\t\tattrName = 'moddate';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'width':\n\t\t\t\t\tattrName = 'filewidth';\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tvalue = this.get(attrName);\n\t\t\tif (_.isArray(value)) {\n\t\t\t\tvalue.join(', ');\n\t\t\t}\n\t\t}\n\n\t\treturn value != null ? value : '';\n\t}\n\n\t/**\n\t * @method\n\t * @return {string} Token string if it exists\n\t */\n\tgetTokenString() {\n\t\tconst token = Netx.getToken();\n\t\treturn token ? '?token=' + token : '';\n\t}\n\n\t/**\n\t * @method\n\t * @return {array} Waveform JSON\n\t */\n\tgetWaveformJSON() {\n\t\treturn $.getJSON(\n\t\t\t`/file/asset/${this.id}/view/previewWaveformJSON${this.getTokenString()}`,\n\t\t).then((json) => {\n\t\t\treturn json.data;\n\t\t});\n\t}\n\n\t/**\n\t * Does asset have audio, get the audio url\n\t * @method\n\t * @param {object} attrs Attributes to use (rather than `this.get`)\n\t * @return {boolean}\n\t */\n\thasAudio(attrs = {}) {\n\t\tconst id = attrs.assetId || this.id;\n\t\tif (\n\t\t\t_.indexOf(\n\t\t\t\tattrs.fileFormatFamily || this.get('fileFormatFamily'),\n\t\t\t\t'audio',\n\t\t\t) < 0\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\n\t\tlet url = false;\n\t\tconst tokenStr = this.getTokenString();\n\t\t// Check in view names\n\t\tif (\n\t\t\t_.indexOf(attrs.viewNames || this.get('viewNames'), 'previewMp3') > -1\n\t\t) {\n\t\t\turl = [\n\t\t\t\t'/file/asset/',\n\t\t\t\tid,\n\t\t\t\t'/view/previewMp3/a_',\n\t\t\t\tid,\n\t\t\t\t'.mp3',\n\t\t\t\ttokenStr,\n\t\t\t].join('');\n\t\t}\n\t\t// Check in file type label\n\t\telse if ((attrs.filetypelabel || this.get('filetypelabel')) === 'mp3') {\n\t\t\turl = ['/file/asset/', id, '/original/a_', id, '.mp3', tokenStr].join('');\n\t\t}\n\n\t\treturn url;\n\t}\n\n\t/**\n\t * @method\n\t * @param {string} format Format\n\t * @return {boolean} Has format family\n\t */\n\thasFormatFamily(format) {\n\t\treturn _.contains(this.get('fileFormatFamily'), format);\n\t}\n\n\t/**\n\t * Does asset have any multimedia (audio/video)\n\t * @method\n\t * @return {boolean|string} Audio url or false\n\t */\n\thasMultimedia() {\n\t\treturn this.hasAudio() || this.hasVideo();\n\t}\n\n\t/**\n\t * Does asset have video, get the video url\n\t * @method\n\t * @param {object} attrs Attributes to use (rather than `this.get`)\n\t * @return {boolean|string} Video url or false\n\t */\n\thasVideo(attrs = {}) {\n\t\tconst id = attrs.assetId || this.id;\n\t\tconst tokenStr = this.getTokenString();\n\n\t\tif (\n\t\t\t_.indexOf(\n\t\t\t\tattrs.fileFormatFamily || this.get('fileFormatFamily'),\n\t\t\t\t'video',\n\t\t\t) < 0\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\n\t\tlet url = false;\n\t\tif (\n\t\t\t_.indexOf(attrs.viewNames || this.get('viewNames'), 'previewH264') !== -1\n\t\t) {\n\t\t\turl = [\n\t\t\t\t'/file/asset/',\n\t\t\t\tid,\n\t\t\t\t'/view/previewH264/v_',\n\t\t\t\tid,\n\t\t\t\t'.mp4',\n\t\t\t\ttokenStr,\n\t\t\t].join('');\n\t\t}\n\t\t// Check in file type label\n\t\telse if ((attrs.filetypelabel || this.get('filetypelabel')) === 'mp4') {\n\t\t\turl = ['/file/asset/', id, '/original/v_', id, '.mp4', tokenStr].join('');\n\t\t}\n\n\t\treturn url;\n\t}\n\n\t/**\n\t * Does asset have a zoom view (Longest side is 1000), get the zoom url\n\t * @method\n\t * @param {object} attrs Attributes to use (rather than `this.get`)\n\t * @return {boolean|string} Zoom url or false\n\t */\n\thasZoom(attrs = {}) {\n\t\tconst id = attrs.assetId || this.id;\n\t\tconst filetypelabel = attrs.filetypelabel || this.get('filetypelabel');\n\t\treturn `/file/asset/${id}/zoom/${id}.${filetypelabel}`;\n\t}\n\n\t/**\n\t * Only for use in updating attribute values locally (like after a change from elsewhere)\n\t * Once we get websockets this will be deprecated\n\t * @method\n\t * @param {number|string} templateId Attribute template id\n\t * @param {string} val Value of the attribute to set\n\t */\n\tsetAttribute(templateId, val, opts) {\n\t\tconst id = _.isString(templateId) ? null : templateId;\n\t\tconst name = _.isString(templateId) ? templateId : null;\n\t\tconst attrModel = Netx.getAttribute(id, name);\n\n\t\tif (!attrModel) return this;\n\n\t\tconst idx = _.indexOf(this.get('attributeIds'), attrModel.id);\n\n\t\tif (attrModel.isCSV || attrModel.isTrueMultivalue()) {\n\t\t\tval = _.arrayToCsv(val);\n\t\t}\n\n\t\tif (idx > -1) {\n\t\t\tconst attributeValues = _.clone(this.get('attributeValues'));\n\t\t\tattributeValues[idx] = val;\n\t\t\treturn this.set(\n\t\t\t\t{\n\t\t\t\t\tattributeValues: attributeValues,\n\t\t\t\t},\n\t\t\t\topts,\n\t\t\t);\n\t\t}\n\n\t\treturn this.set(\n\t\t\t{\n\t\t\t\tattributeIds: this.get('attributeIds').concat([attrModel.id]),\n\t\t\t\tattributeNames: this.get('attributeNames').concat([attrModel.name]),\n\t\t\t\tattributePermissions: this.get('attributePermissions').concat(['r']),\n\t\t\t\tattributeValues: this.get('attributeValues').concat([val]),\n\t\t\t},\n\t\t\topts,\n\t\t);\n\t}\n\n\t/**\n\t * @method\n\t * @listens module:upload#upload:asset:checkin:complete\n\t * @listens module:upload#upload:asset:checkin:progress\n\t * @listens module:upload#upload:asset:checkin:error\n\t */\n\tsetupAssetCheckinListeners() {\n\t\tthis.stopListening(dispatcher, 'upload:asset:checkin:progress')\n\t\t\t.stopListening(dispatcher, 'upload:asset:checkin:complete')\n\t\t\t.stopListening(dispatcher, 'upload:asset:checkin:error')\n\t\t\t.listenTo(\n\t\t\t\tdispatcher,\n\t\t\t\t'upload:asset:checkin:progress',\n\t\t\t\t(assetId, progress, progressMessage, file) => {\n\t\t\t\t\tif (assetId !== this.id) return;\n\n\t\t\t\t\tthis.trigger('checkingIn', this, file);\n\t\t\t\t\tthis.progress.update(progress, progressMessage);\n\t\t\t\t},\n\t\t\t)\n\t\t\t.listenTo(\n\t\t\t\tdispatcher,\n\t\t\t\t'upload:asset:checkin:complete',\n\t\t\t\t(assetId, file) => {\n\t\t\t\t\tif (assetId !== this.id) return;\n\n\t\t\t\t\tthis.trigger('checkedIn', this, file);\n\t\t\t\t\tthis.progress.complete();\n\t\t\t\t\t// Delay slightly so the progress removal does not seem so abrupt\n\t\t\t\t\t_.delay(_.bind(this.fetch, this), 1000);\n\t\t\t\t},\n\t\t\t)\n\t\t\t.listenTo(\n\t\t\t\tdispatcher,\n\t\t\t\t'upload:asset:checkin:error',\n\t\t\t\t(error, assetId, file) => {\n\t\t\t\t\tthis.trigger('checkedIn', this, file);\n\t\t\t\t\tthis.progress.complete();\n\t\t\t\t},\n\t\t\t)\n\t\t\t.stopListening(dispatcher, 'asset:versions:reactivate:progress')\n\t\t\t.stopListening(dispatcher, 'asset:versions:reactivate:succeeded')\n\t\t\t.stopListening(dispatcher, 'asset:versions:reactivate:error')\n\t\t\t.listenTo(\n\t\t\t\tdispatcher,\n\t\t\t\t'asset:versions:reactivate:progress',\n\t\t\t\t(assetId, progress, progressMessage) => {\n\t\t\t\t\tif (assetId !== this.id) return;\n\t\t\t\t\tthis.progress.update(progress, progressMessage);\n\t\t\t\t},\n\t\t\t)\n\t\t\t.listenTo(\n\t\t\t\tdispatcher,\n\t\t\t\t'asset:versions:reactivate:succeeded',\n\t\t\t\t(newVersion) => {\n\t\t\t\t\tif (newVersion.get('assetId') !== this.id) return;\n\t\t\t\t\tthis.progress.complete();\n\t\t\t\t},\n\t\t\t)\n\t\t\t.listenTo(\n\t\t\t\tdispatcher,\n\t\t\t\t'asset:versions:reactivate:error',\n\t\t\t\t(error, newVersion) => {\n\t\t\t\t\tif (newVersion.get('assetId') !== this.id) return;\n\t\t\t\t\tthis.progress.complete();\n\t\t\t\t},\n\t\t\t);\n\t}\n\n\t/**\n\t * Setup asset task listeners (cleans up any old listeners as well)\n\t * @method\n\t * @param {number} oldAssetId Old asset id\n\t */\n\tsetupAssetTaskListeners(oldAssetId) {\n\t\tif (oldAssetId) {\n\t\t\t// asset:task:complete:\n\t\t\tthis.stopListening(dispatcher, 'asset:task:complete:' + oldAssetId);\n\t\t\tthis.stopListening(dispatcher, 'asset:task:' + oldAssetId + ':status');\n\t\t}\n\n\t\tif (!this.id) return;\n\n\t\t// Task completion\n\t\tthis.listenTo(dispatcher, 'asset:task:complete:' + this.id, (task) => {\n\t\t\t// HACKETY-HACK-SMACK-HACK for EIGHT-549:\n\t\t\tconst tempIconPattern = /\\/icons\\/.*\\.png$/;\n\t\t\tlet previewNow = this.get('previewUrl');\n\n\t\t\t// If we currently have no previewUrl, or a temporary icon preview ...\n\t\t\tif (!previewNow || previewNow.match(tempIconPattern)) {\n\t\t\t\t// ... then poll until the DAM generates a proper preview, or we run out of patience.\n\t\t\t\tconst patienceExhausted = 4; // only try this many times.\n\t\t\t\tlet timesPolled = 0;\n\t\t\t\tthis.pollUntil(\n\t\t\t\t\t() => {\n\t\t\t\t\t\tpreviewNow = this.get('previewUrl'); // possibly updated?\n\t\t\t\t\t\ttimesPolled++;\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t(previewNow && !previewNow.match(tempIconPattern)) ||\n\t\t\t\t\t\t\ttimesPolled >= patienceExhausted\n\t\t\t\t\t\t);\n\t\t\t\t\t},\n\t\t\t\t\tundefined,\n\t\t\t\t\tundefined,\n\t\t\t\t\t2000,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.progress.complete();\n\t\t\tthis.trigger('taskComplete', this, task);\n\t\t})\n\t\t\t// Task status\n\t\t\t.listenTo(dispatcher, 'asset:task:' + this.id + ':status', (task) => {\n\t\t\t\t// Shows our import tasks percentage as the second half of our total import progress;\n\t\t\t\t// therefore, we divide by 2 and add 50.\n\t\t\t\tconst realProgress = task.get('percentComplete') / 2 + 50;\n\t\t\t\tconst tasks = task.get('tasks') || [];\n\t\t\t\tthis.progress.update(\n\t\t\t\t\trealProgress,\n\t\t\t\t\timportTasks[tasks[0]] || i18n.t('i18n.processing'),\n\t\t\t\t);\n\t\t\t\tthis.trigger('taskStatus', this, task);\n\t\t\t});\n\t}\n\n\t/**\n\t * Cleans up old listeners (if any) and adds new listeners for all your custom thumbnail needs\n\t * @method\n\t * @param {number} oldAssetId Old asset id\n\t */\n\tsetupCustomThumbnailListeners(oldAssetId) {\n\t\t// NOTE: normalized the 'error' event as we have many a use for a good 'ol lower cased error event\n\t\t// Its return will not be the same as pluploads - it will return an error message and an assetId (if it can get itoff the details)\n\t\tlet eventPrefix;\n\t\t// Clean up any old listeners (really only an issue with Netx.asset.current)\n\t\tif (oldAssetId) {\n\t\t\teventPrefix = 'upload:asset:customThumbnail:' + oldAssetId;\n\t\t\t// asset:customThumbnail:upload::error\n\t\t\t// asset:customThumbnail:upload::FilesAdded\n\t\t\t// asset:customThumbnail:upload::UploadProgress\n\t\t\t// asset:customThumbnail:upload::polling\n\t\t\t// asset:customThumbnail:upload::success\n\t\t\tthis.stopListening(dispatcher, eventPrefix + ':error');\n\t\t\tthis.stopListening(dispatcher, eventPrefix + ':FilesAdded');\n\t\t\tthis.stopListening(dispatcher, eventPrefix + ':UploadProgress');\n\t\t\tthis.stopListening(dispatcher, eventPrefix + ':progress');\n\t\t\tthis.stopListening(dispatcher, eventPrefix + ':success');\n\t\t}\n\n\t\tif (!this.id) return;\n\n\t\t// Events for custom thumbnail\n\t\teventPrefix = 'upload:asset:customThumbnail:' + this.id;\n\n\t\tthis\n\t\t\t// Listen for error\n\t\t\t// asset:customThumbnail:upload::error\n\t\t\t.listenTo(dispatcher, eventPrefix + ':error', (error) => {\n\t\t\t\tthis.set({\n\t\t\t\t\tprogress: 0,\n\t\t\t\t\tupdating: false,\n\t\t\t\t});\n\t\t\t})\n\t\t\t// Listen for FilesAdded\n\t\t\t// This basically means that a new custom thumbnail is being uploaded\n\t\t\t// asset:customThumbnail:upload::FilesAdded\n\t\t\t.listenTo(dispatcher, eventPrefix + ':FilesAdded', (pluploader, file) => {\n\t\t\t\tthis.progress.update(0, i18n.t('i18n.addingCustomThumbnail'));\n\t\t\t})\n\t\t\t// Listen for UploadProgress\n\t\t\t// Half the progress since this is a two part process\n\t\t\t// asset:customThumbnail:upload::UploadProgress\n\t\t\t.listenTo(\n\t\t\t\tdispatcher,\n\t\t\t\teventPrefix + ':UploadProgress',\n\t\t\t\t(pluploader, file) => {\n\t\t\t\t\tthis.progress.update(\n\t\t\t\t\t\tparseInt(file.percent / 2),\n\t\t\t\t\t\ti18n.t('i18n.uploadingCustumThumbnail'),\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t)\n\t\t\t// Listen for polling\n\t\t\t// Thumbnail has been uploaded and the job is running on the server\n\t\t\t// Half the progress and add 50 (two part process and we are the second part)\n\t\t\t// asset:customThumbnail:upload::polling\n\t\t\t.listenTo(dispatcher, eventPrefix + ':progress', (batchJob, progress) => {\n\t\t\t\tthis.progress.update(\n\t\t\t\t\t50 + parseInt(progress / 2),\n\t\t\t\t\ti18n.t('i18n.settingCustomThumbnail'),\n\t\t\t\t);\n\t\t\t})\n\t\t\t// Listen for suceess\n\t\t\t// Thumbnail uploaded and job complete\n\t\t\t// asset:customThumbnail:upload::success\n\t\t\t.listenTo(dispatcher, eventPrefix + ':success', (file) => {\n\t\t\t\tthis.progress.complete();\n\t\t\t\t// If we did not have a thumbUrl at all, just ignore as we are some sort of dummy asset model\n\t\t\t\tif (!this.get('thumbUrl')) return;\n\n\t\t\t\t// Delay slightly since this could have gone way too fast (avoid janky progress)\n\t\t\t\t_.delay(() => {\n\t\t\t\t\tthis.fetch().then(() => {\n\t\t\t\t\t\t// TODO: Need to discuss the DAM updating the moddate when a custom thumbnail is selected\n\t\t\t\t\t\tthis.trigger('thumbnailUpdated', file);\n\t\t\t\t\t});\n\t\t\t\t}, 1000);\n\t\t\t});\n\t}\n\n\t/**\n\t * Deduces the url required to access asset media (video, audio, zoom)\n\t * You know, so we are not repeating this logic all over the place in views etc\n\t * This makes the change silently as nothing abotu the asset has actually changed or needed to come from the server\n\t * These attributes are defined in clientAttrs and cleaned up when this.self is called\n\t * @method\n\t */\n\tsetMediaUrls(attrs) {\n\t\tif (!this.id) return;\n\n\t\t// Check and see if we are video, audio etc and set proper urls\n\t\tthis.set('audioUrl', this.hasAudio(attrs) || '');\n\t\tthis.set('videoUrl', this.hasVideo(attrs) || '');\n\t\tthis.set('zoomUrl', this.hasZoom(attrs) || '');\n\t}\n\n\t/**\n\t * Pretend this is a thing\n\t * @method\n\t */\n\tsetChecksum() {\n\t\tif (checksumEnabled()) {\n\t\t\tthis.set('checksum', this.get('attribute4'));\n\t\t}\n\t}\n\n\t/**\n\t * @method\n\t */\n\tunexpire() {\n\t\treturn this.set('expirationDate', 0).expireAsset();\n\t}\n\n\t/**\n\t * @deprecated\n\t * setCombo() and getCombo() interface with the DAM's internal representation of a choice list, aka a Pulldown,\n\t * as used for attributes of type 'select', 'multiselect' and 'tags'.\n\t *\n\t * setCombo: Encode a combo attribute as CSV before setting. A subsequent save() will write changes to the DAM.\n\t * @method\n\t * @param {String} name Name of the attribute to set choices for.\n\t * @param {Array} vals An array of strings: new values for the attribute. This can be empty, to clear the list.\n\t */\n\tsetCombo(name, vals) {\n\t\tthis.setAttribute(name, _.arrayToCsv(vals));\n\t}\n\n\t/**\n\t * @deprecated\n\t * Decode a combo attribute from CSV before getting\n\t * @method\n\t * @param {String} name Name of the attribute to get choices for.\n\t * @return {Array} a list of strings.\n\t */\n\tgetCombo(name) {\n\t\treturn _.csvToArray(this.getAttribute(null, name));\n\t}\n\n\t/**\n\t * moveCategory: Move an asset from one category to another, triggering events 'asset:category:removed', 'asset:category:added' and 'asset:category:moved'.\n\t * This method calls setAssetCategories(), so other categories may be removed in the process.\n\t * @param {number} from ID of category to leave (if not provided, will remove from all other categories)\n\t * @param {number} to ID of category to enter\n\t *\n\t * @todo this is too sloppy. We need these events in order to do proper UI feedback for recategorization.\n\t * Both 'from' and 'to' should be arrays ... but really 'from' should go away & we should look at asset.categories instead.\n\t * We should then trigger asset:category:removed for every one of those that's not in 'to' .\n\t */\n\tmoveCategory(from, to) {\n\t\tif (from == to) {\n\t\t\t// no-op!\n\t\t\treturn new $.Deferred().resolve();\n\t\t}\n\n\t\tif (from == null || isNaN(from)) from = this.get('categories');\n\t\tif (!Array.isArray(from)) from = [from];\n\t\tthis.linkCategories = _.without\n\t\t\t.apply(_, [this.get('categories')].concat(from))\n\t\t\t.concat([to]);\n\n\t\treturn this.setCategories().then(() => {\n\t\t\treturn this.fetch().then(() => {\n\t\t\t\t// Success\n\t\t\t\tfrom.forEach((catId) => {\n\t\t\t\t\tdispatcher.trigger('asset:category:removed', this.id, catId, this);\n\t\t\t\t\tdispatcher.trigger('asset:category:moved', this.id, catId, to, this);\n\t\t\t\t});\n\t\t\t\tdispatcher.trigger('asset:category:added', this.id, to, this);\n\n\t\t\t\t// DAM-21440: What tasks are there to track on a single asset move?\n\t\t\t\t// this _defer is a hack around a DAM bug ...\n\t\t\t\t// but which one?\n\t\t\t\t// _.defer(() => {\n\t\t\t\t// \tdispatcher.trigger('asset:tasks:track', this.id);\n\t\t\t\t// });\n\t\t\t});\n\t\t});\n\t}\n\n\t/**\n\t * @method\n\t * @return {boolean} Is document\n\t */\n\tisDocument() {\n\t\treturn (\n\t\t\t(this.get('constituentIds').length > 0 && this.isPDF()) ||\n\t\t\tthis.get('fileFormatFamily').includes('document')\n\t\t);\n\t}\n\t/**\n\t * Check if we are an image\n\t * @method\n\t * @return {boolean}\n\t */\n\tisImage() {\n\t\tconst fileFormatFamily = this.get('fileFormatFamily');\n\t\treturn (\n\t\t\tfileFormatFamily.includes('image') ||\n\t\t\tfileFormatFamily.includes('raw') ||\n\t\t\tfileFormatFamily.includes('cameraRaw')\n\t\t);\n\t}\n\n\t/**\n\t * @method\n\t * @return {boolean} Is locked\n\t */\n\tisLocked() {\n\t\treturn this.get('readOnly') === 1;\n\t}\n\n\t/**\n\t * Check if we are a PDF\n\t * @method\n\t * @return {boolean}\n\t */\n\tisPDF() {\n\t\treturn (\n\t\t\t_.indexOf(this.get('viewNames'), 'previewPDF') !== -1 ||\n\t\t\tthis.get('filetypelabel') === 'pdf'\n\t\t);\n\t}\n\n\t/**\n\t * Lock an asset (previously set asset to \"read-only\")\n\t * @method\n\t */\n\tlock(opts) {\n\t\t// Why we need the bean returned on updates\n\t\t// Fetching to get the appropriate permission matrix\n\t\treturn this.save({readOnly: 1}, {wait: true, ...opts}).then(() => {\n\t\t\treturn this.fetch(opts);\n\t\t});\n\t}\n\n\t/**\n\t * Return an assetSet object defining the set that contains just this asset.\n\t * @method\n\t * @return {module:asset/models/assetSet} AssetSet model\n\t */\n\ttoAssetSet() {\n\t\treturn new AssetSetModel({\n\t\t\ttype: assetSetTypes.asset,\n\t\t\tids: [this.id],\n\t\t\tmodels: [this],\n\t\t\tlabel: this.get('name'),\n\t\t});\n\t}\n\n\t/**\n\t * Unlock an asset (previously unset asset from \"read-only\")\n\t * @method\n\t */\n\tunlock(opts) {\n\t\t// Why we need the bean returned on updates\n\t\t// Fetching to get the appropriate permission matrix\n\t\treturn this.save({readOnly: 0}, {wait: true, ...opts}).then(() => {\n\t\t\treturn this.fetch(opts);\n\t\t});\n\t}\n\n\t/**\n\t * return a cache-busting string for the asset preview; this string should change every time the asset preview changes.\n\t * @method\n\t * @return string\n\t */\n\tcacheBuster(prefix) {\n\t\t// If this model doesn't have moddate set, use the current time.\n\t\tconst timeStr = this.get('moddate')\n\t\t\t? _.dateFromAsset(this.get('moddate')).getTime()\n\t\t\t: new Date().getTime();\n\n\t\t// A new checkin will change the preview image without modifying the moddate.\n\t\t// Therefore, encode both versionIds and moddate in the buster-string\n\t\treturn (\n\t\t\t'?' +\n\t\t\t(prefix ? prefix + '&' : '') +\n\t\t\t't=' +\n\t\t\ttimeStr +\n\t\t\t'&v=' +\n\t\t\tthis.get('versionIds')\n\t\t);\n\t}\n\n\t/**\n\t * @deprecated\n\t * Force a local update of the asset's moddate property, so that this.cacheBuster() will return a new string,\n\t * and so that any change listeners for moddate will be jingled.\n\t * Moddate is a read-only property, so any future fetch will reset it to the DAM's value.\n\t * But this method is useful in situations where the client already knows a change has happened,\n\t * and doesn't want to re-fetch.\n\t *\n\t * @method\n\t * @param {Date} date A date object specifying the time to stamp (if undefined, we use the current moment)\n\t */\n\tbumpModdate(date) {\n\t\tdate = date || new Date();\n\t\tthis.set({moddate: _.dateToAsset(date)});\n\t}\n\n\t/**\n\t * Check our permissionMatrix for whether a particular named bit is set.\n\t * @param {string} perm One of the permissions in {module:permissions/properties/assetPermissions#matrixNames}\n\t * @returns {mixed} returns true or false, or undefined (which is falsy) if the argument is undefined.\n\t * @method\n\t */\n\t// DEVNOTE: module:asset/models/asset & Netx.Models.Category use the same method. Change it here, change it there.\n\t// Until we have a better include/export scheme we won't know whether asset or category module inits first,\n\t// so we can't define one of these in terms of the other.\n\t//\n\t//allows: module:asset/models/asset.prototype.allows\n\tallows(perm) {\n\t\tif (perm == null) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst matrixIndex = matrixNames.indexOf(perm);\n\n\t\tif (matrixIndex < 0) {\n\t\t\tthrow new Error(\"Unknown permission '\" + perm + \"'\");\n\t\t}\n\n\t\t// We need the DAM to return appropriate permissions for readOnly assets (even for admins)\n\t\tif (this.get('readOnly') === 1) {\n\t\t\tswitch (perm) {\n\t\t\t\tcase 'delete':\n\t\t\t\tcase 'modify':\n\t\t\t\tcase 'all':\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// The actual test of the actual value in the actual matrix (cast to bool):\n\t\treturn this.get('permissionMatrix')[matrixIndex] ? true : false;\n\t}\n\n\t/**\n\t * Methods for MediaRich zoom feature (if enabled):\n\t *\n\t * This non-standard API call is proxied from the DAM to a connected MediaRich server,\n\t * and tells the MR server to cache the asset from the DAM.\n\t *\n\t * @method\n\t * @returns {promise} resolves/rejects when complete.\n\t */\n\tcacheInMediaRich() {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst mediarichCacheUrl =\n\t\t\t\t// server target (proxied to MS server):\n\t\t\t\t'/mgen/NetX.ms?f=LoadAndCache&assetPath=' +\n\t\t\t\t// URL to original asset, with sessionKey added for authentication:\n\t\t\t\tencodeURIComponent(\n\t\t\t\t\tNetx.URL.asset +\n\t\t\t\t\t\t'/' +\n\t\t\t\t\t\tthis.id +\n\t\t\t\t\t\t'/original/' +\n\t\t\t\t\t\tthis.get('file') +\n\t\t\t\t\t\t'?sessionKey=' +\n\t\t\t\t\t\tNetx.session.get('sessionKey'),\n\t\t\t\t) +\n\t\t\t\t// Session key again, because sessions are key:\n\t\t\t\t'&sessionKey=' +\n\t\t\t\tNetx.session.get('sessionKey');\n\n\t\t\t$.ajax(mediarichCacheUrl).then((responseJSON, responseText, jqXHR) => {\n\t\t\t\t// response must be 200 (ok)\n\t\t\t\tif (jqXHR && jqXHR.status != 200) {\n\t\t\t\t\treturn reject(`Bad response from MediaRich server: ${responseText}`);\n\t\t\t\t} else if (\n\t\t\t\t\ttypeof responseJSON === 'string' &&\n\t\t\t\t\tresponseJSON.includes('not found on NetX')\n\t\t\t\t) {\n\t\t\t\t\treturn reject(responseJSON);\n\t\t\t\t}\n\t\t\t\tresolve(responseJSON);\n\t\t\t}, reject);\n\t\t});\n\t}\n\n\t/** @type {string} */\n\tstatic get __name__() {\n\t\treturn 'Asset';\n\t}\n}\n","import {AssetGalleryAsset} from '@netx/core-asset-gallery/types';\nexport const assetExpires = (asset: AssetGalleryAsset) =>\n\t!!asset.expirationDate;\nexport default assetExpires;\n","import moment from '@netx/core/lib/netx-moment';\n\nexport const userInputToExpirationTime = (expirationDate: string) => {\n\tconst date = moment(expirationDate).endOf('day');\n\tdate.utc();\n\n\tconst tomorrow = moment().utc(false).add(1, 'day').valueOf();\n\n\t// Make sure date is valid and that it is greater than or equal to tomorrow\n\tif (!date.isValid() || date.valueOf() < tomorrow) {\n\t\tthrow new Error('Invalid expiration date');\n\t}\n\n\treturn date.valueOf();\n};\n\nexport default userInputToExpirationTime;\n","// created this file to address the fact that we need to tell moment\n// what locale to use\n// the prime place for this imo was the i18n initialization BUT moment\n// is not needed for logging in (atm) and it increases our pre-logged in bundle\n// enough\n// this file ensures that no matter when moment is called on that we have\n// set the locale\n\nimport {i18n, initialized} from '@netx/core/i18n';\nimport moment from 'moment';\n\ninitialized.then(() => {\n\t// We have to set this manually\n\t// https://momentjs.com/docs/#/i18n/changing-locale/\n\tmoment.locale(i18n.language);\n});\n\nexport {Moment, utc} from 'moment';\nexport {default} from 'moment';\n","/**\n * Asset constituent model\n * @class\n */\nimport Base from '@netx/core/lib/netx-model';\n\nimport AssetSetModel from './assetSet';\n\nimport {types as assetSetTypes} from '../properties/assetSets';\n\nexport default class AssetConstituent extends Base {\n\t/**\n\t * @type {Netx.Rpc}\n\t * @private\n\t */\n\tget rpc() {\n\t\treturn true;\n\t}\n\t/**\n\t * @type {Netx.URL}\n\t * @private\n\t */\n\tget url() {\n\t\treturn Netx.URL.api;\n\t}\n\n\t/**\n\t * The unique ID for this model is \"id\"\n\t * @type {string}\n\t */\n\tget idAttribute() {\n\t\treturn 'constituentId';\n\t}\n\n\t/**\n\t * @property {object} defaults - The default attribute values\n\t * @property {number} defaults.constituentId - Constituent id (Never set the id in defaults)\n\t * @property {number} defaults.display - Display constituent (boolean as number)\n\t * @property {number} defaults.assetId - Asset id (the asset I am a constituent of)\n\t * @property {string} defaults.lowresUrl - Low resolution image (unused?)\n\t * @property {string} defaults.modDate - Modification date string\n\t * @property {string} defaults.previewUrl - Preview image\n\t * @property {number} defaults.rebuildCount - ??? Rebuild count\n\t * @property {number} defaults.rebuildType - ??? Rebuild type\n\t * @property {number} defaults.ref - ???\n\t * @property {string} defaults.thumbUrl - Thumbnail image\n\t * @property {string} defaults.title - Title\n\t * @property {number} defaults.type - 1 = time (keyframe), 2 = layer, 3 = page, 4 = clips\n\t */\n\tget defaults() {\n\t\treturn {\n\t\t\t// constituentId : 0,\n\t\t\tattributes: [],\n\t\t\tdisplay: 0,\n\t\t\tassetId: 0,\n\t\t\tlowresUrl: '',\n\t\t\tmodDate: '',\n\t\t\tpreviewUrl: '',\n\t\t\trebuildType: 0,\n\t\t\trebuildCount: 0,\n\t\t\tref: 1,\n\t\t\tthumbUrl: '',\n\t\t\ttitle: '',\n\t\t\ttype: 0,\n\t\t};\n\t}\n\n\t/**\n\t * @property {object} methods - Model RPC methods\n\t * @property {function|array} methods.read - Fetch constituent\n\t * @property {function|array} methods.setDisplay - Tell the dam to use this constituent as the image thumbnail/preview\n\t */\n\tget methods() {\n\t\treturn {\n\t\t\tread: ['getConstituentObject', 'constituentId'],\n\t\t\tsetDisplay: ['setConstituentDisplay', 'constituentId'],\n\t\t};\n\t}\n\n\t/**\n\t * @property {object} parsers - Model parsers\n\t * @property {function} parsers.setDisplay - Parse the return of our fetch, it is an array with a single record\n\t */\n\tget parsers() {\n\t\treturn {\n\t\t\t/**\n\t\t\t * @function\n\t\t\t * @param {null} result Result (returns `null` - very helpful)\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tsetDisplay(result, opts) {\n\t\t\t\tthis.set({display: 1});\n\t\t\t\treturn result;\n\t\t\t},\n\t\t};\n\t}\n\n\t/**\n\t * @override\n\t * @param {object} attrs Model attributes\n\t * @param {object} opts Model options\n\t */\n\tconstructor(attrs, opts = {}) {\n\t\tsuper(attrs, opts);\n\n\t\t/**\n\t\t * @memberof module:asset/models/assetConstituent\n\t\t * @alias clipAttributes\n\t\t * @type {module:asset/collections/attributes}\n\t\t */\n\t\tthis.clipAttributes =\n\t\t\topts.clipAttributes || Netx.getAttributesByObjectType('clip');\n\t}\n\n\t/**\n\t * Check our permissionMatrix for whether a particular named bit is set.\n\t * Pipes through the asset we belong to\n\t * @method\n\t * @param {string} perm One of the permissions in {module:permissions/properties/assetPermissions#matrixNames}\n\t * @returns {mixed} returns true or false, or undefined (which is falsy) if the argument is undefined.\n\t */\n\tallows(perm) {\n\t\t// TODO: better way to handle the contituents having access to the asset bean they belong to\n\t\t// Maybe, rather than passing an assetId to constituents we passa full on bean - that way when it updates\n\t\t// we update and have proper permission matrix rather than relying that the constituent's asset will always\n\t\t// be Netx.asset.current\n\t\tvar currentAsset = Netx.asset.current;\n\t\treturn currentAsset && currentAsset.allows.apply(currentAsset, arguments);\n\t}\n\n\t/**\n\t * Return an assetSet object defining the set that contains just this constituent.\n\t * @method\n\t * @return {module:asset/models/assetSet} AssetSet model\n\t */\n\ttoAssetSet() {\n\t\treturn new AssetSetModel({\n\t\t\ttype: assetSetTypes.asset,\n\t\t\tids: [this.get('assetId')],\n\t\t\tmodels: [this],\n\t\t\tlabel: this.get('title'),\n\t\t\tcanCreateLink: false,\n\t\t\tcanEmail: false,\n\t\t});\n\t}\n\n\t/** @type {string} */\n\tstatic get __name__() {\n\t\treturn 'AssetConstituent';\n\t}\n}\n","import {i18n} from '@netx/core/i18n';\nimport {notMobile} from '@netx/core/lib/netx-enablers';\n\nexport let constituents = {\n\ttypes: {\n\t\t1: 'keyframe',\n\t\t2: 'layer',\n\t\t3: 'page',\n\t\t4: 'clip',\n\t},\n\ttypeNames: {\n\t\t1: 'asset:i18n.consituentsKeyframes',\n\t\t2: 'asset:i18n.consituentsLayers',\n\t\t3: 'asset:i18n.consituentsPages',\n\t\t4: 'asset:i18n.consituentsClips',\n\t},\n};\n\nexport let dragUserLevel = 8;\n\n// Tasks that run on assets at import\nexport let importTasks = {\n\tAudioTask: i18n.t('i18n.performingTaskAudio'),\n\tFFFViewTask: i18n.t('i18n.performingTaskFFFView'),\n\tINDDPageTask: i18n.t('i18n.performingTaskINDDPage'),\n\tIWorkPageTask: i18n.t('i18n.performingTaskIWorkPage'),\n\tKeyframesTask: i18n.t('i18n.performingTaskKeyframes'),\n\tMetadataTask: i18n.t('i18n.performingTaskMetadata'),\n\tOfficePageTask: i18n.t('i18n.performingTaskOfficePage'),\n\tPDFPageTask: i18n.t('i18n.performingTaskPDFPage'),\n\tPostImportTask: i18n.t('i18n.performingTaskPostImport'),\n\tPreviewTask: i18n.t('i18n.performingTaskPreview'),\n\tRelatedAssetTask: i18n.t('i18n.performingTaskRelatedAssets'),\n\tSWFTask: i18n.t('i18n.performingTaskSWF'),\n\tThumbnailTask: i18n.t('i18n.performingTaskThumbnail'),\n\tVideoPreviewTask: i18n.t('i18n.performingTaskVideoPeview'),\n\tWatermarkTask: i18n.t('i18n.performingTaskWatermark'),\n\tZoomTask: i18n.t('i18n.performingTaskZoom'),\n};\n\nexport let renderableChanges = [\n\t'attributeIds',\n\t'attributeNames',\n\t'attributeValues',\n\t'checkout',\n\t'creationdate',\n\t'expirationDate',\n\t'file',\n\t'fileSize2',\n\t'fileheight',\n\t'filesize',\n\t'filetype',\n\t'filetypelabel',\n\t'filewidth',\n\t'geoLocationLabel',\n\t'imageid',\n\t'importDate',\n\t'locationContext',\n\t'locationid',\n\t'moddate',\n\t'moduserid',\n\t'moduserlabel',\n\t'name',\n\t'path',\n\t'permissionMatrix',\n\t'previewHeight',\n\t'previewUrl',\n\t'previewWidth',\n\t'readOnly',\n\t'repurposeAvailability',\n\t'status',\n\t'thumb',\n\t'thumbUrl',\n\t'versionIds',\n\t'viewIds',\n\t'viewNames',\n\t'zoomAvailable',\n];\n\nexport let status = {\n\tUNKNOWN: 0,\n\tONLINE: 1,\n\tNEARLINE: 2,\n\tOFFLINE: 3,\n\tTEMP: 4,\n\tCHECKOUT: 5,\n\tIMPORT_IN_PROGRESS: 6,\n};\n\nexport let things = {\n\tattributeHistory: {\n\t\tlabel: i18n.t('i18n.attributeHistory'),\n\t\tuserLevel: 4,\n\t\tenableTest: notMobile,\n\t},\n\tattributes: {\n\t\tlabel: i18n.t('i18n.attributes'),\n\t\tuserLevel: 1,\n\t},\n\tcategories: {\n\t\tlabel: i18n.t('i18n.categories'),\n\t\tuserLevel: 2,\n\t},\n\tclips: {\n\t\tlabel: i18n.t('i18n.constituentsClips'),\n\t\tuserLevel: 2,\n\t},\n\tconstituents_keyframes: {\n\t\tlabel: i18n.t('i18n.constituentsKeyframes'),\n\t\tuserLevel: 7,\n\t},\n\tconstituents_layers: {\n\t\tlabel: i18n.t('i18n.constituentsLayers'),\n\t\tuserLevel: 7,\n\t},\n\tconstituents_pages: {\n\t\tlabel: i18n.t('i18n.constituentsPages'),\n\t\tuserLevel: 7,\n\t},\n\tdetail: {\n\t\tlabel: i18n.t('i18n.detail'),\n\t\tmatrix: 'read',\n\t\tuserLevel: 2,\n\t},\n\tfileinfo: {\n\t\tlabel: i18n.t('i18n.fileinfo'),\n\t\tuserLevel: 1,\n\t},\n\tindex: {\n\t\tlabel: i18n.t('i18n.index'),\n\t\tuserLevel: 9,\n\t},\n\tlinks: {\n\t\tlabel: i18n.t('i18n.links'),\n\t\tuserLevel: 2,\n\t},\n\tmetadata: {\n\t\tlabel: i18n.t('i18n.metadata'),\n\t\tuserLevel: 2,\n\t},\n\toverview: {\n\t\tlabel: i18n.t('i18n.overview'),\n\t\tuserLevel: 2,\n\t},\n\tpermissions: {\n\t\tlabel: i18n.t('i18n.permissions'),\n\t\tuserLevel: 8,\n\t},\n\tpreview: {\n\t\tlabel: i18n.t('i18n.preview'),\n\t\tuserLevel: 1,\n\t},\n\tprojects: {\n\t\tlabel: i18n.t('i18n.projects'),\n\t\tuserLevel: 1,\n\t\tenableTest: notMobile,\n\t},\n\tpublicLinks: {\n\t\tlabel: i18n.t('i18n.publicLinks'),\n\t\tuserLevel: 7,\n\t},\n\treviews: {\n\t\tlabel: i18n.t('i18n.reviews'),\n\t\tuserLevel: 1,\n\t\tenableTest: notMobile,\n\t},\n\tusage: {\n\t\tlabel: i18n.t('i18n.usage'),\n\t\tuserLevel: 7,\n\t},\n\tversions: {\n\t\tlabel: i18n.t('i18n.versions'),\n\t\tuserLevel: 4,\n\t},\n\tviews: {\n\t\tlabel: i18n.t('i18n.views'),\n\t\tuserLevel: 2,\n\t},\n};\n\nexport default {\n\tconstituents,\n\tdragUserLevel,\n\timportTasks,\n\trenderableChanges,\n\tstatus,\n\tthings,\n};\n","import {status as assetStatuses} from './properties/asset';\nimport AssetModel from './models/asset';\nimport {getViewCollection, getViewModel} from '@netx/core/lib/utils';\nimport {isMobile} from '@netx/core/lib/underscore-netx';\n\nimport Netx from '@netx/core/bootstrap';\n\n/**\n * @method\n * @return {boolean}\n */\nexport const assetCanRepurpose = (v) => {\n\t// DAM-13617\n\tif (isMobile()) return false;\n\n\tconst model = getViewModel(v);\n\n\t// Once the property repurposeAvailability is considering\n\t// the availability of the engines required to repurpose\n\t// an asset ( https://jira.netx.net/browse/DAM-4564 ) we\n\t// can rely more heavily on `repurposeAvailability` until\n\t// that time... ~SAK\n\t// Vars\n\tvar supported, viewNames;\n\n\t// var manualUserLevel = Netx.getPreference('sys.minUserLevelForManualRepurpose') || 0,\n\t// canManuallyRepurpose = Netx.getUserLevel() >= manualUserLevel;\n\n\tif (model) {\n\t\tviewNames = model.get('viewNames');\n\t\t// Video\n\t\tif (_.indexOf(viewNames, 'previewH264') > -1) {\n\t\t\tsupported = true;\n\t\t}\n\t\t// Document\n\t\telse if (_.indexOf(viewNames, 'previewPDF') > -1) {\n\t\t\t// Not supported\n\t\t}\n\t\t// Audio\n\t\telse if (_.indexOf(viewNames, 'previewMp3') > -1) {\n\t\t\tsupported = true;\n\t\t}\n\t\t// Image\n\t\telse if (_.indexOf(v.model.get('fileFormatFamily'), 'image') > -1) {\n\t\t\tsupported = true;\n\t\t}\n\t\t// We don't know what it is\n\t\telse {\n\t\t\tsupported = false;\n\t\t}\n\t}\n\treturn (\n\t\tsupported && assetIsPresent(v) && v.model.get('repurposeAvailability') > 0\n\t);\n};\n\n/**\n * Can asset be part of a review\n * @method\n * @return {boolean}\n */\nexport const assetCanReview = (v) => {\n\tconst model = getViewModel(v);\n\treturn model && model.hasFormatFamily('image');\n};\n\n/**\n * Is asset expiration enabled\n * @method\n * @param {Netx.View} v Instance of Netx View\n * @returns {boolean}\n */\nexport const assetExpirationEnabled = (v) => {\n\treturn Netx.getPreference('asset.expire.enabled', true);\n};\n\n/**\n * Is asset set to expire\n * @method\n * @param {Netx.View} v Instance of Netx View\n * @returns {boolean}\n */\nexport const assetExpires = (v) => {\n\tconst model = getViewModel(v);\n\n\tif (!model) return false;\n\n\t// Verify we have a timestamp\n\tvar expirationDate = parseInt(model.get('expirationDate'));\n\tif (!expirationDate || isNaN(expirationDate)) return false;\n\n\t// Make into date\n\texpirationDate = new Date(expirationDate);\n\treturn (\n\t\tNetx.getPreference('asset.expire.enabled', true) &&\n\t\t!isNaN(expirationDate.getTime())\n\t);\n};\n\n/**\n * @method\n * @param {Netx.View} v Instance of Netx View\n * @returns {boolean}\n */\nexport const assetHasConstituents_clips = (v) => {\n\tconst model = getViewModel(v);\n\treturn (\n\t\tmodel &&\n\t\tNetx.getPreference('asset.constituent.videoClips.enabled', true) &&\n\t\t_.indexOf(model.get('fileFormatFamily'), 'video') > -1\n\t);\n};\n\nexport const assetHasClips = assetHasConstituents_clips;\n\n/**\n * @method\n * @param {Netx.View} v Instance of Netx View\n * @returns {boolean}\n */\nexport const assetHasConstituents_keyframes = (v) => {\n\tconst model = getViewModel(v);\n\treturn (\n\t\tmodel &&\n\t\tmodel.get('constituentType') === 'time' &&\n\t\t_.size(model.get('constituentIds'))\n\t);\n};\n\n/**\n * @method\n * @param {Netx.View} v Instance of Netx View\n * @returns {boolean}\n */\nexport const assetHasConstituents_layers = (v) => {\n\tconst model = getViewModel(v);\n\treturn (\n\t\tmodel &&\n\t\tmodel.get('constituentType') === 'layer' &&\n\t\t_.size(model.get('constituentIds'))\n\t);\n};\n\n/**\n * @method\n * @param {Netx.View} v Instance of Netx View\n * @returns {boolean}\n */\nexport const assetHasConstituents_pages = (v) => {\n\tconst model = getViewModel(v);\n\treturn (\n\t\tmodel &&\n\t\tmodel.get('constituentType') === 'page' &&\n\t\t_.size(model.get('constituentIds'))\n\t);\n};\n\n/**\n * @method\n * @param {Netx.View} v Instance of Netx View\n * @returns {boolean}\n */\nexport const assetHasDetail = (v) => {\n\treturn true;\n};\n\n/**\n * @method\n * @param {Netx.View} v Instance of Netx View\n * @returns {boolean}\n */\nexport const assetHasLinks = (v) => {\n\tconst model = getViewModel(v);\n\treturn model && model.get('relatedAvailable');\n};\n\n/**\n * @method\n * @param {Netx.View} v Instance of Netx View\n * @returns {boolean}\n */\nexport const assetHasMetadata = (v) => {\n\tconst model = getViewModel(v);\n\treturn model && model.get('metadataAvailable');\n};\n\n/**\n * @method\n * @param {Netx.View} v Instance of Netx View\n * @returns {boolean}\n */\nexport const assetHasPreview = (v) => {\n\treturn true;\n};\n\n/**\n * @method\n * @param {Netx.View} v Instance of Netx View\n * @returns {boolean}\n */\nexport const assetHasProjects = (v) => {\n\t// TODO: have the asset marked with a boolean as well\n\treturn Netx.getPreference('review.enabled', true);\n};\n\n/**\n * @method\n * @param {Netx.View} v Instance of Netx View\n * @returns {boolean}\n */\nexport const assetHasReviews = (v) => {\n\tconst canReview = assetCanReview(v);\n\t// TODO: have the asset marked with a boolean as well\n\treturn canReview && Netx.getPreference('review.enabled', true);\n};\n\n/**\n * @method\n * @param {Netx.View} v Instance of Netx View\n * @returns {boolean}\n */\nexport const assetHasVersions = (v) => {\n\tconst model = getViewModel(v);\n\treturn model && _.size(model.get('versionIds'));\n};\n\n/**\n * For react (non action enabler)\n */\nexport const assetIsEditable = (assetData) => {\n\tconst model = new AssetModel(assetData);\n\tconst canEdit = model.allows('modify');\n\tmodel.garbageCollect();\n\treturn canEdit;\n};\n\n/**\n * @method\n * @param {Netx.View} v Instance of Netx View\n * @returns {boolean}\n */\nexport const assetHasViews = (v) => {\n\tconst model = getViewModel(v);\n\treturn model && _.size(model.get('viewIds'));\n};\n\n/**\n * @method\n * @param {Netx.View} v Instance of Netx View\n * @returns {boolean}\n */\nexport const assetIsImage = (v) => {\n\tconst model = getViewModel(v);\n\treturn model && _.indexOf(v.model.get('fileFormatFamily'), 'image') > -1;\n};\n\n/**\n * Asset status is set to 1\n * @param {Backbone.View} v Backbone view\n * @return {boolean}\n */\nexport const assetIsOnline = (v) => {\n\tconst model = getViewModel(v);\n\tif (!model) return false;\n\tvar stat = model.get('status');\n\treturn stat === assetStatuses.ONLINE;\n};\n\n/**\n * This test is cribbed from Flex: it checks the asset.status value to make sure the asset file is actually available on the DAM.\n * @method\n * @param {Netx.View} v Instance of Netx View\n * @returns {boolean}\n */\nexport const assetIsPresent = (v) => {\n\tconst model = getViewModel(v);\n\n\tif (!model) return false;\n\tvar stat = model.get('status');\n\treturn (\n\t\tstat === assetStatuses.ONLINE ||\n\t\tstat === assetStatuses.TEMP ||\n\t\tstat === assetStatuses.NEARLINE\n\t);\n};\n\n/**\n * Asset locked\n * @method\n * @returns {boolean}\n */\nexport const assetLocked = (v) => {\n\tconst model = getViewModel(v);\n\treturn model.get('readOnly') === 1;\n};\n\n/**\n * @method\n * @returns {boolean}\n */\nexport const assetNotCheckedOut = (v) => {\n\tconst collection = getViewCollection(v);\n\tconst model = getViewModel(v);\n\tvar status;\n\tif (model && model.has('status')) {\n\t\t// check for model\n\t\tstatus = model.get('status');\n\t} else if (\n\t\tcollection &&\n\t\tcollection.length &&\n\t\tcollection.at(0).has('status')\n\t) {\n\t\t// check for first model in collection\n\t\tstatus = collection.at(0).get('status');\n\t} else {\n\t\t// Sometimes we hit this test before the collection on the view in question has any assets\n\t\t// I have provided the view in question with the console warn - in the case of DAM-8288 it is assetListView\n\t\t// and yes, the collection is not ready quite yet. The real thing is what is assetListView doing on an action\n\t\t// requestion this test in the first place\n\t\t// Something must be testing on sync before data is actually available(?)\n\t\t// Perhaps a reset is happening prior to setting data?\n\t\t// It is more than likely coming from the `share:asset:menu` or `share:asset:download` action\n\t\t// Can't imagine it is coming from the `asset:checkout` action\n\t\t// In any case there is no need to blow up the app over it\n\n\t\t// UPDATE: spotted in the wild ... a reset is indeed happening:\n\t\t// user clicks on a category, routing to #category/:id\n\t\t// #category/:id handler triggers category:routed,\n\t\t// category:routed triggers category:current:update,\n\t\t// category:current:update calls Netx.category.current.set(data) to update the ID ... **\n\t\t// change listener on categoryID calls Netx.category.current.fetch() to fetch category ...\n\t\t// a weird fetch wrapper in category.js triggers a fake 'sync' event, **\n\t\t// a sync listener on Netx.category.current triggers category:getAssets,\n\t\t// triggering Netx.category.assets.getCategoryAssets(),\n\t\t// which is a weird wrapper method that sets its own .selection object before fetching ... **\n\t\t// Netx.category.assets has a change listener on its .selection object to !!! call .reset() before a fetch !!! **\n\t\t// and that 'reset' event triggers .configureSyncActions() in the Netx.View actions code **\n\t\t// ... which triggers this enabler at a moment when v.collection.length is certain to be 0.\n\t\t//\n\t\t// Out of all that, at least the lines ending in ** are suspect. Possibly this will work\n\t\t// better as we start to untangle the spagetting of method wrapers & bad RPC method patterns.\n\t\t// (And I don't get why we need to reset categoryAssets before fetching ... the code says\n\t\t// it makes something faster, but we should revisit that.)\n\t\t//\n\t\t// On the other hand, there's no need to issue this warning when we have a collection without assets in it.\n\t\t// Simply disabling the action in that case seems sensible.\n\t\tif (collection && collection.length == 0) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Other than that, I'm not sure this ever happens -- but let's be warned if it does.\n\t\telse {\n\t\t\t// console.warn('tried to test asset checkout status on non-asset', v.template);\n\t\t\t// Just make the assumption it is checked out... because... well, logic is flawed somewhere and saying it is checked out\n\t\t\t// in this odd case won't hurt anyone\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn status !== assetStatuses.CHECKOUT;\n};\n\n/**\n * Check that asset isn't pending\n * @method\n * @return {boolean}\n */\nexport const assetNotPending = (v) => {\n\tconst model = getViewModel(v);\n\treturn model && _.isUndefined(Netx.asset.pending.get(model.id));\n};\n\n/**\n * Are assets requests enabled?\n * @method\n * @return {boolean}\n */\nexport const assetRequestsEnabled = (v) => {\n\treturn Netx.getPreference('asset.assetRequestEnabled', true);\n};\n\n/**\n * Asset unlocked\n * @method\n * @returns {boolean}\n */\nexport const assetUnlocked = (v) => {\n\tconst model = getViewModel(v);\n\treturn model && model.get('readOnly') === 0;\n};\n\n/**\n * @method\n * @returns {boolean}\n */\nexport const canCheckIn = (v) => {\n\tconst model = getViewModel(v);\n\tif (!model) return false;\n\n\tconst checkedOutBy = model.get('checkout');\n\tif (\n\t\tcheckedOutBy &&\n\t\tNetx.getUserLevel() < 9 &&\n\t\tcheckedOutBy !== Netx.getUser().id\n\t)\n\t\treturn false;\n\n\tconst status = model.get('status');\n\t// https://jira.netx.net/browse/DAM-13370\n\treturn (\n\t\tstatus === assetStatuses.NEARLINE ||\n\t\tstatus === assetStatuses.ONLINE ||\n\t\tstatus === assetStatuses.TEMP ||\n\t\tstatus === assetStatuses.CHECKOUT\n\t);\n};\n\n/**\n * @method\n * @returns {boolean}\n */\nexport const canCheckOut = (v) => {\n\tconst model = getViewModel(v);\n\tvar status = model.get('status');\n\n\treturn (\n\t\tassetNotCheckedOut(v) &&\n\t\t// https://jira.netx.net/browse/DAM-13370\n\t\t(status === assetStatuses.NEARLINE ||\n\t\t\tstatus === assetStatuses.ONLINE ||\n\t\t\tstatus === assetStatuses.TEMP)\n\t);\n};\n\n/**\n * Can delete attribute\n * @param {Backbone.View} v Backbone view\n * @return {boolean}\n */\nexport const canDeleteAttribute = (v) => {\n\t// Currently there is nothing to test since `asset.moveDescriptionToAttrTab` went away\n\treturn true;\n};\n\n/**\n * Can we download a version\n * @method\n * @return {boolean}\n */\nexport const canDownloadVersion = (v) => {\n\t// For now we must assume that we are dealing with the current asset\n\treturn Netx.asset.current.allows('download');\n};\n\n/**\n * Can edit attribute\n * @param {Backbone.View} v Backbone view\n * @return {boolean}\n */\nexport const canEditAttribute = (v) => {\n\t// Currently there is nothing to test since `asset.moveDescriptionToAttrTab` went away\n\treturn true;\n};\n\n/**\n * Can expire asset\n * @method\n * @returns {boolean}\n */\nexport const canExpire = (v) => {\n\tconst model = getViewModel(v);\n\tif (!model) return false;\n\n\treturn (\n\t\tassetExpirationEnabled(v) &&\n\t\tNetx.getUserLevel() >= 7 &&\n\t\tmodel.allows('delete')\n\t);\n};\n\n/**\n * Can lock asset\n * @method\n * @returns {boolean}\n */\nexport const canLock = (v) => {\n\tconst model = getViewModel(v);\n\tif (!model || !model.allows || !model.allows('modify')) return false;\n\n\treturn model && model.get('readOnly') !== 1 && Netx.getUserLevel() >= 9;\n};\n\n/**\n * Can manage versions\n * @method\n * @return {boolean}\n */\nexport const canManageVersions = (v) => {\n\t// For now we must assume that we are dealing with the current asset\n\t// we can not manage versions if the asset cannot be checked out\n\treturn (\n\t\tNetx.asset.current.allows('modify') &&\n\t\tcanCheckOut({model: Netx.asset.current})\n\t);\n};\n\n/**\n * Can an asset be removed from a category - an asset must belong to at least one category\n * If an asset does not have more than one category, it may not be removed.\n * This does not check permissions - for that use `module:core/lib/netx-enablers#categoryAndAssetCanEdit`\n * This just tests that an asset can be removed from a category (assuming permissions are good)\n * @param {Backbone.View} v Backbone view\n * @return {boolean}\n */\nexport const canRemoveAssetFromCategory = (v) => {\n\tconst model = getViewModel(v);\n\t// Where model is an asset category from an asset category list\n\tvar asset = model && model.get('asset');\n\treturn ((asset && asset.get('categories')) || []).length > 1;\n};\n\n/**\n * Can unlock asset\n * @method\n * @returns {boolean}\n */\nexport const canUnlock = (v) => {\n\tconst model = getViewModel(v);\n\tif (!model) return false;\n\n\treturn model && model.get('readOnly') === 1 && Netx.getUserLevel() >= 9;\n};\n\n/**\n * @method\n * @returns {boolean}\n */\nexport const canZoomAsset = (v) => {\n\tconst model = getViewModel(v);\n\treturn (\n\t\tmodel &&\n\t\tassetIsPresent(v) &&\n\t\tmodel.get('zoomAvailable') &&\n\t\t// HACKaround for HTML-868:\n\t\tmodel.get('filewidth') > 0 &&\n\t\tmodel.get('fileheight') > 0\n\t);\n};\n\nexport const checksumEnabled = (v) => {\n\treturn Netx.getPreference('metadata.checksumEnabled', true);\n};\n\n/**\n * Can we use semantic metadata\n * @method\n */\nexport const semanticsEnabled = (v) => {\n\treturn Netx.getPreference('metadata.semantic.enabled', true);\n};\n\n/**\n * Can unexpire asset\n * @method\n * @returns {boolean}\n */\nexport const canUnexpire = (v) => {\n\tconst model = getViewModel(v);\n\tif (!model) return false;\n\n\tif (!assetExpires(v)) return false;\n\n\treturn Netx.getUserLevel() >= 7 && model.allows('delete');\n};\n","export let contactSheet = {\n\tdefaultEngine: 'java',\n\tdefaultTemplates: {\n\t\t'1x1': {\n\t\t\tmaxAttributes: 10,\n\t\t},\n\t\t'2x2': {\n\t\t\tmaxAttributes: 5,\n\t\t},\n\t\t'3x3': {\n\t\t\tmaxAttributes: 3,\n\t\t},\n\t},\n};\n\nexport const ignoreDownloadWarningTypes = ['contactSheet', 'metadata'];\n\nexport let types = {\n\toriginal: 'original',\n\tproxy: 'proxy',\n\tassetView: 'assetView',\n\tpresetProcess: 'presetProcess',\n\thistorical: 'historical',\n\tmetadata: 'metadata',\n\tcontactSheet: 'contactSheet',\n\tthumb: 'thumb',\n\ttemplateCustomization: 'templateCustomization',\n\tpreview: 'preview',\n\t'1x1': '1x1',\n\t'2x2': '2x2',\n\t'3x3': '3x3',\n};\n\nexport default {contactSheet, ignoreDownloadWarningTypes, types};\n","module.exports = function(obj){\nvar __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\nwith(obj||{}){\n__p+='\\n\\n
\\n\t
'+\n((__t=( headerTitle ))==null?'':__t)+\n'
\\n\t\\n\t
\\n\t\t\\n\t
\\n
\\n\t\\n
\\n\t
\\n\t\t
\\n\t\t\t
\\n\t\t\t\t
\\n\t\t\t\t\t
i18n.current
\\n\t\t\t\t\t
00:00:00
\\n\t\t\t\t
\\n\t\t\t\t
\\n\t\t\t\t\t
i18n.selection
\\n\t\t\t\t\t
00:00:00:00
\\n\t\t\t\t
\\n\t\t\t\t
\\n\t\t\t\t\t
i18n.length
\\n\t\t\t\t\t
00:00:00
\\n\t\t\t\t
\\n\t\t\t
\\n\t\t\t
\\n\t\t\t\\n\t\t\t\t\\n\t\t\t\\n\t\t\t\t
\\n\t\t\t
\\n\t\t\t
\\n\t\t\t\t\\n\t\t\t\t\\n\t\t\t\t\\n\t\t\t\t\\n\t\t\t\t\\n\t\t\t
\\n\t\t\\n\t\t\t
\\n\t\t\t\t
\\n\t\t\t\t\t
\\n\t\t\t\t\t\t0%\\n\t\t\t\t\t
\\n\t\t\t\t
\\n\t\t\t
\\n\t\t\t\\n\t\t\t
\\n\t\t\t\t
\\n\t\t\t\t\t'+\n((__t=( icons.faExclamationCircle ))==null?'':__t)+\n'\\n\t\t\t\t\t\\n\t\t\t\t
\\n\t\t\t
\\n\t\t
\\n\t\t\\n\t\t
\\n\t\t\t
\\n\t\t\t
\\n\t\t\t
\\n\t\t\t\t\\n\t\t\t
\\n\t\t
\\n\t
\\n
';\n}\nreturn __p;\n};\n","module.exports = function(obj){\nvar __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\nwith(obj||{}){\n__p+='\\n\\n
';\n}\nreturn __p;\n};\n","module.exports = function(obj){\nvar __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\nwith(obj||{}){\n__p+='\\n\\n';\n}\nreturn __p;\n};\n","module.exports = function(obj){\nvar __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\nwith(obj||{}){\n__p+='\\n\\n
\\n\t\\n
\\n
\\n\t\\n\t\\n
';\n}\nreturn __p;\n};\n","module.exports = function(obj){\nvar __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\nwith(obj||{}){\n__p+='\\n\\n\\n\\n
\\n\t
\\n\t\t
\\n\t\t\t\\n\t\t\t\\n\t\t
\\n\t\t
\\n\t\t\t
'+\n((__t=( icons.faPlus ))==null?'':__t)+\n'
\\n\t\t\t
'+\n((__t=( icons.faMinus ))==null?'':__t)+\n'
\\n\t\t
\\n\t
\\n
\\n\\n
\\n\t\\n\t
\\n\t\t
\\n\t\t\t\\n\t\t\t\\n\t\t
\\n\t\t
\\n\t\t\t
'+\n((__t=( icons.faPlus ))==null?'':__t)+\n'
\\n\t\t\t
'+\n((__t=( icons.faMinus ))==null?'':__t)+\n'
\\n\t\t
\\n\t
\\n
\\n\\n';\n}\nreturn __p;\n};\n","import {utc} from '@netx/core/lib/netx-moment';\n\n/**\n * @param expirationDate datetime in milliseconds\n */\nexport const assetExpirationToDateString = (expirationDate: number) => {\n\treturn `${utc(expirationDate).local().format('YYYY-MM-DD')}`;\n};\n\nexport default assetExpirationToDateString;\n","/**\n * @class\n */\nimport Base from '@netx/core/lib/netx-model';\n\nclass Progress extends Base {\n\t/**\n\t * @property {object} defaults - The default attribute values\n\t * @property {boolean} defaults.active - Progress is active\n\t * @property {string} defaults.message - Progress message\n\t * @property {number} defaults.percent - Progress percentage\n\t */\n\tget defaults() {\n\t\treturn {\n\t\t\tpercent: 0,\n\t\t\tmessage: '',\n\t\t\tactive: false,\n\t\t};\n\t}\n\n\t/** @override */\n\tconstructor(attrs, opts = {}) {\n\t\tsuper(attrs, opts);\n\n\t\t// Use delay option if passed\n\t\tthis.delay = opts.delay != null ? opts.delay : 1000;\n\t}\n\n\t/**\n\t * @method\n\t * @param {string} message Message\n\t */\n\tcomplete(message) {\n\t\tthis.set({\n\t\t\tmessage: message || '',\n\t\t\tpercent: 100,\n\t\t});\n\t\t_.delay(() => {\n\t\t\tthis.set({\n\t\t\t\tactive: false,\n\t\t\t\tpercent: 0,\n\t\t\t});\n\t\t}, this.delay);\n\t}\n\n\t/**\n\t * We have no server methods - just cleanup\n\t * @override\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * @method\n\t */\n\treset() {\n\t\tthis.set(this.constructor.GetDefaults());\n\t}\n\n\t/**\n\t * @method\n\t * @param {number} percent Percent\n\t * @param {string} message Message\n\t */\n\tupdate(percent, message) {\n\t\tthis.set({\n\t\t\tactive: true,\n\t\t\tmessage: message || '',\n\t\t\tpercent: percent,\n\t\t});\n\t}\n\n\t/** @type {string} */\n\tstatic get __name__() {\n\t\treturn 'Progress';\n\t}\n}\n\nexport default Progress;\n","export default [];\n","import Menu from '@netx/core/lib/netx-menu';\n\nexport default {};\n","/**\n * @class\n */\nimport Base from '@netx/core/lib/netx-model';\n\nexport default class Operation extends Base {\n\t/** @type {string} */\n\tget idAttribute() {\n\t\treturn 'name';\n\t}\n\n\t/**\n\t * @property {object} defaults - Model defaults\n\t * @property {string} defaults.name - Operation name\n\t * @property {string} defaults.label - Operation label\n\t * @property {string} defaults.type - Operation type\n\t * @property {array} defaults.items - Operation items\n\t * @property {number} defaults.order - Operation order\n\t * @property {mixed} defaults.value - Operation value\n\t */\n\tget defaults() {\n\t\treturn {\n\t\t\tname: '',\n\t\t\tlabel: '',\n\t\t\ttype: '',\n\t\t\titems: [],\n\t\t\torder: 0,\n\t\t\tvalue: null,\n\t\t};\n\t}\n\n\t/**\n\t * @method\n\t * @param {module:audioEditor/models/audio} audio Audio\n\t * @return {mixed}\n\t */\n\tgetValue(audio) {\n\t\treturn this.get('value');\n\t}\n\n\t/**\n\t * @method\n\t * @param {module:audioEditor/models/audio} audio Audio\n\t * @return {boolean}\n\t */\n\thasChanged(audio) {\n\t\treturn false;\n\t}\n\n\t/** @type {string} */\n\tstatic get __name__() {\n\t\treturn 'Operation';\n\t}\n}\n","/**\n * Format\n * @class\n */\nimport Base from './operation';\n\nexport default class Operation_Format extends Base {\n\t/** @type {object} */\n\tget defaults() {\n\t\treturn _.extend(super.defaults, {\n\t\t\tcontrol: 'dropdown',\n\t\t\tlabel: i18n.t('i18n.format'),\n\t\t\ttype: 'string',\n\t\t\trender: false,\n\t\t});\n\t}\n\n\t/**\n\t * @override\n\t * @param {object} attrs Attributes\n\t * @param {object} opts Options\n\t */\n\tconstructor(attrs = {}, opts = {}) {\n\t\tif (attrs.values != null) {\n\t\t\tconst items = (attrs.items = {});\n\t\t\tconst pulldownOptions = (attrs.values || '').split(',');\n\n\t\t\t// Loop over pulldownOptions\n\t\t\t_.each(pulldownOptions, (pulldownOption, idx) => {\n\t\t\t\titems[pulldownOption] = pulldownOption;\n\t\t\t});\n\t\t}\n\n\t\tsuper(attrs, opts);\n\n\t\tthis.set(\n\t\t\t_.pick.apply(_, [attrs].concat(_.keys(this.constructor.GetDefaults()))),\n\t\t);\n\t}\n\n\t/**\n\t * @override\n\t * @return {string} Format\n\t */\n\tgetValue() {\n\t\tconst keys = _.keys(this.get('items'));\n\t\tconst value = this.get('value');\n\t\tif (!_.contains(keys, value)) {\n\t\t\treturn keys[0];\n\t\t}\n\t\treturn value;\n\t}\n\n\t/**\n\t * @override\n\t * @param {module:audioEditor/models/audio} audio Audio\n\t * @return {boolean}\n\t */\n\thasChanged(audio) {\n\t\treturn this.getValue().toLowerCase() !== audio.get('filetypelabel');\n\t}\n\n\t/** @type {string} */\n\tstatic get __name__() {\n\t\treturn 'Operation_Format';\n\t}\n}\n","/**\n * Trim\n * @class\n */\nimport Base from './operation';\n\nimport {pad} from '@netx/core/lib/underscore-netx';\n\nconst floor = Math.floor;\nconst round = Math.round;\n\nexport default class Operation_Trim extends Base {\n\t/** @type {object} */\n\tget defaults() {\n\t\treturn _.extend(super.defaults, {\n\t\t\tcontrol: 'trim',\n\t\t\tlabel: i18n.t('i18n.trim'),\n\t\t\ttype: 'trim',\n\t\t\titems: {\n\t\t\t\tendTime: {\n\t\t\t\t\trange: [0, Infinity],\n\t\t\t\t},\n\t\t\t\tstartTime: {\n\t\t\t\t\trange: [0, Infinity],\n\t\t\t\t},\n\t\t\t},\n\t\t});\n\t}\n\n\t/**\n\t * Server wants \"startMillseconds,endMilliseconds\"\n\t * @param {module:audioEditor/models/audio} audio Audio\n\t * @override\n\t */\n\tconvertValue(audio) {\n\t\tconst value = this.getValue() || [0, 0];\n\t\treturn [Math.round(value[0] * 1000), Math.round(value[1] * 1000)].join(',');\n\t}\n\n\t/**\n\t * @method\n\t * @param {flaot} seconds Seconds\n\t */\n\tgetTimeObject(seconds) {\n\t\tlet time = seconds;\n\n\t\tconst hour = floor(time / 3600);\n\t\ttime -= hour * 3600;\n\n\t\tconst minute = floor(time / 60);\n\t\ttime -= floor(minute * 60);\n\n\t\tconst second = round(time);\n\t\tconst millisecond = round((time - second) * 1000);\n\n\t\treturn {\n\t\t\thour: hour,\n\t\t\tminute: minute,\n\t\t\tsecond: second,\n\t\t\tmillisecond: millisecond,\n\t\t\tseconds: seconds,\n\t\t\tpretty: [\n\t\t\t\tpad(hour, 2),\n\t\t\t\t':',\n\t\t\t\tpad(minute, 2),\n\t\t\t\t':',\n\t\t\t\tpad(second, 2),\n\t\t\t\t'.',\n\t\t\t\tpad(millisecond, 3),\n\t\t\t].join(''),\n\t\t};\n\t}\n\n\t/**\n\t * @method\n\t * @param {module:audioEditor/models/audio} audio Audio\n\t * @return {boolean}\n\t */\n\thasChanged(audio) {\n\t\tconst value = this.get('value');\n\t\treturn value[0] !== 0 || value[1] !== 0;\n\t}\n\n\t/** @type {string} */\n\tstatic get __name__() {\n\t\treturn 'Operation_Trim';\n\t}\n}\n","export default {};\n","/**\n * Audio operations\n * If passed an asset, the operations can be fetched from the server\n * @class\n */\nimport Base from '@netx/core/lib/netx-collection';\n\nimport BaseOperationModel from '../models/operation';\nimport FormatOperationModel from '../models/operation_format';\nimport TrimOperationModel from '../models/operation_trim';\n\nimport customConfig from '../config';\n\nconst Models = {\n\tbase: BaseOperationModel,\n\tformat: FormatOperationModel,\n\ttrim: TrimOperationModel,\n};\n\nexport default class Operations extends Base {\n\t/**\n\t * @type {Netx.Rpc}\n\t * @private\n\t */\n\tget rpc() {\n\t\treturn true;\n\t}\n\t/**\n\t * @type {Netx.URL}\n\t * @private\n\t */\n\tget url() {\n\t\treturn Netx.URL.api;\n\t}\n\n\t/** @type {boolean} */\n\tget xhrTrackProgress() {\n\t\treturn true;\n\t}\n\n\t/**\n\t * Since we are overriding the model proeprty as a method\n\t * we need to point backbone into the right direction with model prototype accessing\n\t * This is the only method in all of the backbone collection code that relys on getting the a property from the model prototype\n\t * @override\n\t * @param {object} attrs Attributes\n\t * @return {mixed} Model id\n\t */\n\tmodelId(attrs) {\n\t\treturn attrs[Models.base.prototype.idAttribute || 'id'];\n\t}\n\n\t/**\n\t * Return an array of the IDs of the models in this collection.\n\t * Se note about `this.modelId` - this is an override of code in module:core/lib/netx-collection\n\t * @override\n\t * @return {array} Array of model ids\n\t */\n\tids() {\n\t\treturn this.pluck(Models.base.prototype.idAttribute || 'id');\n\t}\n\n\t/**\n\t * @property {object} methods - RPC methods\n\t * @property {method} methods.read - Fetch operations\n\t */\n\tget methods() {\n\t\treturn {\n\t\t\t/**\n\t\t\t * @method\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tread(opts) {\n\t\t\t\tconst asset = this.asset;\n\t\t\t\tif (asset == null) {\n\t\t\t\t\treturn new $.Deferred().reject(new Error('`this.asset` required'));\n\t\t\t\t}\n\n\t\t\t\treturn asset.getProcessListForUser().then(userOperations => {\n\t\t\t\t\tlet additionalOptions, dropdownValues, pulldownOptions, userOperation;\n\t\t\t\t\t// Loop over `customConfig.OPERATIONS` and check if within the returned `userOperations`\n\t\t\t\t\tconst operations = _.compact(\n\t\t\t\t\t\t_.map(userOperations, userOperation => {\n\t\t\t\t\t\t\t// Not supported\n\t\t\t\t\t\t\tif (Models[userOperation.name] == null) return;\n\n\t\t\t\t\t\t\tadditionalOptions = {};\n\n\t\t\t\t\t\t\t// Set format value\n\t\t\t\t\t\t\tif (name === 'format') {\n\t\t\t\t\t\t\t\tadditionalOptions.value = asset\n\t\t\t\t\t\t\t\t\t.get('filetypelabel')\n\t\t\t\t\t\t\t\t\t.toUpperCase();\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\treturn _.extend(\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tname: name,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t_.omit(userOperation, 'label'),\n\t\t\t\t\t\t\t\tadditionalOptions,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\n\t\t\t\t\t// Add in trim\n\t\t\t\t\toperations.push({name: 'trim', control: 'trim'});\n\n\t\t\t\t\treturn operations;\n\t\t\t\t});\n\t\t\t},\n\t\t};\n\t}\n\n\t/** @override */\n\tconstructor(models, opts = {}) {\n\t\topts.comparator = opts.comparator || 'name';\n\t\topts.model =\n\t\t\topts.model ||\n\t\t\tfunction(attrs, opts) {\n\t\t\t\tconst modelClass = Models[attrs.name] || Models.base;\n\t\t\t\treturn new modelClass(attrs, opts);\n\t\t\t};\n\n\t\tsuper(models, opts);\n\n\t\t/**\n\t\t * Related asset\n\t\t * @memberof module:audioEditor/models/audioEditorAudio\n\t\t * @alias asset\n\t\t * @type {module:asset/models/asset}\n\t\t */\n\t\tthis.asset = opts.asset;\n\t}\n\n\t/** @type {string} */\n\tstatic get __name__() {\n\t\treturn 'Operations';\n\t}\n}\n","/**\n * @class\n */\nimport Base from '@netx/core/lib/netx-collection';\n\nimport BaseOperationModel from '../models/operation';\nimport FormatOperationModel from '../models/operation_format';\nimport TrimOperationModel from '../models/operation_trim';\n\nimport AudioEditorOperationsCollection from './operations';\n\nconst Models = {\n\tbase: BaseOperationModel,\n\tformat: FormatOperationModel,\n\ttrim: TrimOperationModel,\n};\n\nexport default class OperationsStack extends Base {\n\t/**\n\t * Since we are overriding the model proeprty as a method\n\t * we need to point backbone into the right direction with model prototype accessing\n\t * This is the only method in all of the backbone collection code that relys on getting the a property from the model prototype\n\t * @override\n\t * @param {object} attrs Attributes\n\t * @return {mixed} Model id\n\t */\n\tmodelId(attrs) {\n\t\treturn attrs[Models.base.prototype.idAttribute || 'id'];\n\t}\n\n\t/**\n\t * Return an array of the IDs of the models in this collection.\n\t * Se note about `this.modelId` - this is an override of code in module:core/lib/netx-collection\n\t * @override\n\t * @return {array} Array of model ids\n\t */\n\tids() {\n\t\treturn this.pluck(Models.base.prototype.idAttribute || 'id');\n\t}\n\n\t/** @override */\n\tconstructor(models, opts = {}) {\n\t\topts.comparator = opts.comparator || 'order';\n\t\topts.model =\n\t\t\topts.model ||\n\t\t\tfunction(attrs, opts) {\n\t\t\t\tconst modelClass = Models[attrs.name] || Models.base;\n\t\t\t\treturn new modelClass(attrs, opts);\n\t\t\t};\n\n\t\tsuper(models, opts);\n\n\t\t/**\n\t\t * @memberof module:audioEditor/collections/audioEditorOperationsStack\n\t\t * @alias audioOperations\n\t\t * @type {module:audioEditor/collections/audioEditorOperations}\n\t\t */\n\t\tthis.audioOperations =\n\t\t\topts.audioOperations || new AudioEditorOperationsCollection([]);\n\n\t\t// Hey, listen!\n\t\t// If the operation had a specified index we need to update the collection indexes to get in the right spot\n\t\tthis.listenTo(this, 'add', (operation, collection, options) => {\n\t\t\toperation.get('index') != null && this.updateIndex(collection);\n\t\t});\n\t}\n\n\t/**\n\t * Get a good clone of our operation models\n\t * @return {array} Array of model attributes\n\t */\n\tgetClone() {\n\t\treturn this.map(m => {\n\t\t\tconst attributes = {};\n\t\t\t_.each(m.attributes, (attr, k) => {\n\t\t\t\tif (_.isArray(attr)) {\n\t\t\t\t\tattributes[k] = attr.slice();\n\t\t\t\t} else if (_.isObject(attr)) {\n\t\t\t\t\tattributes[k] = _.clone(attr);\n\t\t\t\t} else {\n\t\t\t\t\tattributes[k] = attr;\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn attributes;\n\t\t});\n\t}\n\n\t/**\n\t * @method\n\t * @param {Netx.Models.ImageEditorImage} image ImageEditorImage model\n\t * @return {object} Data\n\t */\n\tgetData(audio) {\n\t\tconst data = {};\n\n\t\tthis.each(operation => {\n\t\t\t// Find value\n\t\t\tlet value = operation.getValue(audio);\n\n\t\t\tif (\n\t\t\t\tvalue == null ||\n\t\t\t\t(operation.get('name') !== 'format' && !operation.hasChanged(audio))\n\t\t\t)\n\t\t\t\treturn;\n\n\t\t\t// If we have a convert function\n\t\t\tif (_.isFunction(operation.convertValue)) {\n\t\t\t\tvalue = operation.convertValue(audio);\n\t\t\t}\n\n\t\t\t// Just return value on name\n\t\t\tdata[operation.get('name')] = value;\n\t\t});\n\n\t\treturn data;\n\t}\n\n\t/**\n\t * @method\n\t * @param {string} name Operation name\n\t * @param {mixed} value Operation value\n\t * @return {object} Operation object\n\t */\n\tnewOperation(name, value) {\n\t\t// Find our new operation\n\t\tlet operation = this.audioOperations.get(name);\n\n\t\t// Bad operation\n\t\tif (!operation) return false;\n\n\t\t// Need a cloned copy of those attributes\n\t\toperation = _.clone(operation.attributes);\n\t\tif (value != null) {\n\t\t\t_.extend(operation, {value: value});\n\t\t}\n\n\t\treturn operation;\n\t}\n\n\t/**\n\t * @method\n\t * @param {Netx.Models.ImageEditorOperation} model ImageEditorOperation model\n\t * @param {number} amount Amount to move up or down ( 1, -1 ) - Will not work for operations with a specified index\n\t */\n\tupdateIndex(model, amount) {\n\t\t// Placeholders for sorting later\n\t\tconst indexedOrder = [];\n\t\tlet unindexedOrder = [];\n\n\t\t// Original index\n\t\tconst oindex = model.get('order');\n\n\t\t// New index\n\t\tlet nindex = oindex + amount;\n\n\t\t// Check bounds\n\t\tif (nindex < 0) nindex = 0;\n\t\tif (nindex > this.length) nindex = this.length;\n\n\t\t// Set silently\n\t\tmodel.set({order: nindex}, {silent: true});\n\n\t\t// Update all non index enforced operations\n\t\tlet order;\n\t\t_.each(this.models, m => {\n\t\t\torder = m.get('order');\n\t\t\t// Not concerned with indexed enforced operations\n\t\t\tif (m.get('index') != null) return;\n\t\t\t// Not concerned with the model (operation) passed to this method\n\t\t\t// That was already set above\n\t\t\tif (m.cid == model.cid) return;\n\n\t\t\tif (amount < 0) {\n\t\t\t\torder < oindex && m.set({order: order + 1}, {silent: true});\n\t\t\t} else if (amount > 0) {\n\t\t\t\torder > oindex && m.set({order: order - 1}, {silent: true});\n\t\t\t}\n\t\t});\n\n\t\t// Lets create some array that we can play with a little easier than models\n\t\tconst zipped = _.map(\n\t\t\t_.zip(this.pluck('index'), this.pluck('order'), this.pluck('name')),\n\t\t\tn => _.object(['index', 'order', 'name'], n),\n\t\t);\n\n\t\t// Break each off to where it belongs\n\t\t_.each(zipped, (t, i) => {\n\t\t\tif (t.index != null) {\n\t\t\t\t// Don't worry - will _.compact before parsing this\n\t\t\t\tindexedOrder[t.index] = t;\n\t\t\t} else {\n\t\t\t\tunindexedOrder.push(t);\n\t\t\t}\n\t\t});\n\n\t\t// Sort what is left\n\t\tunindexedOrder = _.sortBy(unindexedOrder, obj => obj.order);\n\n\t\t// Combine the two (indexedOrder first) and update each model's order based on the index in the array\n\t\t_.each(_.compact(indexedOrder).concat(unindexedOrder), (op, i) => {\n\t\t\tlet model = this.findWhere({name: op.name});\n\t\t\tif (!model) return;\n\n\t\t\tmodel.set({order: i}, {silent: true});\n\t\t});\n\n\t\t// Sort collection\n\t\tthis.sort();\n\t}\n\n\t/** @type {string} */\n\tstatic get __name__() {\n\t\treturn 'OperationsStack';\n\t}\n}\n","/**\n * @class\n */\nimport Base from '@netx/core/lib/netx-model';\n\nimport AssetSetModel from '@netx/core-asset/models/assetSet';\nimport OperationsCollection from '../collections/operations';\nimport OperationsStackCollection from '../collections/operationsStack';\n\nimport {types as assetSetTypes} from '@netx/core-asset/properties/assetSets';\nimport {types as downloadOptionTypes} from '@netx/core-share/properties/downloadOptions';\n\nexport default class Audio extends Base {\n\t/** @type {string} */\n\tget idAttribute() {\n\t\treturn 'assetId';\n\t}\n\n\t/**\n\t * @property {object} defaults - Model defaults\n\t * @property {number} defaults.assetId - Asset ID\n\t * @property {number} defaults.duration - Duration\n\t * @property {string} defaults.file - File name\n\t * @property {number} defaults.fileSize2 - File size\n\t * @property {string} defaults.filetypelabel - File type label\n\t * @property {string} defaults.name - Asset name\n\t * @property {string} defaults.originalUrl - Path to original file\n\t * @property {string} defaults.path - Path to file\n\t * @property {string} defaults.audioUrl - Path to audio\n\t */\n\tget defaults() {\n\t\treturn {\n\t\t\tassetId: 0,\n\t\t\taudioUrl: '',\n\t\t\tduration: 0,\n\t\t\tfile: '',\n\t\t\tfileSize2: 0,\n\t\t\tfiletypelabel: '',\n\t\t\tname: '',\n\t\t\toriginalUrl: '',\n\t\t\tpath: '',\n\t\t};\n\t}\n\n\t/**\n\t * @override\n\t * @param {object} attrs Model attributes\n\t * @param {object} opts Model options\n\t */\n\tconstructor(attrs = {}, opts = {}) {\n\t\tsuper(attrs, opts);\n\n\t\tconst asset = opts.asset;\n\n\t\tif (asset) {\n\t\t\t// Get pertinent attributes from asset\n\t\t\tthis.set(\n\t\t\t\t_.extend(\n\t\t\t\t\t{},\n\t\t\t\t\t_.pick.apply(\n\t\t\t\t\t\tnull,\n\t\t\t\t\t\t[asset.attributes].concat(_.keys(this.constructor.GetDefaults())),\n\t\t\t\t\t),\n\t\t\t\t\tattrs,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\t/**\n\t\t * Related asset\n\t\t * @memberof module:audioEditor/models/audioEditorAudio\n\t\t * @alias asset\n\t\t * @type {module:asset/models/asset}\n\t\t */\n\t\tthis.asset = opts.asset;\n\n\t\t/**\n\t\t * @memberof module:audioEditor/models/audioEditorAudio\n\t\t * @alias operations\n\t\t * @type {module:audioEditor/collections/audioEditorOperations}\n\t\t */\n\t\tthis.operations =\n\t\t\topts.operations || new OperationsCollection([], {asset: this.asset});\n\n\t\t/**\n\t\t * @memberof module:audioEditor/models/audioEditorAudio\n\t\t * @alias lastOperationsStack\n\t\t * @type {module:audioEditor/collections/audioEditorOperationsStack}\n\t\t */\n\t\tthis.lastOperationsStack =\n\t\t\topts.lastOperationsStack || new OperationsStackCollection([]);\n\n\t\t/**\n\t\t * Hold changes temporarily so that we can have an accurate lastOperationsStack\n\t\t * @memberof module:audioEditor/models/audioEditorAudio\n\t\t * @alias operationStackArray\n\t\t * @type {array}\n\t\t */\n\t\tthis.operationStackArray = opts.operationStackArray || [];\n\n\t\t/**\n\t\t * @memberof module:audioEditor/models/audioEditorAudio\n\t\t * @alias operationStackHistory\n\t\t * @type {array}\n\t\t */\n\t\tthis.operationStackHistory = opts.operationStackHistory || [];\n\n\t\t/**\n\t\t * @memberof module:audioEditor/models/audioEditorAudio\n\t\t * @alias operationsStack\n\t\t * @type {module:audioEditor/collections/audioEditorOperationsStack}\n\t\t */\n\t\tthis.operationsStack =\n\t\t\topts.operationsStack ||\n\t\t\tnew OperationsStackCollection([], {\n\t\t\t\taudioOperations: this.operations,\n\t\t\t});\n\t}\n\n\t/**\n\t * Get our data\n\t * @method\n\t * @return {object} Operations\n\t */\n\tgetData() {\n\t\treturn this.operationsStack.getData(this);\n\t}\n\n\t/**\n\t * Get operation object from stack\n\t * @method\n\t * @param {string} key Operation key\n\t * @param {boolean} alias Whether or not to use alias instead of name\n\t * @return {object} Operation object\n\t */\n\tgetOperation(key, alias) {\n\t\treturn this.operationsStack.findWhere(alias ? {alias: key} : {name: key});\n\t}\n\n\t/**\n\t * @method\n\t * @return {array} Waveform JSON\n\t */\n\tgetWaveformJSON() {\n\t\treturn this.asset.getWaveformJSON().then(peaks => {\n\t\t\tthis.peaks = peaks;\n\t\t\treturn peaks;\n\t\t});\n\t}\n\n\t/**\n\t * Get the manual repurpose options for audio downloading\n\t * @method\n\t * @param {object} data Preset process data\n\t * @return {array} Manual repurpose options\n\t */\n\tgetManualRepurposeOptions(data) {\n\t\t// DAM-12942\n\t\tdata.audio = '';\n\t\treturn _.map(data, (v, k) => {\n\t\t\tif (k === 'trim') k = 'audioTrim';\n\t\t\treturn {\n\t\t\t\tlabel: k,\n\t\t\t\tvalue: v,\n\t\t\t};\n\t\t});\n\t}\n\n\t/**\n\t * @method\n\t * @param {object} opts Request options\n\t */\n\tfetchOperations(opts) {\n\t\treturn this.operations.fetch(opts);\n\t}\n\n\t/**\n\t * Create an assetSet object from this data\n\t * @method\n\t * @return {module:asset/models/assetSet} Asset set\n\t */\n\ttoAssetSet() {\n\t\treturn new AssetSetModel(\n\t\t\t{\n\t\t\t\ttype: assetSetTypes.asset,\n\t\t\t\tids: [this.id],\n\t\t\t\tmodels: [this],\n\t\t\t\tlabel: this.get('name'),\n\t\t\t\tcanCreateLink: false,\n\t\t\t\tcanEmail: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\t// It may not display in the UI at this point but it certainly needs to be in the download options\n\t\t\t\t// See the parser for `getDownloadOptions` in `module:asset/models/assetSet`\n\t\t\t\t// Things that are confusing and/or not supported:\n\t\t\t\t// `contactSheet` - (not supported) User just gets the non-repurposed asset audio\n\t\t\t\t// All the asset preset/views/facades - (confusing) User just trying to download a manual repurpose\n\t\t\t\t// We need the original option in the event that the server does not respond with `manualRepurpose` as an option - it is not fully up to speed yet(?)\n\t\t\t\tdisplayedDownloadOptionTypes: _.values(\n\t\t\t\t\t_.pick(downloadOptionTypes, 'metadata', 'original'),\n\t\t\t\t).concat('manualRepurpose'),\n\t\t\t},\n\t\t);\n\t}\n\n\t/**\n\t * Add operation to stack\n\t * @method\n\t * @return {object} Changes\n\t */\n\tupdateOperations() {\n\t\t// We will store operations with changes here\n\t\tconst changes = {};\n\n\t\t// Store last operations\n\t\tthis.lastOperationsStack.reset(this.operationStackArray.slice());\n\n\t\t// Loop over operations to set\n\t\tlet attributes, lastOp;\n\t\tthis.operationsStack.each(o => {\n\t\t\t// Cloned copy of attributes (otherwise the values will be mirrored before we can compare above)\n\t\t\tattributes = _.clone(o.attributes);\n\n\t\t\t// Check if operation was part of last operation stack\n\t\t\tlastOp = this.lastOperationsStack.findWhere({name: attributes.name});\n\n\t\t\t// Check for changes\n\t\t\tif (lastOp == null || !_.isEqual(lastOp.get('value'), attributes.value)) {\n\t\t\t\t// Store change\n\t\t\t\tchanges[attributes.alias || attributes.name] = {\n\t\t\t\t\tvalue: attributes.value,\n\t\t\t\t};\n\t\t\t}\n\t\t});\n\n\t\t// Loop over last operation stack and if an item is not present in the current operation stack we know it has been removed\n\t\tlet currentOp;\n\t\tthis.lastOperationsStack.each(o => {\n\t\t\t// Find in last operation\n\t\t\tcurrentOp = this.operationsStack.findWhere({name: o.get('name')});\n\t\t\tif (currentOp == null) {\n\t\t\t\tchanges[o.get('alias') || o.get('name')] = {\n\t\t\t\t\tvalue: o.get('value'),\n\t\t\t\t\tremoved: true,\n\t\t\t\t};\n\t\t\t}\n\t\t});\n\n\t\t// Put into history\n\t\tthis.operationStackHistory.push(this.lastOperationsStack.getClone());\n\t\tthis.operationStackArray = this.operationsStack.getClone();\n\n\t\treturn changes;\n\t}\n\n\t/** @type {string} */\n\tstatic get __name__() {\n\t\treturn 'Audio';\n\t}\n}\n","/**\n * @class\n */\nimport Base from '@netx/core/lib/netx-view';\nimport Template from '../templates/operationControl.html';\n\nexport default class OperationControl extends Base {\n\t/** @override */\n\tconstructor(opts = {}) {\n\t\topts.className = opts.className || 'operation';\n\t\topts.events = _.extend(\n\t\t\t{\n\t\t\t\tchange: 'updateValue',\n\t\t\t},\n\t\t\topts.events,\n\t\t);\n\t\topts.template = opts.template || Template;\n\t\tsuper(opts);\n\n\t\t// Debounced/throttled methods\n\t\tthis.updateValue = _.throttle(this.updateValue, 50, true);\n\t}\n\n\t/** @override */\n\tbindModelEvents() {\n\t\tsuper.bindModelEvents();\n\n\t\tconst model = this.model;\n\t\treturn this.listenTo(model.collection, 'reset', this.remove)\n\t\t\t.listenTo(model, 'remove', this.remove)\n\t\t\t.listenTo(model, 'change', this.render);\n\t}\n\n\t/** @override */\n\tpostRender() {\n\t\tsuper.postRender();\n\n\t\t// Cache\n\t\tconst items = this.model.get('items');\n\t\tif (items) {\n\t\t\tconst _items = (this.items = {});\n\t\t\t_.each(items, (item, k) => {\n\t\t\t\t_items[k] = this.$(`[name=\"${k}\"]`);\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Make sure values are within range (if they have a range)\n\t * @method\n\t * @param {event} e `change` event\n\t * @return {number|object} If mutliple items then an object, else a number\n\t */\n\tcheckBounds(e) {\n\t\tif (this.items) {\n\t\t\tconst values = {};\n\t\t\t_.each(this.items, ($item, k) => {\n\t\t\t\tlet range = this.items[k].range;\n\t\t\t\tlet val = parseInt($item.val()) || 0;\n\n\t\t\t\tif (range != null) {\n\t\t\t\t\tlet _val = val;\n\t\t\t\t\tval = Math.max(range[0], Math.min(range[1], val));\n\t\t\t\t\t// Value adjusted to range\n\t\t\t\t\t_val !== val && $item.val(val);\n\t\t\t\t}\n\t\t\t\tvalues[k] = val;\n\t\t\t});\n\t\t\treturn values;\n\t\t} else {\n\t\t\tconst $target = this.$(e.target);\n\t\t\tconst range = this.model.get('range');\n\t\t\tlet val =\n\t\t\t\tparseInt(_.isObject(e.value) ? e.value.newValue : $target.val()) || 0;\n\n\t\t\tif (range != null) {\n\t\t\t\tlet _val = val;\n\t\t\t\tval = Math.max(range[0], Math.min(range[1], val));\n\t\t\t\t// Value adjusted to range\n\t\t\t\t_val !== val && $target.val(val);\n\t\t\t}\n\t\t\treturn val;\n\t\t}\n\t}\n\n\t/**\n\t * @method\n\t * @param {mixed} value The value to set for this operation\n\t * @fires module:audioEditor#audioEditor:operation:set:value\n\t */\n\tsetValue(value) {\n\t\tdispatcher.trigger(\n\t\t\t'audioEditor:operation:set:value',\n\t\t\tthis.model.collection,\n\t\t\tthis.model.get('name'),\n\t\t\tvalue,\n\t\t\tvalue,\n\t\t);\n\t\t// Chain\n\t\treturn this;\n\t}\n\n\t/** @override */\n\tunbindModelEvents() {\n\t\tsuper.unbindModelEvents();\n\t\treturn this.stopListening(this.model.collection);\n\t}\n\n\t/**\n\t * @method\n\t * @param {event} e `change` event\n\t */\n\tupdateValue(e) {\n\t\tconst value = this.checkBounds(e);\n\t\treturn this.setValue(value);\n\t}\n\n\t/** @type {string} */\n\tstatic get __name__() {\n\t\treturn 'OperationControl';\n\t}\n}\n","/**\n * @class\n */\nimport Base from './operationControl';\nimport Template from '../templates/operationControl_dropdown.html';\n\nexport default class OperationControl_Dropdown extends Base {\n\t/** @override */\n\tconstructor(opts = {}) {\n\t\topts.template = opts.template || Template;\n\t\tsuper(opts);\n\t}\n\n\t/**\n\t * We have a very simple task here - no bounds just an option from a dropdown\n\t * @method\n\t * @param {event} e `change` event\n\t */\n\tupdateValue(e) {\n\t\treturn this.setValue(this.$(e.target).val());\n\t}\n\n\t/** @type {string} */\n\tstatic get __name__() {\n\t\treturn 'OperationControl_Dropdown';\n\t}\n}\n","/**\n * @class\n * @override\n */\nimport Base from '@netx/core-audio-editor/views/operationControl_dropdown';\n\nimport Selectpicker from '@netx/core/functionality/selectpicker';\nSelectpicker(Base);\n\nexport default Base;\n","/**\n * @class\n */\nimport Base from './operationControl';\nimport Template from '../templates/operationControl_trim.html';\n\nexport default class OperationControl_Trim extends Base {\n\t/** @override */\n\tconstructor(opts = {}) {\n\t\topts.className = opts.className || 'operation audio-trim';\n\t\topts.events = {\n\t\t\t'click .nx-clear': 'clear',\n\t\t\t'click .nx-trim-start-add': 'addToStartTime',\n\t\t\t'click .nx-trim-end-add': 'addToEndTime',\n\t\t\t'click .nx-trim-start-subtract': 'subtractFromStartTime',\n\t\t\t'click .nx-trim-end-subtract': 'subtractFromEndTime',\n\t\t\t...opts.events,\n\t\t};\n\t\topts.template = opts.template || Template;\n\t\tsuper(opts);\n\n\t\t// Debounced/throttled methods\n\t\tthis.regionUpdating = _.throttle(this.regionUpdating, 50, true);\n\n\t\tthis.sound = opts.sound;\n\n\t\tconst initVal = this.model.get('value');\n\t\t/**\n\t\t * @memberof module:audioEditor/views/audioEditorOperationControlView_trim\n\t\t * @alias currentTime\n\t\t * @type {object}\n\t\t */\n\t\tthis.currentTrim = initVal\n\t\t\t? {start: initVal[0], end: initVal[1], duration: initVal[1] - initVal[0]}\n\t\t\t: {start: 0, end: 0, duration: 0};\n\n\t\t// Hey, listen!\n\t\tthis.listenTo(this, 'media:region-updated', this.regionUpdating).listenTo(\n\t\t\tthis,\n\t\t\t'media:region-update-end',\n\t\t\tthis.regionUpdated,\n\t\t);\n\n\t\t// We need to do this - backbone can't clean up listeners to objects that get destroyed\n\t\t// the alternative is to listen to these and fire off the methods above instead\n\t\t// up to you\n\t\t// But listening to the object directly causes errors in backbone's removal of events\n\t\t// obj.off is undefined - line 181\n\t\t_.each(['region-updated', 'region-update-end'], event => {\n\t\t\tthis.sound.on(event, (...args) => {\n\t\t\t\tthis.trigger(`media:${event}`, ...args);\n\t\t\t});\n\t\t});\n\t}\n\n\t/** @override */\n\tbindModelEvents() {\n\t\tsuper.bindModelEvents();\n\n\t\tthis.stopListening(this.model, 'change');\n\t\treturn this.listenTo(this.model, 'change', model => {\n\t\t\tif (_.isEmpty(_.omit(model.changed, 'value'))) {\n\t\t\t\tconst value = model.getValue();\n\t\t\t\t// check if the value actually needs updating\n\t\t\t\t// This is where a virtual DOM would be awesome - no need to make thses carve outs for renders\n\t\t\t\treturn (\n\t\t\t\t\t(this.$startTime && value[0] !== this.$startTime.val()) ||\n\t\t\t\t\t(this.$endTime && value[1] !== this.$endTime.val() && this.render())\n\t\t\t\t);\n\t\t\t}\n\t\t\t// Render for all other changes\n\t\t\tthis.render();\n\t\t});\n\t}\n\n\t/** @override */\n\tpostRender() {\n\t\tsuper.postRender();\n\n\t\t// Cache\n\t\tthis.$endTime = this.$('.nx-trim-end');\n\t\tthis.$startTime = this.$('.nx-trim-start');\n\n\t\tthis.mediaReady();\n\t}\n\n\t/**\n\t * @method\n\t * @param {event} e `click` event\n\t */\n\taddToEndTime(e) {\n\t\tconst currentTrim = this.currentTrim;\n\n\t\tif (currentTrim.end === this.totalTime.seconds) return;\n\n\t\tthis.updateTrimTime({\n\t\t\tstart: currentTrim.start,\n\t\t\tend: this.model.getTimeObject(currentTrim.end + 1).seconds,\n\t\t});\n\n\t\tthis.updateValue(e);\n\t}\n\n\t/**\n\t * @method\n\t * @param {event} e `click` event\n\t */\n\taddToStartTime(e) {\n\t\tconst currentTrim = this.currentTrim;\n\n\t\tthis.updateTrimTime({\n\t\t\tstart: this.model.getTimeObject(currentTrim.start + 1).seconds,\n\t\t\tend: currentTrim.end,\n\t\t});\n\n\t\tthis.updateValue(e);\n\t}\n\n\t/**\n\t * @method\n\t * @param {event} e `click` event\n\t */\n\tclear(e) {\n\t\tthis.currentTrim = {start: 0, end: 0, duration: 0};\n\t\tthis.updateTrimTime({\n\t\t\tstart: 0,\n\t\t\tend: 0,\n\t\t});\n\t\tthis.updateValue(e);\n\t}\n\n\t/**\n\t * @method\n\t */\n\tmediaReady() {\n\t\tthis.$endTime.enable();\n\t\tthis.$startTime.enable();\n\n\t\t// Get total time object\n\t\tthis.totalTime = this.model.getTimeObject(this.sound.getDuration());\n\n\t\tthis.isReady = true;\n\t}\n\n\t/**\n\t * @method\n\t * @param {object} region WaveSurfer region\n\t * @fires module:audioEditor#audioEditor:operation:set:value\n\t */\n\tregionUpdated(region) {\n\t\tthis.updateTrimTime(region);\n\n\t\tconst model = this.model;\n\t\tconst value = [region.start, region.end];\n\n\t\tthis.currentTrim = {\n\t\t\tstart: region.start,\n\t\t\tend: region.end,\n\t\t\tduration: region.end - region.start,\n\t\t};\n\n\t\tdispatcher.trigger(\n\t\t\t'audioEditor:operation:set:value',\n\t\t\tmodel.collection,\n\t\t\tmodel.get('name'),\n\t\t\tvalue,\n\t\t\tvalue,\n\t\t);\n\t}\n\n\t/**\n\t * @method\n\t * @param {object} region WaveSurfer region\n\t */\n\tregionUpdating(region) {\n\t\tthis.updateTrimTime(region);\n\t}\n\n\t/**\n\t * @method\n\t * @param {event} e `click` event\n\t */\n\tsubtractFromEndTime(e) {\n\t\tconst currentTrim = this.currentTrim;\n\n\t\tthis.updateTrimTime({\n\t\t\tstart: currentTrim.start,\n\t\t\tend: this.model.getTimeObject(currentTrim.end - 1).seconds,\n\t\t});\n\n\t\tthis.updateValue(e);\n\t}\n\n\t/**\n\t * @method\n\t * @param {event} e `click` event\n\t */\n\tsubtractFromStartTime(e) {\n\t\tconst currentTrim = this.currentTrim;\n\n\t\tif (currentTrim.start === 0) return;\n\n\t\tthis.updateTrimTime({\n\t\t\tstart: this.model.getTimeObject(currentTrim.start - 1).seconds,\n\t\t\tend: currentTrim.end,\n\t\t});\n\n\t\tthis.updateValue(e);\n\t}\n\n\t/**\n\t * @method\n\t * @param {object} range Range object\n\t */\n\tupdateTrimTime(region) {\n\t\t// Only update the input if the value does not already match\n\t\tthis.$startTime.val() !== region.start && this.$startTime.val(region.start);\n\n\t\t// Only update the input if the value does not already match\n\t\tthis.$endTime.val() !== region.end && this.$endTime.val(region.end);\n\t}\n\n\t/**\n\t * @override\n\t * @param {event} e `change` event\n\t */\n\tupdateValue(e) {\n\t\tconst currentTrim = this.currentTrim;\n\t\tconst duration = this.totalTime.seconds;\n\n\t\t// Trim start must be at least 0 and not exceed duration\n\t\tcurrentTrim.start = Math.max(0, Math.min(duration, this.$startTime.val()));\n\t\t// Trim end must be at least trim start and not exceed duration\n\t\tcurrentTrim.end = Math.max(\n\t\t\tcurrentTrim.start,\n\t\t\tMath.min(duration, this.$endTime.val()),\n\t\t);\n\n\t\t// Update current duration\n\t\tcurrentTrim.duration = currentTrim.end - currentTrim.start;\n\n\t\tthis.updateTrimTime(currentTrim);\n\n\t\treturn this.setValue([currentTrim.start, currentTrim.end]);\n\t}\n\n\t/** @type {string} */\n\tstatic get __name__() {\n\t\treturn 'OperationControl_Trim';\n\t}\n}\n","/**\n * @class\n * @override\n */\nimport Base from '@netx/core-audio-editor/views/operationControl_trim';\n\n//import MaterialTextFields from '@netx/core/functionality/materialTextFields';\n\nimport 'core-libs/customElements/nx-time';\n\nimport {faMinus, faPlus} from '@fortawesome/pro-solid-svg-icons';\nconst icons = Base.initializeIcons({\n\tfaMinus,\n\tfaPlus,\n});\n\nexport default class OperationControl_Trim extends Base {\n\t/** @override */\n\tconstructor(opts = {}) {\n\t\topts.icons = {...icons, ...opts.icons};\n\t\tsuper(opts);\n\t}\n}\n\n//MaterialTextFields(OperationControl_Trim);\n","/**\n * @class\n */\nimport Base from '@netx/core/lib/netx-view';\nimport Template from '../templates/operationControls.html';\n\nimport ChildViews from '@netx/core/functionality/childViews';\n\nimport OperationControlView from './operationControl';\nimport DropdownOperationControlView from './operationControl_dropdown';\nimport TrimOperationControlView from './operationControl_trim';\nconst _ChildViews = {\n\tbase: OperationControlView,\n\tdropdown: DropdownOperationControlView,\n\ttrim: TrimOperationControlView,\n};\n\nexport default class OperationControls extends Base {\n\t/** @type {media} */\n\tget sound() {\n\t\treturn this.editor.media;\n\t}\n\n\t/** @override */\n\tconstructor(opts = {}) {\n\t\topts.childView = {\n\t\t\tviewClass(m) {\n\t\t\t\treturn _ChildViews[m.get('control') || 'base'];\n\t\t\t},\n\t\t\toptions() {\n\t\t\t\treturn {\n\t\t\t\t\tsound: this.sound,\n\t\t\t\t};\n\t\t\t},\n\t\t\t...opts.childView,\n\t\t};\n\t\topts.className = opts.className || 'operation-controls';\n\t\topts.template = opts.template || Template;\n\t\tsuper(opts);\n\n\t\tthis.editor = opts.editor;\n\n\t\tthis.listenTo(this.editor, 'media:ready', () => {\n\t\t\t// Stick them in there - we are not currently offerring any other operations (more or less than these two)\n\t\t\tthis.addOperationControl(\n\t\t\t\t'format',\n\t\t\t\tthis.model.get('filetypelabel').toUpperCase(),\n\t\t\t);\n\t\t\tif (!this.editor.hasError) {\n\t\t\t\tthis.addOperationControl('trim');\n\t\t\t}\n\t\t});\n\t}\n\n\t/** @override */\n\tbindCollectionEvents() {\n\t\tsuper.bindCollectionEvents();\n\t\treturn this.listenTo(this.collection, 'add', this.addedOperationControl)\n\t\t\t.listenTo(this.collection, 'remove', this.removedOperationControl)\n\t\t\t.listenTo(this.collection, 'sort', (c, a) => {\n\t\t\t\t// We only want to render on a true sort (not one that happens with adding/removing/syncing)\n\t\t\t\tif (!_.isObject(a) || (!a.add && !a.merge && !a.remove)) {\n\t\t\t\t\tthis.render();\n\t\t\t\t}\n\t\t\t});\n\t}\n\n\t/** @override */\n\tpreRender() {\n\t\tsuper.preRender();\n\n\t\t// Additional template vars\n\t\t_.extend(this.templateVars, {\n\t\t\toperations: this.model.operations,\n\t\t\toperationsSelected: this.collection,\n\t\t});\n\t}\n\n\t/**\n\t * Called when an operation is selected in the view\n\t * @method\n\t * @param {event|string} e Either a jQuery event or operation name\n\t * @param {array|number|object|string} value Initial value\n\t * @fires module:audioEditor#audioEditor:operations:add:control\n\t */\n\taddOperationControl(e, value) {\n\t\t// Get operation name off of target if it was from an event\n\t\tlet name = e.preventDefault\n\t\t\t? this.$(e.currentTarget).data('add-operation')\n\t\t\t: e;\n\n\t\t// Add to selected collection\n\t\tdispatcher.trigger(\n\t\t\t'audioEditor:operations:add:control',\n\t\t\tthis.collection,\n\t\t\tname,\n\t\t\tvalue,\n\t\t);\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Called after an operation has been added to this.operationsSelected\n\t * @method\n\t * @param {Netx.Models.AudioEditorOperation} m AudioEditorOperation model\n\t */\n\taddedOperationControl(m) {\n\t\t//\n\t}\n\n\t/**\n\t * @method\n\t * @param {string} name Operation name\n\t */\n\tgetOperation(name) {\n\t\treturn this.collection.findWhere({name: name});\n\t}\n\n\t/**\n\t * Called when an operation has been removed from this.operationsSelected\n\t * @method\n\t * @param {Netx.Models.AudioEditorOperation} m AudioEditorOperation model\n\t */\n\tremovedOperationControl(m) {\n\t\t//\n\t}\n\n\t/**\n\t * Called when 'audioEditor:reset' is fired\n\t * @method\n\t * @fires module:audioEditor#audioEditor:operation:controls:reset\n\t */\n\treset() {\n\t\t// Clear our selections\n\t\tdispatcher.trigger('audioEditor:operation:controls:reset', this.collection);\n\n\t\t// Enable all add operations\n\t\tthis.$operations.enable();\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Swap one control out for another\n\t * @method\n\t * @param {Netx.Models.AudioEditorOperation} a Control to swap out\n\t * @param {object} b Control to swap in\n\t * @fires module:audioEditor#audioEditor:operations:add:control\n\t * @fires module:audioEditor#audioEditor:operations:remove:control\n\t */\n\tswapControls(a, b) {\n\t\tdispatcher.trigger(\n\t\t\t'audioEditor:operations:remove:control',\n\t\t\tthis.collection,\n\t\t\ta,\n\t\t\t{silent: true},\n\t\t);\n\t\tdispatcher.trigger(\n\t\t\t'audioEditor:operations:add:control',\n\t\t\tthis.collection,\n\t\t\tb.name,\n\t\t);\n\t}\n\n\t/**\n\t * Silently update operation control values\n\t * @method\n\t * @param {object} changes Object of changes\n\t * @fires module:audioEditor#audioEditor:operation:update\n\t */\n\tupdateOperationControls(changes) {\n\t\tdispatcher.trigger(\n\t\t\t'audioEditor:operations:update',\n\t\t\tthis.collection,\n\t\t\tchanges,\n\t\t);\n\t}\n\n\t/** @type {string} */\n\tstatic get __name__() {\n\t\treturn 'OperationControls';\n\t}\n}\n\n// Functionality\nChildViews(OperationControls);\n","/**\n * @class\n */\nimport Base from '@netx/core/lib/netx-tabView';\nimport Template from '../templates/editor.html';\n\nimport OperationControlsView from './operationControls';\n\nimport WaveSurfer from 'core-libs/wavesurfer/wavesurfer';\n// Wavesurfer plugins\nimport RegionsPlugin from 'core-libs/wavesurfer/plugins/wavesurfer.regions';\nimport MinimapPlugin from 'core-libs/wavesurfer/plugins/wavesurfer.minimap';\nimport TimelinePlugin from 'core-libs/wavesurfer/plugins/wavesurfer.timeline';\nimport CursorPlugin from 'core-libs/wavesurfer/plugins/wavesurfer.cursor';\n\n// Resize listener\nimport 'core-libs/jquery.resize';\n\nimport customConfig from '../config';\n\nexport default class Editor extends Base {\n\t/** @override */\n\tconstructor(opts = {}) {\n\t\topts.className = `audio-editor ${opts.className || ''}`;\n\t\topts.defaultTab = opts.defaultTab || 'manual';\n\t\topts.events = {\n\t\t\t'click .nx-save': 'submit',\n\t\t\t'click .nx-play': 'togglePlay',\n\t\t\t'click .nx-seek-back': 'seekBack',\n\t\t\t'click .nx-seek-forward': 'seekForward',\n\t\t\t'mousedown .nx-skip-back': 'startSkipBack',\n\t\t\t'mousedown .nx-skip-forward': 'startSkipForward',\n\t\t\t'mouseup .nx-skip-back': 'stopSkipBack',\n\t\t\t'mouseup .nx-skip-forward': 'stopSkipForward',\n\t\t\t'mouseleave .nx-skip-back': 'stopSkipBack',\n\t\t\t'mouseleave .nx-skip-forward': 'stopSkipForward',\n\t\t\t...opts.events,\n\t\t};\n\t\topts.headerTitle = opts.headerTitle || i18n.t('i18n.repurpose');\n\t\topts.id = opts.id || 'audio-editor';\n\t\topts.removeOnHide = opts.removeOnHide !== false;\n\t\topts.template = opts.template || Template;\n\t\tsuper(opts);\n\n\t\t// Debounced methods\n\t\tthis.displayCurrentTime = _.throttle(this.displayCurrentTime, 100, true);\n\t\tthis.resize = _.debounce(this.resize, 25);\n\t\tthis.regionUpdating = _.throttle(this.regionUpdating, 50, true);\n\t\tthis.seeking = _.throttle(this.seeking, 50, true);\n\t\tthis.skipBack = _.throttle(this.skipBack, 175, true);\n\t\tthis.skipForward = _.throttle(this.skipForward, 175, true);\n\n\t\t// Hey, listen!\n\t\tthis\n\t\t\t// Wavesurfer\n\t\t\t.listenTo(this, 'media:audioprocess', this.displayCurrentTime)\n\t\t\t.listenTo(this, 'media:error', this.mediaError)\n\t\t\t.listenTo(this, 'media:finish', this.finish)\n\t\t\t.listenTo(this, 'media:loading', this.mediaLoadProgress)\n\t\t\t.listenTo(this, 'media:pause', this.pause)\n\t\t\t.listenTo(this, 'media:play', this.play)\n\t\t\t.listenTo(this, 'media:ready', this.mediaReady)\n\t\t\t.listenTo(this, 'media:seek', this.seeking)\n\t\t\t// Wavesurfer Regions\n\t\t\t.listenTo(this, 'media:region-click', this.regionClicked)\n\t\t\t.listenTo(this, 'media:region-created', this.regionCreated)\n\t\t\t.listenTo(this, 'media:region-play', this.regionPlay)\n\t\t\t.listenTo(this, 'media:region-removed', this.regionRemoved)\n\t\t\t.listenTo(this, 'media:region-updated', this.regionUpdating)\n\t\t\t.listenTo(this, 'media:region-update-end', this.regionUpdated)\n\t\t\t.listenTo(dispatcher, 'theme:toggled', this.updateTheme);\n\n\t\t// Register our plugins\n\t\tthis.Plugins.Register({\n\t\t\t// Register WaveSurfer plugin\n\t\t\t// WaveSurfer is a vanilla js plugin - so we must define what happens for initialize and destroy\n\t\t\twavesurfer: {\n\t\t\t\tname: 'WaveSurfer',\n\t\t\t\telementKey: 'container',\n\t\t\t\toptions: {\n\t\t\t\t\t// Auto center needs work\n\t\t\t\t\t// it is far too basic in its approach that it can be really annoying in use\n\t\t\t\t\tautoCenter: false,\n\t\t\t\t\tbackend: 'MediaElement',\n\t\t\t\t\tbarWidth: 4,\n\t\t\t\t\tcloseAudioContext: true,\n\t\t\t\t\tminPxPerSec: 1,\n\t\t\t\t\tnormalize: true,\n\t\t\t\t\tprogressColor: Netx.getStyleProperty('primary'),\n\t\t\t\t\twaveColor: Netx.getStyleProperty('text-icon-on-background'),\n\t\t\t\t\tplugins: [\n\t\t\t\t\t\tMinimapPlugin.create({\n\t\t\t\t\t\t\theight: 40,\n\t\t\t\t\t\t\twaveColor: Netx.getStyleProperty('text-secondary-on-background'),\n\t\t\t\t\t\t\tprogressColor: Netx.getStyleProperty(\n\t\t\t\t\t\t\t\t'text-primary-on-background',\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\tcursorColor: Netx.getStyleProperty('text-primary-on-background'),\n\t\t\t\t\t\t\tshowRegions: true,\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tRegionsPlugin.create({\n\t\t\t\t\t\t\tcolor: 'rgba(0, 0, 0, 0.05)',\n\t\t\t\t\t\t\tdragSelection: true,\n\t\t\t\t\t\t}),\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t\tdestroyMethod(instance) {\n\t\t\t\t\t// Pause if playing\n\t\t\t\t\tthis.pauseMedia();\n\t\t\t\t\tdelete this.media;\n\n\t\t\t\t\t// Abort any current loading\n\t\t\t\t\tif (instance.currentAjax != null) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tinstance.currentAjax.abort();\n\t\t\t\t\t\t} catch (e) {}\n\t\t\t\t\t}\n\t\t\t\t\t// Destroy instance\n\t\t\t\t\ttry {\n\t\t\t\t\t\t// Make sure we still have a reference to destroy\n\t\t\t\t\t\tinstance.destroy && instance.destroy();\n\t\t\t\t\t} catch (e) {}\n\t\t\t\t},\n\t\t\t\tinitializeMethod(pluginObj, $pluginEl, initOpts, cb) {\n\t\t\t\t\tinitOpts = initOpts || {};\n\n\t\t\t\t\tconst peaks = initOpts.peaks;\n\t\t\t\t\tconst duration = initOpts.duration;\n\n\t\t\t\t\t// Create wavesurfer instance\n\t\t\t\t\tconst instance = WaveSurfer.create({\n\t\t\t\t\t\tcontainer: $pluginEl[0],\n\t\t\t\t\t\theight: this.$el.height(),\n\t\t\t\t\t\t...pluginObj.options,\n\t\t\t\t\t\t..._.omit(initOpts, 'duration', 'peaks'),\n\t\t\t\t\t});\n\n\t\t\t\t\t// We have to pipe the wavesurfer events\n\t\t\t\t\t_.each(\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t'audioprocess',\n\t\t\t\t\t\t\t'error',\n\t\t\t\t\t\t\t'finish',\n\t\t\t\t\t\t\t'loading',\n\t\t\t\t\t\t\t'pause',\n\t\t\t\t\t\t\t'play',\n\t\t\t\t\t\t\t'ready',\n\t\t\t\t\t\t\t'seek',\n\t\t\t\t\t\t\t// Region plugin events\n\t\t\t\t\t\t\t'region-click',\n\t\t\t\t\t\t\t'region-created',\n\t\t\t\t\t\t\t'region-play',\n\t\t\t\t\t\t\t'region-removed',\n\t\t\t\t\t\t\t'region-updated',\n\t\t\t\t\t\t\t'region-update-end',\n\t\t\t\t\t\t],\n\t\t\t\t\t\tevent => {\n\t\t\t\t\t\t\tinstance.on(event, (...args) => {\n\t\t\t\t\t\t\t\tthis.trigger(`media:${event}`, ...args);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\n\t\t\t\t\tinstance.load(this.$audio[0], peaks, false, duration);\n\t\t\t\t\tinstance.fireEvent('interaction');\n\n\t\t\t\t\t// Return instance to callback\n\t\t\t\t\tcb((this.media = instance));\n\t\t\t\t},\n\t\t\t},\n\t\t});\n\t}\n\n\t/** @override */\n\tbindModelEvents() {\n\t\tsuper.bindModelEvents();\n\t\treturn this.listenTo(\n\t\t\tthis.model.operationsStack,\n\t\t\t'add change remove reset sort',\n\t\t\t_.debounce(this.updateOperations, 75),\n\t\t);\n\t}\n\n\t/** @override */\n\tpreRender() {\n\t\t// Cleanup\n\t\tthis.Plugins.Destroy('resizeListener');\n\t\tthis.Plugins.Destroy('wavesurfer');\n\t\tthis.operationControls && this.removeSubView(this.operationControls, true);\n\n\t\tthis.$el.addClass('media-loading').removeClass('has-error');\n\n\t\tsuper.preRender();\n\t}\n\n\t/** @override */\n\tpostRender() {\n\t\tsuper.postRender();\n\n\t\t// Cache\n\t\tthis.$audio = this.$('.nx-audio');\n\t\tthis.$container = this.$('.nx-audio-container');\n\t\tthis.$currentTime = this.$('.nx-current-time');\n\t\tthis.$durationTime = this.$('.nx-total-time');\n\t\tthis.$errorMessage = this.$('.nx-error-message');\n\t\tthis.$manualOperations = this.$('.nx-manual-operations');\n\t\tthis.$mediaProgress = this.$('.nx-media-progress');\n\t\tthis.$selectionTime = this.$('.nx-selected-time');\n\t\tthis.$timeline = this.$('.nx-wave-timeline');\n\n\t\t// Initialize resize listener plugin\n\t\tthis.Plugins.Initialize('resizeListener', this.$('.stage'));\n\n\t\t// Initialize wavesurfer once shown\n\t\tthis.whenShown.then(this.injectAudio);\n\n\t\tthis.displayDuration();\n\t}\n\n\t/** @override */\n\ttabs() {\n\t\t// Manual\n\t\treturn [\n\t\t\t{\n\t\t\t\tviewClass: OperationControlsView,\n\t\t\t\tlabel: i18n.t('i18n.manual'),\n\t\t\t\tname: 'manual',\n\t\t\t\tviewOptions: {\n\t\t\t\t\tcollection: this.model.operationsStack,\n\t\t\t\t\tmodel: this.model,\n\t\t\t\t\teditor: this,\n\t\t\t\t},\n\t\t\t},\n\t\t];\n\t}\n\n\t/**\n\t * Repurpose\n\t * @method\n\t * @param {event} e `click` event\n\t * @fires module:audioEditor#audioEditor:edit:confirmed\n\t */\n\tsubmit(e) {\n\t\tdispatcher.trigger(\n\t\t\t'audioEditor:edit:confirmed',\n\t\t\tthis.getData(),\n\t\t\tthis.model,\n\t\t);\n\t}\n\n\t/**\n\t * Apply operations to audio\n\t * @method\n\t */\n\tapplyOperations(changes) {\n\t\t// Apply operation stack to audio\n\t\tthis.model.operationsStack.each(op => {\n\t\t\tconst value = op.getValue();\n\n\t\t\t// Not a renderable action\n\t\t\tif (value == null || op.get('render') === false) return;\n\n\t\t\tswitch (op.get('type')) {\n\t\t\t\tcase 'trim':\n\t\t\t\t\tif (this.media.regions) {\n\t\t\t\t\t\tlet regionList = this.media.regions.list;\n\t\t\t\t\t\tlet regionKeys = _.keys(regionList);\n\t\t\t\t\t\tif (value[0] !== 0 || value[1] !== 0) {\n\t\t\t\t\t\t\tif (regionKeys.length) {\n\t\t\t\t\t\t\t\tlet region = regionList[regionKeys[0]];\n\t\t\t\t\t\t\t\tregion.update({\n\t\t\t\t\t\t\t\t\tstart: value[0],\n\t\t\t\t\t\t\t\t\tend: value[1],\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tlet region = this.media.addRegion({\n\t\t\t\t\t\t\t\t\tstart: value[0],\n\t\t\t\t\t\t\t\t\tend: value[1],\n\t\t\t\t\t\t\t\t\tcolor: 'rgba(41, 107, 255, 0.15)',\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (regionKeys.length) {\n\t\t\t\t\t\t\tregionList[regionKeys[0]].remove();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * @method\n\t * @return {boolean} Overflown\n\t */\n\tcheckOverflow() {\n\t\tconst media = this.media;\n\t\tconst drawer = media && media.drawer;\n\t\tif (!drawer) return false;\n\n\t\tconst overflown = drawer.width > drawer.wrapper.clientWidth;\n\t\tthis.el.classList.toggle('audio-editor--wave-fit', !overflown);\n\n\t\treturn overflown;\n\t}\n\n\t/**\n\t * @method\n\t * @param {number} current Current time (seconds)\n\t */\n\tdisplayCurrentTime(current) {\n\t\tconst time = new Date(null);\n\t\ttime.setSeconds(current);\n\t\tconst displayTime = time.toISOString().substr(11, 8);\n\t\tthis.$currentTime.html(displayTime);\n\t}\n\n\t/**\n\t * @method\n\t */\n\tdisplayDuration() {\n\t\tconst time = new Date(null);\n\t\ttime.setSeconds(this.model.get('duration') / 1000);\n\t\tconst duration = time.toISOString().substr(11, 8);\n\t\tthis.$durationTime.html(duration);\n\t}\n\n\t/**\n\t * @method\n\t */\n\tfinish() {\n\t\t//\n\t}\n\n\t/**\n\t * Get our data\n\t * @method\n\t * @return {object} Operations\n\t */\n\tgetData() {\n\t\treturn this.model.getData();\n\t}\n\n\t/**\n\t * Get operation object from stack\n\t * @method\n\t * @param {string} key Operation key\n\t * @param {boolean} alias Whether or not to use alias instead of name\n\t * @return {object} Operation object\n\t */\n\tgetOperation(key, alias) {\n\t\treturn this.model.getOperation(key, alias);\n\t}\n\n\t/**\n\t * Check if operation is in stack\n\t * @method\n\t * @param {string} key Operation key\n\t * @return {boolean} Operation is present\n\t */\n\thasOperation(key) {\n\t\treturn this.getOperation(key) != null;\n\t}\n\n\t/**\n\t * @method\n\t */\n\tinjectAudio() {\n\t\t// We only need to inject the audio plugin again if we have rendered\n\t\t!this.media &&\n\t\t\tthis.rendered.then(() => {\n\t\t\t\t// If the file is longer than 10 minutes scroll the parent\n\t\t\t\tconst duration = this.model.get('duration') / 1000;\n\t\t\t\tconst scrollParent = duration > 10 * 60;\n\n\t\t\t\tthis.peaksUnavailable = this.model.peaks == null;\n\t\t\t\tif (!this.peaksUnavailable) {\n\t\t\t\t\tthis.mediaLoadProgress(100, {active: true});\n\t\t\t\t}\n\n\t\t\t\tthis.hasMediaError = false;\n\n\t\t\t\tthis.Plugins.Initialize('wavesurfer', this.$container, {\n\t\t\t\t\tduration: duration,\n\t\t\t\t\tpeaks: this.model.peaks,\n\t\t\t\t\tscrollParent: scrollParent,\n\t\t\t\t}).then(instance => {\n\t\t\t\t\tthis.$waveContainer = this.$('wave:first');\n\t\t\t\t\tthis.$container.toggleClass('scroll-parent', scrollParent);\n\t\t\t\t\t// Create controls view\n\t\t\t\t\t// this.operationControls = this.addSubView(\n\t\t\t\t\t// \tnew OperationControlsView({\n\t\t\t\t\t// \t\tcollection: this.model.operationsStack,\n\t\t\t\t\t// \t\tmodel: this.model,\n\t\t\t\t\t// \t\tsound: instance,\n\t\t\t\t\t// \t}),\n\t\t\t\t\t// );\n\t\t\t\t\t// this.operationControls.render().$el.appendTo(this.$manualOperations);\n\t\t\t\t});\n\n\t\t\t\t// Update dimensions now that we have some\n\t\t\t\tthis.resize();\n\t\t\t});\n\t}\n\n\t/**\n\t * @method\n\t * @param {string} msg Error message\n\t */\n\tmediaError(msg) {\n\t\tthis.hasMediaError = true;\n\t\tthis.$errorMessage.html(msg);\n\t\tthis.$el.addClass('has-error').removeClass('media-loading');\n\t}\n\n\t/**\n\t * @method\n\t * @param {number} percent Progress percent\n\t * @param {object} opts Options\n\t */\n\tmediaLoadProgress(percent, opts) {\n\t\topts = opts || {};\n\n\t\tconst percentStr = (percent || 0) + '%';\n\n\t\tthis.$el.addClass('media-loading');\n\t\tthis.$mediaProgress\n\t\t\t.toggleClass('progress-striped', opts.active === true)\n\t\t\t.find('.progress-bar')\n\t\t\t.attr('aria-valuenow', percent)\n\t\t\t.css('width', percentStr)\n\t\t\t.toggleClass('active', opts.active === true)\n\t\t\t.find('.sr-only')\n\t\t\t.html(percentStr);\n\t}\n\n\t/**\n\t * @method\n\t */\n\tmediaReady() {\n\t\tthis.$el.removeClass('media-loading');\n\n\t\t// Must be deferred until wavesurfer has finished its ready trigger\n\t\t// and set itself to `isReady` true\n\t\t// I argue that is an oversight in their code and isReady should be\n\t\t// set before triggering `ready`\n\t\t_.defer(() => {\n\t\t\tthis.media.addPlugin(\n\t\t\t\tTimelinePlugin.create({\n\t\t\t\t\tcontainer: this.$timeline[0],\n\t\t\t\t\tnotchPercentHeight: 50,\n\t\t\t\t\tprimaryColor: '#c0c0c0',\n\t\t\t\t\tsecondaryColor: '#c0c0c0',\n\t\t\t\t\tprimaryFontColor: '#c0c0c0',\n\t\t\t\t\tsecondaryFontColor: '#c0c0c0',\n\t\t\t\t\tfontFamily: '\"Source Sans Pro\", sans-serif',\n\t\t\t\t\tfontSize: 10,\n\t\t\t\t}),\n\t\t\t);\n\t\t\tthis.media.initPlugin('timeline');\n\n\t\t\tthis.checkOverflow();\n\t\t});\n\t}\n\n\t/**\n\t * @method\n\t */\n\tpause() {\n\t\tthis.$el.addClass('paused').removeClass('playing');\n\t}\n\n\t/**\n\t * @method\n\t */\n\tpauseMedia() {\n\t\tif (!this.media) return;\n\n\t\tthis.media.isPlaying() && this.media.playPause();\n\t}\n\n\t/**\n\t * @method\n\t */\n\tplay() {\n\t\tthis.$el.addClass('playing').removeClass('paused');\n\t}\n\n\t/**\n\t * @method\n\t * @param {object} region WaveSurfer region\n\t * @param {event} e `region-click` event\n\t */\n\tregionClicked(region, e) {\n\t\te.stopPropagation();\n\n\t\t// Play on click, loop on shift click\n\t\te.shiftKey ? region.playLoop() : region.play();\n\t}\n\n\t/**\n\t * @method\n\t * @param {object} region WaveSurfer region\n\t */\n\tregionCreated(region) {\n\t\tconst regionList = this.media.regions.list;\n\t\tconst regionKeys = _.keys(regionList);\n\n\t\t// Only one at a time\n\t\tregionKeys.length && regionList[regionKeys[0]].remove();\n\n\t\t// Overriding to keep in bounds\n\t\t// Otherwise the plugin shrinks one side as you drag beyond the bounds\n\t\tregion.onDrag = delta => {\n\t\t\tlet start, end;\n\n\t\t\tif (delta) {\n\t\t\t\t// Total length in seconds\n\t\t\t\tconst total = this.media.getDuration();\n\n\t\t\t\t// Moving towards start\n\t\t\t\tif (delta < 0) {\n\t\t\t\t\t// Nothing more to do as we are at the very beginning\n\t\t\t\t\tif (region.start === 0) return;\n\n\t\t\t\t\t// That would go too far - adjust\n\t\t\t\t\tif (region.start + delta < 0) {\n\t\t\t\t\t\tstart = 0;\n\t\t\t\t\t\tend = region.end - region.start;\n\t\t\t\t\t}\n\t\t\t\t\t// Regular behavior\n\t\t\t\t\telse {\n\t\t\t\t\t\tstart = region.start + delta;\n\t\t\t\t\t\tend = region.end + delta;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Moving towards end\n\t\t\t\telse {\n\t\t\t\t\t// Nothing more to do as we are at the very end\n\t\t\t\t\tif (region.end === total) return;\n\n\t\t\t\t\t// That would go too far - adjust\n\t\t\t\t\tif (region.end + delta > total) {\n\t\t\t\t\t\tend = total;\n\t\t\t\t\t\tstart = region.start + (total - region.end);\n\t\t\t\t\t}\n\t\t\t\t\t// Regular behavior\n\t\t\t\t\telse {\n\t\t\t\t\t\tstart = region.start + delta;\n\t\t\t\t\t\tend = region.end + delta;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tregion.update({\n\t\t\t\tstart: start,\n\t\t\t\tend: end,\n\t\t\t});\n\t\t};\n\t}\n\n\t/**\n\t * @method\n\t * @param {object} region WaveSurfer region\n\t */\n\tregionPlay(region) {\n\t\t//\n\t}\n\n\t/**\n\t * @method\n\t * @param {object} region WaveSurfer region\n\t */\n\tregionRemoved(region) {\n\t\tthis.updateSelectionTime({\n\t\t\tend: 0,\n\t\t\tstart: 0,\n\t\t});\n\t}\n\n\t/**\n\t * @method\n\t * @param {object} region WaveSurfer region\n\t */\n\tregionUpdated(region) {\n\t\tthis.updateSelectionTime(region);\n\t}\n\n\t/**\n\t * @method\n\t * @param {object} region WaveSurfer region\n\t */\n\tregionUpdating(region) {\n\t\tthis.updateSelectionTime(region);\n\t}\n\n\t/**\n\t * @method\n\t */\n\tresize() {\n\t\t// Wait until rendered once\n\t\tthis.rendered.then(() => {\n\t\t\tconst media = this.media;\n\t\t\tif (!media || !this.isShown) return;\n\n\t\t\t// If we are not in he midst of loading\n\t\t\t// (otherwise we will be the proper size when loaded)\n\t\t\tif (media.isReady) {\n\t\t\t\t// Backup current time so we can put it back\n\t\t\t\tconst currentTime = media.getCurrentTime();\n\t\t\t\tconst playing = media.isPlaying();\n\n\t\t\t\tthis.$waveContainer.css({\n\t\t\t\t\theight: this.$container.height(),\n\t\t\t\t\twidth: this.$container.width(),\n\t\t\t\t});\n\n\t\t\t\t// Explicitely pause\n\t\t\t\tthis.pauseMedia();\n\n\t\t\t\t// Redraw\n\t\t\t\tmedia.drawBuffer(true);\n\t\t\t\tthis.checkOverflow();\n\n\t\t\t\tconst minimap = media.minimap;\n\t\t\t\tif (minimap) {\n\t\t\t\t\tminimap.render();\n\t\t\t\t\tminimap.renderRegions();\n\t\t\t\t}\n\n\t\t\t\t// Seek to and play where we left off\n\t\t\t\tif (playing) {\n\t\t\t\t\tmedia.play(currentTime);\n\t\t\t\t}\n\t\t\t\t// Just seek to where we left off\n\t\t\t\telse if (currentTime) {\n\t\t\t\t\t// seekTo uses a float to represent play progress - not the time to start at\n\t\t\t\t\tthis.seekTo(currentTime);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * @method\n\t * @param {float} progress Progress\n\t */\n\tseeking(progress) {\n\t\tif (!this.media) return;\n\n\t\tthis.displayCurrentTime(this.media.getCurrentTime());\n\t}\n\n\t/**\n\t * @method\n\t * @param {event} e `click` event\n\t */\n\tseekBack(e) {\n\t\tif (!this.media) return;\n\n\t\tthis.pauseMedia();\n\t\tthis.media.seekTo(0);\n\t}\n\n\t/**\n\t * @method\n\t * @param {event} e `click` event\n\t */\n\tseekForward(e) {\n\t\tif (!this.media) return;\n\n\t\tthis.pauseMedia();\n\t\tthis.media.seekTo(1);\n\t}\n\n\t/**\n\t * @method\n\t * @param {float} seconds Seconds\n\t */\n\tseekTo(seconds) {\n\t\tif (!this.media) return;\n\n\t\t// It is a percent deal\n\t\tthis.media.seekTo(seconds / this.media.getDuration());\n\t}\n\n\t/**\n\t * @method\n\t */\n\tskipBack() {\n\t\tif (!this.media || !this.skipping) return;\n\n\t\tthis.media.skip(-5);\n\t\tthis.skipBack();\n\t}\n\n\t/**\n\t * @method\n\t */\n\tskipForward() {\n\t\tif (!this.media || !this.skipping) return;\n\n\t\tthis.media.skip(5);\n\t\tthis.skipForward();\n\t}\n\n\t/**\n\t * @method\n\t * @param {event} e `mousedown` event\n\t */\n\tstartSkipBack(e) {\n\t\tif (!this.media) return;\n\n\t\tthis.skipping = true;\n\t\tthis.skipBack();\n\t}\n\n\t/**\n\t * @method\n\t * @param {event} e `mousedown` event\n\t */\n\tstartSkipForward(e) {\n\t\tif (!this.media) return;\n\n\t\tthis.skipping = true;\n\t\tthis.skipForward();\n\t}\n\n\t/**\n\t * @method\n\t * @param {event} e `mouseup`/`mouseleave` event\n\t */\n\tstopSkipBack(e) {\n\t\tthis.skipping = false;\n\t}\n\n\t/**\n\t * @method\n\t * @param {event} e `mouseup`/`mouseleave` event\n\t */\n\tstopSkipForward(e) {\n\t\tthis.skipping = false;\n\t}\n\n\t/**\n\t * @method\n\t * @param {event} e `click` event\n\t */\n\ttogglePlay(e) {\n\t\tthis.media && this.media.playPause();\n\t}\n\n\t/** @override */\n\tunbindModelEvents() {\n\t\tsuper.unbindModelEvents();\n\t\treturn this.stopListening(this.model.operationsStack);\n\t}\n\n\t/**\n\t * Add operation to stack\n\t * @method\n\t */\n\tupdateOperations() {\n\t\tconst changes = this.model.updateOperations();\n\n\t\t// Apply current operation stack\n\t\tthis.applyOperations(changes);\n\t}\n\n\t/**\n\t * @method\n\t * @param {object} region WaveSurfer region\n\t */\n\tupdateSelectionTime(region) {\n\t\tconst time = new Date(null);\n\t\ttime.setMilliseconds((region.end - region.start) * 1000);\n\t\tconst displayTime = time.toISOString().substr(11, 11);\n\n\t\tthis.$selectionTime && this.$selectionTime.html(displayTime);\n\t}\n\n\t/** @method */\n\tupdateTheme() {\n\t\tif (!this.media) return;\n\n\t\tthis.media.setWaveColor(Netx.getStyleProperty('text-icon-on-background'));\n\t\tthis.media.setProgressColor(Netx.getStyleProperty('primary'));\n\t}\n\n\t/** @type {string} */\n\tstatic get __name__() {\n\t\treturn 'Editor';\n\t}\n}\n","/**\n * @class\n * @override\n */\nimport Base from '@netx/core-audio-editor/views/editor';\n\nimport Resizable from '@netx/core/functionality/resizable';\n\nimport {\n\tfaBackward,\n\tfaChevronLeft,\n\tfaChevronRight,\n\tfaExclamationCircle,\n\tfaForward,\n\tfaPause,\n\tfaPlay,\n\tfaStepBackward,\n\tfaStepForward,\n\tfaTimes,\n} from '@fortawesome/pro-solid-svg-icons';\nconst icons = Base.initializeIcons({\n\tfaBackward,\n\tfaChevronLeft,\n\tfaChevronRight,\n\tfaExclamationCircle,\n\tfaForward,\n\tfaPause,\n\tfaPlay,\n\tfaStepBackward,\n\tfaStepForward,\n\tfaTimes,\n});\n\nexport default class Editor extends Base {\n\t/** @override */\n\tconstructor(opts = {}) {\n\t\topts.icons = {...icons, ...opts.icons};\n\n\t\topts.resizeDragFrom = 'left';\n\t\topts.resizeMinWidth = 240;\n\t\topts.resizeTargetSelector = '.split-screen__right';\n\n\t\tsuper(opts);\n\t}\n}\n\nResizable(Editor);\n","export default {\n\t// /**\n\t// * audioeditor route. (Lowercased.) Keep routes simple; they should just fire events handled elsewhere.\n\t// * @route\n\t// * @param {number} id\n\t// */\n\t// \"audioeditor(/:id)\": function(id){\n\t// \tdispatcher.trigger('audioEditor:routed', id);\n\t// }\n};\n","/**\n * Audio Editor module\n *\n * @module audioEditor\n */\n\nimport AssetModel from '@netx/core-asset/models/asset';\nimport AudioModel from './models/audio';\nimport AudioEditorView from './views/editor';\n\nimport customConfig from './config';\n\nimport routes from './routes';\n\n// MODULE INITIALIZATION\n// =====================\n// All collection and model instances and event listeners\n// are created when the module is initialized.\n\n/**\n * Init handler\n * @event {@link module:audioEditor#audioEditor:init|audioEditor:init}\n * @param {object} options Normally undefined, but a manual init trigger may override properties of Netx.custom.audioEditor here.\n */\ndispatcher.once('audioEditor:init', function(options) {\n\tvar NS = (Netx.audioEditor = {});\n\t// Check for module options\n\tNS.options = options = _.extend({}, customConfig, options);\n\n\t// PUBLIC MODELS & COLLECTIONS\n\t// ===========================\n\t// Object initializations, etc, go here.\n\n\t// BEGIN DISPATCHER EVENT LISTENERS\n\t// ================================\n\t// All other module event listeners are added here, inside the init handler.\n\n\t/**\n\t * @event module:audioEditor#audioEditor:repurpose:show\n\t * @param {object} viewOptions View options\n\t */\n\tdispatcher.on(\n\t\t'audioEditor:repurpose:show',\n\t\tfunction(viewOptions) {\n\t\t\tNetx.app.fsViews.add({\n\t\t\t\tviewClass: AudioEditorView,\n\t\t\t\tshowActions: ['audioEditor:repurpose:show'],\n\t\t\t\tviewOptions: viewOptions,\n\t\t\t});\n\t\t},\n\t\twindow,\n\t);\n\n\t/**\n\t * @event module:audioEditor#audioEditor:repurpose\n\t * @param {module:asset/models/asset} asset Asset model\n\t * @fires module:audioEditor#audioEditor:repurpose:error\n\t * @fires module:audioEditor#audioEditor:repurpose:show\n\t * @fires module:app#app:confirm\n\t */\n\tdispatcher.on('audioEditor:repurpose', function(asset) {\n\t\t// We cannot do anything useful here - try using a more modern browser\n\t\tif (!Modernizr.webaudioapi) {\n\t\t\tdispatcher.trigger(\n\t\t\t\t'audioEditor:repurpose:error',\n\t\t\t\tnew Error(i18n.t('i18n.noBrowserSupportAudio')),\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tif (!_.contains(asset.get('fileFormatFamily'), 'audio')) {\n\t\t\tdispatcher.trigger(\n\t\t\t\t'audioEditor:repurpose:error',\n\t\t\t\tnew Error(i18n.t('i18n.assetIsNotAudioFile')),\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tif (!asset.get('audioUrl')) {\n\t\t\tdispatcher.trigger(\n\t\t\t\t'audioEditor:repurpose:error',\n\t\t\t\tnew Error('Audio not available'),\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\t// Check permissions\n\t\tconst manualUserLevel =\n\t\t\tNetx.getPreference('sys.minUserLevelForManualRepurpose') || 0;\n\t\tif (Netx.getUserLevel() < manualUserLevel) {\n\t\t\tdispatcher.trigger(\n\t\t\t\t'audioEditor:repurpose:error',\n\t\t\t\tnew Error(i18n.t('i18n.manualRepurposeNotAvailable')),\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\t// Fix route\n\t\tif (!window.location.hash.includes('/audioeditor')) {\n\t\t\tNetx.router.navigate('asset/' + asset.id + '/audioeditor');\n\t\t}\n\n\t\t// We made it so far\n\t\tconst model = new AudioModel({}, {asset: asset});\n\n\t\t// When ready\n\t\tconst ready = function(peaks) {\n\t\t\t// Get supported processes list\n\t\t\tmodel.fetchOperations().then(\n\t\t\t\tfunction() {\n\t\t\t\t\t// Show\n\t\t\t\t\tdispatcher.trigger('audioEditor:repurpose:show', {\n\t\t\t\t\t\tmodel: model,\n\t\t\t\t\t\trouteMatch: new RegExp(/^asset\\/(\\d+)\\/audioeditor/),\n\t\t\t\t\t\tisRouted: true,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tfunction(err) {\n\t\t\t\t\tdispatcher.trigger('audioEditor:repurpose:error', err);\n\t\t\t\t},\n\t\t\t);\n\t\t};\n\n\t\t// Get wavform data\n\t\tmodel.getWaveformJSON().then(ready, function(err) {\n\t\t\t// Could not get waveform data\n\t\t\tdispatcher.trigger('app:confirm', {\n\t\t\t\tmessage: i18n.t(\n\t\t\t\t\t'audioEditor:i18n.waveformUnavailableAudioCouldCrashBrowser',\n\t\t\t\t),\n\t\t\t\tonConfirmed: ready,\n\t\t\t\tonCancelled: function() {\n\t\t\t\t\tNetx.router.exitRoute(/^asset\\/(\\d+)\\/audioEditor/);\n\t\t\t\t},\n\t\t\t});\n\t\t});\n\t});\n\n\t/**\n\t * @event module:imageEditor#imageEditor:routed\n\t * @param {number|string} id Asset id\n\t * @fires module:audioEditor#audioEditor:repurpose\n\t * @fires module:audioEditor#audioEditor:repurpose:error\n\t */\n\tdispatcher.on('audioEditor:routed', function(id) {\n\t\tconst currentAsset = Netx.asset && Netx.asset.current;\n\t\tlet asset;\n\n\t\tif (id && (!currentAsset || currentAsset.id !== id)) {\n\t\t\tasset = new AssetModel({assetId: id});\n\t\t\tasset.fetch().then(\n\t\t\t\tfunction() {\n\t\t\t\t\tdispatcher.trigger('audioEditor:repurpose', asset);\n\t\t\t\t},\n\t\t\t\tfunction(err) {\n\t\t\t\t\tdispatcher.trigger('audioEditor:repurpose:error', err);\n\t\t\t\t},\n\t\t\t);\n\t\t} else if (currentAsset && currentAsset.id) {\n\t\t\tasset = currentAsset;\n\t\t\tdispatcher.trigger('audioEditor:repurpose', asset);\n\t\t} else {\n\t\t\tconsole.error(\n\t\t\t\tnew Error(\n\t\t\t\t\t'An asset id must be provided if there is not a Netx.asset.current set',\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t});\n\n\t/**\n\t * @event module:audioEditor#audioEditor:edit:confirmed\n\t * @param {object} data Repurpose data\n\t * @param {module:audioEditor/models/audioEditorAudio} model Audio model\n\t * @fires module:audioEditor#audioEditor:edit:error\n\t * @fires module:audioEditor#audioEditor:edit:success\n\t * @fires module:share#share:assetSet:repurpose:manual\n\t */\n\tdispatcher.on('audioEditor:edit:confirmed', function(data, model) {\n\t\tif (!data || _.isEmpty(data)) {\n\t\t\tdispatcher.trigger(\n\t\t\t\t'audioEditor:edit:error',\n\t\t\t\ti18n.t('i18n.thereWereNoChangesMadeToAudioFile'),\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\t// Trigger standard share workflow\n\t\tvar assetSet = model.toAssetSet();\n\t\tvar repurposeOptions = model.getManualRepurposeOptions(data);\n\t\tdispatcher.trigger(\n\t\t\t'share:assetSet:repurpose:manual',\n\t\t\tassetSet,\n\t\t\trepurposeOptions,\n\t\t\t'audio',\n\t\t);\n\t\tdispatcher.trigger('audioEditor:edit:success', model, data);\n\t});\n\n\t/**\n\t * @event module:audioEditor#audioEditor:edit:error\n\t * @param {string} error Error string\n\t * @fires module:app#app:alert\n\t */\n\tdispatcher.on(\n\t\t'audioEditor:edit:error',\n\t\tfunction(error) {\n\t\t\tdispatcher.trigger('app:alert', error, i18n.t('i18n.error'));\n\t\t},\n\t\twindow,\n\t);\n\n\t/**\n\t * @event module:audioEditor#audioEditor:edit:success\n\t * @param {Netx.Models.AudioEditorAudio} model Audio model\n\t * @param {object} data Repurpose data\n\t * @fires module:notification#notification\n\t */\n\tdispatcher.on(\n\t\t'audioEditor:edit:success',\n\t\tfunction(model, data) {\n\t\t\tdispatcher.trigger('notification', {\n\t\t\t\tmodule: 'audioEditor',\n\t\t\t\ttitle: i18n.t('i18n.assetRepurpose'),\n\t\t\t\tdescription: i18n.t('i18n.repurposeSuccessful'),\n\t\t\t\ttype: 'success',\n\t\t\t});\n\t\t},\n\t\twindow,\n\t);\n\n\t/**\n\t * @event module:audioEditor#audioEditor:operation:control:move:down\n\t * @param {module:audioEditor/collections/audioEditorOperationsStack} collection Operations stack\n\t * @param {module:audioEditor/models/audioEditorOperation} model AudioEditorOperation model\n\t */\n\tdispatcher.on('audioEditor:operation:control:move:down', function(\n\t\tcollection,\n\t\tmodel,\n\t) {\n\t\tcollection.updateIndex(model, 1);\n\t});\n\n\t/**\n\t * @event module:audioEditor#audioEditor:operation:control:move:up\n\t * @param {module:audioEditor/collections/audioEditorOperationsStack} collection Operations stack\n\t * @param {module:audioEditor/models/audioEditorOperation} model AudioEditorOperation model\n\t */\n\tdispatcher.on('audioEditor:operation:control:move:up', function(\n\t\tcollection,\n\t\tmodel,\n\t) {\n\t\tcollection.updateIndex(model, -1);\n\t});\n\n\t/**\n\t * @event module:audioEditor#audioEditor:operation:controls:reset\n\t * @param {module:audioEditor/collections/audioEditorOperationsStack} collection Operations stack\n\t */\n\tdispatcher.on('audioEditor:operation:controls:reset', function(collection) {\n\t\tcollection.reset();\n\t});\n\n\t/**\n\t * @event module:audioEditor#audioEditor:operation:set:value\n\t * @param {module:audioEditor/collections/audioEditorOperationsStack} collection Operations stack\n\t * @param {string} name Operation name\n\t * @param {array|number|object|string} value Operation value\n\t * @param {object} opts Options\n\t */\n\tdispatcher.on('audioEditor:operation:set:value', function(\n\t\tcollection,\n\t\tname,\n\t\tvalue,\n\t\topts,\n\t) {\n\t\t// Get operation model\n\t\tconst model = collection.get(name);\n\t\tmodel &&\n\t\t\tmodel.set(\n\t\t\t\t{\n\t\t\t\t\tvalue: value,\n\t\t\t\t},\n\t\t\t\topts,\n\t\t\t);\n\t});\n\n\t/**\n\t * @event module:audioEditor#audioEditor:operations:add:control\n\t * @param {name} name Operation name\n\t * @param {module:audioEditor/collections/audioEditorOperationsStack} collection Operations stack\n\t * @param {mixed} value Value\n\t * @param {object} opts Options\n\t * @fires module:app#app:confirm\n\t * @fires module:audioEditor#audioEditor:operations:add:control:confirmed\n\t */\n\tdispatcher.on('audioEditor:operations:add:control', function(\n\t\tcollection,\n\t\tname,\n\t\tvalue,\n\t\topts,\n\t) {\n\t\t// Already in collection\n\t\tif (collection.get(name)) return;\n\n\t\t// New operation control\n\t\tconst control = collection.newOperation(name, value);\n\n\t\t// Bad control\n\t\tif (!control) return;\n\n\t\t// Check if this control exludes any others\n\t\tif (control.excludes != null) {\n\t\t\t// See if this affects any other set operations\n\t\t\tconst affected = collection.filter(function(m) {\n\t\t\t\treturn _.contains(control.excludes, m.get('name'));\n\t\t\t});\n\t\t\tif (affected.length) {\n\t\t\t\treturn dispatcher.trigger('app:confirm', {\n\t\t\t\t\teventStr: 'audioEditor:operations:add:control',\n\t\t\t\t\targs: [collection, control, opts, affected],\n\t\t\t\t\tmessage: i18n.t(\n\t\t\t\t\t\t'audioEditor:i18n.theFollowingControlsWillBeRemoved',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdefaultValue:\n\t\t\t\t\t\t\t\t'The following controls will be removed: __things__',\n\t\t\t\t\t\t\tthings: _.map(affected, function(m) {\n\t\t\t\t\t\t\t\treturn m.get('name');\n\t\t\t\t\t\t\t}).toString(),\n\t\t\t\t\t\t},\n\t\t\t\t\t),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tdispatcher.trigger(\n\t\t\t'audioEditor:operations:add:control:confirmed',\n\t\t\tcollection,\n\t\t\tcontrol,\n\t\t\topts,\n\t\t);\n\t});\n\n\t/**\n\t * @event module:audioEditor#audioEditor:operations:add:control:confirmed\n\t * @param {module:audioEditor/collections/audioEditorOperationsStack} collection Operations stack\n\t * @param {object} control Operation control object ( will be converted to Netx.Models.AudioEditorOperation )\n\t * @param {object} opts Options\n\t * @param {array} toRemove Models to remove\n\t */\n\tdispatcher.on('audioEditor:operations:add:control:confirmed', function(\n\t\tcollection,\n\t\tcontrol,\n\t\topts,\n\t\ttoRemove,\n\t) {\n\t\ttoRemove &&\n\t\t\t_.each(toRemove, function(op) {\n\t\t\t\tcollection.remove(op);\n\t\t\t});\n\n\t\t// Add to collection\n\t\tcollection.add(_.extend(control, {order: collection.length}), opts);\n\t});\n\n\t/**\n\t * @event module:audioEditor#audioEditor:operations:remove:control\n\t * @param {module:audioEditor/collections/audioEditorOperationsStack} collection Operations stack\n\t * @param {module:audioEditor/models/audioEditorOperation} model AudioEditorOperation model\n\t * @param {object} opts Options\n\t */\n\tdispatcher.on('audioEditor:operations:remove:control', function(\n\t\tcollection,\n\t\tmodel,\n\t\topts,\n\t) {\n\t\t// Remove operation from collection\n\t\tcollection.remove(model, opts);\n\t});\n\n\t/**\n\t * @event module:audioEditor#audioEditor:operations:update\n\t * @param {module:audioEditor/collections/audioEditorOperationsStack} collection Operations stack\n\t * @param {object} changes Changes\n\t */\n\tdispatcher.on('audioEditor:operations:update', function(collection, changes) {\n\t\t// Loop over changes and fires off the appropriate events\n\t\t_.each(changes, function(change, k) {\n\t\t\t// Removed\n\t\t\tif (!change || change.removed) {\n\t\t\t\tdispatcher.trigger(\n\t\t\t\t\t'audioEditor:operations:remove:control',\n\t\t\t\t\tcollection,\n\t\t\t\t\tcollection.get(k),\n\t\t\t\t\t{silent: true},\n\t\t\t\t);\n\t\t\t}\n\t\t\t// Added\n\t\t\telse if (change.added && !collection.get(k)) {\n\t\t\t\tdispatcher.trigger(\n\t\t\t\t\t'audioEditor:operations:add:control',\n\t\t\t\t\tcollection,\n\t\t\t\t\tk,\n\t\t\t\t\tnull,\n\t\t\t\t\t{silent: true},\n\t\t\t\t);\n\t\t\t}\n\t\t\t// Edited\n\t\t\telse {\n\t\t\t\tdispatcher.trigger(\n\t\t\t\t\t'audioEditor:operation:set:value',\n\t\t\t\t\tcollection,\n\t\t\t\t\tk,\n\t\t\t\t\tchange.value,\n\t\t\t\t\t{silent: true},\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\t});\n\n\t// END DISPATCHER EVENT LISTENERS\n\n\t// LAST STEPS:\n\n\t// Load audioEditor library before triggering initialized\n\t// non-core extensions may listen on this event to hook into the init process:\n\tdispatcher.trigger('audioEditor:extend', NS);\n\t// Tell the module loader we're initialized.\n\tdispatcher.trigger('audioEditor:initialized', NS);\n});\n\nexport default {\n\tinitialize: function(opts) {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tdispatcher.once('audioEditor:initialized', function() {\n\t\t\t\tresolve(routes);\n\t\t\t});\n\t\t\tdispatcher.trigger('audioEditor:init');\n\t\t});\n\t},\n};\n","/**\n * AudioEditor module\n */\n\nimport actions from './actions';\nimport menus from './menus';\nimport controller from './controller';\n\n/**\n * @property {object} exports - Our module exports\n * @property {string} exports.namespace - Module namespace\n * @property {function} exports.initialize - Module initializer\n */\nexport default {\n\tnamespace: 'audioEditor',\n\tinitialize() {\n\t\t// Register actions\n\t\tNetx.Actions.Register(actions);\n\t\t// Extend menus\n\t\tNetx.addMenus(menus);\n\n\t\treturn controller.initialize();\n\t},\n};\n","const NAME = 'materialList';\n\nimport {MDCList} from '@material/list';\nimport {MDCRipple} from '@material/ripple';\nimport {purgeEls} from '@netx/core/lib/utils';\n\nimport {\n\tarrowNavigationPatch,\n\tdisabledListItemCheckboxPatch,\n} from './patches/mdc-list';\n\n// This must happen on the prototype level due to the order of events\ndisabledListItemCheckboxPatch(MDCList);\n\nconst checkActive = (list) => {\n\tif (!list) return;\n\n\tconst hash = window.location.hash.replace('#');\n\tconst hashSplit = hash.split('/');\n\n\tconst idx = list.listElements.findIndex((el, i, all) => {\n\t\tlet href = el.getAttribute('href');\n\t\tif (!href) return el.classList.contains('active');\n\n\t\thref = href.replace('#');\n\n\t\t// If our item is a multipart href match the whole hash\n\t\tconst hrefSplit = href.split('/');\n\t\tif (hrefSplit.length) {\n\t\t\treturn href === hash;\n\t\t}\n\t\t// Otherwise match the first piece of the current hash\n\t\treturn hrefSplit[0] === hashSplit[0];\n\t});\n\n\tif (idx > -1) {\n\t\tlist.foundation_.setSelectedIndex(idx);\n\t}\n\treturn idx;\n};\n\nclass List {\n\t/**\n\t * @method\n\t * @param {HTMLElement} el The element we are applying the list to\n\t * @param {modules/@netx/core/lib/netx-view} view Intance of Netx view\n\t * @param {object} opts Plugin options\n\t */\n\tconstructor(el, view, opts = {}) {\n\t\tthis.el = el;\n\t\tthis.view = view;\n\n\t\tconst list = (this.list = new MDCList(el));\n\t\tarrowNavigationPatch(list);\n\n\t\tconst materialRipples = (this.materialRipples = list.listElements.map(\n\t\t\t(listItemEl) => new MDCRipple(listItemEl),\n\t\t));\n\n\t\t// list.singleSelection = true;\n\t\tlist.foundation_.setSingleSelection(true);\n\t\tlist.wrapFocus = true;\n\n\t\tel.addEventListener('click', (this.onClick = this.clicked.bind(this)));\n\t\tel.addEventListener(\n\t\t\t'MDCList:action',\n\t\t\t(this.onAction = this.itemSelected.bind(this)),\n\t\t);\n\n\t\tif (view.materialListItemSelected) {\n\t\t\tconst listElements = list.listElements;\n\t\t\tfor (let i = 0, c = listElements.length; i < c; i++) {\n\t\t\t\tif (view.materialListItemSelected(listElements[i])) {\n\t\t\t\t\tlist.foundation_.setSelectedIndex(i);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthis.checkActive();\n\t\t}\n\t}\n\n\t/** @method */\n\tcheckActive() {\n\t\tcheckActive(this.list);\n\t}\n\n\t/** @method */\n\tcleanUp() {\n\t\tconst list = this.list;\n\t\tif (!list) return;\n\n\t\t_.invoke(this.materialRipples, 'destroy');\n\t\tthis.materialRipples = [];\n\n\t\tlist.destroy();\n\t\tdelete this.list;\n\t}\n\n\t/**\n\t * @method\n\t * @param {event} e `click` event\n\t */\n\tclicked(e) {\n\t\t// When we click on an action our event listeners in core fire\n\t\t// but mdc list items (which live in mdc menus) can be triggered\n\t\t// by `space`, `enter` and `click`\n\t\t// So, when a click occurs we do not want to fire the action off in\n\t\t// here as to not have it fire twice\n\t\t// When we rework our actions we should keep this in mind\n\t\tif (e.target.classList.contains('nx-action')) {\n\t\t\tthis._ignoreItemSelection = true;\n\t\t\tsetTimeout(() => {\n\t\t\t\tthis._ignoreItemSelection = false;\n\t\t\t}, 20);\n\t\t}\n\t}\n\n\t/** @method */\n\tdestroy() {\n\t\tthis.cleanUp();\n\n\t\tconst el = this.el;\n\t\tel.removeEventListener('click', this.onClick);\n\t\tel.removeEventListener('MDCList:action', this.onAction);\n\n\t\tdelete this.el;\n\t\tdelete this.view;\n\t}\n\n\t/**\n\t * @method\n\t * @param {event} e `MDCList:action` event\n\t */\n\titemSelected(e) {\n\t\t// Defer because our `click` event comes immediately after `MDCList:action`\n\t\t// we want to know if it was via a `click` or other (`space`, `enter`)\n\t\t_.defer(() => {\n\t\t\tif (!this._ignoreItemSelection) {\n\t\t\t\tconst item = this.list.listElements[e.detail.index];\n\t\t\t\tif (!item || !item.classList.contains('nx-action')) {\n\t\t\t\t\tif (this.view.onListItemSelect) {\n\t\t\t\t\t\tthis.view.onListItemSelect(item, this.list);\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Pass along to our action event handler\n\t\t\t\tconst evt = new MouseEvent('click', {\n\t\t\t\t\tbubbles: false,\n\t\t\t\t\tcancelable: true,\n\t\t\t\t\tview: window,\n\t\t\t\t});\n\t\t\t\titem.dispatchEvent(evt);\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Select all\n\t * Only applies to lists with checkboxes\n\t * @method\n\t */\n\tselectAll() {\n\t\tconst list = this.list;\n\t\tif (!list) return;\n\n\t\tconst adapter = list.foundation_.adapter_;\n\t\tlist.listElements.forEach((listElement, idx) => {\n\t\t\tif (!adapter.hasCheckboxAtIndex(idx)) return;\n\t\t\tadapter.setCheckedCheckboxOrRadioAtIndex(idx, true);\n\t\t});\n\t}\n}\n\nexport default function (target) {\n\tif (!target || target.hasFunctionality(NAME)) return target;\n\n\ttarget.addInitializer((instance, opts = {}) => {\n\t\topts = opts.materialList || {};\n\n\t\tlet materialLists = [];\n\n\t\tconst cleanUp = () => {\n\t\t\t_.invoke(materialLists, 'destroy');\n\t\t\tmaterialLists = [];\n\t\t};\n\n\t\tconst reset = _.debounce(() => {\n\t\t\tcleanUp();\n\t\t\tsetup();\n\t\t}, 25);\n\n\t\tconst setup = () => {\n\t\t\tconst el = instance.el;\n\t\t\tconst classList = el.classList;\n\t\t\tconst els =\n\t\t\t\tclassList.contains('mdc-list') || classList.contains('mdc-list-group')\n\t\t\t\t\t? [el]\n\t\t\t\t\t: purgeEls(\n\t\t\t\t\t\t\t[...el.querySelectorAll('.mdc-list-group, .mdc-list')],\n\t\t\t\t\t\t\tinstance.getExcludedViews(),\n\t\t\t\t\t );\n\n\t\t\tels.forEach((el) => {\n\t\t\t\tif (\n\t\t\t\t\t!el ||\n\t\t\t\t\t(!el.classList.contains('mdc-list-group') &&\n\t\t\t\t\t\tel.closest('.mdc-list-group'))\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst list = new List(el, instance, opts);\n\t\t\t\tmaterialLists.push(list);\n\t\t\t});\n\t\t};\n\n\t\tinstance.getFocusedListItem = () => {\n\t\t\tlet focusedItem;\n\t\t\tmaterialLists.forEach((list) => {\n\t\t\t\tif (focusedItem) return;\n\t\t\t\tfocusedItem =\n\t\t\t\t\tlist.list.listElements[list.list.foundation_.focusedItemIndex_];\n\t\t\t});\n\t\t\treturn focusedItem;\n\t\t};\n\n\t\tinstance.getActiveList = () => {\n\t\t\tconst focusedList = materialLists.find((list) => {\n\t\t\t\treturn list.list.foundation_.focusedItemIndex_ > -1;\n\t\t\t});\n\t\t\tif (focusedList) {\n\t\t\t\treturn focusedList.list;\n\t\t\t}\n\t\t};\n\n\t\t// Hey, listen!\n\t\tinstance\n\t\t\t.listenTo(dispatcher, 'hash:changed', () => {\n\t\t\t\t_.invoke(materialLists, 'checkActive');\n\t\t\t})\n\t\t\t.on('materialList:checkActive', () => {\n\t\t\t\t_.invoke(materialLists, 'checkActive');\n\t\t\t})\n\t\t\t.on('materialList:selectAll', () => {\n\t\t\t\t_.invoke(materialLists, 'selectAll');\n\t\t\t})\n\t\t\t.on('preRenderHook', () => {\n\t\t\t\tif (opts.childViews) {\n\t\t\t\t\tinstance.stopListening('addedNewChildView', reset);\n\t\t\t\t}\n\t\t\t\tcleanUp();\n\t\t\t})\n\t\t\t.on('removeHook', cleanUp)\n\t\t\t.on('renderedHook', () => {\n\t\t\t\tsetup();\n\t\t\t\tif (opts.childViews) {\n\t\t\t\t\tinstance.on('addedNewChildView', (childView) => {\n\t\t\t\t\t\tchildView.rendered.then(reset);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t}, NAME);\n\n\treturn target;\n}\n","/**\n * @class\n */\nimport Base from './assetConstituent';\n\nimport ProgressModel from '@netx/core-app/models/progress';\n\nimport {pad} from '@netx/core/lib/underscore-netx';\n\nexport default class AssetConstituent_Clip extends Base {\n\t/**\n\t * @property {object} defaults - The default attribute values\n\t * @property {string} defaults.endTime - Clip end time string\n\t * @property {string} defaults.startTime - Clip start time string\n\t * @property {string} defaults.title - Default title\n\t * @property {number} defaults.type - Default type (4 = clip)\n\t *\n\t * @property {boolean} defaults.keyframeReady - Default keyframe ready state (client)\n\t * @property {string} defaults.uuid - Default uuid for tracking creation/update progress\n\t */\n\tget defaults() {\n\t\treturn _.extend(super.defaults, {\n\t\t\tendTime: 0,\n\t\t\tstartTime: 0,\n\t\t\ttitle: '',\n\t\t\ttype: 4,\n\t\t\t// Client attrs\n\t\t\tkeyframeReady: true,\n\t\t\tuuid: '',\n\t\t});\n\t}\n\n\t/** @type {array} */\n\tget clientAttrs() {\n\t\treturn super.clientAttrs.concat(['keyframeReady', 'uuid']);\n\t}\n\n\t/**\n\t * Right now, the only constituents that can be created by the client are clips\n\t * @property {object} methods - Model RPC methods\n\t * @property {function|array} methods.create - Create clip\n\t * @property {function|array} methods.remove - Delete clip\n\t * @property {function|array} methods.updated - Update clip\n\t */\n\tget methods() {\n\t\treturn _.extend(super.methods, {\n\t\t\t/**\n\t\t\t * @method\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tcreate(opts) {\n\t\t\t\treturn ['setClip', this.self()];\n\t\t\t},\n\t\t\t/**\n\t\t\t * @method\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tremove(opts) {\n\t\t\t\treturn ['deleteClip', this.id];\n\t\t\t},\n\t\t\t/**\n\t\t\t * @method\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tupdate(opts) {\n\t\t\t\treturn ['setClip', this.self()];\n\t\t\t},\n\t\t\t_prepareDownload: [\n\t\t\t\t'prepareDownload',\n\t\t\t\t'downloadOptions.assets',\n\t\t\t\t'downloadOptions.processes',\n\t\t\t\t'downloadOptions.arg1',\n\t\t\t\t'downloadOptions.arg2',\n\t\t\t],\n\t\t});\n\t}\n\n\t/**\n\t * @property {object} parsers - Model parsers\n\t * @property {function} parsers.create - Parse the return of create clip\n\t * @property {function} parsers.create - Parse the return of update clip\n\t */\n\tget parsers() {\n\t\treturn _.extend(super.parsers, {\n\t\t\t/**\n\t\t\t * @function\n\t\t\t * @param {object} data Clip data (constituent and keyframe uuid)\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tcreate(data, opts) {\n\t\t\t\treturn _.extend(data.constituent, {\n\t\t\t\t\tkeyframeReady: false,\n\t\t\t\t\tuuid: data.progressUuid,\n\t\t\t\t});\n\t\t\t},\n\t\t\t/**\n\t\t\t * @function\n\t\t\t * @param {object} data Clip data (constituent and [possibly] keyframe uuid)\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tupdate(data) {\n\t\t\t\tlet _data = {};\n\t\t\t\tif (data.progressUuid) {\n\t\t\t\t\t_data = {\n\t\t\t\t\t\tkeyframeReady: false,\n\t\t\t\t\t\tuuid: data.progressUuid,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\treturn _.extend(data.constituent, _data);\n\t\t\t},\n\t\t});\n\t}\n\n\t/**\n\t * @override\n\t * @param {object} attr Model attributes\n\t * @param {object} opts Model options\n\t * @fires module:app#app:pollBatchJob\n\t */\n\tconstructor(attrs, opts = {}) {\n\t\tsuper(attrs, opts);\n\n\t\t/**\n\t\t * @memberOf module:asset/models/assetConstituent_clip\n\t\t * @alias downloadOptions\n\t\t * @type {object}\n\t\t */\n\t\tthis.downloadOptions = opts.downloadOptions || {};\n\n\t\t/**\n\t\t * @memberof module:asset/models/assetConstituent_clip\n\t\t * @alias progress\n\t\t * @type {module:app/models/progress}\n\t\t */\n\t\tthis.progress = new ProgressModel();\n\n\t\t// Hey, listen!\n\t\t// When a clip is beign created/updated on the server - track the progress\n\t\tthis.listenTo(this, 'change:uuid', () => {\n\t\t\tthis.trackBatchJob(this.get('uuid'));\n\t\t})\n\t\t\t.listenTo(this, 'progress', (model, batchJob, progress) => {\n\t\t\t\tconst progressMessage = (batchJob && batchJob.get('details')) || '';\n\t\t\t\tthis.progress.update(progress, progressMessage);\n\t\t\t})\n\t\t\t.listenTo(this, 'complete', (model, batchJob) => {\n\t\t\t\tthis.fetch().then(() => {\n\t\t\t\t\tthis.set({\n\t\t\t\t\t\tkeyframeReady: true,\n\t\t\t\t\t});\n\t\t\t\t\tthis.progress.complete();\n\t\t\t\t});\n\t\t\t});\n\t}\n\n\t/**\n\t * return a cache-busting string for the asset preview; this string should change every time the asset preview changes.\n\t * @method\n\t * @return string\n\t */\n\tcacheBuster(prefix) {\n\t\t// If this model doesn't have moddate set, use the current time.\n\t\tconst timeStr = this.get('moddate')\n\t\t\t? _.dateFromAsset(this.get('moddate')).getTime()\n\t\t\t: _.now();\n\n\t\treturn '?' + (prefix ? prefix + '&' : '') + 't=' + timeStr;\n\t}\n\t/**\n\t * @method\n\t * @return {object} Duration\n\t */\n\tgetDuration() {\n\t\tconst start = parseFloat(this.get('startTime'));\n\t\tconst end = parseFloat(this.get('endTime'));\n\t\tconst floor = Math.floor;\n\t\tconst duration = end - start;\n\n\t\tlet hour, minute, second, millisecond, time;\n\n\t\ttime = duration;\n\t\thour = floor(time / 3600);\n\t\ttime -= hour * 3600;\n\t\tminute = floor(time / 60);\n\t\ttime -= floor(minute * 60);\n\t\tsecond = floor(time);\n\t\tmillisecond = Math.round((time - second) * 1000);\n\n\t\treturn {\n\t\t\tseconds: duration,\n\t\t\tpretty: [\n\t\t\t\tpad(hour, 2),\n\t\t\t\t':',\n\t\t\t\tpad(minute, 2),\n\t\t\t\t':',\n\t\t\t\tpad(second, 2),\n\t\t\t\t'.',\n\t\t\t\tpad(millisecond, 3),\n\t\t\t].join(''),\n\t\t};\n\t}\n\t/**\n\t * Get the manual repurpose options for clip downloading\n\t * @method\n\t * @param {module:asset/models/assetProcess} process (Video) preset process data\n\t * @returns {array} Manual repurpose options\n\t */\n\tgetManualRepurposeOptions(process) {\n\t\treturn [\n\t\t\t{\n\t\t\t\tlabel: 'trim',\n\t\t\t\tvalue: [this.get('startTime'), this.get('endTime')].join('-'),\n\t\t\t},\n\t\t\t{label: 'codec', value: process.get('videoCodec')},\n\t\t\t{label: 'videoBitrate', value: process.get('videoBitrate')},\n\t\t\t{label: 'audioBitrate', value: process.get('audioBitrate')},\n\t\t\t{label: 'audioChannels', value: process.get('audioChannels')},\n\t\t\t{\n\t\t\t\tlabel: 'resize',\n\t\t\t\tvalue: [process.get('width'), process.get('height')].join(),\n\t\t\t},\n\t\t\t{label: 'format', value: process.get('format')},\n\t\t];\n\t}\n\t/**\n\t * @method\n\t * @return {object} Pretty range\n\t */\n\tgetPrettyRange() {\n\t\tconst floor = Math.floor;\n\t\tconst round = Math.round;\n\t\tconst prettyRange = {};\n\n\t\t// Loops over start, end, duration\n\t\t_.each(['startTime', 'endTime'], (r) => {\n\t\t\tlet hour, minute, second, millisecond, time;\n\n\t\t\ttime = parseFloat(this.get(r)) || 0;\n\t\t\thour = floor(time / 3600);\n\t\t\ttime -= hour * 3600;\n\t\t\tminute = floor(time / 60);\n\t\t\ttime -= floor(minute * 60);\n\t\t\tsecond = floor(time);\n\t\t\tmillisecond = round((time - second) * 1000);\n\n\t\t\tprettyRange[r] = [\n\t\t\t\tpad(hour, 2),\n\t\t\t\t':',\n\t\t\t\tpad(minute, 2),\n\t\t\t\t':',\n\t\t\t\tpad(second, 2),\n\t\t\t\t'.',\n\t\t\t\tpad(millisecond, 3),\n\t\t\t].join('');\n\t\t});\n\n\t\treturn prettyRange;\n\t}\n\n\t/** @type {string} */\n\tstatic get __name__() {\n\t\treturn 'AssetConstituent_Clip';\n\t}\n}\n","/**\n * DownloadOption collection\n * @class\n */\nimport Base from '@netx/core/lib/netx-collection';\nimport Model from '../models/downloadOption';\n\nimport {types as downloadOptionTypes} from '../properties/downloadOptions';\n\nexport default class DownloadOptions extends Base {\n\t/** @override */\n\tconstructor(models, opts = {}) {\n\t\topts.model = opts.model || Model;\n\t\tsuper(models, opts);\n\t}\n\n\t/**\n\t * @method\n\t * @param {string} type Download options type\n\t */\n\tfilterTypes(type) {\n\t\tif (type != null) {\n\t\t\t// filter us by the given type.\n\t\t\treturn this.where({type: type});\n\t\t}\n\n\t\t// If no argument, return an object with all our models split out by type.\n\t\tconst filtered = {\n\t\t\toriginalOption: this.where({type: downloadOptionTypes.original}) || [],\n\t\t\tproxyOptions: this.where({type: downloadOptionTypes.proxy}) || [],\n\t\t\tviewOptions: this.where({type: downloadOptionTypes.assetView}) || [],\n\t\t\tprocessOptions:\n\t\t\t\tthis.where({type: downloadOptionTypes.presetProcess}) || [],\n\t\t\tmetadataOptions: this.where({type: downloadOptionTypes.metadata}) || [],\n\t\t\tcontactSheetOptions:\n\t\t\t\tthis.where({type: downloadOptionTypes.contactSheet}) || [],\n\t\t};\n\t\t// These three are sometimes lumped together:\n\t\tfiltered.vppOptions = filtered.viewOptions\n\t\t\t.concat(filtered.proxyOptions)\n\t\t\t.concat(filtered.processOptions);\n\t\treturn filtered;\n\t}\n\n\t/**\n\t * @method\n\t * @param {string} type Download options type\n\t * @return {module:share/models/downloadOption}\n\t */\n\tgetOption(type, name) {\n\t\tconst opts = {};\n\n\t\tif (type != null) {\n\t\t\topts.type = type;\n\t\t}\n\n\t\tif (name != null) {\n\t\t\topts.name = name;\n\t\t}\n\n\t\treturn this.findWhere(opts);\n\t}\n\n\t/**\n\t * @method\n\t * @return {boolean} Has manual repurpose options\n\t */\n\thasManualRepurposeOptions() {\n\t\tconst manualRepurpose = this.getOption('manualRepurpose');\n\t\treturn manualRepurpose && manualRepurpose.get('options').length > 0;\n\t}\n\n\t/**\n\t * @method\n\t * @param {string} type Download options type\n\t * @return {boolean} Has option\n\t */\n\thasOption(type, name) {\n\t\treturn this.getOption(type, name) != null;\n\t}\n\n\t/**\n\t * Takes the selected download options and filters this collection to only contain selected download options\n\t * @method\n\t * @param {object} selectedDownloadOptions Form object containing user selected download options\n\t */\n\tparseSelectedDownloadOptions(selectedDownloadOptions) {\n\t\t// reduce the option set to just the selected items\n\t\t// continue to next step in workflow: check justification\n\n\t\t// DAM-12078 - set organizeContentsBy on all options but pdf and metadata\n\n\t\tconst selectedDownloadOptionModels = [];\n\n\t\tlet requiresJustification = false;\n\t\tlet requiresApproval = false;\n\n\t\tif (selectedDownloadOptions.original) {\n\t\t\tconst originalOption = this.getOption('original');\n\t\t\tif (originalOption) {\n\t\t\t\toriginalOption.set({\n\t\t\t\t\torganizeContentsBy: selectedDownloadOptions.organizeContentsBy,\n\t\t\t\t});\n\t\t\t\t// Set the embed metadata options\n\t\t\t\tif (selectedDownloadOptions.embedMetadata) {\n\t\t\t\t\toriginalOption.addOptions({\n\t\t\t\t\t\tmetadataMapping: selectedDownloadOptions.embedMetadata,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tselectedDownloadOptionModels.push(originalOption);\n\t\t\t}\n\t\t}\n\n\t\t// Support embeded metadata for manual repurposes\n\t\tconst manualRepurposeOption = this.getOption('manualRepurpose');\n\t\tif (manualRepurposeOption && selectedDownloadOptions.embedMetadata) {\n\t\t\tmanualRepurposeOption.addOptions({\n\t\t\t\tmetadataMapping: selectedDownloadOptions.embedMetadata,\n\t\t\t});\n\t\t}\n\n\t\t// Manual repurpose\n\t\t// If it has options, we use it.\n\t\tconst manualRepurpose = this.getOption('manualRepurpose');\n\t\tconst manualRepurposeOpts =\n\t\t\t(manualRepurpose && manualRepurpose.get('options')) || [];\n\t\tif (manualRepurposeOpts.length) {\n\t\t\tmanualRepurpose.set({\n\t\t\t\torganizeContentsBy: selectedDownloadOptions.organizeContentsBy,\n\t\t\t});\n\t\t\tselectedDownloadOptionModels.push(manualRepurpose);\n\t\t}\n\n\t\t// Loop over sleected proxies\n\t\tlet proxyDownloadOption;\n\t\t_.each(selectedDownloadOptions.proxies, (proxyName) => {\n\t\t\tproxyDownloadOption = this.getOption('proxy', proxyName);\n\t\t\tif (proxyDownloadOption) {\n\t\t\t\tproxyDownloadOption.set({\n\t\t\t\t\torganizeContentsBy: selectedDownloadOptions.organizeContentsBy,\n\t\t\t\t});\n\t\t\t\tselectedDownloadOptionModels.push(proxyDownloadOption);\n\t\t\t}\n\t\t});\n\n\t\t// Loop over selected views\n\t\tlet viewDownloadOption;\n\t\t_.each(selectedDownloadOptions.views, (viewName) => {\n\t\t\tviewDownloadOption = this.getOption('assetView', viewName);\n\t\t\tif (viewDownloadOption) {\n\t\t\t\tviewDownloadOption.set({\n\t\t\t\t\torganizeContentsBy: selectedDownloadOptions.organizeContentsBy,\n\t\t\t\t});\n\t\t\t\tselectedDownloadOptionModels.push(\n\t\t\t\t\tthis.getOption('assetView', viewName),\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\n\t\t// Loop over selected preset processes\n\t\t_.each(selectedDownloadOptions.processes, (processId) => {\n\t\t\t// If it is a true preset process (user defined) it has a numeric id\n\t\t\t// otherwise it is one of those 'fancy' preset processes that come from an XML file and use a unique name rather than a numeric id\n\t\t\tconst presetProcess = !_.isNumeric(processId)\n\t\t\t\t? // Assume name\n\t\t\t\t this.getOption('presetProcess', processId)\n\t\t\t\t: // Assume id\n\t\t\t\t this.findWhere({type: 'presetProcess', id: parseInt(processId)});\n\n\t\t\tif (!presetProcess) return;\n\n\t\t\tpresetProcess.set({\n\t\t\t\torganizeContentsBy: selectedDownloadOptions.organizeContentsBy,\n\t\t\t});\n\n\t\t\t// Set the embed metadata options\n\t\t\tif (selectedDownloadOptions.embedMetadata) {\n\t\t\t\tpresetProcess.addOptions({\n\t\t\t\t\tmetadataMapping: selectedDownloadOptions.embedMetadata,\n\t\t\t\t});\n\t\t\t}\n\t\t\tselectedDownloadOptionModels.push(presetProcess);\n\t\t});\n\n\t\t// PDF (contact sheet)\n\t\tif (selectedDownloadOptions.contactSheet.selected) {\n\t\t\tlet sheetOption = this.getOption('contactSheet');\n\t\t\tif (sheetOption) {\n\t\t\t\tsheetOption.set(\n\t\t\t\t\t_.pick(selectedDownloadOptions.contactSheet, 'name', 'attributeIds'),\n\t\t\t\t);\n\t\t\t\t// Get rid of our client attributes - do not want to risk borking the prepareDownload call\n\t\t\t\t_.each(sheetOption.clientAttrs, (attr) => {\n\t\t\t\t\tsheetOption.unset(attr);\n\t\t\t\t});\n\t\t\t\t// I am guessing the server does not want a null title - so at least respect the other options\n\t\t\t\tconst toPick = [\n\t\t\t\t\t'displayLabels',\n\t\t\t\t\t'highRes',\n\t\t\t\t\t'pdfExportPreset',\n\t\t\t\t\t'templateName',\n\t\t\t\t];\n\t\t\t\tif (selectedDownloadOptions.contactSheet.title) {\n\t\t\t\t\ttoPick.push('title');\n\t\t\t\t}\n\t\t\t\tsheetOption.addOptions(\n\t\t\t\t\t_.pick.apply(\n\t\t\t\t\t\t_,\n\t\t\t\t\t\t[selectedDownloadOptions.contactSheet].concat(toPick),\n\t\t\t\t\t),\n\t\t\t\t);\n\n\t\t\t\t// DAM-8650: ship our default asset sort prefs to the PDF creator.\n\t\t\t\t// (Maybe someday this will be part of the PDF form, and we'll do this differently.)\n\t\t\t\tsheetOption.addOptions({\n\t\t\t\t\tassetListSortField: Netx.getPreference('asset.list.sort.field'),\n\t\t\t\t\tassetListSortOrder: Netx.getPreference('asset.list.sort.order'),\n\t\t\t\t});\n\n\t\t\t\tselectedDownloadOptionModels.push(sheetOption);\n\t\t\t}\n\t\t}\n\n\t\t// Attribute data\n\t\tif (selectedDownloadOptions.metadata.selected) {\n\t\t\t// Get a clone of our attribute download option model (not entirely sure why we clone since these things get wiped out on each download prompt)\n\t\t\t// I suppose the clone could be a safeguard for when the prepareDownload call fails, that way we haven't modified the model that the downloadOptionsView\n\t\t\t// is using (since it will still be open on an error)\n\t\t\tlet metadataOption = this.getOption('metadata');\n\t\t\tif (metadataOption) {\n\t\t\t\tmetadataOption = metadataOption.clone();\n\t\t\t\tconst setId = selectedDownloadOptions.metadata.setId;\n\t\t\t\t// If metadata manager is not enabled then we have no attributeSets, only custom\n\t\t\t\t// if (setId == 'custom' || setId == '') {\n\t\t\t\t// \t// User specified a custom set. We received the IDs from the selectedDownloadOptions.\n\t\t\t\t// \tmetadataOption.set(\n\t\t\t\t// \t\t_.pick(selectedDownloadOptions.metadata, 'attributeIds'),\n\t\t\t\t// \t);\n\t\t\t\t// } else {\n\t\t\t\t// \t// User specified an existing set. Get those IDs.\n\t\t\t\t// \tmetadataOption.set(\n\t\t\t\t// \t\t'attributeIds',\n\t\t\t\t// \t\tNetx.asset.attributeSets.get(setId).get('attributeIds'),\n\t\t\t\t// \t);\n\t\t\t\t// }\n\t\t\t\tmetadataOption.set(\n\t\t\t\t\t_.pick(selectedDownloadOptions.metadata, 'attributeIds'),\n\t\t\t\t);\n\t\t\t\tselectedDownloadOptionModels.push(metadataOption);\n\t\t\t}\n\t\t}\n\n\t\t// Historical attribute data\n\t\tif (selectedDownloadOptions.historical) {\n\t\t\tconst historicalOption = this.getOption('historical');\n\t\t\tif (historicalOption) {\n\t\t\t\tselectedDownloadOptionModels.push(historicalOption);\n\t\t\t}\n\t\t}\n\n\t\t// Set this collection with the selected download options\n\t\tthis.reset(selectedDownloadOptionModels);\n\t}\n\n\t/**\n\t * Takes the download options that have already been selected and set the selected attribute as true.\n\t * This is used so the correct download options are selected when editing a token\n\t * @method\n\t * @param {Netx.Collection.DownloadOptions} selectedDownloadOptions The collection of downloadOptions that are selected\n\t */\n\tsetUserSelectedDownloadOptions(selectedDownloadOptions) {\n\t\t// Set original download selected to false. If it's undefined the template will default to using the user pref for original which we do not want when editing\n\t\t// If it is selected, it it will be set correctly below\n\t\tconst originalOption = this.findWhere({type: 'original'});\n\t\toriginalOption && originalOption.set({selected: false});\n\n\t\t_.each(selectedDownloadOptions, (option, idx, all) => {\n\t\t\tlet opt;\n\t\t\tswitch (option.type) {\n\t\t\t\tcase 'original':\n\t\t\t\t\topt = this.findWhere({type: 'original'});\n\t\t\t\t\tif (opt) {\n\t\t\t\t\t\topt.set({selected: true});\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'proxy':\n\t\t\t\t\topt = this.findWhere({name: option.name});\n\t\t\t\t\tif (opt) {\n\t\t\t\t\t\topt.set({selected: true});\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'presetProcess':\n\t\t\t\t\topt = this.findWhere({name: option.name});\n\t\t\t\t\tif (opt) {\n\t\t\t\t\t\topt.set(option).set({selected: true});\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'contactSheet':\n\t\t\t\tcase 'historical':\n\t\t\t\tcase 'metadata':\n\t\t\t\t\topt = this.findWhere({type: option.type});\n\t\t\t\t\tif (opt) {\n\t\t\t\t\t\topt.set(option);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\t// todo: what about views?\n\t\t});\n\t}\n\n\t/** @type {string} */\n\tstatic get __name__() {\n\t\treturn 'DownloadOptions';\n\t}\n}\n","/**\n * Describes a possible option for asset downloads(original, view, proxy, repurpose)\n * @class\n * @extends Netx.Model\n */\nimport Base from '@netx/core/lib/netx-model';\n\nimport Collection from '@netx/core/lib/netx-collection';\n\nimport {types as downloadOptionTypes} from '../properties/downloadOptions';\n\nexport default class DownloadOption extends Base {\n\t/**\n\t * @type {Netx.Rpc}\n\t * @private\n\t */\n\tget rpc() {\n\t\treturn true;\n\t}\n\t/**\n\t * @type {Netx.URL}\n\t * @private\n\t */\n\tget url() {\n\t\treturn Netx.URL.api;\n\t}\n\t/** @type {string} */\n\t// not sure if this is right, but for now it has to be something other than 'id'\n\tget idAttribute() {\n\t\treturn 'some-bogus-id';\n\t}\n\t/**\n\t * @property {object} defaults - The default attribute values\n\t * @property {string} defaults.type - The default type (see share/properties/downloadOptions#types)\n\t * @property {string} defaults.name - The defualt name (\"thumb\",\"preview\", asset view name, or PDF contact sheet name [1x1, 3x3, or 9x9])\n\t * @property {number} defaults.id - The default processId / attrFieldSet (preset process Id, or metadata AttrFieldSet Id [if zero for Contact Sheet, then use defaults])\n\t * @property {array} defaults.options - The default options (an array of LabelValue objects)\n\t * @property {boolean} defaults.requiresApproval - The default requires approval (read-only from server)\n\t * @property {boolean} defaults.requiresJustification - The default requires justification (read-only from server)\n\t * @property {array} defaults.attributeIds - The default array of attribute ids (for PDF contact sheets, this is sent as the list of attributes to display)\n\t * @property {number} defaults.organizeContentsBy - default option for recursive download zip origanization\n\t */\n\tget defaults() {\n\t\treturn {\n\t\t\ttype: '',\n\t\t\tname: '',\n\t\t\tid: 0,\n\t\t\tfamily: '',\n\t\t\toptions: [],\n\t\t\trequiresApproval: false,\n\t\t\trequiresJustification: false,\n\t\t\tattributeIds: [],\n\t\t\torganizeContentsBy: 0, // default to no organization, this is not a user option currently\n\n\t\t\t// Client attributes\n\t\t\t// For PDF (contactSheet)\n\t\t\tengine: 'java',\n\t\t\texportOptions: new Collection([]),\n\t\t\ttemplates: new Collection([]),\n\t\t};\n\t}\n\n\t/** @type {array} */\n\tget clientAttrs() {\n\t\treturn ['engine', 'exportOptions', 'templates'];\n\t}\n\n\t////////////////////////////////////\n\t// RPC METHODS\n\t////////////////////////////////////\n\t/**\n\t * @property {object} methods - The methods available on this model\n\t * @property {function|array} methods.getPDFTemplateOptions - Request the template options for generating a PDF\n\t */\n\tget methods() {\n\t\treturn {\n\t\t\tgetPDFTemplateOptions: ['getPDFTemplateOptions'],\n\t\t};\n\t}\n\t////////////////////////////////////\n\t// !RPC METHODS\n\t////////////////////////////////////\n\n\tget parsers() {\n\t\treturn {\n\t\t\tgetPDFTemplateOptions: function (response) {\n\t\t\t\tresponse = response || {};\n\t\t\t\t// Set client attributes\n\t\t\t\tthis.set('engine', response.engine || 'java');\n\t\t\t\tthis.get('exportOptions').reset(response.exportOptions);\n\t\t\t\tthis.get('templates').reset(response.templates);\n\t\t\t\treturn response;\n\t\t\t},\n\t\t};\n\t}\n\n\t/**\n\t * @override\n\t * @param {object} attrs Model attributes\n\t * @param {object} opts Model options\n\t */\n\tconstructor(attrs, opts) {\n\t\tsuper(attrs, opts);\n\n\t\t// Defer so that any code which created this model can have a chance to do anything right after initialization is finished\n\t\t// and just before we shove these client attributes in\n\t\t_.defer(() => {\n\t\t\tswitch (this.get('type')) {\n\t\t\t\tcase downloadOptionTypes.contactSheet:\n\t\t\t\t\tif (!this.has('exportOptions') || !this.has('templates')) {\n\t\t\t\t\t\tthis.set({\n\t\t\t\t\t\t\texportOptions: new Collection([]),\n\t\t\t\t\t\t\ttemplates: new Collection([]),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tthis.getPDFTemplateOptions();\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t});\n\t}\n\n\t// Utility for handling that options array\n\tgetOptions() {\n\t\treturn _.lvbsToObject(this.get('options'));\n\t}\n\n\tsetOptions(obj, opts) {\n\t\treturn this.set({options: _.objectToLvbs(obj)}, opts);\n\t}\n\n\taddOptions(addObject, opts) {\n\t\treturn this.setOptions(_.extend(this.getOptions(), addObject), opts);\n\t}\n\n\t//TODO: this *Options interface is nonstandard and weird. Better to have this.options as a sub-model, and use this.self() & this.parse() to pack it/unpack it.\n\t//see the asset model's .metadata model for an example.\n\n\t/** @type {string} */\n\tstatic get __name__() {\n\t\treturn 'DownloadOption';\n\t}\n}\n","/**\n * @class\n */\nimport Base from '@netx/core/lib/netx-view';\nimport Template from '../templates/appTabItemView.html';\n\nclass AppTabItemView extends Base {\n\t/** @override */\n\tconstructor(opts = {}) {\n\t\tconst model = opts.model;\n\t\tconst tabName = model.get('name') || _.toCamelCase(model.id);\n\t\topts.attributes = {\n\t\t\t'data-nx-control': `tab-${tabName}`,\n\t\t\t...opts.attributes,\n\t\t};\n\t\topts.events = {\n\t\t\tclick: 'tabClicked',\n\t\t\t...opts.events,\n\t\t};\n\t\topts.template = opts.template || Template;\n\t\tif (model.get('hasTotal')) {\n\t\t\topts.collection = model.get('view').collection;\n\t\t}\n\t\tsuper(opts);\n\n\t\tthis.iconOnly = opts.viewSpec.get('iconOnly') || false;\n\n\t\t// Related view\n\t\tthis.model.has('view')\n\t\t\t? this.addRelatedView()\n\t\t\t: this.listenToOnce(this.model, 'change:view', this.addRelatedView);\n\n\t\t// Set our unique tab attribute\n\t\tthis.$el.addClass(`${tabName}-tab-item`);\n\t}\n\n\t/** @override */\n\tbindModelEvents() {\n\t\tsuper.bindModelEvents();\n\t\treturn this.listenTo(\n\t\t\tthis.model,\n\t\t\t'change:active',\n\t\t\tthis.toggleActive,\n\t\t).listenTo(this.model, 'change:unsavedChanges', this.toggleUnsavedChanges);\n\t}\n\n\t/** @override */\n\tpreRender() {\n\t\tsuper.preRender();\n\n\t\tconst model = this.model;\n\t\tconst relatedView = this.relatedView || {};\n\n\t\tconst action = Netx.Actions.Find(model.get('uniqueShowAction')) || {};\n\t\t// Additional template vars\n\t\tObject.assign(this.templateVars, {\n\t\t\taction: model.get('uniqueShowAction'),\n\t\t\tlabel: this.iconOnly\n\t\t\t\t? ''\n\t\t\t\t: model.get('label') || action.label || relatedView.headerTitle,\n\t\t\ticon: model.get('icon') || action.icon,\n\t\t\thasTotal: model.get('hasTotal') === true,\n\t\t});\n\t}\n\n\t/** @override */\n\tpostRender() {\n\t\tsuper.postRender();\n\n\t\t// Cache\n\t\tthis.$title = this.$('.nx-title');\n\n\t\tthis.toggleActive();\n\t}\n\n\t/**\n\t * Once our model has its view property,\n\t * remeber it at .relatedView, and use it to toggle our crumbs.\n\t * (.relatedView also used in theme override ...)\n\t * @method\n\t */\n\taddRelatedView() {\n\t\tthis.relatedView = this.model.get('view');\n\t}\n\n\t/**\n\t * We run everything through actions\n\t * But in some cases one might want to know if a tab was shown strictly via a tab click\n\t * This also presents the ability to silence the click and prevent the action from firing\n\t * should you `preventDefault`\n\t * This event cannot be caught on any view we might be nested in as the action code in netx-view\n\t * silences events and prevent propagation - so it would be too late at any higher level\n\t * @param {event} e Click event\n\t */\n\ttabClicked(e) {\n\t\tconst event = new CustomEvent('tabClick', {\n\t\t\tview: window,\n\t\t\tbubbles: true,\n\t\t\tcancelable: true,\n\t\t\tdetail: this.model,\n\t\t});\n\t\tif (!this.el.dispatchEvent(event)) {\n\t\t\t// User cancelled event - cancel original click event\n\t\t\te.preventDefault();\n\t\t}\n\t}\n\n\t/** @method */\n\ttoggleActive() {\n\t\tthis.$el.toggleClass('active', this.model.get('active') === true);\n\t\t// Update title (it could have changed context)\n\t\t//if (this.relatedView) {\n\t\tthis.$title &&\n\t\t\tthis.$title.html(\n\t\t\t\tthis.model.get('label') ||\n\t\t\t\t\t(this.relatedView && this.relatedView.headerTitle),\n\t\t\t);\n\t\t//}\n\t}\n\n\t/** @method */\n\ttoggleUnsavedChanges() {\n\t\tthis.$el.toggleClass(\n\t\t\t'unsaved-changes',\n\t\t\tthis.model.get('unsavedChanges') === true,\n\t\t);\n\t}\n\n\t/**\n\t * @method\n\t */\n\tupdateCount(count) {\n\t\tif (!this.model.get('hasTotal')) return;\n\n\t\t// Might not have rendered yet\n\t\tif (!this.$count) return;\n\n\t\tif (count == null) {\n\t\t\tconst collection = this.collection;\n\t\t\tif (\n\t\t\t\t!collection ||\n\t\t\t\t!this.$count ||\n\t\t\t\t!this.$count.length ||\n\t\t\t\t(this.requireSync && !collection.syncedOnce)\n\t\t\t)\n\t\t\t\treturn;\n\n\t\t\tcount = collection.getTotal();\n\t\t}\n\n\t\tthis.$count.attr('data-count', count);\n\t\tthis.$count.html(count);\n\t}\n\n\t/** @type {string} */\n\tstatic get __name__() {\n\t\treturn 'AppTabItemView';\n\t}\n}\n\nexport default AppTabItemView;\n","/**\n * @class\n */\nimport Base from '@netx/core-app/views/appTabItemView';\n\nexport default class AppTabItemView extends Base {\n\t/** @override */\n\tconstructor(opts = {}) {\n\t\tconst model = opts.model;\n\t\tconst active = model.get('active');\n\t\tconst index = model.collection.indexOf(model);\n\t\t// Support a vertical list over horizontal tabs\n\t\tconst useList = opts.useList === true;\n\n\t\topts.attributes = {\n\t\t\t'data-action': model.get('uniqueShowAction'),\n\t\t\t'aria-selected': active || !index,\n\t\t\t'data-nx-tab-name': model.get('name'),\n\t\t\t'data-nx-form-ignore': true,\n\t\t\trole: 'tab',\n\t\t};\n\t\tif (!useList) {\n\t\t\topts.attributes.type = 'button';\n\t\t}\n\n\t\topts.className = useList\n\t\t\t? `mdc-list-item nx-action`\n\t\t\t: `mdc-tab ${active || !index ? 'mdc-tab--active' : ''} nx-action`;\n\t\topts.tagName = useList ? 'a' : 'button';\n\n\t\tsuper(opts);\n\n\t\tthis.useList = useList === true;\n\t}\n\n\t/** @override */\n\tpreRender() {\n\t\tsuper.preRender();\n\n\t\tconst model = this.model;\n\t\tObject.assign(this.templateVars, {\n\t\t\tindex: model.collection.indexOf(model),\n\t\t\tuseList: this.useList,\n\t\t});\n\t}\n\n\t/** @method */\n\ttoggleActive() {\n\t\t// We are completely overriding the parent to deal with some inconsistencies\n\t\t// between core design and material theme\n\t\tconst model = this.model;\n\t\tthis.$title &&\n\t\t\tthis.$title.html(\n\t\t\t\tmodel.get('label') ||\n\t\t\t\t\t(this.relatedView && this.relatedView.headerTitle),\n\t\t\t);\n\n\t\tconst active = model.get('active') === true;\n\t\tconst el = this.el;\n\n\t\t// We just need to reflect selected item\n\t\tif (this.useList) {\n\t\t\tel.classList.toggle('mdc-list-item--selected', active);\n\t\t\treturn;\n\t\t}\n\n\t\t// Because we drop and render a bit we need to handle a few more class states\n\t\t// with mdc tabs\n\t\tel.classList.toggle('mdc-tab--active', active);\n\t\tel.setAttribute('aria-selected', active);\n\t\tel.querySelector('.mdc-tab-indicator').classList.toggle(\n\t\t\t'mdc-tab-indicator--active',\n\t\t\tactive,\n\t\t);\n\t}\n}\n","/**\n * @class\n */\nimport Base from '@netx/core/lib/netx-view';\nimport Template from '../templates/appTabItemsView.html';\n\nimport ChildViews from '@netx/core/functionality/childViews';\nimport ChildView from './appTabItemView';\n\nclass AppTabItemsView extends Base {\n\t/** @override */\n\tconstructor(opts = {}) {\n\t\topts.childView = _.extend(\n\t\t\t{\n\t\t\t\tviewClass: ChildView,\n\t\t\t\t// Edge case: this is a view that happens to use a viewCollection to simply populate it's children and not\n\t\t\t\t// to inherit everything from them. Rather than try and accomplish this solution somehow in addChildView\n\t\t\t\t// I figured it best to be handled in the views that are utilizing a viewCollection differently than say\n\t\t\t\t// a netx-multiView would - since these options get applied last (superceed all others) we just put back the\n\t\t\t\t// values we do not want to inherit from a viewSpec\n\t\t\t\toptions(model, opts) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttagName: 'li',\n\t\t\t\t\t\tattributes: {\n\t\t\t\t\t\t\trole: 'presentation',\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmodel: model,\n\t\t\t\t\t\tcollection: model.collection,\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t},\n\t\t\topts.childView,\n\t\t);\n\t\topts.template = opts.template || Template;\n\t\tsuper(opts);\n\t}\n\n\t/** @override */\n\tbindCollectionEvents() {\n\t\tsuper.bindCollectionEvents();\n\t\treturn this.listenTo(\n\t\t\tthis.collection,\n\t\t\t'add remove',\n\t\t\t_.debounce(this.tabsChanged, 25),\n\t\t);\n\t}\n\n\t/** @method */\n\ttabsChanged() {\n\t\tthis.$el.toggleClass('multiple-tabs', this.collection.length > 1);\n\t}\n\n\t/**\n\t * @static\n\t * @type {string}\n\t */\n\tstatic get __name__() {\n\t\treturn 'AppTabItemsView';\n\t}\n}\n\n// Functionality\nChildViews(AppTabItemsView);\n\nexport default AppTabItemsView;\n","/**\n * @class\n */\nimport Base from '@netx/core-app/views/appTabItemsView';\nimport '../css/appTabItems.less';\n\nimport ChildView from './appTabItemView';\n\nimport {MDCTabBar} from '@material/tab-bar';\nimport MaterialList from '@netx/core/functionality/materialList';\n\nclass AppTabItemsView extends Base {\n\t/** @override */\n\tconstructor(opts = {}) {\n\t\topts.childView = {\n\t\t\tviewClass(model) {\n\t\t\t\t// Do not render out a tab item view for this\n\t\t\t\tif (model.get('hideTab')) return;\n\t\t\t\treturn ChildView;\n\t\t\t},\n\t\t\t// Edge case: this is a view that happens to use a viewCollection to simply populate it's children and not\n\t\t\t// to inherit everything from them. Rather than try and accomplish this solution somehow in addChildView\n\t\t\t// I figured it best to be handled in the views that are utilizing a viewCollection differently than say\n\t\t\t// a netx-multiView would - since these options get applied last (superceed all others) we just put back the\n\t\t\t// values we do not want to inherit from a viewSpec\n\t\t\toptions(model, opts) {\n\t\t\t\treturn {\n\t\t\t\t\ttagName: 'li',\n\t\t\t\t\tattributes: {\n\t\t\t\t\t\trole: 'presentation',\n\t\t\t\t\t},\n\t\t\t\t\tmodel: model,\n\t\t\t\t\tcollection: model.collection,\n\t\t\t\t\tuseList: this.useList,\n\t\t\t\t};\n\t\t\t},\n\t\t\t...opts.childView,\n\t\t};\n\t\topts.materialList = {\n\t\t\tchildViews: true,\n\t\t\t...opts.materialList,\n\t\t};\n\t\tsuper(opts);\n\n\t\tthis.useList = opts.useList === true;\n\t}\n\n\t/** @override */\n\tbindCollectionEvents() {\n\t\tsuper.bindCollectionEvents();\n\t\treturn this.listenTo(this.collection, 'change:active', (tab, active) => {\n\t\t\tif (!active) return;\n\t\t\tthis.checkMaterialTabActive();\n\t\t});\n\t}\n\n\t/** @method */\n\tcheckMaterialTabActive() {\n\t\tif (!this.tabBar) return;\n\n\t\tconst active = this.collection.findWhere({active: true});\n\t\tif (!active) return;\n\n\t\tconst name = active.get('name');\n\t\tconst idx = this.tabBar.tabList_.findIndex((tab) => {\n\t\t\treturn tab.root_.getAttribute('data-nx-tab-name') === name;\n\t\t});\n\t\tif (idx > -1) {\n\t\t\tthis.tabBar.activateTab(idx);\n\t\t}\n\t}\n\n\t/** @override */\n\tpreRender() {\n\t\tif (this.tabBar) {\n\t\t\tthis.tabBar.destroy();\n\t\t\tdelete this.tabBar;\n\t\t}\n\n\t\tsuper.preRender();\n\n\t\tObject.assign(this.templateVars, {\n\t\t\tuseList: this.useList,\n\t\t});\n\t}\n\n\t/** @override */\n\tpostRender() {\n\t\tsuper.postRender();\n\n\t\tthis.setupMaterial();\n\t}\n\n\t/** @method */\n\tsetupMaterial() {\n\t\tif (this.useList) return;\n\n\t\tif (this.tabBar) {\n\t\t\tthis.tabBar.destroy();\n\t\t\tdelete this.tabBar;\n\t\t}\n\n\t\tconst el = this.el.querySelector('.mdc-tab-bar');\n\t\tif (!el) return;\n\n\t\tconst tabBar = (this.tabBar = new MDCTabBar(el));\n\t\treturn tabBar;\n\t}\n\n\t/** @override */\n\ttabsChanged() {\n\t\tsuper.tabsChanged();\n\n\t\tthis.setupMaterial();\n\t\tthis.checkMaterialTabActive();\n\t}\n}\n\nMaterialList(AppTabItemsView);\n\nexport default AppTabItemsView;\n","/**\n * A view for managaing tabbed views\n * All objects provided in `this.tabs` must conform to {@link Netx.Models.AppView}\n * @class\n *\n * @example\n * // View\n * /**\n * * @class\n * * @extends Netx.Views.TabView\n * *\\/\n * Netx.Views.ModuleFooView = Netx.Views.TabView.extend(/** @lends Netx.Views.ModuleFooView *\\/{\n * /**\n * * @type {string}\n * * @private\n * *\\/\n * module: 'module',\n * /** @type {template} *\\/\n * template: ModuleFooTemplate,\n * /** @type {string} *\\/\n * id: 'module-foo-view',\n * /** @type {i18n} *\\/\n * headerTitle: i18n.t('i18n.foo'),\n * /** @type {string} *\\/\n * defaultTab: 'fooBar', // The `name` of the tab\n * /**\n * * @override\n * * @returns {array} Tabs\n * * @see Netx.Models.AppView\n * * @see Netx.Collections.AppViews\n * *\\/\n * tabs() {\n * return [\n * // FooFoo\n * {\n * viewClass : ModuleFooFooView,\n * label : i18n.t('i18n.fooFoo'), // If you do not set this we will look into the view for `headerTitle`\n * iconOnly : true, // anything but true will display a label on the tab\n * name : 'fooFoo', // If you did not set this then your tab name is \"moduleFooFooView\"\n * uniqueShowAction : 'module:foo:foo:routed', // The event to fire when clicked. If you do not set this then your tab action will be automatically handled with `appView:[view.cid]:show` and the view will show automatically when clicked.\n * viewOptions : {\n * collection: this.fooFooCollection\n * }\n * },\n * // FooBar\n * {\n * viewClass : ModuleFooBarView,\n * label : i18n.t('i18n.fooBar'), // If you do not set this we will look into the view for `headerTitle`\n * iconOnly : true, // anything but true will display a label on the tab\n * showActions : ['module:foo:fooBar'], // If yet stet this then your view will show when the tab is clicked and when these events fire\n * name : 'fooBar', // If you did not set this then your tab name is \"moduleFooBarView\"\n * viewOptions : {\n * model: this.fooBarModel\n * }\n * }\n * ];\n * }\n * } );\n *\n * // If you want to decide what happens when a tab is clicked - provide a `uniqueShowAction`\n * // When you provide a `uniqueShowAction`, you are telling the tab view that you are going to handle everything to get that view shown\n * // If ommited, a dummy action is created and registered `appView:[view.cid]:show` and the view will just show itself when the corresponding tab is clicked\n * [\n * // Foo\n * {\n * ...\n * uniqueShowAction : 'module:foo:route'\n * }\n * ];\n *\n * // If you want other actions to trigger the showing of a tab - add them to the `showActions` array\n * // This means that, on top of clicking the tab, these actions firing wil lalso cause the corresponding view to show\n * [\n * // Foo\n * {\n * ...\n * showActions : ['module:foo:bar']\n * }\n * ];\n *\n * // If you want a simpler name for targetting your tab view - provide a `name`, otherwise the view name will be used in camelcase form\n * [\n * // Foo\n * {\n * ...\n * name : \"foo\"\n * }\n * ];\n *\n * // Calling on the view from a controller\n * /**\n * * @event module:module#module:foo:show\n * * @param {object} viewOptions View options\n * *\\/\n * dispatcher.on('module:foo:show', function( viewOptions ) {\n * Netx.app.appViews.add( {\n * viewClass : ModuleFooView, // View constructor\n * showActions : ['module:foo:show'], // An array of actions that this view will show itself on\n * viewOptions : viewOptions\n * } );\n * }, window );\n *\n * /**\n * * @event module:module#module:foo:routed\n * * @param {string} tab Tab name (tab name must match either the `name` given to the tabbed view within when it was defined - and if none was provided it would be the `viewClass` in camelCase form \"moduleFooFooView\")\n * * @fires module:module#module:foo\n * *\\/\n * dispatcher.on('module:foo:routed', function( tab ) {\n * // Do anything special because we came from route, if you want and then pass along\n * dispatcher.trigger('module:foo', tab );\n * } );\n *\n * /**\n * * @event module:module#module:foo\n * * @param {string} tab Tab name\n * * @fires module:module#module:foo:show\n * *\\/\n * dispatcher.on('module:foo', function( tab ) {\n * // Do any logic you need before calling on view\n * dispatcher.trigger('module:foo:show', {\n * tab: tab\n * } );\n * } );\n */\n\nimport Base from './netx-multiView';\n\nimport AppViewModel from '@netx/core-app/models/appView';\nimport AppTabItemsView from '@netx/core-app/views/appTabItemsView';\n\nclass TabView extends Base {\n\t/** @type {boolean} */\n\tget isTabView() {\n\t\treturn this.constructor.__isTabView__;\n\t}\n\n\t/**\n\t * @override\n\t * @listens {@link Netx.Models.AppView#change:viewOptions:tab}\n\t * @listens {@link Netx.Collections.AppViews#change:enabled}\n\t */\n\tconstructor(opts = {}) {\n\t\t/**\n\t\t * @property {object} childView - Child view object\n\t\t * @property {string} childView.viewClass - The view class to use when creating `childView`\n\t\t * @property {boolean} childView.noRender - Do not render the `childView` at creation (we will handle that when we need to)\n\t\t * @property {string} childView.target - The css selector to use when injecting a newly created `childView`\n\t\t * @property {object} childView.options - The view option to extend onto `childView` at creation (all the standard backbone view properties)\n\t\t * @property {object} childView.options.attributes - The `data-`attributes to extend on to `childView` at creation\n\t\t */\n\t\topts.childView = {\n\t\t\tviewClass(model) {\n\t\t\t\treturn model.get('viewClass');\n\t\t\t},\n\t\t\tnoRender: true,\n\t\t\ttarget: '[data-nx-control=\"tab-content\"]:first',\n\t\t\toptions: {\n\t\t\t\tattributes: {\n\t\t\t\t\t'data-layer': '',\n\t\t\t\t\trole: 'tabpanel',\n\t\t\t\t},\n\t\t\t},\n\t\t\t...opts.childView,\n\t\t};\n\t\t// Unless explictely asked to, tabs will wait to be activated before instantiating their related view\n\t\topts.instantiateOnAdd = opts.instantiateOnAdd === true;\n\t\tsuper(opts);\n\n\t\t/**\n\t\t * Classes that will be added to views when they enter our `viewCollection`\n\t\t * These classes will be removed when they are removed from our `viewCollection`\n\t\t * This allows for transient views to have what they need when thye move from `multiView` to `multiView`\n\t\t * @type {string}\n\t\t * @default\n\t\t */\n\t\tthis.additionalViewClasses = opts.additionalViewClasses || 'tab-pane';\n\n\t\t/**\n\t\t * Automatically set tabs on first render\n\t\t * This will add the `this.tabs` to `this.viewCollection` and spawn `childView`s accordingly\n\t\t * @type {boolean}\n\t\t */\n\t\tthis.automaticallySetTabs = opts.automaticallySetTabs !== false;\n\n\t\t/**\n\t\t * Should the view be immediately shown when added to our view collection\n\t\t * This would happen in `viewInstantiated`\n\t\t * @type {boolean}\n\t\t * @default\n\t\t */\n\t\tthis.showOnAdd = opts.showOnAdd === true;\n\n\t\t/**\n\t\t * The tab (`viewSpec` name) that should be shown if `tab` was not passed to `this` at creation\n\t\t * @type {string}\n\t\t * @default\n\t\t */\n\t\tthis.defaultTab = opts.defaultTab;\n\n\t\tthis.tab = opts.tab;\n\n\t\t/**\n\t\t * Options for the tabs view\n\t\t * @memberOf Netx.Views.TabView\n\t\t * @alias tabsViewOptions\n\t\t * @type {object}\n\t\t */\n\t\tthis.tabsViewOptions = opts.tabsViewOptions || {};\n\n\t\t/**\n\t\t * Tabs view\n\t\t * @memberOf Netx.Views.TabView\n\t\t * @alias tabsView\n\t\t * @type {Netx.Views.AppTabItemsView}\n\t\t */\n\t\tthis.tabsView = this.addSubView(\n\t\t\tnew AppTabItemsView({\n\t\t\t\tcollection: this.viewCollection,\n\t\t\t\t...this.tabsViewOptions,\n\t\t\t}),\n\t\t);\n\n\t\t// Hey, listen!\n\t\tif (this.viewSpec) {\n\t\t\tthis.listenTo(\n\t\t\t\tthis.viewSpec,\n\t\t\t\t'change:viewOptions:tab',\n\t\t\t\t(viewSpec, tab) => {\n\t\t\t\t\tthis.showViewByName(tab || this.defaultTab);\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\n\t\t// Hey, listen!\n\t\tthis\n\t\t\t// This logic could move to `multiview` itself but am putting in tabs to start with\n\t\t\t.listenTo(this.viewCollection, 'change:enabled', (viewSpec, enabled) => {\n\t\t\t\tconst activeView = this.getActiveView();\n\t\t\t\t// We must have an active view\n\t\t\t\t// The active view must match the view that has changed\n\t\t\t\t// And that view is now disabled\n\t\t\t\tactiveView &&\n\t\t\t\t\tactiveView.viewSpec.id === viewSpec.id &&\n\t\t\t\t\t!enabled &&\n\t\t\t\t\tthis.showFirstEnabledView(viewSpec.id);\n\t\t\t})\n\t\t\t// Tab changed on view\n\t\t\t.listenTo(this, 'nx:change:tab', (view, newTab, oldTab) => {\n\t\t\t\t// Make sure it was us\n\t\t\t\tif (view.cid === this.cid) {\n\t\t\t\t\tthis.tabChanged(newTab, oldTab);\n\t\t\t\t}\n\t\t\t})\n\t\t\t// Wait until we have rendered once\n\t\t\t.listenToOnce(this, 'rendered', () => {\n\t\t\t\tthis.automaticallySetTabs &&\n\t\t\t\t\tthis.viewCollection.set(\n\t\t\t\t\t\t_.isFunction(this.tabs) ? this.tabs() : this.tabs,\n\t\t\t\t\t);\n\t\t\t});\n\n\t\tthis.$el.addClass('tab-view');\n\t}\n\n\t/** @override */\n\tpostRender() {\n\t\tsuper.postRender();\n\n\t\t// Cache\n\t\tthis.$tabs = this.$('[data-nx-control=\"tabpanel\"]:first');\n\n\t\t// Tabs\n\t\tthis.$tabs.length &&\n\t\t\tthis.tabsView &&\n\t\t\tthis.tabsView.setElement(this.$tabs).render();\n\t}\n\n\t/**\n\t * @override\n\t * @param {module:core/lib/netx-view} view Instance of `netx-view`\n\t */\n\tbeforeShowView(view) {\n\t\t// Prevent the content area from jumping\n\t\tconst currentHeight = this.$childTargetEl.height();\n\t\tif (currentHeight) {\n\t\t\tthis.$childTargetEl.height(currentHeight);\n\t\t}\n\n\t\treturn super.beforeShowView(view);\n\t}\n\n\tregisterView(viewSpec) {\n\t\tsuper.registerView(viewSpec);\n\n\t\tconst tabName = viewSpec.get('name');\n\t\t// Defined tab\n\t\tif (this.tab) {\n\t\t\t// Does the view name match our set tab?\n\t\t\tif (tabName === this.tab) {\n\t\t\t\tlet view = viewSpec.get('view');\n\t\t\t\tif (!view) {\n\t\t\t\t\tview = this.instantiateView(viewSpec);\n\t\t\t\t}\n\t\t\t\t// Since a tab was provided - we will not run through the event system\n\t\t\t\t// as the logic to deduce that tab has already occured somewhere - and\n\t\t\t\t// it could very well create a loop\n\t\t\t\tthis.showView(view);\n\t\t\t}\n\t\t}\n\t\t// Default\n\t\telse if (tabName === this.defaultTab) {\n\t\t\tlet view = viewSpec.get('view');\n\t\t\tif (!view) {\n\t\t\t\tview = this.instantiateView(viewSpec);\n\t\t\t}\n\t\t\t// Make sure the shown promise has been fulfilled on this view before we try showing anything further\n\t\t\tthis.whenShown.then(() => {\n\t\t\t\t// Run through actions instead od directly showing the view - as no tab was provided via viewOptions\n\t\t\t\t// If there are no listeners for the view's `uniqueShowAction` - we are still always listening and will\n\t\t\t\t// show the view - if any other view makes further attempts to show the view, nothing will double down\n\t\t\t\t// since the view will already be shown. And if any other event is able to show the view before we try,\n\t\t\t\t// nothing will double down since the veiw has already been shown.\n\t\t\t\tthis.showTab(tabName);\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Provided with the view we are changing to and the knowledge of the current view\n\t * you can block the change by returning `false`\n\t * @method\n\t * @param {Netx.View} view Instance of `Netx.View` we are changing to\n\t * @returns {boolean} Ok to change to and show view\n\t */\n\tviewChanging(view) {\n\t\tlet canChange = super.viewChanging(view);\n\n\t\tif (!canChange) return false;\n\n\t\t// Store last tab (if we can)\n\t\tconst activeView = this.getActiveView();\n\t\tif (activeView) {\n\t\t\tthis.lastTab = activeView.viewSpec.get('name');\n\t\t}\n\n\t\tconst viewSpec = view.viewSpec;\n\n\t\tlet routedView = false;\n\t\t// Only if our original view collection\n\t\tif (view.viewSpec.isMyOriginalCollection(this.viewCollection)) {\n\t\t\t// Check if the view was a result of routing\n\t\t\tif (view.isRouted !== false && Backbone.history.isRouting()) {\n\t\t\t\troutedView = true;\n\t\t\t}\n\t\t}\n\n\t\t// test the view's action\n\t\tcanChange = this.isViewActionValid(viewSpec);\n\n\t\t// We should not be showing this view based on action tests\n\t\tif (!canChange) {\n\t\t\tconst activeView = this.getActiveView();\n\t\t\t// There is not another view already showing ( If there is already an active view we just return false and stay where we are )\n\t\t\t// and we have other views we can show than this one\n\t\t\tif (!activeView && this.viewCollection.length > 1) {\n\t\t\t\t// Defer so our return gets processed first\n\t\t\t\t_.defer(() => {\n\t\t\t\t\tthis.showFirstEnabledView(viewSpec.id);\n\t\t\t\t});\n\t\t\t} else if (activeView && routedView) {\n\t\t\t\t// @if NODE_ENV='development'\n\t\t\t\tconsole.log('Putting route back', view.viewSpec.id);\n\t\t\t\t// @endif\n\n\t\t\t\t// Route back to where we were before we opened the modal.\n\t\t\t\tif (!_.isUndefined(view.routeMatch)) {\n\t\t\t\t\tNetx.router.exitRoute(view.routeMatch);\n\t\t\t\t} else {\n\t\t\t\t\tNetx.router.back();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn canChange;\n\t}\n\n\t/** @override */\n\tviewInstantiated(view) {\n\t\t// All child views will be fully removed on hide\n\t\tif (view.viewSpec.isMyOriginalCollection(this.viewCollection)) {\n\t\t\tview.removeOnHide = true;\n\t\t\tview.removeOnSimpleHide = false;\n\t\t}\n\n\t\tsuper.viewInstantiated(view);\n\n\t\t// // Defer so all actions have been registered in the viewSpec\n\t\t// // These get deduced at the same time as our method\n\t\t// _.defer(() => {\n\t\t// \tconst tabName = view.viewSpec.get('name');\n\t\t// \t// Defined tab\n\t\t// \tif (this.tab) {\n\t\t// \t\t// Does the view name match our set tab?\n\t\t// \t\tif (tabName === this.tab) {\n\t\t// \t\t\t// Since a tab was provided - we will not run through the event system\n\t\t// \t\t\t// as the logic to deduce that tab has already occured somewhere - and\n\t\t// \t\t\t// it could very well create a loop\n\t\t// \t\t\tthis.showView(view);\n\t\t// \t\t}\n\t\t// \t}\n\t\t// \t// Default\n\t\t// \telse if (tabName === this.defaultTab) {\n\t\t// \t\t// Make sure the shown promise has been fulfilled on this view before we try showing anything further\n\t\t// \t\tthis.whenShown.then(() => {\n\t\t// \t\t\t// Run through actions instead od directly showing the view - as no tab was provided via viewOptions\n\t\t// \t\t\t// If there are no listeners for the view's `uniqueShowAction` - we are still always listening and will\n\t\t// \t\t\t// show the view - if any other view makes further attempts to show the view, nothing will double down\n\t\t// \t\t\t// since the view will already be shown. And if any other event is able to show the view before we try,\n\t\t// \t\t\t// nothing will double down since the veiw has already been shown.\n\t\t// \t\t\tthis.showTab(tabName);\n\t\t// \t\t});\n\t\t// \t}\n\t\t// });\n\t}\n\n\t/** @override */\n\tviewAfterShown(view) {\n\t\tsuper.viewAfterShown(view);\n\n\t\t// Reset height\n\t\tview.rendered.then(() => {\n\t\t\tthis.$childTargetEl.height('');\n\t\t});\n\t}\n\n\t/**\n\t * `show` is about to start on a `childView`\n\t * At this point no animations or actual hiding [should] have taken place\n\t * @override\n\t * @param {Netx.View} view View (created via {@link Netx.Models.AppView})\n\t * @listens {@link Netx.Views.MultiView#view:showing|view:showing}\n\t */\n\tviewOnShowing(view) {\n\t\tsuper.viewOnShowing(view);\n\n\t\t// Store current tab\n\t\tthis.tab = view.viewSpec.get('name');\n\n\t\t// Fire custom event\n\t\tthis.trigger('nx:change:tab', this, this.tab, this.lastTab);\n\t}\n\n\t/**\n\t * This is different to `showView` as it will run through the action system\n\t * (and takes a tab name as opposed to a view instance)\n\t * @method\n\t * @param {string} name Tab name\n\t */\n\tshowTab(name) {\n\t\tlet viewSpec;\n\t\t// The `viewSpec` was passed\n\t\tif (name instanceof AppViewModel) {\n\t\t\tviewSpec = name;\n\t\t}\n\t\t// Assume view was passed (if it is a form view we get bad results for instanceof Netx.View - which I beleive is due to our wraaping that view's constructor)\n\t\telse if (name.cid) {\n\t\t\tviewSpec = this.viewCollection.findWhere({view: name});\n\t\t}\n\t\t// The name of the tab was passed\n\t\telse {\n\t\t\tviewSpec = this.viewCollection.findWhere({name: name});\n\t\t}\n\t\tif (viewSpec && this.isViewActionValid(viewSpec)) {\n\t\t\tconst action = Netx.Actions.Find(viewSpec.get('uniqueShowAction'));\n\t\t\taction && this.performAction(action, [viewSpec.get('view'), null]);\n\t\t}\n\t}\n\n\t/**\n\t * Tab has changed\n\t * @param {string} newTab New tab `name`\n\t * @param {string} oldTab Old tab `name`\n\t */\n\ttabChanged(newTab, oldTab) {\n\t\t//\n\t}\n\n\t/**\n\t * Define and return tab objects.\n\t * Override me with an array or method in your view\n\t * @method\n\t * @returns {array} Tabs\n\t * @see Netx.Models.AppView\n\t * @see Netx.Collections.AppViews\n\t */\n\ttabs() {\n\t\treturn [];\n\t}\n\n\t/** @type {boolean} */\n\tstatic get __isTabView__() {\n\t\treturn true;\n\t}\n\n\t/** @type {string} */\n\tstatic get __name__() {\n\t\treturn 'TabView';\n\t}\n}\n\nexport default TabView;\n","/**\n * A Shareable is a simple wrapper for a set of sharable things and its type\n * @class\n * @extends Netx.Model\n */\nimport Base from '@netx/core/lib/netx-model';\n\nimport Collection from '@netx/core/lib/netx-collection';\nimport AssetSetModel from '@netx/core-asset/models/assetSet';\n\nimport {types as assetSetTypes} from '@netx/core-asset/properties/assetSets';\n\nexport default class Shareable extends Base {\n\t/** @type {object} */\n\tget defaults() {\n\t\treturn {\n\t\t\t/** a type from Netx.ShareableTypes */\n\t\t\ttype: '',\n\t\t\t/** array of object ids, */\n\t\t\tids: [],\n\t\t\t/** optional array of models */\n\t\t\tmodels: [],\n\t\t\t/** optional array of collections */\n\t\t\tcollections: [],\n\t\t\t/** label for the share options view */\n\t\t\tlabel: '',\n\t\t};\n\t}\n\n\t/**\n\t * Constructor options: \"type\" (required) plus one of \"ids\", \"model\", \"models\" or \"collection\"\n\t * For model/models, we extract the ids;\n\t * For collection, we extract all the model IDs in the collection.\n\t */\n\tconstructor(attrs = {}, opts = {}) {\n\t\tif (!_.isString(attrs.type)) {\n\t\t\tthrow new Error('new Shareable(opts): type not found');\n\t\t}\n\n\t\tconst ids = attrs.ids,\n\t\t\tmodel = attrs.model,\n\t\t\tmodels = attrs.models,\n\t\t\tcollection = attrs.collection;\n\n\t\tif (_.isArray(ids) && ids.length) {\n\t\t\tattrs.label =\n\t\t\t\tids.length > 1 ? ids.length + ' ' + attrs.type + 's' : attrs.type;\n\t\t} else if (model && model instanceof Base) {\n\t\t\tattrs.ids = [model.id];\n\t\t\tattrs.models = [model];\n\t\t\tattrs.label = _.isFunction(model.getLabel)\n\t\t\t\t? '\"' + model.getLabel() + '\"'\n\t\t\t\t: attrs.type;\n\t\t} else if (_.isArray(models) && models.length) {\n\t\t\tattrs.ids = _.pluck(models, 'id');\n\t\t\tattrs.label =\n\t\t\t\tmodels.length +\n\t\t\t\t' ' +\n\t\t\t\t(models.length === 1 ? attrs.type.slice(0, -1) : attrs.type);\n\t\t} else if (\n\t\t\tcollection &&\n\t\t\tcollection instanceof Collection &&\n\t\t\tcollection.length\n\t\t) {\n\t\t\tattrs.ids = _.pluck(collection.models, 'id');\n\t\t\tattrs.collections = [collection];\n\t\t\tattrs.label = attrs.type;\n\t\t}\n\n\t\tsuper(attrs, opts);\n\n\t\t// DEVNOTE: i am leaving open the possibility of someday sharing more than one collection,\n\t\t// by defining collections[] as an array. But I'm not going to implement the rest until\n\t\t// it's needed.\n\t\t/*\n\t\telse if (_.isArray(opts.collections)) ... etc\n\t\t*/\n\t}\n\n\t/**\n\t * For forwards- compatibility with the token system ...\n\t */\n\ttoAssetSet() {\n\t\tvar aType;\n\t\tswitch (this.get('type')) {\n\t\t\tcase 'current cart':\n\t\t\t\taType = assetSetTypes.cart;\n\t\t\t\tbreak;\n\t\t\tcase 'saved cart':\n\t\t\t\taType = assetSetTypes.savedCart;\n\t\t\t\tbreak;\n\t\t\tcase 'saved search':\n\t\t\t\taType = assetSetTypes.savedSearch;\n\t\t\t\tbreak;\n\t\t\tcase 'assets':\n\t\t\t\taType = assetSetTypes.asset;\n\t\t\t\tbreak;\n\t\t}\n\n\t\treturn new AssetSetModel({\n\t\t\tids: this.get('ids'),\n\t\t\tmodels: this.get('models'),\n\t\t\tlabel: this.get('label'),\n\t\t\ttype: aType,\n\t\t});\n\t}\n\n\t/** @type {string} */\n\tstatic get __name__() {\n\t\treturn 'Shareable';\n\t}\n}\n","/**\n * AssetVersion Model\n * @class\n * @todo Should you be allowed to remove a top version?\n */\nimport Base from '@netx/core/lib/netx-model';\n\nexport default class AssetVersion extends Base {\n\t/**\n\t * @type {Netx.Rpc}\n\t * @private\n\t */\n\tget rpc() {\n\t\treturn true;\n\t}\n\t/**\n\t * @type {Netx.URL}\n\t * @private\n\t */\n\tget url() {\n\t\treturn Netx.URL.api;\n\t}\n\n\t/** @type {string} */\n\tget idAttribute() {\n\t\treturn 'versionId';\n\t}\n\n\t/**\n\t * @property {object} defaults - The default attribute values\n\t * @property {number} defaults.versionId - The default id (do not set this in defaults)\n\t * @property {number} defaults.active - The default active status (number as boolean)\n\t * @property {number} defaults.assetId - The default asset id version belongs to\n\t * @property {string} defaults.creationDate - The default creation date (as string)\n\t * @property {number} defaults.fileSize - The default file size\n\t * @property {number} defaults.fileTypeId - The default file type id\n\t * @property {string} defaults.fileTypeLabel - The default file type label\n\t * @property {number} defaults.memoId - The default memoId (unused as far as I can tell - always comes back 0)\n\t * @property {string} defaults.memoText - The default memo text\n\t * @property {number} defaults.original - The default original status (number as boolean)\n\t * @property {string} defaults.previewUrl - The default preview url\n\t * @property {string} defaults.shortMemoText - The default short memo text (truncated memo text)\n\t * @property {string} defaults.thumbUrl - The default thumbnail url\n\t * @property {number} defaults.userId - The default user id\n\t * @property {string} defaults.userLabel - The default user label\n\t */\n\tget defaults() {\n\t\treturn {\n\t\t\t// versionId: 0\n\t\t\tactive: 0,\n\t\t\tassetId: 0,\n\t\t\tcreationDate: '',\n\t\t\tfileSize: 0,\n\t\t\tfileTypeId: 0,\n\t\t\tfileTypeLabel: '',\n\t\t\tmemoId: 0,\n\t\t\tmemoText: '',\n\t\t\toriginal: 0,\n\t\t\tpreviewUrl: '',\n\t\t\tshortMemoText: '',\n\t\t\tthumbUrl: '',\n\t\t\tuserId: 0,\n\t\t\tuserLabel: '',\n\t\t};\n\t}\n\n\t/**\n\t * @property {object} methods - Model RPC methods\n\t * @property {array} methods.read - Fetch version\n\t * @property {array} methods.remove - Destroy version\n\t * @property {array} methods.reactivateAssetVersion - Reactivate version\n\t */\n\tget methods() {\n\t\treturn {\n\t\t\t/**\n\t\t\t * @method\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tread(opts) {\n\t\t\t\treturn ['getVersionObjects', [this.get('versionId')]];\n\t\t\t},\n\t\t\t/** @method */\n\t\t\tremove: ['deleteAssetVersion', 'versionId'],\n\t\t\t// Reactivate version\n\t\t\t// Deprecated - use new uuid call `reactivateAssetVersion`\n\t\t\t// reactivateVersion: ['reactivateVersion', 'versionId', 'memoText'],\n\t\t\t/** @method */\n\t\t\treactivateAssetVersion: [\n\t\t\t\t'reactivateAssetVersion',\n\t\t\t\t'versionId',\n\t\t\t\t'memoText',\n\t\t\t],\n\t\t};\n\t}\n\t/** @type {object} */\n\tget parsers() {\n\t\treturn {\n\t\t\t/**\n\t\t\t * @function reactivateAssetVersion\n\t\t\t * @param {boolean} response Response\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\treactivateAssetVersion(uuid, opts) {\n\t\t\t\tthis.trackBatchJob(uuid);\n\t\t\t\tdispatcher.trigger(\n\t\t\t\t\t'asset:versions:reactivate:progress',\n\t\t\t\t\tthis.get('assetId'),\n\t\t\t\t\t1,\n\t\t\t\t\ti18n.t('i18n.reactivatingVersion'),\n\t\t\t\t);\n\t\t\t\treturn uuid;\n\t\t\t},\n\t\t};\n\t}\n\n\t/**\n\t * @override\n\t * @param {object} attrs Model attributes\n\t * @param {object} opts Model options\n\t */\n\tconstructor(attrs, opts = {}) {\n\t\tsuper(attrs, opts);\n\n\t\tthis.on('progress', (assetVersion, batchJob, progress) => {\n\t\t\tdispatcher.trigger(\n\t\t\t\t'asset:versions:reactivate:progress',\n\t\t\t\tthis.get('assetId'),\n\t\t\t\tprogress,\n\t\t\t\ti18n.t('i18n.reactivatingVersion'),\n\t\t\t);\n\t\t});\n\t\tthis.on('complete', (assetVersion, batchJob, progress) => {\n\t\t\tdispatcher.trigger('asset:versions:reactivate:succeeded', this);\n\t\t});\n\t\tthis.on('error', (assetVersion, error) => {\n\t\t\tdispatcher.trigger('asset:versions:reactivate:error', error, this);\n\t\t});\n\t}\n\n\t/**\n\t * Unwrap the one-object array returned by `getVersionObjects`\n\t * @method\n\t * @param {object} attrs Model attributes\n\t */\n\tparse(attrs) {\n\t\treturn _.isArray(attrs) ? attrs[0] : attrs;\n\t}\n\n\t/**\n\t * Cache-busting string for asset version objects: encode the versionID and creation date as query args\n\t * @method\n\t * @param {string} prefix Prefix for cachbuster string\n\t * @return {string}\n\t */\n\tcacheBuster(prefix = '') {\n\t\treturn (\n\t\t\tprefix +\n\t\t\t'?t=' +\n\t\t\t_.dateFromAsset(this.get('creationDate')).getTime() +\n\t\t\t'&v=' +\n\t\t\tthis.get('versionId')\n\t\t);\n\t}\n\n\t/** @type {string} */\n\tstatic get __name__() {\n\t\treturn 'AssetVersion';\n\t}\n}\n","const NAME = 'resizable';\n\nimport {isMobile} from '@netx/core/lib/underscore-netx';\n\nimport 'core-libs/nx-drag/jquery-netx-dragresize';\n\n/**\n * @function\n * @param {string} str String\n * @param {boolean} Is percent\n */\nconst isPercent = (str) => {\n\tif (str == null) return false;\n\treturn /^\\d+(\\.\\d+)?\\%$/g.test(str.toString());\n};\n\nconst Props = {\n\t/** @method */\n\tcleanUpResizable() {\n\t\tif (!this.resizeTargets) return;\n\t\tthis.Plugins.Destroy('netxDragResize', this.resizeTargets);\n\t},\n\n\t/** @method */\n\tprepareResizable() {\n\t\tthis.resizeTargets = this.resizeTargetSelector\n\t\t\t? [...this.el.querySelectorAll(this.resizeTargetSelector)]\n\t\t\t: [this.el];\n\n\t\tif (!this.resizeTargets.length) {\n\t\t\tthis.resizeTargets = null;\n\t\t\treturn;\n\t\t}\n\n\t\tlet startSize = this.resizableGetStartSize();\n\t\tthis.Plugins.Initialize('netxDragResize', this.resizeTargets, {\n\t\t\tstartHeigh: startSize,\n\t\t\tstartWidth: startSize,\n\t\t});\n\t},\n\n\t/**\n\t * @method\n\t * @return {number|string} Size\n\t */\n\tresizableGetStartSize() {\n\t\tconst horizontal = this.resizeDirection === 'horizontal';\n\n\t\tif (!this.resizeUserPref)\n\t\t\treturn horizontal ? this.resizeStartWidth : this.resizeStartHeight;\n\n\t\tlet size = Netx.getPreference(this.resizeUserPref) || 0;\n\t\tlet minSize = horizontal ? this.resizeMinWidth : this.resizeMinHeight;\n\n\t\tif (\n\t\t\t!this.resizeUsingPercent &&\n\t\t\t(isPercent(size) || isNaN(parseInt(size)) || size < minSize)\n\t\t) {\n\t\t\tsize = minSize;\n\t\t}\n\n\t\treturn size;\n\t},\n\n\t/**\n\t * @method\n\t * @param {event} e `dragresizestart` event\n\t */\n\tresizeStart(e) {\n\t\te && e.stopPropagation();\n\t},\n\n\t/**\n\t * @method\n\t * @param {event} e `dragresizeend`|`dragresizereset`|`hidden.bs.collapse`|`shown.bs.collapse` event\n\t */\n\tresized(e) {\n\t\te && e.stopPropagation();\n\n\t\tif (!this.resizeTargets) return;\n\n\t\tconst originalEvent = (e && e.originalEvent) || {};\n\t\t// Store user preferred width\n\t\tif (!originalEvent.ui) return;\n\n\t\tif (this.resizeUserPref) {\n\t\t\tNetx.setPreference(\n\t\t\t\tthis.resizeUserPref,\n\t\t\t\tthis.resizeDirection === 'horizontal'\n\t\t\t\t\t? originalEvent.ui.width\n\t\t\t\t\t: originalEvent.ui.height,\n\t\t\t);\n\t\t}\n\t},\n\n\t/**\n\t * @method\n\t * @param {event} e `dragresizing` event\n\t */\n\tresizing(e) {\n\t\t// Prevent parent response\n\t\te && e.stopPropagation();\n\t},\n\n\t/**\n\t * @method\n\t * @param {boolean} resizable Resizable\n\t */\n\ttoggleResizable(resizable) {\n\t\tif (!this.resizeTargets) return;\n\n\t\tresizable = resizable != null ? resizable === true : !this.resizable;\n\t\tthis.resizeDisabled = !resizable;\n\t\tthis.resizeTargets.forEach((target) => {\n\t\t\ttarget.classList.toggle('resize-disabled', !resizable);\n\t\t});\n\t},\n};\n\nexport default function (target) {\n\tif (isMobile() || !target || target.hasFunctionality(NAME)) return target;\n\n\ttarget.extendFunctionality(Props);\n\n\ttarget.addInitializer((instance, opts = {}) => {\n\t\tinstance.events = {\n\t\t\tdragresizestart: 'resizeStart',\n\t\t\tdragresizeend: 'resized',\n\t\t\tdragresizing: 'resizing',\n\t\t\tdragresizereset: 'resized',\n\t\t\t...instance.events,\n\t\t};\n\t\tinstance.resizeStartHeight = opts.resizeStartHeight;\n\t\tinstance.resizeStartWidth = opts.resizeStartWidth;\n\t\tinstance.resizeTargetSelector = opts.resizeTargetSelector;\n\t\tinstance.resizeUserPref = opts.resizeUserPref;\n\t\tinstance.resizeDirection = opts.resizeDirection || 'horizontal';\n\t\tinstance.resizeUsingPercent = opts.resizeUsingPercent === true;\n\t\tinstance.resizeMinHeight = opts.resizeMinHeight;\n\t\tinstance.resizeMinWidth = opts.resizeMinWidth;\n\n\t\t// Add plugins\n\t\tinstance.Plugins.Register({\n\t\t\tnetxDragResize: {\n\t\t\t\tname: 'netxDragResize',\n\t\t\t\toptions: {\n\t\t\t\t\tdirection: instance.resizeDirection,\n\t\t\t\t\tdragFrom: opts.resizeDragFrom || 'right',\n\t\t\t\t\tmaxHeight: opts.resizeMaxHeight,\n\t\t\t\t\tminHeight: opts.resizeMinHeight,\n\t\t\t\t\tmaxWidth: opts.resizeMaxWidth,\n\t\t\t\t\tminWidth: opts.resizeMinWidth,\n\t\t\t\t\tusePercent: instance.resizeUsingPercent,\n\t\t\t\t},\n\t\t\t},\n\t\t});\n\n\t\t// Hey, listen!\n\t\tinstance\n\t\t\t.on('preRenderHook', instance.cleanUpResizable)\n\t\t\t.on('postRenderHook', instance.prepareResizable)\n\t\t\t.on('removeHook', instance.cleanUpResizable)\n\t\t\t.on('hidden', () => {})\n\t\t\t.on('shown', () => {});\n\t}, NAME);\n}\n","import {i18n} from '@netx/core/i18n';\n\nexport let types = {\n\tasset: 'asset',\n\tattributeSet: 'attributeSet',\n\tcart: 'cart',\n\tsavedCart: 'savedCart',\n\tcategory: 'category',\n\tconstituent: 'constituent',\n\t//search: 'search'\n\tsavedSearch: 'savedSearch',\n\t// NOTE: this got changed to 'assets' but these are not strings to i18n, these are DAM symbols. Use share:i18n.asssetSet or similar instead.\n\tassetSet: 'assetSet',\n};\n\nexport let organizeByTypes = {\n\tnone: {\n\t\tvalue: 0,\n\t\tlabel: i18n.t('i18n.noOrganization'),\n\t},\n\tfileType: {\n\t\tvalue: -105,\n\t\tlabel: i18n.t('i18n.fileType'),\n\t},\n\tfileFormatFamily: {\n\t\tvalue: -106,\n\t\tlabel: i18n.t('i18n.fileFormatFamily'),\n\t},\n\tfolderPath: {\n\t\tvalue: -108,\n\t\tlabel: i18n.t('i18n.categoryPath'),\n\t},\n};\n\nexport default {organizeByTypes, types};\n","var map = {\n\t\"./de\": 411,\n\t\"./de-at\": 412,\n\t\"./de-at.js\": 412,\n\t\"./de-ch\": 413,\n\t\"./de-ch.js\": 413,\n\t\"./de.js\": 411,\n\t\"./en-au\": 414,\n\t\"./en-au.js\": 414,\n\t\"./en-ca\": 415,\n\t\"./en-ca.js\": 415,\n\t\"./en-gb\": 416,\n\t\"./en-gb.js\": 416,\n\t\"./en-ie\": 417,\n\t\"./en-ie.js\": 417,\n\t\"./en-il\": 418,\n\t\"./en-il.js\": 418,\n\t\"./en-in\": 419,\n\t\"./en-in.js\": 419,\n\t\"./en-nz\": 420,\n\t\"./en-nz.js\": 420,\n\t\"./en-sg\": 421,\n\t\"./en-sg.js\": 421,\n\t\"./es\": 422,\n\t\"./es-do\": 423,\n\t\"./es-do.js\": 423,\n\t\"./es-us\": 424,\n\t\"./es-us.js\": 424,\n\t\"./es.js\": 422,\n\t\"./fr\": 425,\n\t\"./fr-ca\": 426,\n\t\"./fr-ca.js\": 426,\n\t\"./fr-ch\": 427,\n\t\"./fr-ch.js\": 427,\n\t\"./fr.js\": 425,\n\t\"./gom-deva\": 428,\n\t\"./gom-deva.js\": 428,\n\t\"./ja\": 429,\n\t\"./ja.js\": 429,\n\t\"./ko\": 430,\n\t\"./ko.js\": 430,\n\t\"./nl\": 431,\n\t\"./nl-be\": 432,\n\t\"./nl-be.js\": 432,\n\t\"./nl.js\": 431,\n\t\"./zh-cn\": 433,\n\t\"./zh-cn.js\": 433\n};\n\n\nfunction webpackContext(req) {\n\tvar id = webpackContextResolve(req);\n\treturn __webpack_require__(id);\n}\nfunction webpackContextResolve(req) {\n\tif(!__webpack_require__.o(map, req)) {\n\t\tvar e = new Error(\"Cannot find module '\" + req + \"'\");\n\t\te.code = 'MODULE_NOT_FOUND';\n\t\tthrow e;\n\t}\n\treturn map[req];\n}\nwebpackContext.keys = function webpackContextKeys() {\n\treturn Object.keys(map);\n};\nwebpackContext.resolve = webpackContextResolve;\nmodule.exports = webpackContext;\nwebpackContext.id = 844;","/**\n * This object allows us to specify assets in one of the four Asset Set types\n * we know how to download: a cart, a search, a category or some bare assets.\n * (Other types may be added in the future.)\n * @class\n * @extends Netx.Model\n * @todo Finish documentation of defaults, methods and parsers\n */\nimport Base from '@netx/core/lib/netx-model';\n\nimport DownloadOptionsCollection from '@netx/core-share/collections/downloadOptions';\nimport ShareableModel from '@netx/core-share/models/shareable';\n\nimport Rpc from 'core-libs/backbone.rpc';\n\nimport {i18n} from '@netx/core/i18n';\n\nimport {types as assetSetTypes} from '../properties/assetSets';\nimport {types as downloadOptionTypes} from '@netx/core-share/properties/downloadOptions';\n\nexport default class AssetSet extends Base {\n\t/**\n\t * @type {Netx.Rpc}\n\t * @private\n\t */\n\tget rpc() {\n\t\treturn true;\n\t}\n\t/**\n\t * @type {Netx.URL}\n\t * @private\n\t */\n\tget url() {\n\t\treturn Netx.URL.api;\n\t}\n\n\t/**\n\t * @property {object} defaults - The default attribute values\n\t * @property {array} defaults.ids - The default ids\n\t * @property {boolean} defaults.recursive - The default recursiveness. For completeness, the `category` type needs this extra info. Other types ignore this property.\n\t * @property {string} defaults.type - The default type. See assetSetProps.types\n\t *\n\t * @property {array} defaults.assetIds - The default asset ids belonging to set (client side)\n\t * @property {string} defaults.label - The default label. It's useful to set a label for the set when it's created, since it feeds into a generic system (client side)\n\t * @property {array} defaults.models - The default models. Handy to attach the original models/collections, if we had them (client side)\n\t * @property {boolean} defaults.canCreateLink - The default description (client side)\n\t * @property {boolean} defaults.canEmail - The default description (client side)\n\t */\n\tget defaults() {\n\t\treturn {\n\t\t\tids: [],\n\t\t\trecursive: false,\n\t\t\ttype: '',\n\n\t\t\t// Client\n\t\t\tassetCount: 0,\n\t\t\tassetIds: [],\n\t\t\tcanCreateLink: null,\n\t\t\tcanEmail: null,\n\t\t\tlabel: '',\n\t\t\tmodels: [],\n\t\t};\n\t}\n\n\t/** @type {array} */\n\tget clientAttrs() {\n\t\treturn [\n\t\t\t'assetIds',\n\t\t\t'assetCount',\n\t\t\t'label',\n\t\t\t'models',\n\t\t\t'canCreateLink',\n\t\t\t'canEmail',\n\t\t];\n\t}\n\n\t/**\n\t * @property {object} methods - Model RPC methods\n\t * @property {method} methods.getAssetIdsInSets - Get all asset ids in asset set\n\t * @property {method} methods.getDownloadWarnings - Get any download warnings for asset set\n\t * @property {method} methods.getDownloadOptions - Get any download options for asset set\n\t * @property {method} methods.prepareDownload - Prepare asset set download\n\t */\n\tget methods() {\n\t\treturn {\n\t\t\t/**\n\t\t\t * @method\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tgetAssetIdsInSets(opts) {\n\t\t\t\treturn ['getAssetIdsInSets', [this.self()]];\n\t\t\t},\n\t\t\t/**\n\t\t\t * @method\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tgetDownloadWarnings(opts) {\n\t\t\t\treturn ['getDownloadWarnings', [this.self()]];\n\t\t\t},\n\t\t\t/**\n\t\t\t * @method\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tgetDownloadOptions(opts) {\n\t\t\t\treturn ['getDownloadOptions', [this.self()]];\n\t\t\t},\n\t\t\t/**\n\t\t\t * Request the DAM prepare a set of assets (asset lists, categories, saved searches, carts) in any of several formats (as originals, proxies, views or preset processes).\n\t\t\t * If download is authorized, this returns a progress UUID for tracking the progress of this request.\n\t\t\t * If download is prohibited due to a missing justification, this throws an exception that becomes a JSON-RPC error object.\n\t\t\t * If download is prohibited due to approval, this triggers the server-side asset approval processes for the requested assets\n\t\t\t * (sending email, creating categories, etc -- all the things that requestDownloadApproval does),\n\t\t\t * then throws an exception that becomes a JSON-RPC error object.\n\t\t\t * @function\n\t\t\t * @param {*} assets -- an AssetSets collection, a single AssetSet model, or raw object/array data to instantiate one of those\n\t\t\t * @param {*} options -- a DownloadOptions collection, a single DownloadOption model, or raw object/array data to instantiate one of those\n\t\t\t * @param {String} archiveName -- String of archive name to create\n\t\t\t * @param {String} justification -- Download justification data. Can be null or empty if no justification is needed.\n\t\t\t * @param {Object} syncOptions -- any options for Backbone.Sync\n\t\t\t * @throws JustificationRequired -- if a justification data is required for this download, and none was provided\n\t\t\t * @throws ApprovalRequired -- if approval is required for this download.\n\t\t\t * @return {String} It returns a promise that resolves to a Progress UUID (as String)\n\t\t\t * @todo: the API call works with an array of assetSets. The AssetSets collection should have this method, and then the model\n\t\t\t * method can use the collection version (since we're creating a collection anyway (for some reason).)\n\t\t\t */\n\t\t\tprepareDownload(downloadOptions, archiveName, justification, opts) {\n\t\t\t\tconst assetSets = [this.self()];\n\t\t\t\tdownloadOptions = _.toCollection(\n\t\t\t\t\tdownloadOptions,\n\t\t\t\t\tDownloadOptionsCollection,\n\t\t\t\t);\n\t\t\t\tjustification = justification || '';\n\n\t\t\t\treturn [\n\t\t\t\t\t'prepareDownload',\n\t\t\t\t\tassetSets,\n\t\t\t\t\tdownloadOptions,\n\t\t\t\t\tarchiveName,\n\t\t\t\t\tjustification,\n\t\t\t\t];\n\t\t\t},\n\t\t};\n\t}\n\n\t/**\n\t * @property {object} parsers - Model parsers\n\t * @property {function} parsers.getAssetIdsInSets - Parse the return of asset ids\n\t * @property {function} parsers.getDownloadOptions - Parse the return of download options\n\t */\n\tget parsers() {\n\t\treturn {\n\t\t\t/**\n\t\t\t * @functon\n\t\t\t * @param {array} results Asset ids\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tgetAssetIdsInSets(results, opts) {\n\t\t\t\tif (!_.isArray(results)) {\n\t\t\t\t\tthrow new Rpc.ParseError('getAssetIdsInSets() returned non-array');\n\t\t\t\t}\n\t\t\t\tthis.set({assetIds: results});\n\t\t\t},\n\t\t\t/**\n\t\t\t * Filters the download options to only include the ones in displayedDownloadOptionTypes and turns the results into a collection\n\t\t\t * @function\n\t\t\t * @param {array} downloadOptions array of download options\n\t\t\t * @param {object} opts Request options\n\t\t\t * @return {Netx.Collections.DownloadOptions} Download options collection\n\t\t\t */\n\t\t\tgetDownloadOptions(downloadOptions, opts) {\n\t\t\t\t// this should never be a null array.\n\t\t\t\tif (downloadOptions == null || !downloadOptions.length) {\n\t\t\t\t\tthrow new Rpc.ParseError('bad response from getDownloadOptions');\n\t\t\t\t}\n\t\t\t\t// Filter returned download options by the array of options types we want to show the user\n\t\t\t\t// TODO: Currently \"manualRepurpose\" is not in this list - though we may not want to show it, it still counts as a downloadOption\n\t\t\t\t// I am forcing it into `displayedDownloadOptionTypes` when the `assetSet` is created for the image being repurposed\n\t\t\t\t// I think that `displayedDownloadOptionTypes` should be taken into consideration in the controller or view and not be causing\n\t\t\t\t// data to not get back from the server that is needed. The model should not be concerned with what is displayed in the UI\n\t\t\t\t// Maybe it is the wrong name for the property - maybe it should be `supportedDownloadOptionTypes`?\n\t\t\t\tdownloadOptions = _.filter(downloadOptions, (downloadOption) =>\n\t\t\t\t\t_.contains(this.displayedDownloadOptionTypes, downloadOption.type),\n\t\t\t\t);\n\t\t\t\t// Turn into a proper collection\n\t\t\t\tthis.downloadOptions.set(downloadOptions);\n\t\t\t\treturn this.downloadOptions;\n\t\t\t},\n\t\t\t/**\n\t\t\t * Check that we have any assets left to download/create a link with\n\t\t\t * @function\n\t\t\t * @param {object} warnings Warnings\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tgetDownloadWarnings(warnings, opts) {\n\t\t\t\tif (!warnings.messageCount) return warnings;\n\n\t\t\t\tconst assetsUnavailableCount = _.unique(\n\t\t\t\t\t_.map(warnings.progressMessages, (message) => message.objectId),\n\t\t\t\t).length;\n\n\t\t\t\t// TODO: we need to be passing the thing that made the assetSet\n\t\t\t\t// as a target arguments\n\t\t\t\t// Then we can pass some logic off to the collection/model that\n\t\t\t\t// the asset set spawned from\n\t\t\t\tif (assetsUnavailableCount) {\n\t\t\t\t\tlet abort = false;\n\t\t\t\t\tconst assetCount = this.get('assetCount') || 0;\n\t\t\t\t\tconst ids = this.get('ids') || [];\n\t\t\t\t\tconst type = this.get('type');\n\t\t\t\t\tconst types = assetSetTypes;\n\n\t\t\t\t\tswitch (type) {\n\t\t\t\t\t\tcase types.cart: {\n\t\t\t\t\t\t\tabort =\n\t\t\t\t\t\t\t\tNetx.getCurrentCart().getTotal() <= assetsUnavailableCount;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase types.category:\n\t\t\t\t\t\t\tabort = assetCount <= assetsUnavailableCount;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase types.savedCart: {\n\t\t\t\t\t\t\tconst cart = Netx.cart.saved.all.get(ids[0]);\n\t\t\t\t\t\t\tabort =\n\t\t\t\t\t\t\t\tcart && cart.get('contentCount') <= assetsUnavailableCount;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase types.savedSearch: {\n\t\t\t\t\t\t\tconst search = Netx.search.saved.all.get(ids[0]);\n\t\t\t\t\t\t\tabort =\n\t\t\t\t\t\t\t\tsearch && search.get('contentCount') <= assetsUnavailableCount;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdefault: {\n\t\t\t\t\t\t\tabort = ids.length <= assetsUnavailableCount;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (abort) {\n\t\t\t\t\t\twarnings.abort = new Error(\n\t\t\t\t\t\t\ti18n.t('i18n.noAssetsAvailableForDownload'),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn warnings;\n\t\t\t},\n\t\t};\n\t}\n\n\t/**\n\t * @override\n\t * @param {object} attrs Model attributes\n\t * @param {object} opts Model options\n\t */\n\tconstructor(attrs, opts = {}) {\n\t\tsuper(attrs, opts);\n\n\t\t/**\n\t\t * Contains the downloadOptions returned by getDownloadOptions\n\t\t * @memberOf module:asset/models/assetSet\n\t\t * @alias downloadOptions\n\t\t * @type {Netx.Collections.DownloadOptions}\n\t\t */\n\t\tthis.downloadOptions =\n\t\t\topts.downloadOptions || new DownloadOptionsCollection([]);\n\t\t/**\n\t\t * All of the download option types to filter by after getting download options. Set to all by default(but will only show what the user has permission for).\n\t\t * @memberOf module:asset/models/assetSet\n\t\t * @type {Array}\n\t\t */\n\t\tthis.displayedDownloadOptionTypes =\n\t\t\topts.displayedDownloadOptionTypes || _.values(downloadOptionTypes);\n\t}\n\t/**\n\t * @override\n\t * @return {object}\n\t */\n\tself() {\n\t\tconst attrs = super.self();\n\n\t\t// getDownloadOptions does not work with type assetSet however it does work with asset and will accept multiple ids.\n\t\tif (attrs.type === 'assetSet') {\n\t\t\tattrs.type = 'asset';\n\t\t}\n\t\treturn attrs;\n\t}\n\n\t/**\n\t * @method\n\t * @param {string} type Option type\n\t * @return {boolean} Has option\n\t */\n\thasOption(type) {\n\t\treturn !!this.downloadOptions.findWhere({type: type});\n\t}\n\n\t/**\n\t * For backwards compatibility with the shareways system, this method returns a new Shareable model\n\t * based on the content of this assetSet model.\n\t * @method\n\t * @returns {Netx.Models.Shareable}\n\t */\n\ttoShareable() {\n\t\tlet sType;\n\t\tswitch (this.get('type')) {\n\t\t\tcase 'cart':\n\t\t\t\tsType = 'current cart';\n\t\t\t\tbreak;\n\t\t\tcase 'savedCart':\n\t\t\t\tsType = 'saved cart';\n\t\t\t\tbreak;\n\t\t\tcase 'savedSearch':\n\t\t\t\tsType = 'saved search';\n\t\t\t\tbreak;\n\t\t\tcase 'asset':\n\t\t\t\tsType = 'assets';\n\t\t\t\tbreak;\n\t\t\tcase 'category':\n\t\t\t\t// No shareable for catagory!\n\t\t\t\treturn undefined;\n\t\t}\n\n\t\treturn new ShareableModel({\n\t\t\tids: this.get('ids'),\n\t\t\tmodel: this.get('models')[0],\n\t\t\tmodels: this.get('models'),\n\t\t\tlabel: this.get('label'),\n\t\t\ttype: sType,\n\t\t});\n\t}\n\n\t/** @type {string} */\n\tstatic get __name__() {\n\t\treturn 'AssetSet';\n\t}\n}\n","module.exports = function(obj){\nvar __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\nwith(obj||{}){\n__p+='\\n\\n\\n';\n if (useList) { \n__p+='\\n
\\n';\n } else { \n__p+='\\n
\\n\t
\\n\t\t
\\n\t\t\t
\\n\t\t
\\n\t
\\n
\\n';\n } \n__p+='';\n}\nreturn __p;\n};\n","module.exports = function(obj){\nvar __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\nwith(obj||{}){\n__p+='\\n\\n';\n if (useList) { \n__p+='\\n\t';\n if( icon ) { \n__p+='\\n\t'+\n((__t=( icon ))==null?'':__t)+\n'\\n\t';\n } \n__p+='\\n\t'+\n((__t=( label ))==null?'':__t)+\n'\\n';\n } else { \n__p+='\\n\\n\t';\n if( icon ) { \n__p+='\\n\t\t'+\n((__t=( icon ))==null?'':__t)+\n'\\n\t';\n } \n__p+='\\n\t';\n if( label ) { \n__p+='\\n\t\t\\n\t\t\t'+\n((__t=( label ))==null?'':__t)+\n'\\n\t\t\t';\n if (hasTotal) { \n__p+='\\n\t\t\t2\\n\t\t\t';\n } \n__p+='\\n\t\t\\n\t';\n } \n__p+='\\n\\n\\n\t\\n\\n\\n';\n } \n__p+='';\n}\nreturn __p;\n};\n"],"sourceRoot":""}