Browse Source

:tada: 项目搭建
:truck: 代码清理

zhanghe 6 years ago
commit
4b42709ce0
100 changed files with 11526 additions and 0 deletions
  1. 24 0
      .gitignore
  2. 165 0
      README.md
  3. 332 0
      config/gulpfile.js
  4. 33 0
      src/component/CourseItem.js
  5. 62 0
      src/component/EFMarquee.js
  6. 24 0
      src/component/GoodsItem.js
  7. 413 0
      src/component/KeyboardPanel.js
  8. 195 0
      src/component/Swiper.js
  9. 34 0
      src/component/recommend.js
  10. 144 0
      src/lib/css/base.css
  11. 229 0
      src/lib/css/keyPanel.css
  12. 45 0
      src/lib/css/marquee.css
  13. 3763 0
      src/lib/js/FocusEngine.js
  14. 8 0
      src/lib/js/FocusEngine.min.js
  15. 8 0
      src/lib/js/TVUtil.min.js
  16. 477 0
      src/lib/js/alitv-debug.js
  17. 1 0
      src/lib/js/alitv-debug.min.js
  18. 884 0
      src/lib/js/animate_marquee.js
  19. 1008 0
      src/lib/js/blitz.js
  20. 321 0
      src/lib/js/keyPanel.js
  21. 1625 0
      src/lib/js/moye.js
  22. 740 0
      src/lib/js/moye.min.js
  23. 165 0
      src/lib/js/widget_marquee.js
  24. 51 0
      src/lib/mockapi/collection.json
  25. 39 0
      src/lib/mockapi/course_detail.json
  26. 27 0
      src/lib/mockapi/course_lesson.json
  27. 19 0
      src/lib/mockapi/course_supports.json
  28. 33 0
      src/lib/mockapi/product_list.json
  29. 45 0
      src/lib/mockapi/recommend.json
  30. 9 0
      src/lib/mockapi/shopcart.json
  31. 37 0
      src/lib/mockapi/shopcart_list.json
  32. 7 0
      src/lib/mockapi/shopcart_number.json
  33. 42 0
      src/lib/mockapi/support_detail.json
  34. 49 0
      src/lib/mockapi/tag_list.json
  35. 13 0
      src/lib/mockapi/terminal.json
  36. 10 0
      src/lib/mockapi/token.json
  37. 38 0
      src/lib/mockapi/ware_list.json
  38. 25 0
      src/manifest.json
  39. BIN
      src/res/img/default_bg.jpg
  40. BIN
      src/res/img/icon.png
  41. 7 0
      src/res/tpl/BuyConfirmScene.tpl
  42. 24 0
      src/res/tpl/CLScene.tpl
  43. 18 0
      src/res/tpl/CourseScene.tpl
  44. 3 0
      src/res/tpl/DataBuildingScene.tpl
  45. 8 0
      src/res/tpl/DelConfirmScene.tpl
  46. 107 0
      src/res/tpl/DownloadScene.tpl
  47. 38 0
      src/res/tpl/GlobalGoodDetail.tpl
  48. 5 0
      src/res/tpl/ImageWareFullScreen.tpl
  49. 34 0
      src/res/tpl/IndexScene.tpl
  50. 11 0
      src/res/tpl/LessonScene.tpl
  51. 61 0
      src/res/tpl/LoginScene.tpl
  52. 13 0
      src/res/tpl/QuitConfirmScene.tpl
  53. 14 0
      src/res/tpl/RepeatLoginScene.tpl
  54. 9 0
      src/res/tpl/ShopCartCheckScene.tpl
  55. 13 0
      src/res/tpl/ShopCartScene.tpl
  56. 3 0
      src/res/tpl/SplashScene.tpl
  57. 7 0
      src/res/tpl/TerminalScene.tpl
  58. 1 0
      src/res/tpl/VideoWareFullScreen.tpl
  59. 3 0
      src/res/values/value.json
  60. 3 0
      src/res/values/value_en.json
  61. BIN
      src/stage/index/assets/img/CLScene/background.jpg
  62. BIN
      src/stage/index/assets/img/CLScene/icon_shopcart.png
  63. BIN
      src/stage/index/assets/img/CourseScene/bg.jpg
  64. BIN
      src/stage/index/assets/img/CourseScene/bg.png
  65. BIN
      src/stage/index/assets/img/CourseScene/cart.png
  66. BIN
      src/stage/index/assets/img/CourseScene/cart_selected.png
  67. BIN
      src/stage/index/assets/img/CourseScene/collect.png
  68. BIN
      src/stage/index/assets/img/CourseScene/collected.png
  69. BIN
      src/stage/index/assets/img/CourseScene/course_buy.png
  70. BIN
      src/stage/index/assets/img/CourseScene/course_buyed.png
  71. BIN
      src/stage/index/assets/img/CourseScene/data_not_ready.jpg
  72. BIN
      src/stage/index/assets/img/CourseScene/detail.png
  73. BIN
      src/stage/index/assets/img/CourseScene/detail/add_cart.png
  74. BIN
      src/stage/index/assets/img/CourseScene/detail/added.png
  75. BIN
      src/stage/index/assets/img/CourseScene/detail/added_cart.png
  76. BIN
      src/stage/index/assets/img/CourseScene/detail/buyed.png
  77. BIN
      src/stage/index/assets/img/CourseScene/detail/month_add_cart.png
  78. BIN
      src/stage/index/assets/img/CourseScene/detail/periphery_add_cart.png
  79. BIN
      src/stage/index/assets/img/CourseScene/detail/periphery_added.png
  80. BIN
      src/stage/index/assets/img/CourseScene/detail/renewal_fee.png
  81. BIN
      src/stage/index/assets/img/CourseScene/detail/season_add_cart.png
  82. BIN
      src/stage/index/assets/img/CourseScene/detail/year_add_cart.png
  83. BIN
      src/stage/index/assets/img/CourseScene/detail_selected.png
  84. BIN
      src/stage/index/assets/img/CourseScene/download_btn_icon_ongoing.gif
  85. BIN
      src/stage/index/assets/img/CourseScene/download_btn_icon_ongoing.png
  86. BIN
      src/stage/index/assets/img/CourseScene/download_btn_icon_success.png
  87. BIN
      src/stage/index/assets/img/CourseScene/download_btn_icon_undownload.png
  88. BIN
      src/stage/index/assets/img/CourseScene/download_btn_list_ongoing.gif
  89. BIN
      src/stage/index/assets/img/CourseScene/download_btn_list_ongoing.png
  90. BIN
      src/stage/index/assets/img/CourseScene/download_btn_list_success.png
  91. BIN
      src/stage/index/assets/img/CourseScene/download_btn_list_undownload.png
  92. BIN
      src/stage/index/assets/img/CourseScene/left.png
  93. BIN
      src/stage/index/assets/img/CourseScene/list.png
  94. BIN
      src/stage/index/assets/img/CourseScene/list_selected.png
  95. BIN
      src/stage/index/assets/img/CourseScene/name_wrapper.png
  96. BIN
      src/stage/index/assets/img/CourseScene/periphery.png
  97. BIN
      src/stage/index/assets/img/CourseScene/periphery_selected.png
  98. BIN
      src/stage/index/assets/img/CourseScene/right.png
  99. BIN
      src/stage/index/assets/img/DownloadScene/download.png
  100. 0 0
      src/stage/index/assets/img/DownloadScene/download_del_btn.png

+ 24 - 0
.gitignore

@@ -0,0 +1,24 @@
+.DS_Store
+node_modules
+*/node_modules
+npm-debug.log
+*.swp
+.sw*
+.idea/*
+.editorconfig
+.jshintrc
+.eslintrc
+.travis.yml
+.sass-cache/
+mods/.sass-cache/
+.cache
+build/
+buildLocal/
+.eslintrc.js
+package.json
+# Mock API config file
+api.json
+src/models/*
+*.jade
+**/pug
+*.tar

+ 165 - 0
README.md

@@ -0,0 +1,165 @@
+# To B Web for TV Platform
+
+## 1. 项目结构简述
+- component目录用来存放UI组件相关代码
+- util/API目录用来存在API请求相关代码
+- util目录用来存放其他工具类
+- 其他的照旧
+
+## 2.代码规范简述(待补充)
+- 类型命名,驼峰式命名,component内相关类型建议首字母大写,其他的根据情况可以首字母小写
+- 变量命名,驼峰式命名
+- JSON变量命名,全小写,下划线风格单词
+- html中如无特殊情况class用来写样式,id用来js操作
+- class命名字母小写,中划线风格(CSS中无法识别大小写)
+- CSS书写顺序推荐:只遵循横向顺序即可,先显示定位布局类属性,后盒模型等自身属性,最后是文本类及修饰类属性
+- 公共样式在mixins.less文件中,后续如再有公共样式再补充
+
+| 显示属性    |  自身属性  | 文本类及修饰类属性 |
+| --------   | --------  | --------          |
+| display    | width     | font              |
+| visibility | height    | text-align        |
+| position   | margin    | text-decoration   |
+| float      | padding   | vertical-align    |
+| clear      | border    | white-space       |
+| list-style | overflow  | color             |
+| top        | min-width | background        |
+
+### 附:
+### API Mock方法
+- 添加Mock API的返回数据json文件在 src/lib/mockapi/ 目录下如 src/lib/mockapi/test1.json
+- util/API/APIClient.js中增加访问方法,比如:
+
+```
+static getMockData(callback){
+    let apiUrl = AJAXHelper.genMockDataUrl('test1');
+    AJAXHelper.get(apiUrl,callback);
+}
+```
+
+- sence中引用APIClient
+
+```
+import APIClient from '../../../util/API/APIClient'
+```
+
+- scene业务程序中使用:
+
+```
+APIClient.getMockData((isTrue,res)=>{
+    console.log(res);
+});
+```
+
+### EFMarquee使用说明:
+- 类型导入
+
+```
+import Marquee from '../../../component/EFMarquee.js'
+```
+- 代码中使用
+
+```
+this.marquee = Marquee.getInstance();
+this.marquee.create(document.getElementById('title_marquee'),100);
+this.marquee.setStr(document.getElementById('title_marquee').innerHTML);
+this.marquee.start(true);
+```
+
+- 停止跑马灯
+
+```
+this.marquee.stop();
+```
+
+
+### ScrollEventPlugin使用说明:
+
+>     针对阿里小程序Scroll控件定制的补充事件的插件类。
+>     阿里小程序要求Scroll控件内必须有一个class为scroll-list的元素,这里我们的插件对scroll-list也有一定要求,
+>     scroll-list相对于父级元素不要有高度的padding或margin的情况,否则会导致滚动计算不准确导致无法命中事件的情况
+
+- 类型导入
+
+
+```
+import ScrollEventPlugin from '../../../util/ScrollEventPlugin'
+```
+- 代码中使用
+    
+```
+//创建插件对象
+this.rightScrollEvent = new ScrollEventPlugin();
+//绑定目标Scroll widget
+this.rightScrollEvent.bind(this.moye.root.getWidgetById('cl-right-content-scroll'));
+//设置回调触发事件
+this.rightScrollEvent.onScrollToBottom(()=>{
+    console.log('on scroll to bottom');
+});
+//释放事件锁
+this.rightScrollEvent.releaseEventLock();
+```
+>     本插件在触发“到底”或者“到顶”事件时,为了防止非自愿的再次触发,所以在触发事件之后,插件内部会加锁防止再次触发,
+>     直到调用方完成了触发后的相关任务之后,认为可以再次处理触发事件时,可手工解锁。
+
+### NotificationCenter使用说明
+
+>     专门为moye框架下应用程序实现的全局观察者模式的消息中心,方便跨Scene的消息传递,局部状态变更。
+>     使用时需要在Scene下引用NotificationCenter类
+
+- 类型导入
+
+
+```
+import NotificationCenter from '../../../util/NotificationCenter';
+```
+
+- 注册观察者
+
+
+```
+// name:观察者名称
+// selector:为观察者绑定的消息回调
+static add(name, selector)
+```
+
+```
+//调用示例
+NotificationCenter.add('collection_refresh', this.collectionGlobalListener.bind(this));
+```
+
+
+
+>  同一个name可以依次绑定多个消息回调,可以在不同scene中为同一个name绑定消息回调
+
+
+- 向已注册的观察者发送消息
+
+
+```
+// name:观察者名称
+// obj:需要通过消息中心发送的数据对象(非必要参数)
+static call(name, obj)
+```
+
+```
+//调用示例
+NotificationCenter.call('collection_refresh');
+```
+
+- 删除观察者
+
+>  当观察者所在scene被destroy时,观察者也会失效,这时我们建议手动移除之前注册过的观察者
+
+```
+// name:观察者名称
+// selector:之前注册的观察者,消息中心会通过比对找到之前注册过的同名观察者,然后移除
+static remove(name, selector)
+```
+
+>  selector参数如果缺省,则删除该name下所有的观察者
+
+```
+//调用示例
+NotificationCenter.remove('collection_refresh', this.collectionGlobalListener.bind(this));
+```

+ 332 - 0
config/gulpfile.js

@@ -0,0 +1,332 @@
+//var wrench = require('wrench');
+var gulp = require('gulp');
+var del = require('del');
+var path = require('path');
+var fs = require('fs');
+var gutil = require('gulp-util');
+var minimist = require('minimist');
+var less = require('gulp-less');
+var minifyCss = require('gulp-minify-css');
+var uglify = require('gulp-uglify');
+var rename = require('gulp-rename');
+var footer = require('gulp-footer');
+var webpack = require('webpack-stream');
+var wb = require('webpack');
+var webserver = require('gulp-webserver');
+var replace = require('gulp-replace');
+var babel = require('gulp-babel');
+var es2015 = require('babel-preset-es2015');
+var gulpif = require('gulp-if');
+
+var basePath = process.env.PJ_PATH;
+//var absPath = 'http://127.0.0.1:8080/efunbox-to-b/1.0.0';
+var absPath = 'http://lj-web.api.ai160.com/build';
+
+//var absPath = 'http://2blj.api.ai160.com/build';
+//var absPath = 'http://114.215.119.26:80/efunbox-to-b/1.0.0';
+var pkg = {}
+//兼容
+if(fs.existsSync(path.join(basePath, 'src/package.json'))){
+  pkg = require(path.join(basePath, 'src/package.json'))
+}else{
+  pkg = require(path.join(basePath, 'package.json'))
+  fs.writeFileSync(path.join(basePath, 'src/package.json'), fs.readFileSync(path.join(basePath, 'package.json'), 'utf-8'), 'utf-8');
+  fs.unlinkSync(path.join(basePath, 'package.json'));
+}
+
+//moye配置
+var moyeConf = fs.existsSync(path.join(basePath, 'moye.json')) ? require(path.join(basePath, 'moye.json')) : {}
+
+//js uglify config
+var uglifyConf = {
+  compress: {
+    drop_console: true
+  },
+  output:{
+    ascii_only:true
+  }
+}
+
+//server端口号
+var port = minimist(process.argv.slice(2), {string: 'port'}).port;
+var serverWatch = eval(minimist(process.argv.slice(3), {string: 'watch'}).watch);
+var isUglify = eval(minimist(process.argv.slice(3), {string: 'uglify'}).uglify);
+//老版本兼容
+process.env.C_PATH = fs.existsSync(path.join(basePath, 'src/stage')) ? 'stage' : 'page'
+
+// 获取stage列表
+var stages = []
+fs.readdirSync(path.join(basePath, 'src/'+process.env.C_PATH)).forEach(function(item){
+  if(fs.statSync(path.join(basePath, 'src/'+process.env.C_PATH+'/'+item)).isDirectory())  stages.push(item)
+});
+
+var entry = {};
+for (var i = 0; i < stages.length; i++) {
+  var exists = fs.existsSync(path.join(basePath, 'src/'+process.env.C_PATH+'/' + stages[i] + '/index.js'));
+  if (exists) {
+    entry[stages[i]] = path.join(basePath, 'src/'+process.env.C_PATH+'/') + stages[i] + '/index.js';
+  }
+}
+
+// 获取template列表
+var templates = []
+fs.readdirSync(path.join(basePath, 'src/res/tpl')).forEach(function(item){
+  if(!fs.statSync(path.join(basePath, 'src/res/tpl/'+item)).isDirectory() && /(\.tpl)$|(\.jade)$|(\.juicer)$|(\.ejs)$/g.test(item))  templates.push(item)
+});
+
+var templates_entry = {};
+for (var i = 0; i < templates.length; i++) {
+  var exists = fs.existsSync(path.join(basePath, 'src/res/tpl/' + templates[i]));
+  if (exists) {
+    entry[templates[i]] = path.join(basePath, 'src/res/tpl/') + templates[i];
+  }
+}
+
+//webpack配置
+var webpackConf = function(entry, buidPath){
+  var conf = {
+    cache: true,
+    entry: entry,
+    output: {
+      path: path.join(basePath, './build/' + buidPath),
+      filename:'[name].js',
+      chunkFilename: 'module.[name].js'
+    },
+    module: {
+      loaders: [{
+        test: /\.js$/,
+        loader: 'babel'
+      },{
+        test: /\.jade$/,
+        loader: 'jade-loader'
+      },{
+        test: /\.ejs$/,
+        loader: 'ejs-loader'
+      },{
+        test: /\.tpl$/,
+        loader: 'tpl-loader'
+      },{
+        test: /\.juicer$/,
+        loader: 'juicer-loader'
+      },{
+        test: /\.json$/,
+        loader: 'json-loader'
+      }],
+    },
+    resolveLoader: {
+      root:[
+        path.resolve(__dirname, '../../../node_modules'),
+        path.resolve(__dirname, '../')
+      ]
+    },
+    devtool: 'inline-source-map',
+    plugins: [new wb.optimize.DedupePlugin()]
+  }
+  if(moyeConf.online && moyeConf.online.basePath) conf.output.publicPath = moyeConf.online.basePath
+  return conf
+}
+//模板预编译
+gulp.task('compile-template', function(){
+  for (var i = 0; i < templates.length; i++) {
+    var entry = {};
+    entry[templates[i]] = path.join(basePath, 'src/res/tpl/' + templates[i])
+    gulp.src(entry[templates[i]])
+      .pipe(webpack(webpackConf(entry, '../build/res/tpl'),null,function (err,status) {
+        //console.log('webpack end')
+      }))
+      .pipe(gulpif(isUglify, uglify(uglifyConf)))
+      .pipe(replace('!function','module.exports=(function'))
+      .pipe(replace('(0)}([function','(0)})([function'))
+	//lang
+      .pipe(replace('src="./assets/','src="'+absPath+'/stage/index/assets/'))
+      .pipe(replace('src="./../../stage/','src="'+absPath+'/stage/'))
+      .pipe(replace('src="assets/','src="'+absPath+'/stage/index/assets/'))
+      .pipe(gulp.dest(path.join(basePath, 'build/res/tpl/')))
+  }
+})
+
+//编译任务
+gulp.task('compile', function(){
+  for (var i = 0; i < stages.length; i++) {
+    var entry = {};
+    entry['index'] = path.join(basePath, 'src/'+process.env.C_PATH+'/' + stages[i] + '/index.js')
+    gulp.src(entry['index'])
+      .pipe(webpack(webpackConf(entry, ''),null,function (err,status) {
+        //console.log('webpack end')
+      }))
+	//lang
+      .pipe(replace('src="./assets/','src="'+absPath+'/stage/index/assets/'))
+      .pipe(replace('src="./../../stage/','src="'+absPath+'/stage/'))
+      .pipe(replace('src="assets/','src="'+absPath+'/stage/index/assets/'))
+      .pipe(gulp.dest(path.join(basePath, 'build/'+process.env.C_PATH+'/' + stages[i] + '/')))
+      .pipe(uglify(uglifyConf))
+      .pipe(rename({
+        suffix: '.min'
+      }))
+      .pipe(gulp.dest(path.join(basePath, 'build/'+process.env.C_PATH+'/' + stages[i] + '/')))
+
+    gulp.src(path.join(basePath, 'src/'+process.env.C_PATH+'/' + stages[i] + '/index.less'))
+      .pipe(less())
+	//lang
+      .pipe(replace('assets/',''+absPath+'/stage/index/assets/'))
+      .pipe(gulp.dest(path.join(basePath, 'build/'+process.env.C_PATH+'/') + stages[i]))
+      .pipe(minifyCss({
+        compatibility: '-units.ch,-units.in,-units.pc,-units.pt,-units.vh,-units.vm,-units.vmax,-units.vmin'
+      }))
+      .pipe(rename({
+        suffix: '.min'
+      }))
+      .pipe(footer('/*# sourceMappingURL=index.css.map */'))
+      .pipe(gulp.dest(path.join(basePath, 'build/'+process.env.C_PATH+'/') + stages[i]));
+    gutil.log(gutil.colors.green('Build less: '+path.join(basePath, 'src/'+process.env.C_PATH+'/' + stages[i] + '/index.less')));
+  }
+})
+
+
+gulp.task('copy', function(){
+  gulp.src(path.join(basePath, 'src/'+process.env.C_PATH+'/**/*.html'))
+    .pipe(replace('src="../../lib/','src="'+absPath+'/lib/'))
+    .pipe(replace('./index.css?t=',''+absPath+'/stage/index/index.css?t='))
+    .pipe(replace('./index.js?t=',''+absPath+'/stage/index/index.js?t='))
+    .pipe(gulp.dest(path.join(basePath, 'build/'+process.env.C_PATH+'')));
+  gutil.log(gutil.colors.green('Copy libs: build/'+process.env.C_PATH+'/**/*.html'));
+
+  gulp.src(path.join(basePath, 'src/'+process.env.C_PATH+'/**/assets/**/*'))
+    .pipe(gulp.dest(path.join(basePath, 'build/'+process.env.C_PATH+'/')));
+  gutil.log(gutil.colors.green('Copy libs: build/'+process.env.C_PATH+'/**/assets'));
+
+  gulp.src(path.join(basePath, 'src/lib/**/*'))
+    .pipe(gulp.dest(path.join(basePath, 'build/lib')));
+  gutil.log(gutil.colors.green('Copy libs: build/lib'));
+
+  gulp.src(path.join(basePath, 'src/res/**/*'))
+	//lang
+      .pipe(replace('src="./assets/','src="'+absPath+'/stage/index/assets/'))
+      .pipe(replace('src="./../../stage/','src="'+absPath+'/stage/'))
+      .pipe(replace('src="assets/','src="'+absPath+'/stage/index/assets/'))
+    .pipe(gulp.dest(path.join(basePath, 'build/res/')));
+  gutil.log(gutil.colors.green('Copy res: build/res/values'));
+
+  // gulp.src(path.join(basePath, 'src/res/img/**/*'))
+  //   .pipe(gulp.dest(path.join(basePath, 'build/res/img/')));
+  // gutil.log(gutil.colors.green('Copy res: build/res/img'));
+
+  gulp.src(path.join(basePath, 'src/service/**/*'))
+    .pipe(gulp.dest(path.join(basePath, 'build/service/')));
+  gutil.log(gutil.colors.green('Copy service: build/service'));
+})
+
+gulp.task('default', function() {
+  //console.log(path.join(basePath, 'src/**/*'))
+  var watcherJsLess = gulp.watch(path.join(basePath, 'src/**/*.{js,less,css}'),['compile'])
+  var watcherTemplate = gulp.watch(path.join(basePath, 'src/**/*.{tpl,jade,ejs,juicer}'),['compile'])
+  var watcherRes = gulp.watch(path.join(basePath, 'src/**/*'),['copy'])
+  watcherRes.on('change', function(event) {
+    gutil.log(gutil.colors.yellow('File ' + event.path + ' was ' + event.type));
+  });
+});
+
+// 启动server
+gulp.task('server', function() {
+  gulp.src(path.join(basePath, 'build/'))
+    .pipe(webserver({
+      path: '/' + pkg.name + '/' + pkg.version + '/',
+      host: '0.0.0.0',
+      port: port,
+      livereload: true,
+      directoryListing: {
+        enable: true,
+        path: path.join(basePath, 'build/')
+      },
+      middleware: function(req, res, next) {
+        gutil.log('Request received: ' + req.url);
+        next();
+      }
+    }));
+  gutil.log(gutil.colors.green('http://127.0.0.1'+(parseInt(port) == 80 ? '' : ':'+port)+'/' + pkg.name + '/' + pkg.version + '/'));
+  if(serverWatch){
+    var watcherJsLess = gulp.watch(path.join(basePath, 'src/**/*.{js,less,css}'),['compile'])
+    var watcherTemplate = gulp.watch(path.join(basePath, 'src/**/*.{tpl,jade,ejs,juicer}'),['compile'])
+    var watcherRes = gulp.watch(path.join(basePath, 'src/**/*'),['copy'])
+    watcherRes.on('change', function(event) {
+      gutil.log(gutil.colors.yellow('File ' + event.path + ' was ' + event.type));
+    });
+  }
+});
+
+//service-worker编译任务
+gulp.task('sw-compile', function(){
+  for (var i = 0; i < stages.length; i++) {
+    var entry = {};
+    entry[stages[i]] = path.join(basePath, 'src/'+process.env.C_PATH+'/' + stages[i] + '/service-worker/index.js')
+    if(fs.existsSync(entry[stages[i]])){
+      gulp.src(entry[stages[i]])
+        .pipe(webpack(webpackConf(entry, 'service-worker/'),null,function (err,status) {
+          //console.log('webpack end')
+        }))
+        .pipe(gulp.dest(path.join(basePath, 'build/'+process.env.C_PATH+'/' + stages[i] + '/service-worker/')))
+    }
+  }
+})
+
+// 编译打包cyclone本地app
+gulp.task('cyclone', function() {
+  var cssSrc = [path.join(basePath, 'src/'+process.env.C_PATH+'/**/*.{less,css}')];
+  var jsSrc = [path.join(basePath, 'src/**/*.js'), '!' + path.join(basePath, 'src/lib/**/*'), '!' + path.join(basePath, 'src/service/**/*.js')];
+  // var copySrc = [
+  //       path.join(basePath, 'src/*'),
+  //       path.join(basePath, 'src/'+process.env.C_PATH+'/**/assets/**/*'),
+  //       path.join(basePath, 'src/'+process.env.C_PATH+'/**/*.html'),
+  //       path.join(basePath, 'src/res/**/*'),
+  //       path.join(basePath, 'src/lib/**/*'),
+  //       path.join(basePath, 'src/manifest.json'),
+  //       path.join(basePath, 'src/service/**/*.js'),
+  //       path.join(basePath, 'src/util/**/*'),
+  //       path.join(basePath, 'src/component/**/*'),
+  //       path.join(basePath, 'src/node_modules/**/*')
+  //     ];
+  // var copyDest = [
+  //       path.join(basePath, 'buildLocal/'),
+  //       path.join(basePath, 'buildLocal/'+process.env.C_PATH+'/'),
+  //       path.join(basePath, 'buildLocal/'+process.env.C_PATH+'/'),
+  //       path.join(basePath, 'buildLocal/res/'),
+  //       path.join(basePath, 'buildLocal/lib/'),
+  //       path.join(basePath, 'buildLocal/'),
+  //       path.join(basePath, 'buildLocal/service/'),
+  //       path.join(basePath, 'buildLocal/util/'),
+  //       path.join(basePath, 'buildLocal/component/'),
+  //       path.join(basePath, 'buildLocal/node_modules/')
+  //     ];
+  //for (var i = 0; i < copySrc.length; i++) {
+  gulp.src(path.join(basePath, 'src/manifest.json'))
+    .pipe(gulp.dest(path.join(basePath, 'buildLocal/')))
+  gulp.src(path.join(basePath, 'src/**/*'))
+    .pipe(gulp.dest(path.join(basePath, 'buildLocal/')))
+    .on('end',function(){
+      gulp.src(cssSrc)
+        .pipe(less())
+        .pipe(minifyCss())
+        .pipe(gulp.dest(path.join(basePath, 'buildLocal/'+process.env.C_PATH)))
+      gulp.src(jsSrc)
+        .pipe(babel({
+          presets: [es2015]
+        }))
+        .pipe(replace(/((\.tpl)|(\.jade)|(\.juicer)|(\.ejs))[\'\"]\)/g,'$1.js\'\)'))
+        .pipe(gulpif(isUglify, uglify(uglifyConf)))
+        .pipe(gulp.dest(path.join(basePath, 'buildLocal/')));
+      for (var i = 0; i < templates.length; i++) {
+        var entry = {};
+        entry[templates[i]] = path.join(basePath, 'src/res/tpl/' + templates[i])
+        gulp.src(entry[templates[i]])
+          .pipe(webpack(webpackConf(entry, '../buildLocal/res/tpl'),null,function (err,status) {
+            //console.log('webpack end')
+          }))
+          .pipe(uglify(uglifyConf))
+          .pipe(replace('!function','module.exports=(function'))
+          .pipe(replace('(0)}([function','(0)})([function'))
+          .pipe(gulp.dest(path.join(basePath, 'buildLocal/res/tpl/')))
+      }
+    })
+  //}
+});
+

+ 33 - 0
src/component/CourseItem.js

@@ -0,0 +1,33 @@
+class CourseItem {
+	constructor (){}
+
+	static createElement(data){
+		let d = document.createElement('div');
+		d.innerHTML = CourseItem.createHTMLString(data);
+		return d.childNodes[0];
+	}
+
+	static createHTMLString(data){
+		return `<div class="course-item-frame">
+                    <img src="${data.img}" alt="">
+                    <div class="course-buyed" style="display:${data.buyed ? 'block' : 'none'};"></div>
+                    <div class="course-des">
+						<p class="subject">${data.subject}</p>
+						<p class="subject-sub">${data.subjectSub}</p>
+                    </div>
+                </div>`;
+	}
+  //cart List
+  static createHTMLStringForCart(data){
+		return `<div class="course-item-frame">
+                    <img src="${data.img}" alt="">
+                    <div class="cart-course-des">
+          						<p class="subject">${data.subject}</p>
+          						<p class="subject-sub">${data.subjectSub}</p>
+          						<p class="course-price-in-cart">${data.priceStr}</p>
+                    </div>
+                </div>`;
+	}
+}
+
+module.exports = CourseItem;

+ 62 - 0
src/component/EFMarquee.js

@@ -0,0 +1,62 @@
+class EFMarquee {
+	constructor() {
+		this.element = null;
+	}
+
+	static getInstance() {
+		return (typeof yunos != 'undefined') ? tv_marquee : new EFMarquee();
+	}
+
+	create(node, speed) {
+		this.element = node;
+		this.timer = null;
+		this.startX = 0;
+		this.stopX = 0;
+		this.currentX = 0;
+		return this;
+	}
+
+	start(circle) {
+		// this.element.className = 'ef_marquee';
+		this.element.classList.add('ef_marquee');
+		console.log('document :' + document.body.clientWidth);
+		console.log('marquee p width:' + this.element.childNodes[0].clientWidth);
+		this.startX = this.element.clientWidth;
+		this.stopX = this.element.childNodes[0].clientWidth * -1;
+		this.currentX = this.startX;
+
+		function updateFrame(dom, x) {
+			dom.setAttribute('style', 'left:' + x + 'px');
+		}
+
+		function update(context) {
+			context.timer = setTimeout(function() {
+				context.currentX -= 1;
+				updateFrame(context.element.childNodes[0], context.currentX);
+				if (context.currentX > context.stopX) {
+					update(context);
+					return;
+				}
+				if (circle) {
+					context.currentX = context.startX;
+					update(context);
+				} else {
+					context.currentX = 0;
+					updateFrame(context.element.childNodes[0], context.currentX);
+				}
+			}.bind(this), 30);
+		}
+		update(this);
+	}
+
+	setStr(str) {
+		this.element.innerHTML = '<p>' + str + '</p>';
+	}
+
+	stop() {
+		this.element.className = '';
+		clearTimeout(this.timer);
+	}
+}
+
+module.exports = EFMarquee;

+ 24 - 0
src/component/GoodsItem.js

@@ -0,0 +1,24 @@
+import Utils from '../util/Utils';
+
+class GoodsItem {
+    constructor() { }
+
+    static createElement(data) {
+        let d = document.createElement('div');
+        d.innerHTML = GoodsItem.createHTMLString(data);
+        return d.childNodes[0];
+    }
+
+    static createHTMLString(data) {
+        return `<div class="goods-item-frame clearfix">
+                    <img src="${typeof data.img == 'string' ? data.img : data.img[0]}" alt="">
+                    <div class="goods-des">
+                        <p class="title">${data.title}</p>
+                        <p class="correlative">${data.correlative || ''}</p>
+                        <p class="price">¥${Utils.twoDecimal_f(data.price)}</p>
+                    </div>
+                </div>`;
+    }
+}
+
+module.exports = GoodsItem;

+ 413 - 0
src/component/KeyboardPanel.js

@@ -0,0 +1,413 @@
+
+const mKeyPanelHtml = `
+        <div class="key-input-panel">
+            <div class="key-input-frame">
+                <div id="j-search-panel-tip"></div>
+                <img class="search-icon" src="./assets/img/Search/search.png" />
+            </div>
+        </div>
+        <div id="search-panel" class="key-panel" fe-role="Switch">
+            <!--圆形字母小面板-->
+            <div id="search-panel-popup" class="search-popup" fe-role="Switch">
+                <!--中心小圆-->
+                <div class="center-letter" fe-role="Widget">
+                    <img class="sector" src="http://gtms03.alicdn.com/tps/i3/TB1oCKEJXXXXXc8XXXXszjdGpXX-140-140.png">
+                    <span>K</span>
+                </div>
+                <!--左上角四分之一圆-->
+                <div class="zone top-left" fe-role="Widget">
+                    <img class="sector" src="http://gtms03.alicdn.com/tps/i3/TB1DvCdJXXXXXbVapXXszjdGpXX-140-140.png">
+                    <span>5</span>
+                </div>
+                <!--右上角四分之一圆-->
+                <div class="zone top-right" fe-role="Widget">
+                    <img class="sector" src="http://gtms02.alicdn.com/tps/i2/TB1vfesJXXXXXXtXVXXszjdGpXX-140-140.png">
+                    <span>L</span>
+                </div>
+                <!--左下角四分之一圆-->
+                <div class="zone down-left" fe-role="Widget">
+                    <img class="sector" src="http://gtms01.alicdn.com/tps/i1/TB1Gp9hJXXXXXXpapXXszjdGpXX-140-140.png">
+                    <span>J</span>
+                </div>
+                <!--右下角四分之一圆-->
+                <div class="zone down-right" fe-role="Widget">
+                    <img class="sector"src="http://gtms04.alicdn.com/tps/i4/TB1yViuJXXXXXb1XFXXszjdGpXX-140-140.png">
+                    <span></span>
+                </div>
+            </div>
+            <!--按键列表 12宫格-->
+            <ul id="search-key-list" class="key-list" fe-cfg="default_focus:yes" fe-role="Switch">
+                <li class="_item key" id="key1" fe-role="Widget" data-key-value="1">
+                    <div class="digit">1</div>
+                </li>
+                <li class="_item key" id="key2" fe-role="Widget" data-key-value="2">
+                    <div class="digit">2</div>
+                    <div class="letter">ABC</div>
+                </li>
+                <li class="_item key" id="key3" fe-role="Widget" data-key-value="3">
+                    <div class="digit">3</div>
+                    <div class="letter">DEF</div>
+                </li>
+                <li class="_item key" id="key4" fe-role="Widget" data-key-value="4">
+                    <div class="digit">4</div>
+                    <div class="letter">GHI</div>
+                </li>
+                <li class="_item key" id="key5" fe-role="Widget" fe-cfg="default_focus:yes" data-key-value="5">
+                    <div class="digit">5</div>
+                    <div class="letter">JKL</div>
+                </li>
+                <li class="_item key" id="key6" fe-role="Widget" data-key-value="6">
+                    <div class="digit">6</div>
+                    <div class="letter">MNO</div>
+                </li>
+                <li class="_item key" id="key7" fe-role="Widget" data-key-value="7">
+                    <div class="digit">7</div>
+                    <div class="letter">PQRS</div>
+                </li>
+                <li class="_item key" id="key8" fe-role="Widget" data-key-value="8">
+                    <div class="digit">8</div>
+                    <div class="letter">TUV</div>
+                </li>
+                <li class="_item key" id="key9" fe-role="Widget" data-key-value="9">
+                    <div class="digit">9</div>
+                    <div class="letter">WXYZ</div>
+                </li>
+                <!--清空-->
+                <li class="_item key" id="key10" fe-role="Widget" data-key-value="clear">
+                    <img src="http://gtms04.alicdn.com/tps/i4/TB1vyuFJXXXXXbrXXXXGQA0HXXX-52-51.png" alt="" />
+                    <div>清空</div>
+                </li>
+                <!--数字0-->
+                <li class="_item key" id="key11" fe-role="Widget" data-key-value="0">
+                    <div class="digit">0</div>
+                </li>
+                <!--退格-->
+                <li class="_item key" id="key12" fe-role="Widget" data-key-value="delete">
+                    <img src="http://gtms03.alicdn.com/tps/i3/TB1b9qtJXXXXXczXFXXs2llIXXX-64-51.png" alt="" />
+                    <div>退格</div>
+                </li>
+            </ul>
+        </div>`;
+
+const mPanelMap = {
+    "2": {
+        center: 'B',
+        up: '2',
+        right: 'C',
+        left: 'A',
+        down: '',
+    },
+    "3": {
+        center: 'E',
+        up: '3',
+        right: 'F',
+        left: 'D',
+        down: '',
+    },
+    "4": {
+        center: 'H',
+        up: '4',
+        right: 'I',
+        left: 'G',
+        down: '',
+    },
+    "5": {
+        center: 'K',
+        up: '5',
+        right: 'L',
+        left: 'J',
+        down: '',
+    },
+    "6": {
+        center: 'N',
+        up: '6',
+        right: 'O',
+        left: 'M',
+        down: '',
+    },
+    "7": {
+        center: 'Q',
+        up: '7',
+        right: 'R',
+        left: 'P',
+        down: 'S',
+    },
+    "8": {
+        center: 'U',
+        up: '8',
+        right: 'V',
+        left: 'T',
+        down: '',
+    },
+    "9": {
+        center: 'X',
+        up: '9',
+        right: 'Y',
+        left: 'W',
+        down: 'Z',
+    }
+};
+
+
+class KeyboardPanel {
+
+    // 用来注册接收按键消息
+    keyDown(e) {
+        var keycode = e.which;
+        this.onKeyDown(keycode);
+    }
+
+    constructor() {
+        this.mKeyPanelHtml = mKeyPanelHtml;
+        this.mPanelMap = mPanelMap;
+
+        this.DATA_KEY_VALUE = "data-key-value";
+        this.DATA_KEY_INDEX = "data-key-index";
+        this.mSearchPopupDOM; // 弹出的字母选择盘DOM
+        this.mSearchKeyListDOM; // 键盘
+        this.mSearchPanelDOM; // 整体键盘
+        this.mSearchKeyFocusedWidget; // 弹出键盘之前选中的key值
+        this.mSearchPopupWidth; // 弹出字母选择盘的宽度
+        this.mSearchPopupHeight; // 弹出字母选择盘的高度
+        this.mSearchPopupCenterDOM; // 弹出中间的DOM
+        this.mSearchPopupUpDOM; // 弹出上边的DOM
+        this.mSearchPopupDownDOM; // 弹出下边的DOM
+        this.mSearchPopupLeftDOM; // 弹出左边的DOM
+        this.mSearchPopupRightDOM; // 弹出右边的DOM
+        this.mRenderFunction; // 重新布局focus节点
+        this.mLetterChangedFunction; // 字符变化的回调
+        this.mRoot; // ATV focus框架
+        this.mSearchInputDOM; // 输入的字符内容
+        this.mCurrentFocusItem = null; // 当前focus的节点ID
+
+        document.addEventListener("keydown", this.keyDown.bind(this), false);
+    }
+
+    init(containerId) {
+        var container = document.getElementById(containerId);
+        container.innerHTML = this.mKeyPanelHtml;
+        this.mSearchInputDOM = document.getElementById("j-search-panel-tip");
+        this.mSearchKeyListDOM = document.getElementById("search-key-list");
+        this.initSearchPopup();
+        if (this.mRenderFunction) {
+            this.mRoot = this.mRenderFunction();
+        }
+        this.initKeyList();
+    }
+
+    setRenderListener(listener) {
+        this.mRenderFunction = listener;
+    }
+
+    setLetterChangedListener(listener) {
+        this.mLetterChangedFunction = listener;
+    }
+
+    initKeyList() {
+        var keyListDOM = this.mSearchKeyListDOM.children;
+        var length = keyListDOM.length;
+        var widgetItem;
+        var self = this;
+        var keyDOM;
+        var keyData;
+        for (var i = 0; i < length; i++) {
+            keyDOM = keyListDOM[i];
+            // 设置监听方法
+            widgetItem = this.mRoot.getWidgetById(keyDOM.id);
+            if (widgetItem) {
+                widgetItem.on('focus', function (e) {
+                    var itemDOM = e.target.getDOMNode();
+                    //console.log("initKeyList focus="+itemDOM.id+" mCurrentFocusItem="+self.mCurrentFocusItem);
+                    self.mCurrentFocusItem = itemDOM.id;
+                    self.onKeyItemFocusChanged(itemDOM, true);
+                });
+                widgetItem.on('blur', function (e) {
+                    var itemDOM = e.target.getDOMNode();
+                    self.mCurrentFocusItem = null;
+                    self.onKeyItemFocusChanged(itemDOM, false);
+                });
+                widgetItem.on('ok', function (e) {
+                    var itemDOM = e.target.getDOMNode();
+                    self.onKeyItemOnClick(itemDOM);
+                });
+            }
+        }
+    }
+
+    onKeyItemFocusChanged(focusItemDOM, focused) {
+        //console.log("onKeyItemFocusChanged focusItemDOM="+focusItemDOM.id+" focused="+focused);
+    }
+
+    onKeyItemOnClick(clickItemDOM) {
+        //console.log("onKeyItemOnClick clickItemDOMff="+clickItemDOM.id);
+        var keyValue = clickItemDOM.getAttribute(this.DATA_KEY_VALUE);
+
+        if (keyValue == '0' || keyValue == '1') {
+            this.inputLetter(keyValue);
+        } else if (keyValue == 'clear') {
+            this.clearLetter();
+        } else if (keyValue == 'delete') {
+            this.deleteLetter();
+        } else {
+            this.showSearchPopup(clickItemDOM, this.mPanelMap[keyValue]);
+        }
+    }
+
+
+    inputLetter(letter) {
+        //console.log("inputLetter key="+ letter);
+        this.mSearchInputDOM.innerHTML += letter;
+        if (this.mLetterChangedFunction) {
+            this.mLetterChangedFunction(this.mSearchInputDOM.innerHTML);
+        }
+    }
+
+    clearLetter() {
+        //console.log("clearLetter");
+        this.mSearchInputDOM.innerHTML = "";
+        if (this.mLetterChangedFunction) {
+            this.mLetterChangedFunction("");
+        }
+    }
+
+    deleteLetter() {
+        //console.log("deleteLetter");
+        var letters = this.mSearchInputDOM.innerHTML;
+        letters = letters.slice(0, -1);
+        this.mSearchInputDOM.innerHTML = letters;
+        if (this.mLetterChangedFunction) {
+            this.mLetterChangedFunction(letters);
+        }
+    }
+
+    initSearchPopup() {
+        //console.log("initSearchPopup");
+        // 默认删除弹出盘
+        this.mSearchPopupDOM = document.getElementById("search-panel-popup");
+        this.mSearchPopupWidth = parseInt(window.getComputedStyle(this.mSearchPopupDOM).width);
+        this.mSearchPopupHeight = parseInt(window.getComputedStyle(this.mSearchPopupDOM).height);
+        this.mSearchPanelDOM = this.mSearchPopupDOM.parentNode;
+
+        // DOM顺序:center,up,right,left,down
+        var popupDOMList = this.mSearchPopupDOM.children;
+        this.mSearchPopupCenterDOM = popupDOMList[0];
+        this.mSearchPopupUpDOM = popupDOMList[1];
+        this.mSearchPopupRightDOM = popupDOMList[2];
+        this.mSearchPopupLeftDOM = popupDOMList[3];
+        this.mSearchPopupDownDOM = popupDOMList[4];
+
+        this.mSearchPanelDOM.removeChild(this.mSearchPopupDOM);
+
+    }
+
+    showSearchPopup(focusItemDOM, letter) {
+        // 判断是否已经显示
+        if (!this.mSearchPopupDOM.parentNode) {
+            this.mSearchKeyFocusedWidget = this.mRoot.getFocusedLeaf();
+
+
+            this.resetSearchPopupPos(focusItemDOM);
+            this.setSearchPopupLetter(letter);
+            //console.log('this.mSearchPopupDOM:',this.mSearchPanelDOM,this.mSearchPopupDOM); 
+            this.mSearchPanelDOM.appendChild(this.mSearchPopupDOM);
+            if (this.mRenderFunction) {
+
+                this.mRenderFunction();
+            }
+
+            this.setSearchPopupFocused();
+            var item = this.mRoot.getWidgetById(this.mSearchPopupDOM.id);
+            item.focus();
+        }
+    }
+
+    hideSearchPopup() {
+        // 判断是否已经隐藏
+        if (this.mSearchPopupDOM.parentNode) {
+            this.mSearchPanelDOM.removeChild(this.mSearchPopupDOM);
+            if (this.mSearchKeyFocusedWidget) {
+                this.mSearchKeyFocusedWidget.focus();
+            }
+        }
+        if (this.mRenderFunction) {
+            this.mRenderFunction();
+        }
+    }
+
+    setSearchPopupLetter(letter) {
+        // center
+        this.setSearchPopupItemDOM(this.mSearchPopupCenterDOM, letter.center);
+
+        // up
+        this.setSearchPopupItemDOM(this.mSearchPopupUpDOM, letter.up);
+
+        // right
+        this.setSearchPopupItemDOM(this.mSearchPopupRightDOM, letter.right);
+
+        // left
+        this.setSearchPopupItemDOM(this.mSearchPopupLeftDOM, letter.left);
+
+        // down
+        this.setSearchPopupItemDOM(this.mSearchPopupDownDOM, letter.down);
+    }
+
+    setSearchPopupItemDOM(itemDOM, letter) {
+        var childDOM = itemDOM.children[1]; // 指定显示字符的节点
+        childDOM.innerHTML = "" + letter;
+    }
+
+    setSearchPopupFocused() {
+        var itemDOMList = this.mSearchPopupDOM.children;
+        var length = itemDOMList.length;
+        var self = this;
+        var widgetItem;
+        for (var i = 0; i < length; i++) {
+            widgetItem = this.mRoot.getWidgetById(itemDOMList[i].id);
+            widgetItem.on('focus', function (e) {
+                var itemDOM = e.target.getDOMNode();
+                //console.log("setSearchPopupFocused focus="+itemDOM.id+" mCurrentFocusItem="+self.mCurrentFocusItem);
+                if (self.mCurrentFocusItem == itemDOM.id) {
+                    return;
+                }
+                self.mCurrentFocusItem = itemDOM.id;
+                // 只要不是中间键值就直接输入字符,因为中间键是由OK键来确认的
+                if (itemDOM.id != self.mSearchPopupCenterDOM.id) {
+                    var childDOM = itemDOM.children[1]; // 指定显示字符的节点
+                    self.inputLetter(childDOM.innerHTML);
+                    setTimeout(function () {
+                        self.hideSearchPopup();
+                    }, 300);
+                }
+            });
+        }
+
+        // 默认选中间
+        widgetItem = this.mRoot.getWidgetById(this.mSearchPopupCenterDOM.id);
+        widgetItem.focus();
+        // 中间字符由OK键来确认
+        widgetItem.on('ok', function (e) {
+            var itemDOM = e.target.getDOMNode();
+            var childDOM = itemDOM.children[1]; // 指定显示字符的节点
+            self.inputLetter(childDOM.innerHTML);
+            self.hideSearchPopup();
+        });
+    }
+
+    resetSearchPopupPos(focusItemDOM) {
+        var left = focusItemDOM.getBoundingClientRect().left + (focusItemDOM.getBoundingClientRect().width) / 2;
+        var top = focusItemDOM.getBoundingClientRect().top + (focusItemDOM.getBoundingClientRect().height) / 2;
+        left -= this.mSearchPopupWidth / 2 + this.mSearchPanelDOM.getBoundingClientRect().left;
+        top -= this.mSearchPopupHeight / 2 + this.mSearchPanelDOM.getBoundingClientRect().top;
+        this.mSearchPopupDOM.style.left = left + "px";
+        this.mSearchPopupDOM.style.top = top + "px";
+    }
+
+    onKeyDown(keyCode) {
+        //console.log("onKeyDown keyCode="+keyCode);
+        if (keyCode == 27) {
+            this.hideSearchPopup();
+        }
+    }
+}
+
+module.exports = KeyboardPanel;

+ 195 - 0
src/component/Swiper.js

@@ -0,0 +1,195 @@
+class Swiper {
+	constructor(ElID, imgArr, d, width, height) {
+		/*以下最外层div*/
+		var that = this;
+		this.duration = d;
+		this.width = width;
+		this.height = height;
+		this.oBox = document.getElementById(ElID);
+		this.oBox.style.width = width;
+		this.oBox.style.height = height;
+		this.oBox.style.overflow = 'hidden';
+		this.oBox.style.position = 'relative';
+		/*以下轮播区的div*/
+		this.oBoxInner = this.oBox.getElementsByTagName('div')[0];
+		this.oBoxInner.style.height = height;
+		this.oBoxInner.style.position = 'absolute';
+		this.oBoxInner.style.left = 0;
+		this.oBoxInner.style.right = 0;
+		this.step = 0; //记录每次运动
+		this.timer = null; //定时器
+		this.init(); //初始化轮播图
+		/*渲染dom*/
+		for (let i = 0; i < imgArr.length; i++) {
+			let imgWrapper = document.createElement('div');
+			let img = document.createElement('img');
+			img.src = imgArr[i];
+			imgWrapper.appendChild(img);
+			that.oBoxInner.appendChild(imgWrapper);
+		}
+		this.aDiv = this.oBoxInner.getElementsByTagName('div'); //单个轮播图
+		this.oBoxInner.innerHTML /* 轮播区的内部后面*/ += this.aDiv[0].outerHTML /*第一个轮播图片的外部*/ ;
+		this.oBoxInner.style.width = parseFloat(width) * this.aDiv.length + 'px'; //轮播区的宽度
+		for (var i = 0; i < this.aDiv.length; i++) { /*遍历轮播区的每个div及其内部的图片*/
+			this.aDiv[i].style.width = width;
+			this.aDiv[i].style.height = height;
+			this.aDiv[i].style.float = 'left';
+			this.aDiv[i].aImg = this.aDiv[i].getElementsByTagName('img')[0];
+			this.aDiv[i].aImg.style.width = '100%';
+			this.aDiv[i].aImg.style.height = '100%';
+		}
+		// 小圆点
+		this.dotWrapper = document.createElement('div');
+		this.dotWrapper.style.position = 'absolute';
+		this.dotWrapper.style.height = '0.20rem';
+		this.dotWrapper.style.bottom = '0.20rem';
+		this.dotWrapper.style.left = '0';
+		this.dotWrapper.style.right = '0';
+		this.dotWrapper.style.textAlign = 'center';
+		for (let i = 0; i < imgArr.length; i++) {
+			let dotItem = document.createElement('div')
+			dotItem.style.width = "0.20rem";
+			dotItem.style.height = "0.20rem";
+			dotItem.style.display = "inline-block";
+			dotItem.style.background = "#333";
+			dotItem.style.borderRadius = "50%";
+			dotItem.style.marginLeft = "0.05rem";
+			dotItem.style.marginRight = "0.05rem";
+			dotItem.style.opacity = ".6";
+			this.dotWrapper.appendChild(dotItem)
+		}
+		this.dotArr = this.dotWrapper.getElementsByTagName('div');
+		this.dotArr[0].style.background = "red";
+		this.oBox.appendChild(this.dotWrapper)
+	}
+	// 轮播图小圆点  
+	bannerTip() {
+		if( !this.dotArr ) { console.log(this.dotArr); return;}
+		var tmpStep = this.step >= this.dotArr.length ? 0 : this.step;    
+		for (var i = 0; i < this.dotArr.length; i++) {      
+			this.dotArr[i].className = i === tmpStep ? 'on' : null;      
+			if (this.dotArr[i].className === "on") {        
+				this.dotArr[i].style.background = "red";      
+			} else {        
+				this.dotArr[i].style.background = "#333";      
+			}    
+		}  
+	}
+
+	/*getCss:获取元素的属性值*/
+	getCss(curEle, attr) {
+		var val = null;
+		var reg = null;
+		if (getComputedStyle) { //标准浏览器
+			val = getComputedStyle(curEle, false)[attr];
+		} else { //非标准浏览器
+			if (attr === 'opacity') {
+				val = curEle.currentStyle.filter; //'alpha(opacity=10)'
+				reg = /^alpha\(opacity[=:](\d+)\)$/i;
+				return reg.test(val) ? reg.exec(val)[1] / 100 : 1;
+			}
+			val = curEle.currentStyle[attr];
+		}
+		reg = /^[+-]?((\d|([1-9]\d+))(\.\d+)?)(px|pt|rem|em)$/i;
+		return reg.test(val) ? parseInt(val) : val;
+	}
+
+	/*setCss:设置元素的属性值*/
+	setCss(curEle, attr, value) {
+		if (attr === 'float') {
+			curEle.style.cssFloat = value;
+			curEle.style.styleFloat = value;
+			return;
+		}
+		if (attr === 'opacity') {
+			curEle.style.opacity = value;
+			curEle.style.filter = 'alpha(opacity=' + (value * 100) + ')';
+			return;
+		}
+		var reg = /^(width|height|top|right|bottom|left|((margin|padding)(top|right|bottom|left)?))$/i;
+		if (reg.test(attr)) {
+			if (!(value === 'auto' || value.toString().indexOf('%') !== -1)) {
+				value = parseFloat(value) + 'px';
+			}
+		}
+		curEle.style[attr] = value;
+	}
+
+	/*setGroupCss:设置元素的一组属性值*/
+	setGroupCss(curEle, options) {
+		if (options.toString() !== '[object Object]') return;
+		for (var attr in options) {
+			this.setCss(curEle, attr, options[attr]);
+		}
+	}
+
+	/*css:getCss、setCss、setGroupCss的合写*/
+	css() {
+		if (typeof arguments[1] === 'string') {
+			if (typeof arguments[2] === 'undefined') {
+				return this.getCss(arguments[0], arguments[1]); //当第三个参数不存在,是获取;
+			} else {
+				this.setCss(arguments[0], arguments[1], arguments[2]); //当第三个参数存在时,是设置;
+			}
+		}
+		if (arguments[1].toString() === '[object Object]') {
+			this.setGroupCss(arguments[0], arguments[1]); //设置元素的一组属性值
+		}
+	}
+
+	/*animate:轮播图动画函数*/
+	animate(curEle, target, duration) {
+		/*1.定义动画的运行轨迹*/
+		function tmpEffect(t, b, c, d) {
+			return b + c / d * t; //开始时的位置+总变化/总时间*已经过去的时间
+		}
+		/*2.为公式的每个参数做准备*/
+		var begin = {};
+		var change = {};
+		for (var attr in target) {
+			begin[attr] = this.css(curEle, attr);
+			change[attr] = target[attr] - begin[attr];
+		}
+		duration = duration || 700;
+		var time = 0;
+		var that = this;
+		/*3.开启一个定时器,让时间不断累加;根据时间和公式,求出最新的位置;*/
+		clearInterval(curEle.timer); //开起一个定时器前,先关闭没用的定时器
+		curEle.timer = setInterval(function () {
+			time += 10;
+			/*4.定时器停止运动的条件(time>=duration)*/
+			if (time >= duration) {
+				that.css(curEle, target);
+				clearInterval(curEle.timer);
+				return;
+			}
+			/*5.拿到每个属性的最新值,并且赋值给元素对应的属性;*/
+			for (var attr in target) {
+				var curPos = tmpEffect(time, begin[attr], change[attr], duration);
+				that.css(curEle, attr, curPos);
+			}
+		}, 10);
+	}
+	/*初始化轮播图*/
+	init() {
+		var _this = this;
+		this.timer = setInterval(function () {
+			_this.autoMove();
+		}, _this.duration);
+		this.bannerTip();
+	}
+
+	autoMove() {
+		if (this.step >= this.aDiv.length - 1) {
+			this.step = 0;
+			this.css(this.oBoxInner, 'left', 0);
+		}
+		this.step++;
+		this.animate(this.oBoxInner, {
+			left: -this.step * parseFloat(this.width)
+		}, 700);
+		this.bannerTip();
+	}
+}
+
+module.exports = Swiper;

+ 34 - 0
src/component/recommend.js

@@ -0,0 +1,34 @@
+class RecommendItem {
+	constructor (){}
+
+	static createHTMLString(data){
+		function convertClickCount(num) {
+			if (isNaN(num)) {
+				return 0;
+			}
+			if (num < 10000) {
+				return num;
+			}else{
+				let temp_num = num / 10000;
+				return Math.round(temp_num * Math.pow(10, 1) ) / Math.pow(10, 1) + '万';
+			}
+		}
+		return `<div class="recommend-item-frame">
+					<div class="recommend-cover">
+						<img src="${data.showImg ? data.showImg : ''}" alt="">
+						<div class="recommend-des">
+							<div class="recommend-text">
+								<div class="subject">${data.name}</div>
+								<div class="hits">
+									<img src="http://iptvtest.efunbox.cn:8000/yunos/age/topic/people.png">
+									${data.clickNum}
+								</div>
+							</div>
+							<p class="subject-sub">${data.summary}</p>
+						</div>
+					</div>
+				</div>`;
+	}
+}
+
+module.exports = RecommendItem;

+ 144 - 0
src/lib/css/base.css

@@ -0,0 +1,144 @@
+/** 清除内外边距 **/
+body,
+div,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+hr,
+p,
+blockquote,
+dl,
+dt,
+dd,
+ul,
+ol,
+li,
+pre,
+form,
+fieldset,
+legend,
+button,
+input,
+textarea,
+th,
+td {
+  margin: 0;
+  padding: 0;
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box;
+}
+/** 设置默认字体 **/
+body,
+button,
+input,
+select,
+textarea {
+  font: 12px/1.5 tahoma, arial, 'Heiti SC', '微软雅黑', sans-serif;
+}
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+  font-size: 100%;
+}
+address,
+cite,
+dfn,
+em,
+var {
+  font-style: normal;
+}
+/* 将斜体扶正 */
+code,
+kbd,
+pre,
+samp {
+  font-family: courier new, courier, monospace;
+}
+/* 统一等宽字体 */
+small {
+  font-size: 12px;
+}
+/* 小于 12px 的中文很难阅读,让 small 正常化 */
+/** 重置列表元素 **/
+ul,
+ol {
+  list-style: none;
+}
+/** 重置文本格式元素 **/
+a {
+  text-decoration: none;
+  color: #000;
+}
+a:hover {
+  text-decoration: underline;
+}
+sup {
+  vertical-align: text-top;
+}
+/* 重置,减少对行高的影响 */
+sub {
+  vertical-align: text-bottom;
+}
+/** 重置表单元素 **/
+legend {
+  color: #000;
+}
+/* for ie6 */
+fieldset,
+img {
+  border: 0;
+}
+/* img 搭车:让链接里的 img 无边框 */
+img {
+  vertical-align: bottom;
+}
+button,
+input,
+select,
+textarea {
+  font-size: 100%;
+}
+/* 使得表单元素在 ie 下能继承字体大小 */
+/* 注:optgroup 无法扶正 */
+/** 重置表格元素 **/
+table {
+  border-collapse: collapse;
+  border-spacing: 0;
+}
+/* 重置 HTML5 元素 */
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+menu,
+nav,
+section,
+summary,
+time,
+mark,
+audio,
+video {
+  display: block;
+  margin: 0;
+  padding: 0;
+}
+mark {
+  background: #ff0;
+}
+/* End hide from IE-mac */
+body {
+  font: 12px/1.5 tahoma, arial, 'Heiti SC', 'Microsoft Yahei', sans-serif;
+}
+html body {
+  width: 100%;
+}

+ 229 - 0
src/lib/css/keyPanel.css

@@ -0,0 +1,229 @@
+.sector{
+  opacity: 0;
+  width: 100%;
+  height: 100%;
+  /*width: 1.448rem;
+  height: 1.448rem;*/
+  float: left;
+}
+
+._item.fe-focus {
+  /*background-color: rgb(76, 172, 222);
+  border-radius: 70px;*/
+  background-image: url(http://gtms03.alicdn.com/tps/i3/TB1eAWKJXXXXXXwXXXXszjdGpXX-140-140.png);
+  background-size: 1.447rem 1.447rem;
+  background-repeat: no-repeat;
+  border-color: transparent;
+  /*
+  box-shadow: 0 5px 5px rgba(0, 0, 0, 0.5);
+  */
+}
+
+.key-input-panel {
+  height: 1.334rem;
+}
+
+.key-input-frame {
+  width: 5.1rem;
+  height: 0.77rem;
+  line-height: 0.77rem;
+  margin: 0 auto;
+  border-radius: .5rem;
+  background: white;
+}
+
+.key-input-panel .search-icon {
+  width: .39rem;
+  height: .4rem;
+  margin: .2rem .2rem 0 0;
+  float: right;
+}
+
+#j-search-panel-tip {
+  font-size: .5rem;
+  height: 100%;
+  width: 4.5rem;
+  float: left;
+  text-align: center;
+  overflow: hidden;
+}
+
+.key-panel {
+  height: 7.812rem;
+  position: relative;
+}
+.key-panel ul {
+  /*border-top: .005rem solid rgba(255, 255, 255, 0.5);*/
+  padding-top: .332rem;
+  margin: 0 auto;
+  width: 5.1rem;
+  overflow: hidden;
+  /*最右侧的margin-right = 0*/
+  /*delete back*/
+}
+.key-panel ul li {
+  width: 1.458rem;
+  height: 1.458rem;
+  text-align: center;
+  float: left;
+  margin-top: .425rem;
+  margin-right: .351rem;
+  color: #fff;
+  border: solid 1px #929bab;
+  border-radius: 2rem;
+}
+.key-panel ul li .digit {
+  font-size: .625rem;
+  opacity: 0.5;
+}
+.key-panel ul li.fe-focus .digit {
+  font-size: .625rem;
+  opacity: 1;
+}
+.key-panel ul li .letter {
+  margin-top: -0.2rem;
+  font-size: .338rem;
+}
+.key-panel ul #key1,
+.key-panel ul #key2,
+.key-panel ul #key3 {
+  margin-top: 0;
+}
+.key-panel ul #key7,
+.key-panel ul #key8,
+.key-panel ul #key9 {
+  /*margin-top: .646rem;
+  */
+  margin-top: .351rem;
+}
+.key-panel ul #key3,
+.key-panel ul #key6,
+.key-panel ul #key9,
+.key-panel ul #key12 {
+  margin-right: 0;
+}
+.key-panel ul #key10,
+.key-panel ul #key12 {
+  text-align: center;
+  font-size: .333rem;
+}
+.key-panel ul #key10 img,
+.key-panel ul #key12 img {
+  width: .5rem;
+  height: .396rem;
+  position: relative;
+  top: .271rem;
+}
+.key-panel ul #key10 div,
+.key-panel ul #key12 div {
+  position: relative;
+  top: .312rem;
+  opacity: 0.5;
+  font-size: .333rem;
+}
+.search-popup {
+  position: absolute;
+  top: .677rem;
+  left: .948rem;
+  /*background-color: #615e5e;*/
+  width: 2.916rem;
+  height: 2.916rem;
+  border-radius: 1.458rem;
+  -webkit-transform: rotate(45deg);
+          transform: rotate(45deg);
+  box-shadow: .0521rem .0521rem .0521rem rgba(0, 0, 0, 0.5);
+  background-image: url(http://gtms01.alicdn.com/tps/i1/TB1V01sJXXXXXXGXVXX4_MlUFXX-280-280.png);
+  background-size: 2.916rem 2.916rem;
+  background-repeat: no-repeat;
+  overflow: hidden;
+}
+.search-popup .fe-focus img{
+    opacity: 1;
+  }
+.search-popup .center-letter {
+  width: 1.4584rem;
+  height: 1.4584rem;
+  text-align: center;
+  line-height: 1.4584rem;
+  background-color: rgb(55, 55, 55);
+  margin-top: -.7292rem;
+  position: absolute;
+  top: 50%;
+  margin-left: .7188rem;
+  border-radius: .7192rem;
+  box-shadow: .026rem .026rem .026rem rgba(0, 0, 0, 0.5);
+  background-image: url(http://gtms02.alicdn.com/tps/i2/TB1m0eDJXXXXXXYXpXXszjdGpXX-140-140.png);
+  background-size: 1.4584rem 1.4584rem;
+  background-repeat: no-repeat;
+  z-index: 100;
+}
+.search-popup .center-letter span {
+  font-size: .438rem;
+  color: #fff;
+  /*position: relative;*/
+  position: absolute;
+  top: 0px;
+  left: .562rem;
+  -webkit-transform: rotate(-45deg);
+          transform: rotate(-45deg);
+}
+.search-popup .zone {
+  position: relative;
+  /*width: 1.448rem;
+  height: 1.448rem;*/
+  width: 1.348rem;
+  height: 1.348rem;
+  float: left;
+}
+.search-popup .zone span {
+  font-size: .438rem;
+  color: #fff;
+  /*position: relative;*/
+  position: absolute;
+  -webkit-transform: rotate(-45deg);
+          transform: rotate(-45deg);
+}
+.search-popup .zone.top-left {
+  margin: 0;
+  /*border-right: .006rem rgba(255, 255, 255, 0.2) solid;
+  border-bottom: .006rem rgba(255, 255, 255, 0.2) solid;*/
+}
+.search-popup .zone.top-left span {
+  position: absolute;
+  top: .42rem;
+  left: .572rem;
+}
+.search-popup .zone.top-right {
+  /*border-left: .006rem rgba(255, 255, 255, 0.2) solid;
+  border-bottom: .006rem rgba(255, 255, 255, 0.2) solid;*/
+  margin-left: 0.2rem;
+  /*background-position: -140px 0;*/
+}
+.search-popup .zone.top-right span {
+  position: absolute;
+  top: .42rem;
+  left: .572rem;
+}
+.search-popup .zone.down-left {
+  /*border-top: .006rem rgba(255, 255, 255, 0.2) solid;
+  border-right: .006rem rgba(255, 255, 255, 0.2) solid;*/
+  margin-top: 0.2rem;
+  /*background-position: 0 -140px;*/
+}
+.search-popup .zone.down-left span {
+  position: absolute;
+  top: .35rem;
+  left: .55rem;
+}
+.search-popup .zone.down-right {
+  /*border-top: .006rem rgba(255, 255, 255, 0.2) solid;
+  border-left: .006rem rgba(255, 255, 255, 0.2) solid;*/
+  margin-top: 0.2rem;
+  margin-left: 0.2rem;
+  /*background-position: -140px -140px;*/
+}
+.search-popup .zone.down-right span {
+  position: absolute;
+  top: .42rem;
+  left: .572rem;
+}

+ 45 - 0
src/lib/css/marquee.css

@@ -0,0 +1,45 @@
+.ef_marquee {
+    overflow: hidden;
+    position: relative;
+    height: 100%;
+}
+
+.ef_marquee p {
+    position: absolute;
+    /*width: 100%;*/
+    height: 100%;
+    margin: 0;
+    text-align: center;
+     /* Starting position */
+    /*-moz-transform:translateX(100%);
+    -webkit-transform:translateX(100%);	
+    transform:translateX(100%);*/
+    /* Apply animation to this element */	
+    /*-moz-animation: ef-marquee-scroll-left 18s linear infinite;
+    -webkit-animation: ef-marquee-scroll-left 18s linear infinite;
+    animation: ef-marquee-scroll-left 18s linear infinite;*/
+}
+
+/* Move it (define the animation) 
+@-moz-keyframes ef-marquee-scroll-left {
+    0%   { -moz-transform: translateX(100%); }
+    100% { -moz-transform: translateX(-100%); }
+}
+@-webkit-keyframes ef-marquee-scroll-left {
+    0%   { -webkit-transform: translateX(100%); }
+    100% { -webkit-transform: translateX(-100%); }
+}
+@keyframes ef-marquee-scroll-left {
+    0%   { 
+    -moz-transform: translateX(100%); 
+    -webkit-transform: translateX(100%); 
+    transform: translateX(100%); 		
+    }
+    100% { 
+    -moz-transform: translateX(-100%); 
+    -webkit-transform: translateX(-100%); 
+    transform: translateX(-100%); 
+    }
+}
+
+*/

File diff suppressed because it is too large
+ 3763 - 0
src/lib/js/FocusEngine.js


File diff suppressed because it is too large
+ 8 - 0
src/lib/js/FocusEngine.min.js


File diff suppressed because it is too large
+ 8 - 0
src/lib/js/TVUtil.min.js


File diff suppressed because it is too large
+ 477 - 0
src/lib/js/alitv-debug.js


File diff suppressed because it is too large
+ 1 - 0
src/lib/js/alitv-debug.min.js


+ 884 - 0
src/lib/js/animate_marquee.js

@@ -0,0 +1,884 @@
+window.yunos_animation = (function ($) {
+    var Tween_Algorithm = {
+        Linear: {
+            easeIn: function (t, b, c, d) {
+                return c * t / d + b;
+            },
+            easeOut: function (t, b, c, d) {
+                return c * t / d + b;
+            },
+            easeInOut: function (t, b, c, d) {
+                return c * t / d + b;
+            }
+        },
+        Quad: {
+            easeIn: function (t, b, c, d) {
+                return c * (t /= d) * t + b;
+            },
+            easeOut: function (t, b, c, d) {
+                return -c * (t /= d) * (t - 2) + b;
+            },
+            easeInOut: function (t, b, c, d) {
+                if ((t /= d / 2) < 1) return c / 2 * t * t + b;
+                return -c / 2 * ((--t) * (t - 2) - 1) + b;
+            }
+        },
+        Cubic: {
+            easeIn: function (t, b, c, d) {
+                return c * (t /= d) * t * t + b;
+            },
+            easeOut: function (t, b, c, d) {
+                return c * ((t = t / d - 1) * t * t + 1) + b;
+            },
+            easeInOut: function (t, b, c, d) {
+                if ((t /= d / 2) < 1) return c / 2 * t * t * t + b;
+                return c / 2 * ((t -= 2) * t * t + 2) + b;
+            }
+        },
+        Quart: {
+            easeIn: function (t, b, c, d) {
+                return c * (t /= d) * t * t * t + b;
+            },
+            easeOut: function (t, b, c, d) {
+                return -c * ((t = t / d - 1) * t * t * t - 1) + b;
+            },
+            easeInOut: function (t, b, c, d) {
+                if ((t /= d / 2) < 1) return c / 2 * t * t * t * t + b;
+                return -c / 2 * ((t -= 2) * t * t * t - 2) + b;
+            }
+        },
+        Quint: {
+            easeIn: function (t, b, c, d) {
+                return c * (t /= d) * t * t * t * t + b;
+            },
+            easeOut: function (t, b, c, d) {
+                return c * ((t = t / d - 1) * t * t * t * t + 1) + b;
+            },
+            easeInOut: function (t, b, c, d) {
+                if ((t /= d / 2) < 1) return c / 2 * t * t * t * t * t + b;
+                return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;
+            }
+        },
+        Sine: {
+            easeIn: function (t, b, c, d) {
+                return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;
+            },
+            easeOut: function (t, b, c, d) {
+                return c * Math.sin(t / d * (Math.PI / 2)) + b;
+            },
+            easeInOut: function (t, b, c, d) {
+                return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;
+            }
+        },
+        Expo: {
+            easeIn: function (t, b, c, d) {
+                return (t == 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b;
+            },
+            easeOut: function (t, b, c, d) {
+                return (t == d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;
+            },
+            easeInOut: function (t, b, c, d) {
+                if (t == 0) return b;
+                if (t == d) return b + c;
+                if ((t /= d / 2) < 1) return c / 2 * Math.pow(2, 10 * (t - 1)) + b;
+                return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b;
+            }
+        },
+        Circ: {
+            easeIn: function (t, b, c, d) {
+                return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;
+            },
+            easeOut: function (t, b, c, d) {
+                return c * Math.sqrt(1 - (t = t / d - 1) * t) + b;
+            },
+            easeInOut: function (t, b, c, d) {
+                if ((t /= d / 2) < 1) return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b;
+                return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;
+            }
+        },
+        Elastic: {
+            easeIn: function (t, b, c, d, a, p) {
+                if (t == 0) return b;
+                if ((t /= d) == 1) return b + c;
+                if (!p) p = d * .3;
+                if (!a || a < Math.abs(c)) {
+                    a = c;
+                    var s = p / 4;
+                } else var s = p / (2 * Math.PI) * Math.asin(c / a);
+                return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
+            },
+            easeOut: function (t, b, c, d, a, p) {
+                if (t == 0) return b;
+                if ((t /= d) == 1) return b + c;
+                if (!p) p = d * .3;
+                if (!a || a < Math.abs(c)) {
+                    a = c;
+                    var s = p / 4;
+                } else var s = p / (2 * Math.PI) * Math.asin(c / a);
+                return (a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b);
+            },
+            easeInOut: function (t, b, c, d, a, p) {
+                if (t == 0) return b;
+                if ((t /= d / 2) == 2) return b + c;
+                if (!p) p = d * (.3 * 1.5);
+                if (!a || a < Math.abs(c)) {
+                    a = c;
+                    var s = p / 4;
+                } else var s = p / (2 * Math.PI) * Math.asin(c / a);
+                if (t < 1) return -.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
+                return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p) * .5 + c + b;
+            }
+        },
+        Back: {
+            easeIn: function (t, b, c, d, s) {
+                if (s == undefined) s = 1.70158;
+                return c * (t /= d) * t * ((s + 1) * t - s) + b;
+            },
+            easeOut: function (t, b, c, d, s) {
+                if (s == undefined) s = 1.70158;
+                return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;
+            },
+            easeInOut: function (t, b, c, d, s) {
+                if (s == undefined) s = 1.70158;
+                if ((t /= d / 2) < 1) return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b;
+                return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;
+            }
+        },
+        Bounce: {
+            easeIn: function (t, b, c, d) {
+                return c - Tween_Algorithm.Bounce.easeOut(d - t, 0, c, d) + b;
+            },
+            easeOut: function (t, b, c, d) {
+                if ((t /= d) < (1 / 2.75)) {
+                    return c * (7.5625 * t * t) + b;
+                } else if (t < (2 / 2.75)) {
+                    return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b;
+                } else if (t < (2.5 / 2.75)) {
+                    return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b;
+                } else {
+                    return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b;
+                }
+            },
+            easeInOut: function (t, b, c, d) {
+                if (t < d / 2) return Tween_Algorithm.Bounce.easeIn(t * 2, 0, c, d) * .5 + b;
+                else return Tween_Algorithm.Bounce.easeOut(t * 2 - d, 0, c, d) * .5 + c * .5 + b;
+            }
+        }
+    }
+    window.Tween = Tween_Algorithm;
+
+    var platform_webcore = false,
+        frameCounter = 0,
+        frameTimmer,
+        tickTimmer,
+        defaultMoveFunc = Tween_Algorithm['Sine']['easeOut'],
+        default_duration = 250,
+        defaultMode = 0,
+        frameAniList,
+        tickAniList,
+        timerList = [],
+        ANIMATE_INFO_KEY = 'animate_info';
+
+    function isNumber(n) {
+        return !isNaN(parseFloat(n)) && isFinite(n);
+    }
+
+    function arraySubtract(arr1, arr2) {
+        var retArray = [];
+        if (arr1 instanceof Array && arr2 instanceof Array) {
+            var len = arr1.length;
+            for (var i = 0; i < len; i++) {
+                retArray[i] = arr1[i] - arr2[i];
+            }
+        }
+
+        return retArray;
+    }
+
+    function _frameUpdate(curTime, frames) {
+        var i = 0,
+            aniNums = frames.length;
+
+        while (i < aniNums) {
+            //            var stime = Date.now();
+            var aniFrame = frames[i],
+                aniObj = aniFrame.aniObj,
+                domEle = aniObj._node,
+                st = aniFrame.st,
+                duration = aniFrame.duration;
+
+            if (!domEle || typeof duration === "undefined" || aniFrame.flag !== aniObj._flag || isNaN(duration) || aniObj._isStop) { //如果元素上有其他动画,则取消当前动画
+                frames.splice(i, 1);
+                aniNums--;
+                continue;
+            }
+
+            var offx = aniFrame.offx,
+                offy = aniFrame.offy,
+                offtx = aniFrame.offtx,
+                offty = aniFrame.offty,
+                offsx = aniFrame.offsx,
+                offsy = aniFrame.offsy,
+                offopt = aniFrame.offopt,
+                offw = aniFrame.offw,
+                offh = aniFrame.offh,
+                offdeg = aniFrame.offdeg;
+
+            if (curTime >= st + duration || aniObj._isEnd) {
+                if (offx) aniObj._left = aniObj._endLeft;
+                if (offy) aniObj._top = aniObj._endTop;
+                if (offtx) aniObj._transformX = aniObj._endTransformX;
+                if (offty) aniObj._transformY = aniObj._endTransformY;
+                if (offsx) aniObj._scaleX = aniObj._endScaleX;
+                if (offsy) aniObj._scaleY = aniObj._endScaleY;
+                if (offopt) aniObj._opacity = aniObj._endOpacity;
+                if (offw) aniObj._width = aniObj._endWidth;
+                if (offh) aniObj._height = aniObj._endHeight;
+                if (offdeg) aniObj._rotate = aniObj._endRotate;
+
+                if (offsx || offsy || offtx || offty) {
+                    var transtr = 'translate3d(' + aniObj._transformX + 'px, ' + aniObj._transformY + 'px, 0) scale3d(' + aniObj._scaleX + ', ' + aniObj._scaleY + ', 1)';
+                    domEle.style.webkitTransform = transtr;
+                    domEle.style.transform = transtr;
+                }
+                if (offx) domEle.style.left = aniObj._left + 'px';
+                if (offy) domEle.style.top = aniObj._top + 'px';
+                if (offopt) domEle.style.opacity = aniObj._opacity;
+                if (offw) domEle.style.width = aniObj._width + "px";
+                if (offh) domEle.style.height = aniObj._height + "px";
+
+                if(offdeg){
+                    var transtr = 'rotate(' + aniObj._rotate + 'deg)';
+                    domEle.style.webkitTransform = transtr;
+                    domEle.style.transform = transtr;
+                }
+
+                aniObj._isRunning = false;
+                if (aniFrame.complete) {
+                    aniFrame.complete.apply(aniObj, aniObj._endArgs);
+                }
+                frames.splice(i, 1);
+                aniNums--;
+                continue;
+            } else {
+                if (curTime < st) {
+                    aniFrame.st = curTime;
+                } else {
+                    var moveVal = aniFrame.moveFunc(curTime - st, 0, 1, duration);
+                    if (offtx) aniObj._transformX = aniFrame.btx + offtx * moveVal;
+                    if (offty) aniObj._transformY = aniFrame.bty + offty * moveVal;
+                    if (offsx) aniObj._scaleX = aniFrame.bsx + offsx * moveVal;
+                    if (offsy) aniObj._scaleY = aniFrame.bsx + offsy * moveVal;
+                    if (offtx || offty || offsx || offsy) {
+                        var transtr = 'translate3d(' + aniObj._transformX + 'px, ' + aniObj._transformY + 'px, 0) scale3d(' + aniObj._scaleX + ', ' + aniObj._scaleY + ', 1)';
+                        domEle.style.webkitTransform = transtr;
+                        domEle.style.transform = transtr;
+                    }
+                    if (offx) {
+                        aniObj._left = aniFrame.bx + offx * moveVal;
+                        domEle.style.left = aniObj._left + 'px';
+                    }
+                    if (offy) {
+                        aniObj._top = aniFrame.by + offy * moveVal;
+                        domEle.style.top = aniObj._top + 'px';
+                    }
+                    if (offopt) {
+                        aniObj._opacity = aniFrame.bopt + offopt * moveVal;
+                        domEle.style.opacity = aniObj._opacity;
+                    }
+                    if (offw) {
+                        aniObj._width = aniFrame.bw + offw * moveVal;
+                        domEle.style.width = aniObj._width + "px";
+                    }
+                    if (offh) {
+                        aniObj._height = aniFrame.bh + offh * moveVal;
+                        domEle.style.height = aniObj._height + "px";
+                    }
+
+                    if(offdeg){
+                        aniObj._rotate = aniFrame.bdeg + offdeg * moveVal;
+                        var transtr = 'rotate(' + aniObj._rotate + 'deg)';
+                        domEle.style.webkitTransform = transtr;
+                        domEle.style.transform = transtr;
+                    }
+                }
+            }
+
+            i++;
+            //            var etime = Date.now();
+            //            if (domEle.className === "__focus")
+            //                console.log("frame Time", etime-stime);
+        }
+    }
+    
+    function _timerUpdate (curTime, frames) {
+        var i = 0,
+            aniNums = frames.length;
+
+        while (i < aniNums) {
+            var aniFrame = frames[i],
+                aniObj = aniFrame.aniObj,
+                st = aniFrame.st,
+                update = aniObj._update,
+                finish = aniObj._endFunc,
+                duration = aniFrame.duration;
+
+           if (curTime >= st + duration) {
+                aniObj._isRunning = false;
+                update && update.call(aniObj._target, 1, duration);
+                if (finish) {
+                   finish.apply(aniObj._target, aniObj._endArgs);
+                }
+                frames.splice(i, 1);
+                aniNums--;
+                continue;
+           } else {
+               if (curTime < st) {
+                   aniFrame.st = curTime;
+               } else if (update)  {
+//                var moveVal = aniObj._easing(curTime - st, 0, 1, duration);
+                    var moveVal = curTime - st;
+                    aniObj._now = moveVal;
+                    update.call(aniObj._target, moveVal/duration, moveVal);
+               }
+            }
+            i++;
+        }
+    }
+
+//    if (platform_webcore) {
+//        frameAniList = [];
+//        frameTimmer = setInterval(function () {
+//            _frameUpdate(frameCounter, frameAniList);
+//            frameCounter++;
+//        }, 0);
+//    } else {
+        tickAniList = [];
+        tickTimmer = setInterval(function () {
+            var now = Date.now();
+            _frameUpdate(now, tickAniList);
+//            var t1 = Date.now();
+            _timerUpdate(now, timerList);
+//            var t2 = Date.now();
+//            console.log("frametime", t2-now);
+        }, 0);
+//    }
+
+    function tv_animation(ele) {
+        this._node = ele;
+        this._opacity = 1;
+        this._scaleX = 1;
+        this._scaleY = 1;
+        this._width = 1;
+        this._height = 1;
+        this._left = 0;
+        this._top = 0;
+        this._transformX = 0;
+        this._transformY = 0;
+        this._rotate = 0;
+        this._endOpacity = 1;
+        this._endScaleX = 1;
+        this._endScaleY = 1;
+        this._endLeft = 0;
+        this._endTop = 0;
+        this._endTransformX = 0;
+        this._endTransformY = 0;
+        this._endRotate = 0;
+        this._endWidth = 0;
+        this._endHeight = 0;
+        this._endFunc = null;
+        this._isEnd = false;
+        this._isStop = false;
+        this._isRunning = false;
+        this._duration = default_duration;
+        this._moveFunc = defaultMoveFunc;
+        this._isVisible = true;
+        this._flag = 0;
+        this._endArgs = [];
+    }
+
+    tv_animation.prototype = {
+        /** 
+         *  原型 1:animate( props, duration, easing, complete )
+         *  {object} props: CSS属性集
+         *  {int} duration: 毫秒数
+         *  {function} easing: 动画曲线函数
+         *  {function} complete: 动画结束后的回调函数
+         * 
+         *  原型 2:animate( props, options )
+         *  {object} props: CSS属性集
+         *  {onject} options: 包含 duration、easing、complete 的选项集
+         */
+        animate: function (props, duration, easing, complete) {
+            var aniRunObj = {}, offset;
+            
+            // 若为原型2,则从 options 提取 duration、easing、complete
+            if (typeof duration === 'object') {
+                var opt = duration;
+                duration = opt.duration;
+                easing = opt.easing;
+                complete = opt.complete;
+            }
+
+            // 若duration不为数字,则设为默认值
+            if (!isNumber(duration)) {
+                duration = this._duration;
+            }
+
+            // 若complete不为函数,则设为null
+            if (complete instanceof Function) {
+                aniRunObj.complete = complete;
+            } else {
+                aniRunObj.complete = this._endFunc;
+            }
+
+            // 若easing不为函数,则设为默认函数
+            if (easing instanceof Function) {
+                aniRunObj.moveFunc = easing;
+            } else {
+                aniRunObj.moveFunc = this._moveFunc;
+            }
+
+            // @Mark
+            if (isNumber(props.left)) {
+                if (duration === 0) {
+                    this.setLeft(props.left);
+                } else {
+                    offset = props.left - this._left;
+                    if (offset) {
+                        this._endLeft = props.left;
+                        aniRunObj.bx = this._left;
+                        aniRunObj.offx = offset;
+                    }
+                }
+            }
+
+            // @Mark 
+            if (isNumber(props.top)) {
+                if (duration === 0) {
+                    this.setTop(props.top);
+                } else {
+                    offset = props.top - this._top;
+                    if (offset) {
+                        this._endTop = props.top;
+                        aniRunObj.by = this._top;
+                        aniRunObj.offy = offset;
+                    }
+                }
+            }
+
+            // @Mark
+            if (isNumber(props.transformX)) {
+                if (duration === 0) {
+                    this.setTransformX(props.transformX);
+                } else {
+                    offset = props.transformX - this._transformX;
+                    if (offset) {
+                        this._endTransformX = props.transformX;
+                        aniRunObj.btx = this._transformX;
+                        aniRunObj.offtx = offset;
+                    }
+                }
+            }
+
+            // @Mark
+            if (isNumber(props.transformY)) {
+                if (duration === 0) {
+                    this.setTransformY(props.transformY);
+                } else {
+                    offset = props.transformY - this._transformY;
+                    if (offset) {
+                        this._endTransformY = props.transformY;
+                        aniRunObj.bty = this._transformY;
+                        aniRunObj.offty = offset;
+                    }
+                }
+            }
+
+            // @Mark
+            if(isNumber(props.rotate)){
+                if(duration === 0){
+                    this.setRotate(pros.rotate);
+                }else{
+                    deg = props.rotate - this._rotate;
+                    if(deg){
+                        this._endRotate = props.rotate;
+                        aniRunObj.bdeg = this._rotate;
+                        aniRunObj.offdeg = deg;
+                    }
+                }
+            }
+
+
+            if (isNumber(props.width)) {
+                if (duration === 0) {
+                    this.setWidth(props.width);
+                } else {
+                    offset = props.width - this._width;
+                    if (offset) {
+                        this._endWidth = props.width;
+                        aniRunObj.bw = this._width;
+                        aniRunObj.offw = offset;
+                    }
+                }
+            }
+            if (isNumber(props.height)) {
+                if (duration === 0) {
+                    this.setHeight(props.height);
+                } else {
+                    offset = props.height - this._height;
+                    if (offset) {
+                        this._endHeight = props.height;
+                        aniRunObj.bh = this._height;
+                        aniRunObj.offh = offset;
+                    }
+                }
+            }
+            if (isNumber(props.opacity)) {
+                if (duration === 0) {
+                    this.setOpacity(props.opacity);
+                } else {
+                    offset = props.opacity - this._opacity;
+                    if (offset) {
+                        this._endOpacity = props.opacity;
+                        aniRunObj.bopt = this._opacity;
+                        aniRunObj.offopt = offset;
+                    }
+                }
+            }
+            if (isNumber(props.scaleX)) {
+                if (duration === 0) {
+                    this.setScaleX(props.scaleX);
+                } else {
+                    offset = props.scaleX - this._scaleX;
+                    if (offset) {
+                        this._endScaleX = props.scaleX;
+                        aniRunObj.bsx = this._scaleX;
+                        aniRunObj.offsx = offset;
+                    }
+                }
+            }
+            if (isNumber(props.scaleY)) {
+                if (duration === 0) {
+                    this.setScaleY(props.scaleY);
+                } else {
+                    offset = props.scaleY - this._scaleY;
+                    if (offset) {
+                        this._endScaleY = props.scaleY;
+                        aniRunObj.bsy = this._scaleY;
+                        aniRunObj.offsy = offset;
+                    }
+                }
+            }
+
+            this._isEnd = false;
+            this._isStop = false;
+            this._flag = Date.now();
+
+            // 若时长为0,则直接运行回调函数
+            if (duration === 0 && aniRunObj.complete) {
+                aniRunObj.complete.apply(this, this._endArgs);
+                return;
+            }
+            
+            aniRunObj.aniObj = this;
+            aniRunObj.flag = this._flag;
+//            if (!platform_webcore) {
+
+            // 加入动画队列
+            aniRunObj.st = Date.now();
+                aniRunObj.duration = duration;
+                tickAniList.push(aniRunObj);
+//            } else {
+//                aniRunObj.st = frameCounter;
+//                aniRunObj.duration = duration >> 4;
+//                frameAniList.push(aniRunObj);
+//            }
+            this._isRunning = true;
+
+            return this;
+        },
+        end: function () {
+            this._isEnd = true;
+            return this;
+        },
+        stop: function () {
+            this._isStop = true;
+            return this;
+        },
+        setEasing: function (mode, type) {
+            if (Tween_Algorithm[mode] && Tween_Algorithm[mode][type])
+                this._moveFunc = Tween_Algorithm[mode][type];
+            return this;
+        },
+        setDuration: function (duration) {
+            if (isNumber(duration)) {
+                this._duration = duration;
+            }
+            return this;
+        },
+        // @Mark
+        setEndFunc: function (endFunc) {
+            if (endFunc instanceof Function) {
+                this._endFunc = endFunc;
+                var argLen = arguments.length;
+                if (argLen > 1) {
+                    this._endArgs = arguments.slice(1);
+                } else {
+                    this._endArgs = [];
+                }
+            } else {
+                this._endFunc = null;
+            }
+            return this;
+        },
+        setTop: function (y) {
+            if (isNumber(y)) {
+                this._top = y;
+                if (this._node) {
+                    this._node.style.top = y + 'px';
+                }
+            }
+            return this;
+        },
+        setTransformY: function (y) {
+            if (isNumber(y)) {
+                this._transformY = y;
+                if (this._node) {
+                    var transtr = 'translate3d(' + this._transformX + 'px, ' + y + 'px, 0) scale3d(' +
+                        this._scaleX + ', ' + this._scaleY + ', 1)';
+                    this._node.style.webkitTransform = transtr;
+                    this._node.style.transform = transtr;
+                }
+            }
+            return this;
+        },
+        setRotate: function(deg){
+            if(isNumber(deg)){
+                this._rotate = deg;
+                if(this._node){
+                    var transtr = 'rotate(' + this._rotate + 'deg)';
+                    this._node.style.webkitTransform = transtr;
+                    this._node.style.transform = transtr;
+                }
+            }
+        },
+        setLeft: function (x) {
+            if (isNumber(x)) {
+                this._left = x;
+                if (this._node) {
+                    this._node.style.left = x + 'px';
+                }
+            }
+            return this;
+        },
+        setTransformX: function (x) {
+            if (isNumber(x)) {
+                this._transformX = x;
+                var transtr = 'translate3d(' + x + 'px, ' + this._transformY + 'px, 0) scale3d(' +
+                    this._scaleX + ', ' + this._scaleY + ', 1)';
+                this._node.style.webkitTransform = transtr;
+                this._node.style.transform = transtr;
+            }
+            return this;
+        },
+        setScaleX: function (scaleX) {
+            if (isNumber(scaleX)) {
+                this._scaleX = scaleX;
+                if (this._node) {
+                    var transtr = 'translate3d(' + this._transformX + 'px, ' + this._transformY + 'px, 0) scale3d(' + this._scaleX + ', ' + this._scaleY + ', 1)';
+                    this._node.style.webkitTransform = transtr;
+                    this._node.style.transform = transtr;
+                }
+            }
+            return this;
+        },
+        setScaleY: function (scaleY) {
+            if (isNumber(scaleY)) {
+                this._scaleY = scaleY;
+                if (this._node) {
+                    var transtr = 'translate3d(' + this._transformX + 'px, ' + this._transformY + 'px, 0) scale3d(' + this._scaleX + ', ' + this._scaleY + ', 1)';
+                    this._node.style.webkitTransform = transtr;
+                    this._node.style.transform = transtr;
+                }
+            }
+            return this;
+        },
+        setOpacity: function (opacity) {
+            if (isNumber(opacity)) {
+                this._opacity = opacity;
+                var opt = this._opacity;
+                if (this._node) {
+                    this._node.style.opacity = opt;
+                }
+            }
+            return this;
+        },
+        setWidth: function (width) {
+            if (isNumber(width)) {
+                this._width = width;
+                if (this._node) {
+                    this._node.style.width = this._width + "px";
+                }
+            }
+            return this;
+        },
+        setHeight: function (height) {
+            if (isNumber(height)) {
+                this._height = height;
+                if (this._node) {
+                    this._node.style.height = this._height + "px";
+                }
+            }
+            return this;
+        },
+        //        setColor: function (color) {
+        //            if (color instanceof Array && color.length === 4) {
+        //                this._color = color;
+        //                if (this._node) {
+        //                    this._node.style.color = "rgba(" + Math.round(color[0]) + "," + Math.round(color[1]) + "," + Math.round(color[2]) + "," + color[3] + ")";
+        //                }
+        //            }
+        //            return this;
+        //        },
+//        setMode: function (mode) {
+//            if (mode === 0 || mode === 1) {
+//                this._aniMode = mode;
+//            } else {
+//                this._aniMode = defaultMode;
+//            }
+//            return this;
+//        },
+        getTime: function () {
+//            if (this._aniMode === 1) {
+//                return frameCounter;
+//            } else {
+                return Date.now();
+//            }
+        },
+        // @Mark
+        hide: function (isAnimate) {
+            if (!this._isVisible) {
+                return;
+            }
+            this._isVisible = false;
+
+            if (isAnimate) {
+                this._endFunc = function () {
+                    this._node.style.display = "none";
+                    this._endFunc = null;
+                };
+                this.animate({
+                    opacity: 0
+                });
+            } else {
+                this._node.style.display = "none";
+            }
+        },
+
+        // @Mark
+        show: function (isAnimate) {
+            if (this._isVisible) {
+                return;
+            }
+            this._isVisible = true;
+
+            if (isAnimate) {
+                this._node.style.display = "block";
+                this.animate({
+                    opacity: 1
+                });
+            } else {
+                this._node.style.display = "block";
+            }
+        },
+        isVisible: function () {
+            return this._isVisible;
+        }
+    };
+    
+
+    function tv_timer (target, update, finish, duration) {
+        if (!target) return;
+        
+        this._target = target;
+        if (isNumber(duration)) {
+            this._duration = duration;
+        }
+        if (update instanceof Function) {
+            this._update = target.onTimer;
+        }
+        if (finish instanceof Function) {
+            this._endFunc = finish;
+        }
+        this._isRunning = false;
+        this._now = 0;
+    }
+    
+    tv_timer.prototype = {
+        start: function () {
+            if (this._isRunning) return;
+            
+            var runObj = {};
+            runObj.st = Date.now();
+            runObj.duration = this._duration;
+            runObj.aniObj = this;
+            this._isRunning = true;
+            this._now = 0;
+            timerList.push(runObj);
+        },
+        stop: function () {
+            this._isRunning = false;
+            for (var i = 0, len = timerList.length; i< len; i++) {
+                if (timerList[i].aniObj === this) {
+                    timerList.splice(i, 1);
+                    break;
+                }
+            }
+        },
+        status: function () {
+            return this._isRunning ? 1 : 0;
+        },
+        setDuration: function (duration) {
+            if (isNumber(duration)) {
+                this._duration = duration;
+            }
+        }
+    };
+
+    return {
+        animation: tv_animation,
+        createAnimation: function (ele) {//console.log(ele instanceof HTMLElement)
+            if (typeof ele !== "undefined" && ele instanceof HTMLElement) {
+                return new tv_animation(ele);
+            } else {
+                return null;
+            }
+        },
+        createTimer: function (target, update, finish, duration) {
+            if (!target || !target.onTimer) {
+                return null;
+            }
+            return new tv_timer(target, update, finish, duration);
+        },
+        reset: function () {
+//            if (platform_webcore) {
+//                clearInterval(frameTimmer);
+//                frameAniList = [];
+//                frameTimmer = setInterval(function () {
+//                    _frameUpdate(frameCounter, frameAniList);
+//                    frameCounter++;
+//                }, 0);
+//            } else {
+                tickAniList = [];
+                timerList = [];
+                clearInterval(tickTimmer);
+                tickTimmer = setInterval(function () {
+                    var now = Date.now();
+                    _frameUpdate(now, tickAniList);
+                    _timerUpdate(now, timerList);
+                }, 0);
+//            }
+        }
+    }
+})(window.Zepto);

File diff suppressed because it is too large
+ 1008 - 0
src/lib/js/blitz.js


File diff suppressed because it is too large
+ 321 - 0
src/lib/js/keyPanel.js


File diff suppressed because it is too large
+ 1625 - 0
src/lib/js/moye.js


+ 740 - 0
src/lib/js/moye.min.js

@@ -0,0 +1,740 @@
+/*
+ * Moye 0.0.2 <Fri Aug 26 2016 15:44:17 GMT+0800 (CST)>
+ * Moye 应用框架设计宗旨是告诉开发者如何在 cyclone 系统上开发应用,包括规范应用生 命周期,支持多语言以及开发 Service 服务等。
+ * xuanyong (yujie.pyj@alibaba-inc.com) - http://tv.alibaba.net/_site/index.html
+ *
+ * Copyright 2016, Alibaba Group
+ * Released under the MIT license.
+ */
+
+! function(e) {
+	function t(i) {
+		if (n[i]) return n[i].exports;
+		var o = n[i] = {
+			exports: {},
+			id: i,
+			loaded: !1
+		};
+		return e[i].call(o.exports, o, o.exports, t), o.loaded = !0, o.exports;
+	}
+	var n = {};
+	return t.m = e, t.c = n, t.p = '', t(0);
+}([function(e, t, n) {
+	
+
+	function i(e) {
+		return e && e.__esModule ? e : {
+			'default': e
+		};
+	}
+
+	function o(e, t) {
+		if (!(e instanceof t)) throw new TypeError('Cannot call a class as a function');
+	}
+	var s = 'function' == typeof Symbol && 'symbol' == typeof Symbol.iterator ? function(e) {
+			return typeof e;
+		} : function(e) {
+			return e && 'function' == typeof Symbol && e.constructor === Symbol ? 'symbol' : typeof e;
+		},
+		r = Object.assign || function(e) {
+			for (var t = 1; t < arguments.length; t++) {
+				var n = arguments[t];
+				for (var i in n) Object.prototype.hasOwnProperty.call(n, i) && (e[i] = n[i]);
+			}
+			return e;
+		},
+		u = function() {
+			function e(e, t) {
+				for (var n = 0; n < t.length; n++) {
+					var i = t[n];
+					i.enumerable = i.enumerable || !1, i.configurable = !0, 'value' in i && (i.writable = !0), Object.defineProperty(e, i.key, i);
+				}
+			}
+			return function(t, n, i) {
+				return n && e(t.prototype, n), i && e(t, i), t;
+			};
+		}(),
+		a = n(1),
+		c = i(a),
+		l = n(2),
+		f = i(l),
+		h = n(3),
+		y = i(h),
+		d = n(4),
+		v = i(d),
+		g = n(5),
+		p = i(g),
+		m = function() {
+			function e() {
+				o(this, e), this.utils = c['default'], this.global = new p['default'], this.sceneList = [], this.focusList = [], this.action = {}, this.root = null, this.curScene = null, this.isAtv = !1, this.isTplDebug = !1, this.animate = !1, this.keyCodes = {
+					ENTER: 13,
+					LEFT: 37,
+					UP: 38,
+					RIGHT: 39,
+					DOWN: 40,
+					BACK: 27,
+					MEMU: 18,
+					SOURCE: 690,
+					RECORD: 685,
+					NUM_0: 48,
+					NUM_1: 49,
+					NUM_2: 50,
+					NUM_3: 51,
+					NUM_4: 52,
+					NUM_5: 53,
+					NUM_6: 54,
+					NUM_7: 55,
+					NUM_8: 56,
+					NUM_9: 57,
+					SOUND_UP: 536,
+					SOUND_DOWN: 537,
+					M: 36
+				};
+			}
+			return u(e, [{
+				key: 'init',
+				value: function() {
+					var e = arguments.length <= 0 || void 0 === arguments[0] ? {} : arguments[0];
+					if ('[object Object]' !== this.utils.getType(e)) throw new Error('[Moye] init\u4f20\u5165\u53c2\u6570\u7c7b\u578b\u9519\u8bef\uff0c\u53ea\u63a5\u53d7\u4f20\u5165\u5bf9\u8c61\u3002');
+					e = r({
+						tplmode: 0,
+						packagename: 'com.yunos.moye.demo',
+						isAtv: !0,
+						animate: !1,
+						scene: {}
+					}, e), this.launcher = e.launcher, this.isTplDebug = e.isTplDebug, this.isAtv = e.isAtv, this.animate = e.animate, this.tplmode = e.tplmode, e['default'] && e['default'].lang && '[object Object]' === this.utils.getType(e['default'].lang) ? this.lang = e['default'].lang : this.lang = null, this.scene = e.scene, this.resource = new f['default'](e.packagename, this.lang, this.isTplDebug), this.registerStageListener(), this.isAtv || this.onkeyListener();
+				}
+			}, {
+				key: 'showScene',
+				value: function(e) {
+					var t = this,
+						n = arguments.length <= 1 || void 0 === arguments[1] ? {} : arguments[1];
+					if (this.curScene && this.curScene.onPause(), '[object Object]' !== this.utils.getType(n)) throw new Error('[Moye] showScene\u4f20\u5165\u53c2\u6570(data)\u7c7b\u578b\u9519\u8bef\uff0c\u53ea\u63a5\u53d7\u4f20\u5165\u5bf9\u8c61\u3002');
+					if (this.curScene = new e(this), this.sceneList.push(this.curScene), this.updateDefaultKeyStatus(), this.sceneList.length <= 1 && this.utils.isBlitz()) {
+						var i = blitz.load('base');
+						i.getPageData({}, function(e) {
+							t.curScene.onCreate(r({}, n, {
+								pageData: e
+							}));
+						}, function(e) {
+							t.curScene.onCreate(n);
+						});
+					} else this.curScene.onCreate(n);
+				}
+			}, {
+				key: 'registerStageListener',
+				value: function() {
+					var e = this,
+						t = blitz.load('base');
+					this.isAtv || this.onkeyListener(), this.utils.isBlitz() && (t.addListener({
+						name: 'page_show'
+					}, function(t) {
+						e.curScene && e.curScene.onResume();
+						for (var n = 0, i = e.sceneList.length; i > n; n++) e.sceneList[n].onStageShow && e.sceneList[n].onStageShow();
+					}, function(e) {
+						throw new Error('[ Moye ] page_show\u51fa\u9519\u3002');
+					}), t.addListener({
+						name: 'page_hide'
+					}, function(t) {
+						e.curScene && e.curScene.onPause();
+						for (var n = 0, i = e.sceneList.length; i > n; n++) e.sceneList[n].onStageHide && e.sceneList[n].onStageHide();
+					}, function(e) {
+						throw new Error('[ Moye ] page_hide\u51fa\u9519\u3002');
+					}), t.addListener({
+						name: 'page_stop'
+					}, function(t) {
+						e.curScene && e.curScene.onDestroy();
+					}, function(e) {
+						throw new Error('[ Moye ] page_stop\u51fa\u9519\u3002');
+					}), t.addListener({
+						name: 'stage_resume'
+					}, function(t) {
+						e.curScene.onActive();
+					}, function(e) {
+						throw new Error('[ Moye ] stage_resume\u51fa\u9519\u3002');
+					}), t.addListener({
+						name: 'stage_pause'
+					}, function(t) {
+						e.curScene.onInactive();
+					}, function(e) {
+						throw new Error('[ Moye ] stage_pause\u51fa\u9519\u3002');
+					}));
+				}
+			}, {
+				key: 'onkeyListener',
+				value: function() {
+					var e = this;
+					this.isAtv ? (this.root.on('keydown', function(t) {
+						e.curScene.onKeydown(t);
+					}), this.root.on('ok', function(t) {
+						e.curScene.onOK(t);
+					}), this.root.on('click', function(t) {
+						e.curScene.onClick(t);
+					}), this.root.on('keyup', function(t) {
+						switch (t.keyCode) {
+							case e.keyCodes.BACK:
+								e.hideScene();
+								break;
+							default:
+								e.curScene.onKeyup(t);
+						}
+					})) : (document.body.addEventListener('keydown', function(t) {
+						e.curScene.onKeydown(t);
+					}), document.body.addEventListener('keyup', function(t) {
+						switch (t.keyCode) {
+							case e.keyCodes.BACK:
+								e.hideScene();
+								break;
+							case e.keyCodes.ENTER:
+								e.curScene.onOK(t);
+								break;
+							default:
+								e.curScene.onKeyup(t);
+						}
+					}));
+				}
+			}, {
+				key: 'hideScene',
+				value: function(e, t) {
+					t ? this.showSceneById(e, t) : this.hideCurScene(e);
+				}
+			}, {
+				key: 'showSceneById',
+				value: function(e, t) {
+					var n = this.focusList.indexOf(t);
+					if (-1 == n) throw new Error('[ Moye ] \u672a\u53d1\u73b0\u5bf9\u5e94ID\u7684Scene\u3002');
+					this.curScene.onPause(), this.curScene.onDestroy(), this.curScene = null, this.sceneList.length = n + 1;
+					for (var i = this.focusList.length, o = i - 1; o > n; o--) {
+						var s = this.focusList[o],
+							r = document.getElementById(s);
+						r.parentNode.removeChild(r);
+					}
+					this.focusList.length = n + 1, this.render(), this.isAtv && (this.root.getWidgetById(t).enable(), this.atvFocus(t)), this.curScene = this.sceneList[n], this.curScene.onResume(e), this.updateDefaultKeyStatus();
+				}
+			}, {
+				key: 'hideCurScene',
+				value: function(e) {
+					var t = this,
+						n = this.sceneList;
+					this.curScene = n[n.length - 1];
+					var i = this.curScene.onBack && this.curScene.onBack();
+					if (1 !== n.length) {
+						if (!i) {
+							this.curScene.onPause(), this.curScene.onDestroy(), this.isAtv && ! function() {
+								var e = t.focusList.pop(),
+									n = document.getElementById(e);
+								t.animate ? (n.style.transform = 'scale(1)', n.style.opacity = 1, n.addEventListener('transitionend', function() {
+									n.parentNode.removeChild(n), e = null, t.render();
+								}), n.style.transition = 'all 0.2s ease-in-out', n.style.transform = 'scale(.95)', n.style.opacity = 0) : (n.parentNode.removeChild(n), e = null, t.render());
+							}();
+							var o = n.pop();
+							if (o = null, n.length >= 1) {
+								if (this.curScene = n[n.length - 1], this.isAtv) {
+									var s = this.focusList[this.focusList.length - 1];
+									this.root.getWidgetById(s).enable(), this.atvFocus(s);
+								}
+								this.curScene.onResume(e);
+							}
+						}
+						this.updateDefaultKeyStatus();
+					}
+				}
+			}, {
+				key: 'reload',
+				value: function() {
+					var e = this.sceneList,
+						t = this.focusList;
+					this.resource.lang = null, this.resource.getResourceValue();
+					for (var n = 0, i = t.length; i > n; n++) {
+						var o = document.getElementById(t[n]);
+						o.parentNode.removeChild(o);
+					}
+					t.length = 0, e.length = 1, this.curScene = e[0], this.updateDefaultKeyStatus(), this.curScene.onCreate();
+				}
+			}, {
+				key: 'updateDefaultKeyStatus',
+				value: function() {
+					this.sceneList.length > 1 || this.launcher ? this.utils.setDefaultKeyEvent(!0) : this.utils.setDefaultKeyEvent(!1);
+				}
+			}, {
+				key: 'getResource',
+				value: function() {
+					return this.resource;
+				}
+			}, {
+				key: 'setContentView',
+				value: function(e, t, n, i) {
+					var o = this,
+						r = arguments.length <= 4 || void 0 === arguments[4] ? function() {} : arguments[4],
+						u = i && i.containerId ? i.containerId : null,
+						a = i && i.isParentShow ? i.isParentShow : !1,
+						c = i && i.focusId ? i.focusId : n,
+						l = i && i.isFront ? i.isFront : !1,
+						f = u ? document.getElementById(u) : document.body,
+						h = function(e, t) {
+							o.animate && (f.style.transform = 'scale(0.95)', setTimeout(function() {
+								f.style.transition = 'all 0.2s ease-in-out', f.style.transform = 'scale(1)';
+							}, 300));
+							var i = o.utils.parseToDOM(e);
+							if (i.id || (i.id = n), l ? f.insertBefore(i, f.childNodes[0]) : f.appendChild(i), o.isAtv && (o.render(), o.atvFocus(c), o.focusList.push(n), o.focusList.length > 1)) {
+								var s = o.focusList[o.focusList.length - 2];
+								o.root.getWidgetById(s).disable(), document.getElementById(s).style.visibility = a ? 'visible' : 'hidden';
+							}
+							t();
+						};
+					this.resource.getResourceValue(function(n) {
+						if (t.lang = n, '[object Function]' === o.utils.getType(e)) h(e(t), r);
+						else {
+							if ('[object String]' !== o.utils.getType(e)) throw new Error('[Moye] setContentView\u4f20\u5165\u53c2\u6570(tpl)\u9519\u8bef\uff0c\u4e0d\u63a5\u53d7String & Function\u4ee5\u5916\u7c7b\u578b\u3002');
+							console.log('[Moye] \u901a\u8fc7\u6587\u4ef6\u540d\u83b7\u53d6\u6a21\u677f\u7684\u65b9\u5f0f\u5df2\u4e0d\u5efa\u8bae\u4f7f\u7528,\u8bf7\u76f4\u63a5require\u6a21\u677f\u6587\u4ef6\u3002'), o.resource.getTpl(e, function(e, n) {
+								if (!e) throw new Error('[Moye] \u83b7\u53d6\u6a21\u677f\u6587\u4ef6\u51fa\u9519\u3002');
+								('object' !== ('undefined' == typeof t ? 'undefined' : s(t)) || null == t) && (t = {});
+								var i = o.tplReplace(n, t);
+								h(i, r);
+							});
+						}
+					});
+				}
+			}, {
+				key: 'render',
+				value: function() {
+					return this.root ? this.root.reRender() : (this.root = window.ATV ? ATV.UI.render() : FocusEngine.render(), this.onkeyListener()), this.root;
+				}
+			}, {
+				key: 'assetData',
+				value: function(e, t) {
+					return 'object' !== ('undefined' == typeof t ? 'undefined' : s(t)) && (t = {}), t.lang = this.resource.getLang(), this.tplReplace(e, t);
+				}
+			}, {
+				key: 'atvFocus',
+				value: function(e) {
+					this.root.getWidgetById(e).focus(), document.getElementById(e).style.visibility = 'visible';
+				}
+			}, {
+				key: 'getServiceClient',
+				value: function() {
+					return new y['default'];
+				}
+			}, {
+				key: 'tplReplace',
+				value: function(e, t) {
+					return 0 == this.tplmode ? this.utils.regexView(e, t) : juicer(e, t);
+				}
+			}, {
+				key: 'getSystemLang',
+				value: function(e) {
+					var t = blitz.load('property');
+					t.getSystemProperty({
+						key: 'persist.sys.language'
+					}, function(t) {
+						var n = t.result;
+						e(n);
+					}, function(e) {});
+				}
+			}]), e;
+		}();
+	void 0 !== ('undefined' == typeof window ? 'undefined' : s(window)) ? (window.moye = new m, window.scene = v['default']) : e.exports = moye = new m;
+}, function(module, exports) {
+	
+	Object.defineProperty(exports, '__esModule', {
+		value: !0
+	});
+	var MoyeUtils = {
+		isBlitz: function() {
+			return 'undefined' != typeof yunos;
+		},
+		parseToDOM: function(e) {
+			var t = void 0,
+				n = document.createElement('div'),
+				i = document.createDocumentFragment();
+			for (n.innerHTML = e; t = n.firstChild;) i.appendChild(t);
+			return i;
+		},
+		setDefaultKeyEvent: function(e) {
+			this.isBlitz() && yunos.context.preventDefaultKeyEvent(e);
+		},
+		hasClass: function(e, t) {
+			return e.className.match(new RegExp('(\\s|^)' + t + '(\\s|$)'));
+		},
+		addClass: function(e, t) {
+			this.hasClass(e, t) || (e.className += ' ' + t);
+		},
+		removeClass: function(e, t) {
+			if (this.hasClass(e, t)) {
+				var n = new RegExp('(\\s|^)' + t + '(\\s|$)');
+				e.className = e.className.replace(n, ' ');
+			}
+		},
+		writeFile: function(e, t, n) {
+			var i = blitz.load('file');
+			i.openFile({
+				filename: e.filename,
+				mode: e.mode
+			}, function(o) {
+				console.log('open file success: ' + JSON.stringify(o)), i.write({
+					filename: e.filename,
+					data: e.data
+				}, function(o) {
+					console.log('write file success: ' + JSON.stringify(o)), t && t(o), i.closeFile({
+						filename: e.filename
+					}, function(e) {
+						console.log('close file success: ' + JSON.stringify(e));
+					}, function(e) {
+						console.log('close file fail: ' + JSON.stringify(e)), n && n(e);
+					});
+				}, function(e) {
+					console.log('write file fail: ' + JSON.stringify(e)), n && n(e);
+				});
+			}, function(e) {
+				console.log('open file fail: ' + JSON.stringify(e)), n && n(e);
+			});
+		},
+		getType: function(e) {
+			var t = {}.toString;
+			return t.call(e);
+		},
+		regexView: function regexView(htmlContent, arr) {
+			var result = htmlContent.replace(/\$\{(.*?)\}/g, function() {
+				try {
+					var s = arguments[1].toString(),
+						m = eval('arr.' + s);
+					return void 0 == m ? '' : m;
+				} catch (e) {}
+			});
+			return result.toString();
+		}
+	};
+	window.MoyeUtils = MoyeUtils, exports['default'] = MoyeUtils;
+}, function(e, t, n) {
+	
+
+	function i(e) {
+		return e && e.__esModule ? e : {
+			'default': e
+		};
+	}
+
+	function o(e, t) {
+		if (!(e instanceof t)) throw new TypeError('Cannot call a class as a function');
+	}
+	Object.defineProperty(t, '__esModule', {
+		value: !0
+	});
+	var s = function() {
+			function e(e, t) {
+				for (var n = 0; n < t.length; n++) {
+					var i = t[n];
+					i.enumerable = i.enumerable || !1, i.configurable = !0, 'value' in i && (i.writable = !0), Object.defineProperty(e, i.key, i);
+				}
+			}
+			return function(t, n, i) {
+				return n && e(t.prototype, n), i && e(t, i), t;
+			};
+		}(),
+		r = n(1),
+		u = i(r),
+		a = function() {
+			function e(t, n, i) {
+				o(this, e), this.respath = '/data/app/' + t + '/res/', this.utils = u['default'], this.lang = null === n ? {} : n, this.file = blitz.load('file'), this.isTplDebug = i, this.tpl = {}, console.log(this.lang);
+			}
+			return s(e, [{
+				key: 'getLang',
+				value: function() {
+					return this.lang;
+				}
+			}, {
+				key: 'getString',
+				value: function(e) {
+					return this.lang.data[e];
+				}
+			}, {
+				key: 'getResourceValue',
+				value: function(e) {
+					var t = this;
+					if (this.utils.isBlitz()) {
+						var n = blitz.load('property');
+						n.getSystemProperty({
+							key: 'persist.sys.language'
+						}, function(n) {
+							var i = n.result;
+							if (i === t.lang.type) e && e(t.lang.data);
+							else try {
+								var o = 'value_' + i + '.json';
+								t.lang.data = window.require('../../res/values/' + o), t.lang.type = i, e && e(t.lang.data);
+							} catch (n) {
+								var s = 'value.json';
+								t.lang.data = window.require('../../res/values/' + s), t.lang.type = i, e && e(t.lang.data);
+							}
+						}, function(n) {
+							e && e(t.lang.data);
+						});
+					} else this.lang.type && this.lang.data ? e && e(this.lang.data) : this.sendAjaxRequest('../../res/values/value.json', function(n, i) {
+						t.lang.type = 'zh', t.lang.data = JSON.parse(i), e && e(t.lang.data);
+					});
+				}
+			}, {
+				key: 'sendAjaxRequest',
+				value: function(e, t) {
+					var n = new XMLHttpRequest;
+					n.open('GET', e, !0), n.onreadystatechange = function() {
+						if (4 == n.readyState && 200 == n.status) {
+							var e = n.responseText;
+							t(!0, e);
+						}
+					}, n.send(null);
+				}
+			}, {
+				key: 'getTpl',
+				value: function(e, t) {
+					var n = this;
+					void 0 != this.tpl[e] || this.utils.isBlitz() && !this.isTplDebug ? ! function() {
+						var i = {
+							filename: n.respath + 'tpl/' + e
+						};
+						n.file.openFile(i, function(o) {
+							n.file.read(i, function(o) {
+								n.tpl[e] = o.data, n.file.closeFile(i, function(e) {}, function(e) {
+									throw new Error('[ Moye ] \u5173\u95ed\u6587\u4ef6(' + i.filename + ')\u51fa\u9519\u3002');
+								}), t(!0, o.data);
+							}, function(e) {
+								t(!1);
+							});
+						}, function(e) {
+							t(!1);
+						});
+					}() : this.sendAjaxRequest('../../res/tpl/' + e, t);
+				}
+			}]), e;
+		}();
+	t['default'] = a;
+}, function(e, t, n) {
+	
+
+	function i(e) {
+		return e && e.__esModule ? e : {
+			'default': e
+		};
+	}
+
+	function o(e, t) {
+		if (!(e instanceof t)) throw new TypeError('Cannot call a class as a function');
+	}
+	Object.defineProperty(t, '__esModule', {
+		value: !0
+	});
+	var s = 'function' == typeof Symbol && 'symbol' == typeof Symbol.iterator ? function(e) {
+			return typeof e;
+		} : function(e) {
+			return e && 'function' == typeof Symbol && e.constructor === Symbol ? 'symbol' : typeof e;
+		},
+		r = function() {
+			function e(e, t) {
+				for (var n = 0; n < t.length; n++) {
+					var i = t[n];
+					i.enumerable = i.enumerable || !1, i.configurable = !0, 'value' in i && (i.writable = !0), Object.defineProperty(e, i.key, i);
+				}
+			}
+			return function(t, n, i) {
+				return n && e(t.prototype, n), i && e(t, i), t;
+			};
+		}(),
+		u = n(1),
+		a = i(u),
+		c = function() {
+			function e() {
+				if (o(this, e), void 0 !== ('undefined' == typeof window ? 'undefined' : s(window))) {
+					var t = a['default'];
+					t.isBlitz() ? this.serivceClient = new BlitzServiceClient : this.serivceClient = null;
+				}
+			}
+			return r(e, [{
+				key: 'bindService',
+				value: function(e, t) {
+					this.serivceClient.getService(e, function(e) {
+						t(e);
+					});
+				}
+			}, {
+				key: 'unbindService',
+				value: function(e) {
+					this.serivceClient.release(e);
+				}
+			}, {
+				key: 'startService',
+				value: function(e, t) {
+					this.serivceClient.startService(e, t);
+				}
+			}, {
+				key: 'stopService',
+				value: function(e) {
+					this.serivceClient.stopService(e);
+				}
+			}]), e;
+		}();
+	t['default'] = c;
+}, function(e, t) {
+	
+	function n(e, t) {
+		if (!(e instanceof t)) throw new TypeError('Cannot call a class as a function');
+	}
+	Object.defineProperty(t, '__esModule', {
+		value: !0
+	});
+	var i = function() {
+			function e(e, t) {
+				for (var n = 0; n < t.length; n++) {
+					var i = t[n];
+					i.enumerable = i.enumerable || !1, i.configurable = !0, 'value' in i && (i.writable = !0), Object.defineProperty(e, i.key, i);
+				}
+			}
+			return function(t, n, i) {
+				return n && e(t.prototype, n), i && e(t, i), t;
+			};
+		}(),
+		o = function() {
+			function e(t) {
+				n(this, e), this.moye = t, this.global = t.global;
+			}
+			return i(e, [{
+				key: 'onCreate',
+				value: function(e) {}
+			}, {
+				key: 'onResume',
+				value: function(e) {}
+			}, {
+				key: 'onPause',
+				value: function() {}
+			}, {
+				key: 'onStageShow',
+				value: function(e) {}
+			}, {
+				key: 'onStageHide',
+				value: function() {}
+			}, {
+				key: 'onDestroy',
+				value: function() {}
+			}, {
+				key: 'onActive',
+				value: function() {}
+			}, {
+				key: 'onInactive',
+				value: function() {}
+			}, {
+				key: 'onKeydown',
+				value: function(e) {}
+			}, {
+				key: 'onKeyup',
+				value: function(e) {}
+			}, {
+				key: 'onOK',
+				value: function(e) {}
+			}, {
+				key: 'onBack',
+				value: function() {}
+			}, {
+				key: 'onClick',
+				value: function(e) {}
+			}, {
+				key: 'showScene',
+				value: function(e, t) {
+					return this.moye.showScene(e, t);
+				}
+			}, {
+				key: 'hideScene',
+				value: function(e, t) {
+					return this.moye.hideScene(e, t);
+				}
+			}, {
+				key: 'setContentView',
+				value: function(e, t, n, i, o) {
+					this.moye.setContentView(e, t, n, i, o);
+				}
+			}, {
+				key: 'getResource',
+				value: function() {
+					return this.moye.getResource();
+				}
+			}, {
+				key: 'getAlertDialog',
+				value: function() {
+					return window.require('/system/res/alert-dialog.js');
+				}
+			}, {
+				key: 'getKeyCodes',
+				value: function() {
+					return this.moye.keyCodes;
+				}
+			}, {
+				key: 'getMoye',
+				value: function() {
+					return this.moye;
+				}
+			}, {
+				key: 'getAtvRoot',
+				value: function() {
+					return this.moye.root;
+				}
+			}, {
+				key: 'atvFocus',
+				value: function(e) {
+					this.moye.atvFocus(e);
+				}
+			}, {
+				key: 'atvRender',
+				value: function() {
+					return this.moye.render();
+				}
+			}, {
+				key: 'reload',
+				value: function() {
+					return this.moye.reload();
+				}
+			}, {
+				key: 'isBlitz',
+				value: function() {
+					return this.moye.utils.isBlitz();
+				}
+			}]), e;
+		}();
+	t['default'] = o;
+}, function(e, t) {
+	
+
+	function n(e, t) {
+		if (!(e instanceof t)) throw new TypeError('Cannot call a class as a function');
+	}
+	var i = function() {
+			function e(e, t) {
+				for (var n = 0; n < t.length; n++) {
+					var i = t[n];
+					i.enumerable = i.enumerable || !1, i.configurable = !0, 'value' in i && (i.writable = !0), Object.defineProperty(e, i.key, i);
+				}
+			}
+			return function(t, n, i) {
+				return n && e(t.prototype, n), i && e(t, i), t;
+			};
+		}(),
+		o = function() {
+			function e() {
+				n(this, e), this.map = {};
+			}
+			return i(e, [{
+				key: 'get',
+				value: function(e) {
+					return this.map[e];
+				}
+			}, {
+				key: 'set',
+				value: function(e, t) {
+					this.map[e] = t;
+				}
+			}, {
+				key: 'each',
+				value: function() {
+					var e = arguments.length <= 0 || void 0 === arguments[0] ? function(e) {} : arguments[0];
+					for (var t in this.map) e(t);
+				}
+			}]), e;
+		}();
+	e.exports = o;
+}]);

+ 165 - 0
src/lib/js/widget_marquee.js

@@ -0,0 +1,165 @@
+(function() {
+	window.tv_marquee = {
+		create: function(ele) {
+			//console.log(ele);
+			return new marquee(ele);
+		}
+	};
+
+	var marginContent = '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
+
+	function marquee(ele, speed) {
+		if (ele) {
+			this._parent = ele.parentNode;
+			this._width = ele.parentNode.clientWidth;
+			this._originEle = ele;
+			this._content = ele.innerHTML;
+			this._getTrimContent();
+			this._isRunning = false;
+			if (!speed) {
+				this._speed = 20;
+			}
+			this._isLoop = false;
+		}
+	}
+
+	marquee.prototype = {
+		start: function(circle) {
+			if (!this._content || !this._trimContent) return;
+
+			if (this._isRunning === true) {
+				this.stop();
+			}
+
+			if (!this._marqueeEle) {
+				this._marqueeEle = document.createElement('div');
+				this._marqueeEle.className = 'tv_marquee';
+				/*
+				 * wuzhe add start
+				 */
+				this._marqueeEle.style.left = 0;
+				/**
+				 * wuzhe add end
+				 */
+				this._marqueeEle.appendChild(document.createElement('span'));
+				//                this._marqueeEle.appendChild(document.createElement('span'));
+				this._ani = new yunos_animation.animation(this._marqueeEle);
+				this._ani.setEasing('Linear', 'easeIn');
+			}
+
+			this._parent.removeChild(this._originEle);
+			this._parent.appendChild(this._marqueeEle);
+			var span = this._marqueeEle.children[0],
+				width;
+			span.innerHTML = this._content + marginContent;
+			//var position = $(span).css('position');
+			var position = span.style.position;
+			//$(span).css('position','absolute');
+			// span.style.position = 'absolute';
+			width = span.scrollWidth;
+			if (position) {
+				//$(span).css('position',position);
+				span.style.position = position;
+			}
+
+			span.innerHTML += this._content + marginContent + this._content;
+			this._ani.setTransformX(0);
+			var that = this;
+
+			this._ani.animate({
+				transformX: -width
+			}, {
+				duration: width * this._speed,
+
+				complete: function() {
+					if (circle)
+						that.start(true);
+				}
+			});
+			this._isRunning = true;
+
+		},
+		stop: function() {
+			if (this._isRunning === true) {
+				this._ani.stop();
+				this._parent.removeChild(this._marqueeEle);
+				this._originEle.innerHTML = this._content;
+				this._parent.appendChild(this._originEle);
+				this._isRunning = false;
+				if (!this._trimContent) {
+					this.setStr(this._content);
+				}
+			}
+		},
+		setStr: function(str) {
+			if (!str) return -2;
+			if (str === this._content) return -3;
+
+			this._content = str;
+			if (!this._isRunning) {
+				this._originEle.innerHTML = str;
+				return this._getTrimContent();
+			} else {
+				return -4;
+			}
+		},
+		_getTrimContent: function() {
+			var ele = this._originEle,
+				ruler = document.createElement('span'),
+				str = this._content,
+				ellipsisWidth,
+				parentWidth;
+
+			ruler.className = 'tv_marquee';
+			ruler.innerHTML = '...';
+			this._parent.appendChild(ruler);
+
+			//var position = $(ruler).css('position');
+			//$(ruler).css('position','absolute');
+			var position = ruler.style.position;
+			ruler.style.position = 'absolute';
+			ellipsisWidth = ruler.scrollWidth;
+
+
+			parentWidth = this._width;
+			// console.log('this._width============' + this._width);
+			// console.log('ellipsisWidth============' + ellipsisWidth);
+			ruler.innerHTML = str;
+			// console.log('ruler.scrollWidth============' + ruler.scrollWidth);
+			if (ruler.scrollWidth > parentWidth) {
+				var size = str.length,
+					min = 0,
+					max = size;
+				for (var i = 1; i <= size; i++) {
+					ruler.innerHTML = str.substring(0, i);
+					if (ruler.scrollWidth > parentWidth) {
+						i--;
+						break;
+					}
+				}
+				if (i < size) {
+					this._trimContent = str.substring(0, i) + '...';
+					ele.innerHTML = this._trimContent;
+					this._parent.removeChild(ruler);
+					ruler = null;
+					return i;
+				} else {
+					this._trimContent = null;
+					this._parent.removeChild(ruler);
+					ruler = null;
+					return -1;
+				}
+			} else {
+				this._parent.removeChild(ruler);
+				ruler = null;
+				this._trimContent = null;
+				return -1;
+			}
+			if (position) {
+				//$(ruler).css('position',position);
+				ruler.style.position = position;
+			}
+
+		}
+	};
+})();

+ 51 - 0
src/lib/mockapi/collection.json

@@ -0,0 +1,51 @@
+{
+  "code": 200,
+  "msg": "success",
+  "success": true,
+  "data": {
+    "totalNumber": 50,
+    "pageNo": 1,
+    "pageSize": 20,
+    "recs": [{
+      "id": "1101aaa",
+      "code": "C001",
+      "type": "COURSE",
+      "title": "国学日",
+      "subTitle": "中国经典故事(上)",
+      "breadcrumb": "国学日 - 中国经典故事(上)",
+      "coverUrl": "resources/J/01/03/400002.png"
+    }, {
+      "id": "1101bbb",
+      "code": "C002",
+      "type": "COURSE",
+      "title": "语文",
+      "subTitle": "三年级 - 下册",
+      "breadcrumb": "语文 三年级-下册",
+      "coverUrl": "resources/J/01/03/700021.jpg"
+    }, {
+      "id": "1101ccc",
+      "code": "C003",
+      "type": "COURSE",
+      "title": "学会自我管理",
+      "subTitle": "好习惯",
+      "breadcrumb": "好习惯 养成记",
+      "coverUrl": "resources/C/09/01/01/01.jpg"
+    }, {
+      "id": "1101ddd",
+      "code": "C004",
+      "type": "COURSE",
+      "title": "[初级]感知世界-上",
+      "subTitle": "趣玩生活奥秘",
+      "breadcrumb": "感知世界 适用于一|二年级",
+      "coverUrl": "resources/J/01/03/600002.jpg"
+    }, {
+      "id": "1101eee",
+      "code": "C005",
+      "type": "COURSE",
+      "title": "语文",
+      "subTitle": "一年级 - 上册",
+      "breadcrumb": "语文 一年级-上册",
+      "coverUrl": "resources/J/01/03/000005.png"
+    }]
+  }
+}

+ 39 - 0
src/lib/mockapi/course_detail.json

@@ -0,0 +1,39 @@
+{
+  "code": 200,
+  "msg": "success",
+  "success": true,
+  "data": {
+    "id": "1011aaa",
+    "auth": 1,
+    "collected": 1,
+    "code": "C001",
+    "title": "国学日",
+    "bgUrl": "resources/J/01/04/400002.jpg",
+    "breadcrumb": "国学日 - 中国经典故事(上)",
+    "beginTime": 158972022000,
+    "endTime": 158985022000,
+    "digest": "一站式解决教师备课、上课和学情检测;学生新知、巩固和知识拓展",
+    "detail": "动画辅助教学。专业的动画制作团队精心打造。本课程为小学三年级学生设计。巧用媒体,情境导入,激发孩子的学习语文知识的兴趣;巧设环节,查缺补漏,使知识系统化。三年级是小学的转折点,语言趋向了精细化和审美。如何增强信心和效率是关注学生学习的重心",
+    "goods": [{
+      "id": "3734a12b78913247813427",
+      "chargeUnit": "季",
+      "terminalPrice": 70000,
+      "isInCart": 1
+    }, {
+      "id": "342189adfsjkafdsjkl34",
+      "chargeUnit": "半年",
+      "terminalPrice": 8000,
+      "isInCart": 0
+    }, {
+      "id": "321945234893429834289",
+      "chargeUnit": "年",
+      "terminalPrice": 90000,
+      "isInCart": 0
+    }, {
+      "id": "3219489984893429834289",
+      "chargeUnit": "10年",
+      "terminalPrice": 180000,
+      "isInCart": 0
+    }]
+  }
+}

+ 27 - 0
src/lib/mockapi/course_lesson.json

@@ -0,0 +1,27 @@
+{
+  "code": 200,
+  "msg": "success",
+  "success": true,
+  "data": {
+    "auth": 1,
+    "collected": 1,
+    "breadcrumb": "国学日 - 中国经典故事(上)",
+    "recs": [{
+      "id": "2011aaa",
+      "code": "L001",
+      "name": "画龙点睛"
+    }, {
+      "id": "2011bbb",
+      "code": "L002",
+      "name": "孔融让梨"
+    }, {
+      "id": "2011ccc",
+      "code": "L003",
+      "name": "只要功夫深,铁杵磨成针"
+    }, {
+      "id": "2011ddd",
+      "code": "L004",
+      "name": "怀素写字"
+    }]
+  }
+}

+ 19 - 0
src/lib/mockapi/course_supports.json

@@ -0,0 +1,19 @@
+{
+  "code": 200,
+  "success": true,
+  "msg": "success",
+  "data": {
+    "recs": [{
+      "id": "23138490ASJKJKJK",
+      "code": "S001",
+      "title": "写字教材",
+      "subTitle": "语文一年级上册",
+      "coverUrl": "resources/J/01/08/000011.jpg",
+      "goods": [{
+        "id": "fdjsak34289",
+        "terminalPrice": 29.8,
+        "chargeUnit": "件"
+      }]
+    }]
+  }
+}

+ 33 - 0
src/lib/mockapi/product_list.json

@@ -0,0 +1,33 @@
+{
+  "code": 200,
+  "success": true,
+  "msg": "success",
+  "data": {
+    "pageNum": 1,
+    "pageSize": 20,
+    "totalNumber": 2,
+    "recs": [{
+      "id": "23138490ASJKJKJK",
+      "code": "S001",
+      "title": "写字教材",
+      "subTitle": "语文一年级上册",
+      "coverUrl": "resources/J/01/08/000011.jpg",
+      "goods": [{
+        "id": "fdjsak34289",
+        "terminalPrice": 29.8,
+        "chargeUnit": "件"
+      }]
+    }, {
+      "id": "31429817324098",
+      "code": "C001",
+      "title": "",
+      "subTitle": "语文一年级上册",
+      "coverUrl": "resources/J/01/08/000011.jpg",
+      "goods": [{
+        "id": "fdjsak34289",
+        "terminalPrice": 29.8,
+        "chargeUnit": "件"
+      }]
+    }]
+  }
+}

+ 45 - 0
src/lib/mockapi/recommend.json

@@ -0,0 +1,45 @@
+{
+  "code":200,
+  "msg": "success",
+  "success": true,
+  "data": {
+    "recs":[
+      {
+        "id": "1101aaa",
+        "code": "C001",
+        "title": "国学日",
+        "subTitle": "中国经典故事(上)",
+        "breadcrumb": "国学日 - 中国经典故事(上)",
+        "coverUrl": "resources/J/01/03/400002.png"
+      }, {
+        "id": "1101bbb",
+        "code": "C002",
+        "title": "语文",
+        "subTitle": "三年级 - 下册",
+        "breadcrumb": "语文 三年级-下册",
+        "coverUrl": "resources/J/01/03/700021.jpg"
+      }, {
+        "id": "1101ccc",
+        "code": "C003",
+        "title": "学会自我管理",
+        "subTitle": "好习惯",
+        "breadcrumb": "好习惯 养成记",
+        "coverUrl": "resources/C/09/01/01/01.jpg"
+      }, {
+        "id": "1101ddd",
+        "code": "C004",
+        "title": "[初级]感知世界-上",
+        "subTitle": "趣玩生活奥秘",
+        "breadcrumb": "感知世界 适用于一|二年级",
+        "coverUrl": "resources/J/01/03/600002.jpg"
+      }, {
+        "id": "1101eee",
+        "code": "C005",
+        "title": "语文",
+        "subTitle": "一年级 - 上册",
+        "breadcrumb": "语文 一年级-上册",
+        "coverUrl": "resources/J/01/03/000005.png"
+      }
+    ]
+  }
+}

+ 9 - 0
src/lib/mockapi/shopcart.json

@@ -0,0 +1,9 @@
+{
+  "code": 200,
+  "msg": "success",
+  "success": true,
+  "data": {
+    "name": "张贺",
+    "mobile": "18233561120"
+  }
+}

+ 37 - 0
src/lib/mockapi/shopcart_list.json

@@ -0,0 +1,37 @@
+{
+  "code": 200,
+  "success": true,
+  "data": {
+    "totalNumber": 15,
+    "pageSize": 10,
+    "pageNum": 0,
+    "recs": [{
+      "id": "0x31279fdsajk318409",
+      "pid": "c8934783483478",
+      "title": "国学日",
+      "subTitle": "中国经典故事(上)",
+      "type": "COURSE",
+      "coverUrl": "resources/J/01/03/400002.png",
+      "terminalPrice": 500,
+      "chargeUnit": "季"
+    }, {
+      "id": "23138490ASJKJKJK",
+      "pid": "xxx38941xxx",
+      "title": "写字教材",
+      "subTitle": "语文一年级上册",
+      "type": "SUPPORT",
+      "coverUrl": "resources/J/01/08/000011.jpg",
+      "terminalPrice": 29.8,
+      "chargeUnit": "件"
+    }, {
+      "id": "233498483948923fdjak0ASJKJKJK",
+      "pid": "xxx38941xxx",
+      "title": "写字教材",
+      "subTitle": "语文一年级上册",
+      "type": "SUPPORT",
+      "coverUrl": "resources/J/01/08/000011.jpg",
+      "terminalPrice": 29.8,
+      "chargeUnit": "件"
+    }]
+  }
+}

+ 7 - 0
src/lib/mockapi/shopcart_number.json

@@ -0,0 +1,7 @@
+{
+  "code": 200,
+  "success": true,
+  "data": {
+    "totalNumber": 15
+  }
+}

+ 42 - 0
src/lib/mockapi/support_detail.json

@@ -0,0 +1,42 @@
+{
+  "code": 200,
+  "msg": "success",
+  "success": true,
+  "data": {
+    "id": "supportid1111",
+    "code": "S001",
+    "title": "5·3天天练",
+    "subTitle": "语文一年级上册",
+    "detail": "《5·3天天练》配合义务教育课程标准实验教科书使用,组合形式为“练+讲+答案解析”。产品主要定位于学生对课文或课时所学知识的巩固提升,渗透学科的学习方法,重积累、重实践、重感悟、重学习能力的培养与练习。同时配备了详细的答案解析,帮助教师站在学生未知的角度上对学生进行辅导。",
+    "coverUrl": "resources/J/01/08/000011.jpg",
+    "isInCart": 0,
+    "imgList": [
+      "resources/J/01/08/000011.jpg",
+      "resources/J/01/08/000011.jpg",
+      "resources/J/01/08/000011.jpg"
+    ],
+    "goods": [{
+      "id": "fdjsak34289",
+      "terminalPrice": 29.8,
+      "chargeUnit": "件"
+    }],
+    "relatedSupports": [{
+      "id": "xx1",
+      "code": "codexx1",
+      "coverUrl": "resources/J/01/09/000012.jpg"
+    }, {
+      "id": "xx2",
+      "code": "codexx2",
+      "coverUrl": "resources/J/01/08/000005.jpg"
+    }],
+    "relatedCourses": [{
+      "id": "yy1",
+      "code": "codeyy1",
+      "title": "语文一"
+    }, {
+      "id": "yy2",
+      "code": "codeyy2",
+      "title": "语文二"
+    }]
+  }
+}

+ 49 - 0
src/lib/mockapi/tag_list.json

@@ -0,0 +1,49 @@
+{
+  "code": 200,
+  "msg": "success",
+  "success": true,
+  "data": {
+    "name": "多元兴趣课",
+    "showFirst": {
+      "tagId": "tag-id-001",
+      "recs": [{
+        "id": "course-id-001",
+        "code": "C001",
+        "type": "COURSE",
+        "title": "国学日",
+        "subTitle": "中国经典故事(上)",
+        "breadcrumb": "国学日 - 中国经典故事(上)",
+        "coverUrl": "resources/J/01/03/400002.png"
+      }, {
+        "id": "course-id-002",
+        "code": "C002",
+        "type": "COURSE",
+        "title": "国学日",
+        "subTitle": "中国经典故事(上)",
+        "breadcrumb": "国学日 - 中国经典故事(上)",
+        "coverUrl": "resources/J/01/03/400002.png"
+      }, {
+        "id": "course-id-003",
+        "code": "C003",
+        "type": "COURSE",
+        "title": "国学日",
+        "subTitle": "中国经典故事(上)",
+        "breadcrumb": "国学日 - 中国经典故事(上)",
+        "coverUrl": "resources/J/01/03/400002.png"
+      }]
+    },
+    "recs": [{
+      "id": "tag-id-001",
+      "name": "标签一"
+    }, {
+      "id": "tag-id-002",
+      "name": "标签二"
+    }, {
+      "id": "tag-id-003",
+      "name": "标签三"
+    }, {
+      "id": "tag-id-004",
+      "name": "标签四"
+    }]
+  }
+}

+ 13 - 0
src/lib/mockapi/terminal.json

@@ -0,0 +1,13 @@
+{
+  "code": 200,
+  "msg": "success",
+  "success": true,
+  "data": {
+    "id": "34783adsfjk31298afdk",
+    "eid": "666643010001001",
+    "name": "湖南省长沙市阜宁校区",
+    "merchantName": "贝尔安亲",
+    "merchantContactName": "谭亮",
+    "merchantContactMobile": "18233568890"
+  }
+}

+ 10 - 0
src/lib/mockapi/token.json

@@ -0,0 +1,10 @@
+{
+  "code": 200,
+  "success": true,
+  "data": {
+    "uid": "qewrupizxvcdfsa",
+    "eid": "666643010001001",
+    "name": "湖南省长沙市阜宁校区教室六",
+    "token": "1c2v3dsjf89fads89dfd34423"
+  }
+}

+ 38 - 0
src/lib/mockapi/ware_list.json

@@ -0,0 +1,38 @@
+{
+  "code": 200,
+  "msg": "success",
+  "success": true,
+  "data": {
+    "recs": [{
+      "id": "lessonid001",
+      "code": "L001",
+      "category": "教学指导",
+      "title": "教师参考教学流程",
+      "type": 0,
+      "resources": [{
+        "id": "resourceid001",
+        "type": "IMAGE",
+        "url": "resources/J/02/01/401702.jpg"
+      }, {
+        "id": "resourceid002",
+        "type": "IMAGE",
+        "url": "resources/J/02/01/401701.jpg"
+      }, {
+        "id": "resourceid003",
+        "type": "IMAGE",
+        "url": "resources/J/02/01/601801.jpg"
+      }]
+    }, {
+      "id": "lessonid002",
+      "code": "L002",
+      "category": "科学发现",
+      "title": "迷你动画片",
+      "type": 1,
+      "resources": [{
+        "id": "resource-id-001",
+        "type": "VIDEO",
+        "url": "/hd1m/048/04802007/hd04802007002/hd04802007002.m3u8"
+      }]
+    }]
+  }
+}

+ 25 - 0
src/manifest.json

@@ -0,0 +1,25 @@
+{
+  "package": "tob.tv.efunbox.com",
+  "versioncode": 2100100000,
+  "versionname": "1.0.0",
+  "use-sdk": "yunos_webos_v1.0",
+  "label": "@title",
+  "icon": "res/img/icon.png",
+  "developer": "efunbox",
+  "permissions": [],
+  "use-permissions": [
+    {"name": "INTERNET.permission.yunos.com"}
+  ],
+  "stages": {
+    "index": {
+      "description": "This is main stage.",
+      "entry": "stage/index/index.html",
+      "type": "web",
+      "category": [
+        "yunos.category.main"
+      ],
+      "require-permissions": [],
+      "background-color": "#ffffffff"
+    }
+  }
+}

BIN
src/res/img/default_bg.jpg


BIN
src/res/img/icon.png


+ 7 - 0
src/res/tpl/BuyConfirmScene.tpl

@@ -0,0 +1,7 @@
+<div id="BuyConfirmScene" class="course-buy-wrapper" fe-role="Switch">
+	<div class="toast">
+		<img src="./../../stage/index/assets/img/shopCart.png" alt="">
+		<p class="buy-name" id="buy-name">确认购买</p>
+		<div class="buy" fe-role="Widget" id="buy-btn">去购买</div>
+	</div>
+</div>

+ 24 - 0
src/res/tpl/CLScene.tpl

@@ -0,0 +1,24 @@
+<div id="CLScene" fe-role="Switch">
+	<div class="cl-bg"><img id="CLSceneBG" src="assets/img/CLScene/background.jpg" alt=""></div>
+    <div id="cl-left-panel">
+        <div id="name-text"></div>
+        <div id="cl-left-tab-scroll" fe-role="Scroll" fe-cfg="scroll_dir:v">
+            <ul id="cl-left-tab-list" class="scroll-list"></ul>
+        </div>
+    </div>
+    <div id="cl-right-panel">
+        <div class="control-panel">
+            <div id="cl-shopping-cart-btn" class="shopping-cart-btn-frame" fe-role="Widget">
+                <img src="./assets/img/CLScene/icon_shopcart.png" />
+            </div>
+            <div class="cart-num"></div>
+        </div>
+        <div id="cl-right-content-scroll" fe-role="Scroll" fe-cfg="scroll_dir:v">
+            <ul id="cl-right-content-list" class="scroll-list" >
+            </ul>
+            <div id="no-content-message" style="display:none;">
+                无内容
+            </div>
+        </div>
+    </div>
+</div>

+ 18 - 0
src/res/tpl/CourseScene.tpl

@@ -0,0 +1,18 @@
+<div id="CourseScene" class="course clearfix" fe-role="Switch">
+	<div class="course-bg">
+		<img id="course-bg" src="assets/img/course/bg.jpg">
+	</div>
+	<div class="header">
+		<div class="course-name" id="course-name"></div>
+		<div class="nav" fe-role="Switch" id="course-nav">
+			<div fe-role="Widget" id="course-tab-list" class="nav-item list"></div>
+			<div fe-role="Widget" id="course-tab-detail" class="nav-item detail"></div>
+			<div fe-role="Widget" id="course-tab-periphery" class="nav-item periphery"></div>
+			<div fe-role="Widget" id="course-tab-collect" class="nav-item collect"></div>
+			<div fe-role="Widget" id="course-tab-cart" class="nav-item cart">
+				<div class="cart-num" id="cart-num"></div>
+			</div>
+		</div>
+	</div>
+	<div class="main" id="course-main"></div>
+</div>

+ 3 - 0
src/res/tpl/DataBuildingScene.tpl

@@ -0,0 +1,3 @@
+<div id="DataBuildingScene" fe-role="Switch">
+    <img id="building-pic-bg"  src="http://ljimgs.ai160.com/2b/app_resource/data_building.jpg" alt="数据正在建设中...">
+</div>

+ 8 - 0
src/res/tpl/DelConfirmScene.tpl

@@ -0,0 +1,8 @@
+<div id="DelConfirmScene" class="shop-cart-del-wrapper" fe-role="Switch">
+	<div class="toast">
+		<img src="./../../stage/index/assets/img/ShopCartScene/del.png" alt="">
+		<p class="del-name" id="del-name">确认删除吗</p>
+		<div class="del" fe-role="Widget" id="del-btn">删除</div>
+		<div class="cancle" fe-role="Widget" id="cancle-btn">取消</div>
+	</div>
+</div>

+ 107 - 0
src/res/tpl/DownloadScene.tpl

@@ -0,0 +1,107 @@
+<div id="DownloadManagerScene" fe-role="Switch">
+	<div class="download-manager-bg">
+		<img src="./assets/img/GlobalGoodDetail/background.jpg" alt="" />
+	</div>
+  	<div class="local-download-icon">
+    	<img src="assets/img/DownloadScene/download.png" alt="" />
+    	<div>本地下载列表</div>
+  	</div>
+  	<div class="background-wrapper">
+		<div class="background-header">
+    		<div class="header">
+				<div class="row row-header">
+					<div class="one right-border">下载日期</div>
+					<div class="two right-border">课程名称</div>
+					<div class="three right-border">课名称</div>
+					<div class="four right-border">容量</div>
+					<div class="five right-border">下载状态</div>
+					<div class="six">操作</div>
+	    		</div>
+			</div>
+			<div class="horizon-line first-line"></div>
+			<div class="horizon-line"></div>
+			<div class="horizon-line"></div>
+			<div class="horizon-line"></div>
+			<div class="horizon-line"></div>
+			<div class="horizon-line"></div>
+			<div class="horizon-line"></div>
+			<div class="horizon-line"></div>
+			<div class="horizon-line"></div>
+    	</div>
+		<div class="back-row">
+			<div class="one"></div>
+			<div class="two"></div>
+			<div class="three"></div>
+			<div class="four"></div>
+			<div class="five"></div>
+			<div class="six"></div>
+    	</div>
+		<div class="back-row">
+			<div class="one"></div>
+			<div class="two"></div>
+			<div class="three"></div>
+			<div class="four"></div>
+			<div class="five"></div>
+			<div class="six"></div>
+	    </div>
+		<div class="back-row">
+			<div class="one"></div>
+			<div class="two"></div>
+			<div class="three"></div>
+			<div class="four"></div>
+			<div class="five"></div>
+			<div class="six"></div>
+	    </div>
+		<div class="back-row">
+			<div class="one"></div>
+			<div class="two"></div>
+			<div class="three"></div>
+			<div class="four"></div>
+			<div class="five"></div>
+			<div class="six"></div>
+		</div>
+		<div class="back-row">
+			<div class="one"></div>
+			<div class="two"></div>
+			<div class="three"></div>
+			<div class="four"></div>
+			<div class="five"></div>
+			<div class="six"></div>
+	  	</div>
+		<div class="back-row">
+			<div class="one"></div>
+			<div class="two"></div>
+			<div class="three"></div>
+			<div class="four"></div>
+			<div class="five"></div>
+			<div class="six"></div>
+    	</div>
+		<div class="back-row">
+			<div class="one"></div>
+			<div class="two"></div>
+			<div class="three"></div>
+			<div class="four"></div>
+			<div class="five"></div>
+			<div class="six"></div>
+    	</div>
+		<div class="back-row">
+			<div class="one"></div>
+			<div class="two"></div>
+			<div class="three"></div>
+			<div class="four"></div>
+			<div class="five"></div>
+			<div class="six"></div>
+	  	</div>
+		<div class="back-row">
+			<div class="one"></div>
+			<div class="two"></div>
+			<div class="three"></div>
+			<div class="four"></div>
+			<div class="five"></div>
+			<div class="six"></div>
+    	</div>
+    	<div fe-role="Scroll" fe-cfg="scroll_dir:v,scroll_center:con,scroll_duration:0.2,scroll_easing:linear" class="content-wrapper" >
+			<div class="scroll-list scroll-lines-wrapper clearfix" id="download-status-table-wrapper"></div>
+		</div>
+	</div>
+</div>

+ 38 - 0
src/res/tpl/GlobalGoodDetail.tpl

@@ -0,0 +1,38 @@
+<div id="GlobalGoodDetailScene" fe-role="Switch">
+    <div class="control-panel">
+        <!-- <div class="search-btn-frame" fe-role="Widget">
+            <img src="./assets/img/CLScene/search.png" />
+        </div> -->
+        <div class="shopping-cart-btn-frame" fe-role="Widget">
+            <img src="./assets/img/CLScene/shopping_cart.png" />
+        </div>
+        <div class="cart-num"></div>
+    </div>
+    <div class="detail-panel">
+        <div id="ggd-detail-cover" class="detail-cover"><div></div></div>
+        <div class="detail-text-panel">
+            <p id="ggd-detail-title" class="title">...</p>
+            <p id="ggd-detail-price" class="price">¥...</p>
+            <p id="ggd-detail-desc" class="desc">...
+            </p>
+            <div class="detail-control-panel" id="detail-control-panel">
+                <!-- <div id="add-cart-btn" class="add-shop-cart-btn-frame" fe-role="Widget">
+                    <img src="./assets/img/GlobalGoodDetail/add_shop_cart.png" />
+                </div>
+                <div id="goto-course-btn" class="play-btn-frame" fe-role="Widget" >
+                    <img src="./assets/img/GlobalGoodDetail/play_course.png" />
+                </div> -->
+            </div>
+        </div>
+    </div>
+    <div class="concerned-panel">
+        <p id="ggd-concerned-goods-count" class="concerned-goods-count"></p>
+        <div id="ggd-concerned-goods-scroll" fe-role="Scroll" fe-cfg="scroll_dir:h, auto_list_width:yes">
+            <ul id="ggd-concerned-goods-list" class="scroll-list" >
+                <!--<li class="item" fe-role="Widget">
+                    <img src="https://placeholdit.imgix.net/~text?txtsize=28&txt=Cover&w=114&h=114" />
+                </li>-->
+            </ul>
+        </div>
+    </div>
+</div>

+ 5 - 0
src/res/tpl/ImageWareFullScreen.tpl

@@ -0,0 +1,5 @@
+<div id="ImageWareFullScreen" fe-role="Switch">
+    <img id="wareImg" src="./assets/img/default_bg.jpg" />
+    <img id="imgLeft" src="./assets/img/LessonScene/arrow_left.png" />
+    <img id="imgRight" src="./assets/img/LessonScene/arrow_right.png" />
+</div>

+ 34 - 0
src/res/tpl/IndexScene.tpl

@@ -0,0 +1,34 @@
+<div id="IndexScene" fe-role="Switch">
+	<div class="index-bg"><img src="assets/img/IndexScene/background.jpg" alt=""></div>
+ 	<div class="m-header-user" fe-role="Switch">
+		<div fe-role="Widget" class="user-info" id="user-info">
+			<div class="user-info-text">
+				<div id="terminal-name" class="terminal-name">未登陆, 请先点击这里</div>
+				<div id="terminal-id" class="terminal-id">再点击"退出账号"回到登陆页</div>
+			</div>
+		</div>
+	</div>
+	<!-- 首页底部的五个入口 -->
+	<div id="index-scroll" class="m-main" fe-role="Scroll" fe-cfg="scroll_dir:v,scroll_duration:0.2,scroll_easing:linear">
+		<div class="scroll-list">
+			<div id="history" class="history-wrapper"></div>
+			<div id="fun" class="fun-wrapper">
+				<div id="fun-download" class="fun-item" fe-role="Widget">
+					<img src="./../../stage/index/assets/img/IndexScene/entrance_download.png"/>
+				</div>
+				<div id="fun-collection" class="fun-item" fe-role="Widget">
+					<img src="./../../stage/index/assets/img/IndexScene/entrance_collection.png"/>
+				</div>
+				<div id="fun-resource" class="fun-item" fe-role="Widget">
+					<img src="./../../stage/index/assets/img/IndexScene/entrance_resource.png"/>
+				</div>
+				<div id="fun-periphery" class="fun-item" fe-role="Widget">
+					<img src="./../../stage/index/assets/img/IndexScene/entrance_periphery.png"/>
+				</div>
+				<div id="fun-training" class="fun-item" fe-role="Widget">
+					<img src="./../../stage/index/assets/img/IndexScene/entrance_training.png"/>
+				</div>
+			</div>
+		</div>
+	</div>
+</div>

+ 11 - 0
src/res/tpl/LessonScene.tpl

@@ -0,0 +1,11 @@
+<div id="LessonScene" fe-role="Switch">
+	<div id="title"></div>
+	<div id="list" fe-role="Scroll" fe-cfg="scroll_dir:v">
+		<div id="list-content" class="scroll-list"></div>
+	</div>
+	<div id="view">
+		<div id="view-top"></div>
+		<div id="view-content"></div>
+		<div id="view-bottom"></div>
+	</div>
+</div>

+ 61 - 0
src/res/tpl/LoginScene.tpl

@@ -0,0 +1,61 @@
+<div id="LoginScene" fe-role="Switch">
+	<div class="formBox" fe-role="Switch">
+		<div class="form-sid">
+			<div class="form-sid-label">
+				学&nbsp;&nbsp;号
+			</div>
+			<div class="form-sid-input">
+				<input id="sid-input" class="form-item" name="sid" type="text" readonly fe-role="Widget"/>
+			</div>
+		</div>
+		<div class="form-password">
+			<div class="form-password-label">
+				密&nbsp;&nbsp;码
+			</div>
+			<div class="form-password-input">
+				<input id="password-input" class="form-item" name="password" type="text" readonly fe-role="Widget"/>
+			</div>
+		</div>
+		<div class="form-submit">
+			<input class="form-item" type="submit" id="submit-input" value="登  录" fe-role="Widget"/>
+		</div>
+	</div>
+	<div class="keyborad" fe-role="Switch">
+		<div id="key-1" class="keyborad-item" fe-role="Widget">
+			<div class="key-icon one"></div>
+		</div>
+		<div id="key-2" class="keyborad-item" fe-role="Widget">
+			<div class="key-icon two"></div>
+		</div>
+		<div id="key-3" class="keyborad-item" fe-role="Widget">
+			<div class="key-icon three"></div>
+		</div>
+		<div id="key-4" class="keyborad-item" fe-role="Widget">
+			<div class="key-icon four"></div>
+		</div>
+		<div id="key-5" class="keyborad-item" fe-role="Widget">
+			<div class="key-icon five"></div>
+		</div>
+		<div id="key-6" class="keyborad-item" fe-role="Widget">
+			<div class="key-icon six"></div>
+		</div>
+		<div id="key-7" class="keyborad-item" fe-role="Widget">
+			<div class="key-icon seven"></div>
+		</div>
+		<div id="key-8" class="keyborad-item" fe-role="Widget">
+			<div class="key-icon eight"></div>
+		</div>
+		<div id="key-9" class="keyborad-item" fe-role="Widget">
+			<div class="key-icon nine"></div>
+		</div>
+		<div id="key-0" class="keyborad-item" fe-role="Widget">
+			<div class="key-icon zero"></div>
+		</div>
+		<div id="key-backspace" class="keyborad-item" fe-role="Widget">
+			<div class="key-icon backspace"></div>
+		</div>
+		<div id="key-enter" class="keyborad-item" fe-role="Widget">
+			<div class="key-icon enter"></div>
+		</div>
+	</div>
+</div>

+ 13 - 0
src/res/tpl/QuitConfirmScene.tpl

@@ -0,0 +1,13 @@
+<div id="QuitConfirmScene" fe-role="Switch">
+    <div class="quit-app-bg">
+        <img src="http://ljimgs.ai160.com/2b/app_resource/app_quit_confirm_1116.jpg" alt="" />
+    </div>
+    <div class="btn-select-wrapper">
+        <div id="ret-btn" class="cancel" fe-role="Widget">
+            <img src="assets/img/QuitConfirmScene/focusIcon.png" alt="" />
+        </div>
+        <div id="end-btn" class="exit" fe-role="Widget">
+            <img src="assets/img/QuitConfirmScene/focusIcon.png" alt="" />
+        </div>
+    </div>
+</div>

+ 14 - 0
src/res/tpl/RepeatLoginScene.tpl

@@ -0,0 +1,14 @@
+<div id="RepeatLoginScene" class="repeat-login-prompt-wrapper" fe-role="Switch">
+  <div class="prompt-wrapper">
+    <div class="prompt-bg">
+  	  <img src="./../../stage/index/assets/img/RepeatLoginScene/repeat_login_bg.png" alt="">
+    </div>
+    <div class="prompt-msg">
+  	  <p>有老师在使用这个账号,</p>
+      <p>现在您不能使用。</p>
+    </div>
+    <div class="iknow" id="iknow-btn" fe-role="Widget">
+      <img src="./../../stage/index/assets/img/repeat_login_ikonw_btn.png" alt="">
+    </div>
+  </div>
+</div>

+ 9 - 0
src/res/tpl/ShopCartCheckScene.tpl

@@ -0,0 +1,9 @@
+<div id="ShopCartCheckScene" class="shop-cart-toast-wrapper" fe-role="Switch">
+    <div class="toast">
+        <img src="./../../stage/index/assets/img/ShopCartScene/check.png" alt="">
+        <p class="send-success">购买信息发送成功!</p>
+        <p class="contact-manage">请联系管理员进行购买</p>
+        <p class="manage"></p>
+        <p class="tel"></p>
+    </div>
+</div>

+ 13 - 0
src/res/tpl/ShopCartScene.tpl

@@ -0,0 +1,13 @@
+<div id="ShopCartScene" fe-role="Switch">
+	<div class="cart-bg"><img id="cart-bg" src="assets/img/ShopCartScene/shop_cart_bg.jpg" alt=""></div>
+	<p class="cart-name" fe-role="Widget" id="cart-name">购物车</p>
+	<div id="cart-empty" class="cart-empty">
+		<p class="empty-text">还没有添加商品</p>
+		<div class="back-icon">
+		<img src="assets/img/shopCart/backText.png" alt=""></div>
+	</div>
+	<div class="shop-cart-wrapper clearfix" fe-role="Scroll" fe-cfg="scroll_dir:h, auto_list_width:yes, scroll_right_padding: 3rem">
+		<div class="scroll-list" id="shop-cart-wrapper"></div>
+	</div>
+	<div fe-role="Widget" class="send-msg" id="send-msg"></div>
+</div>

+ 3 - 0
src/res/tpl/SplashScene.tpl

@@ -0,0 +1,3 @@
+<div id="SplashScene" fe-role="Switch">
+    <img src="assets/img/SplashScene/splash.jpg" alt="">
+</div>

+ 7 - 0
src/res/tpl/TerminalScene.tpl

@@ -0,0 +1,7 @@
+<div id="TerminalScene" fe-role="Switch">
+	<div class="terminal-bg">
+		<img src="assets/img/TerminalScene/background.jpg" alt="">
+	</div>
+	<ul fe-role="Switch" class="terminal-wrapper clearfix" id="terminal-wrapper"></ul>
+	<div class="terminal-quit" id="terminal-quit" fe-role="Widget" fe-cfg="default_focus:yes"></div>
+</div>

+ 1 - 0
src/res/tpl/VideoWareFullScreen.tpl

@@ -0,0 +1 @@
+<div id="VideoWareFullScreen" fe-role="Switch"></div>

+ 3 - 0
src/res/values/value.json

@@ -0,0 +1,3 @@
+{
+  "title": "双师教育平台"
+}

+ 3 - 0
src/res/values/value_en.json

@@ -0,0 +1,3 @@
+{
+  "title":"Moye Demo"
+}

BIN
src/stage/index/assets/img/CLScene/background.jpg


BIN
src/stage/index/assets/img/CLScene/icon_shopcart.png


BIN
src/stage/index/assets/img/CourseScene/bg.jpg


BIN
src/stage/index/assets/img/CourseScene/bg.png


BIN
src/stage/index/assets/img/CourseScene/cart.png


BIN
src/stage/index/assets/img/CourseScene/cart_selected.png


BIN
src/stage/index/assets/img/CourseScene/collect.png


BIN
src/stage/index/assets/img/CourseScene/collected.png


BIN
src/stage/index/assets/img/CourseScene/course_buy.png


BIN
src/stage/index/assets/img/CourseScene/course_buyed.png


BIN
src/stage/index/assets/img/CourseScene/data_not_ready.jpg


BIN
src/stage/index/assets/img/CourseScene/detail.png


BIN
src/stage/index/assets/img/CourseScene/detail/add_cart.png


BIN
src/stage/index/assets/img/CourseScene/detail/added.png


BIN
src/stage/index/assets/img/CourseScene/detail/added_cart.png


BIN
src/stage/index/assets/img/CourseScene/detail/buyed.png


BIN
src/stage/index/assets/img/CourseScene/detail/month_add_cart.png


BIN
src/stage/index/assets/img/CourseScene/detail/periphery_add_cart.png


BIN
src/stage/index/assets/img/CourseScene/detail/periphery_added.png


BIN
src/stage/index/assets/img/CourseScene/detail/renewal_fee.png


BIN
src/stage/index/assets/img/CourseScene/detail/season_add_cart.png


BIN
src/stage/index/assets/img/CourseScene/detail/year_add_cart.png


BIN
src/stage/index/assets/img/CourseScene/detail_selected.png


BIN
src/stage/index/assets/img/CourseScene/download_btn_icon_ongoing.gif


BIN
src/stage/index/assets/img/CourseScene/download_btn_icon_ongoing.png


BIN
src/stage/index/assets/img/CourseScene/download_btn_icon_success.png


BIN
src/stage/index/assets/img/CourseScene/download_btn_icon_undownload.png


BIN
src/stage/index/assets/img/CourseScene/download_btn_list_ongoing.gif


BIN
src/stage/index/assets/img/CourseScene/download_btn_list_ongoing.png


BIN
src/stage/index/assets/img/CourseScene/download_btn_list_success.png


BIN
src/stage/index/assets/img/CourseScene/download_btn_list_undownload.png


BIN
src/stage/index/assets/img/CourseScene/left.png


BIN
src/stage/index/assets/img/CourseScene/list.png


BIN
src/stage/index/assets/img/CourseScene/list_selected.png


BIN
src/stage/index/assets/img/CourseScene/name_wrapper.png


BIN
src/stage/index/assets/img/CourseScene/periphery.png


BIN
src/stage/index/assets/img/CourseScene/periphery_selected.png


BIN
src/stage/index/assets/img/CourseScene/right.png


BIN
src/stage/index/assets/img/DownloadScene/download.png


+ 0 - 0
src/stage/index/assets/img/DownloadScene/download_del_btn.png


Some files were not shown because too many files changed in this diff