Repository: powerdong/Music-player Branch: master Commit: c505e40c41a3 Files: 193 Total size: 616.8 KB Directory structure: gitextract_0ydqwdr6/ ├── .vscode/ │ └── settings.json ├── README.md └── musicPlayer/ ├── .babelrc ├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .postcssrc.js ├── README.md ├── build/ │ ├── build.js │ ├── check-versions.js │ ├── utils.js │ ├── vue-loader.conf.js │ ├── webpack.base.conf.js │ ├── webpack.dev.conf.js │ └── webpack.prod.conf.js ├── config/ │ ├── dev.env.js │ ├── index.js │ └── prod.env.js ├── index.html ├── package.json ├── src/ │ ├── App.vue │ ├── api/ │ │ ├── config.js │ │ └── index.js │ ├── assets/ │ │ ├── Bus.js │ │ ├── Mixins.js │ │ ├── styles/ │ │ │ ├── border.css │ │ │ ├── global.less │ │ │ └── reset.css │ │ └── utils/ │ │ ├── cookie.js │ │ ├── filters.js │ │ ├── getAstro.js │ │ ├── getPhone.js │ │ ├── getRandomArrayElements.js │ │ ├── modalScroll.js │ │ ├── scrollStopVideo.js │ │ └── setKeyWords.js │ ├── base/ │ │ ├── albumPage/ │ │ │ ├── index.vue │ │ │ └── index2.vue │ │ ├── alert.vue │ │ ├── audioAllTitle.vue │ │ ├── button.vue │ │ ├── circleLoading.vue │ │ ├── comments.vue │ │ ├── djDetailPage/ │ │ │ ├── components/ │ │ │ │ └── changeNav.vue │ │ │ ├── index.vue │ │ │ └── index2.vue │ │ ├── djSublistCard.vue │ │ ├── generalNav.vue │ │ ├── icon.vue │ │ ├── idxCard.vue │ │ ├── imgCard.vue │ │ ├── interchangeable.vue │ │ ├── loading.vue │ │ ├── loginPageIsShow.vue │ │ ├── pageErrorInfo.vue │ │ ├── pageLoading.vue │ │ ├── searchInput.vue │ │ ├── shouldLogin.vue │ │ ├── slider.vue │ │ ├── sliderNav.vue │ │ ├── song.vue │ │ ├── songListPage/ │ │ │ └── index.vue │ │ └── titleFooter.vue │ ├── components/ │ │ ├── detailPage/ │ │ │ └── index.vue │ │ └── top-tip/ │ │ └── index.vue │ ├── getInfos/ │ │ ├── getData.js │ │ └── icons.js │ ├── main.js │ ├── pages/ │ │ ├── audioIndex/ │ │ │ ├── components/ │ │ │ │ ├── audioList.vue │ │ │ │ ├── bar.vue │ │ │ │ ├── functionButton.vue │ │ │ │ ├── lyricPage.vue │ │ │ │ ├── playIcons.vue │ │ │ │ ├── playing.vue │ │ │ │ └── small.vue │ │ │ └── index.vue │ │ ├── commentsIndex/ │ │ │ ├── components/ │ │ │ │ ├── albumListInfo.vue │ │ │ │ └── centerMenu.vue │ │ │ └── index.vue │ │ ├── dateRecommend/ │ │ │ └── index.vue │ │ ├── dj/ │ │ │ ├── childrenPage/ │ │ │ │ ├── class.vue │ │ │ │ ├── classRecommend.vue │ │ │ │ ├── djPayGift.vue │ │ │ │ ├── ranking-anchor.vue │ │ │ │ ├── ranking-program.vue │ │ │ │ ├── ranking-radio.vue │ │ │ │ ├── ranking.vue │ │ │ │ └── topConDetail.vue │ │ │ ├── components/ │ │ │ │ ├── boutiqueRecom.vue │ │ │ │ ├── icons.vue │ │ │ │ ├── radioRecom.vue │ │ │ │ └── swiper.vue │ │ │ ├── index.vue │ │ │ ├── public.vue │ │ │ ├── publicClass.vue │ │ │ ├── publicImgWrap.vue │ │ │ └── titleAndThree.vue │ │ ├── djSublist/ │ │ │ └── index.vue │ │ ├── findIndex/ │ │ │ ├── components/ │ │ │ │ ├── chinese.vue │ │ │ │ ├── europe.vue │ │ │ │ ├── icons.vue │ │ │ │ ├── japan.vue │ │ │ │ ├── korea.vue │ │ │ │ ├── moreNewDish.vue │ │ │ │ ├── moreNewSongs.vue │ │ │ │ ├── newDish.vue │ │ │ │ ├── personalizedSongList.vue │ │ │ │ └── swiper.vue │ │ │ └── index.vue │ │ ├── friendIndex/ │ │ │ ├── index.vue │ │ │ └── public.vue │ │ ├── homeIndex/ │ │ │ ├── components/ │ │ │ │ ├── addNewPlayList.vue │ │ │ │ ├── homeList.vue │ │ │ │ ├── icons.vue │ │ │ │ └── songList.vue │ │ │ └── index.vue │ │ ├── idx/ │ │ │ └── index.vue │ │ ├── loginIndex/ │ │ │ ├── components/ │ │ │ │ ├── accountLogin.vue │ │ │ │ ├── phoneAccount.vue │ │ │ │ ├── phonePwd.vue │ │ │ │ ├── phoneVerify.vue │ │ │ │ ├── verifyCode.vue │ │ │ │ └── verifyInfo.vue │ │ │ └── index.vue │ │ ├── myFavorite/ │ │ │ ├── components/ │ │ │ │ ├── albums.vue │ │ │ │ ├── artists.vue │ │ │ │ ├── column.vue │ │ │ │ ├── mlog.vue │ │ │ │ └── videos.vue │ │ │ └── index.vue │ │ ├── nav/ │ │ │ ├── components/ │ │ │ │ ├── login-bottom.vue │ │ │ │ ├── login-icons-bottom.vue │ │ │ │ ├── login-icons-top.vue │ │ │ │ ├── login-icons.vue │ │ │ │ ├── login-top.vue │ │ │ │ └── login.vue │ │ │ └── index.vue │ │ ├── recentlyPlayed/ │ │ │ └── index.vue │ │ ├── recommend/ │ │ │ ├── fine/ │ │ │ │ └── index.vue │ │ │ ├── general/ │ │ │ │ └── index.vue │ │ │ ├── index.vue │ │ │ ├── navIndex/ │ │ │ │ └── navList.vue │ │ │ └── recommended/ │ │ │ └── index.vue │ │ ├── searchIndex/ │ │ │ ├── components/ │ │ │ │ ├── history.vue │ │ │ │ └── hotSearch.vue │ │ │ └── index.vue │ │ ├── searchResults/ │ │ │ ├── albumIndex/ │ │ │ │ └── album.vue │ │ │ ├── artistIndex/ │ │ │ │ └── artist.vue │ │ │ ├── composite/ │ │ │ │ ├── components/ │ │ │ │ │ ├── album.vue │ │ │ │ │ ├── artist.vue │ │ │ │ │ ├── djRadio.vue │ │ │ │ │ ├── playList.vue │ │ │ │ │ ├── simQuery.vue │ │ │ │ │ ├── song.vue │ │ │ │ │ ├── user.vue │ │ │ │ │ └── video.vue │ │ │ │ └── composite.vue │ │ │ ├── djRadioIndex/ │ │ │ │ └── djRadio.vue │ │ │ ├── index.vue │ │ │ ├── navIndex/ │ │ │ │ └── index.vue │ │ │ ├── playListIndex/ │ │ │ │ └── playList.vue │ │ │ ├── singerIndex/ │ │ │ │ ├── select.vue │ │ │ │ └── singer.vue │ │ │ ├── songIndex/ │ │ │ │ └── song.vue │ │ │ ├── userIndex/ │ │ │ │ └── user.vue │ │ │ └── videoIndex/ │ │ │ └── video.vue │ │ ├── userInfoIndex/ │ │ │ ├── components/ │ │ │ │ ├── userDynamic.vue │ │ │ │ └── userHome.vue │ │ │ └── index.vue │ │ └── videoIndex/ │ │ ├── components/ │ │ │ ├── acg.vue │ │ │ ├── animation.vue │ │ │ ├── dance.vue │ │ │ ├── game.vue │ │ │ ├── listenBGM.vue │ │ │ ├── musicFestival.vue │ │ │ ├── rock.vue │ │ │ ├── scene.vue │ │ │ └── singing.vue │ │ ├── index.vue │ │ ├── public.vue │ │ └── videoComments/ │ │ ├── components/ │ │ │ ├── video.vue │ │ │ ├── videoCreator.vue │ │ │ └── videoInfo.vue │ │ └── index.vue │ ├── router/ │ │ └── index.js │ └── store/ │ ├── actions.js │ ├── getters.js │ ├── index.js │ ├── mutation-types.js │ ├── mutations.js │ └── state.js └── static/ └── .gitkeep ================================================ FILE CONTENTS ================================================ ================================================ FILE: .vscode/settings.json ================================================ { "cSpell.words": [ "RCVD", "autofocus", "blogaaa", "flexbox", "vmax", "zhidao" ] } ================================================ FILE: README.md ================================================

Welcome to Music-player 👋

webpack vue node dependencies dev dependencies

## :speech_balloon:前言 随着不断的学习 Vue,需要做一个小项目通过在实现项目过程中了解到更多的知识。随着如今人们对于音乐的需求,移动端的使用量愈发增加,项目通过 Vue 编写实现,全面借用**网易云音乐移动端**的 UI 设计、功能实现,努力做到以假乱真的效果。前几天便着手开始弄了,到今天为止也算是勉强能用了。 > 本项目自行构思得出,由个人独立编写程序研究。 **注:此项目纯属个人瞎搞,正常使用请选择[网易云音乐官方](https://music.163.com)客户端。** ## :muscle: 项目目标 全面实现移动端网易云音乐的功能 > **项目还在编写完善中** ## 🚀 如何运行 > node 版本 `[10.15.3]` ### ✨ 开发过程 ``` # 克隆 git clone https://github.com/powerdong/Music-player.git ``` ``` # 打开项目目录 cd Music-player cd musicPlayer ``` ``` # 安装依赖 npm install ``` ``` # 开启本地服务运行项目 npm run dev ``` **欢迎 star,欢迎 issue** ### :eyes: 项目进度 **上一次更新(2020-03-15):** ~~登录功能bug修复~~ **最近一次更新(2020-05-04):** 歌单详情bug修复 > 感谢大家的关注,最近在实习期间未能及时更新,最近发现网易的api返回有变化,回来改了一个问题 ### :memo: 版本更新 - **版本信息:** 2.4.8-> 2.8.10 - **时间:** 2019 年 12 月 7 日 - **更新内容:** - 增加发现页面下拉刷新+轻提示 - 增加电台排行页面主播榜 - 增加电台排行页面节目榜中 24 小时榜 - 增加电台排行页面电台榜中付费精品榜 - 修复登录页面不能返回 Bug - 修复其他已知问题 - 优化结构 使用中有任何问题或建议,欢迎 Issue! 本项目在不断完善中,请大家拭目以待~ ## 技术栈 ### :point_right: 主要依赖 - Vue 全家桶(使用 Vue-cli 作为构建工具) - WebPack4.0 - ES6 - Less - ESLint - Vant UI - [网易云音乐 API](https://binaryify.github.io/NeteaseCloudMusicApi/#/) ### :clap: 项目演示 [demo 地址](http://140.143.128.100:3000)(请用 chrome/firefox 手机模式预览) -- 暂时停止 ## :mega: 目标功能 - [x] 手机登录、注册 - [x] 修改密码 - [x] 我的页面歌单信息 - [x] 添加,删除歌单 - [x] 最近播放 - [x] 心动模式 - [x] 我的电台 - [x] 我的收藏 - [x] 发现页面推荐歌单 - [x] 发现页面新碟 - [x] 发现页面新歌 - [x] 发现页面每日推荐 - [x] 发现页面歌单 - [x] 视频页面 - [ ] 朋友页面 - [x] 歌单广场 - [x] 新歌推荐 - [x] 更多新碟 - [x] 发现页面排行榜 - [x] 发现页面电台 - [x] 退出账号 - [x] 发现页面私人 FM - [x] 搜索功能 - [x] 搜索结果展示 - [x] 热搜榜 - [x] 历史记录 - [x] 搜索推荐 - [x] 歌手分类 - [x] 播放功能(**小播放器进度条**) - [x] 播放列表 - [x] 添加删除播放列表 - [x] 签到 - [x] 歌曲喜欢与否 - [x] 专辑收藏与否 - [x] 歌单评论 - [x] 专辑评论 - [x] 点赞、发送、删除评论 - [x] 电台节目评论 - [x] 视频评论 - [x] 用户相关 - [ ] 页面滚动加载 - [ ] 左右滑动切换 - [ ] 页面切换动画 - [ ] 登陆情况判断 - [ ] 全面优化&修复 ## :computer: 部分截图 侧边账户中心 ![uDnX80.png](https://user-gold-cdn.xitu.io/2019/10/4/16d95706581a456f?w=472&h=837&f=png&s=45997) 发现页面&每日推荐 ![uDuYM8.gif](https://user-gold-cdn.xitu.io/2019/10/4/16d9572548c6aaf3?w=491&h=838&f=gif&s=3519632) 歌单&歌单详情 ![uDuGxf.gif](https://user-gold-cdn.xitu.io/2019/10/4/16d9572540c179b1?w=491&h=838&f=gif&s=2610859) 排行榜&排行榜信息 ![uDu3Gt.gif](https://user-gold-cdn.xitu.io/2019/10/4/16d95725335944d7?w=491&h=838&f=gif&s=934318) 我的页面&最近播放 ![uDu1PI.gif](https://user-gold-cdn.xitu.io/2019/10/4/16d95725267c98e0?w=491&h=838&f=gif&s=290121) 我的歌单&播放歌曲 ![uDutsS.gif](https://user-gold-cdn.xitu.io/2019/10/4/16d9572557bd8143?w=491&h=838&f=gif&s=7018012) 搜索展示 ![uDu8RP.gif](https://user-gold-cdn.xitu.io/2019/10/4/16d9572538e2c261?w=491&h=838&f=gif&s=1094604) ## :page_with_curl: 项目布局 ```js .src +-- api | +-- config.js // 存取相关的api地址 | +-- index.js // 请求相关的api方法 +-- assets | +-- styles | +-- border.css // 移动端的1px边框 | +-- global.less // 全局应用样式 | +-- reset.css // 重置样式 | +-- resetEleUI.less // 修改elementUI组件样式 | +-- utils // 全局要使用的方法 | +-- getPhone // 获取手机号码 | +-- modalScroll // 处理移动端滚动条 | +-- Bus.js // Bus 总线 | +-- Mixins.js // 混入(mixin) +-- base // 存取页面公共的小组件 +-- albumPage // 歌单展示页面组件 +-- songListPage // 展示歌曲列表 +-- alert // 提示消息 +-- audioAllTitle // 播放全部标题行 +-- button // 登陆页面按钮 +-- djSublistCard // 类似于我的电台页面的长卡片组件 +-- generalNav // 通用页面顶部的标题行 +-- icon // 图标展示 +-- idxCard // 官方排行榜 +-- imgCard // 歌单的图片卡 +-- interchangeable // 用来展示搜索展示页面除单曲以外的项目 +-- loading // 转圈loading +-- pageErrorInfo // 出错提醒 +-- pageErrorLoading // 页面加载loading +-- searchInput // 搜索框 +-- slider // 播放列表滑块 +-- sliderNav // 滑动标题 +-- song // 歌曲项 +-- titleFooter // 搜索展示页综合页面各项通用头和尾 +-- getInfos // 获取一些静态信息 +-- getData // 获取静态信息方法 +-- icon // 存取图标信息 +-- pages // 项目路由页面 +-- router // 路由配置 +-- index +-- store // vuex 配置使用 +-- action // 根级别的 action +-- getter // 根级别的 getter +-- index // 组装模块并导出 store 的地方 +-- mutation-types // 根级别的 mutation-types +-- mutation // 根级别的 mutation +-- state // 根级别的 state ``` ## 打包日志 ![M0Apjg.png](https://s2.ax1x.com/2019/11/16/M0Apjg.png) ![M0ASgS.png](https://s2.ax1x.com/2019/11/16/M0ASgS.png) > 本项目会长期更新,欢迎大家指出问题,共同学习 ## 作者 👤 **Lambda** ================================================ FILE: musicPlayer/.babelrc ================================================ { "presets": [ ["env", { "modules": false, "targets": { "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] } }], "stage-2" ], "plugins": [ ["import", { "libraryName": "vant", "libraryDirectory": "es", "style": true }], "transform-vue-jsx", "transform-runtime", [ "component", { "libraryName": "element-ui", "styleLibraryName": "theme-chalk" } ] ] } ================================================ FILE: musicPlayer/.editorconfig ================================================ root = true [*] charset = utf-8 indent_style = space indent_size = 2 end_of_line = lf insert_final_newline = true trim_trailing_whitespace = true ================================================ FILE: musicPlayer/.eslintignore ================================================ /build/ /config/ /dist/ /*.js ================================================ FILE: musicPlayer/.eslintrc.js ================================================ // https://eslint.org/docs/user-guide/configuring module.exports = { root: true, parserOptions: { parser: 'babel-eslint' }, env: { browser: true, }, extends: [ // https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention // consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules. 'plugin:vue/essential', // https://github.com/standard/standard/blob/master/docs/RULES-en.md 'standard' ], // required to lint *.vue files plugins: [ 'vue' ], // add your custom rules here rules: { // allow async-await 'generator-star-spacing': 'off', // allow debugger during development 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', // "quotes": [1, "double"] } } ================================================ FILE: musicPlayer/.gitignore ================================================ .DS_Store node_modules/ /dist/ save/ npm-debug.log* yarn-debug.log* yarn-error.log* # Editor directories and files .idea .vscode *.suo *.ntvs* *.njsproj *.sln ================================================ FILE: musicPlayer/.postcssrc.js ================================================ // https://github.com/michael-ciniawsky/postcss-load-config module.exports = { "plugins": { "postcss-import": {}, "postcss-url": {}, // to edit target browsers: use "browserslist" field in package.json "autoprefixer": {} } } ================================================ FILE: musicPlayer/README.md ================================================ # music-player > 高仿网易云音乐 ## Build Setup ``` bash # install dependencies npm install # serve with hot reload at localhost:8080 npm run dev # build for production with minification npm run build # build for production and view the bundle analyzer report npm run build --report ``` For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). ================================================ FILE: musicPlayer/build/build.js ================================================ 'use strict' require('./check-versions')() process.env.NODE_ENV = 'production' const ora = require('ora') const rm = require('rimraf') const path = require('path') const chalk = require('chalk') const webpack = require('webpack') const config = require('../config') const webpackConfig = require('./webpack.prod.conf') const spinner = ora('building for production...') spinner.start() rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { if (err) throw err webpack(webpackConfig, (err, stats) => { spinner.stop() if (err) throw err process.stdout.write(stats.toString({ colors: true, modules: false, children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build. chunks: false, chunkModules: false }) + '\n\n') if (stats.hasErrors()) { console.log(chalk.red(' Build failed with errors.\n')) process.exit(1) } console.log(chalk.cyan(' Build complete.\n')) console.log(chalk.yellow( ' Tip: built files are meant to be served over an HTTP server.\n' + ' Opening index.html over file:// won\'t work.\n' )) }) }) ================================================ FILE: musicPlayer/build/check-versions.js ================================================ 'use strict' const chalk = require('chalk') const semver = require('semver') const packageConfig = require('../package.json') const shell = require('shelljs') function exec (cmd) { return require('child_process').execSync(cmd).toString().trim() } const versionRequirements = [ { name: 'node', currentVersion: semver.clean(process.version), versionRequirement: packageConfig.engines.node } ] if (shell.which('npm')) { versionRequirements.push({ name: 'npm', currentVersion: exec('npm --version'), versionRequirement: packageConfig.engines.npm }) } module.exports = function () { const warnings = [] for (let i = 0; i < versionRequirements.length; i++) { const mod = versionRequirements[i] if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { warnings.push(mod.name + ': ' + chalk.red(mod.currentVersion) + ' should be ' + chalk.green(mod.versionRequirement) ) } } if (warnings.length) { console.log('') console.log(chalk.yellow('To use this template, you must update following to modules:')) console.log() for (let i = 0; i < warnings.length; i++) { const warning = warnings[i] console.log(' ' + warning) } console.log() process.exit(1) } } ================================================ FILE: musicPlayer/build/utils.js ================================================ 'use strict' const path = require('path') const config = require('../config') const ExtractTextPlugin = require('extract-text-webpack-plugin') const packageConfig = require('../package.json') exports.assetsPath = function (_path) { const assetsSubDirectory = process.env.NODE_ENV === 'production' ? config.build.assetsSubDirectory : config.dev.assetsSubDirectory return path.posix.join(assetsSubDirectory, _path) } exports.cssLoaders = function (options) { options = options || {} const cssLoader = { loader: 'css-loader', options: { sourceMap: options.sourceMap } } const postcssLoader = { loader: 'postcss-loader', options: { sourceMap: options.sourceMap } } // generate loader string to be used with extract text plugin function generateLoaders (loader, loaderOptions) { const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader] if (loader) { loaders.push({ loader: loader + '-loader', options: Object.assign({}, loaderOptions, { sourceMap: options.sourceMap }) }) } // Extract CSS when that option is specified // (which is the case during production build) if (options.extract) { return ExtractTextPlugin.extract({ use: loaders, fallback: 'vue-style-loader' }) } else { return ['vue-style-loader'].concat(loaders) } } // https://vue-loader.vuejs.org/en/configurations/extract-css.html return { css: generateLoaders(), postcss: generateLoaders(), less: generateLoaders('less'), sass: generateLoaders('sass', { indentedSyntax: true }), scss: generateLoaders('sass'), stylus: generateLoaders('stylus'), styl: generateLoaders('stylus') } } // Generate loaders for standalone style files (outside of .vue) exports.styleLoaders = function (options) { const output = [] const loaders = exports.cssLoaders(options) for (const extension in loaders) { const loader = loaders[extension] output.push({ test: new RegExp('\\.' + extension + '$'), use: loader }) } return output } exports.createNotifierCallback = () => { const notifier = require('node-notifier') return (severity, errors) => { if (severity !== 'error') return const error = errors[0] const filename = error.file && error.file.split('!').pop() notifier.notify({ title: packageConfig.name, message: severity + ': ' + error.name, subtitle: filename || '', icon: path.join(__dirname, 'logo.png') }) } } ================================================ FILE: musicPlayer/build/vue-loader.conf.js ================================================ 'use strict' const utils = require('./utils') const config = require('../config') const isProduction = process.env.NODE_ENV === 'production' const sourceMapEnabled = isProduction ? config.build.productionSourceMap : config.dev.cssSourceMap module.exports = { loaders: utils.cssLoaders({ sourceMap: sourceMapEnabled, extract: isProduction }), cssSourceMap: sourceMapEnabled, cacheBusting: config.dev.cacheBusting, transformToRequire: { video: ['src', 'poster'], source: 'src', img: 'src', image: 'xlink:href' } } ================================================ FILE: musicPlayer/build/webpack.base.conf.js ================================================ /* * @Author: 李浩栋 * @Begin: 2019-07-30 16:42:30 * @Update: 2019-11-18 19:13:26 * @Update log: 更新日志 */ 'use strict' const path = require('path') const utils = require('./utils') const config = require('../config') const vueLoaderConfig = require('./vue-loader.conf') function resolve (dir) { return path.join(__dirname, '..', dir) } const createLintingRule = () => ({ test: /\.(js|vue)$/, loader: 'eslint-loader', enforce: 'pre', include: [resolve('src'), resolve('test')], options: { formatter: require('eslint-friendly-formatter'), emitWarning: !config.dev.showEslintErrorsInOverlay } }) module.exports = { context: path.resolve(__dirname, '../'), entry: { app: './src/main.js' }, output: { path: config.build.assetsRoot, filename: '[name].js', publicPath: process.env.NODE_ENV === 'production' ? config.build.assetsPublicPath : config.dev.assetsPublicPath }, resolve: { extensions: ['.js', '.vue', '.json'], alias: { 'vue$': 'vue/dist/vue.esm.js', '@': resolve('src'), 'styles': resolve('src/assets/styles'), 'mixins': resolve('src/assets'), 'getInfos': resolve('src/getInfos'), 'base': resolve('src/base'), 'api': resolve('src/api'), 'utils': resolve('src/assets/utils') } }, module: { rules: [ ...(config.dev.useEslint ? [createLintingRule()] : []), { test: /\.vue$/, loader: 'vue-loader', options: vueLoaderConfig }, { test: /\.js$/, loader: 'babel-loader', include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')] }, { test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000, name: utils.assetsPath('img/[name].[hash:7].[ext]') } }, { test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000, name: utils.assetsPath('media/[name].[hash:7].[ext]') } }, { test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000, name: utils.assetsPath('fonts/[name].[hash:7].[ext]') } } ] }, node: { // prevent webpack from injecting useless setImmediate polyfill because Vue // source contains it (although only uses it if it's native). setImmediate: false, // prevent webpack from injecting mocks to Node native modules // that does not make sense for the client dgram: 'empty', fs: 'empty', net: 'empty', tls: 'empty', child_process: 'empty' } } ================================================ FILE: musicPlayer/build/webpack.dev.conf.js ================================================ 'use strict' const utils = require('./utils') const webpack = require('webpack') const config = require('../config') const merge = require('webpack-merge') const path = require('path') const baseWebpackConfig = require('./webpack.base.conf') const CopyWebpackPlugin = require('copy-webpack-plugin') const HtmlWebpackPlugin = require('html-webpack-plugin') const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') const portfinder = require('portfinder') const HOST = process.env.HOST const PORT = process.env.PORT && Number(process.env.PORT) const devWebpackConfig = merge(baseWebpackConfig, { module: { rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true }) }, // cheap-module-eval-source-map is faster for development devtool: config.dev.devtool, // these devServer options should be customized in /config/index.js devServer: { clientLogLevel: 'warning', historyApiFallback: { rewrites: [ { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') }, ], }, hot: true, contentBase: false, // since we use CopyWebpackPlugin. compress: true, host: HOST || config.dev.host, port: PORT || config.dev.port, open: config.dev.autoOpenBrowser, overlay: config.dev.errorOverlay ? { warnings: false, errors: true } : false, publicPath: config.dev.assetsPublicPath, proxy: config.dev.proxyTable, quiet: true, // necessary for FriendlyErrorsPlugin watchOptions: { poll: config.dev.poll, } }, plugins: [ new webpack.DefinePlugin({ 'process.env': require('../config/dev.env') }), new webpack.HotModuleReplacementPlugin(), new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update. new webpack.NoEmitOnErrorsPlugin(), // https://github.com/ampedandwired/html-webpack-plugin new HtmlWebpackPlugin({ filename: 'index.html', template: 'index.html', inject: true }), // copy custom static assets new CopyWebpackPlugin([ { from: path.resolve(__dirname, '../static'), to: config.dev.assetsSubDirectory, ignore: ['.*'] } ]) ] }) module.exports = new Promise((resolve, reject) => { portfinder.basePort = process.env.PORT || config.dev.port portfinder.getPort((err, port) => { if (err) { reject(err) } else { // publish the new Port, necessary for e2e tests process.env.PORT = port // add port to devServer config devWebpackConfig.devServer.port = port // Add FriendlyErrorsPlugin devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({ compilationSuccessInfo: { messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`], }, onErrors: config.dev.notifyOnErrors ? utils.createNotifierCallback() : undefined })) resolve(devWebpackConfig) } }) }) ================================================ FILE: musicPlayer/build/webpack.prod.conf.js ================================================ 'use strict' const path = require('path') const utils = require('./utils') const webpack = require('webpack') const config = require('../config') const merge = require('webpack-merge') const baseWebpackConfig = require('./webpack.base.conf') const CopyWebpackPlugin = require('copy-webpack-plugin') const HtmlWebpackPlugin = require('html-webpack-plugin') const ExtractTextPlugin = require('extract-text-webpack-plugin') const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') const UglifyJsPlugin = require('uglifyjs-webpack-plugin') const env = require('../config/prod.env') const webpackConfig = merge(baseWebpackConfig, { module: { rules: utils.styleLoaders({ sourceMap: config.build.productionSourceMap, extract: true, usePostCSS: true }) }, devtool: config.build.productionSourceMap ? config.build.devtool : false, output: { path: config.build.assetsRoot, filename: utils.assetsPath('js/[name].[chunkhash].js'), chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') }, plugins: [ // http://vuejs.github.io/vue-loader/en/workflow/production.html new webpack.DefinePlugin({ 'process.env': env }), new UglifyJsPlugin({ uglifyOptions: { compress: { warnings: false } }, sourceMap: config.build.productionSourceMap, parallel: true }), // extract css into its own file new ExtractTextPlugin({ filename: utils.assetsPath('css/[name].[contenthash].css'), // Setting the following option to `false` will not extract CSS from codesplit chunks. // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack. // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110 allChunks: true, }), // Compress extracted CSS. We are using this plugin so that possible // duplicated CSS from different components can be deduped. new OptimizeCSSPlugin({ cssProcessorOptions: config.build.productionSourceMap ? { safe: true, map: { inline: false } } : { safe: true } }), // generate dist index.html with correct asset hash for caching. // you can customize output by editing /index.html // see https://github.com/ampedandwired/html-webpack-plugin new HtmlWebpackPlugin({ filename: config.build.index, template: 'index.html', inject: true, minify: { removeComments: true, collapseWhitespace: true, removeAttributeQuotes: true // more options: // https://github.com/kangax/html-minifier#options-quick-reference }, // necessary to consistently work with multiple chunks via CommonsChunkPlugin chunksSortMode: 'dependency' }), // keep module.id stable when vendor modules does not change new webpack.HashedModuleIdsPlugin(), // enable scope hoisting new webpack.optimize.ModuleConcatenationPlugin(), // split vendor js into its own file new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', minChunks (module) { // any required modules inside node_modules are extracted to vendor return ( module.resource && /\.js$/.test(module.resource) && module.resource.indexOf( path.join(__dirname, '../node_modules') ) === 0 ) } }), // extract webpack runtime and module manifest to its own file in order to // prevent vendor hash from being updated whenever app bundle is updated new webpack.optimize.CommonsChunkPlugin({ name: 'manifest', minChunks: Infinity }), // This instance extracts shared chunks from code splitted chunks and bundles them // in a separate chunk, similar to the vendor chunk // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk new webpack.optimize.CommonsChunkPlugin({ name: 'app', async: 'vendor-async', children: true, minChunks: 3 }), // copy custom static assets new CopyWebpackPlugin([ { from: path.resolve(__dirname, '../static'), to: config.build.assetsSubDirectory, ignore: ['.*'] } ]) ] }) if (config.build.productionGzip) { const CompressionWebpackPlugin = require('compression-webpack-plugin') webpackConfig.plugins.push( new CompressionWebpackPlugin({ asset: '[path].gz[query]', algorithm: 'gzip', test: new RegExp( '\\.(' + config.build.productionGzipExtensions.join('|') + ')$' ), threshold: 10240, minRatio: 0.8 }) ) } if (config.build.bundleAnalyzerReport) { const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin webpackConfig.plugins.push(new BundleAnalyzerPlugin()) } module.exports = webpackConfig ================================================ FILE: musicPlayer/config/dev.env.js ================================================ 'use strict' const merge = require('webpack-merge') const prodEnv = require('./prod.env') module.exports = merge(prodEnv, { NODE_ENV: '"development"' }) ================================================ FILE: musicPlayer/config/index.js ================================================ /* * @Author: 李浩栋 * @Begin: 2019-07-16 19:49:41 * @Update: 2019-08-18 19:16:52 * @Update log: 更新日志 */ 'use strict' // Template version: 1.3.1 // see http://vuejs-templates.github.io/webpack for documentation. const path = require('path') module.exports = { dev: { // Paths assetsSubDirectory: 'static', assetsPublicPath: '/', proxyTable: {// 输入/api 让其去访问http://localhost:3000/api '/api': { target: 'http://140.143.128.100:3000', // 设置调用的接口域名和端口号 ( 设置代理目标) changeOrigin: true, pathRewrite: { '^/api': '' // 这是一个通配符,设置完了之后每个接口都要在前面加上/api(特别注意这一点) } } }, // Various Dev Server settings host: 'localhost', // can be overwritten by process.env.HOST port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined autoOpenBrowser: false, errorOverlay: true, notifyOnErrors: true, poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- // Use Eslint Loader? // If true, your code will be linted during bundling and // linting errors and warnings will be shown in the console. useEslint: true, // If true, eslint errors and warnings will also be shown in the error overlay // in the browser. showEslintErrorsInOverlay: false, /** * Source Maps */ // https://webpack.js.org/configuration/devtool/#development devtool: 'cheap-module-eval-source-map', // If you have problems debugging vue-files in devtools, // set this to false - it *may* help // https://vue-loader.vuejs.org/en/options.html#cachebusting cacheBusting: true, cssSourceMap: true }, build: { // Template for index.html index: path.resolve(__dirname, '../dist/index.html'), // Paths assetsRoot: path.resolve(__dirname, '../dist'), assetsSubDirectory: 'static', assetsPublicPath: '/', /** * Source Maps */ productionSourceMap: true, // https://webpack.js.org/configuration/devtool/#production devtool: '#source-map', // Gzip off by default as many popular static hosts such as // Surge or Netlify already gzip all static assets for you. // Before setting to `true`, make sure to: // npm install --save-dev compression-webpack-plugin productionGzip: false, productionGzipExtensions: ['js', 'css'], // Run the build command with an extra argument to // View the bundle analyzer report after build finishes: // `npm run build --report` // Set to `true` or `false` to always turn it on or off bundleAnalyzerReport: process.env.npm_config_report } } ================================================ FILE: musicPlayer/config/prod.env.js ================================================ 'use strict' module.exports = { NODE_ENV: '"production"' } ================================================ FILE: musicPlayer/index.html ================================================ music-player

音樂的力量

网易云音乐

================================================ FILE: musicPlayer/package.json ================================================ { "name": "music-player", "version": "1.0.0", "description": "高仿网易云音乐", "author": "powerdong ", "private": true, "scripts": { "dev": "webpack-dev-server --inline --progress --host 0.0.0.0 --config build/webpack.dev.conf.js", "start": "npm run dev", "lint": "eslint --ext .js,.vue src", "build": "node build/build.js" }, "dependencies": { "axios": "^0.19.0", "core-js": "3", "fastclick": "^1.0.6", "less": "^3.9.0", "less-loader": "^5.0.0", "qs": "^6.8.0", "vant": "^2.2.10", "vue": "^2.5.2", "vue-lazyload": "^1.3.2", "vue-router": "^3.0.1", "vuex": "^3.1.1" }, "devDependencies": { "autoprefixer": "^7.1.2", "babel-core": "^6.22.1", "babel-eslint": "^8.2.1", "babel-helper-vue-jsx-merge-props": "^2.0.3", "babel-loader": "^7.1.1", "babel-plugin-component": "^1.1.1", "babel-plugin-import": "^1.12.2", "babel-plugin-syntax-jsx": "^6.18.0", "babel-plugin-transform-runtime": "^6.22.0", "babel-plugin-transform-vue-jsx": "^3.5.0", "babel-preset-env": "^1.3.2", "babel-preset-stage-2": "^6.22.0", "chalk": "^2.0.1", "copy-webpack-plugin": "^4.0.1", "css-loader": "^0.28.0", "eslint": "^4.15.0", "eslint-config-standard": "^10.2.1", "eslint-friendly-formatter": "^3.0.0", "eslint-loader": "^1.7.1", "eslint-plugin-import": "^2.7.0", "eslint-plugin-node": "^5.2.0", "eslint-plugin-promise": "^3.4.0", "eslint-plugin-standard": "^3.0.1", "eslint-plugin-vue": "^4.0.0", "extract-text-webpack-plugin": "^3.0.0", "file-loader": "^1.1.4", "friendly-errors-webpack-plugin": "^1.6.1", "html-webpack-plugin": "^2.30.1", "node-notifier": "^5.1.2", "optimize-css-assets-webpack-plugin": "^3.2.0", "ora": "^1.2.0", "portfinder": "^1.0.13", "postcss-import": "^11.0.0", "postcss-loader": "^2.0.8", "postcss-url": "^7.2.1", "rimraf": "^2.6.0", "semver": "^5.3.0", "shelljs": "^0.7.6", "url-loader": "^0.5.8", "vue-loader": "^13.3.0", "vue-style-loader": "^3.0.1", "vue-template-compiler": "^2.5.2", "webpack": "^3.6.0", "webpack-bundle-analyzer": "^2.9.0", "webpack-dev-server": "^2.9.1", "webpack-merge": "^4.1.0" }, "engines": { "node": ">= 6.0.0", "npm": ">= 3.0.0" } } ================================================ FILE: musicPlayer/src/App.vue ================================================ ================================================ FILE: musicPlayer/src/api/config.js ================================================ /* * @Author: 李浩栋 * @Begin: 2019-08-19 13:42:17 * @Update: 2019-12-03 13:37:22 * @Update log: 更新日志 */ const api = process.env.NODE_ENV === 'development' ? '/api' : '' // ===================发现页面 export const bannerSwiper = api + '/banner?type=1' // 请求发现页面轮播图 export const recSongList = api + '/top/playlist' // 推荐歌单,歌单广场 export const highquality = api + '/top/playlist/highquality' // 精品歌单 export const catlist = api + '/playlist/catlist' // 获取歌单分类 !!! export const hot = api + '/playlist/hot' // 获取热门歌单分类 !!! export const topList = api + '/toplist/detail' // 获取所有榜单内容摘要 export const idxList = api + '/top/list' // 获取排行榜 export const albumDetail = api + '/playlist/detail' // 获取歌单详情 export const recSongs = api + '/recommend/songs' // 每日推荐歌曲 export const dateRecSongList = api + '/recommend/resource' // 每日推荐歌单,发现页展示的那六个 export const newDish = api + '/top/album' // 发现页新碟 export const getDishInfo = api + '/album' // 获取专辑内容 export const newSongs = api + '/top/song' // 发现页新歌 export const personalFm = api + '/personal_fm' // 发现页私人FM // ======================播放歌曲 export const songUrl = api + '/song/url' // 获取歌曲url export const checkSong = api + '/check/music' // 查看歌曲是否可用 export const songLyric = api + '/lyric' // 获取歌词 export const heartMode = api + '/playmode/intelligence/list' // 心动模式播放 export const likeMusicList = api + '/likelist' // 喜欢歌曲列表 export const likeMusic = api + '/like' // 喜欢歌曲 // ===================登陆 export const phoneLogin = api + '/login/cellphone' // 手机号登陆 export const phoneRegistered = api + '/cellphone/existence/check' // 手机号是否被注册 export const sendVerify = api + '/captcha/sent' // 发送验证码 export const verify = api + '/captcha/verify' // 验证验证码 export const loginStatus = api + '/login/status' // 登录状态 export const logout = api + '/logout' // 退出登录 export const signIn = api + '/daily_signin' // 签到 export const register = api + '/register/cellphone' // 注册修改密码 // ===================我的页面相关 export const userRecord = api + '/user/record' // 用户播放记录 export const userInfo = api + '/user/subcount' // 用户信息 export const userDetail = api + '/user/detail' // 用户详情 export const userEvent = api + '/user/event' // 用户动态 export const playlist = api + '/user/playlist' // 用户歌单 export const userDj = api + '/user/dj' // 用户电台 申请做主播那一行 export const favoriteAlbums = api + '/album/sublist' // 获取收藏的专辑 export const favoriteArtists = api + '/artist/sublist' // 获取收藏的歌手 export const favoriteVideos = api + '/mv/sublist' // 获取收藏的视频 export const djSublist = api + '/dj/sublist' // 获取订阅的电台 // =================视频页面下相关 export const getVideoTag = api + '/video/group/list' // 获取视频标签导航 export const getVideoGroup = api + '/video/group' // 获取对应标签的视频详情 export const getVideoUrl = api + '/video/url' // 获取视频播放地址 export const getVideoDetail = api + '/video/detail' // 获取视频详情 export const getVideoRelated = api + '/related/allvideo' // 获取相关视频 export const getVideoComments = api + '/comment/video' // 获取视频评论 // ==================搜索页面相关 export const search = api + '/search' // 搜索关键词 export const defaultSearch = api + '/search/default' // 默认搜索关键词 export const suggestSearch = api + '/search/suggest' // 搜索建议 export const hotSearchList = api + '/search/hot/detail' // 热搜列表 export const singerClass = api + '/artist/list' // 歌手分类 // =================朋友页面 export const friend = api + '/event' // 获取朋友页面的动态 // =================歌单事件 export const addOrDeletePlaylist = api + '/playlist/subscribe' // 收藏/取消收藏歌单 export const addPlaylist = api + '/playlist/create' // 添加歌单 export const deletePlaylist = api + '/playlist/delete' // 删除歌单 // ================发现页面的电台页面 export const djBanner = api + '/dj/banner' // 电台页面的轮播图 export const radioRecommendations = api + '/dj/today/perfered' // 电台推荐数据 export const boutiqueRecommendations = api + '/dj/paygift' // 电台精品推荐 export const djClassification = api + '/dj/catelist' // 电台分类 export const djClassificationInfo = api + '/dj/recommend/type' // 电台分类推荐 export const djProgram = api + '/dj/program' // 电台节目 export const djDetail = api + '/dj/detail' // 电台详情 export const djPayGift = api + '/dj/paygift' // 电台付费精选 export const djSub = api + '/dj/sub' // 订阅/取消订阅电台 export const djToplist = api + '/dj/program/toplist' // 获取最热节目 export const djHotToplist = api + '/dj/toplist' // 获取电台榜 export const djProgramTopHours = api + '/dj/program/toplist/hours' // 获取节目榜24小时榜 export const djToplistHours = api + '/dj/toplist/hours' // 获取主播榜24小时榜 export const djToplistNewComers = api + '/dj/toplist/newcomer' // 获取主播榜新人榜 export const djToplistPopulars = api + '/dj/toplist/popular' // 获取主播榜最热主播 export const djToplistPays = api + '/dj/toplist/pay' // 获取电台磅付费精品榜 // ================评论页面相关 export const commentPlaylist = api + '/comment/playlist' // 获取歌单的评论 export const commentAlbum = api + '/comment/album' // 获取专辑的评论 export const commentDj = api + '/comment/dj' // 获取电台节目评论 export const commentLike = api + '/comment/like' // 给评论点赞 export const pushOrDeleteCom = api + '/comment' // 发送删除评论 export const resourceLike = api + '/resource/like' // 资源点赞 ================================================ FILE: musicPlayer/src/api/index.js ================================================ /* * @Author: 李浩栋 * @Begin: 2019-08-19 13:47:19 * @Update: 2019-12-08 12:02:19 * @Update log: 更新日志 */ import axios from 'axios' import { bannerSwiper, recSongList, highquality, recSongs, topList, dateRecSongList, newDish, phoneLogin, albumDetail, sendVerify, verify, phoneRegistered, loginStatus, userRecord, userInfo, playlist, userDj, hotSearchList, search, defaultSearch, suggestSearch, songUrl, checkSong, songLyric, idxList, addOrDeletePlaylist, addPlaylist, deletePlaylist, heartMode, favoriteAlbums, favoriteArtists, favoriteVideos, djSublist, newSongs, getDishInfo, personalFm, singerClass, logout, radioRecommendations, boutiqueRecommendations, djClassification, djClassificationInfo, djProgram, djDetail, djPayGift, djSub, djBanner, djToplist, djHotToplist, likeMusicList, likeMusic, userDetail, signIn, friend, getVideoTag, getVideoGroup, commentPlaylist, commentLike, commentAlbum, userEvent, pushOrDeleteCom, getVideoUrl, register, commentDj, getVideoDetail, getVideoRelated, getVideoComments, resourceLike, djProgramTopHours, djToplistHours, djToplistNewComers, djToplistPopulars, djToplistPays } from './config' // 请求超时时间 axios.defaults.timeout = 30000 // post请求头 axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8' /** * 以后可以利用 ES6 的解构赋值进行重构 * function personInfo({ name, age, address, gender }) { console.log(name, age, address, gender) } personInfo({ gender: 'man', address: 'changsha', name: 'william', age: 18 }) function saveInfo({ name = 'william', age = 18, address = 'changsha', gender = 'man' } = {}) { console.log(name, age, address, gender) } saveInfo() */ export default { /** * 请求发现页面首页轮播图 */ bannerSwiperFn () { return axios.get(bannerSwiper) }, /** * 调用此接口 , 可获得每日推荐歌曲 ( 需要登录 ) */ recSongsFn () { return axios.get(recSongs) }, /** * 调用此接口 , 传入歌单 id, 可 以获取对应歌单内的所有的音乐 * @param {*} id 歌单 id * @param {*} s 歌单最近的 s 个收藏者,默认5个 */ albumDetailFn (id, s = 5) { return axios.get(albumDetail, { params: { id, s } }) }, /** * 调用此接口,可获取所有榜单内容摘要 */ topListFn () { return axios.get(topList) }, /** * 请求 可获取推荐歌单 * ?limit=10&order=hot * @param {*} limit 取出数量,默认是30 * @param {*} order 分别对应最新和最热,可选值为 'new' 和 'hot' * @param {*} cat tag, 比如 " 华语 "、" 古风 " 、" 欧美 "、" 流行 ", 默认为 "全部", * :( 页数 -1)*30, 其中 30 为 limit 的值 , 默认 为 0 */ recSongListFn (limit = 30, order = 'hot', cat) { return axios.get(recSongList, { params: { limit, order, cat } }) }, /** * 获取精品歌单 * @param {*} limit 取出歌单数量 , 默认为 30 * @param {*} before 分页参数,取上一页最后一个歌单的 updateTime 获取下一页数据 * @param {*} cat cat: tag */ highqualityFn (limit = 30, before, cat) { return axios.get(highquality, { params: { limit, before, cat } }) }, /** * 调用此接口 , 传入数字 idx, 可获取不同排行榜 * @param {*} idx 排行榜 idx */ idxListFn (idx) { return axios.get(idxList, { params: { idx } }) }, /** * 可获得每日推荐歌单 ( 需要登录 ) */ dateRecSongListFn () { return axios.get(dateRecSongList) }, /** * 调用此接口 , 可获取新碟上架列表 * @param {*} limit 取出数量 , 默认为 50 * @param {*} offset 偏移数量 , 用于分页 * 如 :( 页数 -1)*50, 其中 50 为 limit 的值 , 默认 为 0 */ newDishFn (limit = 10, offset) { return axios.get(newDish, { params: { limit, offset } }) }, /** * 调用此接口 , 传入专辑 id, 可获得专辑内容 * @param {*} id 专辑id */ getDishInfoFn (id) { return axios.get(getDishInfo, { params: { id } }) }, /** * 检测手机号码是否已注册 * @param {*} phone 手机号 */ phoneRegisteredFn (phone) { return axios.get(phoneRegistered, { params: { phone } }) }, /** * 调用此接口 ,传入手机号码, 可发送验证码 * @param {number} phone 手机号 */ sendVerifyFn (phone) { return axios.get(sendVerify, { params: { phone } }) }, /** * 验证验证码 * 调用此接口 ,传入手机号码和验证码, 可校验验证码是否正确 * @param {*} phone 手机号 * @param {*} captcha 验证码 */ verifyFn (phone, captcha) { return axios.get(verify, { params: { phone, captcha } }) }, /** * 用户通过手机登录 * @param {number} phone 手机号 * @param {String} password 密码 */ phoneLoginFn (phone, password) { return axios.get(phoneLogin, { params: { phone: phone || '', password: password || '' } }) }, /** * 获取当前登录状态 */ loginStatusFn () { return axios.get(loginStatus) }, /** * 获取用户播放记录 * 登陆后调用此接口 , 传入用户 id, 可获取用户播放记录 * @param {*} uid 用户id * @param {*} type type=1 时只返回 weekData, type=0 时返回 allData */ userRecordFn (uid, type = 1) { return axios.get(userRecord, { params: { uid, type } }) }, /** * 获取用户信息 , 歌单,收藏,mv, dj 数量 * 登陆后调用此接口 , 可以获取用户信息 * artistCount: 2 我的收藏中的歌手 * code: 200 * createDjRadioCount: 0 * createdPlaylistCount: 2 创建的歌单数 * djRadioCount: 1 我的电台 * mvCount: 0 * newProgramCount: 0 * programCount: 0 * subPlaylistCount: 3 收藏的歌单数 * @param {*} timestamp 时间戳,使得每次请求的URL不同,除掉了默认的2分钟缓存 */ userInfoFn (timestamp) { return axios.get(userInfo, { params: { timestamp } }) }, /** * 登陆后调用此接口 , 传入用户 id, 可以获取用户详情 * @param {*} uid 用户id */ userDetailFn (uid) { return axios.get(userDetail, { params: { uid } }) }, /** * 登陆后调用此接口 , 传入用户 id, 可以获取用户动态 * @param {*} uid 用户 id * @param {*} limit 返回数量 , 默认为 30 * @param {*} lasttime 返回数据的 lasttime ,默认-1,传入上一次返回结果的 lasttime,将会返回下一页的数据 */ userEventFn (uid, limit = 20, lasttime) { return axios.get(userEvent, { params: { uid, limit, lasttime } }) }, /** * 调用此接口 , 传入签到类型 * @param {*} type 签到类型 , 默认 0, 其中 0 为安卓端签到 ,1 为 web/PC 签到 * 其中安卓端签到可获得 3 点经验 , web/PC 端签到可获得 2 点经验 */ signInFn (type) { return axios.get(signIn, { params: { type } }) }, /** * 调用此接口 ,传入手机号码和验证码,密码,昵称, 可注册网易云音乐账号(同时可修改密码) * @param {*} captcha 验证码 * @param {*} phone 手机号码 * @param {*} password 密码 * @param {*} nickname 昵称 */ registerFn (captcha, phone, password, nickname) { return axios.get(register, { params: { captcha, phone, password, nickname } }) }, /** * 登陆后调用此接口 , 传入用户 id, 可以获取用户歌单 * @param {*} uid 用户id * @param {*} timestamp 时间戳,使得每次请求的URL不同,除掉了默认的2分钟缓存 */ playlistFn (uid, timestamp) { return axios.get(playlist, { params: { uid, timestamp } }) }, /** * 登陆后调用此接口 , 传入用户 id, 可以获取用户电台 * @param {*} uid 用户 id */ userDjFn (uid) { return axios.get(userDj, { params: { uid } }) }, /** * 调用此接口,可获取热门搜索列表 */ hotSearchListFn () { return axios.get(hotSearchList) }, /** * 调用此接口 , 传入搜索关键词可以搜索 * 该音乐 / 专辑 / 歌手 / 歌单 / 用户 , 关键词可以多个 , 以空格隔开 * @param {*} keywords 关键词 * @param {*} limit 返回数量 , 默认为 30 * @param {*} offset 偏移数量,用于分页 默认为 0 * @param {*} type 搜索类型 默认为 1 即单曲 这里设置默认返回综合 * 1: 单曲, 10: 专辑, 100: 歌手, 1000: 歌单 * 1002: 用户, 1004: MV, 1006: 歌词, 1009: 电台, 1014: 视频, 1018:综合 */ searchFn (keywords, limit = 30, offset = 0, type = 1018) { return axios.get(search, { params: { keywords, limit, offset, type } }) }, /** * 调用此接口 , 可获取默认搜索关键词 */ defaultSearchFn () { return axios.get(defaultSearch) }, /** * 调用此接口 * 传入搜索关键词可获得搜索建议 , * 搜索结果同时包含单曲 , 歌手 , 歌单 ,mv 信息 * @param {*} keywords 关键词 * @param {*} type 默认返回移动端数据 */ suggestSearchFn (keywords, type = 'mobile') { return axios.get(suggestSearch, { params: { keywords, type } }) }, /** * 使用歌单详情接口后 , 能得到的音乐的 id, 但不能得到的音乐 url * 调用此接口 , 传入的音乐 id( 可多个 , 用逗号隔开 ) * 可以获取对应的音乐的 url( 不需要登录 ) * @param {*} id 音乐 id * @param {*} br 码率,默认设置了 999000 即最大码率,如果要 320k 则可设置为 320000,其他类推 */ songUrlFn (id, br) { return axios.get(songUrl, { params: { id, br } }) }, /** * 传入歌曲 id, 可获取音乐是否可用 * @param {*} id 歌曲 id * @param {*} br 码率,默认设置了 999000 即最大码率,如果要 320k 则可设置为 320000,其他类推 */ checkSongFn (id, br) { return axios.get(checkSong, { params: { id, br } }) }, /** * 传入音乐 id 可获得对应音乐的歌词 ( 不需要登录 ) * @param {*} id 歌曲id */ songLyricFn (id) { return axios.get(songLyric, { params: { id } }) }, /** * 传入类型和歌单 id 可收藏歌单或者取消收藏歌单 * @param {*} t 1:收藏 2:取消收藏 * @param {*} id 歌单id */ addOrDeletePlaylistFn (t, id) { return axios.get(addOrDeletePlaylist, { params: { t, id } }) }, /** * 调用此接口 , 传入歌单名字可新建歌单 * @param {*} name 歌单名 * @param {*} privacy 是否为隐私歌单 传'10'设置为隐私歌单 */ addPlaylistFn (name, privacy) { return axios.get(addPlaylist, { params: { name, privacy } }) }, /** * 调用此接口 , 传入歌单名字可新建歌单 * @param {*} id 歌单id */ deletePlaylistFn (id) { return axios.get(deletePlaylist, { params: { id } }) }, /** * 登录后调用此接口 , 可获取心动模式/智能播放列表 * @param {*} id 歌曲 id * @param {*} pid 歌单id * @param {*} sid 要开始播放的歌曲id */ heartModeFn (id, pid, sid) { return axios.get(heartMode, { params: { id, pid, sid } }) }, /** * 调用此接口 , 传入音乐 id, 可喜欢该音乐 * @param {*} id 音乐id * @param {*} like 布尔值 , 默认为 true 即喜欢 , 若传 false, 则取消喜欢 */ likeMusicFn (id, like) { return axios.get(likeMusic, { params: { id, like } }) }, /** * 调用此接口 , 传入用户 id, 可获取已喜欢音乐id列表(id数组) * @param {*} uid 用户id */ likeMusicListFn (uid) { const timestamp = +new Date() return axios.get(likeMusicList, { params: { uid, timestamp } }) }, /** * 调用此接口 , 可获得已收藏专辑列表 * @param {*} limit 取出数量 , 默认为 25 * @param {*} offset 偏移数量 , 用于分页 , 如 :( 页数 -1)*25, 其中 25 为 limit 的值 , 默认 为 0 */ favoriteAlbumsFn (limit, offset) { return axios.get(favoriteAlbums, { params: { limit, offset } }) }, /** * 调用此接口,可获取收藏的歌手列表 */ favoriteArtistsFn () { return axios.get(favoriteArtists) }, /** * 调用此接口,可收藏视频 */ favoriteVideosFn () { return axios.get(favoriteVideos) }, /** * 获取视频详情 * @param {*} id 视频id */ getVideoDetailFn (id) { return axios.get(getVideoDetail, { params: { id } }) }, /** * 获取相关视频 * @param {*} id 视频id */ getVideoRelatedFn (id) { return axios.get(getVideoRelated, { params: { id } }) }, /** * 调用此接口 , 传入音乐 id 和 limit 参数 , 可获得该 视频 的所有评论 ( 不需要登录 ) * @param {*} id 视频的 id * @param {*} limit 取出评论数量 , 默认为 20 * @param {*} offset 偏移数量 , 用于分页 , 如 :( 评论页数 -1)*20, 其中 20 为 limit 的值 * @param {*} before 分页参数,取上一页最后一项的 time 获取下一页数据(获取超过5000条评论的时候需要用到) */ getVideoCommentsFn (id, limit = 20, offset, before) { const timestamp = +new Date() return axios.get(getVideoComments, { params: { id, limit, offset, before, timestamp } }) }, /** * 登陆后调用此接口 , 可获取订阅的电台列表 */ djSublistFn (timestamp) { return axios.get(djSublist, { params: { timestamp } }) }, /** * 调用此接口 , 可获取新歌速递 * @param {*} type 地区类型 id,对应以下: * 全部:0 华语:7 欧美:96 日本:8 韩国:16 */ newSongsFn (type = 0) { return axios.get(newSongs, { params: { type } }) }, /** * 获取私人 FM * 需要登录 */ personalFmFn () { return axios.get(personalFm) }, /** * 调用此接口,可获取歌手分类列表 * @param {*} cat 歌手类型, 必选 * 入驻歌手 5001 * 华语男歌手 1001 华语女歌手 1002 华语组合/乐队 1003 * 欧美男歌手 2001 欧美女歌手 2002 欧美组合/乐队 2003 * 日本男歌手 6001 日本女歌手 6002 日本组合/乐队 6003 * 韩国男歌手 7001 韩国女歌手 7002 韩国组合/乐队 7003 * 其他男歌手 4001 其他女歌手 4002 其他组合/乐队 4003 * @param {*} limit 返回数量 , 默认为 30 * @param {*} offset 偏移数量,用于分页,默认为 0 * @param {*} initial 按首字母索引查找参数 * /artist/list?cat=1001&initial=b * 返回内容将以 name 字段开头为 b 或者拼音开头为 b 为顺序排列 */ singerClassFn (cat = 1001, limit = 30, offset = 0, initial) { return axios.get(singerClass, { params: { cat, limit, offset, initial } }) }, /** * 退出账号 */ logoutFn () { return axios.get(logout) }, /** * 调用此接口,可获取电台banner */ djBannerFn () { return axios.get(djBanner) }, /** * 获取电台页面的电台推荐数据 */ radioRecomFn () { return axios.get(radioRecommendations) }, /** * 可以获取付费精选的电台列表 * @param {*} limit 返回数量 , 默认为 30 * @param {*} offset 偏移数量, 默认为 0 */ boutiqueRecomFn (limit = 3, offset = 0) { return axios.get(boutiqueRecommendations, { params: { limit, offset } }) }, /** * 登陆后调用此接口 , 可获得电台类型 */ djClassificationFn () { return axios.get(djClassification) }, /** * 登陆后调用此接口 , 可获得推荐电台 * @param {*} type 电台类型 * 可通过/dj/catelist获取 , 对应关系为 id 对应 此接口的 type, name 对应类型意义 */ djClassificationInfoFn (type) { return axios.get(djClassificationInfo, { params: { type } }) }, /** * 登陆后调用此接口 , 传入rid, 可查看对应电台的电台节目以及对应的 id * 需要 注意的是这个接口返回的 mp3Url 已经无效 , 都为 null * 但是通过调用 /song/url 这 个接口 , 传入节目 id 仍然能获取到节目音频 , * 如 /song/url?id=478446370 获取代 码时间的一个节目的音频 * @param {*} rid 电台 的 id * @param {*} limit 返回数量 , 默认为 30 * @param {*} offset 偏移数量,用于分页 * @param {*} asc 排序方式,默认为 false (新 => 老 ) 设置 true 可改为 老 => 新 */ djProgramFn (rid, limit = 30, offset = 0, asc) { return axios.get(djProgram, { params: { rid, limit, offset, asc } }) }, /** * 登陆后调用此接口 , 传入rid, 可获得对应电台的详情介绍 * @param {*} rid 电台 的 id */ djDetailFn (rid) { return axios.get(djDetail, { params: { rid } }) }, /** * 可以获取付费精选的电台列表 , 传入 limit 和 offset 可以进行分页 * @param {*} limit 返回数量 , 默认为 30 * @param {*} offset 偏移数量,用于分页 */ djPayGiftFn (limit = 30, offset = 0) { return axios.get(djPayGift, { params: { limit, offset } }) }, /** * 登陆后调用此接口 , 传入rid, 可订阅 dj * @param {*} rid 电台 的 id * @param {*} t t=1 对应关注 t=0 对应取消关注 */ djSubFn (rid, t) { return axios.get(djSub, { params: { rid, t } }) }, /** * 登陆后调用此接口 , 可获得电台节目榜 * @param {*} limit 返回数量 , 默认为 100 * @param {*} offset 偏移数量,用于分页 */ djToplistFn (limit = 100, offset = 0) { return axios.get(djToplist, { params: { limit, offset } }) }, /** * 登陆后调用此接口 , 可获得新晋电台榜/热门电台榜 * @param {*} limit 返回数量 , 默认为 100 * @param {*} offset 偏移数量,用于分页 * @param {*} type 榜单类型, new 为新晋电台榜, hot为热门电台榜 */ djHotToplistFn (limit = 100, offset = 0, type = 'hot') { return axios.get(djHotToplist, { params: { limit, offset, type } }) }, /** * 调用此接口,可获取24小时节目榜 * @param {*} limit 返回数量 , 默认为 100 (不支持 offset) */ djProgramTopHoursFn (limit) { return axios.get(djProgramTopHours, { params: { limit } }) }, /** * 调用此接口,可获取24小时主播榜 * @param {*} limit 返回数量 , 默认为 100 (不支持 offset) */ djToplistHoursFn (limit) { return axios.get(djToplistHours, { params: { limit } }) }, /** * 说明 : 调用此接口,可获取主播新人榜 * @param {*} limit 返回数量 , 默认为 100 (不支持 offset) */ djToplistNewComersFn (limit) { return axios.get(djToplistNewComers, { params: { limit } }) }, /** * 调用此接口,可获取最热主播榜 * @param {*} limit 返回数量 , 默认为 100 (不支持 offset) */ djToplistPopularsFn (limit) { return axios.get(djToplistPopulars, { params: { limit } }) }, /** * 调用此接口,可获取付费精品电台 * @param {*} limit 返回数量 , 默认为 100 (不支持 offset) */ djToplistPaysFn (limit) { return axios.get(djToplistPays, { params: { limit } }) }, /** * 调用此接口 , 可获取各种动态 * 对应网页版网易云,朋友界面里的各种动态消息 * 如分享的视频,音乐,照片等! * @param {*} pagesize 每页数据,默认20 * @param {*} lasttime 返回数据的 lasttime ,默认-1 * 传入上一次返回结果的 lasttime,将会返回下一页的数据 */ friendFn (pagesize = 20, lasttime = -1) { return axios.get(friend, { params: { pagesize, lasttime } }) }, /** * 调用此接口 , 可获取视频标签列表 */ getVideoTagFn () { return axios.get(getVideoTag) }, /** * 调用此接口 , 传入id,可获取到相关的视频 * @param {*} id videoGroup 的 id */ getVideoGroupFn (id) { return axios.get(getVideoGroup, { params: { id } }) }, /** * 调用此接口 , 传入视频 id,可获取视频播放地址 * @param {*} id 视频 id */ getVideoUrlFn (id) { return axios.get(getVideoUrl, { params: { id } }) }, /** * 调用此接口 , 传入音乐 id 和 limit 参数 , 可获得该歌单的所有评论 ( 不需要 登录 ) * @param {*} id 歌单id * @param {*} limit 取出评论数量 , 默认为 20 * @param {*} offset 偏移数量 , 用于分页 * @param {*} before 分页参数,取上一页最后一项的 time * 获取下一页数据(获取超过5000条评论的时候需要用到) */ commentPlaylistFn (id, limit = 20, offset, before) { const timestamp = +new Date() return axios.get(commentPlaylist, { params: { id, limit, offset, before, timestamp } }) }, /** * 调用此接口 , 传入音乐 id 和 limit 参数 , 可获得该专辑的所有评论 ( 不需要 登录 ) * @param {*} id 专辑id * @param {*} limit 取出评论数量 , 默认为 20 * @param {*} offset 偏移数量 , 用于分页 * @param {*} before 分页参数,取上一页最后一项的 time * 获取下一页数据(获取超过5000条评论的时候需要用到) */ commentAlbumFn (id, limit = 20, offset, before) { const timestamp = +new Date() return axios.get(commentAlbum, { params: { id, limit, offset, before, timestamp } }) }, commentDjFn (id, limit = 20, offset, before) { const timestamp = +new Date() return axios.get(commentDj, { params: { id, limit, offset, before, timestamp } }) }, /** * 调用此接口 , 传入 type, * 资源 id, 和评论 id cid * 是否点赞参数 t 即可给对 应评论点赞 ( 需要登录 ) * @param {*} id 资源 id, 如歌曲 id,mv id * @param {*} cid 评论 id * @param {*} t 是否点赞 ,1 为点赞 ,0 为取消点赞 * @param {*} type 数字 , 资源类型 , 对应歌曲 , mv, 专辑 , 歌单 , 电台, 视频对应以下类型 * 0: 歌曲 1: mv 2: 歌单 3: 专辑 4: 电台 5: 视频 6: 动态 */ commentLikeFn (id, cid, t, type) { return axios.get(commentLike, { params: { id, cid, t, type } }) }, /** * 调用此接口,可发送评论 * @param {*} t 1: 发送评论 * @param {*} type 数字,资源类型,对应歌曲,mv,专辑,歌单,电台,视频对应以下类型 * 0: 歌曲 1: mv 2: 歌单 3: 专辑 4: 电台 5: 视频 6: 动态 * @param {*} id 对应资源 id * @param {*} content 要发送的内容 * @param {*} commentId 回复的评论id (回复评论时必填) * @param {*} threadId 如给动态发送评论,则不需要传 id,需要传动态的 threadId */ pushComFn (type, id, content, commentId, threadId) { const t = 1 const timestamp = +new Date() return axios.post(pushOrDeleteCom, { t, type, id, content, commentId, threadId, timestamp }) }, /** * 调用此接口,可删除评论 * @param {*} t 0: 删除评论 * @param {*} type 数字,资源类型,对应歌曲,mv,专辑,歌单,电台,视频对应以下类型 * 0: 歌曲 1: mv 2: 歌单 3: 专辑 4: 电台 5: 视频 6: 动态 * @param {*} id 对应资源 id * @param {*} threadId 如给动态删除评论,则不需要传 id,需要传动态的 `threadId` * @param {*} commentId 回复的评论id (回复评论时必填),删除评论时传入评论的id */ delComFn (type, id, commentId, threadId) { const t = 0 return axios.post(pushOrDeleteCom, { t, type, id, threadId, commentId }) }, /** * 调用此接口 , 可对 MV,电台,视频点赞 * @param {*} type 资源类型,对应以下类型 1: mv 4: 电台 5: 视频 6: 动态 * @param {*} id 资源 id */ resourceLikeInFn (type, id) { const t = 1 return axios.get(resourceLike, { params: { t, type, id } }) }, /** * 调用此接口 , 可对 MV,电台,视频取消点赞 * @param {*} type 资源类型,对应以下类型 1: mv 4: 电台 5: 视频 6: 动态 * @param {*} id 资源 id */ resourceLikeOutFn (type, id) { const t = 0 return axios.get(resourceLike, { params: { t, type, id } }) } } ================================================ FILE: musicPlayer/src/assets/Bus.js ================================================ /* * @Author: 李浩栋 * @Begin: 2019-08-29 10:48:10 * @Update: 2019-08-29 10:50:16 * @Update log: 更新日志 */ import Vue from 'vue' export default new Vue() ================================================ FILE: musicPlayer/src/assets/Mixins.js ================================================ /* * @Author: 李浩栋 * @Begin: 2019-09-21 15:14:40 * @Update: 2019-11-24 12:59:18 * @Update log: 更新日志 */ import { mapGetters } from 'vuex' import api from 'api' import isInSport from 'utils/scrollStopVideo' /** * 这里包含对于不同模式下的icon展示 * 对于更改mode * 对播放列表的展示隐藏 */ export const audio = { props: { mode: { type: Number } }, computed: { modeClass: function () { switch (this.mode) { case 0: // 列表循环 return 'audioxunhuan' case 1: // 单曲循环 return 'audiosingle-loop' case 2: // 随机播放 return 'audiosuiji' } } }, methods: { changeMode () { this.$emit('changeMode') }, showAudioList () { this.$emit('showAudioList') } } } let timer = null export const videoPage = { data () { return { data: [], load: true, isLogin: +localStorage.getItem('loginState') || 0 } }, created () { this._getVideoDetail(this.$route.params.id) }, methods: { _getVideoDetail (id) { api.getVideoGroupFn(id) .then(res => { const { data } = res if (data.code === 200) { this.data = data.datas this.load = false } }) .catch(err => { if (err) { this.load = false } }) }, hideVideo () { const self = this if (timer) { clearTimeout(timer) timer = null } timer = setTimeout(() => { this.stopVideo(self) }, 300) }, stopVideo (self) { // 父容器 const wra = self.$el // video集合 const videos = [...wra.querySelectorAll('.video-item')] // 获取到当前正在播放的video const ele = videos[this.index] // 查看当前播放的video是否已经出去!!! if (!isInSport(ele, wra)) { // 出去的话调用方法,停止视频播放 self.$refs.public.stopVideoTag() } }, getIndex (index) { this.index = index } } } /** * 当页面显示了播放组件,页面整体需要设置paddingBottom * 大小为迷你播放器的高度 */ export const paddingBottom = { computed: { ...mapGetters({ miniAudio: 'FULL_SCREEN' }) }, mounted () { console.log(this.miniAudio) if (!this.miniAudio) { this.setPagePb() } }, watch: { /** * 监听当前是否播放 */ miniAudio: function (val) { if (!val) { this.setPagePb() } } }, methods: { setPagePb () { this.$refs.wrapper.style.paddingBottom = '1.3rem' } } } ================================================ FILE: musicPlayer/src/assets/styles/border.css ================================================ @charset "utf-8"; .border, .border-top, .border-right, .border-bottom, .border-left, .border-topbottom, .border-rightleft, .border-topleft, .border-rightbottom, .border-topright, .border-bottomleft { position: relative; } .border::before, .border-top::before, .border-right::before, .border-bottom::before, .border-left::before, .border-topbottom::before, .border-topbottom::after, .border-rightleft::before, .border-rightleft::after, .border-topleft::before, .border-topleft::after, .border-rightbottom::before, .border-rightbottom::after, .border-topright::before, .border-topright::after, .border-bottomleft::before, .border-bottomleft::after { content: "\0020"; overflow: hidden; position: absolute; } /* border * 因,边框是由伪元素区域遮盖在父级 * 故,子级若有交互,需要对子级设置 * 定位 及 z轴 */ .border::before { box-sizing: border-box; top: 0; left: 0; height: 100%; width: 100%; border: 1px solid #eaeaea; transform-origin: 0 0; } .border-top::before, .border-bottom::before, .border-topbottom::before, .border-topbottom::after, .border-topleft::before, .border-rightbottom::after, .border-topright::before, .border-bottomleft::before { left: 0; width: 100%; height: 1px; } .border-right::before, .border-left::before, .border-rightleft::before, .border-rightleft::after, .border-topleft::after, .border-rightbottom::before, .border-topright::after, .border-bottomleft::after { top: 0; width: 1px; height: 100%; } .border-top::before, .border-topbottom::before, .border-topleft::before, .border-topright::before { border-top: 1px solid #eaeaea; transform-origin: 0 0; } .border-right::before, .border-rightbottom::before, .border-rightleft::before, .border-topright::after { border-right: 1px solid #eaeaea; transform-origin: 100% 0; } .border-bottom::before, .border-topbottom::after, .border-rightbottom::after, .border-bottomleft::before { border-bottom: 1px solid #eaeaea; transform-origin: 0 100%; } .border-left::before, .border-topleft::after, .border-rightleft::after, .border-bottomleft::after { border-left: 1px solid #eaeaea; transform-origin: 0 0; } .border-top::before, .border-topbottom::before, .border-topleft::before, .border-topright::before { top: 0; } .border-right::before, .border-rightleft::after, .border-rightbottom::before, .border-topright::after { right: 0; } .border-bottom::before, .border-topbottom::after, .border-rightbottom::after, .border-bottomleft::after { bottom: 0; } .border-left::before, .border-rightleft::before, .border-topleft::after, .border-bottomleft::before { left: 0; } @media (max--moz-device-pixel-ratio: 1.49), (-webkit-max-device-pixel-ratio: 1.49), (max-device-pixel-ratio: 1.49), (max-resolution: 143dpi), (max-resolution: 1.49dppx) { /* 默认值,无需重置 */ } @media (min--moz-device-pixel-ratio: 1.5) and (max--moz-device-pixel-ratio: 2.49), (-webkit-min-device-pixel-ratio: 1.5) and (-webkit-max-device-pixel-ratio: 2.49), (min-device-pixel-ratio: 1.5) and (max-device-pixel-ratio: 2.49), (min-resolution: 144dpi) and (max-resolution: 239dpi), (min-resolution: 1.5dppx) and (max-resolution: 2.49dppx) { .border::before { width: 200%; height: 200%; transform: scale(.5); } .border-top::before, .border-bottom::before, .border-topbottom::before, .border-topbottom::after, .border-topleft::before, .border-rightbottom::after, .border-topright::before, .border-bottomleft::before { transform: scaleY(.5); } .border-right::before, .border-left::before, .border-rightleft::before, .border-rightleft::after, .border-topleft::after, .border-rightbottom::before, .border-topright::after, .border-bottomleft::after { transform: scaleX(.5); } } @media (min--moz-device-pixel-ratio: 2.5), (-webkit-min-device-pixel-ratio: 2.5), (min-device-pixel-ratio: 2.5), (min-resolution: 240dpi), (min-resolution: 2.5dppx) { .border::before { width: 300%; height: 300%; transform: scale(.33333); } .border-top::before, .border-bottom::before, .border-topbottom::before, .border-topbottom::after, .border-topleft::before, .border-rightbottom::after, .border-topright::before, .border-bottomleft::before { transform: scaleY(.33333); } .border-right::before, .border-left::before, .border-rightleft::before, .border-rightleft::after, .border-topleft::after, .border-rightbottom::before, .border-topright::after, .border-bottomleft::after { transform: scaleX(.33333); } } ================================================ FILE: musicPlayer/src/assets/styles/global.less ================================================ // 主题色 @bgcolor: #dd001b; // 图片圆角 @imgBorderRadius: 0.11rem; // 图标宽度 @iconWidth: 1rem; // 图标下方文本大小 @iconText: 0.24rem; // 定义盒子模型 两边对齐布局 .flex-between { display: flex; justify-content: space-between; } .titleFixed { position: sticky; width: 100vw; top: 0; background-color: #fff; z-index: 99; } // 定义盒子模型 分散布局 .flex-around { display: flex; justify-content: space-around; } .flex-center { display: flex; justify-content: center; align-items: center; } // 两行文本溢出打点 ... .twoLinesEllipsis { overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; overflow: hidden; /*! autoprefixer: off */ -webkit-box-orient: vertical; } // 单行文字打点 .ellipsis { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } // 小标签 .smallTag { box-sizing: border-box; padding: 0.1rem 0.1rem 0.1rem 0.13rem; display: flex; align-items: center; // justify-content: center; font-size: 0.2rem; border-radius: 1rem; letter-spacing: 0.05rem; text-align: center; border: 1px solid #ccc; } .tag-group { box-sizing: border-box; padding: 0.1rem 0.2rem 0.1rem 0.2rem; font-size: 0.2rem; border-radius: 0.2rem; background-color: #eee; margin-right: 0.1rem; } // 遮罩层 .mask { position: fixed; z-index: 10; left: 0; top: 0; width: 100vw; height: 100vh; background: rgba(0, 0, 0, 0.7); } // 灰色的数字样式 .num { font-size: 0.24rem; color: #999; } // 导航栏的访问样式 .ac { color: #000; font-size: 0.28rem; } // a标签覆盖整个区域 .cover { position: absolute; top: 0; left: 0; bottom: 0; right: 0; width: 90%; height: 100%; } // 页面灰色分割线样式 .split { width: 100%; height: 0.13rem; background-color: #eee; margin: 0.3rem 0; } // 页面有的左右padding .pd13 { box-sizing: border-box; padding: 0 0.13rem; } // 页面有的左右padding .pd23 { box-sizing: border-box; padding: 0 0.23rem; } .pb1 { box-sizing: border-box; padding-bottom: 1rem; } // 点击有波纹效果 .ripple { position: relative; overflow: hidden; user-select: none; &:after { position: absolute; content: ''; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; //设置径向渐变 background-image: radial-gradient(circle, #666 10%, transparent 10.01%); background-repeat: no-repeat; background-position: 50%; transform: scale(10, 10); opacity: 0; transition: transform .5s, opacity .6s; } &:active:after { transform: scale(0, 0); opacity: .3; //设置初始状态 transition: 0s; } } ================================================ FILE: musicPlayer/src/assets/styles/reset.css ================================================ @charset "utf-8"; html { background-color: #fff; color: #000 } body, ul, ol, dl, dd, h1, h2, h3, h4, h5, h6, figure, form, fieldset, legend, input, textarea, button, p, blockquote, th, td, pre, xmp { margin: 0; padding: 0 } body, input, textarea, button, select, pre, xmp, tt, code, kbd, samp { line-height: 1.5; font-family: tahoma, arial, "Hiragino Sans GB", simsun, sans-serif } h1, h2, h3, h4, h5, h6, small, big, input, textarea, button, select { font-size: 100% } h1, h2, h3, h4, h5, h6 { font-family: tahoma, arial, "Hiragino Sans GB", "微软雅黑", simsun, sans-serif } h1, h2, h3, h4, h5, h6, b, strong { font-weight: normal } address, cite, dfn, em, i, optgroup, var { font-style: normal } table { border-collapse: collapse; border-spacing: 0; text-align: left } caption, th { text-align: inherit } ul, ol, menu { list-style: none } fieldset, img { border: 0 } img, object, input, textarea, button, select { vertical-align: middle } article, aside, footer, header, section, nav, figure, figcaption, hgroup, details, menu { display: block } audio, canvas, video { display: inline-block; *display: inline; *zoom: 1 } blockquote:before, blockquote:after, q:before, q:after { content: "\0020" } textarea { overflow: auto; resize: vertical } input, textarea, button, select, a { outline: 0 none; border: none; } button::-moz-focus-inner, input::-moz-focus-inner { padding: 0; border: 0 } mark { background-color: transparent } a, ins, s, u, del { text-decoration: none } sup, sub { vertical-align: baseline } html { height: 100%; font-size: 14vw; -webkit-tap-highlight-color: transparent; } body { font-family: Arial, "Microsoft Yahei", "Helvetica Neue", Helvetica, sans-serif; color: #333; font-size: .28em; line-height: 1; -webkit-text-size-adjust: none; } hr { height: .02rem; margin: .1rem 0; border: medium none; border-top: .02rem solid #cacaca; } a { color: #25a4bb; text-decoration: none; } #audio_pb1 { box-sizing: border-box ; padding-bottom: 1rem; } ================================================ FILE: musicPlayer/src/assets/utils/cookie.js ================================================ /* * @Author: Lambda * @Begin: 2019-10-24 11:00:35 * @Update: 2019-10-24 11:03:02 * @Update log: 更新日志 */ export const getCookie = _name => { let name = _name + '=' let Cookies = document.cookie.split(';') for (let i = 0; i < Cookies.length; i++) { let Cookie = Cookies[i] while (Cookie.charAt(0) === '') { Cookie = Cookie.substring(1) } if (Cookie.indexOf(name) !== -1) { return Cookie.substring(name.length, Cookie.length) } } return '' } export const setCookie = (name, value, expires, path, domain, secure) => { let cookieText = encodeURIComponent(name) + '=' + encodeURIComponent(value) if (expires instanceof Date) { cookieText += '; expires=' + expires.toGMTString() } if (path) { cookieText += '; path=' + path } if (domain) { cookieText += '; domain=' + domain } if (secure) { cookieText += '; secure' } document.cookie = cookieText } ================================================ FILE: musicPlayer/src/assets/utils/filters.js ================================================ /* * @Author: 李浩栋 * @Begin: 2019-10-14 14:08:38 * @Update: 2019-12-10 13:40:19 * @Update log: 更新日志 */ export const filterSetPlayCount = value => { if (!value) return '' if (value > 10000) { value = parseInt(value / 10000) + '万' } else if (value > 100000000) { value = (value / 100000000).toFixed(1) + '亿' } return value } /** * 将毫秒转换为 分钟:秒数 的形式 */ export const filterSetTime = value => { if (!value) return '' let min = parseInt(value / (1000 * 60)) if (min < 10) { min = '0' + min } let sec = parseInt(value % (1000 * 60) / 1000) if (sec < 10) { sec = '0' + sec } value = `${min}:${sec}` return value } /** * 将毫秒转换为 年.月.日 */ export const filterSetYear = (value, splitY = '.', splitM = '.', splitD = '') => { const oDate = new Date(value) const oYear = oDate.getFullYear() const oMonth = oDate.getMonth() + 1 const oDay = oDate.getDate() value = `${oYear}${splitY}${oMonth}${splitM}${oDay}${splitD}` return value } /** * 将毫秒设置为 月-日 格式 */ export const filterSetMonth = (value, splitM = '-', splitD = '') => { const oDate = new Date(value) let oMonth = oDate.getMonth() + 1 let oDay = oDate.getDate() if (oMonth < 10) { oMonth = '0' + oMonth } if (oDay < 10) { oDay = '0' + oDay } value = `${oMonth}${splitM}${oDay}${splitD}` return value } export const filterAge = time => { if (!time) { // 这里是因为默认值为0的话会返回1970 // 当传入默认值退出 return } let year = new Date(time).getFullYear() const nowYear = new Date().getFullYear() let age = '' // 存下从1950年到现在时间每5年一个间隔的数值 let ages = [] for (let i = 1950; i < nowYear; i += 5) { ages.push(i) } // 这里不能使用 forEach 因为forEach无法跳出循环!!! for (let i = 0; i < ages.length; i++) { const ele = ages[i] if (year <= ele + 5) { // 找到第一个满足条件的年份,拆分成数组,截取最后两位,组合返回 age = ele.toString().split('').splice(-2).join('') break } } return age } export const filterJson = json => { return JSON.parse(json.toString()) } ================================================ FILE: musicPlayer/src/assets/utils/getAstro.js ================================================ /* * @Author: Lambda * @Begin: 2019-10-28 12:05:42 * @Update: 2019-10-28 12:06:27 * @Update log: 更新日志 */ export const getAstro = (m, d) => { return '魔羯水瓶双鱼牡羊金牛双子巨蟹狮子处女天秤天蝎射手魔羯'.substr(m * 2 - (d < '102223444433'.charAt(m - 1) - -19) * 2, 2) } ================================================ FILE: musicPlayer/src/assets/utils/getPhone.js ================================================ /* * @Author: 李浩栋 * @Begin: 2019-08-26 13:35:48 * @Update: 2019-08-26 13:47:13 * @Update log: 更新日志 */ export function getPhone () { // 创建一个正则表达式 let reg = new RegExp(/\d*$/) // window.location.hash 返回从 “#” 开始的 url // 返回一个数组(未匹配到则返回 null) let phone = reg.exec(window.location.hash)[0] return phone } ================================================ FILE: musicPlayer/src/assets/utils/getRandomArrayElements.js ================================================ /* * @Author: 李浩栋 * @Begin: 2019-10-11 13:17:17 * @Update: 2019-10-11 13:18:07 * @Update log: 更新日志 */ /** * 随机取出数组中的几项 */ export const getRandomArrayElements = (arr, count) => { // eslint-disable-next-line one-var let shuffled = arr.slice(0), // 克隆一个数组,为了不影响外边的数据 i = arr.length, min = i - count, temp, index // 存下来数组信息 数组的长度 // 通过改变数组项的位置 输出后边的几位 while (--i > min) { // 随机生成出一个索引 index = Math.floor((i + 1) * Math.random()) // 将随机索引项暂存 // 将数组后边的项与随机项调换 temp = shuffled[index] shuffled[index] = shuffled[i] shuffled[i] = temp } return shuffled.slice(min) } ================================================ FILE: musicPlayer/src/assets/utils/modalScroll.js ================================================ /* * @Author: 李浩栋 * @Begin: 2019-07-27 17:08:42 * @Update: 2019-08-10 16:42:32 * @Update log: 更新日志 */ // 解决遮罩层滚动穿透问题,分别在遮罩层弹出后和关闭前调用 let _scrollTop class ModalHelper { // popup 显示时调用 static afterOpen () { _scrollTop = document.scrollingElement.scrollTop document.body.style.position = 'fixed' document.body.style.top = -_scrollTop + 'px' document.body.style.left = 0 document.body.style.bottom = 0 document.body.style.right = 0 } // popup 关闭时调用 static beforeClose () { document.body.style.position = '' document.body.style.top = '' document.body.style.left = '' document.body.style.right = '' document.body.style.bottom = '' document.scrollingElement.scrollTop = _scrollTop } } export default ModalHelper ================================================ FILE: musicPlayer/src/assets/utils/scrollStopVideo.js ================================================ /* * @Author: Lambda * @Begin: 2019-11-19 12:37:10 * @Update: 2019-11-19 13:48:22 * @Update log: 更新日志 */ // 判断一个元素是否在视窗内 function isInSport (ele, wra) { // 判断该图片是否能够加载,判断图片是否在可视区域内 const wraHeight = wra.clientHeight const rect = ele.getBoundingClientRect() // 如果超出视窗返回false if (rect.bottom <= (wraHeight + 100) && rect.bottom >= (wraHeight / 2)) { return true } if (rect.top <= (wraHeight + 100) && rect.top >= 0) { return true } return false } export default isInSport ================================================ FILE: musicPlayer/src/assets/utils/setKeyWords.js ================================================ /* * @Author: Lambda * @Begin: 2019-11-01 13:07:59 * @Update: 2019-11-04 13:40:35 * @Update log: 更新日志 */ /** * 传入关键字和内容,将内容中含有关键字的部分添加对应的高亮样式 * @param {*} keyword * @param {*} val */ export const filterSetKeyWords = (keyword, val, property) => { let results = [] const _val = val _val.map((item, index) => { if (keyword && keyword.length > 0) { // 匹配关键字正则 let replaceReg = new RegExp(keyword, 'g') // 高亮替换v-html值 let replaceString = `${keyword}` _val[index][property] = item[property].replace( replaceReg, replaceString ) } }) results = _val return results } ================================================ FILE: musicPlayer/src/base/albumPage/index.vue ================================================ ================================================ FILE: musicPlayer/src/base/albumPage/index2.vue ================================================ ================================================ FILE: musicPlayer/src/base/alert.vue ================================================ ================================================ FILE: musicPlayer/src/base/audioAllTitle.vue ================================================ ================================================ FILE: musicPlayer/src/base/button.vue ================================================ ================================================ FILE: musicPlayer/src/base/circleLoading.vue ================================================ ================================================ FILE: musicPlayer/src/base/comments.vue ================================================ ================================================ FILE: musicPlayer/src/base/djDetailPage/components/changeNav.vue ================================================ ================================================ FILE: musicPlayer/src/base/djDetailPage/index.vue ================================================ ================================================ FILE: musicPlayer/src/base/djDetailPage/index2.vue ================================================ ================================================ FILE: musicPlayer/src/base/djSublistCard.vue ================================================ ================================================ FILE: musicPlayer/src/base/generalNav.vue ================================================ ================================================ FILE: musicPlayer/src/base/icon.vue ================================================ ================================================ FILE: musicPlayer/src/base/idxCard.vue ================================================ ================================================ FILE: musicPlayer/src/base/imgCard.vue ================================================ ================================================ FILE: musicPlayer/src/base/interchangeable.vue ================================================ ================================================ FILE: musicPlayer/src/base/loading.vue ================================================ ================================================ FILE: musicPlayer/src/base/loginPageIsShow.vue ================================================ ================================================ FILE: musicPlayer/src/base/pageErrorInfo.vue ================================================ ================================================ FILE: musicPlayer/src/base/pageLoading.vue ================================================ ================================================ FILE: musicPlayer/src/base/searchInput.vue ================================================ ================================================ FILE: musicPlayer/src/base/shouldLogin.vue ================================================ ================================================ FILE: musicPlayer/src/base/slider.vue ================================================ ================================================ FILE: musicPlayer/src/base/sliderNav.vue ================================================ ================================================ FILE: musicPlayer/src/base/song.vue ================================================ ================================================ FILE: musicPlayer/src/base/songListPage/index.vue ================================================ ================================================ FILE: musicPlayer/src/base/titleFooter.vue ================================================ ================================================ FILE: musicPlayer/src/components/detailPage/index.vue ================================================ ================================================ FILE: musicPlayer/src/components/top-tip/index.vue ================================================ ================================================ FILE: musicPlayer/src/getInfos/getData.js ================================================ /* * @Author: 李浩栋 * @Begin: 2019-07-30 16:42:30 * @Update: 2019-07-30 16:42:30 * @Update log: 更新日志 */ import Icons from './icons' /** * 获取我的页面上边的图标 */ export const homeIcons = () => { return Icons.homeIcons } /** * 获取我的页面列表图标 */ export const homeList = () => { return Icons.homeList } /** * 获取发现页面上边的图标 */ export const findIcons = () => { return Icons.findIcons } /** * 获取登陆页面上边的图标 */ export const loginIcons = () => { return Icons.loginIcons } /** * 获取登陆列表上边的图标 */ export const loginIconsTop = () => { return Icons.loginIconsTop } /** * 获取登陆列表下边的图标 */ export const loginIconsBottom = () => { return Icons.loginIconsBottom } /** * 获取电台页面图标数据 */ export const djIcons = () => { return Icons.djIcons } ================================================ FILE: musicPlayer/src/getInfos/icons.js ================================================ /* * @Author: Lambda * @Begin: 2019-07-30 16:42:30 * @Update: 2019-10-18 11:25:41 * @Update log: 更新日志 */ let homeIcons = [{ text: '私藏推荐', icon: 'home iconxindian' }, { text: '私人FM', icon: 'home iconshouyinji' }, { text: 'Sati空间', icon: 'home iconyueliang' }, { text: '最新电音', icon: 'home iconduodian' }, { text: '因乐交友', icon: 'home iconjiaoyou' }, { text: '亲子频道', icon: 'home iconertong' }, { text: '古典专区', icon: 'home icongangqin' }, { text: '跑步FM', icon: 'home iconorder-received' }, { text: '小冰电台', icon: 'home iconbingjiling' }, { text: '爵士电台', icon: 'home iconyandou' }, { text: '驾驶模式', icon: 'home iconqiche' }, { text: '编辑', icon: 'home icontoggle' }] let findIcons = [{ text: '每日推荐', icon: 'find rili', linkTo: 'dateRecommend' }, { text: '歌单', icon: 'find gedan', linkTo: 'recommend' }, { text: '排行榜', icon: 'find paixingbang', linkTo: 'idx' }, { text: '电台', icon: 'find diantai', linkTo: 'dj' }, { text: '私人FM', icon: 'find shouyin', linkTo: 'personalFm' }] let djIcons = [{ text: '电台分类', icon: 'dj dj-caidan1', linkTo: 'classification' }, { text: '电台排行', icon: 'dj dj-paixing', linkTo: 'ranking' }, { text: '付费精品', icon: 'dj dj-gerenzhongxin_wodeguizu', linkTo: 'pay_fine' }, { text: '主播学院', icon: 'dj dj-shucopy', linkTo: 'anchor_college' }] let homeList = [{ icon: 'iconyinyue', text: '本地音乐', num: 0 }, { icon: 'iconzuijinbofang', text: '最近播放', num: 0 }, { icon: 'iconxiazai', text: '下载管理', num: 0 }, { icon: 'icondiantai', text: '我的电台', num: 0 }, { icon: 'iconicon-31', text: '我的收藏', num: 0 }] let loginIcons = [{ icon: 'login iconwodexiaoxi', text: '我的消息' }, { icon: 'login iconyonghu', text: '我的好友' }, { icon: 'login iconpifu', text: '个性皮肤' }, { icon: 'login icontinggeshiqu40x40', text: '听歌识曲' }] let loginIconsTop = [{ icon: 'iconhuopiaotongxing', text: '演出' }, { icon: 'icongouwuche', text: '商城' }, { icon: 'icondibiao', text: '附近的人' }, { icon: 'iconicon--', text: '口袋铃声' }, { icon: 'icondingdan', text: '我的订单' }] let loginIconsBottom = [{ icon: 'iconicon--2', text: '定时停止播放' }, { icon: 'iconsaoyisao', text: '扫一扫' }, { icon: 'iconicon--1', text: '音乐闹钟' }, { icon: 'iconhezi501', text: '在线听歌免流量' }, { icon: 'iconyouxi', text: '游戏推荐' }, { icon: 'iconCoupon', text: '优惠券' }, { icon: 'iconmaikefeng', text: '我要直播' }] export default { homeIcons, findIcons, homeList, loginIcons, loginIconsTop, loginIconsBottom, djIcons } ================================================ FILE: musicPlayer/src/main.js ================================================ /* * @Author: Lambda * @Begin: 2019-08-30 19:47:55 * @Update: 2020-03-13 22:29:57 * @Update log: 更新日志 */ // The Vue build version to load with the `import` command // (runtime-only or standalone) has been set in webpack.base.conf with an alias. import Vue from 'vue' import App from './App' import router from './router' import store from './store' import fastclick from 'fastclick' import VueLazyload from 'vue-lazyload' import topTip from '@/components/top-tip' import { Search, ActionSheet, Swipe, SwipeItem, Button, Checkbox, CheckboxGroup, PasswordInput, NumberKeyboard, PullRefresh } from 'vant' import 'styles/reset.css' import 'styles/border.css' fastclick.attach(document.body) // import "" Vue.use(Search) Vue.use(Button) Vue.use(ActionSheet) Vue.use(PullRefresh) Vue.use(Swipe).use(SwipeItem) Vue.use(Checkbox).use(CheckboxGroup) Vue.use(PasswordInput).use(NumberKeyboard) Vue.config.productionTip = false Vue.use(VueLazyload, { preLoad: 1.3, error: './assets/load.gif', loading: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAiMAAAIjCAMAAADm9OuDAAAA/FBMVEX///8CAgL8/PwHBwf5+fn39/cKCgr7+/sODg709PQSEhIWFhbw8PAaGhru7u7q6uoeHh7m5uYiIiIpKSkmJiZYWFjj4+Pg4OAtLS1cXFxUVFQwMDDd3d3Q0NAzMzM2NjY7Ozva2tpgYGBAQEDX19dDQ0NGRkZOTk5LS0vU1NRRUVHKysp9fX2BgYE4ODhnZ2ehoaHHx8fExMTNzc26urqampo9PT21tbVkZGRISEiLi4uXl5d1dXW9vb2oqKilpaWUlJSFhYVtbW1qamqOjo6IiIienp6RkZFwcHB6enq/v793d3fBwcG3t7ewsLCurq6ysrKsrKxycnKrq6uIVM+mAACzH0lEQVR42uzJsQkAIBAEQbEDC7AOm3i+/3IUQYxMjWaSO9gCW+sxMkf0VgAAAAAAAOCzurzSnfOY5Jh5T9RAGMbL0/eZt287PXbBFmUlLKwnuiou8eDwQI3iEfj+X8a2i4JXJLgmBX7JTLL/bDrP/Oad4x9Am7aesxQBNK3VRAOIApAaQIXtcABVpQBQXPq4/nnQUKEwOFcAApLms7xXVWU1GAyHw9FoNBwOBlVZVmWeeU+aKBWqwAwdUaXwckkSQIDgPDkitKrsVaNHO09evLz/+u7a0kJRpElLWhT9xfHt1e23m7tP9tfvVL0yNzOdcVxyqRxBIATRYUfQNHyzI8urxzsHH6+tFGnkwrmasO5/S+iipD++dm93Z33Qyz1PTixw1o9RAfVyORIEVPWgdnaPlRpCmfXKO49ebN/o124ce/GrI81P545FCWtXipXVrY3rVe7NSANUADnr58CLSGfjmjFoO4p6AaWra0PI2o/Bo3d7y7GLotaIade44lySxHEyJS7SOIqiuO7cCZHCGtfvx8mz5wfrw0FpAlXRM241AmOH45o5qFEG9MZAJOgi4nuDjc3bhZtzUTPdjR+usaLfn18er926uvfh/svDg8n+xsannU8Hm6/e761eu7kyXpovkqSRJWwlKdKj7ae48Xx/VOVecKa8FIR4M2g345oNOA5HSVFQ0UANugZqQa4/vJG6uUaNpmvOGOnC0tqDzcmdMvMi+HYRFhw9mZABlPR5+fjLy6drywtFEsXzyVFRaZWJFz9sDHNPfIsDf6u2LRCqgIIGXlxHYPa9TiqhEApFpFu1UwRCZuX628U0nGvtcC6K42L+7r3DQWZ2ypuFqFheTV69vjtfNDXl+MzikrU3j0e5eRPLgD/GxeO4QCiUQnYtrtkCE4CcLjoRUAMhoB278UOyslzfKuoCUre2fKT9le390gsVosAp5wiqECMsG+zujRfS2LmpKK79zweTwTA3g/41rgBQggIQ0AutiICeNRJAxQLSWHdoC2p39hpk+WhrXM+maytInPRXnlcZxQiYCoDTvq+3gjSY9xl9dXhlsYhd2HjnavUil67sDns5g9/zY1wQM0KIC/3AD9Ijmw5aBIEaxABFl4YM602uxFNBojBJF9/v5yIKNBZDA0Cgp14U1OnTaCACQIS9z9vLRRy1+rUXpGj8cJixrQw/50D18MdxgaqGqaLdyWu2AKzxZqZNZEYV0y7trVClrzaXmg2hPVymy/fXvXC260SsPFydTyJ3dBJ2YXplUlUZVQDlybjEJDMjoQQpQlF2J67/A2FKMwKEmBBC0c6sCahVo3upayYvDONk8cMgU8FsJwWAmWg23FprzrGtJi6sH2QnZc6fshBQSKOAgAmlU3F9ZeZK2NpGYmgqSyPLntgOxAlOoIVwFgpsSikQWKAFeixt9/j/P2YzmjhpC98e3SRetcV8dThGfiM9PWkyI0NAay0oRlgQyZWK1RpMfE5rK4dREKgKEmXFkQUAIeQp/0AiYrFEtPzlLKvHgQaThSxYuNtIieBr4Z3ZWsueJzt3QeXdT5g5RJkQmInQLRY0hFZZ0UBpnl5uHEYjFSQ+OG5p1UkwbYgotXD/1BfpSbEQGlfmZAtBEG3+2hL+WoSmkbuA9K/8b9w1QwPEke+ZGAkqipxaR2FpZIXEDrOMShdhVM9/tnP7taD9+1k9DBxIQmPC5mDNEgoxjJQa8u4CRCau0F2AYyPScDcr6gwu3/gdgVSrSCwEDWiTthhbShq3TWOeKE/tPRea43YVouXrpciY+qKq/VH+MkmYx+5iIARhJqisXaEAmeABGGmm1Bk1zAISMEJFi2Yi+LYnc/Sh8yx2LbrsYk0I51k8ICOj7F0s1LP4SRA6RebsJJWRa1jdxV67q0hCYiJ8EFZoZhvcwQOoph8ZCCoRg4AIYJJjWdqDXl7kO3WzcLGGDDCFUgb+xRMAZCZuXW7FppwoeHbV8OoqsY+6QAjE1bgLid3A4JiT+PUBzSbTIAkAEhNTVcNnAOMgQgiIIq2Tm6LoFEXv9OMR0T9DOoJbCBMhMgohCZE4MTVNnKVJKkJEep8ZWMcBRGp/kS8QZa+Iw8Ar9UH3XZpYSZC9u7hG1VARRci3VgJmFh0UYK5hTbUgZoKKIuc4jwCJJWl82n69nQ/t8G5DSPifpQcgDwxptNsbe1/O7w/z3a3VZ0+73aWhPX262tna2i1uXhx/XlluNVIrIsrRkfgvwCuydrcUBkNzmsnSsdPVZCSdVZVosAz2DuVIalDW5tMGiYYndIKIY6u1qrgIlCt060Xb2I+DIIgPehf9VNAm8E+2lhVKG8t75/unr12fLhi3c0sLFmK9aFCIs6Wtw/3LlVbD0l9kcRUVRRqXq5HxvCTontjE1rhad5XEaCzfwZixzmBCQRtTNUIkqGpXKPRLToIs/R0vu9f3G161ob9PVUn7ZFAcNEOnopdAUAsmEIn0+s1Eo6kvbv7xrt8QfFxh0DY4IJG82nYoCYY4iXp7CSEpQarEgHjMSfRa5h/PlqY+iMyCRMQ1EapkokhXSDDZFZK8WwyjODTh5qcU/R3E71ghMzIDOicBpRu/fdjshmM8TABi/PCi3jHN2N8xpnyZflBFNTsorldaFhUpyI8Jp4wv83gIkJ3V0Ly+XbaCFquoe8G5o4wmUMZe0oDCBP7GdEk0Uc3zcxVJqun0Kvy55nYFY2v/bDcvhn/etSyViZe+AwkCAJFIkq6c507BKK2cTAvCuF7Pmt3XnZv7F28Gt+9vj8/vBm9efMjXn3WbWRxppPIvLr803rx/1RAUZJRHNRM8KrL1ojuE2cHhT6kQVyPCM5YcwWskDM60r1juqemCREURcJyVqKJpACC9oCAg9T/mnWJod2ukohkiKJIf+ImlsXLXWRi188tgEURxttW7v7769LzdSMj7j1ELWRQgYmCyafv5L1eDofrieIszH2EcB3r94reGJXm8xrHYHxSx467Zwc5PKVbS1wJivQgBIBGUta9mHg8SFpgqRogJdQCNK9JFytBJCCSv3hZFr+gdXibadx+B5AFXB2l9uem6eY9JGIiy1eL6896y9SIos3MbTwQEIOBJrgJAxCHMfj4+XM8iLVpGecpkO+dr8nhjhMSu5GYkl+ysSBWcFXFc4/psM1qiokfvehhNWT6rsrHNIH7NVqRxfFq4PHPRT6h0hM8z6hdtFiCJbV91sgk4giHxzN9/WUmIfqQjhpT2f7rp1kf0xLeHNm+XE6YH5yEAhOXqmdHYFdZvGxZ5vjiBMowQ+E993plwf81/0+l5wuScW7Uj/yUNF8Lnpx0Hkd5tOxWrwc0POrtA4qdHhcWuXW/XAxMYowMDUZYPTpYtIZEF+MHg7Wz594+rsX5Pj7to+7oliON8MnEXNe6ywLPfnT075+IGoNw9JZUHLxhovmHywAGeVs3rW2hU6anNEiOc4HJnNXcQOW8JilgcETO/aF9xyNplJzMmVFoaRIv5eb9BiCigVAN/sLnOiExCsnJ56qpnT01MsPDWDUTS1+6CGglbu1KESmBM/a6VzhkkIxbP48+IGMlBGUYqtZL6qU1MMDqqA1ir0BAVC8neZrQ9hMjh7xYRfPzwqiEjgIZW23/bHD1BY+rrg08qU/hX6wDuD2KkbKE6V6cnf3TDMTkxW5dt8eqlPyqgqCXk9HLJxxyz1Z/vDmMCJWj+AdagbHWO+jeirppKsgEg0j1KTFDp8CorPbfJ56dhvVP0Pu4JTMDjt4lomdu62omMn0cLs+J4Y0a/NGD624fMBONG3qCNIqQzaoAC3l2crN0s6EyjaZ6nyDCvs9GKDC+B6B5S1UKNccTGRXP0NKiqAIrDiSBUpItMMAJoXzaNWciL/Zaw5lPd3KwlMVlEe3S/5I/BmGghv2pbK7VZGZG0zs8iU4aspfOWlYRFFCSk7hLE5NViYHS2pNcWgHkE44cYARohQ+94IYF4KhhhRFYiQjX9mRVjBGmlM9yU9eJ9iyz4ulQrDn1iaKV9tW08SaifnW8kQnaG8hURYZK+ummaJ/4wT3Rw6XiJTmCxussLvMt5PXAwMetHhFBFHHG5ZfQ4AVD0BkwFI+VBd0QmAqz2YIiWt0c328Mckt2mJIQMKomgF4SQbP/4pvc60C398ZNDx2znA4EJBEU27rqhp6/B5uBlSl+7S4cV2b73Sclkl3YuIHkcI4BK6j1eCAimgxGfaJig8jfNEEv26G1xFj6JD5ORD7wOpLUKJv0/mnmeHzgN9Lo911k027hdDY0JTLCzG9+7YUn6jrph/8AfLI8HKXqperamgIBR9IVv3IU18hiZVq4BJCCC/8F7RzDZ5zdFnkfxRYPcxvCL1gkgQdu+WozqnbzTrO9+SWSuNRiiSON6NQpMsL4bmYMTEXqA8EYnU3IbHS4TM88FI2Xti6BVKQOqbAIlRmAKtS+40klBwtWf5yV5+aFXdIrV+1SIffNXUKsapOTlRR6bZl4UvS+pDuzPcQhKp4ik8WYxCLJ8yzyJ36T24WxU+iIOXKMo3F6xKPPACHhGCbrDfXGqyWd6GPHDKORnnKH6OCL9blHk+elxaknKateLZ7Jxe1qcmaDbG+wpHYC5HohjbaZSsteLzWJnyxjT2fue3jNw8pNrLBoTr/eT2WdCqJX9/xFfA1R3Mdb4K4wQ/LeKBsB3eQmrPvUtKLixHm7lxeG5EEGp1CBoV+b4sCiGRCS6+UWjfBUGiCzp5dNwqdgyQfD0l0cKquTnJX1npGjxc0Kz53eIY66P454ljkR41v/7bxwCNH0xK0gqTzTC2NoJTbbbu038EMuot00Jpf3tZ52i6Cws7jeEqSJqTcA60fo2a267LvOf7F0LU9tGEDbrXZ1OOuks+YXBQDCEN2lIS0jIg5AASUkJpPz//1LtCiJstaSUGkkevpmEiZVh0LG3t/vt7nfBbp5617T+0quzLwneW9TjjvEAIZssTOkR+ZouHSEp/vueYiNEYnRYuInUDHVfceLQ3rZXDTKgiKGpu9uK20kcstH+1VJxArnEjJomY3djV4p9/pbNxy1m8bU/5fLE+vOI9PgdCaSlLJU1ock/Jb0RFpjU/fyIhpr0WpVAXYT0oZtsQLdnpWj7oyHTJBs3iGfavcGXS2sIsbDgmq5EAshuPkm7kfyPIeQ6kDGa8eSxt2vHniumQQLInHZWcSKUR2JA9zERqY1JL54uXDADSaE58B3XcRa6pCD9TCtFnM48DaaT+t6r/cUQ8R7Z/r1Vgq8URgwqitpu2lI/6KAebccC227xaVP3T0KiMf+81yOcUkhJlR0pXUGgtOx4j8EdBZIuaEQqXDCDV/6dz8O0rc2svxtJkwn3ns6utge9jwc2VKSKqDn+oKekopUe++ZTKgTrzESYZ3ls2xVK1j8IyYz5aBQbTF3JFVDVrisE12fRfwEggx0UFK+YIWKOc7MuO+/3GoDUtc9UZN+9GiTJcO/PHatBZiceXmoMrpYLiOCq3xyYCklrwe0O5AX9bNvnyQon+B6NOwsDxGtDTpGNUqC6zwyWNNcj71+kEsSrRNGqx2v6e1eEuFNfmSA8Hwxmeq8GX/tWI0FB0g3iRYSYIqSUJdAqfMPMu5t4Egv5oXrbc8VIGnsdHL8aCMjXH/gxAXwvrleBVgoBik95ayIBG215jufUV0PSqc2I3hTZb70etxoddqwpstSINY1AteHlwpNgSsQuehHkeXm75tRlkmfHaLavcQJJQS6SvTcUcOQl37toiGzlHhdCpp5FlK4mgMQi9nLANjI4jEIqsBcb2EYIaDSj0id+GpN8jCh/enaXnCkRZZzTMO7KEiiirO1fGJL7A0ETf6cy+BFQsBgzJ9XYJCDIBJQ7xysrr58szH6yhMXZiLS4XrHRgMPb98RPa3jbEYwusA778+Jl3LW+Hm+gnQ1HM66sBf4XaTxNUIISDb+NbbtMJxyFQOrHgIixh17dq7uNPyMiUkX16wOgkrKzzg31GtQf0qlR74PJ/86is3nuSXK8XoceYjIWkPH/nQwKIYEqwzUBCPTGYTphJvxhBjZU2N31eBd6HyNdUG4u640JmJFmEOaGkw+9VOb3e55kgvB7nPYvHllT/Jn+38p5ZWDg2fw3fe4CbC4avDGdGV4GouPci7RSBdnI1WggpeW8vxVwDN+mMUmwHOaeKiOpT0KTnJsyOOy7A1Q5FL4pWhFa+/JGFZXI/NrkqRZvqVOYbgMQSAiSxkipIHrODqgzcIUnafbDfNxqv3iOPJyroI1ASW62hVpNH/OUnfvJksbMtyzP1/nKgNnFUBXGA5PMyEv/zj8ul4buk1TnZqEL+VO0syr34bgb3VrlUHiFJgUaotMgWUNnuosAWTW6+9pnBireoQJDprSBE/RtjgwVpB4vaVC0BHp0xH1x1kkzn5B0GU72O6AUCQ3vQhutOTxQ+z282YMd7nPl1GlcaizQRBDFSPC2/E8B4WngMlvmfrB5W6KzlhhJsFd85fSOKEHvKgMU7Tq8C3smi0UQ9ZnPyjLefohQpCouIPEfRbfZCCAd+KJH4b/o5Lk0u+3JWbS0XK5bov4RZbtgH3A9Zi32Vj9bQACaazpsOTNdpYorOAKmV/UC3cY08n9A87Yh0jjNvFQJqs5Gyrd+7ZRk0SsG1J/kTrJ9DTrzLdGGjPI21wttWgCZJkH98+FyRXbgSRb2uq9Q0ch9ey+a/I7O/EVIqmq+pATAU89N2LOXliA7a/Rzj6th/pkp9ASXcFUR/VzJmBTNpVN87lGIBmBEFHm3kWyDOFjqa1O1mKQEME9dp+7456Qyd64WY/Yi7ltbcGMLIGQ1mp/wkfhb4CSJWD04twpGn9mB57a8urdlC78LqILY5WDE+xLevI4tmvGYX+VdV7BnRsoI+J9JTplDvm7AT9gyjTDyDOdmY77cpLmjH8+aO0Ep7MQsb/dkXV+reKmaDi8l7Q3OqPjmFkwb/34GSIBh2xf1zpkO5Yo6Zrcl4uED+3jW3AmK6HeO95u/38hpCLvTDhvOVlgrAf79jVJ4xZbVnc92NG0E05kRXYpg79GP3AmIy8ywtqa7Cm8owrzltlZ3ul+xkxtRvwuECAlyeleQPItF+3U1Kgd3WRUgfnKmvNg91oRZLvzC55lq/zysmFcGo8x22gz/JEeEEIZfXWHZDipm+gUCAIQ+c5verMXMNatwlVlJpx1VjUngF+pwWSEx8f3RsANQrc+LjOtStxTzblWAAgDTbjWmXXcXbn5+4Yuq/yYpXascVH86rc2c5jWfaV/mcbzPtmLGXxwA8dT1nsTOs6HY1M6y1Kp7bBBK0I19VwB+C6TIu5KPpmD5mSNlmwgKn3irCBSYNa/pNoNLqmWAE5fXcbqDUIoWuTuCUA/SToBdk49X0tZX7wDVY9z6bwCovvktJwk8rMpWGKJYql+fI4BaBRcSELtChNTjOaMBh57RojiS+kr0GLb+KxCGq6Jm+T1zFxrpg+zC+U5Vj2yVBFRBndHuEA3XbYg+i8yvf1FFF1kAkL4x41R/qbMgH7HfEkd9bmxFbQRqEG54rBiQvMSIH0Gam5bBvXYp2MHyQ6UHt3N+g28n/UHuuHtpVUW9sYxaLLd4Vshd6moYeqYo3BJV+XiuojvggaEvXCann968xgu7DZlU+a3ShS8yco2o473RCCMKp5stHqRwvxpQjxzJrVA8nbQkc7IXQ6v7QW6yWgqrvXwQLYiy4sp6TufK/CLTNvORUhXM7B8UUMM9kRNbGOLJOpwSOP5vFSPh83WbvSAxhFa8HeZ2x57PSY9/gVjtlxw7AGtmTWYcT9QQN+I7dcd9WfGIDkCFq2694dfjTZVzMU+dOqva6Ece7XYA0jthCqZDylYWbZNvPHO/UXk6sv8LUGn4rdHg+9PehiOKOmCOHE5/m8v4aCO3ArVZk+nHz1n+gqS/yd3sC7aCdZpRmEHMGUxjdIAMcCcQkvD541lzO1DvSI4bRxkpDTqaCXj1Dqo2zPZ3gF/FRqb+HGm2BGVXZYB8Q1MFaeQHhNa9KcahNpRxrKdunDCU0zacgMUDM+Ok5WtFI7TQGxkgb3Yfz5pbgX1f6NQ+UeZHwkG9HgfO/kQMFwBtNuQ0PQ4Jclwr8/F7j3z8rdDb3Gnm/DK0weZ83ncLHSjJkOm9oFS0Vhd/MadGAtroVew6dfdjlWnCB4BteomReHNDdrPFybC7XQYNv/uDiKS31XGPDIwMWRzFcXIOzdoJOFLHBzxgqsxZwyH+LBaZmkUsh0Lb/Xm0cEVI4/nFERuB06DRcKYay5OwF8YDqIFZYmkf90zd/PS5xHgbBmqT4EiwBvq9zx11zoEefn3VadYDN8l+K1q2fAAghO+EYm0ZzHYd6SW5FuiPCVo4uyB3DsxEChGGuBO53PPVBIRdYwJB2Jb7tI/1TZWXHRkseGYrzsPfBG1LbSb4g9RQGK6eyzTWgqk94u8BuutJ4tvVmNmN/uLw/conZoI2F61LI4DDjQBYywAvPP68UUF9tAeCCo9kKLYdZgSBoogJE6dlJ6kZGPQal+/qzxaRhj7vN/kQCnaqXJQaK8C+nEqWyDvDzEaA3nNna/0XPQnx6jUADoQqdM/1sOmbtvT+bxMWPvJeTtALTnyn5gmy3YXhU27KcTf1BJkIy87OC482sGrYvxzLVPAKwiRQymOA6Ukb62cEyvzIpmQ6S4Ymyf0i0CexkXidYOjBhdT7Zg1O1p74vwA2lSjqK7ihbbUlB/c21iap0AWIf/iiNbGLwyHZZsAhWdzFx9rvX+xdh1YbORSNJT3V0TRXcMMFgw0G03vvCbAJ+f9/2dUbAmNICAay2eVEyUmI4ipdvXJf0XdbR10jQ91jQ9UGWadq3puhL4BF9Ywb6z4ZNlpLbtZU//S9+u5VF/6UqzCRe5AuN1jGpLSpd8SNuKEYYYdJIkBjeBmCcTcrv4j3JDbfaICAAt7RYO84VqddyLx2uub0nZ0qJgj7YvBIfCbD7v8nNFoP3kf88m2HIt4md7TSEUAqQzgwztOJ30OO4oNyGlKYc9YpnX3QsHUFc0vW/+S0Ph6E3VbVrH1Ic6zX1E2OqXcmR9xQPURDJyL/jHvwrHE3Xf/j1jweDCq4OGFASCqe10TcLL9HjLB9Td0XXgDB0o4NhiNK//Nas18ywD9LSCVgKcEb4ILl/PeYmEVmQscq8wFL2aeEtS1+5f9r4fuvHMRfRQLtSqX4M/aXRFXj5n40/reXKECUXH907rMURkgxi+K0+Acjjwa0HRxoLkjlmjEYcyeNrsEviOcRwphgeO+qF0W+u1td3cKF/CvVlOS2AqATiDRGoonkAr4/8ZpHA/ax6eB5urEg80NKOQ8D+AVbxggOCGZuVq2dKjJn/+C1eIQR/PsXDwJnMqHjBaQEmofI0Vd//JpHw191HDRfZiR1qJapG02P/Ao5IkCo4OORuwyHU32lPM/zfQ8Y3r3+L1QvEDETJrFfJlJ+jerj5OkfiDwakcGExICl75i4wADXANivuGOCeR+PcjyDg8pWpz7RqZXrk+NH/a3PjeBfuE6VFcrote2nxCQTah8nj/+Eax6ajLCGYmRqOAhadhgxhTfWMXilutc9qMlMalCe03c/6+zE2MpM0QOBZgv5FZX8hPjT+G7bCkSq1++uOxf85sOfMTyIN0+Tcuj0bIM62fLG/SQIY8qLTjuSUj6EkfgeMnj/nZR2tbnS9UExYL+ibQxjSX7AVMBICjlrSL82P/wZD+RIkHPLZbpDGNnHXevDG2PEm5ktce5gkIIIz/I0YBKkcMrt3Pppw2fsV8gRtplwqkWRxshHN0mn/9gjQ0MQUcXWRbVhKyCPJ2pRvCkL4l+PG44YSGOEx5JyifPpQSmVnJtW/2MAb/+1xXVCEbZJenYRSYDVPxh52I81Meb798dVMPANqoA3sh4ZMAVesDIhXUGxpMO2SKwpD/Nng9ODo416qPXd/yNMOZe1o88FxRg4SoWxN5JoVXRs7HBLoxnt8r7L75FaftViBRjPMzspjpWoGdyn8TeKbjmINE7qkqISMe4Ep6VI4t1sDKJA+VH189an6ZxBoY/DwUSX1neLylMM3mj7iCiiY6PXhjBSNShcvD8YSQ+lIoMYKTKRAs4JYmQF3ggjqniQ4xR1munc6DRE0AXmGS657HwOwMkL5RWqg+3pUCbPwMFlLj9oe28UGSCERK2ECxl6vSRgE/8J2AwN5u8gHDoesFRW8BSe7fbb0FmicZDlWARHbXM5OEzbIqXYasnRRKXcfCoqIQhjCJTK2onDyZ1O4jzODypvI9qE8JOvuDlkEVdC+v4w8mr2QHh9jG7Nwn1hI4CXnKfXXnmlXFjGi/brnOOGlD/N+IotTVrn3jqmvzm4bLcXvmxOmkRW6I1uAApYEo4lyqt8uZhweoe63yhN5q+x4btwjyCv8fibKKQuWHq2iBgJo/eFkdcedAgwjiV31L3MYLCQNAcDwl7b7oMVTsvSIUTK7GzDU0IRL1rRXFJpbyqe5wtQ4PuL85ZySaksLXoA90EBovxo6XispDnn30zY8kHVAwWvOR2uC8IF4vYTDGEkdnNh4V0Rra+XI1Ho1l4XFKRI6VN6y46w1zZqvNqQHG/8D88XK4HHCLjbxp0YmduJnE4B4qY87+Mkx1uUsos+ejDfbkoBUMorXM/XDb9zdcLmsrtH5DUYISK5/uocyFC34veWHEA+KL/9SrMSqjSpsxIilRU8hhi5fC3B6bXPjSO3nSIxpTiu5/fbHqxl3VSr6hLUhfvtRIlS0bxBrVc+/etjO0Czg+AQAhjzorWbsubfUGJ7XyIiXnW2trR7qcNhjGQdDicq7wIjwAQB7+PYfLjgudN4S4cRIthoCRj+vqur4RfDFSg5R4Rqn7x8BwRhKlgpmSEClVIebi46D4fXKkwwvBMeLdSgsrx1aClCk0ttOycLnnI5JoLdAgUgiK7Xs5Jmbj3oyb1IvSLiSAboXs0PPT8qOWc823gXugYEsGDTyCk9EYEAuI2GMCDINZHnYySP/c52h4sI0Eqsq9fkhwjv44bmlCfwwJH4vjnKeSaeAQAHAVBB8XIw24kNR530zYmR9rzquW/j+cWFtesv1zvtCJRfPJsyKEj++a07X3wg6qUY2fseRsqUxtq+j35XAKw9ZgzXsV6PblPFHET8Qrtd9NTzQRIgPyG7Q1u8iBvVhFeEQ6ByYu7CMlSHtXrJchQBTvPwM8VA+UF3Z+V8OqdlAg+udQISfJzOnVYqiyvzrVjjCDe2ur7yo+VmLGkilGx+wX+xHPnyHYwEdR7bjKm+Dzni7UzIbJiR1Or1tmK3bWYG8zVrS82t7rNPV8Fg0w1vCCNJCvSxeDFGwLuaxABM0jG3udKOgmhxtoRbSzmdiFQ0czY/Z7XGRziYxq2jgyan92E9biZyRvJ7XSWzWxGAHzROajyDYsmYmy554We8/h5G5mJDM2bpw3sYrBDzjOaZPM+HpnRa8ZUKFk9yVkq5IaUJ+21FnnPLqrjEnZyAIQDOo2m4Q17mjTPwCgeW3ooDaue7iVwjUO3oxOLY6251ku1HXkTHnfPdYuDP5OjDsN4dZji6X/MNjzGliid1LRPrNfc1cDYLqJdhZNhm9fNu0iy+i3IRdpjlPB9TbXPccF0au5mvW0lDynXNcsplPIgE+zm9Ace4Z/2hB5IyHuzopXlE3uKGvGNHs9f3hX6q28I9DzdzRlLHdUhbao33ryuBD77f2EuZuHd2SXmytVoyPHFo5HwBc0qCaGWCc8Rh9mjJA0ZgVIz8hRjZHnqev+Hm9M670DXeusnWiqtctiQ3mTimnFNNKdVGSs7d4upmQ/2cO1FNFOKfxRBwkopp72WmiIpOncFwmwVSrvrqHiOwRZGAxysy7UTz+Eu1GHjK96KFr596Oce/PsDI9OlOtxIV1uZzhmLQ+NwnHgPwVXE258wYY3R8GgGMuq3kK+YBDJ8Ov+WElv78PjCyQ2XrxIZcS8mp5PRbSGNSuqyLnMvIGF/6eXGzX3M7qavDbGNS6KhexnFXto1LfcQ8NhleKab8eysqj5FezSXPbs8EPigFKuju3ZSMuRULDwSJNLY01h+szSyPW7SBzR4wJzaAeY1mSOOQZ6hsdn02sl+DGNkcxkgHSeev76J2AoKQ2zl54exNzrldlzyj6xMhdX+vayNzMpebWlLABJAn9EIUZvijAMUaug2HI2MEua6del07HmRijmeo2fTdZKoTTsY5l5zKsYISHzzGIFobs4mfggyKllpyRMedj+Ogr/9BSi2ZyHaVw11UKETFq3yJIx7Ly54QACNkPJEV6QTT/rCuSbpL7L8LOSLUntE2hzfLGMr1rs7Qyb9Oy07ncMu5juV2T89VgSnBfgwRKGL/1dIwjjZxb1bY6DLEjwYx5yUtc5vLWlNtGwEAuwMbu+SUhzLDaQ9R6algedKRp9xpEZ2rd+bPBmduIvGR09TKXQqsWS/urDQnc9lsa3rvajarpZOjdiXwQI2iE8/cV9e7w23zxt9RYjwDvymtLDlB65bQuZDGGon6RnI3UzJUj1cUY0+sk1dF+2CDkPT0PO7O8ugYUY1ttBpKrcXCmHaKYX1zJmJ3ho3a4phSRGVP4b+rh8ZJfE1ldvrkqhFFXtDN3soRiUYN/qB5Kr+R61YoOXcginPh9H4HF0Ca8wLAKKmTB+71zc6D1or4Dpvvg0NjasH0jM5xJBykTA6bNPXxT/3+eX6y3rJax7r/VJ0dIWof/cdPRKSnp/HItkfGiOpOSy7/2fJeMdqxiD4j7VH3DiNwKGPtpmkcOF/4Kuc+OFod15EzM0AFU+ZWfkxOJ16OnO+PT9jkcbiDXN86zbnYSZ/OuJWaSi6n2oo8/5paOOdOUS8x8hgjBx/eyRBj8SSPyzwbZif3xzSlMizfVCMF4OKoUXt/I6u53VHwY4yooJnYaIykkg3AKf5RozVCKH+x5CwNak+ixlmMEJEOt7kd3w2lwNvIylsbo8GcusQdccaqnihgeAZ2dVI+wTN60OOOc9cTbS+YmS1LN40DI4S1WstJHHep7HlWu2MiVxf85+a7EqFQreQaQxjxMZip+2R0dw4Ig//edXILZor3tnIlG2Zjq8NacyG6v6yKAASVfkmPF358uAQkuaxykaWNFA+JrhKQ0aizwm4oXeppeS3odkxJ0ozk2m0yNb1/xtj58WC5p7/ZobugdtFRMed164ByGDAAKNQTW8Tp0OnFOayy0KeOuC/0syg/UIBsfyxUioXlqdhlr3E7j/qG0/KOD8/FSFKEVYuG/ZomYmSWjF5eoCCK1H+u5RPLxxPx1WqpdtJsHm5VowhS4oAxh+tqz17BjzFCgixyRtWUPcJEEaX65GgYYdEp8lx6eilYcM5tiWs6Xb+3O7nkpm7uJMGFv2xQO55GbeebOP+bEXXqxIgeC52zYvYGIWqYKdduyIuqLYlyJ0PHAwUEQPk7dcm1pKbfTERK+Dl4BkZSPQI2AkbeAiMKGit745X/XPNf+CjHTXMrLF8GTo4LxshQ5BUEg/bcWPBETnwUoqdQEClwQZITnx8pcZQUPhkUSZNVfyeUVBua5U6OyHR6s7znP3pLIcZuWgELLo1zbDqBJwJHntK5pRp3omWjO4WUid0RhIBfOPyGsGxBgQAimB/lsw5q4dmJRYbNrPnPxEgBG20eeYJ9ByMj64zqTs10Svv/uSRHgHp52i5rPRaQH7dvbj3xuUmSE2+DlBYn6nMGV4/B8/0ZKK7feqbl6kKMGSmUZrVLW7WO9UASONYphkxmcfv1AAR401L+M7MAMIOf5yY61nj71ukeYphvuyyBQl9/Sx6wjVuR6bHgPKYIo91E5thrxZ4h8gkk9TV9GNY16/h+n9hojRpZd9ZKro3d8VzeFIOksNn3Iw8Ijt/lTBP1l7yRJWPM4g8XhS0ue09gpMJxX2EIIwPcxFkBz+/vWmnKb8JivOTUBSaMZWOdzcfIjtqjeqtm9YNiPM4tMjhr1m3vuA9HSM4uQzSBH2xucSJJ2o988PeNsz0QCHqNJJoQiBfkETqr0VqM7nF85UHwjOSFz+hgbZEHIY4Ek2y0KHdjzMVEONX1q0gx5hw0aHd313vT86ftSAnx2+7EEcKvl60j3leDJ6L03lNdOFB0bxAiUilkxzi59fyKOGj09L2AwPwQ3HRe3qtU+lg0YapBsVFdK6cxgjv6V8FTLLIOEqbiZ6lzz7oKBgaZkdlZRFXu68LSwHDOwzy6PfEJUyJh7Qgrlp0Q0lvecozAyl168Aybdd89WH8VhLwWI9CYsy7Nv2UvSna+HQFTXvFyPA6lzhkT5hcD//fdaQpsoGmmE2rz40vgniKoCVtGgd9k6cZx5Aa37xrEc7Fa6ch7LYLh3FzCaZ8r8KraTZrPTgR70/QBSLSpnxYV63BngJzOGEeN9SICwRQKjGxPJg+zGNILt6o5Z33EG8xTuALuRb9oZ/uGDbUTu48ha9Vn6BpygVUSM48wMrquiQ4s1WUpbTxhJY8Pvyx+WS9ZbjSXLePcrsPub7wjSriDVzvTMlsQQEbuSUcA1Qo9h9RCCZbH7bsE8jzjz6tMytTWO27DrhzhWp8JxYKS80vLTeZSXG8exf4p1XN70alxFuf0sXRTBwqALVunQR5AKtxcmtc0NpmSR9wFIpg44gV5mWwsLMcOI3qyAj/rvsSS8pp6kYlHvi/lo9msfpbK+KrM43FDDdfaGKkpOnOJcuQ8+zUS4jf5PIQcUyovy5TPKoDRnw6JWpmFFJAI6+F+LMEzYzTtDRfjTWc2y/HCLFKh80CEN845jU3NXRzEth5hxC2lnl6RjnwNW1jd+9WJnGDMyabh4fCU19a69phOzRCihABQCxpjfZGAryGlMiN7hZ/QWQyCjsPgmOvd9AgjcjTfl53wTPY6DOOSdEEFi6SOiwXFTogYZ6jY7QKw32W3FkNKz06lCYvwgo+gtpOGTymMEMI6uCEN8byXaEzJTBoklNJso3CBP0+AIP4Jp7GmWjFC2M7DyH/yNIPt22/lhplhIFS0Lx/qJQzwSuMcpbDo8AFe4CnhMX8Sv8YuELVinGzih8HTR0ZAxdX9xNuKsMcY4aPxrNA1nJfiQ8mp825yWemCC4bLkNPShK1LqXV4FMHvwoi6oOHYqq7r9aL/gmePJZmDLIURxlZxR6JnFXeRyjimNsX6Xo7w8wAS3yj0gXhtm9M0oyP1QbDuMEbkVI4nsMK8qOT5YUMI8BxpOwwRox3TFscIqqqCqLt3tH50ttTwPHw3PsUEqL7jdzPmVHlPn/2ZOKdje8wIDHPxiNyDEenDprTZXI27cDvn5VPDaXP3uOy+kSlJrXP6KNY3hd9lk6i2sdLS8nl46b0gHyhpE/9X2q8RoubO0nNqfQlTlTym1Zcv0p2IWhEs4b9NAwQrrMZO8BbVB0YqwxgptxfH7AOjg+aqkVdYc0U4QzlH8mDdmasWJ3hvsDxlsZbclD8tVQxy9u1AgJ/n/wwaLisgT0Qz2UDremj+IuQBnZTcPMFGy9Mo5uKsplRTF3riMae0tRoi+hNvnRstTT9wePwNg8ERNTlpt2wvGB0jfg1Xfzl9BzgRZVcObn3xnPte1xOIDDrpfQ4b0LZJdw8fvMiGhlIZwT/vUhjGSD6qVPftg95oenVs86szg6XkKZPEzlnKY3vXjFHf1+LEh2Wn7OjcSSCgMOEKh3mtIAh5AiPbMrbZ7MxDyjGPmbyj5Y8w4g1Kh9bJU4v21a3elLY0PTbeKcfOJDE2t6aY9zv0jYAZU86vl2on2dETdUlQRowM3VZKWClDQ0Of0V8Bom2N1Pjy7nDbmU0V1fGVWxFAQdLQ8BBvow/4EEa2b6brlj9MYXUy22W924thGcOpDWkKUPfaTWKmlKRyOwKYCZGhaQZAxI/dmnyouexFD12UceTiByOGvFmQnaxzzbm1YTiZde9vws7xTtHFu4sza8e9XBjLVlH9lhu2GPPzuYXTvD2Y6I1ukERZ3Mml9IkTkOXWZJ6DEb9vkcTYrawP79yE56M1TO1xAA1KaRxOOjEilB56nOFuz4d9XHprnkpq92ZN6j+4LE3UwlQbLCT58c/kSS7N6lMAcIpiX+8/lV4VjZuMu8z44TfqIUY+k9H4bgJnNl8aa+kpU+tMtayJW5sLEQjiWHn3h9/eWrW6r36L/wtEXZlyaG1rQy+P3No9SDBSTXNoAsqxWz+f/MwWUacY3A9XvJn4boNxxBW4THKJ9KfiHnWxmxMgDiMmjQVKJTc2Lm/k5/M8VS5BE5zoo+JhaPgtJkxpe7FaPONDL1BbnzNpUSNl3xfqnLvcgnDxx54EaWTd07fhwXziIelLMWJJkYhyrXBqLabl6Xpptbm/GIBAaurbwgoobMXl7m8xSJhQ3qTmvb6RvBWAGhEjuSGM4GDQcRv5MznClL8WO+1rjz21easvvsmD8IoUY0pRDfTGqdvhBeZqwJVNb6gp9y6+flwqBoFfCe8bcTZrqMHk6oJX/LzSui3RO6l6IFg3HlIyZqWwt5FCCaVmV7FKTTs/efLHN3glXRXlini4IHMo3mbY6P6l7cRfJ012qYAdNL6Tg+Tt2guP/YabNxgR8NWUynVN58wCsJdhhKQbS7AWLnf0M0NoqeTOtJPuUYsO19XpC+YlkRZMVU6KNz3PD4o2JQfoRcUDxsD9gtzdtKxtlhFoyz5TUC3hC67OeMAEYTMmDRGq4xlVOAjvXtRJrLavdhC9vO/98OT3nbAyj0y4qJx41mJkjBTiqXBuz5ozT4EggnynerG4uvEDm5X80lseBRMkmpiqS8q3wvFIvEjXLBGR5kfKuNzFp+HNGhtISTYLyrvWd03L6gb/6nhQNYmdkFiTq8dbg0F/vkVlaosXgBDspwmCtFLbnBR5xlUByv+EP+s+ADDG1Mk9xiS+/7jP1GXt26yrCsj7nr+pHVzDhR+tB6BtmmuL7xpopiFG9x0O7ZgdK5tsFdIYSR29D2pl82/mrkKxjV2JNlqNYBnMzBRmThpooE2aNv3/f3k7Izu2Qy/pQ93e2lnXsVc6GjgDcuGt3qTyPwcSlg695oi+EIvnYUX/lc26+GXOZl2h6e68fx5wvqWojK6jtXvzBBFnzfgzWV8GRTEX6FMqkxFCzPop0VjQoqVSnDFOzdNMFfVZxjKsFnDMyaiUnzxeL2vSBO64djt9MbWH1JqGqE3WcCmA1zdosGNRysHzF3Okyrw8+7zO74QlT9j73lkArxZaM0zfAvnWRpf/WY9HRgVrX4n9X/aBz/4GI3ezbdUYGJ51k70TEOPBmYPvrC+CTNX/0+p2K3umBDfPoFNQYgITy4T6QmsWI8qdmb+WNYWTZbi0Ow3NrqBLmWvOODB3zXmqy+pWEstknXAOnf0ZJiXJS7hzKHfxIHo9e6ZDJuu5fv6iMYvCHPu8HAmKobKSsJCsa/lJ0xQwsxT+o6YJZ5dKWFk7a2dy7C/4EfEwI0cY4/u0CluSvRPrfQipacSulhxO1dOqX+pDXJr91h139UY4TTwzTRHDcJYL8fSrGFHKYMQ+6uSuCRNWGJ8xkBKa9Snteh7t2lTXPATO/KVZH/mHBjgTxBY3Xz8x0iQ1Xb+4xaGz8Hd9Fbnmm6FQe12vcB4A+5yPC19ckPAfPVgJeD4jVKIs8UmDnPl1E69hfNYAL9ESrb2DERiWcY6dy4gzZnJAJ+phVyBGiiegtf+rPiZDHc/z4vLo/OrQmiXdX5Uj6qjsjEVFclQ2+YehOkBN45+JJ3PEPmNR17IsxCWwYHuGYBFOFSBXs3AUX7cAviEO1cOLpVw0nKD/Fzrf9UfKiv9knJUt1IufJGqBafhPOsYc+JJt1bJiRd1EwD6DkQFhZHsGI5zBHs30t9fJFol0aZRV6Na2IsYAmtPksn1ffrexNrS47UYuwPDGUB2HW/fHw0hzOJ3NMyn4nH/hY1ImO3nFXu8se7O+C7Kr6iuC8c6b1AVj+IbDOoVp6ppx/WvW9rGyLoddB9lW5+6V5gkSyPoJNzl7ZtuZMwVq8Hk5wtM3e8L5lbWd1fwn8wCAgdaay/8gUc+BdUKrfe/Ue0kO+Kc6VBjqfJYe+QJnNNXnXL7lprnfkCS32x3GuYa1J69GPHJJTLjav9LAGNdVg5FVbVCol2YworyhBs3NHegnv0Ytgi7NMh5e+mHqOlfJV3vWlGMVRxKCMiLDrkgOD/Pc/L0r9YWNnHgveBG3YWDqJuq5Z9c5PxYUk/w7se92VXh9owqZE/9dkLH5pmAyxSw+sP8sRiR/tJ22sM+c3U/1U9dLJjWPzRY58isTb3tLXgJ8j6l9yAYguxGcCzpYxGSHQm6vnYjUlkBLHaKSMJZHB5iZxVk5okqBNhgBcJ+4MXHH4dR+AomJ9IowKRSSsaFicNd3eXBtQpKM81kBhXWgAfCmKdA61fw5RmST2JiS/xwj8Id+QfbvHFE4cWqOLUq1naGW70AEUOhMPlJKySVIziT/j+oaztgwVLG10Ar7AZOfOZCT5qQ1j+xfhuKANwu/G1Rzfu1jyWhlo5b0Bg1yUb1FAP+ol60rsU98xuaYAlVHxoMIvNnkEUstB740zl/eeVriY82jGRfXG8Ni2pjRNGsMO5pXFEXyGcCcoYP5RprxawrCFnLP5Yhk3x1Kv9PP7mxynt4N/N06BCvKztjly/DwHf+SkxPPJyuXDhIj/D+bgsTSza/Pk1Vlh3tek8MnwHVCczqat1kXaaZrWr5xEt2RwthsPxdEx8uDJCy0kySpJ8RJAeZv1Es1pweMrFlLkPHgLAKi7xSXeY5Kd2U6mIRjynenqyea6yPyZ8gWmforlMjo9bZjYZQN6FyMl1YZh8tnSSg7eYlIw2Li62fRVinlpSJTHdhzu9Mc5XPwd6E3DV/tJGnEe/uFDi7+G0IfAFUsI0zy9E2aveXTMKrVQWOWp8+l/Fdx0vE855vdUsufKK8DuWGZ+hpgM/ZInubbDtjr9/grRGOwsBnd9SkFrZdpN9oreIjiSgTMvxCiUWr0OWO6agthmaXtRUxLf2CJyXKbR+84AuLi9yjCQhevNeP5HcoaFiRFpv5K2H7cjdzVsQJrBlEskCHhEn48w4j4qvm4U1Emx/kzlbJHN7jF5TP54hcJI7//bjkYzxf21xdH3lK87DPN3zzKR3MCCUdyVXP+ZoI2aAlb65c/m7lA63+diZXuhSXWQqeQyclPOGwV45r6HGbsEW028fB1vyafKETGaXAS01LHjULNCRuYxFnEnoeXthDl7A1jEKwqVBY2SZI1zE1G4T8LEgsLdIGDrlBZuHntwmUcNuhTQm9W7NiDdRfl9L1aMGYURCHKGtRrpWfFXQuFAGTQoI9Z9uGZO0cGctx5tjRcRiakV/275ZCML3n7cagG9bj6lv8L3OW+piMR4AtDwx6rW4C9Vf8YhkrF+0u/8v6/nDOtoepZK6tOX53CJzCSUzQps7XMTPIGKYLf8KrxTl3dVSt3nJgYftjLrMT1Qoznm2it3bW2ElZynUrRIVoj9lWCARsRV12/T54r8SUT81OEXyNf524EBnxrdLERMA16t6ZQisxWC/+IsFxCs2Y4FkKdyCZPF7i7I57nR3/VwI/tcVrc/HavEL3cjVDFzr+QIfDk2N/JEQbNgqf6K7Yjlv03MYIAcblEY0Rj/E/LNzk35p6pBSWUJ1R7XfvsXz2jRLeE98vzwpXchw92keOa8KSq2awSLNJKLutXZkEeh5QOMvT7RokI0S4X6nHDwbIU0BAclNL18na59JcxZrITHZLyV/0mNSAjs/PHkSHDyBLtbZ/sYeahs7ZMF+O8xEh6NZuE1kzR52gDzNKxYGCuq4t1Shb9AeAnYl7XpComD65fImP31p0NSDG+SNgrPl9GJqv0QoJ2/1+C5MIO4wF2FB3C6+vOycDAF8mfASNP3lqfoWep0LFsIXZ2trR8q7XbZOBPb6ANB0DVsdo1MfI24KO5tZwHBfQuM1vzk7JEK/lKXhvoXAPbxzgnOl/A2S/fhgted2dlv4CZQat4PES2MHAsb5NDBSfc+6UNmhbEeWLsV0sUgwcxW4al0AiOt90te9zpgiYouCRhQ3x7eXXLn0rgbxPPqEHVOd8Bck99TcwDhQEDDeuOEAgXPhdt+EOfs6Tlcw5tkV4o67+nxasxhm2cpfhQA3t93bkEzhElZKy+10SXwU9HFTZ+KaVE2f4Fb6o40ECDc+DsbSniDze6lhqpZW8Qcck+WGOHPWo8x7me//c/CSMZ/TIoAT+oaLuUgzuiLVonNiqJxLMKXdvKAoNcG4tmkoC7y7hkdZ9DxYBDjO1VpxVBxZ4NCWN9cHvLDZq0jcUWNxN04E0MkbOc1mzG8VIT6YI4TXKgv0+y1agAJ0yH56TXQY+o7eI3l89q01uBwFvjDJ7pmntBbLH8+1NP3Kxjl5WzO2hU+FsLjwABBArFKRnIt+sWRiqMjwrCqQmVqcg3OvOjwpr+9HqaAdp8JyPPVpawLdu2N0Dqj8YJLizPWVDF+fupGMcm9/KDOjWRipF46MLvEC3PUXHSdTcc9eyRr1k1RHe3r01mvL3LA1f/soVRKwiIzKEPnLenakR5Ttj4GoDWJuXJMkoO4NoeC4VkCHJqsXE0G6ZVfvYp991vEz+ptl8albLZUrY06l35HNYJynFuNkMGRoiml6mdbEyPLLG/xwh8z4gjT309CH/r1+UIHciD3q5G1uxdpoJXHWxYIbBJrajl+OtxGD7FyxNF9/wjv0CwXVYKWzwLK3PoiWwgP+YAg4a1EMveavPQAxNtfZiT0Hi90sdWzCl7JvlPx8KJtk22scLy7e5+XruEh/BQ62usfCi4tG2W0Umm2t7kvEJMCTEUNDJnlyd5HyhBuCTIT4kMFA7tMYjmY/ggo9KMP3zkA/dLVEJa7meLxWJ2PIrnPriaaoGdq5lsY+m28VPCxecbjgePpOse+N9TEcztC0slybJ94b9uPpAhIrlmTHOAt1gPMiz4Dy9jWQdKlMurqXqAl+pjDAdG/03JW7qzp5sLfOlu9NCBcJaLwhL27kXGW/ygCcwkG4bjJjVzwOvS9B/NGTaYBfbgiBTRO7iGG44RIGQR1Afpcsal0obfqaP8L1d4M2NhtyqD8ijrmZqs0xyM+2k5kwRpL3kItOSSlJzpEU4GidT3nvn9yTqf1+j69ImrbfzUjEEUY9fx1nULsTFBSSt7rzl8twmIMz4Mj2r0WysvZiPapy9UZZz/Pee96y2omiOsQpW9tfjUx4bcXvZmJ260F3JeWy3gGQDoBvZehGuRnZ0/M2+aYS1njFcN/pWjLBsb1DVSKsIu71bD1YjLj3YFc0y2Ip/P9qS1abiawUzirAzQOU11mTSnipmKudjxdkrEzoels8qtwGT4A55fpv4j4+AW+PuK1rvW8elbMz1OdyUbtrTou5pN0sAs9ZuTzDw29oh9O58npDncPUURrzUq9XvLcnrZq+hiIkJGJfz7yE3/NVnMGLWZ0o30Kd3gxWQ04wme2N8fqe0PhBXGouyt6Td4Vs3QUiWQvO2BogF64BRRtVP7Wav+3MBhAGzmOZnBkwtzd8BzP7BdfFLAtqhqQYWW82MvXAzYx0h8HhUove8E5u7jO9kOKprDCPCvqR4R4oJOm0OBjUMMime3bWUlqRKK+20kzEQjp9EasZzfYJDOIVgh/lzUNoFIAh7hETST1ESVXcwjSHhD4YxcIJB01LLHOJjHCABVE9NAHAMEI8spZVer+k9qifR7O/X6TndQKmZb68BkNYN6qD6V1Oye9kXLfTEd66Rja//KCcIckxLE+aF9Ucv6b3ghaKZKzgkk7yQtySip254gVzD9Ez7HiORjwUGGajoA9JNHxqd4kcEqtljq5lMnCRX+3qanrKzT+iBG2Bd3RHv5EebtFEXrh4X4M4bPMEQh4VVBIrr2xoIg3qssKyHa2HtX4M1Y4U8dLCH8C64rmXkz5OsWOSLhJiU6A2zEljXtB6Da900X+KlpM7sIoDtFNS6tqg+BzRYA8ag/5V4XOYeh7Y2yrWUA/6YdTn6rqvWzj5pz/QNXXmw9iQ24Iuz9eA4FJn+a5MfPJqlLuh/OJjUlXVEoiUIxs8FeBVGqRTkDolj520SW5HrNydpHyrKoNZSnduFZUgGbaBwURzM/0O6nR9pQuRtbCLWSq3bFYzZdlp9+wbJF8vF8NCC1osp8Hjs75rA0PZXQWrtHwiIylfu4Zg/jsJv65p54YiHM1oThMrwDF4YhmpM/5xov1g1N4jz4BDL/LlQIpOlyd7c312NKBmitP5RsYcCT/rUXoedv/F4A7iK/MUHCMuf5ot3PZlcXJYMrJaZt5kVcOg44VEco/XpPXhqcKXz7AUgAPmduLpFM/frpw1iC3ObJt3s9QcGpY1vKa8Vnr/AslCgCnME/s3k4uEkhDtcdZVHgcmT3sIJ5pv+unPD1jAAORNriE05Gj4EQd/1DoUI7/FkKkRVYUGrQyVi25zgt/6N3aKJ6dn7+tg/oaiHv6unNNWk/hhXJqJVIPkMzWu9X3WrLs+JSQ9nITtTufR3cYDVleU6au1Gb2j5Y6jJA4HM9XLHt+TiwSIERewgvyxIEASJznW0XgBk1KyGfSqBJwEcsJBB8t7vF7N43AHDdfeNl47soU85nWlOLaNV5mt1z+tVXnM/TXCwY4XuczmcLE/TvRIiwH0zcv6C7UlJWv9vIc/nSVaUTVSnY+z7Ron+rVfv8zL5IbJoYIc5yICebliBmNs04mEzSDF9GCNI1s7XvlDgqCiEynrN020WTpKf21YXTCDc/Ki4jj3itn/NgN8hRXiOYWkWPZD2dBQxrAzXXfSqmbD1oWTkvdUeluDuq7eyt5bjmVcd6ceKYdv2SUESZlXIATAPPLYW2mG9CI2KHngvqEW7j/KA1/EtLbmbG9X96ysGAsoGV3cwV4la21aJ+87qqhF3uDQa9svHK17nkW60UI1P7A0hTicPOMOJsPlmeyJjocxhBM8ZwudOTEzwvbntZD+PHLxuG4xbDTSb/CS9RT0bOYijsAp5r9rssbHVeeUpw42bPMBQaJA+ZJLUu8SkA2sKakKJrVulaKWE1nPDO/ano0Jcw/b+1V4WPlmHVUd+JJTbnd0E8bjN0MrkT2XFQMxbyXOvmQSO75T9iO8P91QrnQanb72fEmeRkasjoQqTI7wYwr2CZ/2gbM718DEwC9iH6RsllNEwyQMYyT5E4an+vlOzxCfOBJFMkaK4qxPTjzsQt+tkXg2xxbxF8PE8rOOtnx2Pfsaj/nutfrChLPYlKt010nmeLrxhxl8wMye+pqqvNP1PEwLjM13Cfb8I0dJ6rW86hVy6sRs9AwtEMoTVEuLB35ci9UlZm1VbfnO2MZd1iJ347XJs4wJJT2hAQ2STZ7DQD6RlmBAk/tMSpo6wQm4A5t4ZNaGXUgqiF/Ugy9gE5yfUZJRKXXReCGbzfjPX9N7N9NdcXZB+sgcvXYhTjt0focPdWOxzglljxC240INyhtemtvyxtcU9sS+BQRwG4gJaVP1yue46wDMkWh9ZY/6jeWgVAN9vpj54lMg++6+P5aI6Nyn7NX08vEnEbiniULX6PouGfi1H3Zg3pkWK2VCqWSoX0W3S0ZCclhZUSrjHn8hN4WY3W0vbWsIKj2Vn/00LeXt36jHH3Q213Oeeu64+EhaQh0+xJBBw61m1flcPn9ScM0IygjcTZu7FBCX2xoGwh2uv18HtCd2rj7vpj1sm8HblSYqDllEZjwMfGCP7lNoSFR8rtFe3pZrw4SzEysE9BfuQemYTvFmXiDFqb7vQ7kvf7dLQp3lmTznGPK8D8fdrq5jOT1Y7m3PQuG/gm+J3Df2BfcICXGQxD5Njwhmu7foDmhWYc/Oju8LaV7e9nL0qt85BO+xWtiqsldzt1hVmpylnL+Zs3DjIFdqHj8+irQ05hipT9YvG4epkooaxesYQM2qhkaJIVSyxFnAWtmgn5G7OjNhcqmjmfmgTZltYSNC7jR0665u4lmgtneobPkpDbEfE3r+Bd+OwFMwYfWBcGekMpq2B11R/oFMIuoleg3I5FCzl5xg2UgCBh6DNpHgg/pIoQPJsiofq3HayHU5MUL6GUsAv5j9QBMcnd/L0z9kfOXbqGg2uemLL/Hhg5Ao9kDB66HKLEfI4gy7DdBOC/bHOGgznQYRe1Qxy9kq0XcB49KmVRV4k9+o4kKiV9KGoqTF9OBZtC+N1HAOBjqR5qOXuvRL2kRLjto6uZawmLXhHZ1auLvUGYtGsDQ8WX+gMDklLZiiOf80us9VTHRo4EKzPO1ITJo0smGbJ8exe5oOEDYhi4e6jSsRSg7pghcA5tsVQLV5LNWSLUKFzSEu8PvL2iY3lXTiYJONuM8fyO+Lgs6JzbbpNUDXlUpFHwKbEjMJYuKXK0lPj45UAoIZRVQwcxfPQWZtiGXx+ACJNu5yyxU4kw7qZ7HNEIAsyTOjMYiV2UkJOUi0wETFbi2WkNq1zLITGXGdL40CxYwkq1gfuFv7x5rJIpjKlD+1vEuZGRknYAIyWrsfMNlfKWtyuB1rmiMolr5Dp7SxEw4JpDsGeZCq1ice/ix0YOwPU3H7OtfY/8XmOXhOLQl6zTUgI7a3HCyF37qSJ0Pr/WSJZ02OWbYeD+0wnkwdZICSv8EyAzpqduqa40hNcI98IlmEvgQCn7Rcp/Zu9oyTdsy769UNaNzyHI7Xg2St6CRZq6NPFqOJ+4wJwecJvRT8ZQQYFSTO+mfmF30n2hrhrKQvvXsNd773JoDDie2FBZLqQzN9MF1VY4bNsJCzv7WXNN5SVuKX+JFulaS8ZMTawq9HYwsbXW5CBzlOPnbdISnOFS7rzd1iEKUhAIAlh8GbiulGwWTSD1JRpoBu7hyqA0ciaprpZ31OSTVCP3WqFf4xSyq1/z3Jc4cdJd3hmTLqqBAb6uaOe1hMcMWqkVGK/tJsE8jj3bVgqnHe+a5o4aYRAk4+J6AC5332ZdYbNhWY5z1JGT5vUYz3Xd6lIbq1iFsFVtCDB2yCTHFQTN/nmcRDMo2r2DSkY4Q0bBxrVQ0ZFxKY+d7DtzGKG99STExlj5wscYwQzix3111RYmtThUtjIzWfXfS0XDTeg/dG0qlxUTW2aKlbkftygn1wRSHNQOX5p0uEy9NRoVU2Cv+lzLgIJhzhYqwUUsmfI24Z1T3vSwJ4QRXpkDH0DPpk9J8PV9RqiZYnLzB4dzm9fuOCvH/0Z50aqxFgGpeaQIXL+G4oHIljaaJKFqBqAf2khDbwcGInqDaie23SgX5SpNHJX8Zp32CZk1lqAeTMl1DuDtQ2Hl7s7+3p+clsDlhM7i/ve2IyxyvOO+UNcBIoMEqGRgir8/YAPkbUuUr5VY8Q34oLNKrUcdCrXPY0SOhQmbsiKAqo8wUhJ71mVfhU63JYQgo8bQGqp++V7gl7vRIR2fTBkXO49iHhVzP1lHlFZ3KPDCeYSmQz5EpmnQVnY3m6grwJLsIkHoJP3QYIR5LI+ufBsjnEHuuI4riavhHeXnos4aE6byLaNvjD4wffRMADB+7AA3OiMrLDrqGiR3tU8zo6VfdSaWmZ0aJa2G1QokC0YKQ72RASE/ECa3hYoJx/v8jlTuwK9srGYU6UIMK1zkQb5jNriMODEOE0IrVYxY+36I/nB9qyfqFWCMGHKtOcO5+kBPcM5+OKInlFhYg7HyAb1Rx29Fu2UOI+jTGKORoGo8GjnByFdxJy5PFan2GqZ/eU+hVHUs3+kWcBmOP87JbkXuppgDhekb+YSY/YAxHphTgJvUBAQjviv9LCYtDkr9IW4e94L24OEXBg9IjZajtz1Hjbm+AO5ugZySdDilqsv5XFGJ1MPz+EmUKKd+sNFS43x6u/cz4Ez6JzZlGAWAWgbz1DQuRgCX1BIY72AltWAHwquA1JRAq9aZCbu1iEWuIESM6Ef/xKLcEQ0AQXU5RtFMJE2r+daaSsreIcN7IiF/ZuiDhTNw0ndnj6+9SwpM4/8oZgAk/HPqhee8UssRXjccu2KUhON/c7A/hxBiYrOiGsNfRw6kcXmJOEG7WBtd03T2yt182w7tFSeLirUsrPSr2emfQvOtzEcIMFGdUnJWTiONXPVaa9VQBsnuz9+n2wdL59luHDpmicKASX2iBFVamzh/zapnR/1sXaQU2h+CMJie4mfa3YyRKz2GD5xi7z800MMher67VPUZk7TK46AEBNWT5cebmx/XD9VIM+5uEsuB7xDxaHmphi6y03dhvIlIjjCpv0QZq1waJSjsS9liyq9jStSxg0L2yCdhH7URRtlguqUZz5eMScW5Cwx0cF90jHliOTd5DVjl/K56wPV3D3Dz2QpRQlu3/ru70pRG0ZjkxA9Rm7CkDjp96yrO+jDrEN8nwrlwLMIIXQK8bBwZsokYf44RfeT0RWu9LoiKtMrYr9yzS4WwsNyE1/ld7m40bBTRys6uay5dzWjz/bRMyb7kpjKMu1Fz15gMVQBt/PNNZjz8vhoMlNoZpSApLBpA35rjGiBooZFxAB8IrzPQ/sbIo6+exJZdP6i6wE1K8Ph1DaApCgNM4rqtZx1hTb0PpAsq2jVynqbLrNWywmxFka44esCWKERcR5RaGecxRWucQHIAcmo+8s2QWLXc4s/jXARuoPVw2bPJvVaYwKwZ/2cKQi97As99vFRId6nSZWiHxfCQBKcm9vODZ09EoVDZ8/hKfed8tnmUu5WxbKdnMGKo/clNj31veIGRoO4VlBejHb6yi/ySEPEfPx2vs3hMQnM1FChC7OImJWc3f1+MlvKgI4901KkmHtCgfszHL7msisfiWbVgLPd+2IMUNFYjZR/2IwPoZYuKovSVSiGy70v2EYxIrv3UuRJWSIshVOHxGKMu0jhwVKdkuGBN9CHTQedbZlJ0ge8oV33D1KHINxMHHPKqVMriYUhO+lBMpWrVle6tonRqwNLRn7Yp05vtAvfL1PTVhRLh/vdIa9A6fxkbH0d1v8O7rjDFXQ+w8XBhWOmK/URZaq1TEyIM6zmEPQP888EclAOFWqFfT4LpW2jp9TKCz5nDCFKsWjLSNS8xImHYsAfnREnV90uxsER/CJrDG0sk3Yey6WpZWg+QB9nMetSS+NIfn9xwTutDzBYAu6DVaLv6SFEqF5jJYPfeTilBm6zvNfLMCEfio5YXY6FEoapxIT5E8iLJerzcUEYsUDnv0ZbpT4XfgB7J7U8H0SL+IoUSCSTebQ60nGCEszFGJPTbKdv6JEcWnCXNYNNBIugmwN91ZBrmzYbn9fLEQiZFkf1+VFzddaFy5BhH2jtz+T+RImueEAvew1KKjHoKfPtrs6Y8x1bXwA1CPlixy9xM3Sl1rSt7yQU+RTGa11iH4tVJcoyVDQNpsozw0Th3VCU6JmM5yHzLSTJY5N9GG6u8/WYhJ4DW0SNyAEKVf+X/9JMwoTRYdIac++CcBEHC2XQJ5ZUgiirIecRlRJKu65S7Eu1SBjtfiq6RLXBDIdizfSFE/PC5ejIGkD++qalJtF+pcOd8+7gZaOATsBujz81vLbfRs24vFQej1bWm0dYgCUgap4i+oD4dlYqYeJ9JSdd+um57OQmuoUQqGGNpI8KKs/YF1XXNDoUW/SjH9HpPEOWnBlXUem/7OJuhWu2JJLSV0+thpDI8Dwtx1w7reQ6MbuAjJaJSwonIiIxjF+PhMyJUAmwmXmyTEDYX2FMEmNG2M5ABzuXYVEFjd2s/pl7bltNei4C/o/2HfYWJYCnFcLdjTsM1ddgWauwt05KwMoNbqJiaqd1tQWX6PiP7X282xILaKZEFXzR4cFdJCOyoFCiXPvBPFrelI1g8LIXKOOTEJjqFldLS1cP3aicd1btfV8uleqzS6+XlxcjFolHtyokHaFQXTRkRLMUsHfDXTYN7XWHViyeuK4+EOe1aQjPBLzvXv5cNJ+TxDAMgRKOj3eAwNjVdmV0t4W1XZEWUUnUvrLbXqEZrNqLdWXFG+7dHQ5P/zhj7WHP3tuURD5J1+TyqACR8K6v2mG+nRTJaeKzumJkCBvRFYZxxI1Ppe7q8er70Z+jqd9pwcf++ICyUNfe5barUpUno7pP5p3YDh1zvEz4VnhwK5EVeUBmuM3Q5Sv1UGrVWUpC0++j33GqzC7MUzUHYHbnycxiRRjhy7UZ3V6sJUkWTU9Qo1oADiVAlbK9+87vqao46SjJNCs1YbDRDkqYLny3te/iVMUe+YKls8SbQMHSI7gk0xyPsRbg+N1e740QW8pqn3ftqVZfnq32bPCrnHX3D1lT4OzYFLKq3RkWMXjmujUq3y2suR0340drJn0KtekqFzh08exMyD/ma7UxvmigSBihyORhqHi+CpMvjch4AqcFFD4ADYubN9v/XHqUxZ5uVR/spSuF1KjVKqt2PCnhRTPNasQbkB+HGsC47AQDKNXfbK5d2sEoD37fNDb0+yCgyEexswNln5QjeOpUmAWg/v/lweT7IeI5jK2GGsh2vXlza3mj6GshGY5Mx5p/NdAHNB87EJa1pN3V9U385LmZLGyBNgVdSAX0hsEFJxGaB+nVynkW41rJmGgInd8B1gAdMU8Pi4K1Ii58oB9PdBpjwImzk8uP96mFpkKk1foKWKPw/iJEu0rSFtbjrE/MyP1WMLythlNs0OZ6NpRST5ictEUHwud6hECzRiZfOt/wWUsVCmY3SB/fQ9AbazJKQ783dyW81LbE+1cwF7up8IlL6oSHMhI7zZpsFkbHx146a//KJ+5RyF+SHm+vHW1v3u1vHxxvVTg7Rwd68PzYRxSRPQP4SGMrKpqNmWfvZbGEQcbglVG+4GPcld22WrDkfbxtV1PmGUFNZEi7nXen+TizaQ/088Od3SOGRDY/ccrHqIKhR/HqF+nItW7OTlbz8xOFGsGErsSq2D+2T4NWbHWbUONI7l+Vs7pxABRw1EXzyHOvccoh2V2a7cxuiBZaJDR9yzXU+JAl7eC0IK/58HqM1aecRR8ScgLuMgbxkYGLFpcCkTm45qU1rKzFocvj3dK+m2gIwIhQ4f7+Z5cx0SXpzU1h2r5iSJPtqwctmu8rJcbYZovw4C+jR2Z3DSFSfxDXvuV4Typvp9tpYC7Su7iiF4Y6VPPdfSVdkNwptEeUIyusXlq1sR6mwVBPOV/cz/VohK2wndDaSRvAGx1X0JqydidGQ7DTTZaxX+rhP9hFm0VlCG2t3d0WNE76EYRWB+1mEgMh+N75ndW7ue09it+UywkhUtJWXCNtsujXjWXAM54iM06vCv6erl0yHqRB5UinvGXzz04U5AvWVEUqRkWNZKxg3tk6A+RmUFd2IOlTXm3PLVp2AAg/B7WQysycfiLBx6ru5gZEk9aZ+rfIOzfVaHG6HlhWflmwLwVJeUd1R3K+QX/rRUbWt4qVttcXvN6YSDu25nWHmiI/pBkY1ekBT8uGBYbazAiqa2skjqhkyBsdR1GOYdK0MOw5h5M/ce7efTibDiheuQR+VSr1S3xu/f4PYrdStoaSL7KaGf9tBT6Ri8YlByrsQmW4ak6uk4YxSjUYe6tN+iOZUxPgeNSjY6KE4OZ83P3+qp9OZAHIDJeZamQg1+K6jrEXO4ErleUwdSaxEiIXlsvOrLISFVFoj9uoZZTmDi3VNNOhHF+tWiLOsUmKQA3hdsW54T0/5a0zCuELjMz2wIDgooAKufaujx2t75QzqHRMI/+brnENO4XqBrLTH2cIPPrTHlXSFyPDk1dBb2e/Gk3bd2y7S5e4i9eJsDOHL/2oY023Gy2ilINk3vA7eAzVxfSDf7WtI7c9hSmhRy70xILIu+PexeHEcW2YpFxWJw1HdJoD7bGWhrBJ7qyZ6Xr8sqGyq1rocpU8yf4IXspX8ARxukMvlokCDlByIjOVRmHVsu73jLb7RihP8zXimoSybSLLJFTlhSz4+mHbXynhrIdXR2YXL9a3kiSgSzpIblC1iqXskR7pI500x2xg7hEs5l2vO/XPUt8rujh3UQcQxjvKDQl9rqUz5n41Jmg0z87WebZXqaiacLU40z4f4vIwAyAxnm01I92Z6EqB7nKFy9/lh242HXNa0buoHAM8CwKwU7npbJccSoSOS0LK8bKmEx4YfBe5LYxuTeLW/eXY0SDJxptt6PK34XCNM9IHoKktcqh+av77O3D8NZyMAfK7VP5d/1d93q2GqmShX40czWMdELTXmNIW3FvQII9stk57kw0ygiy0Lo5MfL6s6At4JHTTNumVSVhTz4FxvhajKBhEKoP/dYLPT1SzthPPrXPSlLtO90E/uTIhO8mAw2TUnUZXYo+cDWb2b5j6RwerC9Z/3R99NTZHbjdhWjh1feJZqHBV2Ro69mkeH7JWcZv9hFCuVQoQaWSln8LUDgLV5qXAXvW6SeysxX3bahXl3GL0ZeuSzePnMxK13CQ/GVLWzf77XVSp/v6mJri1XV+n1pa9mLoazYX2+rsb8uNM/uHP1bdzfFyI5tyf1knsBh+YA9XR8/D85UPCN6cqH8+tMbWr4qhof0qjW+KwYYZ3JKVzOXa6E+H8BErxmt+/rlEYvzvSzRWB+PW6Ea4exZXtCKavdy8btbHhRwWI1/jIiE6zaqi7s21+HZ55JHEr1fgX4L2shW7J/qENXvhV0W29fPbtkfJq/26ESy6VGxtk3okMoJ0Tm/mR65JhztmZqLu7MXOzOgFEyTZOnPGHFe72vm/VRKUmDVVSASgacsxZV9hyMC35z0/f9z4cpn+ccQvVskVWHUx80gnZYncfWxmQ6Mp2fatKp/CIZT920sKKddm8inunedee9/FSYJqHTq1PsfXXFDks7TmYp7766cjwo2ogk5TnlRNieowS+r32s+5a9ZvdWytE7Z37k/Ve2x7+go6MfauHpDid1JPGJ3wyfNkhhyxhreWOoHQKfUXC6REURRW9BNLL9vVIxsdQqdRtyHGRaVXzTw7pK7zFNA/w/wMhkumTvhdm5BrITjtd/P5ifpwkwVK/anSS/Oet3iSHojWYmimD/t4M1yKLQcee5NIi2w7hUx2Tt8Pb0W02Usxe/A3g9kUZf2XVlQmVW4o2uHtYeMXQmkge1sNcSJbGm4R3qiD2/9C+cjiRBX2F62xgi5bZtkRwd5CBXfxLCzgbpmp5vJrDF+Wz6cY3wM8Cs7Ppg1I+F5SB/JsT5YUh8AQVTkq+BZP8PcmQyXfxm4floueAnY8ZjG+Yx8tWYZ3ZS33Im8+IF/q5nMCJCesREq6MzzOBYsEv+fCdM13V3616rjBGxUisUIl7OufAGXZQvNK5UmO2h1rMycXg23MhYqpCoUFhrKpNZCd6hEMbL82+SJRyGNfEkKJ3Tyo2jKJJ7G/nL05YOvwQ+rGjjw9S+zGJkmEWKYTQQ5dAWjiOQb6dswUEnePRMjZvwshskef8PQMIm2sM4s7PFM+WA6bZ56i2y+Tbxj8YCz4iV7QmzrFa1jgoGI5nv9bEcSRNeB3RSn30N/Fn7Zr95kc0mQjSKozjZ+x64yCfJ1/buhncY137vOaFjPxasdmLHeKBL5gYJhIHVVSeg+Tu3+O+aZop7BS01naP9CHadsTtyoNc9ocbYOaEndX9kwnwzGlTCWcqXpbjZq5XvRrbzFD1X7c1AR4crCqs26vc+//J/NviDICtzJtQf5xgcmZ92cs/MgxJeV7GwantP4c6hH52p8Xxt3jtPhxWsx+QBx1X3BXXhDv9cDsr14vZpNYK306z0mWqH6+fK2wi9xLNEUhZezbLsHeTxVabc0F/+S4MxfkKYMEMdaDpy1xj5W1F/UpugTOQu0UY8q9wMFQW1uD/wLNEt7VRzB/GEpY0fKxFocBdrC0LV1tPN8v82+JAkAMW6x8i281I+KHp+pudVTW4HQ+J4nEVtNJ4x50L7W84k0PfVvXiarqtDRdGMvv9SC3DfD/L5yAft8rcx4raUV6w6qnhgK+IvqyV7OdVolLCZWRVr/x15TFI311BTjISLkFsR1sQ2aa5P4nX2rk3bTF+b175PvyFUHdsbDUIh2tmrwK/uJaETlgfL6wEAMMgXlWUl3zX873XMP6i7Dva2bSBqYhwxCG7tYcm25L33HvF27CTN//8vLQBSolS7jeN+/WT0a23JTGpCj3eHu3fvxhfyzCQDyYaGhDURWpR2KNIIqF098ghYor3y9Gw+pzgi3XQQ7c/wRZYf99tRyRDTDHcTjfG4uI5BOPepF3j0TYyUQH35CayqbL5aRHOJsM3GjSVWbftT/9NCiK8WVYJmI74c4vxG2UF0JCAr2kiDIf/RbshGYbbeRu8Q5Pyhwmxvvcy9qPx1pxUFnm7Nc3lwooUhf/p0Au3IFGobNLRHMEIrJi5Pu2jUjnxVWNjGmL0MI2rT82ua3m5j1djjfchj/+/b0kTrjYj8TQabcM5p0H2+OPpyEZC3MLIO7WSFMaiFTCk9YXb3MNTWHeOnOwa7/MMV0bxD3LDQXPOFuOSVc28rTwzlEz+eRSa1rJHxGF3H+kXY2QoNVKIyWJXlAkYOarM6rdw3elOcmHxTltJ0g1WpKaze1CQuF61jE4EPm76hS4iVPGiU0ejF3wQzEHFgaV47U5Xse/zUAMQKYbAyvxu0Dc4HD7ZsfhIQOoYR6gWtl+uGFErV38xx0CN2xWYZYx0G9Y3UcZhgsZQX2zGcL+E08D5685T6Z7cXO4sRpzwIPEK5pU2ML8QHPZr2o3fRGZjWK+uTe1G0NdObXbprLhosia5vM0zrpKBxVNf0NOOki4+NbkzxzhUAm4no1CQuRHbBYmRYcWlSatuWVQuNXStjm1yFmUvdEl9bjGg0rbMGMGtbSbuky3CeXGtlyglhefT44XPafFkK26VYiLT09c3yFWoZxyYTyQBM97hONNWC5Zgdr+BVSj6MEX7GpJDx4erORq8zc7tZ9ugr2tWI6lHYwwV3yL3D5gxYNe+rXRr4WkeCWAMsWkGq7R10hrHWaVxfAwztOphyl1eoN/LlhAGe7fLJi0Xs7dspA1UxDMjKueiz2BrDyF3CrNIeXEUbl9dbEaX8WPsWUDsmDoEW4hYXGjGr3oVtPl4Zy5FEW1chQPVL7eHFPMNv/XYWqpgtaD4RmHQkQOlHVeCVkqp8OLwjtGK6qWUipMCApWqcvFQ88nczciKcwoJdQo7Ms7J0B+aN2cBOg8z7rzb9jjkAxsMbvxHT9SSslebBtL4MBFcI4V1NaU0eOZnAWMRO5pHGg1bzsNPZ83mm4AX7o7+0tzLIv68EnpGwpJEtQjxE0sFGB9tbw3ndpuFZn4XD0VEQlZm9Ujvsb5Qjj7v/NAea31hCN6tihiEGJvsCWEdhuBLrH3/qiLeCQbaFRh62rQagqneL3thcR95M8ChGKL2x85FbqblTdWa6mV03snbklNfMrqYByVw67QH060/7tdQ2VuxVApKJ9wUHwsHhxkTUaF7HCO2YAGMdsvsXGxx5bftiLM0a9HNRI6EbLzWrnF+DYxRLInM0YouILw3TCJvesUkkitHJnmdx2P/jZzng/+YsvHKVhbJ2qAAwZksYL8QLNXwQr8Ge2Ebkw3bEXwJYb9WA2fqL1XqpTu+O15iuxThGyI0JwJaCB9sz2wtsE0K5am58n644NjBxM1JFWRdkkvtWhjaA2QoNrFzUrcQgnoIpNJlmRCeH7LjpPkDualwUxfb7S46K11YaOcNI7hhtRsK7KQAGWA+axtewsp2ebhee8QKlIQRpNKLktX92WvE8/1+dhRucho12+NKH2LgZENWt5VDE9VjVTeDwscUjxVivLp3DWEvXiyzuTsKvo/2oQRuPYuSOuBfm4n7zhzT2R7Yo94OyH6xZEg69sDvwnLdkPxvtul4rzBVTZaflIcPdTpnD1iN3Msp4rwckp2A0/dYygPcrFD2KnEsycq1uEc+PvM3bk/vdbvRNmPBk/eEBG3viTRGLkXyk9aUZps+OySgZjhue9r9V2DjxblXCGuuwJjssETgWnR7DHdFX3wn5sB2hNwwExICFiPHT3EatyrADWDS+j4ZILwrDCP9hhZAfzOiSzoYA1g6Xnx86Se1l1mra0hd75R3JrPWDdWVPps3RNjQmFU081wNIYL5JJtXTmOEcQWzLLixLilUI0X3htldoxI6cysHY+ts9ATJO7wyHzXSAmY6IJWKUf/MFD3ROmP1d88Ykn7Xo0y/U46n3siaYAgAFijkNqQMTliTzHkIfss3aMQTVjsDxPK4m6YFzywO/uaFbf2C2qFlMCV8yCCmQHw4CfqqySUPZxAfRFqC9qrAg4os2KrtH2WG/k3ny3uBvgk6FEDrXZxh6XTqB+dViveoeDLHQVr5xGCGa+5TqaL3mbKhcyjK7DObVoGVwPaC8cIzGScBrgC0li3q/kwNHfrMW46wd0bEsIzja26Uftp9aNL+OMQhHMMycc01y4s2j9tpDl5IRF5sWuP9ZHcvfNr8UFgww4HFxK3xAA1veKRHbx9FleaXDfmEs7m97hJZrEtSCps9MMEb+Wl/NGNDwRFqlmbK2LHalo+ONjqHw8dvEmcVIvndMLGxHof3ekvpuvW/Wbz1F9DeJG9w/rcUKK4mZwYhss+p1RD6cY+XeWlI1gaqB3zUnhBqJRI+6qCjz+EMUzIiVMNxanGFGcaV/IFkeyBeUSvvET8zLjmsB+TyqpYcvXjYDwsta8UvNRATxCceIv6c3SvyhpAMaI6Sr8hLwyNgAsjo+Yzy7ZZGuW2l57WRXM06aiW9wz4tslNYIXPJ7ToG6ftS9qDdCKYykroyrpUXifZz7/U3Mg3naQ7DDjwlHmirr6ux4oRO/PnA1KqcqlqrMQqLResox0qiJwc5MT3mz5ueC23PNUw6O7Ot14BNPOxqIj5qUo4kgFf3Dos9C04LCG+NMO2V6nt9s2BqJINeLEAF5JfNJ1Zvd+YHkrbDGRn21Yo4tav8UW/7NfAZHprzjVbrLPy9OHna/L8+VI4+6H/Y13lLYEH8Y3VL9bxyYZsdXDj+NAV31KB1QFcE8EpjN32aZJbUcXQ0cTpIREzEuW5z3TfeRYLm67Ref0vJOg8npLT7h8DCLB3uG6dHrSKWqmwF6YvmmLI8cAfsjA8anmyvZdfM/+szEMgUWymFzz9Zq+A5YZ/Mh8kw+eiaXbPrwvnK6LGbYwTWWRqhD9PTE8tc0MdCAceckm/csO7pmTZyAGcs2QezQxYEvjl26YndpGRlJ72nNu5r9lgC2ybq9ZnN7RrH4j+Zk1mjGl0ceTbzKnh5uzioedQdxPPuKRpiDTmHBA69MZ5eJTEiYFX68YAmva35g97gTTBTBivolscR2Olj3ZDqQCCzP/VfKAsSIf9lV26wPQpN0tqEENivbhEs3UvlDoig5txh5Np2zWyoBx7mKWn3FDA9e7FVVHM+0ypN8niksyvmlmbQV7kYRdxGvDkrAOyO9viOdOHKLVvILTW6EMSEKOgKZUCw0qfVDMpqoNCJfVjPx2jkIuaCwI3eYEOqy8vdQmJvagl39JDcamD1VKptXIbOjFqy2BCl4JU429bvAbo0dOQYVA97ltHLeAGwUkMLGjRapm/BYNV96sP0B0+5V3WsB2CDOXQbsF687lUVfEzdpUw4n0oNYOno508IbBdjYdNIdtinHybGqiCA+wwSbb0OnFq4oLBfM5PTpWy0xN2JL3HJaxL2azvonwu+cB986oczPdLjt+Qt5rk14KDIsvOTEdGGvYyxTaGlxoBYzcdpGK6JoclOrY8u498qBANDzAlfnKrm9wA7eRwVpoHNRSALgalBeZjifKisaG4HHo2L4nj9enm3KwQ/+1IQsLVCq5zVjIcRxK5y9BUtscEDWz30ajDxAxSeDhdePYXZfyZZPePnrzYCnqbabdXCYxYiPPD3rJJUlo7SlKVxi2hBlIpnN3Pt0y2vexaayBWF7bZgq2y+wHOjlyOyJ6fLPHmDIBWoWOSHBjcgPxfGgFaXqB6FReaoFUxOydBH/RI/Olamq0Nt4IdZ4UYAxE+FT5I1g5LpAh5cX5XuWN0ZXd3zNUWKQ900kdd26mGOEHzoQSrxm8oDMjs/VGLHcCfYJMUIo37xKlBEXyrmt2k0XhFn5/UgqsX+nYEBLVF1KvPIfajDq8yoRA5mwoA0YVJxMDEZc4jZjjOslUPeEBxtVARjP3Fr1+/RLgIrXHsAwDj+pbCaDF5Dclf1oYeBrAGDQXiA5ousQK8cJNUYWDWlt3ugmEhP5Q3nq0y1kUhCnt5cnD9er+ZMjklM09EfBgcTFNLsCPDA4Ypf7m32JRb6B09/zABdq39YZViGWzakJWZx6KxLCrzEWy1pd7tse00zTIymAyba85q47UMXy6sM4HGaen2CQk8eOWHh5Fs5rK6SEH2uIOKAl+8+w4+S6iZaLgeemPuNCtohN6XkWlkEsntGwP7g8m4pCunm0ETzeXreaRvmfPV8bqi5KCDWLfGtSIjRCoqpq756D0zF+xZ87CQVACGxepL0wriBKspGafLGaDJ0Nk9JqAuY1GlXFr0EE9gglLWtJN13XqntnszGo1bxanJTN+L11xCzXLAVxWuAiLYcQCgOI11YIFj8CGmC+Fm2OVGaa+qQkSJB3xEAs9TBcE2tX+POSMOX6RCNlhROSTZHan2ViqMSTBVk9bXfs69cXrCDi+hYjP6eIO2OIjY+WJ1Ayf0frc2PkymAEUnDk18Lo1RfhQKg99+s7k7licXVp9qB4lVTmy8qkHH7daC1la0wwNYcyqW4ebVQFFolBejVTV3a9rpmKHeYgyW6+9pyA80+LPbou8WzK8QIRNG34V9lgY0vC2P7cGJlhWLdaAThycCeIoF2m9f7mxxzwWD4E1yqbOOc8j0LEKfGpyVjehbhYAzhUCx7N+3k57x7EKagUMIY56mZS0gumIzcenW7VaZ0bw/jmTiSBdlN18/IEUSpNft4WI9CK2cHlz42RGmjqJWBd0xtihJvch7xpw5vbwzCeX/RzSaecVqEyiODepLQYBY1w9zlUF+wbLUgx02A3lkldmKlaKGvPm7YRVQhFjIjS2Qq8jREsdnVLV0ZpXaAosO0pnuUJrCbg4M+OkSXsZK1W8Rwa0C0Cw2WWjw8KD8KMcYywvc3TE2nFznOMyPx6vDYhGCE/pFA3jaV6HLmkoG/sepcSRBxip8aRZbPnTJoMJPk4ByFi8Qo28hi9FHDkIrJhOTgczZlvetxi5CSM8ae3I/MAqd2NamVwrsmUWNLF/WmRQ2Iej2FE3C+ENubHAIAzR5OvxoQkWr2egFTI4/CJELco4ej5JQFMgtPzMztSNhjBOUhCq4GIXw3KBnmSw65HESJ0024Kz76pc+vYnkCG8NkxssSSzAZ0omHM2jLb1ahE60kGkvQJxnaJCQAwkYiMF5TxTWEhez8JGNGCXawuLmT8JJcL2mjI1T9qpiZWXwsyjAQDmqI+3YA6KmHnXxYW+1wrhnIaMfO6TJ4ttZUSa0fAkSn+5BiZr0JOAhmmHMl3ad+hrY41tDhewm/tE7veNEN9VFh4t+q/Z3xCJkpM/muM8Gge2rLHqu0eH6dNU7IrHClxO79vngxvKQbMkkuJ37xpa0gg0YOcNTEqUObtRdc6nTuCLEZ07Sb95OeaL4PM4rpfkEZg5mzicW8nTIXJFbyZHmAzXiV1sI1F3o8RhKidD+G6/3np3OXbEg4ZCMF+umQUgoh40Sw4XyDHCHLruFDQA8xmZthbZ3+QwhBL0sjVjEeP+1Vb83KPzAVnbo6RT1rTK675wS5c8+H+2Qp/aW4uaqVgph6/mSqRh4HRqpGquIe/Ho8gSsxMIpe4/zmPjwQlHN4zEarE10P2xnVRngWr4o7nZhj5wUYCDgiPF9gbGJF3R5o6rsQ2Cco7F7sVr2c1vrMDzn4RI3hx6lOvgQvBP4dt71k+WcjkcjM126XSGDPntbVQ0YIToMLRt6e9X37Wg8VmpAcZ/ud0ceS1pMMkW7+TF39TL3T/+sfTo1V7HslcXjMcbYrAS1s1gV/FyDTtMhwrh11XbhoM2ItnEyQ39MH8/DTzNUamArpTn3rlFW4sTtHQjd8PnpeHnuk2qHVPJbwGEtUlfBZAhmPv73lj2pg2yT+m247QFD9/Sqrt6dn+wf5/LcmBKg+YyT21OR9WXh9p8pOFzhXPNLlc2sejLlV8r6y+ChK4Il0RC3C0yoHep/OsY/HEfTBfv2ZJF53GxvC5fQ06GFCeh4EV8mtDDCRYFz21VgzDr2QZrzj9DiYWGV19b1T7g3NiZ3tp10KG/B8S9c1krRTLhQfvP765csikjHv78u51DjaJVAPvD7r93fH4A+pRc0/f/7jINXsobydKT+oGhrHByKVt6nMzO2IxiWqgr/6E3IDCQl9yjCTN4eM9UIofaBaBSBlmY+UavUXLnPexVH9DzzofOUL40dxct1mOgiCIAj7ECCFbCkAIKUAlyX+MEXoJ4kLX6Rrl11vKKZoH1rS3rSPaezFevHz2ri1vTY0aGFEtKVwg4J2TY1uCcC1FficbIztvpd2mPvNCD7l1mA+G8UjUccZAYvap+FacoaSCHsdjkUwZu/hZdFfbSqowTtp7s/NXhaQ/8lYwTnbXAQSTax/zNW7OGc1m+7hBAvK8ypg4pkNfh+zS8ESU3EDbRyRnzRwJPO5T/Dswx7pZWUywAo7DrEoFGUbO7S6SG/P6W4aRWeOwPzdGpi5y4/CHP8RIuT2yV2MQMXtWs9/AI69riODx9MGISqO/JCDvPMBi+pEUGNgHmB3+6ECaMEg/lh9pdivlwPcoQWaKguv/FAdSwr1a8zkyZs3jhAZRs9LstpY3d54Xfb7BVguySz/G7QgkW18yM3uo7yCnfIuqEqrgl+CM7NsKIN2w7ZvEFgqnDbnzk2PkPG8Q2KCo0Fzzd4zgAgMAnHAtw8jPVtWMlh/PH4zQaryjWn2p32kkcRy3T1r+ECNuUIeQSSaA9dP4Y7nZUKl4eulmf9H3CCKEBGuiDSL+Ira4az8yTunmehwrqRcDeRL0w25Ban5ZjoEds9VMhUeu5yQZjNX56kxp5iYtbMgL2coKNhYr98Tm4qvmzYkhbv7e2hdZFLZVOHl207HHSTBgMhHDmK2ffY+P7hSYbMLoktEYgZZyz/eDIDIPeoEU2UwAWF2yGSHEB583KU3DpYiXXgJOKd0UWEpxk5SISxC1cVGUWHNgf+P4h6zxwjzXOfU3sM+uZXd8OIAEsPndSkCD+SGgYIcs2vumy+brUjay3Ljk6ifHyKbIorPFgqFfHAswxOrVwdHzcrWQicbZd1ezr+bW2qM9CdwOEdWtmUS/GGo+fJWHACmTAoNItj50K98vdAAODmBxeObz8gxjF3FaD+eIZk3ZVtxjYf2F+Q+r33QqtICRSozh9QIvdgZMRcCJYv3twDsZYoR9pRX7DW2aNztWHIkrsxmfHCOtDCO9qJBj2h47p8RdQvnyEhR8SU6mn8bOa2XRkj96fhhOfyyOikSc76o6AICZOD5d4mTq9zV+FAAwKZRgmImZSlNB9Z6tJg/UHWL1MQbt1wQTQoWlMi+PhMl+dXAvb9dpWCp0MuAs2h1ezBapb7Umfc8KhBuMINtfMzFcmt9cXRuvw6pXGLe4JceSpk0efQ8h55+NcldfXXfer/W++DUVG51DCSKNw++B1pQnv8dh04IARztbZwtMYMZ6K8B+xqodVigt1GiWL1Yu737uPy63mmV/fAQGWYB/K/RCv5RiAAfk9Q4MrhYB8UJb+HWNvYE5Mwm0awBT/+QYqajMoRZGQqCdcYz40YXE2tmzkU2U6i2S2hz9teNqM2nLEMygy0Tci3gz4r898wcYYDb9Y3GDYbYkQOD0D9hTR4iSwsg+M+gXIUo5MmKRdFR0hf0LRBy2Et1IE9OIp+HFMUFeYgu/fMaE+GcGI3aE6/ok8CQ+sMoqm2RM0DCUPBvbqsNoVegjX7h2kBTDlNB5YyWB+2tZrsd4Xv4RYpAsARB62uWi97vjGNpflOgwJgQGNh87WPz1uh2WC+pjLjHq3y6aQkbA3SWjGHH35T8BxJDDHwj/Ftsq5zAe6VCXts0Vm/xGYwTuPb2Ry4ZR/vTJ7UimPLQWTSFanHI9suYvmXbEpTnu7xWsSPzmbpa8X/uY+YXqpTupXGMpgDrShiA92Qz4b5kSoSQAk0xr7TWkFtaRS+ryfbPj47fjEdHGAHH4hbp8J5SjYKoRxHvGDz+7pybl2DC42DIiWZeTwv/+vYWCGOPxVgd0M5YlCJmmnZ1ECAWNAVNPvk0Xx+e/aArKtWR6el+wxowCGZo+DsAivlyk3vvzaUZxqL4Vd2pa2A8DFrVOWH5fpnbWeXPJBYBYslVKCP8ajupzHiOXL5kT0zH1wME4q9E8m8tuPzlGjP4Ixi9F30Ce8HikBjhc8QiaCqoZKV7HIm+uMPg1jKDFeCE8vHBkv3qcGFasRomSWB1V6PtjVuwAHAYXDCz9ozYN8Sp9nwzF9dsBSVKHUDpiH1Hk8h+iCBI4dRGv2eQZJVYc7lbv6Lm56nFS+tF+FyNtc1r5VsQIXR9PSWMHDk3uy2/YNnrDXX3Tjiz4U78Uj5AduVDda7Dachp/S3VMPM2sp2fz78+ngRIY9i5WlQmuHfnYk6pC3tc/3gzftI29UqgwTroUEUT4bRFM0CKI/2EetpKuARnuCTXilOaMM1GCPe8nBVds+XJEmtmrjR9THFwt+0iX4PYsPzpN/wEizvMvjl7mKwAqlu0V3kplBxwc7l+E5vy0xA7eHbmGl2dCMHPkSDa3mGrF7Mv7aEuU8j382o1hDPFuX+rxj75N+Pj3zBkMOg5916W3Ns9E0SYYbT6fUqKPPlhEn9iOaPpedoQ5KtrkwPDu1HQxInm2ct2+nZ++l7C/U5/NXG8AB8cR+rWZw8ECdkRci7+RoHwvrH77ghNPY9xw5E/yzpgEAwOTSwe569+A2j4Ui+/DCKHk4lVOEYb49lzpz9sORCNTNGqzHEys5JIp8phN50QkMRbljBNSB1OX+MSUZ0KQ27MZ0yteLKAmplJxiYefv/05Rd53/ZyGSr52NARxaaKbE/4rw5cJcreVw9YX0k6Tuh5vlaQJNRmWAA7D1co7DzdGobetDYk6vmdCPsYLHiHv1HGtpK8fexe2EqwzaH7eEOq25EAB6pJMEdK0l1YIerBqtT7yZkHD5jNjhFIahDiPIIZrS+l7rA8pwNCO3KxZPEodkIoB/P1RA7V7xrSl76JfFN36KXCyH0Lf16R1GgQXfcYwFpk2+3uPA6AzNiDTWTt7RFyK5XeeoQkiwcxrHQAAe1WdDkmy8VU6bg0u7IUM2FekyShgvNQp9bZBXwtznFTNE/WZMYI43xHW/a4FxdELpq/kanuQ/5CPhNiWWOTf47jqvEKSx7JWoQ394db9X+yZ8J+YWtlneJZMUdenmiJfflACO/CgLUnyTu1e6eBEsmpHrsbhAVag2h56v/xvKzZq52kiCooSOJTAMIRbHifWjngk2ByoDV67hCLaNqyJW+LSeRPUXPk2P598aoxQXsN2HxrRcDAjvTMTjC4r9cFZdq/MCeeu4RH3wldqo2J2o4n4V9DP8rL7i//3ylpSOr9x2Akfvoeax5KxBbyAHdgk78MIxgywhPXmacim01jt899o2aElZtzm8ZWAQfyqtVgEVB85p9R2RKNgeUDwxWqOEpfOGGt64lK0AwA6A+ALE+D7nxgjf3J3HVxtHEEYdndm2+111LsAUYTovTcbsB2b+P//l2T3BAIEsZ1YArIvyYuiPOtu7rup38xwGdwlOdL8oM4mz61owsO1gR7B+FAyFjgZVswjjGSbPqel9KTXsCa65cHP2X62miRCKaG+PyyoQFApU2FZXnjxa7I1yYzZFUYbEwoxg+FMQBjjv4yRdbfMF2vTa22kmGFAuVJ3uOkxPzO6nlzR4j4Awq7FSJe60XEAxC843t5JU2TDJt8xRibYtrorSlUGzy7o2AgjXSs9JLDqD9CnaOZW1WM/hOJVxCQj3nfrjejpn8yfSTgqG6NVO5wmg8DCMuWjLU1pSukM/8UcmpuXaKigVOh24xP7h7U30G/5IsMvTktNUmG3CEarywYtREyf06tmKpkyDfyuwD5G7D+Nzydgxf1rCkzCClpdVLjJ2h2Dd4wRxu5hYKYH+ehcw4U1K+ZheoDqy0w8LFpQj/259meQjEjmu2WJB3JC/tyPB58ax5rWDpI8f+DIcvBZ1MNJITD8Nad1MHPLBuFHjQp58bfzm6VCodfo7BxL/qSEyLx5x1XDeNsuRLtIVawH96p38tKD4LD92GkX25yRpvt1YTkwvnFe93kWM77nkh6P7mGgqwM9shg60sPy077e2WkJMrdkKN73Tyhd7t58/vhpRUoSLFnJ1iNCyAPTIRlwRl7gBfRuPpcbnS359HsyXaO4MCt+bY4YYuFuPqiarac3L29qhxWBgppEYXq+DgQe51q9C7e0FsszSe/8j/Xjnh6EOoi6XHLLSh4Lp8RgAjIsNQlhcg8Hi36677lcA/v6fp7mYl/tErsg3PEBwqFUo14oFjRSvLMxYvfrRSdVKIRoAaxqOzXry8N1gowRH15aLUI2lNad+Cwtcj7sFGiKSh3+EkY+7sYiuzilZnZXgpf9omAKUSBqIVri29Nd4QBRu99URFGoxtzpbQcfWFaabd14EtR5cDd3wC7/Y5WsdS0bkvZWRsP9m+P17jWmWhvIyO1ypjEO5QhMYt+Oe1ctLcVKYEakEE3fshbxyuqEgeng0NxYe77AR+QlxVCZy3CPkKEv/U37hH4NI1IG86sbX49ut79MB54PL2+LXRdUnZ0oxzvMP530zz1v3fKbsyxNGFJUMT7FBH2qSL4Al7v9ziJg4B3j/f+z8p4xUtUD8sygH4adPjtq0orLGZj+F4NVHc56X/5pc6P1HHvoBUJu2QjdW+fPvsylOC1N6aWwyp5xHP0ODcUf5Nen4XPOfzSAgFQF1c0u6nOcVIGUjD/ZcAcXuq8sEzsxfsiyUGo9r0cTR5cA2FnWFu7I3UFD3HHsv8p3amwISHC9viqjgRwDZ/0vzp6fH2hCfAwdig4ymebdUog0Xnvi/526fR5dnw+rElYtxEaHGCa5Z/QIkHkTu20pZAT3fig0jYVANC09DVwS8tgnAb+Y+VypSRcSgU/HkFjlaVpXiA+mpQMjF9l+J+b2e/4h7hTuIbzTmh4hMm/QzjnLeL6bQHj2hVd6ruyZaZHByVQxmoUrc7+gUKzIJ7I+c1+G8/5wnoJva6ERNc7KYYxwwrzzSbE4IowsoZgsL4hUpanY9ABsRfsxRCtb7sIVqsLFt27y0NagUKZwvt3MFx6qF+0RtpKFMcw1i3j3Exmq7xQiE4wT577jdrZY/uKuv4H7u3S4XKFC4yz0I4zo3tRsQyP2e6Px0mPwmGe+aKymUcWIMTLMC6gfUNUzXRjGiA2G1oXIjQgjM2VFTSyEdXE7nzpzhwweY4TJxdTlRSiiKi+tby8bHPSfrcxHnvSOH5kgzHHy1X0+5/b6ga+ZvimuvJPVRsOHRKmFSJpbQmdFJSH9/94e1iPi6uZo7/J0aXaAElFvhwJROOg4TXMQcELYk6mG7mtx4g/Ft0EHhVLXH8yX5/TI3ycIe3IEGCEcAlWi9xt4hUKzToYeIzsspOau9h+3/li8KKusn9V2AnZOv8w3LFVVt+/48hUGWRvneR9vXn95i2jKd+q0MvY1phTVvszoedde9ngJixrDZc+wsRas79lN/c5jQwyXu2WkdwrE0m3wOgfDvK5qaC0SNUc+Y4yTQXzJqgkVu+FRqxwBPO/Thq1RyJZNyG80U5Wiv2+643M+BEW5UXvAjTCzH5obZ2l/i6KNiVPbEIi9++WdOSK/ZGzFvssMUfYHiIr3Tn1W7rcLmtIwB/sO7gde/21muWGMmFCUy0ZQzGIgUdhbK2qrH9DOzk4RKYpPOeYNx7feR0WFZWodAnA2wA7nR4qKOP5aaAF71qfjH8XRKBKUfAK6ekagc0mznOwiTBA+HFr9kdKBdy7UwmrQPJ4ydDAMnaJAhZnhjSWBbffdUh8jhB2qrL3Nf6d6hH9XNDV46vMVPUgYOz2yNcQITx/kA4SeO5pebCh0aVazsH+gEalYigCGTQaAf6aoQFSFQ2D8Ab3Iu8ZwSos03GYEyLMY2Y1G0SdLuOwVdLvkQlqXEFNLETA27BL5h4VH9rZwG0X5xZMpTQfB/13VDz8Bh1vaT5kRexj4xn2nt99pMt4r27mASQXIt0EvWYaRmScQsSkkvOdcpX92u8sJolW77f35agmtmliRDCbYMEY8CIqaWuewNk/YgzWI0ZaY+2ZQ1HIv9eV5ORiFjrZrJmfxvIsz4r5sW/605ksg/EmNj623xcOF+rpcqzcadXP3WTyYo5AHgJNspGKQvzn68PHy48dNlRnqdo4R9s54z0wSZklmKE4DMpFpxKlKYI/vB9FUHw59XOjwMQ0Ys8nfNlUZBX+Uhd1SufFy3ls2ZxzE9MYgSUI4WY8xrpuOWR63HmawUTjHbz3aLuAgnDXtg/lhvxrmdx6tJ70/95/6NZzrigQOB+7jbi81yqpOodznMBWdQLJ3FgBzCX7PFb2bbGLis3J30q4lcZrUGnOtGs3SR5nN1mawe+SRuIT+Y76lFUVRrP7D2Ezw5rfsaLmpHMh7jAAcmWUjkutwbdyyY+zP5CpeN5OJUYPbwVDFZ9NsSA9G++lQ2l305zEpLZQQyszsLQYMpL++JbLvER/MgtYxVfrMh3fmkwB4xxbjtOsHZGJN3WuHv8/dHdI/L0OraLV5bngEUhHWTg5qilJMjnOSc/ZyFUVWD4rXXyPPY3yQ5L0WMYrGXCMat8/PoF6olS+QflB9WxEqpxapbjTZ03QvyNUp8fjtMM7Y0PT74uLnLxufFyuR7wXTJ2eNO37eQL/Y0cYxoqLq5L3xjIBFNasZwgpIQhZ1Vk43ymrIe0SIpBeHJq0ZZeLZ5DFKhJjaPNqJFdpVWE0pgb8sAQnMDwJfMgaMkDuXP+pQ09bF9HrsuQOIkCLWlGo4HUiRLq3UnK4o63pzOAyHyoe6oPY8YN6hXp6WYI/n59ZWdrZChfaPdWFxXF9YPj9fLrZjpdLZOtpfMbc+sPekS4jcQ/uguz4njOTPi8VOce/7xs3Nxu3J2VwsaN8dQVErdY9vqvnmWgMfqBNa6J7uhlbtqNKNR34ESOCSydz62u3m5oeva9NOL1djOnMV/hmvjT0Hyb5TSk3SmNv7eNzVwnFxW0q1KU0EtoKh6+EQNC96wj3/QXXmtlrJV6pr307PO2WjsgiJWnLJ1YcvzVzke54fRJWbo7Xm59ClVOLP3rvZJW8PTLtmuCTyGeEA2cxUsEdKP6j8cbngduujzVersFc8vV1cbalBzQILobIdV6a0Hcgf/phk/vzlVLnQMFoIq5QODgP5TYmDctxoROPHyN/cqXRHm5NAQrB+lSBSoVAklGo6qT4DGbJNIIPmZkeLB6pEmDiNQ6ONEhT7biyGpb3DKPC8/lATyUACA3mkJ7PlE5LDO8JIy1pgPPEJEO5xRzQknGR/cZB+MP9hJxFoQqc8Uekw2Y0HIspSrenZWiR/bCrAX1uOlU63NE7SzNk1U2unaD6aJPzTk+P2We3a96uWwO8AhIE3v7+gBbVG1nUa7+bIcF8WY+BFa92GHhr2Zf/FJdRUuXXc9KU1p2ww+JwTTiC4dK+X3qp670iP3CiKFBsRWKfMkicYAGPEFlvsPy3/Avzm7XXJ3HUPIEX6UEAiaa1UfEnYj0O64DJWGB5snrat8RLoUJLUsHagyuG2HDdGSFWgWawJnM5mbhIvWO2W7VNsC0RRWOcv6R8vd3hqiQJDEZ4IG91vFZ+9uPziSlvhia15yYG/A5wwArktapXfV+8HvQ0y+rxXrGmHk4GdQZXMXn9vBvBzvxYtKzR0thhrIUp7t9sXmmK7Rimdret2L8dgnLklWyLcx0JrUUym3p3/DODlP5YV1pURsV6S/yAQL6h8OTko1dNQK3dMWJ/q3lZznnz5PsCLWspSTsTWtM8lf/sYAQaXwlqahR9HnUR6fn515fJqpzTbqPcsj/xgaXMtF3iS8J8MNLuKKqESq7mEWdjcOBB0sl607q5K4inJYdx6ZA6VmUWclX3ira1VQzBdFEhVXdNa9HJihYNkTPpBlJ9eX129+by6OF/J+b5k5J9273Dm53aVrXqKrUWfvQOfhMnFjPfT/PHT4cAIA5DWR8/lclEU+X8fIM4u/RzZbT1RgoY94Xq9w9gYq5ZU3U1SPAs3ORkzRog0IZZVgi240yN/HwmQ27HFI0XN9It1Hsa589isGwvMfnKfs5iesZelCCw3K2zPjm6s+e8AI5B1WOGeD/InWukY6TsohGT0MOesWMn8XE5zp7yv425bCHHVwTDURl8ZVApRzKQ6rRJCxmprOPk8+bGs6JLY50/pNMuFONQCD0eh2iC/5Xqode2Lxzl/w/YGGCfSNvMibo2ld4x7SbuYbC6rmTmVaES8WqnVtGtPMkdzdGvss/aBnIqVxTmxL4bWIPJgSqO6EityBBghMF0XjgYbHvnsDUNkAgjwReO2sWyMRcWTKP5UOP0Squ9tRSki/ZRfMRQxbqtwu0fHXs8jjM1isrNb6Opo2CTkeoiJOvU4//0/DFGzbX0SislmBOTtgsQaxo5whZrxTDBnUViqLZ4LceC6oyhtnxTFJE2/Vnt6f8l8GHv+jAUalRGdUkM+QwJfjC3j0h/BE2QEosqscJROc1B5wz4JMNlVNoxtRONhvbCgvKBv5lCotlH1nqZC2d/fza8YLO6lzXGLisMGLagl3DE78rmXfU8l6nwUGMm49h3tGLGiY8Mb+fYIJcSV174apIhmbUzsOe51ympnTihxZnD2tJzRG7F2kQjc6jTGPrsF4E8s0Tma4sdnbW20FYorj4zGDnPIL2vXw4a17wG8xUIwIXZFPOKkUKfemDJX4C+HrbimhA15lUAqjNYahe1bKCTLY6cCg6zTUAhE8XzPi3drsOuPKBPKmRftqGx3jrnMv0V7QyZINONIIlORHNMFMrYYdqzqCnXdOFqS0gthO0m20kSbj2OXkswh7cZYSBOfP+8/FSb3PTYaYwM2C7MUousp16X5N0iWJxNBSziaRFOyMVVJiPR3hfXThKiHdnhpAcO4sHFiRFurcHXsFlneIo1FvB22nhcAeEV9M6qrIn8f8I8TkfXj1LcDsFW/N6RPCMg9G9KI8Js/vtCLwVpq+29Sg84QC8tJ+bSgUOhCIzd2yo23gzQ1O9u4Cez52LgVTk+M8HDiHTaEY1mgua4AI+wNEV0BVpzDJC688b2+tvi+qTHWrZWy0FqIOFRlbeEiGrM73tjF4xeo6uFBVzWBPG9rkvpo83qEePMlnTVt6N11T5I3VAeWh8YV+YvBGCutQIj0D5L2jN45V4nZVfUUFTpiZLFTHT91b55i3WBqZl5ghMFqYbQ7IhgBwvJXKbq52Crej+TbyaeRxcRhdzdiY2SQEgIAueOCobqgKMW7vUA0MWGnCWOt5xFO2DGlXzqo6KYEt9hv2H+qjH5OJkBwlGLW6GeKTc/WBV/f3hCAasHRYcoV8qRkS9zfIwIzceVSWS2GAp0J7ndyqbjzbdwsRcYJ7KBo6bThdmM9O5dzHC81IcyrNjLSMFXpcQ7YGxjgyljF7QdAs8qee4xklEwfIIxVpk8aiXbtKEKHSWlzPpLjFgvhALVGTeN1OCW5BMbIuG3doJru5Q8MxWxnRbHqs9cnzEOznS1HvQ2ewQjhjI0wAuOEMeB+lK8eruztbd6uTUc+SI+PHyM8J2pa0EvcYIRZP+B1ngyzryREX2r9bkeRfAhePVdCmrOOuG0+BhyewzUhEyNU/JxYg0sY4dLzJDBiz2jbCAjwbP8mA3dnzF2Cd4xYxkJL+9bQEO81QwoywZpF3ffQdKnig+0IfqXrAYD8VtZ7eCLJc1fBgXic8JE+s8zUj00GDCQDIv2oOT09P93M52wLmOefIT3GnbAo/xYLZx4B/pqd2hB9LehsRIWKL/L25XmlXAnz5mvUsfs/+i9usfEYe0u5nP98gIOXq+y3amlojAnT8txSNQCvjeEePcOvcsLqMSmZ5K+pSpisXhkx6Z5OuLUR8NfilXirZYdVtSfZC5fqxAWMv71i9X9YlnBYSpRb9ZtNxMB46jCv6dkcbehAcjtHkdnmoFd8M4jkEG3XTX+AiWmtv1L/DXwrZCbv8tlab9YlRIiUQP4nisSa9VylpFHHl91TRalyTT1CpZ8QV3Qcdzw3nxysW/S63S6WPZ3fC5E6lIhkLxdw6zyNq4ZjnzwD78S4LipzIQc08EFdkzPgYMOOVxfX71ThRM7XVJ3G3d04VGGxu7+X6kZ7AYXQ16In9u3tAmMMXr8B11b5FkuKZi1Mqr4SSc4JjCkqtxDxogPHXkW94g80HNxPNSaSWHFZlMCri+s3pkGadUWRUi0o0rj0vblWmq2Xj2Y0xUTNiQr4YF/VjJP/yndtFVr+ay9DySSazk0AY+sLZpx5zQV0c7rDWw8GUSFYQHAnTc4lMOu/ubaR/wVICOPBmRAU7aGKojFJoRTPzHyqNahQU1NTjHsAnIO74VeulhDOOWOysldG1zCLGC5UAyBjom6At1FHS9envY1BZYQRCQzsZ2JNMgcnLv4GxPX7/NVq2mmY8BoFjc8VNpQunM62TWG3pnTc2Fmx5pXDG2ly6ZdGvOqBEdmQcWp2qgHjBEYbCrvWs+DCUDc0sjM/GLJPgEnuSYA7bQtWYm9DXL/t5TgOvydb3xrqTGy19SQ130vFs56ptUNR3CyVNjxOrHV9U/dMPH9t2TqvbpRUulz1wQfGRqhPbMKoumxQIApzkJOP7J9kHnjAspAXOAB/W+L6z0d+Mjvx5wVsLAqqKUUzvX4Vz/SSYqiulkpz+cy8vi2tyRl40caURnRT1DA+r+Y8GGUi2Idgv6YSgUjDkwAGWy+zpYYgAbKI160cBfK25PUfD/HPVVivGtyxdDdFJ9Xt39qjkFxNF01pe+7a2lry2kU08lTmnNm03/aCRjdBStB4eTWQo0sDk9z8lEIqykJvHT5Z9WM9JClZX4+46O+1a47k92KUBF1l5uaFUCqkGCpEpVRhZm41v1zQ82YTJOPsdUo12X0ye6A/8eWJIPyNKS2oc0vQTG1HgaNtkN99EYxFl6nb6KXqf+bBFnafbnRw0S4BTpzz9oriIgNx/TZJEPiLvWthayKLoeVMMpk7nUdboKXlURAoD0FePlh5iIiwKuLu+v//y+696bTAAmqpzrBLlJEC8s2k5ya5ybnJYdgeOwgn/Zerfrj3wea6LU4O92ebM0feK0KOhhPQfgMAQMzM0rPwKpScb1SCbj+68uJew/UWJjO8OyBmTi8WtXOZ/+zVTcQEcWE9iECcq1+GOH3BituPK0xw73redKUZL4eBH5b9wA7hjT2/4tnGEZ3x4yCl3BLKAF3VN4SYr5U6idLt41o27yVor08nTDxEjDBXt5sOhn5Q/mvBEN/EKRIqubBNclaXXFGX8HCITiJT82Njvue3w1rF821jLT9ulzu/tfyZ+XdLLJRXsVcBoZJx/3At1wsyzNHC+5nQVwqSX2m+qSdmeBCJnm7Yk3h2OO7S58jIjd3GiMQhhAm5qUsBcVVdqsN7CyjdC8qujjc/blvhrfrxcvzpaTOOV+PlFxGB8OvTqyjJlco6gK7LvVoEERekgOqby7E3ogXJYGJtOzFCEK2wDVgagoAoPd+NPZ2uMrqXAjdFg8hSI0wl4lxCN7gwpO9WAPQsnMgwfn3Dzhv1wlB7FYz5yy8XDw8XR0Yro/GXvGbbSWYvYP8o41qd642VMvdujgVet5ITL548TQwBoEEeABAiNkn1y5NYG5kHY5/mzK25X6OJM2HOi4eFPkIydaEXxMoQomE6qIReZeb1Ez/wbYpo9nhjtRIErc54eTqvo9g9iFAm/RIZ8Y1lp2j6ZDZ0ZHG3zVl9vZNoGWUA5jnIJHMnHaWee2H8afvWtqkgACxERMitikeZS5Hr6kJpGOUswBzG5d3y8nn8LK5VxnaD+d1FPwiefVp7ndMYVVAfIr2cd/+xiW5oAwIxJn21UQu7B06sNVl/VU0YA+wOourFcS3QRG5QOd5JDZO5zcpzSRjCoNxqeNJXlyBDS7YNBNFQQpLPE2Hoj7ZHbHGvFvrPWu0gaD1ZPM2jZTtKPSpT11PAigDEGhtdJ4xo2AEIwI0Xy+XA0wFklmSyu/k0NYahTotQymbQ4SorqARVKISjqYv9ycAdIB3xg4kPK+aOZIMQcVbIy8Uvo9SzFKIRKlRKYCL3fZZhOH+zsh/rGLPKTGvS89utxYnW0ccoj3BEMaBQgS5rtmJfiT7uneYzefp2NvZ74x78uN08255Lo8gIExvWhKhKBgsmhwNmk27tPbGdh91RDb/ceTFlvsGO0+wZ5zWXCS7iUKiI+smeurI2nIwhOH9iM722WA79oNJsxUEQLr++aEQRmVyWBmtZ3a4K3fQrVJiQOV6m2826sTmTtU4cBv3hSkGls3/0cSpNI2OYQIBIDyWwwDEmShvPzzYmQ8cPsX+D0ePP6TcIkcQw6GJO8gpGqEvSk8vqAtvXLHqX9/aCLopnSle+rr8bP3v7ZH1zq55aC20oj3hEOBs/ptazt5kjlq4lIcZdiCemZOH10liYjchR6lhlcvn3o6/PtxdSO+giiYy9REk6tXP+x+laazJ2qNIgJBxtHjYi4m94WyIx0Ba0nA9EMs8rhhxE+uoSJgsS2O/h3kCEUh+IYLFiWAREwiXJIR5B5j4ZWciKrBwBJhef3UlhFSWASYmrf+w/i63fUKBk3dmDsPJyqbO82mo2V5c68zOjlTDozf3XwxmTu1+qhgQAfXOOHjNypBMhC96YekundyFWSzLc1s8AI9+BhwIFvfCl7Q2gT00Zleg7N5kmmjv8sFhznUxH+lAJakGvq793beB/ONZ6+7lqvkVuQw/Q+bLfAZbMmkhfXVlgJ5opIBlqPRksuda2Ae7ehntuZDGrMx8WJC5ghXzvJpo5ShdONjqTZY1jtdygiMhQ0516F9QWd4+e1qPIRXz0neqiXHsrZSaVyCEB7pkNMzt1afrXfm1YNSHNOLEuodxEOAuzhNRgsgDZvo7pRwwJ2B2EEmKTTp2/+bT0crIWVGbKFhAuNlWJR2cWn6xfLFQjIhKdeUD4HnUhS7/nJmB0ryB0HxkQYqjh7avr/kJEgOIu14cGETRFIgxA70uxI5o1lO8/cQ1i9NwzCBRFaWPl4OLN0dH79bW1tbev9za/Huw00siwUP/ZvxVgqIsvgrqcltQzM8HVuaR/g2pInBaHYrIIhgVMjFw7tAsDWm2HgXP4V/d4BPcTJPdyqEDfdQ+UrGcuGUMwxKACLCmwmpJLWQGQXoeFERAzWGmJBBq00Dt8jGSmlHrROREYucbVKEHYgAyxCOeQg78DI2DRL2qRwH2DZSgYERIBGWG15AXCCHH39qSbQAPnjJHsjYEhMkCudPDrGFGdQdUl3TU2HIyACJEBSIhB+Z4dgmKESB+ayF4caKApeFbjmacdIYaJ7D2QcRa9ML5GLyJajjaZuoaDEWdEBFSAY8xEGpBrnA4miH4CDQ5ZsZNrwxy4Ok0h1AXKynpOS9RTF5WyJSVDWVIQYQsT4VLuArqcE3KcDCa4h+dCYCQLBAulLhJdU8RZ0hwYoroAgK33Ii5CUxVwz5ww6X7fkHtNulLAqpmcRNXlEEIFUJe+/Up7yNTFTovDwwgxGwIxYCDIv6mK9ubTRCuT3qHoS9K4RPLEiDAbBtmbA5UKoS5k9RphaHFPiUWXzO79UsEkorMwi9N1JyM9cI9VpDVMUTMiSg78QU3C7Vj1iVEaeOcm7n8zF8Qvq8HVfy6rC5TFsCASe7nfLkIp/8zFGVvHPayAWAB9eDApuYrtVQbootHjFA2+X2UIMZWcuorgaBT02WYLwtRVl762SmS5Z90XBCZiAhfBz1wlzYB1RViRjJUmRAL9/AeECCCBisjg/cTJmjcmMBVHXcJQOhr11EUZxxVMpOoaXKDuynDu55j/xVWUkhjG5cqLFm2+5V7x72lJaX3685uj9x+On/wj7/5aP9v8sj1XjQZw0gYsRVOXOmcBmHEJOKRBHUGpOPfhQsLizhRrrn8P92QYACTjxEObnhLdbhbhdvGQCIaT+s7p+ORoXJkMbe2/J46LGMa1Z09OF6qGNAi9u2kI9IMdsZGj/PMifekfoRGTuWaFCzQlOnjkpNxHZhCjSGNh+sdr1NUYY7KDrO5uBSy35Tat6zUwYK5On6zOxLHFw0g45o1cE2XN24ljYWXx00FqmAAB7mSfMwmbEnHuCfgb15SG5dfVpSeR7xOii4Cd7S6M6XQCfS4rQL9MS8zAnaeuIYTI1P/4fSYOLKOobA9zh2O+r7MbPSdKSPQy3NgTivHk8avqXTPxoOqiEhuUcu/HcvsZrEtlbSUD071ulgQg1qE5hYm/uiLIlgYunQe3SL7b5DGnH48nHIdVgTDiB7Xl31p/vd18vr0zbWXn6fPT9ePWbK0cKEoUO0FQ67ypRneuKGUlFLCpJiAslzid6J22uedoA0FExEUzmz0hElynC93yHGDYC0WNk04lcFMrrScpT2y8ONiZS41x5EOBihC5kxLVla0/1+3PWwKjGpTK4mmqQTExcH2vZRgMKsyW96rI9b4nNIyFTzACLnBTc2HDkrkQYsLthWIWSbb222Vfe1/58W9rFyv1amSMEZIb61MQjuyOZ+7gfScOvYzxXGs+TwFcP1GFLkaYCjCE63YOEOHS4cHhDKszzFLkJqIgNuyEcGcaMFo4ace+Czb8Sutkay4xhjkyejLq3ylz90XAopA4SRvb6y8tTJz5idtHqZFr3XEgTl2GSgW1I3qb3BW9ewwBI67hSuHir6ukQJW7zU19b7Yc+s5btM+2ppKIIc6nQEAAbinMiX6ItdNJuvJ1ueyOk9vjE7srBnQ5EhYhgTFckgINGL7luYa46LuZ/KLFXz8SqEUMTp4v1UKdWzb+ZSWNBn0PwenK3mygsYxfaU1HwsRErG2KVF0l4eKakZ8hEKEHDBGLj2hqfaYc2iMQ5ebhXGLukyKHcFTd2q/5DifluLllxLhyhxDMQ1fXvTrUFNnB3iUQSraaE4E9KVPuHK6kEQBjDAb/hS44WdmbDL3Qt+fIdxcca0JAYEKmr4eprkFEn/UB9yNG8ueymyDuj57sJIZh5V7VWE3Im2RucybwtcPVWp0hRvuuPmx1DSYP1WwKiGGqe/OxbyfM736pJzRU8FFUP22HI7amU549TIkjjgSF4Jz9ailOcftHV3vEjfft0LMtFNd3koiGzPYhMaa+N+EG1dSWVj8ajpipVNz938+TQlV6v1+Ikobtx+r5fntvITU87EASYthwMr0We17YWSpX3qeRQTG4q79Wch9pNajw1NuZss2I/nbYSPS4OIbsa4iFhNKDVhCOz/peubkS/e8ikQcpYGEBVY/abtMxf9gwP3dpI6mfTrSeeZ43dnxWJ8NS3LLFozgRYTbJ4Xw5cDaknshPpguCOVk5G499f75Z62yxAR6oe/7fCDEnn1crwYgftDcbEdPPfssANlH1425nqdXxwtEXKRWHFf4oNwqZ6Xe2ra4/eraQMjH/9PG5LERcbZy1ZkM7dHp3ioQebhz3XxaARICo8XYi9Ea82v508itrJsLpi4qrKAeL52wANqVHKZiQCJjTw5ehZ8t2B6n5xYkdJB87gQNJ7UXKVOA6+f9XWNjsNCs2qTr7phEBv3roJSdzG6HnBZ5f/tSgglF/H8XlzLh+NhrYGa1rc4khkPzaQ6cgw9XXFWdKwvGV6GGmp/+zImCm5Hw19kdGgtZWkhv3FunFhOcqOLPnLPzobwokQtx4P1q2eayzqSTH9AQl54s2dTfiT35h5qj0KAURouhg2e5mwtZ5avIk+AgnU6uhF9jI9TShR4wURrh+NhZ6I/7oUd2YXJtfCChqbMS2khjEJ+nj/vdv9s61qYkYCsPNuWWTprtsCy0ocpFWrSgqlasiXoaiOKOC//+/uFlkHB0dHSklu+Rh+A47J+eWN+cEgSYww7te7G4frpsAGlfA2X6zXIpjz3qN618GHmkwFXmiFZSZN70wSgmidNxGFIV2t8uhTPS5yXD3cVsKlg8WQ/AiBQycvmonSlBkbtFEG7luYDg36xsSC/00DeTIgmFKn88nCpWy9/sxb702gIEbZJ4tWYvYOsopHHkPNMC4k2Upn4vu9dLYl78mGAgo+zorKLazk2WhGMg5xOaZlx2JSvbupBTrm2tBE3P2YkaUaq6NnEvDkn5pQ9n6yvlcgpV+GkYQvHEQmPysbL4vrKbMgeSrFzAwudGalFv31lbD+uNuBEAMQPmub2jas26gui82w8H5Eq3BotGx5zpdmAhMd89iYn226oI0kQYxDVdQip9k0HeUNiJThEib7nYiSau5lVFwI6V+qJ54tIFYyvO7JuatU0VD2ruXoODMOCUTZqRpNAwzu9FGmZPIXi/Wv1ODAIA5H1hR0tpK00AN5PuMSzabS1YJKrmVB7GK4UYABAD5XEcwaR06E2icuYCZN+e9x1N2IXVRvzgdCIiy3bbtoD3MILhpoL8Ajt2m1y8KJk8yF21kKgCQO2pj0y4d9bQL3XuTZnJfZhQWNN+n0UamAhO/mGmi2I+p1qGmqz+9qCf31fqGKyZHKUO8B756iE6agmIX8qpEdwNubEvRUXMr5dhLu3rMsO2D+1KPdUU6DqzZHNtykvjMqamKZVeZfM23t9t3mANtr/4ugzLZRyviZfsnriKWXVWAKP/oe1J2x+lw9CL/pHF9aQUTlPlRGucKXCXE5lVTBOWDyxqVginfFUFJcGPVsIk5yZUBvDrrdaIrWdVe5RNx74EoEbQP8/SGDYGeKpDdFYXYGrGpmh8BoOFKqUvrLOQu2siVQABAp4lClCMT2s62v6MbYNY7VmQ+sWcpxbubq4AJKO+gUrKcV81AzmF30k7aNlH2aU4Q483kYQZ+lPiaZrNiceYCQ+7rShNRqdkvjkK/aaokhtZbWLCbVfTrGmIet8RHy87IhLJivk4Qub0ERTq9qr5WgQLzyHflJdnocdQuThwwO+VezH1uVNSPeCifa6LykqN+RS09ZMgNUBTO5lTlqZaa+9uiRCl5HLCCrqrwZ/GhfD9UhfO/wYbuzIt3JK3T6EgmCTQAeFtQqflcVznUNDSAOWiir89a63Gu/GS/rH5erpzar1gP/nfwuIWqYKMf9UaTQ7Pm+95DtwMZQ3MptHmSqALczcNe8FopiOCZYMFbUwPvDKY7QFWQbMW8dWIQ8d2y8B3W4eARQL+NyqugPzmo6LrT4ADuNlXBwFW6qPkBfbKConBtkV0dzD4AWB+LP3dPuRaxpvjlR+dN+Xd5VbvGoQFuvlx+mVEgI88uDeQbIkqU/WKiH5kIZgeVQvXScF1uwjQNW+Wbm9k+RXXrJHC3yjuOZ/X5mGDcOEGFgnczCP5FahXoJqpguQb9swtMStmceO/Y/MyVkviHymtRBcc1iTMeBnaLHfSCo9uLOqYkl5/iMVCiUBZrZCOawXS3rFJKkkeOalLSXxegqS+q4EFdapoLIJuzqqB54AKbClk1WOt95QP3uG6Na6DVtvI86MZgcylA83Z52rK6+RFy5lhUQXJas/9s2oC+g6rgYe2CtgHObivPUg/izuhLQPS4bKAdch23+L9qqQI7ZtBUg2uGawJ4Hn2oSastUvwD6Rp6llaZoyjtv6GRdyO4wFzHg0YHLYXKJq8r+Dw1HMxjbyJyyFRpIesf0O6+KBFZWqylm5wSvOxz/5m8UUtSt1lmJHIY3//+P0P03ZG5mk51YZPfUwX4II9+5H+Bb+xdi1bbRhAV13c0WknWwzYGjG1ssIkJBGh4NSQQHklDaJqkzf//S70SBvoucUJUlRsfR8eHY6Th7tzZmdndJxVbQ/9QQp2xAPgxK1hWd0v6hPcA9myXhR+X1BMDYdrNxOasbGnkewKUa9komy1xZzBOPTu5rw8eOPI50Emt5n2ZCxr9mp25ecclfsSvCCDMazVRmXeGilpZBuiiRC1U9wiwn0nNMss8M8QP2Xby9bbzgLsD5rmd+VY+scxag7VsRVZwpA/tz3eHRKvWDScxyrwKBeHQHjjgvhItsaJ+LUhqN2HwvheUsVZzDb5wrdgslK5D5j4ghzN2ecEuUMZazQTUA98Grb1UyiypXwlmaDmSlDQPfw0Msp7F2loZO2S+NgaezUBelDgWsVCNVypZ7/MDRe4MbtiI1VsvOUeAcDkYP6n/4WFac2eYrl3BuW9KzhGHMpuMSeJuP3DkbqDIU9dKzWHpi+bglptUKw8cuSuo4XnWD9wvPUcc56xSqVbdHx5i1rsBYZzY5ptHMUquNRhzxJ2pBMnL/8Fo+KIw4V7FcuTYlDp/ZgGc2Txr7efSP+kXhoSr9tioelr6hnFAl+1wSHYf9iG5GzgIbALttPwbDwLmkV3R2d15OLDzbhDrf2f8gZaeJEC8OaZIstQuc+Xya8Bsuq7rvTBA2RewAe3ajFdzZ2M+BCR3yY0wej0cLe81DZQEYE0JLaUvVtlN/IbrnpqH/pF/DzHh5VZvZbR1+OlykIahAlSokp+lOwVfk6/mLGh4Ff+IReFIQW7jb0F5Wfdcz/P9oFYfnl+83n43iI2Qn73gUVlcH4R0WLN7Ps+xMF27KAxd/xKIhp7NjVRsuF8PPC9I6ksLGyfH62kkcO4OiGhhk5g8qPuVSuV1WBwtpWjRMw7GbNQ9t1LJMku+pYqdBrt+tdZ9tPH8w3o7MkJMoMA/EYAAKAV0o6RKuDB+VjfZKU68SgIqxVZpmLTz0/brF61et5d42Vbxrm3ns/3P/lKtUR9tvf6wMxcKlQpQ+PesByEs5MTSkNpp2Ce7KNCpxQIp/I7aFBOZMIya7fbg+PDHhWG9GnhZZt76k8aYNJ5Xrc0/3jg5GKShqFH9B45opCqFkfsbQBgte3Yv/PUC7a1IRIIimusWKBKSUFUgCsO4Odj56c3Z414jO9HDq7tXdPH8pLE0e/ppdxCH/HuOhCKmcCswKELzMcmOpI0LdKSGwBiaYnfX4pYOIn9XGVNlbXf7x0f79WTRr8xcYaxCfpDMD7f2dneaoQCgEgQI6GQiB0KMES3GyABIipj06O3y6SAc+eNHGPWL8hcBrB+hCU1xpll31aB0bvDu5evZXi2wLjoTn7FbyQLapdmN4+/6cShCVSHUco0UBQVUoBir/UAVSTuvVhPfDVb6e7OPt17Ohd9w3nVrOgWlECpQAv/JpRxCKgAxaTy3tnN80dqv+V7FRrMT8Qlq8/svtp+248hQFA5UAdBCpSBlVSNR+2ChEXiW5N1BmqaRKOSbcUSFJCcUuTKXQP6bu2+JqAIgVFVg1aeze3I+XEw895b4BKut2fMnhx+/a4fGEBSFUEkWI0PC/uVGNxj7vsB1k2frNuZWkN9qmRkoOuEISFAIIfifrR3B+T0sU+Y6Hw4Xeo0gZ4rb7daHve5KNZlf/eW405+LI4oRACAA3PtJIFBREApAJf3uybDqZauYvcUf11MC35a5osaIhlaGVQwdQ6MFEeUvCsnnPttvZ5dqQW21sZosrs77M5XqaPn87Nnjje1OM46MgA7g8L6VHyKiUA3D5tGrpZqXMcRLHn3qxwUQP2HIUBgKHFHAEaIowb3FF45TNHMpP+1dLIwWVzbnx2rfm+12W4/qQbC0MGy92d2Zi40ooPdrAUKVUTT4eN6tBtZ/VLxq77DTjAqx42zOERFCxWGmzRQUZJL1BUECTq4ikHSu3X56dLK8WKu2Rp5bfdaquTau9ZOkvv/9q4NOPzX3Go2pCdtP344adsLu2fvYPFxvhiEFRSgMWK0xYt2IUo0IISSAKcMBAChsDRkUCceIx3PkDyfDRlJvtbyrcNaeKFRNGpvLp+/X2s3ICKmOOnqVS1FM/0iA9dOaXTg0DKO59TetetXN515esvSkkwpQmEIIhCY0YjmSp+AJmT4CYwZFQUULpJIiQkZRutY52DscZvFsJa8k28qPLSR3R2+3j8byExkxQgcKgIqMKFNQhCIAAaiJ0vX3Tx7NJ77rZkGqXxuddNrNorDjN/MayxKjEIDktPanCElqdlXILgMVCmnfJKSImDhtj3P5C/Va4lfcGbeSl31mvMBmaHuPz/beDdpzURxJTn1Hp/rlQjEmbvffbYy6taBaTbq91Werw/3Nrd1OakzhSosQilBAgSiEjmI6hogQ11oDFjDPAs1uUEUhRqhiAKEd1c12Z/dweTGpetaVuJlTsaUS257SmB+2fnl+2W8309gYyVUHuIvEwIFazzXXP3q1tdJIfM91q5uj1uzC8tb5m8t2GhkTkkXrziUcQHN6UKCCL9acdCWoYEGSl9fIHplCGkKoQgLXdwwJ0/ba5fOz1Xo18D2by7ew72MH4/nVWn1xZfntyc+XgzFZojAyxpBKkNdfYl9wcJ1yMqExYRTHzf67l4fnw/lGkvhu9q3Jamvh+/MXz3fbcd6qiuKZK9dHCiR/kZhKtzJj34wwTD4v1iFOCghAVVFQQeCPzSRR2lzbebc3u9moBZ7rupn2XMF6lsCvNurzS/srj7dOj98f7YwzcXNzzTRDHKfN7LI51+53nn48fvOitbq/NOaG73s559ws3TvaOjv9ea0dGd42V9GKz7kPIa/ep0lG621VwdW/DBAtTpTuOEoRQpWgEH9yawoLRgqJ02Z/Z3d7PC+tVq00+JXsfPeMKBlvLGF83w+WatUkqdUajXq9Pj9fH6PRqNWSajXw/TwizT2Sm3PMOqTlg3E8HBolAPBmGKFgZ75RjEBVoRNzTRHY4CZyz3AT/hYhFXQNKAChKsk/bWIFSYIhHCVAwITxWIB2Dn54cj5arAaBZ1sHvbxHJadL4s38EZWJ27npUrBN2o3h+fODnUE/EgMKlcIwNIU1VzZkKCCposAUEi866cQQoQJQ3gSsKNRRd0JH8igdwL/I9dxSgTBK2531y4O9i+XRZj0J/DFdXM9bzPTIuoobVMbIPrM/4AdBrTf6/vDDu51BMwoFeWTP3Fy5vW6Zq1CBPsVRAxgIgOlikckXUvPADTcBK5wCaSwoohDis/frBCHxGJYuTy93D14en7zdWmg92+9tLi0uztfHgcpid2mzt/KstXxx+uaHTwdH3+2sNeM4FGBipjwAURHFbXPlmlOgs+NBCvMBNeWkfPJQNMwV3xgjQlxHYAWpE+Jqsk9QPp8jigxC5LoVGhONEWdILfLLKIxCMSYUAkYUuO58k6v/jbUOfmOubIgVp3mHZJ4bMVNyBMLceMKMIYRFPiqY2aMg28jAIZG7EUAF+OwhAUCzF0WUlCvdQo7JdW5doeZGca44cmUuCHPnoRNzwaGwOOZyAAEJErCXmE6y4GhOBxVeVzUgkusMnKJM+0lKHjUJ+UW6VADc/vD2BXA70XZzYa2tgBC5ifLvyK81M1dRkq0Q3JgL0xneQT4soIRzYzNQkLv0oqzG+JW5s12RGwaC4FBU0xhC3v9xA9aKfJH8iYPcHJzWB8eqaI0sz0iu2F10N2fEwmUGwjBbkK555i25d4IOQy3zL5J9I6ad789GGMzM3d+X3Krj+cpmuyoCOnXj+jBrZuyL1r+W+Aj3Pbvi6i7qJz9qx/CG2zBgBRIOP9PLTSYZ0oWr6geX08Ccf8MEwAyCD+Cqa1rZRiCq7g8QOX8bhlGGBDm5UZXspaD5DdfoJMzxQ942LkP7z7jQT+cIP2Qc2n4iqxlOTzYNYCCnC+22R2Z04bo50bIGnDk/N5NCw7hxPecRhsgsZTGYnvcIESVpMHNS3z2SMpOwceXmCGFO4zLrp/Zxj3QHk7IXM4Fw2CNNyBWbhONDdHskMJMuXHzI6XmPYOyVYMIjC0D9BA2yl/baOrM7fZ2OIxGMyQsO4FkecXmE+1PTygLZEJh2zklLY1LzDK66n7V+PMIeCXWgzmmPKAmkb9iLR3aGK0CvDzt7/wUy1/TowgYxJVacR1R38JQZAs3deI1HgldC84qzXG+PEMZuXDCT13ikciWQUh70CLvTc8GaWd/jEWtIeEVGYMWRCQtcHLwbkMXxOh9Hgql5uNPEqcNEmt7WsTBKDnukYvAd5+IRZhjD4iLogFNvjsdxIabG9tFOz5jZmcyEIZ0URuscGxeooqO85B3KcY8ss9Zc6X01MtOQGU7iqlLBPodL12DtkP1v0SGdIT24liMFNUJfsm9QvwOSfVGWeTQ9h0tBTZ7OWJBhhqZDlktQxjUumpnJnBAWijHlDRPNwgU7weVyCQ3TwJBmOIuLJHkY144eBjCJxk7DMFFn9EiCpE6uK6gvKjePbGwbVzvEYUwDOEcUvK7I87i+1yqmM/xcnRlyLqNH5nJqj6cUfxTZuPwdVwPncJEMSpinpSs12OwxYtJh5lIPlcww03CFJudz7T+qWV+PH3G5cjZkzlTtLYea4qXM0yL9FOOZj2Tnhg6V3qFFSdLrPRPNrbhx+ROuBg9tI0DbBhOTzvNqymzBsH4bkDN9TtxJy/qijYIzDH/C1Qk9Y5GopHeb/8KLhA3g+zUPbU5c+VQI9I2HFwz+got9jZ7BJRBGEzv/R2j5aawgpw4zYshEIvQ1b/T4Q+RdAns3zuASQwq0zH8TWvi0z+5tBoevat5yMO/vIi/CVfhyNf5/XJik1EQ59yYyivaKCa84eO4vuDyPa7hxXSYF/vsXgNZTubPNV+UiX76GF+2d/QOu80UtVlK/fL2Knf+us+OWdmakjoHyjnKAd+P61t69pDgQw1AUNZf7EN7/hpsmPexByKeiYJ0d1MOGMpalEjEAdJlu8UaVFLdqHZJU0qCmqO9cUIwsi0ASjesCH23MCqBLCCxs1UDpX/DxuKj6i8v2cb1Eikg6tfDoTFHy+fetV6pIjLNI7kKC5qhFQmVDTLq0xWmNcosm3znT6iGpypZgNaoXaSviDimtLp0K3o29IrsIXzum6UJsDLHJw6Nr4Nq1lJzxh/4kJK46LC5RtFXVWWOWlnbpmnQNJQnmoH3xdFxF+t5pvR4KnLUvnkBZnHTu/QWl2muIQWOU3zuE9VHQuRign/PiOutrJ68xxhhjjDHGGGOMMcYYY9z8APvhwA92drMnAAAAAElFTkSuQmCC', attempt: 1, listenEvents: ['scroll', 'wheel', 'mousewheel', 'resize', 'animationend', 'transitionend', 'touchmove'] }) Vue.component('top-tip', topTip) /* eslint-disable no-new */ // eslint-disable-next-line no-unused-vars var vm = new Vue({ el: '#app', router, store, components: { App }, template: '' }) window.vm = vm ================================================ FILE: musicPlayer/src/pages/audioIndex/components/audioList.vue ================================================ ================================================ FILE: musicPlayer/src/pages/audioIndex/components/bar.vue ================================================ ================================================ FILE: musicPlayer/src/pages/audioIndex/components/functionButton.vue ================================================ ================================================ FILE: musicPlayer/src/pages/audioIndex/components/lyricPage.vue ================================================ ================================================ FILE: musicPlayer/src/pages/audioIndex/components/playIcons.vue ================================================ ================================================ FILE: musicPlayer/src/pages/audioIndex/components/playing.vue ================================================ ================================================ FILE: musicPlayer/src/pages/audioIndex/components/small.vue ================================================ ================================================ FILE: musicPlayer/src/pages/audioIndex/index.vue ================================================ ================================================ FILE: musicPlayer/src/pages/commentsIndex/components/albumListInfo.vue ================================================ ================================================ FILE: musicPlayer/src/pages/commentsIndex/components/centerMenu.vue ================================================ ================================================ FILE: musicPlayer/src/pages/commentsIndex/index.vue ================================================ ================================================ FILE: musicPlayer/src/pages/dateRecommend/index.vue ================================================ ================================================ FILE: musicPlayer/src/pages/dj/childrenPage/class.vue ================================================ ================================================ FILE: musicPlayer/src/pages/dj/childrenPage/classRecommend.vue ================================================ ================================================ FILE: musicPlayer/src/pages/dj/childrenPage/djPayGift.vue ================================================ ================================================ FILE: musicPlayer/src/pages/dj/childrenPage/ranking-anchor.vue ================================================ ================================================ FILE: musicPlayer/src/pages/dj/childrenPage/ranking-program.vue ================================================ ================================================ FILE: musicPlayer/src/pages/dj/childrenPage/ranking-radio.vue ================================================ ================================================ FILE: musicPlayer/src/pages/dj/childrenPage/ranking.vue ================================================ ================================================ FILE: musicPlayer/src/pages/dj/childrenPage/topConDetail.vue ================================================ ================================================ FILE: musicPlayer/src/pages/dj/components/boutiqueRecom.vue ================================================ ================================================ FILE: musicPlayer/src/pages/dj/components/icons.vue ================================================ ================================================ FILE: musicPlayer/src/pages/dj/components/radioRecom.vue ================================================ ================================================ FILE: musicPlayer/src/pages/dj/components/swiper.vue ================================================ ================================================ FILE: musicPlayer/src/pages/dj/index.vue ================================================ ================================================ FILE: musicPlayer/src/pages/dj/public.vue ================================================ ================================================ FILE: musicPlayer/src/pages/dj/publicClass.vue ================================================ ================================================ FILE: musicPlayer/src/pages/dj/publicImgWrap.vue ================================================ ================================================ FILE: musicPlayer/src/pages/dj/titleAndThree.vue ================================================ ================================================ FILE: musicPlayer/src/pages/djSublist/index.vue ================================================ ================================================ FILE: musicPlayer/src/pages/findIndex/components/chinese.vue ================================================ ================================================ FILE: musicPlayer/src/pages/findIndex/components/europe.vue ================================================ ================================================ FILE: musicPlayer/src/pages/findIndex/components/icons.vue ================================================ ================================================ FILE: musicPlayer/src/pages/findIndex/components/japan.vue ================================================ ================================================ FILE: musicPlayer/src/pages/findIndex/components/korea.vue ================================================ ================================================ FILE: musicPlayer/src/pages/findIndex/components/moreNewDish.vue ================================================ ================================================ FILE: musicPlayer/src/pages/findIndex/components/moreNewSongs.vue ================================================ ================================================ FILE: musicPlayer/src/pages/findIndex/components/newDish.vue ================================================ ================================================ FILE: musicPlayer/src/pages/findIndex/components/personalizedSongList.vue ================================================ ================================================ FILE: musicPlayer/src/pages/findIndex/components/swiper.vue ================================================ ================================================ FILE: musicPlayer/src/pages/findIndex/index.vue ================================================ ================================================ FILE: musicPlayer/src/pages/friendIndex/index.vue ================================================ ================================================ FILE: musicPlayer/src/pages/friendIndex/public.vue ================================================ ================================================ FILE: musicPlayer/src/pages/homeIndex/components/addNewPlayList.vue ================================================ ================================================ FILE: musicPlayer/src/pages/homeIndex/components/homeList.vue ================================================ ================================================ FILE: musicPlayer/src/pages/homeIndex/components/icons.vue ================================================ ================================================ FILE: musicPlayer/src/pages/homeIndex/components/songList.vue ================================================ ================================================ FILE: musicPlayer/src/pages/homeIndex/index.vue ================================================ ================================================ FILE: musicPlayer/src/pages/idx/index.vue ================================================ ================================================ FILE: musicPlayer/src/pages/loginIndex/components/accountLogin.vue ================================================ ================================================ FILE: musicPlayer/src/pages/loginIndex/components/phoneAccount.vue ================================================ ================================================ FILE: musicPlayer/src/pages/loginIndex/components/phonePwd.vue ================================================ ================================================ FILE: musicPlayer/src/pages/loginIndex/components/phoneVerify.vue ================================================ ================================================ FILE: musicPlayer/src/pages/loginIndex/components/verifyCode.vue ================================================ ================================================ FILE: musicPlayer/src/pages/loginIndex/components/verifyInfo.vue ================================================ ================================================ FILE: musicPlayer/src/pages/loginIndex/index.vue ================================================ ================================================ FILE: musicPlayer/src/pages/myFavorite/components/albums.vue ================================================ ================================================ FILE: musicPlayer/src/pages/myFavorite/components/artists.vue ================================================ ================================================ FILE: musicPlayer/src/pages/myFavorite/components/column.vue ================================================ ================================================ FILE: musicPlayer/src/pages/myFavorite/components/mlog.vue ================================================ ================================================ FILE: musicPlayer/src/pages/myFavorite/components/videos.vue ================================================ ================================================ FILE: musicPlayer/src/pages/myFavorite/index.vue ================================================ ================================================ FILE: musicPlayer/src/pages/nav/components/login-bottom.vue ================================================ ================================================ FILE: musicPlayer/src/pages/nav/components/login-icons-bottom.vue ================================================ ================================================ FILE: musicPlayer/src/pages/nav/components/login-icons-top.vue ================================================ ================================================ FILE: musicPlayer/src/pages/nav/components/login-icons.vue ================================================ ================================================ FILE: musicPlayer/src/pages/nav/components/login-top.vue ================================================ ================================================ FILE: musicPlayer/src/pages/nav/components/login.vue ================================================ ================================================ FILE: musicPlayer/src/pages/nav/index.vue ================================================ ================================================ FILE: musicPlayer/src/pages/recentlyPlayed/index.vue ================================================ ================================================ FILE: musicPlayer/src/pages/recommend/fine/index.vue ================================================ ================================================ FILE: musicPlayer/src/pages/recommend/general/index.vue ================================================ ================================================ FILE: musicPlayer/src/pages/recommend/index.vue ================================================ ================================================ FILE: musicPlayer/src/pages/recommend/navIndex/navList.vue ================================================ ================================================ FILE: musicPlayer/src/pages/recommend/recommended/index.vue ================================================ ================================================ FILE: musicPlayer/src/pages/searchIndex/components/history.vue ================================================ ================================================ FILE: musicPlayer/src/pages/searchIndex/components/hotSearch.vue ================================================ ================================================ FILE: musicPlayer/src/pages/searchIndex/index.vue ================================================ ================================================ FILE: musicPlayer/src/pages/searchResults/albumIndex/album.vue ================================================ ================================================ FILE: musicPlayer/src/pages/searchResults/artistIndex/artist.vue ================================================ ================================================ FILE: musicPlayer/src/pages/searchResults/composite/components/album.vue ================================================ ================================================ FILE: musicPlayer/src/pages/searchResults/composite/components/artist.vue ================================================ ================================================ FILE: musicPlayer/src/pages/searchResults/composite/components/djRadio.vue ================================================ ================================================ FILE: musicPlayer/src/pages/searchResults/composite/components/playList.vue ================================================ ================================================ FILE: musicPlayer/src/pages/searchResults/composite/components/simQuery.vue ================================================ ================================================ FILE: musicPlayer/src/pages/searchResults/composite/components/song.vue ================================================ ================================================ FILE: musicPlayer/src/pages/searchResults/composite/components/user.vue ================================================ ================================================ FILE: musicPlayer/src/pages/searchResults/composite/components/video.vue ================================================ ================================================ FILE: musicPlayer/src/pages/searchResults/composite/composite.vue ================================================ ================================================ FILE: musicPlayer/src/pages/searchResults/djRadioIndex/djRadio.vue ================================================ ================================================ FILE: musicPlayer/src/pages/searchResults/index.vue ================================================ ================================================ FILE: musicPlayer/src/pages/searchResults/navIndex/index.vue ================================================ ================================================ FILE: musicPlayer/src/pages/searchResults/playListIndex/playList.vue ================================================ ================================================ FILE: musicPlayer/src/pages/searchResults/singerIndex/select.vue ================================================ ================================================ FILE: musicPlayer/src/pages/searchResults/singerIndex/singer.vue ================================================ ================================================ FILE: musicPlayer/src/pages/searchResults/songIndex/song.vue ================================================ ================================================ FILE: musicPlayer/src/pages/searchResults/userIndex/user.vue ================================================ ================================================ FILE: musicPlayer/src/pages/searchResults/videoIndex/video.vue ================================================ ================================================ FILE: musicPlayer/src/pages/userInfoIndex/components/userDynamic.vue ================================================ ================================================ FILE: musicPlayer/src/pages/userInfoIndex/components/userHome.vue ================================================ ================================================ FILE: musicPlayer/src/pages/userInfoIndex/index.vue ================================================ ================================================ FILE: musicPlayer/src/pages/videoIndex/components/acg.vue ================================================ ================================================ FILE: musicPlayer/src/pages/videoIndex/components/animation.vue ================================================ ================================================ FILE: musicPlayer/src/pages/videoIndex/components/dance.vue ================================================ ================================================ FILE: musicPlayer/src/pages/videoIndex/components/game.vue ================================================ ================================================ FILE: musicPlayer/src/pages/videoIndex/components/listenBGM.vue ================================================ ================================================ FILE: musicPlayer/src/pages/videoIndex/components/musicFestival.vue ================================================ ================================================ FILE: musicPlayer/src/pages/videoIndex/components/rock.vue ================================================ ================================================ FILE: musicPlayer/src/pages/videoIndex/components/scene.vue ================================================ ================================================ FILE: musicPlayer/src/pages/videoIndex/components/singing.vue ================================================ ================================================ FILE: musicPlayer/src/pages/videoIndex/index.vue ================================================ ================================================ FILE: musicPlayer/src/pages/videoIndex/public.vue ================================================ ================================================ FILE: musicPlayer/src/pages/videoIndex/videoComments/components/video.vue ================================================ ================================================ FILE: musicPlayer/src/pages/videoIndex/videoComments/components/videoCreator.vue ================================================ ================================================ FILE: musicPlayer/src/pages/videoIndex/videoComments/components/videoInfo.vue ================================================ ================================================ FILE: musicPlayer/src/pages/videoIndex/videoComments/index.vue ================================================ ================================================ FILE: musicPlayer/src/router/index.js ================================================ /* * @Author: 李浩栋 * @Begin: 2019-07-27 17:08:42 * @Update: 2019-12-07 13:17:07 * @Update log: 更新日志 */ import Vue from 'vue' import Router from 'vue-router' const navIndex = () => import(/* webpackChunkName: "group-nav" */ '@/pages/nav/index') const findIndex = () => import(/* webpackChunkName: "group-findPage" */ '@/pages/findIndex/index') const homeIndex = () => import(/* webpackChunkName: "group-homePage" */ '@/pages/homeIndex/index') const videoIndex = () => import(/* webpackChunkName: "group-homePage" */ '@/pages/videoIndex/index') const videoComments = () => import(/* webpackChunkName: "group-homePage" */ '@/pages/videoIndex/videoComments/index') const userInfoIndex = () => import(/* webpackChunkName: "group-homePage" */ '@/pages/userInfoIndex/index') const musicFestival = () => import(/* webpackChunkName: "group-homePage" */ '@/pages/videoIndex/components/musicFestival') const scene = () => import(/* webpackChunkName: "group-homePage" */ '@/pages/videoIndex/components/scene') const listenBGM = () => import(/* webpackChunkName: "group-homePage" */ '@/pages/videoIndex/components/listenBGM') const singing = () => import(/* webpackChunkName: "group-homePage" */ '@/pages/videoIndex/components/singing') const dance = () => import(/* webpackChunkName: "group-homePage" */ '@/pages/videoIndex/components/dance') const acg = () => import(/* webpackChunkName: "group-homePage" */ '@/pages/videoIndex/components/acg') const rock = () => import(/* webpackChunkName: "group-homePage" */ '@/pages/videoIndex/components/rock') const game = () => import(/* webpackChunkName: "group-homePage" */ '@/pages/videoIndex/components/game') const animation = () => import(/* webpackChunkName: "group-homePage" */ '@/pages/videoIndex/components/animation') const friend = () => import(/* webpackChunkName: "group-homePage" */ '@/pages/friendIndex/index') const loginIndex = () => import(/* webpackChunkName: "group-loginPage" */ '@/pages/loginIndex/index') const phoneAccount = () => import(/* webpackChunkName: "group-login-phonePage" */ '@/pages/loginIndex/components/phoneAccount') const phonePwd = () => import(/* webpackChunkName: "group-login-pwdPage" */ '@/pages/loginIndex/components/phonePwd') const phoneVerify = () => import(/* webpackChunkName: "group-login-verifyPage" */ '@/pages/loginIndex/components/phoneVerify') const search = () => import(/* webpackChunkName: "group-searchPage" */ '@/pages/searchIndex/index') const searchResults = () => import(/* webpackChunkName: "group-resultPage" */ '@/pages/searchResults/index') const singer = () => import(/* webpackChunkName: "group-resultPage" */ '@/pages/searchResults/singerIndex/singer') const composite = () => import(/* webpackChunkName: "group-result-comPage" */ '@/pages/searchResults/composite/composite') const song = () => import(/* webpackChunkName: "group-result-songPage" */ '@/pages/searchResults/songIndex/song') const video = () => import(/* webpackChunkName: "group-result-videoPage" */ '@/pages/searchResults/videoIndex/video') const artist = () => import(/* webpackChunkName: "group-result-artistPage" */ '@/pages/searchResults/artistIndex/artist') const album = () => import(/* webpackChunkName: "group-result-albumPage" */ '@/pages/searchResults/albumIndex/album') const playList = () => import(/* webpackChunkName: "group-result-playlistPage" */ '@/pages/searchResults/playListIndex/playList') const djRadio = () => import(/* webpackChunkName: "group-result-djRadioPage" */ '@/pages/searchResults/djRadioIndex/djRadio') const user = () => import(/* webpackChunkName: "group-result-userPage" */ '@/pages/searchResults/userIndex/user') const dateRecommend = () => import(/* webpackChunkName: "group-date-recommendPage" */ '@/pages/dateRecommend') const recommend = () => import(/* webpackChunkName: "group-recommendPage" */ '@/pages/recommend') const recommended = () => import(/* webpackChunkName: "group-recommendedPage" */ '@/pages/recommend/recommended') const fine = () => import(/* webpackChunkName: "group-recommendedPage" */ '@/pages/recommend/fine') const general = () => import(/* webpackChunkName: "group-recommendedPage" */ '@/pages/recommend/general') const idx = () => import(/* webpackChunkName: "group-idxPage" */ '@/pages/idx') const dj = () => import(/* webpackChunkName: "group-djPage" */ '@/pages/dj') const classification = () => import(/* webpackChunkName: "group-myFavorite" */ '@/pages/dj/childrenPage/class') const djPayGift = () => import(/* webpackChunkName: "group-myFavorite" */ '@/pages/dj/childrenPage/djPayGift') const djRanking = () => import(/* webpackChunkName: "group-myFavorite" */ '@/pages/dj/childrenPage/ranking') const djRankingAnchor = () => import(/* webpackChunkName: "group-myFavorite" */ '@/pages/dj/childrenPage/ranking-anchor') const djRankingProgram = () => import(/* webpackChunkName: "group-myFavorite" */ '@/pages/dj/childrenPage/ranking-program') const djRankingRadio = () => import(/* webpackChunkName: "group-myFavorite" */ '@/pages/dj/childrenPage/ranking-radio') const albumPage = () => import(/* webpackChunkName: "group-albumPage" */ 'base/albumPage') const djDetailPage = () => import(/* webpackChunkName: "group-djDetailPage" */ 'base/djDetailPage') const djTopConDetailPage = () => import(/* webpackChunkName: "group-djDetailPage" */ '@/pages/dj/childrenPage/topConDetail') const djClassRecommendDetailPage = () => import(/* webpackChunkName: "group-djDetailPage" */ '@/pages/dj/childrenPage/classRecommend') const artistDetailPage = () => import(/* webpackChunkName: "group-djDetailPage" */ '@/components/detailPage') const recentlyPlayed = () => import(/* webpackChunkName: "group-recentlyPlayed" */ '@/pages/recentlyPlayed') const djSublist = () => import(/* webpackChunkName: "group-djSublist" */ '@/pages/djSublist') const myFavorite = () => import(/* webpackChunkName: "group-myFavorite" */ '@/pages/myFavorite') const albums = () => import(/* webpackChunkName: "group-myFavorite" */ '@/pages/myFavorite/components/albums') const artists = () => import(/* webpackChunkName: "group-myFavorite" */ '@/pages/myFavorite/components/artists') const column = () => import(/* webpackChunkName: "group-myFavorite" */ '@/pages/myFavorite/components/column') const mlog = () => import(/* webpackChunkName: "group-myFavorite" */ '@/pages/myFavorite/components/mlog') const videos = () => import(/* webpackChunkName: "group-myFavorite" */ '@/pages/myFavorite/components/videos') const moreNewDish = () => import(/* webpackChunkName: "group-myFavorite" */ '@/pages/findIndex/components/moreNewDish') const moreNewSongs = () => import(/* webpackChunkName: "group-myFavorite" */ '@/pages/findIndex/components/moreNewSongs') const chinese = () => import(/* webpackChunkName: "group-myFavorite" */ '@/pages/findIndex/components/chinese') const europe = () => import(/* webpackChunkName: "group-myFavorite" */ '@/pages/findIndex/components/europe') const korea = () => import(/* webpackChunkName: "group-myFavorite" */ '@/pages/findIndex/components/korea') const japan = () => import(/* webpackChunkName: "group-myFavorite" */ '@/pages/findIndex/components/japan') const comments = () => import(/* webpackChunkName: "group-myFavorite" */ '@/pages/commentsIndex/index') Vue.use(Router) export default new Router({ /************************************************** * * 设置 链接激活时使用的 CSS 类名 * 默认值: "router-link-active" * 可以通过路由的构造选项 linkActiveClass 来全局配置。 * * 通过设置 meta: { keepAlive: true },来定义一个页面是否需要做缓存 * **************************************************/ linkActiveClass: 'ac', routes: [{ /** * 设置页面初次加载后默认显示 find 页面 */ path: '/', name: 'main', component: navIndex, redirect: '/find', children: [{ path: '/find', component: findIndex }, { path: '/home', name: 'home', component: homeIndex }, { path: '/friend', component: friend }, { path: '/videoPage', name: 'videoPage', component: videoIndex, redirect: '/videoPage/musicFestival', children: [{ path: '/videoPage/musicFestival', component: musicFestival }, { path: '/videoPage/scene/:id', component: scene }, { path: '/videoPage/listenBGM/:id', component: listenBGM }, { path: '/videoPage/singing/:id', component: singing }, { path: '/videoPage/dance/:id', component: dance }, { path: '/videoPage/ACG/:id', component: acg }, { path: '/videoPage/rock/:id', component: rock }, { path: '/videoPage/game/:id', component: game }, { path: '/videoPage/animation/:id', component: animation }] }] }, { // 视频评论页面 // 使用 this.$router.push({ name: 'videoComments', params: { id } }) // 可以使得地址栏不显示 id 信息,并且可以通过 this.$route.params 获取到值 // 要注意这时候在path中不能再写 /:id path: '/videoComments', name: 'videoComments', component: videoComments }, { // 更多新碟 path: '/moreNewDish', component: moreNewDish }, { // 新歌推荐 path: '/moreNewSongs', component: moreNewSongs, redirect: '/chinese', children: [{ path: '/chinese', component: chinese }, { path: '/europe', component: europe }, { path: '/korea', component: korea }, { path: '/japan', component: japan }] }, { // 最近播放 path: '/recently', component: recentlyPlayed }, { path: '/dj_sublist', component: djSublist }, { path: '/favorite', component: myFavorite, redirect: '/albums', children: [{ path: '/albums', component: albums }, { path: '/artists', component: artists }, { path: '/videos', component: videos }, { path: '/column', component: column }, { path: '/mlog', component: mlog }] }, { path: '/login', name: 'login', component: loginIndex }, { // 登录的一系列路由 path: '/phone', component: phoneAccount }, { path: '/pwd', name: 'phonePwd', component: phonePwd }, { path: '/verify', name: 'phoneVerify', component: phoneVerify }, { // 搜索页 path: '/search', component: search }, { // 搜索展示页面 path: '/searchResults/:id', component: searchResults, redirect: '/composite/:id', children: [{ // 综合页面 path: '/composite/:id', component: composite }, { // 单曲页面 path: '/song/:id', component: song }, { // 视频页面 path: '/video/:id', component: video }, { // 歌手页面 path: '/artist/:id', component: artist }, { // 专辑页面 path: '/album/:id', component: album }, { // 歌单页面 path: '/playList/:id', component: playList }, { // 主播电台页面 path: '/djRadio/:id', component: djRadio }, { // 用户页面 path: '/user/:id', component: user }] }, { // 歌手分类页面 path: '/singer', component: singer }, { // 用户信息展示页面 path: '/user_info', name: 'user_info', component: userInfoIndex }, { // 每日推荐页面 path: '/dateRecommend', component: dateRecommend }, { // 歌单广场页面 path: '/recommend', component: recommend, redirect: '/recommended', children: [{ // 推荐歌单 path: '/recommended', component: recommended }, { // 精品歌单 path: '/fine', component: fine }, { // 通用歌单 path: '/general/:id', component: general }] }, { // 排行榜页面 path: '/idx', component: idx }, { // 电台页面 path: '/dj', component: dj }, { path: '/conDetail', name: 'conDetail', component: djTopConDetailPage }, { // 电台分类 path: '/classification', component: classification }, { // 电台分类详情 path: '/classDetail', name: 'classDetail', component: djClassRecommendDetailPage }, { path: '/pay_fine', component: djPayGift }, { path: '/ranking', component: djRanking, redirect: '/program', children: [{ path: '/anchor', component: djRankingAnchor }, { path: '/program', component: djRankingProgram }, { path: '/radio', component: djRankingRadio }] }, { // 通用专辑展示页面 path: '/albumPage', name: 'albumPage', component: albumPage }, { // 通用电台详情展示页面 path: '/djDetailPage', name: 'djDetailPage', component: djDetailPage }, { // 通用歌手展示页面 path: '/artistDetailPage', name: 'artistDetailPage', component: artistDetailPage }, { // 通用评论展示页面 path: '/comments', name: 'comments', component: comments } ] }) ================================================ FILE: musicPlayer/src/store/actions.js ================================================ /* * @Author: 李浩栋 * @Begin: 2019-09-12 14:11:33 * @Update: 2019-09-22 12:15:54 * @Update log: 更新日志 */ import { SET_PLAY_SATE, SET_FULL_SCREEN, SET_AUDIO_LIST, SET_AUDIO_INDEX, SET_AUDIO_MODE, SET_PLAY_LIST } from './mutation-types' /** * 获取随机值 */ function getRandomIndex (min, max) { return Math.floor(Math.random() * (max - min + 1) + min) } /** * 打乱一个数组 */ function shuffle (arr) { const _arr = arr.slice() for (let i = 0; i < _arr.length; i++) { const j = getRandomIndex(0, i) const t = _arr[i] _arr[i] = _arr[j] _arr[j] = t } return _arr } function findIndex (list, song) { return list.findIndex(item => { return item.id === song.id }) } export default { /** * 点击歌曲项进行播放 */ selectPlay ({ commit, state }, { list, index }) { commit(SET_AUDIO_LIST, list) if (state.mode === 2) { const randomList = shuffle(list) commit(SET_PLAY_LIST, randomList) index = findIndex(randomList, state.audioList[index]) } else { commit(SET_PLAY_LIST, list) } commit(SET_AUDIO_INDEX, index) commit(SET_PLAY_SATE, true) commit(SET_FULL_SCREEN, true) }, /** * 播放全部 * 传入播放列表 */ startPlayAll ({ commit }, { list }) { commit(SET_AUDIO_LIST, list) commit(SET_AUDIO_INDEX, 0) commit(SET_PLAY_LIST, list) commit(SET_PLAY_SATE, true) commit(SET_FULL_SCREEN, true) commit(SET_AUDIO_MODE, 0) }, /** * 向播放列表添加歌曲 * 当播放列表为空时添加后开始播放 */ addToAudioList ({ commit, state }, song) { let audioList = state.audioList let playList = state.playList let currentIndex = state.audioIngIndex // 记录当前歌曲 let audioIng = audioList[currentIndex] // 查找当前列表中是否有要插入的歌曲,并返回它的索引 let findAudioIndex = findIndex(audioList, song) // 因为是插入歌曲,所以索引要+1 currentIndex++ // 插入这首歌到当前索引位置 audioList.splice(currentIndex, 0, song) // 如果已经有了这首歌 if (findAudioIndex > -1) { // 如果当前插入序号大于列表中的序号 if (currentIndex > findAudioIndex) { audioList.splice(findAudioIndex, 1) currentIndex-- } else { audioList.splice(currentIndex + 1, 1) } } let currentPlayIndex = findIndex(playList, audioIng) + 1 let findPlayIndex = findIndex(playList, song) playList.splice(currentPlayIndex, 0, song) if (findPlayIndex > -1) { if (currentPlayIndex > findPlayIndex) { playList.splice(findPlayIndex, 1) } else { playList.splice(findPlayIndex + 1, 1) } } commit(SET_AUDIO_INDEX, currentIndex) commit(SET_PLAY_SATE, true) }, deleteSong ({ commit, state }, song) { let audioList = state.audioList.slice() let playList = state.playList.slice() let currentIndex = state.audioIngIndex // 删除的歌曲是当前播放歌曲之前 let pIndex = findIndex(audioList, song) audioList.splice(pIndex, 1) // 删除的歌曲是当前歌曲之后 let sIndex = findIndex(playList, song) playList.splice(sIndex, 1) if (currentIndex > pIndex || currentIndex === audioList.length) { currentIndex-- } commit(SET_AUDIO_LIST, audioList) commit(SET_PLAY_LIST, playList) commit(SET_AUDIO_INDEX, currentIndex) if (!audioList.length) { commit(SET_PLAY_SATE, false) } } } ================================================ FILE: musicPlayer/src/store/getters.js ================================================ /* * @Author: 李浩栋 * @Begin: 2019-08-24 11:44:49 * @Update: 2019-09-15 12:29:49 * @Update log: 更新日志 */ const getters = { LOGIN_PAGE: state => state.loginPage, ICON_SUN: state => state.icontaiyang, ICON_NIGHT: state => state.iconyueliang1, MODE_TEXT: state => state.modeText, LOGIN_STATE: state => state.loginState, LEVEL: state => state.level, ACCOUNT_UID: state => state.accountUid, LOAD: state => state.load, LINK_PAGE: state => state.linkPage, PLAY_STATE: state => state.playState, FULL_SCREEN: state => state.fullScreen, AUDIO_LIST: state => state.audioList, AUDIO_ING_INDEX: state => state.audioIngIndex, PLAY_LIST: state => state.playList, MODE: state => state.mode, OFFSET_LYRIC: state => state.offsetLyric, PLAYING_SHOW: state => state.playingShow, AUDIO_ING_SONG: state => { // 返回当前播放歌曲对象的信息 return state.playList[state.audioIngIndex] || {} } } export default getters ================================================ FILE: musicPlayer/src/store/index.js ================================================ /* * @Author: 李浩栋 * @Begin: 2019-07-30 16:42:30 * @Update: 2019-09-12 14:23:38 * @Update log: 更新日志 */ import Vue from 'vue' import Vuex from 'vuex' import state from './state' import mutations from './mutations' import getters from './getters' import actions from './actions' Vue.use(Vuex) const store = new Vuex.Store({ state, mutations, getters, actions }) export default store ================================================ FILE: musicPlayer/src/store/mutation-types.js ================================================ /* * @Author: 李浩栋 * @Begin: 2019-07-30 16:42:30 * @Update: 2019-08-11 18:00:46 * @Update log: 更新日志 */ export const SHOW_LOGIN = 'SHOW_LOGIN' // 显示侧边栏 export const HIDE_LOGIN = 'HIDE_LOGIN' // 隐藏侧边栏 export const TOGGLE_MODE = 'TOGGLE_MODE' // 日夜模式切换 export const TOGGLE_MODE_TEXT = 'TOGGLE_MODE_TEXT' // 日夜文字切换 export const TO_SUN = 'TO_SUN' // 由夜转换到日 export const TO_YUE = 'TO_YUE' // 由日转换到夜 export const LOGIN_STATE = 'LOGIN_STATE' // 登陆状态 export const SET_LEVEL = 'SET_LEVEL' // 设置用户等级 export const ACCOUNT_UID = 'ACCOUNT_UID' // 存取用户id export const SET_LOAD = 'SET_LOAD' // 设置当前已经返回数据,显示界面 export const RETURN_LOAD = 'RETURN_LOAD' // 将load返回默认的true export const SET_LINK_PAGE = 'SET_LINK_PAGE' // 将load返回默认的true export const SET_PLAY_SATE = 'SET_PLAY_SATE' // 设置当前的播放状态 export const SET_FULL_SCREEN = 'SET_FULL_SCREEN' // 设置当前的播放器的状态,是大还是小 export const SET_AUDIO_LIST = 'SET_AUDIO_LIST' // 设置当前的播放列表的展示 export const SET_PLAY_LIST = 'SET_PLAY_LIST' // 设置当前的播放列表 export const SET_AUDIO_INDEX = 'SET_AUDIO_INDEX' // 设置当前的播放歌曲是第几个,索引值 export const SET_AUDIO_MODE = 'SET_AUDIO_MODE' // 设置当前的播放模式 export const SET_PLAYING_SHOW = 'SET_PLAYING_SHOW' // 设置当前是否显示转盘播放页面 ================================================ FILE: musicPlayer/src/store/mutations.js ================================================ /* * @Author: 李浩栋 * @Begin: 2019-07-30 16:42:30 * @Update: 2019-09-12 13:48:12 * @Update log: 更新日志 */ import { SHOW_LOGIN, HIDE_LOGIN, TOGGLE_MODE, TOGGLE_MODE_TEXT, TO_SUN, TO_YUE, LOGIN_STATE, ACCOUNT_UID, SET_LOAD, RETURN_LOAD, SET_LINK_PAGE, SET_PLAY_SATE, SET_FULL_SCREEN, SET_AUDIO_LIST, SET_AUDIO_INDEX, SET_PLAY_LIST, SET_AUDIO_MODE, SET_PLAYING_SHOW, SET_LEVEL } from './mutation-types' // 实现侧边栏显示时底部不跟随滚动 import ModalHelper from 'utils/modalScroll' export default { // 显示左侧侧边栏页面 [SHOW_LOGIN] (state) { state.loginPage = true ModalHelper.afterOpen() }, // 隐藏左侧侧边栏页面 [HIDE_LOGIN] (state) { state.loginPage = false ModalHelper.beforeClose() }, // 从日间模式切换到夜间模式 [TO_YUE] (state) { console.log('切换到夜间') state.iconyueliang1 = false state.icontaiyang = true this._mutations.TOGGLE_MODE_TEXT[0](state) }, // 从夜间模式切换到日间模式 [TO_SUN] (state) { console.log('切换到日间') state.iconyueliang1 = true state.icontaiyang = false this._mutations.TOGGLE_MODE_TEXT[0](state) }, // 切换夜间 日间模式 [TOGGLE_MODE] (state) { if (state.iconyueliang1) { this._mutations.TO_YUE[0](state) } else if (state.icontaiyang) { this._mutations.TO_SUN[0](state) } }, // 切换夜间 日间模式文本 [TOGGLE_MODE_TEXT] (state) { if (state.icontaiyang) { state.modeText = '日' } else { state.modeText = '夜' } }, // 设置用户登陆状态 [LOGIN_STATE] (state, num) { state.loginState = num }, [SET_LEVEL] (state, num) { state.level = num }, // 存取用户 uid [ACCOUNT_UID] (state, id) { state.accountUid = id }, // 设置搜索展示页面的loading图标 [SET_LOAD] (state) { state.load = false }, [RETURN_LOAD] (state) { state.load = true }, /** * 设置搜索展示页标签导航条 */ [SET_LINK_PAGE] (state, page) { state.linkPage = page }, /** * 设置播放状态 * @param {*} state state 数据 * @param {*} flag 播放状态 */ [SET_PLAY_SATE] (state, flag) { state.playState = flag }, /** * 设置播放器是大还是小 */ [SET_FULL_SCREEN] (state, flag) { if (flag) { ModalHelper.afterOpen() } else { ModalHelper.beforeClose() } state.fullScreen = flag }, /** * 设置播放列表信息 */ [SET_AUDIO_LIST] (state, list) { state.audioList = list }, /** * 设置索引 */ [SET_AUDIO_INDEX] (state, index) { state.audioIngIndex = index }, /** * 设置当前播放列表 */ [SET_PLAY_LIST] (state, list) { state.playList = list }, /** * 设置当前播放模式 * @param {*} state state数据 * @param {*} mode 模式索引 */ [SET_AUDIO_MODE] (state, mode) { state.mode = mode }, /** * 设置当前是否显示转盘播放页面 */ [SET_PLAYING_SHOW] (state, boolean) { state.playingShow = boolean } } ================================================ FILE: musicPlayer/src/store/state.js ================================================ /* * @Author: 李浩栋 * @Begin: 2019-07-30 16:42:30 * @Update: 2019-10-09 12:15:26 * @Update log: 更新日志 */ export default { loginPage: false, // 侧边栏显示与否 icontaiyang: false, // 日间模式 iconyueliang1: true, // 夜间模式 modeText: '夜', // 日夜模式文字信息 loginState: 0, // 登陆状态,初始值为 0 未登录,登陆成功设置为 1 accountUid: 0, // 存取用户 uid load: true, // 定义搜索展示界面 loading 图标的展示与否 linkPage: 'composite', // 定义搜索展示页的标签导航条应该根据路由信息进行滚动 playState: false, // 是否正在播放, fullScreen: false, // 是否是全屏展示播放页 audioList: [], // 用来展示播放列表项 playList: [], // 用来存储各种播放模式的列表 mode: 0, // 用来记录当前播放模式 0:列表循环,1:单曲循环 2:随机播放 audioIngIndex: -1, // 正在播放的这一首歌曲索引 playingShow: true, // 是否显示转盘播放页面 offsetLyric: 0, // 设置歌词偏移 level: 0 // 用户等级 } ================================================ FILE: musicPlayer/static/.gitkeep ================================================