{"version":3,"sources":["VizApp.js","DataResponseModel.js","SelectorsModel.js","VizRouterBase.js","LoadingSpinnerView.js","NoDataView.js","SelectorsView.js","SourceDefinitionNotesView.js","WindowshadeView.js"],"names":["$","_","ns","window","nspace","VizApp","options","self","this","indicatorGroupId","routerType","router","tabsSelector","dispatcher","model","ccc","indicatorSelection","IndicatorSelectionModel","treeView","IndicatorSelectionTreeView","buttonView","IndicatorSelectionButtonsView","optOutOfLinkRewrite","windowshadeView","viz","shared","views","WindowshadeView","initialRenderPromise","Deferred","once","resolve","prototype","start","Backbone","history","clone","Events","jQuery","DataResponseModel","Model","extend","initialize","bindAll","validateOptions","selectorsModel","dataUrl","cache","on","getDataResponseOnChange","getDataResponse","filterString","deferredLoad","areModelArraysValid","getFilterString","hasOwnProperty","setTimeout","set","trigger","name","text","ajax","url","data","getDataParams","complete","success","response","SelectorsModel","props","convertedPropNames","propNames","Array","split","any","attributes","value","key","prop","length","VizRouterBase","ArraySerializationRouterBase","$tabs","urlParts","table","get","map","bar","updateLinks","each","$self","hash","href","join","attr","getValueOrDefault","val","routeUrlParts","updateUrl","urlPart","navigate","replace","initializeModelListeners","completeRouterInitialization","initialRenderPromises","filter","view","getInitialRenderPromise","when","apply","done","selectorsView","LoadingSpinnerView","View","el","loadingTasks","addTask","endTask","endAllTasks","args","push","render","i","splice","task","$el","stop","css","fadeOut","NoDataView","validateView","templateSelector","loadTemplate","template","$tmpl","html","hide","fadeIn","SelectorsView","validate","initializeSelectors","initializeView","getSelectorInfoOrThrow","selectorInfo","getSelectorInfo","onSuccess","selectorUrl","selectorData","setDefaultIfMissing","items","find","item","selected","id","Object","keys","selectors","characteristics","locationTypes","getDataSummaryText","propertyNames","texts","selector","str","isBlank","indexOf","propertyName","getDataSummary","allSelectors","getDataSummaryByPropertyNames","names","getIndicatorSpecificSelectors","renderSelectors","indicatorSpecificSelectors","indicatorSelectorInfo","breakdownSelectorView","SourceDefinitionNotesView","currentIndicatorId","templateData","source","definition","notes","collapse","events","click button.change-indicator-link-cancel","click button.change-indicator-link","expand","$shade","height","$tabContainer","fadeTo","animateExpand","show","animate","$indicatorContainer","duration","always","animateCollapse"],"mappings":"cAKA,SAAUA,EAAGC,GAEX,IAAIC,GAEJA,EAAKC,OAAOC,OAAO,mBAMhBC,OAAS,SAASC,GACnB,IAAIC,EAAOC,KAEX,IAAKF,EACH,KAAM,+DAGR,IAAKA,EAAQG,iBACX,KAAM,sEAGR,IAAKH,EAAQI,WACX,KAAM,+DAIRF,KAAKG,OAAS,IAAIL,EAAQI,WAAW,CACnCD,iBAAkBH,EAAQG,iBAC1BG,aAAc,2CACdC,WAAYX,EAAGG,OAAOQ,aAGxBL,KAAKM,MAAQ,IAAIX,OAAOY,IAAIC,mBAAmBC,wBAG/CT,KAAKU,SAAW,IAAIf,OAAOY,IAAIC,mBAAmBG,2BAChD,CACEL,MAAON,KAAKM,QAGhBN,KAAKY,WAAa,IAAIjB,OAAOY,IAAIC,mBAAmBK,8BAClD,CACEP,MAAON,KAAKM,MACZQ,qBAAqB,IAGzBd,KAAKe,gBAAkB,IAAIpB,OAAOY,IAAIS,IAAIC,OAAOC,MAAMC,gBAAgB,CACrEb,MAAON,KAAKM,QAGdN,KAAKoB,qBAAuB5B,EAAE6B,WAE9B3B,EAAGG,OAAOQ,WAAWiB,KAAK,0BAA2B,WACnDvB,EAAKqB,qBAAqBG,aAY3B7B,EAAGG,OAAO2B,UAJLC,MAAQ,WAEZC,SAASC,QAAQF,SAOrB/B,EAAGG,OAAOQ,WAAaZ,EAAEmC,MAAMF,SAASG,QAtE1C,CAuEGC,OAAQrC,GCxEX,SAAUD,EAAGC,GAGFE,OAAOC,OAAO,yBAOpBmC,kBAAoBL,SAASM,MAAMC,OAAO,CAC3CC,WAAY,SAASpC,GACnBL,EAAE0C,QAAQnC,MAEVA,KAAKoC,gBAAgBtC,GAErBE,KAAKK,WAAaP,EAAQO,WAC1BL,KAAKqC,eAAiBvC,EAAQuC,eAC9BrC,KAAKsC,QAAUxC,EAAQwC,QAGvBtC,KAAKuC,MAAQ,GAGbvC,KAAKqC,eAAeG,GAAG,SAAUxC,KAAKyC,0BAMxCA,wBAAyB,WACvB,KAAM,yEAGRC,gBAAiB,WACf,IAAI3C,EAAM4C,EAGV,OAAI3C,KAAK4C,aACA5C,KAAK4C,cAId5C,KAAK4C,aAAepD,EAAE6B,WAEjBrB,KAAKqC,eAAeQ,uBASzBF,GADA5C,EAAOC,MACa8C,kBAEhB9C,KAAKuC,MAAMQ,eAAeJ,GAC5BK,WAAW,WAETjD,EAAKkD,IAAI,WAAYlD,EAAKwC,MAAMI,IAChC5C,EAAKmD,QAAQ,QAGbnD,EAAK6C,aAAarB,UAClBxB,EAAK6C,aAAe,MACnB,IAIL5C,KAAKkD,QAAQ,QAGblD,KAAKK,WAAW6C,QAAQ,WAAY,CAClCC,KAAM,eACNC,KAAM,oBAER5D,EAAE6D,KAAK,CACLC,IAAKvD,EAAKuC,QACViB,KAAMxD,EAAKyD,cAAcb,GACzBc,SAAU,WACR1D,EAAKmD,QAAQ,QACbnD,EAAKM,WAAW6C,QAAQ,WAAY,CAAEC,KAAM,iBAG5CpD,EAAK6C,aAAarB,UAClBxB,EAAK6C,aAAe,MAEtBc,QAAS,SAASC,GAEhB5D,EAAKwC,MAAMI,GAAgBgB,EAG3B5D,EAAKkD,IAAI,WAAYU,OA1BhB3D,KAAK4C,eApBZ5C,KAAKiD,IAAI,WAAY,IAErBjD,KAAK4C,aAAarB,UAClBvB,KAAK4C,aAAe,KACb5C,KAAK4C,gBAqDhBY,cAAe,WACb,KAAM,6EAMRV,gBAAiB,WACf,KAAM,uEAGRV,gBAAiB,SAAStC,GACxB,IAAKA,EAAQO,WACX,KAAM,iDAGR,IAAKP,EAAQuC,eACX,KAAM,+CAGR,IAAKvC,EAAQwC,QACX,KAAM,uDA5Hd,CAgIGR,OAAQrC,GChIX,SAAUD,EAAGkC,GAKN/B,OAAOC,OAAO,yBAMhBgE,eAAiBlC,EAASM,MAAMC,OAAO,CAMxCY,oBAAqB,WACnB,IAAIgB,EAEsBC,EAqC1B,OArC0BA,EAYD9D,KAAK+D,UAA9BF,EAXOC,EAICA,aAA8BE,MAI7BF,EAHEA,EAAmBG,MAAM,KAJzBH,GAYerE,EAAEyE,IAAIlE,KAAKmE,WAAY,SAASC,EAAOC,GAG/D,OAAMD,aAAiBJ,QAIlBH,IAKmBpE,EAAEyE,IAAIL,EAAO,SAASS,GAC5C,OAAOA,IAASD,MAIRD,EAAMG,QARNH,EAAMG,aA3CxB,CA4DGzC,OAAQJ,UC5DX,SAAUjC,GAGHE,OAAOC,OAAO,0BAEhB4E,cAAgB7E,OAAOY,IAAIU,OAAOwD,6BAA6BxC,OAAO,CACvEC,WAAY,SAASpC,GACnBE,KAAKC,iBAAmBH,EAAQG,iBAChCD,KAAKK,WAAaP,EAAQO,WAC1BL,KAAK0E,MAAQlF,EAAEM,EAAQM,cAEvBX,EAAE0C,QAAQnC,OAMZ2E,SAAU,WACR,MAAO,CACLC,MAAO,CACL5E,KAAKqC,eAAewC,IAAI,eACxB7E,KAAKqC,eAAewC,IAAI,gBACxB7E,KAAKqC,eAAewC,IAAI,gBAE1BC,IAAK,CACH9E,KAAKqC,eAAewC,IAAI,eACxB,IACA,IACA7E,KAAKqC,eAAewC,IAAI,gBACxB7E,KAAKqC,eAAewC,IAAI,gBAE1BE,IAAK,CACH/E,KAAKqC,eAAewC,IAAI,eACuB,MAA/C7E,KAAKqC,eAAewC,IAAI,oBACpB,IACA7E,KAAKqC,eAAewC,IAAI,oBAC5B,IACA7E,KAAKqC,eAAewC,IAAI,gBACxB7E,KAAKqC,eAAewC,IAAI,kBAK9BG,YAAa,WACX,IAAIjF,GAEJA,EAAOC,MAKF0E,MAAMO,KAAK,WACd,IAAIC,EAAOC,EAAMC,EAEjBF,EAAQ1F,EAAEQ,MAEVmF,EAAOpF,EAAK4E,WAAWO,EAAM3B,KAAK,YAAY8B,KAAK,KACnDD,EAAOF,EAAMI,KAAK,QAAQrB,MAAM,KAAK,GAAK,IAAMkB,EAEhDD,EAAMI,KAAK,OAAQF,MAIvBG,kBAAmB,SAASC,GAC1B,OAAW,MAAPA,EACK,IAEFA,GAGTC,cAAe,WACb,KAAM,wDAGRC,UAAW,WACT,IAAI3F,EAAOC,KACP2E,EAAWlF,EAAEqF,IAAI/E,EAAK0F,gBAAiB,SAASE,GAClD,OAAO5F,EAAKwF,kBAAkBI,KAGhC5F,EAAK6F,SAASjB,EAASU,KAAK,KAAM,CAAEQ,SAAS,KAG/CC,yBAA0B,WAExB9F,KAAKqC,eAAeG,GAAG,SAAUxC,KAAK0F,WACtC1F,KAAKqC,eAAeG,GAAG,SAAUxC,KAAKgF,cAGxCe,6BAA8B,WAC5B,IAAIhG,EAAOC,KAEXA,KAAK8F,2BAKL,IAAIE,EAAwBvG,EAAEqF,IAC5BrF,EAAEwG,OAAOlG,EAAKmB,MAAO,SAASgF,GAC5B,QAASA,EAAKC,0BAEhB,SAASD,GACP,OAAOA,EAAKC,4BAGhB3G,EAAE4G,KAAKC,MAAMrG,KAAMgG,GAAuBM,KAAK,WAC7CvG,EAAKM,WAAW6C,QAAQ,6BAK1BlD,KAAKkB,MAAMqF,cAAcjF,KAAK,OAAQ,WACpCvB,EAAKsC,eAAea,QAAQ,eAhHpC,CAoHGzD,GCxHH,SAAUD,EAAGC,GACFE,OAAOC,OAAO,wBAKpB4G,mBAAqB9E,SAAS+E,KAAKxE,OAAO,CAC3CyE,GAAI,mBAEJxE,WAAY,SAASpC,GACnB,IAAKA,EAAQO,WACX,KAAM,yDAGRZ,EAAE0C,QAAQnC,KAAM,SAAU,UAAW,UAAW,eAEhDA,KAAK2G,aAAe,GAEpB3G,KAAKK,WAAaP,EAAQO,WAC1BL,KAAKK,WAAWmC,GAAG,WAAYxC,KAAK4G,SACpC5G,KAAKK,WAAWmC,GAAG,WAAYxC,KAAK6G,SACpC7G,KAAKK,WAAWmC,GAAG,gBAAiBxC,KAAK8G,cAM3CF,QAAS,SAASG,GAChB,IAAI3D,EAAO2D,EAAK3D,KACZD,EAAO4D,EAAK5D,UAEI,IAATC,IACTA,EAAO,cAGTpD,KAAK2G,aAAaK,KAAK,CACrB7D,KAAMA,EACNC,KAAMA,IAGRpD,KAAKiH,UAMPJ,QAAS,SAASE,GAGhB,IAFA,IAAI5D,EAAO4D,EAAK5D,KAEP+D,EAAI,EAAGA,EAAIlH,KAAK2G,aAAapC,OAAQ2C,IAC5C,GAAIlH,KAAK2G,aAAaO,GAAG/D,OAASA,EAAM,CACtCnD,KAAK2G,aAAaQ,OAAOD,EAAG,GAC5B,MAIJlH,KAAKiH,UAMPH,YAAa,SAASC,GAGpB,IAFA,IAAI5D,EAAO4D,EAAK5D,KAEP+D,EAAI,EAAGA,EAAIlH,KAAK2G,aAAapC,OAAQ2C,IACxClH,KAAK2G,aAAaO,GAAG/D,OAASA,IAChCnD,KAAK2G,aAAaQ,OAAOD,EAAG,GAC5BA,KAIJlH,KAAKiH,UAGPA,OAAQ,WAEN,GAAiC,IAA7BjH,KAAK2G,aAAapC,OAAtB,CAMA,IAAI6C,EAAOpH,KAAK2G,aAAa,GAC7B3G,KAAKqH,IAAIC,MAAK,GAAMC,IAAI,UAAW,WACnC/H,EAAE,OAAQQ,KAAKqH,KAAKjE,KAAKgE,EAAKhE,WAP5BpD,KAAKqH,IAAIG,aA9EjB,CAwFG1F,OAAQrC,GCtFX,SAAUD,EAAGC,GACFE,OAAOC,OAAO,wBAKpB6H,WAAa/F,SAAS+E,KAAKxE,OAAO,CACnCC,WAAY,SAASpC,GACnBL,EAAE0C,QAAQnC,MAEVA,KAAK0H,eAEL1H,KAAKoB,qBAAuB5B,EAAE6B,WAE9BrB,KAAKqC,eAAiBvC,EAAQuC,eAE9BrC,KAAKM,MAAMkC,GAAG,SAAUxC,KAAKiH,SAG/BS,aAAc,WACZ,IAAK1H,KAAK0G,GACR,KAAM,8CAER,IAAK1G,KAAKmD,KACR,KAAM,gDAER,IAAKnD,KAAK2H,iBACR,KAAM,6DAIVxB,wBAAyB,WACvB,OAAOnG,KAAKoB,sBAGdwG,aAAc,WAEZ,IAAK5H,KAAK6H,SAAU,CAClB,IAAIC,EAAQtI,EAAEQ,KAAK2H,kBACnB,GAAqB,IAAjBG,EAAMvD,OACR,KAAM,sBACJvE,KAAKmD,KACL,cACAnD,KAAK2H,iBAIT3H,KAAK6H,SAAWpI,EAAEoI,SAASC,EAAMC,UAIrCd,OAAQ,WACN,IAAIlH,EAGJ,KADAA,EAAOC,MACEqC,eAAeQ,sBAAxB,CAKA,GAAwB,IAApB9C,EAAKsH,IAAI9C,OACX,KAAM,sBAAwBxE,EAAKoD,KAAO,eAAiBpD,EAAK2G,GAIlE3G,EAAK6H,eAGL7H,EAAKsH,IAAIU,KAAKhI,EAAK8H,YAGnB9H,EAAKsH,IAAIW,OAAOC,OAAO,WACrBlI,EAAKqB,qBAAqBG,gBAxElC,CA4EGO,OAAQrC,GC1EX,SAAUD,EAAGC,GAGNE,OAAOC,OAAO,wBAEhBsI,cAAgBxG,SAAS+E,KAAKxE,OAAO,CACtCC,WAAY,SAASpC,GACnBE,KAAKmI,SAASrI,GAEdE,KAAKC,iBAAmBH,EAAQG,iBAChCD,KAAKK,WAAaP,EAAQO,WAE1BZ,EAAE0C,QAAQnC,MAEVA,KAAKM,MAAMkC,GAAG,qBAAsBxC,KAAKiH,QAGzCjH,KAAKoI,sBAGLpI,KAAKiH,SACLjH,KAAKqI,kBAMPA,eAAgB,aAIhBF,SAAU,SAASrI,GACjB,IAAKA,EAAQO,WACX,KAAM,oDAOV+H,oBAAqB,WACnB,KAAM,+CASRE,uBAAwB,WACtB,IAAKtI,KAAKuI,aACR,KAAM,4DAER,OAAOvI,KAAKuI,cAGdC,gBAAiB,SAASC,GACxB,IAAI1I,EAAOC,KAGPA,KAAKuI,aACPvF,WAAW,WAELyF,GACFA,EAAU1I,EAAKwI,eAEhB,IAKLvI,KAAKkD,QAAQ,QACblD,KAAKK,WAAW6C,QAAQ,WAAY,CAClCC,KAAM,oBACNC,KAAM,yBAER5D,EAAE6D,KAAK,CACLC,IAAKtD,KAAKF,QAAQ4I,aAAe,iCACjCnF,KAAMvD,KAAKF,QAAQ6I,cAAgB,CACjC1I,iBAAkBD,KAAKC,kBAEzBwD,SAAU,WACR1D,EAAKmD,QAAQ,QACbnD,EAAKM,WAAW6C,QAAQ,WAAY,CAAEC,KAAM,uBAE9CO,QAAS,SAASC,GAEhB,SAASiF,EAAoBC,GACvBA,GAASA,EAAMtE,SACEsE,EAAMC,KAAK,SAASC,GACrC,OAAyB,IAAlBA,EAAKC,aAGZH,EAAM,GAAGG,UAAW,IAM1B,IAAIC,EAAKC,OAAOC,KAAKxF,EAASyF,WAAW,GAGzCR,EAAoBjF,EAASyF,UAAUH,GAAII,iBAG3CT,EAAoBjF,EAASyF,UAAUH,GAAIK,eAM3CvJ,EAAKwI,aAAe5E,EACpB5D,EAAKO,MAAMiI,aAAe5E,EAGtB8E,GACFA,EAAU9E,QAMlB4F,mBAAoB,SAASH,EAAWI,GACtC,IAAIC,EAAQ,GAYZ,OAXAjK,EAAEyF,KAAKmE,EAAW,SAASlC,EAAGwC,GAC5B,IAAItG,EAAOsG,EAASH,qBAEjB9J,EAAEkK,IAAIC,QAAQxG,IACboG,MACmD,EAAnD/J,EAAEoK,QAAQL,EAAeE,EAASI,gBAEpCL,EAAMzC,KAAK5D,KAIRqG,EAAMpE,KAAK,OAGpB0E,eAAgB,WACd,OAAO/J,KAAKuJ,mBAAmBvJ,KAAKgK,eAGtCC,8BAA+B,SAASC,GACtC,OAAOlK,KAAKuJ,mBAAmBvJ,KAAKgK,aAAcE,IAKpDC,8BAA+B,WAC7B,KAAM,kEAMRC,gBAAiB,SAAS7B,GACxB,IAAI8B,EAA4BC,EAIhCD,EAA6BrK,KAAKmK,gCAGlCnK,KAAKuK,sBAAsBtD,OAAOsB,GAGlC+B,EACE/B,EAAaa,UAAUpJ,KAAKM,MAAMuE,IAAI,gBACxC,IAAK,IAAIqC,EAAI,EAAGA,EAAImD,EAA2B9F,OAAQ2C,IAErDmD,EAA2BnD,GAAGD,OAAOqD,IAIzCrD,OAAQ,WACN,IAAIlH,EAAOC,KAGPA,KAAKuI,aACPvI,KAAKoK,gBAAgBpK,KAAKuI,cAG1BvI,KAAKwI,gBAAgB,SAASD,GAC5BxI,EAAKqK,gBAAgB7B,QAxL/B,CA6LGzG,OAAQrC,GCjMX,SAAUD,EAAGC,GACFE,OAAOC,OAAO,wBAKpB4K,0BAA4B9I,SAAS+E,KAAKxE,OAAO,CAClDyE,GAAI,qCACJvD,KAAM,+BACNwE,iBAAkB,oCAElBzF,WAAY,SAASpC,GACnBL,EAAE0C,QAAQnC,KAAM,SAAU,eAAgB,2BAE1CA,KAAKoB,qBAAuB5B,EAAE6B,WAE9BrB,KAAKqC,eAAiBvC,EAAQuC,eAE9BrC,KAAKM,MAAMkC,GAAG,SAAUxC,KAAKiH,SAG/Bd,wBAAyB,WACvB,OAAOnG,KAAKoB,sBAGdwG,aAAc,WAEZ,IAAK5H,KAAK6H,SAAU,CAClB,IAAIC,EAAQtI,EAAEQ,KAAK2H,kBACnB,GAAqB,IAAjBG,EAAMvD,OACR,KAAM,sBACJvE,KAAKmD,KACL,cACAnD,KAAK2H,iBAIT3H,KAAK6H,SAAWpI,EAAEoI,SAASC,EAAMC,UAIrCd,OAAQ,WACN,IAAIlH,EAAOC,KAGX,GAAwB,IAApBA,KAAKqH,IAAI9C,OACX,KAAM,sBAAwBvE,KAAKmD,KAAO,eAAiBnD,KAAK0G,GAOlE,GAHA1G,KAAK4H,eAGD5H,KAAKqC,eAAewC,IAAI,iBAAmB7E,KAAKyK,mBAApD,CAIAzK,KAAKyK,mBAAqBzK,KAAKqC,eAAewC,IAAI,eAGlD,IAAIlB,EAAW5D,EAAKO,MAAMuE,IAAI,YAC1B6F,EAAe,CACjBC,OAAQhH,EAASgH,OACjBC,WAAYjH,EAASiH,WACrBC,MAAOlH,EAASkH,OAIlB9K,EAAKsH,IAAIU,KAAKhI,EAAK8H,SAAS6C,IAG5B3K,EAAKsH,IAAIW,OAAOC,OAAO,WACrBlI,EAAKqB,qBAAqBG,gBAxElC,CA4EGO,OAAQrC,GC5EX,SAAUD,EAAGC,GACFE,OAAOC,OAAO,wBAKpBuB,gBAAkBO,SAAS+E,KAAKxE,OAAO,CAMxCyE,GAAI,0BAEJxE,WAAY,WACVlC,KAAKM,MAAMkC,GAAG,cAAexC,KAAK8K,SAAU9K,MAC5CP,EAAE0C,QAAQnC,OAGZ+K,OAAQ,CACNC,4CAA6C,WAC7CC,qCAAsC,UAGxCC,OAAQ,WACNlL,KAAKmL,OAAOC,OAAOpL,KAAK0E,MAAM0G,UAC9BpL,KAAKqL,cAAcC,OAAO,IAAK,EAAGtL,KAAKuL,gBAGzCA,cAAe,WACbvL,KAAKmL,OAAOK,OAAOC,QAAQ,CAAEL,OAAQ,KAAO,KAE5CpL,KAAK0L,oBAAoBJ,OAAO,IAAK,IAGvCR,SAAU,WACR9K,KAAK0L,oBAAoBJ,OAAO,IAAK,GACrCtL,KAAKmL,OAAOM,QACV,CAAEL,OAAQpL,KAAK0E,MAAM0G,UACrB,CACEO,SAAU,IACVC,OAAQ5L,KAAK6L,mBAKnBA,gBAAiB,WACf7L,KAAKmL,OAAOnD,OACZhI,KAAKqL,cAAcC,OAAO,IAAK,IAGjCH,OAAQ3L,EAAE,mBACVkF,MAAOlF,EAAE,0BACT6L,cAAe7L,EAAE,kBACjBkM,oBAAqBlM,EAAE,0BAtD3B,CAwDGsC,OAAQrC","file":"viz-shared-generated.js","sourcesContent":["/// \r\n/// \r\n/// \r\n/// \r\n\r\n(function($, _) {\r\n \"use strict\";\r\n var ns;\r\n\r\n ns = window.nspace(\"ccc.viz.shared\");\r\n\r\n /**\r\n * The main visualization application class\r\n * @param options A configuration object.\r\n */\r\n ns.VizApp = function(options) {\r\n var self = this;\r\n\r\n if (!options) {\r\n throw \"A configuration object needs to be passed when constructing.\";\r\n }\r\n\r\n if (!options.indicatorGroupId) {\r\n throw \"An indicatorGroupId needs to be passed in the configuration object.\";\r\n }\r\n\r\n if (!options.routerType) {\r\n throw \"A routerType needs to be passed in the configuration object.\";\r\n }\r\n\r\n // Init the router\r\n this.router = new options.routerType({\r\n indicatorGroupId: options.indicatorGroupId,\r\n tabsSelector: \"ul.map-table-tabs-list li a:not(.active)\",\r\n dispatcher: ns.VizApp.dispatcher\r\n });\r\n\r\n this.model = new window.ccc.indicatorSelection.IndicatorSelectionModel();\r\n\r\n // Init the indictor selection view\r\n this.treeView = new window.ccc.indicatorSelection.IndicatorSelectionTreeView(\r\n {\r\n model: this.model\r\n }\r\n );\r\n this.buttonView = new window.ccc.indicatorSelection.IndicatorSelectionButtonsView(\r\n {\r\n model: this.model,\r\n optOutOfLinkRewrite: true\r\n }\r\n );\r\n this.windowshadeView = new window.ccc.viz.shared.views.WindowshadeView({\r\n model: this.model\r\n });\r\n\r\n this.initialRenderPromise = $.Deferred();\r\n\r\n ns.VizApp.dispatcher.once(\"initial-render-complete\", function() {\r\n self.initialRenderPromise.resolve();\r\n });\r\n };\r\n\r\n /**\r\n * VizApp Prototype\r\n */\r\n (function(proto) {\r\n proto.start = function() {\r\n // Start Backbone's history tracking\r\n Backbone.history.start();\r\n };\r\n })(ns.VizApp.prototype);\r\n\r\n /**\r\n * Global \"static\" VizApp event dispatcher\r\n */\r\n ns.VizApp.dispatcher = _.clone(Backbone.Events);\r\n})(jQuery, _);\r\n","/// \r\n/// \r\n/// \r\n\r\n(function($, _) {\r\n \"use strict\";\r\n\r\n var ns = window.nspace(\"ccc.viz.shared.models\");\r\n\r\n /**\r\n * Data response model is responsible for querying the server-side for data,\r\n * storing the response, and other views listen for the response to change\r\n * in order to be updated when new data is retrieved\r\n */\r\n ns.DataResponseModel = Backbone.Model.extend({\r\n initialize: function(options) {\r\n _.bindAll(this);\r\n\r\n this.validateOptions(options);\r\n\r\n this.dispatcher = options.dispatcher;\r\n this.selectorsModel = options.selectorsModel;\r\n this.dataUrl = options.dataUrl;\r\n\r\n // Data responses will be cached\r\n this.cache = {};\r\n\r\n // Listen for the selector options to change and update our data\r\n this.selectorsModel.on(\"change\", this.getDataResponseOnChange);\r\n },\r\n\r\n /**\r\n * When the selectors model changes, determines how/when to get the data response./\r\n */\r\n getDataResponseOnChange: function() {\r\n throw \"The data response change event callback be implemented in sub models.\";\r\n },\r\n\r\n getDataResponse: function() {\r\n var self, filterString;\r\n\r\n // If there's a pending data load, return the $.Deferred\r\n if (this.deferredLoad) {\r\n return this.deferredLoad;\r\n }\r\n\r\n // New async loading task\r\n this.deferredLoad = $.Deferred();\r\n\r\n if (!this.selectorsModel.areModelArraysValid()) {\r\n this.set(\"response\", {});\r\n // Resolve our async loading task\r\n this.deferredLoad.resolve();\r\n this.deferredLoad = null;\r\n return this.deferredLoad;\r\n }\r\n\r\n self = this;\r\n filterString = self.getFilterString();\r\n // Do we already have the response stored locally?\r\n if (this.cache.hasOwnProperty(filterString)) {\r\n setTimeout(function() {\r\n // Update the model\r\n self.set(\"response\", self.cache[filterString]);\r\n self.trigger(\"idle\");\r\n\r\n // Resolve our async loading task\r\n self.deferredLoad.resolve();\r\n self.deferredLoad = null;\r\n }, 0);\r\n return this.deferredLoad;\r\n }\r\n\r\n this.trigger(\"busy\");\r\n\r\n // Otherwise, hit the web service\r\n this.dispatcher.trigger(\"add-task\", {\r\n name: \"data-loading\",\r\n text: \"Loading data...\"\r\n });\r\n $.ajax({\r\n url: self.dataUrl,\r\n data: self.getDataParams(filterString),\r\n complete: function() {\r\n self.trigger(\"idle\");\r\n self.dispatcher.trigger(\"end-task\", { name: \"data-loading\" });\r\n\r\n // Resolve our async loading task\r\n self.deferredLoad.resolve();\r\n self.deferredLoad = null;\r\n },\r\n success: function(response) {\r\n // Save for future use\r\n self.cache[filterString] = response;\r\n\r\n // Update the model\r\n self.set(\"response\", response);\r\n }\r\n });\r\n\r\n return this.deferredLoad;\r\n },\r\n\r\n /**\r\n * Allows sub models to pass in custom params to the request specified by the data url.\r\n * @param filterString The filter string to use as a stub across models.\r\n */\r\n getDataParams: function(filterString) {\r\n throw \"The way we get params for the data url must be implemented in sub models.\";\r\n },\r\n\r\n /**\r\n * Constructs a filter string NameValueCollection from model parameters.\r\n */\r\n getFilterString: function() {\r\n throw \"The way we get the filter string must be implemented in sub models.\";\r\n },\r\n\r\n validateOptions: function(options) {\r\n if (!options.dispatcher) {\r\n throw \"Sub models must be passed an event dispatcher.\";\r\n }\r\n\r\n if (!options.selectorsModel) {\r\n throw \"Sub models must be passed a selectors model.\";\r\n }\r\n\r\n if (!options.dataUrl) {\r\n throw \"Sub models must be passed a url to get data from.\";\r\n }\r\n }\r\n });\r\n})(jQuery, _);\r\n","/// \r\n/// \r\n/// \r\n\r\n(function($, Backbone) {\r\n \"use strict\";\r\n\r\n var ns;\r\n\r\n ns = window.nspace(\"ccc.viz.shared.models\");\r\n\r\n /**\r\n * Records the data selector values representing the data set currently selected\r\n * by the user. The values in this model are represented in the URL.\r\n */\r\n ns.SelectorsModel = Backbone.Model.extend({\r\n /**\r\n * Checks if model arrays are in a valid state.\r\n * Set this.propNames if you want to limit which model properties are examined for validity.\r\n * See ccc.viz.profile.models.SelectorsModel for a working example.\r\n */\r\n areModelArraysValid: function() {\r\n var props, anyModelArrayIsInvalid;\r\n\r\n function convertPropNames(convertedPropNames) {\r\n if (!convertedPropNames) {\r\n return convertedPropNames;\r\n }\r\n\r\n if (!(convertedPropNames instanceof Array)) {\r\n return convertedPropNames.split(\",\");\r\n }\r\n\r\n return convertedPropNames;\r\n }\r\n\r\n props = convertPropNames(this.propNames);\r\n\r\n anyModelArrayIsInvalid = !_.any(this.attributes, function(value, key) {\r\n var shouldPropBeEvaluated;\r\n\r\n if (!(value instanceof Array)) {\r\n return false;\r\n }\r\n\r\n if (!props) {\r\n // If there's no length, we're in an invalid state.\r\n return !value.length;\r\n }\r\n\r\n shouldPropBeEvaluated = _.any(props, function(prop) {\r\n return prop === key;\r\n });\r\n\r\n if (shouldPropBeEvaluated) {\r\n return !value.length;\r\n }\r\n\r\n return false;\r\n });\r\n\r\n return anyModelArrayIsInvalid;\r\n }\r\n });\r\n})(jQuery, Backbone);\r\n","/// \r\n/// \r\n/// \r\n\r\n(function(_) {\r\n var ns;\r\n\r\n ns = window.nspace(\"ccc.viz.shared.routers\");\r\n\r\n ns.VizRouterBase = window.ccc.shared.ArraySerializationRouterBase.extend({\r\n initialize: function(options) {\r\n this.indicatorGroupId = options.indicatorGroupId;\r\n this.dispatcher = options.dispatcher;\r\n this.$tabs = $(options.tabsSelector);\r\n\r\n _.bindAll(this);\r\n },\r\n\r\n /**\r\n * The url parts to keep when constructing a default intertab url.\r\n */\r\n urlParts: function() {\r\n return {\r\n table: [\r\n this.selectorsModel.get(\"indicatorId\"),\r\n this.selectorsModel.get(\"dataFormatId\"),\r\n this.selectorsModel.get(\"timeFrameId\")\r\n ],\r\n map: [\r\n this.selectorsModel.get(\"indicatorId\"),\r\n \"a\", // characteristic\r\n \"a\", // location type\r\n this.selectorsModel.get(\"dataFormatId\"),\r\n this.selectorsModel.get(\"timeFrameId\")\r\n ],\r\n bar: [\r\n this.selectorsModel.get(\"indicatorId\"),\r\n this.selectorsModel.get(\"characteristicId\") == null\r\n ? \"n\"\r\n : this.selectorsModel.get(\"characteristicId\"), //\"n\" default\r\n \"n\", // locations\r\n this.selectorsModel.get(\"dataFormatId\"),\r\n this.selectorsModel.get(\"timeFrameId\")\r\n ]\r\n };\r\n },\r\n\r\n updateLinks: function() {\r\n var self;\r\n\r\n self = this;\r\n\r\n // Table, map, and bar have slightly different options. Going between the visualizations we can retain\r\n // the selected indicator, data type, and timeframe.\r\n // Order matters.\r\n this.$tabs.each(function() {\r\n var $self, hash, href;\r\n\r\n $self = $(this);\r\n\r\n hash = self.urlParts()[$self.data(\"viztype\")].join(\"/\");\r\n href = $self.attr(\"href\").split(\"#\")[0] + \"#\" + hash;\r\n\r\n $self.attr(\"href\", href);\r\n });\r\n },\r\n\r\n getValueOrDefault: function(val) {\r\n if (val == null) {\r\n return \"a\";\r\n }\r\n return val;\r\n },\r\n\r\n routeUrlParts: function() {\r\n throw \"routeUrlParts needs to be implemented in subclasses.\";\r\n },\r\n\r\n updateUrl: function() {\r\n var self = this;\r\n var urlParts = _.map(self.routeUrlParts(), function(urlPart) {\r\n return self.getValueOrDefault(urlPart);\r\n });\r\n\r\n self.navigate(urlParts.join(\"/\"), { replace: true });\r\n },\r\n\r\n initializeModelListeners: function() {\r\n // Listen for changes to the selectors model and update our URL\r\n this.selectorsModel.on(\"change\", this.updateUrl);\r\n this.selectorsModel.on(\"change\", this.updateLinks);\r\n },\r\n\r\n completeRouterInitialization: function() {\r\n var self = this;\r\n\r\n this.initializeModelListeners();\r\n\r\n // For anything that might need to know when the views are finished with their initial render,\r\n // such as the server-side screenshot-taking code, wait for each view to signal that initial render is complete\r\n // then emit an event indicating that everything is finished\r\n var initialRenderPromises = _.map(\r\n _.filter(self.views, function(view) {\r\n return !!view.getInitialRenderPromise;\r\n }),\r\n function(view) {\r\n return view.getInitialRenderPromise();\r\n }\r\n );\r\n $.when.apply(this, initialRenderPromises).done(function() {\r\n self.dispatcher.trigger(\"initial-render-complete\");\r\n });\r\n\r\n // Trigger a change notification on the model now that all of the selectors have finished initializing\r\n // so that other components can update themselves to reflect the current app state\r\n this.views.selectorsView.once(\"idle\", function() {\r\n self.selectorsModel.trigger(\"change\");\r\n });\r\n }\r\n });\r\n})(_);\r\n","(function($, _) {\r\n var ns = window.nspace(\"ccc.viz.shared.views\");\r\n\r\n /**\r\n * Shows a spinner while waiting for asynchronous server communications to complete\r\n */\r\n ns.LoadingSpinnerView = Backbone.View.extend({\r\n el: \"#loading-spinner\",\r\n\r\n initialize: function(options) {\r\n if (!options.dispatcher) {\r\n throw \"The loading spinner view requires an event dispatcher.\";\r\n }\r\n\r\n _.bindAll(this, \"render\", \"addTask\", \"endTask\", \"endAllTasks\");\r\n\r\n this.loadingTasks = [];\r\n\r\n this.dispatcher = options.dispatcher;\r\n this.dispatcher.on(\"add-task\", this.addTask);\r\n this.dispatcher.on(\"end-task\", this.endTask);\r\n this.dispatcher.on(\"end-all-tasks\", this.endAllTasks);\r\n },\r\n\r\n /**\r\n * Adds a new loading task to display\r\n */\r\n addTask: function(args) {\r\n var text = args.text;\r\n var name = args.name;\r\n\r\n if (typeof text === \"undefined\") {\r\n text = \"Loading...\";\r\n }\r\n\r\n this.loadingTasks.push({\r\n name: name,\r\n text: text\r\n });\r\n\r\n this.render();\r\n },\r\n\r\n /**\r\n * Removes a loading task\r\n */\r\n endTask: function(args) {\r\n var name = args.name;\r\n\r\n for (var i = 0; i < this.loadingTasks.length; i++) {\r\n if (this.loadingTasks[i].name === name) {\r\n this.loadingTasks.splice(i, 1);\r\n break;\r\n }\r\n }\r\n\r\n this.render();\r\n },\r\n\r\n /**\r\n * Removes all loading tasks matching the taskName\r\n */\r\n endAllTasks: function(args) {\r\n var name = args.name;\r\n\r\n for (var i = 0; i < this.loadingTasks.length; i++) {\r\n if (this.loadingTasks[i].name === name) {\r\n this.loadingTasks.splice(i, 1);\r\n i--; // adjust the index since we just removed an item\r\n }\r\n }\r\n\r\n this.render();\r\n },\r\n\r\n render: function() {\r\n // Hide the spinner if there are no pending tasks\r\n if (this.loadingTasks.length === 0) {\r\n this.$el.fadeOut();\r\n return;\r\n }\r\n\r\n // Otherwise, show the next task in the queue\r\n var task = this.loadingTasks[0];\r\n this.$el.stop(true).css(\"display\", \"inherit\");\r\n $(\"span\", this.$el).text(task.text);\r\n }\r\n });\r\n})(jQuery, _);\r\n","/// \r\n\r\n(function($, _) {\r\n var ns = window.nspace(\"ccc.viz.shared.views\");\r\n\r\n /**\r\n * A friendly no data message view that appears if a user unselects all checkboxes.\r\n */\r\n ns.NoDataView = Backbone.View.extend({\r\n initialize: function(options) {\r\n _.bindAll(this);\r\n\r\n this.validateView();\r\n\r\n this.initialRenderPromise = $.Deferred();\r\n\r\n this.selectorsModel = options.selectorsModel;\r\n\r\n this.model.on(\"change\", this.render);\r\n },\r\n\r\n validateView: function() {\r\n if (!this.el) {\r\n throw \"Subviews need to implement the el property.\";\r\n }\r\n if (!this.name) {\r\n throw \"Subviews need to implement the name property.\";\r\n }\r\n if (!this.templateSelector) {\r\n throw \"Subviews need to implement the templateSelector property.\";\r\n }\r\n },\r\n\r\n getInitialRenderPromise: function() {\r\n return this.initialRenderPromise;\r\n },\r\n\r\n loadTemplate: function() {\r\n // Get the underscore template\r\n if (!this.template) {\r\n var $tmpl = $(this.templateSelector);\r\n if ($tmpl.length === 0) {\r\n throw \"Could not find the \" +\r\n this.name +\r\n \" template: \" +\r\n this.templateSelector;\r\n }\r\n\r\n // Pre-compile and cache the template\r\n this.template = _.template($tmpl.html());\r\n }\r\n },\r\n\r\n render: function() {\r\n var self;\r\n\r\n self = this;\r\n if (self.selectorsModel.areModelArraysValid()) {\r\n return;\r\n }\r\n\r\n // Verify this selector's container is present\r\n if (self.$el.length === 0) {\r\n throw \"Could not find the \" + self.name + \" container: \" + self.el;\r\n }\r\n\r\n // Load the template\r\n self.loadTemplate();\r\n\r\n // Render the output\r\n self.$el.html(self.template());\r\n\r\n // Animate the transition\r\n self.$el.hide().fadeIn(function() {\r\n self.initialRenderPromise.resolve();\r\n });\r\n }\r\n });\r\n})(jQuery, _);\r\n","/// \r\n/// \r\n/// \r\n\r\n(function($, _) {\r\n var ns;\r\n\r\n ns = window.nspace(\"ccc.viz.shared.views\");\r\n\r\n ns.SelectorsView = Backbone.View.extend({\r\n initialize: function(options) {\r\n this.validate(options);\r\n\r\n this.indicatorGroupId = options.indicatorGroupId;\r\n this.dispatcher = options.dispatcher;\r\n\r\n _.bindAll(this);\r\n\r\n this.model.on(\"change:indicatorId\", this.render);\r\n\r\n // Initialize the various selectors\r\n this.initializeSelectors();\r\n\r\n // Initial render\r\n this.render();\r\n this.initializeView();\r\n },\r\n\r\n /**\r\n * Exposing an additional initialize method so that sub views can override if desired.\r\n */\r\n initializeView: function() {\r\n // no-op\r\n },\r\n\r\n validate: function(options) {\r\n if (!options.dispatcher) {\r\n throw \"The selectors view requires an event dispatcher.\";\r\n }\r\n },\r\n\r\n /**\r\n * Initialize selector views. Specific to each sub view.\r\n */\r\n initializeSelectors: function() {\r\n throw \"Selectors must be initialized in sub views.\";\r\n },\r\n\r\n /**\r\n * Returns selector info if we already have it stored locally. Throws an exception if we don't already\r\n * have it loaded. Seems like the least terrible solution for the fact that the Data Type selector needs to retrieve\r\n * selector info non-asynchronously within the \"before-change\" handler (If the handler isn't synchronous, then there's\r\n * no point in even having a \"before-change\" event.)\r\n */\r\n getSelectorInfoOrThrow: function() {\r\n if (!this.selectorInfo) {\r\n throw \"Selector info has not yet been retrieved from the server.\";\r\n }\r\n return this.selectorInfo;\r\n },\r\n\r\n getSelectorInfo: function(onSuccess) {\r\n var self = this;\r\n\r\n // Do we already have the response stored locally?\r\n if (this.selectorInfo) {\r\n setTimeout(function() {\r\n // Invoke the callback\r\n if (onSuccess) {\r\n onSuccess(self.selectorInfo);\r\n }\r\n }, 0);\r\n return;\r\n }\r\n\r\n // Otherwise, hit the web service\r\n this.trigger(\"busy\");\r\n this.dispatcher.trigger(\"add-task\", {\r\n name: \"selectors-loading\",\r\n text: \"Loading selectors...\"\r\n });\r\n $.ajax({\r\n url: this.options.selectorUrl || \"/api/selectors/GetSelectorInfo\",\r\n data: this.options.selectorData || {\r\n indicatorGroupId: this.indicatorGroupId\r\n },\r\n complete: function() {\r\n self.trigger(\"idle\");\r\n self.dispatcher.trigger(\"end-task\", { name: \"selectors-loading\" });\r\n },\r\n success: function(response) {\r\n // if there is no selected=true, select the first option\r\n function setDefaultIfMissing(items) {\r\n if (items && items.length) {\r\n var selectedItem = items.find(function(item) {\r\n return item.selected === true;\r\n });\r\n if (!selectedItem) {\r\n items[0].selected = true;\r\n }\r\n }\r\n }\r\n\r\n // are there ever more than 1 selector?? ¯\\_(ツ)_/¯\r\n var id = Object.keys(response.selectors)[0];\r\n\r\n // make sure there is a selected characteristicId\r\n setDefaultIfMissing(response.selectors[id].characteristics);\r\n\r\n // make sure there is a selected locationType\r\n setDefaultIfMissing(response.selectors[id].locationTypes);\r\n\r\n // make sure there is a selected indicatorId\r\n // setDefaultIfMissing(response.indicators); do we need this?\r\n\r\n // Save for future use\r\n self.selectorInfo = response;\r\n self.model.selectorInfo = response;\r\n\r\n // Invoke the callback\r\n if (onSuccess) {\r\n onSuccess(response);\r\n }\r\n }\r\n });\r\n },\r\n\r\n getDataSummaryText: function(selectors, propertyNames) {\r\n var texts = [];\r\n $.each(selectors, function(i, selector) {\r\n var text = selector.getDataSummaryText();\r\n if (\r\n !_.str.isBlank(text) &&\r\n (!propertyNames ||\r\n _.indexOf(propertyNames, selector.propertyName) > -1)\r\n ) {\r\n texts.push(text);\r\n }\r\n });\r\n\r\n return texts.join(\"; \");\r\n },\r\n\r\n getDataSummary: function() {\r\n return this.getDataSummaryText(this.allSelectors);\r\n },\r\n\r\n getDataSummaryByPropertyNames: function(names) {\r\n return this.getDataSummaryText(this.allSelectors, names);\r\n },\r\n /**\r\n * Gets the list of selectors specific to indicators.\r\n */\r\n getIndicatorSpecificSelectors: function() {\r\n throw \"Indicator specific selectors must be implemented in sub views.\";\r\n },\r\n\r\n /**\r\n * Default implementation: override in sub classes.\r\n */\r\n renderSelectors: function(selectorInfo) {\r\n var indicatorSpecificSelectors, indicatorSelectorInfo;\r\n\r\n // Selectors that are specific to a single indicator. This is all selectors\r\n // besides the breakdown selector.\r\n indicatorSpecificSelectors = this.getIndicatorSpecificSelectors();\r\n\r\n // Breakdown selector\r\n this.breakdownSelectorView.render(selectorInfo);\r\n\r\n // The other selectors all expect indicator-specific selector info\r\n indicatorSelectorInfo =\r\n selectorInfo.selectors[this.model.get(\"indicatorId\")];\r\n for (var i = 0; i < indicatorSpecificSelectors.length; i++) {\r\n // Render the selector\r\n indicatorSpecificSelectors[i].render(indicatorSelectorInfo);\r\n }\r\n },\r\n\r\n render: function() {\r\n var self = this;\r\n\r\n // Operate synchronously if we have selectorInfo available already. (Otherwise the data summary update happens before the selectors update, which can lead to an incorrect data summary.)\r\n if (this.selectorInfo) {\r\n this.renderSelectors(this.selectorInfo);\r\n }\r\n else {\r\n this.getSelectorInfo(function(selectorInfo) {\r\n self.renderSelectors(selectorInfo);\r\n });\r\n }\r\n }\r\n });\r\n})(jQuery, _);\r\n","(function($, _) {\r\n var ns = window.nspace(\"ccc.viz.shared.views\");\r\n\r\n /**\r\n * The source/definition/notes that appears below the map\r\n */\r\n ns.SourceDefinitionNotesView = Backbone.View.extend({\r\n el: \"#source-definition-notes-container\",\r\n name: \"Source/Definition/Notes view\",\r\n templateSelector: \"#source-definition-notes-template\",\r\n\r\n initialize: function(options) {\r\n _.bindAll(this, \"render\", \"loadTemplate\", \"getInitialRenderPromise\");\r\n\r\n this.initialRenderPromise = $.Deferred();\r\n\r\n this.selectorsModel = options.selectorsModel;\r\n\r\n this.model.on(\"change\", this.render);\r\n },\r\n\r\n getInitialRenderPromise: function() {\r\n return this.initialRenderPromise;\r\n },\r\n\r\n loadTemplate: function() {\r\n // Get the underscore template\r\n if (!this.template) {\r\n var $tmpl = $(this.templateSelector);\r\n if ($tmpl.length === 0) {\r\n throw \"Could not find the \" +\r\n this.name +\r\n \" template: \" +\r\n this.templateSelector;\r\n }\r\n\r\n // Pre-compile and cache the template\r\n this.template = _.template($tmpl.html());\r\n }\r\n },\r\n\r\n render: function() {\r\n var self = this;\r\n\r\n // Verify this selector's container is present\r\n if (this.$el.length === 0) {\r\n throw \"Could not find the \" + this.name + \" container: \" + this.el;\r\n }\r\n\r\n // Load the template\r\n this.loadTemplate();\r\n\r\n // Only rerender if the indicator has change from the last render\r\n if (this.selectorsModel.get(\"indicatorId\") === this.currentIndicatorId) {\r\n return;\r\n }\r\n\r\n this.currentIndicatorId = this.selectorsModel.get(\"indicatorId\");\r\n\r\n // Render the text\r\n var response = self.model.get(\"response\");\r\n var templateData = {\r\n source: response.source,\r\n definition: response.definition,\r\n notes: response.notes\r\n };\r\n\r\n // Render the output\r\n self.$el.html(self.template(templateData));\r\n\r\n // Animate the transition\r\n self.$el.hide().fadeIn(function() {\r\n self.initialRenderPromise.resolve();\r\n });\r\n }\r\n });\r\n})(jQuery, _);\r\n","(function($, _) {\r\n var ns = window.nspace(\"ccc.viz.shared.views\");\r\n\r\n /**\r\n * Toggles the visibility of the change indicator/location windowshade.\r\n */\r\n ns.WindowshadeView = Backbone.View.extend({\r\n /**\r\n * Using the main content container as our container.\r\n * This probably should be narrowed in scope, but it's\r\n * big enough to encompass other areas.\r\n */\r\n el: \".main-content-container\",\r\n\r\n initialize: function(options) {\r\n this.model.on(\"hrefChanged\", this.collapse, this);\r\n _.bindAll(this);\r\n },\r\n\r\n events: {\r\n \"click button.change-indicator-link-cancel\": \"collapse\",\r\n \"click button.change-indicator-link\": \"expand\"\r\n },\r\n\r\n expand: function() {\r\n this.$shade.height(this.$tabs.height());\r\n this.$tabContainer.fadeTo(750, 0, this.animateExpand);\r\n },\r\n\r\n animateExpand: function() {\r\n this.$shade.show().animate({ height: 500 }, 800);\r\n\r\n this.$indicatorContainer.fadeTo(750, 1);\r\n },\r\n\r\n collapse: function() {\r\n this.$indicatorContainer.fadeTo(750, 0);\r\n this.$shade.animate(\r\n { height: this.$tabs.height() },\r\n {\r\n duration: 800,\r\n always: this.animateCollapse\r\n }\r\n );\r\n },\r\n\r\n animateCollapse: function() {\r\n this.$shade.hide();\r\n this.$tabContainer.fadeTo(750, 1);\r\n },\r\n\r\n $shade: $(\".dc-menu__shade\"),\r\n $tabs: $(\".map-table-tab-content\"),\r\n $tabContainer: $(\".tab-container\"),\r\n $indicatorContainer: $(\".indicator-container\")\r\n });\r\n})(jQuery, _);\r\n"]}