1 line
No EOL
304 KiB
Text
1 line
No EOL
304 KiB
Text
{"version":3,"sources":["webpack:///index.js","webpack:///webpack/bootstrap 25216f7880c3d8ac65d6","webpack:///external \"winston\"","webpack:///./server/helpers/errorHandlers.js","webpack:///./server/models/index.js","webpack:///./config/siteConfig.js","webpack:///./server/helpers/googleAnalytics.js","webpack:///./server/helpers/lbryApi.js","webpack:///./server/controllers/serveController.js","webpack:///./server/speechPassport/index.js","webpack:///./server/controllers/publishController.js","webpack:///./server/helpers/publishHelpers.js","webpack:///./config/mysqlConfig.js","webpack:///external \"passport-local\"","webpack:///./server/helpers/sequelizeHelpers.js","webpack:///external \"sequelize\"","webpack:///./server/helpers/handlePageRender.jsx","webpack:///external \"react\"","webpack:///external \"react-dom/server\"","webpack:///external \"redux\"","webpack:///external \"react-redux\"","webpack:///external \"react-router-dom\"","webpack:///external \"spee.ch-components\"","webpack:///./server/helpers/renderFullPage.js","webpack:///external \"react-helmet\"","webpack:///./server/helpers/serveHelpers.js","webpack:///./server/helpers/lbryUri.js","webpack:///./server/helpers/handleShowRender.jsx","webpack:///external \"babel-polyfill\"","webpack:///external \"whatwg-fetch\"","webpack:///./server/index.js","webpack:///external \"express\"","webpack:///external \"body-parser\"","webpack:///external \"express-handlebars\"","webpack:///external \"handlebars\"","webpack:///external \"helmet\"","webpack:///external \"cookie-session\"","webpack:///external \"http\"","webpack:///./server/middleware/requestLogger.js","webpack:///external \"path\"","webpack:///./config/loggerConfig.js","webpack:///./config/slackConfig.js","webpack:///external \"winston-slack-webhook\"","webpack:///external \"passport\"","webpack:///./server/speechPassport/local-login.js","webpack:///./server/models/certificate.js","webpack:///./server/models/channel.js","webpack:///./server/models/claim.js","webpack:///./server/models/file.js","webpack:///./server/models/request.js","webpack:///./server/models/user.js","webpack:///external \"bcrypt\"","webpack:///./server/speechPassport/local-signup.js","webpack:///external \"axios\"","webpack:///./config/lbryConfig.js","webpack:///external \"universal-analytics\"","webpack:///./server/helpers/authHelpers.js","webpack:///./server/routes/auth/index.js","webpack:///./server/routes/auth/signup.js","webpack:///./server/routes/auth/login.js","webpack:///./server/routes/auth/logout.js","webpack:///./server/routes/auth/user.js","webpack:///./server/routes/api/index.js","webpack:///./server/routes/api/channelAvailability.js","webpack:///external \"fs\"","webpack:///./server/routes/api/channelClaims.js","webpack:///./server/helpers/channelPagination.js","webpack:///./server/routes/api/channelData.js","webpack:///./server/routes/api/channelShortId.js","webpack:///./server/routes/api/claimAvailability.js","webpack:///./server/routes/api/claimData.js","webpack:///./server/routes/api/claimGet.js","webpack:///./server/routes/api/claimLongId.js","webpack:///./server/routes/api/claimPublish.js","webpack:///./server/auth/authentication.js","webpack:///./server/routes/api/claimResolve.js","webpack:///./server/routes/api/claimShortId.js","webpack:///./server/routes/api/claimList.js","webpack:///./server/routes/api/fileAvailability.js","webpack:///./server/helpers/multipartMiddleware.js","webpack:///external \"connect-multiparty\"","webpack:///./server/routes/pages/index.js","webpack:///./server/routes/pages/sendReactApp.js","webpack:///./server/routes/pages/sendEmbedPage.js","webpack:///./server/routes/pages/redirect.js","webpack:///./server/routes/assets/index.js","webpack:///./server/routes/assets/serveAssetByClaim.js","webpack:///external \"redux-saga\"","webpack:///external \"redux-saga/effects\"","webpack:///./server/routes/assets/serveAssetByIdentifierAndClaim.js","webpack:///./server/routes/fallback/index.js","webpack:///./server/routes/fallback/sendReactApp.js"],"names":["module","exports","modules","__webpack_require__","moduleId","installedModules","i","l","call","m","c","d","name","getter","o","Object","defineProperty","configurable","enumerable","get","n","__esModule","object","property","prototype","hasOwnProperty","p","s","require","_slicedToArray","sliceIterator","arr","_arr","_n","_d","_e","undefined","_s","_i","Symbol","iterator","next","done","push","value","length","err","Array","isArray","TypeError","logger","handleErrorResponse","originalUrl","ip","error","res","useObjectPropertiesIfNoKeys","_module$exports$retur","returnErrorMessageAndStatus","_module$exports$retur2","status","message","json","createErrorResponsePayload","code","keys","newErrorObject","getOwnPropertyNames","forEach","key","success","Certificate","Channel","Claim","File","Request","User","Sequelize","_require","database","username","password","sequelize","host","dialect","dialectOptions","decimalNumbers","logging","pool","max","min","idle","acquire","authenticate","then","info","catch","db","import","modelName","associate","upsert","Model","values","condition","tableName","findOne","where","obj","debug","update","create","SiteConfig","_this","this","analytics","googleId","assetDefaults","description","thumbnail","title","auth","sessionKey","customComponents","customContainers","customPages","details","port","twitter","publishing","additionalClaimAddresses","disabled","disabledMessage","primaryClaimAddress","thumbnailChannel","thumbnailChannelId","uploadDirectory","routes","config","console","log","createServeEventParams","headers","eventCategory","eventAction","eventLabel","ipOverride","userAgentOverride","createPublishTimingEventParams","category","variable","label","startTime","endTime","userTimingCategory","userTimingVariableName","userTimingTime","userTimingLabel","sendGoogleAnalyticsEvent","params","visitorId","replace","ua","strictCidFormat","https","event","sendGoogleAnalyticsTiming","timing","sendGAServeEvent","sendGATimingEvent","chooseGaLbrynetPublishLabel","_ref","channelName","channel_name","channelId","channel_id","axios","_require$api","api","apiHost","apiPort","lbryApiUri","_require2","handleLbrynetResponse","resolve","reject","data","result","Error","JSON","stringify","publishClaim","publishParams","gaStartTime","Date","now","Promise","post","method","response","getClaim","uri","timeout","getClaimList","claimName","resolveUri","_ref2","getDownloadDirectory","_ref3","download_directory","createChannel","amount","returnPaginatedChannelClaims","getClaimId","channelClaimId","claimId","getClaimIdByChannel","getClaimIdByClaim","getLongClaimId","longClaimId","getLongChannelId","longChannelId","all","getClaimIdByLongChannelId","getChannelData","page","longChannelClaimId","getShortChannelIdFromLongChannelId","_ref4","shortChannelClaimId","getChannelClaims","getAllChannelClaims","_ref5","_ref6","channelClaimsArray","paginatedChannelViewData","getLocalFileRecord","file","dataValues","passport","localLoginStrategy","localSignupStrategy","serializeSpeechUser","deserializeSpeechUser","deserializeUser","serializeUser","use","_defineProperty","writable","lbryApi","publishHelpers","_require$publishing","Op","publish","fileName","fileType","publishResults","certificateId","tx","channel","fileRecord","claim_id","metadata","address","claim_address","outpoint","txid","nout","height","filePath","file_path","nsfw","claimRecord","contentType","bid","upsertCriteria","claim","setClaim","setFile","deleteTemporaryFile","claimNameIsAvailable","claimAddresses","findAll","attributes","or","checkChannelAvailability","fs","parsePublishApiRequestBody","license","exec","parsePublishApiRequestFiles","path","type","size","test","validateFileTypeAndSize","thumbnailFileName","thumbnailFilePath","thumbnailFileType","createBasicPublishParams","trim","author","language","createThumbnailPublishParams","unlink","addGetResultsToFileData","fileInfo","getResult","file_name","download_path","createFileData","mysql","warn","returnShortId","claimsArray","longId","claimIndex","shortId","substring","shortIdLength","findIndex","element","possibleMatches","slice","filter","_interopRequireDefault","default","_react","_react2","_server","_redux","_reactRedux","_reactRouterDom","_spee","_renderFullPage","_renderFullPage2","_reactHelmet","_reactHelmet2","siteConfig","req","context","MyReducers","Reducers","MyApp","App","MyGAListener","GAListener","store","createStore","html","renderToString","createElement","Provider","StaticRouter","location","url","helmet","renderStatic","redirect","preloadedState","getState","send","toString","meta","link","clientAcceptsHtml","accept","match","requestIsFromBrowser","clientWantsAsset","range","imageIsWanted","videoIsWanted","isValidClaimId","isValidShortId","isValidShortIdOrClaimId","input","serveAssetToClient","NO_FILE","verbose","sendFileOptions","X-Content-Type-Options","Content-Type","sendFile","getClaimIdAndServeAsset","fullClaimId","determineResponseType","hasFileExtension","responseType","flipClaimNameAndIdForBackwardsCompatibility","identifier","tempName","logRequestData","REGEXP_INVALID_CLAIM","REGEXP_INVALID_CHANNEL","REGEXP_ADDRESS","CHANNEL_CHAR","parseIdentifier","componentsRegex","RegExp","_componentsRegex$exec","map","_componentsRegex$exec2","proto","modifierSeperator","modifier","isChannel","startsWith","nameBadChars","join","parseClaim","_componentsRegex$exec3","_componentsRegex$exec4","parseModifier","_componentsRegex$exec5","_componentsRegex$exec6","_reduxSaga","_reduxSaga2","_effects","returnSagaWithParams","saga","regeneratorRuntime","mark","_callee","wrap","_context","prev","stop","sagaMiddleware","middleware","applyMiddleware","action","Actions","onHandleShowPageUri","Sagas","handleShowPageUri","run","Server","configureLogger","userConfig","loggerConfig","configureMysql","mysqlConfig","configureSite","configureSlack","slackConfig","configureModels","configureRoutes","createApp","app","express","enable","publicFolder","Path","process","cwd","static","publicPath","__dirname","bodyParser","urlencoded","extended","requestLogger","speechPassport","cookieSession","maxAge","initialize","session","hbs","expressHandlebars","defaultLayout","handlebars","Handlebars","engine","set","server","http","start","PORT","sync","listen","LoggerConfig","logLevel","configure","transports","Console","level","timestamp","colorize","prettyPrint","handleExceptions","humanReadableUnhandledException","silly","SlackConfig","slackWebHook","slackErrorChannel","slackInfoChannel","winston","add","winstonSlackWebHook","webhookUrl","iconEmoji","SlackWebHook","PassportLocalStrategy","Strategy","returnUserAndChannelInfo","userInstance","userInfo","id","userName","getChannel","shortChannelId","usernameField","passwordField","user","comparePassword","isMatch","STRING","BOOLEAN","INTEGER","TEXT","DECIMAL","define","claimSequence","decodedClaim","depth","effectiveAmount","hasSignature","hex","validAtHeight","valueVersion","claimType","certificateVersion","keyType","publicKey","freezeTableName","belongsTo","foreignKey","allowNull","order","getLongChannelIdFromShortChannelId","_this2","$like","getLongChannelIdFromChannelName","_this3","validateLongChannelId","_this4","hasOne","determineFileExtensionFromContentType","determineThumbnail","storedThumbnail","defaultThumbnail","prepareClaimData","licenseUrl","preview","metadataVersion","source","sourceType","sourceVersion","streamVersion","getShortClaimIdFromLongClaimId","raw","getLongClaimIdFromShortClaimId","getTopFreeClaimIdByClaimName","_this5","validateLongClaimId","_this6","resolveClaim","_this7","claimArray","defaultValue","trendingEligible","hasMany","getRecentClaims","limit","ipAddress","bcrypt","compare","changePassword","newPassword","genSalt","saltError","salt","hash","hashError","hook","options","userData","channelData","certificateData","newUser","newChannel","newCertificate","setChannel","setUser","lbryConfig","handleSignupRequest","handleLoginRequest","handleLogoutRequest","handleUserRequest","signup","login","logIn","logout","channelAvailability","channelClaims","channelShortId","claimAvailability","claimData","claimGet","claimLongId","claimPublish","claimResolve","claimShortId","claimList","fileAvailability","multipartMiddleware","_require3","availableName","body","claims","totalPages","determineTotalPages","paginationPage","getPageFromQuery","extractPageFromClaims","previousPage","determinePreviousPage","currentPage","nextPage","determineNextPage","totalResults","determineTotalClaims","parseInt","pageNumber","claimStartIndex","claimEndIndex","totalClaims","fullPages","Math","floor","channelShortIdRoute","claimInfo","resolveResult","fileData","_ref5$","completed","authenticateUser","_require4","_require5","_require6","files","channelPassword","_parsePublishApiReque","_parsePublishApiReque2","_ref3$","thumbnailPublishParams","lbryTx","authenticateChannelCredentials","userPassword","channelFindParams","resolvedUri","claimsList","multipart","uploadDir","handlePageRequest","handleEmbedRequest","handlePageRender","sendReactApp","sendEmbedPage","render","layout","route","serveAssetByClaim","serveAssetByIdentifierAndClaim","lbryUri","handleShowRender","serverAssetByClaim","serverAssetByIdentifierAndClaim","_lbryUri$parseIdentif","_flipClaimNameAndIdFo","_flipClaimNameAndIdFo2"],"mappings":"AAAAA,OAAOC,QACE,SAAUC,GCGnB,QAAAC,GAAAC,GAGA,GAAAC,EAAAD,GACA,MAAAC,GAAAD,GAAAH,OAGA,IAAAD,GAAAK,EAAAD,IACAE,EAAAF,EACAG,GAAA,EACAN,WAUA,OANAC,GAAAE,GAAAI,KAAAR,EAAAC,QAAAD,IAAAC,QAAAE,GAGAH,EAAAO,GAAA,EAGAP,EAAAC,QAvBA,GAAAI,KA4DA,OAhCAF,GAAAM,EAAAP,EAGAC,EAAAO,EAAAL,EAGAF,EAAAQ,EAAA,SAAAV,EAAAW,EAAAC,GACAV,EAAAW,EAAAb,EAAAW,IACAG,OAAAC,eAAAf,EAAAW,GACAK,cAAA,EACAC,YAAA,EACAC,IAAAN,KAMAV,EAAAiB,EAAA,SAAApB,GACA,GAAAa,GAAAb,KAAAqB,WACA,WAA2B,MAAArB,GAAA,SAC3B,WAAiC,MAAAA,GAEjC,OADAG,GAAAQ,EAAAE,EAAA,IAAAA,GACAA,GAIAV,EAAAW,EAAA,SAAAQ,EAAAC,GAAsD,MAAAR,QAAAS,UAAAC,eAAAjB,KAAAc,EAAAC,IAGtDpB,EAAAuB,EAAA,IAGAvB,IAAAwB,EAAA,MDOM,SAAU3B,EAAQC,GEpExBD,EAAAC,QAAA2B,QAAA,YF0EM,SAAU5B,EAAQC,EAASE,GAEjC,YAGA,IAAI0B,GAAiB,WAAc,QAASC,GAAcC,EAAKzB,GAAK,GAAI0B,MAAeC,GAAK,EAAUC,GAAK,EAAWC,MAAKC,EAAW,KAAM,IAAK,GAAiCC,GAA7BC,EAAKP,EAAIQ,OAAOC,cAAmBP,GAAMI,EAAKC,EAAGG,QAAQC,QAAoBV,EAAKW,KAAKN,EAAGO,QAAYtC,GAAK0B,EAAKa,SAAWvC,GAA3D2B,GAAK,IAAoE,MAAOa,GAAOZ,GAAK,EAAMC,EAAKW,EAAO,QAAU,KAAWb,GAAMK,EAAW,QAAGA,EAAW,SAAO,QAAU,GAAIJ,EAAI,KAAMC,IAAQ,MAAOH,GAAQ,MAAO,UAAUD,EAAKzB,GAAK,GAAIyC,MAAMC,QAAQjB,GAAQ,MAAOA,EAAY,IAAIQ,OAAOC,WAAYzB,QAAOgB,GAAQ,MAAOD,GAAcC,EAAKzB,EAAa,MAAM,IAAI2C,WAAU,4DG/EhlBC,EAAS/C,EAAQ,EAEvBH,GAAOC,SACLkD,oBAAqB,SAAUC,EAAaC,EAAIC,EAAOC,GACrDL,EAAOI,MAAP,YAAyBF,EAAepD,EAAOC,QAAQuD,4BAA4BF,GADzB,IAAAG,GAEhCzD,EAAOC,QAAQyD,4BAA4BJ,GAFXK,EAAA9B,EAAA4B,EAAA,GAEnDG,EAFmDD,EAAA,GAE3CE,EAF2CF,EAAA,EAG1DJ,GACGK,OAAOA,GACPE,KAAK9D,EAAOC,QAAQ8D,2BAA2BH,EAAQC,KAE5DH,4BAA6B,SAAUJ,GACrC,GAAIM,UAAQC,QAcZ,OAZmB,iBAAfP,EAAMU,MACRJ,EAAS,IACTC,EAAU,wDAGVD,EAAS,IAEPC,EADEP,EAAMO,QACEP,EAAMO,QAENP,IAGNM,EAAQC,IAElBL,4BAA6B,SAAUV,GACrC,GAAgC,IAA5B/B,OAAOkD,KAAKnB,GAAKD,OAAc,CACjC,GAAIqB,KAIJ,OAHAnD,QAAOoD,oBAAoBrB,GAAKsB,QAAQ,SAACC,GACvCH,EAAeG,GAAOvB,EAAIuB,KAErBH,EAET,MAAOpB,IAETiB,2BAnCe,SAmCaH,EAAQC,GAClC,OACED,SACAU,SAAS,EACTT,cH4FA,SAAU7D,EAAQC,EAASE,GAEjC,YIvIA,IAAMoE,GAAcpE,EAAQ,IACtBqE,EAAUrE,EAAQ,IAClBsE,EAAQtE,EAAQ,IAChBuE,EAAOvE,EAAQ,IACfwE,EAAUxE,EAAQ,IAClByE,EAAOzE,EAAQ,IAEf0E,EAAY1E,EAAQ,IACpB+C,EAAS/C,EAAQ,GJ4InB2E,EI1ImC3E,EAAQ,IAAxC4E,EJ2IQD,EI3IRC,SAAUC,EJ4IFF,EI5IEE,SAAUC,EJ6IZH,EI7IYG,SAGrBC,EAAY,GAAIL,GAAUE,EAAUC,EAAUC,GAClDE,KAAgB,YAChBC,QAAgB,QAChBC,gBAAiBC,gBAAgB,GACjCC,SAAgB,EAChBC,MACEC,IAAS,EACTC,IAAS,EACTC,KAAS,IACTC,QAAS,MAKbV,GACGW,eACAC,KAAK,WACJ5C,EAAO6C,KAAK,8DAEbC,MAAM,SAAAlD,GACLI,EAAOI,MAAM,mDAAoDR,IAIrE,IAAMmD,KACNA,GAAA,YAAoBf,EAAUgB,OAAO,cAAe3B,GACpD0B,EAAA,QAAgBf,EAAUgB,OAAO,UAAW1B,GAC5CyB,EAAA,MAAcf,EAAUgB,OAAO,QAASzB,GACxCwB,EAAA,KAAaf,EAAUgB,OAAO,OAAQxB,GACtCuB,EAAA,QAAgBf,EAAUgB,OAAO,UAAWvB,GAC5CsB,EAAA,KAAaf,EAAUgB,OAAO,OAAQtB,GAGtC1B,EAAO6C,KAAK,4BACZhF,OAAOkD,KAAKgC,GAAI7B,QAAQ,SAAA+B,GAClBF,EAAGE,GAAWC,YAChBlD,EAAO6C,KAAK,qBAAsBI,GAClCF,EAAGE,GAAWC,UAAUH,MAK5BA,EAAGf,UAAYA,EACfe,EAAGpB,UAAYA,EAEfoB,EAAGI,OAAS,SAACC,EAAOC,EAAQC,EAAWC,GACrC,MAAOH,GACJI,SACCC,MAAOH,IAERV,KAAK,SAAAc,GACJ,MAAIA,IACF1D,EAAO2D,MAAP,yBAAsCJ,GAC/BG,EAAIE,OAAOP,KAElBrD,EAAO2D,MAAP,yBAAsCJ,GAC/BH,EAAMS,OAAOR,MAGvBP,MAAM,SAAU1C,GAEf,KADAJ,GAAOI,MAASmD,EAAhB,gBAA0CnD,GACpCA,KAIZtD,EAAOC,QAAUgG,GJ+IX,SAAUjG,EAAQC,EAASE,GAEjC,YK/NA,SAAS6G,KAAc,GAAAC,GAAAC,IACrBA,MAAKC,WACHC,SAAU,WAEZF,KAAKG,eACHC,YAAa,gCACbC,UAAa,qDACbC,MAAa,WAEfN,KAAKO,MACHC,WAAY,WAEdR,KAAKS,oBACLT,KAAKU,oBACLV,KAAKW,eACLX,KAAKY,SACHR,YAAa,sDACbnC,KAAa,UACb4C,KAAa,IACbP,MAAa,UACbQ,QAAa,YAEfd,KAAKe,YACHC,4BACAC,UAA0B,EAC1BC,gBAA0B,0BAC1BC,oBAA0B,UAC1BC,iBAA0B,UAC1BC,mBAA0B,UAC1BC,gBAA0B,sBAE5BtB,KAAKuB,UACLvB,KAAKJ,OAAS,SAAC4B,GACb,IAAKA,EACH,MAAOC,SAAQC,IAAI,2BAFG,IAIhBzB,GAAiHuB,EAAjHvB,UAAWE,EAAsGqB,EAAtGrB,cAAeI,EAAuFiB,EAAvFjB,KAAME,EAAiFe,EAAjFf,iBAAkBC,EAA+Dc,EAA/Dd,iBAAkBC,EAA6Ca,EAA7Cb,YAAaC,EAAgCY,EAAhCZ,QAASG,EAAuBS,EAAvBT,WAAYQ,EAAWC,EAAXD,MAC9GE,SAAQC,IAAI,+BACZ3B,EAAKE,UAAYA,EACjBF,EAAKI,cAAgBA,EACrBJ,EAAKQ,KAAOA,EACZR,EAAKa,QAAUA,EACfb,EAAKgB,WAAaA,EAClBhB,EAAKU,iBAAmBA,EACxBV,EAAKW,iBAAmBA,EACxBX,EAAKY,YAAcA,EACnBZ,EAAKwB,OAASA,GAIlBzI,EAAOC,QAAU,GAAI+G,ILiPf,SAAUhH,EAAQC,EAASE,GAEjC,YMjSA,SAAS0I,GAAwBC,EAASzF,EAAID,GAC5C,OACE2F,cAAmB,kBACnBC,YAAmB,gBACnBC,WAAmB7F,EACnB8F,WAAmB7F,EACnB8F,kBAAmBL,EAAQ,eAI/B,QAASM,GAAgCC,EAAUC,EAAUC,EAAOC,EAAWC,GAE7E,OACEC,mBAAwBL,EACxBM,uBAAwBL,EACxBM,eAJeH,EAAUD,EAKzBK,gBAAwBN,GAI5B,QAASO,GAA0BzG,EAAI0G,GACrC,GAAMC,GAAY3G,EAAG4G,QAAQ,MAAO,IACpBC,GAAG9C,EAAU4C,GAAaG,iBAAiB,EAAOC,OAAO,IACjEC,MAAMN,EAAQ,SAACjH,GACjBA,GACFI,EAAOI,MAAM,kCAAmCR,KAKtD,QAASwH,GAA2BN,EAAWD,GAC7BG,EAAG9C,EAAU4C,GAAaG,iBAAiB,EAAOC,OAAO,IACjEG,OAAOR,EAAQ,SAACjH,GAClBA,GACFI,EAAOI,MAAM,kCAAmCR,GAElDI,EAAO2D,MAAP,wDAxCJ,GAAM3D,GAAS/C,EAAQ,GACjB+J,EAAK/J,EAAQ,IN0Sf2E,EMzSqD3E,EAAQ,GAA3CiH,EN0SPtC,EM1SPqC,UAAcC,SAAuBI,EN2SjC1C,EM3SsBgD,QAAWN,KA0C7CxH,GAAOC,SACLuK,iBADe,SACG1B,EAASzF,EAAID,GAE7B0G,EAAyBzG,EADVwF,EAAuBC,EAASzF,EAAID,KAGrDqH,kBALe,SAKIpB,EAAUC,EAAUC,EAAOC,EAAWC,GACvD,GAAMM,GAASX,EAA+BC,EAAUC,EAAUC,EAAOC,EAAWC,EACpFa,GAA0B9C,EAAOuC,IAEnCW,4BATe,SAAAC,GASoE,GAAtCC,GAAsCD,EAApDE,aAAuCC,EAAaH,EAAzBI,UACxD,OAAQH,IAAeE,EAAY,2BAA6B,6BNoT9D,SAAU9K,EAAQC,EAASE,GAEjC,YO5WA,IAAM6K,GAAQ7K,EAAQ,IAChB+C,EAAS/C,EAAQ,GPiXnB2E,EOhXkC3E,EAAQ,IPiX1C8K,EAAenG,EOjXXoG,IAAOC,EPkXDF,EOlXCE,QAASC,EPmXVH,EOnXUG,QAClBC,EAAa,UAAYF,EAAU,IAAMC,EPsX3CE,EOrXuDnL,EAAQ,GAA3DuK,EPsX0BY,EOtX1BZ,4BAA6BD,EPuXba,EOvXab,kBAE/Bc,EAAwB,SAAAZ,EAAWa,EAASC,GAAW,GAA5BC,GAA4Bf,EAA5Be,IAE/B,IADAxI,EAAO2D,MAAM,iBAAkB6E,GAC3BA,EAAKC,OAEP,MAAID,GAAKC,OAAOrI,OACdJ,EAAO2D,MAAM,qBAAsB6E,EAAKC,OAAOrI,WAC/CmI,GAAO,GAAIG,OAAMF,EAAKC,OAAOrI,aAG/BkI,GAAQE,EAAKC,OAIfF,GAAOI,KAAKC,UAAUJ,IAGxB1L,GAAOC,SACL8L,aADe,SACDC,GACZ9I,EAAO2D,MAAP,mCAAgDmF,EAAcpL,KAA9D,IACA,IAAMqL,GAAcC,KAAKC,KACzB,OAAO,IAAIC,SAAQ,SAACZ,EAASC,GAC3BT,EACGqB,KAAKhB,GACJiB,OAAQ,UACRvC,OAAQiC,IAETlG,KAAK,SAAAyG,GACJ9B,EAAkB,UAAW,UAAWC,EAA4BsB,GAAgBC,EAAaC,KAAKC,OACtGZ,EAAsBgB,EAAUf,EAASC,KAE1CzF,MAAM,SAAA1C,GACLmI,EAAOnI,QAIfkJ,SAnBe,SAmBLC,GACRvJ,EAAO2D,MAAP,iCAA8C4F,EAA9C,IACA,IAAMR,GAAcC,KAAKC,KACzB,OAAO,IAAIC,SAAQ,SAACZ,EAASC,GAC3BT,EACGqB,KAAKhB,GACJiB,OAAQ,MACRvC,QAAU0C,MAAKC,QAAS,MAEzB5G,KAAK,SAAAyG,GACJ9B,EAAkB,UAAW,WAAY,MAAOwB,EAAaC,KAAKC,OAClEZ,EAAsBgB,EAAUf,EAASC,KAE1CzF,MAAM,SAAA1C,GACLmI,EAAOnI,QAIfqJ,aArCe,SAqCDC,GACZ1J,EAAO2D,MAAP,sCAAmD+F,EAAnD,IACA,IAAMX,GAAcC,KAAKC,KACzB,OAAO,IAAIC,SAAQ,SAACZ,EAASC,GAC3BT,EACGqB,KAAKhB,GACJiB,OAAQ,aACRvC,QAAUnJ,KAAMgM,KAEjB9G,KAAK,SAAAyG,GACJ9B,EAAkB,UAAW,eAAgB,aAAcwB,EAAaC,KAAKC,OAC7EZ,EAAsBgB,EAAUf,EAASC,KAE1CzF,MAAM,SAAA1C,GACLmI,EAAOnI,QAIfuJ,WAvDe,SAuDHJ,GACVvJ,EAAO2D,MAAP,iCAA8C4F,EAA9C,IACA,IAAMR,GAAcC,KAAKC,KACzB,OAAO,IAAIC,SAAQ,SAACZ,EAASC,GAC3BT,EACGqB,KAAKhB,GACJiB,OAAQ,UACRvC,QAAU0C,SAEX3G,KAAK,SAAAgH,GAAc,GAAXpB,GAAWoB,EAAXpB,IACPjB,GAAkB,UAAW,aAAc,UAAWwB,EAAaC,KAAKC,OACpET,EAAKC,OAAOc,GAAKnJ,MACnBmI,EAAOC,EAAKC,OAAOc,GAAKnJ,OAExBkI,EAAQE,EAAKC,OAAOc,MAGvBzG,MAAM,SAAA1C,GACLmI,EAAOnI,QAIfyJ,qBA7Ee,WA8Eb7J,EAAO2D,MAAM,wEACb,IAAMoF,GAAcC,KAAKC,KACzB,OAAO,IAAIC,SAAQ,SAACZ,EAASC,GAC3BT,EACGqB,KAAKhB,GACJiB,OAAQ,iBAETxG,KAAK,SAAAkH,GAAc,GAAXtB,GAAWsB,EAAXtB,IAEP,IADAjB,EAAkB,UAAW,uBAAwB,eAAgBwB,EAAaC,KAAKC,QACnFT,EAAKC,OAGP,MAAO,IAAIC,OAAM,wFAFjBJ,GAAQE,EAAKC,OAAOsB,sBAKvBjH,MAAM,SAAA1C,GACLJ,EAAOI,MAAM,iBAAkBA,GAC/BkI,EAAQ,8BAIhB0B,cAnGe,SAmGAtM,GACbsC,EAAO2D,MAAP,mCAAgDjG,EAAhD,MACA,IAAMqL,GAAcC,KAAKC,KACzB,OAAO,IAAIC,SAAQ,SAACZ,EAASC,GAC3BT,EACGqB,KAAKhB,GACJiB,OAAQ,cACRvC,QACEc,aAAcjK,EACduM,OAAc,MAGjBrH,KAAK,SAAAyG,GACJ9B,EAAkB,UAAW,gBAAiB,cAAewB,EAAaC,KAAKC,OAC/EZ,EAAsBgB,EAAUf,EAASC,KAE1CzF,MAAM,SAAA1C,GACLmI,EAAOnI,UPqXX,SAAUtD,EAAQC,EAASE,GAEjC,YAGA,IAAI0B,GAAiB,WAAc,QAASC,GAAcC,EAAKzB,GAAK,GAAI0B,MAAeC,GAAK,EAAUC,GAAK,EAAWC,MAAKC,EAAW,KAAM,IAAK,GAAiCC,GAA7BC,EAAKP,EAAIQ,OAAOC,cAAmBP,GAAMI,EAAKC,EAAGG,QAAQC,QAAoBV,EAAKW,KAAKN,EAAGO,QAAYtC,GAAK0B,EAAKa,SAAWvC,GAA3D2B,GAAK,IAAoE,MAAOa,GAAOZ,GAAK,EAAMC,EAAKW,EAAO,QAAU,KAAWb,GAAMK,EAAW,QAAGA,EAAW,SAAO,QAAU,GAAIJ,EAAI,KAAMC,IAAQ,MAAOH,GAAQ,MAAO,UAAUD,EAAKzB,GAAK,GAAIyC,MAAMC,QAAQjB,GAAQ,MAAOA,EAAY,IAAIQ,OAAOC,WAAYzB,QAAOgB,GAAQ,MAAOD,GAAcC,EAAKzB,EAAa,MAAM,IAAI2C,WAAU,4DQpgBhlBgD,EAAK9F,EAAQ,GACb+C,EAAS/C,EAAQ,GRwgBnB2E,EQvgBqC3E,EAAQ,IAAzCiN,ERwgB2BtI,EQxgB3BsI,4BAMRpN,GAAOC,SACLoN,WADe,SACHzC,EAAa0C,EAAgB1M,EAAM2M,GAC7C,MAAI3C,GACK5K,EAAOC,QAAQuN,oBAAoB5C,EAAa0C,EAAgB1M,GAEhEZ,EAAOC,QAAQwN,kBAAkB7M,EAAM2M,IAGlDE,kBARe,SAQIb,EAAWW,GAE5B,MADArK,GAAO2D,MAAP,qBAAkC+F,EAAlC,KAAgDW,EAAhD,KACO,GAAInB,SAAQ,SAACZ,EAASC,GAC3BxF,EAAGxB,MAAMiJ,eAAed,EAAWW,GAChCzH,KAAK,SAAA6H,GACCA,GACHnC,EAjBK,YAmBPA,EAAQmC,KAET3H,MAAM,SAAA1C,GACLmI,EAAOnI,QAIfkK,oBAvBe,SAuBM5C,EAAa0C,EAAgBV,GAEhD,MADA1J,GAAO2D,MAAP,uBAAoC+D,EAApC,KAAoD0C,EAApD,KAAuEV,EAAvE,KACO,GAAIR,SAAQ,SAACZ,EAASC,GAC3BxF,EAAG1B,YAAYqJ,iBAAiBhD,EAAa0C,GAC1CxH,KAAK,SAAA+H,GACJ,MAAKA,GAGEzB,QAAQ0B,KAAKD,EAAe5H,EAAGxB,MAAMsJ,0BAA0BF,EAAejB,MAF3E,KAAM,QAIjB9G,KAAK,SAAA6E,GAAkC,GAAAmC,GAAAjL,EAAA8I,EAAA,GAAhCkD,EAAgCf,EAAA,GAAjBa,EAAiBb,EAAA,EACtC,OAAKe,GAGAF,MAGLnC,GAAQmC,GAFCnC,EAzCF,YAsCEA,EAvCA,gBA8CVxF,MAAM,SAAA1C,GACLmI,EAAOnI,QAIf0K,eA/Ce,SA+CCpD,EAAa0C,EAAgBW,GAC3C,MAAO,IAAI7B,SAAQ,SAACZ,EAASC,GAE3BxF,EAAG1B,YAAYqJ,iBAAiBhD,EAAa0C,GAC1CxH,KAAK,SAAAoI,GACJ,MAAKA,GAIE9B,QAAQ0B,KAAKI,EAAoBjI,EAAG1B,YAAY4J,mCAAmCD,EAAoBtD,MAHpG,KAAM,KAAM,QAKvB9E,KAAK,SAAAkH,GAA+C,GAAAoB,GAAAvM,EAAAmL,EAAA,GAA7CkB,EAA6CE,EAAA,GAAzBC,EAAyBD,EAAA,EACnD,KAAKF,EACH,MAAO1C,GAhEA,aAmETA,IACEZ,cACAsD,qBACAG,0BAGHrI,MAAM,SAAA1C,GACLmI,EAAOnI,QAIfgL,iBA1Ee,SA0EG1D,EAAa0C,EAAgBW,GAC7C,MAAO,IAAI7B,SAAQ,SAACZ,EAASC,GAE3BxF,EAAG1B,YAAYqJ,iBAAiBhD,EAAa0C,GAC1CxH,KAAK,SAAAoI,GACJ,MAAKA,GAIE9B,QAAQ0B,KAAKI,EAAoBjI,EAAGxB,MAAM8J,oBAAoBL,MAH3D,KAAM,KAAM,QAKvBpI,KAAK,SAAA0I,GAA8C,GAAAC,GAAA5M,EAAA2M,EAAA,GAA5CN,EAA4CO,EAAA,GAAxBC,EAAwBD,EAAA,EAClD,KAAKP,EACH,MAAO1C,GA3FA,aA8FT,IAAImD,GAA2BvB,EAA6BxC,EAAasD,EAAoBQ,EAAoBT,EAEjHzC,GAAQmD,KAET3I,MAAM,SAAA1C,GACLmI,EAAOnI,QAIfsL,mBAnGe,SAmGKrB,EAAS3M,GAC3B,MAAOqF,GAAGvB,KAAKgC,SAASC,OAAQ4G,UAAS3M,UACtCkF,KAAK,SAAA+I,GACJ,MAAKA,GAGEA,EAAKC,WA3GJ,eR2nBV,SAAU9O,EAAQC,EAASE,GAEjC,YSnoBA,IAAM4O,GAAW5O,EAAQ,IACnB6O,EAAqB7O,EAAQ,IAC7B8O,EAAsB9O,EAAQ,ITwoBhC2E,ESvoBmD3E,EAAQ,IAAvD+O,ETwoBkBpK,ESxoBlBoK,oBAAqBC,ETyoBDrK,ESzoBCqK,qBAE7BJ,GAASK,gBAAgBD,GACzBJ,EAASM,cAAcH,GACvBH,EAASO,IAAI,cAAeN,GAC5BD,EAASO,IAAI,eAAgBL,GAE7BjP,EAAOC,QAAU8O,GT6oBX,SAAU/O,EAAQC,EAASE,GAEjC,YAKA,SAASoP,GAAgB3I,EAAKvC,EAAKzB,GAAiK,MAApJyB,KAAOuC,GAAO7F,OAAOC,eAAe4F,EAAKvC,GAAOzB,MAAOA,EAAO1B,YAAY,EAAMD,cAAc,EAAMuO,UAAU,IAAkB5I,EAAIvC,GAAOzB,EAAgBgE,EAF3M,GAAI/E,GAAiB,WAAc,QAASC,GAAcC,EAAKzB,GAAK,GAAI0B,MAAeC,GAAK,EAAUC,GAAK,EAAWC,MAAKC,EAAW,KAAM,IAAK,GAAiCC,GAA7BC,EAAKP,EAAIQ,OAAOC,cAAmBP,GAAMI,EAAKC,EAAGG,QAAQC,QAAoBV,EAAKW,KAAKN,EAAGO,QAAYtC,GAAK0B,EAAKa,SAAWvC,GAA3D2B,GAAK,IAAoE,MAAOa,GAAOZ,GAAK,EAAMC,EAAKW,EAAO,QAAU,KAAWb,GAAMK,EAAW,QAAGA,EAAW,SAAO,QAAU,GAAIJ,EAAI,KAAMC,IAAQ,MAAOH,GAAQ,MAAO,UAAUD,EAAKzB,GAAK,GAAIyC,MAAMC,QAAQjB,GAAQ,MAAOA,EAAY,IAAIQ,OAAOC,WAAYzB,QAAOgB,GAAQ,MAAOD,GAAcC,EAAKzB,EAAa,MAAM,IAAI2C,WAAU,4DU5pBhlBC,EAAS/C,EAAQ,GACjB8F,EAAK9F,EAAQ,GACbsP,EAAUtP,EAAQ,GAClBuP,EAAiBvP,EAAQ,GVkqB3B2E,EUjqBsE3E,EAAQ,GVkqB9EwP,EAAsB7K,EUlqBlBmD,WAAcI,EVmqBIsH,EUnqBJtH,oBAAqBH,EVoqBZyH,EUpqBYzH,yBACrCrD,EAAY1E,EAAQ,IACpByP,EAAK/K,EAAU+K,EAErB5P,GAAOC,SACL4P,QADe,SACN7D,EAAe8D,EAAUC,GAChC,MAAO,IAAI3D,SAAQ,SAACZ,EAASC,GAC3B,GAAIuE,UAAgBC,SAAerF,QAEnC,OAAO6E,GAAQ1D,aAAaC,GACzBlG,KAAK,SAAAoK,GAIJ,MAHAhN,GAAO6C,KAAP,0BAAsCiG,EAAcpL,KAApD,IAA4DkP,EAAYI,GACxEF,EAAiBE,EAEblE,EAAcnB,cAChB3H,EAAO2D,MAAP,wCAAqDmF,EAAcnB,cAC5D5E,EAAGzB,QAAQkC,SAChBC,OACEiE,YAAaoB,EAAcnB,kBAI/B3H,EAAO2D,MAAM,6CACN,QAGVf,KAAK,SAAAqK,GAEJF,EAAgB,KAChBrF,EAAc,KACVuF,IACFF,EAAgBE,EAAQ7C,eACxB1C,EAAcuF,EAAQvF,aAExB1H,EAAO2D,MAAP,kBAA+BoJ,KAEhCnK,KAAK,WAEJ,GAAMsK,IACJxP,KAAaoL,EAAcpL,KAC3B2M,QAAayC,EAAeK,SAC5B7I,MAAawE,EAAcsE,SAAS9I,MACpCF,YAAa0E,EAAcsE,SAAShJ,YACpCiJ,QAAavE,EAAcwE,cAC3BC,SAAgBT,EAAeU,KAA/B,IAAuCV,EAAeW,KACtDC,OAAa,EACbd,WACAe,SAAa7E,EAAc8E,UAC3Bf,WACAgB,KAAa/E,EAAcsE,SAASS,MAGhCC,GACJpQ,KAAaoL,EAAcpL,KAC3B2M,QAAayC,EAAeK,SAC5B7I,MAAawE,EAAcsE,SAAS9I,MACpCF,YAAa0E,EAAcsE,SAAShJ,YACpCiJ,QAAavE,EAAcwE,cAC3BjJ,UAAayE,EAAcsE,SAAS/I,UACpCkJ,SAAgBT,EAAeU,KAA/B,IAAuCV,EAAeW,KACtDC,OAAa,EACbK,YAAalB,EACbgB,KAAa/E,EAAcsE,SAASS,KACpC5D,OAAanB,EAAckF,IAC3BjB,gBACArF,eAGIuG,GACJvQ,KAASoL,EAAcpL,KACvB2M,QAASyC,EAAeK,SAG1B,OAAOjE,SAAQ0B,KAAK7H,EAAGI,OAAOJ,EAAGvB,KAAM0L,EAAYe,EAAgB,QAASlL,EAAGI,OAAOJ,EAAGxB,MAAOuM,EAAaG,EAAgB,aAE9HrL,KAAK,SAAA6E,GAAmB,GAAAmC,GAAAjL,EAAA8I,EAAA,GAAjBkE,EAAiB/B,EAAA,GAAXsE,EAAWtE,EAAA,EAEvB,OADA5J,GAAO2D,MAAM,+CACNuF,QAAQ0B,KAAKe,EAAKwC,SAASD,GAAQA,EAAME,QAAQzC,OAEzD/I,KAAK,WACJ5C,EAAO2D,MAAM,kDACb2E,EAAQwE,KAEThK,MAAM,SAAA1C,GACLJ,EAAOI,MAAM,gBAAiBA,GAC9BoM,EAAe6B,oBAAoBvF,EAAc8E,WACjDrF,EAAOnI,QAIfkO,qBAtFe,SAsFO5Q,GACpB,GAAM6Q,GAAiBvJ,KAGvB,OAFAuJ,GAAe9O,KAAK0F,GAEbpC,EAAGxB,MACPiN,SACCC,YAAa,WACbhL,OACE/F,OACA2P,aACGX,EAAGgC,GAAKH,MAId3L,KAAK,SAAA6F,GACJ,GAAIA,EAAO9I,QAAU,EACnB,KAAM,IAAI+I,OAAM,+BAElB,OAAOhL,KAERoF,MAAM,SAAA1C,GACL,KAAMA,MAGZuO,yBA9Ge,SA8GWjR,GACxB,MAAOqF,GAAGzB,QACPkN,SACC/K,OAASiE,YAAahK,KAEvBkF,KAAK,SAAA6F,GACJ,GAAIA,EAAO9I,QAAU,EACnB,KAAM,IAAI+I,OAAM,wCAElB,OAAOhL,KAERoF,MAAM,SAAA1C,GACL,KAAMA,QVoqBR,SAAUtD,EAAQC,EAASE,GAEjC,YWxyBA,IAAM+C,GAAS/C,EAAQ,GACjB2R,EAAK3R,EAAQ,IX6yBf2E,EW3yB4B3E,EAAQ,GAAhC2H,EX4yBMhD,EW5yBNgD,QAASG,EX6yBAnD,EW7yBAmD,UAEjBjI,GAAOC,SACL8R,2BADe,SAAApH,GACmE,GAArD/J,GAAqD+J,EAArD/J,KAAMmQ,EAA+CpG,EAA/CoG,KAAMiB,EAAyCrH,EAAzCqH,QAASxK,EAAgCmD,EAAhCnD,MAAOF,EAAyBqD,EAAzBrD,YAAaC,EAAYoD,EAAZpD,SAEpE,KAAK3G,EACH,KAAM,IAAIgL,OAAM,iCAGlB,IAD8B,iBAAiBqG,KAAKrR,GAElD,KAAM,IAAIgL,OAAM,iHASlB,OANAmF,GAAiB,SAATA,EACRiB,EAAUA,GAAW,KACrBxK,EAAQA,GAAS,KACjBF,EAAcA,GAAe,KAC7BC,EAAYA,GAAa,MAGvB3G,OACAmQ,OACAiB,UACAxK,QACAF,cACAC,cAGJ2K,4BA1Be,SAAApF,GA0BiC,GAAlB+B,GAAkB/B,EAAlB+B,KAAMtH,EAAYuF,EAAZvF,SAElC,KAAKsH,EACH,KAAM,IAAIjD,OAAM,8CAElB,KAAKiD,EAAKsD,KACR,KAAM,IAAIvG,OAAM,qBAElB,KAAKiD,EAAKuD,KACR,KAAM,IAAIxG,OAAM,qBAElB,KAAKiD,EAAKwD,KACR,KAAM,IAAIzG,OAAM,qBAGlB,IAAI,IAAI0G,KAAKzD,EAAKjO,MAChB,KAAM,IAAIgL,OAAM,+CAKlB,OAFA5L,GAAOC,QAAQsS,wBAAwB1D,IAGrCiB,SAAmBjB,EAAKjO,KACxBiQ,SAAmBhC,EAAKsD,KACxBpC,SAAmBlB,EAAKuD,KACxBI,kBAAoBjL,EAAYA,EAAU3G,KAAO,KACjD6R,kBAAoBlL,EAAYA,EAAU4K,KAAO,KACjDO,kBAAoBnL,EAAYA,EAAU6K,KAAO,OAGrDG,wBAxDe,SAwDU1D,GAEvB,OAAQA,EAAKuD,MACX,IAAK,aACL,IAAK,YACL,IAAK,YACH,GAAIvD,EAAKwD,KAAO,IAEd,KADAnP,GAAO2D,MAAM,2DACP,GAAI+E,OAAM,6CAElB,MACF,KAAK,YACH,GAAIiD,EAAKwD,KAAO,IAEd,KADAnP,GAAO2D,MAAM,gDACP,GAAI+E,OAAM,4CAElB,MACF,KAAK,YACH,GAAIiD,EAAKwD,KAAO,IAEd,KADAnP,GAAO2D,MAAM,gDACP,GAAI+E,OAAM,6CAElB,MACF,SAEE,KADA1I,GAAO2D,MAAM,sDACP,GAAI+E,OAAM,OAASiD,EAAKuD,KAAO,qGAEzC,MAAOvD,IAET8D,yBArFe,SAqFW9B,EAAUjQ,EAAM4G,EAAOF,EAAa0K,EAASjB,EAAMxJ,GAC3ErE,EAAO2D,MAAP,+BAEc,OAAVW,GAAmC,KAAjBA,EAAMoL,SAC1BpL,EAAQ5G,GAGU,OAAhB0G,GAA+C,KAAvBA,EAAYsL,SACtCtL,EAAc,IAGA,OAAZ0K,GAAuC,KAAnBA,EAAQY,SAC9BZ,EAAU,IAGZ,IAAMhG,IACJpL,OACAkQ,UAAWD,EACXK,IAAW,IACXZ,UACEhJ,cACAE,QACAqL,OAAU/K,EAAQN,MAClBsL,SAAU,KACVd,UACAjB,QAEFP,cAAevI,EAAWI,oBAM5B,OAHId,KACFyE,EAAA,mBAAyCzE,GAEpCyE,GAET+G,6BAxHe,SAwHeN,EAAmB7F,EAAWoF,EAASjB,GACnE,GAAK0B,EAKL,MAFAvP,GAAO2D,MAAP,0CAGEjG,KAAcgM,EAAd,SACAkE,UAAW2B,EACXvB,IAAW,IACXZ,UACE9I,MAAgBoF,EAAhB,aACAtF,+BAAgCsF,EAChCiG,OAAa/K,EAAQN,MACrBsL,SAAa,KACbd,UACAjB,QAEFP,cAAevI,EAAWI,oBAC1BwC,aAAe5C,EAAWK,iBAC1ByC,WAAe9C,EAAWM,qBAG9BgJ,oBA/Ie,SA+IMV,GACnBiB,EAAGkB,OAAOnC,EAAU,SAAA/N,GAClB,GAAIA,EAEF,KADAI,GAAOI,MAAP,iCAA8CuN,GACxC/N,CAERI,GAAO2D,MAAP,wBAAqCgK,MAGzCoC,wBAxJe,SAwJUC,EAAUC,GAGjC,MAFAD,GAASpD,SAAWqD,EAAUC,UAC9BF,EAASrC,SAAWsC,EAAUE,cACvBH,GAETI,eA7Je,SAAAtG,GA6JkE,GAA/DpM,GAA+DoM,EAA/DpM,KAAM2M,EAAyDP,EAAzDO,QAASkD,EAAgDzD,EAAhDyD,SAAUG,EAAsC5D,EAAtC4D,OAAQL,EAA8BvD,EAA9BuD,QAASQ,EAAqB/D,EAArB+D,IAC1D,QACEnQ,OACA2M,UACAkD,WACAG,SACAL,UACAT,SAAU,GACVe,SAAU,GACVd,SAT6E/C,EAAfiE,YAU9DF,WXs0BA,SAAU/Q,EAAQC,EAASE,GAEjC,YYl/BA,SAASoT,KAAS,GAAAtM,GAAAC,IAChBA,MAAKnC,SAAW,UAChBmC,KAAKlC,SAAW,UAChBkC,KAAKjC,SAAW,UAChBiC,KAAKJ,OAAS,SAAC4B,GACb,IAAKA,EACH,MAAOxF,GAAOsQ,KAAK,4BAGrBtQ,GAAO6C,KAAK,uBALY,IAMhBhB,GAAiC2D,EAAjC3D,SAAUC,EAAuB0D,EAAvB1D,SAAUC,EAAayD,EAAbzD,QAC5BgC,GAAKlC,SAAWA,EAChBkC,EAAKjC,SAAWA,EAChBiC,EAAKhC,SAAWA,GAfpB,GAAM/B,GAAS/C,EAAQ,EAmBvBH,GAAOC,QAAU,GAAIsT,IZggCf,SAAUvT,EAAQC,GanhCxBD,EAAAC,QAAA2B,QAAA,mBbyhCM,SAAU5B,EAAQC,EAASE,GAEjC,Yc3hCAH,GAAOC,SACLwT,cAAe,SAAUC,EAAaC,GACpC,GAAIC,UACAC,EAAUF,EAAOG,UAAU,EAAG,GAC9BC,EAAgB,CAKpB,KAHAH,EAAaF,EAAYM,UAAU,SAAAC,GACjC,MAAOA,GAAQ1G,UAAYoG,KAEZ,EACf,KAAM,IAAI/H,OAAM,oCAKlB,KAFA,GAAIsI,GAAkBR,EAAYS,MAAM,EAAGP,GAEpCM,EAAgBrR,OAAS,GAC9BkR,GAAiB,EACjBF,EAAUF,EAAOG,UAAU,EAAGC,GAC9BG,EAAkBA,EAAgBE,OAAO,SAAAH,GACvC,MAAQA,GAAQ1G,SAAY0G,EAAQ1G,QAAQuG,UAAU,EAAGC,KAAmBF,GAGhF,OAAOA,MdoiCL,SAAU7T,EAAQC,Ge1jCxBD,EAAAC,QAAA2B,QAAA,cfgkCM,SAAU5B,EAAQC,EAASE,GAEjC,YAyBA,SAASkU,GAAuBzN,GAAO,MAAOA,IAAOA,EAAIvF,WAAauF,GAAQ0N,QAAS1N,GgB3lCvF,GAAA2N,GAAApU,EAAA,IhBukCIqU,EAAUH,EAAuBE,GgBtkCrCE,EAAAtU,EAAA,IACAuU,EAAAvU,EAAA,IACAwU,EAAAxU,EAAA,IACAyU,EAAAzU,EAAA,IACA0U,EAAA1U,EAAA,IAQA2U,EAAA3U,EAAA,IhBwkCI4U,EAAmBV,EAAuBS,GgBvkC9CE,EAAA7U,EAAA,IhB2kCI8U,EAAgBZ,EAAuBW,GgBzkCrCE,EAAa/U,EAAQ,EAE3BH,GAAOC,QAAU,SAACkV,EAAK5R,GACrB,GAAI6R,MAGEC,GAAa,EAAAR,EAAAS,UAASJ,GACtBK,GAAQ,EAAAV,EAAAW,KAAIN,GACZO,GAAe,EAAAZ,EAAAa,YAAWR,GAG1BS,GAAQ,EAAAjB,EAAAkB,aAAYP,GAGpBQ,GAAO,EAAApB,EAAAqB,gBACXtB,EAAAF,QAAAyB,cAAApB,EAAAqB,UAAUL,MAAOA,GACfnB,EAAAF,QAAAyB,cAAAnB,EAAAqB,cAAcC,SAAUf,EAAIgB,IAAKf,QAASA,GACxCZ,EAAAF,QAAAyB,cAACN,EAAD,KACEjB,EAAAF,QAAAyB,cAACR,EAAD,UAOFa,EAASnB,EAAAX,QAAO+B,cAGtB,IAAIjB,EAAQe,IAEV,MAAO5S,GAAI+S,SAAS,IAAKlB,EAAQe,IAMnC,IAAMI,GAAiBZ,EAAMa,UAG7BjT,GAAIkT,MAAK,EAAA1B,EAAAT,SAAe8B,EAAQP,EAAMU,IAEtC5N,QAAQC,IAAI,6ChB6lCR,SAAU5I,EAAQC,GiBtpCxBD,EAAAC,QAAA2B,QAAA,UjB4pCM,SAAU5B,EAAQC,GkB5pCxBD,EAAAC,QAAA2B,QAAA,qBlBkqCM,SAAU5B,EAAQC,GmBlqCxBD,EAAAC,QAAA2B,QAAA,UnBwqCM,SAAU5B,EAAQC,GoBxqCxBD,EAAAC,QAAA2B,QAAA,gBpB8qCM,SAAU5B,EAAQC,GqB9qCxBD,EAAAC,QAAA2B,QAAA,qBrBorCM,SAAU5B,EAAQC,GsBprCxBD,EAAAC,QAAA2B,QAAA,uBtB0rCM,SAAU5B,EAAQC,EAASE,GAEjC,YuB5rCAH,GAAOC,QAAU,SAACmW,EAAQP,EAAMU,GAE9B,yYAQYH,EAAO5O,MAAMkP,WARzB,iBASYN,EAAOO,KAAKD,WATxB,iBAUYN,EAAOQ,KAAKF,WAVxB,inBAoBiFb,EApBjF,kGAuB6ChK,KAAKC,UAAUyK,GAAgBtM,QAAQ,KAAM,OAvB1F,uHvBosCI,SAAUjK,EAAQC,GwBtsCxBD,EAAAC,QAAA2B,QAAA,iBxB4sCM,SAAU5B,EAAQC,EAASE,GAEjC,YyBpsCA,SAAS0W,GAATlM,GAAsC,GAATmM,GAASnM,EAATmM,MAC3B,OAAOA,IAAUA,EAAOC,MAAM,cAGhC,QAASC,GAAsBlO,GAC7B,MAAOA,GAAQ,eAAiBA,EAAQ,cAAciO,MAAM,WAG9D,QAASE,GAATnK,GAA4C,GAAhBgK,GAAgBhK,EAAhBgK,OAAQI,EAAQpK,EAARoK,MAC5BC,EAAgBL,GAAUA,EAAOC,MAAM,eAAiBD,EAAOC,MAAM,gBAAkBD,EAAOC,MAAM,YACpGK,EAAgBN,GAAUI,CAChC,OAAOC,IAAiBC,EAG1B,QAASC,GAAgB9J,GACvB,MAA4B,MAAnBA,EAAQ1K,SAAmB,gBAAgByP,KAAK/E,GAG3D,QAAS+J,GAAgB/J,GACvB,MAA0B,KAAnBA,EAAQ1K,OAGjB,QAAS0U,GAAyBC,GAChC,MAAQH,GAAeG,IAAUF,EAAeE,GAGlD,QAASC,GAAoBlK,EAAS3M,EAAM2C,GAC1C,MAAOqL,GAAmBrB,EAAS3M,GAChCkF,KAAK,SAAAsK,GAEJ,GAAIA,IAAesH,EACjB,MAAOnU,GAAIK,OAAO,KAAK0S,SAAhB,kBAA2C1V,EAA3C,IAAmD2M,EAH1C,IAMXsD,GAAsBT,EAAtBS,SAAUd,EAAYK,EAAZL,QACjB7M,GAAOyU,QAAP,iBAAgC9G,EAChC,IAAM+G,IACJ9O,SACE+O,yBAA0B,UAC1BC,eAA0B/H,GAAY,cAG1CxM,GAAIK,OAAO,KAAKmU,SAASlH,EAAU+G,KAEpC5R,MAAM,SAAA1C,GACL,KAAMA,KAvDZ,GAAMJ,GAAS/C,EAAQ,GzBmtCnB2E,EyBltCuC3E,EAAQ,GAA3CkN,EzBmtCSvI,EyBntCTuI,WAAYuB,EzBotCK9J,EyBptCL8J,mBzBstChBtD,EyBrtC4BnL,EAAQ,GAAhCgD,EzBstCkBmI,EyBttClBnI,oBAIFuU,EAAU,SAqDhB1X,GAAOC,SACL+X,wBADe,SACUpN,EAAa0C,EAAgBV,EAAWW,EAASnK,EAAaC,EAAIE,GAEzF8J,EAAWzC,EAAa0C,EAAgBV,EAAWW,GAChDzH,KAAK,SAAAmS,GACJ,MAxDS,aAwDLA,EACK1U,EAAIK,OAAO,KAAKE,MAAMQ,SAAS,EAAOT,QAAS,+BA1D7C,eA2DAoU,EACF1U,EAAIK,OAAO,KAAKE,MAAMQ,SAAS,EAAOT,QAAS,qCAExD4T,GAAmBQ,EAAarL,EAAWrJ,KAG5CyC,MAAM,SAAA1C,GACLH,EAAoBC,EAAaC,EAAIC,EAAOC,MAIlD2U,sBAlBe,SAkBQC,EAAkBrP,GACvC,GAAIsP,SAaJ,OAZID,IACFC,EA5EQ,QA6EJvB,EAAkB/N,KACpBsP,EA7EK,UAgFPA,EAhFO,OAiFHnB,EAAiBnO,IAAYkO,EAAqBlO,KACpD5F,EAAO2D,MAAM,0FACbuR,EApFM,UAuFHA,GAETC,4CAlCe,SAkC8BC,EAAY1X,GAEvD,GAAI2W,EAAwB3W,KAAU2W,EAAwBe,GAAa,CACzE,GAAMC,GAAW3X,CACjBA,GAAO0X,EACPA,EAAaC,EAEf,OAAQD,EAAY1X,IAEtB4X,eA3Ce,SA2CCJ,EAAcxL,EAAWhC,EAAa2C,GACpDrK,EAAO2D,MAAM,mBAAoBuR,GACjClV,EAAO2D,MAAM,kBAAmB+F,GAChC1J,EAAO2D,MAAM,mBAAoB+D,GACjC1H,EAAO2D,MAAM,eAAgB0G,MzBiuC3B,SAAUvN,EAAQC,EAASE,GAEjC,YAGA,IAAI0B,GAAiB,WAAc,QAASC,GAAcC,EAAKzB,GAAK,GAAI0B,MAAeC,GAAK,EAAUC,GAAK,EAAWC,MAAKC,EAAW,KAAM,IAAK,GAAiCC,GAA7BC,EAAKP,EAAIQ,OAAOC,cAAmBP,GAAMI,EAAKC,EAAGG,QAAQC,QAAoBV,EAAKW,KAAKN,EAAGO,QAAYtC,GAAK0B,EAAKa,SAAWvC,GAA3D2B,GAAK,IAAoE,MAAOa,GAAOZ,GAAK,EAAMC,EAAKW,EAAO,QAAU,KAAWb,GAAMK,EAAW,QAAGA,EAAW,SAAO,QAAU,GAAIJ,EAAI,KAAMC,IAAQ,MAAOH,GAAQ,MAAO,UAAUD,EAAKzB,GAAK,GAAIyC,MAAMC,QAAQjB,GAAQ,MAAOA,EAAY,IAAIQ,OAAOC,WAAYzB,QAAOgB,GAAQ,MAAOD,GAAcC,EAAKzB,EAAa,MAAM,IAAI2C,WAAU,4D0Bh1ChlBC,EAAS/C,EAAQ,EAEvBH,GAAOC,SACLwY,qBAAwB,iBACxBC,uBAAwB,kBACxBC,eAAwB,0CACxBC,aAAwB,IACxBC,gBAAwB,SAAUP,GAChCpV,EAAO2D,MAAM,sBAAuByR,EACpC,IAAMQ,GAAkB,GAAIC,QAC1B,6BAH0CC,EAMQF,EACjD7G,KAAKqG,GACLW,IAAI,SAAAlC,GAAA,MAASA,IAAS,OARmBmC,EAAArX,EAAAmX,EAAA,GAMrCG,EANqCD,EAAA,GAM9BtW,EAN8BsW,EAAA,GAMvBE,EANuBF,EAAA,GAMJG,EANIH,EAAA,EAY5C,IAHAhW,EAAO2D,MAASsS,EAAhB,KAA0BvW,EAA1B,KAAoCwW,EAApC,KAA0DC,IAGrDzW,EACH,KAAM,IAAIgJ,OAAJ,qDAA+DwN,EAA/D,IAER,IAAME,GAAY1W,EAAM2W,WAAWvZ,EAAOC,QAAQ2Y,cAC5ChO,EAAc0O,EAAY1W,EAAQ,KACpC2K,QACJ,IAAI+L,EAAW,CACb,IAAK1O,EACH,KAAM,IAAIgB,OAAM,2BAElB,IAAM4N,GAAgB5O,EAAamM,MAAM/W,EAAOC,QAAQyY,uBACxD,IAAIc,EACF,KAAM,IAAI5N,OAAJ,uCAAiD4N,EAAaC,KAAK,MAAnE,SAGRlM,GAAU3K,CAIZ,IAAI0K,SACJ,IAAI8L,EAAmB,CACrB,IAAKC,EACH,KAAM,IAAIzN,OAAJ,yCAAmDwN,EAAnD,IAGR,IAA0B,MAAtBA,EAGF,KAAM,IAAIxN,OAAJ,QAAkBwN,EAAlB,wCAFN9L,GAAiB+L,EAKrB,OACEC,YACA1O,cACA0C,iBACAC,YAGJmM,WAAY,SAAUtI,GACpBlO,EAAO2D,MAAM,gBAAiBuK,EAC9B,IAAM0H,GAAkB,GAAIC,QAC1B,+BAHyBY,EAM6Bb,EACrD7G,KAAKb,GACL6H,IAAI,SAAAlC,GAAA,MAASA,IAAS,OARE6C,EAAA/X,EAAA8X,EAAA,GAMpBR,EANoBS,EAAA,GAMbhN,EANagN,EAAA,GAMFR,EANEQ,EAAA,GAMiBP,EANjBO,EAAA,EAY3B,IAHA1W,EAAO2D,MAASsS,EAAhB,KAA0BvM,EAA1B,KAAwCwM,EAAxC,KAA8DC,IAGzDzM,EACH,KAAM,IAAIhB,OAAM,kCAElB,IAAM4N,GAAgB5M,EAAWmK,MAAM/W,EAAOC,QAAQwY,qBACtD,IAAIe,EACF,KAAM,IAAI5N,OAAJ,qCAA+C4N,EAAaC,KAAK,MAAjE,IAGR,IAAIL,EAAmB,CACrB,IAAKC,EACH,KAAM,IAAIzN,OAAJ,8CAAwDwN,EAAxD,IAER,IAA0B,MAAtBA,EACF,KAAM,IAAIxN,OAAJ,OAAiBwN,EAAjB,gDAIV,OACExM,cAGJiN,cAAe,SAAUzI,GACvBlO,EAAO2D,MAAM,oBAAqBuK,EAClC,IAAM0H,GAAkB,GAAIC,QAC1B,+BAH4Be,EAM0BhB,EACrD7G,KAAKb,GACL6H,IAAI,SAAAlC,GAAA,MAASA,IAAS,OARKgD,EAAAlY,EAAAiY,EAAA,GAMvBX,EANuBY,EAAA,GAMhBnN,EANgBmN,EAAA,GAMLX,EANKW,EAAA,GAMcV,EANdU,EAAA,EAS9B7W,GAAO2D,MAASsS,EAAhB,KAA0BvM,EAA1B,KAAwCwM,EAAxC,KAA8DC,EAE9D,IAAIlB,IAAmB,CAIvB,OAHIiB,KACFjB,GAAmB,IAGnBA,uB1B22CA,SAAUnY,EAAQC,EAASE,GAEjC,YA+BA,SAASkU,GAAuBzN,GAAO,MAAOA,IAAOA,EAAIvF,WAAauF,GAAQ0N,QAAS1N,G2Bt/CvF,GAAA2N,GAAApU,EAAA,I3B49CIqU,EAAUH,EAAuBE,G2B39CrCE,EAAAtU,EAAA,IACAuU,EAAAvU,EAAA,IACAwU,EAAAxU,EAAA,IACAyU,EAAAzU,EAAA,IACA2U,EAAA3U,EAAA,I3Bm+CI4U,EAAmBV,EAAuBS,G2Bl+C9CkF,EAAA7Z,EAAA,I3Bs+CI8Z,EAAc5F,EAAuB2F,G2Br+CzCE,EAAA/Z,EAAA,IACA0U,EAAA1U,EAAA,IAQA6U,EAAA7U,EAAA,I3Bo+CI8U,EAAgBZ,EAAuBW,G2Bj+CrCE,EAAa/U,EAAQ,GACrBkV,GAAa,EAAAR,EAAAS,UAASJ,GACtBK,GAAQ,EAAAV,EAAAW,KAAIN,GACZO,GAAe,EAAAZ,EAAAa,YAAWR,GAE1BiF,EAAuB,SAACC,EAAMrQ,GAClC,MAAAsQ,oBAAAC,KAAO,QAAAC,KAAA,MAAAF,oBAAAG,KAAA,SAAAC,GAAA,cAAAA,EAAAC,KAAAD,EAAAhY,MAAA,aAAAgY,GAAAhY,KAAA,GACC,EAAAyX,EAAA1Z,MAAK4Z,EAAMrQ,EADZ,wBAAA0Q,GAAAE,SAAAJ,EAAArT,QAKTlH,GAAOC,QAAU,SAACkV,EAAK5R,GACrB,GAAI6R,MAGEwF,GAAiB,EAAAX,EAAA3F,WACjBuG,GAAa,EAAAnG,EAAAoG,iBAAgBF,GAG7BjF,GAAQ,EAAAjB,EAAAkB,aAAYP,EAAYwF,GAGhCE,EAASlG,EAAAmG,QAAQC,oBAAoB9F,EAAIpL,QACzCqQ,EAAOD,EAAqBtF,EAAAqG,MAAMC,kBAAmBJ,EAG3DH,GACGQ,IAAIhB,GACJ1X,KACAoD,KAAK,WAEJ,GAAM+P,IAAO,EAAApB,EAAAqB,gBACXtB,EAAAF,QAAAyB,cAAApB,EAAAqB,UAAUL,MAAOA,GACfnB,EAAAF,QAAAyB,cAAAnB,EAAAqB,cAAcC,SAAUf,EAAIgB,IAAKf,QAASA,GACxCZ,EAAAF,QAAAyB,cAACN,EAAD,KACEjB,EAAAF,QAAAyB,cAACR,EAAD,UAOFa,EAASnB,EAAAX,QAAO+B,cAGtB,IAAIjB,EAAQe,IACV,MAAO5S,GAAI+S,SAAS,IAAKlB,EAAQe,IAInC,IAAMI,GAAiBZ,EAAMa,UAG7BjT,GAAIkT,MAAK,EAAA1B,EAAAT,SAAe8B,EAAQP,EAAMU,MAG1C5N,QAAQC,IAAI,6C3BigDR,SAAU5I,EAAQC,EAASE,GAEjCA,EAAoB,IACpBA,EAAoB,IACpBH,EAAOC,QAAUE,EAAoB,KAK/B,SAAUH,EAAQC,G4BrlDxBD,EAAAC,QAAA2B,QAAA,mB5B2lDM,SAAU5B,EAAQC,G6B3lDxBD,EAAAC,QAAA2B,QAAA,iB7BimDM,SAAU5B,EAAQC,EAASE,GAEjC,Y8BnlDA,SAASkb,KAAU,GAAApU,GAAAC,IACjBA,MAAKoU,gBAAkB,SAACC,GACtBC,EAAa1U,OAAOyU,IAEtBrU,KAAKuU,eAAiB,SAACF,GACrBG,EAAY5U,OAAOyU,IAErBrU,KAAKyU,cAAgB,SAACJ,GACpBrG,EAAWpO,OAAOyU,IAEpBrU,KAAK0U,eAAiB,SAACL,GACrBM,EAAY/U,OAAOyU,IAErBrU,KAAK4U,gBAAkB,WACrB5Y,EAAO2D,MAAM,6DAEfK,KAAK6U,gBAAkB,WACrB7Y,EAAO2D,MAAM,6DAEfK,KAAK8U,UAAY,WAEf,GAAMC,GAAMC,GASZ,IANAD,EAAIE,OAAO,eAIXF,EAAI3M,IAAI8G,KAEJlB,EAAWzM,OAAO2T,aAAc,CAElC,GAAMA,GAAeC,EAAK7Q,QAAQ8Q,QAAQC,MAAOrH,EAAWzM,OAAO2T,aACnEH,GAAI3M,IAAI4M,EAAQM,OAAOJ,IACvBlZ,EAAO6C,KAAK,yCAA0CqW,OACjD,CACL,GAAMK,GAAaJ,EAAK7Q,QAAQkR,UAAW,SAC3CT,GAAI3M,IAAI4M,EAAQM,OAAOC,IACvBvZ,EAAO6C,KAAK,0CAA2C0W,GAGzDR,EAAI3M,IAAIqN,EAAW7Y,QAEnBmY,EAAI3M,IAAIqN,EAAWC,YAAaC,UAAU,KAG1CZ,EAAI3M,IAAIwN,EAGR,IAAMC,GAAiB5c,EAAQ,GAEzBuH,EAAawN,EAAWzN,KAAKC,UACnCuU,GAAI3M,IAAI0N,GACNpc,KAAQ,UACRqD,MAASyD,GACTuV,OAAQ,SAEVhB,EAAI3M,IAAIyN,EAAeG,cACvBjB,EAAI3M,IAAIyN,EAAeI,UAGvB,IAAMC,GAAMC,EAAkBtW,QAC5BuW,cAAe,QACfC,WAAeC,GAEjBvB,GAAIwB,OAAO,aAAcL,EAAIK,QAC7BxB,EAAIyB,IAAI,cAAe,cAGvBvd,EAAQ,IAAkB8b,GAC1B9b,EAAQ,IAAiB8b,GACzB9b,EAAQ,IAAmB8b,GAC3B9b,EAAQ,IAAoB8b,GAC5B9b,EAAQ,IAAsB8b,GAE9BhV,EAAKgV,IAAMA,GAEb/U,KAAKgW,WAAa,WAChBjW,EAAK+U,YACL/U,EAAK0W,OAASC,EAAKvC,OAAOpU,EAAKgV,MAEjC/U,KAAK2W,MAAQ,WACX,GAAM5X,GAAK9F,EAAQ,GACb2d,EAAO5I,EAAWpN,QAAQC,IAEhC9B,GAAGf,UAAU6Y,OAEVjY,KAAK,WACJmB,EAAK0W,OAAOK,OAAOF,EAAM,WACvB5a,EAAO6C,KAAP,+BAA2C+X,OAG9C9X,MAAM,SAAC1C,GACNJ,EAAOI,MAAP,iBAA+BA,MA5GvC,GAAM4Y,GAAU/b,EAAQ,IAClBwc,EAAaxc,EAAQ,IACrBkd,EAAoBld,EAAQ,IAC5Bqd,EAAard,EAAQ,IACrBiW,EAASjW,EAAQ,IACjB6c,EAAgB7c,EAAQ,IACxByd,EAAOzd,EAAQ,IACf+C,EAAS/C,EAAQ,GACjB2c,EAAgB3c,EAAQ,IACxBkc,EAAOlc,EAAQ,IACfqb,EAAerb,EAAQ,IACvBub,EAAcvb,EAAQ,IACtB+U,EAAa/U,EAAQ,GACrB0b,EAAc1b,EAAQ,GAoG5BH,GAAOC,QAAUob,G9B2mDX,SAAUrb,EAAQC,G+B7tDxBD,EAAAC,QAAA2B,QAAA,Y/BmuDM,SAAU5B,EAAQC,GgCnuDxBD,EAAAC,QAAA2B,QAAA,gBhCyuDM,SAAU5B,EAAQC,GiCzuDxBD,EAAAC,QAAA2B,QAAA,uBjC+uDM,SAAU5B,EAAQC,GkC/uDxBD,EAAAC,QAAA2B,QAAA,elCqvDM,SAAU5B,EAAQC,GmCrvDxBD,EAAAC,QAAA2B,QAAA,WnC2vDM,SAAU5B,EAAQC,GoC3vDxBD,EAAAC,QAAA2B,QAAA,mBpCiwDM,SAAU5B,EAAQC,GqCjwDxBD,EAAAC,QAAA2B,QAAA,SrCuwDM,SAAU5B,EAAQC,EAASE,GAEjC,YsCzwDA,IAAM+C,GAAS/C,EAAQ,GAEjB2c,EAAgB,SAAC3H,EAAK5R,EAAKd,GAC/BS,EAAOyU,QAAP,cAA6BxC,EAAI/R,YAAjC,SAAqD+R,EAAI9R,IACzDZ,IAGFzC,GAAOC,QAAU6c,GtCixDX,SAAU9c,EAAQC,GuCxxDxBD,EAAAC,QAAA2B,QAAA,SvC8xDM,SAAU5B,EAAQC,EAASE,GAEjC,YwC9xDA,SAAS8d,KAAgB,GAAAhX,GAAAC,IACvBA,MAAKgX,SAAW,QAChBhX,KAAKJ,OAAS,SAAC4B,GACb,IAAKA,EACH,MAAOxF,GAAOsQ,KAAK,6BAErBtQ,GAAO6C,KAAK,gCAJY,IAMjBmY,GAAYxV,EAAZwV,QACPjX,GAAKiX,SAAWA,EAEhBhb,EAAOib,WACLC,YACE,GAAKlb,GAAOkb,WAAWC,SACrBC,MAAiCrX,EAAKiX,SACtCK,WAAiC,EACjCC,UAAiC,EACjCC,aAAiC,EACjCC,kBAAiC,EACjCC,iCAAiC,OAKvCzb,EAAO6C,KAAK,iCACZ7C,EAAOI,MAAM,WACbJ,EAAOsQ,KAAK,WACZtQ,EAAO6C,KAAK,WACZ7C,EAAOyU,QAAQ,WACfzU,EAAO2D,MAAM,WACb3D,EAAO0b,MAAM,YAhCjB,GAAM1b,GAAS/C,EAAQ,EAoCvBH,GAAOC,QAAU,GAAIge,IxCwyDf,SAAUje,EAAQC,EAASE,GAEjC,YyC30DA,SAAS0e,KAAe,GAAA5X,GAAAC,IACtBA,MAAK4X,aAAoB,UACzB5X,KAAK6X,kBAAoB,UACzB7X,KAAK8X,iBAAoB,UACzB9X,KAAKJ,OAAS,SAAC4B,GACb,IAAKA,EACH,MAAOuW,GAAQzL,KAAK,2BAGtByL,GAAQlZ,KAAK,8BALW,IAMjB+Y,GAAqDpW,EAArDoW,aAAcC,EAAuCrW,EAAvCqW,kBAAmBC,EAAoBtW,EAApBsW,gBACxC/X,GAAK6X,aAAeA,EACpB7X,EAAK8X,kBAAoBA,EACzB9X,EAAK+X,iBAAmBA,EAEpB/X,EAAK6X,cAEH7X,EAAK8X,mBACPE,EAAQC,IAAIC,GACVve,KAAY,yBACZ0d,MAAY,OACZc,WAAYnY,EAAK6X,aACjB3O,QAAYlJ,EAAK8X,kBACjB/Z,SAAY,UACZqa,UAAY,6BAGZL,GACFC,EAAQC,IAAIC,GACVve,KAAY,uBACZ0d,MAAY,OACZc,WAAYnY,EAAK6X,aACjB3O,QAAYlJ,EAAK+X,iBACjBha,SAAY,UACZqa,UAAY,gBAIhBJ,EAAQlZ,KAAK,2BACbkZ,EAAQ3b,MAAM,oCACd2b,EAAQlZ,KAAK,oCAEbkZ,EAAQzL,KAAK,8EA7CnB,GAAM2L,GAAsBhf,EAAQ,IAAyBmf,aACvDL,EAAU9e,EAAQ,EAiDxBH,GAAOC,QAAU,GAAI4e,IzC01Df,SAAU7e,EAAQC,G0C54DxBD,EAAAC,QAAA2B,QAAA,0B1Ck5DM,SAAU5B,EAAQC,G2Cl5DxBD,EAAAC,QAAA2B,QAAA,a3Cw5DM,SAAU5B,EAAQC,EAASE,GAEjC,Y4C15DA,IAAMof,GAAwBpf,EAAQ,IAAkBqf,SAClDtc,EAAS/C,EAAQ,GACjB8F,EAAK9F,EAAQ,GAEbsf,EAA2B,SAACC,GAChC,MAAO,IAAItT,SAAQ,SAACZ,EAASC,GAC3B,GAAIkU,KACJA,GAAA,GAAiBD,EAAaE,GAC9BD,EAAA,SAAuBD,EAAaG,SACpCH,EACGI,aACAha,KAAK,SAAA6E,GAAmC,GAAjCC,GAAiCD,EAAjCC,YAAa0C,EAAoB3C,EAApB2C,cAGnB,OAFAqS,GAAA,YAA0B/U,EAC1B+U,EAAA,eAA6BrS,EACtBrH,EAAG1B,YAAY4J,mCAAmCb,EAAgB1C,KAE1E9E,KAAK,SAAAia,GACJJ,EAAA,eAA6BI,EAC7BvU,EAAQmU,KAET3Z,MAAM,SAAA1C,GACLmI,EAAOnI,OAKftD,GAAOC,QAAU,GAAIsf,IAEjBS,cAAe,WACfC,cAAe,YAEjB,SAACjb,EAAUC,EAAUvC,GACnB,MAAOuD,GAAGrB,KACP8B,SACCC,OAAQkZ,SAAU7a,KAEnBc,KAAK,SAAAoa,GACJ,MAAKA,GAIEA,EAAKC,gBAAgBlb,GACzBa,KAAK,SAAAsa,GACJ,MAAKA,IAILld,EAAO2D,MAAM,wCACN4Y,EAAyBS,GAC7Bpa,KAAK,SAAA6Z,GACJ,MAAOjd,GAAK,KAAMid,KAEnB3Z,MAAM,SAAA1C,GACL,MAAOA,OATTJ,EAAO2D,MAAM,sBACNnE,EAAK,MAAM,GAAQmB,QAAS,sCAWtCmC,MAAM,SAAA1C,GACL,MAAOA,MAnBTJ,EAAO2D,MAAM,iBACNnE,EAAK,MAAM,GAAQmB,QAAS,sCAqBtCmC,MAAM,SAAA1C,GACL,MAAOZ,GAAKY,Q5Cy5Dd,SAAUtD,EAAQC,EAASE,GAEjC,Y6Cx9DA,IAAM+C,GAAS/C,EAAQ,G7C69DnB2E,E6C59DsB3E,EAAQ,IAA1BsT,E7C69DY3O,E6C79DZ2O,aAERzT,GAAOC,QAAU,SAACiF,EAADyF,GAA4D,GAA9C0V,GAA8C1V,EAA9C0V,OAAQC,EAAsC3V,EAAtC2V,QAASC,EAA6B5V,EAA7B4V,QAASC,EAAoB7V,EAApB6V,KAAMC,EAAc9V,EAAd8V,QACvDlc,EAAcW,EAAUwb,OAC5B,eAEEnQ,SACE6B,KAASiO,EACT/L,QAAS,MAEXnH,QACEiF,KAASqO,EAAQ,GAAI,GACrBnM,QAAS,MAEX/G,SACE6E,KAASiO,EACT/L,QAAS,MAEXqM,eACEvO,KAASmO,EACTjM,QAAS,MAEXsM,cACExO,KAASkO,EACThM,QAAS,MAEXuM,OACEzO,KAASmO,EACTjM,QAAS,MAEXwM,iBACE1O,KAASqO,EAAQ,GAAI,GACrBnM,QAAS,MAEXyM,cACE3O,KAASkO,EACThM,QAAS,MAEX1D,QACEwB,KAASmO,EACTjM,QAAS,MAEX0M,KACE5O,KAASoO,EAAK,QACdlM,QAAS,MAEX1T,MACEwR,KAASiO,EACT/L,QAAS,MAEX3D,MACEyB,KAASmO,EACTjM,QAAS,MAEX5D,MACE0B,KAASiO,EACT/L,QAAS,MAEX2M,eACE7O,KAASmO,EACTjM,QAAS,MAEX7D,UACE2B,KAASiO,EACT/L,QAAS,MAEX4M,cACE9O,KAASiO,EACT/L,QAAS,MAEX6M,WACE/O,KAASiO,EACT/L,QAAS,MAEX8M,oBACEhP,KAASiO,EACT/L,QAAS,MAEX+M,SACEjP,KAASiO,EACT/L,QAAS,MAEXgN,WACElP,KAASoO,EAAK,QACdlM,QAAS,QAIXiN,iBAAiB,GAgHrB,OA5GAhd,GAAY6B,UAAY,SAAAH,GACtB1B,EAAYid,UAAUvb,EAAGzB,SACvBid,YACEC,WAAW,MAKjBnd,EAAY4J,mCAAqC,SAAUN,EAAejD,GAAa,GAAA3D,GAAAC,IAErF,OADAhE,GAAO2D,MAAP,sCAAmD+D,EAAnD,IAAkEiD,GAC3D,GAAIzB,SAAQ,SAACZ,EAASC,GAC3BxE,EACGyK,SACC/K,OAAQ/F,KAAMgK,GACd+W,QAAS,SAAU,UAEpB7b,KAAK,SAAA6F,GACJ,OAAQA,EAAO9I,QACb,IAAK,GACH,KAAM,IAAI+I,OAAM,6CAClB,SACE,MAAOJ,GAAQiI,EAAc9H,EAAQkC,OAG1C7H,MAAM,SAAA1C,GACLmI,EAAOnI,QAKfiB,EAAYqd,mCAAqC,SAAUhX,EAAa0C,GAAgB,GAAAuU,GAAA3a,IAEtF,OADAhE,GAAO2D,MAAP,sCAAmD+D,EAAnD,KAAmE0C,EAAnE,KACO,GAAIlB,SAAQ,SAACZ,EAASC,GAC3BoW,EACGnQ,SACC/K,OACE/F,KAASgK,EACT2C,SACEuU,MAAUxU,EAAV,MAGJqU,QAAS,SAAU,UAEpB7b,KAAK,SAAA6F,GACJ,OAAQA,EAAO9I,QACb,IAAK,GACH,MAAO2I,GAAQ,KACjB,SACE,MAAOA,GAAQG,EAAO,GAAG4B,YAG9BvH,MAAM,SAAA1C,GACLmI,EAAOnI,QAKfiB,EAAYwd,gCAAkC,SAAUnX,GAAa,GAAAoX,GAAA9a,IAEnE,OADAhE,GAAO2D,MAAP,mCAAgD+D,EAAhD,KACO,GAAIwB,SAAQ,SAACZ,EAASC,GAC3BuW,EACGtQ,SACC/K,OAAS/F,KAAMgK,GACf+W,QAAS,kBAAmB,SAAU,SAAU,UAEjD7b,KAAK,SAAA6F,GACJ,OAAQA,EAAO9I,QACb,IAAK,GACH,MAAO2I,GAAQ,KACjB,SACE,MAAOA,GAAQG,EAAO,GAAG4B,YAG9BvH,MAAM,SAAA1C,GACLmI,EAAOnI,QAKfiB,EAAY0d,sBAAwB,SAAUrhB,EAAM2M,GAAS,GAAA2U,GAAAhb,IAE3D,OADAhE,GAAO2D,MAAP,yBAAsCjG,EAAtC,KAA+C2M,EAA/C,KACO,GAAInB,SAAQ,SAACZ,EAASC,GAC3ByW,EAAKxb,SACHC,OAAQ/F,OAAM2M,aAEbzH,KAAK,SAAA6F,GACJ,IAAKA,EACH,MAAOH,GAAQ,KAEjBA,GAAQ+B,KAETvH,MAAM,SAAA1C,GACLmI,EAAOnI,QAKfiB,EAAYqJ,iBAAmB,SAAUhD,EAAa0C,GAEpD,MADApK,GAAO2D,MAAP,oBAAiC+D,EAAjC,KAAiD0C,EAAjD,KACIA,GAA6C,KAA1BA,EAAezK,OAC7BqE,KAAK+a,sBAAsBrX,EAAa0C,GACtCA,GAAkBA,EAAezK,OAAS,GAC5CqE,KAAK0a,mCAAmChX,EAAa0C,GAErDpG,KAAK6a,gCAAgCnX,IAIzCrG,I7Co+DH,SAAUvE,EAAQC,EAASE,GAEjC,Y8C/qEAH,GAAOC,QAAU,SAACiF,EAADyF,GAA2B,GAAb0V,GAAa1V,EAAb0V,OACvB7b,EAAUU,EAAUwb,OACxB,WAEE9V,aACEwH,KAAWiO,EACXqB,WAAW,GAEbpU,gBACE8E,KAAWiO,EACXqB,WAAW,KAIbH,iBAAiB,GASrB,OALA/c,GAAQ4B,UAAY,SAAAH,GAClBzB,EAAQgd,UAAUvb,EAAGrB,MACrBJ,EAAQ2d,OAAOlc,EAAG1B,cAGbC,I9CqrEH,SAAUxE,EAAQC,EAASE,GAEjC,Y+C1sEA,SAASiiB,GAAuCnR,GAC9C,OAAQA,GACN,IAAK,aACL,IAAK,YACH,MAAO,MACT,KAAK,YACH,MAAO,KACT,KAAK,YACH,MAAO,KACT,KAAK,YACH,MAAO,KACT,SAEE,MADA/N,GAAO2D,MAAM,oDACN,QAIb,QAASwb,GAAoBC,EAAiBC,GAC5C,MAAwB,KAApBD,EACKC,EAEFD,EAGT,QAASE,GAAkBpR,GAKzB,MAHAA,GAAA,UAAqBiR,EAAmBjR,EAAM7J,UAAWgb,GACzDnR,EAAA,QAAmBgR,EAAsChR,EAAMH,aAC/DG,EAAA,KAAgBjM,EACTiM,EAjCT,GAAMlO,GAAS/C,EAAQ,G/CmtEnB2E,E+CltEsB3E,EAAQ,IAA1BsT,E/CmtEY3O,E+CntEZ2O,c/CqtEJnI,E+CptE0EnL,EAAQ,GAAlDoiB,E/CqtEbjX,E+CrtEfjE,cAAiBE,UAA0CpC,E/CstExDmG,E+CttE6CxD,QAAW3C,IAkCnEnF,GAAOC,QAAU,SAACiF,EAADyF,GAA4D,GAA9C0V,GAA8C1V,EAA9C0V,OAAQC,EAAsC3V,EAAtC2V,QAASC,EAA6B5V,EAA7B4V,QAASC,EAAoB7V,EAApB6V,KAAMC,EAAc9V,EAAd8V,QACvDhc,EAAQS,EAAUwb,OACtB,SAEEnQ,SACE6B,KAASiO,EACT/L,QAAS,MAEXnH,QACEiF,KAASqO,EAAQ,GAAI,GACrBnM,QAAS,MAEX/G,SACE6E,KAASiO,EACT/L,QAAS,MAEXqM,eACEvO,KAASmO,EACTjM,QAAS,MAEXsM,cACExO,KAASkO,EACThM,QAAS,MAEXuM,OACEzO,KAASmO,EACTjM,QAAS,MAEXwM,iBACE1O,KAASqO,EAAQ,GAAI,GACrBnM,QAAS,MAEXyM,cACE3O,KAASkO,EACThM,QAAS,MAEX1D,QACEwB,KAASmO,EACTjM,QAAS,MAEX0M,KACE5O,KAASoO,EAAK,QACdlM,QAAS,MAEX1T,MACEwR,KAASiO,EACT/L,QAAS,MAEX3D,MACEyB,KAASmO,EACTjM,QAAS,MAEX5D,MACE0B,KAASiO,EACT/L,QAAS,MAEX2M,eACE7O,KAASmO,EACTjM,QAAS,MAEX7D,UACE2B,KAASiO,EACT/L,QAAS,MAEX6M,WACE/O,KAASiO,EACT/L,QAAS,MAEXrE,eACEmC,KAASiO,EACT/L,QAAS,MAEXzB,QACET,KAASiO,EACT/L,QAAS,MAEXhN,aACE8K,KAASoO,EAAK,QACdlM,QAAS,MAEXxB,UACEV,KAASiO,EACT/L,QAAS,MAEXtC,SACEI,KAASiO,EACT/L,QAAS,MAEXmO,YACErQ,KAASiO,EACT/L,QAAS,MAEXvD,MACEqB,KAASkO,EACThM,QAAS,MAEXoO,SACEtQ,KAASiO,EACT/L,QAAS,MAEX/M,WACE6K,KAASiO,EACT/L,QAAS,MAEX9M,OACE4K,KAASiO,EACT/L,QAAS,MAEXqO,iBACEvQ,KAASiO,EACT/L,QAAS,MAEXrD,aACEmB,KAASiO,EACT/L,QAAS,MAEXsO,QACExQ,KAASiO,EACT/L,QAAS,MAEXuO,YACEzQ,KAASiO,EACT/L,QAAS,MAEXwO,eACE1Q,KAASiO,EACT/L,QAAS,MAEXyO,eACE3Q,KAASiO,EACT/L,QAAS,MAEX4M,cACE9O,KAASiO,EACT/L,QAAS,MAEX1J,aACEwH,KAAWiO,EACXqB,WAAW,EACXpN,QAAW,QAIbiN,iBAAiB,GA2LrB,OAvLA9c,GAAM2B,UAAY,SAAAH,GAChBxB,EAAM+c,UAAUvb,EAAGvB,MACjB+c,YACEC,WAAW,MAKjBjd,EAAMue,+BAAiC,SAAUzV,EAASX,GAAW,GAAA3F,GAAAC,IAEnE,OADAhE,GAAO2D,MAAP,4CAAyD+F,EAAzD,IAAsEW,GAC/D,GAAInB,SAAQ,SAACZ,EAASC,GAC3BxE,EACGyK,SACC/K,OAAS/F,KAAMgM,GACf+U,QAAS,SAAU,UAEpB7b,KAAK,SAAA6F,GACJ,OAAQA,EAAO9I,QACb,IAAK,GACH,KAAM,IAAI+I,OAAM,yCAClB,SACEJ,EAAQiI,EAAc9H,EAAQ4B,OAGnCvH,MAAM,SAAA1C,GACLmI,EAAOnI,QAKfmB,EAAM8J,oBAAsB,SAAUjB,GAAgB,GAAAuU,GAAA3a,IAEpD,OADAhE,GAAO2D,MAAP,iCAA8CyG,GACvC,GAAIlB,SAAQ,SAACZ,EAASC,GAC3BoW,EACGnQ,SACC/K,OAASsJ,cAAe3C,GACxBqU,QAAS,SAAU,QACnBsB,KAAO,IAERnd,KAAK,SAAA4I,GAEJ,OAAQA,EAAmB7L,QACzB,IAAK,GACH,MAAO2I,GAAQ,KACjB,SAME,MALAkD,GAAmBtK,QAAQ,SAAAgN,GAGzB,MAFAA,GAAA,QAAmBgR,EAAsChR,EAAMH,aAC/DG,EAAA,UAAqBiR,EAAmBjR,EAAM7J,UAAWgb,GAClDnR,IAEF5F,EAAQkD,MAGpB1I,MAAM,SAAA1C,GACLmI,EAAOnI,QAKfmB,EAAMsJ,0BAA4B,SAAUT,EAAgBV,GAAW,GAAAoV,GAAA9a,IAErE,OADAhE,GAAO2D,MAAP,8BAA2C+F,EAA3C,iBAAqEU,GAC9D,GAAIlB,SAAQ,SAACZ,EAASC,GAC3BuW,EACGtQ,SACC/K,OAAS/F,KAAMgM,EAAWqD,cAAe3C,GACzCqU,QAAS,KAAM,UAEhB7b,KAAK,SAAA6F,GACJ,OAAQA,EAAO9I,QACb,IAAK,GACH,MAAO2I,GAAQ,KACjB,KAAK,GACH,MAAOA,GAAQG,EAAO,GAAG4B,QAC3B,SAEE,MADArK,GAAOI,MAASqI,EAAO9I,OAAvB,uBAAoD+J,EAApD,iBAA8EU,EAA9E,KACO9B,EAAQG,EAAO,GAAG4B,YAG9BvH,MAAM,SAAA1C,GACLmI,EAAOnI,QAKfmB,EAAMye,+BAAiC,SAAUtiB,EAAMiT,GAAS,GAAAqO,GAAAhb,IAC9D,OAAO,IAAIkF,SAAQ,SAACZ,EAASC,GAC3ByW,EACGxQ,SACC/K,OACE/F,OACA2M,SACEuU,MAAUjO,EAAV,MAEJ8N,QAAS,SAAU,UAEpB7b,KAAK,SAAA6F,GACJ,OAAQA,EAAO9I,QACb,IAAK,GACH,MAAO2I,GAAQ,KACjB,SACE,MAAOA,GAAQG,EAAO,GAAG4B,YAG9BvH,MAAM,SAAA1C,GACLmI,EAAOnI,QAKfmB,EAAM0e,6BAA+B,SAAUviB,GAAM,GAAAwiB,GAAAlc,IACnD,OAAO,IAAIkF,SAAQ,SAACZ,EAASC,GAC3B2X,EACG1R,SACC/K,OAAS/F,QACT+gB,QAAS,kBAAmB,SAAU,SAAU,UAEjD7b,KAAK,SAAA6F,GAEJ,OADAzI,EAAO2D,MAAM,mBAAoB8E,EAAO9I,QAChC8I,EAAO9I,QACb,IAAK,GACH,MAAO2I,GAAQ,KACjB,SACE,MAAOA,GAAQG,EAAO,GAAGmD,WAAWvB,YAGzCvH,MAAM,SAAA1C,GACLmI,EAAOnI,QAKfmB,EAAM4e,oBAAsB,SAAUziB,EAAM2M,GAAS,GAAA+V,GAAApc,IACnD,OAAO,IAAIkF,SAAQ,SAACZ,EAASC,GAC3B6X,EAAK5c,SACHC,OAAQ/F,OAAM2M,aAEbzH,KAAK,SAAA6F,GACJ,IAAKA,EACH,MAAOH,GAAQ,KAEjBA,GAAQ+B,KAETvH,MAAM,SAAA1C,GACLmI,EAAOnI,QAKfmB,EAAMiJ,eAAiB,SAAUd,EAAWW,GAE1C,MADArK,GAAO2D,MAAP,kBAA+B+F,EAA/B,KAA6CW,EAA7C,KACIA,GAA+B,KAAnBA,EAAQ1K,OACfqE,KAAKmc,oBAAoBzW,EAAWW,GAClCA,GAAWA,EAAQ1K,OAAS,GAC9BqE,KAAKgc,+BAA+BtW,EAAWW,GAE/CrG,KAAKic,6BAA6BvW,IAI7CnI,EAAM8e,aAAe,SAAU3iB,EAAM2M,GAAS,GAAAiW,GAAAtc,IAE5C,OADAhE,GAAO2D,MAAP,uBAAoCjG,EAApC,IAA4C2M,GACrC,GAAInB,SAAQ,SAACZ,EAASC,GAC3B+X,EACG9R,SACC/K,OAAS/F,OAAM2M,aAEhBzH,KAAK,SAAA2d,GACJ,OAAQA,EAAW5gB,QACjB,IAAK,GACH,MAAO2I,GAAQ,KACjB,KAAK,GACH,MAAOA,GAAQgX,EAAiBiB,EAAW,GAAG3U,YAChD,SAEE,MADA5L,GAAOI,MAAP,gCAA6C1C,EAA7C,IAAqD2M,EAArD,gBACO/B,EAAQgX,EAAiBiB,EAAW,GAAG3U,gBAGnD9I,MAAM,SAAA1C,GACLmI,EAAOnI,QAKRmB,I/CytEH,SAAUzE,EAAQC,EAASE,GAEjC,YgDzkFAH,GAAOC,QAAU,SAACiF,EAADyF,GAA6C,GAA/B0V,GAA+B1V,EAA/B0V,OAAQC,EAAuB3V,EAAvB2V,QAASC,EAAc5V,EAAd4V,QACxC7b,EAAOQ,EAAUwb,OACrB,QAEE9f,MACEwR,KAAWiO,EACXqB,WAAW,GAEbnU,SACE6E,KAAWiO,EACXqB,WAAW,GAEbnR,SACE6B,KAAWiO,EACXqB,WAAW,GAEbjR,UACE2B,KAAWiO,EACXqB,WAAW,GAEb9Q,QACEwB,KAAWmO,EACXmB,WAAW,EACXpN,QAAW,GAEbxE,UACEsC,KAAWiO,EACXqB,WAAW,GAEb7Q,UACEuB,KAAWiO,EACXqB,WAAW,GAEb3R,UACEqC,KAAMiO,GAERtP,MACEqB,KAAckO,EACdoB,WAAc,EACdgC,cAAc,GAEhBC,kBACEvR,KAAckO,EACdoB,WAAc,EACdgC,cAAc,KAIhBnC,iBAAiB,GAiBrB,OAbA7c,GAAK0B,UAAY,SAAAH,GACfvB,EAAKkf,QAAQ3d,EAAGtB,SAChBD,EAAKyd,OAAOlc,EAAGxB,QAGjBC,EAAKmf,gBAAkB,WACrB,MAAO3c,MAAKwK,SACV/K,OAASoK,MAAM,EAAO4S,kBAAkB,GACxChC,QAAS,YAAa,SACtBmC,MAAO,MAIJpf,IhDilFH,SAAU1E,EAAQC,EAASE,GAEjC,YiDppFAH,GAAOC,QAAU,SAACiF,EAADyF,GAA0C,GAA5B0V,GAA4B1V,EAA5B0V,OAAiBG,GAAW7V,EAApB2V,QAAoB3V,EAAX6V,MACxC7b,EAAUO,EAAUwb,OACxB,WAEE3F,QACE3I,KAAWiO,EACXqB,WAAW,GAEbvL,KACE/D,KAAWiO,EACXqB,WAAW,GAEbqC,WACE3R,KAAWiO,EACXqB,WAAW,GAEb/V,QACEyG,KAAWoO,EAAK,QAChBkB,WAAW,EACXpN,QAAW,QAIbiN,iBAAiB,GAYrB,OARA5c,GAAQyB,UAAY,SAAAH,GAClBtB,EAAQ6c,UAAUvb,EAAGvB,MACnB+c,YACEC,WAAW,MAKV/c,IjD4pFH,SAAU3E,EAAQC,EAASE,GAEjC,YkDhsFA,IAAM6jB,GAAS7jB,EAAQ,IACjB+C,EAAS/C,EAAQ,EAEvBH,GAAOC,QAAU,SAACiF,EAADyF,GAA2B,GAAb0V,GAAa1V,EAAb0V,OACvBzb,EAAOM,EAAUwb,OACrB,QAEEb,UACEzN,KAAWiO,EACXqB,WAAW,GAEbzc,UACEmN,KAAWiO,EACXqB,WAAW,KAIbH,iBAAiB,GAsErB,OAlEA3c,GAAKwB,UAAY,SAAAH,GACfrB,EAAKud,OAAOlc,EAAGzB,UAGjBI,EAAKpD,UAAU2e,gBAAkB,SAAUlb,GACzC,MAAO+e,GAAOC,QAAQhf,EAAUiC,KAAKjC,WAGvCL,EAAKpD,UAAU0iB,eAAiB,SAAUC,GAAa,GAAAld,GAAAC,IACrD,OAAO,IAAIkF,SAAQ,SAACZ,EAASC,GAE3BuY,EAAOI,QAAQ,SAACC,EAAWC,GACzB,GAAID,EAGF,MAFAnhB,GAAOI,MAAM,aAAc+gB,OAC3B5Y,GAAO4Y,EAITL,GAAOO,KAAKJ,EAAaG,EAAM,SAACE,EAAWD,GAEzC,GAAIC,EAGF,MAFAthB,GAAOI,MAAM,aAAckhB,OAC3B/Y,GAAO+Y,EAITvd,GACGH,QAAQ7B,SAAUsf,IAClBze,KAAK,WACJ0F,MAEDxF,MAAM,SAAA1C,GACLmI,EAAOnI,YAQnBsB,EAAK6f,KAAK,eAAgB,SAACvE,EAAMwE,GAE/B,MADAxhB,GAAO2D,MAAM,6BACN,GAAIuF,SAAQ,SAACZ,EAASC,GAE3BuY,EAAOI,QAAQ,SAACC,EAAWC,GACzB,GAAID,EAGF,MAFAnhB,GAAOI,MAAM,aAAc+gB,OAC3B5Y,GAAO4Y,EAITL,GAAOO,KAAKrE,EAAKjb,SAAUqf,EAAM,SAACE,EAAWD,GAE3C,GAAIC,EAGF,MAFAthB,GAAOI,MAAM,aAAckhB,OAC3B/Y,GAAO+Y,EAITtE,GAAKjb,SAAWsf,EAChB/Y,YAMD5G,IlDqsFH,SAAU5E,EAAQC,GmD7xFxBD,EAAAC,QAAA2B,QAAA,WnDmyFM,SAAU5B,EAAQC,EAASE,GAEjC,YAGA,IAAI0B,GAAiB,WAAc,QAASC,GAAcC,EAAKzB,GAAK,GAAI0B,MAAeC,GAAK,EAAUC,GAAK,EAAWC,MAAKC,EAAW,KAAM,IAAK,GAAiCC,GAA7BC,EAAKP,EAAIQ,OAAOC,cAAmBP,GAAMI,EAAKC,EAAGG,QAAQC,QAAoBV,EAAKW,KAAKN,EAAGO,QAAYtC,GAAK0B,EAAKa,SAAWvC,GAA3D2B,GAAK,IAAoE,MAAOa,GAAOZ,GAAK,EAAMC,EAAKW,EAAO,QAAU,KAAWb,GAAMK,EAAW,QAAGA,EAAW,SAAO,QAAU,GAAIJ,EAAI,KAAMC,IAAQ,MAAOH,GAAQ,MAAO,UAAUD,EAAKzB,GAAK,GAAIyC,MAAMC,QAAQjB,GAAQ,MAAOA,EAAY,IAAIQ,OAAOC,WAAYzB,QAAOgB,GAAQ,MAAOD,GAAcC,EAAKzB,EAAa,MAAM,IAAI2C,WAAU,4DoDxyFhlBsc,EAAwBpf,EAAQ,IAAkBqf,SAClD/P,EAAUtP,EAAQ,GAClB+C,EAAS/C,EAAQ,GACjB8F,EAAK9F,EAAQ,EAEnBH,GAAOC,QAAU,GAAIsf,IAEjBS,cAAe,WACfC,cAAe,YAEjB,SAACjb,EAAUC,EAAUvC,GACnBQ,EAAOyU,QAAP,qCAAoD3S,EAApD,UAAsEC,EAAtE,KACA,IAAI0a,KAIJ,OAAOlQ,GAAQvC,cAAR,IAA0BlI,GAC9Bc,KAAK,SAAAoK,GAEJ,GAAMyU,IACJ9E,SAAU7a,EACVC,SAAUA,EAEZ/B,GAAOyU,QAAQ,aAAcgN,EAE7B,IAAMC,IACJha,gBAAoB5F,EACpBsI,eAAgB4C,EAAGG,SAErBnN,GAAOyU,QAAQ,gBAAiBiN,EAEhC,IAAMC,IACJtX,QAAS2C,EAAGG,SACZzP,SAAaoE,EAKf,OAFA9B,GAAOyU,QAAQ,oBAAqBkN,GAE7BzY,QAAQ0B,KAAK7H,EAAGrB,KAAKmC,OAAO4d,GAAW1e,EAAGzB,QAAQuC,OAAO6d,GAAc3e,EAAG1B,YAAYwC,OAAO8d,OAErG/e,KAAK,SAAA6E,GAA2C,GAAAmC,GAAAjL,EAAA8I,EAAA,GAAzCma,EAAyChY,EAAA,GAAhCiY,EAAgCjY,EAAA,GAApBkY,EAAoBlY,EAAA,EAQ/C,OAPA5J,GAAOyU,QAAQ,6CAEfgI,EAAA,GAAiBmF,EAAQlF,GACzBD,EAAA,SAAuBmF,EAAQjF,SAC/BF,EAAA,YAA0BoF,EAAWna,YACrC+U,EAAA,eAA6BoF,EAAWzX,eAEjClB,QAAQ0B,KAAKkX,EAAeC,WAAWF,GAAaA,EAAWG,QAAQJ,OAE/Ehf,KAAK,WAEJ,MADA5C,GAAOyU,QAAQ,gDACR1R,EAAG1B,YAAY4J,mCAAmCwR,EAASrS,eAAgBqS,EAAS/U,eAE5F9E,KAAK,SAAAia,GAEJ,MADAJ,GAAA,eAA6BI,EACtBrd,EAAK,KAAMid,KAEnB3Z,MAAM,SAAA1C,GAEL,MADAJ,GAAOI,MAAM,eAAgBA,GACtBZ,EAAKY,QpD8yFd,SAAUtD,EAAQC,GqD12FxBD,EAAAC,QAAA2B,QAAA,UrDg3FM,SAAU5B,EAAQC,EAASE,GAEjC,YsDl3FA,IAAMglB,IACJja,KACEC,QAAS,YACTC,QAAS,QAIbpL,GAAOC,QAAUklB,GtDy3FX,SAAUnlB,EAAQC,GuDh4FxBD,EAAAC,QAAA2B,QAAA,wBvDs4FM,SAAU5B,EAAQC,EAASE,GAEjC,YwDx4FAH,GAAOC,SACLiP,oBADe,SACMgR,EAAMxd,GACzBiG,QAAQC,IAAI,oBACZlG,EAAK,KAAMwd,IAEb/Q,sBALe,SAKQ+Q,EAAMxd,GAC3BiG,QAAQC,IAAI,sBACZlG,EAAK,KAAMwd,MxDm5FT,SAAUlgB,EAAQC,EAASE,GAEjC,YyD55FA,IAAM4c,GAAiB5c,EAAQ,GACzBilB,EAAsBjlB,EAAQ,IAC9BklB,EAAqBllB,EAAQ,IAC7BmlB,EAAsBnlB,EAAQ,IAC9BolB,EAAoBplB,EAAQ,GAElCH,GAAOC,QAAU,SAACgc,GAChBA,EAAI5P,KAAK,UAAW0Q,EAAelX,aAAa,gBAAiBuf,GACjEnJ,EAAI5P,KAAK,SAAUgZ,GACnBpJ,EAAI9a,IAAI,UAAWmkB,GACnBrJ,EAAI9a,IAAI,QAASokB,KzDo6Fb,SAAUvlB,EAAQC,EAASE,GAEjC,Y0Dh7FA,IAAMqlB,GAAS,SAACrQ,EAAK5R,GACnBA,EAAIK,OAAO,KAAKE,MACdQ,SAAgB,EAChBsG,YAAgBuK,EAAI+K,KAAKtV,YACzB0C,eAAgB6H,EAAI+K,KAAK5S,eACzByS,eAAgB5K,EAAI+K,KAAKH,iBAI7B/f,GAAOC,QAAUulB,G1Du7FX,SAAUxlB,EAAQC,EAASE,GAEjC,Y2Dl8FA,IAAM4c,GAAiB5c,EAAQ,GAEzBslB,EAAQ,SAACtQ,EAAK5R,EAAKd,GACvBsa,EAAelX,aAAa,cAAe,SAAC/C,EAAKod,EAAMna,GACrD,MAAIjD,GACKL,EAAKK,GAETod,MAML/K,GAAIuQ,MAAMxF,EAAM,SAACpd,GACf,MAAIA,GACKL,EAAKK,GAEPS,EAAIK,OAAO,KAAKE,MACrBQ,SAAgB,EAChBsG,YAAgBuK,EAAI+K,KAAKtV,YACzB0C,eAAgB6H,EAAI+K,KAAK5S,eACzByS,eAAgB5K,EAAI+K,KAAKH,mBAbpBxc,EAAIK,OAAO,KAAKE,MACrBQ,SAAS,EACTT,QAASkC,EAAKlC,YAcjBsR,EAAK5R,EAAKd,GAGfzC,GAAOC,QAAUwlB,G3Dy8FX,SAAUzlB,EAAQC,EAASE,GAEjC,Y4Dt+FA,IAAMwlB,GAAS,SAACxQ,EAAK5R,GACnB4R,EAAIwQ,SACJpiB,EAAIK,OAAO,KAAKE,MAAMQ,SAAS,EAAMT,QAAS,gCAGhD7D,GAAOC,QAAU0lB,G5D6+FX,SAAU3lB,EAAQC,EAASE,GAEjC,Y6Dp/FA,IAAM+f,GAAO,SAAC/K,EAAK5R,GACb4R,EAAI+K,KACN3c,EAAIK,OAAO,KAAKE,MAAMQ,SAAS,EAAMoH,KAAMyJ,EAAI+K,OAE/C3c,EAAIK,OAAO,KAAKE,MAAMQ,SAAS,EAAOT,QAAS,0BAInD7D,GAAOC,QAAUigB,G7D2/FX,SAAUlgB,EAAQC,EAASE,GAEjC,Y8DrgGA,IAAMylB,GAAsBzlB,EAAQ,IAC9B0lB,EAAgB1lB,EAAQ,IACxBykB,EAAczkB,EAAQ,IACtB2lB,EAAiB3lB,EAAQ,IACzB4lB,EAAoB5lB,EAAQ,IAC5B6lB,EAAY7lB,EAAQ,IACpB8lB,EAAW9lB,EAAQ,IACnB+lB,EAAc/lB,EAAQ,IACtBgmB,EAAehmB,EAAQ,IACvBimB,EAAejmB,EAAQ,IACvBkmB,EAAelmB,EAAQ,IACvBmmB,EAAYnmB,EAAQ,IACpBomB,EAAmBpmB,EAAQ,IAE3BqmB,EAAsBrmB,EAAQ,GAEpCH,GAAOC,QAAU,SAACgc,GAEhBA,EAAI9a,IAAI,kCAAmCykB,GAC3C3J,EAAI9a,IAAI,sCAAuC2kB,GAC/C7J,EAAI9a,IAAI,iDAAkDyjB,GAC1D3I,EAAI9a,IAAI,yDAA0D0kB,GAElE5J,EAAI9a,IAAI,wBAAyBmlB,GACjCrK,EAAI9a,IAAI,gCAAiC8kB,GACzChK,EAAI9a,IAAI,gCAAiC4kB,GACzC9J,EAAI9a,IAAI,oCAAqCilB,GAC7CnK,EAAI5P,KAAK,qBAAsBma,EAAqBL,GACpDlK,EAAI9a,IAAI,oCAAqCklB,GAC7CpK,EAAI5P,KAAK,qBAAsB6Z,GAC/BjK,EAAI9a,IAAI,sCAAuC6kB,GAE/C/J,EAAI9a,IAAI,wCAAyColB,K9D6gG7C,SAAUvmB,EAAQC,EAASE,GAEjC,YAGA,IAAI2E,G+DljGiC3E,EAAQ,GAArC0R,E/DmjGuB/M,E+DnjGvB+M,yB/DqjGJvG,E+DpjG0BnL,EAAQ,GAA9BsK,E/DqjGgBa,E+DrjGhBb,kB/DujGJgc,E+DtjG4BtmB,EAAQ,GAAhCgD,E/DujGkBsjB,E+DvjGlBtjB,oBAQFyiB,EAAsB,SAAAjb,EAAwCpH,GAAQ,GAA7CF,GAA6CsH,EAA7CtH,GAAID,EAAyCuH,EAAzCvH,YAAuBxC,EAAkB+J,EAA5BZ,OAAUnJ,KAClDqL,EAAcC,KAAKC,KACzB0F,GAAyBjR,GACtBkF,KAAK,SAAA4gB,GACJnjB,EAAIK,OAAO,KAAKE,KAAK4iB,GACrBjc,EAAkB,aAAc,0BAA2B7J,EAAMqL,EAAaC,KAAKC,SAEpFnG,MAAM,SAAA1C,GACLH,EAAoBC,EAAaC,EAAIC,EAAOC,KAIlDvD,GAAOC,QAAU2lB,G/D6jGX,SAAU5lB,EAAQC,GgEnlGxBD,EAAAC,QAAA2B,QAAA,OhEylGM,SAAU5B,EAAQC,EAASE,GAEjC,YAGA,IAAI2E,GiE9lGyB3E,EAAQ,GAA7BmO,EjE+lGexJ,EiE/lGfwJ,iBjEimGJhD,EiEhmG4BnL,EAAQ,GAAhCgD,EjEimGkBmI,EiEjmGlBnI,oBAUF0iB,EAAgB,SAAAlb,EAAoCpH,GAAQ,GAAzCF,GAAyCsH,EAAzCtH,GAAID,EAAqCuH,EAArCvH,YAAmB2G,GAAkBY,EAAxBgc,KAAwBhc,EAAlBZ,QACxCa,EAAcb,EAAOa,YACvB0C,EAAiBvD,EAAOuD,cACL,UAAnBA,IAA2BA,EAAiB,KAChD,IAAMW,GAAOlE,EAAOkE,IACpBK,GAAiB1D,EAAa0C,EAAgBW,GAC3CnI,KAAK,SAAA4F,GACJ,GAfa,eAeTA,EACF,MAAOnI,GAAIK,OAAO,KAAKE,MAAMQ,SAAS,EAAOT,QAAS,iCAExDN,GAAIK,OAAO,KAAKE,MAAMQ,SAAS,EAAMoH,WAEtC1F,MAAM,SAAA1C,GACLH,EAAoBC,EAAaC,EAAIC,EAAOC,KAIlDvD,GAAOC,QAAU4lB,GjEwmGX,SAAU7lB,EAAQC,EAASE,GAEjC,YkEpoGAH,GAAOC,SACLmN,6BADe,SACexC,EAAasD,EAAoB0Y,EAAQ3Y,GACrE,GAAM4Y,GAAa7mB,EAAOC,QAAQ6mB,oBAAoBF,GAChDG,EAAiB/mB,EAAOC,QAAQ+mB,iBAAiB/Y,EAWvD,QATErD,YAAoBA,EACpBsD,mBAAoBA,EACpB0Y,OAAoB5mB,EAAOC,QAAQgnB,sBAAsBL,EAAQG,GACjEG,aAAoBlnB,EAAOC,QAAQknB,sBAAsBJ,GACzDK,YAAoBL,EACpBM,SAAoBrnB,EAAOC,QAAQqnB,kBAAkBT,EAAYE,GACjEF,WAAoBA,EACpBU,aAAoBvnB,EAAOC,QAAQunB,qBAAqBZ,KAI5DI,iBAhBe,SAgBG/Y,GAChB,MAAIA,GACKwZ,SAASxZ,GAEX,GAETgZ,sBAtBe,SAsBQL,EAAQc,GAC7B,IAAKd,EACH,QAIF,IAAMe,GA9Bc,IA8BKD,EAAa,GAChCE,EAAgBD,EA/BF,EAiCpB,OADqBf,GAAOzS,MAAMwT,EAAiBC,IAGrDd,oBAjCe,SAiCMF,GACnB,GAAKA,EAEE,CACL,GAAMiB,GAAcjB,EAAO/jB,MAC3B,IAAIglB,EAxCc,GAyChB,MAAO,EAET,IAAMC,GAAYC,KAAKC,MAAMH,EA3CX,GA6ClB,OAAkB,KADAA,EA5CA,GA8CTC,EAEFA,EAAY,EAXnB,MAAO,IAcXX,sBAjDe,SAiDQC,GACrB,MAAoB,KAAhBA,EACK,KAEFA,EAAc,GAEvBE,kBAvDe,SAuDIT,EAAYO,GAC7B,MAAIA,KAAgBP,EACX,KAEFO,EAAc,GAEvBI,qBA7De,SA6DOZ,GACpB,MAAKA,GAGEA,EAAO/jB,OAFL,KlEipGP,SAAU7C,EAAQC,EAASE,GAEjC,YAGA,IAAI2E,GmEvtGuB3E,EAAQ,GAA3B6N,EnEwtGalJ,EmExtGbkJ,enE0tGJ1C,EmEztG4BnL,EAAQ,GAAhCgD,EnE0tGkBmI,EmE1tGlBnI,oBAUFyhB,EAAc,SAAAja,EAAoCpH,GAAQ,GAAzCF,GAAyCsH,EAAzCtH,GAAID,EAAqCuH,EAArCvH,YAAmB2G,GAAkBY,EAAxBgc,KAAwBhc,EAAlBZ,QACtCa,EAAcb,EAAOa,YACvB0C,EAAiBvD,EAAOuD,cACL,UAAnBA,IAA2BA,EAAiB,MAChDU,EAAepD,EAAa0C,EAAgB,GACzCxH,KAAK,SAAA4F,GACJ,GAda,eAcTA,EACF,MAAOnI,GAAIK,OAAO,KAAKE,MAAMQ,SAAS,EAAOT,QAAS,iCAExDN,GAAIK,OAAO,KAAKE,MAAMQ,SAAS,EAAMoH,WAEtC1F,MAAM,SAAA1C,GACLH,EAAoBC,EAAaC,EAAIC,EAAOC,KAIlDvD,GAAOC,QAAU2kB,GnEiuGX,SAAU5kB,EAAQC,EAASE,GAEjC,YAGA,IAAI2E,GoEjwG4B3E,EAAQ,GAAhCgD,EpEkwGkB2B,EoElwGlB3B,oBACF8C,EAAK9F,EAAQ,GAQb8nB,EAAsB,SAAAtd,EAA8BpH,GAAQ,GAAnCF,GAAmCsH,EAAnCtH,GAAID,EAA+BuH,EAA/BvH,YAAa2G,EAAkBY,EAAlBZ,MAC9C9D,GAAG1B,YAAY4J,mCAAmCpE,EAAO4J,OAAQ5J,EAAOnJ,MACrEkF,KAAK,SAAA+N,GACJtQ,EAAIK,OAAO,KAAKE,KAAK+P,KAEtB7N,MAAM,SAAA1C,GACLH,EAAoBC,EAAaC,EAAIC,EAAOC,KAIlDvD,GAAOC,QAAUgoB,GpEywGX,SAAUjoB,EAAQC,EAASE,GAEjC,YAGA,IAAI2E,GqEjyG6B3E,EAAQ,GAAjCqR,ErEkyGmB1M,EqElyGnB0M,qBrEoyGJlG,EqEnyG0BnL,EAAQ,GAA9BsK,ErEoyGgBa,EqEpyGhBb,kBrEsyGJgc,EqEryG4BtmB,EAAQ,GAAhCgD,ErEsyGkBsjB,EqEtyGlBtjB,oBAQF4iB,EAAoB,SAAApb,EAAwCpH,GAAQ,GAA7CF,GAA6CsH,EAA7CtH,GAAID,EAAyCuH,EAAzCvH,YAAuBxC,EAAkB+J,EAA5BZ,OAAUnJ,KAChDqL,EAAcC,KAAKC,KACzBqF,GAAqB5Q,GAClBkF,KAAK,SAAA6F,GACJpI,EAAIK,OAAO,KAAKE,KAAK6H,GACrBlB,EAAkB,aAAc,0BAA2B7J,EAAMqL,EAAaC,KAAKC,SAEpFnG,MAAM,SAAA1C,GACLH,EAAoBC,EAAaC,EAAIC,EAAOC,KAIlDvD,GAAOC,QAAU8lB,GrE4yGX,SAAU/lB,EAAQC,EAASE,GAEjC,YAGA,IAAI2E,GsEv0G4B3E,EAAQ,GAAhCgD,EtEw0GkB2B,EsEx0GlB3B,oBACF8C,EAAK9F,EAAQ,GAQb6lB,EAAY,SAAArb,EAAoCpH,GAAQ,GAAzCF,GAAyCsH,EAAzCtH,GAAID,EAAqCuH,EAArCvH,YAAmB2G,GAAkBY,EAAxBgc,KAAwBhc,EAAlBZ,QACpC6C,EAAY7C,EAAO6C,UACrBW,EAAUxD,EAAOwD,OACL,UAAZA,IAAoBA,EAAU,MAClCtH,EAAGxB,MAAM8e,aAAa3W,EAAWW,GAC9BzH,KAAK,SAAAoiB,GACJ,IAAKA,EACH,MAAO3kB,GAAIK,OAAO,KAAKE,MAAMQ,SAAS,EAAOT,QAAS,2BAExDN,GAAIK,OAAO,KAAKE,MAAMQ,SAAS,EAAMoH,KAAMwc,MAE5CliB,MAAM,SAAA1C,GACLH,EAAoBC,EAAaC,EAAIC,EAAOC,KAIlDvD,GAAOC,QAAU+lB,GtEg1GX,SAAUhmB,EAAQC,EAASE,GAEjC,YAGA,IAAI0B,GAAiB,WAAc,QAASC,GAAcC,EAAKzB,GAAK,GAAI0B,MAAeC,GAAK,EAAUC,GAAK,EAAWC,MAAKC,EAAW,KAAM,IAAK,GAAiCC,GAA7BC,EAAKP,EAAIQ,OAAOC,cAAmBP,GAAMI,EAAKC,EAAGG,QAAQC,QAAoBV,EAAKW,KAAKN,EAAGO,QAAYtC,GAAK0B,EAAKa,SAAWvC,GAA3D2B,GAAK,IAAoE,MAAOa,GAAOZ,GAAK,EAAMC,EAAKW,EAAO,QAAU,KAAWb,GAAMK,EAAW,QAAGA,EAAW,SAAO,QAAU,GAAIJ,EAAI,KAAMC,IAAQ,MAAOH,GAAQ,MAAO,UAAUD,EAAKzB,GAAK,GAAIyC,MAAMC,QAAQjB,GAAQ,MAAOA,EAAY,IAAIQ,OAAOC,WAAYzB,QAAOgB,GAAQ,MAAOD,GAAcC,EAAKzB,EAAa,MAAM,IAAI2C,WAAU,4DAEllB6B,EuEh3GiB3E,EAAQ,GAArBqM,EvEi3GO1H,EuEj3GP0H,SvEm3GJlB,EuEl3GgDnL,EAAQ,GAApD8S,EvEm3GsB3H,EuEn3GtB2H,wBAAyBK,EvEo3GZhI,EuEp3GYgI,evEs3G7BmT,EuEr3G4BtmB,EAAQ,GAAhCgD,EvEs3GkBsjB,EuEt3GlBtjB,oBACF8C,EAAK9F,EAAQ,GAQb8lB,EAAW,SAAAtb,EAA8BpH,GAAQ,GAAnCF,GAAmCsH,EAAnCtH,GAAID,EAA+BuH,EAA/BvH,YAAa2G,EAAkBY,EAAlBZ,OAC7BnJ,EAAOmJ,EAAOnJ,KACd2M,EAAUxD,EAAOwD,OAEvBtH,GAAGxB,MAAM8e,aAAa3iB,EAAM2M,GACzBzH,KAAK,SAAAqiB,GAEJ,IAAKA,EACH,KAAM,IAAIvc,OAAM,uCAElB,IAAIwc,GAAW9U,EAAe6U,EAE9B,OAAO/b,SAAQ0B,KAAKsa,EAAU5b,EAAY5L,EAAZ,IAAoB2M,OAEnDzH,KAAK,SAAAgH,GAA6B,GAAAE,GAAAnL,EAAAiL,EAAA,GAA1Bsb,EAA0Bpb,EAAA,GAAhBmG,EAAgBnG,EAAA,EAEjC,OADAob,GAAWnV,EAAwBmV,EAAUjV,GACtC/G,QAAQ0B,KAAK7H,EAAGI,OAAOJ,EAAGvB,KAAM0jB,GAAWxnB,OAAM2M,WAAU,QAAS4F,MAE5ErN,KAAK,SAAAsI,GAA0C,GAAAI,GAAA3M,EAAAuM,EAAA,GAAAia,GAAA7Z,EAAA,GAAAA,EAAA,IAA1B3K,EAA0BwkB,EAA1BxkB,QAASykB,EAAiBD,EAAjBC,SAC7B/kB,GAAIK,OAAO,KAAKE,MAAOQ,SAAS,EAAMT,UAASykB,gBAEhDtiB,MAAM,SAAA1C,GACLH,EAAoBC,EAAaC,EAAIC,EAAOC,KAIlDvD,GAAOC,QAAUgmB,GvEq4GX,SAAUjmB,EAAQC,EAASE,GAEjC,YAGA,IAAI2E,GwE/6GmB3E,EAAQ,GAAvBkN,ExEg7GSvI,EwEh7GTuI,WxEk7GJ/B,EwEj7G4BnL,EAAQ,GAAhCgD,ExEk7GkBmI,EwEl7GlBnI,oBAWF+iB,EAAc,SAAAvb,EAAoCpH,GAAQ,GAAzCF,GAAyCsH,EAAzCtH,GAAID,EAAqCuH,EAArCvH,YAAaujB,EAAwBhc,EAAxBgc,KAChC/b,GADwDD,EAAlBZ,OACxB4c,EAAK/b,aACnB0C,EAAiBqZ,EAAKrZ,eACtBV,EAAY+Z,EAAK/Z,UACjBW,EAAUoZ,EAAKpZ,OACrBF,GAAWzC,EAAa0C,EAAgBV,EAAWW,GAChDzH,KAAK,SAAA6F,GACJ,MAhBa,eAgBTA,EACKpI,EAAIK,OAAO,KAAKE,MAAMQ,SAAS,EAAOT,QAAS,uCAhB7C,aAkBP8H,EACKpI,EAAIK,OAAO,KAAKE,MAAMQ,SAAS,EAAOT,QAAS,4CAExDN,GAAIK,OAAO,KAAKE,MAAMQ,SAAS,EAAMoH,KAAMC,MAE5C3F,MAAM,SAAA1C,GACLH,EAAoBC,EAAaC,EAAIC,EAAOC,KAIlDvD,GAAOC,QAAUimB,GxEy7GX,SAAUlmB,EAAQC,EAASE,GAEjC,YAGA,IAAI0B,GAAiB,WAAc,QAASC,GAAcC,EAAKzB,GAAK,GAAI0B,MAAeC,GAAK,EAAUC,GAAK,EAAWC,MAAKC,EAAW,KAAM,IAAK,GAAiCC,GAA7BC,EAAKP,EAAIQ,OAAOC,cAAmBP,GAAMI,EAAKC,EAAGG,QAAQC,QAAoBV,EAAKW,KAAKN,EAAGO,QAAYtC,GAAK0B,EAAKa,SAAWvC,GAA3D2B,GAAK,IAAoE,MAAOa,GAAOZ,GAAK,EAAMC,EAAKW,EAAO,QAAU,KAAWb,GAAMK,EAAW,QAAGA,EAAW,SAAO,QAAU,GAAIJ,EAAI,KAAMC,IAAQ,MAAOH,GAAQ,MAAO,UAAUD,EAAKzB,GAAK,GAAIyC,MAAMC,QAAQjB,GAAQ,MAAOA,EAAY,IAAIQ,OAAOC,WAAYzB,QAAOgB,GAAQ,MAAOD,GAAcC,EAAKzB,EAAa,MAAM,IAAI2C,WAAU,4DAEllB6B,EyEh+GwH3E,EAAQ,GAA5HwS,EzEi+GuB7N,EyEj+GvB6N,yBAA0BI,EzEk+GCjO,EyEl+GDiO,6BAA8BhB,EzEm+G/BjN,EyEn+G+BiN,2BAA4BG,EzEo+G1DpN,EyEp+G0DoN,4BzEs+GxF5G,EyEr+GsCnL,EAAQ,GAA1CqR,EzEs+GmBlG,EyEt+GnBkG,qBAAsB3B,EzEu+GhBvE,EyEv+GgBuE,QzEy+G1B4W,EyEx+GyBtmB,EAAQ,IAA7BooB,EzEy+Ge9B,EyEz+Gf8B,iBzE2+GJC,EyE1+G0BroB,EAAQ,GAA9BsK,EzE2+GgB+d,EyE3+GhB/d,kBzE6+GJge,EyE5+G4BtoB,EAAQ,GAAhCgD,EzE6+GkBslB,EyE7+GlBtlB,oBzE++GJulB,EyE9+G0BvoB,EAAQ,GAAnBgF,EzE++GRujB,EyE/+GH5gB,QAAW3C,KAQbghB,EAAe,SAAAxb,EAAkDpH,GAAQ,GAAvDojB,GAAuDhc,EAAvDgc,KAAMgC,EAAiDhe,EAAjDge,MAAgBtlB,GAAiCsH,EAA1C7B,QAA0C6B,EAAjCtH,IAAID,EAA6BuH,EAA7BvH,YAAa8c,EAAgBvV,EAAhBuV,KAExDtV,SAAaE,SAAW8d,SAAiBthB,SAAawI,SAAUe,SAAUd,SAAU9D,SAAa+F,SAASpR,SAAMmQ,SAAMxJ,SAAWiL,SAAmBC,SAAmBC,SAAmBlL,QAE/LyE,GAAcC,KAAKC,KAEnB,KAAI,GAAA0c,GAEsD9W,EAA2B4U,EAAjF/lB,GAFAioB,EAEAjoB,KAAMmQ,EAFN8X,EAEM9X,KAAMiB,EAFZ6W,EAEY7W,QAASxK,EAFrBqhB,EAEqBrhB,MAAOF,EAF5BuhB,EAE4BvhB,YAAaC,EAFzCshB,EAEyCthB,SAFzC,IAAAuhB,GAGyF5W,EAA4ByW,EAArH7Y,GAHAgZ,EAGAhZ,SAAUe,EAHViY,EAGUjY,SAAUd,EAHpB+Y,EAGoB/Y,SAAUyC,EAH9BsW,EAG8BtW,kBAAmBC,EAHjDqW,EAGiDrW,kBAAmBC,EAHpEoW,EAGoEpW,kBACpE9H,EAA2C+b,EAA3C/b,YAAaE,EAA8B6b,EAA9B7b,UAAW8d,EAAmBjC,EAAnBiC,gBAC1B,MAAOtlB,GACP,MAAOC,GAAIK,OAAO,KAAKE,MAAMQ,SAAS,EAAOT,QAASP,EAAMO,UAG9DuI,QACG0B,KACCya,EAAiB3d,EAAaE,EAAW8d,EAAiB1I,GAC1D1O,EAAqB5Q,GACrB+R,EAAyB9B,EAAUjQ,EAAM4G,EAAOF,EAAa0K,EAASjB,EAAMxJ,GAC5EwL,EAA6BN,EAAmB7R,EAAMoR,EAASjB,KAEhEjL,KAAK,SAAAgH,GAAgG,GAAAE,GAAAnL,EAAAiL,EAAA,GAAAic,EAAA/b,EAAA,GAA7FpC,EAA6Fme,EAA7Fne,YAAa0C,EAAgFyb,EAAhFzb,eAAqCtB,GAA2CgB,EAAA,GAAAA,EAAA,IAA5Bgc,EAA4Bhc,EAAA,EAWpG,OATIpC,IAAe0C,IACjBtB,EAAA,aAAgCpB,EAChCoB,EAAA,WAA8BsB,GAG5B0b,GACFnZ,EAAQmZ,EAAwBxW,EAAmBE,GAG9C7C,EAAQ7D,EAAe8D,EAAUC,KAEzCjK,KAAK,SAAA6F,GACJpI,EAAIK,OAAO,KAAKE,MACdQ,SAAS,EACTT,QAAS,iCACT6H,MACE9K,OACA2M,QAAS5B,EAAO0E,SAChB8F,IAAYhR,EAAZ,IAAoBwG,EAAO0E,SAA3B,IAAuCzP,EACvCqoB,OAAStd,KAIblB,EAAkB,aAAc,UAAWsF,EAAU9D,EAAaC,KAAKC,SAExEnG,MAAM,SAAA1C,GACLH,EAAoBC,EAAaC,EAAIC,EAAOC,KAIlDvD,GAAOC,QAAUkmB,GzE0hHX,SAAUnmB,EAAQC,EAASE,GAEjC,Y0E/lHA,IAAM8F,GAAK9F,EAAQ,GACb+C,EAAS/C,EAAQ,EAEvBH,GAAOC,SACLsoB,iBADe,SACG3d,EAAaE,EAAW8d,EAAiB1I,GAEzD,IAAKtV,IAAgBE,EACnB,OACEF,YAAgB,KAChB0C,eAAgB,KAIpB,IAAI4S,EAAM,CACR,GAAItV,GAAeA,IAAgBsV,EAAKtV,YACtC,KAAM,IAAIgB,OAAM,4DAElB,IAAId,GAAaA,IAAcoV,EAAK5S,eAClC,KAAM,IAAI1B,OAAM,0DAElB,QACEhB,YAAgBsV,EAAKtV,YACrB0C,eAAgB4S,EAAK5S,gBAIzB,IAAKsb,EAAiB,KAAM,IAAIhd,OAAM,+BACtC,OAAO5L,GAAOC,QAAQipB,+BAA+Bte,EAAaE,EAAW8d,IAE/EM,+BA1Be,SA0BiBte,EAAaE,EAAWqe,GACtD,MAAO,IAAI/c,SAAQ,SAACZ,EAASC,GAE3B,GAAImZ,UAEAwE,IACAxe,KAAawe,EAAA,YAAmCxe,GAChDE,IAAWse,EAAA,eAAsCte,GAErD7E,EAAGzB,QACAkC,SACCC,MAAOyiB,IAERtjB,KAAK,SAAAqK,GACJ,IAAKA,EAEH,KADAjN,GAAO2D,MAAM,oBACP,GAAI+E,OAAM,gEAIlB,OAFAgZ,GAAczU,EAAQhP,MACtB+B,EAAO2D,MAAM,gBAAiB+d,GACvB3e,EAAGrB,KAAK8B,SACbC,OAASkZ,SAAU+E,EAAYha,YAAYkJ,UAAU,QAGxDhO,KAAK,SAAAoa,GACJ,IAAKA,EAEH,KADAhd,GAAO2D,MAAM,iBACP,GAAI+E,OAAM,gEAElB,OAAOsU,GAAKC,gBAAgBgJ,KAE7BrjB,KAAK,SAAAsa,GACJ,IAAKA,EAEH,KADAld,GAAO2D,MAAM,sBACP,GAAI+E,OAAM,gEAElB1I,GAAO2D,MAAM,8BACb2E,EAAQoZ,KAET5e,MAAM,SAAA1C,GACLmI,EAAOnI,U1EqmHX,SAAUtD,EAAQC,EAASE,GAEjC,YAGA,IAAI2E,G2E/qHmB3E,EAAQ,GAAvB0M,E3EgrHS/H,E2EhrHT+H,W3EkrHJvB,E2EjrH4BnL,EAAQ,GAAhCgD,E3EkrHkBmI,E2ElrHlBnI,oBAQFijB,EAAe,SAAAzb,EAAuCpH,GAAQ,GAAnCF,IAAmCsH,EAA5C7B,QAA4C6B,EAAnCtH,IAAID,EAA+BuH,EAA/BvH,YAAa2G,EAAkBY,EAAlBZ,MAChD8C,GAAc9C,EAAOnJ,KAArB,IAA6BmJ,EAAOwD,SACjCzH,KAAK,SAAAujB,GACJ9lB,EAAIK,OAAO,KAAKE,KAAKulB,KAEtBrjB,MAAM,SAAA1C,GACLH,EAAoBC,EAAaC,EAAIC,EAAOC,KAIlDvD,GAAOC,QAAUmmB,G3EyrHX,SAAUpmB,EAAQC,EAASE,GAEjC,YAGA,IAAI2E,G4EjtH4B3E,EAAQ,GAAhCgD,E5EktHkB2B,E4EltHlB3B,oBACF8C,EAAK9F,EAAQ,GAQbkmB,EAAe,SAAA1b,EAAoCpH,GAAQ,GAAzCF,GAAyCsH,EAAzCtH,GAAID,EAAqCuH,EAArCvH,YAAmB2G,GAAkBY,EAAxBgc,KAAwBhc,EAAlBZ,OAC7C9D,GAAGxB,MAAMue,+BAA+BjZ,EAAO4J,OAAQ5J,EAAOnJ,MAC3DkF,KAAK,SAAA+N,GACJtQ,EAAIK,OAAO,KAAKE,MAAMQ,SAAS,EAAMoH,KAAMmI,MAE5C7N,MAAM,SAAA1C,GACLH,EAAoBC,EAAaC,EAAIC,EAAOC,KAIlDvD,GAAOC,QAAUomB,G5E0tHX,SAAUrmB,EAAQC,EAASE,GAEjC,YAGA,IAAI2E,G6ElvHqB3E,EAAQ,GAAzBwM,E7EmvHW7H,E6EnvHX6H,a7EqvHJrB,E6EpvH4BnL,EAAQ,GAAhCgD,E7EqvHkBmI,E6ErvHlBnI,oBAQFmjB,EAAY,SAAA3b,EAA8BpH,GAAQ,GAAnCF,GAAmCsH,EAAnCtH,GAAID,EAA+BuH,EAA/BvH,YAAa2G,EAAkBY,EAAlBZ,MACpC4C,GAAa5C,EAAOnJ,MACjBkF,KAAK,SAAAwjB,GACJ/lB,EAAIK,OAAO,KAAKE,KAAKwlB,KAEtBtjB,MAAM,SAAA1C,GACLH,EAAoBC,EAAaC,EAAIC,EAAOC,KAIlDvD,GAAOC,QAAUqmB,G7E2vHX,SAAUtmB,EAAQC,EAASE,GAEjC,YAGA,IAAI2E,G8EnxH4B3E,EAAQ,GAAhCgD,E9EoxHkB2B,E8EpxHlB3B,oBACF8C,EAAK9F,EAAQ,GAQbomB,EAAmB,SAAA5b,EAA8BpH,GAAQ,GAAnCF,GAAmCsH,EAAnCtH,GAAID,EAA+BuH,EAA/BvH,YAAa2G,EAAkBY,EAAlBZ,OACrCnJ,EAAOmJ,EAAOnJ,KACd2M,EAAUxD,EAAOwD,OACvBtH,GAAGvB,KACAgC,SACCC,OACE/F,OACA2M,aAGHzH,KAAK,SAAA6F,GACJ,GAAIA,EACF,MAAOpI,GAAIK,OAAO,KAAKE,MAAMQ,SAAS,EAAMoH,MAAM,GAEpDnI,GAAIK,OAAO,KAAKE,MAAMQ,SAAS,EAAMoH,MAAM,MAE5C1F,MAAM,SAAA1C,GACLH,EAAoBC,EAAaC,EAAIC,EAAOC,KAIlDvD,GAAOC,QAAUsmB,G9E0xHX,SAAUvmB,EAAQC,EAASE,GAEjC,Y+E1zHA,IAAMopB,GAAYppB,EAAQ,I/E+zHtB2E,E+E9zHwC3E,EAAQ,GAA9BqI,E/E+zHA1D,E+E/zHdmD,WAAcO,gBAChBge,EAAsB+C,GAAWC,UAAWhhB,GAElDxI,GAAOC,QAAUumB,G/Eo0HX,SAAUxmB,EAAQC,GgFx0HxBD,EAAAC,QAAA2B,QAAA,uBhF80HM,SAAU5B,EAAQC,EAASE,GAEjC,YiFh1HA,IAAMspB,GAAoBtpB,EAAQ,IAC5BupB,EAAqBvpB,EAAQ,IAC7BmW,EAAWnW,EAAQ,GAEzBH,GAAOC,QAAU,SAACgc,GAChBA,EAAI9a,IAAI,IAAKsoB,GACbxN,EAAI9a,IAAI,SAAUsoB,GAClBxN,EAAI9a,IAAI,SAAUsoB,GAClBxN,EAAI9a,IAAI,YAAamV,EAAS,aAC9B2F,EAAI9a,IAAI,WAAYsoB,GACpBxN,EAAI9a,IAAI,OAAQsoB,GAChBxN,EAAI9a,IAAI,wBAAyBuoB,KjFw1H7B,SAAU1pB,EAAQC,EAASE,GAEjC,YkFr2HA,IAAMwpB,GAAmBxpB,EAAQ,IAE3BypB,EAAe,SAACzU,EAAK5R,GACzBomB,EAAiBxU,EAAK5R,GAGxBvD,GAAOC,QAAU2pB,GlF42HX,SAAU5pB,EAAQC,EAASE,GAEjC,YAGA,IAAI2E,GmFv3H0B3E,EAAQ,GAAnBgF,EnFw3HRL,EmFx3HHgD,QAAW3C,KAEb0kB,EAAgB,SAAAlf,EAAapH,GAAQ,GAAlBwG,GAAkBY,EAAlBZ,OACjBwD,EAAUxD,EAAOwD,QACjB3M,EAAOmJ,EAAOnJ,IAEpB2C,GAAIK,OAAO,KAAKkmB,OAAO,SAAWC,OAAQ,QAAS5kB,OAAMoI,UAAS3M,SAGpEZ,GAAOC,QAAU4pB,GnF83HX,SAAU7pB,EAAQC,EAASE,GAEjC,YoFz4HA,IAAMmW,GAAW,SAAC0T,GAChB,MAAO,UAAC7U,EAAK5R,GACXA,EAAIK,OAAO,KAAK0S,SAAS0T,IAI7BhqB,GAAOC,QAAUqW,GpFg5HX,SAAUtW,EAAQC,EAASE,GAEjC,YqFx5HA,IAAM8pB,GAAoB9pB,EAAQ,IAC5B+pB,EAAiC/pB,EAAQ,GAE/CH,GAAOC,QAAU,SAACgc,EAAKhW,GACrBgW,EAAI9a,IAAI,sBAAuB+oB,GAC/BjO,EAAI9a,IAAI,UAAW8oB,KrFg6Hf,SAAUjqB,EAAQC,EAASE,GAEjC,YAGA,IAAI2E,GsF16HyB3E,EAAQ,GAA7BqK,EtF26He1F,EsF36Hf0F,iBtF66HJc,EsF56HuEnL,EAAQ,IAA3E+X,EtF66HoB5M,EsF76HpB4M,sBAAuBM,EtF86HVlN,EsF96HUkN,eAAgBR,EtF+6HjB1M,EsF/6HiB0M,wBACzCmS,EAAUhqB,EAAQ,IAClBiqB,EAAmBjqB,EAAQ,IAS3BkqB,EAAqB,SAAClV,EAAK5R,GAAQ,GAC/BuF,GAAqCqM,EAArCrM,QAASzF,EAA4B8R,EAA5B9R,GAAID,EAAwB+R,EAAxB/R,YAAa2G,EAAWoL,EAAXpL,OAE9BoO,QACJ,KACKA,EAAqBgS,EAAQtQ,cAAc9P,EAAOqH,OAAlD+G,iBACH,MAAO7U,GACP,MAAOC,GAAIK,OAAO,KAAKE,MAAMQ,SAAS,EAAOT,QAASP,EAAMO,UAE9D,GAAIuU,GAAeF,EAAsBC,EAAkBrP,EAC3D,IAlBY,UAkBRsP,EACF,MAAOgS,GAAiBjV,EAAK5R,EAI/BiH,GAAiB1B,EAASzF,EAAID,EAE9B,IAAIwJ,SACJ,KACIA,EAAaud,EAAQzQ,WAAW3P,EAAOqH,OAAvCxE,UACF,MAAOtJ,GACP,MAAOC,GAAIK,OAAO,KAAKE,MAAMQ,SAAS,EAAOT,QAASP,EAAMO,UAG9D2U,EAAeJ,EAAcxL,EAAW,KAAM,MAE9CoL,EAAwB,KAAM,KAAMpL,EAAW,KAAMxJ,EAAaC,EAAIE,GAGxEvD,GAAOC,QAAUoqB,GtF47HX,SAAUrqB,EAAQC,GuFr+HxBD,EAAAC,QAAA2B,QAAA,evF2+HM,SAAU5B,EAAQC,GwF3+HxBD,EAAAC,QAAA2B,QAAA,uBxFi/HM,SAAU5B,EAAQC,EAASE,GAEjC,YAGA,IAAI0B,GAAiB,WAAc,QAASC,GAAcC,EAAKzB,GAAK,GAAI0B,MAAeC,GAAK,EAAUC,GAAK,EAAWC,MAAKC,EAAW,KAAM,IAAK,GAAiCC,GAA7BC,EAAKP,EAAIQ,OAAOC,cAAmBP,GAAMI,EAAKC,EAAGG,QAAQC,QAAoBV,EAAKW,KAAKN,EAAGO,QAAYtC,GAAK0B,EAAKa,SAAWvC,GAA3D2B,GAAK,IAAoE,MAAOa,GAAOZ,GAAK,EAAMC,EAAKW,EAAO,QAAU,KAAWb,GAAMK,EAAW,QAAGA,EAAW,SAAO,QAAU,GAAIJ,EAAI,KAAMC,IAAQ,MAAOH,GAAQ,MAAO,UAAUD,EAAKzB,GAAK,GAAIyC,MAAMC,QAAQjB,GAAQ,MAAOA,EAAY,IAAIQ,OAAOC,WAAYzB,QAAOgB,GAAQ,MAAOD,GAAcC,EAAKzB,EAAa,MAAM,IAAI2C,WAAU,4DAEllB6B,EyFx/HyB3E,EAAQ,GAA7BqK,EzFy/He1F,EyFz/Hf0F,iBzF2/HJc,EyFr/HAnL,EAAQ,IAJV+X,EzF0/H0B5M,EyF1/H1B4M,sBACAG,EzF0/HgD/M,EyF1/HhD+M,4CACAG,EzF0/HmBlN,EyF1/HnBkN,eACAR,EzF0/H4B1M,EyF1/H5B0M,wBAEImS,EAAUhqB,EAAQ,IAClBiqB,EAAmBjqB,EAAQ,IAU3BmqB,EAAkC,SAACnV,EAAK5R,GAAQ,GAC5CuF,GAAqCqM,EAArCrM,QAASzF,EAA4B8R,EAA5B9R,GAAID,EAAwB+R,EAAxB/R,YAAa2G,EAAWoL,EAAXpL,OAE9BoO,QACJ,KACKA,EAAqBgS,EAAQtQ,cAAc9P,EAAOqH,OAAlD+G,iBACH,MAAO7U,GACP,MAAOC,GAAIK,OAAO,KAAKE,MAAMQ,SAAS,EAAOT,QAASP,EAAMO,UAE9D,GAAIuU,GAAeF,EAAsBC,EAAkBrP,EAC3D,IAlBY,UAkBRsP,EACF,MAAOgS,GAAiBjV,EAAK5R,EAI/BiH,GAAiB1B,EAASzF,EAAID,EAE9B,IAAIwJ,SACJ,KACKA,EAAcud,EAAQzQ,WAAW3P,EAAOqH,OAAxCxE,UACH,MAAOtJ,GACP,MAAOC,GAAIK,OAAO,KAAKE,MAAMQ,SAAS,EAAOT,QAASP,EAAMO,UAG9D,GAAIyV,UAAW1O,SAAa0C,SAAgBC,QAC5C,KAAI,GAAAgd,GACqDJ,EAAQtR,gBAAgB9O,EAAOuO,WAAnFgB,GADDiR,EACCjR,UAAW1O,EADZ2f,EACY3f,YAAa0C,EADzBid,EACyBjd,eAAgBC,EADzCgd,EACyChd,QAC3C,MAAOjK,GACP,MAAOC,GAAIK,OAAO,KAAKE,MAAMQ,SAAS,EAAOT,QAASP,EAAMO,UAE9D,IAAKyV,EAAW,IAAAkR,GACSnS,EAA4C9K,EAASX,GAD9D6d,EAAA5oB,EAAA2oB,EAAA,EACbjd,GADakd,EAAA,GACJ7d,EADI6d,EAAA,GAIhBjS,EAAeJ,EAAcxL,EAAWhC,EAAa2C,GAErDyK,EAAwBpN,EAAa0C,EAAgBV,EAAWW,EAASnK,EAAaC,EAAIE,GAG5FvD,GAAOC,QAAUqqB,GzFmhIX,SAAUtqB,EAAQC,EAASE,GAEjC,Y0F9kIA,IAAMspB,GAAoBtpB,EAAQ,GAElCH,GAAOC,QAAU,SAACgc,GAChBA,EAAI9a,IAAI,IAAKsoB,K1FslIT,SAAUzpB,EAAQC,EAASE,GAEjC,Y2F3lIA,IAAMwpB,GAAmBxpB,EAAQ,IAE3BypB,EAAe,SAACzU,EAAK5R,GACzBomB,EAAiBxU,EAAK5R,GAGxBvD,GAAOC,QAAU2pB","file":"index.js","sourcesContent":["module.exports =\n/******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, {\n/******/ \t\t\t\tconfigurable: false,\n/******/ \t\t\t\tenumerable: true,\n/******/ \t\t\t\tget: getter\n/******/ \t\t\t});\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"/\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 26);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"winston\");\n\n/***/ }),\n/* 1 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"]) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); } }; }();\n\nvar logger = __webpack_require__(0);\n\nmodule.exports = {\n handleErrorResponse: function handleErrorResponse(originalUrl, ip, error, res) {\n logger.error('Error on ' + originalUrl, module.exports.useObjectPropertiesIfNoKeys(error));\n\n var _module$exports$retur = module.exports.returnErrorMessageAndStatus(error),\n _module$exports$retur2 = _slicedToArray(_module$exports$retur, 2),\n status = _module$exports$retur2[0],\n message = _module$exports$retur2[1];\n\n res.status(status).json(module.exports.createErrorResponsePayload(status, message));\n },\n returnErrorMessageAndStatus: function returnErrorMessageAndStatus(error) {\n var status = void 0,\n message = void 0;\n // check for daemon being turned off\n if (error.code === 'ECONNREFUSED') {\n status = 503;\n message = 'Connection refused. The daemon may not be running.';\n // fallback for everything else\n } else {\n status = 400;\n if (error.message) {\n message = error.message;\n } else {\n message = error;\n };\n };\n return [status, message];\n },\n useObjectPropertiesIfNoKeys: function useObjectPropertiesIfNoKeys(err) {\n if (Object.keys(err).length === 0) {\n var newErrorObject = {};\n Object.getOwnPropertyNames(err).forEach(function (key) {\n newErrorObject[key] = err[key];\n });\n return newErrorObject;\n }\n return err;\n },\n createErrorResponsePayload: function createErrorResponsePayload(status, message) {\n return {\n status: status,\n success: false,\n message: message\n };\n }\n};\n\n/***/ }),\n/* 2 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar Certificate = __webpack_require__(44);\nvar Channel = __webpack_require__(45);\nvar Claim = __webpack_require__(46);\nvar File = __webpack_require__(47);\nvar Request = __webpack_require__(48);\nvar User = __webpack_require__(49);\n\nvar Sequelize = __webpack_require__(13);\nvar logger = __webpack_require__(0);\n\nvar _require = __webpack_require__(10),\n database = _require.database,\n username = _require.username,\n password = _require.password;\n\n// set sequelize options\n\n\nvar sequelize = new Sequelize(database, username, password, {\n host: 'localhost',\n dialect: 'mysql',\n dialectOptions: { decimalNumbers: true },\n logging: false,\n pool: {\n max: 5,\n min: 0,\n idle: 10000,\n acquire: 10000\n }\n});\n\n// establish mysql connection\nsequelize.authenticate().then(function () {\n logger.info('Sequelize has established mysql connection successfully.');\n}).catch(function (err) {\n logger.error('Sequelize was unable to connect to the database:', err);\n});\n\n// manually add each model to the db object (note: make this dynamic)\nvar db = {};\ndb['Certificate'] = sequelize.import('Certificate', Certificate);\ndb['Channel'] = sequelize.import('Channel', Channel);\ndb['Claim'] = sequelize.import('Claim', Claim);\ndb['File'] = sequelize.import('File', File);\ndb['Request'] = sequelize.import('Request', Request);\ndb['User'] = sequelize.import('User', User);\n\n// run model.association for each model in the db object that has an association\nlogger.info('associating db models...');\nObject.keys(db).forEach(function (modelName) {\n if (db[modelName].associate) {\n logger.info('Associating model:', modelName);\n db[modelName].associate(db);\n }\n});\n\n// add sequelize/Sequelize to db\ndb.sequelize = sequelize;\ndb.Sequelize = Sequelize;\n// add an 'upsert' method to the db object\ndb.upsert = function (Model, values, condition, tableName) {\n return Model.findOne({\n where: condition\n }).then(function (obj) {\n if (obj) {\n // update\n logger.debug('updating record in db.' + tableName);\n return obj.update(values);\n } else {\n // insert\n logger.debug('creating record in db.' + tableName);\n return Model.create(values);\n }\n }).catch(function (error) {\n logger.error(tableName + '.upsert error', error);\n throw error;\n });\n};\n\nmodule.exports = db;\n\n/***/ }),\n/* 3 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nfunction SiteConfig() {\n var _this = this;\n\n this.analytics = {\n googleId: 'default'\n };\n this.assetDefaults = {\n description: 'An asset published on Spee.ch',\n thumbnail: 'https://spee.ch/assets/img/video_thumb_default.png',\n title: 'Spee.ch'\n };\n this.auth = {\n sessionKey: 'default'\n };\n this.customComponents = {};\n this.customContainers = {};\n this.customPages = {};\n this.details = {\n description: 'Open-source, decentralized image and video sharing.',\n host: 'default',\n port: 3000,\n title: 'Spee.ch',\n twitter: '@spee_ch'\n };\n this.publishing = {\n additionalClaimAddresses: [],\n disabled: false,\n disabledMessage: 'Please check back soon.',\n primaryClaimAddress: 'default',\n thumbnailChannel: 'default',\n thumbnailChannelId: 'default',\n uploadDirectory: '/home/lbry/Uploads'\n };\n this.routes = {};\n this.update = function (config) {\n if (!config) {\n return console.log('No site config received.');\n }\n var analytics = config.analytics,\n assetDefaults = config.assetDefaults,\n auth = config.auth,\n customComponents = config.customComponents,\n customContainers = config.customContainers,\n customPages = config.customPages,\n details = config.details,\n publishing = config.publishing,\n routes = config.routes;\n\n console.log('Configuring site details...');\n _this.analytics = analytics;\n _this.assetDefaults = assetDefaults;\n _this.auth = auth;\n _this.details = details;\n _this.publishing = publishing;\n _this.customComponents = customComponents;\n _this.customContainers = customContainers;\n _this.customPages = customPages;\n _this.routes = routes;\n };\n};\n\nmodule.exports = new SiteConfig();\n\n/***/ }),\n/* 4 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar logger = __webpack_require__(0);\nvar ua = __webpack_require__(54);\n\nvar _require = __webpack_require__(3),\n googleId = _require.analytics.googleId,\n title = _require.details.title;\n\nfunction createServeEventParams(headers, ip, originalUrl) {\n return {\n eventCategory: 'client requests',\n eventAction: 'serve request',\n eventLabel: originalUrl,\n ipOverride: ip,\n userAgentOverride: headers['user-agent']\n };\n};\n\nfunction createPublishTimingEventParams(category, variable, label, startTime, endTime) {\n var duration = endTime - startTime;\n return {\n userTimingCategory: category,\n userTimingVariableName: variable,\n userTimingTime: duration,\n userTimingLabel: label\n };\n};\n\nfunction sendGoogleAnalyticsEvent(ip, params) {\n var visitorId = ip.replace(/\\./g, '-');\n var visitor = ua(googleId, visitorId, { strictCidFormat: false, https: true });\n visitor.event(params, function (err) {\n if (err) {\n logger.error('Google Analytics Event Error >>', err);\n }\n });\n};\n\nfunction sendGoogleAnalyticsTiming(visitorId, params) {\n var visitor = ua(googleId, visitorId, { strictCidFormat: false, https: true });\n visitor.timing(params, function (err) {\n if (err) {\n logger.error('Google Analytics Event Error >>', err);\n }\n logger.debug('Timing event successfully sent to google analytics');\n });\n};\n\nmodule.exports = {\n sendGAServeEvent: function sendGAServeEvent(headers, ip, originalUrl) {\n var params = createServeEventParams(headers, ip, originalUrl);\n sendGoogleAnalyticsEvent(ip, params);\n },\n sendGATimingEvent: function sendGATimingEvent(category, variable, label, startTime, endTime) {\n var params = createPublishTimingEventParams(category, variable, label, startTime, endTime);\n sendGoogleAnalyticsTiming(title, params);\n },\n chooseGaLbrynetPublishLabel: function chooseGaLbrynetPublishLabel(_ref) {\n var channelName = _ref.channel_name,\n channelId = _ref.channel_id;\n\n return channelName || channelId ? 'PUBLISH_IN_CHANNEL_CLAIM' : 'PUBLISH_ANONYMOUS_CLAIM';\n }\n};\n\n/***/ }),\n/* 5 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar axios = __webpack_require__(52);\nvar logger = __webpack_require__(0);\n\nvar _require = __webpack_require__(53),\n _require$api = _require.api,\n apiHost = _require$api.apiHost,\n apiPort = _require$api.apiPort;\n\nvar lbryApiUri = 'http://' + apiHost + ':' + apiPort;\n\nvar _require2 = __webpack_require__(4),\n chooseGaLbrynetPublishLabel = _require2.chooseGaLbrynetPublishLabel,\n sendGATimingEvent = _require2.sendGATimingEvent;\n\nvar handleLbrynetResponse = function handleLbrynetResponse(_ref, resolve, reject) {\n var data = _ref.data;\n\n logger.debug('lbry api data:', data);\n if (data.result) {\n // check for an error\n if (data.result.error) {\n logger.debug('Lbrynet api error:', data.result.error);\n reject(new Error(data.result.error));\n return;\n };\n resolve(data.result);\n return;\n }\n // fallback in case it just timed out\n reject(JSON.stringify(data));\n};\n\nmodule.exports = {\n publishClaim: function publishClaim(publishParams) {\n logger.debug('lbryApi >> Publishing claim to \"' + publishParams.name + '\"');\n var gaStartTime = Date.now();\n return new Promise(function (resolve, reject) {\n axios.post(lbryApiUri, {\n method: 'publish',\n params: publishParams\n }).then(function (response) {\n sendGATimingEvent('lbrynet', 'publish', chooseGaLbrynetPublishLabel(publishParams), gaStartTime, Date.now());\n handleLbrynetResponse(response, resolve, reject);\n }).catch(function (error) {\n reject(error);\n });\n });\n },\n getClaim: function getClaim(uri) {\n logger.debug('lbryApi >> Getting Claim for \"' + uri + '\"');\n var gaStartTime = Date.now();\n return new Promise(function (resolve, reject) {\n axios.post(lbryApiUri, {\n method: 'get',\n params: { uri: uri, timeout: 20 }\n }).then(function (response) {\n sendGATimingEvent('lbrynet', 'getClaim', 'GET', gaStartTime, Date.now());\n handleLbrynetResponse(response, resolve, reject);\n }).catch(function (error) {\n reject(error);\n });\n });\n },\n getClaimList: function getClaimList(claimName) {\n logger.debug('lbryApi >> Getting claim_list for \"' + claimName + '\"');\n var gaStartTime = Date.now();\n return new Promise(function (resolve, reject) {\n axios.post(lbryApiUri, {\n method: 'claim_list',\n params: { name: claimName }\n }).then(function (response) {\n sendGATimingEvent('lbrynet', 'getClaimList', 'CLAIM_LIST', gaStartTime, Date.now());\n handleLbrynetResponse(response, resolve, reject);\n }).catch(function (error) {\n reject(error);\n });\n });\n },\n resolveUri: function resolveUri(uri) {\n logger.debug('lbryApi >> Resolving URI for \"' + uri + '\"');\n var gaStartTime = Date.now();\n return new Promise(function (resolve, reject) {\n axios.post(lbryApiUri, {\n method: 'resolve',\n params: { uri: uri }\n }).then(function (_ref2) {\n var data = _ref2.data;\n\n sendGATimingEvent('lbrynet', 'resolveUri', 'RESOLVE', gaStartTime, Date.now());\n if (data.result[uri].error) {\n // check for errors\n reject(data.result[uri].error);\n } else {\n // if no errors, resolve\n resolve(data.result[uri]);\n }\n }).catch(function (error) {\n reject(error);\n });\n });\n },\n getDownloadDirectory: function getDownloadDirectory() {\n logger.debug('lbryApi >> Retrieving the download directory path from lbry daemon...');\n var gaStartTime = Date.now();\n return new Promise(function (resolve, reject) {\n axios.post(lbryApiUri, {\n method: 'settings_get'\n }).then(function (_ref3) {\n var data = _ref3.data;\n\n sendGATimingEvent('lbrynet', 'getDownloadDirectory', 'SETTINGS_GET', gaStartTime, Date.now());\n if (data.result) {\n resolve(data.result.download_directory);\n } else {\n return new Error('Successfully connected to lbry daemon, but unable to retrieve the download directory.');\n }\n }).catch(function (error) {\n logger.error('Lbrynet Error:', error);\n resolve('/home/lbry/Downloads/');\n });\n });\n },\n createChannel: function createChannel(name) {\n logger.debug('lbryApi >> Creating channel for ' + name + '...');\n var gaStartTime = Date.now();\n return new Promise(function (resolve, reject) {\n axios.post(lbryApiUri, {\n method: 'channel_new',\n params: {\n channel_name: name,\n amount: 0.1\n }\n }).then(function (response) {\n sendGATimingEvent('lbrynet', 'createChannel', 'CHANNEL_NEW', gaStartTime, Date.now());\n handleLbrynetResponse(response, resolve, reject);\n }).catch(function (error) {\n reject(error);\n });\n });\n }\n};\n\n/***/ }),\n/* 6 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"]) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); } }; }();\n\nvar db = __webpack_require__(2);\nvar logger = __webpack_require__(0);\n\nvar _require = __webpack_require__(65),\n returnPaginatedChannelClaims = _require.returnPaginatedChannelClaims;\n\nvar NO_CHANNEL = 'NO_CHANNEL';\nvar NO_CLAIM = 'NO_CLAIM';\nvar NO_FILE = 'NO_FILE';\n\nmodule.exports = {\n getClaimId: function getClaimId(channelName, channelClaimId, name, claimId) {\n if (channelName) {\n return module.exports.getClaimIdByChannel(channelName, channelClaimId, name);\n } else {\n return module.exports.getClaimIdByClaim(name, claimId);\n }\n },\n getClaimIdByClaim: function getClaimIdByClaim(claimName, claimId) {\n logger.debug('getClaimIdByClaim(' + claimName + ', ' + claimId + ')');\n return new Promise(function (resolve, reject) {\n db.Claim.getLongClaimId(claimName, claimId).then(function (longClaimId) {\n if (!longClaimId) {\n resolve(NO_CLAIM);\n }\n resolve(longClaimId);\n }).catch(function (error) {\n reject(error);\n });\n });\n },\n getClaimIdByChannel: function getClaimIdByChannel(channelName, channelClaimId, claimName) {\n logger.debug('getClaimIdByChannel(' + channelName + ', ' + channelClaimId + ', ' + claimName + ')');\n return new Promise(function (resolve, reject) {\n db.Certificate.getLongChannelId(channelName, channelClaimId) // 1. get the long channel id\n .then(function (longChannelId) {\n if (!longChannelId) {\n return [null, null];\n }\n return Promise.all([longChannelId, db.Claim.getClaimIdByLongChannelId(longChannelId, claimName)]); // 2. get the long claim id\n }).then(function (_ref) {\n var _ref2 = _slicedToArray(_ref, 2),\n longChannelId = _ref2[0],\n longClaimId = _ref2[1];\n\n if (!longChannelId) {\n return resolve(NO_CHANNEL);\n }\n if (!longClaimId) {\n return resolve(NO_CLAIM);\n }\n resolve(longClaimId);\n }).catch(function (error) {\n reject(error);\n });\n });\n },\n getChannelData: function getChannelData(channelName, channelClaimId, page) {\n return new Promise(function (resolve, reject) {\n // 1. get the long channel Id (make sure channel exists)\n db.Certificate.getLongChannelId(channelName, channelClaimId).then(function (longChannelClaimId) {\n if (!longChannelClaimId) {\n return [null, null, null];\n }\n // 2. get the short ID and all claims for that channel\n return Promise.all([longChannelClaimId, db.Certificate.getShortChannelIdFromLongChannelId(longChannelClaimId, channelName)]);\n }).then(function (_ref3) {\n var _ref4 = _slicedToArray(_ref3, 2),\n longChannelClaimId = _ref4[0],\n shortChannelClaimId = _ref4[1];\n\n if (!longChannelClaimId) {\n return resolve(NO_CHANNEL);\n }\n // 3. return all the channel information\n resolve({\n channelName: channelName,\n longChannelClaimId: longChannelClaimId,\n shortChannelClaimId: shortChannelClaimId\n });\n }).catch(function (error) {\n reject(error);\n });\n });\n },\n getChannelClaims: function getChannelClaims(channelName, channelClaimId, page) {\n return new Promise(function (resolve, reject) {\n // 1. get the long channel Id (make sure channel exists)\n db.Certificate.getLongChannelId(channelName, channelClaimId).then(function (longChannelClaimId) {\n if (!longChannelClaimId) {\n return [null, null, null];\n }\n // 2. get the short ID and all claims for that channel\n return Promise.all([longChannelClaimId, db.Claim.getAllChannelClaims(longChannelClaimId)]);\n }).then(function (_ref5) {\n var _ref6 = _slicedToArray(_ref5, 2),\n longChannelClaimId = _ref6[0],\n channelClaimsArray = _ref6[1];\n\n if (!longChannelClaimId) {\n return resolve(NO_CHANNEL);\n }\n // 3. format the data for the view, including pagination\n var paginatedChannelViewData = returnPaginatedChannelClaims(channelName, longChannelClaimId, channelClaimsArray, page);\n // 4. return all the channel information and contents\n resolve(paginatedChannelViewData);\n }).catch(function (error) {\n reject(error);\n });\n });\n },\n getLocalFileRecord: function getLocalFileRecord(claimId, name) {\n return db.File.findOne({ where: { claimId: claimId, name: name } }).then(function (file) {\n if (!file) {\n return NO_FILE;\n }\n return file.dataValues;\n });\n }\n};\n\n/***/ }),\n/* 7 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar passport = __webpack_require__(42);\nvar localLoginStrategy = __webpack_require__(43);\nvar localSignupStrategy = __webpack_require__(51);\n\nvar _require = __webpack_require__(55),\n serializeSpeechUser = _require.serializeSpeechUser,\n deserializeSpeechUser = _require.deserializeSpeechUser;\n\npassport.deserializeUser(deserializeSpeechUser);\npassport.serializeUser(serializeSpeechUser);\npassport.use('local-login', localLoginStrategy);\npassport.use('local-signup', localSignupStrategy);\n\nmodule.exports = passport;\n\n/***/ }),\n/* 8 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"]) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); } }; }();\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nvar logger = __webpack_require__(0);\nvar db = __webpack_require__(2);\nvar lbryApi = __webpack_require__(5);\nvar publishHelpers = __webpack_require__(9);\n\nvar _require = __webpack_require__(3),\n _require$publishing = _require.publishing,\n primaryClaimAddress = _require$publishing.primaryClaimAddress,\n additionalClaimAddresses = _require$publishing.additionalClaimAddresses;\n\nvar Sequelize = __webpack_require__(13);\nvar Op = Sequelize.Op;\n\nmodule.exports = {\n publish: function publish(publishParams, fileName, fileType) {\n return new Promise(function (resolve, reject) {\n var publishResults = void 0,\n certificateId = void 0,\n channelName = void 0;\n // publish the file\n return lbryApi.publishClaim(publishParams).then(function (tx) {\n logger.info('Successfully published ' + publishParams.name + ' ' + fileName, tx);\n publishResults = tx;\n // get the channel information\n if (publishParams.channel_name) {\n logger.debug('this claim was published in channel: ' + publishParams.channel_name);\n return db.Channel.findOne({\n where: {\n channelName: publishParams.channel_name\n }\n });\n } else {\n logger.debug('this claim was not published in a channel');\n return null;\n }\n }).then(function (channel) {\n // set channel information\n certificateId = null;\n channelName = null;\n if (channel) {\n certificateId = channel.channelClaimId;\n channelName = channel.channelName;\n }\n logger.debug('certificateId: ' + certificateId);\n }).then(function () {\n // create the File record\n var fileRecord = {\n name: publishParams.name,\n claimId: publishResults.claim_id,\n title: publishParams.metadata.title,\n description: publishParams.metadata.description,\n address: publishParams.claim_address,\n outpoint: publishResults.txid + ':' + publishResults.nout,\n height: 0,\n fileName: fileName,\n filePath: publishParams.file_path,\n fileType: fileType,\n nsfw: publishParams.metadata.nsfw\n };\n // create the Claim record\n var claimRecord = {\n name: publishParams.name,\n claimId: publishResults.claim_id,\n title: publishParams.metadata.title,\n description: publishParams.metadata.description,\n address: publishParams.claim_address,\n thumbnail: publishParams.metadata.thumbnail,\n outpoint: publishResults.txid + ':' + publishResults.nout,\n height: 0,\n contentType: fileType,\n nsfw: publishParams.metadata.nsfw,\n amount: publishParams.bid,\n certificateId: certificateId,\n channelName: channelName\n };\n // upsert criteria\n var upsertCriteria = {\n name: publishParams.name,\n claimId: publishResults.claim_id\n };\n // upsert the records\n return Promise.all([db.upsert(db.File, fileRecord, upsertCriteria, 'File'), db.upsert(db.Claim, claimRecord, upsertCriteria, 'Claim')]);\n }).then(function (_ref) {\n var _ref2 = _slicedToArray(_ref, 2),\n file = _ref2[0],\n claim = _ref2[1];\n\n logger.debug('File and Claim records successfully created');\n return Promise.all([file.setClaim(claim), claim.setFile(file)]);\n }).then(function () {\n logger.debug('File and Claim records successfully associated');\n resolve(publishResults); // resolve the promise with the result from lbryApi.publishClaim;\n }).catch(function (error) {\n logger.error('PUBLISH ERROR', error);\n publishHelpers.deleteTemporaryFile(publishParams.file_path); // delete the local file\n reject(error);\n });\n });\n },\n claimNameIsAvailable: function claimNameIsAvailable(name) {\n var claimAddresses = additionalClaimAddresses || [];\n claimAddresses.push(primaryClaimAddress);\n // find any records where the name is used\n return db.Claim.findAll({\n attributes: ['address'],\n where: {\n name: name,\n address: _defineProperty({}, Op.or, claimAddresses)\n }\n }).then(function (result) {\n if (result.length >= 1) {\n throw new Error('That claim is already in use');\n };\n return name;\n }).catch(function (error) {\n throw error;\n });\n },\n checkChannelAvailability: function checkChannelAvailability(name) {\n return db.Channel.findAll({\n where: { channelName: name }\n }).then(function (result) {\n if (result.length >= 1) {\n throw new Error('That channel has already been claimed');\n }\n return name;\n }).catch(function (error) {\n throw error;\n });\n }\n};\n\n/***/ }),\n/* 9 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar logger = __webpack_require__(0);\nvar fs = __webpack_require__(63);\n\nvar _require = __webpack_require__(3),\n details = _require.details,\n publishing = _require.publishing;\n\nmodule.exports = {\n parsePublishApiRequestBody: function parsePublishApiRequestBody(_ref) {\n var name = _ref.name,\n nsfw = _ref.nsfw,\n license = _ref.license,\n title = _ref.title,\n description = _ref.description,\n thumbnail = _ref.thumbnail;\n\n // validate name\n if (!name) {\n throw new Error('no name field found in request');\n }\n var invalidNameCharacters = /[^A-Za-z0-9,-]/.exec(name);\n if (invalidNameCharacters) {\n throw new Error('The claim name you provided is not allowed. Only the following characters are allowed: A-Z, a-z, 0-9, and \"-\"');\n }\n // optional parameters\n nsfw = nsfw === 'true';\n license = license || null;\n title = title || null;\n description = description || null;\n thumbnail = thumbnail || null;\n // return results\n return {\n name: name,\n nsfw: nsfw,\n license: license,\n title: title,\n description: description,\n thumbnail: thumbnail\n };\n },\n parsePublishApiRequestFiles: function parsePublishApiRequestFiles(_ref2) {\n var file = _ref2.file,\n thumbnail = _ref2.thumbnail;\n\n // make sure a file was provided\n if (!file) {\n throw new Error('no file with key of [file] found in request');\n }\n if (!file.path) {\n throw new Error('no file path found');\n }\n if (!file.type) {\n throw new Error('no file type found');\n }\n if (!file.size) {\n throw new Error('no file type found');\n }\n // validate the file name\n if (/'/.test(file.name)) {\n throw new Error('apostrophes are not allowed in the file name');\n }\n // validate the file\n module.exports.validateFileTypeAndSize(file);\n // return results\n return {\n fileName: file.name,\n filePath: file.path,\n fileType: file.type,\n thumbnailFileName: thumbnail ? thumbnail.name : null,\n thumbnailFilePath: thumbnail ? thumbnail.path : null,\n thumbnailFileType: thumbnail ? thumbnail.type : null\n };\n },\n validateFileTypeAndSize: function validateFileTypeAndSize(file) {\n // check file type and size\n switch (file.type) {\n case 'image/jpeg':\n case 'image/jpg':\n case 'image/png':\n if (file.size > 10000000) {\n logger.debug('publish > file validation > .jpeg/.jpg/.png was too big');\n throw new Error('Sorry, images are limited to 10 megabytes.');\n }\n break;\n case 'image/gif':\n if (file.size > 50000000) {\n logger.debug('publish > file validation > .gif was too big');\n throw new Error('Sorry, .gifs are limited to 50 megabytes.');\n }\n break;\n case 'video/mp4':\n if (file.size > 50000000) {\n logger.debug('publish > file validation > .mp4 was too big');\n throw new Error('Sorry, videos are limited to 50 megabytes.');\n }\n break;\n default:\n logger.debug('publish > file validation > unrecognized file type');\n throw new Error('The ' + file.type + ' content type is not supported. Only, .jpeg, .png, .gif, and .mp4 files are currently supported.');\n }\n return file;\n },\n createBasicPublishParams: function createBasicPublishParams(filePath, name, title, description, license, nsfw, thumbnail) {\n logger.debug('Creating Publish Parameters');\n // provide defaults for title\n if (title === null || title.trim() === '') {\n title = name;\n }\n // provide default for description\n if (description === null || description.trim() === '') {\n description = '';\n }\n // provide default for license\n if (license === null || license.trim() === '') {\n license = ' '; // default to empty string\n }\n // create the publish params\n var publishParams = {\n name: name,\n file_path: filePath,\n bid: 0.01,\n metadata: {\n description: description,\n title: title,\n author: details.title,\n language: 'en',\n license: license,\n nsfw: nsfw\n },\n claim_address: publishing.primaryClaimAddress\n };\n // add thumbnail to channel if video\n if (thumbnail) {\n publishParams['metadata']['thumbnail'] = thumbnail;\n }\n return publishParams;\n },\n createThumbnailPublishParams: function createThumbnailPublishParams(thumbnailFilePath, claimName, license, nsfw) {\n if (!thumbnailFilePath) {\n return;\n }\n logger.debug('Creating Thumbnail Publish Parameters');\n // create the publish params\n return {\n name: claimName + '-thumb',\n file_path: thumbnailFilePath,\n bid: 0.01,\n metadata: {\n title: claimName + ' thumbnail',\n description: 'a thumbnail for ' + claimName,\n author: details.title,\n language: 'en',\n license: license,\n nsfw: nsfw\n },\n claim_address: publishing.primaryClaimAddress,\n channel_name: publishing.thumbnailChannel,\n channel_id: publishing.thumbnailChannelId\n };\n },\n deleteTemporaryFile: function deleteTemporaryFile(filePath) {\n fs.unlink(filePath, function (err) {\n if (err) {\n logger.error('error deleting temporary file ' + filePath);\n throw err;\n }\n logger.debug('successfully deleted ' + filePath);\n });\n },\n addGetResultsToFileData: function addGetResultsToFileData(fileInfo, getResult) {\n fileInfo.fileName = getResult.file_name;\n fileInfo.filePath = getResult.download_path;\n return fileInfo;\n },\n createFileData: function createFileData(_ref3) {\n var name = _ref3.name,\n claimId = _ref3.claimId,\n outpoint = _ref3.outpoint,\n height = _ref3.height,\n address = _ref3.address,\n nsfw = _ref3.nsfw,\n contentType = _ref3.contentType;\n\n return {\n name: name,\n claimId: claimId,\n outpoint: outpoint,\n height: height,\n address: address,\n fileName: '',\n filePath: '',\n fileType: contentType,\n nsfw: nsfw\n };\n }\n};\n\n/***/ }),\n/* 10 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar logger = __webpack_require__(0);\n\nfunction mysql() {\n var _this = this;\n\n this.database = 'default';\n this.username = 'default';\n this.password = 'default';\n this.update = function (config) {\n if (!config) {\n return logger.warn('No MySQL config received.');\n }\n // configure credentials\n logger.info('configuring mysql...');\n var database = config.database,\n username = config.username,\n password = config.password;\n\n _this.database = database;\n _this.username = username;\n _this.password = password;\n };\n};\n\nmodule.exports = new mysql();\n\n/***/ }),\n/* 11 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"passport-local\");\n\n/***/ }),\n/* 12 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nmodule.exports = {\n returnShortId: function returnShortId(claimsArray, longId) {\n var claimIndex = void 0;\n var shortId = longId.substring(0, 1); // default short id is the first letter\n var shortIdLength = 0;\n // find the index of this claim id\n claimIndex = claimsArray.findIndex(function (element) {\n return element.claimId === longId;\n });\n if (claimIndex < 0) {\n throw new Error('claim id not found in claims list');\n }\n // get an array of all claims with lower height\n var possibleMatches = claimsArray.slice(0, claimIndex);\n // remove certificates with the same prefixes until none are left.\n while (possibleMatches.length > 0) {\n shortIdLength += 1;\n shortId = longId.substring(0, shortIdLength);\n possibleMatches = possibleMatches.filter(function (element) {\n return element.claimId && element.claimId.substring(0, shortIdLength) === shortId;\n });\n }\n return shortId;\n }\n};\n\n/***/ }),\n/* 13 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"sequelize\");\n\n/***/ }),\n/* 14 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _react = __webpack_require__(15);\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _server = __webpack_require__(16);\n\nvar _redux = __webpack_require__(17);\n\nvar _reactRedux = __webpack_require__(18);\n\nvar _reactRouterDom = __webpack_require__(19);\n\nvar _spee = __webpack_require__(20);\n\nvar _renderFullPage = __webpack_require__(21);\n\nvar _renderFullPage2 = _interopRequireDefault(_renderFullPage);\n\nvar _reactHelmet = __webpack_require__(22);\n\nvar _reactHelmet2 = _interopRequireDefault(_reactHelmet);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/*\n ^ note: to do this right, maybe\n these should be passed in from the implementation (www.spee.ch) itself,\n so that there are no conflicts between the SSR here and\n the bundle sent to the server?\n there might also be issues if this package uses a different version of spee.ch-components than www.spee.ch does?\n*/\nvar siteConfig = __webpack_require__(3);\n\nmodule.exports = function (req, res) {\n var context = {};\n\n // customize the reducer by passing in intial state configs\n var MyReducers = (0, _spee.Reducers)(siteConfig);\n var MyApp = (0, _spee.App)(siteConfig);\n var MyGAListener = (0, _spee.GAListener)(siteConfig);\n\n // create a new Redux store instance\n var store = (0, _redux.createStore)(MyReducers);\n\n // render component to a string\n var html = (0, _server.renderToString)(_react2.default.createElement(\n _reactRedux.Provider,\n { store: store },\n _react2.default.createElement(\n _reactRouterDom.StaticRouter,\n { location: req.url, context: context },\n _react2.default.createElement(\n MyGAListener,\n null,\n _react2.default.createElement(MyApp, null)\n )\n )\n ));\n\n // get head tags from helmet\n var helmet = _reactHelmet2.default.renderStatic();\n\n // check for a redirect\n if (context.url) {\n // Somewhere a `<Redirect>` was rendered\n return res.redirect(301, context.url);\n } else {}\n // we're good, send the response\n\n\n // get the initial state from our Redux store\n var preloadedState = store.getState();\n\n // send the rendered page back to the client\n res.send((0, _renderFullPage2.default)(helmet, html, preloadedState));\n\n console.log('hello from spee.ch handlePageRender.jsx');\n};\n\n/***/ }),\n/* 15 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"react\");\n\n/***/ }),\n/* 16 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"react-dom/server\");\n\n/***/ }),\n/* 17 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"redux\");\n\n/***/ }),\n/* 18 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"react-redux\");\n\n/***/ }),\n/* 19 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"react-router-dom\");\n\n/***/ }),\n/* 20 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"spee.ch-components\");\n\n/***/ }),\n/* 21 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nmodule.exports = function (helmet, html, preloadedState) {\n // take the html and preloadedState and return the full page\n return '\\n <!DOCTYPE html>\\n <html lang=\"en\" prefix=\"og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#\">\\n <head>\\n <meta charset=\"UTF-8\">\\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1, user-scalable=no\">\\n <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">\\n <!--helmet-->\\n ' + helmet.title.toString() + '\\n ' + helmet.meta.toString() + '\\n ' + helmet.link.toString() + '\\n <!--style sheets-->\\n <link rel=\"stylesheet\" href=\"/assets/css/reset.css\" type=\"text/css\">\\n <link rel=\"stylesheet\" href=\"/assets/css/general.css\" type=\"text/css\">\\n <link rel=\"stylesheet\" href=\"/assets/css/mediaQueries.css\" type=\"text/css\">\\n <!--google font-->\\n <link href=\"https://fonts.googleapis.com/css?family=Roboto:300\" rel=\"stylesheet\">\\n </head>\\n <body id=\"main-body\">\\n <div class=\"row row--tall flex-container--column\">\\n <div id=\"react-app\" class=\"row row--tall flex-container--column\">' + html + '</div>\\n </div>\\n <script>\\n window.__PRELOADED_STATE__ = ' + JSON.stringify(preloadedState).replace(/</g, '\\\\<') + '\\n </script>\\n <script src=\"/bundle/bundle.js\"></script>\\n </body>\\n </html>\\n ';\n};\n\n/***/ }),\n/* 22 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"react-helmet\");\n\n/***/ }),\n/* 23 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar logger = __webpack_require__(0);\n\nvar _require = __webpack_require__(6),\n getClaimId = _require.getClaimId,\n getLocalFileRecord = _require.getLocalFileRecord;\n\nvar _require2 = __webpack_require__(1),\n handleErrorResponse = _require2.handleErrorResponse;\n\nvar SERVE = 'SERVE';\nvar SHOW = 'SHOW';\nvar NO_FILE = 'NO_FILE';\nvar NO_CHANNEL = 'NO_CHANNEL';\nvar NO_CLAIM = 'NO_CLAIM';\n\nfunction clientAcceptsHtml(_ref) {\n var accept = _ref.accept;\n\n return accept && accept.match(/text\\/html/);\n};\n\nfunction requestIsFromBrowser(headers) {\n return headers['user-agent'] && headers['user-agent'].match(/Mozilla/);\n};\n\nfunction clientWantsAsset(_ref2) {\n var accept = _ref2.accept,\n range = _ref2.range;\n\n var imageIsWanted = accept && accept.match(/image\\/.*/) && !accept.match(/text\\/html/) && !accept.match(/text\\/\\*/);\n var videoIsWanted = accept && range;\n return imageIsWanted || videoIsWanted;\n};\n\nfunction isValidClaimId(claimId) {\n return claimId.length === 40 && !/[^A-Za-z0-9]/g.test(claimId);\n};\n\nfunction isValidShortId(claimId) {\n return claimId.length === 1; // it should really evaluate the short url itself\n};\n\nfunction isValidShortIdOrClaimId(input) {\n return isValidClaimId(input) || isValidShortId(input);\n};\n\nfunction serveAssetToClient(claimId, name, res) {\n return getLocalFileRecord(claimId, name).then(function (fileRecord) {\n // check that a local record was found\n if (fileRecord === NO_FILE) {\n return res.status(307).redirect('/api/claim/get/' + name + '/' + claimId);\n }\n // serve the file\n var filePath = fileRecord.filePath,\n fileType = fileRecord.fileType;\n\n logger.verbose('serving file: ' + filePath);\n var sendFileOptions = {\n headers: {\n 'X-Content-Type-Options': 'nosniff',\n 'Content-Type': fileType || 'image/jpeg'\n }\n };\n res.status(200).sendFile(filePath, sendFileOptions);\n }).catch(function (error) {\n throw error;\n });\n};\n\nmodule.exports = {\n getClaimIdAndServeAsset: function getClaimIdAndServeAsset(channelName, channelClaimId, claimName, claimId, originalUrl, ip, res) {\n // get the claim Id and then serve the asset\n getClaimId(channelName, channelClaimId, claimName, claimId).then(function (fullClaimId) {\n if (fullClaimId === NO_CLAIM) {\n return res.status(404).json({ success: false, message: 'no claim id could be found' });\n } else if (fullClaimId === NO_CHANNEL) {\n return res.status(404).json({ success: false, message: 'no channel id could be found' });\n }\n serveAssetToClient(fullClaimId, claimName, res);\n // postToStats(responseType, originalUrl, ip, claimName, fullClaimId, 'success');\n }).catch(function (error) {\n handleErrorResponse(originalUrl, ip, error, res);\n // postToStats(responseType, originalUrl, ip, claimName, fullClaimId, 'fail');\n });\n },\n determineResponseType: function determineResponseType(hasFileExtension, headers) {\n var responseType = void 0;\n if (hasFileExtension) {\n responseType = SERVE; // assume a serve request if file extension is present\n if (clientAcceptsHtml(headers)) {\n // if the request comes from a browser, change it to a show request\n responseType = SHOW;\n }\n } else {\n responseType = SHOW;\n if (clientWantsAsset(headers) && requestIsFromBrowser(headers)) {\n // this is in case someone embeds a show url\n logger.debug('Show request came from browser but wants an image/video. Changing response to serve...');\n responseType = SERVE;\n }\n }\n return responseType;\n },\n flipClaimNameAndIdForBackwardsCompatibility: function flipClaimNameAndIdForBackwardsCompatibility(identifier, name) {\n // this is a patch for backwards compatability with '/name/claim_id' url format\n if (isValidShortIdOrClaimId(name) && !isValidShortIdOrClaimId(identifier)) {\n var tempName = name;\n name = identifier;\n identifier = tempName;\n }\n return [identifier, name];\n },\n logRequestData: function logRequestData(responseType, claimName, channelName, claimId) {\n logger.debug('responseType ===', responseType);\n logger.debug('claim name === ', claimName);\n logger.debug('channel name ===', channelName);\n logger.debug('claim id ===', claimId);\n }\n};\n\n/***/ }),\n/* 24 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"]) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); } }; }();\n\nvar logger = __webpack_require__(0);\n\nmodule.exports = {\n REGEXP_INVALID_CLAIM: /[^A-Za-z0-9-]/g,\n REGEXP_INVALID_CHANNEL: /[^A-Za-z0-9-@]/g,\n REGEXP_ADDRESS: /^b(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/,\n CHANNEL_CHAR: '@',\n parseIdentifier: function parseIdentifier(identifier) {\n logger.debug('parsing identifier:', identifier);\n var componentsRegex = new RegExp('([^:$#/]*)' + // value (stops at the first separator or end)\n '([:$#]?)([^/]*)' // modifier separator, modifier (stops at the first path separator or end)\n );\n\n var _componentsRegex$exec = componentsRegex.exec(identifier).map(function (match) {\n return match || null;\n }),\n _componentsRegex$exec2 = _slicedToArray(_componentsRegex$exec, 4),\n proto = _componentsRegex$exec2[0],\n value = _componentsRegex$exec2[1],\n modifierSeperator = _componentsRegex$exec2[2],\n modifier = _componentsRegex$exec2[3];\n\n logger.debug(proto + ', ' + value + ', ' + modifierSeperator + ', ' + modifier);\n\n // Validate and process name\n if (!value) {\n throw new Error('Check your url. No channel name provided before \"' + modifierSeperator + '\"');\n }\n var isChannel = value.startsWith(module.exports.CHANNEL_CHAR);\n var channelName = isChannel ? value : null;\n var claimId = void 0;\n if (isChannel) {\n if (!channelName) {\n throw new Error('No channel name after @.');\n }\n var nameBadChars = channelName.match(module.exports.REGEXP_INVALID_CHANNEL);\n if (nameBadChars) {\n throw new Error('Invalid characters in channel name: ' + nameBadChars.join(', ') + '.');\n }\n } else {\n claimId = value;\n }\n\n // Validate and process modifier\n var channelClaimId = void 0;\n if (modifierSeperator) {\n if (!modifier) {\n throw new Error('No modifier provided after separator \"' + modifierSeperator + '\"');\n }\n\n if (modifierSeperator === ':') {\n channelClaimId = modifier;\n } else {\n throw new Error('The \"' + modifierSeperator + '\" modifier is not currently supported');\n }\n }\n return {\n isChannel: isChannel,\n channelName: channelName,\n channelClaimId: channelClaimId,\n claimId: claimId\n };\n },\n parseClaim: function parseClaim(claim) {\n logger.debug('parsing name:', claim);\n var componentsRegex = new RegExp('([^:$#/.]*)' + // name (stops at the first modifier)\n '([:$#.]?)([^/]*)' // modifier separator, modifier (stops at the first path separator or end)\n );\n\n var _componentsRegex$exec3 = componentsRegex.exec(claim).map(function (match) {\n return match || null;\n }),\n _componentsRegex$exec4 = _slicedToArray(_componentsRegex$exec3, 4),\n proto = _componentsRegex$exec4[0],\n claimName = _componentsRegex$exec4[1],\n modifierSeperator = _componentsRegex$exec4[2],\n modifier = _componentsRegex$exec4[3];\n\n logger.debug(proto + ', ' + claimName + ', ' + modifierSeperator + ', ' + modifier);\n\n // Validate and process name\n if (!claimName) {\n throw new Error('No claim name provided before .');\n }\n var nameBadChars = claimName.match(module.exports.REGEXP_INVALID_CLAIM);\n if (nameBadChars) {\n throw new Error('Invalid characters in claim name: ' + nameBadChars.join(', ') + '.');\n }\n // Validate and process modifier\n if (modifierSeperator) {\n if (!modifier) {\n throw new Error('No file extension provided after separator ' + modifierSeperator + '.');\n }\n if (modifierSeperator !== '.') {\n throw new Error('The ' + modifierSeperator + ' modifier is not supported in the claim name');\n }\n }\n // return results\n return {\n claimName: claimName\n };\n },\n parseModifier: function parseModifier(claim) {\n logger.debug('parsing modifier:', claim);\n var componentsRegex = new RegExp('([^:$#/.]*)' + // name (stops at the first modifier)\n '([:$#.]?)([^/]*)' // modifier separator, modifier (stops at the first path separator or end)\n );\n\n var _componentsRegex$exec5 = componentsRegex.exec(claim).map(function (match) {\n return match || null;\n }),\n _componentsRegex$exec6 = _slicedToArray(_componentsRegex$exec5, 4),\n proto = _componentsRegex$exec6[0],\n claimName = _componentsRegex$exec6[1],\n modifierSeperator = _componentsRegex$exec6[2],\n modifier = _componentsRegex$exec6[3];\n\n logger.debug(proto + ', ' + claimName + ', ' + modifierSeperator + ', ' + modifier);\n // Validate and process modifier\n var hasFileExtension = false;\n if (modifierSeperator) {\n hasFileExtension = true;\n }\n return {\n hasFileExtension: hasFileExtension\n };\n }\n};\n\n/***/ }),\n/* 25 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _react = __webpack_require__(15);\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _server = __webpack_require__(16);\n\nvar _redux = __webpack_require__(17);\n\nvar _reactRedux = __webpack_require__(18);\n\nvar _reactRouterDom = __webpack_require__(19);\n\nvar _renderFullPage = __webpack_require__(21);\n\nvar _renderFullPage2 = _interopRequireDefault(_renderFullPage);\n\nvar _reduxSaga = __webpack_require__(86);\n\nvar _reduxSaga2 = _interopRequireDefault(_reduxSaga);\n\nvar _effects = __webpack_require__(87);\n\nvar _spee = __webpack_require__(20);\n\nvar _reactHelmet = __webpack_require__(22);\n\nvar _reactHelmet2 = _interopRequireDefault(_reactHelmet);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n// configure the reducers by passing initial state configs\nvar siteConfig = __webpack_require__(3);\n/*\n ^ note: to do this right, maybe\n these should be passed in from the implementation (www.spee.ch) itself,\n so that there are no conflicts between the SSR here and\n the bundle sent to the server?\n there might also be issues if this package uses a different version of spee.ch-components than www.spee.ch does?\n*/\n\nvar MyReducers = (0, _spee.Reducers)(siteConfig);\nvar MyApp = (0, _spee.App)(siteConfig);\nvar MyGAListener = (0, _spee.GAListener)(siteConfig);\n\nvar returnSagaWithParams = function returnSagaWithParams(saga, params) {\n return (/*#__PURE__*/regeneratorRuntime.mark(function _callee() {\n return regeneratorRuntime.wrap(function _callee$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n _context.next = 2;\n return (0, _effects.call)(saga, params);\n\n case 2:\n case 'end':\n return _context.stop();\n }\n }\n }, _callee, this);\n })\n );\n};\n\nmodule.exports = function (req, res) {\n var context = {};\n\n // create and apply middleware\n var sagaMiddleware = (0, _reduxSaga2.default)();\n var middleware = (0, _redux.applyMiddleware)(sagaMiddleware);\n\n // create a new Redux store instance\n var store = (0, _redux.createStore)(MyReducers, middleware);\n\n // create saga\n var action = _spee.Actions.onHandleShowPageUri(req.params);\n var saga = returnSagaWithParams(_spee.Sagas.handleShowPageUri, action);\n\n // run the saga middleware\n sagaMiddleware.run(saga).done.then(function () {\n // render component to a string\n var html = (0, _server.renderToString)(_react2.default.createElement(\n _reactRedux.Provider,\n { store: store },\n _react2.default.createElement(\n _reactRouterDom.StaticRouter,\n { location: req.url, context: context },\n _react2.default.createElement(\n MyGAListener,\n null,\n _react2.default.createElement(MyApp, null)\n )\n )\n ));\n\n // get head tags from helmet\n var helmet = _reactHelmet2.default.renderStatic();\n\n // check for a redirect\n if (context.url) {\n return res.redirect(301, context.url);\n }\n\n // get the initial state from our Redux store\n var preloadedState = store.getState();\n\n // send the rendered page back to the client\n res.send((0, _renderFullPage2.default)(helmet, html, preloadedState));\n });\n\n console.log('hello from spee.ch handleShowRender.jsx');\n};\n\n/***/ }),\n/* 26 */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(27);\n__webpack_require__(28);\nmodule.exports = __webpack_require__(29);\n\n\n/***/ }),\n/* 27 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"babel-polyfill\");\n\n/***/ }),\n/* 28 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"whatwg-fetch\");\n\n/***/ }),\n/* 29 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\n// app dependencies\nvar express = __webpack_require__(30);\nvar bodyParser = __webpack_require__(31);\nvar expressHandlebars = __webpack_require__(32);\nvar Handlebars = __webpack_require__(33);\nvar helmet = __webpack_require__(34);\nvar cookieSession = __webpack_require__(35);\nvar http = __webpack_require__(36);\nvar logger = __webpack_require__(0);\nvar requestLogger = __webpack_require__(37);\nvar Path = __webpack_require__(38);\nvar loggerConfig = __webpack_require__(39);\nvar mysqlConfig = __webpack_require__(10);\nvar siteConfig = __webpack_require__(3);\nvar slackConfig = __webpack_require__(40);\n\nfunction Server() {\n var _this = this;\n\n this.configureLogger = function (userConfig) {\n loggerConfig.update(userConfig);\n };\n this.configureMysql = function (userConfig) {\n mysqlConfig.update(userConfig);\n };\n this.configureSite = function (userConfig) {\n siteConfig.update(userConfig);\n };\n this.configureSlack = function (userConfig) {\n slackConfig.update(userConfig);\n };\n this.configureModels = function () {\n logger.debug('here is where you could add/overwrite the default models');\n };\n this.configureRoutes = function () {\n logger.debug('here is where you could add/overwrite the default routes');\n };\n this.createApp = function () {\n // create an Express application\n var app = express();\n\n // trust the proxy to get ip address for us\n app.enable('trust proxy');\n\n /* add middleware */\n // set HTTP headers to protect against well-known web vulnerabilties\n app.use(helmet());\n // 'express.static' to serve static files from public directory\n if (siteConfig.routes.publicFolder) {\n // take in a different public folder, so it can serve it's own bundle if needed\n var publicFolder = Path.resolve(process.cwd(), siteConfig.routes.publicFolder);\n app.use(express.static(publicFolder));\n logger.info('serving static files from custom path:', publicFolder);\n } else {\n var publicPath = Path.resolve(__dirname, 'public');\n app.use(express.static(publicPath));\n logger.info('serving static files from default path:', publicPath);\n };\n // 'body parser' for parsing application/json\n app.use(bodyParser.json());\n // 'body parser' for parsing application/x-www-form-urlencoded\n app.use(bodyParser.urlencoded({ extended: true }));\n\n // add custom middleware (note: build out to accept dynamically use what is in server/middleware/\n app.use(requestLogger);\n\n // configure passport\n var speechPassport = __webpack_require__(7);\n // initialize passport\n var sessionKey = siteConfig.auth.sessionKey;\n app.use(cookieSession({\n name: 'session',\n keys: [sessionKey],\n maxAge: 24 * 60 * 60 * 1000 // i.e. 24 hours\n }));\n app.use(speechPassport.initialize());\n app.use(speechPassport.session());\n\n // configure handlebars & register it with express app\n var hbs = expressHandlebars.create({\n defaultLayout: 'embed',\n handlebars: Handlebars\n });\n app.engine('handlebars', hbs.engine);\n app.set('view engine', 'handlebars');\n\n // set the routes on the app\n __webpack_require__(56)(app);\n __webpack_require__(61)(app);\n __webpack_require__(80)(app);\n __webpack_require__(84)(app);\n __webpack_require__(89)(app);\n\n _this.app = app;\n };\n this.initialize = function () {\n _this.createApp();\n _this.server = http.Server(_this.app);\n };\n this.start = function () {\n var db = __webpack_require__(2);\n var PORT = siteConfig.details.port;\n // sync sequelize\n db.sequelize.sync()\n // start the server\n .then(function () {\n _this.server.listen(PORT, function () {\n logger.info('Server is listening on PORT ' + PORT);\n });\n }).catch(function (error) {\n logger.error('Startup Error:', error);\n });\n };\n};\n\nmodule.exports = Server;\n\n/***/ }),\n/* 30 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"express\");\n\n/***/ }),\n/* 31 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"body-parser\");\n\n/***/ }),\n/* 32 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"express-handlebars\");\n\n/***/ }),\n/* 33 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"handlebars\");\n\n/***/ }),\n/* 34 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"helmet\");\n\n/***/ }),\n/* 35 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"cookie-session\");\n\n/***/ }),\n/* 36 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"http\");\n\n/***/ }),\n/* 37 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar logger = __webpack_require__(0);\n\nvar requestLogger = function requestLogger(req, res, next) {\n // custom logging middleware to log all incoming http requests\n logger.verbose('Request on ' + req.originalUrl + ' from ' + req.ip);\n next();\n};\n\nmodule.exports = requestLogger;\n\n/***/ }),\n/* 38 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"path\");\n\n/***/ }),\n/* 39 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar logger = __webpack_require__(0);\n\nfunction LoggerConfig() {\n var _this = this;\n\n this.logLevel = 'debug';\n this.update = function (config) {\n if (!config) {\n return logger.warn('No logger config received.');\n }\n logger.info('configuring winston logger...');\n // update values with local config params\n var logLevel = config.logLevel;\n\n _this.logLevel = logLevel;\n // configure the winston logger\n logger.configure({\n transports: [new logger.transports.Console({\n level: _this.logLevel,\n timestamp: false,\n colorize: true,\n prettyPrint: true,\n handleExceptions: true,\n humanReadableUnhandledException: true\n })]\n });\n // test all the log levels\n logger.info('testing winston log levels...');\n logger.error('Level 0');\n logger.warn('Level 1');\n logger.info('Level 2');\n logger.verbose('Level 3');\n logger.debug('Level 4');\n logger.silly('Level 5');\n };\n};\n\nmodule.exports = new LoggerConfig();\n\n/***/ }),\n/* 40 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar winstonSlackWebHook = __webpack_require__(41).SlackWebHook;\nvar winston = __webpack_require__(0);\n\nfunction SlackConfig() {\n var _this = this;\n\n this.slackWebHook = 'default';\n this.slackErrorChannel = 'default';\n this.slackInfoChannel = 'default';\n this.update = function (config) {\n if (!config) {\n return winston.warn('No slack config received');\n }\n // update variables\n winston.info('configuring slack logger...');\n var slackWebHook = config.slackWebHook,\n slackErrorChannel = config.slackErrorChannel,\n slackInfoChannel = config.slackInfoChannel;\n\n _this.slackWebHook = slackWebHook;\n _this.slackErrorChannel = slackErrorChannel;\n _this.slackInfoChannel = slackInfoChannel;\n // update slack webhook settings\n if (_this.slackWebHook) {\n // add a transport for errors to slack\n if (_this.slackErrorChannel) {\n winston.add(winstonSlackWebHook, {\n name: 'slack-errors-transport',\n level: 'warn',\n webhookUrl: _this.slackWebHook,\n channel: _this.slackErrorChannel,\n username: 'spee.ch',\n iconEmoji: ':face_with_head_bandage:'\n });\n };\n if (slackInfoChannel) {\n winston.add(winstonSlackWebHook, {\n name: 'slack-info-transport',\n level: 'info',\n webhookUrl: _this.slackWebHook,\n channel: _this.slackInfoChannel,\n username: 'spee.ch',\n iconEmoji: ':nerd_face:'\n });\n };\n // send test messages\n winston.info('testing slack logger...');\n winston.error('Slack \"error\" logging is online.');\n winston.info('Slack \"info\" logging is online.');\n } else {\n winston.warn('Slack logging is not enabled because no slackWebHook config var provided.');\n }\n };\n};\n\nmodule.exports = new SlackConfig();\n\n/***/ }),\n/* 41 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"winston-slack-webhook\");\n\n/***/ }),\n/* 42 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"passport\");\n\n/***/ }),\n/* 43 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar PassportLocalStrategy = __webpack_require__(11).Strategy;\nvar logger = __webpack_require__(0);\nvar db = __webpack_require__(2);\n\nvar returnUserAndChannelInfo = function returnUserAndChannelInfo(userInstance) {\n return new Promise(function (resolve, reject) {\n var userInfo = {};\n userInfo['id'] = userInstance.id;\n userInfo['userName'] = userInstance.userName;\n userInstance.getChannel().then(function (_ref) {\n var channelName = _ref.channelName,\n channelClaimId = _ref.channelClaimId;\n\n userInfo['channelName'] = channelName;\n userInfo['channelClaimId'] = channelClaimId;\n return db.Certificate.getShortChannelIdFromLongChannelId(channelClaimId, channelName);\n }).then(function (shortChannelId) {\n userInfo['shortChannelId'] = shortChannelId;\n resolve(userInfo);\n }).catch(function (error) {\n reject(error);\n });\n });\n};\n\nmodule.exports = new PassportLocalStrategy({\n usernameField: 'username',\n passwordField: 'password'\n}, function (username, password, done) {\n return db.User.findOne({\n where: { userName: username }\n }).then(function (user) {\n if (!user) {\n logger.debug('no user found');\n return done(null, false, { message: 'Incorrect username or password' });\n }\n return user.comparePassword(password).then(function (isMatch) {\n if (!isMatch) {\n logger.debug('incorrect password');\n return done(null, false, { message: 'Incorrect username or password' });\n }\n logger.debug('Password was a match, returning User');\n return returnUserAndChannelInfo(user).then(function (userInfo) {\n return done(null, userInfo);\n }).catch(function (error) {\n return error;\n });\n }).catch(function (error) {\n return error;\n });\n }).catch(function (error) {\n return done(error);\n });\n});\n\n/***/ }),\n/* 44 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar logger = __webpack_require__(0);\n\nvar _require = __webpack_require__(12),\n returnShortId = _require.returnShortId;\n\nmodule.exports = function (sequelize, _ref) {\n var STRING = _ref.STRING,\n BOOLEAN = _ref.BOOLEAN,\n INTEGER = _ref.INTEGER,\n TEXT = _ref.TEXT,\n DECIMAL = _ref.DECIMAL;\n\n var Certificate = sequelize.define('Certificate', {\n address: {\n type: STRING,\n default: null\n },\n amount: {\n type: DECIMAL(19, 8),\n default: null\n },\n claimId: {\n type: STRING,\n default: null\n },\n claimSequence: {\n type: INTEGER,\n default: null\n },\n decodedClaim: {\n type: BOOLEAN,\n default: null\n },\n depth: {\n type: INTEGER,\n default: null\n },\n effectiveAmount: {\n type: DECIMAL(19, 8),\n default: null\n },\n hasSignature: {\n type: BOOLEAN,\n default: null\n },\n height: {\n type: INTEGER,\n default: null\n },\n hex: {\n type: TEXT('long'),\n default: null\n },\n name: {\n type: STRING,\n default: null\n },\n nout: {\n type: INTEGER,\n default: null\n },\n txid: {\n type: STRING,\n default: null\n },\n validAtHeight: {\n type: INTEGER,\n default: null\n },\n outpoint: {\n type: STRING,\n default: null\n },\n valueVersion: {\n type: STRING,\n default: null\n },\n claimType: {\n type: STRING,\n default: null\n },\n certificateVersion: {\n type: STRING,\n default: null\n },\n keyType: {\n type: STRING,\n default: null\n },\n publicKey: {\n type: TEXT('long'),\n default: null\n }\n }, {\n freezeTableName: true\n });\n\n Certificate.associate = function (db) {\n Certificate.belongsTo(db.Channel, {\n foreignKey: {\n allowNull: true\n }\n });\n };\n\n Certificate.getShortChannelIdFromLongChannelId = function (longChannelId, channelName) {\n var _this = this;\n\n logger.debug('getShortChannelIdFromLongChannelId ' + channelName + ':' + longChannelId);\n return new Promise(function (resolve, reject) {\n _this.findAll({\n where: { name: channelName },\n order: [['height', 'ASC']]\n }).then(function (result) {\n switch (result.length) {\n case 0:\n throw new Error('No channel(s) found with that channel name');\n default:\n return resolve(returnShortId(result, longChannelId));\n }\n }).catch(function (error) {\n reject(error);\n });\n });\n };\n\n Certificate.getLongChannelIdFromShortChannelId = function (channelName, channelClaimId) {\n var _this2 = this;\n\n logger.debug('getLongChannelIdFromShortChannelId(' + channelName + ', ' + channelClaimId + ')');\n return new Promise(function (resolve, reject) {\n _this2.findAll({\n where: {\n name: channelName,\n claimId: {\n $like: channelClaimId + '%'\n }\n },\n order: [['height', 'ASC']]\n }).then(function (result) {\n switch (result.length) {\n case 0:\n return resolve(null);\n default:\n // note results must be sorted\n return resolve(result[0].claimId);\n }\n }).catch(function (error) {\n reject(error);\n });\n });\n };\n\n Certificate.getLongChannelIdFromChannelName = function (channelName) {\n var _this3 = this;\n\n logger.debug('getLongChannelIdFromChannelName(' + channelName + ')');\n return new Promise(function (resolve, reject) {\n _this3.findAll({\n where: { name: channelName },\n order: [['effectiveAmount', 'DESC'], ['height', 'ASC']]\n }).then(function (result) {\n switch (result.length) {\n case 0:\n return resolve(null);\n default:\n return resolve(result[0].claimId);\n }\n }).catch(function (error) {\n reject(error);\n });\n });\n };\n\n Certificate.validateLongChannelId = function (name, claimId) {\n var _this4 = this;\n\n logger.debug('validateLongChannelId(' + name + ', ' + claimId + ')');\n return new Promise(function (resolve, reject) {\n _this4.findOne({\n where: { name: name, claimId: claimId }\n }).then(function (result) {\n if (!result) {\n return resolve(null);\n };\n resolve(claimId);\n }).catch(function (error) {\n reject(error);\n });\n });\n };\n\n Certificate.getLongChannelId = function (channelName, channelClaimId) {\n logger.debug('getLongChannelId(' + channelName + ', ' + channelClaimId + ')');\n if (channelClaimId && channelClaimId.length === 40) {\n // if a full channel id is provided\n return this.validateLongChannelId(channelName, channelClaimId);\n } else if (channelClaimId && channelClaimId.length < 40) {\n // if a short channel id is provided\n return this.getLongChannelIdFromShortChannelId(channelName, channelClaimId);\n } else {\n return this.getLongChannelIdFromChannelName(channelName); // if no channel id provided\n }\n };\n\n return Certificate;\n};\n\n/***/ }),\n/* 45 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nmodule.exports = function (sequelize, _ref) {\n var STRING = _ref.STRING;\n\n var Channel = sequelize.define('Channel', {\n channelName: {\n type: STRING,\n allowNull: false\n },\n channelClaimId: {\n type: STRING,\n allowNull: false\n }\n }, {\n freezeTableName: true\n });\n\n Channel.associate = function (db) {\n Channel.belongsTo(db.User);\n Channel.hasOne(db.Certificate);\n };\n\n return Channel;\n};\n\n/***/ }),\n/* 46 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar logger = __webpack_require__(0);\n\nvar _require = __webpack_require__(12),\n returnShortId = _require.returnShortId;\n\nvar _require2 = __webpack_require__(3),\n defaultThumbnail = _require2.assetDefaults.thumbnail,\n host = _require2.details.host;\n\nfunction determineFileExtensionFromContentType(contentType) {\n switch (contentType) {\n case 'image/jpeg':\n case 'image/jpg':\n return 'jpeg';\n case 'image/png':\n return 'png';\n case 'image/gif':\n return 'gif';\n case 'video/mp4':\n return 'mp4';\n default:\n logger.debug('setting unknown file type as file extension jpeg');\n return 'jpeg';\n }\n};\n\nfunction determineThumbnail(storedThumbnail, defaultThumbnail) {\n if (storedThumbnail === '') {\n return defaultThumbnail;\n }\n return storedThumbnail;\n};\n\nfunction prepareClaimData(claim) {\n // logger.debug('preparing claim data based on resolved data:', claim);\n claim['thumbnail'] = determineThumbnail(claim.thumbnail, defaultThumbnail);\n claim['fileExt'] = determineFileExtensionFromContentType(claim.contentType);\n claim['host'] = host;\n return claim;\n};\n\nmodule.exports = function (sequelize, _ref) {\n var STRING = _ref.STRING,\n BOOLEAN = _ref.BOOLEAN,\n INTEGER = _ref.INTEGER,\n TEXT = _ref.TEXT,\n DECIMAL = _ref.DECIMAL;\n\n var Claim = sequelize.define('Claim', {\n address: {\n type: STRING,\n default: null\n },\n amount: {\n type: DECIMAL(19, 8),\n default: null\n },\n claimId: {\n type: STRING,\n default: null\n },\n claimSequence: {\n type: INTEGER,\n default: null\n },\n decodedClaim: {\n type: BOOLEAN,\n default: null\n },\n depth: {\n type: INTEGER,\n default: null\n },\n effectiveAmount: {\n type: DECIMAL(19, 8),\n default: null\n },\n hasSignature: {\n type: BOOLEAN,\n default: null\n },\n height: {\n type: INTEGER,\n default: null\n },\n hex: {\n type: TEXT('long'),\n default: null\n },\n name: {\n type: STRING,\n default: null\n },\n nout: {\n type: INTEGER,\n default: null\n },\n txid: {\n type: STRING,\n default: null\n },\n validAtHeight: {\n type: INTEGER,\n default: null\n },\n outpoint: {\n type: STRING,\n default: null\n },\n claimType: {\n type: STRING,\n default: null\n },\n certificateId: {\n type: STRING,\n default: null\n },\n author: {\n type: STRING,\n default: null\n },\n description: {\n type: TEXT('long'),\n default: null\n },\n language: {\n type: STRING,\n default: null\n },\n license: {\n type: STRING,\n default: null\n },\n licenseUrl: {\n type: STRING,\n default: null\n },\n nsfw: {\n type: BOOLEAN,\n default: null\n },\n preview: {\n type: STRING,\n default: null\n },\n thumbnail: {\n type: STRING,\n default: null\n },\n title: {\n type: STRING,\n default: null\n },\n metadataVersion: {\n type: STRING,\n default: null\n },\n contentType: {\n type: STRING,\n default: null\n },\n source: {\n type: STRING,\n default: null\n },\n sourceType: {\n type: STRING,\n default: null\n },\n sourceVersion: {\n type: STRING,\n default: null\n },\n streamVersion: {\n type: STRING,\n default: null\n },\n valueVersion: {\n type: STRING,\n default: null\n },\n channelName: {\n type: STRING,\n allowNull: true,\n default: null\n }\n }, {\n freezeTableName: true\n });\n\n Claim.associate = function (db) {\n Claim.belongsTo(db.File, {\n foreignKey: {\n allowNull: true\n }\n });\n };\n\n Claim.getShortClaimIdFromLongClaimId = function (claimId, claimName) {\n var _this = this;\n\n logger.debug('Claim.getShortClaimIdFromLongClaimId for ' + claimName + '#' + claimId);\n return new Promise(function (resolve, reject) {\n _this.findAll({\n where: { name: claimName },\n order: [['height', 'ASC']]\n }).then(function (result) {\n switch (result.length) {\n case 0:\n throw new Error('No claim(s) found with that claim name');\n default:\n resolve(returnShortId(result, claimId));\n }\n }).catch(function (error) {\n reject(error);\n });\n });\n };\n\n Claim.getAllChannelClaims = function (channelClaimId) {\n var _this2 = this;\n\n logger.debug('Claim.getAllChannelClaims for ' + channelClaimId);\n return new Promise(function (resolve, reject) {\n _this2.findAll({\n where: { certificateId: channelClaimId },\n order: [['height', 'ASC']],\n raw: true // returns an array of only data, not an array of instances\n }).then(function (channelClaimsArray) {\n // logger.debug('channelclaimsarray length:', channelClaimsArray.length);\n switch (channelClaimsArray.length) {\n case 0:\n return resolve(null);\n default:\n channelClaimsArray.forEach(function (claim) {\n claim['fileExt'] = determineFileExtensionFromContentType(claim.contentType);\n claim['thumbnail'] = determineThumbnail(claim.thumbnail, defaultThumbnail);\n return claim;\n });\n return resolve(channelClaimsArray);\n }\n }).catch(function (error) {\n reject(error);\n });\n });\n };\n\n Claim.getClaimIdByLongChannelId = function (channelClaimId, claimName) {\n var _this3 = this;\n\n logger.debug('finding claim id for claim ' + claimName + ' from channel ' + channelClaimId);\n return new Promise(function (resolve, reject) {\n _this3.findAll({\n where: { name: claimName, certificateId: channelClaimId },\n order: [['id', 'ASC']]\n }).then(function (result) {\n switch (result.length) {\n case 0:\n return resolve(null);\n case 1:\n return resolve(result[0].claimId);\n default:\n logger.error(result.length + ' records found for \"' + claimName + '\" in channel \"' + channelClaimId + '\"');\n return resolve(result[0].claimId);\n }\n }).catch(function (error) {\n reject(error);\n });\n });\n };\n\n Claim.getLongClaimIdFromShortClaimId = function (name, shortId) {\n var _this4 = this;\n\n return new Promise(function (resolve, reject) {\n _this4.findAll({\n where: {\n name: name,\n claimId: {\n $like: shortId + '%'\n } },\n order: [['height', 'ASC']]\n }).then(function (result) {\n switch (result.length) {\n case 0:\n return resolve(null);\n default:\n // note results must be sorted\n return resolve(result[0].claimId);\n }\n }).catch(function (error) {\n reject(error);\n });\n });\n };\n\n Claim.getTopFreeClaimIdByClaimName = function (name) {\n var _this5 = this;\n\n return new Promise(function (resolve, reject) {\n _this5.findAll({\n where: { name: name },\n order: [['effectiveAmount', 'DESC'], ['height', 'ASC']] // note: maybe height and effective amount need to switch?\n }).then(function (result) {\n logger.debug('length of result', result.length);\n switch (result.length) {\n case 0:\n return resolve(null);\n default:\n return resolve(result[0].dataValues.claimId);\n }\n }).catch(function (error) {\n reject(error);\n });\n });\n };\n\n Claim.validateLongClaimId = function (name, claimId) {\n var _this6 = this;\n\n return new Promise(function (resolve, reject) {\n _this6.findOne({\n where: { name: name, claimId: claimId }\n }).then(function (result) {\n if (!result) {\n return resolve(null);\n };\n resolve(claimId);\n }).catch(function (error) {\n reject(error);\n });\n });\n };\n\n Claim.getLongClaimId = function (claimName, claimId) {\n logger.debug('getLongClaimId(' + claimName + ', ' + claimId + ')');\n if (claimId && claimId.length === 40) {\n // if a full claim id is provided\n return this.validateLongClaimId(claimName, claimId);\n } else if (claimId && claimId.length < 40) {\n return this.getLongClaimIdFromShortClaimId(claimName, claimId); // if a short claim id is provided\n } else {\n return this.getTopFreeClaimIdByClaimName(claimName); // if no claim id is provided\n }\n };\n\n Claim.resolveClaim = function (name, claimId) {\n var _this7 = this;\n\n logger.debug('Claim.resolveClaim: ' + name + ' ' + claimId);\n return new Promise(function (resolve, reject) {\n _this7.findAll({\n where: { name: name, claimId: claimId }\n }).then(function (claimArray) {\n switch (claimArray.length) {\n case 0:\n return resolve(null);\n case 1:\n return resolve(prepareClaimData(claimArray[0].dataValues));\n default:\n logger.error('more than one record matches ' + name + '#' + claimId + ' in db.Claim');\n return resolve(prepareClaimData(claimArray[0].dataValues));\n }\n }).catch(function (error) {\n reject(error);\n });\n });\n };\n\n return Claim;\n};\n\n/***/ }),\n/* 47 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nmodule.exports = function (sequelize, _ref) {\n var STRING = _ref.STRING,\n BOOLEAN = _ref.BOOLEAN,\n INTEGER = _ref.INTEGER;\n\n var File = sequelize.define('File', {\n name: {\n type: STRING,\n allowNull: false\n },\n claimId: {\n type: STRING,\n allowNull: false\n },\n address: {\n type: STRING,\n allowNull: false\n },\n outpoint: {\n type: STRING,\n allowNull: false\n },\n height: {\n type: INTEGER,\n allowNull: false,\n default: 0\n },\n fileName: {\n type: STRING,\n allowNull: false\n },\n filePath: {\n type: STRING,\n allowNull: false\n },\n fileType: {\n type: STRING\n },\n nsfw: {\n type: BOOLEAN,\n allowNull: false,\n defaultValue: false\n },\n trendingEligible: {\n type: BOOLEAN,\n allowNull: false,\n defaultValue: true\n }\n }, {\n freezeTableName: true\n });\n\n File.associate = function (db) {\n File.hasMany(db.Request);\n File.hasOne(db.Claim);\n };\n\n File.getRecentClaims = function () {\n return this.findAll({\n where: { nsfw: false, trendingEligible: true },\n order: [['createdAt', 'DESC']],\n limit: 25\n });\n };\n\n return File;\n};\n\n/***/ }),\n/* 48 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nmodule.exports = function (sequelize, _ref) {\n var STRING = _ref.STRING,\n BOOLEAN = _ref.BOOLEAN,\n TEXT = _ref.TEXT;\n\n var Request = sequelize.define('Request', {\n action: {\n type: STRING,\n allowNull: false\n },\n url: {\n type: STRING,\n allowNull: false\n },\n ipAddress: {\n type: STRING,\n allowNull: true\n },\n result: {\n type: TEXT('long'),\n allowNull: true,\n default: null\n }\n }, {\n freezeTableName: true\n });\n\n Request.associate = function (db) {\n Request.belongsTo(db.File, {\n foreignKey: {\n allowNull: true\n }\n });\n };\n\n return Request;\n};\n\n/***/ }),\n/* 49 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar bcrypt = __webpack_require__(50);\nvar logger = __webpack_require__(0);\n\nmodule.exports = function (sequelize, _ref) {\n var STRING = _ref.STRING;\n\n var User = sequelize.define('User', {\n userName: {\n type: STRING,\n allowNull: false\n },\n password: {\n type: STRING,\n allowNull: false\n }\n }, {\n freezeTableName: true\n });\n\n User.associate = function (db) {\n User.hasOne(db.Channel);\n };\n\n User.prototype.comparePassword = function (password) {\n return bcrypt.compare(password, this.password);\n };\n\n User.prototype.changePassword = function (newPassword) {\n var _this = this;\n\n return new Promise(function (resolve, reject) {\n // generate a salt string to use for hashing\n bcrypt.genSalt(function (saltError, salt) {\n if (saltError) {\n logger.error('salt error', saltError);\n reject(saltError);\n return;\n }\n // generate a hashed version of the user's password\n bcrypt.hash(newPassword, salt, function (hashError, hash) {\n // if there is an error with the hash generation return the error\n if (hashError) {\n logger.error('hash error', hashError);\n reject(hashError);\n return;\n }\n // replace the current password with the new hash\n _this.update({ password: hash }).then(function () {\n resolve();\n }).catch(function (error) {\n reject(error);\n });\n });\n });\n });\n };\n\n // pre-save hook method to hash the user's password before the user's info is saved to the db.\n User.hook('beforeCreate', function (user, options) {\n logger.debug('User.beforeCreate hook...');\n return new Promise(function (resolve, reject) {\n // generate a salt string to use for hashing\n bcrypt.genSalt(function (saltError, salt) {\n if (saltError) {\n logger.error('salt error', saltError);\n reject(saltError);\n return;\n }\n // generate a hashed version of the user's password\n bcrypt.hash(user.password, salt, function (hashError, hash) {\n // if there is an error with the hash generation return the error\n if (hashError) {\n logger.error('hash error', hashError);\n reject(hashError);\n return;\n }\n // replace the password string with the hash password value\n user.password = hash;\n resolve();\n });\n });\n });\n });\n\n return User;\n};\n\n/***/ }),\n/* 50 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"bcrypt\");\n\n/***/ }),\n/* 51 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"]) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); } }; }();\n\nvar PassportLocalStrategy = __webpack_require__(11).Strategy;\nvar lbryApi = __webpack_require__(5);\nvar logger = __webpack_require__(0);\nvar db = __webpack_require__(2);\n\nmodule.exports = new PassportLocalStrategy({\n usernameField: 'username',\n passwordField: 'password'\n}, function (username, password, done) {\n logger.verbose('new channel signup request. user: ' + username + ' pass: ' + password + ' .');\n var userInfo = {};\n // server-side validaton of inputs (username, password)\n\n // create the channel and retrieve the metadata\n return lbryApi.createChannel('@' + username).then(function (tx) {\n // create user record\n var userData = {\n userName: username,\n password: password\n };\n logger.verbose('userData >', userData);\n // create user record\n var channelData = {\n channelName: '@' + username,\n channelClaimId: tx.claim_id\n };\n logger.verbose('channelData >', channelData);\n // create certificate record\n var certificateData = {\n claimId: tx.claim_id,\n name: '@' + username\n // address,\n };\n logger.verbose('certificateData >', certificateData);\n // save user and certificate to db\n return Promise.all([db.User.create(userData), db.Channel.create(channelData), db.Certificate.create(certificateData)]);\n }).then(function (_ref) {\n var _ref2 = _slicedToArray(_ref, 3),\n newUser = _ref2[0],\n newChannel = _ref2[1],\n newCertificate = _ref2[2];\n\n logger.verbose('user and certificate successfully created');\n // store the relevant newUser info to be passed back for req.User\n userInfo['id'] = newUser.id;\n userInfo['userName'] = newUser.userName;\n userInfo['channelName'] = newChannel.channelName;\n userInfo['channelClaimId'] = newChannel.channelClaimId;\n // associate the instances\n return Promise.all([newCertificate.setChannel(newChannel), newChannel.setUser(newUser)]);\n }).then(function () {\n logger.verbose('user and certificate successfully associated');\n return db.Certificate.getShortChannelIdFromLongChannelId(userInfo.channelClaimId, userInfo.channelName);\n }).then(function (shortChannelId) {\n userInfo['shortChannelId'] = shortChannelId;\n return done(null, userInfo);\n }).catch(function (error) {\n logger.error('signup error', error);\n return done(error);\n });\n});\n\n/***/ }),\n/* 52 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"axios\");\n\n/***/ }),\n/* 53 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar lbryConfig = {\n api: {\n apiHost: 'localhost',\n apiPort: '5279'\n }\n};\n\nmodule.exports = lbryConfig;\n\n/***/ }),\n/* 54 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"universal-analytics\");\n\n/***/ }),\n/* 55 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nmodule.exports = {\n serializeSpeechUser: function serializeSpeechUser(user, done) {\n // returns user data to be serialized into session\n console.log('serializing user');\n done(null, user);\n },\n deserializeSpeechUser: function deserializeSpeechUser(user, done) {\n // deserializes session and populates additional info to req.user\n console.log('deserializing user');\n done(null, user);\n }\n};\n\n/***/ }),\n/* 56 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar speechPassport = __webpack_require__(7);\nvar handleSignupRequest = __webpack_require__(57);\nvar handleLoginRequest = __webpack_require__(58);\nvar handleLogoutRequest = __webpack_require__(59);\nvar handleUserRequest = __webpack_require__(60);\n\nmodule.exports = function (app) {\n app.post('/signup', speechPassport.authenticate('local-signup'), handleSignupRequest);\n app.post('/login', handleLoginRequest);\n app.get('/logout', handleLogoutRequest);\n app.get('/user', handleUserRequest);\n};\n\n/***/ }),\n/* 57 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar signup = function signup(req, res) {\n res.status(200).json({\n success: true,\n channelName: req.user.channelName,\n channelClaimId: req.user.channelClaimId,\n shortChannelId: req.user.shortChannelId\n });\n};\n\nmodule.exports = signup;\n\n/***/ }),\n/* 58 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar speechPassport = __webpack_require__(7);\n\nvar login = function login(req, res, next) {\n speechPassport.authenticate('local-login', function (err, user, info) {\n if (err) {\n return next(err);\n }\n if (!user) {\n return res.status(400).json({\n success: false,\n message: info.message\n });\n }\n req.logIn(user, function (err) {\n if (err) {\n return next(err);\n }\n return res.status(200).json({\n success: true,\n channelName: req.user.channelName,\n channelClaimId: req.user.channelClaimId,\n shortChannelId: req.user.shortChannelId\n });\n });\n })(req, res, next);\n};\n\nmodule.exports = login;\n\n/***/ }),\n/* 59 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar logout = function logout(req, res) {\n req.logout();\n res.status(200).json({ success: true, message: 'you successfully logged out' });\n};\n\nmodule.exports = logout;\n\n/***/ }),\n/* 60 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar user = function user(req, res) {\n if (req.user) {\n res.status(200).json({ success: true, data: req.user });\n } else {\n res.status(401).json({ success: false, message: 'user is not logged in' });\n }\n};\n\nmodule.exports = user;\n\n/***/ }),\n/* 61 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar channelAvailability = __webpack_require__(62);\nvar channelClaims = __webpack_require__(64);\nvar channelData = __webpack_require__(66);\nvar channelShortId = __webpack_require__(67);\nvar claimAvailability = __webpack_require__(68);\nvar claimData = __webpack_require__(69);\nvar claimGet = __webpack_require__(70);\nvar claimLongId = __webpack_require__(71);\nvar claimPublish = __webpack_require__(72);\nvar claimResolve = __webpack_require__(74);\nvar claimShortId = __webpack_require__(75);\nvar claimList = __webpack_require__(76);\nvar fileAvailability = __webpack_require__(77);\n\nvar multipartMiddleware = __webpack_require__(78);\n\nmodule.exports = function (app) {\n // channel routes\n app.get('/api/channel/availability/:name', channelAvailability);\n app.get('/api/channel/short-id/:longId/:name', channelShortId);\n app.get('/api/channel/data/:channelName/:channelClaimId', channelData);\n app.get('/api/channel/claims/:channelName/:channelClaimId/:page', channelClaims);\n // claim routes\n app.get('/api/claim/list/:name', claimList);\n app.get('/api/claim/get/:name/:claimId', claimGet);\n app.get('/api/claim/availability/:name', claimAvailability);\n app.get('/api/claim/resolve/:name/:claimId', claimResolve);\n app.post('/api/claim/publish', multipartMiddleware, claimPublish);\n app.get('/api/claim/short-id/:longId/:name', claimShortId);\n app.post('/api/claim/long-id', claimLongId);\n app.get('/api/claim/data/:claimName/:claimId', claimData);\n // file routes\n app.get('/api/file/availability/:name/:claimId', fileAvailability);\n};\n\n/***/ }),\n/* 62 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _require = __webpack_require__(8),\n checkChannelAvailability = _require.checkChannelAvailability;\n\nvar _require2 = __webpack_require__(4),\n sendGATimingEvent = _require2.sendGATimingEvent;\n\nvar _require3 = __webpack_require__(1),\n handleErrorResponse = _require3.handleErrorResponse;\n\n/*\n\n route to check whether site has published to a channel\n\n*/\n\nvar channelAvailability = function channelAvailability(_ref, res) {\n var ip = _ref.ip,\n originalUrl = _ref.originalUrl,\n name = _ref.params.name;\n\n var gaStartTime = Date.now();\n checkChannelAvailability(name).then(function (availableName) {\n res.status(200).json(availableName);\n sendGATimingEvent('end-to-end', 'claim name availability', name, gaStartTime, Date.now());\n }).catch(function (error) {\n handleErrorResponse(originalUrl, ip, error, res);\n });\n};\n\nmodule.exports = channelAvailability;\n\n/***/ }),\n/* 63 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"fs\");\n\n/***/ }),\n/* 64 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _require = __webpack_require__(6),\n getChannelClaims = _require.getChannelClaims;\n\nvar _require2 = __webpack_require__(1),\n handleErrorResponse = _require2.handleErrorResponse;\n\nvar NO_CHANNEL = 'NO_CHANNEL';\n\n/*\n\n route to get all claims for channel\n\n*/\n\nvar channelClaims = function channelClaims(_ref, res) {\n var ip = _ref.ip,\n originalUrl = _ref.originalUrl,\n body = _ref.body,\n params = _ref.params;\n\n var channelName = params.channelName;\n var channelClaimId = params.channelClaimId;\n if (channelClaimId === 'none') channelClaimId = null;\n var page = params.page;\n getChannelClaims(channelName, channelClaimId, page).then(function (data) {\n if (data === NO_CHANNEL) {\n return res.status(404).json({ success: false, message: 'No matching channel was found' });\n }\n res.status(200).json({ success: true, data: data });\n }).catch(function (error) {\n handleErrorResponse(originalUrl, ip, error, res);\n });\n};\n\nmodule.exports = channelClaims;\n\n/***/ }),\n/* 65 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar CLAIMS_PER_PAGE = 12;\n\nmodule.exports = {\n returnPaginatedChannelClaims: function returnPaginatedChannelClaims(channelName, longChannelClaimId, claims, page) {\n var totalPages = module.exports.determineTotalPages(claims);\n var paginationPage = module.exports.getPageFromQuery(page);\n var viewData = {\n channelName: channelName,\n longChannelClaimId: longChannelClaimId,\n claims: module.exports.extractPageFromClaims(claims, paginationPage),\n previousPage: module.exports.determinePreviousPage(paginationPage),\n currentPage: paginationPage,\n nextPage: module.exports.determineNextPage(totalPages, paginationPage),\n totalPages: totalPages,\n totalResults: module.exports.determineTotalClaims(claims)\n };\n return viewData;\n },\n getPageFromQuery: function getPageFromQuery(page) {\n if (page) {\n return parseInt(page);\n }\n return 1;\n },\n extractPageFromClaims: function extractPageFromClaims(claims, pageNumber) {\n if (!claims) {\n return []; // if no claims, return this default\n }\n // logger.debug('claims is array?', Array.isArray(claims));\n // logger.debug(`pageNumber ${pageNumber} is number?`, Number.isInteger(pageNumber));\n var claimStartIndex = (pageNumber - 1) * CLAIMS_PER_PAGE;\n var claimEndIndex = claimStartIndex + CLAIMS_PER_PAGE;\n var pageOfClaims = claims.slice(claimStartIndex, claimEndIndex);\n return pageOfClaims;\n },\n determineTotalPages: function determineTotalPages(claims) {\n if (!claims) {\n return 0;\n } else {\n var totalClaims = claims.length;\n if (totalClaims < CLAIMS_PER_PAGE) {\n return 1;\n }\n var fullPages = Math.floor(totalClaims / CLAIMS_PER_PAGE);\n var remainder = totalClaims % CLAIMS_PER_PAGE;\n if (remainder === 0) {\n return fullPages;\n }\n return fullPages + 1;\n }\n },\n determinePreviousPage: function determinePreviousPage(currentPage) {\n if (currentPage === 1) {\n return null;\n }\n return currentPage - 1;\n },\n determineNextPage: function determineNextPage(totalPages, currentPage) {\n if (currentPage === totalPages) {\n return null;\n }\n return currentPage + 1;\n },\n determineTotalClaims: function determineTotalClaims(claims) {\n if (!claims) {\n return 0;\n }\n return claims.length;\n }\n};\n\n/***/ }),\n/* 66 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _require = __webpack_require__(6),\n getChannelData = _require.getChannelData;\n\nvar _require2 = __webpack_require__(1),\n handleErrorResponse = _require2.handleErrorResponse;\n\nvar NO_CHANNEL = 'NO_CHANNEL';\n\n/*\n\n route to get data for a channel\n\n*/\n\nvar channelData = function channelData(_ref, res) {\n var ip = _ref.ip,\n originalUrl = _ref.originalUrl,\n body = _ref.body,\n params = _ref.params;\n\n var channelName = params.channelName;\n var channelClaimId = params.channelClaimId;\n if (channelClaimId === 'none') channelClaimId = null;\n getChannelData(channelName, channelClaimId, 0).then(function (data) {\n if (data === NO_CHANNEL) {\n return res.status(404).json({ success: false, message: 'No matching channel was found' });\n }\n res.status(200).json({ success: true, data: data });\n }).catch(function (error) {\n handleErrorResponse(originalUrl, ip, error, res);\n });\n};\n\nmodule.exports = channelData;\n\n/***/ }),\n/* 67 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _require = __webpack_require__(1),\n handleErrorResponse = _require.handleErrorResponse;\n\nvar db = __webpack_require__(2);\n\n/*\n\nroute to get a short channel id from long channel Id\n\n*/\n\nvar channelShortIdRoute = function channelShortIdRoute(_ref, res) {\n var ip = _ref.ip,\n originalUrl = _ref.originalUrl,\n params = _ref.params;\n\n db.Certificate.getShortChannelIdFromLongChannelId(params.longId, params.name).then(function (shortId) {\n res.status(200).json(shortId);\n }).catch(function (error) {\n handleErrorResponse(originalUrl, ip, error, res);\n });\n};\n\nmodule.exports = channelShortIdRoute;\n\n/***/ }),\n/* 68 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _require = __webpack_require__(8),\n claimNameIsAvailable = _require.claimNameIsAvailable;\n\nvar _require2 = __webpack_require__(4),\n sendGATimingEvent = _require2.sendGATimingEvent;\n\nvar _require3 = __webpack_require__(1),\n handleErrorResponse = _require3.handleErrorResponse;\n\n/*\n\n route to check whether this site published to a claim\n\n*/\n\nvar claimAvailability = function claimAvailability(_ref, res) {\n var ip = _ref.ip,\n originalUrl = _ref.originalUrl,\n name = _ref.params.name;\n\n var gaStartTime = Date.now();\n claimNameIsAvailable(name).then(function (result) {\n res.status(200).json(result);\n sendGATimingEvent('end-to-end', 'claim name availability', name, gaStartTime, Date.now());\n }).catch(function (error) {\n handleErrorResponse(originalUrl, ip, error, res);\n });\n};\n\nmodule.exports = claimAvailability;\n\n/***/ }),\n/* 69 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _require = __webpack_require__(1),\n handleErrorResponse = _require.handleErrorResponse;\n\nvar db = __webpack_require__(2);\n\n/*\n\n route to return data for a claim\n\n*/\n\nvar claimData = function claimData(_ref, res) {\n var ip = _ref.ip,\n originalUrl = _ref.originalUrl,\n body = _ref.body,\n params = _ref.params;\n\n var claimName = params.claimName;\n var claimId = params.claimId;\n if (claimId === 'none') claimId = null;\n db.Claim.resolveClaim(claimName, claimId).then(function (claimInfo) {\n if (!claimInfo) {\n return res.status(404).json({ success: false, message: 'No claim could be found' });\n }\n res.status(200).json({ success: true, data: claimInfo });\n }).catch(function (error) {\n handleErrorResponse(originalUrl, ip, error, res);\n });\n};\n\nmodule.exports = claimData;\n\n/***/ }),\n/* 70 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"]) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); } }; }();\n\nvar _require = __webpack_require__(5),\n getClaim = _require.getClaim;\n\nvar _require2 = __webpack_require__(9),\n addGetResultsToFileData = _require2.addGetResultsToFileData,\n createFileData = _require2.createFileData;\n\nvar _require3 = __webpack_require__(1),\n handleErrorResponse = _require3.handleErrorResponse;\n\nvar db = __webpack_require__(2);\n\n/*\n\n route to get a claim\n\n*/\n\nvar claimGet = function claimGet(_ref, res) {\n var ip = _ref.ip,\n originalUrl = _ref.originalUrl,\n params = _ref.params;\n\n var name = params.name;\n var claimId = params.claimId;\n // resolve the claim\n db.Claim.resolveClaim(name, claimId).then(function (resolveResult) {\n // make sure a claim actually exists at that uri\n if (!resolveResult) {\n throw new Error('No matching uri found in Claim table');\n }\n var fileData = createFileData(resolveResult);\n // get the claim\n return Promise.all([fileData, getClaim(name + '#' + claimId)]);\n }).then(function (_ref2) {\n var _ref3 = _slicedToArray(_ref2, 2),\n fileData = _ref3[0],\n getResult = _ref3[1];\n\n fileData = addGetResultsToFileData(fileData, getResult);\n return Promise.all([db.upsert(db.File, fileData, { name: name, claimId: claimId }, 'File'), getResult]);\n }).then(function (_ref4) {\n var _ref5 = _slicedToArray(_ref4, 2),\n fileRecord = _ref5[0],\n _ref5$ = _ref5[1],\n message = _ref5$.message,\n completed = _ref5$.completed;\n\n res.status(200).json({ success: true, message: message, completed: completed });\n }).catch(function (error) {\n handleErrorResponse(originalUrl, ip, error, res);\n });\n};\n\nmodule.exports = claimGet;\n\n/***/ }),\n/* 71 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _require = __webpack_require__(6),\n getClaimId = _require.getClaimId;\n\nvar _require2 = __webpack_require__(1),\n handleErrorResponse = _require2.handleErrorResponse;\n\nvar NO_CHANNEL = 'NO_CHANNEL';\nvar NO_CLAIM = 'NO_CLAIM';\n\n/*\n\n route to get a long claim id\n\n*/\n\nvar claimLongId = function claimLongId(_ref, res) {\n var ip = _ref.ip,\n originalUrl = _ref.originalUrl,\n body = _ref.body,\n params = _ref.params;\n\n var channelName = body.channelName;\n var channelClaimId = body.channelClaimId;\n var claimName = body.claimName;\n var claimId = body.claimId;\n getClaimId(channelName, channelClaimId, claimName, claimId).then(function (result) {\n if (result === NO_CHANNEL) {\n return res.status(404).json({ success: false, message: 'No matching channel could be found' });\n }\n if (result === NO_CLAIM) {\n return res.status(404).json({ success: false, message: 'No matching claim id could be found' });\n }\n res.status(200).json({ success: true, data: result });\n }).catch(function (error) {\n handleErrorResponse(originalUrl, ip, error, res);\n });\n};\n\nmodule.exports = claimLongId;\n\n/***/ }),\n/* 72 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"]) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); } }; }();\n\nvar _require = __webpack_require__(9),\n createBasicPublishParams = _require.createBasicPublishParams,\n createThumbnailPublishParams = _require.createThumbnailPublishParams,\n parsePublishApiRequestBody = _require.parsePublishApiRequestBody,\n parsePublishApiRequestFiles = _require.parsePublishApiRequestFiles;\n\nvar _require2 = __webpack_require__(8),\n claimNameIsAvailable = _require2.claimNameIsAvailable,\n publish = _require2.publish;\n\nvar _require3 = __webpack_require__(73),\n authenticateUser = _require3.authenticateUser;\n\nvar _require4 = __webpack_require__(4),\n sendGATimingEvent = _require4.sendGATimingEvent;\n\nvar _require5 = __webpack_require__(1),\n handleErrorResponse = _require5.handleErrorResponse;\n\nvar _require6 = __webpack_require__(3),\n host = _require6.details.host;\n\n/*\n\n route to publish a claim through the daemon\n\n*/\n\nvar claimPublish = function claimPublish(_ref, res) {\n var body = _ref.body,\n files = _ref.files,\n headers = _ref.headers,\n ip = _ref.ip,\n originalUrl = _ref.originalUrl,\n user = _ref.user;\n\n // define variables\n var channelName = void 0,\n channelId = void 0,\n channelPassword = void 0,\n description = void 0,\n fileName = void 0,\n filePath = void 0,\n fileType = void 0,\n gaStartTime = void 0,\n license = void 0,\n name = void 0,\n nsfw = void 0,\n thumbnail = void 0,\n thumbnailFileName = void 0,\n thumbnailFilePath = void 0,\n thumbnailFileType = void 0,\n title = void 0;\n // record the start time of the request\n gaStartTime = Date.now();\n // validate the body and files of the request\n try {\n var _parsePublishApiReque = parsePublishApiRequestBody(body);\n // validateApiPublishRequest(body, files);\n\n\n name = _parsePublishApiReque.name;\n nsfw = _parsePublishApiReque.nsfw;\n license = _parsePublishApiReque.license;\n title = _parsePublishApiReque.title;\n description = _parsePublishApiReque.description;\n thumbnail = _parsePublishApiReque.thumbnail;\n\n var _parsePublishApiReque2 = parsePublishApiRequestFiles(files);\n\n fileName = _parsePublishApiReque2.fileName;\n filePath = _parsePublishApiReque2.filePath;\n fileType = _parsePublishApiReque2.fileType;\n thumbnailFileName = _parsePublishApiReque2.thumbnailFileName;\n thumbnailFilePath = _parsePublishApiReque2.thumbnailFilePath;\n thumbnailFileType = _parsePublishApiReque2.thumbnailFileType;\n channelName = body.channelName;\n channelId = body.channelId;\n channelPassword = body.channelPassword;\n } catch (error) {\n return res.status(400).json({ success: false, message: error.message });\n }\n // check channel authorization\n Promise.all([authenticateUser(channelName, channelId, channelPassword, user), claimNameIsAvailable(name), createBasicPublishParams(filePath, name, title, description, license, nsfw, thumbnail), createThumbnailPublishParams(thumbnailFilePath, name, license, nsfw)]).then(function (_ref2) {\n var _ref3 = _slicedToArray(_ref2, 4),\n _ref3$ = _ref3[0],\n channelName = _ref3$.channelName,\n channelClaimId = _ref3$.channelClaimId,\n validatedClaimName = _ref3[1],\n publishParams = _ref3[2],\n thumbnailPublishParams = _ref3[3];\n\n // add channel details to the publish params\n if (channelName && channelClaimId) {\n publishParams['channel_name'] = channelName;\n publishParams['channel_id'] = channelClaimId;\n }\n // publish the thumbnail\n if (thumbnailPublishParams) {\n publish(thumbnailPublishParams, thumbnailFileName, thumbnailFileType);\n }\n // publish the asset\n return publish(publishParams, fileName, fileType);\n }).then(function (result) {\n res.status(200).json({\n success: true,\n message: 'publish completed successfully',\n data: {\n name: name,\n claimId: result.claim_id,\n url: host + '/' + result.claim_id + '/' + name,\n lbryTx: result\n }\n });\n // record the publish end time and send to google analytics\n sendGATimingEvent('end-to-end', 'publish', fileType, gaStartTime, Date.now());\n }).catch(function (error) {\n handleErrorResponse(originalUrl, ip, error, res);\n });\n};\n\nmodule.exports = claimPublish;\n\n/***/ }),\n/* 73 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar db = __webpack_require__(2);\nvar logger = __webpack_require__(0);\n\nmodule.exports = {\n authenticateUser: function authenticateUser(channelName, channelId, channelPassword, user) {\n // case: no channelName or channel Id are provided (anonymous), regardless of whether user token is provided\n if (!channelName && !channelId) {\n return {\n channelName: null,\n channelClaimId: null\n };\n }\n // case: channelName or channel Id are provided with user token\n if (user) {\n if (channelName && channelName !== user.channelName) {\n throw new Error('the provided channel name does not match user credentials');\n }\n if (channelId && channelId !== user.channelClaimId) {\n throw new Error('the provided channel id does not match user credentials');\n }\n return {\n channelName: user.channelName,\n channelClaimId: user.channelClaimId\n };\n }\n // case: channelName or channel Id are provided with password instead of user token\n if (!channelPassword) throw new Error('no channel password provided');\n return module.exports.authenticateChannelCredentials(channelName, channelId, channelPassword);\n },\n authenticateChannelCredentials: function authenticateChannelCredentials(channelName, channelId, userPassword) {\n return new Promise(function (resolve, reject) {\n // hoisted variables\n var channelData = void 0;\n // build the params for finding the channel\n var channelFindParams = {};\n if (channelName) channelFindParams['channelName'] = channelName;\n if (channelId) channelFindParams['channelClaimId'] = channelId;\n // find the channel\n db.Channel.findOne({\n where: channelFindParams\n }).then(function (channel) {\n if (!channel) {\n logger.debug('no channel found');\n throw new Error('Authentication failed, you do not have access to that channel');\n }\n channelData = channel.get();\n logger.debug('channel data:', channelData);\n return db.User.findOne({\n where: { userName: channelData.channelName.substring(1) }\n });\n }).then(function (user) {\n if (!user) {\n logger.debug('no user found');\n throw new Error('Authentication failed, you do not have access to that channel');\n }\n return user.comparePassword(userPassword);\n }).then(function (isMatch) {\n if (!isMatch) {\n logger.debug('incorrect password');\n throw new Error('Authentication failed, you do not have access to that channel');\n }\n logger.debug('...password was a match...');\n resolve(channelData);\n }).catch(function (error) {\n reject(error);\n });\n });\n }\n};\n\n/***/ }),\n/* 74 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _require = __webpack_require__(5),\n resolveUri = _require.resolveUri;\n\nvar _require2 = __webpack_require__(1),\n handleErrorResponse = _require2.handleErrorResponse;\n\n/*\n\n route to run a resolve request on the daemon\n\n*/\n\nvar claimResolve = function claimResolve(_ref, res) {\n var headers = _ref.headers,\n ip = _ref.ip,\n originalUrl = _ref.originalUrl,\n params = _ref.params;\n\n resolveUri(params.name + '#' + params.claimId).then(function (resolvedUri) {\n res.status(200).json(resolvedUri);\n }).catch(function (error) {\n handleErrorResponse(originalUrl, ip, error, res);\n });\n};\n\nmodule.exports = claimResolve;\n\n/***/ }),\n/* 75 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _require = __webpack_require__(1),\n handleErrorResponse = _require.handleErrorResponse;\n\nvar db = __webpack_require__(2);\n\n/*\n\n route to get a short claim id from long claim Id\n\n*/\n\nvar claimShortId = function claimShortId(_ref, res) {\n var ip = _ref.ip,\n originalUrl = _ref.originalUrl,\n body = _ref.body,\n params = _ref.params;\n\n db.Claim.getShortClaimIdFromLongClaimId(params.longId, params.name).then(function (shortId) {\n res.status(200).json({ success: true, data: shortId });\n }).catch(function (error) {\n handleErrorResponse(originalUrl, ip, error, res);\n });\n};\n\nmodule.exports = claimShortId;\n\n/***/ }),\n/* 76 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _require = __webpack_require__(5),\n getClaimList = _require.getClaimList;\n\nvar _require2 = __webpack_require__(1),\n handleErrorResponse = _require2.handleErrorResponse;\n\n/*\n\n route to get list of claims\n\n*/\n\nvar claimList = function claimList(_ref, res) {\n var ip = _ref.ip,\n originalUrl = _ref.originalUrl,\n params = _ref.params;\n\n getClaimList(params.name).then(function (claimsList) {\n res.status(200).json(claimsList);\n }).catch(function (error) {\n handleErrorResponse(originalUrl, ip, error, res);\n });\n};\n\nmodule.exports = claimList;\n\n/***/ }),\n/* 77 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _require = __webpack_require__(1),\n handleErrorResponse = _require.handleErrorResponse;\n\nvar db = __webpack_require__(2);\n\n/*\n\n route to see if asset is available locally\n\n*/\n\nvar fileAvailability = function fileAvailability(_ref, res) {\n var ip = _ref.ip,\n originalUrl = _ref.originalUrl,\n params = _ref.params;\n\n var name = params.name;\n var claimId = params.claimId;\n db.File.findOne({\n where: {\n name: name,\n claimId: claimId\n }\n }).then(function (result) {\n if (result) {\n return res.status(200).json({ success: true, data: true });\n }\n res.status(200).json({ success: true, data: false });\n }).catch(function (error) {\n handleErrorResponse(originalUrl, ip, error, res);\n });\n};\n\nmodule.exports = fileAvailability;\n\n/***/ }),\n/* 78 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar multipart = __webpack_require__(79);\n\nvar _require = __webpack_require__(3),\n uploadDirectory = _require.publishing.uploadDirectory;\n\nvar multipartMiddleware = multipart({ uploadDir: uploadDirectory });\n\nmodule.exports = multipartMiddleware;\n\n/***/ }),\n/* 79 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"connect-multiparty\");\n\n/***/ }),\n/* 80 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar handlePageRequest = __webpack_require__(81);\nvar handleEmbedRequest = __webpack_require__(82);\nvar redirect = __webpack_require__(83);\n\nmodule.exports = function (app) {\n app.get('/', handlePageRequest);\n app.get('/login', handlePageRequest);\n app.get('/about', handlePageRequest);\n app.get('/trending', redirect('/popular'));\n app.get('/popular', handlePageRequest);\n app.get('/new', handlePageRequest);\n app.get('/embed/:claimId/:name', handleEmbedRequest); // route to send embedable video player (for twitter)\n};\n\n/***/ }),\n/* 81 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar handlePageRender = __webpack_require__(14);\n\nvar sendReactApp = function sendReactApp(req, res) {\n handlePageRender(req, res);\n};\n\nmodule.exports = sendReactApp;\n\n/***/ }),\n/* 82 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _require = __webpack_require__(3),\n host = _require.details.host;\n\nvar sendEmbedPage = function sendEmbedPage(_ref, res) {\n var params = _ref.params;\n\n var claimId = params.claimId;\n var name = params.name;\n // get and render the content\n res.status(200).render('embed', { layout: 'embed', host: host, claimId: claimId, name: name });\n};\n\nmodule.exports = sendEmbedPage;\n\n/***/ }),\n/* 83 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar redirect = function redirect(route) {\n return function (req, res) {\n res.status(301).redirect(route);\n };\n};\n\nmodule.exports = redirect;\n\n/***/ }),\n/* 84 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar serveAssetByClaim = __webpack_require__(85);\nvar serveAssetByIdentifierAndClaim = __webpack_require__(88);\n\nmodule.exports = function (app, db) {\n app.get('/:identifier/:claim', serveAssetByIdentifierAndClaim);\n app.get('/:claim', serveAssetByClaim);\n};\n\n/***/ }),\n/* 85 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _require = __webpack_require__(4),\n sendGAServeEvent = _require.sendGAServeEvent;\n\nvar _require2 = __webpack_require__(23),\n determineResponseType = _require2.determineResponseType,\n logRequestData = _require2.logRequestData,\n getClaimIdAndServeAsset = _require2.getClaimIdAndServeAsset;\n\nvar lbryUri = __webpack_require__(24);\nvar handleShowRender = __webpack_require__(25);\nvar SERVE = 'SERVE';\n\n/*\n\n route to serve an asset or the react app via the claim name only\n\n*/\n\nvar serverAssetByClaim = function serverAssetByClaim(req, res) {\n var headers = req.headers,\n ip = req.ip,\n originalUrl = req.originalUrl,\n params = req.params;\n // decide if this is a show request\n\n var hasFileExtension = void 0;\n try {\n var _lbryUri$parseModifie = lbryUri.parseModifier(params.claim);\n\n hasFileExtension = _lbryUri$parseModifie.hasFileExtension;\n } catch (error) {\n return res.status(400).json({ success: false, message: error.message });\n }\n var responseType = determineResponseType(hasFileExtension, headers);\n if (responseType !== SERVE) {\n return handleShowRender(req, res);\n }\n // handle serve request\n // send google analytics\n sendGAServeEvent(headers, ip, originalUrl);\n // parse the claim\n var claimName = void 0;\n try {\n var _lbryUri$parseClaim = lbryUri.parseClaim(params.claim);\n\n claimName = _lbryUri$parseClaim.claimName;\n } catch (error) {\n return res.status(400).json({ success: false, message: error.message });\n }\n // log the request data for debugging\n logRequestData(responseType, claimName, null, null);\n // get the claim Id and then serve the asset\n getClaimIdAndServeAsset(null, null, claimName, null, originalUrl, ip, res);\n};\n\nmodule.exports = serverAssetByClaim;\n\n/***/ }),\n/* 86 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"redux-saga\");\n\n/***/ }),\n/* 87 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"redux-saga/effects\");\n\n/***/ }),\n/* 88 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"]) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); } }; }();\n\nvar _require = __webpack_require__(4),\n sendGAServeEvent = _require.sendGAServeEvent;\n\nvar _require2 = __webpack_require__(23),\n determineResponseType = _require2.determineResponseType,\n flipClaimNameAndIdForBackwardsCompatibility = _require2.flipClaimNameAndIdForBackwardsCompatibility,\n logRequestData = _require2.logRequestData,\n getClaimIdAndServeAsset = _require2.getClaimIdAndServeAsset;\n\nvar lbryUri = __webpack_require__(24);\nvar handleShowRender = __webpack_require__(25);\n\nvar SERVE = 'SERVE';\n\n/*\n\n route to serve an asset or the react app via the claim name and an identifier\n\n*/\n\nvar serverAssetByIdentifierAndClaim = function serverAssetByIdentifierAndClaim(req, res) {\n var headers = req.headers,\n ip = req.ip,\n originalUrl = req.originalUrl,\n params = req.params;\n // decide if this is a show request\n\n var hasFileExtension = void 0;\n try {\n var _lbryUri$parseModifie = lbryUri.parseModifier(params.claim);\n\n hasFileExtension = _lbryUri$parseModifie.hasFileExtension;\n } catch (error) {\n return res.status(400).json({ success: false, message: error.message });\n }\n var responseType = determineResponseType(hasFileExtension, headers);\n if (responseType !== SERVE) {\n return handleShowRender(req, res);\n }\n // handle serve request\n // send google analytics\n sendGAServeEvent(headers, ip, originalUrl);\n // parse the claim\n var claimName = void 0;\n try {\n var _lbryUri$parseClaim = lbryUri.parseClaim(params.claim);\n\n claimName = _lbryUri$parseClaim.claimName;\n } catch (error) {\n return res.status(400).json({ success: false, message: error.message });\n }\n // parse the identifier\n var isChannel = void 0,\n channelName = void 0,\n channelClaimId = void 0,\n claimId = void 0;\n try {\n var _lbryUri$parseIdentif = lbryUri.parseIdentifier(params.identifier);\n\n isChannel = _lbryUri$parseIdentif.isChannel;\n channelName = _lbryUri$parseIdentif.channelName;\n channelClaimId = _lbryUri$parseIdentif.channelClaimId;\n claimId = _lbryUri$parseIdentif.claimId;\n } catch (error) {\n return res.status(400).json({ success: false, message: error.message });\n }\n if (!isChannel) {\n var _flipClaimNameAndIdFo = flipClaimNameAndIdForBackwardsCompatibility(claimId, claimName);\n\n var _flipClaimNameAndIdFo2 = _slicedToArray(_flipClaimNameAndIdFo, 2);\n\n claimId = _flipClaimNameAndIdFo2[0];\n claimName = _flipClaimNameAndIdFo2[1];\n }\n // log the request data for debugging\n logRequestData(responseType, claimName, channelName, claimId);\n // get the claim Id and then serve the asset\n getClaimIdAndServeAsset(channelName, channelClaimId, claimName, claimId, originalUrl, ip, res);\n};\n\nmodule.exports = serverAssetByIdentifierAndClaim;\n\n/***/ }),\n/* 89 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar handlePageRequest = __webpack_require__(90);\n\nmodule.exports = function (app) {\n app.get('*', handlePageRequest);\n};\n\n/***/ }),\n/* 90 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar handlePageRender = __webpack_require__(14);\n\nvar sendReactApp = function sendReactApp(req, res) {\n handlePageRender(req, res);\n};\n\nmodule.exports = sendReactApp;\n\n/***/ })\n/******/ ]);\n\n\n// WEBPACK FOOTER //\n// index.js"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 26);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 25216f7880c3d8ac65d6","module.exports = require(\"winston\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"winston\"\n// module id = 0\n// module chunks = 0","const logger = require('winston');\n\nmodule.exports = {\n handleErrorResponse: function (originalUrl, ip, error, res) {\n logger.error(`Error on ${originalUrl}`, module.exports.useObjectPropertiesIfNoKeys(error));\n const [status, message] = module.exports.returnErrorMessageAndStatus(error);\n res\n .status(status)\n .json(module.exports.createErrorResponsePayload(status, message));\n },\n returnErrorMessageAndStatus: function (error) {\n let status, message;\n // check for daemon being turned off\n if (error.code === 'ECONNREFUSED') {\n status = 503;\n message = 'Connection refused. The daemon may not be running.';\n // fallback for everything else\n } else {\n status = 400;\n if (error.message) {\n message = error.message;\n } else {\n message = error;\n };\n };\n return [status, message];\n },\n useObjectPropertiesIfNoKeys: function (err) {\n if (Object.keys(err).length === 0) {\n let newErrorObject = {};\n Object.getOwnPropertyNames(err).forEach((key) => {\n newErrorObject[key] = err[key];\n });\n return newErrorObject;\n }\n return err;\n },\n createErrorResponsePayload (status, message) {\n return {\n status,\n success: false,\n message,\n };\n },\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/helpers/errorHandlers.js","const Certificate = require('models/certificate.js');\nconst Channel = require('models/channel.js');\nconst Claim = require('models/claim.js');\nconst File = require('models/file.js');\nconst Request = require('models/request.js');\nconst User = require('models/user.js');\n\nconst Sequelize = require('sequelize');\nconst logger = require('winston');\n\nconst {database, username, password} = require('mysqlConfig.js');\n\n// set sequelize options\nconst sequelize = new Sequelize(database, username, password, {\n host : 'localhost',\n dialect : 'mysql',\n dialectOptions: {decimalNumbers: true},\n logging : false,\n pool : {\n max : 5,\n min : 0,\n idle : 10000,\n acquire: 10000,\n },\n});\n\n// establish mysql connection\nsequelize\n .authenticate()\n .then(() => {\n logger.info('Sequelize has established mysql connection successfully.');\n })\n .catch(err => {\n logger.error('Sequelize was unable to connect to the database:', err);\n });\n\n// manually add each model to the db object (note: make this dynamic)\nconst db = {};\ndb['Certificate'] = sequelize.import('Certificate', Certificate);\ndb['Channel'] = sequelize.import('Channel', Channel);\ndb['Claim'] = sequelize.import('Claim', Claim);\ndb['File'] = sequelize.import('File', File);\ndb['Request'] = sequelize.import('Request', Request);\ndb['User'] = sequelize.import('User', User);\n\n// run model.association for each model in the db object that has an association\nlogger.info('associating db models...');\nObject.keys(db).forEach(modelName => {\n if (db[modelName].associate) {\n logger.info('Associating model:', modelName);\n db[modelName].associate(db);\n }\n});\n\n// add sequelize/Sequelize to db\ndb.sequelize = sequelize;\ndb.Sequelize = Sequelize;\n// add an 'upsert' method to the db object\ndb.upsert = (Model, values, condition, tableName) => {\n return Model\n .findOne({\n where: condition,\n })\n .then(obj => {\n if (obj) { // update\n logger.debug(`updating record in db.${tableName}`);\n return obj.update(values);\n } else { // insert\n logger.debug(`creating record in db.${tableName}`);\n return Model.create(values);\n }\n })\n .catch(function (error) {\n logger.error(`${tableName}.upsert error`, error);\n throw error;\n });\n};\n\nmodule.exports = db;\n\n\n\n// WEBPACK FOOTER //\n// ./server/models/index.js","function SiteConfig () {\n this.analytics = {\n googleId: 'default',\n };\n this.assetDefaults = {\n description: 'An asset published on Spee.ch',\n thumbnail : 'https://spee.ch/assets/img/video_thumb_default.png',\n title : 'Spee.ch',\n };\n this.auth = {\n sessionKey: 'default',\n };\n this.customComponents = {};\n this.customContainers = {};\n this.customPages = {};\n this.details = {\n description: 'Open-source, decentralized image and video sharing.',\n host : 'default',\n port : 3000,\n title : 'Spee.ch',\n twitter : '@spee_ch',\n };\n this.publishing = {\n additionalClaimAddresses: [],\n disabled : false,\n disabledMessage : 'Please check back soon.',\n primaryClaimAddress : 'default',\n thumbnailChannel : 'default',\n thumbnailChannelId : 'default',\n uploadDirectory : '/home/lbry/Uploads',\n };\n this.routes = {};\n this.update = (config) => {\n if (!config) {\n return console.log('No site config received.');\n }\n const { analytics, assetDefaults, auth, customComponents, customContainers, customPages, details, publishing, routes } = config;\n console.log('Configuring site details...');\n this.analytics = analytics;\n this.assetDefaults = assetDefaults;\n this.auth = auth;\n this.details = details;\n this.publishing = publishing;\n this.customComponents = customComponents;\n this.customContainers = customContainers;\n this.customPages = customPages;\n this.routes = routes;\n };\n};\n\nmodule.exports = new SiteConfig();\n\n\n\n// WEBPACK FOOTER //\n// ./config/siteConfig.js","const logger = require('winston');\nconst ua = require('universal-analytics');\nconst { analytics : { googleId }, details: { title } } = require('../../config/siteConfig.js');\n\nfunction createServeEventParams (headers, ip, originalUrl) {\n return {\n eventCategory : 'client requests',\n eventAction : 'serve request',\n eventLabel : originalUrl,\n ipOverride : ip,\n userAgentOverride: headers['user-agent'],\n };\n};\n\nfunction createPublishTimingEventParams (category, variable, label, startTime, endTime) {\n const duration = endTime - startTime;\n return {\n userTimingCategory : category,\n userTimingVariableName: variable,\n userTimingTime : duration,\n userTimingLabel : label,\n };\n};\n\nfunction sendGoogleAnalyticsEvent (ip, params) {\n const visitorId = ip.replace(/\\./g, '-');\n const visitor = ua(googleId, visitorId, { strictCidFormat: false, https: true });\n visitor.event(params, (err) => {\n if (err) {\n logger.error('Google Analytics Event Error >>', err);\n }\n });\n};\n\nfunction sendGoogleAnalyticsTiming (visitorId, params) {\n const visitor = ua(googleId, visitorId, { strictCidFormat: false, https: true });\n visitor.timing(params, (err) => {\n if (err) {\n logger.error('Google Analytics Event Error >>', err);\n }\n logger.debug(`Timing event successfully sent to google analytics`);\n });\n};\n\nmodule.exports = {\n sendGAServeEvent (headers, ip, originalUrl) {\n const params = createServeEventParams(headers, ip, originalUrl);\n sendGoogleAnalyticsEvent(ip, params);\n },\n sendGATimingEvent (category, variable, label, startTime, endTime) {\n const params = createPublishTimingEventParams(category, variable, label, startTime, endTime);\n sendGoogleAnalyticsTiming(title, params);\n },\n chooseGaLbrynetPublishLabel ({ channel_name: channelName, channel_id: channelId }) {\n return (channelName || channelId ? 'PUBLISH_IN_CHANNEL_CLAIM' : 'PUBLISH_ANONYMOUS_CLAIM');\n },\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/helpers/googleAnalytics.js","const axios = require('axios');\nconst logger = require('winston');\nconst { api: { apiHost, apiPort } } = require('../../config/lbryConfig.js');\nconst lbryApiUri = 'http://' + apiHost + ':' + apiPort;\nconst { chooseGaLbrynetPublishLabel, sendGATimingEvent } = require('./googleAnalytics.js');\n\nconst handleLbrynetResponse = ({ data }, resolve, reject) => {\n logger.debug('lbry api data:', data);\n if (data.result) {\n // check for an error\n if (data.result.error) {\n logger.debug('Lbrynet api error:', data.result.error);\n reject(new Error(data.result.error));\n return;\n };\n resolve(data.result);\n return;\n }\n // fallback in case it just timed out\n reject(JSON.stringify(data));\n};\n\nmodule.exports = {\n publishClaim (publishParams) {\n logger.debug(`lbryApi >> Publishing claim to \"${publishParams.name}\"`);\n const gaStartTime = Date.now();\n return new Promise((resolve, reject) => {\n axios\n .post(lbryApiUri, {\n method: 'publish',\n params: publishParams,\n })\n .then(response => {\n sendGATimingEvent('lbrynet', 'publish', chooseGaLbrynetPublishLabel(publishParams), gaStartTime, Date.now());\n handleLbrynetResponse(response, resolve, reject);\n })\n .catch(error => {\n reject(error);\n });\n });\n },\n getClaim (uri) {\n logger.debug(`lbryApi >> Getting Claim for \"${uri}\"`);\n const gaStartTime = Date.now();\n return new Promise((resolve, reject) => {\n axios\n .post(lbryApiUri, {\n method: 'get',\n params: { uri, timeout: 20 },\n })\n .then(response => {\n sendGATimingEvent('lbrynet', 'getClaim', 'GET', gaStartTime, Date.now());\n handleLbrynetResponse(response, resolve, reject);\n })\n .catch(error => {\n reject(error);\n });\n });\n },\n getClaimList (claimName) {\n logger.debug(`lbryApi >> Getting claim_list for \"${claimName}\"`);\n const gaStartTime = Date.now();\n return new Promise((resolve, reject) => {\n axios\n .post(lbryApiUri, {\n method: 'claim_list',\n params: { name: claimName },\n })\n .then(response => {\n sendGATimingEvent('lbrynet', 'getClaimList', 'CLAIM_LIST', gaStartTime, Date.now());\n handleLbrynetResponse(response, resolve, reject);\n })\n .catch(error => {\n reject(error);\n });\n });\n },\n resolveUri (uri) {\n logger.debug(`lbryApi >> Resolving URI for \"${uri}\"`);\n const gaStartTime = Date.now();\n return new Promise((resolve, reject) => {\n axios\n .post(lbryApiUri, {\n method: 'resolve',\n params: { uri },\n })\n .then(({ data }) => {\n sendGATimingEvent('lbrynet', 'resolveUri', 'RESOLVE', gaStartTime, Date.now());\n if (data.result[uri].error) { // check for errors\n reject(data.result[uri].error);\n } else { // if no errors, resolve\n resolve(data.result[uri]);\n }\n })\n .catch(error => {\n reject(error);\n });\n });\n },\n getDownloadDirectory () {\n logger.debug('lbryApi >> Retrieving the download directory path from lbry daemon...');\n const gaStartTime = Date.now();\n return new Promise((resolve, reject) => {\n axios\n .post(lbryApiUri, {\n method: 'settings_get',\n })\n .then(({ data }) => {\n sendGATimingEvent('lbrynet', 'getDownloadDirectory', 'SETTINGS_GET', gaStartTime, Date.now());\n if (data.result) {\n resolve(data.result.download_directory);\n } else {\n return new Error('Successfully connected to lbry daemon, but unable to retrieve the download directory.');\n }\n })\n .catch(error => {\n logger.error('Lbrynet Error:', error);\n resolve('/home/lbry/Downloads/');\n });\n });\n },\n createChannel (name) {\n logger.debug(`lbryApi >> Creating channel for ${name}...`);\n const gaStartTime = Date.now();\n return new Promise((resolve, reject) => {\n axios\n .post(lbryApiUri, {\n method: 'channel_new',\n params: {\n channel_name: name,\n amount : 0.1,\n },\n })\n .then(response => {\n sendGATimingEvent('lbrynet', 'createChannel', 'CHANNEL_NEW', gaStartTime, Date.now());\n handleLbrynetResponse(response, resolve, reject);\n })\n .catch(error => {\n reject(error);\n });\n });\n },\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/helpers/lbryApi.js","const db = require('models');\nconst logger = require('winston');\nconst { returnPaginatedChannelClaims } = require('helpers/channelPagination.js');\n\nconst NO_CHANNEL = 'NO_CHANNEL';\nconst NO_CLAIM = 'NO_CLAIM';\nconst NO_FILE = 'NO_FILE';\n\nmodule.exports = {\n getClaimId (channelName, channelClaimId, name, claimId) {\n if (channelName) {\n return module.exports.getClaimIdByChannel(channelName, channelClaimId, name);\n } else {\n return module.exports.getClaimIdByClaim(name, claimId);\n }\n },\n getClaimIdByClaim (claimName, claimId) {\n logger.debug(`getClaimIdByClaim(${claimName}, ${claimId})`);\n return new Promise((resolve, reject) => {\n db.Claim.getLongClaimId(claimName, claimId)\n .then(longClaimId => {\n if (!longClaimId) {\n resolve(NO_CLAIM);\n }\n resolve(longClaimId);\n })\n .catch(error => {\n reject(error);\n });\n });\n },\n getClaimIdByChannel (channelName, channelClaimId, claimName) {\n logger.debug(`getClaimIdByChannel(${channelName}, ${channelClaimId}, ${claimName})`);\n return new Promise((resolve, reject) => {\n db.Certificate.getLongChannelId(channelName, channelClaimId) // 1. get the long channel id\n .then(longChannelId => {\n if (!longChannelId) {\n return [null, null];\n }\n return Promise.all([longChannelId, db.Claim.getClaimIdByLongChannelId(longChannelId, claimName)]); // 2. get the long claim id\n })\n .then(([longChannelId, longClaimId]) => {\n if (!longChannelId) {\n return resolve(NO_CHANNEL);\n }\n if (!longClaimId) {\n return resolve(NO_CLAIM);\n }\n resolve(longClaimId);\n })\n .catch(error => {\n reject(error);\n });\n });\n },\n getChannelData (channelName, channelClaimId, page) {\n return new Promise((resolve, reject) => {\n // 1. get the long channel Id (make sure channel exists)\n db.Certificate.getLongChannelId(channelName, channelClaimId)\n .then(longChannelClaimId => {\n if (!longChannelClaimId) {\n return [null, null, null];\n }\n // 2. get the short ID and all claims for that channel\n return Promise.all([longChannelClaimId, db.Certificate.getShortChannelIdFromLongChannelId(longChannelClaimId, channelName)]);\n })\n .then(([longChannelClaimId, shortChannelClaimId]) => {\n if (!longChannelClaimId) {\n return resolve(NO_CHANNEL);\n }\n // 3. return all the channel information\n resolve({\n channelName,\n longChannelClaimId,\n shortChannelClaimId,\n });\n })\n .catch(error => {\n reject(error);\n });\n });\n },\n getChannelClaims (channelName, channelClaimId, page) {\n return new Promise((resolve, reject) => {\n // 1. get the long channel Id (make sure channel exists)\n db.Certificate.getLongChannelId(channelName, channelClaimId)\n .then(longChannelClaimId => {\n if (!longChannelClaimId) {\n return [null, null, null];\n }\n // 2. get the short ID and all claims for that channel\n return Promise.all([longChannelClaimId, db.Claim.getAllChannelClaims(longChannelClaimId)]);\n })\n .then(([longChannelClaimId, channelClaimsArray]) => {\n if (!longChannelClaimId) {\n return resolve(NO_CHANNEL);\n }\n // 3. format the data for the view, including pagination\n let paginatedChannelViewData = returnPaginatedChannelClaims(channelName, longChannelClaimId, channelClaimsArray, page);\n // 4. return all the channel information and contents\n resolve(paginatedChannelViewData);\n })\n .catch(error => {\n reject(error);\n });\n });\n },\n getLocalFileRecord (claimId, name) {\n return db.File.findOne({where: {claimId, name}})\n .then(file => {\n if (!file) {\n return NO_FILE;\n }\n return file.dataValues;\n });\n },\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/controllers/serveController.js","const passport = require('passport');\nconst localLoginStrategy = require('./local-login.js');\nconst localSignupStrategy = require('./local-signup.js');\nconst { serializeSpeechUser, deserializeSpeechUser } = require('helpers/authHelpers.js');\n\npassport.deserializeUser(deserializeSpeechUser);\npassport.serializeUser(serializeSpeechUser);\npassport.use('local-login', localLoginStrategy);\npassport.use('local-signup', localSignupStrategy);\n\nmodule.exports = passport;\n\n\n\n// WEBPACK FOOTER //\n// ./server/speechPassport/index.js","const logger = require('winston');\nconst db = require('models');\nconst lbryApi = require('helpers/lbryApi.js');\nconst publishHelpers = require('helpers/publishHelpers.js');\nconst { publishing: { primaryClaimAddress, additionalClaimAddresses } } = require('siteConfig.js');\nconst Sequelize = require('sequelize');\nconst Op = Sequelize.Op;\n\nmodule.exports = {\n publish (publishParams, fileName, fileType) {\n return new Promise((resolve, reject) => {\n let publishResults, certificateId, channelName;\n // publish the file\n return lbryApi.publishClaim(publishParams)\n .then(tx => {\n logger.info(`Successfully published ${publishParams.name} ${fileName}`, tx);\n publishResults = tx;\n // get the channel information\n if (publishParams.channel_name) {\n logger.debug(`this claim was published in channel: ${publishParams.channel_name}`);\n return db.Channel.findOne({\n where: {\n channelName: publishParams.channel_name,\n },\n });\n } else {\n logger.debug('this claim was not published in a channel');\n return null;\n }\n })\n .then(channel => {\n // set channel information\n certificateId = null;\n channelName = null;\n if (channel) {\n certificateId = channel.channelClaimId;\n channelName = channel.channelName;\n }\n logger.debug(`certificateId: ${certificateId}`);\n })\n .then(() => {\n // create the File record\n const fileRecord = {\n name : publishParams.name,\n claimId : publishResults.claim_id,\n title : publishParams.metadata.title,\n description: publishParams.metadata.description,\n address : publishParams.claim_address,\n outpoint : `${publishResults.txid}:${publishResults.nout}`,\n height : 0,\n fileName,\n filePath : publishParams.file_path,\n fileType,\n nsfw : publishParams.metadata.nsfw,\n };\n // create the Claim record\n const claimRecord = {\n name : publishParams.name,\n claimId : publishResults.claim_id,\n title : publishParams.metadata.title,\n description: publishParams.metadata.description,\n address : publishParams.claim_address,\n thumbnail : publishParams.metadata.thumbnail,\n outpoint : `${publishResults.txid}:${publishResults.nout}`,\n height : 0,\n contentType: fileType,\n nsfw : publishParams.metadata.nsfw,\n amount : publishParams.bid,\n certificateId,\n channelName,\n };\n // upsert criteria\n const upsertCriteria = {\n name : publishParams.name,\n claimId: publishResults.claim_id,\n };\n // upsert the records\n return Promise.all([db.upsert(db.File, fileRecord, upsertCriteria, 'File'), db.upsert(db.Claim, claimRecord, upsertCriteria, 'Claim')]);\n })\n .then(([file, claim]) => {\n logger.debug('File and Claim records successfully created');\n return Promise.all([file.setClaim(claim), claim.setFile(file)]);\n })\n .then(() => {\n logger.debug('File and Claim records successfully associated');\n resolve(publishResults); // resolve the promise with the result from lbryApi.publishClaim;\n })\n .catch(error => {\n logger.error('PUBLISH ERROR', error);\n publishHelpers.deleteTemporaryFile(publishParams.file_path); // delete the local file\n reject(error);\n });\n });\n },\n claimNameIsAvailable (name) {\n const claimAddresses = additionalClaimAddresses || [];\n claimAddresses.push(primaryClaimAddress);\n // find any records where the name is used\n return db.Claim\n .findAll({\n attributes: ['address'],\n where : {\n name,\n address: {\n [Op.or]: claimAddresses,\n },\n },\n })\n .then(result => {\n if (result.length >= 1) {\n throw new Error('That claim is already in use');\n };\n return name;\n })\n .catch(error => {\n throw error;\n });\n },\n checkChannelAvailability (name) {\n return db.Channel\n .findAll({\n where: { channelName: name },\n })\n .then(result => {\n if (result.length >= 1) {\n throw new Error('That channel has already been claimed');\n }\n return name;\n })\n .catch(error => {\n throw error;\n });\n },\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/controllers/publishController.js","const logger = require('winston');\nconst fs = require('fs');\n\nconst { details, publishing } = require('../../config/siteConfig.js');\n\nmodule.exports = {\n parsePublishApiRequestBody ({name, nsfw, license, title, description, thumbnail}) {\n // validate name\n if (!name) {\n throw new Error('no name field found in request');\n }\n const invalidNameCharacters = /[^A-Za-z0-9,-]/.exec(name);\n if (invalidNameCharacters) {\n throw new Error('The claim name you provided is not allowed. Only the following characters are allowed: A-Z, a-z, 0-9, and \"-\"');\n }\n // optional parameters\n nsfw = (nsfw === 'true');\n license = license || null;\n title = title || null;\n description = description || null;\n thumbnail = thumbnail || null;\n // return results\n return {\n name,\n nsfw,\n license,\n title,\n description,\n thumbnail,\n };\n },\n parsePublishApiRequestFiles ({file, thumbnail}) {\n // make sure a file was provided\n if (!file) {\n throw new Error('no file with key of [file] found in request');\n }\n if (!file.path) {\n throw new Error('no file path found');\n }\n if (!file.type) {\n throw new Error('no file type found');\n }\n if (!file.size) {\n throw new Error('no file type found');\n }\n // validate the file name\n if (/'/.test(file.name)) {\n throw new Error('apostrophes are not allowed in the file name');\n }\n // validate the file\n module.exports.validateFileTypeAndSize(file);\n // return results\n return {\n fileName : file.name,\n filePath : file.path,\n fileType : file.type,\n thumbnailFileName: (thumbnail ? thumbnail.name : null),\n thumbnailFilePath: (thumbnail ? thumbnail.path : null),\n thumbnailFileType: (thumbnail ? thumbnail.type : null),\n };\n },\n validateFileTypeAndSize (file) {\n // check file type and size\n switch (file.type) {\n case 'image/jpeg':\n case 'image/jpg':\n case 'image/png':\n if (file.size > 10000000) {\n logger.debug('publish > file validation > .jpeg/.jpg/.png was too big');\n throw new Error('Sorry, images are limited to 10 megabytes.');\n }\n break;\n case 'image/gif':\n if (file.size > 50000000) {\n logger.debug('publish > file validation > .gif was too big');\n throw new Error('Sorry, .gifs are limited to 50 megabytes.');\n }\n break;\n case 'video/mp4':\n if (file.size > 50000000) {\n logger.debug('publish > file validation > .mp4 was too big');\n throw new Error('Sorry, videos are limited to 50 megabytes.');\n }\n break;\n default:\n logger.debug('publish > file validation > unrecognized file type');\n throw new Error('The ' + file.type + ' content type is not supported. Only, .jpeg, .png, .gif, and .mp4 files are currently supported.');\n }\n return file;\n },\n createBasicPublishParams (filePath, name, title, description, license, nsfw, thumbnail) {\n logger.debug(`Creating Publish Parameters`);\n // provide defaults for title\n if (title === null || title.trim() === '') {\n title = name;\n }\n // provide default for description\n if (description === null || description.trim() === '') {\n description = '';\n }\n // provide default for license\n if (license === null || license.trim() === '') {\n license = ' '; // default to empty string\n }\n // create the publish params\n const publishParams = {\n name,\n file_path: filePath,\n bid : 0.01,\n metadata : {\n description,\n title,\n author : details.title,\n language: 'en',\n license,\n nsfw,\n },\n claim_address: publishing.primaryClaimAddress,\n };\n // add thumbnail to channel if video\n if (thumbnail) {\n publishParams['metadata']['thumbnail'] = thumbnail;\n }\n return publishParams;\n },\n createThumbnailPublishParams (thumbnailFilePath, claimName, license, nsfw) {\n if (!thumbnailFilePath) {\n return;\n }\n logger.debug(`Creating Thumbnail Publish Parameters`);\n // create the publish params\n return {\n name : `${claimName}-thumb`,\n file_path: thumbnailFilePath,\n bid : 0.01,\n metadata : {\n title : `${claimName} thumbnail`,\n description: `a thumbnail for ${claimName}`,\n author : details.title,\n language : 'en',\n license,\n nsfw,\n },\n claim_address: publishing.primaryClaimAddress,\n channel_name : publishing.thumbnailChannel,\n channel_id : publishing.thumbnailChannelId,\n };\n },\n deleteTemporaryFile (filePath) {\n fs.unlink(filePath, err => {\n if (err) {\n logger.error(`error deleting temporary file ${filePath}`);\n throw err;\n }\n logger.debug(`successfully deleted ${filePath}`);\n });\n },\n addGetResultsToFileData (fileInfo, getResult) {\n fileInfo.fileName = getResult.file_name;\n fileInfo.filePath = getResult.download_path;\n return fileInfo;\n },\n createFileData ({ name, claimId, outpoint, height, address, nsfw, contentType }) {\n return {\n name,\n claimId,\n outpoint,\n height,\n address,\n fileName: '',\n filePath: '',\n fileType: contentType,\n nsfw,\n };\n },\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/helpers/publishHelpers.js","const logger = require('winston');\n\nfunction mysql () {\n this.database = 'default';\n this.username = 'default';\n this.password = 'default';\n this.update = (config) => {\n if (!config) {\n return logger.warn('No MySQL config received.');\n }\n // configure credentials\n logger.info('configuring mysql...');\n const { database, username, password } = config;\n this.database = database;\n this.username = username;\n this.password = password;\n };\n};\n\nmodule.exports = new mysql();\n\n\n\n// WEBPACK FOOTER //\n// ./config/mysqlConfig.js","module.exports = require(\"passport-local\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"passport-local\"\n// module id = 11\n// module chunks = 0","module.exports = {\n returnShortId: function (claimsArray, longId) {\n let claimIndex;\n let shortId = longId.substring(0, 1); // default short id is the first letter\n let shortIdLength = 0;\n // find the index of this claim id\n claimIndex = claimsArray.findIndex(element => {\n return element.claimId === longId;\n });\n if (claimIndex < 0) {\n throw new Error('claim id not found in claims list');\n }\n // get an array of all claims with lower height\n let possibleMatches = claimsArray.slice(0, claimIndex);\n // remove certificates with the same prefixes until none are left.\n while (possibleMatches.length > 0) {\n shortIdLength += 1;\n shortId = longId.substring(0, shortIdLength);\n possibleMatches = possibleMatches.filter(element => {\n return (element.claimId && (element.claimId.substring(0, shortIdLength) === shortId));\n });\n }\n return shortId;\n },\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/helpers/sequelizeHelpers.js","module.exports = require(\"sequelize\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"sequelize\"\n// module id = 13\n// module chunks = 0","import React from 'react';\nimport { renderToString } from 'react-dom/server';\nimport { createStore } from 'redux';\nimport { Provider } from 'react-redux';\nimport { StaticRouter } from 'react-router-dom';\nimport { Reducers, GAListener, App } from 'spee.ch-components';\n/*\n ^ note: to do this right, maybe\n these should be passed in from the implementation (www.spee.ch) itself,\n so that there are no conflicts between the SSR here and\n the bundle sent to the server?\n there might also be issues if this package uses a different version of spee.ch-components than www.spee.ch does?\n*/\nimport renderFullPage from './renderFullPage.js';\nimport Helmet from 'react-helmet';\n\nconst siteConfig = require('siteConfig.js');\n\nmodule.exports = (req, res) => {\n let context = {};\n\n // customize the reducer by passing in intial state configs\n const MyReducers = Reducers(siteConfig);\n const MyApp = App(siteConfig);\n const MyGAListener = GAListener(siteConfig);\n\n // create a new Redux store instance\n const store = createStore(MyReducers);\n\n // render component to a string\n const html = renderToString(\n <Provider store={store}>\n <StaticRouter location={req.url} context={context}>\n <MyGAListener>\n <MyApp />\n </MyGAListener>\n </StaticRouter>\n </Provider>\n );\n\n // get head tags from helmet\n const helmet = Helmet.renderStatic();\n\n // check for a redirect\n if (context.url) {\n // Somewhere a `<Redirect>` was rendered\n return res.redirect(301, context.url);\n } else {\n // we're good, send the response\n }\n\n // get the initial state from our Redux store\n const preloadedState = store.getState();\n\n // send the rendered page back to the client\n res.send(renderFullPage(helmet, html, preloadedState));\n\n console.log('hello from spee.ch handlePageRender.jsx');\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/helpers/handlePageRender.jsx","module.exports = require(\"react\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"react\"\n// module id = 15\n// module chunks = 0","module.exports = require(\"react-dom/server\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"react-dom/server\"\n// module id = 16\n// module chunks = 0","module.exports = require(\"redux\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"redux\"\n// module id = 17\n// module chunks = 0","module.exports = require(\"react-redux\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"react-redux\"\n// module id = 18\n// module chunks = 0","module.exports = require(\"react-router-dom\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"react-router-dom\"\n// module id = 19\n// module chunks = 0","module.exports = require(\"spee.ch-components\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"spee.ch-components\"\n// module id = 20\n// module chunks = 0","module.exports = (helmet, html, preloadedState) => {\n // take the html and preloadedState and return the full page\n return `\n <!DOCTYPE html>\n <html lang=\"en\" prefix=\"og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#\">\n <head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1, user-scalable=no\">\n <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">\n <!--helmet-->\n ${helmet.title.toString()}\n ${helmet.meta.toString()}\n ${helmet.link.toString()}\n <!--style sheets-->\n <link rel=\"stylesheet\" href=\"/assets/css/reset.css\" type=\"text/css\">\n <link rel=\"stylesheet\" href=\"/assets/css/general.css\" type=\"text/css\">\n <link rel=\"stylesheet\" href=\"/assets/css/mediaQueries.css\" type=\"text/css\">\n <!--google font-->\n <link href=\"https://fonts.googleapis.com/css?family=Roboto:300\" rel=\"stylesheet\">\n </head>\n <body id=\"main-body\">\n <div class=\"row row--tall flex-container--column\">\n <div id=\"react-app\" class=\"row row--tall flex-container--column\">${html}</div>\n </div>\n <script>\n window.__PRELOADED_STATE__ = ${JSON.stringify(preloadedState).replace(/</g, '\\\\\\u003c')}\n </script>\n <script src=\"/bundle/bundle.js\"></script>\n </body>\n </html>\n `;\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/helpers/renderFullPage.js","module.exports = require(\"react-helmet\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"react-helmet\"\n// module id = 22\n// module chunks = 0","const logger = require('winston');\nconst { getClaimId, getLocalFileRecord } = require('../controllers/serveController.js');\nconst { handleErrorResponse } = require('./errorHandlers.js');\n\nconst SERVE = 'SERVE';\nconst SHOW = 'SHOW';\nconst NO_FILE = 'NO_FILE';\nconst NO_CHANNEL = 'NO_CHANNEL';\nconst NO_CLAIM = 'NO_CLAIM';\n\nfunction clientAcceptsHtml ({accept}) {\n return accept && accept.match(/text\\/html/);\n};\n\nfunction requestIsFromBrowser (headers) {\n return headers['user-agent'] && headers['user-agent'].match(/Mozilla/);\n};\n\nfunction clientWantsAsset ({accept, range}) {\n const imageIsWanted = accept && accept.match(/image\\/.*/) && !accept.match(/text\\/html/) && !accept.match(/text\\/\\*/);\n const videoIsWanted = accept && range;\n return imageIsWanted || videoIsWanted;\n};\n\nfunction isValidClaimId (claimId) {\n return ((claimId.length === 40) && !/[^A-Za-z0-9]/g.test(claimId));\n};\n\nfunction isValidShortId (claimId) {\n return claimId.length === 1; // it should really evaluate the short url itself\n};\n\nfunction isValidShortIdOrClaimId (input) {\n return (isValidClaimId(input) || isValidShortId(input));\n};\n\nfunction serveAssetToClient (claimId, name, res) {\n return getLocalFileRecord(claimId, name)\n .then(fileRecord => {\n // check that a local record was found\n if (fileRecord === NO_FILE) {\n return res.status(307).redirect(`/api/claim/get/${name}/${claimId}`);\n }\n // serve the file\n const {filePath, fileType} = fileRecord;\n logger.verbose(`serving file: ${filePath}`);\n const sendFileOptions = {\n headers: {\n 'X-Content-Type-Options': 'nosniff',\n 'Content-Type' : fileType || 'image/jpeg',\n },\n };\n res.status(200).sendFile(filePath, sendFileOptions);\n })\n .catch(error => {\n throw error;\n });\n};\n\nmodule.exports = {\n getClaimIdAndServeAsset (channelName, channelClaimId, claimName, claimId, originalUrl, ip, res) {\n // get the claim Id and then serve the asset\n getClaimId(channelName, channelClaimId, claimName, claimId)\n .then(fullClaimId => {\n if (fullClaimId === NO_CLAIM) {\n return res.status(404).json({success: false, message: 'no claim id could be found'});\n } else if (fullClaimId === NO_CHANNEL) {\n return res.status(404).json({success: false, message: 'no channel id could be found'});\n }\n serveAssetToClient(fullClaimId, claimName, res);\n // postToStats(responseType, originalUrl, ip, claimName, fullClaimId, 'success');\n })\n .catch(error => {\n handleErrorResponse(originalUrl, ip, error, res);\n // postToStats(responseType, originalUrl, ip, claimName, fullClaimId, 'fail');\n });\n },\n determineResponseType (hasFileExtension, headers) {\n let responseType;\n if (hasFileExtension) {\n responseType = SERVE; // assume a serve request if file extension is present\n if (clientAcceptsHtml(headers)) { // if the request comes from a browser, change it to a show request\n responseType = SHOW;\n }\n } else {\n responseType = SHOW;\n if (clientWantsAsset(headers) && requestIsFromBrowser(headers)) { // this is in case someone embeds a show url\n logger.debug('Show request came from browser but wants an image/video. Changing response to serve...');\n responseType = SERVE;\n }\n }\n return responseType;\n },\n flipClaimNameAndIdForBackwardsCompatibility (identifier, name) {\n // this is a patch for backwards compatability with '/name/claim_id' url format\n if (isValidShortIdOrClaimId(name) && !isValidShortIdOrClaimId(identifier)) {\n const tempName = name;\n name = identifier;\n identifier = tempName;\n }\n return [identifier, name];\n },\n logRequestData (responseType, claimName, channelName, claimId) {\n logger.debug('responseType ===', responseType);\n logger.debug('claim name === ', claimName);\n logger.debug('channel name ===', channelName);\n logger.debug('claim id ===', claimId);\n },\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/helpers/serveHelpers.js","const logger = require('winston');\n\nmodule.exports = {\n REGEXP_INVALID_CLAIM : /[^A-Za-z0-9-]/g,\n REGEXP_INVALID_CHANNEL: /[^A-Za-z0-9-@]/g,\n REGEXP_ADDRESS : /^b(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/,\n CHANNEL_CHAR : '@',\n parseIdentifier : function (identifier) {\n logger.debug('parsing identifier:', identifier);\n const componentsRegex = new RegExp(\n '([^:$#/]*)' + // value (stops at the first separator or end)\n '([:$#]?)([^/]*)' // modifier separator, modifier (stops at the first path separator or end)\n );\n const [proto, value, modifierSeperator, modifier] = componentsRegex\n .exec(identifier)\n .map(match => match || null);\n logger.debug(`${proto}, ${value}, ${modifierSeperator}, ${modifier}`);\n\n // Validate and process name\n if (!value) {\n throw new Error(`Check your url. No channel name provided before \"${modifierSeperator}\"`);\n }\n const isChannel = value.startsWith(module.exports.CHANNEL_CHAR);\n const channelName = isChannel ? value : null;\n let claimId;\n if (isChannel) {\n if (!channelName) {\n throw new Error('No channel name after @.');\n }\n const nameBadChars = (channelName).match(module.exports.REGEXP_INVALID_CHANNEL);\n if (nameBadChars) {\n throw new Error(`Invalid characters in channel name: ${nameBadChars.join(', ')}.`);\n }\n } else {\n claimId = value;\n }\n\n // Validate and process modifier\n let channelClaimId;\n if (modifierSeperator) {\n if (!modifier) {\n throw new Error(`No modifier provided after separator \"${modifierSeperator}\"`);\n }\n\n if (modifierSeperator === ':') {\n channelClaimId = modifier;\n } else {\n throw new Error(`The \"${modifierSeperator}\" modifier is not currently supported`);\n }\n }\n return {\n isChannel,\n channelName,\n channelClaimId,\n claimId,\n };\n },\n parseClaim: function (claim) {\n logger.debug('parsing name:', claim);\n const componentsRegex = new RegExp(\n '([^:$#/.]*)' + // name (stops at the first modifier)\n '([:$#.]?)([^/]*)' // modifier separator, modifier (stops at the first path separator or end)\n );\n const [proto, claimName, modifierSeperator, modifier] = componentsRegex\n .exec(claim)\n .map(match => match || null);\n logger.debug(`${proto}, ${claimName}, ${modifierSeperator}, ${modifier}`);\n\n // Validate and process name\n if (!claimName) {\n throw new Error('No claim name provided before .');\n }\n const nameBadChars = (claimName).match(module.exports.REGEXP_INVALID_CLAIM);\n if (nameBadChars) {\n throw new Error(`Invalid characters in claim name: ${nameBadChars.join(', ')}.`);\n }\n // Validate and process modifier\n if (modifierSeperator) {\n if (!modifier) {\n throw new Error(`No file extension provided after separator ${modifierSeperator}.`);\n }\n if (modifierSeperator !== '.') {\n throw new Error(`The ${modifierSeperator} modifier is not supported in the claim name`);\n }\n }\n // return results\n return {\n claimName,\n };\n },\n parseModifier: function (claim) {\n logger.debug('parsing modifier:', claim);\n const componentsRegex = new RegExp(\n '([^:$#/.]*)' + // name (stops at the first modifier)\n '([:$#.]?)([^/]*)' // modifier separator, modifier (stops at the first path separator or end)\n );\n const [proto, claimName, modifierSeperator, modifier] = componentsRegex\n .exec(claim)\n .map(match => match || null);\n logger.debug(`${proto}, ${claimName}, ${modifierSeperator}, ${modifier}`);\n // Validate and process modifier\n let hasFileExtension = false;\n if (modifierSeperator) {\n hasFileExtension = true;\n }\n return {\n hasFileExtension,\n };\n },\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/helpers/lbryUri.js","import React from 'react';\nimport { renderToString } from 'react-dom/server';\nimport { createStore, applyMiddleware } from 'redux';\nimport { Provider } from 'react-redux';\nimport { StaticRouter } from 'react-router-dom';\nimport renderFullPage from './renderFullPage';\nimport createSagaMiddleware from 'redux-saga';\nimport { call } from 'redux-saga/effects';\nimport { Reducers, GAListener, App, Sagas, Actions } from 'spee.ch-components';\n/*\n ^ note: to do this right, maybe\n these should be passed in from the implementation (www.spee.ch) itself,\n so that there are no conflicts between the SSR here and\n the bundle sent to the server?\n there might also be issues if this package uses a different version of spee.ch-components than www.spee.ch does?\n*/\nimport Helmet from 'react-helmet';\n\n// configure the reducers by passing initial state configs\nconst siteConfig = require('siteConfig.js');\nconst MyReducers = Reducers(siteConfig);\nconst MyApp = App(siteConfig);\nconst MyGAListener = GAListener(siteConfig);\n\nconst returnSagaWithParams = (saga, params) => {\n return function * () {\n yield call(saga, params);\n };\n};\n\nmodule.exports = (req, res) => {\n let context = {};\n\n // create and apply middleware\n const sagaMiddleware = createSagaMiddleware();\n const middleware = applyMiddleware(sagaMiddleware);\n\n // create a new Redux store instance\n const store = createStore(MyReducers, middleware);\n\n // create saga\n const action = Actions.onHandleShowPageUri(req.params);\n const saga = returnSagaWithParams(Sagas.handleShowPageUri, action);\n\n // run the saga middleware\n sagaMiddleware\n .run(saga)\n .done\n .then(() => {\n // render component to a string\n const html = renderToString(\n <Provider store={store}>\n <StaticRouter location={req.url} context={context}>\n <MyGAListener>\n <MyApp />\n </MyGAListener>\n </StaticRouter>\n </Provider>\n );\n\n // get head tags from helmet\n const helmet = Helmet.renderStatic();\n\n // check for a redirect\n if (context.url) {\n return res.redirect(301, context.url);\n }\n\n // get the initial state from our Redux store\n const preloadedState = store.getState();\n\n // send the rendered page back to the client\n res.send(renderFullPage(helmet, html, preloadedState));\n });\n\n console.log('hello from spee.ch handleShowRender.jsx');\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/helpers/handleShowRender.jsx","module.exports = require(\"babel-polyfill\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"babel-polyfill\"\n// module id = 27\n// module chunks = 0","module.exports = require(\"whatwg-fetch\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"whatwg-fetch\"\n// module id = 28\n// module chunks = 0","// app dependencies\nconst express = require('express');\nconst bodyParser = require('body-parser');\nconst expressHandlebars = require('express-handlebars');\nconst Handlebars = require('handlebars');\nconst helmet = require('helmet');\nconst cookieSession = require('cookie-session');\nconst http = require('http');\nconst logger = require('winston');\nconst requestLogger = require('middleware/requestLogger.js');\nconst Path = require('path');\nconst loggerConfig = require('loggerConfig.js');\nconst mysqlConfig = require('mysqlConfig.js');\nconst siteConfig = require('siteConfig.js');\nconst slackConfig = require('slackConfig.js');\n\nfunction Server () {\n this.configureLogger = (userConfig) => {\n loggerConfig.update(userConfig);\n };\n this.configureMysql = (userConfig) => {\n mysqlConfig.update(userConfig);\n };\n this.configureSite = (userConfig) => {\n siteConfig.update(userConfig);\n };\n this.configureSlack = (userConfig) => {\n slackConfig.update(userConfig);\n };\n this.configureModels = () => {\n logger.debug('here is where you could add/overwrite the default models')\n };\n this.configureRoutes = () => {\n logger.debug('here is where you could add/overwrite the default routes')\n };\n this.createApp = () => {\n // create an Express application\n const app = express();\n\n // trust the proxy to get ip address for us\n app.enable('trust proxy');\n\n /* add middleware */\n // set HTTP headers to protect against well-known web vulnerabilties\n app.use(helmet());\n // 'express.static' to serve static files from public directory\n if (siteConfig.routes.publicFolder) {\n // take in a different public folder, so it can serve it's own bundle if needed\n const publicFolder = Path.resolve(process.cwd(), siteConfig.routes.publicFolder);\n app.use(express.static(publicFolder));\n logger.info('serving static files from custom path:', publicFolder);\n } else {\n const publicPath = Path.resolve(__dirname, 'public');\n app.use(express.static(publicPath));\n logger.info('serving static files from default path:', publicPath);\n };\n // 'body parser' for parsing application/json\n app.use(bodyParser.json());\n // 'body parser' for parsing application/x-www-form-urlencoded\n app.use(bodyParser.urlencoded({ extended: true }));\n\n // add custom middleware (note: build out to accept dynamically use what is in server/middleware/\n app.use(requestLogger);\n\n // configure passport\n const speechPassport = require('speechPassport');\n // initialize passport\n const sessionKey = siteConfig.auth.sessionKey;\n app.use(cookieSession({\n name : 'session',\n keys : [sessionKey],\n maxAge: 24 * 60 * 60 * 1000, // i.e. 24 hours\n }));\n app.use(speechPassport.initialize());\n app.use(speechPassport.session());\n\n // configure handlebars & register it with express app\n const hbs = expressHandlebars.create({\n defaultLayout: 'embed',\n handlebars : Handlebars,\n });\n app.engine('handlebars', hbs.engine);\n app.set('view engine', 'handlebars');\n\n // set the routes on the app\n require('./routes/auth/')(app);\n require('./routes/api/')(app);\n require('./routes/pages/')(app);\n require('./routes/assets/')(app);\n require('./routes/fallback/')(app);\n\n this.app = app;\n };\n this.initialize = () => {\n this.createApp();\n this.server = http.Server(this.app);\n };\n this.start = () => {\n const db = require('models');\n const PORT = siteConfig.details.port;\n // sync sequelize\n db.sequelize.sync()\n // start the server\n .then(() => {\n this.server.listen(PORT, () => {\n logger.info(`Server is listening on PORT ${PORT}`);\n });\n })\n .catch((error) => {\n logger.error(`Startup Error:`, error);\n });\n };\n};\n\nmodule.exports = Server;\n\n\n\n// WEBPACK FOOTER //\n// ./server/index.js","module.exports = require(\"express\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"express\"\n// module id = 30\n// module chunks = 0","module.exports = require(\"body-parser\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"body-parser\"\n// module id = 31\n// module chunks = 0","module.exports = require(\"express-handlebars\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"express-handlebars\"\n// module id = 32\n// module chunks = 0","module.exports = require(\"handlebars\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"handlebars\"\n// module id = 33\n// module chunks = 0","module.exports = require(\"helmet\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"helmet\"\n// module id = 34\n// module chunks = 0","module.exports = require(\"cookie-session\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"cookie-session\"\n// module id = 35\n// module chunks = 0","module.exports = require(\"http\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"http\"\n// module id = 36\n// module chunks = 0","const logger = require('winston');\n\nconst requestLogger = (req, res, next) => { // custom logging middleware to log all incoming http requests\n logger.verbose(`Request on ${req.originalUrl} from ${req.ip}`);\n next();\n};\n\nmodule.exports = requestLogger;\n\n\n\n// WEBPACK FOOTER //\n// ./server/middleware/requestLogger.js","module.exports = require(\"path\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"path\"\n// module id = 38\n// module chunks = 0","const logger = require('winston');\n\nfunction LoggerConfig () {\n this.logLevel = 'debug';\n this.update = (config) => {\n if (!config) {\n return logger.warn('No logger config received.');\n }\n logger.info('configuring winston logger...');\n // update values with local config params\n const {logLevel} = config;\n this.logLevel = logLevel;\n // configure the winston logger\n logger.configure({\n transports: [\n new (logger.transports.Console)({\n level : this.logLevel,\n timestamp : false,\n colorize : true,\n prettyPrint : true,\n handleExceptions : true,\n humanReadableUnhandledException: true,\n }),\n ],\n });\n // test all the log levels\n logger.info('testing winston log levels...');\n logger.error('Level 0');\n logger.warn('Level 1');\n logger.info('Level 2');\n logger.verbose('Level 3');\n logger.debug('Level 4');\n logger.silly('Level 5');\n };\n};\n\nmodule.exports = new LoggerConfig();\n\n\n\n// WEBPACK FOOTER //\n// ./config/loggerConfig.js","const winstonSlackWebHook = require('winston-slack-webhook').SlackWebHook;\nconst winston = require('winston');\n\nfunction SlackConfig () {\n this.slackWebHook = 'default';\n this.slackErrorChannel = 'default';\n this.slackInfoChannel = 'default';\n this.update = (config) => {\n if (!config) {\n return winston.warn('No slack config received');\n }\n // update variables\n winston.info('configuring slack logger...');\n const {slackWebHook, slackErrorChannel, slackInfoChannel} = config;\n this.slackWebHook = slackWebHook;\n this.slackErrorChannel = slackErrorChannel;\n this.slackInfoChannel = slackInfoChannel;\n // update slack webhook settings\n if (this.slackWebHook) {\n // add a transport for errors to slack\n if (this.slackErrorChannel) {\n winston.add(winstonSlackWebHook, {\n name : 'slack-errors-transport',\n level : 'warn',\n webhookUrl: this.slackWebHook,\n channel : this.slackErrorChannel,\n username : 'spee.ch',\n iconEmoji : ':face_with_head_bandage:',\n });\n };\n if (slackInfoChannel) {\n winston.add(winstonSlackWebHook, {\n name : 'slack-info-transport',\n level : 'info',\n webhookUrl: this.slackWebHook,\n channel : this.slackInfoChannel,\n username : 'spee.ch',\n iconEmoji : ':nerd_face:',\n });\n };\n // send test messages\n winston.info('testing slack logger...');\n winston.error('Slack \"error\" logging is online.');\n winston.info('Slack \"info\" logging is online.');\n } else {\n winston.warn('Slack logging is not enabled because no slackWebHook config var provided.');\n }\n };\n};\n\nmodule.exports = new SlackConfig();\n\n\n\n// WEBPACK FOOTER //\n// ./config/slackConfig.js","module.exports = require(\"winston-slack-webhook\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"winston-slack-webhook\"\n// module id = 41\n// module chunks = 0","module.exports = require(\"passport\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"passport\"\n// module id = 42\n// module chunks = 0","const PassportLocalStrategy = require('passport-local').Strategy;\nconst logger = require('winston');\nconst db = require('models');\n\nconst returnUserAndChannelInfo = (userInstance) => {\n return new Promise((resolve, reject) => {\n let userInfo = {};\n userInfo['id'] = userInstance.id;\n userInfo['userName'] = userInstance.userName;\n userInstance\n .getChannel()\n .then(({channelName, channelClaimId}) => {\n userInfo['channelName'] = channelName;\n userInfo['channelClaimId'] = channelClaimId;\n return db.Certificate.getShortChannelIdFromLongChannelId(channelClaimId, channelName);\n })\n .then(shortChannelId => {\n userInfo['shortChannelId'] = shortChannelId;\n resolve(userInfo);\n })\n .catch(error => {\n reject(error);\n });\n });\n};\n\nmodule.exports = new PassportLocalStrategy(\n {\n usernameField: 'username',\n passwordField: 'password',\n },\n (username, password, done) => {\n return db.User\n .findOne({\n where: {userName: username},\n })\n .then(user => {\n if (!user) {\n logger.debug('no user found');\n return done(null, false, {message: 'Incorrect username or password'});\n }\n return user.comparePassword(password)\n .then(isMatch => {\n if (!isMatch) {\n logger.debug('incorrect password');\n return done(null, false, {message: 'Incorrect username or password'});\n }\n logger.debug('Password was a match, returning User');\n return returnUserAndChannelInfo(user)\n .then(userInfo => {\n return done(null, userInfo);\n })\n .catch(error => {\n return error;\n });\n })\n .catch(error => {\n return error;\n });\n })\n .catch(error => {\n return done(error);\n });\n },\n);\n\n\n\n// WEBPACK FOOTER //\n// ./server/speechPassport/local-login.js","const logger = require('winston');\nconst { returnShortId } = require('../helpers/sequelizeHelpers.js');\n\nmodule.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, DECIMAL }) => {\n const Certificate = sequelize.define(\n 'Certificate',\n {\n address: {\n type : STRING,\n default: null,\n },\n amount: {\n type : DECIMAL(19, 8),\n default: null,\n },\n claimId: {\n type : STRING,\n default: null,\n },\n claimSequence: {\n type : INTEGER,\n default: null,\n },\n decodedClaim: {\n type : BOOLEAN,\n default: null,\n },\n depth: {\n type : INTEGER,\n default: null,\n },\n effectiveAmount: {\n type : DECIMAL(19, 8),\n default: null,\n },\n hasSignature: {\n type : BOOLEAN,\n default: null,\n },\n height: {\n type : INTEGER,\n default: null,\n },\n hex: {\n type : TEXT('long'),\n default: null,\n },\n name: {\n type : STRING,\n default: null,\n },\n nout: {\n type : INTEGER,\n default: null,\n },\n txid: {\n type : STRING,\n default: null,\n },\n validAtHeight: {\n type : INTEGER,\n default: null,\n },\n outpoint: {\n type : STRING,\n default: null,\n },\n valueVersion: {\n type : STRING,\n default: null,\n },\n claimType: {\n type : STRING,\n default: null,\n },\n certificateVersion: {\n type : STRING,\n default: null,\n },\n keyType: {\n type : STRING,\n default: null,\n },\n publicKey: {\n type : TEXT('long'),\n default: null,\n },\n },\n {\n freezeTableName: true,\n }\n );\n\n Certificate.associate = db => {\n Certificate.belongsTo(db.Channel, {\n foreignKey: {\n allowNull: true,\n },\n });\n };\n\n Certificate.getShortChannelIdFromLongChannelId = function (longChannelId, channelName) {\n logger.debug(`getShortChannelIdFromLongChannelId ${channelName}:${longChannelId}`);\n return new Promise((resolve, reject) => {\n this\n .findAll({\n where: {name: channelName},\n order: [['height', 'ASC']],\n })\n .then(result => {\n switch (result.length) {\n case 0:\n throw new Error('No channel(s) found with that channel name');\n default:\n return resolve(returnShortId(result, longChannelId));\n }\n })\n .catch(error => {\n reject(error);\n });\n });\n };\n\n Certificate.getLongChannelIdFromShortChannelId = function (channelName, channelClaimId) {\n logger.debug(`getLongChannelIdFromShortChannelId(${channelName}, ${channelClaimId})`);\n return new Promise((resolve, reject) => {\n this\n .findAll({\n where: {\n name : channelName,\n claimId: {\n $like: `${channelClaimId}%`,\n },\n },\n order: [['height', 'ASC']],\n })\n .then(result => {\n switch (result.length) {\n case 0:\n return resolve(null);\n default: // note results must be sorted\n return resolve(result[0].claimId);\n }\n })\n .catch(error => {\n reject(error);\n });\n });\n };\n\n Certificate.getLongChannelIdFromChannelName = function (channelName) {\n logger.debug(`getLongChannelIdFromChannelName(${channelName})`);\n return new Promise((resolve, reject) => {\n this\n .findAll({\n where: { name: channelName },\n order: [['effectiveAmount', 'DESC'], ['height', 'ASC']],\n })\n .then(result => {\n switch (result.length) {\n case 0:\n return resolve(null);\n default:\n return resolve(result[0].claimId);\n }\n })\n .catch(error => {\n reject(error);\n });\n });\n };\n\n Certificate.validateLongChannelId = function (name, claimId) {\n logger.debug(`validateLongChannelId(${name}, ${claimId})`);\n return new Promise((resolve, reject) => {\n this.findOne({\n where: {name, claimId},\n })\n .then(result => {\n if (!result) {\n return resolve(null);\n };\n resolve(claimId);\n })\n .catch(error => {\n reject(error);\n });\n });\n };\n\n Certificate.getLongChannelId = function (channelName, channelClaimId) {\n logger.debug(`getLongChannelId(${channelName}, ${channelClaimId})`);\n if (channelClaimId && (channelClaimId.length === 40)) { // if a full channel id is provided\n return this.validateLongChannelId(channelName, channelClaimId);\n } else if (channelClaimId && channelClaimId.length < 40) { // if a short channel id is provided\n return this.getLongChannelIdFromShortChannelId(channelName, channelClaimId);\n } else {\n return this.getLongChannelIdFromChannelName(channelName); // if no channel id provided\n }\n };\n\n return Certificate;\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/models/certificate.js","module.exports = (sequelize, { STRING }) => {\n const Channel = sequelize.define(\n 'Channel',\n {\n channelName: {\n type : STRING,\n allowNull: false,\n },\n channelClaimId: {\n type : STRING,\n allowNull: false,\n },\n },\n {\n freezeTableName: true,\n }\n );\n\n Channel.associate = db => {\n Channel.belongsTo(db.User);\n Channel.hasOne(db.Certificate);\n };\n\n return Channel;\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/models/channel.js","const logger = require('winston');\nconst { returnShortId } = require('../helpers/sequelizeHelpers.js');\nconst { assetDefaults: { thumbnail: defaultThumbnail }, details: { host } } = require('../../config/siteConfig.js');\n\nfunction determineFileExtensionFromContentType (contentType) {\n switch (contentType) {\n case 'image/jpeg':\n case 'image/jpg':\n return 'jpeg';\n case 'image/png':\n return 'png';\n case 'image/gif':\n return 'gif';\n case 'video/mp4':\n return 'mp4';\n default:\n logger.debug('setting unknown file type as file extension jpeg');\n return 'jpeg';\n }\n};\n\nfunction determineThumbnail (storedThumbnail, defaultThumbnail) {\n if (storedThumbnail === '') {\n return defaultThumbnail;\n }\n return storedThumbnail;\n};\n\nfunction prepareClaimData (claim) {\n // logger.debug('preparing claim data based on resolved data:', claim);\n claim['thumbnail'] = determineThumbnail(claim.thumbnail, defaultThumbnail);\n claim['fileExt'] = determineFileExtensionFromContentType(claim.contentType);\n claim['host'] = host;\n return claim;\n};\n\nmodule.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, DECIMAL }) => {\n const Claim = sequelize.define(\n 'Claim',\n {\n address: {\n type : STRING,\n default: null,\n },\n amount: {\n type : DECIMAL(19, 8),\n default: null,\n },\n claimId: {\n type : STRING,\n default: null,\n },\n claimSequence: {\n type : INTEGER,\n default: null,\n },\n decodedClaim: {\n type : BOOLEAN,\n default: null,\n },\n depth: {\n type : INTEGER,\n default: null,\n },\n effectiveAmount: {\n type : DECIMAL(19, 8),\n default: null,\n },\n hasSignature: {\n type : BOOLEAN,\n default: null,\n },\n height: {\n type : INTEGER,\n default: null,\n },\n hex: {\n type : TEXT('long'),\n default: null,\n },\n name: {\n type : STRING,\n default: null,\n },\n nout: {\n type : INTEGER,\n default: null,\n },\n txid: {\n type : STRING,\n default: null,\n },\n validAtHeight: {\n type : INTEGER,\n default: null,\n },\n outpoint: {\n type : STRING,\n default: null,\n },\n claimType: {\n type : STRING,\n default: null,\n },\n certificateId: {\n type : STRING,\n default: null,\n },\n author: {\n type : STRING,\n default: null,\n },\n description: {\n type : TEXT('long'),\n default: null,\n },\n language: {\n type : STRING,\n default: null,\n },\n license: {\n type : STRING,\n default: null,\n },\n licenseUrl: {\n type : STRING,\n default: null,\n },\n nsfw: {\n type : BOOLEAN,\n default: null,\n },\n preview: {\n type : STRING,\n default: null,\n },\n thumbnail: {\n type : STRING,\n default: null,\n },\n title: {\n type : STRING,\n default: null,\n },\n metadataVersion: {\n type : STRING,\n default: null,\n },\n contentType: {\n type : STRING,\n default: null,\n },\n source: {\n type : STRING,\n default: null,\n },\n sourceType: {\n type : STRING,\n default: null,\n },\n sourceVersion: {\n type : STRING,\n default: null,\n },\n streamVersion: {\n type : STRING,\n default: null,\n },\n valueVersion: {\n type : STRING,\n default: null,\n },\n channelName: {\n type : STRING,\n allowNull: true,\n default : null,\n },\n },\n {\n freezeTableName: true,\n }\n );\n\n Claim.associate = db => {\n Claim.belongsTo(db.File, {\n foreignKey: {\n allowNull: true,\n },\n });\n };\n\n Claim.getShortClaimIdFromLongClaimId = function (claimId, claimName) {\n logger.debug(`Claim.getShortClaimIdFromLongClaimId for ${claimName}#${claimId}`);\n return new Promise((resolve, reject) => {\n this\n .findAll({\n where: { name: claimName },\n order: [['height', 'ASC']],\n })\n .then(result => {\n switch (result.length) {\n case 0:\n throw new Error('No claim(s) found with that claim name');\n default:\n resolve(returnShortId(result, claimId));\n }\n })\n .catch(error => {\n reject(error);\n });\n });\n };\n\n Claim.getAllChannelClaims = function (channelClaimId) {\n logger.debug(`Claim.getAllChannelClaims for ${channelClaimId}`);\n return new Promise((resolve, reject) => {\n this\n .findAll({\n where: { certificateId: channelClaimId },\n order: [['height', 'ASC']],\n raw : true, // returns an array of only data, not an array of instances\n })\n .then(channelClaimsArray => {\n // logger.debug('channelclaimsarray length:', channelClaimsArray.length);\n switch (channelClaimsArray.length) {\n case 0:\n return resolve(null);\n default:\n channelClaimsArray.forEach(claim => {\n claim['fileExt'] = determineFileExtensionFromContentType(claim.contentType);\n claim['thumbnail'] = determineThumbnail(claim.thumbnail, defaultThumbnail);\n return claim;\n });\n return resolve(channelClaimsArray);\n }\n })\n .catch(error => {\n reject(error);\n });\n });\n };\n\n Claim.getClaimIdByLongChannelId = function (channelClaimId, claimName) {\n logger.debug(`finding claim id for claim ${claimName} from channel ${channelClaimId}`);\n return new Promise((resolve, reject) => {\n this\n .findAll({\n where: { name: claimName, certificateId: channelClaimId },\n order: [['id', 'ASC']],\n })\n .then(result => {\n switch (result.length) {\n case 0:\n return resolve(null);\n case 1:\n return resolve(result[0].claimId);\n default:\n logger.error(`${result.length} records found for \"${claimName}\" in channel \"${channelClaimId}\"`);\n return resolve(result[0].claimId);\n }\n })\n .catch(error => {\n reject(error);\n });\n });\n };\n\n Claim.getLongClaimIdFromShortClaimId = function (name, shortId) {\n return new Promise((resolve, reject) => {\n this\n .findAll({\n where: {\n name,\n claimId: {\n $like: `${shortId}%`,\n }},\n order: [['height', 'ASC']],\n })\n .then(result => {\n switch (result.length) {\n case 0:\n return resolve(null);\n default: // note results must be sorted\n return resolve(result[0].claimId);\n }\n })\n .catch(error => {\n reject(error);\n });\n });\n };\n\n Claim.getTopFreeClaimIdByClaimName = function (name) {\n return new Promise((resolve, reject) => {\n this\n .findAll({\n where: { name },\n order: [['effectiveAmount', 'DESC'], ['height', 'ASC']], // note: maybe height and effective amount need to switch?\n })\n .then(result => {\n logger.debug('length of result', result.length);\n switch (result.length) {\n case 0:\n return resolve(null);\n default:\n return resolve(result[0].dataValues.claimId);\n }\n })\n .catch(error => {\n reject(error);\n });\n });\n };\n\n Claim.validateLongClaimId = function (name, claimId) {\n return new Promise((resolve, reject) => {\n this.findOne({\n where: {name, claimId},\n })\n .then(result => {\n if (!result) {\n return resolve(null);\n };\n resolve(claimId);\n })\n .catch(error => {\n reject(error);\n });\n });\n };\n\n Claim.getLongClaimId = function (claimName, claimId) {\n logger.debug(`getLongClaimId(${claimName}, ${claimId})`);\n if (claimId && (claimId.length === 40)) { // if a full claim id is provided\n return this.validateLongClaimId(claimName, claimId);\n } else if (claimId && claimId.length < 40) {\n return this.getLongClaimIdFromShortClaimId(claimName, claimId); // if a short claim id is provided\n } else {\n return this.getTopFreeClaimIdByClaimName(claimName); // if no claim id is provided\n }\n };\n\n Claim.resolveClaim = function (name, claimId) {\n logger.debug(`Claim.resolveClaim: ${name} ${claimId}`);\n return new Promise((resolve, reject) => {\n this\n .findAll({\n where: { name, claimId },\n })\n .then(claimArray => {\n switch (claimArray.length) {\n case 0:\n return resolve(null);\n case 1:\n return resolve(prepareClaimData(claimArray[0].dataValues));\n default:\n logger.error(`more than one record matches ${name}#${claimId} in db.Claim`);\n return resolve(prepareClaimData(claimArray[0].dataValues));\n }\n })\n .catch(error => {\n reject(error);\n });\n });\n };\n\n return Claim;\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/models/claim.js","module.exports = (sequelize, { STRING, BOOLEAN, INTEGER }) => {\n const File = sequelize.define(\n 'File',\n {\n name: {\n type : STRING,\n allowNull: false,\n },\n claimId: {\n type : STRING,\n allowNull: false,\n },\n address: {\n type : STRING,\n allowNull: false,\n },\n outpoint: {\n type : STRING,\n allowNull: false,\n },\n height: {\n type : INTEGER,\n allowNull: false,\n default : 0,\n },\n fileName: {\n type : STRING,\n allowNull: false,\n },\n filePath: {\n type : STRING,\n allowNull: false,\n },\n fileType: {\n type: STRING,\n },\n nsfw: {\n type : BOOLEAN,\n allowNull : false,\n defaultValue: false,\n },\n trendingEligible: {\n type : BOOLEAN,\n allowNull : false,\n defaultValue: true,\n },\n },\n {\n freezeTableName: true,\n }\n );\n\n File.associate = db => {\n File.hasMany(db.Request);\n File.hasOne(db.Claim);\n };\n\n File.getRecentClaims = function () {\n return this.findAll({\n where: { nsfw: false, trendingEligible: true },\n order: [['createdAt', 'DESC']],\n limit: 25,\n });\n };\n\n return File;\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/models/file.js","module.exports = (sequelize, { STRING, BOOLEAN, TEXT }) => {\n const Request = sequelize.define(\n 'Request',\n {\n action: {\n type : STRING,\n allowNull: false,\n },\n url: {\n type : STRING,\n allowNull: false,\n },\n ipAddress: {\n type : STRING,\n allowNull: true,\n },\n result: {\n type : TEXT('long'),\n allowNull: true,\n default : null,\n },\n },\n {\n freezeTableName: true,\n }\n );\n\n Request.associate = db => {\n Request.belongsTo(db.File, {\n foreignKey: {\n allowNull: true,\n },\n });\n };\n\n return Request;\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/models/request.js","'use strict';\nconst bcrypt = require('bcrypt');\nconst logger = require('winston');\n\nmodule.exports = (sequelize, { STRING }) => {\n const User = sequelize.define(\n 'User',\n {\n userName: {\n type : STRING,\n allowNull: false,\n },\n password: {\n type : STRING,\n allowNull: false,\n },\n },\n {\n freezeTableName: true,\n }\n );\n\n User.associate = db => {\n User.hasOne(db.Channel);\n };\n\n User.prototype.comparePassword = function (password) {\n return bcrypt.compare(password, this.password);\n };\n\n User.prototype.changePassword = function (newPassword) {\n return new Promise((resolve, reject) => {\n // generate a salt string to use for hashing\n bcrypt.genSalt((saltError, salt) => {\n if (saltError) {\n logger.error('salt error', saltError);\n reject(saltError);\n return;\n }\n // generate a hashed version of the user's password\n bcrypt.hash(newPassword, salt, (hashError, hash) => {\n // if there is an error with the hash generation return the error\n if (hashError) {\n logger.error('hash error', hashError);\n reject(hashError);\n return;\n }\n // replace the current password with the new hash\n this\n .update({password: hash})\n .then(() => {\n resolve();\n })\n .catch(error => {\n reject(error);\n });\n });\n });\n });\n };\n\n // pre-save hook method to hash the user's password before the user's info is saved to the db.\n User.hook('beforeCreate', (user, options) => {\n logger.debug('User.beforeCreate hook...');\n return new Promise((resolve, reject) => {\n // generate a salt string to use for hashing\n bcrypt.genSalt((saltError, salt) => {\n if (saltError) {\n logger.error('salt error', saltError);\n reject(saltError);\n return;\n }\n // generate a hashed version of the user's password\n bcrypt.hash(user.password, salt, (hashError, hash) => {\n // if there is an error with the hash generation return the error\n if (hashError) {\n logger.error('hash error', hashError);\n reject(hashError);\n return;\n }\n // replace the password string with the hash password value\n user.password = hash;\n resolve();\n });\n });\n });\n });\n\n return User;\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/models/user.js","module.exports = require(\"bcrypt\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"bcrypt\"\n// module id = 50\n// module chunks = 0","const PassportLocalStrategy = require('passport-local').Strategy;\nconst lbryApi = require('../helpers/lbryApi.js');\nconst logger = require('winston');\nconst db = require('models');\n\nmodule.exports = new PassportLocalStrategy(\n {\n usernameField: 'username',\n passwordField: 'password',\n },\n (username, password, done) => {\n logger.verbose(`new channel signup request. user: ${username} pass: ${password} .`);\n let userInfo = {};\n // server-side validaton of inputs (username, password)\n\n // create the channel and retrieve the metadata\n return lbryApi.createChannel(`@${username}`)\n .then(tx => {\n // create user record\n const userData = {\n userName: username,\n password: password,\n };\n logger.verbose('userData >', userData);\n // create user record\n const channelData = {\n channelName : `@${username}`,\n channelClaimId: tx.claim_id,\n };\n logger.verbose('channelData >', channelData);\n // create certificate record\n const certificateData = {\n claimId: tx.claim_id,\n name : `@${username}`,\n // address,\n };\n logger.verbose('certificateData >', certificateData);\n // save user and certificate to db\n return Promise.all([db.User.create(userData), db.Channel.create(channelData), db.Certificate.create(certificateData)]);\n })\n .then(([newUser, newChannel, newCertificate]) => {\n logger.verbose('user and certificate successfully created');\n // store the relevant newUser info to be passed back for req.User\n userInfo['id'] = newUser.id;\n userInfo['userName'] = newUser.userName;\n userInfo['channelName'] = newChannel.channelName;\n userInfo['channelClaimId'] = newChannel.channelClaimId;\n // associate the instances\n return Promise.all([newCertificate.setChannel(newChannel), newChannel.setUser(newUser)]);\n })\n .then(() => {\n logger.verbose('user and certificate successfully associated');\n return db.Certificate.getShortChannelIdFromLongChannelId(userInfo.channelClaimId, userInfo.channelName);\n })\n .then(shortChannelId => {\n userInfo['shortChannelId'] = shortChannelId;\n return done(null, userInfo);\n })\n .catch(error => {\n logger.error('signup error', error);\n return done(error);\n });\n }\n);\n\n\n\n// WEBPACK FOOTER //\n// ./server/speechPassport/local-signup.js","module.exports = require(\"axios\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"axios\"\n// module id = 52\n// module chunks = 0","const lbryConfig = {\n api: {\n apiHost: 'localhost',\n apiPort: '5279',\n },\n};\n\nmodule.exports = lbryConfig;\n\n\n\n// WEBPACK FOOTER //\n// ./config/lbryConfig.js","module.exports = require(\"universal-analytics\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"universal-analytics\"\n// module id = 54\n// module chunks = 0","module.exports = {\n serializeSpeechUser (user, done) { // returns user data to be serialized into session\n console.log('serializing user');\n done(null, user);\n },\n deserializeSpeechUser (user, done) { // deserializes session and populates additional info to req.user\n console.log('deserializing user');\n done(null, user);\n },\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/helpers/authHelpers.js","const speechPassport = require('speechPassport');\nconst handleSignupRequest = require('./signup');\nconst handleLoginRequest = require('./login');\nconst handleLogoutRequest = require('./logout');\nconst handleUserRequest = require('./user');\n\nmodule.exports = (app) => {\n app.post('/signup', speechPassport.authenticate('local-signup'), handleSignupRequest);\n app.post('/login', handleLoginRequest);\n app.get('/logout', handleLogoutRequest);\n app.get('/user', handleUserRequest);\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/routes/auth/index.js","const signup = (req, res) => {\n res.status(200).json({\n success : true,\n channelName : req.user.channelName,\n channelClaimId: req.user.channelClaimId,\n shortChannelId: req.user.shortChannelId,\n });\n};\n\nmodule.exports = signup;\n\n\n\n// WEBPACK FOOTER //\n// ./server/routes/auth/signup.js","const speechPassport = require('speechPassport');\n\nconst login = (req, res, next) => {\n speechPassport.authenticate('local-login', (err, user, info) => {\n if (err) {\n return next(err);\n }\n if (!user) {\n return res.status(400).json({\n success: false,\n message: info.message,\n });\n }\n req.logIn(user, (err) => {\n if (err) {\n return next(err);\n }\n return res.status(200).json({\n success : true,\n channelName : req.user.channelName,\n channelClaimId: req.user.channelClaimId,\n shortChannelId: req.user.shortChannelId,\n });\n });\n })(req, res, next);\n};\n\nmodule.exports = login;\n\n\n\n// WEBPACK FOOTER //\n// ./server/routes/auth/login.js","const logout = (req, res) => {\n req.logout();\n res.status(200).json({success: true, message: 'you successfully logged out'});\n};\n\nmodule.exports = logout;\n\n\n\n// WEBPACK FOOTER //\n// ./server/routes/auth/logout.js","const user = (req, res) => {\n if (req.user) {\n res.status(200).json({success: true, data: req.user});\n } else {\n res.status(401).json({success: false, message: 'user is not logged in'});\n }\n};\n\nmodule.exports = user;\n\n\n\n// WEBPACK FOOTER //\n// ./server/routes/auth/user.js","const channelAvailability = require('./channelAvailability');\nconst channelClaims = require('./channelClaims');\nconst channelData = require('./channelData');\nconst channelShortId = require('./channelShortId');\nconst claimAvailability = require('./claimAvailability');\nconst claimData = require('./claimData');\nconst claimGet = require('./claimGet');\nconst claimLongId = require('./claimLongId');\nconst claimPublish = require('./claimPublish');\nconst claimResolve = require('./claimResolve');\nconst claimShortId = require('./claimShortId');\nconst claimList = require('./claimList');\nconst fileAvailability = require('./fileAvailability');\n\nconst multipartMiddleware = require('helpers/multipartMiddleware');\n\nmodule.exports = (app) => {\n // channel routes\n app.get('/api/channel/availability/:name', channelAvailability);\n app.get('/api/channel/short-id/:longId/:name', channelShortId);\n app.get('/api/channel/data/:channelName/:channelClaimId', channelData);\n app.get('/api/channel/claims/:channelName/:channelClaimId/:page', channelClaims);\n // claim routes\n app.get('/api/claim/list/:name', claimList);\n app.get('/api/claim/get/:name/:claimId', claimGet);\n app.get('/api/claim/availability/:name', claimAvailability);\n app.get('/api/claim/resolve/:name/:claimId', claimResolve);\n app.post('/api/claim/publish', multipartMiddleware, claimPublish);\n app.get('/api/claim/short-id/:longId/:name', claimShortId);\n app.post('/api/claim/long-id', claimLongId);\n app.get('/api/claim/data/:claimName/:claimId', claimData);\n // file routes\n app.get('/api/file/availability/:name/:claimId', fileAvailability);\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/routes/api/index.js","const { checkChannelAvailability } = require('controllers/publishController.js');\nconst { sendGATimingEvent } = require('helpers/googleAnalytics.js');\nconst { handleErrorResponse } = require('helpers/errorHandlers.js');\n\n/*\n\n route to check whether site has published to a channel\n\n*/\n\nconst channelAvailability = ({ ip, originalUrl, params: { name } }, res) => {\n const gaStartTime = Date.now();\n checkChannelAvailability(name)\n .then(availableName => {\n res.status(200).json(availableName);\n sendGATimingEvent('end-to-end', 'claim name availability', name, gaStartTime, Date.now());\n })\n .catch(error => {\n handleErrorResponse(originalUrl, ip, error, res);\n });\n};\n\nmodule.exports = channelAvailability;\n\n\n\n// WEBPACK FOOTER //\n// ./server/routes/api/channelAvailability.js","module.exports = require(\"fs\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"fs\"\n// module id = 63\n// module chunks = 0","const { getChannelClaims } = require('controllers/serveController.js');\nconst { handleErrorResponse } = require('helpers/errorHandlers.js');\n\nconst NO_CHANNEL = 'NO_CHANNEL';\n\n/*\n\n route to get all claims for channel\n\n*/\n\nconst channelClaims = ({ ip, originalUrl, body, params }, res) => {\n const channelName = params.channelName;\n let channelClaimId = params.channelClaimId;\n if (channelClaimId === 'none') channelClaimId = null;\n const page = params.page;\n getChannelClaims(channelName, channelClaimId, page)\n .then(data => {\n if (data === NO_CHANNEL) {\n return res.status(404).json({success: false, message: 'No matching channel was found'});\n }\n res.status(200).json({success: true, data});\n })\n .catch(error => {\n handleErrorResponse(originalUrl, ip, error, res);\n });\n};\n\nmodule.exports = channelClaims;\n\n\n\n// WEBPACK FOOTER //\n// ./server/routes/api/channelClaims.js","const CLAIMS_PER_PAGE = 12;\n\nmodule.exports = {\n returnPaginatedChannelClaims (channelName, longChannelClaimId, claims, page) {\n const totalPages = module.exports.determineTotalPages(claims);\n const paginationPage = module.exports.getPageFromQuery(page);\n const viewData = {\n channelName : channelName,\n longChannelClaimId: longChannelClaimId,\n claims : module.exports.extractPageFromClaims(claims, paginationPage),\n previousPage : module.exports.determinePreviousPage(paginationPage),\n currentPage : paginationPage,\n nextPage : module.exports.determineNextPage(totalPages, paginationPage),\n totalPages : totalPages,\n totalResults : module.exports.determineTotalClaims(claims),\n };\n return viewData;\n },\n getPageFromQuery (page) {\n if (page) {\n return parseInt(page);\n }\n return 1;\n },\n extractPageFromClaims (claims, pageNumber) {\n if (!claims) {\n return []; // if no claims, return this default\n }\n // logger.debug('claims is array?', Array.isArray(claims));\n // logger.debug(`pageNumber ${pageNumber} is number?`, Number.isInteger(pageNumber));\n const claimStartIndex = (pageNumber - 1) * CLAIMS_PER_PAGE;\n const claimEndIndex = claimStartIndex + CLAIMS_PER_PAGE;\n const pageOfClaims = claims.slice(claimStartIndex, claimEndIndex);\n return pageOfClaims;\n },\n determineTotalPages (claims) {\n if (!claims) {\n return 0;\n } else {\n const totalClaims = claims.length;\n if (totalClaims < CLAIMS_PER_PAGE) {\n return 1;\n }\n const fullPages = Math.floor(totalClaims / CLAIMS_PER_PAGE);\n const remainder = totalClaims % CLAIMS_PER_PAGE;\n if (remainder === 0) {\n return fullPages;\n }\n return fullPages + 1;\n }\n },\n determinePreviousPage (currentPage) {\n if (currentPage === 1) {\n return null;\n }\n return currentPage - 1;\n },\n determineNextPage (totalPages, currentPage) {\n if (currentPage === totalPages) {\n return null;\n }\n return currentPage + 1;\n },\n determineTotalClaims (claims) {\n if (!claims) {\n return 0;\n }\n return claims.length;\n },\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/helpers/channelPagination.js","const { getChannelData } = require('controllers/serveController.js');\nconst { handleErrorResponse } = require('helpers/errorHandlers.js');\n\nconst NO_CHANNEL = 'NO_CHANNEL';\n\n/*\n\n route to get data for a channel\n\n*/\n\nconst channelData = ({ ip, originalUrl, body, params }, res) => {\n const channelName = params.channelName;\n let channelClaimId = params.channelClaimId;\n if (channelClaimId === 'none') channelClaimId = null;\n getChannelData(channelName, channelClaimId, 0)\n .then(data => {\n if (data === NO_CHANNEL) {\n return res.status(404).json({success: false, message: 'No matching channel was found'});\n }\n res.status(200).json({success: true, data});\n })\n .catch(error => {\n handleErrorResponse(originalUrl, ip, error, res);\n });\n};\n\nmodule.exports = channelData;\n\n\n\n// WEBPACK FOOTER //\n// ./server/routes/api/channelData.js","const { handleErrorResponse } = require('helpers/errorHandlers.js');\nconst db = require('models');\n\n/*\n\nroute to get a short channel id from long channel Id\n\n*/\n\nconst channelShortIdRoute = ({ ip, originalUrl, params }, res) => {\n db.Certificate.getShortChannelIdFromLongChannelId(params.longId, params.name)\n .then(shortId => {\n res.status(200).json(shortId);\n })\n .catch(error => {\n handleErrorResponse(originalUrl, ip, error, res);\n });\n};\n\nmodule.exports = channelShortIdRoute;\n\n\n\n// WEBPACK FOOTER //\n// ./server/routes/api/channelShortId.js","const { claimNameIsAvailable } = require('controllers/publishController.js');\nconst { sendGATimingEvent } = require('helpers/googleAnalytics.js');\nconst { handleErrorResponse } = require('helpers/errorHandlers.js');\n\n/*\n\n route to check whether this site published to a claim\n\n*/\n\nconst claimAvailability = ({ ip, originalUrl, params: { name } }, res) => {\n const gaStartTime = Date.now();\n claimNameIsAvailable(name)\n .then(result => {\n res.status(200).json(result);\n sendGATimingEvent('end-to-end', 'claim name availability', name, gaStartTime, Date.now());\n })\n .catch(error => {\n handleErrorResponse(originalUrl, ip, error, res);\n });\n};\n\nmodule.exports = claimAvailability;\n\n\n\n// WEBPACK FOOTER //\n// ./server/routes/api/claimAvailability.js","const { handleErrorResponse } = require('helpers/errorHandlers.js');\nconst db = require('models');\n\n/*\n\n route to return data for a claim\n\n*/\n\nconst claimData = ({ ip, originalUrl, body, params }, res) => {\n const claimName = params.claimName;\n let claimId = params.claimId;\n if (claimId === 'none') claimId = null;\n db.Claim.resolveClaim(claimName, claimId)\n .then(claimInfo => {\n if (!claimInfo) {\n return res.status(404).json({success: false, message: 'No claim could be found'});\n }\n res.status(200).json({success: true, data: claimInfo});\n })\n .catch(error => {\n handleErrorResponse(originalUrl, ip, error, res);\n });\n};\n\nmodule.exports = claimData;\n\n\n\n// WEBPACK FOOTER //\n// ./server/routes/api/claimData.js","const { getClaim } = require('helpers/lbryApi.js');\nconst { addGetResultsToFileData, createFileData } = require('../../helpers/publishHelpers.js');\nconst { handleErrorResponse } = require('helpers/errorHandlers.js');\nconst db = require('models');\n\n/*\n\n route to get a claim\n\n*/\n\nconst claimGet = ({ ip, originalUrl, params }, res) => {\n const name = params.name;\n const claimId = params.claimId;\n // resolve the claim\n db.Claim.resolveClaim(name, claimId)\n .then(resolveResult => {\n // make sure a claim actually exists at that uri\n if (!resolveResult) {\n throw new Error('No matching uri found in Claim table');\n }\n let fileData = createFileData(resolveResult);\n // get the claim\n return Promise.all([fileData, getClaim(`${name}#${claimId}`)]);\n })\n .then(([ fileData, getResult ]) => {\n fileData = addGetResultsToFileData(fileData, getResult);\n return Promise.all([db.upsert(db.File, fileData, {name, claimId}, 'File'), getResult]);\n })\n .then(([ fileRecord, {message, completed} ]) => {\n res.status(200).json({ success: true, message, completed });\n })\n .catch(error => {\n handleErrorResponse(originalUrl, ip, error, res);\n });\n};\n\nmodule.exports = claimGet;\n\n\n\n// WEBPACK FOOTER //\n// ./server/routes/api/claimGet.js","const { getClaimId } = require('controllers/serveController.js');\nconst { handleErrorResponse } = require('helpers/errorHandlers.js');\n\nconst NO_CHANNEL = 'NO_CHANNEL';\nconst NO_CLAIM = 'NO_CLAIM';\n\n/*\n\n route to get a long claim id\n\n*/\n\nconst claimLongId = ({ ip, originalUrl, body, params }, res) => {\n const channelName = body.channelName;\n const channelClaimId = body.channelClaimId;\n const claimName = body.claimName;\n const claimId = body.claimId;\n getClaimId(channelName, channelClaimId, claimName, claimId)\n .then(result => {\n if (result === NO_CHANNEL) {\n return res.status(404).json({success: false, message: 'No matching channel could be found'});\n }\n if (result === NO_CLAIM) {\n return res.status(404).json({success: false, message: 'No matching claim id could be found'});\n }\n res.status(200).json({success: true, data: result});\n })\n .catch(error => {\n handleErrorResponse(originalUrl, ip, error, res);\n });\n};\n\nmodule.exports = claimLongId;\n\n\n\n// WEBPACK FOOTER //\n// ./server/routes/api/claimLongId.js","const { createBasicPublishParams, createThumbnailPublishParams, parsePublishApiRequestBody, parsePublishApiRequestFiles } = require('helpers/publishHelpers.js');\nconst { claimNameIsAvailable, publish } = require('controllers/publishController.js');\nconst { authenticateUser } = require('auth/authentication.js');\nconst { sendGATimingEvent } = require('helpers/googleAnalytics.js');\nconst { handleErrorResponse } = require('helpers/errorHandlers.js');\nconst { details: { host } } = require('siteConfig.js');\n\n/*\n\n route to publish a claim through the daemon\n\n*/\n\nconst claimPublish = ({ body, files, headers, ip, originalUrl, user }, res) => {\n // define variables\n let channelName, channelId, channelPassword, description, fileName, filePath, fileType, gaStartTime, license, name, nsfw, thumbnail, thumbnailFileName, thumbnailFilePath, thumbnailFileType, title;\n // record the start time of the request\n gaStartTime = Date.now();\n // validate the body and files of the request\n try {\n // validateApiPublishRequest(body, files);\n ({name, nsfw, license, title, description, thumbnail} = parsePublishApiRequestBody(body));\n ({fileName, filePath, fileType, thumbnailFileName, thumbnailFilePath, thumbnailFileType} = parsePublishApiRequestFiles(files));\n ({channelName, channelId, channelPassword} = body);\n } catch (error) {\n return res.status(400).json({success: false, message: error.message});\n }\n // check channel authorization\n Promise\n .all([\n authenticateUser(channelName, channelId, channelPassword, user),\n claimNameIsAvailable(name),\n createBasicPublishParams(filePath, name, title, description, license, nsfw, thumbnail),\n createThumbnailPublishParams(thumbnailFilePath, name, license, nsfw),\n ])\n .then(([{channelName, channelClaimId}, validatedClaimName, publishParams, thumbnailPublishParams]) => {\n // add channel details to the publish params\n if (channelName && channelClaimId) {\n publishParams['channel_name'] = channelName;\n publishParams['channel_id'] = channelClaimId;\n }\n // publish the thumbnail\n if (thumbnailPublishParams) {\n publish(thumbnailPublishParams, thumbnailFileName, thumbnailFileType);\n }\n // publish the asset\n return publish(publishParams, fileName, fileType);\n })\n .then(result => {\n res.status(200).json({\n success: true,\n message: 'publish completed successfully',\n data : {\n name,\n claimId: result.claim_id,\n url : `${host}/${result.claim_id}/${name}`,\n lbryTx : result,\n },\n });\n // record the publish end time and send to google analytics\n sendGATimingEvent('end-to-end', 'publish', fileType, gaStartTime, Date.now());\n })\n .catch(error => {\n handleErrorResponse(originalUrl, ip, error, res);\n });\n};\n\nmodule.exports = claimPublish;\n\n\n\n// WEBPACK FOOTER //\n// ./server/routes/api/claimPublish.js","const db = require('models');\nconst logger = require('winston');\n\nmodule.exports = {\n authenticateUser (channelName, channelId, channelPassword, user) {\n // case: no channelName or channel Id are provided (anonymous), regardless of whether user token is provided\n if (!channelName && !channelId) {\n return {\n channelName : null,\n channelClaimId: null,\n };\n }\n // case: channelName or channel Id are provided with user token\n if (user) {\n if (channelName && channelName !== user.channelName) {\n throw new Error('the provided channel name does not match user credentials');\n }\n if (channelId && channelId !== user.channelClaimId) {\n throw new Error('the provided channel id does not match user credentials');\n }\n return {\n channelName : user.channelName,\n channelClaimId: user.channelClaimId,\n };\n }\n // case: channelName or channel Id are provided with password instead of user token\n if (!channelPassword) throw new Error('no channel password provided');\n return module.exports.authenticateChannelCredentials(channelName, channelId, channelPassword);\n },\n authenticateChannelCredentials (channelName, channelId, userPassword) {\n return new Promise((resolve, reject) => {\n // hoisted variables\n let channelData;\n // build the params for finding the channel\n let channelFindParams = {};\n if (channelName) channelFindParams['channelName'] = channelName;\n if (channelId) channelFindParams['channelClaimId'] = channelId;\n // find the channel\n db.Channel\n .findOne({\n where: channelFindParams,\n })\n .then(channel => {\n if (!channel) {\n logger.debug('no channel found');\n throw new Error('Authentication failed, you do not have access to that channel');\n }\n channelData = channel.get();\n logger.debug('channel data:', channelData);\n return db.User.findOne({\n where: { userName: channelData.channelName.substring(1) },\n });\n })\n .then(user => {\n if (!user) {\n logger.debug('no user found');\n throw new Error('Authentication failed, you do not have access to that channel');\n }\n return user.comparePassword(userPassword);\n })\n .then(isMatch => {\n if (!isMatch) {\n logger.debug('incorrect password');\n throw new Error('Authentication failed, you do not have access to that channel');\n }\n logger.debug('...password was a match...');\n resolve(channelData);\n })\n .catch(error => {\n reject(error);\n });\n });\n },\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/auth/authentication.js","const { resolveUri } = require('helpers/lbryApi.js');\nconst { handleErrorResponse } = require('helpers/errorHandlers.js');\n\n/*\n\n route to run a resolve request on the daemon\n\n*/\n\nconst claimResolve = ({ headers, ip, originalUrl, params }, res) => {\n resolveUri(`${params.name}#${params.claimId}`)\n .then(resolvedUri => {\n res.status(200).json(resolvedUri);\n })\n .catch(error => {\n handleErrorResponse(originalUrl, ip, error, res);\n });\n};\n\nmodule.exports = claimResolve;\n\n\n\n// WEBPACK FOOTER //\n// ./server/routes/api/claimResolve.js","const { handleErrorResponse } = require('helpers/errorHandlers.js');\nconst db = require('models');\n\n/*\n\n route to get a short claim id from long claim Id\n\n*/\n\nconst claimShortId = ({ ip, originalUrl, body, params }, res) => {\n db.Claim.getShortClaimIdFromLongClaimId(params.longId, params.name)\n .then(shortId => {\n res.status(200).json({success: true, data: shortId});\n })\n .catch(error => {\n handleErrorResponse(originalUrl, ip, error, res);\n });\n};\n\nmodule.exports = claimShortId;\n\n\n\n// WEBPACK FOOTER //\n// ./server/routes/api/claimShortId.js","const { getClaimList } = require('helpers/lbryApi.js');\nconst { handleErrorResponse } = require('helpers/errorHandlers.js');\n\n/*\n\n route to get list of claims\n\n*/\n\nconst claimList = ({ ip, originalUrl, params }, res) => {\n getClaimList(params.name)\n .then(claimsList => {\n res.status(200).json(claimsList);\n })\n .catch(error => {\n handleErrorResponse(originalUrl, ip, error, res);\n });\n};\n\nmodule.exports = claimList;\n\n\n\n// WEBPACK FOOTER //\n// ./server/routes/api/claimList.js","const { handleErrorResponse } = require('helpers/errorHandlers.js');\nconst db = require('models');\n\n/*\n\n route to see if asset is available locally\n\n*/\n\nconst fileAvailability = ({ ip, originalUrl, params }, res) => {\n const name = params.name;\n const claimId = params.claimId;\n db.File\n .findOne({\n where: {\n name,\n claimId,\n },\n })\n .then(result => {\n if (result) {\n return res.status(200).json({success: true, data: true});\n }\n res.status(200).json({success: true, data: false});\n })\n .catch(error => {\n handleErrorResponse(originalUrl, ip, error, res);\n });\n};\n\nmodule.exports = fileAvailability;\n\n\n\n// WEBPACK FOOTER //\n// ./server/routes/api/fileAvailability.js","const multipart = require('connect-multiparty');\nconst { publishing: { uploadDirectory } } = require('siteConfig.js');\nconst multipartMiddleware = multipart({uploadDir: uploadDirectory});\n\nmodule.exports = multipartMiddleware;\n\n\n\n// WEBPACK FOOTER //\n// ./server/helpers/multipartMiddleware.js","module.exports = require(\"connect-multiparty\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"connect-multiparty\"\n// module id = 79\n// module chunks = 0","const handlePageRequest = require('./sendReactApp');\nconst handleEmbedRequest = require('./sendEmbedPage');\nconst redirect = require('./redirect');\n\nmodule.exports = (app) => {\n app.get('/', handlePageRequest);\n app.get('/login', handlePageRequest);\n app.get('/about', handlePageRequest);\n app.get('/trending', redirect('/popular'));\n app.get('/popular', handlePageRequest);\n app.get('/new', handlePageRequest);\n app.get('/embed/:claimId/:name', handleEmbedRequest); // route to send embedable video player (for twitter)\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/routes/pages/index.js","const handlePageRender = require('helpers/handlePageRender.jsx');\n\nconst sendReactApp = (req, res) => {\n handlePageRender(req, res);\n};\n\nmodule.exports = sendReactApp;\n\n\n\n// WEBPACK FOOTER //\n// ./server/routes/pages/sendReactApp.js","const { details: { host } } = require('siteConfig.js');\n\nconst sendEmbedPage = ({ params }, res) => {\n const claimId = params.claimId;\n const name = params.name;\n // get and render the content\n res.status(200).render('embed', { layout: 'embed', host, claimId, name });\n};\n\nmodule.exports = sendEmbedPage;\n\n\n\n// WEBPACK FOOTER //\n// ./server/routes/pages/sendEmbedPage.js","const redirect = (route) => {\n return (req, res) => {\n res.status(301).redirect(route);\n };\n};\n\nmodule.exports = redirect;\n\n\n\n// WEBPACK FOOTER //\n// ./server/routes/pages/redirect.js","const serveAssetByClaim = require('./serveAssetByClaim');\nconst serveAssetByIdentifierAndClaim = require('./serveAssetByIdentifierAndClaim');\n\nmodule.exports = (app, db) => {\n app.get('/:identifier/:claim', serveAssetByIdentifierAndClaim);\n app.get('/:claim', serveAssetByClaim);\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/routes/assets/index.js","const { sendGAServeEvent } = require('helpers/googleAnalytics');\nconst { determineResponseType, logRequestData, getClaimIdAndServeAsset } = require('helpers/serveHelpers.js');\nconst lbryUri = require('helpers/lbryUri.js');\nconst handleShowRender = require('helpers/handleShowRender.jsx');\nconst SERVE = 'SERVE';\n\n/*\n\n route to serve an asset or the react app via the claim name only\n\n*/\n\nconst serverAssetByClaim = (req, res) => {\n const { headers, ip, originalUrl, params } = req;\n // decide if this is a show request\n let hasFileExtension;\n try {\n ({ hasFileExtension } = lbryUri.parseModifier(params.claim));\n } catch (error) {\n return res.status(400).json({success: false, message: error.message});\n }\n let responseType = determineResponseType(hasFileExtension, headers);\n if (responseType !== SERVE) {\n return handleShowRender(req, res);\n }\n // handle serve request\n // send google analytics\n sendGAServeEvent(headers, ip, originalUrl);\n // parse the claim\n let claimName;\n try {\n ({claimName} = lbryUri.parseClaim(params.claim));\n } catch (error) {\n return res.status(400).json({success: false, message: error.message});\n }\n // log the request data for debugging\n logRequestData(responseType, claimName, null, null);\n // get the claim Id and then serve the asset\n getClaimIdAndServeAsset(null, null, claimName, null, originalUrl, ip, res);\n};\n\nmodule.exports = serverAssetByClaim;\n\n\n\n// WEBPACK FOOTER //\n// ./server/routes/assets/serveAssetByClaim.js","module.exports = require(\"redux-saga\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"redux-saga\"\n// module id = 86\n// module chunks = 0","module.exports = require(\"redux-saga/effects\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"redux-saga/effects\"\n// module id = 87\n// module chunks = 0","const { sendGAServeEvent } = require('helpers/googleAnalytics');\nconst {\n determineResponseType,\n flipClaimNameAndIdForBackwardsCompatibility,\n logRequestData,\n getClaimIdAndServeAsset,\n} = require('helpers/serveHelpers.js');\nconst lbryUri = require('helpers/lbryUri.js');\nconst handleShowRender = require('helpers/handleShowRender.jsx');\n\nconst SERVE = 'SERVE';\n\n/*\n\n route to serve an asset or the react app via the claim name and an identifier\n\n*/\n\nconst serverAssetByIdentifierAndClaim = (req, res) => {\n const { headers, ip, originalUrl, params } = req;\n // decide if this is a show request\n let hasFileExtension;\n try {\n ({ hasFileExtension } = lbryUri.parseModifier(params.claim));\n } catch (error) {\n return res.status(400).json({success: false, message: error.message});\n }\n let responseType = determineResponseType(hasFileExtension, headers);\n if (responseType !== SERVE) {\n return handleShowRender(req, res);\n }\n // handle serve request\n // send google analytics\n sendGAServeEvent(headers, ip, originalUrl);\n // parse the claim\n let claimName;\n try {\n ({ claimName } = lbryUri.parseClaim(params.claim));\n } catch (error) {\n return res.status(400).json({success: false, message: error.message});\n }\n // parse the identifier\n let isChannel, channelName, channelClaimId, claimId;\n try {\n ({ isChannel, channelName, channelClaimId, claimId } = lbryUri.parseIdentifier(params.identifier));\n } catch (error) {\n return res.status(400).json({success: false, message: error.message});\n }\n if (!isChannel) {\n [claimId, claimName] = flipClaimNameAndIdForBackwardsCompatibility(claimId, claimName);\n }\n // log the request data for debugging\n logRequestData(responseType, claimName, channelName, claimId);\n // get the claim Id and then serve the asset\n getClaimIdAndServeAsset(channelName, channelClaimId, claimName, claimId, originalUrl, ip, res);\n};\n\nmodule.exports = serverAssetByIdentifierAndClaim;\n\n\n\n// WEBPACK FOOTER //\n// ./server/routes/assets/serveAssetByIdentifierAndClaim.js","const handlePageRequest = require('./sendReactApp');\n\nmodule.exports = (app) => {\n app.get('*', handlePageRequest);\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/routes/fallback/index.js","const handlePageRender = require('helpers/handlePageRender.jsx');\n\nconst sendReactApp = (req, res) => {\n handlePageRender(req, res);\n};\n\nmodule.exports = sendReactApp;\n\n\n\n// WEBPACK FOOTER //\n// ./server/routes/fallback/sendReactApp.js"],"sourceRoot":""} |