xtzero.me
欢迎访问 xtzero.me !
「从前从前,有个人爱你很久」
最近文章
centos7 安装 php7.4 提示 No package 'openssl' found
yum install openssl openssl-devel 傻逼csdn
发表时间 2022-09-26 11:49:37
发表在 技术学习
阅读数 0
搭建一整套服务器
硬件准备 主板:B310m CPU:i5 8400F 内存:2 x 8G 硬盘:240 SSD,3T HDD 电源:额定功率 200w 机箱 服务器规划 由于使用的小米路由器,所以内网下所有设备的ip都是 192.168.31.* 。 主机 内网ip:192.168.31.50 hyper-v SMB 文件服务 虚拟机 1:web 服务 内网ip:192.168.31.51 ssh 端口:2201 nginx php、php-fpm、swoole node.js 虚拟机 2:数据库服务 内网ip:192.168.31.52 ssh 端口:2202 mysql 内网端口:3306 外网端口:3000 用户名和密码: redis 内网端口:6379 外网端口:3001 密码: mongodb 内网端口:27017 外网端口:3002 用户名和密码: nginx 虚拟机 3:运维服务 内网ip:192.168.31.53 ssh 端口:2203 gogs 内网端口:3000 外网端口:3003 外网访问地址:http://gogs.xtzero.me:3003 得建个 git 用户,git 用户密码得记。 jenkins 内网端口:8080 外网端口:3004 外网访问地址:http://jenkins.xtzero.me:3004 git nginx java 1.8 daemonize 虚拟机 4:文档、ddns、日志 内网ip:192.168.31.54 ssh 端口:2204 yapi 内网端口:3001 外网端口:3005 外网访问地址:http://yapi.xtzero.me:3005 ddns nginx nodejs 日志服务(还没看) 虚拟机 5:邮件服务 内网ip:192.168.31.55 ssh 端口:2205 SMTP 邮件服务(还没看) 实施顺序 主机安装 windows server 主机安装 hyper-v 主机安装 SMB服务 主机安装向日葵 ddns gogs jenkins mysql、redis web 服务 剩下的随便装了 具体实施过程 等 12 月服务器到期之前实际安装的时候再记录。
发表时间 2022-08-16 17:24:47
发表在 技术学习
阅读数 0
将家里的电脑当成服务器放到公网并允许域名访问
起因 最近搬了新家,第一件事就是把原来移动的渣渣宽带退掉,然后携号转网,投靠了联通,顺带办了联通的宽带。租房子的时候一直想在家里搭一个服务器,终于搬进了自己的房子里,就马上开始着手做这件事了。 家里有一个台式机,是之前为了玩游戏自己组的主机,后来又为了装黑苹果换了一套硬件。本来想另外买一套硬件来专门搭服务器的,因为弄房子花光了钱,就只能先用这个台式机先猜猜坑了。尝试着搭一下,看看方案可不可行。如果这次成功了,至少证明这个方案是可行的。等真正需要在家里搭服务器了,再重新来过也可以。 期望 把原来在阿里云上的服务都转移到台式机上来,配置域名解析,让外网可以通过域名访问到台式机的服务上来。 主要还是因为之前买的三年的阿里云服务器要到期了,续期的价格还高了三倍。 方案 先在台式机上装个 CentOS,搭建好服务器环境,把项目都下载下来,代码都跑起来。 配置解析,让域名解析到本地服务器的公网 ip 上。 根据 dnspod 的文档写个定时脚本,让公网 ip 变化后及时上报到 dnspod,修改解析记录。 实现 装系统和搭环境都比较容易,毕竟一直以来做的就是这些东西,这部分略过不写。 配置解析,就需要有当前机器的公网 ip。最开始想要尝试一下 ipv6 的,因为 ipv4 指向的是家里的路由器,ipv6 指向的是具体的设备。 于是使用 IPv6 测试检测了一下,发现家里的网是支持 ipv6 的。 但是友人 Hermit 及时指出了问题所在。 于是转而使用 ipv4 进行配置了。 使用百度获取到家里的 ip,在 dnspod 将域名解析到百度给的 ip 上。 然后在小米路由器的后台配置端口转发,需要将路由器被请求的接口映射到电脑上对应服务的端口上。这步没有图,因为我没在家。想起来再补图。 最蛋疼的一步来了,由于是家用宽带,即使提供了动态的公网 ip,也是不允许 80 端口被外部访问的。也就是说,无论服务器内部如何配置,只要客户端访问的端口是 80,这个请求就不会进到服务器中。 这时候就需要使用 dnspod 提供的隐形URL解析功能了。将另一个二级域名的 80 端口隐形转发到主域名的非 80 端口下,这样就实现了外部能访问 80 端口的效果。整个流程大概是这个样子: 不光这样就够了,在服务器上还需要用 nginx 来处理对应域名来的请求。以上图举例,nginx 需要处理的是 really.hostname.com:8888,而不是fake.hostname.com,因为真正访问到服务器上的域名是前者。 这样就绕了一个大圈子,终于让外网域名和内网的服务连通了。还有最后一件事,就是依照文档 写定时脚本,定期上报本机 ip 即可。 由于是动态 ip,所以无法避免一个问题:用脚本上报 ip 后,解析生效还需要一段时间,大约五六分钟左右。所以每次 ip 变更后都会有五六分钟的宕机时间,这个暂时没想到方案可以避免。由于搭建的服务器就是我个人的博客和一些小的项目,这个影响暂时不是很大。如果是很多人用的在线服务,这个影响就很大了。
发表时间 2022-05-19 16:44:50
发表在 技术学习
阅读数 0
我们做了一个领养平台
大约是2020年的3月,我找到叶姨,我说想做一个领养平台。 感觉现在送养和领养的市场很大,而且信息不对等。想领养的人找不到靠谱的养猫人,想送猫的人找不到想领养的人,找到了也怕不靠谱。那会我刚好在看boss直聘,发现可以用简历和岗位的方式去做领养和送养。领养的人需要制作一份自己的领养简历,说明自己的养宠物经历。送养的人也可以在平台上积累自己送养的经历,以显示自己在养猫这条路上的经验积累。 科学喂养很重要。这件事是我养了大C之后才明白的。在那之前,我以为养猫养狗就是让它能吃能睡就可以了。把大C领回家之后,我发现需要学习的东西太多了,就连最基本的选粮选猫砂选玩具,都是从头学起。这学习的过程中,叶姨帮了我许多。 大C是我毕业后领养的一只大白猫,名字是室友楠哥起的。楠哥为我以后养宠物都布好了局,养猫叫大C,养狗叫大D,养猪叫大P,以此类推。叶姨是我探索领养过程中认识的资深养猫人,我从叶姨手里领养到了一只三花妹妹,只是三花妹妹胆子太小了,来了家里不吃不喝,就被叶姨领走了。从那之后,养猫的事情事无巨细,我都是问叶姨,从某种角度上来讲,叶姨是我养猫路上的老师。 叶姨是一位资深铲屎官,家里有好多好多猫,都是被救助回来的。叶姨在救助这条路上走了十多年,被救回来的猫数不胜数,这其中故事也三天三夜都讲不完。我想做这样一个平台,可以承载领养和送养之中信息交接的事情,让有爱心的人可以多救助流浪猫,让想领养猫的人也能很快的找到靠谱的送养人。 前些天一个朋友跟我说,“我被一只猫咪捡到了,来告诉你一下”。这是多么幸运的一件事啊,无论对于猫还是对于人,我这样想。做这样的一个平台完全是公益性质的,只是不愿意看见有很多的流浪猫再在街上跑了。有的时候走在街上,看到一只特别可爱的猫咪在捡路边的剩饭,我就想,这本来应该是跟人类抢沙发的猫咪啊。如果这个平台能在“世界上再也没有流浪猫”这件事上产生一点点的推动作用,我就知足了。 “喵爪”是我一直想做的东西,这可能是我学技术以来第一次想为世界做点什么,也可能是一种莫名的使命感。学习的过程就好像在磨一把剑,小有成就后就会觉得自己手里有了一把不算很锋利的利器。有的人手里有刀了之后第一想法是砍向那些本来砍不到的人,而我想用这把刀去保护那些本来保护不了的人和动物。 这个东西很久之前就开始做了,但是没有想到会有一天能有这么多人和我一起做。叶姨在圈子里算是小有名气,还有很多像我一样的追随者随时准备帮忙。于是我们的小团队就这样组建好了。我负责把东西做出来,让这些信息可以在网上流通。伙伴们负责想点子和提供内容。第一批的数据已经跑在数据库里了,最初的梦想也就是让这些小动物都有家可归。 我们提倡科学喂养,希望所有想要养猫的人都能学习正确的喂养知识,让更多可爱的猫咪有一个温暖的家。后期可能会发展一些内容上的功能,分享一些喂养知识,或者是邀请一些资深铲屎官来分享一些养猫途中的故事和经验。叶姨十年来的故事我也很好奇,希望有一天能让这些故事出现在我的平台上。 更长远一点的梦想,可能就不限于流浪猫。等我们足够强大,我们希望可以帮助更多流浪动物找到自己的铲屎官。天下苍生与我们出生在同一个世界上,只是因为人类的进化而走到了食物链的顶端。作为高等动物,更应该去帮助其他动物更好地生存。我们不希望看到有虐猫虐狗的事情出现,正所谓“弱者抽刀向更弱者”,如果一个人只能靠欺凌更弱小的动物来获得快乐,那和野兽还有什么区别。 更远的梦想就不敢提了,毕竟现在连第一步还没有迈出。希望我们的努力会让世界变得哪怕一点点的更好吧,这是我喜欢做的,也是我想做的,也是大C想看到的。 “喵爪”开业大吉。
发表时间 2021-09-18
发表在 技术学习
阅读数 0
使用自定义指令完成页面间保留状态
业务需求 我们需要在单页面应用中,在页面切换的过程中也保持某些输入框的状态。例如在页面A使用手机号搜索出了一个列表,从B页面切换回A页面时,还要保持手机号的输入和搜索结果。 页面生命周期 对于传统页面,一个页面的生命周期就是从加载网页到关闭或刷新网页,用户的操作全部都是在这个生命周期里,开发的时候考虑单个生命周期的状态及数据流动即可。页面切换会导致url变化,从而重载页面。 对于SPA项目,整个网站是一个页面,也是一个完整的生命周期。每个子页面各自的生命周期只是整体生命周期中事件循环的一部分。SPA项目使用路由来控制子页面切换,路由切换会导致锚点(有的项目则是url参数)变化,而不会重载整个页面。可以理解为SPA项目把页面切换变成了一个网页中的功能,开发者开发一个又一个“页面”则是当前页面下的一个组件。页面切换则是通过diff算法来改变页面上显示的元素来实现的。 方案 <keep-alive> keep-alive是Vue官方提供的页面缓存组件,官方对此的解释是: <keep-alive> 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。和 <transition> 相似,<keep-alive> 是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在父组件链中。 当组件在 <keep-alive> 内被切换,它的 activated 和 deactivated 这两个生命周期钩子函数将会被对应执行。 在 2.2.0 及其更高版本中,activated 和 deactivated 将会在 <keep-alive> 树内的所有嵌套组件中触发。 主要用于保留组件状态或避免重新渲染 但是在实际使用过程中,keep-alive会导致在路由切换时传页面,搞得我的前端同事很痛苦。具体为什么串页面,以及keep-alive的运行原理,我没有仔细研究,这个是未来需要学习的一个点。而且在这个业务需求里,我们也不是想要完全保留页面的状态,而是保留某个组件的值。如果未来有某个需求,只想让页面中的某几个输入框保留状态,keep-alive的优势就一点都没有了,反而成了bug。于是这让我想到,有没有什么办法也能保留页面状态,而且是组件级别的。 v-directive 这就让我想到了Vue的自定义指令Directive。Directive是写在每一个组件上的,可以根据自己写的逻辑,让这个组件的生命周期里实现不同的逻辑。 于是我想,能不能写一个指令,让所有带这个指令的组件在状态被更新的时候,都把当前值保存到store,在这个组件重新被创建时,都从store里取到值,并重新填回组件的绑定对象里。查了一下自定义指令的功能,这么干是可以的。干成功之后发现这玩意确实是可以的。 干 Directive 指令 官方文档 对于Vue的指令我们已经很熟悉了,平时常用的v-if、v-for都属于Vue指令。Vue对于指令的描述是: 在 Vue2.0 中,代码复用和抽象的主要形式是组件。然而,有的情况下,你仍然需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令。 钩子函数 在Vue的文档中,我们直接复制过来钩子函数的内容: bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。 inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。 update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。 componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。 unbind:只调用一次,指令与元素解绑时调用。 在这次的开发中,我们用到了bind和componentUpdated钩子。我们在组件更新状态时将新的值保存到store中,在页面重新被进入,组件在本次进入页面中第一次出现时从store中取值,如果有值则存入组件的状态里。 组件的全局唯一key 既然要全局保存一个组件的状态,我们则需要试图从directive提供的参数里找到能在全局代表一个唯一组件的值。这里就需要提到bind和componentUpdated钩子提供的参数。 bind(el, binding, vnode); componentUpdated(el, binding, vnode, oldVnode); 在一番console.log观察后,我发现vnode.data.model.expression是组件绑定值的表达式。例如有组件<input v-model="search.mobile"></input>,那么这个组件绑定值的表达式就是search.mobile。只要在一个页面中,data中的某一个值只被一个组件绑定,那么vnode.data.model.expression在当前页面就是唯一的。如果一个页面中data中的某个值被多个组件绑定,那也满足我们的需求——这多个组件共用一个状态,我们为这些个组件保留为同一个状态,这也合理。 在另一番console.log观察中,我发现vnode.child.$route.fullPath是这个组件所在的页面的路由值。如果当前页面路由值是全局唯一的,那么${vnode.child.$route.fullPath}_${vnode.data.model.expression}就是这个组件在全局的唯一标识。例如当前页面的路由是/home/page1,组件的v-model是search.mobile,此时唯一标识是/home/page1search.mobile,表示在页面/home/page1中,绑定了search.mobile的组件。如果想更人性化一些,可以使用md5或sha1等的方式,让这个唯一标识更像id一些,但我没有这样做,现在这样就足够了。 不使用v-model的麻烦组件 到这里还有一个问题。对于普通的使用v-model来绑定值的组件来说,vnode.data.model.expression可以直接拿到v-model里的表达式,我们这个方法还好用。如果是element-ui里的pagination这样的组件,绑定值是用:page.sync这样的属性来实现的,我们的表达式就不管用了。所以对于非v-model绑定的组件,我们提供了state-key属性。在这种组件中使用指令的时候,需要额外使用state-key来指定绑定的值。比如: <pagination v-stateful state-key="page.page" :page.sync="page.page" /> 在实际使用过程中,我们发现这类组件不光有state-key的问题,由于不是使用v-model更新的状态,就算是我们用指令把数据塞到page.sync绑定的值里,组件的显示状态也不会变。也就是说会有可能当时页面已经被指令翻到第4页了,但页面上显示的还是1。为了解决这个问题,我们尝试了Vue.$forceUpdate,但是不管用,问题出在组件的:key上。如果使用指令改动了这个组件的绑定值,也需要更新这个组件对应的:key值,这样才会更新这个组件的显示状态。 <pagination v-stateful state-key="page.page" :page.sync="page.page" :key="randnum" /> data() {return { randnum: 1 }}, methods: { switchPage() { // .... randnum ++ } } 这里其实有改进的余地,可以让指令的代码不用污染到具体的业务组件。可以在state中创建一个randnum的对象,每个页面的全局唯一key都是这个对象下的子对象。对于这些“麻烦组件”,让它们的key去绑定这个store里的值,在指令更新了组件的值之后,再去更新对应的randnum就好了。 // $store.state { stateful: { randnum: { "/home/login_mobile": 1, "/home/login_passwd": 1, "/home/dashboard_mobile": 1, "/home/dashboard_gender": 1, } } } componentUpdated(el, binding, vnode, oldVnode) { // ... vnode.context.$store.state.stateful.randnum[vnodeKey] ++ } 上面说的“改进的余地”实际还没有改进,现在的项目中还是在每个页面里为这些麻烦组件在data里单独声明一个随机数变量,有机会一定把这些麻烦分子都干掉。 起个名 既然这个自定义指令让使用它的组件都更富有状态,甚至可以抵抗路由切换,那么我们就叫它stateful吧。那么对应的指令就是v-stateful了。 这个名字在前面的实例代码里也出现过好多次了。 全局绑定 指令开发好了,被我放在了@/directive/stateful里,在main.js里全局声明一下,就能在整个项目的任何地方都使用v-stateful来应用这个命令了。 // @/main.js import stateful from '@/directive/Stateful/stateful.js' Vue.directive('stateful', stateful) // @/views/*.vue <pagination v-stateful state-key="page.page" :page.sync="page.page" :key="randnum" /> NPM 既然是一个独立的功能,能不能不让它出现在我们代码的业务目录里,而是像某一个独立的模块一样,被yarn安装在node_modules里。于是我想,能不能把它发布到npm上。 先去npm的官网注册个账号,然后去github上创建个仓库,把自己的代码组织一下。 / ---- src -------- stateful.js ---- index.js ---- package.json /src/stateful.js就是刚刚写完的完整的业务代码,index.js负责导出。在加上其他乱七八糟的文件(.gitignore、readme),就可以准备发布了。发布过程没什么含金量,我就罗列了。 $ yarn init $ npm login -d # 在这输入在npm官网注册的用户名、密码、邮箱 # 而且邮箱是公开的 $ npm publish 如果输出绿色的话,不出意外你就可以在npm仓库里搜到自己的成果了。 发布成功后,我们把@/src/directive里的代码删掉,使用yarn安装自己的库,从库中引入。 $ yarn add statefulvue import stateful from 'statefulvue' Vue.directive('stateful', stateful) 十分炫酷。 相关地址 npm地址 github源码
发表时间 2021-08-27
发表在 技术学习
阅读数 0
StatefulVue - 保存状态的自定义指令
statefulvue 保存状态的自定义指令 @xt 在任意需要保存状态的组件上使用 v-stateful,即可在当前Vue生命周期内,路由切换的过程中保留其绑定的值。例如: <el-input v-model="value" v-stateful></el-input> 可以对组件提供 :query-key=“queryKey” 属性,来优先从queryKey的url参数里获取值。例如: <el-input v-model="value" query-key="input_value" v-stateful></el-input> 对于一些不是使用v-model绑定的组件,需要为其指定 state-key,来让stateful指令知道需要绑定到data下的哪个值 这些组件往往不是双向绑定,所以需要将key绑定到 $store.getters.randNum 上,来保证每次都会更新组件状态。例如: <pagination v-stateful state-key="page.page" :page.sync="page.page" :key="$store.getters.randNum" /> 如果一个组件使用了v-stateful,但没有v-model和state-key,则会报错:使用v-stateful,v-model 和 :state-key至少有其一。
发表时间 2021-08-25
发表在 技术学习
阅读数 0
charles 在线破解
链接
发表时间 2021-04-27
发表在 技术学习
阅读数 0
小程序中使用组件和插槽
小程序中页面和组件是完全不同的两个东西,这里跟Vue还是有很大的差别的。最近写小程序用到了,就做个记录。 定义组件 创建组件的时候使用小程序开发工具中的“新建Components”,就可以创建组件四件套。 其中,组件的js文件中,构造方法和页面是不一样的。 Component({ /** * 组件的属性列表 */ properties: { }, /** * 组件的初始数据 */ data: { }, /** * 组件的方法列表 */ methods: { } }) 组件属性 和Vue相同的是,组件中data和properties是区分开的。二者的区别是“在使用组件时需要不需要从父组件/页面中传入”。data中存放内部的值,是不需要从父页面传入的;properties中存放组件属性,这里的值是可以从父页面传入的。 本文中我们想要开发一个“设置”页面。在这个页面中,每一行设置项都使用封装的组件。每个组件需要标题、图标、右侧的文字内容或图标。从而我们描述如何在小程序中封装组件和使用插槽,还有父页面和子组件之间通信。 本文中使用page代表页面,使用components代表组件。使用wxml代表页面/组件文件,使用wxss代表样式文件,使用js代表js文件。 <!-- page.wxml --> <list-card title="设置用户信息" icon="flower-o" ></list-card> <!-- component.js --> properties: { title: { type: String, value: "" }, icon: { type: String, value: "" } } 从代码中可见,properties中定义的值可以被父页面中的组件标签传入。在定义properties时,可以指定类型和默认值。 插槽 slot是Vue中的特性,既然提到了组件,那么小程序中就也有插槽的特性。很幸运地,小程序中,插槽和Vue中的插槽用法大致相同。 例如在上面的例子中,我们需要使用插槽来自定义右侧的图标或文字。 <!-- page.wxml --> <list-card title="设置用户信息" icon="flower-o" > <van-icon slot="subtitle" name="arrow" /> </list-card> <!-- components.wxml --> <view class="card"> <slot name="subtitle"></slot> </view> 父页面中给组件绑定事件 也就是在组件中调用父页面中的方法 我们需要在组件中预置点击事件,触发事件时主动调用父组件中的方法。 <!-- components.wxml --> <view class="card" bindtap="onCardClick"></view> 组件中的点击事件这样写,从而触发父页面中,写在组件属性中的事件。 // components.js onCardClick() { this.triggerEvent("click", {}) } 看组件js的代码意思大概是触发当前组件的click事件,在父页面中,我们需要给组件指定一个bindclick属性。 <!-- page.wxml --> <list-card title="关于" icon="warning-o" bindclick="setUserInfo" > 不知道小程序这样设计是为了什么,明明在组件中指定的是click事件,但在父页面中得在这个词前面再加bind。不得不说这样的设计惊为天人。 // page.js setUserInfo() { // 在这写具体的逻辑 } 父页面中调用组件的方法 首页中的tab页我使用组件方式实现,使用tab切换的页面都使用组件实现,首页里套这些组件。 现在需要在列表触底时触发组件的列表翻页事件。只需要在父页面中取到组件的节点,直接调用节点下的方法即可。 // page.js // onReachBottom 是小程序的页面触底事件 onReachBottom() { if (this.data.tabbarActive == 'home') { const homepage = this.selectComponent('#homepageComponent') homepage.onPagePullUp() } } // components.js /** * 当页面上拉加载 * 从父页面index触发 */ onPagePullUp() { // 里边是具体的上拉加载逻辑 const _this = this _this.setData({ ["where.page"]: _this.data.where.page + 1 }) _this.getList() }, 总结 小程序真好玩。
发表时间 2021-04-12
发表在 技术学习
阅读数 0
在easyswoole里内置文档
YAPI时代 在之前的文章里我给内网搭了个YAPI文档管理站。在那之前,我跟前端的交流基本全靠企业微信。写好了接口在企业微信把参数和路径发过去,前端有问题了再找我。后来有了YAPI,从那之后我跟前端的互动就友好了很多。写完接口我就把接口填到YAPI里,需要特殊标记的事情我就写到备注里。 就这样,我跟我的前端度过了一年的快乐时光。这段时间里我送走了(他们自己离职)三个前端,在又收获了三个前端之后,我决定重新构建接口文档这一体系。 新的想法 公司的后端项目使用EasySwoole搭配FastRoute开发,正赶上最近开了新的项目,我和另一个后端哥哥想要使用PHP Annotation的注解功能来标注参数,从而进行参数验证。查看EasySwoole文档后发现框架已经自带注解功能了,于是想要使用框架自带的注解功能来获取参数,对接到原来的参数验证方法上。 引入相关的EasySwoole\HttpAnnotation\Utility\AnnotationDoc库等进行调试,发现EasySwoole的AnnotationDoc有个很致命的问题,那就是注解获取参数只能在控制器层进行。通常在后端架构上,参数验证功能通常都是在中间件中进行,稍微low一点的(比如我们)也是在BaseController中进行,但他们这东西只能在业务控制器上进行。如果采用这个方案的话,参数验证就不能统一处理了,只能在进入业务层之前验证前端参数。更鬼畜的是,用这种方式接收的前端参数,要么分成多个控制器参数接受,要么再多写一行注解统一堆到一个变量里。类似这个样子: /** * @Param a * @Param b * @Param c */ function example($a, $b, $c) { } 或者是 /** * @Param a * @Param b * @Param c * @Data $data */ function example() { } 无论哪种都不能实现我们的需求,于是我打算自己写一个。 在想用注解之前,我们的规则验证是用抽象类规定,在每个业务控制器里都必须包含一个getRule方法,用来规定每个接口的参数,例如: protected function getRules() { $rules = parent::getRules(); return array_merge($rules, [ 'infoMemo' => [ 'cid' => ['type' => 'int', 'default' => 0, 'desc' => ''], 'uid' => ['type' => 'int', 'default' => 0, 'desc' => ''] ], 'link' => [ 'cid' => ['type' => 'int', 'require' => false, 'default' => 0, 'desc' => '显示的cid'], 'mobile' => ['type' => 'string', 'require' => false, 'default' => '', 'desc' => '输入的手机号'] ] ]); } 这样也不是很人性化,特别是一个控制器里的接口多了之后,getRule方法就会变得特别特别长,代码逐渐变得不可维护。 在我自己的项目中,我都是在业务控制器中调用一个param方法来单独处理参数,这样就把标注参数的任务平摊到了每个业务控制器上,这样可以让代码看起来更加平均,参数维护起来也很省心。 既然这次接触了注解,那我们就重新设计参数验证方案,来从注解中获取参数,并对接到之前的参数验证逻辑中。 注解格式设计 既然要使用新式的注解,又要兼容之前的验证逻辑,那我们新设计的注解就长这个样子: /** * @Apiname 列表 * * @Param type {"type": "int", "desc": "类型"} * @Param order_by {"type": "string", "desc": "排序方式"} * @Param page {"type": "int", "default": "1", "desc": "第几页"} * @Param limit {"type": "int", "default": "20", "desc": "每页几个"} * * @Apidesc 一个列表接口 * */ 使用@Param关键字标注一个参数,接下来是参数名,最后是规则。新的规则表达式跟之前的表达式一样,只不过是转换为了json格式,这样更方便后边解析。 获取注解内容并解析 在EasySwoole中,我们可以使用控制器中的Request对象来获取当前请求的程序路径,例如这样就可以获取到当前程序运行的命名空间、类、方法: $this->request()->getUri()->getPath() 于是我们经过一番操作,就能分别获取到当前的类的路径和方法名。 $path = $this->request()->getUri()->getPath(); $pathArr = explode('/', $path); $pathArrWithoutFunction = $pathArr; $functionName = $pathArrWithoutFunction[count($pathArrWithoutFunction) - 1]; unset($pathArrWithoutFunction[count($pathArrWithoutFunction) - 1]); $controllerName = 'App\\HttpController\\' . implode('\\', $pathArrWithoutFunction); // $controllerName 是控制器类路径 // $functionName 是方法名 然后通过PHP的反射类,获取到对应的注释文本。 $ref = new \ReflectionClass($controllerName); $methodRef = $ref->getMethod($functionName); $doc = $methodRef->getDocComment(); // $doc 是完整的注释字符串 然后我们通过explode函数,使用\n将注释按行分割,逐行解析注释内容,提取到我们在注释中写的参数名和规则。 $_a = strpos($line, '@Param') + 6; $_b = strpos($line, "{"); $_name = trim(substr($line, $_a, $_b - $_a)); $_value = substr($line, $_b); $_rule = array_merge(json_decode($_value, true) ?? [], self::$commonRule); // $_name 是参数名 // $_rule 是规则数组 // self::$commonRule 是控制器里定义的公共参数,类似于appid之类的 这样我们就可以将参数名和规则数组传入原来的参数验证逻辑中处理了。到此为止,新的注解方式的参数标注就已经完全对接到我们原来的参数验证逻辑上了。 本来这个想法应该到此为止,但是我不满足于仅仅一个参数验证,我还希望借助这个注解的方式,可以自动生成接口文档。于是就有了后面的内容。 抛弃YAPI 由于所有的路由都定义在一张路由表Route.php中,所以我们可以从中获取到当前项目全部的接口。这里就出现了另一个恶心的事情,那就是FastRoute没有获取全部路由列表的功能(或者是我找遍了文档都没找到)。只能再次使用解析字符串的老本行了。 使用file_get_contents读取文件内容,再解析字符串。遇到带addGroup的行就分组,遇到post或get就用反射处理注释。 $routeFileContent = file_get_contents(self::$routerFilePath); $routeFileContentArr = []; $currentGroup = "/"; foreach (explode("\n", $routeFileContent) as $line) { if (stripos($line, 'addGroup') !== false) { preg_match_all('/addGroup\((.*), function/', $line, $matchGroup); $currentGroup = str_replace(["\""], "", $matchGroup[1][0]); } if (stripos($line, '$route->get') !== false || stripos($line, '$route->post') !== false) { preg_match_all('/\$route->(post|get)((.*), (.*));/', $line, $matchRoute); $method = $matchRoute[1][0] ?? ''; $url = str_replace(["(", "'", '"'], '', $matchRoute[3][0] ?? ''); $function = str_replace(['"', ")", "'"], '', $matchRoute[4][0] ?? ''); $group = $currentGroup; $params = []; // ... 就这样,我们就得到了一个完整的路由数组。 为了显示页面,我们需要写一个简单的模板变量替换的方法。 /** * 模板变量替换 * @param $templateFilePath * @param $data * @return false|string|string[] */ public static function C($templateFilePath, $data) { if (file_exists($templateFilePath)) { $content = file_get_contents($templateFilePath); foreach ($data as $k => $v) { $content = str_replace('{{'. $k .'}}', $v, $content); } return $content; } else { return ""; } } 然后使用这个简陋的模板渲染方法,将页面一点一点渲染出来。 public static function getDocHtml(Response $response) { if (ENVIRONMENT !== 'development') { self::display($response, ""); } else { $allRoutes = self::getAllRoutes(); $html = self::C(self::$phpdocPath . "/index.html", [ "title" => "接口文档", "baseHost" => Config::getInstance()->getConf('BASE_HOST'), "routes" => implode('', array_map(function($group) { return self::C(self::$phpdocPath . '/routeGroup.html', [ 'groupName' => $group['group'], 'routes' => implode('', array_map(function($route) { return self::C(self::$phpdocPath . '/route.html', [ 'method' => $route['method'], 'route' => $route['url'], 'group' => $route['group'], 'function' => $route['function'], 'apiname' => $route['apiname'] ?: "{$route['group']}{$route['url']}", 'apidesc' => $route['apidesc'], 'params' => implode('', array_map(function($param) { return self::C(self::$phpdocPath . '/param.html', [ "name" => $param['name'], "rule_desc" => $param['rule']['desc'] ?? '', "rule_require" => $param['rule']['require'] == 1 ? "是" : "否", "rule_type" => $param['rule']['type'] ?? '', "rule_enum" => implode(',', $param['rule']['enum'] ?? []), ]); }, $route['params'])), ]); }, $group['routes'] ?? [])) ]); }, $allRoutes ?? [])), "columns" => implode("", array_map(function($route) { return self::C(self::$phpdocPath . '/columnItem.html', [ 'name' => implode(" ", [$route['group'], $route['apiname'] ?: $route['url']]), 'id' => "{$route['group']}{$route['url']}" ]); }, (function () use($allRoutes){ $_allRoutes = []; foreach ($allRoutes as $v) { foreach ($v['routes'] as $vv) { array_push($_allRoutes, $vv); } } return $_allRoutes; })())) ]); self::display($response, $html); } } 如此大费周折,还不是模板变量替换方法太简陋了。为了前后端逻辑分离,在这里浪费了太多精力。 最后我们将得到的html字符串传送到浏览器就可以了。 $response->write($html); $response->withHeader('Content-type', 'text/html; charset=UTF-8'); $response->withStatus(200); 最后的实现结果是 新的计划 写到这里我就有点沾沾自喜了,因为接下来的开发里,我不需要再写完接口去给前端填写YAPI了,省去了一大部分编写文档的时间。 但到了自己调试接口的时候我就发现问题了,没有YAPI的话,我自己没法调试啊!YAPI有发送接口的功能,但我这玩意没有。要是想让我这个东西能发包,我还得开发个chrome插件来实现,或者是把公司前端项目里的参数验证逻辑也搬进来,包括恶心人的参数签名。 然后我发现了YAPI有json导入功能,可以识别YAPI、Postman、Swagger生成的json文件。于是我就有了下一步的计划。 下一步打算将获得的路由数组处理成YAPI能读的格式,然后对外网开放一个获取JSON的接口,这样把接口填到YAPI的后台,就能让YAPI也自动拉取接口文档了。这样就真的全自动了。
发表时间 2021-03-19
发表在 技术学习
阅读数 0
Effie - 一款简约、冷静、优雅的写作app
(我居然写软文了) Effie - 一款简约、冷静、优雅的写作app 我与markdown 在我很久之前的一篇文章中曾经求过你学习一下markdown,因为大部分对写作有需求的用户都有着这样的需求,那就是需要专注于写作内容,同时也需要一定的格式支持。 于是市面上就出现了两极分化的写作软件:第一种是类似于记事本一类的软件,它们不支持格式,或者一个文档仅支持同样的格式,它们的格式设置就像凑数的一样;另一种是类似word一类的软件,它们对格式支持特别强大,强大到你需要对这一种软件进行专门的学习。 在接触markdown之前,我的世界就像上面说的那样两极分化。有的时候仅仅是想记录下当前所想的内容,却在“打开word-保存文件-起文件名”的过程中就忘了想要写什么了。 从写博客开始 后来自己有了写博客的需求。在那之前,博客对于我来说就是QQ空间的日志,时不时记录一些鸡毛蒜皮的小事。博客的需求对于我来说,定位更加精确一些——我需要一个技术博客,来记录自己技术学习的历程。作为PHPer的我,自然而然地选择了typecho作为第一个博客。决定搭建博客的那个夜晚,我用几个小时的时间,购买了服务器,把typecho部署到了服务器上。当使用公网ip访问到了自己的typecho首页时,决定要经常更新博客,早日成为技术大牛。 typecho自带的markdown支持,让我获得了非常舒爽的写作感受。一个#代表一级标题,两个#代表二级标题,使用小角号框起来代表代码块…只需要记住一些简单的语法,就可以让markdown引擎处理成精美的文档页面。typecho伴随了我写博客的前两年。 后来在工作中使用了npm,与之一起出现在我的世界中的是另一个文档构建工具gitbook。gitbook甚至比typecho还便捷,它不需要数据库支持,也不需要把整个系统都部署到服务器,只需要在本地写好了md文档,上传到服务器上执行构建,就会变成静态的网站页面,连php处理伪静态都省了,人家可是真静态。 这时候就需要在本地使用一个支持markdown的编辑器了,在朋友的推荐下,我开始使用typora编写md文档。写完表示格式的符号之后马上就会显示出对应的样式,丝滑的体验让我爱上了这种写作体验。与之同时我接触到了hexo,我的博客体系正式敲定,这一套工具也伴随我到现在。 markdown 一柄写作利器 写博客的过程中,我发现markdown是可以抽离出来的单独的知识体系,只要会了markdown的语法,在任何支持markdown的地方都可以用它进行书写。不仅如此,不同的工具或网站还会把同样的markdown文档处理成不同样式的页面。比如github的readme页面和我自己的博客页面的展示样式就不一样。这让我很乐在其中。 会了markdown这柄利器后,我开始在其他需要书写的场景也寻找markdown的用武之地,很快地我盯上了最常用的写作场景——笔记。无论是学习中的笔记还是工作中的会议记录,我都可以在markdown的加持下展现更高的效率。 由markdown到笔记 在使用markdown记笔记的过程中,我体验了很多基于markdown的笔记软件,例如很常见的简书、熊掌记、语雀、我来等等。此类软件中的markdown大多是markdown的子集,也就是在markdown基础上削减一些复杂的书写格式,毕竟面向的是不会写代码的普通用户,跟写代码一样的道理,让用户写复杂的markdown也是不合理的。普遍的弥补方式是将复杂的类似表格的功能做成可点击的按钮,这样就可以使用简单的markdown语法配合简单的图形界面操作,在专注于写作的同事,也能写出好看的笔记了。 与Effie相识 这时候就要提到这次的主角Effie了。跟上面提到的其他工具不同,Effie是一款客户端软件,但它不是像typora那样的“文件编辑器”;同时Effie是在线的文档工具,但它不像语雀、简书那样只能在网页上操作。Effie同时具备客户端软件和web工具的优点,它具有网页的在线保存文档等优点,同时具有客户端软件的美观和流畅性。 简约的Effie Effie很简约,简约到它的官网不需要任何使用说明。任何用户注册进入程序后,都会在作品库里默认添加Effie使用入门和Effie快捷键列表。Effie支持markdown中的标题、字体、列表等语法,你可以使用#快速打出一个一级标题,也可以使用+或-创建一个无序列表。 在Effie中,你甚至可以体验到typora一样的所写即所得的体验,在空行输入三个减号---,可以快速创建一个分割线。 对于程序员或专业领域人员,可以使用一对``````来创建代码块,对于需要标注代码、公式或是其他场景都十分好用。 创建列表后,还可以点击左侧的符号来创建思维导图,这是迄今为止我所用过的最快的创建思维导图的方式。手里的mindnode瞬间就不香了。 一切都编写完成后,如果没有特殊需求,你可以将文档保存到云端,这样你只需要在其他位置登录你的Effie账号,就可以实现文档漫游。如果需要将文档导出成文件,Effie还提供了多种格式的文件导出支持。 冷静的Effie Effie很冷静,她不会在自己身上随意做加法,相反地,纵观Effie的界面,连按钮都几乎没有。她不需要更多的操作点来触发很多的功能,她只是在你需要的时候——例如需要写作的时候——给你展现出需要的功能组件——例如一个编辑区,这就足够了。 冷静是功能设计中很难得的点,大多数产品在设计阶段就开始了无尽的加法,产品经理恨不得把毕生所学都堆到一个功能里,这就导致了大部分的产品都很难逃离“臃肿”这一大弊。 其实一个好的产品,对于用户来说,只需要在需要的时候拿出必要的部分就足够了。至于其他没有展现的部分,总有需要它们的地方。如果一个软件的某些部分,在整个软件中根本没有需要展现的位置,那甚至就需要讨论这个部分是不是需要继续留下了。 在Effie中几乎不需要考虑这些问题,在足够的冷静下,任何一个多余的按钮都会打破这美好的意境。 优雅的Effie 在注册app后自带的几篇文档中,开发团队提到: Effie 是思想家专用的写作软件。 并解释说: 即使是优秀的思想,也只有变成文字才能为人所知,这就是思想家的宿命。 Effie 致力于把思想变成文字,最终成为价值。 作为一个开发者,同时也是内容创作者,这句话直接戳中我的心。一款好的写作软件,它不应该专注于提现它有多么多么多的功能点,或者是多么多么的庞大。相反地,庞大则意味着臃肿。一个好的写作软件,应该可以让使用它的人沉迷于写作本身,应该做到“无感”。 对于“思想家”,开发团队做了如下诠释: 思想家是心无旁骛的 —— “不觉已春深,物我两相忘” 思想家是注重逻辑的 —— “桐花诗八韵,思绪一何深” 思想家是敏捷高效的 —— “无穷如天地,不竭如江海” 程序工作者不应该是笨拙且木讷的,相反地,程序工作者应该是世界上最优雅的群体。他们使用内心的禅意,创造着改变他人的产品,用自己的理念来潜移默化地改变着世界,这是多么中二且热血的事。 Effie和Effie的创造者们一样,整个产品整体流露着优雅和禅意。创造者们使用自己的内心浇筑着Effie,使得Effie一样优雅且充满自信。 像Effie的创造者在文档中写的那样,文字工作本就应该有意清秋入衡霍,为君无尽写江天。
发表时间 2021-03-03
发表在 技术学习
阅读数 0
一个刷访问量的前端脚本
在主流浏览器中按F12打开开发者工具,点击选项卡console。要是没有console的话在右边的>>里找试试。 把下面的代码粘贴进去就可以用了。 复制粘贴后按回车,网页上会出现一个小窗口并不断刷新。 想要停掉的话就刷新网页(F5)或者关掉当前网页(Ctrl+w)就可以了。 下面是代码,两个版本都可以用,加密版本更俏皮,但也更长。 代码原文 (function(){var c=document.createElement("div");c.style.width="200px";c.style.height="22px";c.style.position="fixed";c.style.top="22px";c.style.right="10px";c.innerHTML="刷访问量插件";c.style.fontSize="12px";c.style.textAlign="center";c.style.backgroundColor="black";c.style.color="white";document.body.append(c);var b=document.createElement("div");b.style.width="200px";b.style.height="22px";b.style.position="fixed";b.style.top="144px";b.style.right="10px";var a=1;b.innerHTML="已经访问了"+a+"次";b.style.fontSize="12px";b.style.textAlign="center";b.style.backgroundColor="black";b.style.color="white";document.body.append(b);var d=document.createElement("iframe");d.style.width="200px";d.style.height="100px";d.style.position="fixed";d.style.top="44px";d.style.right="10px";d.src=window.location.href;d.onload=function(){b.innerHTML="加载完成,1s后刷新";setTimeout(function(){d.contentWindow.location.reload(true);a++;b.innerHTML="已经访问了"+a+"次"},1000)};document.body.append(d)})(); 加密版本 ゚ω゚ノ= /`m´)ノ ~┻━┻ //*´∇`*/ ['_']; o=(゚ー゚) =_=3; c=(゚Θ゚) =(゚ー゚)-(゚ー゚); (゚Д゚) =(゚Θ゚)= (o^_^o)/ (o^_^o);(゚Д゚)={゚Θ゚: '_' ,゚ω゚ノ : ((゚ω゚ノ==3) +'_') [゚Θ゚] ,゚ー゚ノ :(゚ω゚ノ+ '_')[o^_^o -(゚Θ゚)] ,゚Д゚ノ:((゚ー゚==3) +'_')[゚ー゚] }; (゚Д゚) [゚Θ゚] =((゚ω゚ノ==3) +'_') [c^_^o];(゚Д゚) ['c'] = ((゚Д゚)+'_') [ (゚ー゚)+(゚ー゚)-(゚Θ゚) ];(゚Д゚) ['o'] = ((゚Д゚)+'_') [゚Θ゚];(゚o゚)=(゚Д゚) ['c']+(゚Д゚) ['o']+(゚ω゚ノ +'_')[゚Θ゚]+ ((゚ω゚ノ==3) +'_') [゚ー゚] + ((゚Д゚) +'_') [(゚ー゚)+(゚ー゚)]+ ((゚ー゚==3) +'_') [゚Θ゚]+((゚ー゚==3) +'_') [(゚ー゚) - (゚Θ゚)]+(゚Д゚) ['c']+((゚Д゚)+'_') [(゚ー゚)+(゚ー゚)]+ (゚Д゚) ['o']+((゚ー゚==3) +'_') [゚Θ゚];(゚Д゚) ['_'] =(o^_^o) [゚o゚] [゚o゚];(゚ε゚)=((゚ー゚==3) +'_') [゚Θ゚]+ (゚Д゚) .゚Д゚ノ+((゚Д゚)+'_') [(゚ー゚) + (゚ー゚)]+((゚ー゚==3) +'_') [o^_^o -゚Θ゚]+((゚ー゚==3) +'_') [゚Θ゚]+ (゚ω゚ノ +'_') [゚Θ゚]; (゚ー゚)+=(゚Θ゚); (゚Д゚)[゚ε゚]='\\'; (゚Д゚).゚Θ゚ノ=(゚Д゚+ ゚ー゚)[o^_^o -(゚Θ゚)];(o゚ー゚o)=(゚ω゚ノ +'_')[c^_^o];(゚Д゚) [゚o゚]='\"';(゚Д゚) ['_'] ( (゚Д゚) ['_'] (゚ε゚+(゚Д゚)[゚o゚]+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (c^_^o)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(o゚ー゚o)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) - (゚Θ゚))+ (o^_^o)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(o゚ー゚o)+ ((゚ー゚) + (゚ー゚))+ (゚Д゚) .゚Θ゚ノ+ (゚Д゚) .゚Θ゚ノ+ (゚Д゚) [゚Θ゚]+ (゚Д゚)[゚ε゚]+(o゚ー゚o)+ ((゚ー゚) + (゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚) .゚Д゚ノ+ (゚Д゚) .゚Д゚ノ+ (゚Д゚)[゚ε゚]+(o゚ー゚o)+ ((゚ー゚) + (゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚) ['c']+ (゚Д゚) [゚Θ゚]+ (゚Д゚)[゚ε゚]+(o゚ー゚o)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚) .゚ー゚ノ+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(o゚ー゚o)+ (゚ー゚)+ (゚Д゚) .゚Д゚ノ+ (゚Д゚) [゚Θ゚]+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (c^_^o)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (c^_^o)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (c^_^o)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(o゚ー゚o)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚) .゚ー゚ノ+ (゚Д゚) [゚Θ゚]+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(o゚ー゚o)+ ((゚ー゚) + (o^_^o))+ (゚Д゚) .゚Д゚ノ+ (゚Д゚) ['c']+ (゚Д゚) [゚Θ゚]+ (゚Д゚)[゚ε゚]+(o゚ー゚o)+ ((゚ー゚) + (゚ー゚))+ (゚Д゚) .゚Θ゚ノ+ (゚Д゚) .゚Θ゚ノ+ (゚Д゚) [゚Θ゚]+ (゚Д゚)[゚ε゚]+(o゚ー゚o)+ ((゚ー゚) + (゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚) .゚Д゚ノ+ (゚Д゚) .゚Д゚ノ+ (゚Д゚)[゚ε゚]+(o゚ー゚o)+ (゚ー゚)+ (゚Д゚) .゚Д゚ノ+ ((゚ー゚) + (゚ー゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(o゚ー゚o)+ ((o^_^o) +(o^_^o))+ (゚Д゚) .゚Θ゚ノ+ ((o^_^o) - (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (c^_^o)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (c^_^o)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (c^_^o)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(o゚ー゚o)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚) .゚ω゚ノ+ (c^_^o)+ (゚Д゚)[゚ε゚]+(o゚ー゚o)+ ((゚ー゚) + (゚ー゚))+ (゚Д゚) [゚Θ゚]+ ((゚ー゚) + (o^_^o))+ (゚Д゚) .゚ー゚ノ+ (゚Д゚)[゚ε゚]+(o゚ー゚o)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚) .゚Θ゚ノ+ ((゚ー゚) + (゚ー゚))+ (゚Д゚) ['c']+ (゚Д゚)[゚ε゚]+(o゚ー゚o)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Θ゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(o゚ー゚o)+ (゚Д゚) [゚Θ゚]+ (゚Д゚) [゚Θ゚]+ (c^_^o)+ (゚Д゚) ['c']+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(o゚ー゚o)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (c^_^o)+ (゚Д゚) .゚Д゚ノ+ (゚Д゚)[゚ε゚]+(o゚ー゚o)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) - (゚Θ゚))+ (o^_^o)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(o゚ー゚o)+ ((o^_^o) +(o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚) .゚Θ゚ノ+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (o^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (o^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(o゚ー゚o)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚) .゚ー゚ノ+ (゚Д゚) [゚Θ゚]+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(o゚ー゚o)+ ((゚ー゚) + (o^_^o))+ (゚Д゚) .゚Д゚ノ+ (゚Д゚) ['c']+ (゚Д゚) [゚Θ゚]+ (゚Д゚)[゚ε゚]+(o゚ー゚o)+ ((゚ー゚) + (゚ー゚))+ (゚Д゚) .゚Θ゚ノ+ (゚Д゚) .゚Θ゚ノ+ (゚Д゚) [゚Θ゚]+ (゚Д゚)[゚ε゚]+(o゚ー゚o)+ ((゚ー゚) + (゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚) .゚Д゚ノ+ (゚Д゚) .゚Д゚ノ+ (゚Д゚)[゚ε゚]+(o゚ー゚o)+ (゚ー゚)+ (゚Д゚) .゚Д゚ノ+ ((゚ー゚) + (゚ー゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(o゚ー゚o)+ ((o^_^o) +(o^_^o))+ (゚Д゚) .゚Θ゚ノ+ ((o^_^o) - (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚o゚]) (゚Θ゚)) ('_');
发表时间 2021-03-01
发表在 技术学习
阅读数 0
vue中监听store中值的变化
才知道watch是可以监听store中的值的。 watch: { "$store.state.userInfo.Name":{ handler:function(newVal,oldVal){ console.log(newVal,oldVal); } } } 如果监听的是对象,需要加上深度 watch: { //此时我监听的是对象,当$store.state.userInfo.Name发生修改时,此时需要深度监听才能监听到数据变化 "$store.state.userInfo":{ deep:true,//深度监听设置为 true handler:function(newVal,oldVal){ console.log("数据发生变化啦"); //修改数据时,能看到输出结果 console.log(newVal,oldVal); } } } 如果用计算属性监听的话,监听对象就不好使了。 computed: { isEdit () { return this.$store.state.userInfo;  //需要监听的数据 }, }, watch: { isEdit(newVal, oldVal) { console.log("数据发生变化啦"); //修改数据时,看不到该输出结果,因为无法监听到数据的变化 console.log(newVal,oldVal); } }, 参考链接
发表时间 2021-02-26
发表在 技术学习
阅读数 0
整一波ts
安装 npm install -g typescript 运行 tsc index.ts 基础类型 布尔值、数字 let isDone: boolean = false let dec: number = 6 let hex: number = 0xf00d let bin: number = 0b1010 let oct: number = 0o744 console.log(isDone, dec, hex, bin, oct) 字符串 模板字符串 let onename: string = "bob" onename = "smith" let name2: string = `Gene` let age: number = 37 let sentense: string = `my name is ${name2}. I'll be ${age + 1} years old next month` console.log(onename, name2, sentense) 数组 let list: number[] = [1, 2, 3] let list2: Array<number> = [1, 2, 3] console.log(list, list2) 元组 let x: [string, number] x = ['hello', 10] 枚举 enum Color {Red, Green, Blue} let c: Color = Color.Green let colorName: string = Color[2] console.log(c, colorName) any let notSure: any = 4 // console.log(notSure.ifItExist(), notSure.toFixed()) let prettySure: Object = 4 // console.log(prettySure.toFixed()) let list1: any[] = [1, true, "free"] console.log(list1) list1[1] = 100 console.log(list1) void function warnUser(): void { console.log("warning!") } let unusable: void = undefined console.log(warnUser(), unusable) undefined 和 null 没啥用 undefined和null是任何类型的子类型 let u: undefined = undefined let n: null = null console.log(u, n) never never 表示永不存在的值的类型 never 也是任何类型的子类型 function error(message: string): never { throw new Error(message) } console.log(error("error!")) object 表示非原始类型,除了number string boolean symbol null undefined之外的类型 declare function create(o: object | null): void; create({ prop: 0}) create(null) 断言 let someValue: any = "string" let strLen: number = (<string>someValue).length console.log(someValue, strLen) let someValue2: any = "string" let strLen2: number = (someValue2 as string).length console.log(someValue2, strLen2) 变量声明 let是块作用域 多用let少用var 同一个作用域里一个变量只能let一次 const作用域跟let一样,声明完了不能再改 解构 let input: [number, number] = [1, 2] let [first, second] = input console.log(first, second) function f([first, second]: [number, number]) { console.log(first, second) } f(input) let [one, ...rest] = [1, 2, 3, 4] console.log(one, rest) // 1 [2, 3, 4] 太乱了不研究了用上了再说。 接口 interface SquareConfig { color?: string, width?: number } function createSquare( config: SquareConfig ): {color: string; area: number} { let newSquare = {color: "white", area: 100} if (config.color) { newSquare.color = config.color } if (config.width) { newSquare.area = config.width * config.width } return newSquare } let mysquire = createSquare({color: "black"}) console.log(mysquire) 函数类型的接口 interface SearchFunc { ( source: string, subString: string ): boolean } let mySearch: SearchFunc = function( source: string, subStirng: string ) { let result = source.search(subStirng) return result > -1 } console.log(mySearch("abc", 'a')) 可索引的类型 interface StringArray { [index: number]: string } let myarray: StringArray = ["bob", "fred"] let myStr: string = myarray[0] console.log(myarray, myStr)
发表时间 2021-02-25
发表在 技术学习
阅读数 0
做一个博客系统
年前做的东西,早就想写个博客记录一下,然后就过年了。电脑充满电带回了家,一条电居然撑到了上班。事实证明mbp的电池是可以在开机状态下合盖待机11天的。 今天的课题是用php做一个静态网站生成器,也叫博客系统。 东西已经做完了,官网是 Hikari 官网,文档里边有,文档本身就是示例,所以这一个地址点进去啥都有。 如果你是在公众号阅读的这篇文章,上边的Hikari官网可能不能点击。你需要点击左下角阅读原文进入原文链接,再点链接进入官网。或者直接复制网址http://hikari.website访问。 文档写得挺详细了,这边就记录一些知识点和坑吧。第一次用php写控制台程序,有很多东西都是之前没用过的。 控制台程序 在php程序中,使用$argc获取控制台参数数量,使用$argv获取控制台参数数组。比较难受的是,就算控制台里按照选项和选项值(command -a 1 -b 2)来输入,$argv也不会给出索引数组,而是将选项也当做一个值。如果要将程序设计成需要分析选项的,就需要特别处理才能获取到选项和选项值的索引数组了。 psr4自动加载 使用composer安装类库的话,项目根目录下就会有vendor目录,我们需要在项目启动的时候引入/vendor/autoload.php,来让composer加载类库。 接口 用interface规定程序模板,让实现同一个接口的类都遵循一样的模板。在Hikari中用interface规定了Cmd和Template。 <?php namespace Lib\Base; interface BaseCmd { /** * A command line command must have a `handle` function which is public and static! * @return mixed */ public static function handle($argv); } 一个Cmd类必须有handle方法,这样才能根据控制台输入找到对应的Cmd类,来执行对应类的handle方法。 <?php namespace Lib\Base; interface BaseTemplate { public static function render($data); } 一个Template类必须有一个render方法,这样的设计下,将Template类放在主题的配置数组里,执行构建命令时就可以依次执行每个Template下的render方法来输出静态页了。 markdown解析 直接使用了SegmentFault/HyperDown库,可以输入markdown输出html字符串。然后在模板渲染里写样式。 模板渲染 先写了一个模板渲染方法。 function C($filePath, $replaceData = []) { if (!file_exists($filePath)) { return ""; } $contents = file_get_contents($filePath); if (!empty($replaceData)) { foreach ($replaceData as $k => $v) { $contents = str_replace("{{{$k}}}", $v, $contents); } } return $contents; } 然后准备了一个页面目录pages和组件目录Components,里边存带有模板语法的html片段啥的。比如首页 <body> {{navbar}} <div class="container"> <img class="logo" src="/hikarilogo.png"></img> <h2 id="title"> {{title}} <!-- <span class="version">beta 1</span> --> </h2> <h3 id="subtitle">{{subtitle}}</h3> <div id="menus"> {{menu}} <script> ((function() { var menus = document.getElementsByClassName('menu-action') for (var i = 0; i < menus.length; i ++) { menus[i].addEventListener('click', function() { window.location.href = this.getAttribute('link') }) } })()) </script> </div> </div> {{footer}} </body> footer组件 <style> .footer { display: flex; flex-direction: column; align-items: center; margin-top: 100px; color: #3E4857; font-size: 13px; } </style> <div class="footer"> <div class="footer-author"> 使用 <a href="https://gitee.com/xtzero/hikari">Hikari</a> 构建 </div> <div class="footer-desc">一个简洁、高效、可定制的博客框架。</div> <div class="footer-statistic"> {{busuanzi}} </div> <div class="footer-police">*ICP备*号-*</div> </div> 和不蒜子组件 <!-- 放在页头 --> <script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script> <!-- 显示代码是 --> <span id="busuanzi_container_site_pv">👁 <span id="busuanzi_value_site_pv">加载中...</span></span> 我就可以使用模板渲染方法这样渲染一个主页 $html = C(THEME_BASE_DIR . '/page/index.html', [ 'title' => ENV['title'], 'subtitle' => ENV['subtitle'], 'navbar' => C(THEME_BASE_DIR . '/components/navbar', [ "title" => ENV['title'], "items" => implode("\n", array_map(function($v) { return C(THEME_BASE_DIR . '/components/navbarItem', $v); }, THEME_CONFIG['navbar'])) ]), 'menu' => implode("\n", array_map(function($v) { return C(THEME_BASE_DIR . '/components/indexNav', $v); }, THEME_CONFIG['homepageMenu'])), 'footer' => C(THEME_BASE_DIR . '/components/footer', [ "busuanzi" => C(THEME_BASE_DIR . '/components/busuanzi') ]) ]); 要是模板能支持条件和循环渲染就好了,暂时还没做,只能用implode和array_map来代替了。
发表时间 2021-02-18
发表在 技术学习
阅读数 0
iOS14搭配快捷指令在手机上写hexo博客
这次研究的课题是用iOS快捷指令通过ssh执行远程服务器上的操作,如果你没有服务器也没有iOS设备,那么你可以图一乐。 起因 最近工作忙/天冷/吃饱了撑的,导致睡眠不怎么规律,昨天下班到家就睡着了,结果8点多醒了,这就导致了半夜睡不太着觉。突然想起博客年久失修,生活博客半年没更,技术博客半年内倒是更了两个,但都是写了标题没写多少内容。不玩lol了之后是越来越懒得动电脑,家里的台式机也就是在吃饭的时候才打开20分钟用B站下饭。由于博客使用hexo搭建,不开电脑的话更新的几率就很小。所以我就想,我能不能在手机上写博客,再用一种快捷的方式推送到服务器上? 之前的操作 对于技术博客,通常就是学习到了新东西或者有一些阿妹子嘤的新发现,趁着兴奋劲在电脑上就写了;对于另一个生活博客,通常是在手机上用zine写完,再等有空(划水)的时候在电脑上同步一下。 对于hexo,通常是用 hexo new postname 创建一个markdown文件,写好内容后使用 hexo clean hexo g 生成静态页,再复制到nginx配置中对应的网站目录,这一番操作过后,新的创作就对外显示了。 由于这一番操作太复杂,我还搭建了jenkins,配合git来了一波自动部署。这样每次写完内容,只需要push到git上,就可以等待jenkins帮我把后续工作处理好了。这一番操作被我记录在了搭建jenkins配合gitee实现自动部署里。 新的想法 我可以不可以在手机上编写好内容,然后通过app的分享,把内容分享给iOS的快捷指令,然后拜托快捷指令帮我把内容上传到服务器,顺便同步到git,再自动部署呢? 打开快捷指令app,发现是有ssh功能的 这样思路基本就清晰了 用app分享文件给快捷指令 通过ssh传到服务器 服务器把文件内容保存下来 从git下载仓库 用yarn安装hexo 把博文内容移动到hexo目录下 构建hexo 复制hexo静态文件到网站目录 输出成功 开始实操 接受来自分享的数据 在快捷指令的设置里,可以设置当前快捷指令接受哪些消息,顺便我们用“显示结果”把获取到的内容显示出来以供调试。 需要注意的是,显示结果时需要选择“作为文件”。 打开备忘录,随便分享一个文件进来,可以看到快捷指令已经接收到了分享过来的备忘录,并显示了内容。 选择仓库 由于有两个博客,所以每次推送的时候需要手动选择要推送的博客。这里用到了快捷指令的列表和从列表选取的功能。 增加了这一步骤,顺便我们让它们一起展示出来。 编码传输 在实际操作过程中,我发现如果是用简单的echo markdown_content >> markdown_file.md的方式来保存文件内容是不可行的,原因有二: echo内容的时候会被markdown里不可预料的字符截断。 使用echo的话还需要处理换行等特殊字符。 可能还有其他麻烦事我没遇到,仅仅是这两个麻烦的问题就够我麻烦半天了。在友人Hermit的建议下,我决定使用base64传输博文数据。这样就算是换行都能处理在里边了。 可以看到,原文里不管是有换行还是特殊符号,一律转码成奇怪的人类看不懂的字符了。这边转成了base64,就肯定要在某个地方转换回来。我们只有指望服务器那边的shell能解码了。由于博客是在完成了之后才写的,所以我知道shell肯定能解码。 快捷指令连接服务器 在连接服务器的时候我们有两个选择,一个是用密码连接,一个是用SSH密钥连接。 由于我在电脑上一直是用SSH连接,所以这次也直接就想到用SSH连接了。生成密钥-上传到服务器一气呵成之后,出现了一个奇怪的问题。在快捷指令app里直接点击快捷指令运行时可以用SSH连接到服务器,脚本也都正常运行,也能正常输出结果,但是通过分享触发快捷指令时,服务器就会连接失败。调试了很多次之后放弃了SSH连接,改为密码登录了。 本来后续的文件处理、构建、同步git等操作都准备在快捷指令写的,转念一想,好像操作挺多的。决定在服务器上写个脚本执行后续操作,快捷指令只负责传值就好了。 在这一步,我们只需要把这几个参数 博客名 文件名 博文内容(base64) 传过去就可以了。 编写脚本 由于之前没怎么写过shell脚本,这一步可是费了好大的劲。但写博客就简单了,我直接复制过来就可以了。注释写得很全,就不多写别的了。 # 文件名,用在hexo new {filename} postname="$3.md" # 分类 blog_tech blog_life category=$1 # 博客内容 content=$2 echo 文件名是 echo $postname echo 分类是 echo $category echo 内容长度 echo ${#content} # 写入本地文件 echo $content | base64 -d > $postname echo 写入本地文件成功 # 上传到git rm -rf blog_$category git clone -b $category git@gitee.com:xtzero/blog.git blog_$category mv $postname blog_$category/source/_posts cd blog_$category git add source/_posts/$postname git commit -m 'write by phone' git push echo 已经上传到git # 生成hexo静态文件 yarn install hexo clean hexo g # 转移到网站目录 cd .. rm -rf /data/www/blog/$category cp -R blog_$category /data/www/blog/$category echo 🍺全部完成~! 调试 为了写这篇博客,我又传上去了一篇测试文章。从步骤和结果来看,是生效了。 在分享中点击快捷指令 进度条的速度取决于脚本的运行时间,由于涉及了git、hexo的操作,进度条还是挺慢的。 进度条转完了之后会显示运行结果,由于想看完整的输出,我就把全部输出都搞出来了。 由于想让各位也看看都输出了啥,我决定把图片上没显示完全的东西给复制出来。 文件名是 writebyphone20201231151624.md 分类是 tech 内容长度 72 写入本地文件成功 Cloning into 'blog_tech'... [tech 4bc2ca3] write by phone 1 file changed, 5 insertions(+) create mode 100644 source/_posts/writebyphone20201231151624.md 已经上传到git yarn install v1.21.1 info No lockfile found. [1/4] Resolving packages... [2/4] Fetching packages... info fsevents@2.1.3: The platform "linux" is incompatible with this module. info "fsevents@2.1.3" is an optional dependency and failed compatibility check. Excluding it from installation. [3/4] Linking dependencies... [4/4] Building fresh packages... success Saved lockfile. Done in 4.71s. INFO Start processing INFO ------------------------------------------------ | | | ________ __ _ __ | | |_ __ |[ | (_) | ] | | | |_ \_| | | __ _ __ .--.| | | | | _| | |[ | | | [ |/ /'`\' | | | _| |_ | | | \_/ |, | || \__/ | | | |_____| [___]'.__.'_/[___]'.__.;__] | | | | Thank you for using Fluid theme ! | | Docs: https://hexo.fluid-dev.com/docs/en/ | | | ------------------------------------------------ Version 9 of Highlight.js has reached EOL and is no longer supported. Please upgrade or ask whatever dependency you are using to upgrade. https://github.com/highlightjs/highlight.js/issues/2877 INFO Files loaded in 2.14 s INFO Generated: xtblog_rss.xml INFO Generated: local-search.xml INFO Generated: 404.html INFO Generated: index.html INFO Generated: about/index.html INFO Generated: children/index.html INFO Generated: client/index.html INFO Generated: features/index.html INFO Generated: friends/index.html INFO Generated: index/index.html INFO Generated: me/shortWorks.html INFO Generated: archives/index.html INFO Generated: tags/index.html INFO Generated: categories/index.html INFO Generated: links/index.html INFO Generated: teapot/index.html INFO Generated: me/skills.html INFO Generated: me/index.html INFO Generated: me/inSchool.html INFO Generated: me/old20200513.html INFO Generated: img/avatar.png INFO Generated: xml/local-search.xml INFO Generated: me/me202005.docx INFO Generated: img/favicon.png INFO Generated: img/default.png INFO Generated: img/loading.gif INFO Generated: img/police_beian.png INFO Generated: archives/page/2/index.html INFO Generated: archives/2017/12/index.html INFO Generated: archives/2018/01/index.html INFO Generated: archives/2019/03/index.html INFO Generated: archives/2020/02/index.html INFO Generated: page/2/index.html INFO Generated: archives/page/3/index.html INFO Generated: archives/page/4/index.html INFO Generated: archives/2018/02/index.html INFO Generated: archives/2018/04/index.html INFO Generated: archives/2018/05/index.html INFO Generated: archives/2018/08/index.html INFO Generated: archives/2018/10/index.html INFO Generated: archives/2019/07/index.html INFO Generated: archives/2019/08/index.html INFO Generated: archives/2019/11/index.html INFO Generated: archives/2019/12/index.html INFO Generated: archives/2020/03/index.html INFO Generated: archives/2020/04/index.html INFO Generated: archives/2020/11/index.html INFO Generated: archives/2020/12/index.html INFO Generated: categories/技术学习/index.html INFO Generated: categories/技术吹逼/index.html INFO Generated: tags/php/index.html INFO Generated: tags/小程序/index.html INFO Generated: tags/javascript/index.html INFO Generated: tags/xss/index.html INFO Generated: tags/散装技术/index.html INFO Generated: tags/composer-php/index.html INFO Generated: tags/布朗熊与可妮兔/index.html INFO Generated: tags/屏保/index.html INFO Generated: tags/域名-网站/index.html INFO Generated: tags/github-hosts/index.html INFO Generated: tags/laravel-php/index.html INFO Generated: archives/2017/index.html INFO Generated: archives/2018/index.html INFO Generated: archives/2019/index.html INFO Generated: archives/2020/index.html INFO Generated: tags/markdown/index.html INFO Generated: tags/es6-promise-javascript/index.html INFO Generated: tags/bash-shell/index.html INFO Generated: tags/shell/index.html INFO Generated: tags/swift/index.html INFO Generated: tags/yapi-接口管理/index.html INFO Generated: page/3/index.html INFO Generated: page/4/index.html INFO Generated: me/me202005.pdf INFO Generated: css/gitalk.css INFO Generated: js/boot.js INFO Generated: js/color-schema.js INFO Generated: js/debouncer.js INFO Generated: js/events.js INFO Generated: js/lazyload.js INFO Generated: js/leancloud.js INFO Generated: js/local-search.js INFO Generated: js/plugins.js INFO Generated: js/utils.js INFO Generated: css/main.css INFO Generated: lib/hint/hint.min.css INFO Generated: archives/2019/page/2/index.html INFO Generated: categories/技术学习/page/2/index.html INFO Generated: 2020/12/31/writebyphone20201231151624/index.html INFO Generated: 2019/12/27/brown/index.html INFO Generated: 2018/10/25/181025/index.html INFO Generated: 2017/12/17/171217/index.html INFO Generated: 2019/11/27/domaincandowhat/4.jpg INFO Generated: 2020/04/15/jenkins202004/Xnip2020-04-15_21-49-11.png INFO Generated: 2019/08/03/pleaseusemarkdown/sendbyaxios.jpg INFO Generated: 2020/02/15/makepostcard2020/Xnip2020-02-16_14-37-46.png INFO Generated: 2019/07/07/190707/2.png INFO Generated: 2020/03/14/autohealthy202003/Xnip2020-03-14_11-35-35.png INFO Generated: 2020/11/16/macnopower202011/index.html INFO Generated: 2019/03/31/190331/index.html INFO Generated: 2018/08/28/180828/index.html INFO Generated: 2018/05/23/180523-2/index.html INFO Generated: 2018/04/17/180417/index.html INFO Generated: 2018/02/18/180218/index.html INFO Generated: 2018/01/04/180104/index.html INFO Generated: 2020/02/04/windowsbug/index.html INFO Generated: 2019/12/18/shellHotkey/index.html INFO Generated: 2019/08/07/aliyuncomposer/index.html INFO Generated: 2018/08/24/180824/index.html INFO Generated: 2019/11/28/yapi1-1/10.jpg INFO Generated: 2020/11/15/front-struct-202011/index.html INFO Generated: 2019/12/26/githubhosts/index.html INFO Generated: 2020/04/09/gitlabrunner202004/index.html INFO Generated: 2019/12/15/swift2/index.html INFO Generated: 2019/12/17/swift3/index.html INFO Generated: 2019/12/14/swift1/index.html INFO Generated: 2019/12/11/shell20191211/index.html INFO Generated: 2019/08/15/promise/index.html INFO Generated: 2019/08/05/laravelnote/index.html INFO Generated: 2018/05/23/180523/index.html INFO Generated: 2020/04/15/byegithub202004/Xnip2020-04-15_17-54-50.png INFO Generated: 2019/08/07/laravel2/index.html INFO Generated: 2019/11/28/yapi1-1/8.jpg INFO Generated: 2019/08/03/pleaseusemarkdown/Xnip2019-08-04_13-10-42.jpg INFO Generated: 2019/08/03/pleaseusemarkdown/Xnip2019-08-04_13-12-30.jpg INFO Generated: 2020/04/15/jenkins202004/Xnip2020-04-15_21-21-30.png INFO Generated: 2019/12/27/brown/Xnip2019-12-27_23-48-45.jpg INFO Generated: 2019/12/27/brown/1577461641987.jpg INFO Generated: 2020/04/15/jenkins202004/Xnip2020-04-15_21-27-48.png INFO Generated: 2020/04/15/jenkins202004/Xnip2020-04-15_21-48-17.png INFO Generated: 2020/04/15/jenkins202004/Xnip2020-04-15_21-48-22.png INFO Generated: 2020/04/15/jenkins202004/Xnip2020-04-15_21-51-14.png INFO Generated: 2019/11/28/yapi1-1/11.jpg INFO Generated: 2020/02/15/makepostcard2020/Xnip2020-02-16_14-38-05.png INFO Generated: 2020/02/15/makepostcard2020/image-20200215204839677.png INFO Generated: 2019/08/03/pleaseusemarkdown/WeChat952c26237293beeef80e2ea3f9577153.png INFO Generated: 2020/04/15/byegithub202004/Xnip2020-04-15_17-58-02.png INFO Generated: 2020/04/15/jenkins202004/Xnip2020-04-15_21-47-44.png INFO Generated: 2019/11/28/yapi1-1/5.jpg INFO Generated: 2019/11/28/yapi1-1/6.jpg INFO Generated: 2019/11/28/yapi1-1/2.jpg INFO Generated: 2020/04/15/jenkins202004/index.html INFO Generated: 2020/04/15/byegithub202004/index.html INFO Generated: 2020/03/14/autohealthy202003/index.html INFO Generated: 2019/11/28/yapi1-1/index.html INFO Generated: 2020/02/15/makepostcard2020/index.html INFO Generated: 2019/11/27/domaincandowhat/index.html INFO Generated: 2019/08/03/pleaseusemarkdown/index.html INFO Generated: 2019/07/07/190707/index.html INFO Generated: 2019/11/28/yapi1-1/1.jpg INFO Generated: 2019/11/28/yapi1-1/7.jpg INFO Generated: 2019/11/28/yapi1-1/9.jpg INFO Generated: 2020/04/15/byegithub202004/Xnip2020-04-15_17-43-51.png INFO Generated: 2019/11/27/domaincandowhat/1.jpg INFO Generated: 2019/11/27/domaincandowhat/2.jpg INFO Generated: 2019/11/27/domaincandowhat/3.jpg INFO Generated: 2019/08/03/pleaseusemarkdown/pleaseusemarkdown.jpg INFO Generated: 2019/08/03/pleaseusemarkdown/sendbymyajax.jpg INFO Generated: 2020/04/15/jenkins202004/Xnip2020-04-15_21-23-51.png INFO Generated: 2020/04/15/jenkins202004/Xnip2020-04-15_21-28-37.png INFO Generated: 2019/11/28/yapi1-1/3.jpg INFO Generated: 2019/11/28/yapi1-1/4.jpg INFO Generated: 2020/02/15/makepostcard2020/Xnip2020-02-15_20-50-16.png INFO Generated: 2020/02/15/makepostcard2020/Xnip2020-02-16_13-24-08.png INFO Generated: 2020/02/15/makepostcard2020/Xnip2020-02-16_13-26-19.png INFO Generated: 2020/02/15/makepostcard2020/Xnip2020-02-16_14-32-33.png INFO Generated: 2020/02/15/makepostcard2020/Xnip2020-02-16_14-34-24.png INFO Generated: 2020/02/15/makepostcard2020/Xnip2020-02-16_14-50-56.png INFO Generated: 2020/02/15/makepostcard2020/Xnip2020-02-16_14-52-26.png INFO Generated: 2020/02/15/makepostcard2020/githubrepo.png INFO Generated: 2020/02/15/makepostcard2020/nightqr.png INFO Generated: 2020/02/15/makepostcard2020/banner.png INFO Generated: 2019/08/03/pleaseusemarkdown/Xnip2019-08-04_13-14-36.jpg INFO Generated: 2019/07/07/190707/1.png INFO Generated: 2020/04/15/jenkins202004/Xnip2020-04-15_21-49-30.png INFO 175 files generated in 983 ms 🍺全部完成~! 再打开git,发现git上显示了今天调试过程中的提交记录: 打开页面发现内容也更新上去了 这还愣着干啥,完事了就。 总结 shell脚本真难写,if的格式都有要求。可能不是shell太难,是我平时不用,没怎么写过。以后多写就好了。 那个通过分享触发的不能用SSH密钥登录的问题到最后也没解决,等下次(3000年13月32日)再看看。 粘贴运行结果太无耻了,但是字数一下子就上来了,还是原创。 这篇博客我决定也用这个快捷指令发送,但我是在电脑上写的,我还得想办法给拿到手机上去。 用快捷指令发送博客的话还没法处理图片,下一步准备搭个图床,用手机写博客的时候直接粘贴图床链接就好了。 手机真难用,改个root密码从11点改到2点还没成功。
发表时间 2020-12-31
发表在 技术学习
阅读数 0
跟ci/cd纠缠的日子
之前的日子里,我的网站的自动部署经历了三个阶段。 第一阶段 服务器上运行一个 php while(1)和 git pull的脚本,使用nohup给放到后台,每次pull之后就sleep(10),也就是每10秒pull一次。博客有变动的时候,最多10秒就会被服务器重新拉取。 缺点太多了,比如浪费资源。为了看拉取结果,我还在每次pull的时候把控制台输出的信息都保存在了日志里。最开始几天的日子里,还能cat log看看最近有没有冲突有没有拉取失败,一个月之后,再cat就能看到长达一分多钟的滚动字幕了。 时间再久一点,log文件就变得比代码都大了。这时候有智障就问了,为什么不把日志分开保存。每天一个日志文件不就好啦? 我干嘛不换个自动拉取程序呢…… 第二阶段 第二阶段的开始,得益于我看到github有一个东西叫webhook。 和第一阶段一样的是,任何静态资源仍然都在本地生成,统一push到github上。服务器上有一个脚本,push成功后,使用github webhook向服务器脚本post一个消息,脚本接收到消息后前往对应的项目下执行git pull。 后来为了适应不同的项目类型,我在脚本里使用switch对repo名字进行匹配,执行不一样的脚本。 第二阶段的自动部署完成后,我写了一篇文章:让git push之后服务器能自动更新代码,顺便还把第一阶段的蠢逼设计也写了进去。这一部分的脚本代码被我放在了这个github repo里。 这一阶段的缺陷也很明显,它没法像runner那样有一个任务队列。如果两次push的间隔小于项目构建的过程,那么一定会导致一些不可预料的问题。所以就只能控制两次push的间隔,尽力避免因为缺陷而导致的问题。 关于这些问题,在github repo的readme里写得也很清楚 第三阶段 在工作中使用runner爽得不行,但是github上没有对应的工具,只能借助一些第三方的ci/cd工具,所以一直在用自己的傻狗伪装ci脚本。有一天我突然发现github更新了,多出了一个叫Github Actions的东西。于是我的第三阶段开始了。 Github Action的基本原理是,在启动action后生成一个虚拟容器,可以在这个虚拟容器下进行一系列的操作。 配置脚本之前,需要前往repo的配置下,设置私有变量ACTIONS_DEPLOY_KEY,这个变量是服务器的私钥。 新建一个github action workflow,用这样一个脚本 .github/workflows/main.yml name: 就直接怼进去 on: [push] jobs: build: runs-on: ubuntu-latest steps: - name: ssh env: ACTIONS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }} HOST: 39.***.***.207 USER: root DEVELOP_SH_PATH: /root/hexobuild.sh run: | SSH_PATH="$HOME/.ssh" mkdir -p $SSH_PATH touch "$SSH_PATH/known_hosts" echo "$ACTIONS_DEPLOY_KEY" > "$SSH_PATH/id_rsa" chmod 700 "$SSH_PATH" chmod 600 "$SSH_PATH/known_hosts" chmod 600 "$SSH_PATH/id_rsa" eval $(ssh-agent) ssh-add "$SSH_PATH/id_rsa" ssh-keyscan -t rsa $HOST >> "$SSH_PATH/known_hosts" ssh -o StrictHostKeyChecking=no -i $SSH_PATH/id_rsa -A -tt $USER@$HOST sh $DEVELOP_SH_PATH 脚本大意是,把服务器私钥给容器,让容器通过ssh连接服务器,前往一个目录,执行一个脚本,这个脚本的内容是: #!/bin/sh cd /data/wwwroot/blog/tech git pull hexo clean hexo g 这样不是常规的Github Action的使用方式。平常的用法应该是,在虚拟容器里先clone仓库文件,执行安装,执行生成静态文件,再把静态文件复制到服务器的对应目录。 管什么常规不常规的,好用就完事了。 从那之后,我再也不用每次push完博客再去ssh连接服务器看日志了。每次push完之后,我就安安静静等博客那边自己拉取最新再生成静态页。Actions页面里的记录是这样的: 第三阶段终于看上去高端一些了,Github Actions算是跟runner接近一些,可以抛弃笨比Webhook和我的蠢狗脚本。在用了一段时间后,Github Actions的问题又出现了…… Github最近好慢啊! 在服务器上clone根本不动,在本地挂了梯子也是龟速。有的网站被完全墙了,有的完全没墙,就github墙了一半,带死不死,难受死了。 所以这就是我最近好久好久没更新博客的理由。 既然更新了,说明我找到了新的方案。已经更新了搭建Gitlab+Runner,本来以为能进行完全自动化部署。结果服务器性能不够用,Gitlab给我开了30多个进程,直接卡死。下一篇更新用Jenkins+码云进行自动化部署。
发表时间 2020-04-15
发表在 技术学习
阅读数 0
搭建jenkins配合gitee实现自动部署
在上一篇文章里我讲到了自己最近日子里与自动部署这件事的爱恨情仇,最后由于github太卡,但又抵抗不了墙的存在,最后更改了自己项目分享和部署的方案。 在之前的日子里,我的全部项目都在github里,需要分享的就设置为public,只是部署使用的就用private。变更方案后,github只用作代码分享,因为它毕竟是一个社交网站。用作部署的代码转移到码云。再在自己的服务器上搭建一个jenkins用于自动部署。 jenkins是一个开源的ci/cd工具,可以用于项目的自动部署。它还有很多其他作用,但我没用上。 jenkins的中文文档是:Jenkins 用户手册 。 环境准备 由于是在自己的服务器上搭建,所以下面一切的描述均基于CentOS7操作系统,运行于阿里云的ECS T5云主机。 参考jenkins用户指南,我们知道jenkins需要 机器要求: 256 MB 内存,建议大于 512 MB 10 GB 的硬盘空间(用于 Jenkins 和 Docker 镜像) 需要安装以下软件: Java 8 ( JRE 或者 JDK 都可以) Docker (导航到网站顶部的Get Docker链接以访问适合您平台的Docker下载) 安装Java8 这部分参考Linux下通过yum命令安装jdk8。 查看已安装/卸载 先查看有没有已经安装java8。 # rpm -qa | grep java javapackages-tools-3.4.1-11.el7.noarch python-javapackages-3.4.1-11.el7.noarch java-1.8.0-openjdk-headless-1.8.0.242.b08-0.el7_7.x86_64 tzdata-java-2019c-1.el7.noarch java-1.8.0-openjdk-1.8.0.242.b08-0.el7_7.x86_64 由于我已经安装,所以会显示一系列名字里带有java的包。如果已经安装其他版本的java jdk,使用 # rpm -e --allmatches --nodeps java-1.6.0-openjdk-1.6.0.38-1.13.10.4.el6.x86_64 卸载。 查找jdk8包 # yum search jdk 已加载插件:fastestmirror Loading mirror speeds from cached hostfile * epel: mirrors.yun-idc.com * webtatic: uk.repo.webtatic.com ======================================================== N/S matched: jdk ======================================================== copy-jdk-configs.noarch : JDKs configuration files copier java-1.6.0-openjdk.x86_64 : OpenJDK Runtime Environment java-1.6.0-openjdk-demo.x86_64 : OpenJDK Demos java-1.6.0-openjdk-devel.x86_64 : OpenJDK Development Environment java-1.6.0-openjdk-javadoc.x86_64 : OpenJDK API Documentation java-1.6.0-openjdk-src.x86_64 : OpenJDK Source Bundle java-1.7.0-openjdk.x86_64 : OpenJDK Runtime Environment java-1.7.0-openjdk-accessibility.x86_64 : OpenJDK accessibility connector java-1.7.0-openjdk-demo.x86_64 : OpenJDK Demos java-1.7.0-openjdk-devel.x86_64 : OpenJDK Development Environment java-1.7.0-openjdk-headless.x86_64 : The OpenJDK runtime environment without audio and video support java-1.7.0-openjdk-javadoc.noarch : OpenJDK API Documentation java-1.7.0-openjdk-src.x86_64 : OpenJDK Source Bundle java-1.8.0-openjdk.i686 : OpenJDK Runtime Environment 8 java-1.8.0-openjdk.x86_64 : OpenJDK Runtime Environment 8 java-1.8.0-openjdk-accessibility.i686 : OpenJDK accessibility connector java-1.8.0-openjdk-accessibility.x86_64 : OpenJDK accessibility connector java-1.8.0-openjdk-accessibility-debug.i686 : OpenJDK 8 accessibility connector for packages with debug on java-1.8.0-openjdk-accessibility-debug.x86_64 : OpenJDK 8 accessibility connector for packages with debug on java-1.8.0-openjdk-debug.i686 : OpenJDK Runtime Environment 8 with full debug on java-1.8.0-openjdk-debug.x86_64 : OpenJDK Runtime Environment 8 with full debug on java-1.8.0-openjdk-demo.i686 : OpenJDK Demos 8 java-1.8.0-openjdk-demo.x86_64 : OpenJDK Demos 8 java-1.8.0-openjdk-demo-debug.i686 : OpenJDK Demos 8 with full debug on java-1.8.0-openjdk-demo-debug.x86_64 : OpenJDK Demos 8 with full debug on java-1.8.0-openjdk-devel.i686 : OpenJDK Development Environment 8 java-1.8.0-openjdk-devel.x86_64 : OpenJDK Development Environment 8 java-1.8.0-openjdk-devel-debug.i686 : OpenJDK Development Environment 8 with full debug on java-1.8.0-openjdk-devel-debug.x86_64 : OpenJDK Development Environment 8 with full debug on java-1.8.0-openjdk-headless.i686 : OpenJDK Headless Runtime Environment 8 java-1.8.0-openjdk-headless.x86_64 : OpenJDK Headless Runtime Environment 8 java-1.8.0-openjdk-headless-debug.i686 : OpenJDK Runtime Environment with full debug on java-1.8.0-openjdk-headless-debug.x86_64 : OpenJDK Runtime Environment with full debug on java-1.8.0-openjdk-javadoc.noarch : OpenJDK 8 API documentation java-1.8.0-openjdk-javadoc-debug.noarch : OpenJDK 8 API documentation for packages with debug on java-1.8.0-openjdk-javadoc-zip.noarch : OpenJDK 8 API documentation compressed in a single archive java-1.8.0-openjdk-javadoc-zip-debug.noarch : OpenJDK 8 API documentation compressed in a single archive for packages with debug : on java-1.8.0-openjdk-src.i686 : OpenJDK Source Bundle 8 java-1.8.0-openjdk-src.x86_64 : OpenJDK Source Bundle 8 java-1.8.0-openjdk-src-debug.i686 : OpenJDK Source Bundle 8 for packages with debug on java-1.8.0-openjdk-src-debug.x86_64 : OpenJDK Source Bundle 8 for packages with debug on ... 名称和简介匹配 only,使用“search all”试试。 安装 在输出的包名中找到需要的java8安装包,执行命令 # yum install java-1.8.0-openjdk.x86_64 进行安装。 安装过程中会同时安装依赖项。 安装成功后,使用 # java -version openjdk version "1.8.0_242" OpenJDK Runtime Environment (build 1.8.0_242-b08) OpenJDK 64-Bit Server VM (build 25.242-b08, mixed mode) 检测是否已经安装成功。 安装成功后,就可以在后面使用java命令了。 安装docker 就没啥好解释的,直接 # yum install docker 安装就完事了。 下载jenkins 官方文档给的链接是http://mirrors.jenkins.io/war-stable/latest/jenkins.war,我们这里可以使用清华大学开源镜像站-jenkins,使用wget下载最新的镜像。 # wget https://mirrors.tuna.tsinghua.edu.cn/jenkins/war/2.231/jenkins.war 启动jenkins cd到下载目录下,使用命令 # java -jar jenkins.war --httpPort=8080 来启动jenkins。 如果8080端口被占用了,可以使用任何其他未占用接口。如果安装了防火墙,则需要将端口加到防火墙白名单里。如果像我一样用了云主机,则需要在安全组配置允许此端口通行。 启动成功后,在浏览器访问http://ip:8080,按照引导进行安装。 启动jenkins安装程序的时候会在控制台显示一个密码,在第一步会用到。 如果控制台没有显示,可以使用cat命令查看界面上显示的文件。 下一步选择插件。 选择第二个,然后搜索Chinese,安装一个中文插件就行。其他安装起来太慢,也没啥用。 下一步创建用户,完事就能进jenkins的界面了。 现在有一个问题,命令行那边还等着呢,我们关闭了控制台就没法用了啊。 使用守护进程方式启动jenkins 参考了这篇文章,首先使用yum安装daemonize。 # yum install daemonize daemonize的使用方法是 daemonize -E BUILD_ID=dontKillMe -o some.log -c /home/User/victor /home/User/victor/test.sh -E BUILD_ID=dontKillMe是这次运行的id,可以随便写一个。 -o some.log是这次运行的日志文件。 -c /home/User/victor是运行前要切换的目录。 /home/User/victor/test.sh是要启动的脚本。 于是我们前往一个特殊目录cd /usr/local/bin && mkdir jenkins,编写一个脚本,用来启动jenkins。 # vim jenkins_daemonize.sh #!/bin/bash java -jar /usr/local/bin/jenkins/jenkins.war --httpPort=8081 <esc> :eq 再编写另一个脚本,使用daemonize运行上一个脚本。 # vim jenkins_start.sh #!/bin/bash daemonize -E BUILD_ID=dontKillMe -o jenkins.log -c /usr/local/bin/jenkins "/usr/local/bin/jenkins/jenkins_daemonize.sh" <esc> :eq 为啥要写俩脚本呢,因为daemonize最后一个参数接受的就是sh脚本啊。 再建立一个日志文件。 # touch jenkins.log 修改脚本文件和日志文件的权限。 # chmod +x jenkins_daemonize.sh # chmod +x jenkins_start.sh # chmod 777 jenkins.log 然后运行脚本jenkins_start.sh,jenkins就以守护进程的方式启动了。 # ./jenkins_start.sh 我们可以使用ps命令查看运行情况。 # ps -ef | grep jenkins root 15735 13474 0 21:01 pts/0 00:00:00 grep --color=auto jenkins root 30515 1 0 4月14 ? 00:00:00 /bin/bash /usr/local/bin/jenkins/jenkins_daemonize.sh root 30516 30515 0 4月14 ? 00:03:58 java -jar /usr/local/bin/jenkins/jenkins.war --httpPort=8081 配置nginx反向代理 用daemonize启动成功后,服务启动在http://127.0.0.1:8081上,这时候我们需要配置nginx代理,从而可以使用域名访问。 server { listen 80; server_name jenkins.xtzero.me; location / { proxy_pass http://127.0.0.1:8081; } } 保存后重新载入nginx配置。 # nginx -s reload 在浏览器中访问http://jenkins.xtzero.me,即可看到启动好的jenkins。 jenkins与gitee联动 先将代码传到gitee,同一个项目下的不同子项目使用分支实现,例如我的博客分为life、tech、api,在仓库里新建三个分支。 联动的思路是,在jenkins里配置好构建脚本,gitee push成功时告诉jenkins仓库名和分支名,jenkins分别进行构建。构建的过程就是在服务器上拉取代码,执行安装、构建,再将生成好的资源复制到网页目录。 下面将用我的blog项目进行说明。 需要解释的是,jenkins有gitee插件,可以像runner那样来进行自动部署。由于我的需求特殊,也有更省事(或许是我更能理解的方式)来解决,所以我决定走自己的路线。 配置jenkins 流水线 点击jenkins首页的新建item,任务名称为“仓库名_分支名”,任务类型选择criswu擅长的freestyle。 进入任务配置,勾选触发远程构建 在最下方选择增加构建步骤,选择shell方式 添加脚本进去 rm -rf blog_tech git clone -b tech git@gitee.com:xtzero/blog.git blog_tech cd blog_tech yarn install hexo g rm -rf /data/www/blog/tech cp -R ../blog_tech /data/www/blog/tech 我的博客是用hexo搭建的,所以会进行上面的步骤。 jenkins的原理是,在~/.jenkins/workspace目录下会为每一个项目建立一个单独的目录。为了避免重复,在git clone的时候我们依然使用“仓库名_分支名”的形式。 clone项目后,执行安装、构建。构建出静态资源后,删除网站目录的旧版文件,把构建好的静态资源复制进去。一次流水线结束。 由于勾选了远程构建,所以我们需要在gitee push成功的时候发送消息到jenkins。这时候就需要服务器上有一个接口脚本来接受push消息,再请求jenkins的远程构建接口。 脚本使用php编写。 <?php require_once 'curl.php'; $avaliableRepoBranch = [ 'blog_tech', 'blog_life', 'blog_api', 'xtCBook_master', 'brown-and-cony_master' ]; $postData = file_get_contents('php://input'); $d = json_decode($postData, true); $refArr = explode('/', $d['ref']); $branchName = $refArr[count($refArr) - 1]; $repoName = $d['repository']['name']; $repoAndBranch = implode('_', [$repoName, $branchName]); if (in_array($repoAndBranch, $avaliableRepoBranch)) { echo '访问了http://jenkins.xtzero.me/job/'.$repoAndBranch.'/build?token=jenkins'; echo curlGet('http://jenkins.xtzero.me/job/'.$repoAndBranch.'/build?token=jenkins'); } else { echo '不在数组里,构建直接他妈结束'; } 编写好脚本后,配置nginx解析。 server { listen 80; server_name webhook.jenkins.xtzero.me; location ~ \.php$ { root /data/www/forJenkins; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; include fastcgi.conf; } } jenkins远程构建地址的特点是http://jenkins地址/job/任务名称/build?token=TOKEN,由于我们的任务名称是仓库名和分支名决定的,所以只要在push信息里获取到仓库名和分支名,就可以请求到对应的jenkins地址了。 前往gitee项目页面,点击右上角管理,选择WebHooks,将上一步配置的接口地址填上。 一旦执行了push动作,就会在WebHooks页面看到请求结果。 前往jenkins页面,可以看到构建已经开始了。 点进去具体一个构建,点击左侧控制台输出,可以看到详细的控制台输出信息。 访问对应的网站地址,可以看到确实已经构建成功。 配置更多项目 每一个项目的构建流程都不尽相同,所以需要对每一个项目配置不同的构建脚本。但是思路都大致相同,都是clone项目、安装、构建、复制到网站目录。 依次配置好需要构建的项目,就可以开始快乐写代码了。 完事 就完事了。今天一日三更,不知道下一次是哪年更新了。
发表时间 2020-04-15
发表在 技术学习
阅读数 0
centOS7安装Gitlab和Runner
安装依赖 yum install -y curl policycoreutils-python openssh-server 配置ssh服务 将SSH服务设置成开机自启动 sudo systemctl enable sshd 启动SSH服务 sudo systemctl start sshd 配置防火墙 安装防火墙 yum install firewalld systemd -y 启动防火墙 service firewalld start 添加http服务到防火墙 sudo firewall-cmd --permanent --add-service=http 重启防火墙 sudo systemctl reload firewalld 配置postfix 安装postfix sudo yum install postfix 设置开机启动 sudo systemctl enable postfix 启动postfix sudo systemctl start postfix 在安装Postfix期间,可能会出现配置屏幕。选择“Internet Site”并按enter键。使用您的服务器的外部DNS以“mail name”并按enter。如果出现额外的屏幕,继续按enter键接受默认值。 准备工具 wget vim 如果没有安装,使用下面的命令来安装 yum install wget -y yum install vim -y 安装gitlab 下载gitlab镜像 wget https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gitlab-ce-10.0.0-ce.0.el7.x86_64.rpm 上面的命令是安装10.0.0版本的gitlab社区版。所有的镜像在https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/。 安装gitlab rpm -i gitlab-ce-10.0.0-ce.0.el7.x86_64.rpm 后边的rpm文件是上一步下载好的包。 这样显示就是安装成功了 配置gitlab 打开gitlab配置文件 vim /etc/gitlab/gitlab.rb 将external_url改为http://服务器ip:端口。 重置并重启 gitlab-ctl reconfigure gitlab-ctl restart 访问gitlab 直接访问上一步填写的ip和端口地址,初始账户是 初始账户: root 密码:5iveL!fe 汉化gitlab 在另一个目录clone这个仓库: https://gitlab.com/xhang/gitlab/ 如果clone太慢,可以使用国内gitee上的同款仓库: https://gitee.com/zhangzheng_764/gitlab-zh。 进入仓库目录下,查看所有分支。 git branch -a 根据已安装的版本,进行对比,生成补丁包。 git diff remotes/origin/10-2-stable remotes/origin/10-2-stable-zh > /tmp/10.2.2-zh.diff 上面示例中是10.2.2版本,要根据实际安装的版本进行更改。 生成补丁包后,先停止gitlab服务。 gitlab-ctl stop 打补丁 patch -d /opt/gitlab/embedded/service/gitlab-rails -p1 < /tmp/10.2.2-zh.diff 启动gitlab并重新配置 gitlab-ctl start gitlab-ctl reconfigure 刷新页面,汉化完成。 安装gitlab runner 用wget下载镜像 https://mirrors.tuna.tsinghua.edu.cn/gitlab-ci-multi-runner/ 安装镜像 rpm -i gitlab-ci-multi-runner-9.5.1-1.x86_64.rpm 获得gitlab-ci的token 项目主页 -> Sttings -> CI/CD -> Runners Expand 注册一个runner出来 gitlab-runner register 配置自动部署 # This file is a template, and might need editing before it works on your project. # Full project: https://gitlab.com/pages/hexo image: node:10.15.3 stages: - deploy before_script: - echo '开始准备服务' - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )' - eval $(ssh-agent -s) - mkdir -p ~/.ssh - rm -Rf ~/.ssh/id_rsa - touch ~/.ssh/id_rsa - echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa - rm -Rf ~/.ssh/known_hosts - touch ~/.ssh/known_hosts - echo "$SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts - chmod 700 ~/.ssh - chmod 700 ~/.ssh/* - echo '执行git设置' - git config --global user.email "t@xtzero.me" - git config --global user.name "xtGitlabRuner" - echo '给npm设置成淘宝源' - npm config set registry https://registry.npm.taobao.org/ - npm config get registry deploy: stage: deploy script: - cd /data/www/night/web - git pull - echo 开始构建项目 - npm run build - ls - ls dist 参考 gitlab官网 Centos 7搭建Gitlab服务器超详细 gitlab 安装及汉化 Gitlab CI持续集成 - GitLab Runner 安装与注册
发表时间 2020-04-09
发表在 技术学习
阅读数 0
一个充满炫酷黑科技的外挂网站
这个网站的成品在这里。 本期向你演示如何用一群菜鸡组合起来玩出花样。 重要:这个属于日站范畴,未经允许日站属于犯法,请谨慎模仿。 起因 一切的开始,始于这个页面 疫情期间,学校要求每个人每天都要前往这个页面上报自己的健康情况,以及有没有接触过相关敏感人员,还有体温等信息。打开页面后,首先使用自己的学号+身份证后六位登录,然后填写信息提交。 我向相关好友提及此事,好友说,我要是有了问题,还用在这填写这个吗,我早去医院了。有问题的不会填写这个,填写这个的大多都没问题。我听闻此言大受启发,决定开发一个自动上报的工具,造福大家,这样就不需要早起填写了。 然鹅整个项目只是为了学习交流而开发,并没有投入真实使用。 开发准备 我掐指一算,这个项目需要用到前端页面、后端接口、定时任务、数据库、短信服务。要是搁平时,可能就用正常的php、html、mysql组合了。突然意识到这次需要定时任务,需要用到linux crontab,于是决定这次使用一次php控制台。然后还懒得用框架,因为项目太小了,所以接口就用php单文件。没有框架的话就没有好用的mysql类库了,还懒得自己一遍一遍地写那个单例模式的数据库类,所以这次不用数据库了。我研究了一个文件存储数据的方式,类似于平时的日志。反正程序小,也是自己玩,怎么开心怎么做。 这玩意具体的流程是这么设计的。 先整个前端页面,让人进来填自己的用户名和密码,然后还得填手机号。填完了信息之后调一下大学印象的接口,看看登录成功没。要是登录成功了就给存到服务器上。为了体现自己这个东西的与众不同,我自动签到完得给人发个短信通知一下。再安排个定时任务,每天定时就给签了。流程上看挺简单的。 准备目录结构 我们需要这样几个目录分别做不同的事。 /api 接口目录 /commandLineTools 命令行程序目录 /pages 前端页面目录 /data 存点数据啥的 /data/log 存放每次执行定时任务后的日志 /data/sysconfig 存放系统配置,这个要被gitignore忽略掉 /data/userconfig 存放用户配置,主要是用户名密码手机号啥的 抓包 用浏览器打开大学印象的页面,按F12,输入借到的账号,登录一波,然后控制台就显示了登录的接口。 Request URL: https://www.dxever.com/Wxminiprog/Disease/login Request Method: POST Status Code: 200 OK Remote Address: 127.0.0.1:7890 Referrer Policy: no-referrer-when-downgrade Access-Control-Allow-Headers: x-requested-with,content-type Access-Control-Allow-Origin: * Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Connection: keep-alive Content-Type: application/json; charset=utf8 Date: Sat, 14 Mar 2020 14:58:52 GMT Expires: Thu, 19 Nov 1981 08:52:00 GMT Pragma: no-cache Server: nginx Status: 200 OK Transfer-Encoding: chunked Via: 100167 Accept: application/json Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.9,en;q=0.8 Connection: keep-alive Content-Length: 33 Content-Type: application/x-www-form-urlencoded Cookie: PHPSESSID=896f5e9bdfeab7fe4f556f07176fa72e Host: www.dxever.com Origin: https://www.dxever.com Referer: https://www.dxever.com/fei/delete/ncp/login.html Sec-Fetch-Dest: empty Sec-Fetch-Mode: cors Sec-Fetch-Site: same-origin User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1 X-Requested-With: XMLHttpRequest studno: 16******** password: 123456 写接口 写页面 写控制台程序 配置定时任务 完事了
发表时间 2020-03-14
发表在 技术学习
阅读数 0
做一个在线明信片
今天的主题是,要做一个在线明信片的项目。这个项目已经开发完毕,并且还有宣传海报。 虽然用户量不是很大,但我今天还是想从决定要做一个项目开始,完整地描述这个东西的开发过程。 可能不是符合一般企业技术团队(朋友圈大神技术团队)的开发流程,所以如果读着读着发现我哪里做得不是很符合您的心意,请您对着房顶喊出您的不满。 这篇文章作于作者在家办公的第二周周末,已经很久没有活人交流,自然显得十分话痨。作为话痨的补偿,长篇大论中会夹杂一些段子。如果不喜欢作者的幽默风格,请您对房顶喊出您的不满。请勿抬杠,抬杠算您赢。 冒出来一个需求 过年回老家之前国内爆发了新冠,导致这个年就没是过得很好,对普通老百姓来说,最直接的影响就是没法在短短的一周假期里串完所有的亲戚,见到自己想见到的人了。如果屏幕前的读者非要说自己过年把所有的亲戚都串完了,那你就串完了,反正我没串完。 在我百无聊赖躺在奶奶的炕头上时,电视上说,这个不平凡的中国年,大家应该理性拒绝集会balabalabalabala…然后建议大家线上拜年,或者写邮件,体验一下传统的拜年方式。 虽然我并不会写电子邮件来拜年,这显得会用微信的我异常沙雕,但我想到了,我们可以用另一种方式——明信片。为了让会用微信的我不显得异常沙雕,我想到了可以用电子明信片。互联网思维就是好互联网思维就是妙,电子明信片的想法冒出来之后,我都想给我家猫改装成电子的。 需求有了,接下来细化一下需求,设计一个方案出来。 设计一个方案 沙雕设计 要是电子明信片给沙雕来设计,那可能就是每个人上线注册一个账号,然后微信告诉对方我的账号,然后两个人用这个账号来互发明信片。这就好像上世纪四十年代,原本相隔千里的两个人,因为不能上网而只能书信交流,但是不知道对方的具体地址,没法告诉邮差怎么走,就只能凭借记忆跑到对方老家,问了详细地址,再跑回自己家,写信告诉对方自己想说的话。 上述设计方案简称“脱裤子放屁”,是产品设计阶段的一种设计方法(我现编的)。 开始设计 如果知道对方的手机号,就可以线上填写想说的话,再告诉系统对方的手机号,系统给对方发短信告知要说的话就好了。我们能上网,为啥不用21世纪人类的方式来做这件事呢。 要是直接就把内容发送过去了,会有两个问题: 短信服务那边不允许短信内容完全自定义; 要是有人想给对方发一篇完整的千字文,我的短信服务余额可能直接被榨干; 一点都不好玩。 我也不知道为啥说好了两个问题,随手就摁了个3出来。不过不重要,代码打多了难免数学(数[shû]数[shù])不好。 如果不直接用短信发送内容,那我直接想到了快递柜的模式。 将收件人的手机号和要发送的内容记录下来,生成一个随机的取件码。短信告知对方有明信片要取,再告知取件码。 收件人点开短信里的地址,输入取件码,打开明信片,色卜ruai兹! 这个方案简直太鹅妹子嘤了,于是我赶紧结束设计阶段,开始下一步。 各种评估 技术评估 作为本身就是一个臭写代码的,首先进行技术评估,要是技术上不能实现(就是做不出来的高级说法),那就不往下看了。如果在公司里,可能会先评估符不符合公司业务之类的。 都做出来了,肯定是能做。所以技术评估就是一闪鹅过,走个流程。 花多少钱评估 因为要使用短信服务,所以不得不看一下需要花多少钱。 在众多臭卖短信的的服务商中,我选中了腾讯云。虽然腾讯云的价格看上去我买不起(也用不上) ,旁边还是有个自定义可以用的。于是我选了个最卑微的价格,充值了信仰。 总共就需要花50块钱,少吃两顿饭就省出来了,这步评估也通过。 评估到这,基本就可以开始做了。 决定技术方案 决定啥啊,我就会这么些个东西,又要做网页,又要接口,还得用数据库,那没啥选择了。我会的东西排列组合一下,符合要求的也就这么一种了。 前端:html三件套、jquery 后端:php 数据库:mysql 服务器:阿里云ecs-t5,centos 由于需要保存验证码和登录套什么的,正常来说应该加个redis,但我估计这玩意也不会有很多人来用,就暂时用mysql代替。等什么时候mysql扛不住这巨大的登录频率了,再换redis。估计到时候我直接花钱升级mysql硬顶都能顶住了。 前端选择了最原始的人类科技jquery,不是因为我不会vue,而是用脚手架太麻烦。要是看热闹的您非要看我用vue脚手架搭个什么,下次更新用vue脚手架搭建一个fade流项目。 下次更新是指我什么时候想起来。2018年9月我打算写一个php入门手册,到现在还在拖着。但是我没忘,没忘就不算tj了。初中的时候想要拍一个短片,当时还没有vlog的概念,现在vlog热乎劲都过去了,我还没开始拍,但我还没忘,没忘就不算tj。 虽然说了很多废话来掩饰我拖延的尴尬,但是这个fade流的东西真的存在,并且可以扫描下面的二维码访问: 因为域名是night,所以下文提到这个fade流都称之为night。可能是脑抽了,让我觉得这个明信片在night中,所以跟night共用同一个后端项目和同一个前端文件夹。 服务器选用阿里云的ecs-t5,因为啥呢,因为我只有这个。服务器os选用centos,原因也一如既往地简单,我只有这个。我也想让服务器用macos,但是实力不允许。 技术方案决定了,中午请前端老哥吃个椒麻鸡,就开始做了。 编码开发 写代码之前要做的事也太多了,要不是写文章,我都不知道自己动手之前拖了这么久。 在服务器建文件夹 这一步是让项目有一个安稳的家。 设置nginx解析 先搞一个前端解析 server { listen 80; server_name postcard.host.host; location / { root /path/path/path; } } 再搞一个接口解析 nginx下的接口需要通过php-fpm来实现(?解读/分析/认识/转发?),总之就是php-fpm能读php脚本而nginx不能,php-fpm的服务在127.0.0.1:9000,我们就需要用端口转发的方式让nginx去认识127.0.0.1:9000来的请求,并当成接口来给前端。 我也不知道上边这段我写了什么几把,可能就是对php-fpm的概念掌握不牢固而导致的心虚而导致的语无伦次吧。 server { listen 80; server_name apihost.host.host; location / { root /path/path/path/api; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; } location ~ [^/]\.php(/|$) { root /path/path/path/api; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; include fastcgi.conf; } } 抄这两段配置之前需要明白一件事,我在域名后台把*直接解析到服务器ip了,这样就可以不用每次都去登录域名后台了。要是你没跟我一样设置,就算喊破喉咙也没有用的。 配置里还有一个fastcgi.conf,跟这次业务没啥关系,我就不发了,所以你完全没法照抄这段代码。 然后就完事了。上边配置里的域名和路径信息我都使用了国内最流行也是最安全的瞎几把混淆方式,具体路径以我服务器存放路径为准,具体域名以网站真实使用为准。 部署后端代码 后端代码在写night的时候就已经部署好了。 在我年少无知不会用composer的时候自己写了个框架,可以参考我之前的文章《搞一个框架出来》。这个破框架唯一的优点是有一个跟ci差不多的路由,这个破框架的缺点是 不支持composer 没有orm 不知道psr4是啥 不分业务层和数据层 db底层是mysqli不是pdo 等等你能想得到的缺点 由于night就用的是它,所以这次很艰难地继续用了。 代码分享 为了展现程序员人性化的一面,这次项目所有的代码我都放在一个单独的github仓库里了,仓库地址我会变成二维码和地址本身放在文章最后。如果看编码实现这段不知所云,建议你先滑到最后看一下代码。 转念一想还是别放最后了,你再懒得滑回来咋整。大放假的都怪懒的,我先把地址放出来吧。 地址是 https://github.com/xtzero/xtPostcard_Share 部署前端代码 前端部署就很简单了,在服务器上建个文件夹再建个index.html,再写点骚话,试一下域名能访问就是成功了。 开发(写代码|扯皮|水群|撸猫|刷微博|抠脚) 开发就是一把梭,由于写文章没法体现我具体的开发过程,所以建议您去读代码。在后台回复“我想看过程”并留下你想看开发过程了三万字理由,下次我直播开发东西的时候叫你。 自动部署 我也没用ci也没用action,我用的是xtGithubWeebhookCi.php,是一个同样出自本人之手的沙雕自动部署工具。使用了github的webhook功能,在push的时候向服务器post一个消息,服务器就屁颠屁颠自动去项目目录下执行git pull了。 有了自动部署,就可以专心修bug(关掉ssh终端而放心地出好多好多bug只管本地push不用费劲巴力ssh登录服务器像蠢狗一样这边push那边pull)了。 后事 后事不是gg了而是开发之后的事。大概就分为测试和发布了。 测试 我前前后后找了一些最近在聊天的人帮我测试,这种测试方式叫喊人测试。一般专业一些的互联网公司的技术团队都会有专门的测试人员,而测试人员们通常都会使用更专业一些的黑白盒和自动化测试之类的。我们喊人测试中最大的技术要点就是点点点测试。告诉他们可以体验我们的新功能,他们就会帮我们点点点,并告诉哪里有问题。 切记,这时候出现bug,不要引导用户向天花板大喊,这样我们会错过bug而导致发布的时候也有bug。 测试通过后就等待0点的到来,于是就到了我们激动人心的 发布 环节。 在发布环节我们将再次见到最开始的那张海报。 这样我们就告诉了一整个朋友圈我们发布了这个东西。一整个朋友圈是什么概念呢,就是一整个好友列表都知道了,神奇不神奇?如果要学习怎么发朋友圈,后面我可能会专门写一次文章来教学。 总结 数据 这玩意从发到朋友圈让一整个列表都知道了之后,到现在总共有 条数据。 快乐得一批。 所有参与的人(鸣谢|谢谢喃) 开发 前端:js兄弟 后端:啊你亲爱的彤彤姐 测试 本来一个下午就能做完的玩意,让我硬生生拖了半个月,像毕设一样。最离谱的是我还写了论文(本文)。真的是闲在家里,什么沙雕事都能干得出来。 要是当毕设做 下载你学校的封皮和模板 要是下载不到就问问学委能不能干了不能干就下班。 摘要 描述一下你为啥要做,还有大致要写的内容啥的。重要的是把字数凑够了。 再挑几个关键词出来。 随着xxx在市场上的推广,xx在中国乃至世界上的普及率日益增高,人们对xx的依赖性也日益增长。 在xxx时间,xx如何如何。 在xxx时间,xx如何如何。 在xxx时间,xx如何如何。 随着xxx时间的普及,xxx已经走进千家万户。 再夸一夸xxx的理念和优点。 本系统基于xxx技术。本论文基于此项目,从需求分析、产品设计、功能的编码与实现、系统测试等方面,按照在企业中一个项目的生命周期的顺序进行详细叙述。系统具有科学且严谨的架构,遵循软件工程基本原理,遵循一套详尽的代码格式要求。系统使用前后端分离开发的方式,在最大程度上降低了开发成本与系统复杂性,让一切问题都有迹可循,同时也提高了系统的性能,提高安全性,易于维护和操作。 关键词:随便挑几个;差不多就行;三四个就够;四个不算多 翻译摘要 banana apple niubility do you know google translate 目录 目录用word自带目录功能生成,不会就学。 引言 我到现在也没分清引言和摘要有啥区别,反正都是写一些套话,夸一夸这个东西哪好。 我的意思不是这里只能写套话,而是写套话也可以。 你要是会写论文就别看我在这胡诌八扯了,用你古灵精怪聪明伶俐的才能去自己写啊。 xxx已经成为了未来xxx的一种趋势,相比市场上现阶段流行的xxx,xxx具有什么什么优点。xxx的这种特点顺应时代的趋势,大大满足了用户的需求。 随着xxx市场的不断完善,已经有大部分主流应用都入驻了xxx。而借助(夸时代好),xxx也得到了很好的引流。基于xxx进行开发,有如下优势: 第一,可以提高程序的开发效率。夸它开发快。 第二,很大程度上降低了用户的使用门槛。夸它。 夸你项目的优点。 (当今市场上社交应用层出不穷,而大多应用都是微信、微博、贴吧等应用的子功能。但是这些巨头的应用也有其缺点,那就是不具有特异性。例如,贴吧上可以找到具有各种爱好的人,但是如果想要聚集更多喜欢某一个爱好的人,贴吧却受到其推广程度的限制以至于做不到。) 夸你需求设计得好 (随着人们生活质量的提升,旅行已经不是一种高成本的活动,同时旅行也已经被大众的价值观接受。这时旅行者们就需要一个平台可以来分享旅行见闻。市场上已经存在的每个平台上都有其他社交圈子上的朋友或者是亲友,将旅行见闻分享到这些通用的平台上,有的时候反而不会收获到期望中的成就感与满足感。 ) 再说明你做这玩意为了啥,为了世界和平之类的。 需求分析 用户需求分析 先分析一下主流的同类竞品如何,再夸你这玩意有自己独特的点。 需求列表 把你要做的需求细分一下都列出来。 (1)登录/注册 (2)设置用户基本资料(昵称、头像) (3)按时间顺序查看帖子 (4)基于帖子进行互动(评论、回复评论) (5)发送帖子 (6)查看我发送的帖子 (7)查看我参与过的帖子 (8)查看攻略 (9)进行系统设置 开发工具及技术 架构 前端 后端 数据库 缓存 服务器 代码版本管理 开发工具 有啥写啥,每项技术都介绍两句,不知道咋介绍的,把你这项技术打到百度上,随便抄两句,改改句子结构。 产品设计 可行性分析 经济可行性 算算钱,计划一下钱够不够花。最后得出结论经济可行。 不可行你还写啥论文,直接毕设题目都换了。 本系统运行于xxx平台。服务器xx元/天。 xxxxxxx 综上,经济可行性得以论证,答案是可行的。 技术可行性 再叨叨一遍你都用啥技术,再说技术可行, 系统流程设计 描述一遍用户打开你这玩意之后的操作流程,再画个流程图。流程图在课上应该学过,没学过就去翻翻书。 系统功能设计 建议在这个地方按照功能画原型图,显得很专业。不画原型图的话就按照功能一个一个描述它应该是什么样子。 原型图用墨刀或者axure画,实在不行就用windows画图也行。 用户用例图 要是没听过用例图,也去翻翻书。 开发准备 挨个去描述你都怎么做的,一边打字一边截图,有理有据令人信服证据确凿百口莫辩。 购买服务器 购买域名 设置解析 安装git本地仓库 设置自动部署 上传初始代码到git仓库 数据库设计 概念结构设计 画ER图。 逻辑结构设计 将ER图转换为关系模式。 数据库物理实现 先跑去数据库建库建表,然后直接复制表结构的SQL。再加点废话,描述一下主键外键索引啥的。 在DBMS上,我们选择MySQL,配合PHP 5.3下的Thinkphp框架,可以发挥其最大的优势。 创建数据表user,用于存储用户信息。其中id是主键,为用户表的索引行。openid是唯一字段,为微信提供的用户唯一id。执行语句: CREATE TABLE IF NOT EXISTS user ( id int(11) NOT NULL AUTO_INCREMENT, openid varchar(64) NOT NULL, create_time varchar(25) NOT NULL, change_time varchar(25) NOT NULL, nickname varchar(25) NOT NULL, usericon varchar(1024) NOT NULL, sina varchar(255) NOT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=6 ; 上边说的两个图还有一系列数据库术语在数据库课应该都学过,要是没学过你就翻翻书。 编码开发 反正就挨个写你都咋做的,别贴代码。 发送验证码 发送明信片 读取明信片 软件测试 夸一夸各种技术架构好用,然后把表格直接贴上就行了。 都能写论文了说明项目早就过了测试,好使就完事了。 功能测试 可用性测试 测试结果分析 在编写代码过程中,已经对致命性缺陷进行排除,但由于小程序方面的经验不足,写代码的过程中依然造成了许多缺陷。在反复地调试之后,将前后端成功地组装在了一起,完成了整个系统的编码开发。 经过编码调试、功能测试、可用性测试,此程序可以满足用户的需求和要求,所有基本功能齐全,操作简单且友好,系统性能优良,可以完美运行于任何能运行微信的终端。 结论 我也不知道咋编,反正就是编。夸你这玩意好使,还顺应时代需求,用户用得还爽。 参考文献 去搜几个跟你这一堆技术相关的书放上去,记得用参考文献标准格式。标准格式也能搜到。 附录 附录有没有都行,贴代码也行。 后记 写点煽情的话,感谢导师感谢学校啥的。
发表时间 2020-02-15
发表在 技术学习
阅读数 0
xtzero.me
从前从前,有个人爱你很久
友情链接
这里是友情链接
虽然我很菜,但是也希望可以和更多人交换友链。
作品站
这里是我的 作品站
虽然菜,但还没放弃创造。
推广内容
或许你需要买便宜的服务器
你有优惠我有返利,何乐而不为呢。

立即查看 >>
也想使用 Hikari 2 ?
Hikari 2 已经被用来建站啦!点击这里来查看都有哪些案例以及我们的联系方式吧。