├── .dockerignore ├── public ├── favicon.ico ├── img │ ├── android.png │ ├── fb_share.png │ ├── timeline_line.png │ ├── example_gearbest.png │ ├── loading.svg │ └── logo.svg ├── favicon-16x16.png ├── favicon-32x32.png ├── apple-touch-icon.png ├── mstile-150x150.png ├── android-chrome-192x192.png ├── android-chrome-256x256.png ├── fonts │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.ttf │ ├── glyphicons-halflings-regular.woff │ └── glyphicons-halflings-regular.woff2 ├── browserconfig.xml ├── manifest.json ├── safari-pinned-tab.svg ├── js │ ├── vendor │ │ ├── moment-pt.js │ │ ├── moment-timezone.min.js │ │ ├── jquery.timeago.js │ │ ├── moment-timezone-with-data-2010-2020.min.js │ │ └── bootstrap.min.js │ └── main.js └── css │ └── main.css ├── views ├── error.hbs ├── 404.hbs ├── partials │ ├── footer.hbs │ ├── cainiaoEmpty.hbs │ ├── navbar.hbs │ ├── aliTemplate.hbs │ ├── cttTemplate.hbs │ ├── adicionalTemplate.hbs │ ├── expresso24Template.hbs │ ├── correosTemplate.hbs │ ├── skyTemplate.hbs │ └── correosOldTemplate.hbs ├── about.hbs ├── layout.hbs ├── index.hbs ├── faqs.hbs └── news.hbs ├── Dockerfile ├── .gitignore ├── package.json ├── routes ├── index.js └── api.js ├── LICENSE ├── services ├── cacheMiddleware.js └── hbsService.js ├── README.md ├── bin └── www └── app.js /.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules/* -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hdnpt/geartrack-website/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /public/img/android.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hdnpt/geartrack-website/HEAD/public/img/android.png -------------------------------------------------------------------------------- /views/error.hbs: -------------------------------------------------------------------------------- 1 |

{{message}}

2 |

{{error.status}}

3 |
{{error.stack}}
4 | -------------------------------------------------------------------------------- /public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hdnpt/geartrack-website/HEAD/public/favicon-16x16.png -------------------------------------------------------------------------------- /public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hdnpt/geartrack-website/HEAD/public/favicon-32x32.png -------------------------------------------------------------------------------- /public/img/fb_share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hdnpt/geartrack-website/HEAD/public/img/fb_share.png -------------------------------------------------------------------------------- /public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hdnpt/geartrack-website/HEAD/public/apple-touch-icon.png -------------------------------------------------------------------------------- /public/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hdnpt/geartrack-website/HEAD/public/mstile-150x150.png -------------------------------------------------------------------------------- /public/img/timeline_line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hdnpt/geartrack-website/HEAD/public/img/timeline_line.png -------------------------------------------------------------------------------- /public/img/example_gearbest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hdnpt/geartrack-website/HEAD/public/img/example_gearbest.png -------------------------------------------------------------------------------- /public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hdnpt/geartrack-website/HEAD/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /public/android-chrome-256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hdnpt/geartrack-website/HEAD/public/android-chrome-256x256.png -------------------------------------------------------------------------------- /public/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hdnpt/geartrack-website/HEAD/public/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /public/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hdnpt/geartrack-website/HEAD/public/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /public/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hdnpt/geartrack-website/HEAD/public/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /public/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hdnpt/geartrack-website/HEAD/public/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:7 2 | COPY . /geartrack-website 3 | ENV NODE_ENV=production 4 | WORKDIR /geartrack-website 5 | EXPOSE 3000 6 | RUN npm install 7 | ENTRYPOINT ["npm", "start"] -------------------------------------------------------------------------------- /views/404.hbs: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

Página não encontrada!

5 | 6 |

Voltar ao 7 | inicio. 8 |

9 |
10 | 11 |
12 |
13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### Node 2 | node_modules 3 | 4 | ### Jetbrains 5 | .idea 6 | 7 | ### Certificates 8 | .well-known 9 | 10 | ### VS Code 11 | .vscode/* 12 | 13 | ### PM2 configuration file 14 | gear.json 15 | 16 | ### NPM Lock file (having some problems when updating on production server) 17 | package-lock.json -------------------------------------------------------------------------------- /public/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | #ff851b 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Geartrack", 3 | "icons": [ 4 | { 5 | "src": "/android-chrome-192x192.png?v=47rnj2zzvB", 6 | "sizes": "192x192", 7 | "type": "image/png" 8 | }, 9 | { 10 | "src": "/android-chrome-256x256.png?v=47rnj2zzvB", 11 | "sizes": "256x256", 12 | "type": "image/png" 13 | } 14 | ], 15 | "theme_color": "#ff851b", 16 | "background_color": "#ff851b", 17 | "display": "standalone" 18 | } -------------------------------------------------------------------------------- /public/img/loading.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "geartrack-website", 3 | "version": "1.0.2", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www", 7 | "test": "supervisor -w routes,views/partials,app.js -e hbs,js bin/www" 8 | }, 9 | "license": "MIT", 10 | "homepage": "https://geartrack.pt", 11 | "dependencies": { 12 | "bugsnag": "^1.11.0", 13 | "debug": "^2.6.8", 14 | "express": "^4.15.3", 15 | "geartrack": "^2.7.19", 16 | "hbs": "^4.0.1", 17 | "memory-cache": "^0.2.0", 18 | "morgan": "^1.8.2", 19 | "qs": "^6.5.0", 20 | "rr": "^0.1.0", 21 | "serve-favicon": "^2.4.3" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /routes/index.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | 4 | /** 5 | * Home page 6 | */ 7 | router.get('/', function(req, res, next) { 8 | res.render('index'); 9 | }); 10 | 11 | /** 12 | * About 13 | */ 14 | router.get('/about', function(req, res, next) { 15 | res.render('about', { title: 'Sobre' }); 16 | }); 17 | 18 | /** 19 | * News 20 | */ 21 | router.get('/news', function(req, res, next) { 22 | res.render('news', { title: 'Notícias' }); 23 | }); 24 | 25 | /** 26 | * FAQs 27 | */ 28 | router.get('/faqs', function(req, res, next) { 29 | res.render('faqs', { title: 'FAQs' }); 30 | }); 31 | 32 | module.exports = router; 33 | -------------------------------------------------------------------------------- /views/partials/footer.hbs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /views/partials/cainiaoEmpty.hbs: -------------------------------------------------------------------------------- 1 | 2 | 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2017 Carlos Florêncio 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /services/cacheMiddleware.js: -------------------------------------------------------------------------------- 1 | const mcache = require('memory-cache') 2 | 3 | /** 4 | * Cache middleware 5 | * Caches the response for a period of time 6 | * 7 | * Uses memory cache (RAM) 8 | * 9 | * Modify res.locals.expire to control the seconds of the cache 10 | * res.locals.expire = 0 will prevent caching the response 11 | * 12 | * @param seconds 13 | * @param type default = json 14 | * @return {function(*, *, *)} 15 | */ 16 | module.exports = function(seconds, type = 'json') { 17 | return (req, res, next) => { 18 | let key = req.originalUrl 19 | let cachedBody = mcache.get(key) 20 | res.type(type) 21 | 22 | if (cachedBody) { 23 | let body = JSON.parse(cachedBody) // we know that is json 24 | if (body.error) res.status(400) 25 | 26 | res.send(cachedBody) 27 | return 28 | } 29 | 30 | res.sendResponse = res.send 31 | res.send = (body) => { 32 | 33 | let time = seconds 34 | if (typeof res.locals.expire != 'undefined') 35 | time = parseInt(res.locals.expire) 36 | 37 | if (time > 0) { 38 | mcache.put(key, body, time * 1000) //ms 39 | //res.header('cache-control', 'max-age=' + time) browser was not clearing cache right :/ 40 | } 41 | 42 | res.sendResponse(body) 43 | } 44 | next() 45 | } 46 | } -------------------------------------------------------------------------------- /views/partials/navbar.hbs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /views/about.hbs: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
6 | Sobre 7 |
8 |
    9 |
  • 10 |

    Sobre a cache do servidor:

    11 |

    Toda a informação sobre uma encomenda proveninente de terceiros (Sky56, Correos, Adicional, etc) é guardada no servidor por 30 minutos. (Cache)

    12 |

    Durante o tempo de vida dessa cache, a informação apresentada sobre essa encomenda no website não muda.

    13 |

    Quando o tempo de vida da cache expirar, é recolhida novamente informação do site de terceiros.

    14 |

    Para aqueles que mantêm o site aberto, existe um refresh automatico a cada 31 minutos para actualizar a informação apresentada.

    15 |
  • 16 |
  • Este website não guarda nenhuns dados sobre as suas encomendas.
  • 17 |
  • Este website não usa cookies.
  • 18 |
  • Não está afiliado com o Gearbest.
  • 19 |
  • Não gera lucro, é apenas informativo.
  • 20 |
  • Mete like na nossa página do Facebook para saberes quando lançamos novidades!
  • 21 |
22 |
23 | 24 |
25 |
26 | -------------------------------------------------------------------------------- /public/safari-pinned-tab.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | Created by potrace 1.11, written by Peter Selinger 2001-2013 9 | 10 | 12 | 22 | 24 | 27 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /services/hbsService.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | 3 | /** 4 | * Load all partials and helpers to handlebars 5 | * Just a configurator for the hbs package 6 | */ 7 | module.exports = function (handlebars) { 8 | 9 | /* 10 | |-------------------------------------------------------------------------- 11 | | Partials 12 | |-------------------------------------------------------------------------- 13 | */ 14 | handlebars.registerPartials(path.join(__dirname, '../views/partials')); 15 | 16 | /* 17 | |-------------------------------------------------------------------------- 18 | | Helpers 19 | |-------------------------------------------------------------------------- 20 | */ 21 | /** 22 | * Append content to a named section 23 | * usage: 24 | * 25 | * {{#append 'scripts'}} 26 | * 27 | * {{/append}} 28 | * 29 | */ 30 | handlebars.registerHelper('append', function (name, options) { 31 | if(!this._sections) 32 | this._sections = {} 33 | 34 | if(this._sections[name]) 35 | this._sections[name] += options.fn(this) // append if there is already content 36 | else 37 | this._sections[name] = options.fn(this) // save the content of the block 38 | 39 | return null 40 | }) 41 | 42 | /** 43 | * Display the content of the section 44 | * usage: 45 | * 46 | * {{section 'scripts' }} 47 | */ 48 | handlebars.registerHelper('section', function (name) { 49 | if(this._sections && this._sections[name]) 50 | return new handlebars.handlebars.SafeString(this._sections[name]) 51 | 52 | return null 53 | }) 54 | 55 | /** 56 | * Current year 57 | * usage: 58 | * 59 | * {{year}} 60 | */ 61 | handlebars.registerHelper('year', function () { 62 | return new Date().getFullYear() 63 | }) 64 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Geartrack 1.0 (No further updates to this version) 2 | 3 | [![Join the chat at https://gitter.im/hdnpt/geartrack-website](https://badges.gitter.im/hdnpt/geartrack-website.svg)](https://gitter.im/hdnpt/geartrack-website?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 4 | 5 | >Online version: [https://geartrack.pt](https://geartrack.pt) 6 | 7 | **Geartrack 2.0 is under development, this version will no longer be mantained. Use the online version which will always be updated :)** 8 | 9 | This is an Express.js app. 10 | 11 | ### Screenshot 12 | ![Screen](http://i.imgur.com/wUhzJO3.png) 13 | 14 | ### Requirements 15 | - Node 16 | - Environment variables: 17 | - (optional) **GEARTRACK_PROXYS**: `ip,ip,ip` - Some trackers may block your machine ip, use different proxies to get the data. 18 | - (optional) **GEARTRACK_BUGSNAG**: `apikey` - When an exception occurs on production you are notified by email. 19 | 20 | ### Instructions 21 | - clone this repo to a folder 22 | - `npm install` 23 | - `npm start` - will run `node bin/wwww` 24 | 25 | ### Developer instructions 26 | - `npm test` - Runs a local server and watches for file changes to reload the page. 27 | 28 | ### Docker instructions 29 | To build and run locally: 30 | - `docker build -t geartrack-website .` 31 | - `docker run -d -p 80:3000 geartrack-website` 32 | 33 | Using the public image on docker hub: 34 | - `docker run -d -p 80:3000 hdnpt/geartrack-website` - the latest image will be downloaded and the geartrack will be available at `http://localhost` (to stop use `docker stop [containerid]`) 35 | 36 | Passing environment variables: 37 | - `docker run -d -p 80:3000 -e "GEARTRACK_BUGSNAG=apikey" hdnpt/geartrack-website` 38 | 39 | ### Todo 40 | - A better version is under development using .net core and will support notifications and other features! 41 | 42 | ### License 43 | MIT 44 | -------------------------------------------------------------------------------- /views/partials/aliTemplate.hbs: -------------------------------------------------------------------------------- 1 | 2 | 41 | -------------------------------------------------------------------------------- /bin/www: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /** 4 | * Module dependencies. 5 | */ 6 | 7 | var app = require('../app'); 8 | var debug = require('debug')('geartrack-website:server'); 9 | var http = require('http'); 10 | 11 | /** 12 | * Get port from environment and store in Express. 13 | */ 14 | 15 | var port = normalizePort(process.env.PORT || '3000'); 16 | app.set('port', port); 17 | 18 | /** 19 | * Create HTTP server. 20 | */ 21 | 22 | var server = http.createServer(app); 23 | 24 | /** 25 | * Listen on provided port, on all network interfaces. 26 | */ 27 | 28 | server.listen(port); 29 | server.on('error', onError); 30 | server.on('listening', onListening); 31 | 32 | /** 33 | * Normalize a port into a number, string, or false. 34 | */ 35 | 36 | function normalizePort(val) { 37 | var port = parseInt(val, 10); 38 | 39 | if (isNaN(port)) { 40 | // named pipe 41 | return val; 42 | } 43 | 44 | if (port >= 0) { 45 | // port number 46 | return port; 47 | } 48 | 49 | return false; 50 | } 51 | 52 | /** 53 | * Event listener for HTTP server "error" event. 54 | */ 55 | 56 | function onError(error) { 57 | if (error.syscall !== 'listen') { 58 | throw error; 59 | } 60 | 61 | var bind = typeof port === 'string' 62 | ? 'Pipe ' + port 63 | : 'Port ' + port; 64 | 65 | // handle specific listen errors with friendly messages 66 | switch (error.code) { 67 | case 'EACCES': 68 | console.error(bind + ' requires elevated privileges'); 69 | process.exit(1); 70 | break; 71 | case 'EADDRINUSE': 72 | console.error(bind + ' is already in use'); 73 | process.exit(1); 74 | break; 75 | default: 76 | throw error; 77 | } 78 | } 79 | 80 | /** 81 | * Event listener for HTTP server "listening" event. 82 | */ 83 | 84 | function onListening() { 85 | var addr = server.address(); 86 | var bind = typeof addr === 'string' 87 | ? 'pipe ' + addr 88 | : 'port ' + addr.port; 89 | debug('Listening on ' + bind); 90 | } 91 | -------------------------------------------------------------------------------- /views/partials/cttTemplate.hbs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /views/partials/adicionalTemplate.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 53 | -------------------------------------------------------------------------------- /views/partials/expresso24Template.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 55 | -------------------------------------------------------------------------------- /public/js/vendor/moment-pt.js: -------------------------------------------------------------------------------- 1 | //! moment.js locale configuration 2 | //! locale : Portuguese [pt] 3 | //! author : Jefferson : https://github.com/jalex79 4 | 5 | ;(function (global, factory) { 6 | typeof exports === 'object' && typeof module !== 'undefined' 7 | && typeof require === 'function' ? factory(require('../moment')) : 8 | typeof define === 'function' && define.amd ? define(['../moment'], factory) : 9 | factory(global.moment) 10 | }(this, (function (moment) { 'use strict'; 11 | 12 | 13 | var pt = moment.defineLocale('pt', { 14 | months : 'Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro'.split('_'), 15 | monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'), 16 | weekdays : 'Domingo_Segunda-Feira_Terça-Feira_Quarta-Feira_Quinta-Feira_Sexta-Feira_Sábado'.split('_'), 17 | weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'), 18 | weekdaysMin : 'Do_2ª_3ª_4ª_5ª_6ª_Sá'.split('_'), 19 | weekdaysParseExact : true, 20 | longDateFormat : { 21 | LT : 'HH:mm', 22 | LTS : 'HH:mm:ss', 23 | L : 'DD/MM/YYYY', 24 | LL : 'D [de] MMMM [de] YYYY', 25 | LLL : 'D [de] MMMM [de] YYYY HH:mm', 26 | LLLL : 'dddd, D [de] MMMM [de] YYYY HH:mm' 27 | }, 28 | calendar : { 29 | sameDay: '[Hoje às] LT', 30 | nextDay: '[Amanhã às] LT', 31 | nextWeek: 'dddd [às] LT', 32 | lastDay: '[Ontem às] LT', 33 | lastWeek: function () { 34 | return (this.day() === 0 || this.day() === 6) ? 35 | '[Último] dddd [às] LT' : // Saturday + Sunday 36 | '[Última] dddd [às] LT'; // Monday - Friday 37 | }, 38 | sameElse: 'L' 39 | }, 40 | relativeTime : { 41 | future : 'em %s', 42 | past : 'há %s', 43 | s : 'segundos', 44 | m : 'um minuto', 45 | mm : '%d minutos', 46 | h : 'uma hora', 47 | hh : '%d horas', 48 | d : 'um dia', 49 | dd : '%d dias', 50 | M : 'um mês', 51 | MM : '%d meses', 52 | y : 'um ano', 53 | yy : '%d anos' 54 | }, 55 | dayOfMonthOrdinalParse: /\d{1,2}º/, 56 | ordinal : '%dº', 57 | week : { 58 | dow : 1, // Monday is the first day of the week. 59 | doy : 4 // The week that contains Jan 4th is the first week of the year. 60 | } 61 | }); 62 | 63 | return pt; 64 | 65 | }))); 66 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | const express = require('express') 2 | const path = require('path') 3 | const favicon = require('serve-favicon') 4 | const logger = require('morgan') 5 | const hbs = require('hbs') 6 | const bugsnag = require("bugsnag") 7 | const index = require('./routes/index') 8 | const api = require('./routes/api') 9 | const hbsService = require('./services/hbsService') 10 | 11 | // Error reporting on production 12 | bugsnag.register(process.env.GEARTRACK_BUGSNAG, { 13 | notifyReleaseStages: ['production'] 14 | }) 15 | 16 | const app = express() 17 | 18 | /* 19 | |-------------------------------------------------------------------------- 20 | | App configuration 21 | |-------------------------------------------------------------------------- 22 | */ 23 | app.set('views', path.join(__dirname, 'views')) 24 | app.set('view engine', 'hbs') 25 | app.set('bugsnag', bugsnag) // save the object for responses notify when a parse fails 26 | app.locals.app_name = 'Geartrack' 27 | hbsService(hbs) // Register hbs partials and helpers 28 | 29 | /* 30 | |-------------------------------------------------------------------------- 31 | | App middlewares 32 | |-------------------------------------------------------------------------- 33 | */ 34 | app.use(bugsnag.requestHandler) 35 | app.use(logger('dev')) 36 | app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))) 37 | app.use(express.static(path.join(__dirname, 'public'))) 38 | 39 | /* 40 | |-------------------------------------------------------------------------- 41 | | App Routes 42 | |-------------------------------------------------------------------------- 43 | */ 44 | app.use('/', index) 45 | app.use('/api', api) 46 | 47 | app.use(bugsnag.errorHandler) 48 | /* 49 | |-------------------------------------------------------------------------- 50 | | 404 51 | |-------------------------------------------------------------------------- 52 | */ 53 | app.use(function(req, res, next) { 54 | const err = new Error('Not Found') 55 | err.status = 404 56 | res.type('html') 57 | res.status(404).render('404', {title: "404"}) 58 | }) 59 | 60 | /* 61 | |-------------------------------------------------------------------------- 62 | | Error handle 63 | |-------------------------------------------------------------------------- 64 | */ 65 | app.use(function(err, req, res, next) { 66 | // set locals, only providing error in development 67 | res.locals.message = err.message 68 | res.locals.error = req.app.get('env') === 'development' ? err : {} 69 | 70 | // render the error page 71 | res.status(err.status || 500) 72 | res.render('error') 73 | }) 74 | 75 | module.exports = app 76 | -------------------------------------------------------------------------------- /views/partials/correosTemplate.hbs: -------------------------------------------------------------------------------- 1 | 2 | 67 | -------------------------------------------------------------------------------- /views/partials/skyTemplate.hbs: -------------------------------------------------------------------------------- 1 | 2 | 62 | -------------------------------------------------------------------------------- /public/js/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | |-------------------------------------------------------------------------- 3 | | Main 4 | |-------------------------------------------------------------------------- 5 | */ 6 | 'use strict' 7 | 8 | $('body').tooltip({ 9 | selector: '[data-toggle="tooltip"]' 10 | }) 11 | 12 | moment.locale('pt') 13 | var timezone = moment.tz.guess() 14 | 15 | /* 16 | |-------------------------------------------------------------------------- 17 | | Handlebars templates 18 | |-------------------------------------------------------------------------- 19 | */ 20 | Handlebars.registerHelper('HelperFromNow', function (date) { 21 | return moment(date).tz(timezone).fromNow() 22 | }) 23 | 24 | Handlebars.registerHelper('HelperDate', function (date) { 25 | return moment(date).tz(timezone).format('DD/MM/YYYY') 26 | }) 27 | 28 | Handlebars.registerHelper('HelperDateWithHours', function (date) { 29 | return moment(date).tz(timezone).format('DD/MM/YYYY HH:mm') 30 | }) 31 | 32 | Handlebars.registerHelper('HelperHours', function (date) { 33 | return moment(date).tz(timezone).format('HH:mm') 34 | }) 35 | 36 | Handlebars.registerHelper('HelperCapitalize', function (string) { 37 | var lower = string.toLowerCase() 38 | 39 | if (lower.charAt(0) == '[') { // cainiao states have [country] message 40 | lower = lower.replaceAt(1, lower.charAt(1).toUpperCase()) 41 | var idx = lower.indexOf(']') + 2 42 | lower = lower.replaceAt(idx, lower.charAt(idx).toUpperCase()) 43 | } 44 | 45 | return lower.charAt(0).toUpperCase() + lower.slice(1) 46 | }) 47 | 48 | Handlebars.registerHelper('HelperCapitalizeWords', function (string) { 49 | if(string.length == 2) { // uppercase country codes 50 | return string.toUpperCase() 51 | } 52 | 53 | string = string.toLowerCase() 54 | return string.replace(/(?:^|\s)\S/g, function (a) { 55 | return a.toUpperCase() 56 | }) 57 | }) 58 | 59 | Handlebars.registerHelper('HelperLowerCase', function (string) { 60 | return string.toLowerCase() 61 | }) 62 | 63 | Handlebars.registerHelper('HelperState', function (state, first, insideFirst) { 64 | switch (state.toLowerCase()) { 65 | case 'product delivered': 66 | case 'entregue': 67 | case 'entregado': 68 | case 'delivery success': 69 | case 'order delivered': 70 | case 'item delivered': 71 | case 'the item has been delivered successfully': 72 | case 'entregado. su envío está entregado.': 73 | return 'delivered' 74 | default: 75 | if (typeof insideFirst == 'boolean') { 76 | if (insideFirst && first) 77 | return 'new' 78 | } else { 79 | if (first) 80 | return 'new' 81 | } 82 | 83 | return '' 84 | } 85 | }) 86 | 87 | Handlebars.registerHelper('HelperTrackerSkyPQ', function (skyinfo, options) { 88 | if (skyinfo.id.indexOf('PQ') != -1) { // is PQ 89 | if (skyinfo.messages.length == 0 && skyinfo.status.length > 0) 90 | return options.fn(this) 91 | 92 | return options.inverse(this) 93 | } else { 94 | return options.fn(this) 95 | } 96 | }) 97 | 98 | /* 99 | |-------------------------------------------------------------------------- 100 | | String utils 101 | |-------------------------------------------------------------------------- 102 | */ 103 | String.prototype.replaceAt = function (index, replacement) { 104 | return this.substr(0, index) + replacement + this.substr(index + replacement.length) 105 | } 106 | -------------------------------------------------------------------------------- /views/partials/correosOldTemplate.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 89 | -------------------------------------------------------------------------------- /public/img/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 13 | 15 | 17 | 20 | 22 | 25 | 27 | 31 | 43 | 44 | 48 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /views/layout.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {{#if title}} 6 | {{ title }} - Geartrack 7 | {{else}} 8 | Geartrack 9 | {{/if}} 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | {{> navbar }} 65 | 66 |
67 | 68 |
69 |
70 | {{{ body }}} 71 |
72 |
73 | 74 | {{> footer }} 75 |
76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | {{section 'scripts' }} 86 | 87 | 88 | 97 | 98 | 99 | 100 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /public/js/vendor/moment-timezone.min.js: -------------------------------------------------------------------------------- 1 | //! moment-timezone.js 2 | //! version : 0.5.10 3 | //! Copyright (c) JS Foundation and other contributors 4 | //! license : MIT 5 | //! github.com/moment/moment-timezone 6 | !function(a,b){"use strict";"function"==typeof define&&define.amd?define(["moment"],b):"object"==typeof module&&module.exports?module.exports=b(require("moment")):b(a.moment)}(this,function(a){"use strict";function b(a){return a>96?a-87:a>64?a-29:a-48}function c(a){var c,d=0,e=a.split("."),f=e[0],g=e[1]||"",h=1,i=0,j=1;for(45===a.charCodeAt(0)&&(d=1,j=-1),d;d0?k[0].zone.name:void 0}function q(a){return D&&!a||(D=p()),D}function r(a){return(a||"").toLowerCase().replace(/\//g,"_")}function s(a){var b,c,d,e;for("string"==typeof a&&(a=[a]),b=0;b= 2.6.0. You are using Moment.js "+a.version+". See momentjs.com"),h.prototype={_set:function(a){this.name=a.name,this.abbrs=a.abbrs,this.untils=a.untils,this.offsets=a.offsets,this.population=a.population},_index:function(a){var b,c=+a,d=this.untils;for(b=0;bd&&A.moveInvalidForward&&(b=d),f= 2.9.0. You are using Moment.js "+a.version+"."),a.defaultZone=b?t(b):null,a};var N=a.momentProperties;return"[object Array]"===Object.prototype.toString.call(N)?(N.push("_z"),N.push("_a")):N&&(N._z=null),a}); -------------------------------------------------------------------------------- /public/css/main.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 70px; 3 | font-family: 'Roboto', sans-serif; 4 | } 5 | 6 | .mb0 { 7 | margin-bottom: 0; 8 | } 9 | 10 | .mb10 { 11 | margin-bottom: 10px; 12 | } 13 | 14 | .mr10 { 15 | margin-right: 10px; 16 | } 17 | 18 | .track-entries { 19 | font-size: 14px; 20 | line-height: 14px; 21 | } 22 | 23 | .track-entries h4 { 24 | padding: 0; 25 | margin: 0 0 2px 0; 26 | white-space: nowrap; 27 | overflow: hidden; 28 | text-overflow: ellipsis; 29 | } 30 | 31 | .label-yellow { 32 | background-color: #f1af00; 33 | } 34 | 35 | .track-entries p { 36 | margin: 0; 37 | } 38 | 39 | .track-entries .remove-container { 40 | padding-top: 12px; 41 | } 42 | 43 | .track h4 { 44 | margin: 0; 45 | padding: 0; 46 | display: inline-block; 47 | } 48 | 49 | .track .right-id { 50 | font-size: 12px; 51 | float: right; 52 | } 53 | 54 | .center-img { 55 | margin: 0 auto; 56 | display: block; 57 | } 58 | 59 | .track .panel-body { 60 | padding: 5px 15px; 61 | } 62 | 63 | .track h2 { 64 | margin: 5px 0 10px 0; 65 | font-size: 18.75px; 66 | color: #ffffff; 67 | padding: 0 12px !important; 68 | line-height: 35px; 69 | border-radius: .25em; 70 | } 71 | 72 | .track h2 a { 73 | float: right; 74 | color: white; 75 | font-size: 15px; 76 | line-height: 35px; 77 | } 78 | 79 | .track h2 a:hover, 80 | .track h2 a:focus{ 81 | outline: none; 82 | } 83 | 84 | .track h2 span { 85 | text-align: left; 86 | } 87 | 88 | .track h3 { 89 | margin: 5px 0 10px 0; 90 | font-size: 18px; 91 | } 92 | 93 | .heading { 94 | color: white; 95 | } 96 | 97 | .footer { 98 | padding-top: 19px; 99 | color: #777; 100 | border-top: 1px solid #e5e5e5; 101 | } 102 | 103 | #hide-info { 104 | display: none; 105 | } 106 | 107 | .close-btn { 108 | position: absolute; 109 | right: 33px; 110 | top: 13px; 111 | } 112 | 113 | .jumbotron { 114 | padding-top: 20px; 115 | padding-bottom: 20px; 116 | } 117 | 118 | /* FAQs 119 | ========================================================================== */ 120 | #accordion a:hover, 121 | #accordion a:focus { 122 | text-decoration: none; 123 | } 124 | 125 | .faqHeader { 126 | font-size: 27px; 127 | margin: 20px; 128 | } 129 | 130 | .panel-heading [data-toggle="collapse"]:after { 131 | font-family: 'Glyphicons Halflings'; 132 | content: "\e072"; /* "play" icon */ 133 | float: right; 134 | color: #F58723; 135 | font-size: 18px; 136 | line-height: 22px; 137 | /* rotate "play" icon from > (right arrow) to down arrow */ 138 | -webkit-transform: rotate(-90deg); 139 | -moz-transform: rotate(-90deg); 140 | -ms-transform: rotate(-90deg); 141 | -o-transform: rotate(-90deg); 142 | transform: rotate(-90deg); 143 | } 144 | 145 | .panel-heading [data-toggle="collapse"].collapsed:after { 146 | /* rotate "play" icon from > (right arrow) to ^ (up arrow) */ 147 | -webkit-transform: rotate(90deg); 148 | -moz-transform: rotate(90deg); 149 | -ms-transform: rotate(90deg); 150 | -o-transform: rotate(90deg); 151 | transform: rotate(90deg); 152 | color: #454444; 153 | } 154 | 155 | #help_block { 156 | display: none; 157 | } 158 | 159 | 160 | .central-text { 161 | font-size: 13px; 162 | } 163 | 164 | .help-cursor, [data-toggle="tooltip"] { 165 | cursor: help; 166 | } 167 | 168 | /* Timeline 169 | ========================================================================== */ 170 | .result-details dt { 171 | padding: 10px 0 10px; 172 | } 173 | 174 | .result-details dd.new { 175 | color: #ff851b; 176 | } 177 | 178 | .result-details dd.new i { 179 | border-color: #ff851b; 180 | background: #ff851b; 181 | } 182 | 183 | .result-details dd.delivered { 184 | color: #309c40; 185 | } 186 | 187 | .result-details dd.delivered i { 188 | border-color: #309c40; 189 | background: #309c40; 190 | } 191 | 192 | .result-details dd:first-child { 193 | background-position: 0 10px !important; 194 | background-repeat: no-repeat !important; 195 | } 196 | 197 | .result-details dd { 198 | position: relative; 199 | margin-left: 10px; 200 | background: url('/img/timeline_line.png') left repeat-y; 201 | } 202 | 203 | .result-details dd i { 204 | display: inline-block; 205 | float: left; 206 | margin: 10px 0 0 -3px; 207 | width: 7px; 208 | height: 7px; 209 | line-height: 16px; 210 | border-radius: 50%; 211 | border: 2px solid #e0e0e0; 212 | background: #e0e0e0; 213 | } 214 | 215 | .result-details i { 216 | font-style: normal; 217 | } 218 | 219 | .result-details dd .track-news { 220 | position: relative; 221 | margin-right: 0; 222 | padding: 0 !important; 223 | background: 0; 224 | } 225 | 226 | .result-details dd span.date { 227 | position: absolute; 228 | width: 105px; 229 | overflow: hidden; 230 | white-space: nowrap; 231 | padding: 0 !important; 232 | height: 25px; 233 | line-height: 25px; 234 | text-align: center; 235 | font-weight: bold; 236 | cursor: help; 237 | } 238 | 239 | .result-details dd table { 240 | margin-left: 20px; 241 | margin-bottom: 10px; 242 | } 243 | 244 | .result-details dd table td { 245 | height: 25px; 246 | line-height: 25px; 247 | } 248 | 249 | 250 | .result-details dd table td.date { 251 | width: 120px; 252 | font-weight: bold; 253 | } 254 | 255 | .result-details dd table td.area { 256 | width: 200px; 257 | } 258 | 259 | .result-details dd .track-news p { 260 | margin-left: 110px; 261 | line-height: 25px; 262 | } 263 | 264 | .result-details dd:last-child { 265 | background-position: 0 -190px; 266 | background-repeat: no-repeat; 267 | } 268 | 269 | .result-details dd:only-child { 270 | background: none !important; 271 | } 272 | 273 | .area-break:before { 274 | content: " - "; 275 | } 276 | 277 | @media (max-width: 768px) { 278 | .area-break:before { 279 | content: ""; 280 | } 281 | 282 | .area-break { 283 | font-size: 13px; 284 | line-height: 13px; 285 | display: block; 286 | } 287 | 288 | .break-strong strong { 289 | display: block; 290 | } 291 | } 292 | 293 | /* Fixes cross browser support 294 | ========================================================================== */ 295 | body:last-child abbr[title], x:-moz-any-link { 296 | cursor: help; 297 | border-bottom: none !important; 298 | } 299 | 300 | .central-text { 301 | font-size: 13px; 302 | } -------------------------------------------------------------------------------- /routes/api.js: -------------------------------------------------------------------------------- 1 | const express = require('express') 2 | const router = express.Router() 3 | const geartrack = require('geartrack') 4 | const roundrobin = require('rr') 5 | const cache = require('../services/cacheMiddleware') 6 | 7 | // default cache time - 30 min 8 | const CACHE_TIME = 30 * 60 9 | 10 | // All this routes will be cached 11 | // Error responses can manipulate cache time 12 | router.use(cache(CACHE_TIME)) 13 | 14 | // All common providers, name, cssClass for color 15 | let providers = { 16 | 'sky': new Provider('Sky56', 'primary'), 17 | 'correoses': new Provider('Correos ES', 'yellow'), 18 | 'expresso24': new Provider('Expresso24', 'warning'), 19 | 'singpost': new Provider('Singpost', 'danger'), 20 | 'ctt': new Provider('CTT', 'primary'), 21 | 'directlink': new Provider('Direct Link', 'yellow'), 22 | 'trackchinapost': new Provider('Track China Post', 'danger'), 23 | 'cainiao': new Provider('Cainiao', 'danger'), 24 | 'yanwen': new Provider('Yanwen', 'success'), 25 | 'cjah': new Provider('Cjah Tracking', 'success'), 26 | 'postNL': new Provider('Post NL', 'warning'), 27 | 'malaysiaPos': new Provider('Malasya Pos', 'danger'), 28 | 'winit': new Provider('Winit', 'primary'), 29 | 'panasia': new Provider('Panasia', 'info'), 30 | 'pitneybowes': new Provider('Pitney Bowes', 'primary'), 31 | 'dhl': new Provider('DHL', 'yellow'), 32 | 'track24': new Provider('Track24', 'info'), 33 | 'correos': new Provider('Correos Express Novo', 'danger'), 34 | 'correosOld': new Provider('Correos Express Antigo', 'danger'), 35 | 'mrw': new Provider('MRW', 'primary'), 36 | 'ips': new Provider('IPS', 'yellow'), 37 | 'track17': new Provider('17track', 'warning') 38 | } 39 | 40 | /** 41 | * Adicional data 42 | */ 43 | router.get('/adicional', validateId, validatePostalCode, function (req, res) { 44 | let id = req.query.id, postalcode = req.query.postalcode 45 | 46 | //return processErrorResponse(new Error('DOWN - '), res, 'Adicional') 47 | 48 | geartrack.adicional.getInfo(id, postalcode, (err, adicionalEntity) => { 49 | if (err) { 50 | // sets the status code and the appropriate message 51 | return processErrorResponse(err, res, { 52 | provider: 'adicional', 53 | providerInfo: new Provider('Adicional', 'success'), 54 | id: id 55 | }) 56 | } 57 | 58 | res.json(adicionalEntity) 59 | }) 60 | }) 61 | 62 | let proxys = [] 63 | if (process.env.GEARTRACK_PROXYS) { 64 | proxys = process.env.GEARTRACK_PROXYS.split(',').map(ip => ip.trim()).filter(ip => ip.length > 0) 65 | } 66 | 67 | /** 68 | * General providers that only need an id 69 | */ 70 | router.get('/:provider', validateId, function (req, res, next) { 71 | const id = req.query.id 72 | const tracker = req.params.provider 73 | 74 | let providerObj = providers[tracker] 75 | 76 | if (!providerObj) // no provider found 77 | return next() 78 | 79 | if(geartrack[tracker].getInfoProxy && proxys.length > 0) { // this tracker supports proxy requests 80 | let proxy = roundrobin(proxys) 81 | let proxyUrl = 'http://' + proxy + '/' + tracker 82 | 83 | geartrack[tracker].getInfoProxy(id, proxyUrl, providerCallback(res, tracker, providerObj, id)) 84 | } else { 85 | geartrack[tracker].getInfo(id, providerCallback(res, tracker, providerObj, id)) 86 | } 87 | }) 88 | 89 | function providerCallback (res, tracker, providerObj, id) { 90 | return (err, entity) => { 91 | if (err) { 92 | // sets the status code and the appropriate message 93 | return processErrorResponse(err, res, { 94 | provider: tracker, 95 | providerInfo: providerObj, 96 | id: id 97 | }) 98 | } 99 | 100 | if (entity.constructor && 101 | entity.constructor.name && 102 | entity.constructor.name == 'SkyInfo' && 103 | entity.messages && 104 | entity.messages.length == 0 && 105 | entity.status && 106 | entity.status.length == 0) { 107 | // Sky has no info 108 | return processErrorResponse(new Error('DEFAULT - no info'), res, { 109 | provider: tracker, 110 | providerInfo: providerObj, 111 | id: id 112 | }) 113 | } 114 | 115 | entity.provider = providerObj.name // name shown: 'Informação [provider]' 116 | entity.color = providerObj.cssClass // color of the background, may use bootstrap classes 117 | 118 | res.json(entity) 119 | } 120 | } 121 | 122 | /* 123 | |-------------------------------------------------------------------------- 124 | | Process Error Response 125 | |-------------------------------------------------------------------------- 126 | */ 127 | function processErrorResponse (err, res, info) { 128 | let cacheSeconds = 10 * 60 // error responses are cached for 10 min 129 | let code = 400 130 | let message = '' 131 | 132 | let type = getErrorType(err.message) 133 | let bugsnag = res.app.get('bugsnag') 134 | 135 | switch (type) { 136 | case 'BUSY': 137 | message = 'O servidor está sobrecarregado, tenta novamente daqui a um minuto.' 138 | cacheSeconds = 60 // cache for 1min 139 | break 140 | case 'UNAVAILABLE': 141 | message = 'O servidor não está disponível de momento. Tenta mais tarde.' 142 | break 143 | case 'DOWN': 144 | case 'EMPTY': 145 | message = 'De momento este serviço está com problemas. Tenta mais tarde.' 146 | break 147 | case 'PARSER': 148 | if(info.provider != 'correosOld' && bugsnag) bugsnag.notify(err) // send error to be analysed 149 | message = 'De momento estamos com dificuldade em aceder à informação deste servidor. Tenta mais tarde.' 150 | break 151 | case 'ACTION_REQUIRED': 152 | if(bugsnag) bugsnag.notify(err) // send error to be analysed 153 | cacheSeconds = 0 // prevent cache 154 | message = 'Este tracker pode precisar de um passo adicional no seu website. Se efetuares esse passo volta e atualiza a pagina para tentarmos de novo! :)' 155 | break 156 | default: // NO_DATA 157 | message = 'Ainda não existe informação disponível para este ID.' 158 | break 159 | } 160 | 161 | res.locals.expire = cacheSeconds 162 | return res.status(code).json({ 163 | error: message, 164 | provider: info.providerInfo.name, 165 | link: geartrack[info.provider].getLink(info.id), 166 | color: info.providerInfo.cssClass // color of the background, may use bootstrap classes 167 | }) 168 | } 169 | 170 | function getErrorType (errorMessage) { 171 | let idx = errorMessage.indexOf(' - ') 172 | return errorMessage.substring(0, idx) 173 | } 174 | 175 | /* 176 | |-------------------------------------------------------------------------- 177 | | Validation Middlewares 178 | |-------------------------------------------------------------------------- 179 | */ 180 | function validateId (req, res, next) { 181 | let id = req.query.id 182 | 183 | if (!id) { 184 | res.status(400).json({error: 'ID must be passed in the query string!'}) 185 | return 186 | } 187 | 188 | next() 189 | } 190 | 191 | function validatePostalCode (req, res, next) { 192 | let postalcode = req.query.postalcode 193 | 194 | if (!postalcode) { 195 | res.status(400).json({error: 'Postalcode must be passed in the query string!'}) 196 | return 197 | } 198 | 199 | next() 200 | } 201 | 202 | /* 203 | |-------------------------------------------------------------------------- 204 | | Utils 205 | |-------------------------------------------------------------------------- 206 | */ 207 | function Provider (name, cssClass) { 208 | this.name = name 209 | this.cssClass = cssClass 210 | } 211 | 212 | function getRandomIntInclusive (min, max) { 213 | min = Math.ceil(min) 214 | max = Math.floor(max) 215 | return Math.floor(Math.random() * (max - min + 1)) + min 216 | } 217 | 218 | module.exports = router 219 | -------------------------------------------------------------------------------- /public/js/vendor/jquery.timeago.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Timeago is a jQuery plugin that makes it easy to support automatically 3 | * updating fuzzy timestamps (e.g. "4 minutes ago" or "about 1 day ago"). 4 | * 5 | * @name timeago 6 | * @version 1.5.4 7 | * @requires jQuery v1.2.3+ 8 | * @author Ryan McGeary 9 | * @license MIT License - http://www.opensource.org/licenses/mit-license.php 10 | * 11 | * For usage and examples, visit: 12 | * http://timeago.yarp.com/ 13 | * 14 | * Copyright (c) 2008-2017, Ryan McGeary (ryan -[at]- mcgeary [*dot*] org) 15 | */ 16 | 17 | (function (factory) { 18 | if (typeof define === 'function' && define.amd) { 19 | // AMD. Register as an anonymous module. 20 | define(['jquery'], factory); 21 | } else if (typeof module === 'object' && typeof module.exports === 'object') { 22 | factory(require('jquery')); 23 | } else { 24 | // Browser globals 25 | factory(jQuery); 26 | } 27 | }(function ($) { 28 | $.timeago = function(timestamp) { 29 | if (timestamp instanceof Date) { 30 | return inWords(timestamp); 31 | } else if (typeof timestamp === "string") { 32 | return inWords($.timeago.parse(timestamp)); 33 | } else if (typeof timestamp === "number") { 34 | return inWords(new Date(timestamp)); 35 | } else { 36 | return inWords($.timeago.datetime(timestamp)); 37 | } 38 | }; 39 | var $t = $.timeago; 40 | 41 | $.extend($.timeago, { 42 | settings: { 43 | refreshMillis: 60000, 44 | allowPast: true, 45 | allowFuture: false, 46 | localeTitle: false, 47 | cutoff: 0, 48 | autoDispose: true, 49 | strings: { 50 | prefixAgo: null, 51 | prefixFromNow: null, 52 | suffixAgo: "ago", 53 | suffixFromNow: "from now", 54 | inPast: 'any moment now', 55 | seconds: "less than a minute", 56 | minute: "about a minute", 57 | minutes: "%d minutes", 58 | hour: "about an hour", 59 | hours: "about %d hours", 60 | day: "a day", 61 | days: "%d days", 62 | month: "about a month", 63 | months: "%d months", 64 | year: "about a year", 65 | years: "%d years", 66 | wordSeparator: " ", 67 | numbers: [] 68 | } 69 | }, 70 | 71 | inWords: function(distanceMillis) { 72 | if (!this.settings.allowPast && ! this.settings.allowFuture) { 73 | throw 'timeago allowPast and allowFuture settings can not both be set to false.'; 74 | } 75 | 76 | var $l = this.settings.strings; 77 | var prefix = $l.prefixAgo; 78 | var suffix = $l.suffixAgo; 79 | if (this.settings.allowFuture) { 80 | if (distanceMillis < 0) { 81 | prefix = $l.prefixFromNow; 82 | suffix = $l.suffixFromNow; 83 | } 84 | } 85 | 86 | if (!this.settings.allowPast && distanceMillis >= 0) { 87 | return this.settings.strings.inPast; 88 | } 89 | 90 | var seconds = Math.abs(distanceMillis) / 1000; 91 | var minutes = seconds / 60; 92 | var hours = minutes / 60; 93 | var days = hours / 24; 94 | var years = days / 365; 95 | 96 | function substitute(stringOrFunction, number) { 97 | var string = $.isFunction(stringOrFunction) ? stringOrFunction(number, distanceMillis) : stringOrFunction; 98 | var value = ($l.numbers && $l.numbers[number]) || number; 99 | return string.replace(/%d/i, value); 100 | } 101 | 102 | var words = seconds < 45 && substitute($l.seconds, Math.round(seconds)) || 103 | seconds < 90 && substitute($l.minute, 1) || 104 | minutes < 45 && substitute($l.minutes, Math.round(minutes)) || 105 | minutes < 90 && substitute($l.hour, 1) || 106 | hours < 24 && substitute($l.hours, Math.round(hours)) || 107 | hours < 42 && substitute($l.day, 1) || 108 | days < 30 && substitute($l.days, Math.round(days)) || 109 | days < 45 && substitute($l.month, 1) || 110 | days < 365 && substitute($l.months, Math.round(days / 30)) || 111 | years < 1.5 && substitute($l.year, 1) || 112 | substitute($l.years, Math.round(years)); 113 | 114 | var separator = $l.wordSeparator || ""; 115 | if ($l.wordSeparator === undefined) { separator = " "; } 116 | return $.trim([prefix, words, suffix].join(separator)); 117 | }, 118 | 119 | parse: function(iso8601) { 120 | var s = $.trim(iso8601); 121 | s = s.replace(/\.\d+/,""); // remove milliseconds 122 | s = s.replace(/-/,"/").replace(/-/,"/"); 123 | s = s.replace(/T/," ").replace(/Z/," UTC"); 124 | s = s.replace(/([\+\-]\d\d)\:?(\d\d)/," $1$2"); // -04:00 -> -0400 125 | s = s.replace(/([\+\-]\d\d)$/," $100"); // +09 -> +0900 126 | return new Date(s); 127 | }, 128 | datetime: function(elem) { 129 | var iso8601 = $t.isTime(elem) ? $(elem).attr("datetime") : $(elem).attr("title"); 130 | return $t.parse(iso8601); 131 | }, 132 | isTime: function(elem) { 133 | // jQuery's `is()` doesn't play well with HTML5 in IE 134 | return $(elem).get(0).tagName.toLowerCase() === "time"; // $(elem).is("time"); 135 | } 136 | }); 137 | 138 | // functions that can be called via $(el).timeago('action') 139 | // init is default when no action is given 140 | // functions are called with context of a single element 141 | var functions = { 142 | init: function() { 143 | functions.dispose.call(this); 144 | var refresh_el = $.proxy(refresh, this); 145 | refresh_el(); 146 | var $s = $t.settings; 147 | if ($s.refreshMillis > 0) { 148 | this._timeagoInterval = setInterval(refresh_el, $s.refreshMillis); 149 | } 150 | }, 151 | update: function(timestamp) { 152 | var date = (timestamp instanceof Date) ? timestamp : $t.parse(timestamp); 153 | $(this).data('timeago', { datetime: date }); 154 | if ($t.settings.localeTitle) { 155 | $(this).attr("title", date.toLocaleString()); 156 | } 157 | refresh.apply(this); 158 | }, 159 | updateFromDOM: function() { 160 | $(this).data('timeago', { datetime: $t.parse( $t.isTime(this) ? $(this).attr("datetime") : $(this).attr("title") ) }); 161 | refresh.apply(this); 162 | }, 163 | dispose: function () { 164 | if (this._timeagoInterval) { 165 | window.clearInterval(this._timeagoInterval); 166 | this._timeagoInterval = null; 167 | } 168 | } 169 | }; 170 | 171 | $.fn.timeago = function(action, options) { 172 | var fn = action ? functions[action] : functions.init; 173 | if (!fn) { 174 | throw new Error("Unknown function name '"+ action +"' for timeago"); 175 | } 176 | // each over objects here and call the requested function 177 | this.each(function() { 178 | fn.call(this, options); 179 | }); 180 | return this; 181 | }; 182 | 183 | function refresh() { 184 | var $s = $t.settings; 185 | 186 | //check if it's still visible 187 | if ($s.autoDispose && !$.contains(document.documentElement,this)) { 188 | //stop if it has been removed 189 | $(this).timeago("dispose"); 190 | return this; 191 | } 192 | 193 | var data = prepareData(this); 194 | 195 | if (!isNaN(data.datetime)) { 196 | if ( $s.cutoff === 0 || Math.abs(distance(data.datetime)) < $s.cutoff) { 197 | $(this).text(inWords(data.datetime)); 198 | } else { 199 | if ($(this).attr('title').length > 0) { 200 | $(this).text($(this).attr('title')); 201 | } 202 | } 203 | } 204 | return this; 205 | } 206 | 207 | function prepareData(element) { 208 | element = $(element); 209 | if (!element.data("timeago")) { 210 | element.data("timeago", { datetime: $t.datetime(element) }); 211 | var text = $.trim(element.text()); 212 | if ($t.settings.localeTitle) { 213 | element.attr("title", element.data('timeago').datetime.toLocaleString()); 214 | } else if (text.length > 0 && !($t.isTime(element) && element.attr("title"))) { 215 | element.attr("title", text); 216 | } 217 | } 218 | return element.data("timeago"); 219 | } 220 | 221 | function inWords(date) { 222 | return $t.inWords(distance(date)); 223 | } 224 | 225 | function distance(date) { 226 | return (new Date().getTime() - date.getTime()); 227 | } 228 | 229 | // fix for IE6 suckage 230 | document.createElement("abbr"); 231 | document.createElement("time"); 232 | })); 233 | -------------------------------------------------------------------------------- /views/index.hbs: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

Segue as tuas encomendas até Portugal

5 |

Este website ajuda-te a saber por onde andam as tuas encomendas.

6 | Métodos de envio suportados: 7 |
8 |
9 | Gearbest 10 |
    11 |
  • PQ Spain Priority Line (Spain Express)
  • 12 |
  • NL Netherlands Post surface mail
  • 13 |
  • LV Bpost International
  • 14 |
  • SYB Malasya Pos
  • 15 |
  • GE e SB Switzerland Post Unregistered
  • 16 |
  • Q..XX Sweden Registered
  • 17 |
  • R..HU Hungary Registered Mail
  • 18 |
  • ID númerico DHL
  • 19 |
20 | 21 | Geekbuying 22 |
    23 |
  • YT.. Yun Express
  • 24 |
  • R..AT Austrian Post
  • 25 |
26 | 27 | Amazon 28 |
    29 |
  • ID númerico MRW
  • 30 |
31 |
32 |
33 | AliExpress 34 |
    35 |
  • R..SG Singapore Post
  • 36 |
  • R..MY Malaysia Post
  • 37 |
  • R..SE Sweden Post
  • 38 |
  • R..CN China Post Register Airmail
  • 39 |
  • R..NL Netherlands Post
  • 40 |
  • L..CN China EMS ePacket
  • 41 |
  • U..YP Special Line YW
  • 42 |
  • LP.. AliExpress Standard Shipping
  • 43 |
  • BZ..CN China EMS ePacket
  • 44 |
  • CP..CN China Post
  • 45 |
  • AA..YN Yanwen
  • 46 |
  • R..LA Laos Post
  • 47 |
  • ID númerico China Post Small Packet, Yanwen e DHL
  • 48 |
49 |
50 |
51 | CTT Expresso 52 |
    53 |
  • ED123456789PT
  • 54 |
  • LX123456789PT
  • 55 |
  • RR123456789PT
  • 56 |
  • DA123456789PT
  • 57 |
58 | 59 | Ebay 60 |
    61 |
  • ID..CN Winit
  • 62 |
  • YF.. Yanwen
  • 63 |
  • UPA.. Pitney Bowes
  • 64 |
  • LA.. Laos Post
  • 65 |
  • HK..AM SFC
  • 66 |
  • EY.. Chukou1
  • 67 |
  • R..GB Royal Mail
  • 68 |
  • A.. DHT
  • 69 |
  • U..SE Sweden Post
  • 70 |
  • KWT.. KWT
  • 71 |
  • R..IN India Post
  • 72 |
  • ID númerico PTT Turkey
  • 73 |
74 |
75 |
76 | 77 | Esconder 78 |
79 |
80 |
81 | 82 |
83 |
84 | 85 |
86 |
Encomendas a seguir 87 |
88 | Adicionar 89 | 90 |
91 |
92 |
    93 |
  • 94 | Nenhuma.. 95 |
  • 96 |
97 |
98 |
99 | 100 |
101 |
102 |
103 |
104 |
105 | Informações das encomendas 106 |
107 |
108 |

Para veres a informação sobre as tuas encomendas adiciona primeiro os teus IDs, no painel Encomendas a seguir.

109 |

Se não tiveres nenhuma encomenda podes ver como funciona com este id: PQ4F6P0705248940181750G

110 |
111 |
112 |
113 |
114 |
115 |
116 | 117 | 118 | 150 | 151 | 152 | 153 | 168 | 169 | 170 | 171 | 199 | 200 | 201 | {{> skyTemplate }} 202 | 203 | {{> correosTemplate }} 204 | 205 | {{> correosOldTemplate }} 206 | 207 | {{> adicionalTemplate }} 208 | 209 | {{> expresso24Template }} 210 | 211 | {{> cttTemplate }} 212 | 213 | {{> aliTemplate }} 214 | 215 | {{> cainiaoEmpty }} 216 | 217 | 218 | 232 | 233 | 234 | {{#append 'scripts'}} 235 | 236 | {{/append}} 237 | -------------------------------------------------------------------------------- /views/faqs.hbs: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 | 6 | 7 |
Spain Priority Line
8 |
9 | 16 |
17 |
18 |

Pode levar entre 3 a 15 dias até aparecer a mensagem "Information sent to Spain", o mais comum é demorar uma semana (7 dias).

19 |
20 |
21 |
22 | 23 |
24 | 31 |
32 |
33 |

A partir do momento em que aparece a mensagem "Information sent to Spain", pode levar entre 1 e 15 dias a aparecer o estado "Admitido".

34 |

O mais comum é demorar uma semana (7 dias).

35 |

A informação do Correos Express costuma aparecer um dia depois do estado passar a "Admitido", poderá demorar mais tempo em épocas altas.

36 |
37 |
38 |
39 | 40 |
41 | 48 |
49 |
50 |

Pode levar entre 3 a 15 dias, vai depender do tempo que a Correos demore a passar a encomenda à Adicional e o tempo que a Adicional demore a entregar.

51 |

O mais comum é demorar uma semana (7 dias).

52 |
53 |
54 |
55 | 56 |
57 | 64 |
65 |
66 |

No melhor dos casos pode ser entregue em duas semanas (ou até menos), em epócas altas como o natal pode demorar até um mês (ou mais).

67 |

O mais comum é demorar 3 semanas a ser entregue.

68 |
69 |
70 |
71 | 72 |
73 | 80 |
81 |
82 |

Usando o método de envio Spain priority line (Spain Express) a sua encomenda não passa pela alfândega.

83 |
84 |
85 |
86 | 87 |
88 | 95 |
96 |
97 |

Todas as encomendas que fiz chegaram sempre sem problemas, mas para quem é mais impaciente:

98 | 104 |
105 |
106 |
107 | 108 | 109 | 110 |
Outros
111 |
112 | 119 |
120 |
121 | 135 |
136 |

Deverá obter o Shippment number, é algo assim: PQ4F6P2342340181150W

137 |
138 |
139 |
140 | 141 |
142 | 149 |
150 |
151 |
    152 |
  • Ainda não existe informação nos sites de rastreamento da encomenda.
  • 153 |
      154 |
    • Depois de efectuar a encomenda pode demorar alguns dias até à Gearbest enviar a mesma. (Recebe um email a dizer quando a encomenda foi dispatched, e mesmo depois de estar dispatched ainda pode demorar algum tempo até haver informações de envio) Aguarde uns dias. 155 |
    • 156 |
    • O site da empresa de rastreamente pode estar offline (pouco provavel)
    • 157 |
    158 |
  • O id introduzido está incorrecto, confirme se está certo.
  • 159 |
  • O Geartrack pode não ter conseguido obter a informação nesse instante, aguarde 10 min até a cache do Geartrack expirar e experimente novamente. (Situação pouco provavel)
  • 160 |
161 |
162 |
163 |
164 | 165 |
166 | 173 |
174 |
175 |
    176 |
  • Usando o Chrome:
  • 177 | 178 |
179 |
180 |
181 |
182 | 183 |
184 | 191 |
192 |
193 |

As datas apresentadas são as que os sites onde vamos obter informação mostram.

194 |

Essas datas poderão estar no futuro ou no passado consoante o fuso horário desse país.

195 |

As diferenças serão no máximo 12 horas para os países de origem.

196 |
197 |
198 |
199 | 200 |
201 | 202 | 205 | 206 |
207 |
208 | -------------------------------------------------------------------------------- /views/news.hbs: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
6 | Notícias 7 |
8 |
    9 |
  • 10 |
    11 |
    12 | 13 | 14 | 15 |
    16 |
    17 |

    Adicionado dados da Malasya Pos (além do Sky56) para ids da Gearbest GEG...

    18 |
    19 |
    20 |
  • 21 |
  • 22 |
    23 |
    24 | 25 | 26 | 27 |
    28 |
    29 |

    Dados da Adicional novamente online!

    30 |

    Caso tenhas recebido a encomenda pela Expresso24 entra em contacto connosco!

    31 |
    32 |
    33 |
  • 34 |
  • 35 |
    36 |
    37 | 38 | 39 | 40 |
    41 |
    42 |

    Adicionado suporte para ids do tipo TH.. do Gearbest.

    43 |
    44 |
    45 |
  • 46 |
  • 47 |
    48 |
    49 | 50 | 51 | 52 |
    53 |
    54 |

    Tempo de cache alterado para 30 minutos. Agora sempre que um tracker retorne dados, esses dados são guardados por 30 minutos antes de irmos buscar novos dados (Estávamos a sobrecarregar alguns servidores).

    55 |

    Adicionado suporte para 17track em alguns ids.

    56 |

    A partir de agora aceitamos todo o tipo de ids, usamos o 17track e o track24 para ir buscar informação. Caso um id esteja associado a um tracker errado fala connosco para corrigirmos!

    57 |
    58 |
    59 |
  • 60 |
  • 61 |
    62 |
    63 | 64 | 65 | 66 |
    67 |
    68 |

    Adicionado suporte para a transportadora MRW usada nas encomendas da Amazon. Ids numéricos.

    69 |

    Adicionado suporte para India Post R..IN usado pelo Ebay.

    70 |
    71 |
    72 |
  • 73 |
  • 74 |
    75 |
    76 | 77 | 78 | 79 |
    80 |
    81 |

    Adicionado suporte para ID's do tipo R..DE do AliExpress. Por agora só mostra informação dos CTT.

    82 |
    83 |
    84 |
  • 85 |
  • 86 |
    87 |
    88 | 89 | 90 | 91 |
    92 |
    93 |

    Adicionado suporte para ID's do tipo R..LA Laos Post do AliExpress.

    94 |
    95 |
    96 |
  • 97 |
  • 98 |
    99 |
    100 | 101 | 102 | 103 |
    104 |
    105 |

    Adicionado suporte para ID's do tipo U..SE Sweden Post do Ebay.

    106 |

    Adicionado suporte para ID's do tipo KWT.. do Ebay.

    107 |
    108 |
    109 |
  • 110 |
  • 111 |
    112 |
    113 | 114 | 115 | 116 |
    117 |
    118 |

    Adicionado suporte para ID's do tipo A.. do Ebay.

    119 |
    120 |
    121 |
  • 122 |
  • 123 |
    124 |
    125 | 126 | 127 | 128 |
    129 |
    130 |

    Adicionado suporte para ID's do tipo AA..YN do AliExpress.

    131 |
    132 |
    133 |
  • 134 |
  • 135 |
    136 |
    137 | 138 | 139 | 140 |
    141 |
    142 |

    Adicionado suporte para ID's do tipo YT.. do Geekbuying.

    143 |

    Adicionado suporte para ID's do tipo LA.. do Ebay.

    144 |

    Adicionado suporte para ID's do tipo HK..AM do Ebay.

    145 |

    Adicionado suporte para ID's do tipo EY.. do Ebay.

    146 |

    Adicionado suporte para ID's do tipo R..GB do Ebay.

    147 |

    Adicionado suporte para ID's numéricos do método de envio Ptt Turkey do Ebay.

    148 |
    149 |
    150 |
  • 151 |
  • 152 |
    153 |
    154 | 155 | 156 | 157 |
    158 |
    159 |

    Adicionado suporte para o tipo de Id's UPA.. do Ebay.

    160 |

    Adicionado suporte para o tipo de Id's BZ..CN do AliExpress.

    161 |

    Adicionado suporte para o tipo de Id's CP..CN do AliExpress.

    162 |

    Adicionado suporte para o tracker DHL, aceita ids numéricos (Usado em encomendas do Gearbest PT).

    163 |

    Suporte inicial para ids da Gearbest R..HU e R..AT.

    164 |
    165 |
    166 |
  • 167 |
  • 168 |
    169 |
    170 | 171 | 172 | 173 |
    174 |
    175 |

    Adicionado suporte para o tipo de Id's YF.. do Ebay!

    176 |
    177 |
    178 |
  • 179 |
  • 180 |
    181 |
    182 | 183 | 184 | 185 |
    186 |
    187 |

    Adicionado suporte para o tipo de Id's ID..CN do Ebay!

    188 |

    Adicionado suporte para Id's dos CTT Expresso E..PT, R..PT e L..PT.

    189 |

    Agora é apresentada informação do Panasia para encomendas Priority Line, pois parece que o Sky56 foi substituído.

    190 |

    Novo domínio .pt: https://geartrack.pt. Este novo domínio vai passar a ser o principal quando introduzirmos os registos!
    Começa já a usar! (É preciso introduzir os ids a seguir de novo)

    191 |

    Agora todos os trackers contêm o seu link no lado direito!

    192 |
    193 |
    194 |
  • 195 |
  • 196 |
    197 |
    198 | 199 | 200 | 201 |
    202 |
    203 |

    Adicionado suporte para o tipo de Id's S000011754755.

    204 |

    É apresentada informação do tracker Cainiao.

    205 |
    206 |
    207 |
  • 208 |
  • 209 |
    210 |
    211 | 212 | 213 | 214 |
    215 |
    216 |

    Trocado o tracking para ids do tipo R..MY da Malasya Pos para o original. Pois 217 | o Cainiao estava a precisar de interação.

    218 |

    Adicionado mais um tracker para ids do tipo SB.. da Switzerland Post Unregistered.

    219 |
    220 |
    221 |
  • 222 |
  • 223 |
    224 |
    225 | 226 | 227 | 228 |
    229 |
    230 |

    Adicionado suporte para o método de envio Sweden Registered da Gearbest - 231 | Q..XX 232 |

    233 |
    234 |
    235 |
  • 236 |
  • 237 |
    238 |
    239 | 240 | 241 | 242 |
    243 |
    244 |

    Adicionado suporte para o método de envio AliExpress Standard Shipping - 245 | LP..

    246 |

    Adicionado suporte para o método de envio AliExpress Special Line YW - 247 | U..YP

    248 |

    Ambos mostram informações do provedor Yanwen se existir e Cainiao.

    249 |
    250 |
    251 |
  • 252 |
  • 253 |
    254 |
    255 | 256 | 257 | 258 |
    259 |
    260 |

    Arranjámos forma de aceder à informação antiga do Correos Express de novo.

    261 |

    Apresentamos os dados da versão antiga e nova do Correos Express.

    262 |

    Dados da Adicional e Expresso24 novamente disponíveis.

    263 |
    264 |
    265 |
  • 266 |
  • 267 |
    268 |
    269 | 270 | 271 | 272 |
    273 |
    274 |

    Adicionado suporte para o método de envio China EMS ePacket do AliExpress L..CN.

    275 |
      276 |
    • Mostra informação dos CTT e Cainiao
    • 277 |
    278 |

    Os Correos Express têm um novo design! Neste momento não estão a fornecer os IDs para consultarmos a informação na adicional e expresso24.

    279 |

    Enquanto eles não disponibilizarem de novo essa informação, nada podemos fazer. Tentem contactá-los para se sentirem obrigados a adicionar de novo essa informação.

    280 |
    281 |
    282 |
  • 283 |
  • 284 |
    285 |
    286 | 287 | 288 | 289 |
    290 |
    291 |

    Adicionado suporte para o método de envio Netherlands Post do AliExpress R..NL.

    292 |
      293 |
    • Mostra informação dos CTT e Post NL
    • 294 |
    295 | 296 |
    297 |
    298 |
  • 299 |
  • 300 |
    301 |
    302 | 303 | 304 | 305 |
    306 |
    307 |

    Adicionado suporte para o método de envio China Post do AliExpress R..CN.

    308 |
      309 |
    • Mostra informação dos CTT e Track China Post
    • 310 |
    311 |

    Adicionado suporte para o método de envio China Post do AliExpress ID numérico.

    312 |
      313 |
    • Apenas informação do Track China Post disponível.
    • 314 |
    315 |

    Adicionado suporte também para o método de envio via Sweden do AliExpress R..SE.

    316 |
      317 |
    • Mostra informação dos CTT e Direct Link.
    • 318 |
    319 |
    320 |
    321 |
  • 322 |
  • 323 |
    324 |
    325 | 326 | 327 | 328 |
    329 |
    330 |

    Adicionada informação proveniente do Correos.es para o método de envio Priority Line.

    331 | 332 |
    333 |
    334 |
  • 335 |
  • 336 |
    337 |
    338 | 339 | 340 | 341 |
    342 |
    343 |

    Novo visual: A maneira de apresentação dos estados e mensagens está renovada.

    344 |

    Início do suporte para Ids do tipo R..SG e R..MY do Aliexpress.

    345 |

    É apresentada informação do CTT e Singpost para ids de Singapura e Cainiao para ids da Malásia.

    346 |

    Funcionalidade de registo a caminho.

    347 |

    Nova página de Facebook, mete já like!

    348 |
    349 |
    350 |
  • 351 |
  • 352 |
    353 |
    354 | 355 | 356 | 357 |
    358 |
    359 |

    Adicionada FAQ: Como adicionar um atalho ao Home screen no Android?

    360 |
    361 |
    362 |
  • 363 |
  • 364 |
    365 |
    366 | 367 | 368 | 369 |
    370 |
    371 |

    Adicionado suporte para ids do tipo SB3000023412

    372 |

    Apenas o site Sky56 é usado para obter estas informações.

    373 |
    374 |
    375 |
  • 376 |
  • 377 |
    378 |
    379 | 380 | 381 | 382 |
    383 |
    384 |

    Adicionado suporte para Switzerland Post Unregistered

    385 |

    Já podes fazer track de ids do tipo: GEGMY00023153

    386 |

    Apenas o site Sky56 é usado para obter estas informações.

    387 |

    Uma nova versão do Geartrack está em construção, vai ter suporte a notificações quando ocorre alterações no estado das encomendas e mais novidades.

    388 |
    389 |
    390 |
  • 391 |
  • 392 |
    393 |
    394 | 395 | 396 | 397 |
    398 |
    399 |

    Adicionado suporte para Malasya Pos

    400 |

    Já podes fazer track de ids do tipo: SYBPL3435312

    401 |

    Apenas o site Sky56 é usado para obter estas informações.

    402 |
    403 |
    404 |
  • 405 |
  • 406 |
    407 |
    408 | 409 | 410 | 411 |
    412 |
    413 |

    Adicionada informação da Expresso24, pois parece que a Correos Express anda a usar esta empresa para algumas encomendas em vez da Adicional.

    414 |
    415 |
    416 |
  • 417 |
  • 418 |
    419 |
    420 | 421 | 422 | 423 |
    424 |
    425 |

    Adicionada nova página com 426 | perguntas frequentes.

    427 |

    Página 428 | Sobre também foi atualizada.

    429 |
    430 |
    431 |
  • 432 |
  • 433 |
    434 |
    435 | 436 | 437 | 438 |
    439 |
    440 |

    Adicionado suporte para o método de envio Bpost International.

    441 |

    Já podes fazer track de ids do tipo: LVS236700681531

    442 |

    Apenas o site Sky56 é usado para obter estas informações.

    443 |

    Sugestões de novos métodos de envio é só enviar email.

    444 |
    445 |
    446 |
  • 447 |
  • 448 |
    449 |
    450 | 451 | 452 | 453 |
    454 |
    455 |

    Adicionado suporte para o método de envio Netherlands 456 | Post surface mail.

    457 |

    Já podes fazer track de ids do tipo: NL14812456123607

    458 |

    Apenas o site Sky56 é usado para obter estas informações.

    459 |
    460 |
    461 |
  • 462 |
463 |
464 | 465 |
466 |
467 | 468 | {{#append 'scripts'}} 469 | 470 | 490 | {{/append}} 491 | -------------------------------------------------------------------------------- /public/js/vendor/moment-timezone-with-data-2010-2020.min.js: -------------------------------------------------------------------------------- 1 | //! moment-timezone.js 2 | //! version : 0.5.10 3 | //! Copyright (c) JS Foundation and other contributors 4 | //! license : MIT 5 | //! github.com/moment/moment-timezone 6 | !function(a,b){"use strict";"function"==typeof define&&define.amd?define(["moment"],b):"object"==typeof module&&module.exports?module.exports=b(require("moment")):b(a.moment)}(this,function(a){"use strict";function b(a){return a>96?a-87:a>64?a-29:a-48}function c(a){var c,d=0,e=a.split("."),f=e[0],g=e[1]||"",h=1,i=0,j=1;for(45===a.charCodeAt(0)&&(d=1,j=-1),d;d0?k[0].zone.name:void 0}function q(a){return D&&!a||(D=p()),D}function r(a){return(a||"").toLowerCase().replace(/\//g,"_")}function s(a){var b,c,d,e;for("string"==typeof a&&(a=[a]),b=0;b= 2.6.0. You are using Moment.js "+a.version+". See momentjs.com"),h.prototype={_set:function(a){this.name=a.name,this.abbrs=a.abbrs,this.untils=a.untils,this.offsets=a.offsets,this.population=a.population},_index:function(a){var b,c=+a,d=this.untils;for(b=0;bd&&A.moveInvalidForward&&(b=d),f= 2.9.0. You are using Moment.js "+a.version+"."),a.defaultZone=b?t(b):null,a};var N=a.momentProperties;return"[object Array]"===Object.prototype.toString.call(N)?(N.push("_z"),N.push("_a")):N&&(N._z=null),w({version:"2016j",zones:["Africa/Abidjan|GMT|0|0||48e5","Africa/Khartoum|EAT|-30|0||51e5","Africa/Algiers|CET|-10|0||26e5","Africa/Lagos|WAT|-10|0||17e6","Africa/Maputo|CAT|-20|0||26e5","Africa/Cairo|EET EEST|-20 -30|010101010|1Cby0 Fb0 c10 8n0 8Nd0 gL0 e10 mn0|15e6","Africa/Casablanca|WET WEST|0 -10|01010101010101010101010101010101010101010|1Cco0 Db0 1zd0 Lz0 1Nf0 wM0 co0 go0 1o00 s00 dA0 vc0 11A0 A00 e00 y00 11A0 uM0 e00 Dc0 11A0 s00 e00 IM0 WM0 mo0 gM0 LA0 WM0 jA0 e00 Rc0 11A0 e00 e00 U00 11A0 8o0 e00 11A0|32e5","Europe/Paris|CET CEST|-10 -20|01010101010101010101010|1BWp0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|11e6","Africa/Johannesburg|SAST|-20|0||84e5","Africa/Tripoli|EET CET CEST|-20 -10 -20|0120|1IlA0 TA0 1o00|11e5","Africa/Windhoek|WAST WAT|-20 -10|01010101010101010101010|1C1c0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0|32e4","America/Adak|HST HDT|a0 90|01010101010101010101010|1BR00 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|326","America/Anchorage|AKST AKDT|90 80|01010101010101010101010|1BQX0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|30e4","America/Santo_Domingo|AST|40|0||29e5","America/Araguaina|BRT BRST|30 20|010|1IdD0 Lz0|14e4","America/Argentina/Buenos_Aires|ART|30|0|","America/Asuncion|PYST PYT|30 40|01010101010101010101010|1C430 1a10 1fz0 1a10 1fz0 1cN0 17b0 1ip0 17b0 1ip0 17b0 1ip0 19X0 1fB0 19X0 1fB0 19X0 1ip0 17b0 1ip0 17b0 1ip0|28e5","America/Panama|EST|50|0||15e5","America/Bahia|BRT BRST|30 20|010|1FJf0 Rb0|27e5","America/Bahia_Banderas|MST CDT CST|70 50 60|01212121212121212121212|1C1l0 1nW0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0|84e3","America/Fortaleza|BRT|30|0||34e5","America/Managua|CST|60|0||22e5","America/Manaus|AMT|40|0||19e5","America/Bogota|COT|50|0||90e5","America/Denver|MST MDT|70 60|01010101010101010101010|1BQV0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|26e5","America/Campo_Grande|AMST AMT|30 40|01010101010101010101010|1BIr0 1zd0 On0 1zd0 Rb0 1zd0 Lz0 1C10 Lz0 1C10 On0 1zd0 On0 1zd0 On0 1zd0 On0 1C10 Lz0 1C10 Lz0 1C10|77e4","America/Cancun|CST CDT EST|60 50 50|010101010102|1C1k0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 Dd0|63e4","America/Caracas|VET VET|4u 40|01|1QMT0|29e5","America/Cayenne|GFT|30|0||58e3","America/Chicago|CST CDT|60 50|01010101010101010101010|1BQU0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|92e5","America/Chihuahua|MST MDT|70 60|01010101010101010101010|1C1l0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0|81e4","America/Phoenix|MST|70|0||42e5","America/Los_Angeles|PST PDT|80 70|01010101010101010101010|1BQW0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|15e6","America/New_York|EST EDT|50 40|01010101010101010101010|1BQT0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|21e6","America/Rio_Branco|AMT ACT|40 50|01|1KLE0|31e4","America/Fort_Nelson|PST PDT MST|80 70 70|010101010102|1BQW0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0|39e2","America/Halifax|AST ADT|40 30|01010101010101010101010|1BQS0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|39e4","America/Godthab|WGT WGST|30 20|01010101010101010101010|1BWp0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|17e3","America/Goose_Bay|AST ADT|40 30|01010101010101010101010|1BQQ1 1zb0 Op0 1zcX Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|76e2","America/Grand_Turk|EST EDT AST|50 40 40|0101010101012|1BQT0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|37e2","America/Guayaquil|ECT|50|0||27e5","America/Guyana|GYT|40|0||80e4","America/Havana|CST CDT|50 40|01010101010101010101010|1BQR0 1wo0 U00 1zc0 U00 1qM0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0|21e5","America/La_Paz|BOT|40|0||19e5","America/Lima|PET|50|0||11e6","America/Mexico_City|CST CDT|60 50|01010101010101010101010|1C1k0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0|20e6","America/Metlakatla|PST AKST AKDT|80 90 80|012121212121|1PAa0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|14e2","America/Miquelon|PMST PMDT|30 20|01010101010101010101010|1BQR0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|61e2","America/Montevideo|UYST UYT|20 30|010101010101|1BQQ0 1ld0 14n0 1ld0 14n0 1o10 11z0 1o10 11z0 1o10 11z0|17e5","America/Noronha|FNT|20|0||30e2","America/North_Dakota/Beulah|MST MDT CST CDT|70 60 60 50|01232323232323232323232|1BQV0 1zb0 Oo0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0","America/Paramaribo|SRT|30|0||24e4","America/Port-au-Prince|EST EDT|50 40|010101010|1GI70 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|23e5","America/Santiago|CLST CLT|30 40|010101010101010101010|1C1f0 1fB0 1nX0 G10 1EL0 Op0 1zb0 Rd0 1wn0 Rd0 46n0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Ap0|62e5","America/Sao_Paulo|BRST BRT|20 30|01010101010101010101010|1BIq0 1zd0 On0 1zd0 Rb0 1zd0 Lz0 1C10 Lz0 1C10 On0 1zd0 On0 1zd0 On0 1zd0 On0 1C10 Lz0 1C10 Lz0 1C10|20e6","America/Scoresbysund|EGT EGST|10 0|01010101010101010101010|1BWp0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|452","America/St_Johns|NST NDT|3u 2u|01010101010101010101010|1BQPv 1zb0 Op0 1zcX Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|11e4","Antarctica/Casey|+11 +08|-b0 -80|01010|1BN30 40P0 KL0 blz0|10","Antarctica/Davis|+05 +07|-50 -70|0101|1BPw0 3Wn0 KN0|70","Antarctica/DumontDUrville|+10|-a0|0||80","Antarctica/Macquarie|AEDT MIST|-b0 -b0|01|1C140|1","Asia/Tashkent|+05|-50|0||23e5","Pacific/Auckland|NZDT NZST|-d0 -c0|01010101010101010101010|1C120 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00|14e5","Antarctica/Rothera|-03|30|0||130","Antarctica/Syowa|+03|-30|0||20","Antarctica/Troll|+00 +02|0 -20|01010101010101010101010|1BWp0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|40","Asia/Almaty|+06|-60|0||15e5","Asia/Baghdad|AST|-30|0||66e5","Asia/Amman|EET EEST|-20 -30|010101010101010101010|1BVy0 1qM0 11A0 1o00 11A0 4bX0 Dd0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0|25e5","Asia/Kamchatka|+12 +11|-c0 -b0|010|1Dp30 WM0|18e4","Asia/Baku|+04 +05|-40 -50|0101010101010|1BWo0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|27e5","Asia/Bangkok|ICT|-70|0||15e6","Asia/Barnaul|+06 +07|-60 -70|010101|1BWk0 1qM0 WM0 8Hz0 3rd0","Asia/Beirut|EET EEST|-20 -30|01010101010101010101010|1BWm0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0|22e5","Asia/Brunei|BNT|-80|0||42e4","Asia/Kolkata|IST|-5u|0||15e6","Asia/Chita|+09 +10 +08|-90 -a0 -80|010120|1BWh0 1qM0 WM0 8Hz0 3re0|33e4","Asia/Choibalsan|CHOT CHOST|-80 -90|0101010101010|1O8G0 1cJ0 1cP0 1cJ0 1cP0 1fx0 1cP0 1cJ0 1cP0 1cJ0 1cP0 1cJ0|38e3","Asia/Shanghai|CST|-80|0||23e6","Asia/Colombo|+0530|-5u|0||22e5","Asia/Dhaka|BDT|-60|0||16e6","Asia/Damascus|EET EEST|-20 -30|01010101010101010101010|1C0m0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0|26e5","Asia/Dili|TLT|-90|0||19e4","Asia/Dubai|GST|-40|0||39e5","Asia/Famagusta|EET EEST +03|-20 -30 -30|010101010101012|1BWp0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 15U0","Asia/Gaza|EET EEST|-20 -30|01010101010101010101010|1BVW1 SKX 1xd1 MKX 1AN0 1a00 1fA0 1cL0 1cN0 1nX0 1210 1nz0 1220 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0|18e5","Asia/Hebron|EET EEST|-20 -30|0101010101010101010101010|1BVy0 Tb0 1xd1 MKX bB0 cn0 1cN0 1a00 1fA0 1cL0 1cN0 1nX0 1210 1nz0 1220 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0|25e4","Asia/Hong_Kong|HKT|-80|0||73e5","Asia/Hovd|HOVT HOVST|-70 -80|0101010101010|1O8H0 1cJ0 1cP0 1cJ0 1cP0 1fx0 1cP0 1cJ0 1cP0 1cJ0 1cP0 1cJ0|81e3","Asia/Irkutsk|+08 +09|-80 -90|01010|1BWi0 1qM0 WM0 8Hz0|60e4","Europe/Istanbul|EET EEST +03|-20 -30 -30|010101010101012|1BWp0 1qM0 Xc0 1qo0 WM0 1qM0 11A0 1o00 1200 1nA0 11A0 1tA0 U00 15w0|13e6","Asia/Jakarta|WIB|-70|0||31e6","Asia/Jayapura|WIT|-90|0||26e4","Asia/Jerusalem|IST IDT|-20 -30|01010101010101010101010|1BVA0 17X0 1kp0 1dz0 1c10 1aL0 1eN0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0|81e4","Asia/Kabul|AFT|-4u|0||46e5","Asia/Karachi|PKT|-50|0||24e6","Asia/Urumqi|XJT|-60|0||32e5","Asia/Kathmandu|NPT|-5J|0||12e5","Asia/Khandyga|+10 +11 +09|-a0 -b0 -90|010102|1BWg0 1qM0 WM0 17V0 7zD0|66e2","Asia/Krasnoyarsk|+07 +08|-70 -80|01010|1BWj0 1qM0 WM0 8Hz0|10e5","Asia/Kuala_Lumpur|MYT|-80|0||71e5","Asia/Magadan|+11 +12 +10|-b0 -c0 -a0|010120|1BWf0 1qM0 WM0 8Hz0 3Cq0|95e3","Asia/Makassar|WITA|-80|0||15e5","Asia/Manila|PHT|-80|0||24e6","Europe/Athens|EET EEST|-20 -30|01010101010101010101010|1BWp0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|35e5","Asia/Novokuznetsk|+07 +06|-70 -60|010|1Dp80 WM0|55e4","Asia/Novosibirsk|+06 +07|-60 -70|010101|1BWk0 1qM0 WM0 8Hz0 4eN0|15e5","Asia/Omsk|+06 +07|-60 -70|01010|1BWk0 1qM0 WM0 8Hz0|12e5","Asia/Pyongyang|KST KST|-90 -8u|01|1P4D0|29e5","Asia/Rangoon|MMT|-6u|0||48e5","Asia/Sakhalin|+10 +11|-a0 -b0|010101|1BWg0 1qM0 WM0 8Hz0 3rd0|58e4","Asia/Seoul|KST|-90|0||23e6","Asia/Singapore|SGT|-80|0||56e5","Asia/Srednekolymsk|+11 +12|-b0 -c0|01010|1BWf0 1qM0 WM0 8Hz0|35e2","Asia/Tbilisi|+04|-40|0||11e5","Asia/Tehran|IRST IRDT|-3u -4u|01010101010101010101010|1BTUu 1dz0 1cp0 1dz0 1cp0 1dz0 1cN0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cN0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0|14e6","Asia/Thimphu|BTT|-60|0||79e3","Asia/Tokyo|JST|-90|0||38e6","Asia/Tomsk|+06 +07|-60 -70|010101|1BWk0 1qM0 WM0 8Hz0 3Qp0|10e5","Asia/Ulaanbaatar|ULAT ULAST|-80 -90|0101010101010|1O8G0 1cJ0 1cP0 1cJ0 1cP0 1fx0 1cP0 1cJ0 1cP0 1cJ0 1cP0 1cJ0|12e5","Asia/Ust-Nera|+11 +12 +10|-b0 -c0 -a0|010102|1BWf0 1qM0 WM0 17V0 7zD0|65e2","Asia/Vladivostok|+10 +11|-a0 -b0|01010|1BWg0 1qM0 WM0 8Hz0|60e4","Asia/Yakutsk|+09 +10|-90 -a0|01010|1BWh0 1qM0 WM0 8Hz0|28e4","Asia/Yekaterinburg|+05 +06|-50 -60|01010|1BWl0 1qM0 WM0 8Hz0|14e5","Asia/Yerevan|+04 +05|-40 -50|01010|1BWm0 1qM0 WM0 1qM0|13e5","Atlantic/Azores|AZOT AZOST|10 0|01010101010101010101010|1BWp0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|25e4","Europe/Lisbon|WET WEST|0 -10|01010101010101010101010|1BWp0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|27e5","Atlantic/Cape_Verde|CVT|10|0||50e4","Atlantic/South_Georgia|GST|20|0||30","Atlantic/Stanley|FKST FKT|30 40|010|1C6R0 U10|21e2","Australia/Sydney|AEDT AEST|-b0 -a0|01010101010101010101010|1C140 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0|40e5","Australia/Adelaide|ACDT ACST|-au -9u|01010101010101010101010|1C14u 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0|11e5","Australia/Brisbane|AEST|-a0|0||20e5","Australia/Darwin|ACST|-9u|0||12e4","Australia/Eucla|ACWST|-8J|0||368","Australia/Lord_Howe|LHDT LHST|-b0 -au|01010101010101010101010|1C130 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu|347","Australia/Perth|AWST|-80|0||18e5","Pacific/Easter|EASST EAST|50 60|010101010101010101010|1C1f0 1fB0 1nX0 G10 1EL0 Op0 1zb0 Rd0 1wn0 Rd0 46n0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Ap0|30e2","Europe/Dublin|GMT IST|0 -10|01010101010101010101010|1BWp0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|12e5","Etc/GMT+1|-01|10|0|","Etc/GMT+10|-10|a0|0|","Etc/GMT+11|-11|b0|0|","Etc/GMT+12|-12|c0|0|","Etc/GMT+2|-02|20|0|","Etc/GMT+4|-04|40|0|","Etc/GMT+5|-05|50|0|","Etc/GMT+6|-06|60|0|","Etc/GMT+7|-07|70|0|","Etc/GMT+8|-08|80|0|","Etc/GMT+9|-09|90|0|","Etc/GMT-1|+01|-10|0|","Etc/GMT-11|+11|-b0|0|","Etc/GMT-12|+12|-c0|0|","Etc/GMT-13|+13|-d0|0|","Etc/GMT-14|+14|-e0|0|","Etc/GMT-2|+02|-20|0|","Etc/GMT-7|+07|-70|0|","Etc/GMT-8|+08|-80|0|","Etc/GMT-9|+09|-90|0|","Etc/UCT|UCT|0|0|","Etc/UTC|UTC|0|0|","Europe/Astrakhan|+03 +04|-30 -40|010101|1BWn0 1qM0 WM0 8Hz0 3rd0","Europe/London|GMT BST|0 -10|01010101010101010101010|1BWp0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|10e6","Europe/Chisinau|EET EEST|-20 -30|01010101010101010101010|1BWo0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|67e4","Europe/Kaliningrad|EET EEST +03|-20 -30 -30|01020|1BWo0 1qM0 WM0 8Hz0|44e4","Europe/Volgograd|+03 +04|-30 -40|01010|1BWn0 1qM0 WM0 8Hz0|10e5","Europe/Minsk|EET EEST +03|-20 -30 -30|0102|1BWo0 1qM0 WM0|19e5","Europe/Moscow|MSK MSD MSK|-30 -40 -40|01020|1BWn0 1qM0 WM0 8Hz0|16e6","Europe/Samara|+04 +03|-40 -30|010|1Dpb0 WM0|12e5","Europe/Saratov|+03 +04|-30 -40|010101|1BWn0 1qM0 WM0 8Hz0 5810","Europe/Simferopol|EET EEST MSK MSK|-20 -30 -40 -30|01010101023|1BWp0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11z0 1nW0|33e4","Pacific/Honolulu|HST|a0|0||37e4","Indian/Chagos|IOT|-60|0||30e2","Indian/Christmas|CXT|-70|0||21e2","Indian/Cocos|CCT|-6u|0||596","Indian/Mahe|SCT|-40|0||79e3","Indian/Maldives|MVT|-50|0||35e4","Indian/Mauritius|MUT|-40|0||15e4","Indian/Reunion|RET|-40|0||84e4","Pacific/Majuro|MHT|-c0|0||28e3","MET|MET MEST|-10 -20|01010101010101010101010|1BWp0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00","Pacific/Chatham|CHADT CHAST|-dJ -cJ|01010101010101010101010|1C120 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00|600","Pacific/Apia|SST SDT WSDT WSST|b0 a0 -e0 -d0|01012323232323232323232|1Dbn0 1ff0 1a00 CI0 AQ0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00|37e3","Pacific/Bougainville|PGT BST|-a0 -b0|01|1NwE0|18e4","Pacific/Chuuk|CHUT|-a0|0||49e3","Pacific/Efate|VUT|-b0|0||66e3","Pacific/Enderbury|PHOT|-d0|0||1","Pacific/Fakaofo|TKT TKT|b0 -d0|01|1Gfn0|483","Pacific/Fiji|FJST FJT|-d0 -c0|01010101010101010101010|1BWe0 1o00 Rc0 1wo0 Ao0 1Nc0 Ao0 1Q00 xz0 1SN0 uM0 1SM0 uM0 1VA0 s00 1VA0 uM0 1SM0 uM0 1SM0 uM0 1SM0|88e4","Pacific/Funafuti|TVT|-c0|0||45e2","Pacific/Galapagos|GALT|60|0||25e3","Pacific/Gambier|GAMT|90|0||125","Pacific/Guadalcanal|SBT|-b0|0||11e4","Pacific/Guam|ChST|-a0|0||17e4","Pacific/Kiritimati|LINT|-e0|0||51e2","Pacific/Kosrae|KOST|-b0|0||66e2","Pacific/Marquesas|MART|9u|0||86e2","Pacific/Pago_Pago|SST|b0|0||37e2","Pacific/Nauru|NRT|-c0|0||10e3","Pacific/Niue|NUT|b0|0||12e2","Pacific/Norfolk|NFT NFT|-bu -b0|01|1PoCu|25e4","Pacific/Noumea|NCT|-b0|0||98e3","Pacific/Palau|PWT|-90|0||21e3","Pacific/Pitcairn|PST|80|0||56","Pacific/Pohnpei|PONT|-b0|0||34e3","Pacific/Port_Moresby|PGT|-a0|0||25e4","Pacific/Rarotonga|CKT|a0|0||13e3","Pacific/Tahiti|TAHT|a0|0||18e4","Pacific/Tarawa|GILT|-c0|0||29e3","Pacific/Tongatapu|+13 +14|-d0 -e0|0101010101|1S4d0 s00 1VA0 uM0 1SM0 uM0 1SM0 uM0 1SM0|75e3","Pacific/Wake|WAKT|-c0|0||16e3","Pacific/Wallis|WFT|-c0|0||94"],links:["Africa/Abidjan|Africa/Accra","Africa/Abidjan|Africa/Bamako","Africa/Abidjan|Africa/Banjul","Africa/Abidjan|Africa/Bissau","Africa/Abidjan|Africa/Conakry","Africa/Abidjan|Africa/Dakar","Africa/Abidjan|Africa/Freetown","Africa/Abidjan|Africa/Lome","Africa/Abidjan|Africa/Monrovia","Africa/Abidjan|Africa/Nouakchott","Africa/Abidjan|Africa/Ouagadougou","Africa/Abidjan|Africa/Sao_Tome","Africa/Abidjan|Africa/Timbuktu","Africa/Abidjan|America/Danmarkshavn","Africa/Abidjan|Atlantic/Reykjavik","Africa/Abidjan|Atlantic/St_Helena","Africa/Abidjan|Etc/GMT","Africa/Abidjan|Etc/GMT+0","Africa/Abidjan|Etc/GMT-0","Africa/Abidjan|Etc/GMT0","Africa/Abidjan|Etc/Greenwich","Africa/Abidjan|GMT","Africa/Abidjan|GMT+0","Africa/Abidjan|GMT-0","Africa/Abidjan|GMT0","Africa/Abidjan|Greenwich","Africa/Abidjan|Iceland","Africa/Algiers|Africa/Tunis","Africa/Cairo|Egypt","Africa/Casablanca|Africa/El_Aaiun","Africa/Johannesburg|Africa/Maseru","Africa/Johannesburg|Africa/Mbabane","Africa/Khartoum|Africa/Addis_Ababa","Africa/Khartoum|Africa/Asmara","Africa/Khartoum|Africa/Asmera","Africa/Khartoum|Africa/Dar_es_Salaam","Africa/Khartoum|Africa/Djibouti","Africa/Khartoum|Africa/Juba","Africa/Khartoum|Africa/Kampala","Africa/Khartoum|Africa/Mogadishu","Africa/Khartoum|Africa/Nairobi","Africa/Khartoum|Indian/Antananarivo","Africa/Khartoum|Indian/Comoro","Africa/Khartoum|Indian/Mayotte","Africa/Lagos|Africa/Bangui","Africa/Lagos|Africa/Brazzaville","Africa/Lagos|Africa/Douala","Africa/Lagos|Africa/Kinshasa","Africa/Lagos|Africa/Libreville","Africa/Lagos|Africa/Luanda","Africa/Lagos|Africa/Malabo","Africa/Lagos|Africa/Ndjamena","Africa/Lagos|Africa/Niamey","Africa/Lagos|Africa/Porto-Novo","Africa/Maputo|Africa/Blantyre","Africa/Maputo|Africa/Bujumbura","Africa/Maputo|Africa/Gaborone","Africa/Maputo|Africa/Harare","Africa/Maputo|Africa/Kigali","Africa/Maputo|Africa/Lubumbashi","Africa/Maputo|Africa/Lusaka","Africa/Tripoli|Libya","America/Adak|America/Atka","America/Adak|US/Aleutian","America/Anchorage|America/Juneau","America/Anchorage|America/Nome","America/Anchorage|America/Sitka","America/Anchorage|America/Yakutat","America/Anchorage|US/Alaska","America/Argentina/Buenos_Aires|America/Argentina/Catamarca","America/Argentina/Buenos_Aires|America/Argentina/ComodRivadavia","America/Argentina/Buenos_Aires|America/Argentina/Cordoba","America/Argentina/Buenos_Aires|America/Argentina/Jujuy","America/Argentina/Buenos_Aires|America/Argentina/La_Rioja","America/Argentina/Buenos_Aires|America/Argentina/Mendoza","America/Argentina/Buenos_Aires|America/Argentina/Rio_Gallegos","America/Argentina/Buenos_Aires|America/Argentina/Salta","America/Argentina/Buenos_Aires|America/Argentina/San_Juan","America/Argentina/Buenos_Aires|America/Argentina/San_Luis","America/Argentina/Buenos_Aires|America/Argentina/Tucuman","America/Argentina/Buenos_Aires|America/Argentina/Ushuaia","America/Argentina/Buenos_Aires|America/Buenos_Aires","America/Argentina/Buenos_Aires|America/Catamarca","America/Argentina/Buenos_Aires|America/Cordoba","America/Argentina/Buenos_Aires|America/Jujuy","America/Argentina/Buenos_Aires|America/Mendoza","America/Argentina/Buenos_Aires|America/Rosario","America/Campo_Grande|America/Cuiaba","America/Chicago|America/Indiana/Knox","America/Chicago|America/Indiana/Tell_City","America/Chicago|America/Knox_IN","America/Chicago|America/Matamoros","America/Chicago|America/Menominee","America/Chicago|America/North_Dakota/Center","America/Chicago|America/North_Dakota/New_Salem","America/Chicago|America/Rainy_River","America/Chicago|America/Rankin_Inlet","America/Chicago|America/Resolute","America/Chicago|America/Winnipeg","America/Chicago|CST6CDT","America/Chicago|Canada/Central","America/Chicago|US/Central","America/Chicago|US/Indiana-Starke","America/Chihuahua|America/Mazatlan","America/Chihuahua|Mexico/BajaSur","America/Denver|America/Boise","America/Denver|America/Cambridge_Bay","America/Denver|America/Edmonton","America/Denver|America/Inuvik","America/Denver|America/Ojinaga","America/Denver|America/Shiprock","America/Denver|America/Yellowknife","America/Denver|Canada/Mountain","America/Denver|MST7MDT","America/Denver|Navajo","America/Denver|US/Mountain","America/Fortaleza|America/Belem","America/Fortaleza|America/Maceio","America/Fortaleza|America/Recife","America/Fortaleza|America/Santarem","America/Halifax|America/Glace_Bay","America/Halifax|America/Moncton","America/Halifax|America/Thule","America/Halifax|Atlantic/Bermuda","America/Halifax|Canada/Atlantic","America/Havana|Cuba","America/Los_Angeles|America/Dawson","America/Los_Angeles|America/Ensenada","America/Los_Angeles|America/Santa_Isabel","America/Los_Angeles|America/Tijuana","America/Los_Angeles|America/Vancouver","America/Los_Angeles|America/Whitehorse","America/Los_Angeles|Canada/Pacific","America/Los_Angeles|Canada/Yukon","America/Los_Angeles|Mexico/BajaNorte","America/Los_Angeles|PST8PDT","America/Los_Angeles|US/Pacific","America/Los_Angeles|US/Pacific-New","America/Managua|America/Belize","America/Managua|America/Costa_Rica","America/Managua|America/El_Salvador","America/Managua|America/Guatemala","America/Managua|America/Regina","America/Managua|America/Swift_Current","America/Managua|America/Tegucigalpa","America/Managua|Canada/East-Saskatchewan","America/Managua|Canada/Saskatchewan","America/Manaus|America/Boa_Vista","America/Manaus|America/Porto_Velho","America/Manaus|Brazil/West","America/Mexico_City|America/Merida","America/Mexico_City|America/Monterrey","America/Mexico_City|Mexico/General","America/New_York|America/Detroit","America/New_York|America/Fort_Wayne","America/New_York|America/Indiana/Indianapolis","America/New_York|America/Indiana/Marengo","America/New_York|America/Indiana/Petersburg","America/New_York|America/Indiana/Vevay","America/New_York|America/Indiana/Vincennes","America/New_York|America/Indiana/Winamac","America/New_York|America/Indianapolis","America/New_York|America/Iqaluit","America/New_York|America/Kentucky/Louisville","America/New_York|America/Kentucky/Monticello","America/New_York|America/Louisville","America/New_York|America/Montreal","America/New_York|America/Nassau","America/New_York|America/Nipigon","America/New_York|America/Pangnirtung","America/New_York|America/Thunder_Bay","America/New_York|America/Toronto","America/New_York|Canada/Eastern","America/New_York|EST5EDT","America/New_York|US/East-Indiana","America/New_York|US/Eastern","America/New_York|US/Michigan","America/Noronha|Brazil/DeNoronha","America/Panama|America/Atikokan","America/Panama|America/Cayman","America/Panama|America/Coral_Harbour","America/Panama|America/Jamaica","America/Panama|EST","America/Panama|Jamaica","America/Phoenix|America/Creston","America/Phoenix|America/Dawson_Creek","America/Phoenix|America/Hermosillo","America/Phoenix|MST","America/Phoenix|US/Arizona","America/Rio_Branco|America/Eirunepe","America/Rio_Branco|America/Porto_Acre","America/Rio_Branco|Brazil/Acre","America/Santiago|Antarctica/Palmer","America/Santiago|Chile/Continental","America/Santo_Domingo|America/Anguilla","America/Santo_Domingo|America/Antigua","America/Santo_Domingo|America/Aruba","America/Santo_Domingo|America/Barbados","America/Santo_Domingo|America/Blanc-Sablon","America/Santo_Domingo|America/Curacao","America/Santo_Domingo|America/Dominica","America/Santo_Domingo|America/Grenada","America/Santo_Domingo|America/Guadeloupe","America/Santo_Domingo|America/Kralendijk","America/Santo_Domingo|America/Lower_Princes","America/Santo_Domingo|America/Marigot","America/Santo_Domingo|America/Martinique","America/Santo_Domingo|America/Montserrat","America/Santo_Domingo|America/Port_of_Spain","America/Santo_Domingo|America/Puerto_Rico","America/Santo_Domingo|America/St_Barthelemy","America/Santo_Domingo|America/St_Kitts","America/Santo_Domingo|America/St_Lucia","America/Santo_Domingo|America/St_Thomas","America/Santo_Domingo|America/St_Vincent","America/Santo_Domingo|America/Tortola","America/Santo_Domingo|America/Virgin","America/Sao_Paulo|Brazil/East","America/St_Johns|Canada/Newfoundland","Antarctica/DumontDUrville|Etc/GMT-10","Antarctica/Rothera|Etc/GMT+3","Antarctica/Syowa|Etc/GMT-3","Asia/Almaty|Antarctica/Vostok","Asia/Almaty|Asia/Bishkek","Asia/Almaty|Asia/Qyzylorda","Asia/Almaty|Etc/GMT-6","Asia/Baghdad|Asia/Aden","Asia/Baghdad|Asia/Bahrain","Asia/Baghdad|Asia/Kuwait","Asia/Baghdad|Asia/Qatar","Asia/Baghdad|Asia/Riyadh","Asia/Bangkok|Asia/Ho_Chi_Minh","Asia/Bangkok|Asia/Phnom_Penh","Asia/Bangkok|Asia/Saigon","Asia/Bangkok|Asia/Vientiane","Asia/Dhaka|Asia/Dacca","Asia/Dubai|Asia/Muscat","Asia/Hong_Kong|Hongkong","Asia/Jakarta|Asia/Pontianak","Asia/Jerusalem|Asia/Tel_Aviv","Asia/Jerusalem|Israel","Asia/Kamchatka|Asia/Anadyr","Asia/Kathmandu|Asia/Katmandu","Asia/Kolkata|Asia/Calcutta","Asia/Kuala_Lumpur|Asia/Kuching","Asia/Makassar|Asia/Ujung_Pandang","Asia/Rangoon|Asia/Yangon","Asia/Seoul|ROK","Asia/Shanghai|Asia/Chongqing","Asia/Shanghai|Asia/Chungking","Asia/Shanghai|Asia/Harbin","Asia/Shanghai|Asia/Macao","Asia/Shanghai|Asia/Macau","Asia/Shanghai|Asia/Taipei","Asia/Shanghai|PRC","Asia/Shanghai|ROC","Asia/Singapore|Singapore","Asia/Tashkent|Antarctica/Mawson","Asia/Tashkent|Asia/Aqtau","Asia/Tashkent|Asia/Aqtobe","Asia/Tashkent|Asia/Ashgabat","Asia/Tashkent|Asia/Ashkhabad","Asia/Tashkent|Asia/Atyrau","Asia/Tashkent|Asia/Dushanbe","Asia/Tashkent|Asia/Oral","Asia/Tashkent|Asia/Samarkand","Asia/Tashkent|Etc/GMT-5","Asia/Tashkent|Indian/Kerguelen","Asia/Tbilisi|Etc/GMT-4","Asia/Tehran|Iran","Asia/Thimphu|Asia/Thimbu","Asia/Tokyo|Japan","Asia/Ulaanbaatar|Asia/Ulan_Bator","Asia/Urumqi|Asia/Kashgar","Australia/Adelaide|Australia/Broken_Hill","Australia/Adelaide|Australia/South","Australia/Adelaide|Australia/Yancowinna","Australia/Brisbane|Australia/Lindeman","Australia/Brisbane|Australia/Queensland","Australia/Darwin|Australia/North","Australia/Lord_Howe|Australia/LHI","Australia/Perth|Australia/West","Australia/Sydney|Australia/ACT","Australia/Sydney|Australia/Canberra","Australia/Sydney|Australia/Currie","Australia/Sydney|Australia/Hobart","Australia/Sydney|Australia/Melbourne","Australia/Sydney|Australia/NSW","Australia/Sydney|Australia/Tasmania","Australia/Sydney|Australia/Victoria","Etc/UCT|UCT","Etc/UTC|Etc/Universal","Etc/UTC|Etc/Zulu","Etc/UTC|UTC","Etc/UTC|Universal","Etc/UTC|Zulu","Europe/Astrakhan|Europe/Ulyanovsk","Europe/Athens|Asia/Nicosia","Europe/Athens|EET","Europe/Athens|Europe/Bucharest","Europe/Athens|Europe/Helsinki","Europe/Athens|Europe/Kiev","Europe/Athens|Europe/Mariehamn","Europe/Athens|Europe/Nicosia","Europe/Athens|Europe/Riga","Europe/Athens|Europe/Sofia","Europe/Athens|Europe/Tallinn","Europe/Athens|Europe/Uzhgorod","Europe/Athens|Europe/Vilnius","Europe/Athens|Europe/Zaporozhye","Europe/Chisinau|Europe/Tiraspol","Europe/Dublin|Eire","Europe/Istanbul|Asia/Istanbul","Europe/Istanbul|Turkey","Europe/Lisbon|Atlantic/Canary","Europe/Lisbon|Atlantic/Faeroe","Europe/Lisbon|Atlantic/Faroe","Europe/Lisbon|Atlantic/Madeira","Europe/Lisbon|Portugal","Europe/Lisbon|WET","Europe/London|Europe/Belfast","Europe/London|Europe/Guernsey","Europe/London|Europe/Isle_of_Man","Europe/London|Europe/Jersey","Europe/London|GB","Europe/London|GB-Eire","Europe/Moscow|W-SU","Europe/Paris|Africa/Ceuta","Europe/Paris|Arctic/Longyearbyen","Europe/Paris|Atlantic/Jan_Mayen","Europe/Paris|CET","Europe/Paris|Europe/Amsterdam","Europe/Paris|Europe/Andorra","Europe/Paris|Europe/Belgrade","Europe/Paris|Europe/Berlin","Europe/Paris|Europe/Bratislava","Europe/Paris|Europe/Brussels","Europe/Paris|Europe/Budapest","Europe/Paris|Europe/Busingen","Europe/Paris|Europe/Copenhagen","Europe/Paris|Europe/Gibraltar","Europe/Paris|Europe/Ljubljana","Europe/Paris|Europe/Luxembourg","Europe/Paris|Europe/Madrid","Europe/Paris|Europe/Malta","Europe/Paris|Europe/Monaco","Europe/Paris|Europe/Oslo","Europe/Paris|Europe/Podgorica","Europe/Paris|Europe/Prague","Europe/Paris|Europe/Rome","Europe/Paris|Europe/San_Marino","Europe/Paris|Europe/Sarajevo","Europe/Paris|Europe/Skopje","Europe/Paris|Europe/Stockholm","Europe/Paris|Europe/Tirane","Europe/Paris|Europe/Vaduz","Europe/Paris|Europe/Vatican","Europe/Paris|Europe/Vienna","Europe/Paris|Europe/Warsaw","Europe/Paris|Europe/Zagreb","Europe/Paris|Europe/Zurich","Europe/Paris|Poland","Europe/Volgograd|Europe/Kirov","Pacific/Auckland|Antarctica/McMurdo","Pacific/Auckland|Antarctica/South_Pole","Pacific/Auckland|NZ","Pacific/Chatham|NZ-CHAT","Pacific/Chuuk|Pacific/Truk","Pacific/Chuuk|Pacific/Yap","Pacific/Easter|Chile/EasterIsland","Pacific/Guam|Pacific/Saipan","Pacific/Honolulu|HST","Pacific/Honolulu|Pacific/Johnston","Pacific/Honolulu|US/Hawaii","Pacific/Majuro|Kwajalein","Pacific/Majuro|Pacific/Kwajalein","Pacific/Pago_Pago|Pacific/Midway","Pacific/Pago_Pago|Pacific/Samoa","Pacific/Pago_Pago|US/Samoa","Pacific/Pohnpei|Pacific/Ponape"] 7 | }),a}); -------------------------------------------------------------------------------- /public/js/vendor/bootstrap.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v3.3.7 (http://getbootstrap.com) 3 | * Copyright 2011-2016 Twitter, Inc. 4 | * Licensed under the MIT license 5 | */ 6 | if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1||b[0]>3)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){if(a(b.target).is(this))return b.handleObj.handler.apply(this,arguments)}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.7",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a("#"===f?[]:f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.7",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c).prop(c,!0)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c).prop(c,!1))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target).closest(".btn");b.call(d,"toggle"),a(c.target).is('input[type="radio"], input[type="checkbox"]')||(c.preventDefault(),d.is("input,button")?d.trigger("focus"):d.find("input:visible,button:visible").first().trigger("focus"))}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.7",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));if(!(a>this.$items.length-1||a<0))return this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){if(!this.sliding)return this.slide("next")},c.prototype.prev=function(){if(!this.sliding)return this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.7",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger(a.Event("hidden.bs.dropdown",f)))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.7",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger(a.Event("shown.bs.dropdown",h))}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&jdocument.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth
',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);if(c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),!c.isInStateTrue())return clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-mo.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null,a.$element=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;!e&&/destroy|hide/.test(b)||(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.7",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.7",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b=e[a]&&(void 0===e[a+1]||b .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.7",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return e=a-d&&"bottom"},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery); --------------------------------------------------------------------------------