├── .gitignore ├── bin └── autoUpdateScript.txt ├── package.json ├── public ├── index.html ├── index.js └── style.css ├── readme.md ├── server ├── getIpAddress.js ├── index.js └── updateGpx.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /bin/autoUpdateScript.txt: -------------------------------------------------------------------------------- 1 | #Will continue update the location to the location name below from Xcode: 2 | 3 | property locationName : "pokemonLocation" #name of your gpx filex 4 | 5 | ########################### 6 | tell application "System Events" 7 | tell process "Xcode" 8 | repeat while true 9 | click menu item "Location" of menu 1 of menu item "Simulate Location" of menu 1 of menu bar item "Debug" of menu bar 1 10 | delay 0.5 11 | end repeat 12 | end tell 13 | end tell -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "iosSimulateLocation", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node server" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "koa": "^2.6.2", 15 | "koa-router": "^7.4.0", 16 | "koa-static": "^5.0.0" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 遥控器 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 |
17 |
18 |
19 |
20 |
21 |
22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /public/index.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | (async _ => { 5 | const wrap = document.getElementById('app'); 6 | const control = document.getElementById('control'); 7 | const randomNode = document.getElementById('random'); 8 | const currentPos = document.getElementById('currentPos'); 9 | let {lat, lon} = await fetchApi('/getCurrentPosition'); 10 | const marks = []; 11 | let timer; 12 | const {abs, atan, sqrt, floor, PI, random} = Math; 13 | let speed = 0; 14 | let deg = 0; 15 | let enableRandom = false; 16 | 17 | const map = new AMap.Map('container', { 18 | zoom: 20,//级别 19 | center: [lon, lat],//中心点坐标 20 | viewMode: '3D'//使用3D视图 21 | }); 22 | setMark([lon, lat]); 23 | 24 | initMap(map); 25 | 26 | timer = setInterval(sendRoute, 300); 27 | 28 | let controlLock = false; 29 | (function interval(){ 30 | setTimeout(interval, 1000); 31 | if(controlLock || !enableRandom){return;} 32 | deg = `${(random() - 0.5).toFixed(1)},${(random() - 0.5).toFixed(1)}`; 33 | speed = 7; 34 | })(); 35 | 36 | randomNode.addEventListener('click', (e) => { 37 | enableRandom = !enableRandom; 38 | randomNode.style.backgroundColor = enableRandom ? '#fff' : '#333'; 39 | }); 40 | window.addEventListener('keydown', e => { 41 | controlLock = true; 42 | let d = ({38: '0,1',39: '1,0',40: '0,-1', 37: '-1,0'})[e.keyCode]; 43 | if(d !== undefined){ 44 | deg = d; 45 | speed = 10; 46 | } 47 | }); 48 | window.addEventListener('keyup', e => { 49 | controlLock = false; 50 | deg = 0; 51 | speed = 0; 52 | }); 53 | wrap.addEventListener('touchstart', e => { 54 | controlLock = true; 55 | }); 56 | wrap.addEventListener('touchmove', e => { 57 | let {pageX, pageY} = e.touches[0]; 58 | let top = wrap.offsetTop; 59 | let left = wrap.offsetLeft; 60 | let width = wrap.clientWidth; 61 | let height = wrap.clientHeight; 62 | let offsetX = .5 * width - pageX + left; 63 | let offsetY = .5 * height - pageY + top; 64 | deg = `${(-offsetX / width * 2).toFixed(1)},${(offsetY / height * 2).toFixed(1)}`; 65 | speed = floor(sqrt(offsetX * offsetX + offsetY * offsetY)) / 3; 66 | 67 | control.style.transform = `translate(${-offsetX}px,${-offsetY}px)`; 68 | }); 69 | wrap.addEventListener('touchend', e => { 70 | controlLock = false; 71 | speed = deg = 0; 72 | control.style.transform = `translate(0)`; 73 | }); 74 | 75 | async function sendRoute(){ 76 | if(!speed){return;} 77 | console.log('move', `deg: ${deg}, speed: ${speed}`) 78 | let {lat, lon} = await fetchApi(`/goDegWithSpeed?speed=${speed / 10}°=${deg}`, 1); 79 | setMark([lon, lat]); 80 | } 81 | function setMark([lon, lat]){ 82 | if(!lon){return;} 83 | currentPos.innerHTML = `lon: ${lon}; lat: ${lat}`; 84 | let marker = buildMarker([lon, lat]); 85 | map.add(marker); 86 | map.setCenter(new AMap.LngLat(lon, lat)); 87 | marks.push(marker); 88 | if(marks.length > 1000){marks.shift().setMap(null)} 89 | } 90 | function buildMarker([lon, lat]){ 91 | // 构造矢量圆形 92 | return new AMap.Circle({ 93 | center: new AMap.LngLat(lon, lat), // 圆心位置 94 | radius: 1, //半径 95 | strokeColor: "#1202ff", //线颜色 96 | strokeOpacity: 1, //线透明度 97 | strokeWeight: 0, //线粗细度 98 | fillColor: "#878cff", //填充颜色 99 | fillOpacity: 0.7 //填充透明度 100 | }); 101 | } 102 | 103 | function fetchApi(api, ignoreError){ 104 | return fetch(api).then(res => { 105 | return res.json(); 106 | }).catch(e => { 107 | if(ignoreError){ 108 | console.error(e); 109 | } 110 | else{ 111 | alert(e); 112 | throw e; 113 | } 114 | }); 115 | } 116 | function initMap(){ 117 | AMap.plugin([ 118 | 'AMap.ToolBar', 119 | 'AMap.Scale', 120 | 'AMap.OverView', 121 | ], function(){ 122 | // 在图面添加工具条控件,工具条控件集成了缩放、平移、定位等功能按钮在内的组合控件 123 | map.addControl(new AMap.ToolBar()); 124 | 125 | // 在图面添加比例尺控件,展示地图在当前层级和纬度下的比例尺 126 | map.addControl(new AMap.Scale()); 127 | 128 | // 在图面添加鹰眼控件,在地图右下角显示地图的缩略图 129 | map.addControl(new AMap.OverView({isOpen:true})); 130 | }); 131 | } 132 | })(); 133 | -------------------------------------------------------------------------------- /public/style.css: -------------------------------------------------------------------------------- 1 | html * { 2 | touch-action: manipulation; 3 | -webkit-user-select: none; 4 | user-select: none; 5 | } 6 | 7 | #container{ 8 | position: fixed; 9 | top: 0; 10 | left: 0; 11 | bottom: 0; 12 | right: 0; 13 | } 14 | #app{ 15 | position: fixed; 16 | left: 0; 17 | bottom: 0; 18 | right: 0; 19 | margin: auto; 20 | height: 30%; 21 | height: 100vw; 22 | background: rgba(0,0,0,.2); 23 | } 24 | @media (min-width: 500px){ 25 | #app{ 26 | left: initial; 27 | right: 0; 28 | height: 30vh; 29 | width: 30vh; 30 | } 31 | } 32 | #app:before, 33 | #app:after{ 34 | content: ''; 35 | position: absolute; 36 | display: block; 37 | background: #fff; 38 | pointer-events: none; 39 | } 40 | #app:before{ 41 | width: 100%; 42 | height: 1px; 43 | top: 50%; 44 | left: 0; 45 | } 46 | #app:after{ 47 | height: 100%; 48 | width: 1px; 49 | left: 50%; 50 | top: 0; 51 | } 52 | #random{ 53 | position: fixed; 54 | background: #333; 55 | border-radius: 4px; 56 | width: 20px; 57 | height: 20px; 58 | top: 5px; 59 | right: 5px; 60 | box-shadow: rgba(0,0,0,.4) 0 0 4px; 61 | } 62 | #currentPos{ 63 | position: fixed; 64 | font-size: 12px; 65 | top: 5px; 66 | left: 5px; 67 | } 68 | #control{ 69 | position: absolute; 70 | left: 50%; 71 | top: 50%; 72 | margin: -15px 0 0 -15px; 73 | height: 30px; 74 | width: 30px; 75 | border-radius: 100%; 76 | background: #fff; 77 | z-index: 1; 78 | pointer-events: none; 79 | } -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # ios虚拟定位套餐 2 | 3 | 为了玩游戏也是没谁了... 4 | 5 | 思路参考[Pokemon-Go-Controller](https://github.com/kahopoon/Pokemon-Go-Controller); 6 | 1. xcode新建一个项目,run到手机上>新建gpx文件>修改坐标>debug>simulate location 7 | 2. 建一套界面让修改坐标更加方便,browser操作方向>server修改文件 8 | 3. 因为xcode贼恶心每次改完都要手动操作点击生效,所以需要一个脚本自动生效 9 | 10 | 自己写个nodejs版的用起来方便&安全 11 | 12 | ## 如何使用 13 | 1. xcode创建空白ios项目,配置好之后run到手机。创建gpx文件(文件名就叫Location),debug > simulate location选择Location 14 | 2. 脚本执行./bin/ 里面那个文件 15 | 2. node server $gpxPath 16 | 3. 找个顺手的设备打开 http://$ip:9000/ 17 | 4. pc可以上下左右控制,或者拖动操作面板控制方向和速度 18 | 19 | -------------------------------------------------------------------------------- /server/getIpAddress.js: -------------------------------------------------------------------------------- 1 | const os = require('os'); 2 | 3 | function getIPAdress(){ 4 | var interfaces = os.networkInterfaces(); 5 | for(var devName in interfaces){ 6 | var iface = interfaces[devName]; 7 | for(var i=0;i { 22 | console.log('receive ', ctx.url); 23 | const {deg, speed} = ctx.query; 24 | if(!deg || !speed){return;} 25 | let latlon = updateFileWithDegAndSpeed(gpxPath, {deg, speed}); 26 | ctx.body = {...latlon}; 27 | }); 28 | router.get('/getCurrentPosition', (ctx, next) => { 29 | console.log('receive ', ctx.url); 30 | let latlon = getCurrentLatlon(gpxPath); 31 | ctx.body = {...latlon}; 32 | }); 33 | 34 | app.use(router.routes()); 35 | app.use(serve(path.resolve(__dirname, '../public/'))); 36 | app.listen(port, _ => { 37 | console.log(`server runnning @ http://${ip}:${port}/index.html`); 38 | exec(`open http://${ip}:${port}/index.html`); 39 | }); 40 | 41 | 42 | -------------------------------------------------------------------------------- /server/updateGpx.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | 3 | module.exports = { 4 | updateFileWithDegAndSpeed, 5 | getCurrentLatlon, 6 | }; 7 | 8 | function calcOffset(deg, speed = 2){ 9 | // let r = deg / 360 * 2 * Math.PI; 10 | let d = deg.split(','); 11 | let dir = [+d[0], +d[1]]; 12 | let dis = dir.map(d => d * speed); 13 | let fix = 0.00002; 14 | let offset = { 15 | lat: dis[1] * fix, 16 | lon: dis[0] * fix, 17 | } 18 | console.log(offset); 19 | return offset; 20 | } 21 | 22 | function updateFile(filePath, {lat: latOffset, lon: lonOffset}){ 23 | {/* */} 24 | let content = fs.readFileSync(filePath, 'utf8'); 25 | let rsLat, rsLon; 26 | 27 | content = content.replace(//i, (match, lat, lon) => { 28 | rsLat = (+lat + latOffset).toFixed(6); 29 | rsLon = (+lon + lonOffset).toFixed(6); 30 | return ``; 31 | }); 32 | 33 | fs.writeFileSync(filePath, content, 'utf8'); 34 | return { 35 | lat: rsLat, 36 | lon: rsLon, 37 | } 38 | } 39 | 40 | function updateFileWithDegAndSpeed(filePath, {deg, speed}){ 41 | return updateFile(filePath, calcOffset(deg, speed)); 42 | } 43 | 44 | function getCurrentLatlon(filePath){ 45 | let content = fs.readFileSync(filePath, 'utf8'); 46 | let [match, lat, lon] = //i.exec(content) || []; 47 | return {lat, lon} 48 | } -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | accepts@^1.3.5: 6 | version "1.3.5" 7 | resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2" 8 | dependencies: 9 | mime-types "~2.1.18" 10 | negotiator "0.6.1" 11 | 12 | any-promise@^1.0.0, any-promise@^1.1.0: 13 | version "1.3.0" 14 | resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" 15 | 16 | cache-content-type@^1.0.0: 17 | version "1.0.1" 18 | resolved "https://registry.yarnpkg.com/cache-content-type/-/cache-content-type-1.0.1.tgz#035cde2b08ee2129f4a8315ea8f00a00dba1453c" 19 | dependencies: 20 | mime-types "^2.1.18" 21 | ylru "^1.2.0" 22 | 23 | co@^4.6.0: 24 | version "4.6.0" 25 | resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" 26 | 27 | content-disposition@~0.5.2: 28 | version "0.5.2" 29 | resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" 30 | 31 | content-type@^1.0.4: 32 | version "1.0.4" 33 | resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" 34 | 35 | cookies@~0.7.1: 36 | version "0.7.3" 37 | resolved "https://registry.yarnpkg.com/cookies/-/cookies-0.7.3.tgz#7912ce21fbf2e8c2da70cf1c3f351aecf59dadfa" 38 | dependencies: 39 | depd "~1.1.2" 40 | keygrip "~1.0.3" 41 | 42 | debug@^3.1.0: 43 | version "3.2.6" 44 | resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" 45 | dependencies: 46 | ms "^2.1.1" 47 | 48 | debug@~3.1.0: 49 | version "3.1.0" 50 | resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" 51 | dependencies: 52 | ms "2.0.0" 53 | 54 | deep-equal@~1.0.1: 55 | version "1.0.1" 56 | resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" 57 | 58 | delegates@^1.0.0: 59 | version "1.0.0" 60 | resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" 61 | 62 | depd@^1.1.2, depd@~1.1.2: 63 | version "1.1.2" 64 | resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" 65 | 66 | destroy@^1.0.4: 67 | version "1.0.4" 68 | resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" 69 | 70 | ee-first@1.1.1: 71 | version "1.1.1" 72 | resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" 73 | 74 | error-inject@^1.0.0: 75 | version "1.0.0" 76 | resolved "https://registry.yarnpkg.com/error-inject/-/error-inject-1.0.0.tgz#e2b3d91b54aed672f309d950d154850fa11d4f37" 77 | 78 | escape-html@^1.0.3: 79 | version "1.0.3" 80 | resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" 81 | 82 | fresh@~0.5.2: 83 | version "0.5.2" 84 | resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" 85 | 86 | http-assert@^1.3.0: 87 | version "1.4.0" 88 | resolved "https://registry.yarnpkg.com/http-assert/-/http-assert-1.4.0.tgz#0e550b4fca6adf121bbeed83248c17e62f593a9a" 89 | dependencies: 90 | deep-equal "~1.0.1" 91 | http-errors "~1.7.1" 92 | 93 | http-errors@^1.3.1, http-errors@^1.6.3, http-errors@~1.7.1: 94 | version "1.7.1" 95 | resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.1.tgz#6a4ffe5d35188e1c39f872534690585852e1f027" 96 | dependencies: 97 | depd "~1.1.2" 98 | inherits "2.0.3" 99 | setprototypeof "1.1.0" 100 | statuses ">= 1.5.0 < 2" 101 | toidentifier "1.0.0" 102 | 103 | http-errors@~1.6.2: 104 | version "1.6.3" 105 | resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" 106 | integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= 107 | dependencies: 108 | depd "~1.1.2" 109 | inherits "2.0.3" 110 | setprototypeof "1.1.0" 111 | statuses ">= 1.4.0 < 2" 112 | 113 | inherits@2.0.3: 114 | version "2.0.3" 115 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 116 | 117 | is-generator-function@^1.0.7: 118 | version "1.0.7" 119 | resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.7.tgz#d2132e529bb0000a7f80794d4bdf5cd5e5813522" 120 | 121 | isarray@0.0.1: 122 | version "0.0.1" 123 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" 124 | 125 | keygrip@~1.0.3: 126 | version "1.0.3" 127 | resolved "https://registry.yarnpkg.com/keygrip/-/keygrip-1.0.3.tgz#399d709f0aed2bab0a059e0cdd3a5023a053e1dc" 128 | 129 | koa-compose@^3.0.0: 130 | version "3.2.1" 131 | resolved "https://registry.yarnpkg.com/koa-compose/-/koa-compose-3.2.1.tgz#a85ccb40b7d986d8e5a345b3a1ace8eabcf54de7" 132 | dependencies: 133 | any-promise "^1.1.0" 134 | 135 | koa-compose@^4.1.0: 136 | version "4.1.0" 137 | resolved "https://registry.yarnpkg.com/koa-compose/-/koa-compose-4.1.0.tgz#507306b9371901db41121c812e923d0d67d3e877" 138 | 139 | koa-convert@^1.2.0: 140 | version "1.2.0" 141 | resolved "https://registry.yarnpkg.com/koa-convert/-/koa-convert-1.2.0.tgz#da40875df49de0539098d1700b50820cebcd21d0" 142 | dependencies: 143 | co "^4.6.0" 144 | koa-compose "^3.0.0" 145 | 146 | koa-is-json@^1.0.0: 147 | version "1.0.0" 148 | resolved "https://registry.yarnpkg.com/koa-is-json/-/koa-is-json-1.0.0.tgz#273c07edcdcb8df6a2c1ab7d59ee76491451ec14" 149 | 150 | koa-router@^7.4.0: 151 | version "7.4.0" 152 | resolved "https://registry.yarnpkg.com/koa-router/-/koa-router-7.4.0.tgz#aee1f7adc02d5cb31d7d67465c9eacc825e8c5e0" 153 | dependencies: 154 | debug "^3.1.0" 155 | http-errors "^1.3.1" 156 | koa-compose "^3.0.0" 157 | methods "^1.0.1" 158 | path-to-regexp "^1.1.1" 159 | urijs "^1.19.0" 160 | 161 | koa-send@^5.0.0: 162 | version "5.0.0" 163 | resolved "https://registry.yarnpkg.com/koa-send/-/koa-send-5.0.0.tgz#5e8441e07ef55737734d7ced25b842e50646e7eb" 164 | integrity sha512-90ZotV7t0p3uN9sRwW2D484rAaKIsD8tAVtypw/aBU+ryfV+fR2xrcAwhI8Wl6WRkojLUs/cB9SBSCuIb+IanQ== 165 | dependencies: 166 | debug "^3.1.0" 167 | http-errors "^1.6.3" 168 | mz "^2.7.0" 169 | resolve-path "^1.4.0" 170 | 171 | koa-static@^5.0.0: 172 | version "5.0.0" 173 | resolved "https://registry.yarnpkg.com/koa-static/-/koa-static-5.0.0.tgz#5e92fc96b537ad5219f425319c95b64772776943" 174 | integrity sha512-UqyYyH5YEXaJrf9S8E23GoJFQZXkBVJ9zYYMPGz919MSX1KuvAcycIuS0ci150HCoPf4XQVhQ84Qf8xRPWxFaQ== 175 | dependencies: 176 | debug "^3.1.0" 177 | koa-send "^5.0.0" 178 | 179 | koa@^2.6.2: 180 | version "2.6.2" 181 | resolved "https://registry.yarnpkg.com/koa/-/koa-2.6.2.tgz#57ba4d049b0a99cae0d594e6144e2931949a7ce1" 182 | dependencies: 183 | accepts "^1.3.5" 184 | cache-content-type "^1.0.0" 185 | content-disposition "~0.5.2" 186 | content-type "^1.0.4" 187 | cookies "~0.7.1" 188 | debug "~3.1.0" 189 | delegates "^1.0.0" 190 | depd "^1.1.2" 191 | destroy "^1.0.4" 192 | error-inject "^1.0.0" 193 | escape-html "^1.0.3" 194 | fresh "~0.5.2" 195 | http-assert "^1.3.0" 196 | http-errors "^1.6.3" 197 | is-generator-function "^1.0.7" 198 | koa-compose "^4.1.0" 199 | koa-convert "^1.2.0" 200 | koa-is-json "^1.0.0" 201 | on-finished "^2.3.0" 202 | only "~0.0.2" 203 | parseurl "^1.3.2" 204 | statuses "^1.5.0" 205 | type-is "^1.6.16" 206 | vary "^1.1.2" 207 | 208 | media-typer@0.3.0: 209 | version "0.3.0" 210 | resolved "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" 211 | 212 | methods@^1.0.1: 213 | version "1.1.2" 214 | resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" 215 | 216 | mime-db@~1.37.0: 217 | version "1.37.0" 218 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.37.0.tgz#0b6a0ce6fdbe9576e25f1f2d2fde8830dc0ad0d8" 219 | 220 | mime-types@^2.1.18, mime-types@~2.1.18: 221 | version "2.1.21" 222 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.21.tgz#28995aa1ecb770742fe6ae7e58f9181c744b3f96" 223 | dependencies: 224 | mime-db "~1.37.0" 225 | 226 | ms@2.0.0: 227 | version "2.0.0" 228 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" 229 | 230 | ms@^2.1.1: 231 | version "2.1.1" 232 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" 233 | 234 | mz@^2.7.0: 235 | version "2.7.0" 236 | resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" 237 | integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== 238 | dependencies: 239 | any-promise "^1.0.0" 240 | object-assign "^4.0.1" 241 | thenify-all "^1.0.0" 242 | 243 | negotiator@0.6.1: 244 | version "0.6.1" 245 | resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" 246 | 247 | object-assign@^4.0.1: 248 | version "4.1.1" 249 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" 250 | integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= 251 | 252 | on-finished@^2.3.0: 253 | version "2.3.0" 254 | resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" 255 | dependencies: 256 | ee-first "1.1.1" 257 | 258 | only@~0.0.2: 259 | version "0.0.2" 260 | resolved "https://registry.yarnpkg.com/only/-/only-0.0.2.tgz#2afde84d03e50b9a8edc444e30610a70295edfb4" 261 | 262 | parseurl@^1.3.2: 263 | version "1.3.2" 264 | resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" 265 | 266 | path-is-absolute@1.0.1: 267 | version "1.0.1" 268 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 269 | integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= 270 | 271 | path-to-regexp@^1.1.1: 272 | version "1.7.0" 273 | resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.7.0.tgz#59fde0f435badacba103a84e9d3bc64e96b9937d" 274 | dependencies: 275 | isarray "0.0.1" 276 | 277 | resolve-path@^1.4.0: 278 | version "1.4.0" 279 | resolved "https://registry.yarnpkg.com/resolve-path/-/resolve-path-1.4.0.tgz#c4bda9f5efb2fce65247873ab36bb4d834fe16f7" 280 | integrity sha1-xL2p9e+y/OZSR4c6s2u02DT+Fvc= 281 | dependencies: 282 | http-errors "~1.6.2" 283 | path-is-absolute "1.0.1" 284 | 285 | setprototypeof@1.1.0: 286 | version "1.1.0" 287 | resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" 288 | 289 | "statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@^1.5.0: 290 | version "1.5.0" 291 | resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" 292 | 293 | thenify-all@^1.0.0: 294 | version "1.6.0" 295 | resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" 296 | integrity sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY= 297 | dependencies: 298 | thenify ">= 3.1.0 < 4" 299 | 300 | "thenify@>= 3.1.0 < 4": 301 | version "3.3.0" 302 | resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.0.tgz#e69e38a1babe969b0108207978b9f62b88604839" 303 | integrity sha1-5p44obq+lpsBCCB5eLn2K4hgSDk= 304 | dependencies: 305 | any-promise "^1.0.0" 306 | 307 | toidentifier@1.0.0: 308 | version "1.0.0" 309 | resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" 310 | 311 | type-is@^1.6.16: 312 | version "1.6.16" 313 | resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" 314 | dependencies: 315 | media-typer "0.3.0" 316 | mime-types "~2.1.18" 317 | 318 | urijs@^1.19.0: 319 | version "1.19.1" 320 | resolved "https://registry.yarnpkg.com/urijs/-/urijs-1.19.1.tgz#5b0ff530c0cbde8386f6342235ba5ca6e995d25a" 321 | 322 | vary@^1.1.2: 323 | version "1.1.2" 324 | resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" 325 | 326 | ylru@^1.2.0: 327 | version "1.2.1" 328 | resolved "https://registry.yarnpkg.com/ylru/-/ylru-1.2.1.tgz#f576b63341547989c1de7ba288760923b27fe84f" 329 | --------------------------------------------------------------------------------