diff --git a/campus/README.md b/campus/README.md
new file mode 100644
index 0000000..24762dd
--- /dev/null
+++ b/campus/README.md
@@ -0,0 +1,94 @@
+# 校园二手交易微信小程序
+校园二手交易微信小程序实现的功能:定位大学,当地天气,轮播图,推荐列表,购物车,发布功能,订单,身份验证等。
+**以下对每一项进行了简单的阐述,“详情”则是对每一项内容具体的描述。**
+## 首页
+首页实现了一些简单的功能,而且界面的设计也不是美观,设计的比较粗糙,后续会完善的功能是:用户下滑加载更多的内容,内容也会更加丰富。
+
+ Class used for all objects passed to error callbacks. Bmob.Events 是 fork of Backbone's Events module A module that can be mixed in to any object in order to provide
+ * it with custom events. You may bind callback functions to an event
+ * with `on`, or remove these functions with `off`.
+ * Triggering an event fires all callbacks in the order that `on` was
+ * called.
+ *
+ *
+
+#### 定位
+定位功能调用的是百度的接口,本来是想腾讯地图的,但是自己在使用的过程中,出现了一些错误(后续会完善腾讯地图的使用),导致调用接口失败了,然后才用的[百度地图web端的api](http://lbsyun.baidu.com/index.php?title=jspopular),而且官方给了代码实例,我们稍作修改即可使用。 [定位详情](https://blog.csdn.net/zyz00000000/article/details/82531397)
+
+
+#### 天气
+天气功能调用的是百度的接口,在百度地图官网给的代码实例里面除了位置功能,还有当地天气的数据,可以直接拿来使用。[天气详情](https://blog.csdn.net/zyz00000000/article/details/82531397)
+
+
+
+
+#### 轮播图
+轮播图直接用微信小程序的组件,<swiper>设置轮播图属性——> <block>循环遍历每一项——> <swiper-item>轮播每一项——> <image>每一项的图片。[详情](https://developers.weixin.qq.com/miniprogram/dev/component/swiper.html)
+
+
+下面是代码截图:
+
+
+
+
+#### 搜索框
+首页的所搜框用的是一张图片,当然这样的搜索框,微信小程序是有组件的,
+[微信小程序的icon组件](https://developers.weixin.qq.com/miniprogram/dev/component/icon.html)
+
+
+#### 滚动条
+我采用引入模板的方式,将这个功能写好后,引入到首页,同样用的<swiper>标签。[详情](https://developers.weixin.qq.com/miniprogram/dev/component/swiper.html)
+
+
+下面是代码截图:
+
+
+
+
+#### 四个分类功能
+分类功能实现的也比较简单,没有什么技术性的东西,或许wxss样式对你有所帮助。
+
+
+
+#### 今日推荐
+今日推荐功能使用了[微信小程序的scroll-view](https://developers.weixin.qq.com/miniprogram/dev/component/scroll-view.html),要注意的是,推荐好书和推荐好物在同一个页面,那么当点击“更多”的时候,要跳转到相应内容上。
+
+
+
+## 购物车
+购物车的实现也较为简单,将用户id和商品id传给后端,后端才能把对应的数据给前端。[详情](https://blog.csdn.net/zyz00000000/article/details/82532998)
+
+
+
+## 发布
+发布功能,注意一点,必填的内容都填了“发布”按钮才可以点击
+
+
+
+
+## 订单
+订单功能,请求数据,展示数据,没什么难度
+
+
+
+## 我的
+样式,每一项后面有的" > "是如何实现的呢?
+通过伪元素,transform: matrix()实现>的效果。
+
+
+
+
+
+
+## 身份验证
+#### 因为需要学校的学生身份才可以使用小程序的功能,这里给出一个测试的账号和密码
+#### 账号:20151621029 密码:666666
+
+
+### 校园兼职
+#### 用户可以通过小程序,发布兼职信息,发布的兼职信息会在“首页——校园兼职”中,可以在兼职列表中查看兼职的详情
+
+
+
+#### 当点击“家教老师”这则兼职的时候,会跳转到相应的详情页面
+
+
+### 商品详细
+
+
+#### 预约购买
+
diff --git a/campus/app.js b/campus/app.js
new file mode 100644
index 0000000..9faf77e
--- /dev/null
+++ b/campus/app.js
@@ -0,0 +1,162 @@
+//app.js
+var Bmob = require('utils/bmob.js');
+Bmob.initialize("59c6af950c7ae5ae07df0e5291cdf708", "1be7b1ea080e159e483a330dba10cd07");
+App({
+ onLaunch: function () {
+ var user = new Bmob.User();//开始注册用户
+ var newOpenid = wx.getStorageSync('openid')
+ // 展示本地存储能力
+ var logs = wx.getStorageSync('logs') || []
+ logs.unshift(Date.now())
+ wx.setStorageSync('logs', logs)
+
+ // 登录
+ if (!newOpenid) {
+ wx.login({
+ success: function (res) {
+ user.loginWithWeapp(res.code).then(function (user) {
+ var openid = user.get("authData").weapp.openid;
+ console.log(user, 'user', user.id, res);
+
+ if (user.get("nickName")) {
+ // 第二次访问
+ console.log(user.get("nickName"), 'res.get("nickName")');
+
+ wx.setStorageSync('openid', openid)
+ } else {
+
+ //保存用户其他信息
+ wx.getUserInfo({
+ success: function (result) {
+ var userInfo = result.userInfo;
+ var nickName = userInfo.nickName;
+ var avatarUrl = userInfo.avatarUrl;
+ var gender = userInfo.gender;
+ var u = Bmob.Object.extend("_User");
+ var query = new Bmob.Query(u);
+ // 这个 id 是要修改条目的 id,你在生成这个存储并成功时可以获取到,请看前面的文档
+ query.get(user.id, {
+ success: function (result) {
+ // 自动绑定之前的账号
+ result.set('nickName', nickName);
+ result.set("userPic", avatarUrl);
+ result.set("openid", openid);
+ result.set("gender", gender);
+
+ result.save();
+ }
+ });
+ }
+ });
+ }
+ }, function (err) {
+ console.log(err, 'errr');
+ });
+ }
+ });
+ }
+
+ // 获取用户信息
+ wx.getSetting({
+ success: res => {
+ if (res.authSetting['scope.userInfo']) {
+ // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
+ wx.getUserInfo({
+ success: res => {
+ // 可以将 res 发送给后台解码出 unionId
+ this.globalData.userInfo = res.userInfo
+
+ // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
+ // 所以此处加入 callback 以防止这种情况
+ if (this.userInfoReadyCallback) {
+ this.userInfoReadyCallback(res)
+ }
+ }
+ })
+ }
+ // res.authSetting['scope.userLocation'] == undefined 表示 初始化进入该页面
+ // res.authSetting['scope.userLocation'] == false 表示 非初始化进入该页面,且未授权
+ // res.authSetting['scope.userLocation'] == true 表示 地理位置授权
+ if (res.authSetting['scope.userLocation'] != undefined && res.authSetting['scope.userLocation'] != true) {
+ wx.showModal({
+ title: '请求授权当前位置',
+ content: '需要获取您的地理位置,请确认授权',
+ success: function (res) {
+ if (res.cancel) {
+ wx.showToast({
+ title: '拒绝授权',
+ icon: 'none',
+ duration: 1000
+ })
+ } else if (res.confirm) {
+ wx.openSetting({
+ success: function (dataAu) {
+ if (dataAu.authSetting["scope.userLocation"] == true) {
+ wx.showToast({
+ title: '授权成功',
+ icon: 'success',
+ duration: 1000
+ })
+ //再次授权,调用wx.getLocation的API
+
+ } else {
+ wx.showToast({
+ title: '授权失败',
+ icon: 'none',
+ duration: 1000
+ })
+ }
+ }
+ })
+ }
+ }
+ })
+ } else if (res.authSetting['scope.userLocation'] == undefined) {
+ //调用wx.getLocation的API
+ }
+ else {
+ //调用wx.getLocation的API
+ }
+
+ }
+ })
+ },
+ getUserInfo: function (cb) {
+ var that = this
+ if (this.globalData.userInfo) {
+ typeof cb == "function" && cb(this.globalData.userInfo)
+ } else {
+ //调用登录接口
+ wx.login({
+ success: function () {
+
+ wx.getUserInfo({
+ success: function (res) {
+ that.globalData.userInfo = res.userInfo
+ typeof cb == "function" && cb(that.globalData.userInfo)
+ }
+ })
+ }
+ })
+ }
+ },
+ globalData: {
+ userInfo: null
+ },
+ // 下拉刷新
+
+ // 获取电影的数据URL
+ globalData: {
+ userInfo: null,
+ // huanbaoBase: 'https://www.hukebme.com/', //唤宝的网址
+ huanbaoBase: 'http://192.168.0.111/',
+ // doubanBase: 'https://douban.uieee.com',
+ //huanbaoBase: 'http://localhost/',
+ ResourcesURL: '/v2/movie/search?q=',
+ inThearters: '/v2/movie/in_theaters',//热映
+ comingSoon: '/v2/movie/coming_soon',//即将上映
+ subject: '/v2/movie/subject/'
+ },
+
+
+})
\ No newline at end of file
diff --git a/campus/app.json b/campus/app.json
new file mode 100644
index 0000000..aa673ee
--- /dev/null
+++ b/campus/app.json
@@ -0,0 +1,85 @@
+{
+ "pages": [
+ "pages/shouye/shouye",
+ "pages/shoppingCart/shoppingCart",
+ "pages/my/my",
+ "pages/logs/logs",
+ "pages/index/index",
+ "pages/release/release",
+ "pages/order/order",
+ "pages/search/search",
+ "pages/search-book/search-book",
+ "pages/post/post",
+ "pages/weather/weather",
+ "pages/movie-detail/movie-detail",
+ "pages/components/news/news",
+ "pages/components/weatherLocationTrand/weatherLocationTrand",
+ "pages/components/recommend/recommend",
+ "pages/sonShouye/movie-more/movie-more",
+ "pages/sonShouye/movie-list/movie-list",
+ "mapWeather/search/search",
+ "mapWeather/regeocoding/regeocoding",
+ "mapWeather/suggestion/suggestion",
+ "mapWeather/weather/weather",
+ "pages/my/mySetting/mySetting",
+ "pages/my/myPost/myPost",
+ "pages/my/myorder/myorder",
+ "pages/my/purchaseHistory/purchaseHistory",
+ "pages/my/addressAdmin/addressAdmin",
+ "pages/my/myCart/myCart",
+ "pages/my/systemNotification/systemNotification",
+ "pages/classify/thing-search/thing-search",
+ "pages/classify/sale/sale",
+ "pages/classify/welfare/welfare",
+ "pages/classify/job/job",
+ "pages/sonShouye/headline/headline",
+ "pages/classify/jobDetail/jobDetail",
+ "pages/thing-detail/thing-detail",
+ "pages/search-thing-result/search-thing-result",
+ "pages/settlement/settlement"
+ ],
+ "window": {
+ "navigationBarBackgroundColor": "#1E68C9",
+ "backgroundTextStyle": "dark",
+ "navigationBarTitleText": "校园二手交易",
+ "navigationBarTextStyle": "#fff",
+ "enablePullDownRefresh": true
+ },
+ "tabBar": {
+ "list": [
+ {
+ "text": "首页",
+ "pagePath": "pages/shouye/shouye",
+ "iconPath": "images/tabBar/home.png",
+ "selectedIconPath": "images/tabBar/home.fill.png"
+ },
+ {
+ "text": "购物车",
+ "pagePath": "pages/shoppingCart/shoppingCart",
+ "iconPath": "images/tabBar/shoppingCart.png",
+ "selectedIconPath": "images/tabBar/shoppingCart.fill.png"
+ },
+ {
+ "text": "发布",
+ "pagePath": "pages/post/post",
+ "iconPath": "images/tabBar/release.png",
+ "selectedIconPath": "images/tabBar/release.png"
+ },
+ {
+ "text": "订单",
+ "pagePath": "pages/order/order",
+ "iconPath": "images/tabBar/order.png",
+ "selectedIconPath": "images/tabBar/order.fill.png"
+ },
+ {
+ "text": "我的",
+ "pagePath": "pages/my/my",
+ "iconPath": "images/tabBar/mine.png",
+ "selectedIconPath": "images/tabBar/mine.fill.png"
+ }
+ ],
+ "color": "#000000",
+ "selectedColor": "#1E68C9"
+ },
+ "debug": true
+}
\ No newline at end of file
diff --git a/campus/app.wxss b/campus/app.wxss
new file mode 100644
index 0000000..34ed8da
--- /dev/null
+++ b/campus/app.wxss
@@ -0,0 +1,159 @@
+/**app.wxss**/
+@import "./style/weui.wxss";
+
+.container {
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: space-between;
+ padding: 200rpx 0;
+ box-sizing: border-box;
+}
+
+page {
+ background-color: #f3f3f3;
+ font-family: "微软雅黑", "宋体";
+}
+
+.logo {
+ background-color: #f0eff4;
+ height: 90rpx;
+ line-height: 88rpx;
+ display: flex;
+ justify-content: space-between;
+ padding: 0 20rpx;
+ color: #fff;
+ font-size: 40rpx;
+}
+
+.logo image {
+ width: 90rpx;
+ height: 90rpx;
+}
+
+.logo .input {
+ width: 710rpx;
+ height: 50rpx;
+ border: 0;
+ border-radius: 10rpx;
+ background-color: #fff;
+ color: #999;
+ text-align: center;
+ margin-top: 20rpx;
+}
+
+.head {
+ display: flex;
+ justify-content: space-between;
+ text-align: center;
+ line-height: 100rpx;
+ font-size: 32rpx;
+ background-color: #fff;
+}
+
+.head view {
+ flex: 1;
+}
+
+.head navigator {
+ display: inline-block;
+ line-height: 100rpx;
+}
+
+.head navigator.on {
+ border-bottom: 1px solid #363636;
+}
+
+.modular {
+ background-color: #fff;
+ padding: 20rpx 0 0;
+ margin-top: 20rpx;
+}
+
+.modular .h1 {
+ font-size: 40rpx;
+ line-height: 90rpx;
+}
+
+.modular .h1 .span {
+ border-left: 10rpx solid #cda663;
+ padding-left: 10rpx;
+ display: inline;
+}
+
+.modular .content {
+ column-count: 4;
+ column-gap: 32rpx;
+ border-bottom: 2rpx solid #f1f1f1;
+ overflow: hidden;
+ padding: 0 20rpx;
+}
+
+.modular .content image {
+ width: 100%;
+ height: 190rpx;
+}
+
+.modular .content view {
+ padding: 14rpx 0;
+ line-height: 34rpx;
+ font-size: 28rpx;
+ text-align: center;
+}
+
+.modular .more {
+ line-height: 90rpx;
+ text-align: center;
+ color: #727ba6;
+ font-size: 32rpx;
+}
+
+.modular .more .next {
+ height: 16rpx;
+ display: inline-block;
+ width: 16rpx;
+ border-right: 6rpx solid #c9c8cd;
+ border-bottom: 6rpx solid #c9c8cd;
+ transform: rotate(-45deg);
+ margin-top: 6rpx;
+}
+/* 收货地址的全部配置 */
+.citypickers{
+ position: fixed;
+ height: 100%;
+ width: 100%;
+ min-height: 100%;
+ background-color: red;
+}
+
+.citybody {
+ position: fixed;
+ bottom: 0px;
+}
+
+.cityheader {
+ position: absolute;
+ top:0px;
+ width: 100%;
+ z-index: 4;
+}
+
+.city-cancel {
+ float: left;
+ margin: 20rpx;
+ color: #818181;
+}
+
+.city-true {
+ float: right;
+ margin: 20rpx;
+ color: #2FB42E
+}
+
+.section .picker {
+ background-color: #fff;
+ border-bottom: 1px #d9d9d9 solid;
+ border-top: 1px #d9d9d9 solid;
+ padding: 20rpx;
+}
\ No newline at end of file
diff --git a/campus/images/fenlei/gongyi.png b/campus/images/fenlei/gongyi.png
new file mode 100644
index 0000000..5eece2b
Binary files /dev/null and b/campus/images/fenlei/gongyi.png differ
diff --git a/campus/images/fenlei/jianzhi.png b/campus/images/fenlei/jianzhi.png
new file mode 100644
index 0000000..1ed4fc1
Binary files /dev/null and b/campus/images/fenlei/jianzhi.png differ
diff --git a/campus/images/fenlei/jishou.png b/campus/images/fenlei/jishou.png
new file mode 100644
index 0000000..f58d336
Binary files /dev/null and b/campus/images/fenlei/jishou.png differ
diff --git a/campus/images/fenlei/toutiao.png b/campus/images/fenlei/toutiao.png
new file mode 100644
index 0000000..f5d58f1
Binary files /dev/null and b/campus/images/fenlei/toutiao.png differ
diff --git a/campus/images/fenlei/zahuopu.png b/campus/images/fenlei/zahuopu.png
new file mode 100644
index 0000000..d6e5547
Binary files /dev/null and b/campus/images/fenlei/zahuopu.png differ
diff --git a/campus/images/map/marker_red.png b/campus/images/map/marker_red.png
new file mode 100644
index 0000000..8b4e20d
Binary files /dev/null and b/campus/images/map/marker_red.png differ
diff --git a/campus/images/map/marker_yellow.png b/campus/images/map/marker_yellow.png
new file mode 100644
index 0000000..febe8f6
Binary files /dev/null and b/campus/images/map/marker_yellow.png differ
diff --git a/campus/images/shouye/lunbotu2.png b/campus/images/shouye/lunbotu2.png
new file mode 100644
index 0000000..d63e2bf
Binary files /dev/null and b/campus/images/shouye/lunbotu2.png differ
diff --git a/campus/images/shouye/lunbotu3.png b/campus/images/shouye/lunbotu3.png
new file mode 100644
index 0000000..e879f6c
Binary files /dev/null and b/campus/images/shouye/lunbotu3.png differ
diff --git a/campus/images/shouye/lunbotu6.jpg b/campus/images/shouye/lunbotu6.jpg
new file mode 100644
index 0000000..2e59496
Binary files /dev/null and b/campus/images/shouye/lunbotu6.jpg differ
diff --git a/campus/images/shouye/lunbotu7.jpg b/campus/images/shouye/lunbotu7.jpg
new file mode 100644
index 0000000..231a240
Binary files /dev/null and b/campus/images/shouye/lunbotu7.jpg differ
diff --git a/campus/images/shouye/sousuo.png b/campus/images/shouye/sousuo.png
new file mode 100644
index 0000000..29d0617
Binary files /dev/null and b/campus/images/shouye/sousuo.png differ
diff --git a/campus/images/tabBar/home.fill.png b/campus/images/tabBar/home.fill.png
new file mode 100644
index 0000000..567d484
Binary files /dev/null and b/campus/images/tabBar/home.fill.png differ
diff --git a/campus/images/tabBar/home.png b/campus/images/tabBar/home.png
new file mode 100644
index 0000000..09421e6
Binary files /dev/null and b/campus/images/tabBar/home.png differ
diff --git a/campus/images/tabBar/mine.fill.png b/campus/images/tabBar/mine.fill.png
new file mode 100644
index 0000000..4eba89f
Binary files /dev/null and b/campus/images/tabBar/mine.fill.png differ
diff --git a/campus/images/tabBar/mine.png b/campus/images/tabBar/mine.png
new file mode 100644
index 0000000..40220de
Binary files /dev/null and b/campus/images/tabBar/mine.png differ
diff --git a/campus/images/tabBar/order.fill.png b/campus/images/tabBar/order.fill.png
new file mode 100644
index 0000000..22ea737
Binary files /dev/null and b/campus/images/tabBar/order.fill.png differ
diff --git a/campus/images/tabBar/order.png b/campus/images/tabBar/order.png
new file mode 100644
index 0000000..35537e7
Binary files /dev/null and b/campus/images/tabBar/order.png differ
diff --git a/campus/images/tabBar/release.png b/campus/images/tabBar/release.png
new file mode 100644
index 0000000..a86e1c5
Binary files /dev/null and b/campus/images/tabBar/release.png differ
diff --git a/campus/images/tabBar/shoppingCart.fill.png b/campus/images/tabBar/shoppingCart.fill.png
new file mode 100644
index 0000000..6a6c5a2
Binary files /dev/null and b/campus/images/tabBar/shoppingCart.fill.png differ
diff --git a/campus/images/tabBar/shoppingCart.png b/campus/images/tabBar/shoppingCart.png
new file mode 100644
index 0000000..6547db4
Binary files /dev/null and b/campus/images/tabBar/shoppingCart.png differ
diff --git a/campus/images/tuijian.png b/campus/images/tuijian.png
new file mode 100644
index 0000000..4e67375
Binary files /dev/null and b/campus/images/tuijian.png differ
diff --git a/campus/mapWeather/regeocoding/regeocoding.js b/campus/mapWeather/regeocoding/regeocoding.js
new file mode 100644
index 0000000..485575d
--- /dev/null
+++ b/campus/mapWeather/regeocoding/regeocoding.js
@@ -0,0 +1,66 @@
+var bmap = require('../../utils/bmap-wx.min.js');
+var wxMarkerData = [],
+ originalData;
+Page({
+ data: {
+ markers: [],
+ latitude: '',
+ longitude: '',
+ school: '',
+ rgcData: {}
+ },
+ makertap: function(e) {
+ var that = this;
+ var id = e.markerId;
+ that.showSearchInfo(wxMarkerData, id);
+ },
+ onLoad: function() {
+ var that = this;
+ var BMap = new bmap.BMapWX({
+ ak: 'zuwiVmIUj822mmW6psamM888QLz8Q5wF'
+ });
+ var fail = function(data) {
+ console.log(data)
+ };
+ var success = function(data) {
+ var school = '11';
+ originalData = data.originalData;
+ wxMarkerData = data.wxMarkerData;
+ that.setData({
+ // markers是一个在data中定义的数据,用来存储百度地图获取的数据
+ markers: wxMarkerData
+ });
+ that.setData({
+ // 经度
+ latitude: wxMarkerData[0].latitude
+ });
+ that.setData({
+ // 纬度
+ longitude: wxMarkerData[0].longitude
+ });
+ that.setData({
+ // 获取当前位置的大学名称
+ school: originalData.result.poiRegions[0].name,
+ });
+
+ }
+ BMap.regeocoding({
+ "query": '湖北',//在湖北地区进行搜索
+ fail: fail,
+ success: success,
+ iconPath: '../../images/map/marker_red.png',
+ iconTapPath: '../../images/map/marker_red.png'
+ });
+ },
+ showSearchInfo: function(data, i) {
+ var that = this;
+ that.setData({
+ rgcData: {
+ address: '地址:' + data[i].address + '\n',
+ desc: '描述:' + data[i].desc + '\n',
+ business: '商圈:' + data[i].business
+ }
+ });
+ }
+
+})
\ No newline at end of file
diff --git a/campus/mapWeather/regeocoding/regeocoding.json b/campus/mapWeather/regeocoding/regeocoding.json
new file mode 100644
index 0000000..9e26dfe
--- /dev/null
+++ b/campus/mapWeather/regeocoding/regeocoding.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/campus/mapWeather/regeocoding/regeocoding.wxml b/campus/mapWeather/regeocoding/regeocoding.wxml
new file mode 100644
index 0000000..045969f
--- /dev/null
+++ b/campus/mapWeather/regeocoding/regeocoding.wxml
@@ -0,0 +1,9 @@
+
Bmob.Error
.
+ * @param {String} message A detailed description of the error.
+ *
+ *
+ * var object = {};
+ * _.extend(object, Bmob.Events);
+ * object.on('expand', function(){ alert('expanded'); });
+ * object.trigger('expand');
For more information, see the + * Backbone + * documentation.
+ */ + Bmob.Events = { + /** + * Bind one or more space separated events, `events`, to a `callback` + * function. Passing `"all"` will bind the callback to all events fired. + */ + on: function (events, callback, context) { + + var calls, event, node, tail, list; + if (!callback) { + return this; + } + events = events.split(eventSplitter); + calls = this._callbacks || (this._callbacks = {}); + + // Create an immutable callback list, allowing traversal during + // modification. The tail is an empty object that will always be used + // as the next node. + event = events.shift(); + while (event) { + list = calls[event]; + node = list ? list.tail : {}; + node.next = tail = {}; + node.context = context; + node.callback = callback; + calls[event] = { + tail: tail, + next: list ? list.next : node + }; + event = events.shift(); + } + + return this; + }, + + /** + * Remove one or many callbacks. If `context` is null, removes all callbacks + * with that function. If `callback` is null, removes all callbacks for the + * event. If `events` is null, removes all bound callbacks for all events. + */ + off: function (events, callback, context) { + var event, calls, node, tail, cb, ctx; + + // No events, or removing *all* events. + if (!(calls = this._callbacks)) { + return; + } + if (!(events || callback || context)) { + delete this._callbacks; + return this; + } + + // Loop through the listed events and contexts, splicing them out of the + // linked list of callbacks if appropriate. + events = events ? events.split(eventSplitter) : _.keys(calls); + event = events.shift(); + while (event) { + node = calls[event]; + delete calls[event]; + if (!node || !(callback || context)) { + continue; + } + // Create a new list, omitting the indicated callbacks. + tail = node.tail; + node = node.next; + while (node !== tail) { + cb = node.callback; + ctx = node.context; + if ((callback && cb !== callback) || (context && ctx !== context)) { + this.on(event, cb, ctx); + } + node = node.next; + } + event = events.shift(); + } + + return this; + }, + + /** + * Trigger one or many events, firing all bound callbacks. Callbacks are + * passed the same arguments as `trigger` is, apart from the event name + * (unless you're listening on `"all"`, which will cause your callback to + * receive the true name of the event as the first argument). + */ + trigger: function (events) { + var event, node, calls, tail, args, all, rest; + if (!(calls = this._callbacks)) { + return this; + } + all = calls.all; + events = events.split(eventSplitter); + rest = slice.call(arguments, 1); + + // For each event, walk through the linked list of callbacks twice, + // first to trigger the event, then to trigger any `"all"` callbacks. + event = events.shift(); + while (event) { + node = calls[event]; + if (node) { + tail = node.tail; + while ((node = node.next) !== tail) { + node.callback.apply(node.context || this, rest); + } + } + node = all; + if (node) { + tail = node.tail; + args = [event].concat(rest); + while ((node = node.next) !== tail) { + node.callback.apply(node.context || this, args); + } + } + event = events.shift(); + } + + return this; + } + }; + + /** + * @function + */ + Bmob.Events.bind = Bmob.Events.on; + + /** + * @function + */ + Bmob.Events.unbind = Bmob.Events.off; + + /** + * 通过下面的任意一种形式可以创建GeoPoint+ * new GeoPoint(otherGeoPoint) + * new GeoPoint(30, 30) + * new GeoPoint([30, 30]) + * new GeoPoint({latitude: 30, longitude: 30}) + * new GeoPoint() // defaults to (0, 0) + *+ * @class + * + *
在BmobObject中使用坐标点,或者在geo查询中使用
+ *在一个表中只有一个字段能使用GeoPoint.
+ * + *Example:
+ * var point = new Bmob.GeoPoint(30.0, -20.0); + * var object = new Bmob.Object("PlaceObject"); + * object.set("location", point); + * object.save();+ */ + Bmob.GeoPoint = function (arg1, arg2) { + if (_.isArray(arg1)) { + Bmob.GeoPoint._validate(arg1[0], arg1[1]); + this.latitude = arg1[0]; + this.longitude = arg1[1]; + } else if (_.isObject(arg1)) { + Bmob.GeoPoint._validate(arg1.latitude, arg1.longitude); + this.latitude = arg1.latitude; + this.longitude = arg1.longitude; + } else if (_.isNumber(arg1) && _.isNumber(arg2)) { + Bmob.GeoPoint._validate(arg1, arg2); + this.latitude = arg1; + this.longitude = arg2; + } else { + this.latitude = 0; + this.longitude = 0; + } + + // Add properties so that anyone using Webkit or Mozilla will get an error + // if they try to set values that are out of bounds. + var self = this; + if (this.__defineGetter__ && this.__defineSetter__) { + // Use _latitude and _longitude to actually store the values, and add + // getters and setters for latitude and longitude. + this._latitude = this.latitude; + this._longitude = this.longitude; + this.__defineGetter__("latitude", + function () { + return self._latitude; + }); + this.__defineGetter__("longitude", + function () { + return self._longitude; + }); + this.__defineSetter__("latitude", + function (val) { + Bmob.GeoPoint._validate(val, self.longitude); + self._latitude = val; + }); + this.__defineSetter__("longitude", + function (val) { + Bmob.GeoPoint._validate(self.latitude, val); + self._longitude = val; + }); + } + }; + + /** + * @lends Bmob.GeoPoint.prototype + * @property {float} latitude North-south portion of the coordinate, in range + * [-90, 90]. Throws an exception if set out of range in a modern browser. + * @property {float} longitude East-west portion of the coordinate, in range + * [-180, 180]. Throws if set out of range in a modern browser. + */ + + /** + * Throws an exception if the given lat-long is out of bounds. + */ + Bmob.GeoPoint._validate = function (latitude, longitude) { + if (latitude < -90.0) { + throw "Bmob.GeoPoint latitude " + latitude + " < -90.0."; + } + if (latitude > 90.0) { + throw "Bmob.GeoPoint latitude " + latitude + " > 90.0."; + } + if (longitude < -180.0) { + throw "Bmob.GeoPoint longitude " + longitude + " < -180.0."; + } + if (longitude > 180.0) { + throw "Bmob.GeoPoint longitude " + longitude + " > 180.0."; + } + }; + + /** + * 使用用户当前的位置创建GeoPoint对象。 + * 成功时调用options.success,或者options.error。 + * @param {Object} options 调用成功或失败的回调 + */ + Bmob.GeoPoint.current = function (options) { + var promise = new Bmob.Promise(); + navigator.geolocation.getCurrentPosition(function (location) { + promise.resolve(new Bmob.GeoPoint({ + latitude: location.coords.latitude, + longitude: location.coords.longitude + })); + + }, + function (error) { + promise.reject(error); + }); + + return promise._thenRunCallbacks(options); + }; + + Bmob.GeoPoint.prototype = { + /** + * 返回geopoint的json + * @return {Object} + */ + toJSON: function () { + Bmob.GeoPoint._validate(this.latitude, this.longitude); + return { + "__type": "GeoPoint", + latitude: this.latitude, + longitude: this.longitude + }; + }, + + /** + * 返回两个geopoint之间的弧度 + * @param {Bmob.GeoPoint} point 另一个Bmob.GeoPoint. + * @return {Number} + */ + radiansTo: function (point) { + var d2r = Math.PI / 180.0; + var lat1rad = this.latitude * d2r; + var long1rad = this.longitude * d2r; + var lat2rad = point.latitude * d2r; + var long2rad = point.longitude * d2r; + var deltaLat = lat1rad - lat2rad; + var deltaLong = long1rad - long2rad; + var sinDeltaLatDiv2 = Math.sin(deltaLat / 2); + var sinDeltaLongDiv2 = Math.sin(deltaLong / 2); + // Square of half the straight line chord distance between both points. + var a = ((sinDeltaLatDiv2 * sinDeltaLatDiv2) + (Math.cos(lat1rad) * Math.cos(lat2rad) * sinDeltaLongDiv2 * sinDeltaLongDiv2)); + a = Math.min(1.0, a); + return 2 * Math.asin(Math.sqrt(a)); + }, + + /** + * 返回两个geopoint之间的千米数 + * @param {Bmob.GeoPoint} point 另一个Bmob.GeoPoint. + * @return {Number} + */ + kilometersTo: function (point) { + return this.radiansTo(point) * 6371.0; + }, + + /** + * 返回两个geopoint之间的米数 + * @param {Bmob.GeoPoint} point 另一个Bmob.GeoPoint. + * @return {Number} + */ + milesTo: function (point) { + return this.radiansTo(point) * 3958.8; + } + }; + + var PUBLIC_KEY = "*"; + + /** + * 创建ACL + * 如果传任何参数,则任何人都没有权限 + * 如果传入的参数是Bmob.User,那个usr会有读写权限。 + * 如果传入的参数是json对象,则会有相应的acl权限。 + * + * @see Bmob.Object#setACL + * @class + * + *
权限控制可以被添加到任何
+ * Bmob.Object
,用来控制用户的访问权限
+ *
object.set("foo", "bar")
+ * is an example of a Bmob.Op.Set. Calling object.unset("foo")
+ * is a Bmob.Op.Unset. These operations are stored in a Bmob.Object and
+ * sent to the server as part of object.save()
operations.
+ * Instances of Bmob.Op should be immutable.
+ *
+ * You should not create subclasses of Bmob.Op or instantiate Bmob.Op
+ * directly.
+ */
+ Bmob.Op = function () {
+ this._initialize.apply(this, arguments);
+ };
+
+ Bmob.Op.prototype = {
+ _initialize: function () { }
+ };
+
+ _.extend(Bmob.Op, {
+ /**
+ * To create a new Op, call Bmob.Op._extend();
+ */
+ _extend: Bmob._extend,
+
+ // A map of __op string to decoder function.
+ _opDecoderMap: {},
+
+ /**
+ * Registers a function to convert a json object with an __op field into an
+ * instance of a subclass of Bmob.Op.
+ */
+ _registerDecoder: function (opName, decoder) {
+ Bmob.Op._opDecoderMap[opName] = decoder;
+ },
+
+ /**
+ * Converts a json object into an instance of a subclass of Bmob.Op.
+ */
+ _decode: function (json) {
+ var decoder = Bmob.Op._opDecoderMap[json.__op];
+ if (decoder) {
+ return decoder(json);
+ } else {
+ return undefined;
+ }
+ }
+ });
+
+ /*
+ * Add a handler for Batch ops.
+ */
+ Bmob.Op._registerDecoder("Batch",
+ function (json) {
+ var op = null;
+ Bmob._arrayEach(json.ops,
+ function (nextOp) {
+ nextOp = Bmob.Op._decode(nextOp);
+ op = nextOp._mergeWithPrevious(op);
+ });
+ return op;
+ });
+
+ /**
+ * @class
+ * set操作是表明字段的值会在Bmob.Object.set中改变,或者这确定要修改值。
+ */
+ Bmob.Op.Set = Bmob.Op._extend(
+ /** @lends Bmob.Op.Set.prototype */
+ {
+ _initialize: function (value) {
+ this._value = value;
+ },
+
+ /**
+ * 返回设置后的新值
+ */
+ value: function () {
+ return this._value;
+ },
+
+ /**
+ * 返回发送到bmob的json
+ * @return {Object}
+ */
+ toJSON: function () {
+ return Bmob._encode(this.value());
+ },
+
+ _mergeWithPrevious: function (previous) {
+ return this;
+ },
+
+ _estimate: function (oldValue) {
+ return this.value();
+ }
+ });
+
+ /**
+ * A sentinel value that is returned by Bmob.Op.Unset._estimate to
+ * indicate the field should be deleted. Basically, if you find _UNSET as a
+ * value in your object, you should remove that key.
+ */
+ Bmob.Op._UNSET = {};
+
+ /**
+ * @class
+ * Unset 操作表明字段将会从对象中删除。
+ */
+ Bmob.Op.Unset = Bmob.Op._extend(
+ /** @lends Bmob.Op.Unset.prototype */
+ {
+ /**
+ * 返回发送到bmob的json
+ * @return {Object}
+ */
+ toJSON: function () {
+ return {
+ __op: "Delete"
+ };
+ },
+
+ _mergeWithPrevious: function (previous) {
+ return this;
+ },
+
+ _estimate: function (oldValue) {
+ return Bmob.Op._UNSET;
+ }
+ });
+
+ Bmob.Op._registerDecoder("Delete",
+ function (json) {
+ return new Bmob.Op.Unset();
+ });
+
+ /**
+ * @class
+ * 将字段的值自增或自减
+ */
+ Bmob.Op.Increment = Bmob.Op._extend(
+ /** @lends Bmob.Op.Increment.prototype */
+ {
+
+ _initialize: function (amount) {
+ this._amount = amount;
+ },
+
+ /**
+ * 返回添加的数目。
+ * @return {Number} 增加或减少的数目。
+ */
+ amount: function () {
+ return this._amount;
+ },
+
+ /**
+ * 返回发送到bmob的json
+ * @return {Object}
+ */
+ toJSON: function () {
+ return {
+ __op: "Increment",
+ amount: this._amount
+ };
+ },
+
+ _mergeWithPrevious: function (previous) {
+ if (!previous) {
+ return this;
+ } else if (previous instanceof Bmob.Op.Unset) {
+ return new Bmob.Op.Set(this.amount());
+ } else if (previous instanceof Bmob.Op.Set) {
+ return new Bmob.Op.Set(previous.value() + this.amount());
+ } else if (previous instanceof Bmob.Op.Increment) {
+ return new Bmob.Op.Increment(this.amount() + previous.amount());
+ } else {
+ throw "Op is invalid after previous op.";
+ }
+ },
+
+ _estimate: function (oldValue) {
+ if (!oldValue) {
+ return this.amount();
+ }
+ return oldValue + this.amount();
+ }
+ });
+
+ Bmob.Op._registerDecoder("Increment",
+ function (json) {
+ return new Bmob.Op.Increment(json.amount);
+ });
+
+ /**
+ * @class
+ * 添加一个对象到数组中,不管元素是否存在。
+ */
+ Bmob.Op.Add = Bmob.Op._extend(
+ /** @lends Bmob.Op.Add.prototype */
+ {
+ _initialize: function (objects) {
+ this._objects = objects;
+ },
+
+ /**
+ * 返回添加到数组中的对象
+ * @return {Array} 添加到数组中的对象
+ */
+ objects: function () {
+ return this._objects;
+ },
+
+ /**
+ * 返回发送到bmob的json
+ * @return {Object}
+ */
+ toJSON: function () {
+ return {
+ __op: "Add",
+ objects: Bmob._encode(this.objects())
+ };
+ },
+
+ _mergeWithPrevious: function (previous) {
+ if (!previous) {
+ return this;
+ } else if (previous instanceof Bmob.Op.Unset) {
+ return new Bmob.Op.Set(this.objects());
+ } else if (previous instanceof Bmob.Op.Set) {
+ return new Bmob.Op.Set(this._estimate(previous.value()));
+ } else if (previous instanceof Bmob.Op.Add) {
+ return new Bmob.Op.Add(previous.objects().concat(this.objects()));
+ } else {
+ throw "Op is invalid after previous op.";
+ }
+ },
+
+ _estimate: function (oldValue) {
+ if (!oldValue) {
+ return _.clone(this.objects());
+ } else {
+ return oldValue.concat(this.objects());
+ }
+ }
+ });
+
+ Bmob.Op._registerDecoder("Add",
+ function (json) {
+ return new Bmob.Op.Add(Bmob._decode(undefined, json.objects));
+ });
+
+ /**
+ * @class
+ * 添加一个元素到数组中,当元素已经存在,将不会重复添加。
+ */
+ Bmob.Op.AddUnique = Bmob.Op._extend(
+ /** @lends Bmob.Op.AddUnique.prototype */
+ {
+
+ _initialize: function (objects) {
+ this._objects = _.uniq(objects);
+ },
+
+ /**
+ * 返回添加到数组中的对象
+ * @return {Array} 添加到数组中的对象
+ */
+ objects: function () {
+ return this._objects;
+ },
+
+ /**
+ * 返回发送到bmob的json
+ * @return {Object}
+ */
+ toJSON: function () {
+ return {
+ __op: "AddUnique",
+ objects: Bmob._encode(this.objects())
+ };
+ },
+
+ _mergeWithPrevious: function (previous) {
+ if (!previous) {
+ return this;
+ } else if (previous instanceof Bmob.Op.Unset) {
+ return new Bmob.Op.Set(this.objects());
+ } else if (previous instanceof Bmob.Op.Set) {
+ return new Bmob.Op.Set(this._estimate(previous.value()));
+ } else if (previous instanceof Bmob.Op.AddUnique) {
+ return new Bmob.Op.AddUnique(this._estimate(previous.objects()));
+ } else {
+ throw "Op is invalid after previous op.";
+ }
+ },
+
+ _estimate: function (oldValue) {
+ if (!oldValue) {
+ return _.clone(this.objects());
+ } else {
+ // We can't just take the _.uniq(_.union(...)) of oldValue and
+ // this.objects, because the uniqueness may not apply to oldValue
+ // (especially if the oldValue was set via .set())
+ var newValue = _.clone(oldValue);
+ Bmob._arrayEach(this.objects(),
+ function (obj) {
+ if (obj instanceof Bmob.Object && obj.id) {
+ var matchingObj = _.find(newValue,
+ function (anObj) {
+ return (anObj instanceof Bmob.Object) && (anObj.id === obj.id);
+ });
+ if (!matchingObj) {
+ newValue.push(obj);
+ } else {
+ var index = _.indexOf(newValue, matchingObj);
+ newValue[index] = obj;
+ }
+ } else if (!_.contains(newValue, obj)) {
+ newValue.push(obj);
+ }
+ });
+ return newValue;
+ }
+ }
+ });
+
+ Bmob.Op._registerDecoder("AddUnique",
+ function (json) {
+ return new Bmob.Op.AddUnique(Bmob._decode(undefined, json.objects));
+ });
+
+ /**
+ * @class
+ * 从数组中移除一个元素。
+ */
+ Bmob.Op.Remove = Bmob.Op._extend(
+ /** @lends Bmob.Op.Remove.prototype */
+ {
+ _initialize: function (objects) {
+ this._objects = _.uniq(objects);
+ },
+
+ /**
+ * 返回移除出数组的对象
+ * @return {Array} 移除出数组的对象
+ */
+ objects: function () {
+ return this._objects;
+ },
+
+ /**
+ * 返回发送到bmob的json
+ * @return {Object}
+ */
+ toJSON: function () {
+ return {
+ __op: "Remove",
+ objects: Bmob._encode(this.objects())
+ };
+ },
+
+ _mergeWithPrevious: function (previous) {
+ if (!previous) {
+ return this;
+ } else if (previous instanceof Bmob.Op.Unset) {
+ return previous;
+ } else if (previous instanceof Bmob.Op.Set) {
+ return new Bmob.Op.Set(this._estimate(previous.value()));
+ } else if (previous instanceof Bmob.Op.Remove) {
+ return new Bmob.Op.Remove(_.union(previous.objects(), this.objects()));
+ } else {
+ throw "Op is invalid after previous op.";
+ }
+ },
+
+ _estimate: function (oldValue) {
+ if (!oldValue) {
+ return [];
+ } else {
+ var newValue = _.difference(oldValue, this.objects());
+ // If there are saved Bmob Objects being removed, also remove them.
+ Bmob._arrayEach(this.objects(),
+ function (obj) {
+ if (obj instanceof Bmob.Object && obj.id) {
+ newValue = _.reject(newValue,
+ function (other) {
+ return (other instanceof Bmob.Object) && (other.id === obj.id);
+ });
+ }
+ });
+ return newValue;
+ }
+ }
+ });
+
+ Bmob.Op._registerDecoder("Remove",
+ function (json) {
+ return new Bmob.Op.Remove(Bmob._decode(undefined, json.objects));
+ });
+
+ /**
+ * @class
+ * 关系操作标明这个字段是Bmob.Relation的实体,同时对象可以从关系中添加或移除
+ */
+ Bmob.Op.Relation = Bmob.Op._extend(
+ /** @lends Bmob.Op.Relation.prototype */
+ {
+
+ _initialize: function (adds, removes) {
+ this._targetClassName = null;
+
+ var self = this;
+
+ var pointerToId = function (object) {
+ if (object instanceof Bmob.Object) {
+ if (!object.id) {
+ throw "You can't add an unsaved Bmob.Object to a relation.";
+ }
+ if (!self._targetClassName) {
+ self._targetClassName = object.className;
+ }
+ if (self._targetClassName !== object.className) {
+ throw "Tried to create a Bmob.Relation with 2 different types: " + self._targetClassName + " and " + object.className + ".";
+ }
+ return object.id;
+ }
+ return object;
+ };
+
+ this.relationsToAdd = _.uniq(_.map(adds, pointerToId));
+ this.relationsToRemove = _.uniq(_.map(removes, pointerToId));
+ },
+
+ /**
+ * 返回添加到关系中的Bmob.Object的数组对象
+ * @return {Array}
+ */
+ added: function () {
+ var self = this;
+ return _.map(this.relationsToAdd,
+ function (objectId) {
+ var object = Bmob.Object._create(self._targetClassName);
+ object.id = objectId;
+ return object;
+ });
+ },
+
+ /**
+ * 返回移除的Bmob.Object的数组对象
+ * @return {Array}
+ */
+ removed: function () {
+ var self = this;
+ return _.map(this.relationsToRemove,
+ function (objectId) {
+ var object = Bmob.Object._create(self._targetClassName);
+ object.id = objectId;
+ return object;
+ });
+ },
+
+ /**
+ * 返回发送到bmob的json
+ * @return {Object}
+ */
+ toJSON: function () {
+ var adds = null;
+ var removes = null;
+ var self = this;
+ var idToPointer = function (id) {
+ return {
+ __type: 'Pointer',
+ className: self._targetClassName,
+ objectId: id
+ };
+ };
+ var pointers = null;
+ if (this.relationsToAdd.length > 0) {
+ pointers = _.map(this.relationsToAdd, idToPointer);
+ adds = {
+ "__op": "AddRelation",
+ "objects": pointers
+ };
+ }
+
+ if (this.relationsToRemove.length > 0) {
+ pointers = _.map(this.relationsToRemove, idToPointer);
+ removes = {
+ "__op": "RemoveRelation",
+ "objects": pointers
+ };
+ }
+
+ if (adds && removes) {
+ return {
+ "__op": "Batch",
+ "ops": [adds, removes]
+ };
+ }
+
+ return adds || removes || {};
+ },
+
+ _mergeWithPrevious: function (previous) {
+ if (!previous) {
+ return this;
+ } else if (previous instanceof Bmob.Op.Unset) {
+ throw "You can't modify a relation after deleting it.";
+ } else if (previous instanceof Bmob.Op.Relation) {
+ if (previous._targetClassName && previous._targetClassName !== this._targetClassName) {
+ throw "Related object must be of class " + previous._targetClassName + ", but " + this._targetClassName + " was passed in.";
+ }
+ var newAdd = _.union(_.difference(previous.relationsToAdd, this.relationsToRemove), this.relationsToAdd);
+ var newRemove = _.union(_.difference(previous.relationsToRemove, this.relationsToAdd), this.relationsToRemove);
+
+ var newRelation = new Bmob.Op.Relation(newAdd, newRemove);
+ newRelation._targetClassName = this._targetClassName;
+ return newRelation;
+ } else {
+ throw "Op is invalid after previous op.";
+ }
+ },
+
+ _estimate: function (oldValue, object, key) {
+ if (!oldValue) {
+ var relation = new Bmob.Relation(object, key);
+ relation.targetClassName = this._targetClassName;
+ } else if (oldValue instanceof Bmob.Relation) {
+ if (this._targetClassName) {
+ if (oldValue.targetClassName) {
+ if (oldValue.targetClassName !== this._targetClassName) {
+ throw "Related object must be a " + oldValue.targetClassName + ", but a " + this._targetClassName + " was passed in.";
+ }
+ } else {
+ oldValue.targetClassName = this._targetClassName;
+ }
+ }
+ return oldValue;
+ } else {
+ throw "Op is invalid after previous op.";
+ }
+ }
+ });
+
+ Bmob.Op._registerDecoder("AddRelation",
+ function (json) {
+ return new Bmob.Op.Relation(Bmob._decode(undefined, json.objects), []);
+ });
+ Bmob.Op._registerDecoder("RemoveRelation",
+ function (json) {
+ return new Bmob.Op.Relation([], Bmob._decode(undefined, json.objects));
+ });
+
+ /**
+ * Creates a new Relation for the given parent object and key. This
+ * constructor should rarely be used directly, but rather created by
+ * Bmob.Object.relation.
+ * @param {Bmob.Object} parent The parent of this relation.
+ * @param {String} key The key for this relation on the parent.
+ * @see Bmob.Object#relation
+ *
+ * + * A class that is used to access all of the children of a many-to-many + * relationship. Each instance of Bmob.Relation is associated with a + * particular parent object and key. + *
+ */ + Bmob.Relation = function (parent, key) { + this.parent = parent; + this.key = key; + this.targetClassName = null; + }; + + /** + * Creates a query that can be used to query the parent objects in this relation. + * @param {String} parentClass The parent class or name. + * @param {String} relationKey The relation field key in parent. + * @param {Bmob.Object} child The child object. + * @return {Bmob.Query} + */ + Bmob.Relation.reverseQuery = function (parentClass, relationKey, child) { + var query = new Bmob.Query(parentClass); + query.equalTo(relationKey, child._toPointer()); + return query; + }; + + Bmob.Relation.prototype = { + /** + * Makes sure that this relation has the right parent and key. + */ + _ensureParentAndKey: function (parent, key) { + this.parent = this.parent || parent; + this.key = this.key || key; + if (this.parent !== parent) { + throw "Internal Error. Relation retrieved from two different Objects."; + } + if (this.key !== key) { + throw "Internal Error. Relation retrieved from two different keys."; + } + }, + + /** + * Adds a Bmob.Object or an array of Bmob.Objects to the relation. + * @param {} objects The item or items to add. + */ + add: function (objects) { + if (!_.isArray(objects)) { + objects = [objects]; + } + + var change = new Bmob.Op.Relation(objects, []); + this.parent.set(this.key, change); + this.targetClassName = change._targetClassName; + }, + + /** + * Removes a Bmob.Object or an array of Bmob.Objects from this relation. + * @param {} objects The item or items to remove. + */ + remove: function (objects) { + if (!_.isArray(objects)) { + objects = [objects]; + } + + var change = new Bmob.Op.Relation([], objects); + this.parent.set(this.key, change); + this.targetClassName = change._targetClassName; + }, + + /** + * Returns a JSON version of the object suitable for saving to disk. + * @return {Object} + */ + toJSON: function () { + return { + "__type": "Relation", + "className": this.targetClassName + }; + }, + + /** + * Returns a Bmob.Query that is limited to objects in this + * relation. + * @return {Bmob.Query} + */ + query: function () { + var targetClass; + var query; + if (!this.targetClassName) { + targetClass = Bmob.Object._getSubclass(this.parent.className); + query = new Bmob.Query(targetClass); + query._extraOptions.redirectClassNameForKey = this.key; + } else { + targetClass = Bmob.Object._getSubclass(this.targetClassName); + query = new Bmob.Query(targetClass); + } + query._addCondition("$relatedTo", "object", this.parent._toPointer()); + query._addCondition("$relatedTo", "key", this.key); + + return query; + } + }; + + /** + * A Promise is returned by async methods as a hook to provide callbacks to be + * called when the async task is fulfilled. + * + *Typical usage would be like:
+ * query.findAsync().then(function(results) { + * results[0].set("foo", "bar"); + * return results[0].saveAsync(); + * }).then(function(result) { + * console.log("Updated " + result.id); + * }); + *+ * + * @see Bmob.Promise.prototype.next + */ + Bmob.Promise = function () { + this._resolved = false; + this._rejected = false; + this._resolvedCallbacks = []; + this._rejectedCallbacks = []; + }; + + _.extend(Bmob.Promise, + /** @lends Bmob.Promise */ + { + + /** + * Returns true iff the given object fulfils the Promise interface. + * @return {Boolean} + */ + is: function (promise) { + return promise && promise.then && _.isFunction(promise.then); + }, + + /** + * Returns a new promise that is resolved with a given value. + * @return {Bmob.Promise} the new promise. + */ + as: function () { + var promise = new Bmob.Promise(); + promise.resolve.apply(promise, arguments); + return promise; + }, + + /** + * Returns a new promise that is rejected with a given error. + * @return {Bmob.Promise} the new promise. + */ + error: function () { + var promise = new Bmob.Promise(); + promise.reject.apply(promise, arguments); + return promise; + }, + + /** + * Returns a new promise that is fulfilled when all of the input promises + * are resolved. If any promise in the list fails, then the returned promise + * will fail with the last error. If they all succeed, then the returned + * promise will succeed, with the result being an array with the results of + * all the input promises. + * @param {Array} promises a list of promises to wait for. + * @return {Bmob.Promise} the new promise. + */ + when: function (promises) { + // Allow passing in Promises as separate arguments instead of an Array. + var objects; + if (promises && Bmob._isNullOrUndefined(promises.length)) { + objects = arguments; + } else { + objects = promises; + } + + var total = objects.length; + var hadError = false; + var results = []; + var errors = []; + results.length = objects.length; + errors.length = objects.length; + + if (total === 0) { + return Bmob.Promise.as.apply(this, results); + } + + var promise = new Bmob.Promise(); + + var resolveOne = function () { + total = total - 1; + if (total === 0) { + if (hadError) { + promise.reject(errors); + } else { + promise.resolve.apply(promise, results); + } + } + }; + + Bmob._arrayEach(objects, + function (object, i) { + if (Bmob.Promise.is(object)) { + object.then(function (result) { + results[i] = result; + resolveOne(); + }, + function (error) { + errors[i] = error; + hadError = true; + resolveOne(); + }); + } else { + results[i] = object; + resolveOne(); + } + }); + + return promise; + }, + + /** + * Runs the given asyncFunction repeatedly, as long as the predicate + * function returns a truthy value. Stops repeating if asyncFunction returns + * a rejected promise. + * @param {Function} predicate should return false when ready to stop. + * @param {Function} asyncFunction should return a Promise. + */ + _continueWhile: function (predicate, asyncFunction) { + if (predicate()) { + return asyncFunction().then(function () { + return Bmob.Promise._continueWhile(predicate, asyncFunction); + }); + } + return Bmob.Promise.as(); + } + }); + + _.extend(Bmob.Promise.prototype, + /** @lends Bmob.Promise.prototype */ + { + + /** + * Marks this promise as fulfilled, firing any callbacks waiting on it. + * @param {Object} result the result to pass to the callbacks. + */ + resolve: function (result) { + if (this._resolved || this._rejected) { + throw "A promise was resolved even though it had already been " + (this._resolved ? "resolved" : "rejected") + "."; + } + this._resolved = true; + this._result = arguments; + var results = arguments; + Bmob._arrayEach(this._resolvedCallbacks, + function (resolvedCallback) { + resolvedCallback.apply(this, results); + }); + this._resolvedCallbacks = []; + this._rejectedCallbacks = []; + }, + + /** + * Marks this promise as fulfilled, firing any callbacks waiting on it. + * @param {Object} error the error to pass to the callbacks. + */ + reject: function (error) { + if (this._resolved || this._rejected) { + throw "A promise was rejected even though it had already been " + (this._resolved ? "resolved" : "rejected") + "."; + } + this._rejected = true; + this._error = error; + Bmob._arrayEach(this._rejectedCallbacks, + function (rejectedCallback) { + rejectedCallback(error); + }); + this._resolvedCallbacks = []; + this._rejectedCallbacks = []; + }, + + /** + * Adds callbacks to be called when this promise is fulfilled. Returns a new + * Promise that will be fulfilled when the callback is complete. It allows + * chaining. If the callback itself returns a Promise, then the one returned + * by "then" will not be fulfilled until that one returned by the callback + * is fulfilled. + * @param {Function} resolvedCallback Function that is called when this + * Promise is resolved. Once the callback is complete, then the Promise + * returned by "then" will also be fulfilled. + * @param {Function} rejectedCallback Function that is called when this + * Promise is rejected with an error. Once the callback is complete, then + * the promise returned by "then" with be resolved successfully. If + * rejectedCallback is null, or it returns a rejected Promise, then the + * Promise returned by "then" will be rejected with that error. + * @return {Bmob.Promise} A new Promise that will be fulfilled after this + * Promise is fulfilled and either callback has completed. If the callback + * returned a Promise, then this Promise will not be fulfilled until that + * one is. + */ + then: function (resolvedCallback, rejectedCallback) { + var promise = new Bmob.Promise(); + + var wrappedResolvedCallback = function () { + var result = arguments; + if (resolvedCallback) { + result = [resolvedCallback.apply(this, result)]; + } + if (result.length === 1 && Bmob.Promise.is(result[0])) { + result[0].then(function () { + promise.resolve.apply(promise, arguments); + }, + function (error) { + promise.reject(error); + }); + } else { + promise.resolve.apply(promise, result); + } + }; + + var wrappedRejectedCallback = function (error) { + var result = []; + if (rejectedCallback) { + result = [rejectedCallback(error)]; + if (result.length === 1 && Bmob.Promise.is(result[0])) { + result[0].then(function () { + promise.resolve.apply(promise, arguments); + }, + function (error) { + promise.reject(error); + }); + } else { + // A Promises/A+ compliant implementation would call: + // promise.resolve.apply(promise, result); + promise.reject(result[0]); + } + } else { + promise.reject(error); + } + }; + + if (this._resolved) { + wrappedResolvedCallback.apply(this, this._result); + } else if (this._rejected) { + wrappedRejectedCallback(this._error); + } else { + this._resolvedCallbacks.push(wrappedResolvedCallback); + this._rejectedCallbacks.push(wrappedRejectedCallback); + } + + return promise; + }, + + /** + * Run the given callbacks after this promise is fulfilled. + * @param optionsOrCallback {} A Backbone-style options callback, or a + * callback function. If this is an options object and contains a "model" + * attributes, that will be passed to error callbacks as the first argument. + * @param model {} If truthy, this will be passed as the first result of + * error callbacks. This is for Backbone-compatability. + * @return {Bmob.Promise} A promise that will be resolved after the + * callbacks are run, with the same result as this. + */ + _thenRunCallbacks: function (optionsOrCallback, model) { + var options; + if (_.isFunction(optionsOrCallback)) { + var callback = optionsOrCallback; + options = { + success: function (result) { + callback(result, null); + }, + error: function (error) { + callback(null, error); + } + }; + } else { + options = _.clone(optionsOrCallback); + } + options = options || {}; + + return this.then(function (result) { + if (options.success) { + options.success.apply(this, arguments); + } else if (model) { + // When there's no callback, a sync event should be triggered. + model.trigger('sync', model, result, options); + } + return Bmob.Promise.as.apply(Bmob.Promise, arguments); + }, + function (error) { + if (options.error) { + if (!_.isUndefined(model)) { + options.error(model, error); + } else { + options.error(error); + } + } else if (model) { + // When there's no error callback, an error event should be triggered. + model.trigger('error', model, error, options); + } + // By explicitly returning a rejected Promise, this will work with + // either jQuery or Promises/A semantics. + return Bmob.Promise.error(error); + }); + }, + + /** + * Adds a callback function that should be called regardless of whether + * this promise failed or succeeded. The callback will be given either the + * array of results for its first argument, or the error as its second, + * depending on whether this Promise was rejected or resolved. Returns a + * new Promise, like "then" would. + * @param {Function} continuation the callback. + */ + _continueWith: function (continuation) { + return this.then(function () { + return continuation(arguments, null); + }, + function (error) { + return continuation(null, error); + }); + } + + }); + + var b64Digit = function (number) { + if (number < 26) { + return String.fromCharCode(65 + number); + } + if (number < 52) { + return String.fromCharCode(97 + (number - 26)); + } + if (number < 62) { + return String.fromCharCode(48 + (number - 52)); + } + if (number === 62) { + return "+"; + } + if (number === 63) { + return "/"; + } + throw "Tried to encode large digit " + number + " in base64."; + }; + + var encodeBase64 = function (str) { + var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + var out, i, len; + var c1, c2, c3; + + len = str.length; + i = 0; + out = ""; + while (i < len) { + c1 = str.charCodeAt(i++) & 0xff; + if (i == len) { + out += base64EncodeChars.charAt(c1 >> 2); + out += base64EncodeChars.charAt((c1 & 0x3) << 4); + out += "=="; + break; + } + c2 = str.charCodeAt(i++); + if (i == len) { + out += base64EncodeChars.charAt(c1 >> 2); + out += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4)); + out += base64EncodeChars.charAt((c2 & 0xF) << 2); + out += "="; + break; + } + c3 = str.charCodeAt(i++); + out += base64EncodeChars.charAt(c1 >> 2); + out += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4)); + out += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6)); + out += base64EncodeChars.charAt(c3 & 0x3F); + } + return out; + + }; + + var utf16to8 = function (str) { + var out, i, len, c; + + out = ""; + len = str.length; + for (i = 0; i < len; i++) { + c = str.charCodeAt(i); + if ((c >= 0x0001) && (c <= 0x007F)) { + out += str.charAt(i); + } else if (c > 0x07FF) { + out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F)); + out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F)); + out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F)); + } else { + out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F)); + out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F)); + } + } + return out; + + }; + + // A list of file extensions to mime types as found here: + // http://stackoverflow.com/questions/58510/using-net-how-can-you-find-the- + // mime-type-of-a-file-based-on-the-file-signature + var mimeTypes = { + ai: "application/postscript", + aif: "audio/x-aiff", + aifc: "audio/x-aiff", + aiff: "audio/x-aiff", + asc: "text/plain", + atom: "application/atom+xml", + au: "audio/basic", + avi: "video/x-msvideo", + bcpio: "application/x-bcpio", + bin: "application/octet-stream", + bmp: "image/bmp", + cdf: "application/x-netcdf", + cgm: "image/cgm", + "class": "application/octet-stream", + cpio: "application/x-cpio", + cpt: "application/mac-compactpro", + csh: "application/x-csh", + css: "text/css", + dcr: "application/x-director", + dif: "video/x-dv", + dir: "application/x-director", + djv: "image/vnd.djvu", + djvu: "image/vnd.djvu", + dll: "application/octet-stream", + dmg: "application/octet-stream", + dms: "application/octet-stream", + doc: "application/msword", + docx: "application/vnd.openxmlformats-officedocument.wordprocessingml." + "document", + dotx: "application/vnd.openxmlformats-officedocument.wordprocessingml." + "template", + docm: "application/vnd.ms-word.document.macroEnabled.12", + dotm: "application/vnd.ms-word.template.macroEnabled.12", + dtd: "application/xml-dtd", + dv: "video/x-dv", + dvi: "application/x-dvi", + dxr: "application/x-director", + eps: "application/postscript", + etx: "text/x-setext", + exe: "application/octet-stream", + ez: "application/andrew-inset", + gif: "image/gif", + gram: "application/srgs", + grxml: "application/srgs+xml", + gtar: "application/x-gtar", + hdf: "application/x-hdf", + hqx: "application/mac-binhex40", + htm: "text/html", + html: "text/html", + ice: "x-conference/x-cooltalk", + ico: "image/x-icon", + ics: "text/calendar", + ief: "image/ief", + ifb: "text/calendar", + iges: "model/iges", + igs: "model/iges", + jnlp: "application/x-java-jnlp-file", + jp2: "image/jp2", + jpe: "image/jpeg", + jpeg: "image/jpeg", + jpg: "image/jpeg", + js: "application/x-javascript", + kar: "audio/midi", + latex: "application/x-latex", + lha: "application/octet-stream", + lzh: "application/octet-stream", + m3u: "audio/x-mpegurl", + m4a: "audio/mp4a-latm", + m4b: "audio/mp4a-latm", + m4p: "audio/mp4a-latm", + m4u: "video/vnd.mpegurl", + m4v: "video/x-m4v", + mac: "image/x-macpaint", + man: "application/x-troff-man", + mathml: "application/mathml+xml", + me: "application/x-troff-me", + mesh: "model/mesh", + mid: "audio/midi", + midi: "audio/midi", + mif: "application/vnd.mif", + mov: "video/quicktime", + movie: "video/x-sgi-movie", + mp2: "audio/mpeg", + mp3: "audio/mpeg", + mp4: "video/mp4", + mpe: "video/mpeg", + mpeg: "video/mpeg", + mpg: "video/mpeg", + mpga: "audio/mpeg", + ms: "application/x-troff-ms", + msh: "model/mesh", + mxu: "video/vnd.mpegurl", + nc: "application/x-netcdf", + oda: "application/oda", + ogg: "application/ogg", + pbm: "image/x-portable-bitmap", + pct: "image/pict", + pdb: "chemical/x-pdb", + pdf: "application/pdf", + pgm: "image/x-portable-graymap", + pgn: "application/x-chess-pgn", + pic: "image/pict", + pict: "image/pict", + png: "image/png", + pnm: "image/x-portable-anymap", + pnt: "image/x-macpaint", + pntg: "image/x-macpaint", + ppm: "image/x-portable-pixmap", + ppt: "application/vnd.ms-powerpoint", + pptx: "application/vnd.openxmlformats-officedocument.presentationml." + "presentation", + potx: "application/vnd.openxmlformats-officedocument.presentationml." + "template", + ppsx: "application/vnd.openxmlformats-officedocument.presentationml." + "slideshow", + ppam: "application/vnd.ms-powerpoint.addin.macroEnabled.12", + pptm: "application/vnd.ms-powerpoint.presentation.macroEnabled.12", + potm: "application/vnd.ms-powerpoint.template.macroEnabled.12", + ppsm: "application/vnd.ms-powerpoint.slideshow.macroEnabled.12", + ps: "application/postscript", + qt: "video/quicktime", + qti: "image/x-quicktime", + qtif: "image/x-quicktime", + ra: "audio/x-pn-realaudio", + ram: "audio/x-pn-realaudio", + ras: "image/x-cmu-raster", + rdf: "application/rdf+xml", + rgb: "image/x-rgb", + rm: "application/vnd.rn-realmedia", + roff: "application/x-troff", + rtf: "text/rtf", + rtx: "text/richtext", + sgm: "text/sgml", + sgml: "text/sgml", + sh: "application/x-sh", + shar: "application/x-shar", + silo: "model/mesh", + sit: "application/x-stuffit", + skd: "application/x-koan", + skm: "application/x-koan", + skp: "application/x-koan", + skt: "application/x-koan", + smi: "application/smil", + smil: "application/smil", + snd: "audio/basic", + so: "application/octet-stream", + spl: "application/x-futuresplash", + src: "application/x-wais-source", + sv4cpio: "application/x-sv4cpio", + sv4crc: "application/x-sv4crc", + svg: "image/svg+xml", + swf: "application/x-shockwave-flash", + t: "application/x-troff", + tar: "application/x-tar", + tcl: "application/x-tcl", + tex: "application/x-tex", + texi: "application/x-texinfo", + texinfo: "application/x-texinfo", + tif: "image/tiff", + tiff: "image/tiff", + tr: "application/x-troff", + tsv: "text/tab-separated-values", + txt: "text/plain", + ustar: "application/x-ustar", + vcd: "application/x-cdlink", + vrml: "model/vrml", + vxml: "application/voicexml+xml", + wav: "audio/x-wav", + wbmp: "image/vnd.wap.wbmp", + wbmxl: "application/vnd.wap.wbxml", + wml: "text/vnd.wap.wml", + wmlc: "application/vnd.wap.wmlc", + wmls: "text/vnd.wap.wmlscript", + wmlsc: "application/vnd.wap.wmlscriptc", + wrl: "model/vrml", + xbm: "image/x-xbitmap", + xht: "application/xhtml+xml", + xhtml: "application/xhtml+xml", + xls: "application/vnd.ms-excel", + xml: "application/xml", + xpm: "image/x-xpixmap", + xsl: "application/xml", + xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + xltx: "application/vnd.openxmlformats-officedocument.spreadsheetml." + "template", + xlsm: "application/vnd.ms-excel.sheet.macroEnabled.12", + xltm: "application/vnd.ms-excel.template.macroEnabled.12", + xlam: "application/vnd.ms-excel.addin.macroEnabled.12", + xlsb: "application/vnd.ms-excel.sheet.binary.macroEnabled.12", + xslt: "application/xslt+xml", + xul: "application/vnd.mozilla.xul+xml", + xwd: "image/x-xwindowdump", + xyz: "chemical/x-xyz", + zip: "application/zip" + }; + + /** + * Reads a File using a FileReader. + * @param file {File} the File to read. + * @param type {String} (optional) the mimetype to override with. + * @return {Bmob.Promise} A Promise that will be fulfilled with a + * base64-encoded string of the data and its mime type. + */ + var readAsync = function (file, type) { + var promise = new Bmob.Promise(); + + if (typeof (FileReader) === "undefined") { + return Bmob.Promise.error(new Bmob.Error(- 1, "Attempted to use a FileReader on an unsupported browser.")); + } + + var reader = new FileReader(); + reader.onloadend = function () { + + promise.resolve(reader.result); + }; + reader.readAsBinaryString(file); + return promise; + }; + + /** + * Bmob.File 保存文件到bmob + * cloud. + * @param name {String} 文件名。在服务器中,这会改为唯一的文件名 + * @param data {file} 文件的数据 + * + * 文件对象是在" file upload control"中被选中,只能在下面的浏览器使用 + * in Firefox 3.6+, Safari 6.0.2+, Chrome 7+, and IE 10+. + * 例如:
+ * + * var fileUploadControl = $("#profilePhotoFileUpload")[0]; + * if (fileUploadControl.files.length > 0) { + * var file = fileUploadControl.files[0]; + * var name = "photo.jpg"; + * var bmobFile = new Bmob.File(name, file); + * bmobFile.save().then(function() { + * // The file has been saved to Bmob. + * }, function(error) { + * // The file either could not be read, or could not be saved to Bmob. + * }); + * }+ * @param type {String} 文件的类型. + */ + Bmob.File = function (name, data, type) { + data = data[0]; + this._name = name; + // this._name = encodeBase64(utf16to8(name)); + var currentUser = Bmob.User.current(); + this._metaData = { + owner: (currentUser != null ? currentUser.id : 'unknown') + }; + + // Guess the content type from the extension if we need to. + var extension = /\.([^.]*)$/.exec(name); + if (extension) { + extension = extension[1].toLowerCase(); + } + var guessedType = type || mimeTypes[extension] || "text/plain"; + this._guessedType = guessedType; + + if (typeof (File) !== "undefined" && data instanceof File) { + this._source = readAsync(data, type); + } else { + // throw "Creating a Bmob.File from a String is not yet supported."; + this._source = Bmob.Promise.as(data, guessedType); + this._metaData.size = data.length; + } + }; + + + + Bmob.File.prototype = { + + /** + * Gets the name of the file. Before save is called, this is the filename + * given by the user. After save is called, that name gets prefixed with a + * unique identifier. + */ + name: function () { + return this._name; + }, + + setName: function (name) { + this._name = name; + }, + + /** + * Gets the url of the file. It is only available after you save the file or + * after you get the file from a Bmob.Object. + * @return {String} + */ + url: function () { + return this._url; + }, + + setUrl: function (url) { + this._url = url; + }, + + /** + * Gets the group of the file. It is only available after you save the file or + * after you get the file from a Bmob.Object. + * @return {String} + */ + cdn: function () { + return this._cdn; + }, + + /** + *
Returns the file's metadata JSON object if no arguments is given.Returns the + * metadata value if a key is given.Set metadata value if key and value are both given.
+ *+ * var metadata = file.metaData(); //Get metadata JSON object. + * var size = file.metaData('size'); // Get the size metadata value. + * file.metaData('format', 'jpeg'); //set metadata attribute and value. + *+ * @return {Object} The file's metadata JSON object. + * @param {String} attr an optional metadata key. + * @param {Object} value an optional metadata value. + **/ + metaData: function (attr, value) { + if (attr != null && value != null) { + this._metaData[attr] = value; + return this; + } else if (attr != null) { + return this._metaData[attr]; + } else { + return this._metaData; + } + }, + + /** + * Destroy the file. + * @return {Bmob.Promise} A promise that is fulfilled when the destroy + * completes. + */ + destroy: function (options) { + if (!this._url && !this._cdn) return Bmob.Promise.error('The file url and cdn is not eixsts.')._thenRunCallbacks(options); + + var data = { + cdn: this._cdn, + _ContentType: "application/json", + url: this._url, + metaData: self._metaData, + }; + var request = Bmob._request("2/files", null, null, 'DELETE', data); + return request._thenRunCallbacks(options); + }, + + /** + * Saves the file to the Bmob cloud. + * @param {Object} options A Backbone-style options object. + * @return {Bmob.Promise} Promise that is resolved when the save finishes. + */ + save: function (options) { + var self = this; + if (!self._previousSave) { + if (self._source) { + self._previousSave = self._source.then(function (base64, type) { + var data = { + base64: base64, + // base64: encodeBase64(base64), + _ContentType: "text/plain", + mime_type: "text/plain", + metaData: self._metaData, + category: "wechatApp", + }; + if (!self._metaData.size) { + self._metaData.size = base64.length; + } + return Bmob._request("2/files", self._name, null, 'POST', data); + }).then(function (response) { + + self._name = response.filename; + self._url = response.url; + self._cdn = response.cdn; + + return self; + }); + } else { + throw "not source file" + } + } + return self._previousSave._thenRunCallbacks(options); + } + }; + + + /** + * 包含push的函数 + * @name Bmob.Push + * @namespace 推送消息 + */ + Bmob.Files = Bmob.Files || {}; + + + Bmob.Files.del = function (urls, options) { + var _url = urls.split(".com"); + if (!_url) { + return Bmob.Promise.error('The file url and cdn is not eixsts.')._thenRunCallbacks(options); + } + + var data = { + _ContentType: "application/json", + // url:_url, + }; + var request = Bmob._request("2/files/upyun", _url[1], null, 'DELETE', data); + return request.then(function (resp) { + return Bmob._decode(null, resp); + })._thenRunCallbacks(options); + }; + + /** + * Creates a new model with defined attributes. A client id (cid) is + * automatically generated and assigned for you. + * + *
You won't normally call this method directly. It is recommended that
+ * you use a subclass of Bmob.Object
instead, created by calling
+ * extend
.
However, if you don't want to use a subclass, or aren't sure which + * subclass is appropriate, you can use this form:
+ * var object = new Bmob.Object("ClassName"); + *+ * That is basically equivalent to:
+ * var MyClass = Bmob.Object.extend("ClassName"); + * var object = new MyClass(); + *+ * + * @param {Object} attributes The initial set of data to store in the object. + * @param {Object} options A set of Backbone-like options for creating the + * object. The only option currently supported is "collection". + * @see Bmob.Object.extend + * + * + *
The fundamental unit of Bmob data, which implements the Backbone Model + * interface.
+ */ + Bmob.Object = function (attributes, options) { + // Allow new Bmob.Object("ClassName") as a shortcut to _create. + if (_.isString(attributes)) { + return Bmob.Object._create.apply(this, arguments); + } + + attributes = attributes || {}; + if (options && options.parse) { + attributes = this.parse(attributes); + } + var defaults = Bmob._getValue(this, 'defaults'); + if (defaults) { + attributes = _.extend({}, + defaults, attributes); + } + if (options && options.collection) { + this.collection = options.collection; + } + + this._serverData = {}; // The last known data for this object from cloud. + this._opSetQueue = [{}]; // List of sets of changes to the data. + this.attributes = {}; // The best estimate of this's current data. + this._hashedJSON = {}; // Hash of values of containers at last save. + this._escapedAttributes = {}; + this.cid = _.uniqueId('c'); + this.changed = {}; + this._silent = {}; + this._pending = {}; + if (!this.set(attributes, { + silent: true + })) { + throw new Error("Can't create an invalid Bmob.Object"); + } + this.changed = {}; + this._silent = {}; + this._pending = {}; + this._hasData = true; + this._previousAttributes = _.clone(this.attributes); + this.initialize.apply(this, arguments); + }; + + /** + * @lends Bmob.Object.prototype + * @property {String} id The objectId of the Bmob Object. + */ + + /** + * Saves the given list of Bmob.Object. + * If any error is encountered, stops and calls the error handler. + * There are two ways you can call this function. + * + * The Backbone way:+ * Bmob.Object.saveAll([object1, object2, ...], { + * success: function(list) { + * // All the objects were saved. + * }, + * error: function(error) { + * // An error occurred while saving one of the objects. + * }, + * }); + *+ * A simplified syntax:
+ * Bmob.Object.saveAll([object1, object2, ...], function(list, error) { + * if (list) { + * // All the objects were saved. + * } else { + * // An error occurred. + * } + * }); + *+ * + * @param {Array} list A list of
Bmob.Object
.
+ * @param {Object} options A Backbone-style callback object.
+ */
+ Bmob.Object.saveAll = function (list, options) {
+ return Bmob.Object._deepSaveAsync(list)._thenRunCallbacks(options);
+ };
+
+ // Attach all inheritable methods to the Bmob.Object prototype.
+ _.extend(Bmob.Object.prototype, Bmob.Events,
+ /** @lends Bmob.Object.prototype */
+ {
+ _existed: false,
+ _fetchWhenSave: false,
+
+ /**
+ * Initialize is an empty function by default. Override it with your own
+ * initialization logic.
+ */
+ initialize: function () { },
+
+ /**
+ * Set whether to enable fetchWhenSave option when updating object.
+ * When set true, SDK would fetch the latest object after saving.
+ * Default is false.
+ * @param {boolean} enable true to enable fetchWhenSave option.
+ */
+ fetchWhenSave: function (enable) {
+ if (typeof enable !== 'boolean') {
+ throw "Expect boolean value for fetchWhenSave";
+ }
+ this._fetchWhenSave = enable;
+ },
+
+ /**
+ * Returns a JSON version of the object suitable for saving to Bmob.
+ * @return {Object}
+ */
+ toJSON: function () {
+ var json = this._toFullJSON();
+ Bmob._arrayEach(["__type", "className"],
+ function (key) {
+ delete json[key];
+ });
+ return json;
+ },
+
+ _toFullJSON: function (seenObjects) {
+ var json = _.clone(this.attributes);
+ Bmob._objectEach(json,
+ function (val, key) {
+ json[key] = Bmob._encode(val, seenObjects);
+ });
+ Bmob._objectEach(this._operations,
+ function (val, key) {
+ json[key] = val;
+ });
+
+ if (_.has(this, "id")) {
+ json.objectId = this.id;
+ }
+ if (_.has(this, "createdAt")) {
+ if (_.isDate(this.createdAt)) {
+ json.createdAt = this.createdAt.toJSON();
+ } else {
+ json.createdAt = this.createdAt;
+ }
+ }
+
+ if (_.has(this, "updatedAt")) {
+ if (_.isDate(this.updatedAt)) {
+ json.updatedAt = this.updatedAt.toJSON();
+ } else {
+ json.updatedAt = this.updatedAt;
+ }
+ }
+ json.__type = "Object";
+ json.className = this.className;
+ return json;
+ },
+
+ /**
+ * Updates _hashedJSON to reflect the current state of this object.
+ * Adds any changed hash values to the set of pending changes.
+ */
+ _refreshCache: function () {
+ var self = this;
+ if (self._refreshingCache) {
+ return;
+ }
+ self._refreshingCache = true;
+ Bmob._objectEach(this.attributes,
+ function (value, key) {
+ if (value instanceof Bmob.Object) {
+ value._refreshCache();
+ } else if (_.isObject(value)) {
+ if (self._resetCacheForKey(key)) {
+ self.set(key, new Bmob.Op.Set(value), {
+ silent: true
+ });
+ }
+ }
+ });
+ delete self._refreshingCache;
+ },
+
+ /**
+ * Returns true if this object has been modified since its last
+ * save/refresh. If an attribute is specified, it returns true only if that
+ * particular attribute has been modified since the last save/refresh.
+ * @param {String} attr An attribute name (optional).
+ * @return {Boolean}
+ */
+ dirty: function (attr) {
+ this._refreshCache();
+
+ var currentChanges = _.last(this._opSetQueue);
+
+ if (attr) {
+ return (currentChanges[attr] ? true : false);
+ }
+ if (!this.id) {
+ return true;
+ }
+ if (_.keys(currentChanges).length > 0) {
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * Gets a Pointer referencing this Object.
+ */
+ _toPointer: function () {
+ // if (!this.id) {
+ // throw new Error("Can't serialize an unsaved Bmob.Object");
+ // }
+ return {
+ __type: "Pointer",
+ className: this.className,
+ objectId: this.id
+ };
+ },
+
+ /**
+ * Gets the value of an attribute.
+ * @param {String} attr The string name of an attribute.
+ */
+ get: function (attr) {
+ return this.attributes[attr];
+ },
+
+ /**
+ * Gets a relation on the given class for the attribute.
+ * @param String attr The attribute to get the relation for.
+ */
+ relation: function (attr) {
+ var value = this.get(attr);
+ if (value) {
+ if (!(value instanceof Bmob.Relation)) {
+ throw "Called relation() on non-relation field " + attr;
+ }
+ value._ensureParentAndKey(this, attr);
+ return value;
+ } else {
+ return new Bmob.Relation(this, attr);
+ }
+ },
+
+ /**
+ * Gets the HTML-escaped value of an attribute.
+ */
+ escape: function (attr) {
+ var html = this._escapedAttributes[attr];
+ if (html) {
+ return html;
+ }
+ var val = this.attributes[attr];
+ var escaped;
+ if (Bmob._isNullOrUndefined(val)) {
+ escaped = '';
+ } else {
+ escaped = _.escape(val.toString());
+ }
+ this._escapedAttributes[attr] = escaped;
+ return escaped;
+ },
+
+ /**
+ * Returns true
if the attribute contains a value that is not
+ * null or undefined.
+ * @param {String} attr The string name of the attribute.
+ * @return {Boolean}
+ */
+ has: function (attr) {
+ return !Bmob._isNullOrUndefined(this.attributes[attr]);
+ },
+
+ /**
+ * Pulls "special" fields like objectId, createdAt, etc. out of attrs
+ * and puts them on "this" directly. Removes them from attrs.
+ * @param attrs - A dictionary with the data for this Bmob.Object.
+ */
+ _mergeMagicFields: function (attrs) {
+ // Check for changes of magic fields.
+ var model = this;
+ var specialFields = ["id", "objectId", "createdAt", "updatedAt"];
+ Bmob._arrayEach(specialFields,
+ function (attr) {
+ if (attrs[attr]) {
+ if (attr === "objectId") {
+ model.id = attrs[attr];
+ } else {
+ model[attr] = attrs[attr];
+ }
+ delete attrs[attr];
+ }
+ });
+ },
+
+ /**
+ * Returns the json to be sent to the server.
+ */
+ _startSave: function () {
+ this._opSetQueue.push({});
+ },
+
+ /**
+ * Called when a save fails because of an error. Any changes that were part
+ * of the save need to be merged with changes made after the save. This
+ * might throw an exception is you do conflicting operations. For example,
+ * if you do:
+ * object.set("foo", "bar");
+ * object.set("invalid field name", "baz");
+ * object.save();
+ * object.increment("foo");
+ * then this will throw when the save fails and the client tries to merge
+ * "bar" with the +1.
+ */
+ _cancelSave: function () {
+ var self = this;
+ var failedChanges = _.first(this._opSetQueue);
+ this._opSetQueue = _.rest(this._opSetQueue);
+ var nextChanges = _.first(this._opSetQueue);
+ Bmob._objectEach(failedChanges,
+ function (op, key) {
+ var op1 = failedChanges[key];
+ var op2 = nextChanges[key];
+ if (op1 && op2) {
+ nextChanges[key] = op2._mergeWithPrevious(op1);
+ } else if (op1) {
+ nextChanges[key] = op1;
+ }
+ });
+ this._saving = this._saving - 1;
+ },
+
+ /**
+ * Called when a save completes successfully. This merges the changes that
+ * were saved into the known server data, and overrides it with any data
+ * sent directly from the server.
+ */
+ _finishSave: function (serverData) {
+ // Grab a copy of any object referenced by this object. These instances
+ // may have already been fetched, and we don't want to lose their data.
+ // Note that doing it like this means we will unify separate copies of the
+ // same object, but that's a risk we have to take.
+ var fetchedObjects = {};
+ Bmob._traverse(this.attributes,
+ function (object) {
+ if (object instanceof Bmob.Object && object.id && object._hasData) {
+ fetchedObjects[object.id] = object;
+ }
+ });
+
+ var savedChanges = _.first(this._opSetQueue);
+ this._opSetQueue = _.rest(this._opSetQueue);
+ this._applyOpSet(savedChanges, this._serverData);
+ this._mergeMagicFields(serverData);
+ var self = this;
+ Bmob._objectEach(serverData,
+ function (value, key) {
+ self._serverData[key] = Bmob._decode(key, value);
+
+ // Look for any objects that might have become unfetched and fix them
+ // by replacing their values with the previously observed values.
+ var fetched = Bmob._traverse(self._serverData[key],
+ function (object) {
+ if (object instanceof Bmob.Object && fetchedObjects[object.id]) {
+ return fetchedObjects[object.id];
+ }
+ });
+ if (fetched) {
+ self._serverData[key] = fetched;
+ }
+ });
+ this._rebuildAllEstimatedData();
+ this._saving = this._saving - 1;
+ },
+
+ /**
+ * Called when a fetch or login is complete to set the known server data to
+ * the given object.
+ */
+ _finishFetch: function (serverData, hasData) {
+ // Clear out any changes the user might have made previously.
+ this._opSetQueue = [{}];
+
+ // Bring in all the new server data.
+ this._mergeMagicFields(serverData);
+ var self = this;
+ Bmob._objectEach(serverData,
+ function (value, key) {
+ self._serverData[key] = Bmob._decode(key, value);
+ });
+
+ // Refresh the attributes.
+ this._rebuildAllEstimatedData();
+
+ // Clear out the cache of mutable containers.
+ this._refreshCache();
+ this._opSetQueue = [{}];
+
+ this._hasData = hasData;
+ },
+
+ /**
+ * Applies the set of Bmob.Op in opSet to the object target.
+ */
+ _applyOpSet: function (opSet, target) {
+ var self = this;
+ Bmob._objectEach(opSet,
+ function (change, key) {
+ target[key] = change._estimate(target[key], self, key);
+ if (target[key] === Bmob.Op._UNSET) {
+ delete target[key];
+ }
+ });
+ },
+
+ /**
+ * Replaces the cached value for key with the current value.
+ * Returns true if the new value is different than the old value.
+ */
+ _resetCacheForKey: function (key) {
+ var value = this.attributes[key];
+ if (_.isObject(value) && !(value instanceof Bmob.Object) && !(value instanceof Bmob.File)) {
+ value = value.toJSON ? value.toJSON() : value;
+ var json = JSON.stringify(value);
+ if (this._hashedJSON[key] !== json) {
+ this._hashedJSON[key] = json;
+ return true;
+ }
+ }
+ return false;
+ },
+
+ /**
+ * Populates attributes[key] by starting with the last known data from the
+ * server, and applying all of the local changes that have been made to that
+ * key since then.
+ */
+ _rebuildEstimatedDataForKey: function (key) {
+ var self = this;
+ delete this.attributes[key];
+ if (this._serverData[key]) {
+ this.attributes[key] = this._serverData[key];
+ }
+ Bmob._arrayEach(this._opSetQueue,
+ function (opSet) {
+ var op = opSet[key];
+ if (op) {
+ self.attributes[key] = op._estimate(self.attributes[key], self, key);
+ if (self.attributes[key] === Bmob.Op._UNSET) {
+ delete self.attributes[key];
+ } else {
+ self._resetCacheForKey(key);
+ }
+ }
+ });
+ },
+
+ /**
+ * Populates attributes by starting with the last known data from the
+ * server, and applying all of the local changes that have been made since
+ * then.
+ */
+ _rebuildAllEstimatedData: function () {
+ var self = this;
+
+ var previousAttributes = _.clone(this.attributes);
+
+ this.attributes = _.clone(this._serverData);
+ Bmob._arrayEach(this._opSetQueue,
+ function (opSet) {
+ self._applyOpSet(opSet, self.attributes);
+ Bmob._objectEach(opSet,
+ function (op, key) {
+ self._resetCacheForKey(key);
+ });
+ });
+
+ // Trigger change events for anything that changed because of the fetch.
+ Bmob._objectEach(previousAttributes,
+ function (oldValue, key) {
+ if (self.attributes[key] !== oldValue) {
+ self.trigger('change:' + key, self, self.attributes[key], {});
+ }
+ });
+ Bmob._objectEach(this.attributes,
+ function (newValue, key) {
+ if (!_.has(previousAttributes, key)) {
+ self.trigger('change:' + key, self, newValue, {});
+ }
+ });
+ },
+
+ /**
+ * Sets a hash of model attributes on the object, firing
+ * "change"
unless you choose to silence it.
+ *
+ * You can call it with an object containing keys and values, or with one + * key and value. For example:
+ * gameTurn.set({ + * player: player1, + * diceRoll: 2 + * }, { + * error: function(gameTurnAgain, error) { + * // The set failed validation. + * } + * }); + * + * game.set("currentPlayer", player2, { + * error: function(gameTurnAgain, error) { + * // The set failed validation. + * } + * }); + * + * game.set("finished", true);+ * + * @param {String} key The key to set. + * @param {} value The value to give it. + * @param {Object} options A set of Backbone-like options for the set. + * The only supported options are
silent
,
+ * error
, and promise
.
+ * @return {Boolean} true if the set succeeded.
+ * @see Bmob.Object#validate
+ * @see Bmob.Error
+ */
+ set: function (key, value, options) {
+ var attrs, attr;
+ if (_.isObject(key) || Bmob._isNullOrUndefined(key)) {
+ attrs = key;
+ Bmob._objectEach(attrs,
+ function (v, k) {
+ attrs[k] = Bmob._decode(k, v);
+ });
+ options = value;
+ } else {
+ attrs = {};
+ attrs[key] = Bmob._decode(key, value);
+ }
+
+ // Extract attributes and options.
+ options = options || {};
+ if (!attrs) {
+ return this;
+ }
+ if (attrs instanceof Bmob.Object) {
+ attrs = attrs.attributes;
+ }
+
+ // If the unset option is used, every attribute should be a Unset.
+ if (options.unset) {
+ Bmob._objectEach(attrs,
+ function (unused_value, key) {
+ attrs[key] = new Bmob.Op.Unset();
+ });
+ }
+
+ // Apply all the attributes to get the estimated values.
+ var dataToValidate = _.clone(attrs);
+ var self = this;
+ Bmob._objectEach(dataToValidate,
+ function (value, key) {
+ if (value instanceof Bmob.Op) {
+ dataToValidate[key] = value._estimate(self.attributes[key], self, key);
+ if (dataToValidate[key] === Bmob.Op._UNSET) {
+ delete dataToValidate[key];
+ }
+ }
+ });
+
+ // Run validation.
+ if (!this._validate(attrs, options)) {
+ return false;
+ }
+
+ this._mergeMagicFields(attrs);
+
+ options.changes = {};
+ var escaped = this._escapedAttributes;
+ var prev = this._previousAttributes || {};
+
+ // Update attributes.
+ Bmob._arrayEach(_.keys(attrs),
+ function (attr) {
+ var val = attrs[attr];
+
+ // If this is a relation object we need to set the parent correctly,
+ // since the location where it was parsed does not have access to
+ // this object.
+ if (val instanceof Bmob.Relation) {
+ val.parent = self;
+ }
+
+ if (!(val instanceof Bmob.Op)) {
+ val = new Bmob.Op.Set(val);
+ }
+
+ // See if this change will actually have any effect.
+ var isRealChange = true;
+ if (val instanceof Bmob.Op.Set && _.isEqual(self.attributes[attr], val.value)) {
+ isRealChange = false;
+ }
+
+ if (isRealChange) {
+ delete escaped[attr];
+ if (options.silent) {
+ self._silent[attr] = true;
+ } else {
+ options.changes[attr] = true;
+ }
+ }
+
+ var currentChanges = _.last(self._opSetQueue);
+ currentChanges[attr] = val._mergeWithPrevious(currentChanges[attr]);
+ self._rebuildEstimatedDataForKey(attr);
+
+ if (isRealChange) {
+ self.changed[attr] = self.attributes[attr];
+ if (!options.silent) {
+ self._pending[attr] = true;
+ }
+ } else {
+ delete self.changed[attr];
+ delete self._pending[attr];
+ }
+ });
+
+ if (!options.silent) {
+ this.change(options);
+ }
+ return this;
+ },
+
+ /**
+ * Remove an attribute from the model, firing "change"
unless
+ * you choose to silence it. This is a noop if the attribute doesn't
+ * exist.
+ */
+ unset: function (attr, options) {
+ options = options || {};
+ options.unset = true;
+ return this.set(attr, null, options);
+ },
+
+ /**
+ * Atomically increments the value of the given attribute the next time the
+ * object is saved. If no amount is specified, 1 is used by default.
+ *
+ * @param attr {String} The key.
+ * @param amount {Number} The amount to increment by.
+ */
+ increment: function (attr, amount) {
+ if (_.isUndefined(amount) || _.isNull(amount)) {
+ amount = 1;
+ }
+ return this.set(attr, new Bmob.Op.Increment(amount));
+ },
+
+ /**
+ * Atomically add an object to the end of the array associated with a given
+ * key.
+ * @param attr {String} The key.
+ * @param item {} The item to add.
+ */
+ add: function (attr, item) {
+ return this.set(attr, new Bmob.Op.Add([item]));
+ },
+
+ /**
+ * Atomically add an object to the array associated with a given key, only
+ * if it is not already present in the array. The position of the insert is
+ * not guaranteed.
+ *
+ * @param attr {String} The key.
+ * @param item {} The object to add.
+ */
+ addUnique: function (attr, item) {
+ return this.set(attr, new Bmob.Op.AddUnique([item]));
+ },
+
+ /**
+ * Atomically remove all instances of an object from the array associated
+ * with a given key.
+ *
+ * @param attr {String} The key.
+ * @param item {} The object to remove.
+ */
+ remove: function (attr, item) {
+ return this.set(attr, new Bmob.Op.Remove([item]));
+ },
+
+ /**
+ * Returns an instance of a subclass of Bmob.Op describing what kind of
+ * modification has been performed on this field since the last time it was
+ * saved. For example, after calling object.increment("x"), calling
+ * object.op("x") would return an instance of Bmob.Op.Increment.
+ *
+ * @param attr {String} The key.
+ * @returns {Bmob.Op} The operation, or undefined if none.
+ */
+ op: function (attr) {
+ return _.last(this._opSetQueue)[attr];
+ },
+
+ /**
+ * Clear all attributes on the model, firing "change"
unless
+ * you choose to silence it.
+ */
+ clear: function (options) {
+ options = options || {};
+ options.unset = true;
+ var keysToClear = _.extend(this.attributes, this._operations);
+ return this.set(keysToClear, options);
+ },
+
+ /**
+ * Returns a JSON-encoded set of operations to be sent with the next save
+ * request.
+ */
+ _getSaveJSON: function () {
+ var json = _.clone(_.first(this._opSetQueue));
+ Bmob._objectEach(json,
+ function (op, key) {
+ json[key] = op.toJSON();
+ });
+ return json;
+ },
+
+ /**
+ * Returns true if this object can be serialized for saving.
+ */
+ _canBeSerialized: function () {
+ return Bmob.Object._canBeSerializedAsValue(this.attributes);
+ },
+
+ /**
+ * Fetch the model from the server. If the server's representation of the
+ * model differs from its current attributes, they will be overriden,
+ * triggering a "change"
event.
+ * @return {Bmob.Promise} A promise that is fulfilled when the fetch
+ * completes.
+ */
+ fetch: function (options) {
+ var self = this;
+ var request = Bmob._request("classes", this.className, this.id, 'GET');
+ return request.then(function (response, status, xhr) {
+ self._finishFetch(self.parse(response, status, xhr), true);
+ return self;
+ })._thenRunCallbacks(options, this);
+ },
+
+ /**
+ * Set a hash of model attributes, and save the model to the server.
+ * updatedAt will be updated when the request returns.
+ * You can either call it as:+ * object.save();+ * or
+ * object.save(null, options);+ * or
+ * object.save(attrs, options);+ * or
+ * object.save(key, value, options);+ * + * For example,
+ * gameTurn.save({ + * player: "Jake Cutter", + * diceRoll: 2 + * }, { + * success: function(gameTurnAgain) { + * // The save was successful. + * }, + * error: function(gameTurnAgain, error) { + * // The save failed. Error is an instance of Bmob.Error. + * } + * });+ * or with promises:
+ * gameTurn.save({ + * player: "Jake Cutter", + * diceRoll: 2 + * }).then(function(gameTurnAgain) { + * // The save was successful. + * }, function(error) { + * // The save failed. Error is an instance of Bmob.Error. + * });+ * + * @return {Bmob.Promise} A promise that is fulfilled when the save + * completes. + * @see Bmob.Error + */ + save: function (arg1, arg2, arg3) { + var i, attrs, current, options, saved; + if (_.isObject(arg1) || Bmob._isNullOrUndefined(arg1)) { + attrs = arg1; + options = arg2; + } else { + attrs = {}; + attrs[arg1] = arg2; + options = arg3; + } + + // Make save({ success: function() {} }) work. + if (!options && attrs) { + var extra_keys = _.reject(attrs, + function (value, key) { + return _.include(["success", "error", "wait"], key); + }); + if (extra_keys.length === 0) { + var all_functions = true; + if (_.has(attrs, "success") && !_.isFunction(attrs.success)) { + all_functions = false; + } + if (_.has(attrs, "error") && !_.isFunction(attrs.error)) { + all_functions = false; + } + if (all_functions) { + // This attrs object looks like it's really an options object, + // and there's no other options object, so let's just use it. + return this.save(null, attrs); + } + } + } + + options = _.clone(options) || {}; + if (options.wait) { + current = _.clone(this.attributes); + } + + var setOptions = _.clone(options) || {}; + if (setOptions.wait) { + setOptions.silent = true; + } + var setError; + setOptions.error = function (model, error) { + setError = error; + }; + if (attrs && !this.set(attrs, setOptions)) { + return Bmob.Promise.error(setError)._thenRunCallbacks(options, this); + } + + var model = this; + + // If there is any unsaved child, save it first. + model._refreshCache(); + + var unsavedChildren = []; + var unsavedFiles = []; + Bmob.Object._findUnsavedChildren(model.attributes, unsavedChildren, unsavedFiles); + if (unsavedChildren.length + unsavedFiles.length > 0) { + return Bmob.Object._deepSaveAsync(this.attributes).then(function () { + return model.save(null, options); + }, + function (error) { + return Bmob.Promise.error(error)._thenRunCallbacks(options, model); + }); + } + + this._startSave(); + this._saving = (this._saving || 0) + 1; + + this._allPreviousSaves = this._allPreviousSaves || Bmob.Promise.as(); + this._allPreviousSaves = this._allPreviousSaves._continueWith(function () { + var method = model.id ? 'PUT' : 'POST'; + + var json = model._getSaveJSON(); + + if (method === 'PUT' && model._fetchWhenSave) { + //Sepcial-case fetchWhenSave when updating object. + json._fetchWhenSave = true; + } + + var route = "classes"; + var className = model.className; + if (model.className === "_User" && !model.id) { + // Special-case user sign-up. + route = "users"; + className = null; + } + var request = Bmob._request(route, className, model.id, method, json); + + request = request.then(function (resp, status, xhr) { + var serverAttrs = model.parse(resp, status, xhr); + if (options.wait) { + serverAttrs = _.extend(attrs || {}, + serverAttrs); + } + model._finishSave(serverAttrs); + if (options.wait) { + model.set(current, setOptions); + } + return model; + + }, + function (error) { + model._cancelSave(); + return Bmob.Promise.error(error); + + })._thenRunCallbacks(options, model); + + return request; + }); + return this._allPreviousSaves; + }, + + /** + * Destroy this model on the server if it was already persisted. + * Optimistically removes the model from its collection, if it has one. + * If `wait: true` is passed, waits for the server to respond + * before removal. + * + * @return {Bmob.Promise} A promise that is fulfilled when the destroy + * completes. + */ + destroy: function (options) { + options = options || {}; + var model = this; + + var triggerDestroy = function () { + model.trigger('destroy', model, model.collection, options); + }; + + if (!this.id) { + return triggerDestroy(); + } + + if (!options.wait) { + triggerDestroy(); + } + + var request = Bmob._request("classes", this.className, this.id, 'DELETE'); + return request.then(function () { + if (options.wait) { + triggerDestroy(); + } + return model; + })._thenRunCallbacks(options, this); + }, + + /** + * Converts a response into the hash of attributes to be set on the model. + * @ignore + */ + parse: function (resp, status, xhr) { + var output = _.clone(resp); + _(["createdAt", "updatedAt"]).each(function (key) { + if (output[key]) { + output[key] = output[key]; + } + }); + if (!output.updatedAt) { + output.updatedAt = output.createdAt; + } + if (status) { + this._existed = (status !== 201); + } + return output; + }, + + /** + * Creates a new model with identical attributes to this one. + * @return {Bmob.Object} + */ + clone: function () { + return new this.constructor(this.attributes); + }, + + /** + * Returns true if this object has never been saved to Bmob. + * @return {Boolean} + */ + isNew: function () { + return !this.id; + }, + + /** + * Call this method to manually fire a `"change"` event for this model and + * a `"change:attribute"` event for each changed attribute. + * Calling this will cause all objects observing the model to update. + */ + change: function (options) { + options = options || {}; + var changing = this._changing; + this._changing = true; + + // Silent changes become pending changes. + var self = this; + Bmob._objectEach(this._silent, + function (attr) { + self._pending[attr] = true; + }); + + // Silent changes are triggered. + var changes = _.extend({}, + options.changes, this._silent); + this._silent = {}; + Bmob._objectEach(changes, + function (unused_value, attr) { + self.trigger('change:' + attr, self, self.get(attr), options); + }); + if (changing) { + return this; + } + + // This is to get around lint not letting us make a function in a loop. + var deleteChanged = function (value, attr) { + if (!self._pending[attr] && !self._silent[attr]) { + delete self.changed[attr]; + } + }; + + // Continue firing `"change"` events while there are pending changes. + while (!_.isEmpty(this._pending)) { + this._pending = {}; + this.trigger('change', this, options); + // Pending and silent changes still remain. + Bmob._objectEach(this.changed, deleteChanged); + self._previousAttributes = _.clone(this.attributes); + } + + this._changing = false; + return this; + }, + + /** + * Returns true if this object was created by the Bmob server when the + * object might have already been there (e.g. in the case of a Facebook + * login) + */ + existed: function () { + return this._existed; + }, + + /** + * Determine if the model has changed since the last
"change"
+ * event. If you specify an attribute name, determine if that attribute
+ * has changed.
+ * @param {String} attr Optional attribute name
+ * @return {Boolean}
+ */
+ hasChanged: function (attr) {
+ if (!arguments.length) {
+ return !_.isEmpty(this.changed);
+ }
+ return this.changed && _.has(this.changed, attr);
+ },
+
+ /**
+ * Returns an object containing all the attributes that have changed, or
+ * false if there are no changed attributes. Useful for determining what
+ * parts of a view need to be updated and/or what attributes need to be
+ * persisted to the server. Unset attributes will be set to undefined.
+ * You can also pass an attributes object to diff against the model,
+ * determining if there *would be* a change.
+ */
+ changedAttributes: function (diff) {
+ if (!diff) {
+ return this.hasChanged() ? _.clone(this.changed) : false;
+ }
+ var changed = {};
+ var old = this._previousAttributes;
+ Bmob._objectEach(diff,
+ function (diffVal, attr) {
+ if (!_.isEqual(old[attr], diffVal)) {
+ changed[attr] = diffVal;
+ }
+ });
+ return changed;
+ },
+
+ /**
+ * Gets the previous value of an attribute, recorded at the time the last
+ * "change"
event was fired.
+ * @param {String} attr Name of the attribute to get.
+ */
+ previous: function (attr) {
+ if (!arguments.length || !this._previousAttributes) {
+ return null;
+ }
+ return this._previousAttributes[attr];
+ },
+
+ /**
+ * Gets all of the attributes of the model at the time of the previous
+ * "change"
event.
+ * @return {Object}
+ */
+ previousAttributes: function () {
+ return _.clone(this._previousAttributes);
+ },
+
+ /**
+ * Checks if the model is currently in a valid state. It's only possible to
+ * get into an *invalid* state if you're using silent changes.
+ * @return {Boolean}
+ */
+ isValid: function () {
+ return !this.validate(this.attributes);
+ },
+
+ /**
+ * You should not call this function directly unless you subclass
+ * Bmob.Object
, in which case you can override this method
+ * to provide additional validation on set
and
+ * save
. Your implementation should return
+ *
+ * @param {Object} attrs The current data to validate.
+ * @param {Object} options A Backbone-like options object.
+ * @return {} False if the data is valid. An error object otherwise.
+ * @see Bmob.Object#set
+ */
+ validate: function (attrs, options) {
+ if (_.has(attrs, "ACL") && !(attrs.ACL instanceof Bmob.ACL)) {
+ return new Bmob.Error(Bmob.Error.OTHER_CAUSE, "ACL must be a Bmob.ACL.");
+ }
+ return false;
+ },
+
+ /**
+ * Run validation against a set of incoming attributes, returning `true`
+ * if all is well. If a specific `error` callback has been passed,
+ * call that instead of firing the general `"error"` event.
+ */
+ _validate: function (attrs, options) {
+ if (options.silent || !this.validate) {
+ return true;
+ }
+ attrs = _.extend({},
+ this.attributes, attrs);
+ var error = this.validate(attrs, options);
+ if (!error) {
+ return true;
+ }
+ if (options && options.error) {
+ options.error(this, error, options);
+ } else {
+ this.trigger('error', this, error, options);
+ }
+ return false;
+ },
+
+ /**
+ * Returns the ACL for this object.
+ * @returns {Bmob.ACL} An instance of Bmob.ACL.
+ * @see Bmob.Object#get
+ */
+ getACL: function () {
+ return this.get("ACL");
+ },
+
+ /**
+ * Sets the ACL to be used for this object.
+ * @param {Bmob.ACL} acl An instance of Bmob.ACL.
+ * @param {Object} options Optional Backbone-like options object to be
+ * passed in to set.
+ * @return {Boolean} Whether the set passed validation.
+ * @see Bmob.Object#set
+ */
+ setACL: function (acl, options) {
+ return this.set("ACL", acl, options);
+ }
+
+ });
+
+ /**
+ * Creates an instance of a subclass of Bmob.Object for the give classname
+ * and id.
+ * @param {String} className The name of the Bmob class backing this model.
+ * @param {String} id The object id of this model.
+ * @return {Bmob.Object} A new subclass instance of Bmob.Object.
+ */
+ Bmob.Object.createWithoutData = function (className, id, hasData) {
+ var result = new Bmob.Object(className);
+ result.id = id;
+ result._hasData = hasData;
+ return result;
+ };
+ /**
+ * Delete objects in batch.The objects className must be the same.
+ * @param {Array} The ParseObject array to be deleted.
+ * @param {Object} options Standard options object with success and error
+ * callbacks.
+ * @return {Bmob.Promise} A promise that is fulfilled when the save
+ * completes.
+ */
+ Bmob.Object.destroyAll = function (objects, options) {
+ if (objects == null || objects.length == 0) {
+ return Bmob.Promise.as()._thenRunCallbacks(options);
+ }
+ var className = objects[0].className;
+ var id = "";
+ var wasFirst = true;
+ objects.forEach(function (obj) {
+ if (obj.className != className) throw "Bmob.Object.destroyAll requires the argument object array's classNames must be the same";
+ if (!obj.id) throw "Could not delete unsaved object";
+ if (wasFirst) {
+ id = obj.id;
+ wasFirst = false;
+ } else {
+ id = id + ',' + obj.id;
+ }
+ });
+ var request = Bmob._request("classes", className, id, 'DELETE');
+ return request._thenRunCallbacks(options);
+ };
+
+ /**
+ * Returns the appropriate subclass for making new instances of the given
+ * className string.
+ */
+ Bmob.Object._getSubclass = function (className) {
+ if (!_.isString(className)) {
+ throw "Bmob.Object._getSubclass requires a string argument.";
+ }
+ var ObjectClass = Bmob.Object._classMap[className];
+ if (!ObjectClass) {
+ ObjectClass = Bmob.Object.extend(className);
+ Bmob.Object._classMap[className] = ObjectClass;
+ }
+ return ObjectClass;
+ };
+
+ /**
+ * Creates an instance of a subclass of Bmob.Object for the given classname.
+ */
+ Bmob.Object._create = function (className, attributes, options) {
+ var ObjectClass = Bmob.Object._getSubclass(className);
+ return new ObjectClass(attributes, options);
+ };
+
+ // Set up a map of className to class so that we can create new instances of
+ // Bmob Objects from JSON automatically.
+ Bmob.Object._classMap = {};
+
+ Bmob.Object._extend = Bmob._extend;
+
+ /**
+ * Creates a new subclass of Bmob.Object for the given Bmob class name.
+ *
+ * Every extension of a Bmob class will inherit from the most recent + * previous extension of that class. When a Bmob.Object is automatically + * created by parsing JSON, it will use the most recent extension of that + * class.
+ * + *You should call either:
+ * var MyClass = Bmob.Object.extend("MyClass", { + * Instance properties + * }, { + * Class properties + * });+ * or, for Backbone compatibility:
+ * var MyClass = Bmob.Object.extend({ + * className: "MyClass", + * Other instance properties + * }, { + * Class properties + * });+ * + * @param {String} className The name of the Bmob class backing this model. + * @param {Object} protoProps Instance properties to add to instances of the + * class returned from this method. + * @param {Object} classProps Class properties to add the class returned from + * this method. + * @return {Class} A new subclass of Bmob.Object. + */ + Bmob.Object.extend = function (className, protoProps, classProps) { + // Handle the case with only two args. + if (!_.isString(className)) { + if (className && _.has(className, "className")) { + return Bmob.Object.extend(className.className, className, protoProps); + } else { + throw new Error("Bmob.Object.extend's first argument should be the className."); + } + } + + // If someone tries to subclass "User", coerce it to the right type. + if (className === "User") { + className = "_User"; + } + + var NewClassObject = null; + if (_.has(Bmob.Object._classMap, className)) { + var OldClassObject = Bmob.Object._classMap[className]; + // This new subclass has been told to extend both from "this" and from + // OldClassObject. This is multiple inheritance, which isn't supported. + // For now, let's just pick one. + NewClassObject = OldClassObject._extend(protoProps, classProps); + } else { + protoProps = protoProps || {}; + protoProps.className = className; + NewClassObject = this._extend(protoProps, classProps); + } + // Extending a subclass should reuse the classname automatically. + NewClassObject.extend = function (arg0) { + if (_.isString(arg0) || (arg0 && _.has(arg0, "className"))) { + return Bmob.Object.extend.apply(NewClassObject, arguments); + } + var newArguments = [className].concat(Bmob._.toArray(arguments)); + return Bmob.Object.extend.apply(NewClassObject, newArguments); + }; + Bmob.Object._classMap[className] = NewClassObject; + return NewClassObject; + }; + + Bmob.Object._findUnsavedChildren = function (object, children, files) { + Bmob._traverse(object, + function (object) { + if (object instanceof Bmob.Object) { + object._refreshCache(); + if (object.dirty()) { + children.push(object); + } + return; + } + + if (object instanceof Bmob.File) { + if (!object.url()) { + files.push(object); + } + return; + } + + }); + }; + + Bmob.Object._canBeSerializedAsValue = function (object) { + var canBeSerializedAsValue = true; + + if (object instanceof Bmob.Object) { + canBeSerializedAsValue = !!object.id; + + } else if (_.isArray(object)) { + Bmob._arrayEach(object, + function (child) { + if (!Bmob.Object._canBeSerializedAsValue(child)) { + canBeSerializedAsValue = false; + } + }); + + } else if (_.isObject(object)) { + Bmob._objectEach(object, + function (child) { + if (!Bmob.Object._canBeSerializedAsValue(child)) { + canBeSerializedAsValue = false; + } + }); + } + + return canBeSerializedAsValue; + }; + + Bmob.Object._deepSaveAsync = function (object) { + var unsavedChildren = []; + var unsavedFiles = []; + Bmob.Object._findUnsavedChildren(object, unsavedChildren, unsavedFiles); + + var promise = Bmob.Promise.as(); + _.each(unsavedFiles, + function (file) { + promise = promise.then(function () { + return file.save(); + }); + }); + + var objects = _.uniq(unsavedChildren); + var remaining = _.uniq(objects); + + return promise.then(function () { + return Bmob.Promise._continueWhile(function () { + return remaining.length > 0; + }, + function () { + + // Gather up all the objects that can be saved in this batch. + var batch = []; + var newRemaining = []; + Bmob._arrayEach(remaining, + function (object) { + // Limit batches to 20 objects. + if (batch.length > 20) { + newRemaining.push(object); + return; + } + + if (object._canBeSerialized()) { + batch.push(object); + } else { + newRemaining.push(object); + } + }); + remaining = newRemaining; + + // If we can't save any objects, there must be a circular reference. + if (batch.length === 0) { + return Bmob.Promise.error(new Bmob.Error(Bmob.Error.OTHER_CAUSE, "Tried to save a batch with a cycle.")); + } + + // Reserve a spot in every object's save queue. + var readyToStart = Bmob.Promise.when(_.map(batch, + function (object) { + return object._allPreviousSaves || Bmob.Promise.as(); + })); + var batchFinished = new Bmob.Promise(); + Bmob._arrayEach(batch, + function (object) { + object._allPreviousSaves = batchFinished; + }); + + // Save a single batch, whether previous saves succeeded or failed. + return readyToStart._continueWith(function () { + return Bmob._request("batch", null, null, "POST", { + requests: _.map(batch, + function (object) { + var json = object._getSaveJSON(); + var method = "POST"; + + var path = "/1/classes/" + object.className; + if (object.id) { + path = path + "/" + object.id; + method = "PUT"; + } + + object._startSave(); + + return { + method: method, + path: path, + body: json + }; + }) + + }).then(function (response, status, xhr) { + var error; + Bmob._arrayEach(batch, + function (object, i) { + if (response[i].success) { + object._finishSave(object.parse(response[i].success, status, xhr)); + } else { + error = error || response[i].error; + object._cancelSave(); + } + }); + if (error) { + return Bmob.Promise.error(new Bmob.Error(error.code, error.error)); + } + + }).then(function (results) { + batchFinished.resolve(results); + return results; + }, + function (error) { + batchFinished.reject(error); + return Bmob.Promise.error(error); + }); + }); + }); + }).then(function () { + return object; + }); + }; + + /** + * Bmob.Role acl权限控制中的用户角色类 + * + *
角色必须要有名称(名称创建后不能修改), 同时必须指定ACL
+ * @class + * @namespace acl权限控制中的用户角色类 + */ + Bmob.Role = Bmob.Object.extend("_Role", + /** @lends Bmob.Role.prototype */ + { + // Instance Methods + /** + * 通过名称和ACL构造一个BmobRole + * @param {String} name 创建role的名称 + * @param {Bmob.ACL} acl 这个角色的acl,角色必须要有一个ACL。 + */ + constructor: function (name, acl) { + if (_.isString(name) && (acl instanceof Bmob.ACL)) { + Bmob.Object.prototype.constructor.call(this, null, null); + this.setName(name); + this.setACL(acl); + } else { + Bmob.Object.prototype.constructor.call(this, name, acl); + } + }, + + /** + * 获取角色的name。同时可以使用role.get("name") + * @return {String} 角色的名称 + */ + getName: function () { + return this.get("name"); + }, + + /** + * 设置角色的名称。这个值必须要在保存前设置,而且只能设置一次 + *+ * 角色的名称只能包含数字,字母, _, -。 + *
+ * + *等同于使用 role.set("name", name)
+ * @param {String} name 角色的名称 + * @param {Object} options 标准options对象 + */ + setName: function (name, options) { + return this.set("name", name, options); + }, + + /** + * 获取这个角色对应的用户Bmob.Users。这些用户已经被分配了权限(例如读写的权限)。 + * 你能通过relation添加和移除这些用户 + *这等同于使用 role.relation("users")
+ * + * @return {Bmob.Relation} the relation for the users belonging to this + * role. + */ + getUsers: function () { + return this.relation("users"); + }, + + /** + * 获取这个角色对应的角色Bmob.Roles。这些用户已经被分配了权限(例如读写的权限)。 + * 你能通过relation添加和移除这些用户 + *这等同于使用 role.relation("roles")
+ * + * @return {Bmob.Relation} the relation for the roles belonging to this + * role. + */ + getRoles: function () { + return this.relation("roles"); + }, + + /** + * @ignore + */ + validate: function (attrs, options) { + if ("name" in attrs && attrs.name !== this.getName()) { + var newName = attrs.name; + if (this.id && this.id !== attrs.objectId) { + // Check to see if the objectId being set matches this.id. + // This happens during a fetch -- the id is set before calling fetch. + // Let the name be set in this case. + return new Bmob.Error(Bmob.Error.OTHER_CAUSE, "A role's name can only be set before it has been saved."); + } + if (!_.isString(newName)) { + return new Bmob.Error(Bmob.Error.OTHER_CAUSE, "A role's name must be a String."); + } + if (!(/^[0-9a-zA-Z\-_ ]+$/).test(newName)) { + return new Bmob.Error(Bmob.Error.OTHER_CAUSE, "A role's name can only contain alphanumeric characters, _," + " -, and spaces."); + } + } + if (Bmob.Object.prototype.validate) { + return Bmob.Object.prototype.validate.call(this, attrs, options); + } + return false; + } + }); + + /** + *创建model和options的实体。特别地,你不会直接调用这个方法,你会Bmob.Collection.extend
通过创建一*个子类。
+ * @param {Array} Bmob.Object
数组.
+ *
+ * @param {Object} options Backbone-style options 的可选options object.
+ * 有效的 options提供标准的 collection class。 更详细的信息请看 + * Backbone + * documentation.
+ */ + Bmob.Collection = function (models, options) { + options = options || {}; + if (options.comparator) { + this.comparator = options.comparator; + } + if (options.model) { + this.model = options.model; + } + if (options.query) { + this.query = options.query; + } + this._reset(); + this.initialize.apply(this, arguments); + if (models) { + this.reset(models, { + silent: true, + parse: options.parse + }); + } + }; + + // Define the Collection's inheritable methods. + _.extend(Bmob.Collection.prototype, Bmob.Events, + /** @lends Bmob.Collection.prototype */ + { + + // The default model for a collection is just a Bmob.Object. + // This should be overridden in most cases. + model: Bmob.Object, + + /** + * Initialize 默认是空函数. 请根据自身的逻辑重写这个方法 + */ + initialize: function () { }, + + /** + * + * json 格式的models'属性数组 + */ + toJSON: function () { + return this.map(function (model) { + return model.toJSON(); + }); + }, + + /** + * 添加model,或者一系列的对象集合。传入**silent**避免触发`add`事件。 + */ + add: function (models, options) { + var i, index, length, model, cid, id, cids = {}, + ids = {}; + options = options || {}; + models = _.isArray(models) ? models.slice() : [models]; + + // Begin by turning bare objects into model references, and preventing + // invalid models or duplicate models from being added. + for (i = 0, length = models.length; i < length; i++) { + models[i] = this._prepareModel(models[i], options); + model = models[i]; + if (!model) { + throw new Error("Can't add an invalid model to a collection"); + } + cid = model.cid; + if (cids[cid] || this._byCid[cid]) { + throw new Error("Duplicate cid: can't add the same model " + "to a collection twice"); + } + id = model.id; + if (!Bmob._isNullOrUndefined(id) && (ids[id] || this._byId[id])) { + throw new Error("Duplicate id: can't add the same model " + "to a collection twice"); + } + ids[id] = model; + cids[cid] = model; + } + + // Listen to added models' events, and index models for lookup by + // `id` and by `cid`. + for (i = 0; i < length; i++) { + (model = models[i]).on('all', this._onModelEvent, this); + this._byCid[model.cid] = model; + if (model.id) { + this._byId[model.id] = model; + } + } + + // Insert models into the collection, re-sorting if needed, and triggering + // `add` events unless silenced. + this.length += length; + index = Bmob._isNullOrUndefined(options.at) ? this.models.length : options.at; + this.models.splice.apply(this.models, [index, 0].concat(models)); + if (this.comparator) { + this.sort({ + silent: true + }); + } + if (options.silent) { + return this; + } + for (i = 0, length = this.models.length; i < length; i++) { + model = this.models[i]; + if (cids[model.cid]) { + options.index = i; + model.trigger('add', model, this, options); + } + } + return this; + }, + + /** + * 移除一个model,或者从集合中移除一系列models。当移除对象时,传入silent避免触发remove
事件。
+ */
+ remove: function (models, options) {
+ var i, l, index, model;
+ options = options || {};
+ models = _.isArray(models) ? models.slice() : [models];
+ for (i = 0, l = models.length; i < l; i++) {
+ model = this.getByCid(models[i]) || this.get(models[i]);
+ if (!model) {
+ continue;
+ }
+ delete this._byId[model.id];
+ delete this._byCid[model.cid];
+ index = this.indexOf(model);
+ this.models.splice(index, 1);
+ this.length--;
+ if (!options.silent) {
+ options.index = index;
+ model.trigger('remove', model, this, options);
+ }
+ this._removeReference(model);
+ }
+ return this;
+ },
+
+ /**
+ * 通过id获取一个model
+ */
+ get: function (id) {
+ return id && this._byId[id.id || id];
+ },
+
+ /**
+ * 通过client id获取一个model
+ */
+ getByCid: function (cid) {
+ return cid && this._byCid[cid.cid || cid];
+ },
+
+ /**
+ * 通过下标获取一个model
+ */
+ at: function (index) {
+ return this.models[index];
+ },
+
+ /**
+ * 强制collection对自身的元素进行重新排序。一般情况下你不需要调用这个函数,因为当添加对象时这个函数会自动调用
+ */
+ sort: function (options) {
+ options = options || {};
+ if (!this.comparator) {
+ throw new Error('Cannot sort a set without a comparator');
+ }
+ var boundComparator = _.bind(this.comparator, this);
+ if (this.comparator.length === 1) {
+ this.models = this.sortBy(boundComparator);
+ } else {
+ this.models.sort(boundComparator);
+ }
+ if (!options.silent) {
+ this.trigger('reset', this, options);
+ }
+ return this;
+ },
+
+ /**
+ * 采集集合中每个对象的属性
+ */
+ pluck: function (attr) {
+ return _.map(this.models,
+ function (model) {
+ return model.get(attr);
+ });
+ },
+
+ /**
+ * When you have more items than you want to add or remove individually,
+ * you can reset the entire set with a new list of models, without firing
+ * any `add` or `remove` events. Fires `reset` when finished.
+ */
+ reset: function (models, options) {
+ var self = this;
+ models = models || [];
+ options = options || {};
+ Bmob._arrayEach(this.models,
+ function (model) {
+ self._removeReference(model);
+ });
+ this._reset();
+ this.add(models, {
+ silent: true,
+ parse: options.parse
+ });
+ if (!options.silent) {
+ this.trigger('reset', this, options);
+ }
+ return this;
+ },
+
+ /**
+ * Fetches the default set of models for this collection, resetting the
+ * collection when they arrive. If `add: true` is passed, appends the
+ * models to the collection instead of resetting.
+ */
+ fetch: function (options) {
+ options = _.clone(options) || {};
+ if (options.parse === undefined) {
+ options.parse = true;
+ }
+ var collection = this;
+ var query = this.query || new Bmob.Query(this.model);
+ return query.find().then(function (results) {
+ if (options.add) {
+ collection.add(results, options);
+ } else {
+ collection.reset(results, options);
+ }
+ return collection;
+ })._thenRunCallbacks(options, this);
+ },
+
+ /**
+ * Creates a new instance of a model in this collection. Add the model to
+ * the collection immediately, unless `wait: true` is passed, in which case
+ * we wait for the server to agree.
+ */
+ create: function (model, options) {
+ var coll = this;
+ options = options ? _.clone(options) : {};
+ model = this._prepareModel(model, options);
+ if (!model) {
+ return false;
+ }
+ if (!options.wait) {
+ coll.add(model, options);
+ }
+ var success = options.success;
+ options.success = function (nextModel, resp, xhr) {
+ if (options.wait) {
+ coll.add(nextModel, options);
+ }
+ if (success) {
+ success(nextModel, resp);
+ } else {
+ nextModel.trigger('sync', model, resp, options);
+ }
+ };
+ model.save(null, options);
+ return model;
+ },
+
+ /**
+ * Converts a response into a list of models to be added to the collection.
+ * The default implementation is just to pass it through.
+ * @ignore
+ */
+ parse: function (resp, xhr) {
+ return resp;
+ },
+
+ /**
+ * Proxy to _'s chain. Can't be proxied the same way the rest of the
+ * underscore methods are proxied because it relies on the underscore
+ * constructor.
+ */
+ chain: function () {
+ return _(this.models).chain();
+ },
+
+ /**
+ * Reset all internal state. Called when the collection is reset.
+ */
+ _reset: function (options) {
+ this.length = 0;
+ this.models = [];
+ this._byId = {};
+ this._byCid = {};
+ },
+
+ /**
+ * Prepare a model or hash of attributes to be added to this collection.
+ */
+ _prepareModel: function (model, options) {
+ if (!(model instanceof Bmob.Object)) {
+ var attrs = model;
+ options.collection = this;
+ model = new this.model(attrs, options);
+ if (!model._validate(model.attributes, options)) {
+ model = false;
+ }
+ } else if (!model.collection) {
+ model.collection = this;
+ }
+ return model;
+ },
+
+ /**
+ * Internal method to remove a model's ties to a collection.
+ */
+ _removeReference: function (model) {
+ if (this === model.collection) {
+ delete model.collection;
+ }
+ model.off('all', this._onModelEvent, this);
+ },
+
+ /**
+ * Internal method called every time a model in the set fires an event.
+ * Sets need to update their indexes when models change ids. All other
+ * events simply proxy through. "add" and "remove" events that originate
+ * in other collections are ignored.
+ */
+ _onModelEvent: function (ev, model, collection, options) {
+ if ((ev === 'add' || ev === 'remove') && collection !== this) {
+ return;
+ }
+ if (ev === 'destroy') {
+ this.remove(model, options);
+ }
+ if (model && ev === 'change:objectId') {
+ delete this._byId[model.previous("objectId")];
+ this._byId[model.id] = model;
+ }
+ this.trigger.apply(this, arguments);
+ }
+
+ });
+
+ // Underscore methods that we want to implement on the Collection.
+ var methods = ['forEach', 'each', 'map', 'reduce', 'reduceRight', 'find', 'detect', 'filter', 'select', 'reject', 'every', 'all', 'some', 'any', 'include', 'contains', 'invoke', 'max', 'min', 'sortBy', 'sortedIndex', 'toArray', 'size', 'first', 'initial', 'rest', 'last', 'without', 'indexOf', 'shuffle', 'lastIndexOf', 'isEmpty', 'groupBy'];
+
+ // Mix in each Underscore method as a proxy to `Collection#models`.
+ Bmob._arrayEach(methods,
+ function (method) {
+ Bmob.Collection.prototype[method] = function () {
+ return _[method].apply(_, [this.models].concat(_.toArray(arguments)));
+ };
+ });
+
+ /**
+ * Creates a new subclass of Bmob.Collection
. For example,+ * var MyCollection = Bmob.Collection.extend({ + * // Instance properties + * + * model: MyClass, + * query: MyQuery, + * + * getFirst: function() { + * return this.at(0); + * } + * }, { + * // Class properties + * + * makeOne: function() { + * return new MyCollection(); + * } + * }); + * + * var collection = new MyCollection(); + *+ * + * @function + * @param {Object} instanceProps Instance properties for the collection. + * @param {Object} classProps Class properies for the collection. + * @return {Class} A new subclass of
Bmob.Collection
.
+ */
+ Bmob.Collection.extend = Bmob._extend;
+
+ /**
+ * Creating a Bmob.View creates its initial element outside of the DOM,
+ * if an existing element is not provided...
+ *
+ * A fork of Backbone.View, provided for your convenience. If you use this + * class, you must also include jQuery, or another library that provides a + * jQuery-compatible $ function. For more information, see the + * Backbone + * documentation.
+ *Available in the client SDK only.
+ */ + Bmob.View = function (options) { + this.cid = _.uniqueId('view'); + this._configure(options || {}); + this._ensureElement(); + this.initialize.apply(this, arguments); + this.delegateEvents(); + }; + + // Cached regex to split keys for `delegate`. + var eventSplitter = /^(\S+)\s*(.*)$/; + + // List of view options to be merged as properties. + var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName']; + + // Set up all inheritable **Bmob.View** properties and methods. + _.extend(Bmob.View.prototype, Bmob.Events, + /** @lends Bmob.View.prototype */ + { + + // The default `tagName` of a View's element is `"div"`. + tagName: 'div', + + /** + * jQuery delegate for element lookup, scoped to DOM elements within the + * current view. This should be prefered to global lookups where possible. + */ + $: function (selector) { + return this.$el.find(selector); + }, + + /** + * Initialize is an empty function by default. Override it with your own + * initialization logic. + */ + initialize: function () { }, + + /** + * The core function that your view should override, in order + * to populate its element (`this.el`), with the appropriate HTML. The + * convention is for **render** to always return `this`. + */ + render: function () { + return this; + }, + + /** + * Remove this view from the DOM. Note that the view isn't present in the + * DOM by default, so calling this method may be a no-op. + */ + remove: function () { + this.$el.remove(); + return this; + }, + + /** + * For small amounts of DOM Elements, where a full-blown template isn't + * needed, use **make** to manufacture elements, one at a time. + *+ * var el = this.make('li', {'class': 'row'}, + * this.model.escape('title'));+ */ + make: function (tagName, attributes, content) { + var el = document.createElement(tagName); + if (attributes) { + Bmob.$(el).attr(attributes); + } + if (content) { + Bmob.$(el).html(content); + } + return el; + }, + + /** + * Changes the view's element (`this.el` property), including event + * re-delegation. + */ + setElement: function (element, delegate) { + this.$el = Bmob.$(element); + this.el = this.$el[0]; + if (delegate !== false) { + this.delegateEvents(); + } + return this; + }, + + /** + * Set callbacks.
this.events
is a hash of
+ * + * *{"event selector": "callback"}* + * + * { + * 'mousedown .title': 'edit', + * 'click .button': 'save' + * 'click .open': function(e) { ... } + * } + *+ * pairs. Callbacks will be bound to the view, with `this` set properly. + * Uses event delegation for efficiency. + * Omitting the selector binds the event to `this.el`. + * This only works for delegate-able events: not `focus`, `blur`, and + * not `change`, `submit`, and `reset` in Internet Explorer. + */ + delegateEvents: function (events) { + events = events || Bmob._getValue(this, 'events'); + if (!events) { + return; + } + this.undelegateEvents(); + var self = this; + Bmob._objectEach(events, + function (method, key) { + if (!_.isFunction(method)) { + method = self[events[key]]; + } + if (!method) { + throw new Error('Event "' + events[key] + '" does not exist'); + } + var match = key.match(eventSplitter); + var eventName = match[1], + selector = match[2]; + method = _.bind(method, self); + eventName += '.delegateEvents' + self.cid; + if (selector === '') { + self.$el.bind(eventName, method); + } else { + self.$el.delegate(selector, eventName, method); + } + }); + }, + + /** + * Clears all callbacks previously bound to the view with `delegateEvents`. + * You usually don't need to use this, but may wish to if you have multiple + * Backbone views attached to the same DOM element. + */ + undelegateEvents: function () { + this.$el.unbind('.delegateEvents' + this.cid); + }, + + /** + * Performs the initial configuration of a View with a set of options. + * Keys with special meaning *(model, collection, id, className)*, are + * attached directly to the view. + */ + _configure: function (options) { + if (this.options) { + options = _.extend({}, + this.options, options); + } + var self = this; + _.each(viewOptions, + function (attr) { + if (options[attr]) { + self[attr] = options[attr]; + } + }); + this.options = options; + }, + + /** + * Ensure that the View has a DOM element to render into. + * If `this.el` is a string, pass it through `$()`, take the first + * matching element, and re-assign it to `el`. Otherwise, create + * an element from the `id`, `className` and `tagName` properties. + */ + _ensureElement: function () { + if (!this.el) { + var attrs = Bmob._getValue(this, 'attributes') || {}; + if (this.id) { + attrs.id = this.id; + } + if (this.className) { + attrs['class'] = this.className; + } + this.setElement(this.make(this.tagName, attrs), false); + } else { + this.setElement(this.el, false); + } + } + + }); + + /** + * @function + * @param {Object} instanceProps Instance properties for the view. + * @param {Object} classProps Class properies for the view. + * @return {Class} A new subclass of
Bmob.View
.
+ */
+ Bmob.View.extend = Bmob._extend;
+
+ /**
+ * @class
+ *
+ * 这个类是Bmob.Object的子类,同时拥有Bmob.Object的所有函数,但是扩展了用户的特殊函数,例如验证,登录等
+ */ + Bmob.User = Bmob.Object.extend("_User", + /** @lends Bmob.User.prototype */ + { + // Instance Variables + _isCurrentUser: false, + + // Instance Methods + /** + * Internal method to handle special fields in a _User response. + */ + _mergeMagicFields: function (attrs) { + if (attrs.sessionToken) { + this._sessionToken = attrs.sessionToken; + delete attrs.sessionToken; + } + Bmob.User.__super__._mergeMagicFields.call(this, attrs); + }, + + /** + * Removes null values from authData (which exist temporarily for + * unlinking) + */ + _cleanupAuthData: function () { + if (!this.isCurrent()) { + return; + } + var authData = this.get('authData'); + if (!authData) { + return; + } + Bmob._objectEach(this.get('authData'), + function (value, key) { + if (!authData[key]) { + delete authData[key]; + } + }); + }, + + /** + * Synchronizes authData for all providers. + */ + _synchronizeAllAuthData: function () { + var authData = this.get('authData'); + if (!authData) { + return; + } + + var self = this; + Bmob._objectEach(this.get('authData'), + function (value, key) { + self._synchronizeAuthData(key); + }); + }, + + /** + * Synchronizes auth data for a provider (e.g. puts the access token in the + * right place to be used by the Facebook SDK). + */ + _synchronizeAuthData: function (provider) { + if (!this.isCurrent()) { + return; + } + var authType; + if (_.isString(provider)) { + authType = provider; + provider = Bmob.User._authProviders[authType]; + } else { + authType = provider.getAuthType(); + } + var authData = this.get('authData'); + if (!authData || !provider) { + return; + } + var success = provider.restoreAuthentication(authData[authType]); + if (!success) { + this._unlinkFrom(provider); + } + }, + + _handleSaveResult: function (makeCurrent) { + // Clean up and synchronize the authData object, removing any unset values + if (makeCurrent) { + this._isCurrentUser = true; + } + this._cleanupAuthData(); + this._synchronizeAllAuthData(); + // Don't keep the password around. + delete this._serverData.password; + this._rebuildEstimatedDataForKey("password"); + this._refreshCache(); + if (makeCurrent || this.isCurrent()) { + Bmob.User._saveCurrentUser(this); + } + + }, + + + /** + * 使用第三方登录,登录或注册 + * @Magic 2.0.0 + * @return {Bmob.User} + */ + _linkWith: function _linkWith(provider, data) { + var _this = this; + + var authType; + if (_.isString(provider)) { + authType = provider; + provider = Bmob.User._authProviders[provider]; + } else { + authType = provider.getAuthType(); + } + if (data) { + var authData = this.get('authData') || {}; + authData[authType] = data; + this.set('authData', authData); + + var promise = new Bmob.Promise(); + this.save({ + 'authData': authData + }, newOptions).then( + function (model) { + model._handleSaveResult(true); + promise.resolve(model); + } + ); + + + return promise._thenRunCallbacks({}); + + // Overridden so that the user can be made the current user. + var newOptions = _.clone(data) || {}; + newOptions.success = function (model) { + model._handleSaveResult(true); + if (data.success) { + data.success.apply(this, arguments); + } + }; + + return this.save({ + 'authData': authData + }, + newOptions); + } else { + return provider.authenticate().then(function (result) { + return _this._linkWith(provider, result); + }); + } + }, + + /** + * 使用当前使用小程序的微信用户身份注册或登录,成功后用户的 session 会在设备上持久化保存,之后可以使用 Bmob.User.current() 获取当前登录用户。 + * @Magic 2.0.0 + * @return {Bmob.User} + */ + loginWithWeapp: function (code) { + var that = this; + var promise = new Bmob.Promise(); + Bmob.User.requestOpenId(code, { + success: function (authData) {//获取授权成功 + var platform = "weapp"; + var user = Bmob.Object._create("_User"); + user._linkWith(platform, authData).then(function (resp) { + promise.resolve(resp); + }, function (error) { + promise.reject(error); + }); + + }, + error: function (error) { + promise.reject(error); + } + } + + ); + return promise._thenRunCallbacks({}); + + }, + + + /** + * Unlinks a user from a service. + */ + _unlinkFrom: function (provider, options) { + var authType; + if (_.isString(provider)) { + authType = provider; + provider = Bmob.User._authProviders[provider]; + } else { + authType = provider.getAuthType(); + } + var newOptions = _.clone(options); + var self = this; + newOptions.authData = null; + newOptions.success = function (model) { + self._synchronizeAuthData(provider); + if (options.success) { + options.success.apply(this, arguments); + } + }; + return this._linkWith(provider, newOptions); + }, + + /** + * Checks whether a user is linked to a service. + */ + _isLinked: function (provider) { + var authType; + if (_.isString(provider)) { + authType = provider; + } else { + authType = provider.getAuthType(); + } + var authData = this.get('authData') || {}; + return !!authData[authType]; + }, + + /** + * Deauthenticates all providers. + */ + _logOutWithAll: function () { + var authData = this.get('authData'); + if (!authData) { + return; + } + var self = this; + Bmob._objectEach(this.get('authData'), + function (value, key) { + self._logOutWith(key); + }); + }, + + /** + * Deauthenticates a single provider (e.g. removing access tokens from the + * Facebook SDK). + */ + _logOutWith: function (provider) { + if (!this.isCurrent()) { + return; + } + if (_.isString(provider)) { + provider = Bmob.User._authProviders[provider]; + } + if (provider && provider.deauthenticate) { + provider.deauthenticate(); + } + }, + + /** + * 注册一个新用户。当创建一个新用户时,应该调用这个方法而不是save方法。这个方法会创建 + * 一个新的Bmob.User在服务器上,同时保存session在本地磁盘因此你可以通过current
访问user
+ * 在注册前必须设置username和password
+ *完成后调用options.success 或者 options.error
+ * + * @param {Object} attrs 用户的额外的属性,或者null + * @param {Object} options Backbone-style options 对象。 + * @return {Bmob.Promise} 当调用结束将会返回promise。 + * @see Bmob.User.signUp + */ + signUp: function (attrs, options) { + var error; + options = options || {}; + + var username = (attrs && attrs.username) || this.get("username"); + if (!username || (username === "")) { + error = new Bmob.Error(Bmob.Error.OTHER_CAUSE, "Cannot sign up user with an empty name."); + if (options && options.error) { + options.error(this, error); + } + return Bmob.Promise.error(error); + } + + var password = (attrs && attrs.password) || this.get("password"); + if (!password || (password === "")) { + error = new Bmob.Error(Bmob.Error.OTHER_CAUSE, "Cannot sign up user with an empty password."); + if (options && options.error) { + options.error(this, error); + } + return Bmob.Promise.error(error); + } + + // Overridden so that the user can be made the current user. + var newOptions = _.clone(options); + newOptions.success = function (model) { + model._handleSaveResult(true); + if (options.success) { + options.success.apply(this, arguments); + } + }; + return this.save(attrs, newOptions); + }, + + /** + * 用户登录。当登录成功,将会保存session在本地,可以通过current
获取用户对象。
+ * 在注册前必须设置username和password
+ *完成后调用options.success 或者 options.error
+ * + * @param {Object} options Backbone-style options 对象。 + * @see Bmob.User.logIn + * @return {Bmob.Promise} 当调用结束将会返回promise。 + */ + logIn: function (options) { + var model = this; + var request = Bmob._request("login", null, null, "GET", this.toJSON()); + return request.then(function (resp, status, xhr) { + var serverAttrs = model.parse(resp, status, xhr); + model._finishFetch(serverAttrs); + model._handleSaveResult(true); + return model; + })._thenRunCallbacks(options, this); + }, + + /** + * 保存对象 + * @see Bmob.Object#save + */ + save: function (arg1, arg2, arg3) { + var i, attrs, current, options, saved; + if (_.isObject(arg1) || _.isNull(arg1) || _.isUndefined(arg1)) { + attrs = arg1; + options = arg2; + } else { + attrs = {}; + attrs[arg1] = arg2; + options = arg3; + } + options = options || {}; + + var newOptions = _.clone(options); + newOptions.success = function (model) { + model._handleSaveResult(false); + if (options.success) { + options.success.apply(this, arguments); + } + }; + return Bmob.Object.prototype.save.call(this, attrs, newOptions); + }, + + /** + * 获取一个对象 + * @see Bmob.Object#fetch + */ + fetch: function (options) { + var newOptions = options ? _.clone(options) : {}; + newOptions.success = function (model) { + model._handleSaveResult(false); + if (options && options.success) { + options.success.apply(this, arguments); + } + }; + return Bmob.Object.prototype.fetch.call(this, newOptions); + }, + + /** + * 返回true 如果current
可以返回这个user。
+ * @see Bmob.User#cu 你不能添加一个没保存的Bmob.Object到关系中
+ */
+ isCurrent: function () {
+ return this._isCurrentUser;
+ },
+
+ /**
+ * 返回 get("username").
+ * @return {String}
+ * @see Bmob.Object#get
+ */
+ getUsername: function () {
+ return this.get("username");
+ },
+
+ /**
+ * 调用 set("username", username, options) 同时返回结果
+ * @param {String} username
+ * @param {Object} options Backbone-style options 对象。
+ * @return {Boolean}
+ * @see Bmob.Object.set
+ */
+ setUsername: function (username, options) {
+ return this.set("username", username, options);
+ },
+
+ /**
+ * 调用 set("password", password, options) 同时返回结果
+ * @param {String} password
+ * @param {Object} options Backbone-style options 对象。
+ * @return {Boolean}
+ * @see Bmob.Object.set
+ */
+ setPassword: function (password, options) {
+ return this.set("password", password, options);
+ },
+
+ /**
+ * 返回 get("email").
+ * @return {String}
+ * @see Bmob.Object#get
+ */
+ getEmail: function () {
+ return this.get("email");
+ },
+
+ /**
+ * 调用 set("email", email, options) 同时返回结果
+ * @param {String} email
+ * @param {Object} options Backbone-style options 对象。
+ * @return {Boolean}
+ * @see Bmob.Object.set
+ */
+ setEmail: function (email, options) {
+ return this.set("email", email, options);
+ },
+
+ /**
+ * 检查这个用户是否当前用户并且已经登录。
+ * @return (Boolean) 这个用户是否当前用户并且已经登录。
+ */
+ authenticated: function () {
+ return !!this._sessionToken && (Bmob.User.current() && Bmob.User.current().id === this.id);
+ }
+
+ },
+ /** @lends Bmob.User */
+ {
+ // Class Variables
+ // The currently logged-in user.
+ _currentUser: null,
+
+ // Whether currentUser is known to match the serialized version on disk.
+ // This is useful for saving a localstorage check if you try to load
+ // _currentUser frequently while there is none stored.
+ _currentUserMatchesDisk: false,
+
+ // The localStorage key suffix that the current user is stored under.
+ _CURRENT_USER_KEY: "currentUser",
+
+ // The mapping of auth provider names to actual providers
+ _authProviders: {},
+
+ // Class Methods
+ /**
+ * 注册一个新用户。当创建一个新用户时,应该调用这个方法而不是save方法。这个方法会创建
+ * 一个新的Bmob.User在服务器上,同时保存session在本地磁盘因此你可以通过current
访问user
+ *
+ * 完成后调用options.success 或者 options.error
+ * + * @param {String} username 注册的用户名或email + * @param {String} password 注册的密码 + * @param {Object} attrs 新用户所需要的额外数据 + * @param {Object} options Backbone-style options 对象。 + * @return {Bmob.Promise} 当调用结束将会返回promise。 + * @see Bmob.User#signUp + */ + signUp: function (username, password, attrs, options) { + attrs = attrs || {}; + attrs.username = username; + attrs.password = password; + var user = Bmob.Object._create("_User"); + return user.signUp(attrs, options); + }, + + /** + * 用户登录。当登录成功,将会保存session在本地,可以通过current
获取用户对象。
+ *
+ * 完成后调用options.success 或者 options.error
+ * + * @param {String} username 注册的用户名或email + * @param {String} password 注册的密码 + * @param {Object} options 新用户所需要的额外数据 + * @return {Bmob.Promise} Backbone-style options 对象。 + * @see Bmob.User#logIn + */ + logIn: function (username, password, options) { + var user = Bmob.Object._create("_User"); + user._finishFetch({ + username: username, + password: password + }); + return user.logIn(options); + }, + + /** + * 退出当前登录的用户。磁盘中的session将会被移除,调用current
将会
+ * 返回null
。
+ */
+ logOut: function () {
+ if (Bmob.User._currentUser !== null) {
+ Bmob.User._currentUser._logOutWithAll();
+ Bmob.User._currentUser._isCurrentUser = false;
+ }
+ Bmob.User._currentUserMatchesDisk = true;
+ Bmob.User._currentUser = null;
+
+ wx.removeStorage({
+ key: Bmob._getBmobPath(Bmob.User._CURRENT_USER_KEY),
+ success: function (res) {
+ console.log(res.data)
+ }
+ });
+ },
+
+ /**
+
+ * 把重设密码的邮件发送到用户的注册邮箱。邮件允许用户在bmob网站上重设密码。
+ * 完成后调用options.success 或者 options.error
+ * + * @param {String} email 用户注册的邮箱 + * @param {Object} options Backbone-style options 对象。 + */ + requestPasswordReset: function (email, options) { + var json = { + email: email + }; + var request = Bmob._request("requestPasswordReset", null, null, "POST", json); + return request._thenRunCallbacks(options); + }, + + /** + * 请求验证email + *完成后调用options.success 或者 options.error
+ * + * @param {String} email 需要验证email的email的地址 + * @param {Object} options Backbone-style options 对象。 + */ + requestEmailVerify: function (email, options) { + var json = { + email: email + }; + var request = Bmob._request("requestEmailVerify", null, null, "POST", json); + return request._thenRunCallbacks(options); + }, + + /** + * 请求openid值 + *完成后调用options.success 或者 options.error
+ * + * @param {String} code 微信的code + * @param {Object} options Backbone-style options 对象。 + */ + requestOpenId: function (code, options) { + var json = { + code: code + }; + var request = Bmob._request("wechatApp", code, null, "POST", json); + return request._thenRunCallbacks(options); + }, + + /** + * 返回当前已经登陆的用户。 + * @return {Bmob.Object} 已经登录的Bmob.User. + */ + current: function () { + if (Bmob.User._currentUser) { + return Bmob.User._currentUser; + } + + if (Bmob.User._currentUserMatchesDisk) { + + return Bmob.User._currentUser; + } + + // Load the user from local storage. + Bmob.User._currentUserMatchesDisk = true; + + // var userData = Bmob.localStorage.getItem(Bmob._getBmobPath( + // Bmob.User._CURRENT_USER_KEY)); + var userData = false; + try { + var userData = wx.getStorageSync(Bmob._getBmobPath(Bmob.User._CURRENT_USER_KEY)) + if (userData) { + // Do something with return value + Bmob.User._currentUser = Bmob.Object._create("_User"); + Bmob.User._currentUser._isCurrentUser = true; + + var json = JSON.parse(userData); + Bmob.User._currentUser.id = json._id; + delete json._id; + Bmob.User._currentUser._sessionToken = json._sessionToken; + delete json._sessionToken; + Bmob.User._currentUser.set(json); + + Bmob.User._currentUser._synchronizeAllAuthData(); + Bmob.User._currentUser._refreshCache(); + Bmob.User._currentUser._opSetQueue = [{}]; + return Bmob.User._currentUser; + } + } catch (e) { + // Do something when catch error + return null; + } + }, + + /** + * Persists a user as currentUser to localStorage, and into the singleton. + */ + _saveCurrentUser: function (user) { + if (Bmob.User._currentUser !== user) { + Bmob.User.logOut(); + } + user._isCurrentUser = true; + Bmob.User._currentUser = user; + Bmob.User._currentUserMatchesDisk = true; + + var json = user.toJSON(); + json._id = user.id; + json._sessionToken = user._sessionToken; + wx.setStorage({ + key: Bmob._getBmobPath(Bmob.User._CURRENT_USER_KEY), + data: JSON.stringify(json) + }) + }, + + _registerAuthenticationProvider: function (provider) { + Bmob.User._authProviders[provider.getAuthType()] = provider; + // Synchronize the current user with the auth provider. + if (Bmob.User.current()) { + Bmob.User.current()._synchronizeAuthData(provider.getAuthType()); + } + }, + + _logInWith: function (provider, options) { + var user = Bmob.Object._create("_User"); + return user._linkWith(provider, options); + } + + }); + + /** + * 为Bmob.Object类创建一个新的bmob Bmob.Query 。 + * @param objectClass - + * Bmob.Object的实例,或者Bmob类名 + * + * + *Bmob.Query 为Bmob.Objects定义了query操作。最常用的操作就是用queryfind
+ * 操作去获取所有的对象。例如,下面简单的操作是获取所有的MyClass
。根据操作的成功或失败,
+ * 会回调不同的函数。
+ *
+ * var query = new Bmob.Query(MyClass); + * query.find({ + * success: function(results) { + * // results is an array of Bmob.Object. + * }, + * + * error: function(error) { + * // error is an instance of Bmob.Error. + * } + * });+ * + *
Bmob.Query也可以用来获取一个id已知的对象。例如,下面的例子获取了MyClass
和 id myId
+ * 根据操作的成功或失败,会回调不同的函数。
+ *
+ * var query = new Bmob.Query(MyClass); + * query.get(myId, { + * success: function(object) { + * // object is an instance of Bmob.Object. + * }, + * + * error: function(object, error) { + * // error is an instance of Bmob.Error. + * } + * });+ * + *
Bmob.Query 同时也能获取查询结果的数目。例如,下面的例子获取了MyClass
的数目
+ * var query = new Bmob.Query(MyClass); + * query.count({ + * success: function(number) { + * // There are number instances of MyClass. + * }, + * + * error: function(error) { + * // error is an instance of Bmob.Error. + * } + * });+ + * @class Bmob.Query 为Bmob.Objects定义了query操作 + */ + Bmob.Query = function (objectClass) { + if (_.isString(objectClass)) { + objectClass = Bmob.Object._getSubclass(objectClass); + } + + this.objectClass = objectClass; + + this.className = objectClass.prototype.className; + + this._where = {}; + this._include = []; + this._limit = -1; // negative limit means, do not send a limit + this._skip = 0; + this._extraOptions = {}; + }; + + /** + * 通过传递query构造or的Bmob.Query对象。 For + * example: + *
var compoundQuery = Bmob.Query.or(query1, query2, query3);+ * 通过query1, query2, 和 query3创建一个or查询 + * @param {...Bmob.Query} var_args or的query查询. + * @return {Bmob.Query} 查询结果. + */ + Bmob.Query.or = function () { + var queries = _.toArray(arguments); + var className = null; + Bmob._arrayEach(queries, + function (q) { + if (_.isNull(className)) { + className = q.className; + } + + if (className !== q.className) { + throw "All queries must be for the same class"; + } + }); + var query = new Bmob.Query(className); + query._orQuery(queries); + return query; + }; + + Bmob.Query._extend = Bmob._extend; + + Bmob.Query.prototype = { + //hook to iterate result. Added by dennis
Bmob.history
+ * that will be created for you automatically if you make use of
+ * Routers with routes.
+ *
+ * A fork of Backbone.History, provided for your convenience. If you + * use this class, you must also include jQuery, or another library + * that provides a jQuery-compatible $ function. For more information, + * see the + * Backbone documentation.
+ *Available in the client SDK only.
+ */ + Bmob.History = function () { + this.handlers = []; + _.bindAll(this, 'checkUrl'); + }; + + // Cached regex for cleaning leading hashes and slashes . + var routeStripper = /^[#\/]/; + + // Cached regex for detecting MSIE. + var isExplorer = /msie [\w.]+/; + + // Has the history handling already been started? + Bmob.History.started = false; + + // Set up all inheritable **Bmob.History** properties and methods. + _.extend(Bmob.History.prototype, Bmob.Events, + /** @lends Bmob.History.prototype */ + { + + // The default interval to poll for hash changes, if necessary, is + // twenty times a second. + interval: 50, + + // Gets the true hash value. Cannot use location.hash directly due to bug + // in Firefox where location.hash will always be decoded. + getHash: function (windowOverride) { + var loc = windowOverride ? windowOverride.location : window.location; + var match = loc.href.match(/#(.*)$/); + return match ? match[1] : ''; + }, + + // Get the cross-browser normalized URL fragment, either from the URL, + // the hash, or the override. + getFragment: function (fragment, forcePushState) { + if (Bmob._isNullOrUndefined(fragment)) { + if (this._hasPushState || forcePushState) { + fragment = window.location.pathname; + var search = window.location.search; + if (search) { + fragment += search; + } + } else { + fragment = this.getHash(); + } + } + if (!fragment.indexOf(this.options.root)) { + fragment = fragment.substr(this.options.root.length); + } + return fragment.replace(routeStripper, ''); + }, + + /** + * Start the hash change handling, returning `true` if the current + * URL matches an existing route, and `false` otherwise. + */ + start: function (options) { + if (Bmob.History.started) { + throw new Error("Bmob.history has already been started"); + } + Bmob.History.started = true; + + // Figure out the initial configuration. Do we need an iframe? + // Is pushState desired ... is it available? + this.options = _.extend({}, + { + root: '/' + }, + this.options, options); + this._wantsHashChange = this.options.hashChange !== false; + this._wantsPushState = !!this.options.pushState; + this._hasPushState = !!(this.options.pushState && window.history && window.history.pushState); + var fragment = this.getFragment(); + var docMode = document.documentMode; + var oldIE = (isExplorer.exec(navigator.userAgent.toLowerCase()) && (!docMode || docMode <= 7)); + + if (oldIE) { + this.iframe = Bmob.$('').hide().appendTo('body')[0].contentWindow; + this.navigate(fragment); + } + + // Depending on whether we're using pushState or hashes, and whether + // 'onhashchange' is supported, determine how we check the URL state. + if (this._hasPushState) { + Bmob.$(window).bind('popstate', this.checkUrl); + } else if (this._wantsHashChange && ('onhashchange' in window) && !oldIE) { + Bmob.$(window).bind('hashchange', this.checkUrl); + } else if (this._wantsHashChange) { + this._checkUrlInterval = window.setInterval(this.checkUrl, this.interval); + } + + // Determine if we need to change the base url, for a pushState link + // opened by a non-pushState browser. + this.fragment = fragment; + var loc = window.location; + var atRoot = loc.pathname === this.options.root; + + // If we've started off with a route from a `pushState`-enabled browser, + // but we're currently in a browser that doesn't support it... + if (this._wantsHashChange && this._wantsPushState && !this._hasPushState && !atRoot) { + this.fragment = this.getFragment(null, true); + window.location.replace(this.options.root + '#' + this.fragment); + // Return immediately as browser will do redirect to new url + return true; + + // Or if we've started out with a hash-based route, but we're currently + // in a browser where it could be `pushState`-based instead... + } else if (this._wantsPushState && this._hasPushState && atRoot && loc.hash) { + this.fragment = this.getHash().replace(routeStripper, ''); + window.history.replaceState({}, + document.title, loc.protocol + '//' + loc.host + this.options.root + this.fragment); + } + + if (!this.options.silent) { + return this.loadUrl(); + } + }, + + // Disable Bmob.history, perhaps temporarily. Not useful in a real app, + // but possibly useful for unit testing Routers. + stop: function () { + Bmob.$(window).unbind('popstate', this.checkUrl).unbind('hashchange', this.checkUrl); + window.clearInterval(this._checkUrlInterval); + Bmob.History.started = false; + }, + + // Add a route to be tested when the fragment changes. Routes added later + // may override previous routes. + route: function (route, callback) { + this.handlers.unshift({ + route: route, + callback: callback + }); + }, + + // Checks the current URL to see if it has changed, and if it has, + // calls `loadUrl`, normalizing across the hidden iframe. + checkUrl: function (e) { + var current = this.getFragment(); + if (current === this.fragment && this.iframe) { + current = this.getFragment(this.getHash(this.iframe)); + } + if (current === this.fragment) { + return false; + } + if (this.iframe) { + this.navigate(current); + } + if (!this.loadUrl()) { + this.loadUrl(this.getHash()); + } + }, + + // Attempt to load the current URL fragment. If a route succeeds with a + // match, returns `true`. If no defined routes matches the fragment, + // returns `false`. + loadUrl: function (fragmentOverride) { + var fragment = this.fragment = this.getFragment(fragmentOverride); + var matched = _.any(this.handlers, + function (handler) { + if (handler.route.test(fragment)) { + handler.callback(fragment); + return true; + } + }); + return matched; + }, + + // Save a fragment into the hash history, or replace the URL state if the + // 'replace' option is passed. You are responsible for properly URL-encoding + // the fragment in advance. + // + // The options object can contain `trigger: true` if you wish to have the + // route callback be fired (not usually desirable), or `replace: true`, if + // you wish to modify the current URL without adding an entry to the + // history. + navigate: function (fragment, options) { + if (!Bmob.History.started) { + return false; + } + if (!options || options === true) { + options = { + trigger: options + }; + } + var frag = (fragment || '').replace(routeStripper, ''); + if (this.fragment === frag) { + return; + } + + // If pushState is available, we use it to set the fragment as a real URL. + if (this._hasPushState) { + if (frag.indexOf(this.options.root) !== 0) { + frag = this.options.root + frag; + } + this.fragment = frag; + var replaceOrPush = options.replace ? 'replaceState' : 'pushState'; + window.history[replaceOrPush]({}, + document.title, frag); + + // If hash changes haven't been explicitly disabled, update the hash + // fragment to store history. + } else if (this._wantsHashChange) { + this.fragment = frag; + this._updateHash(window.location, frag, options.replace); + if (this.iframe && (frag !== this.getFragment(this.getHash(this.iframe)))) { + // Opening and closing the iframe tricks IE7 and earlier + // to push a history entry on hash-tag change. + // When replace is true, we don't want this. + if (!options.replace) { + this.iframe.document.open().close(); + } + this._updateHash(this.iframe.location, frag, options.replace); + } + + // If you've told us that you explicitly don't want fallback hashchange- + // based history, then `navigate` becomes a page refresh. + } else { + window.location.assign(this.options.root + fragment); + } + if (options.trigger) { + this.loadUrl(fragment); + } + }, + + // Update the hash location, either replacing the current entry, or adding + // a new one to the browser history. + _updateHash: function (location, fragment, replace) { + if (replace) { + var s = location.toString().replace(/(javascript:|#).*$/, ''); + location.replace(s + '#' + fragment); + } else { + location.hash = fragment; + } + } + }); + + /** + * Routers map faux-URLs to actions, and fire events when routes are + * matched. Creating a new one sets its `routes` hash, if not set statically. + * + *A fork of Backbone.Router, provided for your convenience. + * For more information, see the + * Backbone + * documentation.
+ *Available in the client SDK only.
+ */ + Bmob.Router = function (options) { + options = options || {}; + if (options.routes) { + this.routes = options.routes; + } + this._bindRoutes(); + this.initialize.apply(this, arguments); + }; + + // Cached regular expressions for matching named param parts and splatted + // parts of route strings. + var namedParam = /:\w+/g; + var splatParam = /\*\w+/g; + var escapeRegExp = /[\-\[\]{}()+?.,\\\^\$\|#\s]/g; + + // Set up all inheritable **Bmob.Router** properties and methods. + _.extend(Bmob.Router.prototype, Bmob.Events, + /** @lends Bmob.Router.prototype */ + { + + /** + * Initialize is an empty function by default. Override it with your own + * initialization logic. + */ + initialize: function () { }, + + /** + * Manually bind a single named route to a callback. For example: + * + *this.route('search/:query/p:num', 'search', function(query, num) { + * ... + * });+ */ + route: function (route, name, callback) { + Bmob.history = Bmob.history || new Bmob.History(); + if (!_.isRegExp(route)) { + route = this._routeToRegExp(route); + } + if (!callback) { + callback = this[name]; + } + Bmob.history.route(route, _.bind(function (fragment) { + var args = this._extractParameters(route, fragment); + if (callback) { + callback.apply(this, args); + } + this.trigger.apply(this, ['route:' + name].concat(args)); + Bmob.history.trigger('route', this, name, args); + }, + this)); + return this; + }, + + /** + * Whenever you reach a point in your application that you'd + * like to save as a URL, call navigate in order to update the + * URL. If you wish to also call the route function, set the + * trigger option to true. To update the URL without creating + * an entry in the browser's history, set the replace option + * to true. + */ + navigate: function (fragment, options) { + Bmob.history.navigate(fragment, options); + }, + + // Bind all defined routes to `Bmob.history`. We have to reverse the + // order of the routes here to support behavior where the most general + // routes can be defined at the bottom of the route map. + _bindRoutes: function () { + if (!this.routes) { + return; + } + var routes = []; + for (var route in this.routes) { + if (this.routes.hasOwnProperty(route)) { + routes.unshift([route, this.routes[route]]); + } + } + for (var i = 0, + l = routes.length; i < l; i++) { + this.route(routes[i][0], routes[i][1], this[routes[i][1]]); + } + }, + + // Convert a route string into a regular expression, suitable for matching + // against the current location hash. + _routeToRegExp: function (route) { + route = route.replace(escapeRegExp, '\\$&').replace(namedParam, '([^\/]+)').replace(splatParam, '(.*?)'); + return new RegExp('^' + route + '$'); + }, + + // Given a route, and a URL fragment that it matches, return the array of + // extracted parameters. + _extractParameters: function (route, fragment) { + return route.exec(fragment).slice(1); + } + }); + + /** + * @function + * @param {Object} instanceProps Instance properties for the router. + * @param {Object} classProps Class properies for the router. + * @return {Class} A new subclass of
Bmob.Router
.
+ */
+ Bmob.Router.extend = Bmob._extend;
+
+
+
+ /**
+* @namespace 生成二维码
+*/
+ Bmob.generateCode = Bmob.generateCode || {};
+ Bmob.generateCode = function (data, options) {
+ var request = Bmob._request("wechatApp/qr/generatecode", null, null, 'POST', Bmob._encode(data, null, true));
+ return request.then(function (resp) {
+ return Bmob._decode(null, resp);
+ })._thenRunCallbacks(options);
+
+ }
+
+
+ /**
+ * @namespace 发送模板消息
+ */
+ Bmob.sendMessage = Bmob.sendMessage || {};
+ Bmob.sendMessage = function (data, options) {
+
+ var request = Bmob._request("wechatApp/SendWeAppMessage", null, null, 'POST', Bmob._encode(data, null, true));
+
+ return request.then(function (resp) {
+ return Bmob._decode(null, resp);
+ })._thenRunCallbacks(options);
+
+ }
+
+
+ /**
+ * @namespace 处理短信的函数
+ */
+ Bmob.Sms = Bmob.Sms || {};
+
+ _.extend(Bmob.Sms,
+ /** @lends Bmob.Sms */
+ {
+
+ /**
+ * 请求发送短信内容
+ * @param {Object} 相应的参数
+ * @param {Object} Backbone-style options 对象。 options.success, 如果设置了,将会处理云端代码调用成功的情况。 options.error 如果设置了,将会处理云端代码调用失败的情况。 两个函数都是可选的。两个函数都只有一个参数。
+ * @return {Bmob.Promise}
+ */
+ requestSms: function (data, options) {
+ var request = Bmob._request("requestSms", null, null, 'POST', Bmob._encode(data, null, true));
+ return request.then(function (resp) {
+ return Bmob._decode(null, resp);
+ })._thenRunCallbacks(options);
+
+ },
+
+ /**
+ * 请求短信验证码
+ * @param {Object} 相应的参数
+ * @param {Object} Backbone-style options 对象。 options.success, 如果设置了,将会处理云端代码调用成功的情况。 options.error 如果设置了,将会处理云端代码调用失败的情况。 两个函数都是可选的。两个函数都只有一个参数。
+ * @return {Bmob.Promise}
+ */
+ requestSmsCode: function (data, options) {
+ var request = Bmob._request("requestSmsCode", null, null, 'POST', Bmob._encode(data, null, true));
+ return request.then(function (resp) {
+ return Bmob._decode(null, resp);
+ })._thenRunCallbacks(options);
+
+ },
+
+ /**
+ * 验证短信验证码
+ * @param {Object} 相应的参数
+ * @param {Object} Backbone-style options 对象。 options.success, 如果设置了,将会处理云端代码调用成功的情况。 options.error 如果设置了,将会处理云端代码调用失败的情况。 两个函数都是可选的。两个函数都只有一个参数。
+ * @return {Bmob.Promise}
+ */
+ verifySmsCode: function (mob, verifyCode, options) {
+ var data = {
+ "mobilePhoneNumber": mob
+ };
+ var request = Bmob._request("verifySmsCode/" + verifyCode, null, null, 'POST', Bmob._encode(data, null, true));
+ return request.then(function (resp) {
+ return Bmob._decode(null, resp);
+ })._thenRunCallbacks(options);
+ },
+
+ /**
+ * 查询短信状态
+ * @param {Object} 相应的参数
+ * @param {Object} Backbone-style options 对象。 options.success, 如果设置了,将会处理云端代码调用成功的情况。 options.error 如果设置了,将会处理云端代码调用失败的情况。 两个函数都是可选的。两个函数都只有一个参数。
+ * @return {Bmob.Promise}
+ */
+ querySms: function (smsId, options) {
+ var request = Bmob._request("querySms/" + smsId, null, null, 'GET', null);
+ return request.then(function (resp) {
+ return Bmob._decode(null, resp);
+ })._thenRunCallbacks(options);
+ }
+ });
+
+
+ /**
+ * @namespace 支付功能
+ * cloud functions.
+ */
+ Bmob.Pay = Bmob.Pay || {};
+
+ _.extend(Bmob.Pay, /** @lends Bmob.Cloud */
+ {
+
+ /**
+ * 网页端调起小程序支付接口
+ * @param {float} 价格
+ * @param {String} 商品名称
+ * @param {String} 描述
+ * @param {String} OPEN ID
+ * @param {Object} options -style options 对象。
+ * options.success, 如果设置了,将会处理云端代码调用成功的情况。 options.error 如果设置了,将会处理云端代码调用失败的情况。 两个函数都是可选的。两个函数都只有一个参数。
+ * @return {Bmob.Promise} A promise 将会处理云端代码调用的情况。
+ */
+ wechatPay: function (price, product_name, body, openid, options) {
+ var data = { "order_price": price, "product_name": product_name, "body": body, "open_id": openid, "pay_type": 4 }
+ var request = Bmob._request("pay", null, null, 'POST',
+ Bmob._encode(data, null, true));
+
+ return request.then(function (resp) {
+ return Bmob._decode(null, resp);
+ })._thenRunCallbacks(options);
+ },
+
+ /**
+ * 查询订单
+ * @param {String} 订单id
+ * @param {Object} options Backbone-style options 对象。
+ * options.success, 如果设置了,将会处理云端代码调用成功的情况。 options.error 如果设置了,将会处理云端代码调用失败的情况。 两个函数都是可选的。两个函数都只有一个参数。
+ * @return {Bmob.Promise} A promise 将会处理云端代码调用的情况。
+ */
+ queryOrder: function (orderId, options) {
+
+ var request = Bmob._request("pay/" + orderId, null, null, 'GET',
+ null);
+ return request.then(function (resp) {
+ return Bmob._decode(null, resp);
+ })._thenRunCallbacks(options);
+ }
+ });
+
+
+
+ /**
+ * @namespace 运行云端代码
+ * cloud functions.
+ */
+ Bmob.Cloud = Bmob.Cloud || {};
+
+ _.extend(Bmob.Cloud,
+ /** @lends Bmob.Cloud */
+ {
+ /**
+ * 运行云端代码
+ * @param {String} 云端代码的函数名
+ * @param {Object} 传人云端代码的参数
+ * @param {Object} options Backbone-style options 对象。
+ * options.success, 如果设置了,将会处理云端代码调用成功的情况。 options.error 如果设置了,将会处理云端代码调用失败的情况。 两个函数都是可选的。两个函数都只有一个参数。
+ * @return {Bmob.Promise} A promise 将会处理云端代码调用的情况。
+ */
+ run: function (name, data, options) {
+ var request = Bmob._request("functions", name, null, 'POST', Bmob._encode(data, null, true));
+
+ return request.then(function (resp) {
+ return Bmob._decode(null, resp).result;
+ })._thenRunCallbacks(options);
+ }
+ });
+
+ Bmob.Installation = Bmob.Object.extend("_Installation");
+
+ /**
+ * 包含push的函数
+ * @name Bmob.Push
+ * @namespace 推送消息
+ */
+ Bmob.Push = Bmob.Push || {};
+
+ /**
+ * 推送消息
+ * @param {Object} data - 具体的参数请查看推送文档.
+ * @param {Object} options options 对象。 options.success, 如果设置了,将会处理云端代码调用成功的情况。 options.error 如果设置了,将会处理云端代码调用失败的情况。 两个函数都是可选的。两个函数都只有一个参数。
+ */
+ Bmob.Push.send = function (data, options) {
+ if (data.where) {
+ data.where = data.where.toJSON().where;
+ }
+
+ if (data.push_time) {
+ data.push_time = data.push_time.toJSON();
+ }
+
+ if (data.expiration_time) {
+ data.expiration_time = data.expiration_time.toJSON();
+ }
+
+ if (data.expiration_time && data.expiration_time_interval) {
+ throw "Both expiration_time and expiration_time_interval can't be set";
+ }
+
+ var request = Bmob._request('push', null, null, 'POST', data);
+ return request._thenRunCallbacks(options);
+ };
+}.call(this));
\ No newline at end of file
diff --git a/campus/utils/citys.js b/campus/utils/citys.js
new file mode 100644
index 0000000..109a111
--- /dev/null
+++ b/campus/utils/citys.js
@@ -0,0 +1,16495 @@
+var cityData = [
+ {
+ "name":"北京",
+ "code":"110000",
+ "sub": [
+ {
+ "name": "北京市",
+ "code": "110000",
+ "sub":[
+ {
+ "name":"东城区",
+ "code":"110101"
+ },
+ {
+ "name":"西城区",
+ "code":"110102"
+ },
+ {
+ "name":"朝阳区",
+ "code":"110105"
+ },
+ {
+ "name":"丰台区",
+ "code":"110106"
+ },
+ {
+ "name":"石景山区",
+ "code":"110107"
+ },
+ {
+ "name":"海淀区",
+ "code":"110108"
+ },
+ {
+ "name":"门头沟区",
+ "code":"110109"
+ },
+ {
+ "name":"房山区",
+ "code":"110111"
+ },
+ {
+ "name":"通州区",
+ "code":"110112"
+ },
+ {
+ "name":"顺义区",
+ "code":"110113"
+ },
+ {
+ "name":"昌平区",
+ "code":"110114"
+ },
+ {
+ "name":"大兴区",
+ "code":"110115"
+ },
+ {
+ "name":"怀柔区",
+ "code":"110116"
+ },
+ {
+ "name":"平谷区",
+ "code":"110117"
+ },
+ {
+ "name":"密云县",
+ "code":"110228"
+ },
+ {
+ "name":"延庆县",
+ "code":"110229"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name":"天津",
+ "code":"120000",
+ "sub": [
+ {
+ "name": "天津市",
+ "code": "120000",
+ "sub":[
+ {
+ "name":"和平区",
+ "code":"120101"
+ },
+ {
+ "name":"河东区",
+ "code":"120102"
+ },
+ {
+ "name":"河西区",
+ "code":"120103"
+ },
+ {
+ "name":"南开区",
+ "code":"120104"
+ },
+ {
+ "name":"河北区",
+ "code":"120105"
+ },
+ {
+ "name":"红桥区",
+ "code":"120106"
+ },
+ {
+ "name":"东丽区",
+ "code":"120110"
+ },
+ {
+ "name":"西青区",
+ "code":"120111"
+ },
+ {
+ "name":"津南区",
+ "code":"120112"
+ },
+ {
+ "name":"北辰区",
+ "code":"120113"
+ },
+ {
+ "name":"武清区",
+ "code":"120114"
+ },
+ {
+ "name":"宝坻区",
+ "code":"120115"
+ },
+ {
+ "name":"滨海新区",
+ "code":"120116"
+ },
+ {
+ "name":"宁河县",
+ "code":"120221"
+ },
+ {
+ "name":"静海县",
+ "code":"120223"
+ },
+ {
+ "name":"蓟县",
+ "code":"120225"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name":"河北省",
+ "code":"130000",
+ "sub":[
+ {
+ "name":"石家庄市",
+ "code":"130100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"130101"
+ },
+ {
+ "name":"长安区",
+ "code":"130102"
+ },
+ {
+ "name":"桥西区",
+ "code":"130104"
+ },
+ {
+ "name":"新华区",
+ "code":"130105"
+ },
+ {
+ "name":"井陉矿区",
+ "code":"130107"
+ },
+ {
+ "name":"裕华区",
+ "code":"130108"
+ },
+ {
+ "name":"藁城区",
+ "code":"130109"
+ },
+ {
+ "name":"鹿泉区",
+ "code":"130110"
+ },
+ {
+ "name":"栾城区",
+ "code":"130111"
+ },
+ {
+ "name":"井陉县",
+ "code":"130121"
+ },
+ {
+ "name":"正定县",
+ "code":"130123"
+ },
+ {
+ "name":"行唐县",
+ "code":"130125"
+ },
+ {
+ "name":"灵寿县",
+ "code":"130126"
+ },
+ {
+ "name":"高邑县",
+ "code":"130127"
+ },
+ {
+ "name":"深泽县",
+ "code":"130128"
+ },
+ {
+ "name":"赞皇县",
+ "code":"130129"
+ },
+ {
+ "name":"无极县",
+ "code":"130130"
+ },
+ {
+ "name":"平山县",
+ "code":"130131"
+ },
+ {
+ "name":"元氏县",
+ "code":"130132"
+ },
+ {
+ "name":"赵县",
+ "code":"130133"
+ },
+ {
+ "name":"辛集市",
+ "code":"130181"
+ },
+ {
+ "name":"晋州市",
+ "code":"130183"
+ },
+ {
+ "name":"新乐市",
+ "code":"130184"
+ }
+ ]
+ },
+ {
+ "name":"唐山市",
+ "code":"130200",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"130201"
+ },
+ {
+ "name":"路南区",
+ "code":"130202"
+ },
+ {
+ "name":"路北区",
+ "code":"130203"
+ },
+ {
+ "name":"古冶区",
+ "code":"130204"
+ },
+ {
+ "name":"开平区",
+ "code":"130205"
+ },
+ {
+ "name":"丰南区",
+ "code":"130207"
+ },
+ {
+ "name":"丰润区",
+ "code":"130208"
+ },
+ {
+ "name":"曹妃甸区",
+ "code":"130209"
+ },
+ {
+ "name":"滦县",
+ "code":"130223"
+ },
+ {
+ "name":"滦南县",
+ "code":"130224"
+ },
+ {
+ "name":"乐亭县",
+ "code":"130225"
+ },
+ {
+ "name":"迁西县",
+ "code":"130227"
+ },
+ {
+ "name":"玉田县",
+ "code":"130229"
+ },
+ {
+ "name":"遵化市",
+ "code":"130281"
+ },
+ {
+ "name":"迁安市",
+ "code":"130283"
+ }
+ ]
+ },
+ {
+ "name":"秦皇岛市",
+ "code":"130300",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"130301"
+ },
+ {
+ "name":"海港区",
+ "code":"130302"
+ },
+ {
+ "name":"山海关区",
+ "code":"130303"
+ },
+ {
+ "name":"北戴河区",
+ "code":"130304"
+ },
+ {
+ "name":"青龙满族自治县",
+ "code":"130321"
+ },
+ {
+ "name":"昌黎县",
+ "code":"130322"
+ },
+ {
+ "name":"抚宁县",
+ "code":"130323"
+ },
+ {
+ "name":"卢龙县",
+ "code":"130324"
+ }
+ ]
+ },
+ {
+ "name":"邯郸市",
+ "code":"130400",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"130401"
+ },
+ {
+ "name":"邯山区",
+ "code":"130402"
+ },
+ {
+ "name":"丛台区",
+ "code":"130403"
+ },
+ {
+ "name":"复兴区",
+ "code":"130404"
+ },
+ {
+ "name":"峰峰矿区",
+ "code":"130406"
+ },
+ {
+ "name":"邯郸县",
+ "code":"130421"
+ },
+ {
+ "name":"临漳县",
+ "code":"130423"
+ },
+ {
+ "name":"成安县",
+ "code":"130424"
+ },
+ {
+ "name":"大名县",
+ "code":"130425"
+ },
+ {
+ "name":"涉县",
+ "code":"130426"
+ },
+ {
+ "name":"磁县",
+ "code":"130427"
+ },
+ {
+ "name":"肥乡县",
+ "code":"130428"
+ },
+ {
+ "name":"永年县",
+ "code":"130429"
+ },
+ {
+ "name":"邱县",
+ "code":"130430"
+ },
+ {
+ "name":"鸡泽县",
+ "code":"130431"
+ },
+ {
+ "name":"广平县",
+ "code":"130432"
+ },
+ {
+ "name":"馆陶县",
+ "code":"130433"
+ },
+ {
+ "name":"魏县",
+ "code":"130434"
+ },
+ {
+ "name":"曲周县",
+ "code":"130435"
+ },
+ {
+ "name":"武安市",
+ "code":"130481"
+ }
+ ]
+ },
+ {
+ "name":"邢台市",
+ "code":"130500",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"130501"
+ },
+ {
+ "name":"桥东区",
+ "code":"130502"
+ },
+ {
+ "name":"桥西区",
+ "code":"130503"
+ },
+ {
+ "name":"邢台县",
+ "code":"130521"
+ },
+ {
+ "name":"临城县",
+ "code":"130522"
+ },
+ {
+ "name":"内丘县",
+ "code":"130523"
+ },
+ {
+ "name":"柏乡县",
+ "code":"130524"
+ },
+ {
+ "name":"隆尧县",
+ "code":"130525"
+ },
+ {
+ "name":"任县",
+ "code":"130526"
+ },
+ {
+ "name":"南和县",
+ "code":"130527"
+ },
+ {
+ "name":"宁晋县",
+ "code":"130528"
+ },
+ {
+ "name":"巨鹿县",
+ "code":"130529"
+ },
+ {
+ "name":"新河县",
+ "code":"130530"
+ },
+ {
+ "name":"广宗县",
+ "code":"130531"
+ },
+ {
+ "name":"平乡县",
+ "code":"130532"
+ },
+ {
+ "name":"威县",
+ "code":"130533"
+ },
+ {
+ "name":"清河县",
+ "code":"130534"
+ },
+ {
+ "name":"临西县",
+ "code":"130535"
+ },
+ {
+ "name":"南宫市",
+ "code":"130581"
+ },
+ {
+ "name":"沙河市",
+ "code":"130582"
+ }
+ ]
+ },
+ {
+ "name":"保定市",
+ "code":"130600",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"130601"
+ },
+ {
+ "name":"新市区",
+ "code":"130602"
+ },
+ {
+ "name":"北市区",
+ "code":"130603"
+ },
+ {
+ "name":"南市区",
+ "code":"130604"
+ },
+ {
+ "name":"满城县",
+ "code":"130621"
+ },
+ {
+ "name":"清苑县",
+ "code":"130622"
+ },
+ {
+ "name":"涞水县",
+ "code":"130623"
+ },
+ {
+ "name":"阜平县",
+ "code":"130624"
+ },
+ {
+ "name":"徐水县",
+ "code":"130625"
+ },
+ {
+ "name":"定兴县",
+ "code":"130626"
+ },
+ {
+ "name":"唐县",
+ "code":"130627"
+ },
+ {
+ "name":"高阳县",
+ "code":"130628"
+ },
+ {
+ "name":"容城县",
+ "code":"130629"
+ },
+ {
+ "name":"涞源县",
+ "code":"130630"
+ },
+ {
+ "name":"望都县",
+ "code":"130631"
+ },
+ {
+ "name":"安新县",
+ "code":"130632"
+ },
+ {
+ "name":"易县",
+ "code":"130633"
+ },
+ {
+ "name":"曲阳县",
+ "code":"130634"
+ },
+ {
+ "name":"蠡县",
+ "code":"130635"
+ },
+ {
+ "name":"顺平县",
+ "code":"130636"
+ },
+ {
+ "name":"博野县",
+ "code":"130637"
+ },
+ {
+ "name":"雄县",
+ "code":"130638"
+ },
+ {
+ "name":"涿州市",
+ "code":"130681"
+ },
+ {
+ "name":"定州市",
+ "code":"130682"
+ },
+ {
+ "name":"安国市",
+ "code":"130683"
+ },
+ {
+ "name":"高碑店市",
+ "code":"130684"
+ }
+ ]
+ },
+ {
+ "name":"张家口市",
+ "code":"130700",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"130701"
+ },
+ {
+ "name":"桥东区",
+ "code":"130702"
+ },
+ {
+ "name":"桥西区",
+ "code":"130703"
+ },
+ {
+ "name":"宣化区",
+ "code":"130705"
+ },
+ {
+ "name":"下花园区",
+ "code":"130706"
+ },
+ {
+ "name":"宣化县",
+ "code":"130721"
+ },
+ {
+ "name":"张北县",
+ "code":"130722"
+ },
+ {
+ "name":"康保县",
+ "code":"130723"
+ },
+ {
+ "name":"沽源县",
+ "code":"130724"
+ },
+ {
+ "name":"尚义县",
+ "code":"130725"
+ },
+ {
+ "name":"蔚县",
+ "code":"130726"
+ },
+ {
+ "name":"阳原县",
+ "code":"130727"
+ },
+ {
+ "name":"怀安县",
+ "code":"130728"
+ },
+ {
+ "name":"万全县",
+ "code":"130729"
+ },
+ {
+ "name":"怀来县",
+ "code":"130730"
+ },
+ {
+ "name":"涿鹿县",
+ "code":"130731"
+ },
+ {
+ "name":"赤城县",
+ "code":"130732"
+ },
+ {
+ "name":"崇礼县",
+ "code":"130733"
+ }
+ ]
+ },
+ {
+ "name":"承德市",
+ "code":"130800",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"130801"
+ },
+ {
+ "name":"双桥区",
+ "code":"130802"
+ },
+ {
+ "name":"双滦区",
+ "code":"130803"
+ },
+ {
+ "name":"鹰手营子矿区",
+ "code":"130804"
+ },
+ {
+ "name":"承德县",
+ "code":"130821"
+ },
+ {
+ "name":"兴隆县",
+ "code":"130822"
+ },
+ {
+ "name":"平泉县",
+ "code":"130823"
+ },
+ {
+ "name":"滦平县",
+ "code":"130824"
+ },
+ {
+ "name":"隆化县",
+ "code":"130825"
+ },
+ {
+ "name":"丰宁满族自治县",
+ "code":"130826"
+ },
+ {
+ "name":"宽城满族自治县",
+ "code":"130827"
+ },
+ {
+ "name":"围场满族蒙古族自治县",
+ "code":"130828"
+ }
+ ]
+ },
+ {
+ "name":"沧州市",
+ "code":"130900",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"130901"
+ },
+ {
+ "name":"新华区",
+ "code":"130902"
+ },
+ {
+ "name":"运河区",
+ "code":"130903"
+ },
+ {
+ "name":"沧县",
+ "code":"130921"
+ },
+ {
+ "name":"青县",
+ "code":"130922"
+ },
+ {
+ "name":"东光县",
+ "code":"130923"
+ },
+ {
+ "name":"海兴县",
+ "code":"130924"
+ },
+ {
+ "name":"盐山县",
+ "code":"130925"
+ },
+ {
+ "name":"肃宁县",
+ "code":"130926"
+ },
+ {
+ "name":"南皮县",
+ "code":"130927"
+ },
+ {
+ "name":"吴桥县",
+ "code":"130928"
+ },
+ {
+ "name":"献县",
+ "code":"130929"
+ },
+ {
+ "name":"孟村回族自治县",
+ "code":"130930"
+ },
+ {
+ "name":"泊头市",
+ "code":"130981"
+ },
+ {
+ "name":"任丘市",
+ "code":"130982"
+ },
+ {
+ "name":"黄骅市",
+ "code":"130983"
+ },
+ {
+ "name":"河间市",
+ "code":"130984"
+ }
+ ]
+ },
+ {
+ "name":"廊坊市",
+ "code":"131000",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"131001"
+ },
+ {
+ "name":"安次区",
+ "code":"131002"
+ },
+ {
+ "name":"广阳区",
+ "code":"131003"
+ },
+ {
+ "name":"固安县",
+ "code":"131022"
+ },
+ {
+ "name":"永清县",
+ "code":"131023"
+ },
+ {
+ "name":"香河县",
+ "code":"131024"
+ },
+ {
+ "name":"大城县",
+ "code":"131025"
+ },
+ {
+ "name":"文安县",
+ "code":"131026"
+ },
+ {
+ "name":"大厂回族自治县",
+ "code":"131028"
+ },
+ {
+ "name":"霸州市",
+ "code":"131081"
+ },
+ {
+ "name":"三河市",
+ "code":"131082"
+ }
+ ]
+ },
+ {
+ "name":"衡水市",
+ "code":"131100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"131101"
+ },
+ {
+ "name":"桃城区",
+ "code":"131102"
+ },
+ {
+ "name":"枣强县",
+ "code":"131121"
+ },
+ {
+ "name":"武邑县",
+ "code":"131122"
+ },
+ {
+ "name":"武强县",
+ "code":"131123"
+ },
+ {
+ "name":"饶阳县",
+ "code":"131124"
+ },
+ {
+ "name":"安平县",
+ "code":"131125"
+ },
+ {
+ "name":"故城县",
+ "code":"131126"
+ },
+ {
+ "name":"景县",
+ "code":"131127"
+ },
+ {
+ "name":"阜城县",
+ "code":"131128"
+ },
+ {
+ "name":"冀州市",
+ "code":"131181"
+ },
+ {
+ "name":"深州市",
+ "code":"131182"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name":"山西省",
+ "code":"140000",
+ "sub":[
+ {
+ "name":"太原市",
+ "code":"140100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"140101"
+ },
+ {
+ "name":"小店区",
+ "code":"140105"
+ },
+ {
+ "name":"迎泽区",
+ "code":"140106"
+ },
+ {
+ "name":"杏花岭区",
+ "code":"140107"
+ },
+ {
+ "name":"尖草坪区",
+ "code":"140108"
+ },
+ {
+ "name":"万柏林区",
+ "code":"140109"
+ },
+ {
+ "name":"晋源区",
+ "code":"140110"
+ },
+ {
+ "name":"清徐县",
+ "code":"140121"
+ },
+ {
+ "name":"阳曲县",
+ "code":"140122"
+ },
+ {
+ "name":"娄烦县",
+ "code":"140123"
+ },
+ {
+ "name":"古交市",
+ "code":"140181"
+ }
+ ]
+ },
+ {
+ "name":"大同市",
+ "code":"140200",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"140201"
+ },
+ {
+ "name":"城区",
+ "code":"140202"
+ },
+ {
+ "name":"矿区",
+ "code":"140203"
+ },
+ {
+ "name":"南郊区",
+ "code":"140211"
+ },
+ {
+ "name":"新荣区",
+ "code":"140212"
+ },
+ {
+ "name":"阳高县",
+ "code":"140221"
+ },
+ {
+ "name":"天镇县",
+ "code":"140222"
+ },
+ {
+ "name":"广灵县",
+ "code":"140223"
+ },
+ {
+ "name":"灵丘县",
+ "code":"140224"
+ },
+ {
+ "name":"浑源县",
+ "code":"140225"
+ },
+ {
+ "name":"左云县",
+ "code":"140226"
+ },
+ {
+ "name":"大同县",
+ "code":"140227"
+ }
+ ]
+ },
+ {
+ "name":"阳泉市",
+ "code":"140300",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"140301"
+ },
+ {
+ "name":"城区",
+ "code":"140302"
+ },
+ {
+ "name":"矿区",
+ "code":"140303"
+ },
+ {
+ "name":"郊区",
+ "code":"140311"
+ },
+ {
+ "name":"平定县",
+ "code":"140321"
+ },
+ {
+ "name":"盂县",
+ "code":"140322"
+ }
+ ]
+ },
+ {
+ "name":"长治市",
+ "code":"140400",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"140401"
+ },
+ {
+ "name":"城区",
+ "code":"140402"
+ },
+ {
+ "name":"郊区",
+ "code":"140411"
+ },
+ {
+ "name":"长治县",
+ "code":"140421"
+ },
+ {
+ "name":"襄垣县",
+ "code":"140423"
+ },
+ {
+ "name":"屯留县",
+ "code":"140424"
+ },
+ {
+ "name":"平顺县",
+ "code":"140425"
+ },
+ {
+ "name":"黎城县",
+ "code":"140426"
+ },
+ {
+ "name":"壶关县",
+ "code":"140427"
+ },
+ {
+ "name":"长子县",
+ "code":"140428"
+ },
+ {
+ "name":"武乡县",
+ "code":"140429"
+ },
+ {
+ "name":"沁县",
+ "code":"140430"
+ },
+ {
+ "name":"沁源县",
+ "code":"140431"
+ },
+ {
+ "name":"潞城市",
+ "code":"140481"
+ }
+ ]
+ },
+ {
+ "name":"晋城市",
+ "code":"140500",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"140501"
+ },
+ {
+ "name":"城区",
+ "code":"140502"
+ },
+ {
+ "name":"沁水县",
+ "code":"140521"
+ },
+ {
+ "name":"阳城县",
+ "code":"140522"
+ },
+ {
+ "name":"陵川县",
+ "code":"140524"
+ },
+ {
+ "name":"泽州县",
+ "code":"140525"
+ },
+ {
+ "name":"高平市",
+ "code":"140581"
+ }
+ ]
+ },
+ {
+ "name":"朔州市",
+ "code":"140600",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"140601"
+ },
+ {
+ "name":"朔城区",
+ "code":"140602"
+ },
+ {
+ "name":"平鲁区",
+ "code":"140603"
+ },
+ {
+ "name":"山阴县",
+ "code":"140621"
+ },
+ {
+ "name":"应县",
+ "code":"140622"
+ },
+ {
+ "name":"右玉县",
+ "code":"140623"
+ },
+ {
+ "name":"怀仁县",
+ "code":"140624"
+ }
+ ]
+ },
+ {
+ "name":"晋中市",
+ "code":"140700",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"140701"
+ },
+ {
+ "name":"榆次区",
+ "code":"140702"
+ },
+ {
+ "name":"榆社县",
+ "code":"140721"
+ },
+ {
+ "name":"左权县",
+ "code":"140722"
+ },
+ {
+ "name":"和顺县",
+ "code":"140723"
+ },
+ {
+ "name":"昔阳县",
+ "code":"140724"
+ },
+ {
+ "name":"寿阳县",
+ "code":"140725"
+ },
+ {
+ "name":"太谷县",
+ "code":"140726"
+ },
+ {
+ "name":"祁县",
+ "code":"140727"
+ },
+ {
+ "name":"平遥县",
+ "code":"140728"
+ },
+ {
+ "name":"灵石县",
+ "code":"140729"
+ },
+ {
+ "name":"介休市",
+ "code":"140781"
+ }
+ ]
+ },
+ {
+ "name":"运城市",
+ "code":"140800",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"140801"
+ },
+ {
+ "name":"盐湖区",
+ "code":"140802"
+ },
+ {
+ "name":"临猗县",
+ "code":"140821"
+ },
+ {
+ "name":"万荣县",
+ "code":"140822"
+ },
+ {
+ "name":"闻喜县",
+ "code":"140823"
+ },
+ {
+ "name":"稷山县",
+ "code":"140824"
+ },
+ {
+ "name":"新绛县",
+ "code":"140825"
+ },
+ {
+ "name":"绛县",
+ "code":"140826"
+ },
+ {
+ "name":"垣曲县",
+ "code":"140827"
+ },
+ {
+ "name":"夏县",
+ "code":"140828"
+ },
+ {
+ "name":"平陆县",
+ "code":"140829"
+ },
+ {
+ "name":"芮城县",
+ "code":"140830"
+ },
+ {
+ "name":"永济市",
+ "code":"140881"
+ },
+ {
+ "name":"河津市",
+ "code":"140882"
+ }
+ ]
+ },
+ {
+ "name":"忻州市",
+ "code":"140900",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"140901"
+ },
+ {
+ "name":"忻府区",
+ "code":"140902"
+ },
+ {
+ "name":"定襄县",
+ "code":"140921"
+ },
+ {
+ "name":"五台县",
+ "code":"140922"
+ },
+ {
+ "name":"代县",
+ "code":"140923"
+ },
+ {
+ "name":"繁峙县",
+ "code":"140924"
+ },
+ {
+ "name":"宁武县",
+ "code":"140925"
+ },
+ {
+ "name":"静乐县",
+ "code":"140926"
+ },
+ {
+ "name":"神池县",
+ "code":"140927"
+ },
+ {
+ "name":"五寨县",
+ "code":"140928"
+ },
+ {
+ "name":"岢岚县",
+ "code":"140929"
+ },
+ {
+ "name":"河曲县",
+ "code":"140930"
+ },
+ {
+ "name":"保德县",
+ "code":"140931"
+ },
+ {
+ "name":"偏关县",
+ "code":"140932"
+ },
+ {
+ "name":"原平市",
+ "code":"140981"
+ }
+ ]
+ },
+ {
+ "name":"临汾市",
+ "code":"141000",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"141001"
+ },
+ {
+ "name":"尧都区",
+ "code":"141002"
+ },
+ {
+ "name":"曲沃县",
+ "code":"141021"
+ },
+ {
+ "name":"翼城县",
+ "code":"141022"
+ },
+ {
+ "name":"襄汾县",
+ "code":"141023"
+ },
+ {
+ "name":"洪洞县",
+ "code":"141024"
+ },
+ {
+ "name":"古县",
+ "code":"141025"
+ },
+ {
+ "name":"安泽县",
+ "code":"141026"
+ },
+ {
+ "name":"浮山县",
+ "code":"141027"
+ },
+ {
+ "name":"吉县",
+ "code":"141028"
+ },
+ {
+ "name":"乡宁县",
+ "code":"141029"
+ },
+ {
+ "name":"大宁县",
+ "code":"141030"
+ },
+ {
+ "name":"隰县",
+ "code":"141031"
+ },
+ {
+ "name":"永和县",
+ "code":"141032"
+ },
+ {
+ "name":"蒲县",
+ "code":"141033"
+ },
+ {
+ "name":"汾西县",
+ "code":"141034"
+ },
+ {
+ "name":"侯马市",
+ "code":"141081"
+ },
+ {
+ "name":"霍州市",
+ "code":"141082"
+ }
+ ]
+ },
+ {
+ "name":"吕梁市",
+ "code":"141100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"141101"
+ },
+ {
+ "name":"离石区",
+ "code":"141102"
+ },
+ {
+ "name":"文水县",
+ "code":"141121"
+ },
+ {
+ "name":"交城县",
+ "code":"141122"
+ },
+ {
+ "name":"兴县",
+ "code":"141123"
+ },
+ {
+ "name":"临县",
+ "code":"141124"
+ },
+ {
+ "name":"柳林县",
+ "code":"141125"
+ },
+ {
+ "name":"石楼县",
+ "code":"141126"
+ },
+ {
+ "name":"岚县",
+ "code":"141127"
+ },
+ {
+ "name":"方山县",
+ "code":"141128"
+ },
+ {
+ "name":"中阳县",
+ "code":"141129"
+ },
+ {
+ "name":"交口县",
+ "code":"141130"
+ },
+ {
+ "name":"孝义市",
+ "code":"141181"
+ },
+ {
+ "name":"汾阳市",
+ "code":"141182"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name":"内蒙古自治区",
+ "code":"150000",
+ "sub":[
+ {
+ "name":"呼和浩特市",
+ "code":"150100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"150101"
+ },
+ {
+ "name":"新城区",
+ "code":"150102"
+ },
+ {
+ "name":"回民区",
+ "code":"150103"
+ },
+ {
+ "name":"玉泉区",
+ "code":"150104"
+ },
+ {
+ "name":"赛罕区",
+ "code":"150105"
+ },
+ {
+ "name":"土默特左旗",
+ "code":"150121"
+ },
+ {
+ "name":"托克托县",
+ "code":"150122"
+ },
+ {
+ "name":"和林格尔县",
+ "code":"150123"
+ },
+ {
+ "name":"清水河县",
+ "code":"150124"
+ },
+ {
+ "name":"武川县",
+ "code":"150125"
+ }
+ ]
+ },
+ {
+ "name":"包头市",
+ "code":"150200",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"150201"
+ },
+ {
+ "name":"东河区",
+ "code":"150202"
+ },
+ {
+ "name":"昆都仑区",
+ "code":"150203"
+ },
+ {
+ "name":"青山区",
+ "code":"150204"
+ },
+ {
+ "name":"石拐区",
+ "code":"150205"
+ },
+ {
+ "name":"白云鄂博矿区",
+ "code":"150206"
+ },
+ {
+ "name":"九原区",
+ "code":"150207"
+ },
+ {
+ "name":"土默特右旗",
+ "code":"150221"
+ },
+ {
+ "name":"固阳县",
+ "code":"150222"
+ },
+ {
+ "name":"达尔罕茂明安联合旗",
+ "code":"150223"
+ }
+ ]
+ },
+ {
+ "name":"乌海市",
+ "code":"150300",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"150301"
+ },
+ {
+ "name":"海勃湾区",
+ "code":"150302"
+ },
+ {
+ "name":"海南区",
+ "code":"150303"
+ },
+ {
+ "name":"乌达区",
+ "code":"150304"
+ }
+ ]
+ },
+ {
+ "name":"赤峰市",
+ "code":"150400",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"150401"
+ },
+ {
+ "name":"红山区",
+ "code":"150402"
+ },
+ {
+ "name":"元宝山区",
+ "code":"150403"
+ },
+ {
+ "name":"松山区",
+ "code":"150404"
+ },
+ {
+ "name":"阿鲁科尔沁旗",
+ "code":"150421"
+ },
+ {
+ "name":"巴林左旗",
+ "code":"150422"
+ },
+ {
+ "name":"巴林右旗",
+ "code":"150423"
+ },
+ {
+ "name":"林西县",
+ "code":"150424"
+ },
+ {
+ "name":"克什克腾旗",
+ "code":"150425"
+ },
+ {
+ "name":"翁牛特旗",
+ "code":"150426"
+ },
+ {
+ "name":"喀喇沁旗",
+ "code":"150428"
+ },
+ {
+ "name":"宁城县",
+ "code":"150429"
+ },
+ {
+ "name":"敖汉旗",
+ "code":"150430"
+ }
+ ]
+ },
+ {
+ "name":"通辽市",
+ "code":"150500",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"150501"
+ },
+ {
+ "name":"科尔沁区",
+ "code":"150502"
+ },
+ {
+ "name":"科尔沁左翼中旗",
+ "code":"150521"
+ },
+ {
+ "name":"科尔沁左翼后旗",
+ "code":"150522"
+ },
+ {
+ "name":"开鲁县",
+ "code":"150523"
+ },
+ {
+ "name":"库伦旗",
+ "code":"150524"
+ },
+ {
+ "name":"奈曼旗",
+ "code":"150525"
+ },
+ {
+ "name":"扎鲁特旗",
+ "code":"150526"
+ },
+ {
+ "name":"霍林郭勒市",
+ "code":"150581"
+ }
+ ]
+ },
+ {
+ "name":"鄂尔多斯市",
+ "code":"150600",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"150601"
+ },
+ {
+ "name":"东胜区",
+ "code":"150602"
+ },
+ {
+ "name":"达拉特旗",
+ "code":"150621"
+ },
+ {
+ "name":"准格尔旗",
+ "code":"150622"
+ },
+ {
+ "name":"鄂托克前旗",
+ "code":"150623"
+ },
+ {
+ "name":"鄂托克旗",
+ "code":"150624"
+ },
+ {
+ "name":"杭锦旗",
+ "code":"150625"
+ },
+ {
+ "name":"乌审旗",
+ "code":"150626"
+ },
+ {
+ "name":"伊金霍洛旗",
+ "code":"150627"
+ }
+ ]
+ },
+ {
+ "name":"呼伦贝尔市",
+ "code":"150700",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"150701"
+ },
+ {
+ "name":"海拉尔区",
+ "code":"150702"
+ },
+ {
+ "name":"扎赉诺尔区",
+ "code":"150703"
+ },
+ {
+ "name":"阿荣旗",
+ "code":"150721"
+ },
+ {
+ "name":"莫力达瓦达斡尔族自治旗",
+ "code":"150722"
+ },
+ {
+ "name":"鄂伦春自治旗",
+ "code":"150723"
+ },
+ {
+ "name":"鄂温克族自治旗",
+ "code":"150724"
+ },
+ {
+ "name":"陈巴尔虎旗",
+ "code":"150725"
+ },
+ {
+ "name":"新巴尔虎左旗",
+ "code":"150726"
+ },
+ {
+ "name":"新巴尔虎右旗",
+ "code":"150727"
+ },
+ {
+ "name":"满洲里市",
+ "code":"150781"
+ },
+ {
+ "name":"牙克石市",
+ "code":"150782"
+ },
+ {
+ "name":"扎兰屯市",
+ "code":"150783"
+ },
+ {
+ "name":"额尔古纳市",
+ "code":"150784"
+ },
+ {
+ "name":"根河市",
+ "code":"150785"
+ }
+ ]
+ },
+ {
+ "name":"巴彦淖尔市",
+ "code":"150800",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"150801"
+ },
+ {
+ "name":"临河区",
+ "code":"150802"
+ },
+ {
+ "name":"五原县",
+ "code":"150821"
+ },
+ {
+ "name":"磴口县",
+ "code":"150822"
+ },
+ {
+ "name":"乌拉特前旗",
+ "code":"150823"
+ },
+ {
+ "name":"乌拉特中旗",
+ "code":"150824"
+ },
+ {
+ "name":"乌拉特后旗",
+ "code":"150825"
+ },
+ {
+ "name":"杭锦后旗",
+ "code":"150826"
+ }
+ ]
+ },
+ {
+ "name":"乌兰察布市",
+ "code":"150900",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"150901"
+ },
+ {
+ "name":"集宁区",
+ "code":"150902"
+ },
+ {
+ "name":"卓资县",
+ "code":"150921"
+ },
+ {
+ "name":"化德县",
+ "code":"150922"
+ },
+ {
+ "name":"商都县",
+ "code":"150923"
+ },
+ {
+ "name":"兴和县",
+ "code":"150924"
+ },
+ {
+ "name":"凉城县",
+ "code":"150925"
+ },
+ {
+ "name":"察哈尔右翼前旗",
+ "code":"150926"
+ },
+ {
+ "name":"察哈尔右翼中旗",
+ "code":"150927"
+ },
+ {
+ "name":"察哈尔右翼后旗",
+ "code":"150928"
+ },
+ {
+ "name":"四子王旗",
+ "code":"150929"
+ },
+ {
+ "name":"丰镇市",
+ "code":"150981"
+ }
+ ]
+ },
+ {
+ "name":"兴安盟",
+ "code":"152200",
+ "sub":[
+ {
+ "name":"乌兰浩特市",
+ "code":"152201"
+ },
+ {
+ "name":"阿尔山市",
+ "code":"152202"
+ },
+ {
+ "name":"科尔沁右翼前旗",
+ "code":"152221"
+ },
+ {
+ "name":"科尔沁右翼中旗",
+ "code":"152222"
+ },
+ {
+ "name":"扎赉特旗",
+ "code":"152223"
+ },
+ {
+ "name":"突泉县",
+ "code":"152224"
+ }
+ ]
+ },
+ {
+ "name":"锡林郭勒盟",
+ "code":"152500",
+ "sub":[
+ {
+ "name":"二连浩特市",
+ "code":"152501"
+ },
+ {
+ "name":"锡林浩特市",
+ "code":"152502"
+ },
+ {
+ "name":"阿巴嘎旗",
+ "code":"152522"
+ },
+ {
+ "name":"苏尼特左旗",
+ "code":"152523"
+ },
+ {
+ "name":"苏尼特右旗",
+ "code":"152524"
+ },
+ {
+ "name":"东乌珠穆沁旗",
+ "code":"152525"
+ },
+ {
+ "name":"西乌珠穆沁旗",
+ "code":"152526"
+ },
+ {
+ "name":"太仆寺旗",
+ "code":"152527"
+ },
+ {
+ "name":"镶黄旗",
+ "code":"152528"
+ },
+ {
+ "name":"正镶白旗",
+ "code":"152529"
+ },
+ {
+ "name":"正蓝旗",
+ "code":"152530"
+ },
+ {
+ "name":"多伦县",
+ "code":"152531"
+ }
+ ]
+ },
+ {
+ "name":"阿拉善盟",
+ "code":"152900",
+ "sub":[
+ {
+ "name":"阿拉善左旗",
+ "code":"152921"
+ },
+ {
+ "name":"阿拉善右旗",
+ "code":"152922"
+ },
+ {
+ "name":"额济纳旗",
+ "code":"152923"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name":"辽宁省",
+ "code":"210000",
+ "sub":[
+ {
+ "name":"沈阳市",
+ "code":"210100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"210101"
+ },
+ {
+ "name":"和平区",
+ "code":"210102"
+ },
+ {
+ "name":"沈河区",
+ "code":"210103"
+ },
+ {
+ "name":"大东区",
+ "code":"210104"
+ },
+ {
+ "name":"皇姑区",
+ "code":"210105"
+ },
+ {
+ "name":"铁西区",
+ "code":"210106"
+ },
+ {
+ "name":"苏家屯区",
+ "code":"210111"
+ },
+ {
+ "name":"浑南区",
+ "code":"210112"
+ },
+ {
+ "name":"沈北新区",
+ "code":"210113"
+ },
+ {
+ "name":"于洪区",
+ "code":"210114"
+ },
+ {
+ "name":"辽中县",
+ "code":"210122"
+ },
+ {
+ "name":"康平县",
+ "code":"210123"
+ },
+ {
+ "name":"法库县",
+ "code":"210124"
+ },
+ {
+ "name":"新民市",
+ "code":"210181"
+ }
+ ]
+ },
+ {
+ "name":"大连市",
+ "code":"210200",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"210201"
+ },
+ {
+ "name":"中山区",
+ "code":"210202"
+ },
+ {
+ "name":"西岗区",
+ "code":"210203"
+ },
+ {
+ "name":"沙河口区",
+ "code":"210204"
+ },
+ {
+ "name":"甘井子区",
+ "code":"210211"
+ },
+ {
+ "name":"旅顺口区",
+ "code":"210212"
+ },
+ {
+ "name":"金州区",
+ "code":"210213"
+ },
+ {
+ "name":"长海县",
+ "code":"210224"
+ },
+ {
+ "name":"瓦房店市",
+ "code":"210281"
+ },
+ {
+ "name":"普兰店市",
+ "code":"210282"
+ },
+ {
+ "name":"庄河市",
+ "code":"210283"
+ }
+ ]
+ },
+ {
+ "name":"鞍山市",
+ "code":"210300",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"210301"
+ },
+ {
+ "name":"铁东区",
+ "code":"210302"
+ },
+ {
+ "name":"铁西区",
+ "code":"210303"
+ },
+ {
+ "name":"立山区",
+ "code":"210304"
+ },
+ {
+ "name":"千山区",
+ "code":"210311"
+ },
+ {
+ "name":"台安县",
+ "code":"210321"
+ },
+ {
+ "name":"岫岩满族自治县",
+ "code":"210323"
+ },
+ {
+ "name":"海城市",
+ "code":"210381"
+ }
+ ]
+ },
+ {
+ "name":"抚顺市",
+ "code":"210400",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"210401"
+ },
+ {
+ "name":"新抚区",
+ "code":"210402"
+ },
+ {
+ "name":"东洲区",
+ "code":"210403"
+ },
+ {
+ "name":"望花区",
+ "code":"210404"
+ },
+ {
+ "name":"顺城区",
+ "code":"210411"
+ },
+ {
+ "name":"抚顺县",
+ "code":"210421"
+ },
+ {
+ "name":"新宾满族自治县",
+ "code":"210422"
+ },
+ {
+ "name":"清原满族自治县",
+ "code":"210423"
+ }
+ ]
+ },
+ {
+ "name":"本溪市",
+ "code":"210500",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"210501"
+ },
+ {
+ "name":"平山区",
+ "code":"210502"
+ },
+ {
+ "name":"溪湖区",
+ "code":"210503"
+ },
+ {
+ "name":"明山区",
+ "code":"210504"
+ },
+ {
+ "name":"南芬区",
+ "code":"210505"
+ },
+ {
+ "name":"本溪满族自治县",
+ "code":"210521"
+ },
+ {
+ "name":"桓仁满族自治县",
+ "code":"210522"
+ }
+ ]
+ },
+ {
+ "name":"丹东市",
+ "code":"210600",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"210601"
+ },
+ {
+ "name":"元宝区",
+ "code":"210602"
+ },
+ {
+ "name":"振兴区",
+ "code":"210603"
+ },
+ {
+ "name":"振安区",
+ "code":"210604"
+ },
+ {
+ "name":"宽甸满族自治县",
+ "code":"210624"
+ },
+ {
+ "name":"东港市",
+ "code":"210681"
+ },
+ {
+ "name":"凤城市",
+ "code":"210682"
+ }
+ ]
+ },
+ {
+ "name":"锦州市",
+ "code":"210700",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"210701"
+ },
+ {
+ "name":"古塔区",
+ "code":"210702"
+ },
+ {
+ "name":"凌河区",
+ "code":"210703"
+ },
+ {
+ "name":"太和区",
+ "code":"210711"
+ },
+ {
+ "name":"黑山县",
+ "code":"210726"
+ },
+ {
+ "name":"义县",
+ "code":"210727"
+ },
+ {
+ "name":"凌海市",
+ "code":"210781"
+ },
+ {
+ "name":"北镇市",
+ "code":"210782"
+ }
+ ]
+ },
+ {
+ "name":"营口市",
+ "code":"210800",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"210801"
+ },
+ {
+ "name":"站前区",
+ "code":"210802"
+ },
+ {
+ "name":"西市区",
+ "code":"210803"
+ },
+ {
+ "name":"鲅鱼圈区",
+ "code":"210804"
+ },
+ {
+ "name":"老边区",
+ "code":"210811"
+ },
+ {
+ "name":"盖州市",
+ "code":"210881"
+ },
+ {
+ "name":"大石桥市",
+ "code":"210882"
+ }
+ ]
+ },
+ {
+ "name":"阜新市",
+ "code":"210900",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"210901"
+ },
+ {
+ "name":"海州区",
+ "code":"210902"
+ },
+ {
+ "name":"新邱区",
+ "code":"210903"
+ },
+ {
+ "name":"太平区",
+ "code":"210904"
+ },
+ {
+ "name":"清河门区",
+ "code":"210905"
+ },
+ {
+ "name":"细河区",
+ "code":"210911"
+ },
+ {
+ "name":"阜新蒙古族自治县",
+ "code":"210921"
+ },
+ {
+ "name":"彰武县",
+ "code":"210922"
+ }
+ ]
+ },
+ {
+ "name":"辽阳市",
+ "code":"211000",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"211001"
+ },
+ {
+ "name":"白塔区",
+ "code":"211002"
+ },
+ {
+ "name":"文圣区",
+ "code":"211003"
+ },
+ {
+ "name":"宏伟区",
+ "code":"211004"
+ },
+ {
+ "name":"弓长岭区",
+ "code":"211005"
+ },
+ {
+ "name":"太子河区",
+ "code":"211011"
+ },
+ {
+ "name":"辽阳县",
+ "code":"211021"
+ },
+ {
+ "name":"灯塔市",
+ "code":"211081"
+ }
+ ]
+ },
+ {
+ "name":"盘锦市",
+ "code":"211100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"211101"
+ },
+ {
+ "name":"双台子区",
+ "code":"211102"
+ },
+ {
+ "name":"兴隆台区",
+ "code":"211103"
+ },
+ {
+ "name":"大洼县",
+ "code":"211121"
+ },
+ {
+ "name":"盘山县",
+ "code":"211122"
+ }
+ ]
+ },
+ {
+ "name":"铁岭市",
+ "code":"211200",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"211201"
+ },
+ {
+ "name":"银州区",
+ "code":"211202"
+ },
+ {
+ "name":"清河区",
+ "code":"211204"
+ },
+ {
+ "name":"铁岭县",
+ "code":"211221"
+ },
+ {
+ "name":"西丰县",
+ "code":"211223"
+ },
+ {
+ "name":"昌图县",
+ "code":"211224"
+ },
+ {
+ "name":"调兵山市",
+ "code":"211281"
+ },
+ {
+ "name":"开原市",
+ "code":"211282"
+ }
+ ]
+ },
+ {
+ "name":"朝阳市",
+ "code":"211300",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"211301"
+ },
+ {
+ "name":"双塔区",
+ "code":"211302"
+ },
+ {
+ "name":"龙城区",
+ "code":"211303"
+ },
+ {
+ "name":"朝阳县",
+ "code":"211321"
+ },
+ {
+ "name":"建平县",
+ "code":"211322"
+ },
+ {
+ "name":"喀喇沁左翼蒙古族自治县",
+ "code":"211324"
+ },
+ {
+ "name":"北票市",
+ "code":"211381"
+ },
+ {
+ "name":"凌源市",
+ "code":"211382"
+ }
+ ]
+ },
+ {
+ "name":"葫芦岛市",
+ "code":"211400",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"211401"
+ },
+ {
+ "name":"连山区",
+ "code":"211402"
+ },
+ {
+ "name":"龙港区",
+ "code":"211403"
+ },
+ {
+ "name":"南票区",
+ "code":"211404"
+ },
+ {
+ "name":"绥中县",
+ "code":"211421"
+ },
+ {
+ "name":"建昌县",
+ "code":"211422"
+ },
+ {
+ "name":"兴城市",
+ "code":"211481"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name":"吉林省",
+ "code":"220000",
+ "sub":[
+ {
+ "name":"长春市",
+ "code":"220100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"220101"
+ },
+ {
+ "name":"南关区",
+ "code":"220102"
+ },
+ {
+ "name":"宽城区",
+ "code":"220103"
+ },
+ {
+ "name":"朝阳区",
+ "code":"220104"
+ },
+ {
+ "name":"二道区",
+ "code":"220105"
+ },
+ {
+ "name":"绿园区",
+ "code":"220106"
+ },
+ {
+ "name":"双阳区",
+ "code":"220112"
+ },
+ {
+ "name":"九台区",
+ "code":"220113"
+ },
+ {
+ "name":"农安县",
+ "code":"220122"
+ },
+ {
+ "name":"榆树市",
+ "code":"220182"
+ },
+ {
+ "name":"德惠市",
+ "code":"220183"
+ }
+ ]
+ },
+ {
+ "name":"吉林市",
+ "code":"220200",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"220201"
+ },
+ {
+ "name":"昌邑区",
+ "code":"220202"
+ },
+ {
+ "name":"龙潭区",
+ "code":"220203"
+ },
+ {
+ "name":"船营区",
+ "code":"220204"
+ },
+ {
+ "name":"丰满区",
+ "code":"220211"
+ },
+ {
+ "name":"永吉县",
+ "code":"220221"
+ },
+ {
+ "name":"蛟河市",
+ "code":"220281"
+ },
+ {
+ "name":"桦甸市",
+ "code":"220282"
+ },
+ {
+ "name":"舒兰市",
+ "code":"220283"
+ },
+ {
+ "name":"磐石市",
+ "code":"220284"
+ }
+ ]
+ },
+ {
+ "name":"四平市",
+ "code":"220300",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"220301"
+ },
+ {
+ "name":"铁西区",
+ "code":"220302"
+ },
+ {
+ "name":"铁东区",
+ "code":"220303"
+ },
+ {
+ "name":"梨树县",
+ "code":"220322"
+ },
+ {
+ "name":"伊通满族自治县",
+ "code":"220323"
+ },
+ {
+ "name":"公主岭市",
+ "code":"220381"
+ },
+ {
+ "name":"双辽市",
+ "code":"220382"
+ }
+ ]
+ },
+ {
+ "name":"辽源市",
+ "code":"220400",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"220401"
+ },
+ {
+ "name":"龙山区",
+ "code":"220402"
+ },
+ {
+ "name":"西安区",
+ "code":"220403"
+ },
+ {
+ "name":"东丰县",
+ "code":"220421"
+ },
+ {
+ "name":"东辽县",
+ "code":"220422"
+ }
+ ]
+ },
+ {
+ "name":"通化市",
+ "code":"220500",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"220501"
+ },
+ {
+ "name":"东昌区",
+ "code":"220502"
+ },
+ {
+ "name":"二道江区",
+ "code":"220503"
+ },
+ {
+ "name":"通化县",
+ "code":"220521"
+ },
+ {
+ "name":"辉南县",
+ "code":"220523"
+ },
+ {
+ "name":"柳河县",
+ "code":"220524"
+ },
+ {
+ "name":"梅河口市",
+ "code":"220581"
+ },
+ {
+ "name":"集安市",
+ "code":"220582"
+ }
+ ]
+ },
+ {
+ "name":"白山市",
+ "code":"220600",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"220601"
+ },
+ {
+ "name":"浑江区",
+ "code":"220602"
+ },
+ {
+ "name":"江源区",
+ "code":"220605"
+ },
+ {
+ "name":"抚松县",
+ "code":"220621"
+ },
+ {
+ "name":"靖宇县",
+ "code":"220622"
+ },
+ {
+ "name":"长白朝鲜族自治县",
+ "code":"220623"
+ },
+ {
+ "name":"临江市",
+ "code":"220681"
+ }
+ ]
+ },
+ {
+ "name":"松原市",
+ "code":"220700",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"220701"
+ },
+ {
+ "name":"宁江区",
+ "code":"220702"
+ },
+ {
+ "name":"前郭尔罗斯蒙古族自治县",
+ "code":"220721"
+ },
+ {
+ "name":"长岭县",
+ "code":"220722"
+ },
+ {
+ "name":"乾安县",
+ "code":"220723"
+ },
+ {
+ "name":"扶余市",
+ "code":"220781"
+ }
+ ]
+ },
+ {
+ "name":"白城市",
+ "code":"220800",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"220801"
+ },
+ {
+ "name":"洮北区",
+ "code":"220802"
+ },
+ {
+ "name":"镇赉县",
+ "code":"220821"
+ },
+ {
+ "name":"通榆县",
+ "code":"220822"
+ },
+ {
+ "name":"洮南市",
+ "code":"220881"
+ },
+ {
+ "name":"大安市",
+ "code":"220882"
+ }
+ ]
+ },
+ {
+ "name":"延边朝鲜族自治州",
+ "code":"222400",
+ "sub":[
+ {
+ "name":"延吉市",
+ "code":"222401"
+ },
+ {
+ "name":"图们市",
+ "code":"222402"
+ },
+ {
+ "name":"敦化市",
+ "code":"222403"
+ },
+ {
+ "name":"珲春市",
+ "code":"222404"
+ },
+ {
+ "name":"龙井市",
+ "code":"222405"
+ },
+ {
+ "name":"和龙市",
+ "code":"222406"
+ },
+ {
+ "name":"汪清县",
+ "code":"222424"
+ },
+ {
+ "name":"安图县",
+ "code":"222426"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name":"黑龙江省",
+ "code":"230000",
+ "sub":[
+ {
+ "name":"哈尔滨市",
+ "code":"230100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"230101"
+ },
+ {
+ "name":"道里区",
+ "code":"230102"
+ },
+ {
+ "name":"南岗区",
+ "code":"230103"
+ },
+ {
+ "name":"道外区",
+ "code":"230104"
+ },
+ {
+ "name":"平房区",
+ "code":"230108"
+ },
+ {
+ "name":"松北区",
+ "code":"230109"
+ },
+ {
+ "name":"香坊区",
+ "code":"230110"
+ },
+ {
+ "name":"呼兰区",
+ "code":"230111"
+ },
+ {
+ "name":"阿城区",
+ "code":"230112"
+ },
+ {
+ "name":"双城区",
+ "code":"230113"
+ },
+ {
+ "name":"依兰县",
+ "code":"230123"
+ },
+ {
+ "name":"方正县",
+ "code":"230124"
+ },
+ {
+ "name":"宾县",
+ "code":"230125"
+ },
+ {
+ "name":"巴彦县",
+ "code":"230126"
+ },
+ {
+ "name":"木兰县",
+ "code":"230127"
+ },
+ {
+ "name":"通河县",
+ "code":"230128"
+ },
+ {
+ "name":"延寿县",
+ "code":"230129"
+ },
+ {
+ "name":"尚志市",
+ "code":"230183"
+ },
+ {
+ "name":"五常市",
+ "code":"230184"
+ }
+ ]
+ },
+ {
+ "name":"齐齐哈尔市",
+ "code":"230200",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"230201"
+ },
+ {
+ "name":"龙沙区",
+ "code":"230202"
+ },
+ {
+ "name":"建华区",
+ "code":"230203"
+ },
+ {
+ "name":"铁锋区",
+ "code":"230204"
+ },
+ {
+ "name":"昂昂溪区",
+ "code":"230205"
+ },
+ {
+ "name":"富拉尔基区",
+ "code":"230206"
+ },
+ {
+ "name":"碾子山区",
+ "code":"230207"
+ },
+ {
+ "name":"梅里斯达斡尔族区",
+ "code":"230208"
+ },
+ {
+ "name":"龙江县",
+ "code":"230221"
+ },
+ {
+ "name":"依安县",
+ "code":"230223"
+ },
+ {
+ "name":"泰来县",
+ "code":"230224"
+ },
+ {
+ "name":"甘南县",
+ "code":"230225"
+ },
+ {
+ "name":"富裕县",
+ "code":"230227"
+ },
+ {
+ "name":"克山县",
+ "code":"230229"
+ },
+ {
+ "name":"克东县",
+ "code":"230230"
+ },
+ {
+ "name":"拜泉县",
+ "code":"230231"
+ },
+ {
+ "name":"讷河市",
+ "code":"230281"
+ }
+ ]
+ },
+ {
+ "name":"鸡西市",
+ "code":"230300",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"230301"
+ },
+ {
+ "name":"鸡冠区",
+ "code":"230302"
+ },
+ {
+ "name":"恒山区",
+ "code":"230303"
+ },
+ {
+ "name":"滴道区",
+ "code":"230304"
+ },
+ {
+ "name":"梨树区",
+ "code":"230305"
+ },
+ {
+ "name":"城子河区",
+ "code":"230306"
+ },
+ {
+ "name":"麻山区",
+ "code":"230307"
+ },
+ {
+ "name":"鸡东县",
+ "code":"230321"
+ },
+ {
+ "name":"虎林市",
+ "code":"230381"
+ },
+ {
+ "name":"密山市",
+ "code":"230382"
+ }
+ ]
+ },
+ {
+ "name":"鹤岗市",
+ "code":"230400",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"230401"
+ },
+ {
+ "name":"向阳区",
+ "code":"230402"
+ },
+ {
+ "name":"工农区",
+ "code":"230403"
+ },
+ {
+ "name":"南山区",
+ "code":"230404"
+ },
+ {
+ "name":"兴安区",
+ "code":"230405"
+ },
+ {
+ "name":"东山区",
+ "code":"230406"
+ },
+ {
+ "name":"兴山区",
+ "code":"230407"
+ },
+ {
+ "name":"萝北县",
+ "code":"230421"
+ },
+ {
+ "name":"绥滨县",
+ "code":"230422"
+ }
+ ]
+ },
+ {
+ "name":"双鸭山市",
+ "code":"230500",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"230501"
+ },
+ {
+ "name":"尖山区",
+ "code":"230502"
+ },
+ {
+ "name":"岭东区",
+ "code":"230503"
+ },
+ {
+ "name":"四方台区",
+ "code":"230505"
+ },
+ {
+ "name":"宝山区",
+ "code":"230506"
+ },
+ {
+ "name":"集贤县",
+ "code":"230521"
+ },
+ {
+ "name":"友谊县",
+ "code":"230522"
+ },
+ {
+ "name":"宝清县",
+ "code":"230523"
+ },
+ {
+ "name":"饶河县",
+ "code":"230524"
+ }
+ ]
+ },
+ {
+ "name":"大庆市",
+ "code":"230600",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"230601"
+ },
+ {
+ "name":"萨尔图区",
+ "code":"230602"
+ },
+ {
+ "name":"龙凤区",
+ "code":"230603"
+ },
+ {
+ "name":"让胡路区",
+ "code":"230604"
+ },
+ {
+ "name":"红岗区",
+ "code":"230605"
+ },
+ {
+ "name":"大同区",
+ "code":"230606"
+ },
+ {
+ "name":"肇州县",
+ "code":"230621"
+ },
+ {
+ "name":"肇源县",
+ "code":"230622"
+ },
+ {
+ "name":"林甸县",
+ "code":"230623"
+ },
+ {
+ "name":"杜尔伯特蒙古族自治县",
+ "code":"230624"
+ }
+ ]
+ },
+ {
+ "name":"伊春市",
+ "code":"230700",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"230701"
+ },
+ {
+ "name":"伊春区",
+ "code":"230702"
+ },
+ {
+ "name":"南岔区",
+ "code":"230703"
+ },
+ {
+ "name":"友好区",
+ "code":"230704"
+ },
+ {
+ "name":"西林区",
+ "code":"230705"
+ },
+ {
+ "name":"翠峦区",
+ "code":"230706"
+ },
+ {
+ "name":"新青区",
+ "code":"230707"
+ },
+ {
+ "name":"美溪区",
+ "code":"230708"
+ },
+ {
+ "name":"金山屯区",
+ "code":"230709"
+ },
+ {
+ "name":"五营区",
+ "code":"230710"
+ },
+ {
+ "name":"乌马河区",
+ "code":"230711"
+ },
+ {
+ "name":"汤旺河区",
+ "code":"230712"
+ },
+ {
+ "name":"带岭区",
+ "code":"230713"
+ },
+ {
+ "name":"乌伊岭区",
+ "code":"230714"
+ },
+ {
+ "name":"红星区",
+ "code":"230715"
+ },
+ {
+ "name":"上甘岭区",
+ "code":"230716"
+ },
+ {
+ "name":"嘉荫县",
+ "code":"230722"
+ },
+ {
+ "name":"铁力市",
+ "code":"230781"
+ }
+ ]
+ },
+ {
+ "name":"佳木斯市",
+ "code":"230800",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"230801"
+ },
+ {
+ "name":"向阳区",
+ "code":"230803"
+ },
+ {
+ "name":"前进区",
+ "code":"230804"
+ },
+ {
+ "name":"东风区",
+ "code":"230805"
+ },
+ {
+ "name":"郊区",
+ "code":"230811"
+ },
+ {
+ "name":"桦南县",
+ "code":"230822"
+ },
+ {
+ "name":"桦川县",
+ "code":"230826"
+ },
+ {
+ "name":"汤原县",
+ "code":"230828"
+ },
+ {
+ "name":"抚远县",
+ "code":"230833"
+ },
+ {
+ "name":"同江市",
+ "code":"230881"
+ },
+ {
+ "name":"富锦市",
+ "code":"230882"
+ }
+ ]
+ },
+ {
+ "name":"七台河市",
+ "code":"230900",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"230901"
+ },
+ {
+ "name":"新兴区",
+ "code":"230902"
+ },
+ {
+ "name":"桃山区",
+ "code":"230903"
+ },
+ {
+ "name":"茄子河区",
+ "code":"230904"
+ },
+ {
+ "name":"勃利县",
+ "code":"230921"
+ }
+ ]
+ },
+ {
+ "name":"牡丹江市",
+ "code":"231000",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"231001"
+ },
+ {
+ "name":"东安区",
+ "code":"231002"
+ },
+ {
+ "name":"阳明区",
+ "code":"231003"
+ },
+ {
+ "name":"爱民区",
+ "code":"231004"
+ },
+ {
+ "name":"西安区",
+ "code":"231005"
+ },
+ {
+ "name":"东宁县",
+ "code":"231024"
+ },
+ {
+ "name":"林口县",
+ "code":"231025"
+ },
+ {
+ "name":"绥芬河市",
+ "code":"231081"
+ },
+ {
+ "name":"海林市",
+ "code":"231083"
+ },
+ {
+ "name":"宁安市",
+ "code":"231084"
+ },
+ {
+ "name":"穆棱市",
+ "code":"231085"
+ }
+ ]
+ },
+ {
+ "name":"黑河市",
+ "code":"231100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"231101"
+ },
+ {
+ "name":"爱辉区",
+ "code":"231102"
+ },
+ {
+ "name":"嫩江县",
+ "code":"231121"
+ },
+ {
+ "name":"逊克县",
+ "code":"231123"
+ },
+ {
+ "name":"孙吴县",
+ "code":"231124"
+ },
+ {
+ "name":"北安市",
+ "code":"231181"
+ },
+ {
+ "name":"五大连池市",
+ "code":"231182"
+ }
+ ]
+ },
+ {
+ "name":"绥化市",
+ "code":"231200",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"231201"
+ },
+ {
+ "name":"北林区",
+ "code":"231202"
+ },
+ {
+ "name":"望奎县",
+ "code":"231221"
+ },
+ {
+ "name":"兰西县",
+ "code":"231222"
+ },
+ {
+ "name":"青冈县",
+ "code":"231223"
+ },
+ {
+ "name":"庆安县",
+ "code":"231224"
+ },
+ {
+ "name":"明水县",
+ "code":"231225"
+ },
+ {
+ "name":"绥棱县",
+ "code":"231226"
+ },
+ {
+ "name":"安达市",
+ "code":"231281"
+ },
+ {
+ "name":"肇东市",
+ "code":"231282"
+ },
+ {
+ "name":"海伦市",
+ "code":"231283"
+ }
+ ]
+ },
+ {
+ "name":"大兴安岭地区",
+ "code":"232700",
+ "sub":[
+ {
+ "name":"呼玛县",
+ "code":"232721"
+ },
+ {
+ "name":"塔河县",
+ "code":"232722"
+ },
+ {
+ "name":"漠河县",
+ "code":"232723"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name":"上海",
+ "code":"310000",
+ "sub": [
+ {
+ "name":"上海市",
+ "code": "310000",
+ "sub":[
+ {
+ "name":"黄浦区",
+ "code":"310101"
+ },
+ {
+ "name":"徐汇区",
+ "code":"310104"
+ },
+ {
+ "name":"长宁区",
+ "code":"310105"
+ },
+ {
+ "name":"静安区",
+ "code":"310106"
+ },
+ {
+ "name":"普陀区",
+ "code":"310107"
+ },
+ {
+ "name":"闸北区",
+ "code":"310108"
+ },
+ {
+ "name":"虹口区",
+ "code":"310109"
+ },
+ {
+ "name":"杨浦区",
+ "code":"310110"
+ },
+ {
+ "name":"闵行区",
+ "code":"310112"
+ },
+ {
+ "name":"宝山区",
+ "code":"310113"
+ },
+ {
+ "name":"嘉定区",
+ "code":"310114"
+ },
+ {
+ "name":"浦东新区",
+ "code":"310115"
+ },
+ {
+ "name":"金山区",
+ "code":"310116"
+ },
+ {
+ "name":"松江区",
+ "code":"310117"
+ },
+ {
+ "name":"青浦区",
+ "code":"310118"
+ },
+ {
+ "name":"奉贤区",
+ "code":"310120"
+ },
+ {
+ "name":"崇明县",
+ "code":"310230"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name":"江苏省",
+ "code":"320000",
+ "sub":[
+ {
+ "name":"南京市",
+ "code":"320100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"320101"
+ },
+ {
+ "name":"玄武区",
+ "code":"320102"
+ },
+ {
+ "name":"秦淮区",
+ "code":"320104"
+ },
+ {
+ "name":"建邺区",
+ "code":"320105"
+ },
+ {
+ "name":"鼓楼区",
+ "code":"320106"
+ },
+ {
+ "name":"浦口区",
+ "code":"320111"
+ },
+ {
+ "name":"栖霞区",
+ "code":"320113"
+ },
+ {
+ "name":"雨花台区",
+ "code":"320114"
+ },
+ {
+ "name":"江宁区",
+ "code":"320115"
+ },
+ {
+ "name":"六合区",
+ "code":"320116"
+ },
+ {
+ "name":"溧水区",
+ "code":"320117"
+ },
+ {
+ "name":"高淳区",
+ "code":"320118"
+ }
+ ]
+ },
+ {
+ "name":"无锡市",
+ "code":"320200",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"320201"
+ },
+ {
+ "name":"崇安区",
+ "code":"320202"
+ },
+ {
+ "name":"南长区",
+ "code":"320203"
+ },
+ {
+ "name":"北塘区",
+ "code":"320204"
+ },
+ {
+ "name":"锡山区",
+ "code":"320205"
+ },
+ {
+ "name":"惠山区",
+ "code":"320206"
+ },
+ {
+ "name":"滨湖区",
+ "code":"320211"
+ },
+ {
+ "name":"江阴市",
+ "code":"320281"
+ },
+ {
+ "name":"宜兴市",
+ "code":"320282"
+ }
+ ]
+ },
+ {
+ "name":"徐州市",
+ "code":"320300",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"320301"
+ },
+ {
+ "name":"鼓楼区",
+ "code":"320302"
+ },
+ {
+ "name":"云龙区",
+ "code":"320303"
+ },
+ {
+ "name":"贾汪区",
+ "code":"320305"
+ },
+ {
+ "name":"泉山区",
+ "code":"320311"
+ },
+ {
+ "name":"铜山区",
+ "code":"320312"
+ },
+ {
+ "name":"丰县",
+ "code":"320321"
+ },
+ {
+ "name":"沛县",
+ "code":"320322"
+ },
+ {
+ "name":"睢宁县",
+ "code":"320324"
+ },
+ {
+ "name":"新沂市",
+ "code":"320381"
+ },
+ {
+ "name":"邳州市",
+ "code":"320382"
+ }
+ ]
+ },
+ {
+ "name":"常州市",
+ "code":"320400",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"320401"
+ },
+ {
+ "name":"天宁区",
+ "code":"320402"
+ },
+ {
+ "name":"钟楼区",
+ "code":"320404"
+ },
+ {
+ "name":"戚墅堰区",
+ "code":"320405"
+ },
+ {
+ "name":"新北区",
+ "code":"320411"
+ },
+ {
+ "name":"武进区",
+ "code":"320412"
+ },
+ {
+ "name":"溧阳市",
+ "code":"320481"
+ },
+ {
+ "name":"金坛市",
+ "code":"320482"
+ }
+ ]
+ },
+ {
+ "name":"苏州市",
+ "code":"320500",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"320501"
+ },
+ {
+ "name":"虎丘区",
+ "code":"320505"
+ },
+ {
+ "name":"吴中区",
+ "code":"320506"
+ },
+ {
+ "name":"相城区",
+ "code":"320507"
+ },
+ {
+ "name":"姑苏区",
+ "code":"320508"
+ },
+ {
+ "name":"吴江区",
+ "code":"320509"
+ },
+ {
+ "name":"常熟市",
+ "code":"320581"
+ },
+ {
+ "name":"张家港市",
+ "code":"320582"
+ },
+ {
+ "name":"昆山市",
+ "code":"320583"
+ },
+ {
+ "name":"太仓市",
+ "code":"320585"
+ }
+ ]
+ },
+ {
+ "name":"南通市",
+ "code":"320600",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"320601"
+ },
+ {
+ "name":"崇川区",
+ "code":"320602"
+ },
+ {
+ "name":"港闸区",
+ "code":"320611"
+ },
+ {
+ "name":"通州区",
+ "code":"320612"
+ },
+ {
+ "name":"海安县",
+ "code":"320621"
+ },
+ {
+ "name":"如东县",
+ "code":"320623"
+ },
+ {
+ "name":"启东市",
+ "code":"320681"
+ },
+ {
+ "name":"如皋市",
+ "code":"320682"
+ },
+ {
+ "name":"海门市",
+ "code":"320684"
+ }
+ ]
+ },
+ {
+ "name":"连云港市",
+ "code":"320700",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"320701"
+ },
+ {
+ "name":"连云区",
+ "code":"320703"
+ },
+ {
+ "name":"海州区",
+ "code":"320706"
+ },
+ {
+ "name":"赣榆区",
+ "code":"320707"
+ },
+ {
+ "name":"东海县",
+ "code":"320722"
+ },
+ {
+ "name":"灌云县",
+ "code":"320723"
+ },
+ {
+ "name":"灌南县",
+ "code":"320724"
+ }
+ ]
+ },
+ {
+ "name":"淮安市",
+ "code":"320800",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"320801"
+ },
+ {
+ "name":"清河区",
+ "code":"320802"
+ },
+ {
+ "name":"淮安区",
+ "code":"320803"
+ },
+ {
+ "name":"淮阴区",
+ "code":"320804"
+ },
+ {
+ "name":"清浦区",
+ "code":"320811"
+ },
+ {
+ "name":"涟水县",
+ "code":"320826"
+ },
+ {
+ "name":"洪泽县",
+ "code":"320829"
+ },
+ {
+ "name":"盱眙县",
+ "code":"320830"
+ },
+ {
+ "name":"金湖县",
+ "code":"320831"
+ }
+ ]
+ },
+ {
+ "name":"盐城市",
+ "code":"320900",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"320901"
+ },
+ {
+ "name":"亭湖区",
+ "code":"320902"
+ },
+ {
+ "name":"盐都区",
+ "code":"320903"
+ },
+ {
+ "name":"响水县",
+ "code":"320921"
+ },
+ {
+ "name":"滨海县",
+ "code":"320922"
+ },
+ {
+ "name":"阜宁县",
+ "code":"320923"
+ },
+ {
+ "name":"射阳县",
+ "code":"320924"
+ },
+ {
+ "name":"建湖县",
+ "code":"320925"
+ },
+ {
+ "name":"东台市",
+ "code":"320981"
+ },
+ {
+ "name":"大丰市",
+ "code":"320982"
+ }
+ ]
+ },
+ {
+ "name":"扬州市",
+ "code":"321000",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"321001"
+ },
+ {
+ "name":"广陵区",
+ "code":"321002"
+ },
+ {
+ "name":"邗江区",
+ "code":"321003"
+ },
+ {
+ "name":"江都区",
+ "code":"321012"
+ },
+ {
+ "name":"宝应县",
+ "code":"321023"
+ },
+ {
+ "name":"仪征市",
+ "code":"321081"
+ },
+ {
+ "name":"高邮市",
+ "code":"321084"
+ }
+ ]
+ },
+ {
+ "name":"镇江市",
+ "code":"321100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"321101"
+ },
+ {
+ "name":"京口区",
+ "code":"321102"
+ },
+ {
+ "name":"润州区",
+ "code":"321111"
+ },
+ {
+ "name":"丹徒区",
+ "code":"321112"
+ },
+ {
+ "name":"丹阳市",
+ "code":"321181"
+ },
+ {
+ "name":"扬中市",
+ "code":"321182"
+ },
+ {
+ "name":"句容市",
+ "code":"321183"
+ }
+ ]
+ },
+ {
+ "name":"泰州市",
+ "code":"321200",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"321201"
+ },
+ {
+ "name":"海陵区",
+ "code":"321202"
+ },
+ {
+ "name":"高港区",
+ "code":"321203"
+ },
+ {
+ "name":"姜堰区",
+ "code":"321204"
+ },
+ {
+ "name":"兴化市",
+ "code":"321281"
+ },
+ {
+ "name":"靖江市",
+ "code":"321282"
+ },
+ {
+ "name":"泰兴市",
+ "code":"321283"
+ }
+ ]
+ },
+ {
+ "name":"宿迁市",
+ "code":"321300",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"321301"
+ },
+ {
+ "name":"宿城区",
+ "code":"321302"
+ },
+ {
+ "name":"宿豫区",
+ "code":"321311"
+ },
+ {
+ "name":"沭阳县",
+ "code":"321322"
+ },
+ {
+ "name":"泗阳县",
+ "code":"321323"
+ },
+ {
+ "name":"泗洪县",
+ "code":"321324"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name":"浙江省",
+ "code":"330000",
+ "sub":[
+ {
+ "name":"杭州市",
+ "code":"330100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"330101"
+ },
+ {
+ "name":"上城区",
+ "code":"330102"
+ },
+ {
+ "name":"下城区",
+ "code":"330103"
+ },
+ {
+ "name":"江干区",
+ "code":"330104"
+ },
+ {
+ "name":"拱墅区",
+ "code":"330105"
+ },
+ {
+ "name":"西湖区",
+ "code":"330106"
+ },
+ {
+ "name":"滨江区",
+ "code":"330108"
+ },
+ {
+ "name":"萧山区",
+ "code":"330109"
+ },
+ {
+ "name":"余杭区",
+ "code":"330110"
+ },
+ {
+ "name":"富阳区",
+ "code":"330111"
+ },
+ {
+ "name":"桐庐县",
+ "code":"330122"
+ },
+ {
+ "name":"淳安县",
+ "code":"330127"
+ },
+ {
+ "name":"建德市",
+ "code":"330182"
+ },
+ {
+ "name":"临安市",
+ "code":"330185"
+ }
+ ]
+ },
+ {
+ "name":"宁波市",
+ "code":"330200",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"330201"
+ },
+ {
+ "name":"海曙区",
+ "code":"330203"
+ },
+ {
+ "name":"江东区",
+ "code":"330204"
+ },
+ {
+ "name":"江北区",
+ "code":"330205"
+ },
+ {
+ "name":"北仑区",
+ "code":"330206"
+ },
+ {
+ "name":"镇海区",
+ "code":"330211"
+ },
+ {
+ "name":"鄞州区",
+ "code":"330212"
+ },
+ {
+ "name":"象山县",
+ "code":"330225"
+ },
+ {
+ "name":"宁海县",
+ "code":"330226"
+ },
+ {
+ "name":"余姚市",
+ "code":"330281"
+ },
+ {
+ "name":"慈溪市",
+ "code":"330282"
+ },
+ {
+ "name":"奉化市",
+ "code":"330283"
+ }
+ ]
+ },
+ {
+ "name":"温州市",
+ "code":"330300",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"330301"
+ },
+ {
+ "name":"鹿城区",
+ "code":"330302"
+ },
+ {
+ "name":"龙湾区",
+ "code":"330303"
+ },
+ {
+ "name":"瓯海区",
+ "code":"330304"
+ },
+ {
+ "name":"洞头县",
+ "code":"330322"
+ },
+ {
+ "name":"永嘉县",
+ "code":"330324"
+ },
+ {
+ "name":"平阳县",
+ "code":"330326"
+ },
+ {
+ "name":"苍南县",
+ "code":"330327"
+ },
+ {
+ "name":"文成县",
+ "code":"330328"
+ },
+ {
+ "name":"泰顺县",
+ "code":"330329"
+ },
+ {
+ "name":"瑞安市",
+ "code":"330381"
+ },
+ {
+ "name":"乐清市",
+ "code":"330382"
+ }
+ ]
+ },
+ {
+ "name":"嘉兴市",
+ "code":"330400",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"330401"
+ },
+ {
+ "name":"南湖区",
+ "code":"330402"
+ },
+ {
+ "name":"秀洲区",
+ "code":"330411"
+ },
+ {
+ "name":"嘉善县",
+ "code":"330421"
+ },
+ {
+ "name":"海盐县",
+ "code":"330424"
+ },
+ {
+ "name":"海宁市",
+ "code":"330481"
+ },
+ {
+ "name":"平湖市",
+ "code":"330482"
+ },
+ {
+ "name":"桐乡市",
+ "code":"330483"
+ }
+ ]
+ },
+ {
+ "name":"湖州市",
+ "code":"330500",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"330501"
+ },
+ {
+ "name":"吴兴区",
+ "code":"330502"
+ },
+ {
+ "name":"南浔区",
+ "code":"330503"
+ },
+ {
+ "name":"德清县",
+ "code":"330521"
+ },
+ {
+ "name":"长兴县",
+ "code":"330522"
+ },
+ {
+ "name":"安吉县",
+ "code":"330523"
+ }
+ ]
+ },
+ {
+ "name":"绍兴市",
+ "code":"330600",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"330601"
+ },
+ {
+ "name":"越城区",
+ "code":"330602"
+ },
+ {
+ "name":"柯桥区",
+ "code":"330603"
+ },
+ {
+ "name":"上虞区",
+ "code":"330604"
+ },
+ {
+ "name":"新昌县",
+ "code":"330624"
+ },
+ {
+ "name":"诸暨市",
+ "code":"330681"
+ },
+ {
+ "name":"嵊州市",
+ "code":"330683"
+ }
+ ]
+ },
+ {
+ "name":"金华市",
+ "code":"330700",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"330701"
+ },
+ {
+ "name":"婺城区",
+ "code":"330702"
+ },
+ {
+ "name":"金东区",
+ "code":"330703"
+ },
+ {
+ "name":"武义县",
+ "code":"330723"
+ },
+ {
+ "name":"浦江县",
+ "code":"330726"
+ },
+ {
+ "name":"磐安县",
+ "code":"330727"
+ },
+ {
+ "name":"兰溪市",
+ "code":"330781"
+ },
+ {
+ "name":"义乌市",
+ "code":"330782"
+ },
+ {
+ "name":"东阳市",
+ "code":"330783"
+ },
+ {
+ "name":"永康市",
+ "code":"330784"
+ }
+ ]
+ },
+ {
+ "name":"衢州市",
+ "code":"330800",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"330801"
+ },
+ {
+ "name":"柯城区",
+ "code":"330802"
+ },
+ {
+ "name":"衢江区",
+ "code":"330803"
+ },
+ {
+ "name":"常山县",
+ "code":"330822"
+ },
+ {
+ "name":"开化县",
+ "code":"330824"
+ },
+ {
+ "name":"龙游县",
+ "code":"330825"
+ },
+ {
+ "name":"江山市",
+ "code":"330881"
+ }
+ ]
+ },
+ {
+ "name":"舟山市",
+ "code":"330900",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"330901"
+ },
+ {
+ "name":"定海区",
+ "code":"330902"
+ },
+ {
+ "name":"普陀区",
+ "code":"330903"
+ },
+ {
+ "name":"岱山县",
+ "code":"330921"
+ },
+ {
+ "name":"嵊泗县",
+ "code":"330922"
+ }
+ ]
+ },
+ {
+ "name":"台州市",
+ "code":"331000",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"331001"
+ },
+ {
+ "name":"椒江区",
+ "code":"331002"
+ },
+ {
+ "name":"黄岩区",
+ "code":"331003"
+ },
+ {
+ "name":"路桥区",
+ "code":"331004"
+ },
+ {
+ "name":"玉环县",
+ "code":"331021"
+ },
+ {
+ "name":"三门县",
+ "code":"331022"
+ },
+ {
+ "name":"天台县",
+ "code":"331023"
+ },
+ {
+ "name":"仙居县",
+ "code":"331024"
+ },
+ {
+ "name":"温岭市",
+ "code":"331081"
+ },
+ {
+ "name":"临海市",
+ "code":"331082"
+ }
+ ]
+ },
+ {
+ "name":"丽水市",
+ "code":"331100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"331101"
+ },
+ {
+ "name":"莲都区",
+ "code":"331102"
+ },
+ {
+ "name":"青田县",
+ "code":"331121"
+ },
+ {
+ "name":"缙云县",
+ "code":"331122"
+ },
+ {
+ "name":"遂昌县",
+ "code":"331123"
+ },
+ {
+ "name":"松阳县",
+ "code":"331124"
+ },
+ {
+ "name":"云和县",
+ "code":"331125"
+ },
+ {
+ "name":"庆元县",
+ "code":"331126"
+ },
+ {
+ "name":"景宁畲族自治县",
+ "code":"331127"
+ },
+ {
+ "name":"龙泉市",
+ "code":"331181"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name":"安徽省",
+ "code":"340000",
+ "sub":[
+ {
+ "name":"合肥市",
+ "code":"340100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"340101"
+ },
+ {
+ "name":"瑶海区",
+ "code":"340102"
+ },
+ {
+ "name":"庐阳区",
+ "code":"340103"
+ },
+ {
+ "name":"蜀山区",
+ "code":"340104"
+ },
+ {
+ "name":"包河区",
+ "code":"340111"
+ },
+ {
+ "name":"长丰县",
+ "code":"340121"
+ },
+ {
+ "name":"肥东县",
+ "code":"340122"
+ },
+ {
+ "name":"肥西县",
+ "code":"340123"
+ },
+ {
+ "name":"庐江县",
+ "code":"340124"
+ },
+ {
+ "name":"巢湖市",
+ "code":"340181"
+ }
+ ]
+ },
+ {
+ "name":"芜湖市",
+ "code":"340200",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"340201"
+ },
+ {
+ "name":"镜湖区",
+ "code":"340202"
+ },
+ {
+ "name":"弋江区",
+ "code":"340203"
+ },
+ {
+ "name":"鸠江区",
+ "code":"340207"
+ },
+ {
+ "name":"三山区",
+ "code":"340208"
+ },
+ {
+ "name":"芜湖县",
+ "code":"340221"
+ },
+ {
+ "name":"繁昌县",
+ "code":"340222"
+ },
+ {
+ "name":"南陵县",
+ "code":"340223"
+ },
+ {
+ "name":"无为县",
+ "code":"340225"
+ }
+ ]
+ },
+ {
+ "name":"蚌埠市",
+ "code":"340300",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"340301"
+ },
+ {
+ "name":"龙子湖区",
+ "code":"340302"
+ },
+ {
+ "name":"蚌山区",
+ "code":"340303"
+ },
+ {
+ "name":"禹会区",
+ "code":"340304"
+ },
+ {
+ "name":"淮上区",
+ "code":"340311"
+ },
+ {
+ "name":"怀远县",
+ "code":"340321"
+ },
+ {
+ "name":"五河县",
+ "code":"340322"
+ },
+ {
+ "name":"固镇县",
+ "code":"340323"
+ }
+ ]
+ },
+ {
+ "name":"淮南市",
+ "code":"340400",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"340401"
+ },
+ {
+ "name":"大通区",
+ "code":"340402"
+ },
+ {
+ "name":"田家庵区",
+ "code":"340403"
+ },
+ {
+ "name":"谢家集区",
+ "code":"340404"
+ },
+ {
+ "name":"八公山区",
+ "code":"340405"
+ },
+ {
+ "name":"潘集区",
+ "code":"340406"
+ },
+ {
+ "name":"凤台县",
+ "code":"340421"
+ }
+ ]
+ },
+ {
+ "name":"马鞍山市",
+ "code":"340500",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"340501"
+ },
+ {
+ "name":"花山区",
+ "code":"340503"
+ },
+ {
+ "name":"雨山区",
+ "code":"340504"
+ },
+ {
+ "name":"博望区",
+ "code":"340506"
+ },
+ {
+ "name":"当涂县",
+ "code":"340521"
+ },
+ {
+ "name":"含山县",
+ "code":"340522"
+ },
+ {
+ "name":"和县",
+ "code":"340523"
+ }
+ ]
+ },
+ {
+ "name":"淮北市",
+ "code":"340600",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"340601"
+ },
+ {
+ "name":"杜集区",
+ "code":"340602"
+ },
+ {
+ "name":"相山区",
+ "code":"340603"
+ },
+ {
+ "name":"烈山区",
+ "code":"340604"
+ },
+ {
+ "name":"濉溪县",
+ "code":"340621"
+ }
+ ]
+ },
+ {
+ "name":"铜陵市",
+ "code":"340700",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"340701"
+ },
+ {
+ "name":"铜官山区",
+ "code":"340702"
+ },
+ {
+ "name":"狮子山区",
+ "code":"340703"
+ },
+ {
+ "name":"郊区",
+ "code":"340711"
+ },
+ {
+ "name":"铜陵县",
+ "code":"340721"
+ }
+ ]
+ },
+ {
+ "name":"安庆市",
+ "code":"340800",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"340801"
+ },
+ {
+ "name":"迎江区",
+ "code":"340802"
+ },
+ {
+ "name":"大观区",
+ "code":"340803"
+ },
+ {
+ "name":"宜秀区",
+ "code":"340811"
+ },
+ {
+ "name":"怀宁县",
+ "code":"340822"
+ },
+ {
+ "name":"枞阳县",
+ "code":"340823"
+ },
+ {
+ "name":"潜山县",
+ "code":"340824"
+ },
+ {
+ "name":"太湖县",
+ "code":"340825"
+ },
+ {
+ "name":"宿松县",
+ "code":"340826"
+ },
+ {
+ "name":"望江县",
+ "code":"340827"
+ },
+ {
+ "name":"岳西县",
+ "code":"340828"
+ },
+ {
+ "name":"桐城市",
+ "code":"340881"
+ }
+ ]
+ },
+ {
+ "name":"黄山市",
+ "code":"341000",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"341001"
+ },
+ {
+ "name":"屯溪区",
+ "code":"341002"
+ },
+ {
+ "name":"黄山区",
+ "code":"341003"
+ },
+ {
+ "name":"徽州区",
+ "code":"341004"
+ },
+ {
+ "name":"歙县",
+ "code":"341021"
+ },
+ {
+ "name":"休宁县",
+ "code":"341022"
+ },
+ {
+ "name":"黟县",
+ "code":"341023"
+ },
+ {
+ "name":"祁门县",
+ "code":"341024"
+ }
+ ]
+ },
+ {
+ "name":"滁州市",
+ "code":"341100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"341101"
+ },
+ {
+ "name":"琅琊区",
+ "code":"341102"
+ },
+ {
+ "name":"南谯区",
+ "code":"341103"
+ },
+ {
+ "name":"来安县",
+ "code":"341122"
+ },
+ {
+ "name":"全椒县",
+ "code":"341124"
+ },
+ {
+ "name":"定远县",
+ "code":"341125"
+ },
+ {
+ "name":"凤阳县",
+ "code":"341126"
+ },
+ {
+ "name":"天长市",
+ "code":"341181"
+ },
+ {
+ "name":"明光市",
+ "code":"341182"
+ }
+ ]
+ },
+ {
+ "name":"阜阳市",
+ "code":"341200",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"341201"
+ },
+ {
+ "name":"颍州区",
+ "code":"341202"
+ },
+ {
+ "name":"颍东区",
+ "code":"341203"
+ },
+ {
+ "name":"颍泉区",
+ "code":"341204"
+ },
+ {
+ "name":"临泉县",
+ "code":"341221"
+ },
+ {
+ "name":"太和县",
+ "code":"341222"
+ },
+ {
+ "name":"阜南县",
+ "code":"341225"
+ },
+ {
+ "name":"颍上县",
+ "code":"341226"
+ },
+ {
+ "name":"界首市",
+ "code":"341282"
+ }
+ ]
+ },
+ {
+ "name":"宿州市",
+ "code":"341300",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"341301"
+ },
+ {
+ "name":"埇桥区",
+ "code":"341302"
+ },
+ {
+ "name":"砀山县",
+ "code":"341321"
+ },
+ {
+ "name":"萧县",
+ "code":"341322"
+ },
+ {
+ "name":"灵璧县",
+ "code":"341323"
+ },
+ {
+ "name":"泗县",
+ "code":"341324"
+ }
+ ]
+ },
+ {
+ "name":"六安市",
+ "code":"341500",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"341501"
+ },
+ {
+ "name":"金安区",
+ "code":"341502"
+ },
+ {
+ "name":"裕安区",
+ "code":"341503"
+ },
+ {
+ "name":"寿县",
+ "code":"341521"
+ },
+ {
+ "name":"霍邱县",
+ "code":"341522"
+ },
+ {
+ "name":"舒城县",
+ "code":"341523"
+ },
+ {
+ "name":"金寨县",
+ "code":"341524"
+ },
+ {
+ "name":"霍山县",
+ "code":"341525"
+ }
+ ]
+ },
+ {
+ "name":"亳州市",
+ "code":"341600",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"341601"
+ },
+ {
+ "name":"谯城区",
+ "code":"341602"
+ },
+ {
+ "name":"涡阳县",
+ "code":"341621"
+ },
+ {
+ "name":"蒙城县",
+ "code":"341622"
+ },
+ {
+ "name":"利辛县",
+ "code":"341623"
+ }
+ ]
+ },
+ {
+ "name":"池州市",
+ "code":"341700",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"341701"
+ },
+ {
+ "name":"贵池区",
+ "code":"341702"
+ },
+ {
+ "name":"东至县",
+ "code":"341721"
+ },
+ {
+ "name":"石台县",
+ "code":"341722"
+ },
+ {
+ "name":"青阳县",
+ "code":"341723"
+ }
+ ]
+ },
+ {
+ "name":"宣城市",
+ "code":"341800",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"341801"
+ },
+ {
+ "name":"宣州区",
+ "code":"341802"
+ },
+ {
+ "name":"郎溪县",
+ "code":"341821"
+ },
+ {
+ "name":"广德县",
+ "code":"341822"
+ },
+ {
+ "name":"泾县",
+ "code":"341823"
+ },
+ {
+ "name":"绩溪县",
+ "code":"341824"
+ },
+ {
+ "name":"旌德县",
+ "code":"341825"
+ },
+ {
+ "name":"宁国市",
+ "code":"341881"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name":"福建省",
+ "code":"350000",
+ "sub":[
+ {
+ "name":"福州市",
+ "code":"350100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"350101"
+ },
+ {
+ "name":"鼓楼区",
+ "code":"350102"
+ },
+ {
+ "name":"台江区",
+ "code":"350103"
+ },
+ {
+ "name":"仓山区",
+ "code":"350104"
+ },
+ {
+ "name":"马尾区",
+ "code":"350105"
+ },
+ {
+ "name":"晋安区",
+ "code":"350111"
+ },
+ {
+ "name":"闽侯县",
+ "code":"350121"
+ },
+ {
+ "name":"连江县",
+ "code":"350122"
+ },
+ {
+ "name":"罗源县",
+ "code":"350123"
+ },
+ {
+ "name":"闽清县",
+ "code":"350124"
+ },
+ {
+ "name":"永泰县",
+ "code":"350125"
+ },
+ {
+ "name":"平潭县",
+ "code":"350128"
+ },
+ {
+ "name":"福清市",
+ "code":"350181"
+ },
+ {
+ "name":"长乐市",
+ "code":"350182"
+ }
+ ]
+ },
+ {
+ "name":"厦门市",
+ "code":"350200",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"350201"
+ },
+ {
+ "name":"思明区",
+ "code":"350203"
+ },
+ {
+ "name":"海沧区",
+ "code":"350205"
+ },
+ {
+ "name":"湖里区",
+ "code":"350206"
+ },
+ {
+ "name":"集美区",
+ "code":"350211"
+ },
+ {
+ "name":"同安区",
+ "code":"350212"
+ },
+ {
+ "name":"翔安区",
+ "code":"350213"
+ }
+ ]
+ },
+ {
+ "name":"莆田市",
+ "code":"350300",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"350301"
+ },
+ {
+ "name":"城厢区",
+ "code":"350302"
+ },
+ {
+ "name":"涵江区",
+ "code":"350303"
+ },
+ {
+ "name":"荔城区",
+ "code":"350304"
+ },
+ {
+ "name":"秀屿区",
+ "code":"350305"
+ },
+ {
+ "name":"仙游县",
+ "code":"350322"
+ }
+ ]
+ },
+ {
+ "name":"三明市",
+ "code":"350400",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"350401"
+ },
+ {
+ "name":"梅列区",
+ "code":"350402"
+ },
+ {
+ "name":"三元区",
+ "code":"350403"
+ },
+ {
+ "name":"明溪县",
+ "code":"350421"
+ },
+ {
+ "name":"清流县",
+ "code":"350423"
+ },
+ {
+ "name":"宁化县",
+ "code":"350424"
+ },
+ {
+ "name":"大田县",
+ "code":"350425"
+ },
+ {
+ "name":"尤溪县",
+ "code":"350426"
+ },
+ {
+ "name":"沙县",
+ "code":"350427"
+ },
+ {
+ "name":"将乐县",
+ "code":"350428"
+ },
+ {
+ "name":"泰宁县",
+ "code":"350429"
+ },
+ {
+ "name":"建宁县",
+ "code":"350430"
+ },
+ {
+ "name":"永安市",
+ "code":"350481"
+ }
+ ]
+ },
+ {
+ "name":"泉州市",
+ "code":"350500",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"350501"
+ },
+ {
+ "name":"鲤城区",
+ "code":"350502"
+ },
+ {
+ "name":"丰泽区",
+ "code":"350503"
+ },
+ {
+ "name":"洛江区",
+ "code":"350504"
+ },
+ {
+ "name":"泉港区",
+ "code":"350505"
+ },
+ {
+ "name":"惠安县",
+ "code":"350521"
+ },
+ {
+ "name":"安溪县",
+ "code":"350524"
+ },
+ {
+ "name":"永春县",
+ "code":"350525"
+ },
+ {
+ "name":"德化县",
+ "code":"350526"
+ },
+ {
+ "name":"金门县",
+ "code":"350527"
+ },
+ {
+ "name":"石狮市",
+ "code":"350581"
+ },
+ {
+ "name":"晋江市",
+ "code":"350582"
+ },
+ {
+ "name":"南安市",
+ "code":"350583"
+ }
+ ]
+ },
+ {
+ "name":"漳州市",
+ "code":"350600",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"350601"
+ },
+ {
+ "name":"芗城区",
+ "code":"350602"
+ },
+ {
+ "name":"龙文区",
+ "code":"350603"
+ },
+ {
+ "name":"云霄县",
+ "code":"350622"
+ },
+ {
+ "name":"漳浦县",
+ "code":"350623"
+ },
+ {
+ "name":"诏安县",
+ "code":"350624"
+ },
+ {
+ "name":"长泰县",
+ "code":"350625"
+ },
+ {
+ "name":"东山县",
+ "code":"350626"
+ },
+ {
+ "name":"南靖县",
+ "code":"350627"
+ },
+ {
+ "name":"平和县",
+ "code":"350628"
+ },
+ {
+ "name":"华安县",
+ "code":"350629"
+ },
+ {
+ "name":"龙海市",
+ "code":"350681"
+ }
+ ]
+ },
+ {
+ "name":"南平市",
+ "code":"350700",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"350701"
+ },
+ {
+ "name":"延平区",
+ "code":"350702"
+ },
+ {
+ "name":"建阳区",
+ "code":"350703"
+ },
+ {
+ "name":"顺昌县",
+ "code":"350721"
+ },
+ {
+ "name":"浦城县",
+ "code":"350722"
+ },
+ {
+ "name":"光泽县",
+ "code":"350723"
+ },
+ {
+ "name":"松溪县",
+ "code":"350724"
+ },
+ {
+ "name":"政和县",
+ "code":"350725"
+ },
+ {
+ "name":"邵武市",
+ "code":"350781"
+ },
+ {
+ "name":"武夷山市",
+ "code":"350782"
+ },
+ {
+ "name":"建瓯市",
+ "code":"350783"
+ }
+ ]
+ },
+ {
+ "name":"龙岩市",
+ "code":"350800",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"350801"
+ },
+ {
+ "name":"新罗区",
+ "code":"350802"
+ },
+ {
+ "name":"永定区",
+ "code":"350803"
+ },
+ {
+ "name":"长汀县",
+ "code":"350821"
+ },
+ {
+ "name":"上杭县",
+ "code":"350823"
+ },
+ {
+ "name":"武平县",
+ "code":"350824"
+ },
+ {
+ "name":"连城县",
+ "code":"350825"
+ },
+ {
+ "name":"漳平市",
+ "code":"350881"
+ }
+ ]
+ },
+ {
+ "name":"宁德市",
+ "code":"350900",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"350901"
+ },
+ {
+ "name":"蕉城区",
+ "code":"350902"
+ },
+ {
+ "name":"霞浦县",
+ "code":"350921"
+ },
+ {
+ "name":"古田县",
+ "code":"350922"
+ },
+ {
+ "name":"屏南县",
+ "code":"350923"
+ },
+ {
+ "name":"寿宁县",
+ "code":"350924"
+ },
+ {
+ "name":"周宁县",
+ "code":"350925"
+ },
+ {
+ "name":"柘荣县",
+ "code":"350926"
+ },
+ {
+ "name":"福安市",
+ "code":"350981"
+ },
+ {
+ "name":"福鼎市",
+ "code":"350982"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name":"江西省",
+ "code":"360000",
+ "sub":[
+ {
+ "name":"南昌市",
+ "code":"360100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"360101"
+ },
+ {
+ "name":"东湖区",
+ "code":"360102"
+ },
+ {
+ "name":"西湖区",
+ "code":"360103"
+ },
+ {
+ "name":"青云谱区",
+ "code":"360104"
+ },
+ {
+ "name":"湾里区",
+ "code":"360105"
+ },
+ {
+ "name":"青山湖区",
+ "code":"360111"
+ },
+ {
+ "name":"南昌县",
+ "code":"360121"
+ },
+ {
+ "name":"新建县",
+ "code":"360122"
+ },
+ {
+ "name":"安义县",
+ "code":"360123"
+ },
+ {
+ "name":"进贤县",
+ "code":"360124"
+ }
+ ]
+ },
+ {
+ "name":"景德镇市",
+ "code":"360200",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"360201"
+ },
+ {
+ "name":"昌江区",
+ "code":"360202"
+ },
+ {
+ "name":"珠山区",
+ "code":"360203"
+ },
+ {
+ "name":"浮梁县",
+ "code":"360222"
+ },
+ {
+ "name":"乐平市",
+ "code":"360281"
+ }
+ ]
+ },
+ {
+ "name":"萍乡市",
+ "code":"360300",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"360301"
+ },
+ {
+ "name":"安源区",
+ "code":"360302"
+ },
+ {
+ "name":"湘东区",
+ "code":"360313"
+ },
+ {
+ "name":"莲花县",
+ "code":"360321"
+ },
+ {
+ "name":"上栗县",
+ "code":"360322"
+ },
+ {
+ "name":"芦溪县",
+ "code":"360323"
+ }
+ ]
+ },
+ {
+ "name":"九江市",
+ "code":"360400",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"360401"
+ },
+ {
+ "name":"庐山区",
+ "code":"360402"
+ },
+ {
+ "name":"浔阳区",
+ "code":"360403"
+ },
+ {
+ "name":"九江县",
+ "code":"360421"
+ },
+ {
+ "name":"武宁县",
+ "code":"360423"
+ },
+ {
+ "name":"修水县",
+ "code":"360424"
+ },
+ {
+ "name":"永修县",
+ "code":"360425"
+ },
+ {
+ "name":"德安县",
+ "code":"360426"
+ },
+ {
+ "name":"星子县",
+ "code":"360427"
+ },
+ {
+ "name":"都昌县",
+ "code":"360428"
+ },
+ {
+ "name":"湖口县",
+ "code":"360429"
+ },
+ {
+ "name":"彭泽县",
+ "code":"360430"
+ },
+ {
+ "name":"瑞昌市",
+ "code":"360481"
+ },
+ {
+ "name":"共青城市",
+ "code":"360482"
+ }
+ ]
+ },
+ {
+ "name":"新余市",
+ "code":"360500",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"360501"
+ },
+ {
+ "name":"渝水区",
+ "code":"360502"
+ },
+ {
+ "name":"分宜县",
+ "code":"360521"
+ }
+ ]
+ },
+ {
+ "name":"鹰潭市",
+ "code":"360600",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"360601"
+ },
+ {
+ "name":"月湖区",
+ "code":"360602"
+ },
+ {
+ "name":"余江县",
+ "code":"360622"
+ },
+ {
+ "name":"贵溪市",
+ "code":"360681"
+ }
+ ]
+ },
+ {
+ "name":"赣州市",
+ "code":"360700",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"360701"
+ },
+ {
+ "name":"章贡区",
+ "code":"360702"
+ },
+ {
+ "name":"南康区",
+ "code":"360703"
+ },
+ {
+ "name":"赣县",
+ "code":"360721"
+ },
+ {
+ "name":"信丰县",
+ "code":"360722"
+ },
+ {
+ "name":"大余县",
+ "code":"360723"
+ },
+ {
+ "name":"上犹县",
+ "code":"360724"
+ },
+ {
+ "name":"崇义县",
+ "code":"360725"
+ },
+ {
+ "name":"安远县",
+ "code":"360726"
+ },
+ {
+ "name":"龙南县",
+ "code":"360727"
+ },
+ {
+ "name":"定南县",
+ "code":"360728"
+ },
+ {
+ "name":"全南县",
+ "code":"360729"
+ },
+ {
+ "name":"宁都县",
+ "code":"360730"
+ },
+ {
+ "name":"于都县",
+ "code":"360731"
+ },
+ {
+ "name":"兴国县",
+ "code":"360732"
+ },
+ {
+ "name":"会昌县",
+ "code":"360733"
+ },
+ {
+ "name":"寻乌县",
+ "code":"360734"
+ },
+ {
+ "name":"石城县",
+ "code":"360735"
+ },
+ {
+ "name":"瑞金市",
+ "code":"360781"
+ }
+ ]
+ },
+ {
+ "name":"吉安市",
+ "code":"360800",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"360801"
+ },
+ {
+ "name":"吉州区",
+ "code":"360802"
+ },
+ {
+ "name":"青原区",
+ "code":"360803"
+ },
+ {
+ "name":"吉安县",
+ "code":"360821"
+ },
+ {
+ "name":"吉水县",
+ "code":"360822"
+ },
+ {
+ "name":"峡江县",
+ "code":"360823"
+ },
+ {
+ "name":"新干县",
+ "code":"360824"
+ },
+ {
+ "name":"永丰县",
+ "code":"360825"
+ },
+ {
+ "name":"泰和县",
+ "code":"360826"
+ },
+ {
+ "name":"遂川县",
+ "code":"360827"
+ },
+ {
+ "name":"万安县",
+ "code":"360828"
+ },
+ {
+ "name":"安福县",
+ "code":"360829"
+ },
+ {
+ "name":"永新县",
+ "code":"360830"
+ },
+ {
+ "name":"井冈山市",
+ "code":"360881"
+ }
+ ]
+ },
+ {
+ "name":"宜春市",
+ "code":"360900",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"360901"
+ },
+ {
+ "name":"袁州区",
+ "code":"360902"
+ },
+ {
+ "name":"奉新县",
+ "code":"360921"
+ },
+ {
+ "name":"万载县",
+ "code":"360922"
+ },
+ {
+ "name":"上高县",
+ "code":"360923"
+ },
+ {
+ "name":"宜丰县",
+ "code":"360924"
+ },
+ {
+ "name":"靖安县",
+ "code":"360925"
+ },
+ {
+ "name":"铜鼓县",
+ "code":"360926"
+ },
+ {
+ "name":"丰城市",
+ "code":"360981"
+ },
+ {
+ "name":"樟树市",
+ "code":"360982"
+ },
+ {
+ "name":"高安市",
+ "code":"360983"
+ }
+ ]
+ },
+ {
+ "name":"抚州市",
+ "code":"361000",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"361001"
+ },
+ {
+ "name":"临川区",
+ "code":"361002"
+ },
+ {
+ "name":"南城县",
+ "code":"361021"
+ },
+ {
+ "name":"黎川县",
+ "code":"361022"
+ },
+ {
+ "name":"南丰县",
+ "code":"361023"
+ },
+ {
+ "name":"崇仁县",
+ "code":"361024"
+ },
+ {
+ "name":"乐安县",
+ "code":"361025"
+ },
+ {
+ "name":"宜黄县",
+ "code":"361026"
+ },
+ {
+ "name":"金溪县",
+ "code":"361027"
+ },
+ {
+ "name":"资溪县",
+ "code":"361028"
+ },
+ {
+ "name":"东乡县",
+ "code":"361029"
+ },
+ {
+ "name":"广昌县",
+ "code":"361030"
+ }
+ ]
+ },
+ {
+ "name":"上饶市",
+ "code":"361100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"361101"
+ },
+ {
+ "name":"信州区",
+ "code":"361102"
+ },
+ {
+ "name":"上饶县",
+ "code":"361121"
+ },
+ {
+ "name":"广丰县",
+ "code":"361122"
+ },
+ {
+ "name":"玉山县",
+ "code":"361123"
+ },
+ {
+ "name":"铅山县",
+ "code":"361124"
+ },
+ {
+ "name":"横峰县",
+ "code":"361125"
+ },
+ {
+ "name":"弋阳县",
+ "code":"361126"
+ },
+ {
+ "name":"余干县",
+ "code":"361127"
+ },
+ {
+ "name":"鄱阳县",
+ "code":"361128"
+ },
+ {
+ "name":"万年县",
+ "code":"361129"
+ },
+ {
+ "name":"婺源县",
+ "code":"361130"
+ },
+ {
+ "name":"德兴市",
+ "code":"361181"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name":"山东省",
+ "code":"370000",
+ "sub":[
+ {
+ "name":"济南市",
+ "code":"370100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"370101"
+ },
+ {
+ "name":"历下区",
+ "code":"370102"
+ },
+ {
+ "name":"市中区",
+ "code":"370103"
+ },
+ {
+ "name":"槐荫区",
+ "code":"370104"
+ },
+ {
+ "name":"天桥区",
+ "code":"370105"
+ },
+ {
+ "name":"历城区",
+ "code":"370112"
+ },
+ {
+ "name":"长清区",
+ "code":"370113"
+ },
+ {
+ "name":"平阴县",
+ "code":"370124"
+ },
+ {
+ "name":"济阳县",
+ "code":"370125"
+ },
+ {
+ "name":"商河县",
+ "code":"370126"
+ },
+ {
+ "name":"章丘市",
+ "code":"370181"
+ }
+ ]
+ },
+ {
+ "name":"青岛市",
+ "code":"370200",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"370201"
+ },
+ {
+ "name":"市南区",
+ "code":"370202"
+ },
+ {
+ "name":"市北区",
+ "code":"370203"
+ },
+ {
+ "name":"黄岛区",
+ "code":"370211"
+ },
+ {
+ "name":"崂山区",
+ "code":"370212"
+ },
+ {
+ "name":"李沧区",
+ "code":"370213"
+ },
+ {
+ "name":"城阳区",
+ "code":"370214"
+ },
+ {
+ "name":"胶州市",
+ "code":"370281"
+ },
+ {
+ "name":"即墨市",
+ "code":"370282"
+ },
+ {
+ "name":"平度市",
+ "code":"370283"
+ },
+ {
+ "name":"莱西市",
+ "code":"370285"
+ }
+ ]
+ },
+ {
+ "name":"淄博市",
+ "code":"370300",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"370301"
+ },
+ {
+ "name":"淄川区",
+ "code":"370302"
+ },
+ {
+ "name":"张店区",
+ "code":"370303"
+ },
+ {
+ "name":"博山区",
+ "code":"370304"
+ },
+ {
+ "name":"临淄区",
+ "code":"370305"
+ },
+ {
+ "name":"周村区",
+ "code":"370306"
+ },
+ {
+ "name":"桓台县",
+ "code":"370321"
+ },
+ {
+ "name":"高青县",
+ "code":"370322"
+ },
+ {
+ "name":"沂源县",
+ "code":"370323"
+ }
+ ]
+ },
+ {
+ "name":"枣庄市",
+ "code":"370400",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"370401"
+ },
+ {
+ "name":"市中区",
+ "code":"370402"
+ },
+ {
+ "name":"薛城区",
+ "code":"370403"
+ },
+ {
+ "name":"峄城区",
+ "code":"370404"
+ },
+ {
+ "name":"台儿庄区",
+ "code":"370405"
+ },
+ {
+ "name":"山亭区",
+ "code":"370406"
+ },
+ {
+ "name":"滕州市",
+ "code":"370481"
+ }
+ ]
+ },
+ {
+ "name":"东营市",
+ "code":"370500",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"370501"
+ },
+ {
+ "name":"东营区",
+ "code":"370502"
+ },
+ {
+ "name":"河口区",
+ "code":"370503"
+ },
+ {
+ "name":"垦利县",
+ "code":"370521"
+ },
+ {
+ "name":"利津县",
+ "code":"370522"
+ },
+ {
+ "name":"广饶县",
+ "code":"370523"
+ }
+ ]
+ },
+ {
+ "name":"烟台市",
+ "code":"370600",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"370601"
+ },
+ {
+ "name":"芝罘区",
+ "code":"370602"
+ },
+ {
+ "name":"福山区",
+ "code":"370611"
+ },
+ {
+ "name":"牟平区",
+ "code":"370612"
+ },
+ {
+ "name":"莱山区",
+ "code":"370613"
+ },
+ {
+ "name":"长岛县",
+ "code":"370634"
+ },
+ {
+ "name":"龙口市",
+ "code":"370681"
+ },
+ {
+ "name":"莱阳市",
+ "code":"370682"
+ },
+ {
+ "name":"莱州市",
+ "code":"370683"
+ },
+ {
+ "name":"蓬莱市",
+ "code":"370684"
+ },
+ {
+ "name":"招远市",
+ "code":"370685"
+ },
+ {
+ "name":"栖霞市",
+ "code":"370686"
+ },
+ {
+ "name":"海阳市",
+ "code":"370687"
+ }
+ ]
+ },
+ {
+ "name":"潍坊市",
+ "code":"370700",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"370701"
+ },
+ {
+ "name":"潍城区",
+ "code":"370702"
+ },
+ {
+ "name":"寒亭区",
+ "code":"370703"
+ },
+ {
+ "name":"坊子区",
+ "code":"370704"
+ },
+ {
+ "name":"奎文区",
+ "code":"370705"
+ },
+ {
+ "name":"临朐县",
+ "code":"370724"
+ },
+ {
+ "name":"昌乐县",
+ "code":"370725"
+ },
+ {
+ "name":"青州市",
+ "code":"370781"
+ },
+ {
+ "name":"诸城市",
+ "code":"370782"
+ },
+ {
+ "name":"寿光市",
+ "code":"370783"
+ },
+ {
+ "name":"安丘市",
+ "code":"370784"
+ },
+ {
+ "name":"高密市",
+ "code":"370785"
+ },
+ {
+ "name":"昌邑市",
+ "code":"370786"
+ }
+ ]
+ },
+ {
+ "name":"济宁市",
+ "code":"370800",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"370801"
+ },
+ {
+ "name":"任城区",
+ "code":"370811"
+ },
+ {
+ "name":"兖州区",
+ "code":"370812"
+ },
+ {
+ "name":"微山县",
+ "code":"370826"
+ },
+ {
+ "name":"鱼台县",
+ "code":"370827"
+ },
+ {
+ "name":"金乡县",
+ "code":"370828"
+ },
+ {
+ "name":"嘉祥县",
+ "code":"370829"
+ },
+ {
+ "name":"汶上县",
+ "code":"370830"
+ },
+ {
+ "name":"泗水县",
+ "code":"370831"
+ },
+ {
+ "name":"梁山县",
+ "code":"370832"
+ },
+ {
+ "name":"曲阜市",
+ "code":"370881"
+ },
+ {
+ "name":"邹城市",
+ "code":"370883"
+ }
+ ]
+ },
+ {
+ "name":"泰安市",
+ "code":"370900",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"370901"
+ },
+ {
+ "name":"泰山区",
+ "code":"370902"
+ },
+ {
+ "name":"岱岳区",
+ "code":"370911"
+ },
+ {
+ "name":"宁阳县",
+ "code":"370921"
+ },
+ {
+ "name":"东平县",
+ "code":"370923"
+ },
+ {
+ "name":"新泰市",
+ "code":"370982"
+ },
+ {
+ "name":"肥城市",
+ "code":"370983"
+ }
+ ]
+ },
+ {
+ "name":"威海市",
+ "code":"371000",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"371001"
+ },
+ {
+ "name":"环翠区",
+ "code":"371002"
+ },
+ {
+ "name":"文登市",
+ "code":"371081"
+ },
+ {
+ "name":"荣成市",
+ "code":"371082"
+ },
+ {
+ "name":"乳山市",
+ "code":"371083"
+ }
+ ]
+ },
+ {
+ "name":"日照市",
+ "code":"371100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"371101"
+ },
+ {
+ "name":"东港区",
+ "code":"371102"
+ },
+ {
+ "name":"岚山区",
+ "code":"371103"
+ },
+ {
+ "name":"五莲县",
+ "code":"371121"
+ },
+ {
+ "name":"莒县",
+ "code":"371122"
+ }
+ ]
+ },
+ {
+ "name":"莱芜市",
+ "code":"371200",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"371201"
+ },
+ {
+ "name":"莱城区",
+ "code":"371202"
+ },
+ {
+ "name":"钢城区",
+ "code":"371203"
+ }
+ ]
+ },
+ {
+ "name":"临沂市",
+ "code":"371300",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"371301"
+ },
+ {
+ "name":"兰山区",
+ "code":"371302"
+ },
+ {
+ "name":"罗庄区",
+ "code":"371311"
+ },
+ {
+ "name":"河东区",
+ "code":"371312"
+ },
+ {
+ "name":"沂南县",
+ "code":"371321"
+ },
+ {
+ "name":"郯城县",
+ "code":"371322"
+ },
+ {
+ "name":"沂水县",
+ "code":"371323"
+ },
+ {
+ "name":"兰陵县",
+ "code":"371324"
+ },
+ {
+ "name":"费县",
+ "code":"371325"
+ },
+ {
+ "name":"平邑县",
+ "code":"371326"
+ },
+ {
+ "name":"莒南县",
+ "code":"371327"
+ },
+ {
+ "name":"蒙阴县",
+ "code":"371328"
+ },
+ {
+ "name":"临沭县",
+ "code":"371329"
+ }
+ ]
+ },
+ {
+ "name":"德州市",
+ "code":"371400",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"371401"
+ },
+ {
+ "name":"德城区",
+ "code":"371402"
+ },
+ {
+ "name":"陵城区",
+ "code":"371403"
+ },
+ {
+ "name":"宁津县",
+ "code":"371422"
+ },
+ {
+ "name":"庆云县",
+ "code":"371423"
+ },
+ {
+ "name":"临邑县",
+ "code":"371424"
+ },
+ {
+ "name":"齐河县",
+ "code":"371425"
+ },
+ {
+ "name":"平原县",
+ "code":"371426"
+ },
+ {
+ "name":"夏津县",
+ "code":"371427"
+ },
+ {
+ "name":"武城县",
+ "code":"371428"
+ },
+ {
+ "name":"乐陵市",
+ "code":"371481"
+ },
+ {
+ "name":"禹城市",
+ "code":"371482"
+ }
+ ]
+ },
+ {
+ "name":"聊城市",
+ "code":"371500",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"371501"
+ },
+ {
+ "name":"东昌府区",
+ "code":"371502"
+ },
+ {
+ "name":"阳谷县",
+ "code":"371521"
+ },
+ {
+ "name":"莘县",
+ "code":"371522"
+ },
+ {
+ "name":"茌平县",
+ "code":"371523"
+ },
+ {
+ "name":"东阿县",
+ "code":"371524"
+ },
+ {
+ "name":"冠县",
+ "code":"371525"
+ },
+ {
+ "name":"高唐县",
+ "code":"371526"
+ },
+ {
+ "name":"临清市",
+ "code":"371581"
+ }
+ ]
+ },
+ {
+ "name":"滨州市",
+ "code":"371600",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"371601"
+ },
+ {
+ "name":"滨城区",
+ "code":"371602"
+ },
+ {
+ "name":"沾化区",
+ "code":"371603"
+ },
+ {
+ "name":"惠民县",
+ "code":"371621"
+ },
+ {
+ "name":"阳信县",
+ "code":"371622"
+ },
+ {
+ "name":"无棣县",
+ "code":"371623"
+ },
+ {
+ "name":"博兴县",
+ "code":"371625"
+ },
+ {
+ "name":"邹平县",
+ "code":"371626"
+ }
+ ]
+ },
+ {
+ "name":"菏泽市",
+ "code":"371700",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"371701"
+ },
+ {
+ "name":"牡丹区",
+ "code":"371702"
+ },
+ {
+ "name":"曹县",
+ "code":"371721"
+ },
+ {
+ "name":"单县",
+ "code":"371722"
+ },
+ {
+ "name":"成武县",
+ "code":"371723"
+ },
+ {
+ "name":"巨野县",
+ "code":"371724"
+ },
+ {
+ "name":"郓城县",
+ "code":"371725"
+ },
+ {
+ "name":"鄄城县",
+ "code":"371726"
+ },
+ {
+ "name":"定陶县",
+ "code":"371727"
+ },
+ {
+ "name":"东明县",
+ "code":"371728"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name":"河南省",
+ "code":"410000",
+ "sub":[
+ {
+ "name":"郑州市",
+ "code":"410100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"410101"
+ },
+ {
+ "name":"中原区",
+ "code":"410102"
+ },
+ {
+ "name":"二七区",
+ "code":"410103"
+ },
+ {
+ "name":"管城回族区",
+ "code":"410104"
+ },
+ {
+ "name":"金水区",
+ "code":"410105"
+ },
+ {
+ "name":"上街区",
+ "code":"410106"
+ },
+ {
+ "name":"惠济区",
+ "code":"410108"
+ },
+ {
+ "name":"中牟县",
+ "code":"410122"
+ },
+ {
+ "name":"巩义市",
+ "code":"410181"
+ },
+ {
+ "name":"荥阳市",
+ "code":"410182"
+ },
+ {
+ "name":"新密市",
+ "code":"410183"
+ },
+ {
+ "name":"新郑市",
+ "code":"410184"
+ },
+ {
+ "name":"登封市",
+ "code":"410185"
+ }
+ ]
+ },
+ {
+ "name":"开封市",
+ "code":"410200",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"410201"
+ },
+ {
+ "name":"龙亭区",
+ "code":"410202"
+ },
+ {
+ "name":"顺河回族区",
+ "code":"410203"
+ },
+ {
+ "name":"鼓楼区",
+ "code":"410204"
+ },
+ {
+ "name":"禹王台区",
+ "code":"410205"
+ },
+ {
+ "name":"祥符区",
+ "code":"410212"
+ },
+ {
+ "name":"杞县",
+ "code":"410221"
+ },
+ {
+ "name":"通许县",
+ "code":"410222"
+ },
+ {
+ "name":"尉氏县",
+ "code":"410223"
+ },
+ {
+ "name":"兰考县",
+ "code":"410225"
+ }
+ ]
+ },
+ {
+ "name":"洛阳市",
+ "code":"410300",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"410301"
+ },
+ {
+ "name":"老城区",
+ "code":"410302"
+ },
+ {
+ "name":"西工区",
+ "code":"410303"
+ },
+ {
+ "name":"瀍河回族区",
+ "code":"410304"
+ },
+ {
+ "name":"涧西区",
+ "code":"410305"
+ },
+ {
+ "name":"吉利区",
+ "code":"410306"
+ },
+ {
+ "name":"洛龙区",
+ "code":"410311"
+ },
+ {
+ "name":"孟津县",
+ "code":"410322"
+ },
+ {
+ "name":"新安县",
+ "code":"410323"
+ },
+ {
+ "name":"栾川县",
+ "code":"410324"
+ },
+ {
+ "name":"嵩县",
+ "code":"410325"
+ },
+ {
+ "name":"汝阳县",
+ "code":"410326"
+ },
+ {
+ "name":"宜阳县",
+ "code":"410327"
+ },
+ {
+ "name":"洛宁县",
+ "code":"410328"
+ },
+ {
+ "name":"伊川县",
+ "code":"410329"
+ },
+ {
+ "name":"偃师市",
+ "code":"410381"
+ }
+ ]
+ },
+ {
+ "name":"平顶山市",
+ "code":"410400",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"410401"
+ },
+ {
+ "name":"新华区",
+ "code":"410402"
+ },
+ {
+ "name":"卫东区",
+ "code":"410403"
+ },
+ {
+ "name":"石龙区",
+ "code":"410404"
+ },
+ {
+ "name":"湛河区",
+ "code":"410411"
+ },
+ {
+ "name":"宝丰县",
+ "code":"410421"
+ },
+ {
+ "name":"叶县",
+ "code":"410422"
+ },
+ {
+ "name":"鲁山县",
+ "code":"410423"
+ },
+ {
+ "name":"郏县",
+ "code":"410425"
+ },
+ {
+ "name":"舞钢市",
+ "code":"410481"
+ },
+ {
+ "name":"汝州市",
+ "code":"410482"
+ }
+ ]
+ },
+ {
+ "name":"安阳市",
+ "code":"410500",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"410501"
+ },
+ {
+ "name":"文峰区",
+ "code":"410502"
+ },
+ {
+ "name":"北关区",
+ "code":"410503"
+ },
+ {
+ "name":"殷都区",
+ "code":"410505"
+ },
+ {
+ "name":"龙安区",
+ "code":"410506"
+ },
+ {
+ "name":"安阳县",
+ "code":"410522"
+ },
+ {
+ "name":"汤阴县",
+ "code":"410523"
+ },
+ {
+ "name":"滑县",
+ "code":"410526"
+ },
+ {
+ "name":"内黄县",
+ "code":"410527"
+ },
+ {
+ "name":"林州市",
+ "code":"410581"
+ }
+ ]
+ },
+ {
+ "name":"鹤壁市",
+ "code":"410600",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"410601"
+ },
+ {
+ "name":"鹤山区",
+ "code":"410602"
+ },
+ {
+ "name":"山城区",
+ "code":"410603"
+ },
+ {
+ "name":"淇滨区",
+ "code":"410611"
+ },
+ {
+ "name":"浚县",
+ "code":"410621"
+ },
+ {
+ "name":"淇县",
+ "code":"410622"
+ }
+ ]
+ },
+ {
+ "name":"新乡市",
+ "code":"410700",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"410701"
+ },
+ {
+ "name":"红旗区",
+ "code":"410702"
+ },
+ {
+ "name":"卫滨区",
+ "code":"410703"
+ },
+ {
+ "name":"凤泉区",
+ "code":"410704"
+ },
+ {
+ "name":"牧野区",
+ "code":"410711"
+ },
+ {
+ "name":"新乡县",
+ "code":"410721"
+ },
+ {
+ "name":"获嘉县",
+ "code":"410724"
+ },
+ {
+ "name":"原阳县",
+ "code":"410725"
+ },
+ {
+ "name":"延津县",
+ "code":"410726"
+ },
+ {
+ "name":"封丘县",
+ "code":"410727"
+ },
+ {
+ "name":"长垣县",
+ "code":"410728"
+ },
+ {
+ "name":"卫辉市",
+ "code":"410781"
+ },
+ {
+ "name":"辉县市",
+ "code":"410782"
+ }
+ ]
+ },
+ {
+ "name":"焦作市",
+ "code":"410800",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"410801"
+ },
+ {
+ "name":"解放区",
+ "code":"410802"
+ },
+ {
+ "name":"中站区",
+ "code":"410803"
+ },
+ {
+ "name":"马村区",
+ "code":"410804"
+ },
+ {
+ "name":"山阳区",
+ "code":"410811"
+ },
+ {
+ "name":"修武县",
+ "code":"410821"
+ },
+ {
+ "name":"博爱县",
+ "code":"410822"
+ },
+ {
+ "name":"武陟县",
+ "code":"410823"
+ },
+ {
+ "name":"温县",
+ "code":"410825"
+ },
+ {
+ "name":"沁阳市",
+ "code":"410882"
+ },
+ {
+ "name":"孟州市",
+ "code":"410883"
+ }
+ ]
+ },
+ {
+ "name":"濮阳市",
+ "code":"410900",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"410901"
+ },
+ {
+ "name":"华龙区",
+ "code":"410902"
+ },
+ {
+ "name":"清丰县",
+ "code":"410922"
+ },
+ {
+ "name":"南乐县",
+ "code":"410923"
+ },
+ {
+ "name":"范县",
+ "code":"410926"
+ },
+ {
+ "name":"台前县",
+ "code":"410927"
+ },
+ {
+ "name":"濮阳县",
+ "code":"410928"
+ }
+ ]
+ },
+ {
+ "name":"许昌市",
+ "code":"411000",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"411001"
+ },
+ {
+ "name":"魏都区",
+ "code":"411002"
+ },
+ {
+ "name":"许昌县",
+ "code":"411023"
+ },
+ {
+ "name":"鄢陵县",
+ "code":"411024"
+ },
+ {
+ "name":"襄城县",
+ "code":"411025"
+ },
+ {
+ "name":"禹州市",
+ "code":"411081"
+ },
+ {
+ "name":"长葛市",
+ "code":"411082"
+ }
+ ]
+ },
+ {
+ "name":"漯河市",
+ "code":"411100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"411101"
+ },
+ {
+ "name":"源汇区",
+ "code":"411102"
+ },
+ {
+ "name":"郾城区",
+ "code":"411103"
+ },
+ {
+ "name":"召陵区",
+ "code":"411104"
+ },
+ {
+ "name":"舞阳县",
+ "code":"411121"
+ },
+ {
+ "name":"临颍县",
+ "code":"411122"
+ }
+ ]
+ },
+ {
+ "name":"三门峡市",
+ "code":"411200",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"411201"
+ },
+ {
+ "name":"湖滨区",
+ "code":"411202"
+ },
+ {
+ "name":"渑池县",
+ "code":"411221"
+ },
+ {
+ "name":"陕县",
+ "code":"411222"
+ },
+ {
+ "name":"卢氏县",
+ "code":"411224"
+ },
+ {
+ "name":"义马市",
+ "code":"411281"
+ },
+ {
+ "name":"灵宝市",
+ "code":"411282"
+ }
+ ]
+ },
+ {
+ "name":"南阳市",
+ "code":"411300",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"411301"
+ },
+ {
+ "name":"宛城区",
+ "code":"411302"
+ },
+ {
+ "name":"卧龙区",
+ "code":"411303"
+ },
+ {
+ "name":"南召县",
+ "code":"411321"
+ },
+ {
+ "name":"方城县",
+ "code":"411322"
+ },
+ {
+ "name":"西峡县",
+ "code":"411323"
+ },
+ {
+ "name":"镇平县",
+ "code":"411324"
+ },
+ {
+ "name":"内乡县",
+ "code":"411325"
+ },
+ {
+ "name":"淅川县",
+ "code":"411326"
+ },
+ {
+ "name":"社旗县",
+ "code":"411327"
+ },
+ {
+ "name":"唐河县",
+ "code":"411328"
+ },
+ {
+ "name":"新野县",
+ "code":"411329"
+ },
+ {
+ "name":"桐柏县",
+ "code":"411330"
+ },
+ {
+ "name":"邓州市",
+ "code":"411381"
+ }
+ ]
+ },
+ {
+ "name":"商丘市",
+ "code":"411400",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"411401"
+ },
+ {
+ "name":"梁园区",
+ "code":"411402"
+ },
+ {
+ "name":"睢阳区",
+ "code":"411403"
+ },
+ {
+ "name":"民权县",
+ "code":"411421"
+ },
+ {
+ "name":"睢县",
+ "code":"411422"
+ },
+ {
+ "name":"宁陵县",
+ "code":"411423"
+ },
+ {
+ "name":"柘城县",
+ "code":"411424"
+ },
+ {
+ "name":"虞城县",
+ "code":"411425"
+ },
+ {
+ "name":"夏邑县",
+ "code":"411426"
+ },
+ {
+ "name":"永城市",
+ "code":"411481"
+ }
+ ]
+ },
+ {
+ "name":"信阳市",
+ "code":"411500",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"411501"
+ },
+ {
+ "name":"浉河区",
+ "code":"411502"
+ },
+ {
+ "name":"平桥区",
+ "code":"411503"
+ },
+ {
+ "name":"罗山县",
+ "code":"411521"
+ },
+ {
+ "name":"光山县",
+ "code":"411522"
+ },
+ {
+ "name":"新县",
+ "code":"411523"
+ },
+ {
+ "name":"商城县",
+ "code":"411524"
+ },
+ {
+ "name":"固始县",
+ "code":"411525"
+ },
+ {
+ "name":"潢川县",
+ "code":"411526"
+ },
+ {
+ "name":"淮滨县",
+ "code":"411527"
+ },
+ {
+ "name":"息县",
+ "code":"411528"
+ }
+ ]
+ },
+ {
+ "name":"周口市",
+ "code":"411600",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"411601"
+ },
+ {
+ "name":"川汇区",
+ "code":"411602"
+ },
+ {
+ "name":"扶沟县",
+ "code":"411621"
+ },
+ {
+ "name":"西华县",
+ "code":"411622"
+ },
+ {
+ "name":"商水县",
+ "code":"411623"
+ },
+ {
+ "name":"沈丘县",
+ "code":"411624"
+ },
+ {
+ "name":"郸城县",
+ "code":"411625"
+ },
+ {
+ "name":"淮阳县",
+ "code":"411626"
+ },
+ {
+ "name":"太康县",
+ "code":"411627"
+ },
+ {
+ "name":"鹿邑县",
+ "code":"411628"
+ },
+ {
+ "name":"项城市",
+ "code":"411681"
+ }
+ ]
+ },
+ {
+ "name":"驻马店市",
+ "code":"411700",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"411701"
+ },
+ {
+ "name":"驿城区",
+ "code":"411702"
+ },
+ {
+ "name":"西平县",
+ "code":"411721"
+ },
+ {
+ "name":"上蔡县",
+ "code":"411722"
+ },
+ {
+ "name":"平舆县",
+ "code":"411723"
+ },
+ {
+ "name":"正阳县",
+ "code":"411724"
+ },
+ {
+ "name":"确山县",
+ "code":"411725"
+ },
+ {
+ "name":"泌阳县",
+ "code":"411726"
+ },
+ {
+ "name":"汝南县",
+ "code":"411727"
+ },
+ {
+ "name":"遂平县",
+ "code":"411728"
+ },
+ {
+ "name":"新蔡县",
+ "code":"411729"
+ }
+ ]
+ },
+ {
+ "name":"济源市",
+ "code":"419001"
+ }
+ ]
+ },
+ {
+ "name":"湖北省",
+ "code":"420000",
+ "sub":[
+ {
+ "name":"武汉市",
+ "code":"420100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"420101"
+ },
+ {
+ "name":"江岸区",
+ "code":"420102"
+ },
+ {
+ "name":"江汉区",
+ "code":"420103"
+ },
+ {
+ "name":"硚口区",
+ "code":"420104"
+ },
+ {
+ "name":"汉阳区",
+ "code":"420105"
+ },
+ {
+ "name":"武昌区",
+ "code":"420106"
+ },
+ {
+ "name":"青山区",
+ "code":"420107"
+ },
+ {
+ "name":"洪山区",
+ "code":"420111"
+ },
+ {
+ "name":"东西湖区",
+ "code":"420112"
+ },
+ {
+ "name":"汉南区",
+ "code":"420113"
+ },
+ {
+ "name":"蔡甸区",
+ "code":"420114"
+ },
+ {
+ "name":"江夏区",
+ "code":"420115"
+ },
+ {
+ "name":"黄陂区",
+ "code":"420116"
+ },
+ {
+ "name":"新洲区",
+ "code":"420117"
+ }
+ ]
+ },
+ {
+ "name":"黄石市",
+ "code":"420200",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"420201"
+ },
+ {
+ "name":"黄石港区",
+ "code":"420202"
+ },
+ {
+ "name":"西塞山区",
+ "code":"420203"
+ },
+ {
+ "name":"下陆区",
+ "code":"420204"
+ },
+ {
+ "name":"铁山区",
+ "code":"420205"
+ },
+ {
+ "name":"阳新县",
+ "code":"420222"
+ },
+ {
+ "name":"大冶市",
+ "code":"420281"
+ }
+ ]
+ },
+ {
+ "name":"十堰市",
+ "code":"420300",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"420301"
+ },
+ {
+ "name":"茅箭区",
+ "code":"420302"
+ },
+ {
+ "name":"张湾区",
+ "code":"420303"
+ },
+ {
+ "name":"郧阳区",
+ "code":"420304"
+ },
+ {
+ "name":"郧西县",
+ "code":"420322"
+ },
+ {
+ "name":"竹山县",
+ "code":"420323"
+ },
+ {
+ "name":"竹溪县",
+ "code":"420324"
+ },
+ {
+ "name":"房县",
+ "code":"420325"
+ },
+ {
+ "name":"丹江口市",
+ "code":"420381"
+ }
+ ]
+ },
+ {
+ "name":"宜昌市",
+ "code":"420500",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"420501"
+ },
+ {
+ "name":"西陵区",
+ "code":"420502"
+ },
+ {
+ "name":"伍家岗区",
+ "code":"420503"
+ },
+ {
+ "name":"点军区",
+ "code":"420504"
+ },
+ {
+ "name":"猇亭区",
+ "code":"420505"
+ },
+ {
+ "name":"夷陵区",
+ "code":"420506"
+ },
+ {
+ "name":"远安县",
+ "code":"420525"
+ },
+ {
+ "name":"兴山县",
+ "code":"420526"
+ },
+ {
+ "name":"秭归县",
+ "code":"420527"
+ },
+ {
+ "name":"长阳土家族自治县",
+ "code":"420528"
+ },
+ {
+ "name":"五峰土家族自治县",
+ "code":"420529"
+ },
+ {
+ "name":"宜都市",
+ "code":"420581"
+ },
+ {
+ "name":"当阳市",
+ "code":"420582"
+ },
+ {
+ "name":"枝江市",
+ "code":"420583"
+ }
+ ]
+ },
+ {
+ "name":"襄阳市",
+ "code":"420600",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"420601"
+ },
+ {
+ "name":"襄城区",
+ "code":"420602"
+ },
+ {
+ "name":"樊城区",
+ "code":"420606"
+ },
+ {
+ "name":"襄州区",
+ "code":"420607"
+ },
+ {
+ "name":"南漳县",
+ "code":"420624"
+ },
+ {
+ "name":"谷城县",
+ "code":"420625"
+ },
+ {
+ "name":"保康县",
+ "code":"420626"
+ },
+ {
+ "name":"老河口市",
+ "code":"420682"
+ },
+ {
+ "name":"枣阳市",
+ "code":"420683"
+ },
+ {
+ "name":"宜城市",
+ "code":"420684"
+ }
+ ]
+ },
+ {
+ "name":"鄂州市",
+ "code":"420700",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"420701"
+ },
+ {
+ "name":"梁子湖区",
+ "code":"420702"
+ },
+ {
+ "name":"华容区",
+ "code":"420703"
+ },
+ {
+ "name":"鄂城区",
+ "code":"420704"
+ }
+ ]
+ },
+ {
+ "name":"荆门市",
+ "code":"420800",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"420801"
+ },
+ {
+ "name":"东宝区",
+ "code":"420802"
+ },
+ {
+ "name":"掇刀区",
+ "code":"420804"
+ },
+ {
+ "name":"京山县",
+ "code":"420821"
+ },
+ {
+ "name":"沙洋县",
+ "code":"420822"
+ },
+ {
+ "name":"钟祥市",
+ "code":"420881"
+ }
+ ]
+ },
+ {
+ "name":"孝感市",
+ "code":"420900",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"420901"
+ },
+ {
+ "name":"孝南区",
+ "code":"420902"
+ },
+ {
+ "name":"孝昌县",
+ "code":"420921"
+ },
+ {
+ "name":"大悟县",
+ "code":"420922"
+ },
+ {
+ "name":"云梦县",
+ "code":"420923"
+ },
+ {
+ "name":"应城市",
+ "code":"420981"
+ },
+ {
+ "name":"安陆市",
+ "code":"420982"
+ },
+ {
+ "name":"汉川市",
+ "code":"420984"
+ }
+ ]
+ },
+ {
+ "name":"荆州市",
+ "code":"421000",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"421001"
+ },
+ {
+ "name":"沙市区",
+ "code":"421002"
+ },
+ {
+ "name":"荆州区",
+ "code":"421003"
+ },
+ {
+ "name":"公安县",
+ "code":"421022"
+ },
+ {
+ "name":"监利县",
+ "code":"421023"
+ },
+ {
+ "name":"江陵县",
+ "code":"421024"
+ },
+ {
+ "name":"石首市",
+ "code":"421081"
+ },
+ {
+ "name":"洪湖市",
+ "code":"421083"
+ },
+ {
+ "name":"松滋市",
+ "code":"421087"
+ }
+ ]
+ },
+ {
+ "name":"黄冈市",
+ "code":"421100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"421101"
+ },
+ {
+ "name":"黄州区",
+ "code":"421102"
+ },
+ {
+ "name":"团风县",
+ "code":"421121"
+ },
+ {
+ "name":"红安县",
+ "code":"421122"
+ },
+ {
+ "name":"罗田县",
+ "code":"421123"
+ },
+ {
+ "name":"英山县",
+ "code":"421124"
+ },
+ {
+ "name":"浠水县",
+ "code":"421125"
+ },
+ {
+ "name":"蕲春县",
+ "code":"421126"
+ },
+ {
+ "name":"黄梅县",
+ "code":"421127"
+ },
+ {
+ "name":"麻城市",
+ "code":"421181"
+ },
+ {
+ "name":"武穴市",
+ "code":"421182"
+ }
+ ]
+ },
+ {
+ "name":"咸宁市",
+ "code":"421200",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"421201"
+ },
+ {
+ "name":"咸安区",
+ "code":"421202"
+ },
+ {
+ "name":"嘉鱼县",
+ "code":"421221"
+ },
+ {
+ "name":"通城县",
+ "code":"421222"
+ },
+ {
+ "name":"崇阳县",
+ "code":"421223"
+ },
+ {
+ "name":"通山县",
+ "code":"421224"
+ },
+ {
+ "name":"赤壁市",
+ "code":"421281"
+ }
+ ]
+ },
+ {
+ "name":"随州市",
+ "code":"421300",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"421301"
+ },
+ {
+ "name":"曾都区",
+ "code":"421303"
+ },
+ {
+ "name":"随县",
+ "code":"421321"
+ },
+ {
+ "name":"广水市",
+ "code":"421381"
+ }
+ ]
+ },
+ {
+ "name":"恩施土家族苗族自治州",
+ "code":"422800",
+ "sub":[
+ {
+ "name":"恩施市",
+ "code":"422801"
+ },
+ {
+ "name":"利川市",
+ "code":"422802"
+ },
+ {
+ "name":"建始县",
+ "code":"422822"
+ },
+ {
+ "name":"巴东县",
+ "code":"422823"
+ },
+ {
+ "name":"宣恩县",
+ "code":"422825"
+ },
+ {
+ "name":"咸丰县",
+ "code":"422826"
+ },
+ {
+ "name":"来凤县",
+ "code":"422827"
+ },
+ {
+ "name":"鹤峰县",
+ "code":"422828"
+ }
+ ]
+ },
+ {
+ "name":"仙桃市",
+ "code":"429004"
+ },
+ {
+ "name":"潜江市",
+ "code":"429005"
+ },
+ {
+ "name":"天门市",
+ "code":"429006"
+ },
+ {
+ "name":"神农架林区",
+ "code":"429021"
+ }
+ ]
+ },
+ {
+ "name":"湖南省",
+ "code":"430000",
+ "sub":[
+ {
+ "name":"长沙市",
+ "code":"430100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"430101"
+ },
+ {
+ "name":"芙蓉区",
+ "code":"430102"
+ },
+ {
+ "name":"天心区",
+ "code":"430103"
+ },
+ {
+ "name":"岳麓区",
+ "code":"430104"
+ },
+ {
+ "name":"开福区",
+ "code":"430105"
+ },
+ {
+ "name":"雨花区",
+ "code":"430111"
+ },
+ {
+ "name":"望城区",
+ "code":"430112"
+ },
+ {
+ "name":"长沙县",
+ "code":"430121"
+ },
+ {
+ "name":"宁乡县",
+ "code":"430124"
+ },
+ {
+ "name":"浏阳市",
+ "code":"430181"
+ }
+ ]
+ },
+ {
+ "name":"株洲市",
+ "code":"430200",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"430201"
+ },
+ {
+ "name":"荷塘区",
+ "code":"430202"
+ },
+ {
+ "name":"芦淞区",
+ "code":"430203"
+ },
+ {
+ "name":"石峰区",
+ "code":"430204"
+ },
+ {
+ "name":"天元区",
+ "code":"430211"
+ },
+ {
+ "name":"株洲县",
+ "code":"430221"
+ },
+ {
+ "name":"攸县",
+ "code":"430223"
+ },
+ {
+ "name":"茶陵县",
+ "code":"430224"
+ },
+ {
+ "name":"炎陵县",
+ "code":"430225"
+ },
+ {
+ "name":"醴陵市",
+ "code":"430281"
+ }
+ ]
+ },
+ {
+ "name":"湘潭市",
+ "code":"430300",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"430301"
+ },
+ {
+ "name":"雨湖区",
+ "code":"430302"
+ },
+ {
+ "name":"岳塘区",
+ "code":"430304"
+ },
+ {
+ "name":"湘潭县",
+ "code":"430321"
+ },
+ {
+ "name":"湘乡市",
+ "code":"430381"
+ },
+ {
+ "name":"韶山市",
+ "code":"430382"
+ }
+ ]
+ },
+ {
+ "name":"衡阳市",
+ "code":"430400",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"430401"
+ },
+ {
+ "name":"珠晖区",
+ "code":"430405"
+ },
+ {
+ "name":"雁峰区",
+ "code":"430406"
+ },
+ {
+ "name":"石鼓区",
+ "code":"430407"
+ },
+ {
+ "name":"蒸湘区",
+ "code":"430408"
+ },
+ {
+ "name":"南岳区",
+ "code":"430412"
+ },
+ {
+ "name":"衡阳县",
+ "code":"430421"
+ },
+ {
+ "name":"衡南县",
+ "code":"430422"
+ },
+ {
+ "name":"衡山县",
+ "code":"430423"
+ },
+ {
+ "name":"衡东县",
+ "code":"430424"
+ },
+ {
+ "name":"祁东县",
+ "code":"430426"
+ },
+ {
+ "name":"耒阳市",
+ "code":"430481"
+ },
+ {
+ "name":"常宁市",
+ "code":"430482"
+ }
+ ]
+ },
+ {
+ "name":"邵阳市",
+ "code":"430500",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"430501"
+ },
+ {
+ "name":"双清区",
+ "code":"430502"
+ },
+ {
+ "name":"大祥区",
+ "code":"430503"
+ },
+ {
+ "name":"北塔区",
+ "code":"430511"
+ },
+ {
+ "name":"邵东县",
+ "code":"430521"
+ },
+ {
+ "name":"新邵县",
+ "code":"430522"
+ },
+ {
+ "name":"邵阳县",
+ "code":"430523"
+ },
+ {
+ "name":"隆回县",
+ "code":"430524"
+ },
+ {
+ "name":"洞口县",
+ "code":"430525"
+ },
+ {
+ "name":"绥宁县",
+ "code":"430527"
+ },
+ {
+ "name":"新宁县",
+ "code":"430528"
+ },
+ {
+ "name":"城步苗族自治县",
+ "code":"430529"
+ },
+ {
+ "name":"武冈市",
+ "code":"430581"
+ }
+ ]
+ },
+ {
+ "name":"岳阳市",
+ "code":"430600",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"430601"
+ },
+ {
+ "name":"岳阳楼区",
+ "code":"430602"
+ },
+ {
+ "name":"云溪区",
+ "code":"430603"
+ },
+ {
+ "name":"君山区",
+ "code":"430611"
+ },
+ {
+ "name":"岳阳县",
+ "code":"430621"
+ },
+ {
+ "name":"华容县",
+ "code":"430623"
+ },
+ {
+ "name":"湘阴县",
+ "code":"430624"
+ },
+ {
+ "name":"平江县",
+ "code":"430626"
+ },
+ {
+ "name":"汨罗市",
+ "code":"430681"
+ },
+ {
+ "name":"临湘市",
+ "code":"430682"
+ }
+ ]
+ },
+ {
+ "name":"常德市",
+ "code":"430700",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"430701"
+ },
+ {
+ "name":"武陵区",
+ "code":"430702"
+ },
+ {
+ "name":"鼎城区",
+ "code":"430703"
+ },
+ {
+ "name":"安乡县",
+ "code":"430721"
+ },
+ {
+ "name":"汉寿县",
+ "code":"430722"
+ },
+ {
+ "name":"澧县",
+ "code":"430723"
+ },
+ {
+ "name":"临澧县",
+ "code":"430724"
+ },
+ {
+ "name":"桃源县",
+ "code":"430725"
+ },
+ {
+ "name":"石门县",
+ "code":"430726"
+ },
+ {
+ "name":"津市市",
+ "code":"430781"
+ }
+ ]
+ },
+ {
+ "name":"张家界市",
+ "code":"430800",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"430801"
+ },
+ {
+ "name":"永定区",
+ "code":"430802"
+ },
+ {
+ "name":"武陵源区",
+ "code":"430811"
+ },
+ {
+ "name":"慈利县",
+ "code":"430821"
+ },
+ {
+ "name":"桑植县",
+ "code":"430822"
+ }
+ ]
+ },
+ {
+ "name":"益阳市",
+ "code":"430900",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"430901"
+ },
+ {
+ "name":"资阳区",
+ "code":"430902"
+ },
+ {
+ "name":"赫山区",
+ "code":"430903"
+ },
+ {
+ "name":"南县",
+ "code":"430921"
+ },
+ {
+ "name":"桃江县",
+ "code":"430922"
+ },
+ {
+ "name":"安化县",
+ "code":"430923"
+ },
+ {
+ "name":"沅江市",
+ "code":"430981"
+ }
+ ]
+ },
+ {
+ "name":"郴州市",
+ "code":"431000",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"431001"
+ },
+ {
+ "name":"北湖区",
+ "code":"431002"
+ },
+ {
+ "name":"苏仙区",
+ "code":"431003"
+ },
+ {
+ "name":"桂阳县",
+ "code":"431021"
+ },
+ {
+ "name":"宜章县",
+ "code":"431022"
+ },
+ {
+ "name":"永兴县",
+ "code":"431023"
+ },
+ {
+ "name":"嘉禾县",
+ "code":"431024"
+ },
+ {
+ "name":"临武县",
+ "code":"431025"
+ },
+ {
+ "name":"汝城县",
+ "code":"431026"
+ },
+ {
+ "name":"桂东县",
+ "code":"431027"
+ },
+ {
+ "name":"安仁县",
+ "code":"431028"
+ },
+ {
+ "name":"资兴市",
+ "code":"431081"
+ }
+ ]
+ },
+ {
+ "name":"永州市",
+ "code":"431100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"431101"
+ },
+ {
+ "name":"零陵区",
+ "code":"431102"
+ },
+ {
+ "name":"冷水滩区",
+ "code":"431103"
+ },
+ {
+ "name":"祁阳县",
+ "code":"431121"
+ },
+ {
+ "name":"东安县",
+ "code":"431122"
+ },
+ {
+ "name":"双牌县",
+ "code":"431123"
+ },
+ {
+ "name":"道县",
+ "code":"431124"
+ },
+ {
+ "name":"江永县",
+ "code":"431125"
+ },
+ {
+ "name":"宁远县",
+ "code":"431126"
+ },
+ {
+ "name":"蓝山县",
+ "code":"431127"
+ },
+ {
+ "name":"新田县",
+ "code":"431128"
+ },
+ {
+ "name":"江华瑶族自治县",
+ "code":"431129"
+ }
+ ]
+ },
+ {
+ "name":"怀化市",
+ "code":"431200",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"431201"
+ },
+ {
+ "name":"鹤城区",
+ "code":"431202"
+ },
+ {
+ "name":"中方县",
+ "code":"431221"
+ },
+ {
+ "name":"沅陵县",
+ "code":"431222"
+ },
+ {
+ "name":"辰溪县",
+ "code":"431223"
+ },
+ {
+ "name":"溆浦县",
+ "code":"431224"
+ },
+ {
+ "name":"会同县",
+ "code":"431225"
+ },
+ {
+ "name":"麻阳苗族自治县",
+ "code":"431226"
+ },
+ {
+ "name":"新晃侗族自治县",
+ "code":"431227"
+ },
+ {
+ "name":"芷江侗族自治县",
+ "code":"431228"
+ },
+ {
+ "name":"靖州苗族侗族自治县",
+ "code":"431229"
+ },
+ {
+ "name":"通道侗族自治县",
+ "code":"431230"
+ },
+ {
+ "name":"洪江市",
+ "code":"431281"
+ }
+ ]
+ },
+ {
+ "name":"娄底市",
+ "code":"431300",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"431301"
+ },
+ {
+ "name":"娄星区",
+ "code":"431302"
+ },
+ {
+ "name":"双峰县",
+ "code":"431321"
+ },
+ {
+ "name":"新化县",
+ "code":"431322"
+ },
+ {
+ "name":"冷水江市",
+ "code":"431381"
+ },
+ {
+ "name":"涟源市",
+ "code":"431382"
+ }
+ ]
+ },
+ {
+ "name":"湘西土家族苗族自治州",
+ "code":"433100",
+ "sub":[
+ {
+ "name":"吉首市",
+ "code":"433101"
+ },
+ {
+ "name":"泸溪县",
+ "code":"433122"
+ },
+ {
+ "name":"凤凰县",
+ "code":"433123"
+ },
+ {
+ "name":"花垣县",
+ "code":"433124"
+ },
+ {
+ "name":"保靖县",
+ "code":"433125"
+ },
+ {
+ "name":"古丈县",
+ "code":"433126"
+ },
+ {
+ "name":"永顺县",
+ "code":"433127"
+ },
+ {
+ "name":"龙山县",
+ "code":"433130"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name":"广东省",
+ "code":"440000",
+ "sub":[
+ {
+ "name":"广州市",
+ "code":"440100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"440101"
+ },
+ {
+ "name":"荔湾区",
+ "code":"440103"
+ },
+ {
+ "name":"越秀区",
+ "code":"440104"
+ },
+ {
+ "name":"海珠区",
+ "code":"440105"
+ },
+ {
+ "name":"天河区",
+ "code":"440106"
+ },
+ {
+ "name":"白云区",
+ "code":"440111"
+ },
+ {
+ "name":"黄埔区",
+ "code":"440112"
+ },
+ {
+ "name":"番禺区",
+ "code":"440113"
+ },
+ {
+ "name":"花都区",
+ "code":"440114"
+ },
+ {
+ "name":"南沙区",
+ "code":"440115"
+ },
+ {
+ "name":"从化区",
+ "code":"440117"
+ },
+ {
+ "name":"增城区",
+ "code":"440118"
+ }
+ ]
+ },
+ {
+ "name":"韶关市",
+ "code":"440200",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"440201"
+ },
+ {
+ "name":"武江区",
+ "code":"440203"
+ },
+ {
+ "name":"浈江区",
+ "code":"440204"
+ },
+ {
+ "name":"曲江区",
+ "code":"440205"
+ },
+ {
+ "name":"始兴县",
+ "code":"440222"
+ },
+ {
+ "name":"仁化县",
+ "code":"440224"
+ },
+ {
+ "name":"翁源县",
+ "code":"440229"
+ },
+ {
+ "name":"乳源瑶族自治县",
+ "code":"440232"
+ },
+ {
+ "name":"新丰县",
+ "code":"440233"
+ },
+ {
+ "name":"乐昌市",
+ "code":"440281"
+ },
+ {
+ "name":"南雄市",
+ "code":"440282"
+ }
+ ]
+ },
+ {
+ "name":"深圳市",
+ "code":"440300",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"440301"
+ },
+ {
+ "name":"罗湖区",
+ "code":"440303"
+ },
+ {
+ "name":"福田区",
+ "code":"440304"
+ },
+ {
+ "name":"南山区",
+ "code":"440305"
+ },
+ {
+ "name":"宝安区",
+ "code":"440306"
+ },
+ {
+ "name":"龙岗区",
+ "code":"440307"
+ },
+ {
+ "name":"盐田区",
+ "code":"440308"
+ }
+ ]
+ },
+ {
+ "name":"珠海市",
+ "code":"440400",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"440401"
+ },
+ {
+ "name":"香洲区",
+ "code":"440402"
+ },
+ {
+ "name":"斗门区",
+ "code":"440403"
+ },
+ {
+ "name":"金湾区",
+ "code":"440404"
+ }
+ ]
+ },
+ {
+ "name":"汕头市",
+ "code":"440500",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"440501"
+ },
+ {
+ "name":"龙湖区",
+ "code":"440507"
+ },
+ {
+ "name":"金平区",
+ "code":"440511"
+ },
+ {
+ "name":"濠江区",
+ "code":"440512"
+ },
+ {
+ "name":"潮阳区",
+ "code":"440513"
+ },
+ {
+ "name":"潮南区",
+ "code":"440514"
+ },
+ {
+ "name":"澄海区",
+ "code":"440515"
+ },
+ {
+ "name":"南澳县",
+ "code":"440523"
+ }
+ ]
+ },
+ {
+ "name":"佛山市",
+ "code":"440600",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"440601"
+ },
+ {
+ "name":"禅城区",
+ "code":"440604"
+ },
+ {
+ "name":"南海区",
+ "code":"440605"
+ },
+ {
+ "name":"顺德区",
+ "code":"440606"
+ },
+ {
+ "name":"三水区",
+ "code":"440607"
+ },
+ {
+ "name":"高明区",
+ "code":"440608"
+ }
+ ]
+ },
+ {
+ "name":"江门市",
+ "code":"440700",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"440701"
+ },
+ {
+ "name":"蓬江区",
+ "code":"440703"
+ },
+ {
+ "name":"江海区",
+ "code":"440704"
+ },
+ {
+ "name":"新会区",
+ "code":"440705"
+ },
+ {
+ "name":"台山市",
+ "code":"440781"
+ },
+ {
+ "name":"开平市",
+ "code":"440783"
+ },
+ {
+ "name":"鹤山市",
+ "code":"440784"
+ },
+ {
+ "name":"恩平市",
+ "code":"440785"
+ }
+ ]
+ },
+ {
+ "name":"湛江市",
+ "code":"440800",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"440801"
+ },
+ {
+ "name":"赤坎区",
+ "code":"440802"
+ },
+ {
+ "name":"霞山区",
+ "code":"440803"
+ },
+ {
+ "name":"坡头区",
+ "code":"440804"
+ },
+ {
+ "name":"麻章区",
+ "code":"440811"
+ },
+ {
+ "name":"遂溪县",
+ "code":"440823"
+ },
+ {
+ "name":"徐闻县",
+ "code":"440825"
+ },
+ {
+ "name":"廉江市",
+ "code":"440881"
+ },
+ {
+ "name":"雷州市",
+ "code":"440882"
+ },
+ {
+ "name":"吴川市",
+ "code":"440883"
+ }
+ ]
+ },
+ {
+ "name":"茂名市",
+ "code":"440900",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"440901"
+ },
+ {
+ "name":"茂南区",
+ "code":"440902"
+ },
+ {
+ "name":"电白区",
+ "code":"440904"
+ },
+ {
+ "name":"高州市",
+ "code":"440981"
+ },
+ {
+ "name":"化州市",
+ "code":"440982"
+ },
+ {
+ "name":"信宜市",
+ "code":"440983"
+ }
+ ]
+ },
+ {
+ "name":"肇庆市",
+ "code":"441200",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"441201"
+ },
+ {
+ "name":"端州区",
+ "code":"441202"
+ },
+ {
+ "name":"鼎湖区",
+ "code":"441203"
+ },
+ {
+ "name":"广宁县",
+ "code":"441223"
+ },
+ {
+ "name":"怀集县",
+ "code":"441224"
+ },
+ {
+ "name":"封开县",
+ "code":"441225"
+ },
+ {
+ "name":"德庆县",
+ "code":"441226"
+ },
+ {
+ "name":"高要市",
+ "code":"441283"
+ },
+ {
+ "name":"四会市",
+ "code":"441284"
+ }
+ ]
+ },
+ {
+ "name":"惠州市",
+ "code":"441300",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"441301"
+ },
+ {
+ "name":"惠城区",
+ "code":"441302"
+ },
+ {
+ "name":"惠阳区",
+ "code":"441303"
+ },
+ {
+ "name":"博罗县",
+ "code":"441322"
+ },
+ {
+ "name":"惠东县",
+ "code":"441323"
+ },
+ {
+ "name":"龙门县",
+ "code":"441324"
+ }
+ ]
+ },
+ {
+ "name":"梅州市",
+ "code":"441400",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"441401"
+ },
+ {
+ "name":"梅江区",
+ "code":"441402"
+ },
+ {
+ "name":"梅县区",
+ "code":"441403"
+ },
+ {
+ "name":"大埔县",
+ "code":"441422"
+ },
+ {
+ "name":"丰顺县",
+ "code":"441423"
+ },
+ {
+ "name":"五华县",
+ "code":"441424"
+ },
+ {
+ "name":"平远县",
+ "code":"441426"
+ },
+ {
+ "name":"蕉岭县",
+ "code":"441427"
+ },
+ {
+ "name":"兴宁市",
+ "code":"441481"
+ }
+ ]
+ },
+ {
+ "name":"汕尾市",
+ "code":"441500",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"441501"
+ },
+ {
+ "name":"城区",
+ "code":"441502"
+ },
+ {
+ "name":"海丰县",
+ "code":"441521"
+ },
+ {
+ "name":"陆河县",
+ "code":"441523"
+ },
+ {
+ "name":"陆丰市",
+ "code":"441581"
+ }
+ ]
+ },
+ {
+ "name":"河源市",
+ "code":"441600",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"441601"
+ },
+ {
+ "name":"源城区",
+ "code":"441602"
+ },
+ {
+ "name":"紫金县",
+ "code":"441621"
+ },
+ {
+ "name":"龙川县",
+ "code":"441622"
+ },
+ {
+ "name":"连平县",
+ "code":"441623"
+ },
+ {
+ "name":"和平县",
+ "code":"441624"
+ },
+ {
+ "name":"东源县",
+ "code":"441625"
+ }
+ ]
+ },
+ {
+ "name":"阳江市",
+ "code":"441700",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"441701"
+ },
+ {
+ "name":"江城区",
+ "code":"441702"
+ },
+ {
+ "name":"阳东区",
+ "code":"441704"
+ },
+ {
+ "name":"阳西县",
+ "code":"441721"
+ },
+ {
+ "name":"阳春市",
+ "code":"441781"
+ }
+ ]
+ },
+ {
+ "name":"清远市",
+ "code":"441800",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"441801"
+ },
+ {
+ "name":"清城区",
+ "code":"441802"
+ },
+ {
+ "name":"清新区",
+ "code":"441803"
+ },
+ {
+ "name":"佛冈县",
+ "code":"441821"
+ },
+ {
+ "name":"阳山县",
+ "code":"441823"
+ },
+ {
+ "name":"连山壮族瑶族自治县",
+ "code":"441825"
+ },
+ {
+ "name":"连南瑶族自治县",
+ "code":"441826"
+ },
+ {
+ "name":"英德市",
+ "code":"441881"
+ },
+ {
+ "name":"连州市",
+ "code":"441882"
+ }
+ ]
+ },
+ {
+ "name":"东莞市",
+ "code":"441900",
+ "sub":[
+
+ ]
+ },
+ {
+ "name":"中山市",
+ "code":"442000",
+ "sub":[
+
+ ]
+ },
+ {
+ "name":"潮州市",
+ "code":"445100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"445101"
+ },
+ {
+ "name":"湘桥区",
+ "code":"445102"
+ },
+ {
+ "name":"潮安区",
+ "code":"445103"
+ },
+ {
+ "name":"饶平县",
+ "code":"445122"
+ }
+ ]
+ },
+ {
+ "name":"揭阳市",
+ "code":"445200",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"445201"
+ },
+ {
+ "name":"榕城区",
+ "code":"445202"
+ },
+ {
+ "name":"揭东区",
+ "code":"445203"
+ },
+ {
+ "name":"揭西县",
+ "code":"445222"
+ },
+ {
+ "name":"惠来县",
+ "code":"445224"
+ },
+ {
+ "name":"普宁市",
+ "code":"445281"
+ }
+ ]
+ },
+ {
+ "name":"云浮市",
+ "code":"445300",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"445301"
+ },
+ {
+ "name":"云城区",
+ "code":"445302"
+ },
+ {
+ "name":"云安区",
+ "code":"445303"
+ },
+ {
+ "name":"新兴县",
+ "code":"445321"
+ },
+ {
+ "name":"郁南县",
+ "code":"445322"
+ },
+ {
+ "name":"罗定市",
+ "code":"445381"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name":"广西壮族自治区",
+ "code":"450000",
+ "sub":[
+ {
+ "name":"南宁市",
+ "code":"450100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"450101"
+ },
+ {
+ "name":"兴宁区",
+ "code":"450102"
+ },
+ {
+ "name":"青秀区",
+ "code":"450103"
+ },
+ {
+ "name":"江南区",
+ "code":"450105"
+ },
+ {
+ "name":"西乡塘区",
+ "code":"450107"
+ },
+ {
+ "name":"良庆区",
+ "code":"450108"
+ },
+ {
+ "name":"邕宁区",
+ "code":"450109"
+ },
+ {
+ "name":"武鸣县",
+ "code":"450122"
+ },
+ {
+ "name":"隆安县",
+ "code":"450123"
+ },
+ {
+ "name":"马山县",
+ "code":"450124"
+ },
+ {
+ "name":"上林县",
+ "code":"450125"
+ },
+ {
+ "name":"宾阳县",
+ "code":"450126"
+ },
+ {
+ "name":"横县",
+ "code":"450127"
+ }
+ ]
+ },
+ {
+ "name":"柳州市",
+ "code":"450200",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"450201"
+ },
+ {
+ "name":"城中区",
+ "code":"450202"
+ },
+ {
+ "name":"鱼峰区",
+ "code":"450203"
+ },
+ {
+ "name":"柳南区",
+ "code":"450204"
+ },
+ {
+ "name":"柳北区",
+ "code":"450205"
+ },
+ {
+ "name":"柳江县",
+ "code":"450221"
+ },
+ {
+ "name":"柳城县",
+ "code":"450222"
+ },
+ {
+ "name":"鹿寨县",
+ "code":"450223"
+ },
+ {
+ "name":"融安县",
+ "code":"450224"
+ },
+ {
+ "name":"融水苗族自治县",
+ "code":"450225"
+ },
+ {
+ "name":"三江侗族自治县",
+ "code":"450226"
+ }
+ ]
+ },
+ {
+ "name":"桂林市",
+ "code":"450300",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"450301"
+ },
+ {
+ "name":"秀峰区",
+ "code":"450302"
+ },
+ {
+ "name":"叠彩区",
+ "code":"450303"
+ },
+ {
+ "name":"象山区",
+ "code":"450304"
+ },
+ {
+ "name":"七星区",
+ "code":"450305"
+ },
+ {
+ "name":"雁山区",
+ "code":"450311"
+ },
+ {
+ "name":"临桂区",
+ "code":"450312"
+ },
+ {
+ "name":"阳朔县",
+ "code":"450321"
+ },
+ {
+ "name":"灵川县",
+ "code":"450323"
+ },
+ {
+ "name":"全州县",
+ "code":"450324"
+ },
+ {
+ "name":"兴安县",
+ "code":"450325"
+ },
+ {
+ "name":"永福县",
+ "code":"450326"
+ },
+ {
+ "name":"灌阳县",
+ "code":"450327"
+ },
+ {
+ "name":"龙胜各族自治县",
+ "code":"450328"
+ },
+ {
+ "name":"资源县",
+ "code":"450329"
+ },
+ {
+ "name":"平乐县",
+ "code":"450330"
+ },
+ {
+ "name":"荔浦县",
+ "code":"450331"
+ },
+ {
+ "name":"恭城瑶族自治县",
+ "code":"450332"
+ }
+ ]
+ },
+ {
+ "name":"梧州市",
+ "code":"450400",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"450401"
+ },
+ {
+ "name":"万秀区",
+ "code":"450403"
+ },
+ {
+ "name":"长洲区",
+ "code":"450405"
+ },
+ {
+ "name":"龙圩区",
+ "code":"450406"
+ },
+ {
+ "name":"苍梧县",
+ "code":"450421"
+ },
+ {
+ "name":"藤县",
+ "code":"450422"
+ },
+ {
+ "name":"蒙山县",
+ "code":"450423"
+ },
+ {
+ "name":"岑溪市",
+ "code":"450481"
+ }
+ ]
+ },
+ {
+ "name":"北海市",
+ "code":"450500",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"450501"
+ },
+ {
+ "name":"海城区",
+ "code":"450502"
+ },
+ {
+ "name":"银海区",
+ "code":"450503"
+ },
+ {
+ "name":"铁山港区",
+ "code":"450512"
+ },
+ {
+ "name":"合浦县",
+ "code":"450521"
+ }
+ ]
+ },
+ {
+ "name":"防城港市",
+ "code":"450600",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"450601"
+ },
+ {
+ "name":"港口区",
+ "code":"450602"
+ },
+ {
+ "name":"防城区",
+ "code":"450603"
+ },
+ {
+ "name":"上思县",
+ "code":"450621"
+ },
+ {
+ "name":"东兴市",
+ "code":"450681"
+ }
+ ]
+ },
+ {
+ "name":"钦州市",
+ "code":"450700",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"450701"
+ },
+ {
+ "name":"钦南区",
+ "code":"450702"
+ },
+ {
+ "name":"钦北区",
+ "code":"450703"
+ },
+ {
+ "name":"灵山县",
+ "code":"450721"
+ },
+ {
+ "name":"浦北县",
+ "code":"450722"
+ }
+ ]
+ },
+ {
+ "name":"贵港市",
+ "code":"450800",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"450801"
+ },
+ {
+ "name":"港北区",
+ "code":"450802"
+ },
+ {
+ "name":"港南区",
+ "code":"450803"
+ },
+ {
+ "name":"覃塘区",
+ "code":"450804"
+ },
+ {
+ "name":"平南县",
+ "code":"450821"
+ },
+ {
+ "name":"桂平市",
+ "code":"450881"
+ }
+ ]
+ },
+ {
+ "name":"玉林市",
+ "code":"450900",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"450901"
+ },
+ {
+ "name":"玉州区",
+ "code":"450902"
+ },
+ {
+ "name":"福绵区",
+ "code":"450903"
+ },
+ {
+ "name":"容县",
+ "code":"450921"
+ },
+ {
+ "name":"陆川县",
+ "code":"450922"
+ },
+ {
+ "name":"博白县",
+ "code":"450923"
+ },
+ {
+ "name":"兴业县",
+ "code":"450924"
+ },
+ {
+ "name":"北流市",
+ "code":"450981"
+ }
+ ]
+ },
+ {
+ "name":"百色市",
+ "code":"451000",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"451001"
+ },
+ {
+ "name":"右江区",
+ "code":"451002"
+ },
+ {
+ "name":"田阳县",
+ "code":"451021"
+ },
+ {
+ "name":"田东县",
+ "code":"451022"
+ },
+ {
+ "name":"平果县",
+ "code":"451023"
+ },
+ {
+ "name":"德保县",
+ "code":"451024"
+ },
+ {
+ "name":"靖西县",
+ "code":"451025"
+ },
+ {
+ "name":"那坡县",
+ "code":"451026"
+ },
+ {
+ "name":"凌云县",
+ "code":"451027"
+ },
+ {
+ "name":"乐业县",
+ "code":"451028"
+ },
+ {
+ "name":"田林县",
+ "code":"451029"
+ },
+ {
+ "name":"西林县",
+ "code":"451030"
+ },
+ {
+ "name":"隆林各族自治县",
+ "code":"451031"
+ }
+ ]
+ },
+ {
+ "name":"贺州市",
+ "code":"451100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"451101"
+ },
+ {
+ "name":"八步区",
+ "code":"451102"
+ },
+ {
+ "name":"平桂管理区",
+ "code":"451119"
+ },
+ {
+ "name":"昭平县",
+ "code":"451121"
+ },
+ {
+ "name":"钟山县",
+ "code":"451122"
+ },
+ {
+ "name":"富川瑶族自治县",
+ "code":"451123"
+ }
+ ]
+ },
+ {
+ "name":"河池市",
+ "code":"451200",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"451201"
+ },
+ {
+ "name":"金城江区",
+ "code":"451202"
+ },
+ {
+ "name":"南丹县",
+ "code":"451221"
+ },
+ {
+ "name":"天峨县",
+ "code":"451222"
+ },
+ {
+ "name":"凤山县",
+ "code":"451223"
+ },
+ {
+ "name":"东兰县",
+ "code":"451224"
+ },
+ {
+ "name":"罗城仫佬族自治县",
+ "code":"451225"
+ },
+ {
+ "name":"环江毛南族自治县",
+ "code":"451226"
+ },
+ {
+ "name":"巴马瑶族自治县",
+ "code":"451227"
+ },
+ {
+ "name":"都安瑶族自治县",
+ "code":"451228"
+ },
+ {
+ "name":"大化瑶族自治县",
+ "code":"451229"
+ },
+ {
+ "name":"宜州市",
+ "code":"451281"
+ }
+ ]
+ },
+ {
+ "name":"来宾市",
+ "code":"451300",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"451301"
+ },
+ {
+ "name":"兴宾区",
+ "code":"451302"
+ },
+ {
+ "name":"忻城县",
+ "code":"451321"
+ },
+ {
+ "name":"象州县",
+ "code":"451322"
+ },
+ {
+ "name":"武宣县",
+ "code":"451323"
+ },
+ {
+ "name":"金秀瑶族自治县",
+ "code":"451324"
+ },
+ {
+ "name":"合山市",
+ "code":"451381"
+ }
+ ]
+ },
+ {
+ "name":"崇左市",
+ "code":"451400",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"451401"
+ },
+ {
+ "name":"江州区",
+ "code":"451402"
+ },
+ {
+ "name":"扶绥县",
+ "code":"451421"
+ },
+ {
+ "name":"宁明县",
+ "code":"451422"
+ },
+ {
+ "name":"龙州县",
+ "code":"451423"
+ },
+ {
+ "name":"大新县",
+ "code":"451424"
+ },
+ {
+ "name":"天等县",
+ "code":"451425"
+ },
+ {
+ "name":"凭祥市",
+ "code":"451481"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name":"海南省",
+ "code":"460000",
+ "sub":[
+ {
+ "name":"海口市",
+ "code":"460100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"460101"
+ },
+ {
+ "name":"秀英区",
+ "code":"460105"
+ },
+ {
+ "name":"龙华区",
+ "code":"460106"
+ },
+ {
+ "name":"琼山区",
+ "code":"460107"
+ },
+ {
+ "name":"美兰区",
+ "code":"460108"
+ }
+ ]
+ },
+ {
+ "name":"三亚市",
+ "code":"460200",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"460201"
+ },
+ {
+ "name":"海棠区",
+ "code":"460202"
+ },
+ {
+ "name":"吉阳区",
+ "code":"460203"
+ },
+ {
+ "name":"天涯区",
+ "code":"460204"
+ },
+ {
+ "name":"崖州区",
+ "code":"460205"
+ }
+ ]
+ },
+ {
+ "name":"三沙市",
+ "code":"460300",
+ "sub":[
+ {
+ "name":"西沙群岛",
+ "code":"460321"
+ },
+ {
+ "name":"南沙群岛",
+ "code":"460322"
+ },
+ {
+ "name":"中沙群岛的岛礁及其海域",
+ "code":"460323"
+ }
+ ]
+ },
+ {
+ "name":"五指山市",
+ "code":"469001"
+ },
+ {
+ "name":"琼海市",
+ "code":"469002"
+ },
+ {
+ "name":"儋州市",
+ "code":"469003"
+ },
+ {
+ "name":"文昌市",
+ "code":"469005"
+ },
+ {
+ "name":"万宁市",
+ "code":"469006"
+ },
+ {
+ "name":"东方市",
+ "code":"469007"
+ },
+ {
+ "name":"定安县",
+ "code":"469021"
+ },
+ {
+ "name":"屯昌县",
+ "code":"469022"
+ },
+ {
+ "name":"澄迈县",
+ "code":"469023"
+ },
+ {
+ "name":"临高县",
+ "code":"469024"
+ },
+ {
+ "name":"白沙黎族自治县",
+ "code":"469025"
+ },
+ {
+ "name":"昌江黎族自治县",
+ "code":"469026"
+ },
+ {
+ "name":"乐东黎族自治县",
+ "code":"469027"
+ },
+ {
+ "name":"陵水黎族自治县",
+ "code":"469028"
+ },
+ {
+ "name":"保亭黎族苗族自治县",
+ "code":"469029"
+ },
+ {
+ "name":"琼中黎族苗族自治县",
+ "code":"469030"
+ }
+ ]
+ },
+ {
+ "name":"重庆",
+ "code":"500000",
+ "sub": [
+ {
+ "name": "重庆市",
+ "code": "500000",
+ "sub":[
+ {
+ "name":"万州区",
+ "code":"500101"
+ },
+ {
+ "name":"涪陵区",
+ "code":"500102"
+ },
+ {
+ "name":"渝中区",
+ "code":"500103"
+ },
+ {
+ "name":"大渡口区",
+ "code":"500104"
+ },
+ {
+ "name":"江北区",
+ "code":"500105"
+ },
+ {
+ "name":"沙坪坝区",
+ "code":"500106"
+ },
+ {
+ "name":"九龙坡区",
+ "code":"500107"
+ },
+ {
+ "name":"南岸区",
+ "code":"500108"
+ },
+ {
+ "name":"北碚区",
+ "code":"500109"
+ },
+ {
+ "name":"綦江区",
+ "code":"500110"
+ },
+ {
+ "name":"大足区",
+ "code":"500111"
+ },
+ {
+ "name":"渝北区",
+ "code":"500112"
+ },
+ {
+ "name":"巴南区",
+ "code":"500113"
+ },
+ {
+ "name":"黔江区",
+ "code":"500114"
+ },
+ {
+ "name":"长寿区",
+ "code":"500115"
+ },
+ {
+ "name":"江津区",
+ "code":"500116"
+ },
+ {
+ "name":"合川区",
+ "code":"500117"
+ },
+ {
+ "name":"永川区",
+ "code":"500118"
+ },
+ {
+ "name":"南川区",
+ "code":"500119"
+ },
+ {
+ "name":"璧山区",
+ "code":"500120"
+ },
+ {
+ "name":"铜梁区",
+ "code":"500151"
+ },
+ {
+ "name":"潼南县",
+ "code":"500223"
+ },
+ {
+ "name":"荣昌县",
+ "code":"500226"
+ },
+ {
+ "name":"梁平县",
+ "code":"500228"
+ },
+ {
+ "name":"城口县",
+ "code":"500229"
+ },
+ {
+ "name":"丰都县",
+ "code":"500230"
+ },
+ {
+ "name":"垫江县",
+ "code":"500231"
+ },
+ {
+ "name":"武隆县",
+ "code":"500232"
+ },
+ {
+ "name":"忠县",
+ "code":"500233"
+ },
+ {
+ "name":"开县",
+ "code":"500234"
+ },
+ {
+ "name":"云阳县",
+ "code":"500235"
+ },
+ {
+ "name":"奉节县",
+ "code":"500236"
+ },
+ {
+ "name":"巫山县",
+ "code":"500237"
+ },
+ {
+ "name":"巫溪县",
+ "code":"500238"
+ },
+ {
+ "name":"石柱土家族自治县",
+ "code":"500240"
+ },
+ {
+ "name":"秀山土家族苗族自治县",
+ "code":"500241"
+ },
+ {
+ "name":"酉阳土家族苗族自治县",
+ "code":"500242"
+ },
+ {
+ "name":"彭水苗族土家族自治县",
+ "code":"500243"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name":"四川省",
+ "code":"510000",
+ "sub":[
+ {
+ "name":"成都市",
+ "code":"510100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"510101"
+ },
+ {
+ "name":"锦江区",
+ "code":"510104"
+ },
+ {
+ "name":"青羊区",
+ "code":"510105"
+ },
+ {
+ "name":"金牛区",
+ "code":"510106"
+ },
+ {
+ "name":"武侯区",
+ "code":"510107"
+ },
+ {
+ "name":"成华区",
+ "code":"510108"
+ },
+ {
+ "name":"龙泉驿区",
+ "code":"510112"
+ },
+ {
+ "name":"青白江区",
+ "code":"510113"
+ },
+ {
+ "name":"新都区",
+ "code":"510114"
+ },
+ {
+ "name":"温江区",
+ "code":"510115"
+ },
+ {
+ "name":"金堂县",
+ "code":"510121"
+ },
+ {
+ "name":"双流县",
+ "code":"510122"
+ },
+ {
+ "name":"郫县",
+ "code":"510124"
+ },
+ {
+ "name":"大邑县",
+ "code":"510129"
+ },
+ {
+ "name":"蒲江县",
+ "code":"510131"
+ },
+ {
+ "name":"新津县",
+ "code":"510132"
+ },
+ {
+ "name":"都江堰市",
+ "code":"510181"
+ },
+ {
+ "name":"彭州市",
+ "code":"510182"
+ },
+ {
+ "name":"邛崃市",
+ "code":"510183"
+ },
+ {
+ "name":"崇州市",
+ "code":"510184"
+ }
+ ]
+ },
+ {
+ "name":"自贡市",
+ "code":"510300",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"510301"
+ },
+ {
+ "name":"自流井区",
+ "code":"510302"
+ },
+ {
+ "name":"贡井区",
+ "code":"510303"
+ },
+ {
+ "name":"大安区",
+ "code":"510304"
+ },
+ {
+ "name":"沿滩区",
+ "code":"510311"
+ },
+ {
+ "name":"荣县",
+ "code":"510321"
+ },
+ {
+ "name":"富顺县",
+ "code":"510322"
+ }
+ ]
+ },
+ {
+ "name":"攀枝花市",
+ "code":"510400",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"510401"
+ },
+ {
+ "name":"东区",
+ "code":"510402"
+ },
+ {
+ "name":"西区",
+ "code":"510403"
+ },
+ {
+ "name":"仁和区",
+ "code":"510411"
+ },
+ {
+ "name":"米易县",
+ "code":"510421"
+ },
+ {
+ "name":"盐边县",
+ "code":"510422"
+ }
+ ]
+ },
+ {
+ "name":"泸州市",
+ "code":"510500",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"510501"
+ },
+ {
+ "name":"江阳区",
+ "code":"510502"
+ },
+ {
+ "name":"纳溪区",
+ "code":"510503"
+ },
+ {
+ "name":"龙马潭区",
+ "code":"510504"
+ },
+ {
+ "name":"泸县",
+ "code":"510521"
+ },
+ {
+ "name":"合江县",
+ "code":"510522"
+ },
+ {
+ "name":"叙永县",
+ "code":"510524"
+ },
+ {
+ "name":"古蔺县",
+ "code":"510525"
+ }
+ ]
+ },
+ {
+ "name":"德阳市",
+ "code":"510600",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"510601"
+ },
+ {
+ "name":"旌阳区",
+ "code":"510603"
+ },
+ {
+ "name":"中江县",
+ "code":"510623"
+ },
+ {
+ "name":"罗江县",
+ "code":"510626"
+ },
+ {
+ "name":"广汉市",
+ "code":"510681"
+ },
+ {
+ "name":"什邡市",
+ "code":"510682"
+ },
+ {
+ "name":"绵竹市",
+ "code":"510683"
+ }
+ ]
+ },
+ {
+ "name":"绵阳市",
+ "code":"510700",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"510701"
+ },
+ {
+ "name":"涪城区",
+ "code":"510703"
+ },
+ {
+ "name":"游仙区",
+ "code":"510704"
+ },
+ {
+ "name":"三台县",
+ "code":"510722"
+ },
+ {
+ "name":"盐亭县",
+ "code":"510723"
+ },
+ {
+ "name":"安县",
+ "code":"510724"
+ },
+ {
+ "name":"梓潼县",
+ "code":"510725"
+ },
+ {
+ "name":"北川羌族自治县",
+ "code":"510726"
+ },
+ {
+ "name":"平武县",
+ "code":"510727"
+ },
+ {
+ "name":"江油市",
+ "code":"510781"
+ }
+ ]
+ },
+ {
+ "name":"广元市",
+ "code":"510800",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"510801"
+ },
+ {
+ "name":"利州区",
+ "code":"510802"
+ },
+ {
+ "name":"昭化区",
+ "code":"510811"
+ },
+ {
+ "name":"朝天区",
+ "code":"510812"
+ },
+ {
+ "name":"旺苍县",
+ "code":"510821"
+ },
+ {
+ "name":"青川县",
+ "code":"510822"
+ },
+ {
+ "name":"剑阁县",
+ "code":"510823"
+ },
+ {
+ "name":"苍溪县",
+ "code":"510824"
+ }
+ ]
+ },
+ {
+ "name":"遂宁市",
+ "code":"510900",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"510901"
+ },
+ {
+ "name":"船山区",
+ "code":"510903"
+ },
+ {
+ "name":"安居区",
+ "code":"510904"
+ },
+ {
+ "name":"蓬溪县",
+ "code":"510921"
+ },
+ {
+ "name":"射洪县",
+ "code":"510922"
+ },
+ {
+ "name":"大英县",
+ "code":"510923"
+ }
+ ]
+ },
+ {
+ "name":"内江市",
+ "code":"511000",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"511001"
+ },
+ {
+ "name":"市中区",
+ "code":"511002"
+ },
+ {
+ "name":"东兴区",
+ "code":"511011"
+ },
+ {
+ "name":"威远县",
+ "code":"511024"
+ },
+ {
+ "name":"资中县",
+ "code":"511025"
+ },
+ {
+ "name":"隆昌县",
+ "code":"511028"
+ }
+ ]
+ },
+ {
+ "name":"乐山市",
+ "code":"511100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"511101"
+ },
+ {
+ "name":"市中区",
+ "code":"511102"
+ },
+ {
+ "name":"沙湾区",
+ "code":"511111"
+ },
+ {
+ "name":"五通桥区",
+ "code":"511112"
+ },
+ {
+ "name":"金口河区",
+ "code":"511113"
+ },
+ {
+ "name":"犍为县",
+ "code":"511123"
+ },
+ {
+ "name":"井研县",
+ "code":"511124"
+ },
+ {
+ "name":"夹江县",
+ "code":"511126"
+ },
+ {
+ "name":"沐川县",
+ "code":"511129"
+ },
+ {
+ "name":"峨边彝族自治县",
+ "code":"511132"
+ },
+ {
+ "name":"马边彝族自治县",
+ "code":"511133"
+ },
+ {
+ "name":"峨眉山市",
+ "code":"511181"
+ }
+ ]
+ },
+ {
+ "name":"南充市",
+ "code":"511300",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"511301"
+ },
+ {
+ "name":"顺庆区",
+ "code":"511302"
+ },
+ {
+ "name":"高坪区",
+ "code":"511303"
+ },
+ {
+ "name":"嘉陵区",
+ "code":"511304"
+ },
+ {
+ "name":"南部县",
+ "code":"511321"
+ },
+ {
+ "name":"营山县",
+ "code":"511322"
+ },
+ {
+ "name":"蓬安县",
+ "code":"511323"
+ },
+ {
+ "name":"仪陇县",
+ "code":"511324"
+ },
+ {
+ "name":"西充县",
+ "code":"511325"
+ },
+ {
+ "name":"阆中市",
+ "code":"511381"
+ }
+ ]
+ },
+ {
+ "name":"眉山市",
+ "code":"511400",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"511401"
+ },
+ {
+ "name":"东坡区",
+ "code":"511402"
+ },
+ {
+ "name":"彭山区",
+ "code":"511403"
+ },
+ {
+ "name":"仁寿县",
+ "code":"511421"
+ },
+ {
+ "name":"洪雅县",
+ "code":"511423"
+ },
+ {
+ "name":"丹棱县",
+ "code":"511424"
+ },
+ {
+ "name":"青神县",
+ "code":"511425"
+ }
+ ]
+ },
+ {
+ "name":"宜宾市",
+ "code":"511500",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"511501"
+ },
+ {
+ "name":"翠屏区",
+ "code":"511502"
+ },
+ {
+ "name":"南溪区",
+ "code":"511503"
+ },
+ {
+ "name":"宜宾县",
+ "code":"511521"
+ },
+ {
+ "name":"江安县",
+ "code":"511523"
+ },
+ {
+ "name":"长宁县",
+ "code":"511524"
+ },
+ {
+ "name":"高县",
+ "code":"511525"
+ },
+ {
+ "name":"珙县",
+ "code":"511526"
+ },
+ {
+ "name":"筠连县",
+ "code":"511527"
+ },
+ {
+ "name":"兴文县",
+ "code":"511528"
+ },
+ {
+ "name":"屏山县",
+ "code":"511529"
+ }
+ ]
+ },
+ {
+ "name":"广安市",
+ "code":"511600",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"511601"
+ },
+ {
+ "name":"广安区",
+ "code":"511602"
+ },
+ {
+ "name":"前锋区",
+ "code":"511603"
+ },
+ {
+ "name":"岳池县",
+ "code":"511621"
+ },
+ {
+ "name":"武胜县",
+ "code":"511622"
+ },
+ {
+ "name":"邻水县",
+ "code":"511623"
+ },
+ {
+ "name":"华蓥市",
+ "code":"511681"
+ }
+ ]
+ },
+ {
+ "name":"达州市",
+ "code":"511700",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"511701"
+ },
+ {
+ "name":"通川区",
+ "code":"511702"
+ },
+ {
+ "name":"达川区",
+ "code":"511703"
+ },
+ {
+ "name":"宣汉县",
+ "code":"511722"
+ },
+ {
+ "name":"开江县",
+ "code":"511723"
+ },
+ {
+ "name":"大竹县",
+ "code":"511724"
+ },
+ {
+ "name":"渠县",
+ "code":"511725"
+ },
+ {
+ "name":"万源市",
+ "code":"511781"
+ }
+ ]
+ },
+ {
+ "name":"雅安市",
+ "code":"511800",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"511801"
+ },
+ {
+ "name":"雨城区",
+ "code":"511802"
+ },
+ {
+ "name":"名山区",
+ "code":"511803"
+ },
+ {
+ "name":"荥经县",
+ "code":"511822"
+ },
+ {
+ "name":"汉源县",
+ "code":"511823"
+ },
+ {
+ "name":"石棉县",
+ "code":"511824"
+ },
+ {
+ "name":"天全县",
+ "code":"511825"
+ },
+ {
+ "name":"芦山县",
+ "code":"511826"
+ },
+ {
+ "name":"宝兴县",
+ "code":"511827"
+ }
+ ]
+ },
+ {
+ "name":"巴中市",
+ "code":"511900",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"511901"
+ },
+ {
+ "name":"巴州区",
+ "code":"511902"
+ },
+ {
+ "name":"恩阳区",
+ "code":"511903"
+ },
+ {
+ "name":"通江县",
+ "code":"511921"
+ },
+ {
+ "name":"南江县",
+ "code":"511922"
+ },
+ {
+ "name":"平昌县",
+ "code":"511923"
+ }
+ ]
+ },
+ {
+ "name":"资阳市",
+ "code":"512000",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"512001"
+ },
+ {
+ "name":"雁江区",
+ "code":"512002"
+ },
+ {
+ "name":"安岳县",
+ "code":"512021"
+ },
+ {
+ "name":"乐至县",
+ "code":"512022"
+ },
+ {
+ "name":"简阳市",
+ "code":"512081"
+ }
+ ]
+ },
+ {
+ "name":"阿坝藏族羌族自治州",
+ "code":"513200",
+ "sub":[
+ {
+ "name":"汶川县",
+ "code":"513221"
+ },
+ {
+ "name":"理县",
+ "code":"513222"
+ },
+ {
+ "name":"茂县",
+ "code":"513223"
+ },
+ {
+ "name":"松潘县",
+ "code":"513224"
+ },
+ {
+ "name":"九寨沟县",
+ "code":"513225"
+ },
+ {
+ "name":"金川县",
+ "code":"513226"
+ },
+ {
+ "name":"小金县",
+ "code":"513227"
+ },
+ {
+ "name":"黑水县",
+ "code":"513228"
+ },
+ {
+ "name":"马尔康县",
+ "code":"513229"
+ },
+ {
+ "name":"壤塘县",
+ "code":"513230"
+ },
+ {
+ "name":"阿坝县",
+ "code":"513231"
+ },
+ {
+ "name":"若尔盖县",
+ "code":"513232"
+ },
+ {
+ "name":"红原县",
+ "code":"513233"
+ }
+ ]
+ },
+ {
+ "name":"甘孜藏族自治州",
+ "code":"513300",
+ "sub":[
+ {
+ "name":"康定县",
+ "code":"513321"
+ },
+ {
+ "name":"泸定县",
+ "code":"513322"
+ },
+ {
+ "name":"丹巴县",
+ "code":"513323"
+ },
+ {
+ "name":"九龙县",
+ "code":"513324"
+ },
+ {
+ "name":"雅江县",
+ "code":"513325"
+ },
+ {
+ "name":"道孚县",
+ "code":"513326"
+ },
+ {
+ "name":"炉霍县",
+ "code":"513327"
+ },
+ {
+ "name":"甘孜县",
+ "code":"513328"
+ },
+ {
+ "name":"新龙县",
+ "code":"513329"
+ },
+ {
+ "name":"德格县",
+ "code":"513330"
+ },
+ {
+ "name":"白玉县",
+ "code":"513331"
+ },
+ {
+ "name":"石渠县",
+ "code":"513332"
+ },
+ {
+ "name":"色达县",
+ "code":"513333"
+ },
+ {
+ "name":"理塘县",
+ "code":"513334"
+ },
+ {
+ "name":"巴塘县",
+ "code":"513335"
+ },
+ {
+ "name":"乡城县",
+ "code":"513336"
+ },
+ {
+ "name":"稻城县",
+ "code":"513337"
+ },
+ {
+ "name":"得荣县",
+ "code":"513338"
+ }
+ ]
+ },
+ {
+ "name":"凉山彝族自治州",
+ "code":"513400",
+ "sub":[
+ {
+ "name":"西昌市",
+ "code":"513401"
+ },
+ {
+ "name":"木里藏族自治县",
+ "code":"513422"
+ },
+ {
+ "name":"盐源县",
+ "code":"513423"
+ },
+ {
+ "name":"德昌县",
+ "code":"513424"
+ },
+ {
+ "name":"会理县",
+ "code":"513425"
+ },
+ {
+ "name":"会东县",
+ "code":"513426"
+ },
+ {
+ "name":"宁南县",
+ "code":"513427"
+ },
+ {
+ "name":"普格县",
+ "code":"513428"
+ },
+ {
+ "name":"布拖县",
+ "code":"513429"
+ },
+ {
+ "name":"金阳县",
+ "code":"513430"
+ },
+ {
+ "name":"昭觉县",
+ "code":"513431"
+ },
+ {
+ "name":"喜德县",
+ "code":"513432"
+ },
+ {
+ "name":"冕宁县",
+ "code":"513433"
+ },
+ {
+ "name":"越西县",
+ "code":"513434"
+ },
+ {
+ "name":"甘洛县",
+ "code":"513435"
+ },
+ {
+ "name":"美姑县",
+ "code":"513436"
+ },
+ {
+ "name":"雷波县",
+ "code":"513437"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name":"贵州省",
+ "code":"520000",
+ "sub":[
+ {
+ "name":"贵阳市",
+ "code":"520100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"520101"
+ },
+ {
+ "name":"南明区",
+ "code":"520102"
+ },
+ {
+ "name":"云岩区",
+ "code":"520103"
+ },
+ {
+ "name":"花溪区",
+ "code":"520111"
+ },
+ {
+ "name":"乌当区",
+ "code":"520112"
+ },
+ {
+ "name":"白云区",
+ "code":"520113"
+ },
+ {
+ "name":"观山湖区",
+ "code":"520115"
+ },
+ {
+ "name":"开阳县",
+ "code":"520121"
+ },
+ {
+ "name":"息烽县",
+ "code":"520122"
+ },
+ {
+ "name":"修文县",
+ "code":"520123"
+ },
+ {
+ "name":"清镇市",
+ "code":"520181"
+ }
+ ]
+ },
+ {
+ "name":"六盘水市",
+ "code":"520200",
+ "sub":[
+ {
+ "name":"钟山区",
+ "code":"520201"
+ },
+ {
+ "name":"六枝特区",
+ "code":"520203"
+ },
+ {
+ "name":"水城县",
+ "code":"520221"
+ },
+ {
+ "name":"盘县",
+ "code":"520222"
+ }
+ ]
+ },
+ {
+ "name":"遵义市",
+ "code":"520300",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"520301"
+ },
+ {
+ "name":"红花岗区",
+ "code":"520302"
+ },
+ {
+ "name":"汇川区",
+ "code":"520303"
+ },
+ {
+ "name":"遵义县",
+ "code":"520321"
+ },
+ {
+ "name":"桐梓县",
+ "code":"520322"
+ },
+ {
+ "name":"绥阳县",
+ "code":"520323"
+ },
+ {
+ "name":"正安县",
+ "code":"520324"
+ },
+ {
+ "name":"道真仡佬族苗族自治县",
+ "code":"520325"
+ },
+ {
+ "name":"务川仡佬族苗族自治县",
+ "code":"520326"
+ },
+ {
+ "name":"凤冈县",
+ "code":"520327"
+ },
+ {
+ "name":"湄潭县",
+ "code":"520328"
+ },
+ {
+ "name":"余庆县",
+ "code":"520329"
+ },
+ {
+ "name":"习水县",
+ "code":"520330"
+ },
+ {
+ "name":"赤水市",
+ "code":"520381"
+ },
+ {
+ "name":"仁怀市",
+ "code":"520382"
+ }
+ ]
+ },
+ {
+ "name":"安顺市",
+ "code":"520400",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"520401"
+ },
+ {
+ "name":"西秀区",
+ "code":"520402"
+ },
+ {
+ "name":"平坝区",
+ "code":"520403"
+ },
+ {
+ "name":"普定县",
+ "code":"520422"
+ },
+ {
+ "name":"镇宁布依族苗族自治县",
+ "code":"520423"
+ },
+ {
+ "name":"关岭布依族苗族自治县",
+ "code":"520424"
+ },
+ {
+ "name":"紫云苗族布依族自治县",
+ "code":"520425"
+ }
+ ]
+ },
+ {
+ "name":"毕节市",
+ "code":"520500",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"520501"
+ },
+ {
+ "name":"七星关区",
+ "code":"520502"
+ },
+ {
+ "name":"大方县",
+ "code":"520521"
+ },
+ {
+ "name":"黔西县",
+ "code":"520522"
+ },
+ {
+ "name":"金沙县",
+ "code":"520523"
+ },
+ {
+ "name":"织金县",
+ "code":"520524"
+ },
+ {
+ "name":"纳雍县",
+ "code":"520525"
+ },
+ {
+ "name":"威宁彝族回族苗族自治县",
+ "code":"520526"
+ },
+ {
+ "name":"赫章县",
+ "code":"520527"
+ }
+ ]
+ },
+ {
+ "name":"铜仁市",
+ "code":"520600",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"520601"
+ },
+ {
+ "name":"碧江区",
+ "code":"520602"
+ },
+ {
+ "name":"万山区",
+ "code":"520603"
+ },
+ {
+ "name":"江口县",
+ "code":"520621"
+ },
+ {
+ "name":"玉屏侗族自治县",
+ "code":"520622"
+ },
+ {
+ "name":"石阡县",
+ "code":"520623"
+ },
+ {
+ "name":"思南县",
+ "code":"520624"
+ },
+ {
+ "name":"印江土家族苗族自治县",
+ "code":"520625"
+ },
+ {
+ "name":"德江县",
+ "code":"520626"
+ },
+ {
+ "name":"沿河土家族自治县",
+ "code":"520627"
+ },
+ {
+ "name":"松桃苗族自治县",
+ "code":"520628"
+ }
+ ]
+ },
+ {
+ "name":"黔西南布依族苗族自治州",
+ "code":"522300",
+ "sub":[
+ {
+ "name":"兴义市",
+ "code":"522301"
+ },
+ {
+ "name":"兴仁县",
+ "code":"522322"
+ },
+ {
+ "name":"普安县",
+ "code":"522323"
+ },
+ {
+ "name":"晴隆县",
+ "code":"522324"
+ },
+ {
+ "name":"贞丰县",
+ "code":"522325"
+ },
+ {
+ "name":"望谟县",
+ "code":"522326"
+ },
+ {
+ "name":"册亨县",
+ "code":"522327"
+ },
+ {
+ "name":"安龙县",
+ "code":"522328"
+ }
+ ]
+ },
+ {
+ "name":"黔东南苗族侗族自治州",
+ "code":"522600",
+ "sub":[
+ {
+ "name":"凯里市",
+ "code":"522601"
+ },
+ {
+ "name":"黄平县",
+ "code":"522622"
+ },
+ {
+ "name":"施秉县",
+ "code":"522623"
+ },
+ {
+ "name":"三穗县",
+ "code":"522624"
+ },
+ {
+ "name":"镇远县",
+ "code":"522625"
+ },
+ {
+ "name":"岑巩县",
+ "code":"522626"
+ },
+ {
+ "name":"天柱县",
+ "code":"522627"
+ },
+ {
+ "name":"锦屏县",
+ "code":"522628"
+ },
+ {
+ "name":"剑河县",
+ "code":"522629"
+ },
+ {
+ "name":"台江县",
+ "code":"522630"
+ },
+ {
+ "name":"黎平县",
+ "code":"522631"
+ },
+ {
+ "name":"榕江县",
+ "code":"522632"
+ },
+ {
+ "name":"从江县",
+ "code":"522633"
+ },
+ {
+ "name":"雷山县",
+ "code":"522634"
+ },
+ {
+ "name":"麻江县",
+ "code":"522635"
+ },
+ {
+ "name":"丹寨县",
+ "code":"522636"
+ }
+ ]
+ },
+ {
+ "name":"黔南布依族苗族自治州",
+ "code":"522700",
+ "sub":[
+ {
+ "name":"都匀市",
+ "code":"522701"
+ },
+ {
+ "name":"福泉市",
+ "code":"522702"
+ },
+ {
+ "name":"荔波县",
+ "code":"522722"
+ },
+ {
+ "name":"贵定县",
+ "code":"522723"
+ },
+ {
+ "name":"瓮安县",
+ "code":"522725"
+ },
+ {
+ "name":"独山县",
+ "code":"522726"
+ },
+ {
+ "name":"平塘县",
+ "code":"522727"
+ },
+ {
+ "name":"罗甸县",
+ "code":"522728"
+ },
+ {
+ "name":"长顺县",
+ "code":"522729"
+ },
+ {
+ "name":"龙里县",
+ "code":"522730"
+ },
+ {
+ "name":"惠水县",
+ "code":"522731"
+ },
+ {
+ "name":"三都水族自治县",
+ "code":"522732"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name":"云南省",
+ "code":"530000",
+ "sub":[
+ {
+ "name":"昆明市",
+ "code":"530100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"530101"
+ },
+ {
+ "name":"五华区",
+ "code":"530102"
+ },
+ {
+ "name":"盘龙区",
+ "code":"530103"
+ },
+ {
+ "name":"官渡区",
+ "code":"530111"
+ },
+ {
+ "name":"西山区",
+ "code":"530112"
+ },
+ {
+ "name":"东川区",
+ "code":"530113"
+ },
+ {
+ "name":"呈贡区",
+ "code":"530114"
+ },
+ {
+ "name":"晋宁县",
+ "code":"530122"
+ },
+ {
+ "name":"富民县",
+ "code":"530124"
+ },
+ {
+ "name":"宜良县",
+ "code":"530125"
+ },
+ {
+ "name":"石林彝族自治县",
+ "code":"530126"
+ },
+ {
+ "name":"嵩明县",
+ "code":"530127"
+ },
+ {
+ "name":"禄劝彝族苗族自治县",
+ "code":"530128"
+ },
+ {
+ "name":"寻甸回族彝族自治县",
+ "code":"530129"
+ },
+ {
+ "name":"安宁市",
+ "code":"530181"
+ }
+ ]
+ },
+ {
+ "name":"曲靖市",
+ "code":"530300",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"530301"
+ },
+ {
+ "name":"麒麟区",
+ "code":"530302"
+ },
+ {
+ "name":"马龙县",
+ "code":"530321"
+ },
+ {
+ "name":"陆良县",
+ "code":"530322"
+ },
+ {
+ "name":"师宗县",
+ "code":"530323"
+ },
+ {
+ "name":"罗平县",
+ "code":"530324"
+ },
+ {
+ "name":"富源县",
+ "code":"530325"
+ },
+ {
+ "name":"会泽县",
+ "code":"530326"
+ },
+ {
+ "name":"沾益县",
+ "code":"530328"
+ },
+ {
+ "name":"宣威市",
+ "code":"530381"
+ }
+ ]
+ },
+ {
+ "name":"玉溪市",
+ "code":"530400",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"530401"
+ },
+ {
+ "name":"红塔区",
+ "code":"530402"
+ },
+ {
+ "name":"江川县",
+ "code":"530421"
+ },
+ {
+ "name":"澄江县",
+ "code":"530422"
+ },
+ {
+ "name":"通海县",
+ "code":"530423"
+ },
+ {
+ "name":"华宁县",
+ "code":"530424"
+ },
+ {
+ "name":"易门县",
+ "code":"530425"
+ },
+ {
+ "name":"峨山彝族自治县",
+ "code":"530426"
+ },
+ {
+ "name":"新平彝族傣族自治县",
+ "code":"530427"
+ },
+ {
+ "name":"元江哈尼族彝族傣族自治县",
+ "code":"530428"
+ }
+ ]
+ },
+ {
+ "name":"保山市",
+ "code":"530500",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"530501"
+ },
+ {
+ "name":"隆阳区",
+ "code":"530502"
+ },
+ {
+ "name":"施甸县",
+ "code":"530521"
+ },
+ {
+ "name":"腾冲县",
+ "code":"530522"
+ },
+ {
+ "name":"龙陵县",
+ "code":"530523"
+ },
+ {
+ "name":"昌宁县",
+ "code":"530524"
+ }
+ ]
+ },
+ {
+ "name":"昭通市",
+ "code":"530600",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"530601"
+ },
+ {
+ "name":"昭阳区",
+ "code":"530602"
+ },
+ {
+ "name":"鲁甸县",
+ "code":"530621"
+ },
+ {
+ "name":"巧家县",
+ "code":"530622"
+ },
+ {
+ "name":"盐津县",
+ "code":"530623"
+ },
+ {
+ "name":"大关县",
+ "code":"530624"
+ },
+ {
+ "name":"永善县",
+ "code":"530625"
+ },
+ {
+ "name":"绥江县",
+ "code":"530626"
+ },
+ {
+ "name":"镇雄县",
+ "code":"530627"
+ },
+ {
+ "name":"彝良县",
+ "code":"530628"
+ },
+ {
+ "name":"威信县",
+ "code":"530629"
+ },
+ {
+ "name":"水富县",
+ "code":"530630"
+ }
+ ]
+ },
+ {
+ "name":"丽江市",
+ "code":"530700",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"530701"
+ },
+ {
+ "name":"古城区",
+ "code":"530702"
+ },
+ {
+ "name":"玉龙纳西族自治县",
+ "code":"530721"
+ },
+ {
+ "name":"永胜县",
+ "code":"530722"
+ },
+ {
+ "name":"华坪县",
+ "code":"530723"
+ },
+ {
+ "name":"宁蒗彝族自治县",
+ "code":"530724"
+ }
+ ]
+ },
+ {
+ "name":"普洱市",
+ "code":"530800",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"530801"
+ },
+ {
+ "name":"思茅区",
+ "code":"530802"
+ },
+ {
+ "name":"宁洱哈尼族彝族自治县",
+ "code":"530821"
+ },
+ {
+ "name":"墨江哈尼族自治县",
+ "code":"530822"
+ },
+ {
+ "name":"景东彝族自治县",
+ "code":"530823"
+ },
+ {
+ "name":"景谷傣族彝族自治县",
+ "code":"530824"
+ },
+ {
+ "name":"镇沅彝族哈尼族拉祜族自治县",
+ "code":"530825"
+ },
+ {
+ "name":"江城哈尼族彝族自治县",
+ "code":"530826"
+ },
+ {
+ "name":"孟连傣族拉祜族佤族自治县",
+ "code":"530827"
+ },
+ {
+ "name":"澜沧拉祜族自治县",
+ "code":"530828"
+ },
+ {
+ "name":"西盟佤族自治县",
+ "code":"530829"
+ }
+ ]
+ },
+ {
+ "name":"临沧市",
+ "code":"530900",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"530901"
+ },
+ {
+ "name":"临翔区",
+ "code":"530902"
+ },
+ {
+ "name":"凤庆县",
+ "code":"530921"
+ },
+ {
+ "name":"云县",
+ "code":"530922"
+ },
+ {
+ "name":"永德县",
+ "code":"530923"
+ },
+ {
+ "name":"镇康县",
+ "code":"530924"
+ },
+ {
+ "name":"双江拉祜族佤族布朗族傣族自治县",
+ "code":"530925"
+ },
+ {
+ "name":"耿马傣族佤族自治县",
+ "code":"530926"
+ },
+ {
+ "name":"沧源佤族自治县",
+ "code":"530927"
+ }
+ ]
+ },
+ {
+ "name":"楚雄彝族自治州",
+ "code":"532300",
+ "sub":[
+ {
+ "name":"楚雄市",
+ "code":"532301"
+ },
+ {
+ "name":"双柏县",
+ "code":"532322"
+ },
+ {
+ "name":"牟定县",
+ "code":"532323"
+ },
+ {
+ "name":"南华县",
+ "code":"532324"
+ },
+ {
+ "name":"姚安县",
+ "code":"532325"
+ },
+ {
+ "name":"大姚县",
+ "code":"532326"
+ },
+ {
+ "name":"永仁县",
+ "code":"532327"
+ },
+ {
+ "name":"元谋县",
+ "code":"532328"
+ },
+ {
+ "name":"武定县",
+ "code":"532329"
+ },
+ {
+ "name":"禄丰县",
+ "code":"532331"
+ }
+ ]
+ },
+ {
+ "name":"红河哈尼族彝族自治州",
+ "code":"532500",
+ "sub":[
+ {
+ "name":"个旧市",
+ "code":"532501"
+ },
+ {
+ "name":"开远市",
+ "code":"532502"
+ },
+ {
+ "name":"蒙自市",
+ "code":"532503"
+ },
+ {
+ "name":"弥勒市",
+ "code":"532504"
+ },
+ {
+ "name":"屏边苗族自治县",
+ "code":"532523"
+ },
+ {
+ "name":"建水县",
+ "code":"532524"
+ },
+ {
+ "name":"石屏县",
+ "code":"532525"
+ },
+ {
+ "name":"泸西县",
+ "code":"532527"
+ },
+ {
+ "name":"元阳县",
+ "code":"532528"
+ },
+ {
+ "name":"红河县",
+ "code":"532529"
+ },
+ {
+ "name":"金平苗族瑶族傣族自治县",
+ "code":"532530"
+ },
+ {
+ "name":"绿春县",
+ "code":"532531"
+ },
+ {
+ "name":"河口瑶族自治县",
+ "code":"532532"
+ }
+ ]
+ },
+ {
+ "name":"文山壮族苗族自治州",
+ "code":"532600",
+ "sub":[
+ {
+ "name":"文山市",
+ "code":"532601"
+ },
+ {
+ "name":"砚山县",
+ "code":"532622"
+ },
+ {
+ "name":"西畴县",
+ "code":"532623"
+ },
+ {
+ "name":"麻栗坡县",
+ "code":"532624"
+ },
+ {
+ "name":"马关县",
+ "code":"532625"
+ },
+ {
+ "name":"丘北县",
+ "code":"532626"
+ },
+ {
+ "name":"广南县",
+ "code":"532627"
+ },
+ {
+ "name":"富宁县",
+ "code":"532628"
+ }
+ ]
+ },
+ {
+ "name":"西双版纳傣族自治州",
+ "code":"532800",
+ "sub":[
+ {
+ "name":"景洪市",
+ "code":"532801"
+ },
+ {
+ "name":"勐海县",
+ "code":"532822"
+ },
+ {
+ "name":"勐腊县",
+ "code":"532823"
+ }
+ ]
+ },
+ {
+ "name":"大理白族自治州",
+ "code":"532900",
+ "sub":[
+ {
+ "name":"大理市",
+ "code":"532901"
+ },
+ {
+ "name":"漾濞彝族自治县",
+ "code":"532922"
+ },
+ {
+ "name":"祥云县",
+ "code":"532923"
+ },
+ {
+ "name":"宾川县",
+ "code":"532924"
+ },
+ {
+ "name":"弥渡县",
+ "code":"532925"
+ },
+ {
+ "name":"南涧彝族自治县",
+ "code":"532926"
+ },
+ {
+ "name":"巍山彝族回族自治县",
+ "code":"532927"
+ },
+ {
+ "name":"永平县",
+ "code":"532928"
+ },
+ {
+ "name":"云龙县",
+ "code":"532929"
+ },
+ {
+ "name":"洱源县",
+ "code":"532930"
+ },
+ {
+ "name":"剑川县",
+ "code":"532931"
+ },
+ {
+ "name":"鹤庆县",
+ "code":"532932"
+ }
+ ]
+ },
+ {
+ "name":"德宏傣族景颇族自治州",
+ "code":"533100",
+ "sub":[
+ {
+ "name":"瑞丽市",
+ "code":"533102"
+ },
+ {
+ "name":"芒市",
+ "code":"533103"
+ },
+ {
+ "name":"梁河县",
+ "code":"533122"
+ },
+ {
+ "name":"盈江县",
+ "code":"533123"
+ },
+ {
+ "name":"陇川县",
+ "code":"533124"
+ }
+ ]
+ },
+ {
+ "name":"怒江傈僳族自治州",
+ "code":"533300",
+ "sub":[
+ {
+ "name":"泸水县",
+ "code":"533321"
+ },
+ {
+ "name":"福贡县",
+ "code":"533323"
+ },
+ {
+ "name":"贡山独龙族怒族自治县",
+ "code":"533324"
+ },
+ {
+ "name":"兰坪白族普米族自治县",
+ "code":"533325"
+ }
+ ]
+ },
+ {
+ "name":"迪庆藏族自治州",
+ "code":"533400",
+ "sub":[
+ {
+ "name":"香格里拉市",
+ "code":"533401"
+ },
+ {
+ "name":"德钦县",
+ "code":"533422"
+ },
+ {
+ "name":"维西傈僳族自治县",
+ "code":"533423"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name":"西藏自治区",
+ "code":"540000",
+ "sub":[
+ {
+ "name":"拉萨市",
+ "code":"540100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"540101"
+ },
+ {
+ "name":"城关区",
+ "code":"540102"
+ },
+ {
+ "name":"林周县",
+ "code":"540121"
+ },
+ {
+ "name":"当雄县",
+ "code":"540122"
+ },
+ {
+ "name":"尼木县",
+ "code":"540123"
+ },
+ {
+ "name":"曲水县",
+ "code":"540124"
+ },
+ {
+ "name":"堆龙德庆县",
+ "code":"540125"
+ },
+ {
+ "name":"达孜县",
+ "code":"540126"
+ },
+ {
+ "name":"墨竹工卡县",
+ "code":"540127"
+ }
+ ]
+ },
+ {
+ "name":"日喀则市",
+ "code":"540200",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"540201"
+ },
+ {
+ "name":"桑珠孜区",
+ "code":"540202"
+ },
+ {
+ "name":"南木林县",
+ "code":"540221"
+ },
+ {
+ "name":"江孜县",
+ "code":"540222"
+ },
+ {
+ "name":"定日县",
+ "code":"540223"
+ },
+ {
+ "name":"萨迦县",
+ "code":"540224"
+ },
+ {
+ "name":"拉孜县",
+ "code":"540225"
+ },
+ {
+ "name":"昂仁县",
+ "code":"540226"
+ },
+ {
+ "name":"谢通门县",
+ "code":"540227"
+ },
+ {
+ "name":"白朗县",
+ "code":"540228"
+ },
+ {
+ "name":"仁布县",
+ "code":"540229"
+ },
+ {
+ "name":"康马县",
+ "code":"540230"
+ },
+ {
+ "name":"定结县",
+ "code":"540231"
+ },
+ {
+ "name":"仲巴县",
+ "code":"540232"
+ },
+ {
+ "name":"亚东县",
+ "code":"540233"
+ },
+ {
+ "name":"吉隆县",
+ "code":"540234"
+ },
+ {
+ "name":"聂拉木县",
+ "code":"540235"
+ },
+ {
+ "name":"萨嘎县",
+ "code":"540236"
+ },
+ {
+ "name":"岗巴县",
+ "code":"540237"
+ }
+ ]
+ },
+ {
+ "name":"昌都市",
+ "code":"540300",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"540301"
+ },
+ {
+ "name":"卡若区",
+ "code":"540302"
+ },
+ {
+ "name":"江达县",
+ "code":"540321"
+ },
+ {
+ "name":"贡觉县",
+ "code":"540322"
+ },
+ {
+ "name":"类乌齐县",
+ "code":"540323"
+ },
+ {
+ "name":"丁青县",
+ "code":"540324"
+ },
+ {
+ "name":"察雅县",
+ "code":"540325"
+ },
+ {
+ "name":"八宿县",
+ "code":"540326"
+ },
+ {
+ "name":"左贡县",
+ "code":"540327"
+ },
+ {
+ "name":"芒康县",
+ "code":"540328"
+ },
+ {
+ "name":"洛隆县",
+ "code":"540329"
+ },
+ {
+ "name":"边坝县",
+ "code":"540330"
+ }
+ ]
+ },
+ {
+ "name":"山南地区",
+ "code":"542200",
+ "sub":[
+ {
+ "name":"乃东县",
+ "code":"542221"
+ },
+ {
+ "name":"扎囊县",
+ "code":"542222"
+ },
+ {
+ "name":"贡嘎县",
+ "code":"542223"
+ },
+ {
+ "name":"桑日县",
+ "code":"542224"
+ },
+ {
+ "name":"琼结县",
+ "code":"542225"
+ },
+ {
+ "name":"曲松县",
+ "code":"542226"
+ },
+ {
+ "name":"措美县",
+ "code":"542227"
+ },
+ {
+ "name":"洛扎县",
+ "code":"542228"
+ },
+ {
+ "name":"加查县",
+ "code":"542229"
+ },
+ {
+ "name":"隆子县",
+ "code":"542231"
+ },
+ {
+ "name":"错那县",
+ "code":"542232"
+ },
+ {
+ "name":"浪卡子县",
+ "code":"542233"
+ }
+ ]
+ },
+ {
+ "name":"那曲地区",
+ "code":"542400",
+ "sub":[
+ {
+ "name":"那曲县",
+ "code":"542421"
+ },
+ {
+ "name":"嘉黎县",
+ "code":"542422"
+ },
+ {
+ "name":"比如县",
+ "code":"542423"
+ },
+ {
+ "name":"聂荣县",
+ "code":"542424"
+ },
+ {
+ "name":"安多县",
+ "code":"542425"
+ },
+ {
+ "name":"申扎县",
+ "code":"542426"
+ },
+ {
+ "name":"索县",
+ "code":"542427"
+ },
+ {
+ "name":"班戈县",
+ "code":"542428"
+ },
+ {
+ "name":"巴青县",
+ "code":"542429"
+ },
+ {
+ "name":"尼玛县",
+ "code":"542430"
+ },
+ {
+ "name":"双湖县",
+ "code":"542431"
+ }
+ ]
+ },
+ {
+ "name":"阿里地区",
+ "code":"542500",
+ "sub":[
+ {
+ "name":"普兰县",
+ "code":"542521"
+ },
+ {
+ "name":"札达县",
+ "code":"542522"
+ },
+ {
+ "name":"噶尔县",
+ "code":"542523"
+ },
+ {
+ "name":"日土县",
+ "code":"542524"
+ },
+ {
+ "name":"革吉县",
+ "code":"542525"
+ },
+ {
+ "name":"改则县",
+ "code":"542526"
+ },
+ {
+ "name":"措勤县",
+ "code":"542527"
+ }
+ ]
+ },
+ {
+ "name":"林芝地区",
+ "code":"542600",
+ "sub":[
+ {
+ "name":"林芝县",
+ "code":"542621"
+ },
+ {
+ "name":"工布江达县",
+ "code":"542622"
+ },
+ {
+ "name":"米林县",
+ "code":"542623"
+ },
+ {
+ "name":"墨脱县",
+ "code":"542624"
+ },
+ {
+ "name":"波密县",
+ "code":"542625"
+ },
+ {
+ "name":"察隅县",
+ "code":"542626"
+ },
+ {
+ "name":"朗县",
+ "code":"542627"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name":"陕西省",
+ "code":"610000",
+ "sub":[
+ {
+ "name":"西安市",
+ "code":"610100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"610101"
+ },
+ {
+ "name":"新城区",
+ "code":"610102"
+ },
+ {
+ "name":"碑林区",
+ "code":"610103"
+ },
+ {
+ "name":"莲湖区",
+ "code":"610104"
+ },
+ {
+ "name":"灞桥区",
+ "code":"610111"
+ },
+ {
+ "name":"未央区",
+ "code":"610112"
+ },
+ {
+ "name":"雁塔区",
+ "code":"610113"
+ },
+ {
+ "name":"阎良区",
+ "code":"610114"
+ },
+ {
+ "name":"临潼区",
+ "code":"610115"
+ },
+ {
+ "name":"长安区",
+ "code":"610116"
+ },
+ {
+ "name":"高陵区",
+ "code":"610117"
+ },
+ {
+ "name":"蓝田县",
+ "code":"610122"
+ },
+ {
+ "name":"周至县",
+ "code":"610124"
+ },
+ {
+ "name":"户县",
+ "code":"610125"
+ }
+ ]
+ },
+ {
+ "name":"铜川市",
+ "code":"610200",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"610201"
+ },
+ {
+ "name":"王益区",
+ "code":"610202"
+ },
+ {
+ "name":"印台区",
+ "code":"610203"
+ },
+ {
+ "name":"耀州区",
+ "code":"610204"
+ },
+ {
+ "name":"宜君县",
+ "code":"610222"
+ }
+ ]
+ },
+ {
+ "name":"宝鸡市",
+ "code":"610300",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"610301"
+ },
+ {
+ "name":"渭滨区",
+ "code":"610302"
+ },
+ {
+ "name":"金台区",
+ "code":"610303"
+ },
+ {
+ "name":"陈仓区",
+ "code":"610304"
+ },
+ {
+ "name":"凤翔县",
+ "code":"610322"
+ },
+ {
+ "name":"岐山县",
+ "code":"610323"
+ },
+ {
+ "name":"扶风县",
+ "code":"610324"
+ },
+ {
+ "name":"眉县",
+ "code":"610326"
+ },
+ {
+ "name":"陇县",
+ "code":"610327"
+ },
+ {
+ "name":"千阳县",
+ "code":"610328"
+ },
+ {
+ "name":"麟游县",
+ "code":"610329"
+ },
+ {
+ "name":"凤县",
+ "code":"610330"
+ },
+ {
+ "name":"太白县",
+ "code":"610331"
+ }
+ ]
+ },
+ {
+ "name":"咸阳市",
+ "code":"610400",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"610401"
+ },
+ {
+ "name":"秦都区",
+ "code":"610402"
+ },
+ {
+ "name":"杨陵区",
+ "code":"610403"
+ },
+ {
+ "name":"渭城区",
+ "code":"610404"
+ },
+ {
+ "name":"三原县",
+ "code":"610422"
+ },
+ {
+ "name":"泾阳县",
+ "code":"610423"
+ },
+ {
+ "name":"乾县",
+ "code":"610424"
+ },
+ {
+ "name":"礼泉县",
+ "code":"610425"
+ },
+ {
+ "name":"永寿县",
+ "code":"610426"
+ },
+ {
+ "name":"彬县",
+ "code":"610427"
+ },
+ {
+ "name":"长武县",
+ "code":"610428"
+ },
+ {
+ "name":"旬邑县",
+ "code":"610429"
+ },
+ {
+ "name":"淳化县",
+ "code":"610430"
+ },
+ {
+ "name":"武功县",
+ "code":"610431"
+ },
+ {
+ "name":"兴平市",
+ "code":"610481"
+ }
+ ]
+ },
+ {
+ "name":"渭南市",
+ "code":"610500",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"610501"
+ },
+ {
+ "name":"临渭区",
+ "code":"610502"
+ },
+ {
+ "name":"华县",
+ "code":"610521"
+ },
+ {
+ "name":"潼关县",
+ "code":"610522"
+ },
+ {
+ "name":"大荔县",
+ "code":"610523"
+ },
+ {
+ "name":"合阳县",
+ "code":"610524"
+ },
+ {
+ "name":"澄城县",
+ "code":"610525"
+ },
+ {
+ "name":"蒲城县",
+ "code":"610526"
+ },
+ {
+ "name":"白水县",
+ "code":"610527"
+ },
+ {
+ "name":"富平县",
+ "code":"610528"
+ },
+ {
+ "name":"韩城市",
+ "code":"610581"
+ },
+ {
+ "name":"华阴市",
+ "code":"610582"
+ }
+ ]
+ },
+ {
+ "name":"延安市",
+ "code":"610600",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"610601"
+ },
+ {
+ "name":"宝塔区",
+ "code":"610602"
+ },
+ {
+ "name":"延长县",
+ "code":"610621"
+ },
+ {
+ "name":"延川县",
+ "code":"610622"
+ },
+ {
+ "name":"子长县",
+ "code":"610623"
+ },
+ {
+ "name":"安塞县",
+ "code":"610624"
+ },
+ {
+ "name":"志丹县",
+ "code":"610625"
+ },
+ {
+ "name":"吴起县",
+ "code":"610626"
+ },
+ {
+ "name":"甘泉县",
+ "code":"610627"
+ },
+ {
+ "name":"富县",
+ "code":"610628"
+ },
+ {
+ "name":"洛川县",
+ "code":"610629"
+ },
+ {
+ "name":"宜川县",
+ "code":"610630"
+ },
+ {
+ "name":"黄龙县",
+ "code":"610631"
+ },
+ {
+ "name":"黄陵县",
+ "code":"610632"
+ }
+ ]
+ },
+ {
+ "name":"汉中市",
+ "code":"610700",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"610701"
+ },
+ {
+ "name":"汉台区",
+ "code":"610702"
+ },
+ {
+ "name":"南郑县",
+ "code":"610721"
+ },
+ {
+ "name":"城固县",
+ "code":"610722"
+ },
+ {
+ "name":"洋县",
+ "code":"610723"
+ },
+ {
+ "name":"西乡县",
+ "code":"610724"
+ },
+ {
+ "name":"勉县",
+ "code":"610725"
+ },
+ {
+ "name":"宁强县",
+ "code":"610726"
+ },
+ {
+ "name":"略阳县",
+ "code":"610727"
+ },
+ {
+ "name":"镇巴县",
+ "code":"610728"
+ },
+ {
+ "name":"留坝县",
+ "code":"610729"
+ },
+ {
+ "name":"佛坪县",
+ "code":"610730"
+ }
+ ]
+ },
+ {
+ "name":"榆林市",
+ "code":"610800",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"610801"
+ },
+ {
+ "name":"榆阳区",
+ "code":"610802"
+ },
+ {
+ "name":"神木县",
+ "code":"610821"
+ },
+ {
+ "name":"府谷县",
+ "code":"610822"
+ },
+ {
+ "name":"横山县",
+ "code":"610823"
+ },
+ {
+ "name":"靖边县",
+ "code":"610824"
+ },
+ {
+ "name":"定边县",
+ "code":"610825"
+ },
+ {
+ "name":"绥德县",
+ "code":"610826"
+ },
+ {
+ "name":"米脂县",
+ "code":"610827"
+ },
+ {
+ "name":"佳县",
+ "code":"610828"
+ },
+ {
+ "name":"吴堡县",
+ "code":"610829"
+ },
+ {
+ "name":"清涧县",
+ "code":"610830"
+ },
+ {
+ "name":"子洲县",
+ "code":"610831"
+ }
+ ]
+ },
+ {
+ "name":"安康市",
+ "code":"610900",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"610901"
+ },
+ {
+ "name":"汉阴县",
+ "code":"610921"
+ },
+ {
+ "name":"石泉县",
+ "code":"610922"
+ },
+ {
+ "name":"宁陕县",
+ "code":"610923"
+ },
+ {
+ "name":"紫阳县",
+ "code":"610924"
+ },
+ {
+ "name":"岚皋县",
+ "code":"610925"
+ },
+ {
+ "name":"平利县",
+ "code":"610926"
+ },
+ {
+ "name":"镇坪县",
+ "code":"610927"
+ },
+ {
+ "name":"旬阳县",
+ "code":"610928"
+ },
+ {
+ "name":"白河县",
+ "code":"610929"
+ }
+ ]
+ },
+ {
+ "name":"商洛市",
+ "code":"611000",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"611001"
+ },
+ {
+ "name":"商州区",
+ "code":"611002"
+ },
+ {
+ "name":"洛南县",
+ "code":"611021"
+ },
+ {
+ "name":"丹凤县",
+ "code":"611022"
+ },
+ {
+ "name":"商南县",
+ "code":"611023"
+ },
+ {
+ "name":"山阳县",
+ "code":"611024"
+ },
+ {
+ "name":"镇安县",
+ "code":"611025"
+ },
+ {
+ "name":"柞水县",
+ "code":"611026"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name":"甘肃省",
+ "code":"620000",
+ "sub":[
+ {
+ "name":"兰州市",
+ "code":"620100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"620101"
+ },
+ {
+ "name":"城关区",
+ "code":"620102"
+ },
+ {
+ "name":"七里河区",
+ "code":"620103"
+ },
+ {
+ "name":"西固区",
+ "code":"620104"
+ },
+ {
+ "name":"安宁区",
+ "code":"620105"
+ },
+ {
+ "name":"红古区",
+ "code":"620111"
+ },
+ {
+ "name":"永登县",
+ "code":"620121"
+ },
+ {
+ "name":"皋兰县",
+ "code":"620122"
+ },
+ {
+ "name":"榆中县",
+ "code":"620123"
+ }
+ ]
+ },
+ {
+ "name":"嘉峪关市",
+ "code":"620200",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"620201"
+ }
+ ]
+ },
+ {
+ "name":"金昌市",
+ "code":"620300",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"620301"
+ },
+ {
+ "name":"金川区",
+ "code":"620302"
+ },
+ {
+ "name":"永昌县",
+ "code":"620321"
+ }
+ ]
+ },
+ {
+ "name":"白银市",
+ "code":"620400",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"620401"
+ },
+ {
+ "name":"白银区",
+ "code":"620402"
+ },
+ {
+ "name":"平川区",
+ "code":"620403"
+ },
+ {
+ "name":"靖远县",
+ "code":"620421"
+ },
+ {
+ "name":"会宁县",
+ "code":"620422"
+ },
+ {
+ "name":"景泰县",
+ "code":"620423"
+ }
+ ]
+ },
+ {
+ "name":"天水市",
+ "code":"620500",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"620501"
+ },
+ {
+ "name":"秦州区",
+ "code":"620502"
+ },
+ {
+ "name":"麦积区",
+ "code":"620503"
+ },
+ {
+ "name":"清水县",
+ "code":"620521"
+ },
+ {
+ "name":"秦安县",
+ "code":"620522"
+ },
+ {
+ "name":"甘谷县",
+ "code":"620523"
+ },
+ {
+ "name":"武山县",
+ "code":"620524"
+ },
+ {
+ "name":"张家川回族自治县",
+ "code":"620525"
+ }
+ ]
+ },
+ {
+ "name":"武威市",
+ "code":"620600",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"620601"
+ },
+ {
+ "name":"凉州区",
+ "code":"620602"
+ },
+ {
+ "name":"民勤县",
+ "code":"620621"
+ },
+ {
+ "name":"古浪县",
+ "code":"620622"
+ },
+ {
+ "name":"天祝藏族自治县",
+ "code":"620623"
+ }
+ ]
+ },
+ {
+ "name":"张掖市",
+ "code":"620700",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"620701"
+ },
+ {
+ "name":"甘州区",
+ "code":"620702"
+ },
+ {
+ "name":"肃南裕固族自治县",
+ "code":"620721"
+ },
+ {
+ "name":"民乐县",
+ "code":"620722"
+ },
+ {
+ "name":"临泽县",
+ "code":"620723"
+ },
+ {
+ "name":"高台县",
+ "code":"620724"
+ },
+ {
+ "name":"山丹县",
+ "code":"620725"
+ }
+ ]
+ },
+ {
+ "name":"平凉市",
+ "code":"620800",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"620801"
+ },
+ {
+ "name":"崆峒区",
+ "code":"620802"
+ },
+ {
+ "name":"泾川县",
+ "code":"620821"
+ },
+ {
+ "name":"灵台县",
+ "code":"620822"
+ },
+ {
+ "name":"崇信县",
+ "code":"620823"
+ },
+ {
+ "name":"华亭县",
+ "code":"620824"
+ },
+ {
+ "name":"庄浪县",
+ "code":"620825"
+ },
+ {
+ "name":"静宁县",
+ "code":"620826"
+ }
+ ]
+ },
+ {
+ "name":"酒泉市",
+ "code":"620900",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"620901"
+ },
+ {
+ "name":"肃州区",
+ "code":"620902"
+ },
+ {
+ "name":"金塔县",
+ "code":"620921"
+ },
+ {
+ "name":"瓜州县",
+ "code":"620922"
+ },
+ {
+ "name":"肃北蒙古族自治县",
+ "code":"620923"
+ },
+ {
+ "name":"阿克塞哈萨克族自治县",
+ "code":"620924"
+ },
+ {
+ "name":"玉门市",
+ "code":"620981"
+ },
+ {
+ "name":"敦煌市",
+ "code":"620982"
+ }
+ ]
+ },
+ {
+ "name":"庆阳市",
+ "code":"621000",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"621001"
+ },
+ {
+ "name":"西峰区",
+ "code":"621002"
+ },
+ {
+ "name":"庆城县",
+ "code":"621021"
+ },
+ {
+ "name":"环县",
+ "code":"621022"
+ },
+ {
+ "name":"华池县",
+ "code":"621023"
+ },
+ {
+ "name":"合水县",
+ "code":"621024"
+ },
+ {
+ "name":"正宁县",
+ "code":"621025"
+ },
+ {
+ "name":"宁县",
+ "code":"621026"
+ },
+ {
+ "name":"镇原县",
+ "code":"621027"
+ }
+ ]
+ },
+ {
+ "name":"定西市",
+ "code":"621100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"621101"
+ },
+ {
+ "name":"安定区",
+ "code":"621102"
+ },
+ {
+ "name":"通渭县",
+ "code":"621121"
+ },
+ {
+ "name":"陇西县",
+ "code":"621122"
+ },
+ {
+ "name":"渭源县",
+ "code":"621123"
+ },
+ {
+ "name":"临洮县",
+ "code":"621124"
+ },
+ {
+ "name":"漳县",
+ "code":"621125"
+ },
+ {
+ "name":"岷县",
+ "code":"621126"
+ }
+ ]
+ },
+ {
+ "name":"陇南市",
+ "code":"621200",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"621201"
+ },
+ {
+ "name":"武都区",
+ "code":"621202"
+ },
+ {
+ "name":"成县",
+ "code":"621221"
+ },
+ {
+ "name":"文县",
+ "code":"621222"
+ },
+ {
+ "name":"宕昌县",
+ "code":"621223"
+ },
+ {
+ "name":"康县",
+ "code":"621224"
+ },
+ {
+ "name":"西和县",
+ "code":"621225"
+ },
+ {
+ "name":"礼县",
+ "code":"621226"
+ },
+ {
+ "name":"徽县",
+ "code":"621227"
+ },
+ {
+ "name":"两当县",
+ "code":"621228"
+ }
+ ]
+ },
+ {
+ "name":"临夏回族自治州",
+ "code":"622900",
+ "sub":[
+ {
+ "name":"临夏市",
+ "code":"622901"
+ },
+ {
+ "name":"临夏县",
+ "code":"622921"
+ },
+ {
+ "name":"康乐县",
+ "code":"622922"
+ },
+ {
+ "name":"永靖县",
+ "code":"622923"
+ },
+ {
+ "name":"广河县",
+ "code":"622924"
+ },
+ {
+ "name":"和政县",
+ "code":"622925"
+ },
+ {
+ "name":"东乡族自治县",
+ "code":"622926"
+ },
+ {
+ "name":"积石山保安族东乡族撒拉族自治县",
+ "code":"622927"
+ }
+ ]
+ },
+ {
+ "name":"甘南藏族自治州",
+ "code":"623000",
+ "sub":[
+ {
+ "name":"合作市",
+ "code":"623001"
+ },
+ {
+ "name":"临潭县",
+ "code":"623021"
+ },
+ {
+ "name":"卓尼县",
+ "code":"623022"
+ },
+ {
+ "name":"舟曲县",
+ "code":"623023"
+ },
+ {
+ "name":"迭部县",
+ "code":"623024"
+ },
+ {
+ "name":"玛曲县",
+ "code":"623025"
+ },
+ {
+ "name":"碌曲县",
+ "code":"623026"
+ },
+ {
+ "name":"夏河县",
+ "code":"623027"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name":"青海省",
+ "code":"630000",
+ "sub":[
+ {
+ "name":"西宁市",
+ "code":"630100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"630101"
+ },
+ {
+ "name":"城东区",
+ "code":"630102"
+ },
+ {
+ "name":"城中区",
+ "code":"630103"
+ },
+ {
+ "name":"城西区",
+ "code":"630104"
+ },
+ {
+ "name":"城北区",
+ "code":"630105"
+ },
+ {
+ "name":"大通回族土族自治县",
+ "code":"630121"
+ },
+ {
+ "name":"湟中县",
+ "code":"630122"
+ },
+ {
+ "name":"湟源县",
+ "code":"630123"
+ }
+ ]
+ },
+ {
+ "name":"海东市",
+ "code":"630200",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"630201"
+ },
+ {
+ "name":"乐都区",
+ "code":"630202"
+ },
+ {
+ "name":"平安县",
+ "code":"630221"
+ },
+ {
+ "name":"民和回族土族自治县",
+ "code":"630222"
+ },
+ {
+ "name":"互助土族自治县",
+ "code":"630223"
+ },
+ {
+ "name":"化隆回族自治县",
+ "code":"630224"
+ },
+ {
+ "name":"循化撒拉族自治县",
+ "code":"630225"
+ }
+ ]
+ },
+ {
+ "name":"海北藏族自治州",
+ "code":"632200",
+ "sub":[
+ {
+ "name":"门源回族自治县",
+ "code":"632221"
+ },
+ {
+ "name":"祁连县",
+ "code":"632222"
+ },
+ {
+ "name":"海晏县",
+ "code":"632223"
+ },
+ {
+ "name":"刚察县",
+ "code":"632224"
+ }
+ ]
+ },
+ {
+ "name":"黄南藏族自治州",
+ "code":"632300",
+ "sub":[
+ {
+ "name":"同仁县",
+ "code":"632321"
+ },
+ {
+ "name":"尖扎县",
+ "code":"632322"
+ },
+ {
+ "name":"泽库县",
+ "code":"632323"
+ },
+ {
+ "name":"河南蒙古族自治县",
+ "code":"632324"
+ }
+ ]
+ },
+ {
+ "name":"海南藏族自治州",
+ "code":"632500",
+ "sub":[
+ {
+ "name":"共和县",
+ "code":"632521"
+ },
+ {
+ "name":"同德县",
+ "code":"632522"
+ },
+ {
+ "name":"贵德县",
+ "code":"632523"
+ },
+ {
+ "name":"兴海县",
+ "code":"632524"
+ },
+ {
+ "name":"贵南县",
+ "code":"632525"
+ }
+ ]
+ },
+ {
+ "name":"果洛藏族自治州",
+ "code":"632600",
+ "sub":[
+ {
+ "name":"玛沁县",
+ "code":"632621"
+ },
+ {
+ "name":"班玛县",
+ "code":"632622"
+ },
+ {
+ "name":"甘德县",
+ "code":"632623"
+ },
+ {
+ "name":"达日县",
+ "code":"632624"
+ },
+ {
+ "name":"久治县",
+ "code":"632625"
+ },
+ {
+ "name":"玛多县",
+ "code":"632626"
+ }
+ ]
+ },
+ {
+ "name":"玉树藏族自治州",
+ "code":"632700",
+ "sub":[
+ {
+ "name":"玉树市",
+ "code":"632701"
+ },
+ {
+ "name":"杂多县",
+ "code":"632722"
+ },
+ {
+ "name":"称多县",
+ "code":"632723"
+ },
+ {
+ "name":"治多县",
+ "code":"632724"
+ },
+ {
+ "name":"囊谦县",
+ "code":"632725"
+ },
+ {
+ "name":"曲麻莱县",
+ "code":"632726"
+ }
+ ]
+ },
+ {
+ "name":"海西蒙古族藏族自治州",
+ "code":"632800",
+ "sub":[
+ {
+ "name":"格尔木市",
+ "code":"632801"
+ },
+ {
+ "name":"德令哈市",
+ "code":"632802"
+ },
+ {
+ "name":"乌兰县",
+ "code":"632821"
+ },
+ {
+ "name":"都兰县",
+ "code":"632822"
+ },
+ {
+ "name":"天峻县",
+ "code":"632823"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name":"宁夏回族自治区",
+ "code":"640000",
+ "sub":[
+ {
+ "name":"银川市",
+ "code":"640100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"640101"
+ },
+ {
+ "name":"兴庆区",
+ "code":"640104"
+ },
+ {
+ "name":"西夏区",
+ "code":"640105"
+ },
+ {
+ "name":"金凤区",
+ "code":"640106"
+ },
+ {
+ "name":"永宁县",
+ "code":"640121"
+ },
+ {
+ "name":"贺兰县",
+ "code":"640122"
+ },
+ {
+ "name":"灵武市",
+ "code":"640181"
+ }
+ ]
+ },
+ {
+ "name":"石嘴山市",
+ "code":"640200",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"640201"
+ },
+ {
+ "name":"大武口区",
+ "code":"640202"
+ },
+ {
+ "name":"惠农区",
+ "code":"640205"
+ },
+ {
+ "name":"平罗县",
+ "code":"640221"
+ }
+ ]
+ },
+ {
+ "name":"吴忠市",
+ "code":"640300",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"640301"
+ },
+ {
+ "name":"利通区",
+ "code":"640302"
+ },
+ {
+ "name":"红寺堡区",
+ "code":"640303"
+ },
+ {
+ "name":"盐池县",
+ "code":"640323"
+ },
+ {
+ "name":"同心县",
+ "code":"640324"
+ },
+ {
+ "name":"青铜峡市",
+ "code":"640381"
+ }
+ ]
+ },
+ {
+ "name":"固原市",
+ "code":"640400",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"640401"
+ },
+ {
+ "name":"原州区",
+ "code":"640402"
+ },
+ {
+ "name":"西吉县",
+ "code":"640422"
+ },
+ {
+ "name":"隆德县",
+ "code":"640423"
+ },
+ {
+ "name":"泾源县",
+ "code":"640424"
+ },
+ {
+ "name":"彭阳县",
+ "code":"640425"
+ }
+ ]
+ },
+ {
+ "name":"中卫市",
+ "code":"640500",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"640501"
+ },
+ {
+ "name":"沙坡头区",
+ "code":"640502"
+ },
+ {
+ "name":"中宁县",
+ "code":"640521"
+ },
+ {
+ "name":"海原县",
+ "code":"640522"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name":"新疆维吾尔自治区",
+ "code":"650000",
+ "sub":[
+ {
+ "name":"乌鲁木齐市",
+ "code":"650100",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"650101"
+ },
+ {
+ "name":"天山区",
+ "code":"650102"
+ },
+ {
+ "name":"沙依巴克区",
+ "code":"650103"
+ },
+ {
+ "name":"新市区",
+ "code":"650104"
+ },
+ {
+ "name":"水磨沟区",
+ "code":"650105"
+ },
+ {
+ "name":"头屯河区",
+ "code":"650106"
+ },
+ {
+ "name":"达坂城区",
+ "code":"650107"
+ },
+ {
+ "name":"米东区",
+ "code":"650109"
+ },
+ {
+ "name":"乌鲁木齐县",
+ "code":"650121"
+ }
+ ]
+ },
+ {
+ "name":"克拉玛依市",
+ "code":"650200",
+ "sub":[
+ {
+ "name":"市辖区",
+ "code":"650201"
+ },
+ {
+ "name":"独山子区",
+ "code":"650202"
+ },
+ {
+ "name":"克拉玛依区",
+ "code":"650203"
+ },
+ {
+ "name":"白碱滩区",
+ "code":"650204"
+ },
+ {
+ "name":"乌尔禾区",
+ "code":"650205"
+ }
+ ]
+ },
+ {
+ "name":"吐鲁番地区",
+ "code":"652100",
+ "sub":[
+ {
+ "name":"吐鲁番市",
+ "code":"652101"
+ },
+ {
+ "name":"鄯善县",
+ "code":"652122"
+ },
+ {
+ "name":"托克逊县",
+ "code":"652123"
+ }
+ ]
+ },
+ {
+ "name":"哈密地区",
+ "code":"652200",
+ "sub":[
+ {
+ "name":"哈密市",
+ "code":"652201"
+ },
+ {
+ "name":"巴里坤哈萨克自治县",
+ "code":"652222"
+ },
+ {
+ "name":"伊吾县",
+ "code":"652223"
+ }
+ ]
+ },
+ {
+ "name":"昌吉回族自治州",
+ "code":"652300",
+ "sub":[
+ {
+ "name":"昌吉市",
+ "code":"652301"
+ },
+ {
+ "name":"阜康市",
+ "code":"652302"
+ },
+ {
+ "name":"呼图壁县",
+ "code":"652323"
+ },
+ {
+ "name":"玛纳斯县",
+ "code":"652324"
+ },
+ {
+ "name":"奇台县",
+ "code":"652325"
+ },
+ {
+ "name":"吉木萨尔县",
+ "code":"652327"
+ },
+ {
+ "name":"木垒哈萨克自治县",
+ "code":"652328"
+ }
+ ]
+ },
+ {
+ "name":"博尔塔拉蒙古自治州",
+ "code":"652700",
+ "sub":[
+ {
+ "name":"博乐市",
+ "code":"652701"
+ },
+ {
+ "name":"阿拉山口市",
+ "code":"652702"
+ },
+ {
+ "name":"精河县",
+ "code":"652722"
+ },
+ {
+ "name":"温泉县",
+ "code":"652723"
+ }
+ ]
+ },
+ {
+ "name":"巴音郭楞蒙古自治州",
+ "code":"652800",
+ "sub":[
+ {
+ "name":"库尔勒市",
+ "code":"652801"
+ },
+ {
+ "name":"轮台县",
+ "code":"652822"
+ },
+ {
+ "name":"尉犁县",
+ "code":"652823"
+ },
+ {
+ "name":"若羌县",
+ "code":"652824"
+ },
+ {
+ "name":"且末县",
+ "code":"652825"
+ },
+ {
+ "name":"焉耆回族自治县",
+ "code":"652826"
+ },
+ {
+ "name":"和静县",
+ "code":"652827"
+ },
+ {
+ "name":"和硕县",
+ "code":"652828"
+ },
+ {
+ "name":"博湖县",
+ "code":"652829"
+ }
+ ]
+ },
+ {
+ "name":"阿克苏地区",
+ "code":"652900",
+ "sub":[
+ {
+ "name":"阿克苏市",
+ "code":"652901"
+ },
+ {
+ "name":"温宿县",
+ "code":"652922"
+ },
+ {
+ "name":"库车县",
+ "code":"652923"
+ },
+ {
+ "name":"沙雅县",
+ "code":"652924"
+ },
+ {
+ "name":"新和县",
+ "code":"652925"
+ },
+ {
+ "name":"拜城县",
+ "code":"652926"
+ },
+ {
+ "name":"乌什县",
+ "code":"652927"
+ },
+ {
+ "name":"阿瓦提县",
+ "code":"652928"
+ },
+ {
+ "name":"柯坪县",
+ "code":"652929"
+ }
+ ]
+ },
+ {
+ "name":"克孜勒苏柯尔克孜自治州",
+ "code":"653000",
+ "sub":[
+ {
+ "name":"阿图什市",
+ "code":"653001"
+ },
+ {
+ "name":"阿克陶县",
+ "code":"653022"
+ },
+ {
+ "name":"阿合奇县",
+ "code":"653023"
+ },
+ {
+ "name":"乌恰县",
+ "code":"653024"
+ }
+ ]
+ },
+ {
+ "name":"喀什地区",
+ "code":"653100",
+ "sub":[
+ {
+ "name":"喀什市",
+ "code":"653101"
+ },
+ {
+ "name":"疏附县",
+ "code":"653121"
+ },
+ {
+ "name":"疏勒县",
+ "code":"653122"
+ },
+ {
+ "name":"英吉沙县",
+ "code":"653123"
+ },
+ {
+ "name":"泽普县",
+ "code":"653124"
+ },
+ {
+ "name":"莎车县",
+ "code":"653125"
+ },
+ {
+ "name":"叶城县",
+ "code":"653126"
+ },
+ {
+ "name":"麦盖提县",
+ "code":"653127"
+ },
+ {
+ "name":"岳普湖县",
+ "code":"653128"
+ },
+ {
+ "name":"伽师县",
+ "code":"653129"
+ },
+ {
+ "name":"巴楚县",
+ "code":"653130"
+ },
+ {
+ "name":"塔什库尔干塔吉克自治县",
+ "code":"653131"
+ }
+ ]
+ },
+ {
+ "name":"和田地区",
+ "code":"653200",
+ "sub":[
+ {
+ "name":"和田市",
+ "code":"653201"
+ },
+ {
+ "name":"和田县",
+ "code":"653221"
+ },
+ {
+ "name":"墨玉县",
+ "code":"653222"
+ },
+ {
+ "name":"皮山县",
+ "code":"653223"
+ },
+ {
+ "name":"洛浦县",
+ "code":"653224"
+ },
+ {
+ "name":"策勒县",
+ "code":"653225"
+ },
+ {
+ "name":"于田县",
+ "code":"653226"
+ },
+ {
+ "name":"民丰县",
+ "code":"653227"
+ }
+ ]
+ },
+ {
+ "name":"伊犁哈萨克自治州",
+ "code":"654000",
+ "sub":[
+ {
+ "name":"伊宁市",
+ "code":"654002"
+ },
+ {
+ "name":"奎屯市",
+ "code":"654003"
+ },
+ {
+ "name":"霍尔果斯市",
+ "code":"654004"
+ },
+ {
+ "name":"伊宁县",
+ "code":"654021"
+ },
+ {
+ "name":"察布查尔锡伯自治县",
+ "code":"654022"
+ },
+ {
+ "name":"霍城县",
+ "code":"654023"
+ },
+ {
+ "name":"巩留县",
+ "code":"654024"
+ },
+ {
+ "name":"新源县",
+ "code":"654025"
+ },
+ {
+ "name":"昭苏县",
+ "code":"654026"
+ },
+ {
+ "name":"特克斯县",
+ "code":"654027"
+ },
+ {
+ "name":"尼勒克县",
+ "code":"654028"
+ },
+ {
+ "name":"塔城地区",
+ "code":"654200"
+ },
+ {
+ "name":"塔城市",
+ "code":"654201"
+ },
+ {
+ "name":"乌苏市",
+ "code":"654202"
+ },
+ {
+ "name":"额敏县",
+ "code":"654221"
+ },
+ {
+ "name":"沙湾县",
+ "code":"654223"
+ },
+ {
+ "name":"托里县",
+ "code":"654224"
+ },
+ {
+ "name":"裕民县",
+ "code":"654225"
+ },
+ {
+ "name":"和布克赛尔蒙古自治县",
+ "code":"654226"
+ },
+ {
+ "name":"阿勒泰地区",
+ "code":"654300"
+ },
+ {
+ "name":"阿勒泰市",
+ "code":"654301"
+ },
+ {
+ "name":"布尔津县",
+ "code":"654321"
+ },
+ {
+ "name":"富蕴县",
+ "code":"654322"
+ },
+ {
+ "name":"福海县",
+ "code":"654323"
+ },
+ {
+ "name":"哈巴河县",
+ "code":"654324"
+ },
+ {
+ "name":"青河县",
+ "code":"654325"
+ },
+ {
+ "name":"吉木乃县",
+ "code":"654326"
+ }
+ ]
+ },
+ {
+ "name":"自治区直辖县级行政区划",
+ "code":"659000",
+ "sub":[
+ {
+ "name":"石河子市",
+ "code":"659001"
+ },
+ {
+ "name":"阿拉尔市",
+ "code":"659002"
+ },
+ {
+ "name":"图木舒克市",
+ "code":"659003"
+ },
+ {
+ "name":"五家渠市",
+ "code":"659004"
+ },
+ {
+ "name":"北屯市",
+ "code":"659005"
+ },
+ {
+ "name":"铁门关市",
+ "code":"659006"
+ },
+ {
+ "name":"双河市",
+ "code":"659007"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name":"台湾省",
+ "code":"710000",
+ "sub":[
+ {
+ "name":"台北市",
+ "code":"710100",
+ "sub":[
+ {
+ "name":"松山区",
+ "code":"710101"
+ },
+ {
+ "name":"信义区",
+ "code":"710102"
+ },
+ {
+ "name":"大安区",
+ "code":"710103"
+ },
+ {
+ "name":"中山区",
+ "code":"710104"
+ },
+ {
+ "name":"中正区",
+ "code":"710105"
+ },
+ {
+ "name":"大同区",
+ "code":"710106"
+ },
+ {
+ "name":"万华区",
+ "code":"710107"
+ },
+ {
+ "name":"文山区",
+ "code":"710108"
+ },
+ {
+ "name":"南港区",
+ "code":"710109"
+ },
+ {
+ "name":"内湖区",
+ "code":"710110"
+ },
+ {
+ "name":"士林区",
+ "code":"710111"
+ },
+ {
+ "name":"北投区",
+ "code":"710112"
+ }
+ ]
+ },
+ {
+ "name":"高雄市",
+ "code":"710200",
+ "sub":[
+ {
+ "name":"盐埕区",
+ "code":"710201"
+ },
+ {
+ "name":"鼓山区",
+ "code":"710202"
+ },
+ {
+ "name":"左营区",
+ "code":"710203"
+ },
+ {
+ "name":"楠梓区",
+ "code":"710204"
+ },
+ {
+ "name":"三民区",
+ "code":"710205"
+ },
+ {
+ "name":"新兴区",
+ "code":"710206"
+ },
+ {
+ "name":"前金区",
+ "code":"710207"
+ },
+ {
+ "name":"苓雅区",
+ "code":"710208"
+ },
+ {
+ "name":"前镇区",
+ "code":"710209"
+ },
+ {
+ "name":"旗津区",
+ "code":"710210"
+ },
+ {
+ "name":"小港区",
+ "code":"710211"
+ },
+ {
+ "name":"凤山区",
+ "code":"710212"
+ },
+ {
+ "name":"林园区",
+ "code":"710213"
+ },
+ {
+ "name":"大寮区",
+ "code":"710214"
+ },
+ {
+ "name":"大树区",
+ "code":"710215"
+ },
+ {
+ "name":"大社区",
+ "code":"710216"
+ },
+ {
+ "name":"仁武区",
+ "code":"710217"
+ },
+ {
+ "name":"鸟松区",
+ "code":"710218"
+ },
+ {
+ "name":"冈山区",
+ "code":"710219"
+ },
+ {
+ "name":"桥头区",
+ "code":"710220"
+ },
+ {
+ "name":"燕巢区",
+ "code":"710221"
+ },
+ {
+ "name":"田寮区",
+ "code":"710222"
+ },
+ {
+ "name":"阿莲区",
+ "code":"710223"
+ },
+ {
+ "name":"路竹区",
+ "code":"710224"
+ },
+ {
+ "name":"湖内区",
+ "code":"710225"
+ },
+ {
+ "name":"茄萣区",
+ "code":"710226"
+ },
+ {
+ "name":"永安区",
+ "code":"710227"
+ },
+ {
+ "name":"弥陀区",
+ "code":"710228"
+ },
+ {
+ "name":"梓官区",
+ "code":"710229"
+ },
+ {
+ "name":"旗山区",
+ "code":"710230"
+ },
+ {
+ "name":"美浓区",
+ "code":"710231"
+ },
+ {
+ "name":"六龟区",
+ "code":"710232"
+ },
+ {
+ "name":"甲仙区",
+ "code":"710233"
+ },
+ {
+ "name":"杉林区",
+ "code":"710234"
+ },
+ {
+ "name":"内门区",
+ "code":"710235"
+ },
+ {
+ "name":"茂林区",
+ "code":"710236"
+ },
+ {
+ "name":"桃源区",
+ "code":"710237"
+ },
+ {
+ "name":"那玛夏区",
+ "code":"710238"
+ }
+ ]
+ },
+ {
+ "name":"基隆市",
+ "code":"710300",
+ "sub":[
+ {
+ "name":"中正区",
+ "code":"710301"
+ },
+ {
+ "name":"七堵区",
+ "code":"710302"
+ },
+ {
+ "name":"暖暖区",
+ "code":"710303"
+ },
+ {
+ "name":"仁爱区",
+ "code":"710304"
+ },
+ {
+ "name":"中山区",
+ "code":"710305"
+ },
+ {
+ "name":"安乐区",
+ "code":"710306"
+ },
+ {
+ "name":"信义区",
+ "code":"710307"
+ }
+ ]
+ },
+ {
+ "name":"台中市",
+ "code":"710400",
+ "sub":[
+ {
+ "name":"中区",
+ "code":"710401"
+ },
+ {
+ "name":"东区",
+ "code":"710402"
+ },
+ {
+ "name":"南区",
+ "code":"710403"
+ },
+ {
+ "name":"西区",
+ "code":"710404"
+ },
+ {
+ "name":"北区",
+ "code":"710405"
+ },
+ {
+ "name":"西屯区",
+ "code":"710406"
+ },
+ {
+ "name":"南屯区",
+ "code":"710407"
+ },
+ {
+ "name":"北屯区",
+ "code":"710408"
+ },
+ {
+ "name":"丰原区",
+ "code":"710409"
+ },
+ {
+ "name":"东势区",
+ "code":"710410"
+ },
+ {
+ "name":"大甲区",
+ "code":"710411"
+ },
+ {
+ "name":"清水区",
+ "code":"710412"
+ },
+ {
+ "name":"沙鹿区",
+ "code":"710413"
+ },
+ {
+ "name":"梧栖区",
+ "code":"710414"
+ },
+ {
+ "name":"后里区",
+ "code":"710415"
+ },
+ {
+ "name":"神冈区",
+ "code":"710416"
+ },
+ {
+ "name":"潭子区",
+ "code":"710417"
+ },
+ {
+ "name":"大雅区",
+ "code":"710418"
+ },
+ {
+ "name":"新社区",
+ "code":"710419"
+ },
+ {
+ "name":"石冈区",
+ "code":"710420"
+ },
+ {
+ "name":"外埔区",
+ "code":"710421"
+ },
+ {
+ "name":"大安区",
+ "code":"710422"
+ },
+ {
+ "name":"乌日区",
+ "code":"710423"
+ },
+ {
+ "name":"大肚区",
+ "code":"710424"
+ },
+ {
+ "name":"龙井区",
+ "code":"710425"
+ },
+ {
+ "name":"雾峰区",
+ "code":"710426"
+ },
+ {
+ "name":"太平区",
+ "code":"710427"
+ },
+ {
+ "name":"大里区",
+ "code":"710428"
+ },
+ {
+ "name":"和平区",
+ "code":"710429"
+ }
+ ]
+ },
+ {
+ "name":"台南市",
+ "code":"710500",
+ "sub":[
+ {
+ "name":"东区",
+ "code":"710501"
+ },
+ {
+ "name":"南区",
+ "code":"710502"
+ },
+ {
+ "name":"北区",
+ "code":"710504"
+ },
+ {
+ "name":"安南区",
+ "code":"710506"
+ },
+ {
+ "name":"安平区",
+ "code":"710507"
+ },
+ {
+ "name":"中西区",
+ "code":"710508"
+ },
+ {
+ "name":"新营区",
+ "code":"710509"
+ },
+ {
+ "name":"盐水区",
+ "code":"710510"
+ },
+ {
+ "name":"白河区",
+ "code":"710511"
+ },
+ {
+ "name":"柳营区",
+ "code":"710512"
+ },
+ {
+ "name":"后壁区",
+ "code":"710513"
+ },
+ {
+ "name":"东山区",
+ "code":"710514"
+ },
+ {
+ "name":"麻豆区",
+ "code":"710515"
+ },
+ {
+ "name":"下营区",
+ "code":"710516"
+ },
+ {
+ "name":"六甲区",
+ "code":"710517"
+ },
+ {
+ "name":"官田区",
+ "code":"710518"
+ },
+ {
+ "name":"大内区",
+ "code":"710519"
+ },
+ {
+ "name":"佳里区",
+ "code":"710520"
+ },
+ {
+ "name":"学甲区",
+ "code":"710521"
+ },
+ {
+ "name":"西港区",
+ "code":"710522"
+ },
+ {
+ "name":"七股区",
+ "code":"710523"
+ },
+ {
+ "name":"将军区",
+ "code":"710524"
+ },
+ {
+ "name":"北门区",
+ "code":"710525"
+ },
+ {
+ "name":"新化区",
+ "code":"710526"
+ },
+ {
+ "name":"善化区",
+ "code":"710527"
+ },
+ {
+ "name":"新市区",
+ "code":"710528"
+ },
+ {
+ "name":"安定区",
+ "code":"710529"
+ },
+ {
+ "name":"山上区",
+ "code":"710530"
+ },
+ {
+ "name":"玉井区",
+ "code":"710531"
+ },
+ {
+ "name":"楠西区",
+ "code":"710532"
+ },
+ {
+ "name":"南化区",
+ "code":"710533"
+ },
+ {
+ "name":"左镇区",
+ "code":"710534"
+ },
+ {
+ "name":"仁德区",
+ "code":"710535"
+ },
+ {
+ "name":"归仁区",
+ "code":"710536"
+ },
+ {
+ "name":"关庙区",
+ "code":"710537"
+ },
+ {
+ "name":"龙崎区",
+ "code":"710538"
+ },
+ {
+ "name":"永康区",
+ "code":"710539"
+ }
+ ]
+ },
+ {
+ "name":"新竹市",
+ "code":"710600",
+ "sub":[
+ {
+ "name":"东区",
+ "code":"710601"
+ },
+ {
+ "name":"北区",
+ "code":"710602"
+ },
+ {
+ "name":"香山区",
+ "code":"710603"
+ }
+ ]
+ },
+ {
+ "name":"嘉义市",
+ "code":"710700",
+ "sub":[
+ {
+ "name":"东区",
+ "code":"710701"
+ },
+ {
+ "name":"西区",
+ "code":"710702"
+ }
+ ]
+ },
+ {
+ "name":"新北市",
+ "code":"710800",
+ "sub":[
+ {
+ "name":"板桥区",
+ "code":"710801"
+ },
+ {
+ "name":"三重区",
+ "code":"710802"
+ },
+ {
+ "name":"中和区",
+ "code":"710803"
+ },
+ {
+ "name":"永和区",
+ "code":"710804"
+ },
+ {
+ "name":"新庄区",
+ "code":"710805"
+ },
+ {
+ "name":"新店区",
+ "code":"710806"
+ },
+ {
+ "name":"树林区",
+ "code":"710807"
+ },
+ {
+ "name":"莺歌区",
+ "code":"710808"
+ },
+ {
+ "name":"三峡区",
+ "code":"710809"
+ },
+ {
+ "name":"淡水区",
+ "code":"710810"
+ },
+ {
+ "name":"汐止区",
+ "code":"710811"
+ },
+ {
+ "name":"瑞芳区",
+ "code":"710812"
+ },
+ {
+ "name":"土城区",
+ "code":"710813"
+ },
+ {
+ "name":"芦洲区",
+ "code":"710814"
+ },
+ {
+ "name":"五股区",
+ "code":"710815"
+ },
+ {
+ "name":"泰山区",
+ "code":"710816"
+ },
+ {
+ "name":"林口区",
+ "code":"710817"
+ },
+ {
+ "name":"深坑区",
+ "code":"710818"
+ },
+ {
+ "name":"石碇区",
+ "code":"710819"
+ },
+ {
+ "name":"坪林区",
+ "code":"710820"
+ },
+ {
+ "name":"三芝区",
+ "code":"710821"
+ },
+ {
+ "name":"石门区",
+ "code":"710822"
+ },
+ {
+ "name":"八里区",
+ "code":"710823"
+ },
+ {
+ "name":"平溪区",
+ "code":"710824"
+ },
+ {
+ "name":"双溪区",
+ "code":"710825"
+ },
+ {
+ "name":"贡寮区",
+ "code":"710826"
+ },
+ {
+ "name":"金山区",
+ "code":"710827"
+ },
+ {
+ "name":"万里区",
+ "code":"710828"
+ },
+ {
+ "name":"乌来区",
+ "code":"710829"
+ }
+ ]
+ },
+ {
+ "name":"宜兰县",
+ "code":"712200",
+ "sub":[
+ {
+ "name":"宜兰市",
+ "code":"712201"
+ },
+ {
+ "name":"罗东镇",
+ "code":"712221"
+ },
+ {
+ "name":"苏澳镇",
+ "code":"712222"
+ },
+ {
+ "name":"头城镇",
+ "code":"712223"
+ },
+ {
+ "name":"礁溪乡",
+ "code":"712224"
+ },
+ {
+ "name":"壮围乡",
+ "code":"712225"
+ },
+ {
+ "name":"员山乡",
+ "code":"712226"
+ },
+ {
+ "name":"冬山乡",
+ "code":"712227"
+ },
+ {
+ "name":"五结乡",
+ "code":"712228"
+ },
+ {
+ "name":"三星乡",
+ "code":"712229"
+ },
+ {
+ "name":"大同乡",
+ "code":"712230"
+ },
+ {
+ "name":"南澳乡",
+ "code":"712231"
+ }
+ ]
+ },
+ {
+ "name":"桃园县",
+ "code":"712300",
+ "sub":[
+ {
+ "name":"桃园市",
+ "code":"712301"
+ },
+ {
+ "name":"中坜市",
+ "code":"712302"
+ },
+ {
+ "name":"平镇市",
+ "code":"712303"
+ },
+ {
+ "name":"八德市",
+ "code":"712304"
+ },
+ {
+ "name":"杨梅市",
+ "code":"712305"
+ },
+ {
+ "name":"大溪镇",
+ "code":"712321"
+ },
+ {
+ "name":"芦竹乡",
+ "code":"712323"
+ },
+ {
+ "name":"大园乡",
+ "code":"712324"
+ },
+ {
+ "name":"龟山乡",
+ "code":"712325"
+ },
+ {
+ "name":"龙潭乡",
+ "code":"712327"
+ },
+ {
+ "name":"新屋乡",
+ "code":"712329"
+ },
+ {
+ "name":"观音乡",
+ "code":"712330"
+ },
+ {
+ "name":"复兴乡",
+ "code":"712331"
+ }
+ ]
+ },
+ {
+ "name":"新竹县",
+ "code":"712400",
+ "sub":[
+ {
+ "name":"竹北市",
+ "code":"712401"
+ },
+ {
+ "name":"竹东镇",
+ "code":"712421"
+ },
+ {
+ "name":"新埔镇",
+ "code":"712422"
+ },
+ {
+ "name":"关西镇",
+ "code":"712423"
+ },
+ {
+ "name":"湖口乡",
+ "code":"712424"
+ },
+ {
+ "name":"新丰乡",
+ "code":"712425"
+ },
+ {
+ "name":"芎林乡",
+ "code":"712426"
+ },
+ {
+ "name":"橫山乡",
+ "code":"712427"
+ },
+ {
+ "name":"北埔乡",
+ "code":"712428"
+ },
+ {
+ "name":"宝山乡",
+ "code":"712429"
+ },
+ {
+ "name":"峨眉乡",
+ "code":"712430"
+ },
+ {
+ "name":"尖石乡",
+ "code":"712431"
+ },
+ {
+ "name":"五峰乡",
+ "code":"712432"
+ }
+ ]
+ },
+ {
+ "name":"苗栗县",
+ "code":"712500",
+ "sub":[
+ {
+ "name":"苗栗市",
+ "code":"712501"
+ },
+ {
+ "name":"苑里镇",
+ "code":"712521"
+ },
+ {
+ "name":"通霄镇",
+ "code":"712522"
+ },
+ {
+ "name":"竹南镇",
+ "code":"712523"
+ },
+ {
+ "name":"头份镇",
+ "code":"712524"
+ },
+ {
+ "name":"后龙镇",
+ "code":"712525"
+ },
+ {
+ "name":"卓兰镇",
+ "code":"712526"
+ },
+ {
+ "name":"大湖乡",
+ "code":"712527"
+ },
+ {
+ "name":"公馆乡",
+ "code":"712528"
+ },
+ {
+ "name":"铜锣乡",
+ "code":"712529"
+ },
+ {
+ "name":"南庄乡",
+ "code":"712530"
+ },
+ {
+ "name":"头屋乡",
+ "code":"712531"
+ },
+ {
+ "name":"三义乡",
+ "code":"712532"
+ },
+ {
+ "name":"西湖乡",
+ "code":"712533"
+ },
+ {
+ "name":"造桥乡",
+ "code":"712534"
+ },
+ {
+ "name":"三湾乡",
+ "code":"712535"
+ },
+ {
+ "name":"狮潭乡",
+ "code":"712536"
+ },
+ {
+ "name":"泰安乡",
+ "code":"712537"
+ }
+ ]
+ },
+ {
+ "name":"彰化县",
+ "code":"712700",
+ "sub":[
+ {
+ "name":"彰化市",
+ "code":"712701"
+ },
+ {
+ "name":"鹿港镇",
+ "code":"712721"
+ },
+ {
+ "name":"和美镇",
+ "code":"712722"
+ },
+ {
+ "name":"线西乡",
+ "code":"712723"
+ },
+ {
+ "name":"伸港乡",
+ "code":"712724"
+ },
+ {
+ "name":"福兴乡",
+ "code":"712725"
+ },
+ {
+ "name":"秀水乡",
+ "code":"712726"
+ },
+ {
+ "name":"花坛乡",
+ "code":"712727"
+ },
+ {
+ "name":"芬园乡",
+ "code":"712728"
+ },
+ {
+ "name":"员林镇",
+ "code":"712729"
+ },
+ {
+ "name":"溪湖镇",
+ "code":"712730"
+ },
+ {
+ "name":"田中镇",
+ "code":"712731"
+ },
+ {
+ "name":"大村乡",
+ "code":"712732"
+ },
+ {
+ "name":"埔盐乡",
+ "code":"712733"
+ },
+ {
+ "name":"埔心乡",
+ "code":"712734"
+ },
+ {
+ "name":"永靖乡",
+ "code":"712735"
+ },
+ {
+ "name":"社头乡",
+ "code":"712736"
+ },
+ {
+ "name":"二水乡",
+ "code":"712737"
+ },
+ {
+ "name":"北斗镇",
+ "code":"712738"
+ },
+ {
+ "name":"二林镇",
+ "code":"712739"
+ },
+ {
+ "name":"田尾乡",
+ "code":"712740"
+ },
+ {
+ "name":"埤头乡",
+ "code":"712741"
+ },
+ {
+ "name":"芳苑乡",
+ "code":"712742"
+ },
+ {
+ "name":"大城乡",
+ "code":"712743"
+ },
+ {
+ "name":"竹塘乡",
+ "code":"712744"
+ },
+ {
+ "name":"溪州乡",
+ "code":"712745"
+ }
+ ]
+ },
+ {
+ "name":"南投县",
+ "code":"712800",
+ "sub":[
+ {
+ "name":"南投市",
+ "code":"712801"
+ },
+ {
+ "name":"埔里镇",
+ "code":"712821"
+ },
+ {
+ "name":"草屯镇",
+ "code":"712822"
+ },
+ {
+ "name":"竹山镇",
+ "code":"712823"
+ },
+ {
+ "name":"集集镇",
+ "code":"712824"
+ },
+ {
+ "name":"名间乡",
+ "code":"712825"
+ },
+ {
+ "name":"鹿谷乡",
+ "code":"712826"
+ },
+ {
+ "name":"中寮乡",
+ "code":"712827"
+ },
+ {
+ "name":"鱼池乡",
+ "code":"712828"
+ },
+ {
+ "name":"国姓乡",
+ "code":"712829"
+ },
+ {
+ "name":"水里乡",
+ "code":"712830"
+ },
+ {
+ "name":"信义乡",
+ "code":"712831"
+ },
+ {
+ "name":"仁爱乡",
+ "code":"712832"
+ }
+ ]
+ },
+ {
+ "name":"云林县",
+ "code":"712900",
+ "sub":[
+ {
+ "name":"斗六市",
+ "code":"712901"
+ },
+ {
+ "name":"斗南镇",
+ "code":"712921"
+ },
+ {
+ "name":"虎尾镇",
+ "code":"712922"
+ },
+ {
+ "name":"西螺镇",
+ "code":"712923"
+ },
+ {
+ "name":"土库镇",
+ "code":"712924"
+ },
+ {
+ "name":"北港镇",
+ "code":"712925"
+ },
+ {
+ "name":"古坑乡",
+ "code":"712926"
+ },
+ {
+ "name":"大埤乡",
+ "code":"712927"
+ },
+ {
+ "name":"莿桐乡",
+ "code":"712928"
+ },
+ {
+ "name":"林内乡",
+ "code":"712929"
+ },
+ {
+ "name":"二仑乡",
+ "code":"712930"
+ },
+ {
+ "name":"仑背乡",
+ "code":"712931"
+ },
+ {
+ "name":"麦寮乡",
+ "code":"712932"
+ },
+ {
+ "name":"东势乡",
+ "code":"712933"
+ },
+ {
+ "name":"褒忠乡",
+ "code":"712934"
+ },
+ {
+ "name":"台西乡",
+ "code":"712935"
+ },
+ {
+ "name":"元长乡",
+ "code":"712936"
+ },
+ {
+ "name":"四湖乡",
+ "code":"712937"
+ },
+ {
+ "name":"口湖乡",
+ "code":"712938"
+ },
+ {
+ "name":"水林乡",
+ "code":"712939"
+ }
+ ]
+ },
+ {
+ "name":"嘉义县",
+ "code":"713000",
+ "sub":[
+ {
+ "name":"太保市",
+ "code":"713001"
+ },
+ {
+ "name":"朴子市",
+ "code":"713002"
+ },
+ {
+ "name":"布袋镇",
+ "code":"713023"
+ },
+ {
+ "name":"大林镇",
+ "code":"713024"
+ },
+ {
+ "name":"民雄乡",
+ "code":"713025"
+ },
+ {
+ "name":"溪口乡",
+ "code":"713026"
+ },
+ {
+ "name":"新港乡",
+ "code":"713027"
+ },
+ {
+ "name":"六脚乡",
+ "code":"713028"
+ },
+ {
+ "name":"东石乡",
+ "code":"713029"
+ },
+ {
+ "name":"义竹乡",
+ "code":"713030"
+ },
+ {
+ "name":"鹿草乡",
+ "code":"713031"
+ },
+ {
+ "name":"水上乡",
+ "code":"713032"
+ },
+ {
+ "name":"中埔乡",
+ "code":"713033"
+ },
+ {
+ "name":"竹崎乡",
+ "code":"713034"
+ },
+ {
+ "name":"梅山乡",
+ "code":"713035"
+ },
+ {
+ "name":"番路乡",
+ "code":"713036"
+ },
+ {
+ "name":"大埔乡",
+ "code":"713037"
+ },
+ {
+ "name":"阿里山乡",
+ "code":"713038"
+ }
+ ]
+ },
+ {
+ "name":"屏东县",
+ "code":"713300",
+ "sub":[
+ {
+ "name":"屏东市",
+ "code":"713301"
+ },
+ {
+ "name":"潮州镇",
+ "code":"713321"
+ },
+ {
+ "name":"东港镇",
+ "code":"713322"
+ },
+ {
+ "name":"恒春镇",
+ "code":"713323"
+ },
+ {
+ "name":"万丹乡",
+ "code":"713324"
+ },
+ {
+ "name":"长治乡",
+ "code":"713325"
+ },
+ {
+ "name":"麟洛乡",
+ "code":"713326"
+ },
+ {
+ "name":"九如乡",
+ "code":"713327"
+ },
+ {
+ "name":"里港乡",
+ "code":"713328"
+ },
+ {
+ "name":"盐埔乡",
+ "code":"713329"
+ },
+ {
+ "name":"高树乡",
+ "code":"713330"
+ },
+ {
+ "name":"万峦乡",
+ "code":"713331"
+ },
+ {
+ "name":"内埔乡",
+ "code":"713332"
+ },
+ {
+ "name":"竹田乡",
+ "code":"713333"
+ },
+ {
+ "name":"新埤乡",
+ "code":"713334"
+ },
+ {
+ "name":"枋寮乡",
+ "code":"713335"
+ },
+ {
+ "name":"新园乡",
+ "code":"713336"
+ },
+ {
+ "name":"崁顶乡",
+ "code":"713337"
+ },
+ {
+ "name":"林边乡",
+ "code":"713338"
+ },
+ {
+ "name":"南州乡",
+ "code":"713339"
+ },
+ {
+ "name":"佳冬乡",
+ "code":"713340"
+ },
+ {
+ "name":"琉球乡",
+ "code":"713341"
+ },
+ {
+ "name":"车城乡",
+ "code":"713342"
+ },
+ {
+ "name":"满州乡",
+ "code":"713343"
+ },
+ {
+ "name":"枋山乡",
+ "code":"713344"
+ },
+ {
+ "name":"三地门乡",
+ "code":"713345"
+ },
+ {
+ "name":"雾台乡",
+ "code":"713346"
+ },
+ {
+ "name":"玛家乡",
+ "code":"713347"
+ },
+ {
+ "name":"泰武乡",
+ "code":"713348"
+ },
+ {
+ "name":"来义乡",
+ "code":"713349"
+ },
+ {
+ "name":"春日乡",
+ "code":"713350"
+ },
+ {
+ "name":"狮子乡",
+ "code":"713351"
+ },
+ {
+ "name":"牡丹乡",
+ "code":"713352"
+ }
+ ]
+ },
+ {
+ "name":"台东县",
+ "code":"713400",
+ "sub":[
+ {
+ "name":"台东市",
+ "code":"713401"
+ },
+ {
+ "name":"成功镇",
+ "code":"713421"
+ },
+ {
+ "name":"关山镇",
+ "code":"713422"
+ },
+ {
+ "name":"卑南乡",
+ "code":"713423"
+ },
+ {
+ "name":"鹿野乡",
+ "code":"713424"
+ },
+ {
+ "name":"池上乡",
+ "code":"713425"
+ },
+ {
+ "name":"东河乡",
+ "code":"713426"
+ },
+ {
+ "name":"长滨乡",
+ "code":"713427"
+ },
+ {
+ "name":"太麻里乡",
+ "code":"713428"
+ },
+ {
+ "name":"大武乡",
+ "code":"713429"
+ },
+ {
+ "name":"绿岛乡",
+ "code":"713430"
+ },
+ {
+ "name":"海端乡",
+ "code":"713431"
+ },
+ {
+ "name":"延平乡",
+ "code":"713432"
+ },
+ {
+ "name":"金峰乡",
+ "code":"713433"
+ },
+ {
+ "name":"达仁乡",
+ "code":"713434"
+ },
+ {
+ "name":"兰屿乡",
+ "code":"713435"
+ }
+ ]
+ },
+ {
+ "name":"花莲县",
+ "code":"713500",
+ "sub":[
+ {
+ "name":"花莲市",
+ "code":"713501"
+ },
+ {
+ "name":"凤林镇",
+ "code":"713521"
+ },
+ {
+ "name":"玉里镇",
+ "code":"713522"
+ },
+ {
+ "name":"新城乡",
+ "code":"713523"
+ },
+ {
+ "name":"吉安乡",
+ "code":"713524"
+ },
+ {
+ "name":"寿丰乡",
+ "code":"713525"
+ },
+ {
+ "name":"光复乡",
+ "code":"713526"
+ },
+ {
+ "name":"丰滨乡",
+ "code":"713527"
+ },
+ {
+ "name":"瑞穗乡",
+ "code":"713528"
+ },
+ {
+ "name":"富里乡",
+ "code":"713529"
+ },
+ {
+ "name":"秀林乡",
+ "code":"713530"
+ },
+ {
+ "name":"万荣乡",
+ "code":"713531"
+ },
+ {
+ "name":"卓溪乡",
+ "code":"713532"
+ }
+ ]
+ },
+ {
+ "name":"澎湖县",
+ "code":"713600",
+ "sub":[
+ {
+ "name":"马公市",
+ "code":"713601"
+ },
+ {
+ "name":"湖西乡",
+ "code":"713621"
+ },
+ {
+ "name":"白沙乡",
+ "code":"713622"
+ },
+ {
+ "name":"西屿乡",
+ "code":"713623"
+ },
+ {
+ "name":"望安乡",
+ "code":"713624"
+ },
+ {
+ "name":"七美乡",
+ "code":"713625"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name":"香港特别行政区",
+ "code":"810000",
+ "sub":[
+ {
+ "name":"香港岛",
+ "code":"810100",
+ "sub":[
+ {
+ "name":"中西区",
+ "code":"810101"
+ },
+ {
+ "name":"湾仔区",
+ "code":"810102"
+ },
+ {
+ "name":"东区",
+ "code":"810103"
+ },
+ {
+ "name":"南区",
+ "code":"810104"
+ }
+ ]
+ },
+ {
+ "name":"九龙",
+ "code":"810200",
+ "sub":[
+ {
+ "name":"油尖旺区",
+ "code":"810201"
+ },
+ {
+ "name":"深水埗区",
+ "code":"810202"
+ },
+ {
+ "name":"九龙城区",
+ "code":"810203"
+ },
+ {
+ "name":"黄大仙区",
+ "code":"810204"
+ },
+ {
+ "name":"观塘区",
+ "code":"810205"
+ }
+ ]
+ },
+ {
+ "name":"新界",
+ "code":"810300",
+ "sub":[
+ {
+ "name":"荃湾区",
+ "code":"810301"
+ },
+ {
+ "name":"屯门区",
+ "code":"810302"
+ },
+ {
+ "name":"元朗区",
+ "code":"810303"
+ },
+ {
+ "name":"北区",
+ "code":"810304"
+ },
+ {
+ "name":"大埔区",
+ "code":"810305"
+ },
+ {
+ "name":"西贡区",
+ "code":"810306"
+ },
+ {
+ "name":"沙田区",
+ "code":"810307"
+ },
+ {
+ "name":"葵青区",
+ "code":"810308"
+ },
+ {
+ "name":"离岛区",
+ "code":"810309"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name":"澳门特别行政区",
+ "code":"820000",
+ "sub":[
+ {
+ "name":"澳门半岛",
+ "code":"820100",
+ "sub":[
+ {
+ "name":"花地玛堂区",
+ "code":"820101"
+ },
+ {
+ "name":"圣安多尼堂区",
+ "code":"820102"
+ },
+ {
+ "name":"大堂区",
+ "code":"820103"
+ },
+ {
+ "name":"望德堂区",
+ "code":"820104"
+ },
+ {
+ "name":"风顺堂区",
+ "code":"820105"
+ }
+ ]
+ },
+ {
+ "name":"氹仔岛",
+ "code":"820200",
+ "sub":[
+ {
+ "name":"嘉模堂区",
+ "code":"820201"
+ }
+ ]
+ },
+ {
+ "name":"路环岛",
+ "code":"820300",
+ "sub":[
+ {
+ "name":"圣方济各堂区",
+ "code":"820301"
+ }
+ ]
+ }
+ ]
+ }
+
+];
+
+function init(that){
+ that.setData( {
+ 'cityData': cityData
+ });
+}
+
+module.exports={
+ init:init
+}
\ No newline at end of file
diff --git a/campus/utils/index.js b/campus/utils/index.js
new file mode 100644
index 0000000..ea16c74
--- /dev/null
+++ b/campus/utils/index.js
@@ -0,0 +1,60 @@
+/**
+ * Created by sban on 2017/5/29.
+ */
+
+'use strict'
+
+let service = require('./lib/service')
+var Promise = require('./lib/bluebird-3.5.0.min')
+let page = require('./lib/page')
+var promise = {
+ all: Promise.all,
+}
+
+var app = {
+ data:{
+ loading:false,
+ },
+ version: "1.0",
+ service: service,
+ promise: promise,
+ page: page,
+}
+
+function request(url,data,options) {
+ return new Promise(function (resolve, reject) {
+ wx.showNavigationBarLoading()
+
+ // 调用成功、失败都会执行
+ let complete = function () {
+ wx.hideNavigationBarLoading()
+ }
+ // 去掉微信的封装,直接返回服务器的结果
+ let success = function (res) {
+ if (res.statusCode == 200 && res.errMsg == "request:ok"){
+ resolve(res.data)
+ }else{
+ reject(res.errMsg)
+ }
+ }
+ var args = {
+ url: url,
+ header: { 'Content-Type': 'json' },
+ success: success,
+ fail: reject,
+ complete:complete,
+ }
+ if (data) {
+ args["method"] = "POST"
+ args["data"] = data
+ }
+ if (options){
+ Object.assign(args, options)
+ }
+ wx.request(args)
+ })
+}
+
+app["request"] = request
+
+module.exports = app
\ No newline at end of file
diff --git a/campus/utils/qqmap-wx-jssdk.js b/campus/utils/qqmap-wx-jssdk.js
new file mode 100644
index 0000000..4d53c58
--- /dev/null
+++ b/campus/utils/qqmap-wx-jssdk.js
@@ -0,0 +1,462 @@
+/**
+ * 微信小程序JavaScriptSDK
+ *
+ * @version 1.0
+ * @date 2017-01-10
+ * @author jaysonzhou@tencent.com
+ */
+
+var ERROR_CONF = {
+ KEY_ERR: 311,
+ KEY_ERR_MSG: 'key格式错误',
+ PARAM_ERR: 310,
+ PARAM_ERR_MSG: '请求参数信息有误',
+ SYSTEM_ERR: 600,
+ SYSTEM_ERR_MSG: '系统错误',
+ WX_ERR_CODE: 1000,
+ WX_OK_CODE: 200
+};
+var BASE_URL = 'https://apis.map.qq.com/ws/';
+var URL_SEARCH = BASE_URL + 'place/v1/search';
+var URL_SUGGESTION = BASE_URL + 'place/v1/suggestion';
+var URL_GET_GEOCODER = BASE_URL + 'geocoder/v1/';
+var URL_CITY_LIST = BASE_URL + 'district/v1/list';
+var URL_AREA_LIST = BASE_URL + 'district/v1/getchildren';
+var URL_DISTANCE = BASE_URL + 'distance/v1/';
+var Utils = {
+ /**
+ * 得到终点query字符串
+ * @param {Array|String} 检索数据
+ */
+ location2query(data) {
+ if (typeof data == 'string') {
+ return data;
+ }
+ var query = '';
+ for (var i = 0; i < data.length; i++) {
+ var d = data[i];
+ if (!!query) {
+ query += ';';
+ }
+ if (d.location) {
+ query = query + d.location.lat + ',' + d.location.lng;
+ }
+ if (d.latitude && d.longitude) {
+ query = query + d.latitude + ',' + d.longitude;
+ }
+ }
+ return query;
+ },
+
+ /**
+ * 使用微信接口进行定位
+ */
+ getWXLocation(success, fail, complete) {
+ wx.getLocation({
+ type: 'gcj02',
+ success: success,
+ fail: fail,
+ complete: complete
+ });
+ },
+
+ /**
+ * 获取location参数
+ */
+ getLocationParam(location) {
+ if (typeof location == 'string') {
+ var locationArr = location.split(',');
+ if (locationArr.length === 2) {
+ location = {
+ latitude: location.split(',')[0],
+ longitude: location.split(',')[1]
+ };
+ } else {
+ location = {};
+ }
+ }
+ return location;
+ },
+
+ /**
+ * 回调函数默认处理
+ */
+ polyfillParam(param) {
+ param.success = param.success || function () { };
+ param.fail = param.fail || function () { };
+ param.complete = param.complete || function () { };
+ },
+
+ /**
+ * 验证param对应的key值是否为空
+ *
+ * @param {Object} param 接口参数
+ * @param {String} key 对应参数的key
+ */
+ checkParamKeyEmpty(param, key) {
+ if (!param[key]) {
+ var errconf = this.buildErrorConfig(ERROR_CONF.PARAM_ERR, ERROR_CONF.PARAM_ERR_MSG + key +'参数格式有误');
+ param.fail(errconf);
+ param.complete(errconf);
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * 验证参数中是否存在检索词keyword
+ *
+ * @param {Object} param 接口参数
+ */
+ checkKeyword(param){
+ return !this.checkParamKeyEmpty(param, 'keyword');
+ },
+
+ /**
+ * 验证location值
+ *
+ * @param {Object} param 接口参数
+ */
+ checkLocation(param) {
+ var location = this.getLocationParam(param.location);
+ if (!location || !location.latitude || !location.longitude) {
+ var errconf = this.buildErrorConfig(ERROR_CONF.PARAM_ERR, ERROR_CONF.PARAM_ERR_MSG + ' location参数格式有误')
+ param.fail(errconf);
+ param.complete(errconf);
+ return false;
+ }
+ return true;
+ },
+
+ /**
+ * 构造错误数据结构
+ * @param {Number} errCode 错误码
+ * @param {Number} errMsg 错误描述
+ */
+ buildErrorConfig(errCode, errMsg) {
+ return {
+ status: errCode,
+ message: errMsg
+ };
+ },
+
+ /**
+ * 构造微信请求参数,公共属性处理
+ *
+ * @param {Object} param 接口参数
+ * @param {Object} param 配置项
+ */
+ buildWxRequestConfig(param, options) {
+ var that = this;
+ options.header = { "content-type": "application/json" };
+ options.method = 'GET';
+ options.success = function (res) {
+ var data = res.data;
+ if (data.status === 0) {
+ param.success(data);
+ } else {
+ param.fail(data);
+ }
+ };
+ options.fail = function (res) {
+ res.statusCode = ERROR_CONF.WX_ERR_CODE;
+ param.fail(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, result.errMsg));
+ };
+ options.complete = function (res) {
+ var statusCode = +res.statusCode;
+ switch(statusCode) {
+ case ERROR_CONF.WX_ERR_CODE: {
+ param.complete(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg));
+ break;
+ }
+ case ERROR_CONF.WX_OK_CODE: {
+ var data = res.data;
+ if (data.status === 0) {
+ param.complete(data);
+ } else {
+ param.complete(that.buildErrorConfig(data.status, data.message));
+ }
+ break;
+ }
+ default:{
+ param.complete(that.buildErrorConfig(ERROR_CONF.SYSTEM_ERR, ERROR_CONF.SYSTEM_ERR_MSG));
+ }
+
+ }
+ }
+ return options;
+ },
+
+ /**
+ * 处理用户参数是否传入坐标进行不同的处理
+ */
+ locationProcess(param, locationsuccess, locationfail, locationcomplete) {
+ var that = this;
+ locationfail = locationfail || function (res) {
+ res.statusCode = ERROR_CONF.WX_ERR_CODE;
+ param.fail(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg));
+ };
+ locationcomplete = locationcomplete || function (res) {
+ if (res.statusCode == ERROR_CONF.WX_ERR_CODE) {
+ param.complete(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg));
+ }
+ };
+ if (!param.location) {
+ that.getWXLocation(locationsuccess, locationfail, locationcomplete);
+ } else if (that.checkLocation(param)) {
+ var location = Utils.getLocationParam(param.location);
+ locationsuccess(location);
+ }
+ }
+}
+
+
+class QQMapWX {
+
+ /**
+ * 构造函数
+ *
+ * @param {Object} options 接口参数,key 为必选参数
+ */
+ constructor(options) {
+ if (!options.key) {
+ throw Error('key值不能为空');
+ }
+ this.key = options.key;
+ }
+
+ /**
+ * POI周边检索
+ *
+ * @param {Object} options 接口参数对象
+ *
+ * 参数对象结构可以参考
+ * @see http://lbs.qq.com/webservice_v1/guide-search.html
+ */
+ search(options) {
+ var that = this;
+ options = options || {};
+
+ Utils.polyfillParam(options);
+
+ if (!Utils.checkKeyword(options)) {
+ return;
+ }
+
+ var requestParam = {
+ keyword: options.keyword,
+ orderby: options.orderby || '_distance',
+ page_size: options.page_size || 10,
+ page_index: options.page_index || 1,
+ output: 'json',
+ key: that.key
+ };
+
+ if (options.address_format) {
+ requestParam.address_format = options.address_format;
+ }
+
+ if (options.filter) {
+ requestParam.filter = options.filter;
+ }
+
+ var distance = options.distance || "1000";
+ var auto_extend = options.auto_extend || 1;
+
+ var locationsuccess = function (result) {
+ requestParam.boundary = "nearby(" + result.latitude + "," + result.longitude + "," + distance + "," + auto_extend +")";
+ wx.request(Utils.buildWxRequestConfig(options, {
+ url: URL_SEARCH,
+ data: requestParam
+ }));
+ }
+ Utils.locationProcess(options, locationsuccess);
+ }
+
+ /**
+ * sug模糊检索
+ *
+ * @param {Object} options 接口参数对象
+ *
+ * 参数对象结构可以参考
+ * http://lbs.qq.com/webservice_v1/guide-suggestion.html
+ */
+ getSuggestion(options) {
+ var that = this;
+ options = options || {};
+ Utils.polyfillParam(options);
+
+ if (!Utils.checkKeyword(options)) {
+ return;
+ }
+
+ var requestParam = {
+ keyword: options.keyword,
+ region: options.region || '全国',
+ region_fix: options.region_fix || 0,
+ policy: options.policy || 0,
+ output: 'json',
+ key: that.key
+ };
+ wx.request(Utils.buildWxRequestConfig(options, {
+ url: URL_SUGGESTION,
+ data: requestParam
+ }));
+ }
+
+ /**
+ * 逆地址解析
+ *
+ * @param {Object} options 接口参数对象
+ *
+ * 请求参数结构可以参考
+ * http://lbs.qq.com/webservice_v1/guide-gcoder.html
+ */
+ reverseGeocoder(options) {
+ var that = this;
+ options = options || {};
+ Utils.polyfillParam(options);
+ var requestParam = {
+ coord_type: options.coord_type || 5,
+ get_poi: options.get_poi || 0,
+ output: 'json',
+ key: that.key
+ };
+ if (options.poi_options) {
+ requestParam.poi_options = options.poi_options
+ }
+
+ var locationsuccess = function (result) {
+ requestParam.location = result.latitude + ',' + result.longitude;
+ wx.request(Utils.buildWxRequestConfig(options, {
+ url: URL_GET_GEOCODER,
+ data: requestParam
+ }));
+ };
+ Utils.locationProcess(options, locationsuccess);
+ }
+
+ /**
+ * 地址解析
+ *
+ * @param {Object} options 接口参数对象
+ *
+ * 请求参数结构可以参考
+ * http://lbs.qq.com/webservice_v1/guide-geocoder.html
+ */
+ geocoder(options) {
+ var that = this;
+ options = options || {};
+ Utils.polyfillParam(options);
+
+ if (Utils.checkParamKeyEmpty(options, 'address')) {
+ return;
+ }
+
+ var requestParam = {
+ address: options.address,
+ output: 'json',
+ key: that.key
+ };
+
+ wx.request(Utils.buildWxRequestConfig(options, {
+ url: URL_GET_GEOCODER,
+ data: requestParam
+ }));
+ }
+
+
+ /**
+ * 获取城市列表
+ *
+ * @param {Object} options 接口参数对象
+ *
+ * 请求参数结构可以参考
+ * http://lbs.qq.com/webservice_v1/guide-region.html
+ */
+ getCityList(options) {
+ var that = this;
+ options = options || {};
+ Utils.polyfillParam(options);
+ var requestParam = {
+ output: 'json',
+ key: that.key
+ };
+
+ wx.request(Utils.buildWxRequestConfig(options, {
+ url: URL_CITY_LIST,
+ data: requestParam
+ }));
+ }
+
+ /**
+ * 获取对应城市ID的区县列表
+ *
+ * @param {Object} options 接口参数对象
+ *
+ * 请求参数结构可以参考
+ * http://lbs.qq.com/webservice_v1/guide-region.html
+ */
+ getDistrictByCityId(options) {
+ var that = this;
+ options = options || {};
+ Utils.polyfillParam(options);
+
+ if (Utils.checkParamKeyEmpty(options, 'id')) {
+ return;
+ }
+
+ var requestParam = {
+ id: options.id || '',
+ output: 'json',
+ key: that.key
+ };
+
+ wx.request(Utils.buildWxRequestConfig(options, {
+ url: URL_AREA_LIST,
+ data: requestParam
+ }));
+ }
+
+ /**
+ * 用于单起点到多终点的路线距离(非直线距离)计算:
+ * 支持两种距离计算方式:步行和驾车。
+ * 起点到终点最大限制直线距离10公里。
+ *
+ * @param {Object} options 接口参数对象
+ *
+ * 请求参数结构可以参考
+ * http://lbs.qq.com/webservice_v1/guide-distance.html
+ */
+ calculateDistance(options) {
+ var that = this;
+ options = options || {};
+ Utils.polyfillParam(options);
+
+ if (Utils.checkParamKeyEmpty(options, 'to')) {
+ return;
+ }
+
+ var requestParam = {
+ mode: options.mode || 'walking',
+ to: Utils.location2query(options.to),
+ output: 'json',
+ key: that.key
+ };
+
+ var locationsuccess = function (result) {
+ requestParam.from = result.latitude + ',' + result.longitude;
+ wx.request(Utils.buildWxRequestConfig(options, {
+ url: URL_DISTANCE,
+ data: requestParam
+ }));
+ }
+ if (options.from) {
+ options.location = options.from;
+ }
+
+ Utils.locationProcess(options, locationsuccess);
+ }
+}
+
+module.exports = QQMapWX;
\ No newline at end of file
diff --git a/campus/utils/qqmap-wx-jssdk.min.js b/campus/utils/qqmap-wx-jssdk.min.js
new file mode 100644
index 0000000..f1a1eb6
--- /dev/null
+++ b/campus/utils/qqmap-wx-jssdk.min.js
@@ -0,0 +1,8 @@
+var _createClass = function () { function a(e, c) { for (var b = 0; b < c.length; b++) { var d = c[b]; d.enumerable = d.enumerable || false; d.configurable = true; if ("value" in d) { d.writable = true } Object.defineProperty(e, d.key, d) } } return function (d, b, c) { if (b) { a(d.prototype, b) } if (c) { a(d, c) } return d } }(); function _classCallCheck(a, b) { if (!(a instanceof b)) { throw new TypeError("Cannot call a class as a function") } } var ERROR_CONF = { KEY_ERR: 311, KEY_ERR_MSG: "key格式错误", PARAM_ERR: 310, PARAM_ERR_MSG: "请求参数信息有误", SYSTEM_ERR: 600, SYSTEM_ERR_MSG: "系统错误", WX_ERR_CODE: 1000, WX_OK_CODE: 200 }; var BASE_URL = "https://apis.map.qq.com/ws/"; var URL_SEARCH = BASE_URL + "place/v1/search"; var URL_SUGGESTION = BASE_URL + "place/v1/suggestion"; var URL_GET_GEOCODER = BASE_URL + "geocoder/v1/"; var URL_CITY_LIST = BASE_URL + "district/v1/list"; var URL_AREA_LIST = BASE_URL + "district/v1/getchildren"; var URL_DISTANCE = BASE_URL + "distance/v1/"; var Utils = { location2query: function location2query(c) { if (typeof c == "string") { return c } var b = ""; for (var a = 0; a < c.length; a++) { var e = c[a]; if (!!b) { b += ";" } if (e.location) { b = b + e.location.lat + "," + e.location.lng } if (e.latitude && e.longitude) { b = b + e.latitude + "," + e.longitude } } return b }, getWXLocation: function getWXLocation(c, b, a) { wx.getLocation({ type: "gcj02", success: c, fail: b, complete: a }) }, getLocationParam: function getLocationParam(b) { if (typeof b == "string") { var a = b.split(","); if (a.length === 2) { b = { latitude: b.split(",")[0], longitude: b.split(",")[1] } } else { b = {} } } return b }, polyfillParam: function polyfillParam(a) { a.success = a.success || function () { }; a.fail = a.fail || function () { }; a.complete = a.complete || function () { } }, checkParamKeyEmpty: function checkParamKeyEmpty(c, b) { if (!c[b]) { var a = this.buildErrorConfig(ERROR_CONF.PARAM_ERR, ERROR_CONF.PARAM_ERR_MSG + b + "参数格式有误"); c.fail(a); c.complete(a); return true } return false }, checkKeyword: function checkKeyword(a) { return !this.checkParamKeyEmpty(a, "keyword") }, checkLocation: function checkLocation(c) { var a = this.getLocationParam(c.location); if (!a || !a.latitude || !a.longitude) { var b = this.buildErrorConfig(ERROR_CONF.PARAM_ERR, ERROR_CONF.PARAM_ERR_MSG + " location参数格式有误"); c.fail(b); c.complete(b); return false } return true }, buildErrorConfig: function buildErrorConfig(a, b) { return { status: a, message: b } }, buildWxRequestConfig: function buildWxRequestConfig(c, a) { var b = this; a.header = { "content-type": "application/json" }; a.method = "GET"; a.success = function (d) { var e = d.data; if (e.status === 0) { c.success(e) } else { c.fail(e) } }; a.fail = function (d) { d.statusCode = ERROR_CONF.WX_ERR_CODE; c.fail(b.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, result.errMsg)) }; a.complete = function (d) { var e = +d.statusCode; switch (e) { case ERROR_CONF.WX_ERR_CODE: c.complete(b.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, d.errMsg)); break; case ERROR_CONF.WX_OK_CODE: var f = d.data; if (f.status === 0) { c.complete(f) } else { c.complete(b.buildErrorConfig(f.status, f.message)) } break; default: c.complete(b.buildErrorConfig(ERROR_CONF.SYSTEM_ERR, ERROR_CONF.SYSTEM_ERR_MSG)) } }; return a }, locationProcess: function locationProcess(f, e, c, a) { var d = this; c = c || function (g) { g.statusCode = ERROR_CONF.WX_ERR_CODE; f.fail(d.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, g.errMsg)) }; a = a || function (g) { if (g.statusCode == ERROR_CONF.WX_ERR_CODE) { f.complete(d.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, g.errMsg)) } }; if (!f.location) { d.getWXLocation(e, c, a) } else { if (d.checkLocation(f)) { var b = Utils.getLocationParam(f.location); e(b) } } } }; var QQMapWX = function () {
+ function b(i) { _classCallCheck(this, b); if (!i.key) { throw Error("key值不能为空") } this.key = i.key } _createClass(b, [{ key: "search", value: function f(i) { var l = this; i = i || {}; Utils.polyfillParam(i); if (!Utils.checkKeyword(i)) { return } var k = { keyword: i.keyword, orderby: i.orderby || "_distance", page_size: i.page_size || 10, page_index: i.page_index || 1, output: "json", key: l.key }; if (i.address_format) { k.address_format = i.address_format } if (i.filter) { k.filter = i.filter } var n = i.distance || "1000"; var j = i.auto_extend || 1; var m = function m(o) { k.boundary = "nearby(" + o.latitude + "," + o.longitude + "," + n + "," + j + ")"; wx.request(Utils.buildWxRequestConfig(i, { url: URL_SEARCH, data: k })) }; Utils.locationProcess(i, m) } }, { key: "getSuggestion", value: function h(i) { var k = this; i = i || {}; Utils.polyfillParam(i); if (!Utils.checkKeyword(i)) { return } var j = { keyword: i.keyword, region: i.region || "全国", region_fix: i.region_fix || 0, policy: i.policy || 0, output: "json", key: k.key }; wx.request(Utils.buildWxRequestConfig(i, { url: URL_SUGGESTION, data: j })) } }, { key: "reverseGeocoder", value: function a(i) { var k = this; i = i || {}; Utils.polyfillParam(i); var j = { coord_type: i.coord_type || 5, get_poi: i.get_poi || 0, output: "json", key: k.key }; if (i.poi_options) { j.poi_options = i.poi_options } var l = function l(m) { j.location = m.latitude + "," + m.longitude; wx.request(Utils.buildWxRequestConfig(i, { url: URL_GET_GEOCODER, data: j })) }; Utils.locationProcess(i, l) } }, { key: "geocoder", value: function g(i) { var k = this; i = i || {}; Utils.polyfillParam(i); if (Utils.checkParamKeyEmpty(i, "address")) { return } var j = { address: i.address, output: "json", key: k.key }; wx.request(Utils.buildWxRequestConfig(i, { url: URL_GET_GEOCODER, data: j })) } }, {
+ key: "getCityList", value: function c(i) {
+ var k = this; i = i || {}; Utils.polyfillParam(i); var j = { output: "json", key: k.key };
+ wx.request(Utils.buildWxRequestConfig(i, { url: URL_CITY_LIST, data: j }))
+ }
+ }, { key: "getDistrictByCityId", value: function d(i) { var k = this; i = i || {}; Utils.polyfillParam(i); if (Utils.checkParamKeyEmpty(i, "id")) { return } var j = { id: i.id || "", output: "json", key: k.key }; wx.request(Utils.buildWxRequestConfig(i, { url: URL_AREA_LIST, data: j })) } }, { key: "calculateDistance", value: function e(i) { var k = this; i = i || {}; Utils.polyfillParam(i); if (Utils.checkParamKeyEmpty(i, "to")) { return } var j = { mode: i.mode || "walking", to: Utils.location2query(i.to), output: "json", key: k.key }; var l = function l(m) { j.from = m.latitude + "," + m.longitude; wx.request(Utils.buildWxRequestConfig(i, { url: URL_DISTANCE, data: j })) }; if (i.from) { i.location = i.from } Utils.locationProcess(i, l) } }]); return b
+}(); module.exports = QQMapWX;
\ No newline at end of file
diff --git a/campus/utils/underscore.js b/campus/utils/underscore.js
new file mode 100644
index 0000000..1f79048
--- /dev/null
+++ b/campus/utils/underscore.js
@@ -0,0 +1,1574 @@
+// Underscore.js 1.8.3
+// http://underscorejs.org
+// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+// Underscore may be freely distributed under the MIT license.
+
+(function() {
+
+ // Baseline setup
+ // --------------
+
+ // Establish the root object, `window` in the browser, or `exports` on the server.
+ //var root = this;
+
+ // Save the previous value of the `_` variable.
+ //var previousUnderscore = root._;
+
+ // Save bytes in the minified (but not gzipped) version:
+ var ArrayProto = Array.prototype,
+ ObjProto = Object.prototype,
+ FuncProto = Function.prototype;
+
+ // Create quick reference variables for speed access to core prototypes.
+ var
+ push = ArrayProto.push,
+ slice = ArrayProto.slice,
+ toString = ObjProto.toString,
+ hasOwnProperty = ObjProto.hasOwnProperty;
+
+ // All **ECMAScript 5** native function implementations that we hope to use
+ // are declared here.
+ var
+ nativeIsArray = Array.isArray,
+ nativeKeys = Object.keys,
+ nativeBind = FuncProto.bind,
+ nativeCreate = Object.create;
+
+ // Naked function reference for surrogate-prototype-swapping.
+ var Ctor = function() {};
+
+ // Create a safe reference to the Underscore object for use below.
+ var _ = function(obj) {
+ if (obj instanceof _) return obj;
+ if (!(this instanceof _)) return new _(obj);
+ this._wrapped = obj;
+ };
+
+ // Export the Underscore object for **Node.js**, with
+ // backwards-compatibility for the old `require()` API. If we're in
+ // the browser, add `_` as a global object.
+ if (typeof exports !== 'undefined') {
+ if (typeof module !== 'undefined' && module.exports) {
+ exports = module.exports = _;
+ }
+ exports._ = _;
+ } else {
+ root._ = _;
+ }
+
+ // Current version.
+ _.VERSION = '1.8.3';
+
+ // Internal function that returns an efficient (for current engines) version
+ // of the passed-in callback, to be repeatedly applied in other Underscore
+ // functions.
+ var optimizeCb = function(func, context, argCount) {
+ if (context === void 0) return func;
+ switch (argCount == null ? 3 : argCount) {
+ case 1:
+ return function(value) {
+ return func.call(context, value);
+ };
+ case 2:
+ return function(value, other) {
+ return func.call(context, value, other);
+ };
+ case 3:
+ return function(value, index, collection) {
+ return func.call(context, value, index, collection);
+ };
+ case 4:
+ return function(accumulator, value, index, collection) {
+ return func.call(context, accumulator, value, index, collection);
+ };
+ }
+ return function() {
+ return func.apply(context, arguments);
+ };
+ };
+
+ // A mostly-internal function to generate callbacks that can be applied
+ // to each element in a collection, returning the desired result — either
+ // identity, an arbitrary callback, a property matcher, or a property accessor.
+ var cb = function(value, context, argCount) {
+ if (value == null) return _.identity;
+ if (_.isFunction(value)) return optimizeCb(value, context, argCount);
+ if (_.isObject(value)) return _.matcher(value);
+ return _.property(value);
+ };
+ _.iteratee = function(value, context) {
+ return cb(value, context, Infinity);
+ };
+
+ // An internal function for creating assigner functions.
+ var createAssigner = function(keysFunc, undefinedOnly) {
+ return function(obj) {
+ var length = arguments.length;
+ if (length < 2 || obj == null) return obj;
+ for (var index = 1; index < length; index++) {
+ var source = arguments[index],
+ keys = keysFunc(source),
+ l = keys.length;
+ for (var i = 0; i < l; i++) {
+ var key = keys[i];
+ if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key];
+ }
+ }
+ return obj;
+ };
+ };
+
+ // An internal function for creating a new object that inherits from another.
+ var baseCreate = function(prototype) {
+ if (!_.isObject(prototype)) return {};
+ if (nativeCreate) return nativeCreate(prototype);
+ Ctor.prototype = prototype;
+ var result = new Ctor;
+ Ctor.prototype = null;
+ return result;
+ };
+
+ var property = function(key) {
+ return function(obj) {
+ return obj == null ? void 0 : obj[key];
+ };
+ };
+
+ // Helper for collection methods to determine whether a collection
+ // should be iterated as an array or as an object
+ // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength
+ // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094
+ var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;
+ var getLength = property('length');
+ var isArrayLike = function(collection) {
+ var length = getLength(collection);
+ return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX;
+ };
+
+ // Collection Functions
+ // --------------------
+
+ // The cornerstone, an `each` implementation, aka `forEach`.
+ // Handles raw objects in addition to array-likes. Treats all
+ // sparse array-likes as if they were dense.
+ _.each = _.forEach = function(obj, iteratee, context) {
+ iteratee = optimizeCb(iteratee, context);
+ var i, length;
+ if (isArrayLike(obj)) {
+ for (i = 0, length = obj.length; i < length; i++) {
+ iteratee(obj[i], i, obj);
+ }
+ } else {
+ var keys = _.keys(obj);
+ for (i = 0, length = keys.length; i < length; i++) {
+ iteratee(obj[keys[i]], keys[i], obj);
+ }
+ }
+ return obj;
+ };
+
+ // Return the results of applying the iteratee to each element.
+ _.map = _.collect = function(obj, iteratee, context) {
+ iteratee = cb(iteratee, context);
+ var keys = !isArrayLike(obj) && _.keys(obj),
+ length = (keys || obj).length,
+ results = Array(length);
+ for (var index = 0; index < length; index++) {
+ var currentKey = keys ? keys[index] : index;
+ results[index] = iteratee(obj[currentKey], currentKey, obj);
+ }
+ return results;
+ };
+
+ // Create a reducing function iterating left or right.
+ function createReduce(dir) {
+ // Optimized iterator function as using arguments.length
+ // in the main function will deoptimize the, see #1991.
+ function iterator(obj, iteratee, memo, keys, index, length) {
+ for (; index >= 0 && index < length; index += dir) {
+ var currentKey = keys ? keys[index] : index;
+ memo = iteratee(memo, obj[currentKey], currentKey, obj);
+ }
+ return memo;
+ }
+
+ return function(obj, iteratee, memo, context) {
+ iteratee = optimizeCb(iteratee, context, 4);
+ var keys = !isArrayLike(obj) && _.keys(obj),
+ length = (keys || obj).length,
+ index = dir > 0 ? 0 : length - 1;
+ // Determine the initial value if none is provided.
+ if (arguments.length < 3) {
+ memo = obj[keys ? keys[index] : index];
+ index += dir;
+ }
+ return iterator(obj, iteratee, memo, keys, index, length);
+ };
+ }
+
+ // **Reduce** builds up a single result from a list of values, aka `inject`,
+ // or `foldl`.
+ _.reduce = _.foldl = _.inject = createReduce(1);
+
+ // The right-associative version of reduce, also known as `foldr`.
+ _.reduceRight = _.foldr = createReduce(-1);
+
+ // Return the first value which passes a truth test. Aliased as `detect`.
+ _.find = _.detect = function(obj, predicate, context) {
+ var key;
+ if (isArrayLike(obj)) {
+ key = _.findIndex(obj, predicate, context);
+ } else {
+ key = _.findKey(obj, predicate, context);
+ }
+ if (key !== void 0 && key !== -1) return obj[key];
+ };
+
+ // Return all the elements that pass a truth test.
+ // Aliased as `select`.
+ _.filter = _.select = function(obj, predicate, context) {
+ var results = [];
+ predicate = cb(predicate, context);
+ _.each(obj, function(value, index, list) {
+ if (predicate(value, index, list)) results.push(value);
+ });
+ return results;
+ };
+
+ // Return all the elements for which a truth test fails.
+ _.reject = function(obj, predicate, context) {
+ return _.filter(obj, _.negate(cb(predicate)), context);
+ };
+
+ // Determine whether all of the elements match a truth test.
+ // Aliased as `all`.
+ _.every = _.all = function(obj, predicate, context) {
+ predicate = cb(predicate, context);
+ var keys = !isArrayLike(obj) && _.keys(obj),
+ length = (keys || obj).length;
+ for (var index = 0; index < length; index++) {
+ var currentKey = keys ? keys[index] : index;
+ if (!predicate(obj[currentKey], currentKey, obj)) return false;
+ }
+ return true;
+ };
+
+ // Determine if at least one element in the object matches a truth test.
+ // Aliased as `any`.
+ _.some = _.any = function(obj, predicate, context) {
+ predicate = cb(predicate, context);
+ var keys = !isArrayLike(obj) && _.keys(obj),
+ length = (keys || obj).length;
+ for (var index = 0; index < length; index++) {
+ var currentKey = keys ? keys[index] : index;
+ if (predicate(obj[currentKey], currentKey, obj)) return true;
+ }
+ return false;
+ };
+
+ // Determine if the array or object contains a given item (using `===`).
+ // Aliased as `includes` and `include`.
+ _.contains = _.includes = _.include = function(obj, item, fromIndex, guard) {
+ if (!isArrayLike(obj)) obj = _.values(obj);
+ if (typeof fromIndex != 'number' || guard) fromIndex = 0;
+ return _.indexOf(obj, item, fromIndex) >= 0;
+ };
+
+ // Invoke a method (with arguments) on every item in a collection.
+ _.invoke = function(obj, method) {
+ var args = slice.call(arguments, 2);
+ var isFunc = _.isFunction(method);
+ return _.map(obj, function(value) {
+ var func = isFunc ? method : value[method];
+ return func == null ? func : func.apply(value, args);
+ });
+ };
+
+ // Convenience version of a common use case of `map`: fetching a property.
+ _.pluck = function(obj, key) {
+ return _.map(obj, _.property(key));
+ };
+
+ // Convenience version of a common use case of `filter`: selecting only objects
+ // containing specific `key:value` pairs.
+ _.where = function(obj, attrs) {
+ return _.filter(obj, _.matcher(attrs));
+ };
+
+ // Convenience version of a common use case of `find`: getting the first object
+ // containing specific `key:value` pairs.
+ _.findWhere = function(obj, attrs) {
+ return _.find(obj, _.matcher(attrs));
+ };
+
+ // Return the maximum element (or element-based computation).
+ _.max = function(obj, iteratee, context) {
+ var result = -Infinity,
+ lastComputed = -Infinity,
+ value, computed;
+ if (iteratee == null && obj != null) {
+ obj = isArrayLike(obj) ? obj : _.values(obj);
+ for (var i = 0, length = obj.length; i < length; i++) {
+ value = obj[i];
+ if (value > result) {
+ result = value;
+ }
+ }
+ } else {
+ iteratee = cb(iteratee, context);
+ _.each(obj, function(value, index, list) {
+ computed = iteratee(value, index, list);
+ if (computed > lastComputed || computed === -Infinity && result === -Infinity) {
+ result = value;
+ lastComputed = computed;
+ }
+ });
+ }
+ return result;
+ };
+
+ // Return the minimum element (or element-based computation).
+ _.min = function(obj, iteratee, context) {
+ var result = Infinity,
+ lastComputed = Infinity,
+ value, computed;
+ if (iteratee == null && obj != null) {
+ obj = isArrayLike(obj) ? obj : _.values(obj);
+ for (var i = 0, length = obj.length; i < length; i++) {
+ value = obj[i];
+ if (value < result) {
+ result = value;
+ }
+ }
+ } else {
+ iteratee = cb(iteratee, context);
+ _.each(obj, function(value, index, list) {
+ computed = iteratee(value, index, list);
+ if (computed < lastComputed || computed === Infinity && result === Infinity) {
+ result = value;
+ lastComputed = computed;
+ }
+ });
+ }
+ return result;
+ };
+
+ // Shuffle a collection, using the modern version of the
+ // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
+ _.shuffle = function(obj) {
+ var set = isArrayLike(obj) ? obj : _.values(obj);
+ var length = set.length;
+ var shuffled = Array(length);
+ for (var index = 0, rand; index < length; index++) {
+ rand = _.random(0, index);
+ if (rand !== index) shuffled[index] = shuffled[rand];
+ shuffled[rand] = set[index];
+ }
+ return shuffled;
+ };
+
+ // Sample **n** random values from a collection.
+ // If **n** is not specified, returns a single random element.
+ // The internal `guard` argument allows it to work with `map`.
+ _.sample = function(obj, n, guard) {
+ if (n == null || guard) {
+ if (!isArrayLike(obj)) obj = _.values(obj);
+ return obj[_.random(obj.length - 1)];
+ }
+ return _.shuffle(obj).slice(0, Math.max(0, n));
+ };
+
+ // Sort the object's values by a criterion produced by an iteratee.
+ _.sortBy = function(obj, iteratee, context) {
+ iteratee = cb(iteratee, context);
+ return _.pluck(_.map(obj, function(value, index, list) {
+ return {
+ value: value,
+ index: index,
+ criteria: iteratee(value, index, list)
+ };
+ }).sort(function(left, right) {
+ var a = left.criteria;
+ var b = right.criteria;
+ if (a !== b) {
+ if (a > b || a === void 0) return 1;
+ if (a < b || b === void 0) return -1;
+ }
+ return left.index - right.index;
+ }), 'value');
+ };
+
+ // An internal function used for aggregate "group by" operations.
+ var group = function(behavior) {
+ return function(obj, iteratee, context) {
+ var result = {};
+ iteratee = cb(iteratee, context);
+ _.each(obj, function(value, index) {
+ var key = iteratee(value, index, obj);
+ behavior(result, value, key);
+ });
+ return result;
+ };
+ };
+
+ // Groups the object's values by a criterion. Pass either a string attribute
+ // to group by, or a function that returns the criterion.
+ _.groupBy = group(function(result, value, key) {
+ if (_.has(result, key)) result[key].push(value);
+ else result[key] = [value];
+ });
+
+ // Indexes the object's values by a criterion, similar to `groupBy`, but for
+ // when you know that your index values will be unique.
+ _.indexBy = group(function(result, value, key) {
+ result[key] = value;
+ });
+
+ // Counts instances of an object that group by a certain criterion. Pass
+ // either a string attribute to count by, or a function that returns the
+ // criterion.
+ _.countBy = group(function(result, value, key) {
+ if (_.has(result, key)) result[key]++;
+ else result[key] = 1;
+ });
+
+ // Safely create a real, live array from anything iterable.
+ _.toArray = function(obj) {
+ if (!obj) return [];
+ if (_.isArray(obj)) return slice.call(obj);
+ if (isArrayLike(obj)) return _.map(obj, _.identity);
+ return _.values(obj);
+ };
+
+ // Return the number of elements in an object.
+ _.size = function(obj) {
+ if (obj == null) return 0;
+ return isArrayLike(obj) ? obj.length : _.keys(obj).length;
+ };
+
+ // Split a collection into two arrays: one whose elements all satisfy the given
+ // predicate, and one whose elements all do not satisfy the predicate.
+ _.partition = function(obj, predicate, context) {
+ predicate = cb(predicate, context);
+ var pass = [],
+ fail = [];
+ _.each(obj, function(value, key, obj) {
+ (predicate(value, key, obj) ? pass : fail).push(value);
+ });
+ return [pass, fail];
+ };
+
+ // Array Functions
+ // ---------------
+
+ // Get the first element of an array. Passing **n** will return the first N
+ // values in the array. Aliased as `head` and `take`. The **guard** check
+ // allows it to work with `_.map`.
+ _.first = _.head = _.take = function(array, n, guard) {
+ if (array == null) return void 0;
+ if (n == null || guard) return array[0];
+ return _.initial(array, array.length - n);
+ };
+
+ // Returns everything but the last entry of the array. Especially useful on
+ // the arguments object. Passing **n** will return all the values in
+ // the array, excluding the last N.
+ _.initial = function(array, n, guard) {
+ return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));
+ };
+
+ // Get the last element of an array. Passing **n** will return the last N
+ // values in the array.
+ _.last = function(array, n, guard) {
+ if (array == null) return void 0;
+ if (n == null || guard) return array[array.length - 1];
+ return _.rest(array, Math.max(0, array.length - n));
+ };
+
+ // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
+ // Especially useful on the arguments object. Passing an **n** will return
+ // the rest N values in the array.
+ _.rest = _.tail = _.drop = function(array, n, guard) {
+ return slice.call(array, n == null || guard ? 1 : n);
+ };
+
+ // Trim out all falsy values from an array.
+ _.compact = function(array) {
+ return _.filter(array, _.identity);
+ };
+
+ // Internal implementation of a recursive `flatten` function.
+ var flatten = function(input, shallow, strict, startIndex) {
+ var output = [],
+ idx = 0;
+ for (var i = startIndex || 0, length = getLength(input); i < length; i++) {
+ var value = input[i];
+ if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) {
+ //flatten current level of array or arguments object
+ if (!shallow) value = flatten(value, shallow, strict);
+ var j = 0,
+ len = value.length;
+ output.length += len;
+ while (j < len) {
+ output[idx++] = value[j++];
+ }
+ } else if (!strict) {
+ output[idx++] = value;
+ }
+ }
+ return output;
+ };
+
+ // Flatten out an array, either recursively (by default), or just one level.
+ _.flatten = function(array, shallow) {
+ return flatten(array, shallow, false);
+ };
+
+ // Return a version of the array that does not contain the specified value(s).
+ _.without = function(array) {
+ return _.difference(array, slice.call(arguments, 1));
+ };
+
+ // Produce a duplicate-free version of the array. If the array has already
+ // been sorted, you have the option of using a faster algorithm.
+ // Aliased as `unique`.
+ _.uniq = _.unique = function(array, isSorted, iteratee, context) {
+ if (!_.isBoolean(isSorted)) {
+ context = iteratee;
+ iteratee = isSorted;
+ isSorted = false;
+ }
+ if (iteratee != null) iteratee = cb(iteratee, context);
+ var result = [];
+ var seen = [];
+ for (var i = 0, length = getLength(array); i < length; i++) {
+ var value = array[i],
+ computed = iteratee ? iteratee(value, i, array) : value;
+ if (isSorted) {
+ if (!i || seen !== computed) result.push(value);
+ seen = computed;
+ } else if (iteratee) {
+ if (!_.contains(seen, computed)) {
+ seen.push(computed);
+ result.push(value);
+ }
+ } else if (!_.contains(result, value)) {
+ result.push(value);
+ }
+ }
+ return result;
+ };
+
+ // Produce an array that contains the union: each distinct element from all of
+ // the passed-in arrays.
+ _.union = function() {
+ return _.uniq(flatten(arguments, true, true));
+ };
+
+ // Produce an array that contains every item shared between all the
+ // passed-in arrays.
+ _.intersection = function(array) {
+ var result = [];
+ var argsLength = arguments.length;
+ for (var i = 0, length = getLength(array); i < length; i++) {
+ var item = array[i];
+ if (_.contains(result, item)) continue;
+ for (var j = 1; j < argsLength; j++) {
+ if (!_.contains(arguments[j], item)) break;
+ }
+ if (j === argsLength) result.push(item);
+ }
+ return result;
+ };
+
+ // Take the difference between one array and a number of other arrays.
+ // Only the elements present in just the first array will remain.
+ _.difference = function(array) {
+ var rest = flatten(arguments, true, true, 1);
+ return _.filter(array, function(value) {
+ return !_.contains(rest, value);
+ });
+ };
+
+ // Zip together multiple lists into a single array -- elements that share
+ // an index go together.
+ _.zip = function() {
+ return _.unzip(arguments);
+ };
+
+ // Complement of _.zip. Unzip accepts an array of arrays and groups
+ // each array's elements on shared indices
+ _.unzip = function(array) {
+ var length = array && _.max(array, getLength).length || 0;
+ var result = Array(length);
+
+ for (var index = 0; index < length; index++) {
+ result[index] = _.pluck(array, index);
+ }
+ return result;
+ };
+
+ // Converts lists into objects. Pass either a single array of `[key, value]`
+ // pairs, or two parallel arrays of the same length -- one of keys, and one of
+ // the corresponding values.
+ _.object = function(list, values) {
+ var result = {};
+ for (var i = 0, length = getLength(list); i < length; i++) {
+ if (values) {
+ result[list[i]] = values[i];
+ } else {
+ result[list[i][0]] = list[i][1];
+ }
+ }
+ return result;
+ };
+
+ // Generator function to create the findIndex and findLastIndex functions
+ function createPredicateIndexFinder(dir) {
+ return function(array, predicate, context) {
+ predicate = cb(predicate, context);
+ var length = getLength(array);
+ var index = dir > 0 ? 0 : length - 1;
+ for (; index >= 0 && index < length; index += dir) {
+ if (predicate(array[index], index, array)) return index;
+ }
+ return -1;
+ };
+ }
+
+ // Returns the first index on an array-like that passes a predicate test
+ _.findIndex = createPredicateIndexFinder(1);
+ _.findLastIndex = createPredicateIndexFinder(-1);
+
+ // Use a comparator function to figure out the smallest index at which
+ // an object should be inserted so as to maintain order. Uses binary search.
+ _.sortedIndex = function(array, obj, iteratee, context) {
+ iteratee = cb(iteratee, context, 1);
+ var value = iteratee(obj);
+ var low = 0,
+ high = getLength(array);
+ while (low < high) {
+ var mid = Math.floor((low + high) / 2);
+ if (iteratee(array[mid]) < value) low = mid + 1;
+ else high = mid;
+ }
+ return low;
+ };
+
+ // Generator function to create the indexOf and lastIndexOf functions
+ function createIndexFinder(dir, predicateFind, sortedIndex) {
+ return function(array, item, idx) {
+ var i = 0,
+ length = getLength(array);
+ if (typeof idx == 'number') {
+ if (dir > 0) {
+ i = idx >= 0 ? idx : Math.max(idx + length, i);
+ } else {
+ length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1;
+ }
+ } else if (sortedIndex && idx && length) {
+ idx = sortedIndex(array, item);
+ return array[idx] === item ? idx : -1;
+ }
+ if (item !== item) {
+ idx = predicateFind(slice.call(array, i, length), _.isNaN);
+ return idx >= 0 ? idx + i : -1;
+ }
+ for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) {
+ if (array[idx] === item) return idx;
+ }
+ return -1;
+ };
+ }
+
+ // Return the position of the first occurrence of an item in an array,
+ // or -1 if the item is not included in the array.
+ // If the array is large and already in sort order, pass `true`
+ // for **isSorted** to use binary search.
+ _.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex);
+ _.lastIndexOf = createIndexFinder(-1, _.findLastIndex);
+
+ // Generate an integer Array containing an arithmetic progression. A port of
+ // the native Python `range()` function. See
+ // [the Python documentation](http://docs.python.org/library/functions.html#range).
+ _.range = function(start, stop, step) {
+ if (stop == null) {
+ stop = start || 0;
+ start = 0;
+ }
+ step = step || 1;
+
+ var length = Math.max(Math.ceil((stop - start) / step), 0);
+ var range = Array(length);
+
+ for (var idx = 0; idx < length; idx++, start += step) {
+ range[idx] = start;
+ }
+
+ return range;
+ };
+
+ // Function (ahem) Functions
+ // ------------------
+
+ // Determines whether to execute a function as a constructor
+ // or a normal function with the provided arguments
+ var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) {
+ if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);
+ var self = baseCreate(sourceFunc.prototype);
+ var result = sourceFunc.apply(self, args);
+ if (_.isObject(result)) return result;
+ return self;
+ };
+
+ // Create a function bound to a given object (assigning `this`, and arguments,
+ // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
+ // available.
+ _.bind = function(func, context) {
+ if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
+ if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function');
+ var args = slice.call(arguments, 2);
+ var bound = function() {
+ return executeBound(func, bound, context, this, args.concat(slice.call(arguments)));
+ };
+ return bound;
+ };
+
+ // Partially apply a function by creating a version that has had some of its
+ // arguments pre-filled, without changing its dynamic `this` context. _ acts
+ // as a placeholder, allowing any combination of arguments to be pre-filled.
+ _.partial = function(func) {
+ var boundArgs = slice.call(arguments, 1);
+ var bound = function() {
+ var position = 0,
+ length = boundArgs.length;
+ var args = Array(length);
+ for (var i = 0; i < length; i++) {
+ args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i];
+ }
+ while (position < arguments.length) args.push(arguments[position++]);
+ return executeBound(func, bound, this, this, args);
+ };
+ return bound;
+ };
+
+ // Bind a number of an object's methods to that object. Remaining arguments
+ // are the method names to be bound. Useful for ensuring that all callbacks
+ // defined on an object belong to it.
+ _.bindAll = function(obj) {
+ var i, length = arguments.length,
+ key;
+ if (length <= 1) throw new Error('bindAll must be passed function names');
+ for (i = 1; i < length; i++) {
+ key = arguments[i];
+ obj[key] = _.bind(obj[key], obj);
+ }
+ return obj;
+ };
+
+ // Memoize an expensive function by storing its results.
+ _.memoize = function(func, hasher) {
+ var memoize = function(key) {
+ var cache = memoize.cache;
+ var address = '' + (hasher ? hasher.apply(this, arguments) : key);
+ if (!_.has(cache, address)) cache[address] = func.apply(this, arguments);
+ return cache[address];
+ };
+ memoize.cache = {};
+ return memoize;
+ };
+
+ // Delays a function for the given number of milliseconds, and then calls
+ // it with the arguments supplied.
+ _.delay = function(func, wait) {
+ var args = slice.call(arguments, 2);
+ return setTimeout(function() {
+ return func.apply(null, args);
+ }, wait);
+ };
+
+ // Defers a function, scheduling it to run after the current call stack has
+ // cleared.
+ _.defer = _.partial(_.delay, _, 1);
+
+ // Returns a function, that, when invoked, will only be triggered at most once
+ // during a given window of time. Normally, the throttled function will run
+ // as much as it can, without ever going more than once per `wait` duration;
+ // but if you'd like to disable the execution on the leading edge, pass
+ // `{leading: false}`. To disable execution on the trailing edge, ditto.
+ _.throttle = function(func, wait, options) {
+ var context, args, result;
+ var timeout = null;
+ var previous = 0;
+ if (!options) options = {};
+ var later = function() {
+ previous = options.leading === false ? 0 : _.now();
+ timeout = null;
+ result = func.apply(context, args);
+ if (!timeout) context = args = null;
+ };
+ return function() {
+ var now = _.now();
+ if (!previous && options.leading === false) previous = now;
+ var remaining = wait - (now - previous);
+ context = this;
+ args = arguments;
+ if (remaining <= 0 || remaining > wait) {
+ if (timeout) {
+ clearTimeout(timeout);
+ timeout = null;
+ }
+ previous = now;
+ result = func.apply(context, args);
+ if (!timeout) context = args = null;
+ } else if (!timeout && options.trailing !== false) {
+ timeout = setTimeout(later, remaining);
+ }
+ return result;
+ };
+ };
+
+ // Returns a function, that, as long as it continues to be invoked, will not
+ // be triggered. The function will be called after it stops being called for
+ // N milliseconds. If `immediate` is passed, trigger the function on the
+ // leading edge, instead of the trailing.
+ _.debounce = function(func, wait, immediate) {
+ var timeout, args, context, timestamp, result;
+
+ var later = function() {
+ var last = _.now() - timestamp;
+
+ if (last < wait && last >= 0) {
+ timeout = setTimeout(later, wait - last);
+ } else {
+ timeout = null;
+ if (!immediate) {
+ result = func.apply(context, args);
+ if (!timeout) context = args = null;
+ }
+ }
+ };
+
+ return function() {
+ context = this;
+ args = arguments;
+ timestamp = _.now();
+ var callNow = immediate && !timeout;
+ if (!timeout) timeout = setTimeout(later, wait);
+ if (callNow) {
+ result = func.apply(context, args);
+ context = args = null;
+ }
+
+ return result;
+ };
+ };
+
+ // Returns the first function passed as an argument to the second,
+ // allowing you to adjust arguments, run code before and after, and
+ // conditionally execute the original function.
+ _.wrap = function(func, wrapper) {
+ return _.partial(wrapper, func);
+ };
+
+ // Returns a negated version of the passed-in predicate.
+ _.negate = function(predicate) {
+ return function() {
+ return !predicate.apply(this, arguments);
+ };
+ };
+
+ // Returns a function that is the composition of a list of functions, each
+ // consuming the return value of the function that follows.
+ _.compose = function() {
+ var args = arguments;
+ var start = args.length - 1;
+ return function() {
+ var i = start;
+ var result = args[start].apply(this, arguments);
+ while (i--) result = args[i].call(this, result);
+ return result;
+ };
+ };
+
+ // Returns a function that will only be executed on and after the Nth call.
+ _.after = function(times, func) {
+ return function() {
+ if (--times < 1) {
+ return func.apply(this, arguments);
+ }
+ };
+ };
+
+ // Returns a function that will only be executed up to (but not including) the Nth call.
+ _.before = function(times, func) {
+ var memo;
+ return function() {
+ if (--times > 0) {
+ memo = func.apply(this, arguments);
+ }
+ if (times <= 1) func = null;
+ return memo;
+ };
+ };
+
+ // Returns a function that will be executed at most one time, no matter how
+ // often you call it. Useful for lazy initialization.
+ _.once = _.partial(_.before, 2);
+
+ // Object Functions
+ // ----------------
+
+ // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.
+ var hasEnumBug = !{ toString: null }.propertyIsEnumerable('toString');
+ var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',
+ 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'
+ ];
+
+ function collectNonEnumProps(obj, keys) {
+ var nonEnumIdx = nonEnumerableProps.length;
+ var constructor = obj.constructor;
+ var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto;
+
+ // Constructor is a special case.
+ var prop = 'constructor';
+ if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop);
+
+ while (nonEnumIdx--) {
+ prop = nonEnumerableProps[nonEnumIdx];
+ if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) {
+ keys.push(prop);
+ }
+ }
+ }
+
+ // Retrieve the names of an object's own properties.
+ // Delegates to **ECMAScript 5**'s native `Object.keys`
+ _.keys = function(obj) {
+ if (!_.isObject(obj)) return [];
+ if (nativeKeys) return nativeKeys(obj);
+ var keys = [];
+ for (var key in obj)
+ if (_.has(obj, key)) keys.push(key);
+ // Ahem, IE < 9.
+ if (hasEnumBug) collectNonEnumProps(obj, keys);
+ return keys;
+ };
+
+ // Retrieve all the property names of an object.
+ _.allKeys = function(obj) {
+ if (!_.isObject(obj)) return [];
+ var keys = [];
+ for (var key in obj) keys.push(key);
+ // Ahem, IE < 9.
+ if (hasEnumBug) collectNonEnumProps(obj, keys);
+ return keys;
+ };
+
+ // Retrieve the values of an object's properties.
+ _.values = function(obj) {
+ var keys = _.keys(obj);
+ var length = keys.length;
+ var values = Array(length);
+ for (var i = 0; i < length; i++) {
+ values[i] = obj[keys[i]];
+ }
+ return values;
+ };
+
+ // Returns the results of applying the iteratee to each element of the object
+ // In contrast to _.map it returns an object
+ _.mapObject = function(obj, iteratee, context) {
+ iteratee = cb(iteratee, context);
+ var keys = _.keys(obj),
+ length = keys.length,
+ results = {},
+ currentKey;
+ for (var index = 0; index < length; index++) {
+ currentKey = keys[index];
+ results[currentKey] = iteratee(obj[currentKey], currentKey, obj);
+ }
+ return results;
+ };
+
+ // Convert an object into a list of `[key, value]` pairs.
+ _.pairs = function(obj) {
+ var keys = _.keys(obj);
+ var length = keys.length;
+ var pairs = Array(length);
+ for (var i = 0; i < length; i++) {
+ pairs[i] = [keys[i], obj[keys[i]]];
+ }
+ return pairs;
+ };
+
+ // Invert the keys and values of an object. The values must be serializable.
+ _.invert = function(obj) {
+ var result = {};
+ var keys = _.keys(obj);
+ for (var i = 0, length = keys.length; i < length; i++) {
+ result[obj[keys[i]]] = keys[i];
+ }
+ return result;
+ };
+
+ // Return a sorted list of the function names available on the object.
+ // Aliased as `methods`
+ _.functions = _.methods = function(obj) {
+ var names = [];
+ for (var key in obj) {
+ if (_.isFunction(obj[key])) names.push(key);
+ }
+ return names.sort();
+ };
+
+ // Extend a given object with all the properties in passed-in object(s).
+ _.extend = createAssigner(_.allKeys);
+
+ // Assigns a given object with all the own properties in the passed-in object(s)
+ // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
+ _.extendOwn = _.assign = createAssigner(_.keys);
+
+ // Returns the first key on an object that passes a predicate test
+ _.findKey = function(obj, predicate, context) {
+ predicate = cb(predicate, context);
+ var keys = _.keys(obj),
+ key;
+ for (var i = 0, length = keys.length; i < length; i++) {
+ key = keys[i];
+ if (predicate(obj[key], key, obj)) return key;
+ }
+ };
+
+ // Return a copy of the object only containing the whitelisted properties.
+ _.pick = function(object, oiteratee, context) {
+ var result = {},
+ obj = object,
+ iteratee, keys;
+ if (obj == null) return result;
+ if (_.isFunction(oiteratee)) {
+ keys = _.allKeys(obj);
+ iteratee = optimizeCb(oiteratee, context);
+ } else {
+ keys = flatten(arguments, false, false, 1);
+ iteratee = function(value, key, obj) { return key in obj; };
+ obj = Object(obj);
+ }
+ for (var i = 0, length = keys.length; i < length; i++) {
+ var key = keys[i];
+ var value = obj[key];
+ if (iteratee(value, key, obj)) result[key] = value;
+ }
+ return result;
+ };
+
+ // Return a copy of the object without the blacklisted properties.
+ _.omit = function(obj, iteratee, context) {
+ if (_.isFunction(iteratee)) {
+ iteratee = _.negate(iteratee);
+ } else {
+ var keys = _.map(flatten(arguments, false, false, 1), String);
+ iteratee = function(value, key) {
+ return !_.contains(keys, key);
+ };
+ }
+ return _.pick(obj, iteratee, context);
+ };
+
+ // Fill in a given object with default properties.
+ _.defaults = createAssigner(_.allKeys, true);
+
+ // Creates an object that inherits from the given prototype object.
+ // If additional properties are provided then they will be added to the
+ // created object.
+ _.create = function(prototype, props) {
+ var result = baseCreate(prototype);
+ if (props) _.extendOwn(result, props);
+ return result;
+ };
+
+ // Create a (shallow-cloned) duplicate of an object.
+ _.clone = function(obj) {
+ if (!_.isObject(obj)) return obj;
+ return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
+ };
+
+ // Invokes interceptor with the obj, and then returns obj.
+ // The primary purpose of this method is to "tap into" a method chain, in
+ // order to perform operations on intermediate results within the chain.
+ _.tap = function(obj, interceptor) {
+ interceptor(obj);
+ return obj;
+ };
+
+ // Returns whether an object has a given set of `key:value` pairs.
+ _.isMatch = function(object, attrs) {
+ var keys = _.keys(attrs),
+ length = keys.length;
+ if (object == null) return !length;
+ var obj = Object(object);
+ for (var i = 0; i < length; i++) {
+ var key = keys[i];
+ if (attrs[key] !== obj[key] || !(key in obj)) return false;
+ }
+ return true;
+ };
+
+
+ // Internal recursive comparison function for `isEqual`.
+ var eq = function(a, b, aStack, bStack) {
+ // Identical objects are equal. `0 === -0`, but they aren't identical.
+ // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
+ if (a === b) return a !== 0 || 1 / a === 1 / b;
+ // A strict comparison is necessary because `null == undefined`.
+ if (a == null || b == null) return a === b;
+ // Unwrap any wrapped objects.
+ if (a instanceof _) a = a._wrapped;
+ if (b instanceof _) b = b._wrapped;
+ // Compare `[[Class]]` names.
+ var className = toString.call(a);
+ if (className !== toString.call(b)) return false;
+ switch (className) {
+ // Strings, numbers, regular expressions, dates, and booleans are compared by value.
+ case '[object RegExp]':
+ // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
+ case '[object String]':
+ // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
+ // equivalent to `new String("5")`.
+ return '' + a === '' + b;
+ case '[object Number]':
+ // `NaN`s are equivalent, but non-reflexive.
+ // Object(NaN) is equivalent to NaN
+ if (+a !== +a) return +b !== +b;
+ // An `egal` comparison is performed for other numeric values.
+ return +a === 0 ? 1 / +a === 1 / b : +a === +b;
+ case '[object Date]':
+ case '[object Boolean]':
+ // Coerce dates and booleans to numeric primitive values. Dates are compared by their
+ // millisecond representations. Note that invalid dates with millisecond representations
+ // of `NaN` are not equivalent.
+ return +a === +b;
+ }
+
+ var areArrays = className === '[object Array]';
+ if (!areArrays) {
+ if (typeof a != 'object' || typeof b != 'object') return false;
+
+ // Objects with different constructors are not equivalent, but `Object`s or `Array`s
+ // from different frames are.
+ var aCtor = a.constructor,
+ bCtor = b.constructor;
+ if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor &&
+ _.isFunction(bCtor) && bCtor instanceof bCtor) &&
+ ('constructor' in a && 'constructor' in b)) {
+ return false;
+ }
+ }
+ // Assume equality for cyclic structures. The algorithm for detecting cyclic
+ // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
+
+ // Initializing stack of traversed objects.
+ // It's done here since we only need them for objects and arrays comparison.
+ aStack = aStack || [];
+ bStack = bStack || [];
+ var length = aStack.length;
+ while (length--) {
+ // Linear search. Performance is inversely proportional to the number of
+ // unique nested structures.
+ if (aStack[length] === a) return bStack[length] === b;
+ }
+
+ // Add the first object to the stack of traversed objects.
+ aStack.push(a);
+ bStack.push(b);
+
+ // Recursively compare objects and arrays.
+ if (areArrays) {
+ // Compare array lengths to determine if a deep comparison is necessary.
+ length = a.length;
+ if (length !== b.length) return false;
+ // Deep compare the contents, ignoring non-numeric properties.
+ while (length--) {
+ if (!eq(a[length], b[length], aStack, bStack)) return false;
+ }
+ } else {
+ // Deep compare objects.
+ var keys = _.keys(a),
+ key;
+ length = keys.length;
+ // Ensure that both objects contain the same number of properties before comparing deep equality.
+ if (_.keys(b).length !== length) return false;
+ while (length--) {
+ // Deep compare each member
+ key = keys[length];
+ if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false;
+ }
+ }
+ // Remove the first object from the stack of traversed objects.
+ aStack.pop();
+ bStack.pop();
+ return true;
+ };
+
+ // Perform a deep comparison to check if two objects are equal.
+ _.isEqual = function(a, b) {
+ return eq(a, b);
+ };
+
+ // Is a given array, string, or object empty?
+ // An "empty" object has no enumerable own-properties.
+ _.isEmpty = function(obj) {
+ if (obj == null) return true;
+ if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0;
+ return _.keys(obj).length === 0;
+ };
+
+ // Is a given value a DOM element?
+ _.isElement = function(obj) {
+ return !!(obj && obj.nodeType === 1);
+ };
+
+ // Is a given value an array?
+ // Delegates to ECMA5's native Array.isArray
+ _.isArray = nativeIsArray || function(obj) {
+ return toString.call(obj) === '[object Array]';
+ };
+
+ // Is a given variable an object?
+ _.isObject = function(obj) {
+ var type = typeof obj;
+ return type === 'function' || type === 'object' && !!obj;
+ };
+
+ // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError.
+ _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) {
+ _['is' + name] = function(obj) {
+ return toString.call(obj) === '[object ' + name + ']';
+ };
+ });
+
+ // Define a fallback version of the method in browsers (ahem, IE < 9), where
+ // there isn't any inspectable "Arguments" type.
+ if (!_.isArguments(arguments)) {
+ _.isArguments = function(obj) {
+ return _.has(obj, 'callee');
+ };
+ }
+
+ // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8,
+ // IE 11 (#1621), and in Safari 8 (#1929).
+ if (typeof /./ != 'function' && typeof Int8Array != 'object') {
+ _.isFunction = function(obj) {
+ return typeof obj == 'function' || false;
+ };
+ }
+
+ // Is a given object a finite number?
+ _.isFinite = function(obj) {
+ return isFinite(obj) && !isNaN(parseFloat(obj));
+ };
+
+ // Is the given value `NaN`? (NaN is the only number which does not equal itself).
+ _.isNaN = function(obj) {
+ return _.isNumber(obj) && obj !== +obj;
+ };
+
+ // Is a given value a boolean?
+ _.isBoolean = function(obj) {
+ return obj === true || obj === false || toString.call(obj) === '[object Boolean]';
+ };
+
+ // Is a given value equal to null?
+ _.isNull = function(obj) {
+ return obj === null;
+ };
+
+ // Is a given variable undefined?
+ _.isUndefined = function(obj) {
+ return obj === void 0;
+ };
+
+ // Shortcut function for checking if an object has a given property directly
+ // on itself (in other words, not on a prototype).
+ _.has = function(obj, key) {
+ return obj != null && hasOwnProperty.call(obj, key);
+ };
+
+ // Utility Functions
+ // -----------------
+
+ // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
+ // previous owner. Returns a reference to the Underscore object.
+ _.noConflict = function() {
+ root._ = previousUnderscore;
+ return this;
+ };
+
+ // Keep the identity function around for default iteratees.
+ _.identity = function(value) {
+ return value;
+ };
+
+ // Predicate-generating functions. Often useful outside of Underscore.
+ _.constant = function(value) {
+ return function() {
+ return value;
+ };
+ };
+
+ _.noop = function() {};
+
+ _.property = property;
+
+ // Generates a function for a given object that returns a given property.
+ _.propertyOf = function(obj) {
+ return obj == null ? function() {} : function(key) {
+ return obj[key];
+ };
+ };
+
+ // Returns a predicate for checking whether an object has a given set of
+ // `key:value` pairs.
+ _.matcher = _.matches = function(attrs) {
+ attrs = _.extendOwn({}, attrs);
+ return function(obj) {
+ return _.isMatch(obj, attrs);
+ };
+ };
+
+ // Run a function **n** times.
+ _.times = function(n, iteratee, context) {
+ var accum = Array(Math.max(0, n));
+ iteratee = optimizeCb(iteratee, context, 1);
+ for (var i = 0; i < n; i++) accum[i] = iteratee(i);
+ return accum;
+ };
+
+ // Return a random integer between min and max (inclusive).
+ _.random = function(min, max) {
+ if (max == null) {
+ max = min;
+ min = 0;
+ }
+ return min + Math.floor(Math.random() * (max - min + 1));
+ };
+
+ // A (possibly faster) way to get the current timestamp as an integer.
+ _.now = Date.now || function() {
+ return new Date().getTime();
+ };
+
+ // List of HTML entities for escaping.
+ var escapeMap = {
+ '&': '&',
+ '<': '<',
+ '>': '>',
+ '"': '"',
+ "'": ''',
+ '`': '`'
+ };
+ var unescapeMap = _.invert(escapeMap);
+
+ // Functions for escaping and unescaping strings to/from HTML interpolation.
+ var createEscaper = function(map) {
+ var escaper = function(match) {
+ return map[match];
+ };
+ // Regexes for identifying a key that needs to be escaped
+ var source = '(?:' + _.keys(map).join('|') + ')';
+ var testRegexp = RegExp(source);
+ var replaceRegexp = RegExp(source, 'g');
+ return function(string) {
+ string = string == null ? '' : '' + string;
+ return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;
+ };
+ };
+ _.escape = createEscaper(escapeMap);
+ _.unescape = createEscaper(unescapeMap);
+
+ // If the value of the named `property` is a function then invoke it with the
+ // `object` as context; otherwise, return it.
+ _.result = function(object, property, fallback) {
+ var value = object == null ? void 0 : object[property];
+ if (value === void 0) {
+ value = fallback;
+ }
+ return _.isFunction(value) ? value.call(object) : value;
+ };
+
+ // Generate a unique integer id (unique within the entire client session).
+ // Useful for temporary DOM ids.
+ var idCounter = 0;
+ _.uniqueId = function(prefix) {
+ var id = ++idCounter + '';
+ return prefix ? prefix + id : id;
+ };
+
+ // By default, Underscore uses ERB-style template delimiters, change the
+ // following template settings to use alternative delimiters.
+ _.templateSettings = {
+ evaluate: /<%([\s\S]+?)%>/g,
+ interpolate: /<%=([\s\S]+?)%>/g,
+ escape: /<%-([\s\S]+?)%>/g
+ };
+
+ // When customizing `templateSettings`, if you don't want to define an
+ // interpolation, evaluation or escaping regex, we need one that is
+ // guaranteed not to match.
+ var noMatch = /(.)^/;
+
+ // Certain characters need to be escaped so that they can be put into a
+ // string literal.
+ var escapes = {
+ "'": "'",
+ '\\': '\\',
+ '\r': 'r',
+ '\n': 'n',
+ '\u2028': 'u2028',
+ '\u2029': 'u2029'
+ };
+
+ var escaper = /\\|'|\r|\n|\u2028|\u2029/g;
+
+ var escapeChar = function(match) {
+ return '\\' + escapes[match];
+ };
+
+ // JavaScript micro-templating, similar to John Resig's implementation.
+ // Underscore templating handles arbitrary delimiters, preserves whitespace,
+ // and correctly escapes quotes within interpolated code.
+ // NB: `oldSettings` only exists for backwards compatibility.
+ _.template = function(text, settings, oldSettings) {
+ if (!settings && oldSettings) settings = oldSettings;
+ settings = _.defaults({}, settings, _.templateSettings);
+
+ // Combine delimiters into one regular expression via alternation.
+ var matcher = RegExp([
+ (settings.escape || noMatch).source,
+ (settings.interpolate || noMatch).source,
+ (settings.evaluate || noMatch).source
+ ].join('|') + '|$', 'g');
+
+ // Compile the template source, escaping string literals appropriately.
+ var index = 0;
+ var source = "__p+='";
+ text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
+ source += text.slice(index, offset).replace(escaper, escapeChar);
+ index = offset + match.length;
+
+ if (escape) {
+ source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
+ } else if (interpolate) {
+ source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
+ } else if (evaluate) {
+ source += "';\n" + evaluate + "\n__p+='";
+ }
+
+ // Adobe VMs need the match returned to produce the correct offest.
+ return match;
+ });
+ source += "';\n";
+
+ // If a variable is not specified, place data values in local scope.
+ if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
+
+ source = "var __t,__p='',__j=Array.prototype.join," +
+ "print=function(){__p+=__j.call(arguments,'');};\n" +
+ source + 'return __p;\n';
+
+ try {
+ var render = new Function(settings.variable || 'obj', '_', source);
+ } catch (e) {
+ e.source = source;
+ throw e;
+ }
+
+ var template = function(data) {
+ return render.call(this, data, _);
+ };
+
+ // Provide the compiled source as a convenience for precompilation.
+ var argument = settings.variable || 'obj';
+ template.source = 'function(' + argument + '){\n' + source + '}';
+
+ return template;
+ };
+
+ // Add a "chain" function. Start chaining a wrapped Underscore object.
+ _.chain = function(obj) {
+ var instance = _(obj);
+ instance._chain = true;
+ return instance;
+ };
+
+ // OOP
+ // ---------------
+ // If Underscore is called as a function, it returns a wrapped object that
+ // can be used OO-style. This wrapper holds altered versions of all the
+ // underscore functions. Wrapped objects may be chained.
+
+ // Helper function to continue chaining intermediate results.
+ var result = function(instance, obj) {
+ return instance._chain ? _(obj).chain() : obj;
+ };
+
+ // Add your own custom functions to the Underscore object.
+ _.mixin = function(obj) {
+ _.each(_.functions(obj), function(name) {
+ var func = _[name] = obj[name];
+ _.prototype[name] = function() {
+ var args = [this._wrapped];
+ push.apply(args, arguments);
+ return result(this, func.apply(_, args));
+ };
+ });
+ };
+
+ // Add all of the Underscore functions to the wrapper object.
+ _.mixin(_);
+
+ // Add all mutator Array functions to the wrapper.
+ _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
+ var method = ArrayProto[name];
+ _.prototype[name] = function() {
+ var obj = this._wrapped;
+ method.apply(obj, arguments);
+ if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0];
+ return result(this, obj);
+ };
+ });
+
+ // Add all accessor Array functions to the wrapper.
+ _.each(['concat', 'join', 'slice'], function(name) {
+ var method = ArrayProto[name];
+ _.prototype[name] = function() {
+ return result(this, method.apply(this._wrapped, arguments));
+ };
+ });
+
+ // Extracts the result from a wrapped and chained object.
+ _.prototype.value = function() {
+ return this._wrapped;
+ };
+
+ // Provide unwrapping proxy for some methods used in engine operations
+ // such as arithmetic and JSON stringification.
+ _.prototype.valueOf = _.prototype.toJSON = _.prototype.value;
+
+ _.prototype.toString = function() {
+ return '' + this._wrapped;
+ };
+
+ // AMD registration happens at the end for compatibility with AMD loaders
+ // that may not enforce next-turn semantics on modules. Even though general
+ // practice for AMD registration is to be anonymous, underscore registers
+ // as a named module because, like jQuery, it is a base library that is
+ // popular enough to be bundled in a third party lib, but not be part of
+ // an AMD load request. Those cases could generate an error when an
+ // anonymous define() is called outside of a loader request.
+ if (typeof define === 'function' && define.amd) {
+ define('underscore', [], function() {
+ return _;
+ });
+ }
+}.call(this));
\ No newline at end of file
diff --git a/campus/utils/util.js b/campus/utils/util.js
new file mode 100644
index 0000000..153c05a
--- /dev/null
+++ b/campus/utils/util.js
@@ -0,0 +1,28 @@
+function formatTime(date) {
+ var year = date.getFullYear()
+ var month = date.getMonth() + 1
+ var day = date.getDate()
+
+ var hour = date.getHours()
+ var minute = date.getMinutes()
+ var second = date.getSeconds()
+
+
+ return [hour, minute, second].map(formatNumber).join('-')
+}
+
+const formatDate = date => {
+ const year = date.getFullYear();
+ const month = date.getMonth() + 1;
+ const day = date.getDate()
+ return [year, month, day].map(formatNumber).join('-')
+}
+function formatNumber(n) {
+ n = n.toString()
+ return n[1] ? n : '0' + n
+}
+
+module.exports = {
+ formatTime: formatTime,
+ formatDate: formatDate
+}