text: var ready = require('./auth')
  var mixin = require('../common/mixin')
  var noop = function () {}
  var win = typeof window !== 'undefined' ? window : {}
  var Promise = win.Promise || require('pinkie')
  var wx = () => {
    return window.wx || ( ({ fail=noop }) => fail({error: -1, msg: 'wx sdk is not loaded'}) )
  }
  
  /**
   * 微信官方文档
   * http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#.E6.A6.82.E8.BF.B0
   * **/
  
  /** constants **/
  var WECHAT_FRIENDS = 'WCF'
  var WECHAT_TIMELINE = 'WCT'
  var QQ = 'QQ'
  var QZONE = 'QZONE'
  /** constants **/
  
  function uploadImages (localIds) {
    var ids = localIds.concat()
    var photos = []
    return new Promise((resolve, reject) => {
      function uploadSingleImage () {
        var localId = ids.shift()
        if (!localId) resolve(photos)
        wx().uploadImage({
          localId,
          success: function (photo) {
            photos.push(photo)
            uploadSingleImage()
          },
          fail: reject
        })
      }
      uploadSingleImage()
    })
  }
  
  var KNB = {
    use: function (name, options) {
      if (KNB[name] && !KNB[name].NOTIMPLEMENTED) return KNB[name](options)
      if (wx()[name]) wx()[name](options)
    },
  
    getUA: require('../common/get-ua'),
  
    isApiSupported: ({apiName, success=noop }) => {
      return success(!!(KNB[apiName] && !KNB[apiName].NOTIMPLEMENTED))
    },
    previewImage: (config) => wx().previewImage(config),
    // 建议只用count
    chooseImage: ({count, success=noop, fail=noop }) => {
      wx().chooseImage({
        count: count,
        success: (res) => {
          success({
            photoInfos: res.localIds.map(id => ({localId: id}))
          })
        },
      fail})
    },
    uploadImage: (config) => {
      var { localIds=[], success=noop, fail=noop } = config
  
      uploadImages(localIds)
        .then((photos) => {
          success({
            photoInfos: photos.map(photo => mixin(photo, {picUrl: photo.serverId, picKey: photo.serverId})
            )
          })
        })
        .catch(fail)
    },
    downloadImage: (config) => wx().downloadImage(config),
  
    getNetworkType: (config) => wx().getNetworkType(config),
    closeWindow: (config) => wx().closeWindow(config),
  
    // constants
    share: {
      WECHAT_FRIENDS,
      WECHAT_TIMELINE,
      QQ,
    QZONE},
  
    // share
    // mapping from
    // [knb api]
    //   title:"分享标题",
    //   desc:"分享描述",
    //   image:"http://www.dpfile.com/toevent/img/16d05c85a71b135edc39d197273746d6.png",
    //   url:"http://m.dianping.com",
    //   channel: [KNB.share.WECHAT_FRIENDS,KNB.share.WECHAT_TIMELINE],
    // to
    // [wx api]
    //   title: '', // 分享标题
    //   desc: '', //分享描述
    //   link: '', // 分享链接
    //   imgUrl: '', // 分享图标
    configShare: function ({title, desc='', image='', url='', channel=[WECHAT_FRIENDS, WECHAT_TIMELINE, QQ, QZONE], success=noop, fail=noop }) {
      channel
        .map(c => {
          switch (c) {
            case KNB.share.WECHAT_FRIENDS:
              return x => wx().onMenuShareAppMessage(x)
            case KNB.share.WECHAT_TIMELINE:
              return x => wx().onMenuShareTimeline(x)
            case KNB.share.QQ:
              return x => wx().onMenuShareQQ(x)
            case KNB.share.QZONE:
              return x => wx().onMenuShareQZone(x)
          }
        })
        .filter(Boolean)
        .forEach(configure => {
          configure({
            title: title,
            desc: desc,
            link: url,
            imgUrl: image,
            success,
          fail})
        })
    },
  
    getLocation: ({ fail=noop, success=noop }) => {
      wx().getLocation({
        fail,
        success: (res) => {
          success({
            lat: res.latitude,
            lng: res.longitude
          })
        }
      })
    }
  }
  
  // 所有API调用，自动放入ready里。
  // 如果用户没有主动调KNB.ready，这里会自动调起鉴权。
  var apis = require('../api')
  apis
    .concat('use')
    .forEach(name => {
      if (name === 'config') return
      var isImplemented = KNB[name]
      var method = KNB[name] || ( ({ fail=noop }) => fail({error: -1, msg: `API [${name}] is not implemented`}) )
      if (typeof method !== 'function') return
      KNB[name] = (a, b, c) => {
        KNB.ready(() => method(a, b, c))
      }
      if (!isImplemented) KNB[name].NOTIMPLEMENTED = true
      KNB[name].getSourceCode = () => method.toString() // for debug reason
    })
  
  if (typeof window !== 'undefined') {
    var version = require('../common/version');
    var logEvent = require('../common/log');
    // 统计wx调用次数
    logEvent("wx", version);
  }
  
  KNB.ready = ready; // 增加ready函数
  module.exports = KNB
  