WME WazeMY

WME script for WazeMY editing moderation

目前為 2022-08-08 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         WME WazeMY
// @namespace    https://greasyfork.org/en/scripts/404584-wazemy
// @version      2022.08.08.01
// @description  WME script for WazeMY editing moderation
// @author       junyianl
// @match        https://beta.waze.com/*
// @match        https://www.waze.com/forum/*
// @match        https://www.waze.com/editor*
// @match        https://www.waze.com/*/editor*
// @match        https://www.waze.com/user/editor*
// @require      https://greasyfork.org/scripts/24851-wazewrap/code/WazeWrap.js
// @grant        GM_xmlhttpRequest
// @license      MIT
// ==/UserScript==

// @connect      fgies.com
// @connect      jalanow.com
// @connect      odis.sgp1.digitaloceanspaces.com

/* global W */
/* global WazeWrap */
/* global $ */
/* global OL */
/* global OpenLayers */

/**
 * All mentions of script names and links in this script is my way of giving
 * credit to where it's due.
 * Without those scripts, I would have no place to start.
 * Big thanks to the original script authors.
 *
 * Huge thanks to the following contributors for cam locations around Malaysia.
 * :: epailxi | dckj | firman_bakti | rickylo103 ::
 */

const updateMessage = "► More traffic cams.";
var staticUpdateID;

var trafficCamsData = [
    { desc:'Jalan Sultan Ismail / Jalan Imbi near Berjaya Times Square KL', lat:3.14369, lon:101.71245, url:'https://p4.fgies.com/kl8/img/K012W.jpg' },
    { desc:'Jalan Bukit Bintang / Jalan Raja Chulan near Pavilion KL', lat:3.14833, lon:101.71609, url:'https://p4.fgies.com/kl8/img/K004W.jpg' },
    { desc:'Jalan Sultan Ismail near Sime Darby', lat:3.16102, lon:101.69522, url:'https://p4.fgies.com/kl8/img/K011W.jpg' },
    { desc:'Jalan Sultan Ismail / Jalan P. Ramlee near Shangri-La Hotel', lat:3.15389, lon:101.70761, url:'https://p4.fgies.com/kl8/img/K013W.jpg' },
    { desc:'Jalan Sultan Ismail near Renaissance Hotel', lat:3.15929307072728, lon:101.700892565152, url:'https://p4.fgies.com/kl8/img/K029W.jpg' },
    { desc:'Jalan Raja Laut near KWSP', lat:3.15314, lon:101.69473, url:'https://p4.fgies.com/kl8/img/K037W.jpg' },
    { desc:'Jalan Raja near Stesen LRT Bandaraya', lat:3.15076, lon:101.69461, url:'https://p4.fgies.com/kl8/img/K016W.jpg' },
    { desc:'Bulatan Dato\' Onn near Bank Negara', lat:3.151524, lon:101.693394, url:'https://p4.fgies.com/kl8/img/K036W.jpg' },
    { desc:'Jalan Raja near Dataran Merdeka', lat:3.15130467327156, lon:101.693128740951, url:'https://p4.fgies.com/kl8/img/K028W.jpg' },
    { desc:'Jalan Kuching / Jalan Raja Laut near Bangunan DBKL', lat:3.15328733409485, lon:101.693719456795, url:'https://p4.fgies.com/kl8/img/K001W.jpg' },
    { desc:'Jalan Maharajalela near Maharajalela Monorail Station', lat:3.13992, lon:101.69709, url:'https://p4.fgies.com/kl8/img/K038W.jpg' },
    { desc:'Jalan Kinabalu near Perpustakaan KL', lat:3.14741, lon:101.69247, url:'https://p4.fgies.com/kl8/img/K008W.jpg' },
    { desc:'Jalan Kinabalu near Masjid Negara', lat:3.14325, lon:101.69287, url:'https://p4.fgies.com/kl8/img/K007W.jpg' },
    { desc:'Jalan Kuching near Jalan Sultan Ismail', lat:3.16173, lon:101.69247, url:'https://p4.fgies.com/kl8/img/K047W.jpg' },
    { desc:'Jalan Kuching near Bulatan Kepong', lat:3.20168, lon:101.67037, url:'https://p4.fgies.com/kl8/img/K002W.jpg' },
    { desc:'Jalan Kuching near Hentian Putra / PWTC', lat:3.16693332927155, lon:101.689706476829, url:'https://p4.fgies.com/kl8/img/K046W.jpg' },
    { desc:'Jalan Kuching near Jalan Sultan Ismail', lat:3.16343529038211, lon:101.692232025972, url:'https://p4.fgies.com/kl8/img/K023W.jpg' },
    { desc:'Jalan Tun Razak near Hospital Kuala Lumpur (HKL)', lat:3.17284962099842, lon:101.704733072188, url:'https://p4.fgies.com/kl8/img/K003W.jpg' },
    { desc:'Jalan Tun Razak near U.S Embassy KL', lat:3.15365, lon:101.72267, url:'https://p4.fgies.com/kl8/img/K017W.jpg' },
    { desc:'Jalan Tun Razak near Lembaga Tabung Haji', lat:3.15779, lon:101.72083, url:'https://p4.fgies.com/kl8/img/K024W.jpg' },
    { desc:'Jalan Tuanku Abdul Halim near Taman Duta', lat:3.15073, lon:101.6746, url:'https://p4.fgies.com/kl8/img/K044W.jpg' },
    { desc:'Jalan Tuanku Abdul Halim near Jalan Semantan', lat:3.15269, lon:101.67293, url:'https://p4.fgies.com/kl8/img/K045W.jpg' },
    { desc:'Jalan Damansara near Jalan Istana Lama', lat:3.13603, lon:101.69204, url:'https://p4.fgies.com/kl8/img/K043W.jpg' },
    { desc:'Jalan Syed Putra near Sekolah Kuen Cheng', lat:3.13179, lon:101.69184, url:'https://p4.fgies.com/kl8/img/K034W.jpg' },
    { desc:'Jalan Syed Putra near Kampung Attap', lat:3.13863, lon:101.69531, url:'https://p4.fgies.com/kl8/img/K015W.jpg' },
    { desc:'Jalan Damansara near Carcosa Seri Negara', lat:3.13843, lon:101.68482, url:'https://p4.fgies.com/kl8/img/K005W.jpg' },
    { desc:'Timur–Barat Highway near Bandar Tun Razak', lat:3.09385, lon:101.71095, url:'https://p4.fgies.com/kl8/img/K041W.jpg' },
    { desc:'Timur–Barat Highway near Salak Selatan', lat:3.09785, lon:101.70352, url:'https://p4.fgies.com/kl8/img/K042W.jpg' },
    { desc:'Jalan Cheras near Bulatan Cheras', lat:3.1136, lon:101.72816, url:'https://p4.fgies.com/kl8/img/K031W.jpg' },
    { desc:'Jalan Cheras near Jalan Ikan Ayu', lat:3.11799, lon:101.72806, url:'https://p4.fgies.com/kl8/img/K025W.jpg' },
    { desc:'Bulatan Cheras near Lotus\'s Cheras', lat:3.09925, lon:101.73784, url:'https://p4.fgies.com/kl8/img/K026W.jpg' },
    { desc:'Jalan Sungai Besi Near Lapangan Terbang TUDM', lat:3.12146, lon:101.70823, url:'https://p4.fgies.com/kl8/img/K039W.jpg' },
    { desc:'Jalan Loke Yew near Tsun Jin High School', lat:3.13407, lon:101.70685, url:'https://p4.fgies.com/kl8/img/K035W.jpg' },
    { desc:'Jalan Loke Yew near Viva Shopping Mall', lat:3.11887, lon:101.72196, url:'https://p4.fgies.com/kl8/img/K009W.jpg' },
    { desc:'KL-Seremban Highway near Jalan Sungai Besi (BHP)', lat:3.12252, lon:101.70843, url:'https://p4.fgies.com/kl8/img/K010W.jpg' },
    { desc:'KL-Seremban Highway near Nirvana Memorial Center', lat:3.08873, lon:101.69675, url:'https://p4.fgies.com/kl8/img/K019W.jpg' },
    { desc:'KL-Seremban Highway near Petronas TPM', lat:3.05429, lon:101.70517, url:'https://p4.fgies.com/kl8/img/K040W.jpg' },
    { desc:'MBJB cam 01 near Persimpangan Jalan Skudai / Sutera Utama', lat:1.52143, lon:103.68009, url:'https://p4.fgies.com/bucket-mbjb/01W.jpg' },
    { desc:'MBJB cam 02 near Jalan Skudai (Hadapan Taman Johor)', lat:1.50801450501849, lon:103.689733181908, url:'https://p4.fgies.com/bucket-mbjb/02W.jpg' },
    { desc:'MBJB cam 03 near Jalan Skudai / Jalan Tun Abdul Razak', lat:1.48727160040328, lon:103.716398242299, url:'https://p4.fgies.com/bucket-mbjb/03W.jpg' },
    { desc:'MBJB cam 04 near Jalan Susur 4 / Jalan Tun Abdul Razak', lat:1.47912277436081, lon:103.752466052307, url:'https://p4.fgies.com/bucket-mbjb/04W.jpg' },
    { desc:'MBJB cam 05 near Jalan Tun Abdul Razak / Jalan Tebrau', lat:1.46585995295866, lon:103.761166576913, url:'https://p4.fgies.com/bucket-mbjb/05W.jpg' },
    { desc:'MBJB cam 06 near Jalan Persiaran Abu Bakar Sultan (Danga Bay)', lat:1.47885180802371, lon:103.723480509256, url:'https://p4.fgies.com/bucket-mbjb/06W.jpg' },
    { desc:'MBJB cam 07 near Jalan Persiaran Abu Bakar Sultan (in front of Hospital Sultanah Aminah)', lat:1.4572059284377, lon:103.747094776885, url:'https://p4.fgies.com/bucket-mbjb/07W.jpg' },
    { desc:'MBJB cam 08 near Jalan Persiaran Ismail Sultan / Jalan Ayer Molek', lat:1.45505224686676, lon:103.759729931891, url:'https://p4.fgies.com/bucket-mbjb/08W.jpg' },
    { desc:'MBJB cam 09 near KM0, Hadapan MBJB', lat:1.45538454816586, lon:103.762067556349, url:'https://p4.fgies.com/bucket-mbjb/09W.jpg' },
    { desc:'MBJB cam 10 near Jalan Wong Ah Fook / Plaza Seni', lat:1.46040674713598, lon:103.763869278212, url:'https://p4.fgies.com/bucket-mbjb/10W.jpg' },
    { desc:'MBJB cam 11 near Jalan Segget (Hadapan Bangunan MIC)', lat:1.45791001614459, lon:103.764268946504, url:'https://p4.fgies.com/bucket-mbjb/11W.jpg' },
    { desc:'MBJB cam 12 near Jalan Meldrum/ Jalan Siu Nam', lat:1.45882985226327, lon:103.765712421493, url:'https://p4.fgies.com/bucket-mbjb/12W.jpg' },
    { desc:'MBJB cam 13 near Jalan Trus / Jalan Ungku Puan', lat:1.4587307677419, lon:103.763650801401, url:'https://p4.fgies.com/bucket-mbjb/13W.jpg' },
    { desc:'MBJB cam 14 near Jalan Kempas Lama / Lebuhraya Utara Selatan', lat:1.55127414526798, lon:103.710707183628, url:'https://p4.fgies.com/bucket-mbjb/14W.jpg' },
    { desc:'MBJB cam 15 near Jalan Kempas Spur / Jalan Kempas Lama', lat:1.54622257888336, lon:103.706616462469, url:'https://p4.fgies.com/bucket-mbjb/15W.jpg' },
    { desc:'MBJB cam 16 near Persimpangan Bertingkat Jalan Kempas Baru / Pasir Gudang', lat:1.51940557823981, lon:103.727432162933, url:'https://p4.fgies.com/bucket-mbjb/16W.jpg' },
    { desc:'MBJB cam 17 near Persimpangan Bertingkat Jalan Datin Halimah / Jalan Tampoi', lat:1.5120697707288, lon:103.733145182088, url:'https://p4.fgies.com/bucket-mbjb/17W.jpg' },
    { desc:'MBJB cam 18 near Jalan Stulang Laut / Jalan Ibrahim Sultan', lat:1.46977565748046, lon:103.782259344672, url:'https://p4.fgies.com/bucket-mbjb/18W.jpg' },
    { desc:'MBJB cam 19 near Persimpangan Pesisir Perling / Jalan Tampoi Utama', lat:1.50187688096647, lon:103.686758790376, url:'https://p4.fgies.com/bucket-mbjb/19W.jpg' },
    { desc:'MBJB cam 20 near Jalan Tampoi (Hadapan Plaza Angsana)', lat:1.49594210506084, lon:103.705407431335, url:'https://p4.fgies.com/bucket-mbjb/23W.jpg' },
    { desc:'MBJB cam 21 near Persimpangan Jalan Tampoi / Jalan Ungku Mohsin', lat:1.51520533065784, lon:103.739822579285, url:'https://p4.fgies.com/bucket-mbjb/21W.jpg' },
    { desc:'MBJB cam 22 near Persimpangan Jalan Kota Tinggi / Jalan Ulu Tiram', lat:1.59905398228792, lon:103.820736374127, url:'https://p4.fgies.com/bucket-mbjb/22W.jpg' },
    { desc:'MBJB cam 23 near Persimpangan bertingkat Jalan Kota Tinggi / Persiaran Desa Tebrau', lat:1.5491552104896, lon:103.798860796817, url:'https://p4.fgies.com/bucket-mbjb/23W.jpg' },
    { desc:'MBJB cam 24 near Jalan Kota Tinggi (Hadapan Pasar Borong Pandan)', lat:1.52271947244132, lon:103.766539983458, url:'https://p4.fgies.com/bucket-mbjb/24W.jpg' },
    { desc:'MBJB cam 25 near Jalan Tebrau / Jalan Rebung', lat:1.512418555786, lon:103.759900352551, url:'https://p4.fgies.com/bucket-mbjb/25W.jpg' },
    { desc:'MBJB cam 26 near Jalan Tebrau (Hadapan Wisma Daiman)', lat:1.49348545231193, lon:103.766636743807, url:'https://p4.fgies.com/bucket-mbjb/26W.jpg' },
    { desc:'MBJB cam 27 near Jalan Tebrau / Jalan Keris', lat:1.48713839354697, lon:103.766427939883, url:'https://p4.fgies.com/bucket-mbjb/27W.jpg' },
    { desc:'MBJB cam 28 near Jalan Tebrau (Metropolis Tower)', lat:1.47860201699811, lon:103.763678135017, url:'https://p4.fgies.com/bucket-mbjb/28W.jpg' },
    { desc:'MBJB cam 29 near Persimpangan Lebuhraya Pasir Gudang /Seri Alam', lat:1.50385805346979, lon:103.850538399541, url:'https://p4.fgies.com/bucket-mbjb/29W.jpg' },
    { desc:'MBJB cam 30 near Jalan Tun Razak / Susur 4 (Hadapan Courts)', lat:1.48512, lon:103.74855, url:'https://p4.fgies.com/bucket-mbjb/30W.jpg' },
    { desc:'MBJB cam 31 near Persimpangan Jalan Pasir Pelangi / Jalan Bakar Batu', lat:1.49518256528262, lon:103.782900748942, url:'https://p4.fgies.com/bucket-mbjb/31W.jpg' },
    { desc:'MBJB cam 32 near Lingkaran Dalam / Stulang Darat', lat:1.46819491027982, lon:103.769451244357, url:'https://p4.fgies.com/bucket-mbjb/32W.jpg' },
    { desc:'MBJB cam 33 near Jalan Datin Halimah / Jalan Kenyalang', lat:1.49436, lon:103.73966, url:'https://p4.fgies.com/bucket-mbjb/33W.jpg' },
    { desc:'MBJB cam 35 near Persiaran Kempas Baru / Jalan Banjaran Utama', lat:1.52955, lon:103.71108, url:'https://p4.fgies.com/bucket-mbjb/35W.jpg' },
    { desc:'NSE PNB Penang Bridge CAM 01 PERAI KM136.80 SB', lat:5.385196, lon:100.405228, url:'https://p3.fgies.com/bucket-pnb/PNB-01.jpg' },
    { desc:'NSE PNB Penang Bridge CAM 02 PERAI KM138.75 NB', lat:5.368684, lon:100.399058, url:'https://p3.fgies.com/bucket-pnb/PNB-02.jpg' },
    { desc:'MSE PNB Penang Bridge CAM 03 PERAI KM140.10 NB', lat:5.359994, lon:100.406117, url:'https://p3.fgies.com/bucket-pnb/PNB-03.jpg' },
    { desc:'PNB Penang Bridge CAM 04 LB CH 0.5', lat:5.364437, lon:100.396953, url:'https://p3.fgies.com/bucket-pnb/PNB-04.jpg' },
    { desc:'PNB Penang Bridge CAM 05 LD CH 0.1', lat:5.36087130330266, lon:100.393634442424, url:'https://p3.fgies.com/bucket-pnb/PNB-05.jpg' },
    { desc:'PNB Penang Bridge CAM 06 PNG BRG KM0.30 WB', lat:5.35492, lon:100.39143, url:'https://p3.fgies.com/bucket-pnb/PNB-06.jpg' },
    { desc:'PNB Penang Bridge CAM 07 PNG BRG KM1.00 WB', lat:5.35287, lon:100.38591, url:'https://p3.fgies.com/bucket-pnb/PNB-07.jpg' },
    { desc:'PNB Penang Bridge CAM 08 PNG BRG KM1.60 WB', lat:5.352646, lon:100.38045, url:'https://p3.fgies.com/bucket-pnb/PNB-08.jpg' },
    { desc:'PNB Penang Bridge CAM 09 PNG BRG KM2.80 EB', lat:5.35163, lon:100.369716, url:'https://p3.fgies.com/bucket-pnb/PNB-09.jpg' },
    { desc:'PNB Penang Bridge CAM 10 PNG BRG KM4.00 EB', lat:5.352343, lon:100.358991, url:'https://p3.fgies.com/bucket-pnb/PNB-10.jpg' },
    { desc:'PNB Penang Bridge CAM 11 PNG BRG KM5.40 WB', lat:5.353971, lon:100.346513, url:'https://p3.fgies.com/bucket-pnb/PNB-11.jpg' },
    { desc:'PNB Penang Bridge CAM 12 PNG BRG KM5.40 EB', lat:5.354206, lon:100.34654, url:'https://p3.fgies.com/bucket-pnb/PNB-12.jpg' },
    { desc:'PNB Penang Bridge CAM 13 PNG BRG KM6.80 WB', lat:5.355821, lon:100.333965, url:'https://p3.fgies.com/bucket-pnb/PNB-13.jpg' },
    { desc:'PNB Penang Bridge CAM 14 BRG KM8.0', lat:5.357453, lon:100.323268, url:'https://p3.fgies.com/bucket-pnb/PNB-14.jpg' },
    { desc:'PNB Penang Bridge CAM 15 LY CH 0.6', lat:5.358528, lon:100.316267, url:'https://p3.fgies.com/bucket-pnb/PNB-15.jpg' },
    { desc:'PNB Penang Bridge CAM 16 LQ CH 0.3', lat:5.356265, lon:100.312764, url:'https://p3.fgies.com/bucket-pnb/PNB-16.jpg' },
    { desc:'PNB Penang Bridge CAM 17 LQ CH 0.6', lat:5.361002, lon:100.314399, url:'https://p3.fgies.com/bucket-pnb/PNB-17.jpg' },
    { desc:'PNB Penang Bridge CAM 18 B4 CH 0.6', lat:5.3613, lon:100.31437, url:'https://p3.fgies.com/bucket-pnb/PNB-18.jpg' },
    { desc:'PNB Penang Bridge CAM 19 LN CH 0.8', lat:5.36914, lon:100.313857, url:'https://p3.fgies.com/bucket-pnb/PNB-19.jpg' },
    { desc:'PNB Penang Bridge CAM 20 LM CH 1.2', lat:5.374882, lon:100.315817, url:'https://p3.fgies.com/bucket-pnb/PNB-20.jpg' },
    { desc:'PNB Penang Bridge CAM 21 LN CH 1.9', lat:5.36101, lon:100.314396, url:'https://p3.fgies.com/bucket-pnb/PNB-21.jpg' },
    { desc:'LPT 2 near 01 Perasing R&R KM259.870 NB', lat:4.01753, lon:103.313694, url:'https://p3.fgies.com/bucket-ece2/ECE2-01.jpg' },
    { desc:'LPT 2 near 02 Perasing R&R KM259.870 SB', lat:4.018416, lon:103.314777, url:'https://p3.fgies.com/bucket-ece2/ECE2-02.jpg' },
    { desc:'LPT 2 near 03 Perasing R&R KM259.870 NB', lat:4.019428, lon:103.31341, url:'https://p3.fgies.com/bucket-ece2/ECE2-03.jpg' },
    { desc:'LPT 2 near 04 PTZ CNH IC KM273.4 SB', lat:4.133594, lon:103.282245, url:'https://p3.fgies.com/bucket-ece2/ECE2-40.jpg' },
    { desc:'LPT 2 near 05 Cheneh Interchange KM273.370 ENT', lat:4.127079, lon:103.266866, url:'https://p3.fgies.com/bucket-ece2/ECE2-04.jpg' },
    { desc:'LPT 2 near 06 Cheneh Toll KM273.370 EXT', lat:4.127177, lon:103.26694, url:'https://p3.fgies.com/bucket-ece2/ECE2-05.jpg' },
    { desc:'LPT 2 near 07 Cukai Interchange KM287.1 SB', lat:4.245774, lon:103.312721, url:'https://p3.fgies.com/bucket-ece2/ECE2-06.jpg' },
    { desc:'LPT 2 near 10 PTZ KJLL KM296.9 SB', lat:4.330917, lon:103.30279, url:'https://p3.fgies.com/bucket-ece2/ECE2-41.jpg' },
    { desc:'LPT 2 near 11 Kijal R&R KM296.9 NB', lat:4.332806, lon:103.302717, url:'https://p3.fgies.com/bucket-ece2/ECE2-09.jpg' },
    { desc:'LPT 2 near 12 Kijal Interchange KM305.9 NB', lat:4.385512, lon:103.356951, url:'https://p3.fgies.com/bucket-ece2/ECE2-10.jpg' },
    { desc:'LPT 2 near 13 Kijal Toll KM306.000 ENT', lat:4.376366, lon:103.36256, url:'https://p3.fgies.com/bucket-ece2/ECE2-11.jpg' },
    { desc:'LPT 2 near 14 Kijal Toll KM306.000 EXT', lat:4.376438, lon:103.362822, url:'https://p3.fgies.com/bucket-ece2/ECE2-12.jpg' },
    { desc:'LPT 2 near 15 Kertih Toll KM319.195 ENT', lat:4.481294, lon:103.407874, url:'https://p3.fgies.com/bucket-ece2/ECE2-13.jpg' },
    { desc:'LPT 2 near 16 Kertih Toll KM319.195 EXT', lat:4.481503, lon:103.408069, url:'https://p3.fgies.com/bucket-ece2/ECE2-14.jpg' },
    { desc:'LPT 2 near 17 Kertih Interchange KM319.9 NB', lat:4.490002, lon:103.398428, url:'https://p3.fgies.com/bucket-ece2/ECE2-15.jpg' },
    { desc:'LPT 2 near 18 Paka Toll KM331.487 ENT', lat:4.591732, lon:103.347299, url:'https://p3.fgies.com/bucket-ece2/ECE2-16.jpg' },
    { desc:'LPT 2 near 19 Paka Toll KM331.487 EXT', lat:4.591471, lon:103.347236, url:'https://p3.fgies.com/bucket-ece2/ECE2-17.jpg' },
    { desc:'LPT 2 near 21 Paka R&R KM337.9 SB', lat:4.645889, lon:103.343215, url:'https://p3.fgies.com/bucket-ece2/ECE2-19.jpg' },
    { desc:'LPT 2 near 22 Paka R&R KM337.9 NB', lat:4.646667, lon:103.34351, url:'https://p3.fgies.com/bucket-ece2/ECE2-20.jpg' },
    { desc:'LPT 2 near 23 Dungun Toll KM348.787 ENT', lat:4.741863, lon:103.328688, url:'https://p3.fgies.com/bucket-ece2/ECE2-21.jpg' },
    { desc:'LPT 2 near 24 Dungun Toll KM348.787 EXT', lat:4.742041, lon:103.328492, url:'https://p3.fgies.com/bucket-ece2/ECE2-22.jpg' },
    { desc:'LPT 2 near 25 Dungun Interchange KM348.787 SB', lat:4.735501, lon:103.316052, url:'https://p3.fgies.com/bucket-ece2/ECE2-23.jpg' },
    { desc:'LPT 2 near 26 Bukit Besi Toll KM365.544 ENT', lat:4.801387, lon:103.195628, url:'https://p3.fgies.com/bucket-ece2/ECE2-24.jpg' },
    { desc:'LPT 2 near 27 Bukit Besi Toll KM365.544 EXT', lat:4.801563, lon:103.195842, url:'https://p3.fgies.com/bucket-ece2/ECE2-25.jpg' },
    { desc:'LPT 2 near 28 Bukit Besi Interchange KM365.544 SB', lat:4.807029, lon:103.196351, url:'https://p3.fgies.com/bucket-ece2/ECE2-26.jpg' },
    { desc:'LPT 2 near 29 Bukit Besi R&R KM370.400 NB', lat:4.848288, lon:103.185187, url:'https://p3.fgies.com/bucket-ece2/ECE2-26.jpg' },
    { desc:'LPT 2 near 30 Bukit Besi R&R KM370.400 SB', lat:4.847831, lon:103.18567, url:'https://p3.fgies.com/bucket-ece2/ECE2-28.jpg' },
    { desc:'LPT 2 near 31 Ajil Toll KM403.748 ENT', lat:5.087422, lon:103.073968, url:'https://p3.fgies.com/bucket-ece2/ECE2-29.jpg' },
    { desc:'LPT 2 near 32 Ajil Toll KM403.748 EXT', lat:5.087681, lon:103.073979, url:'https://p3.fgies.com/bucket-ece2/ECE2-30.jpg' },
    { desc:'LPT 2 near 33 Ajil InterchangeIC KM403.7 SB', lat:5.089149, lon:103.064343, url:'https://p3.fgies.com/bucket-ece2/ECE2-31.jpg' },
    { desc:'LPT 2 near 34 Ajil R&R KM411.0 NB', lat:5.141647, lon:103.041384, url:'https://p3.fgies.com/bucket-ece2/ECE2-32.jpg' },
    { desc:'LPT 2 near 35 Ajil KM411.0 SB', lat:5.142714, lon:103.041562, url:'https://p3.fgies.com/bucket-ece2/ECE2-33.jpg' },
    { desc:'LPT 2 near 36 Telemung Toll KM423.246 ENT', lat:5.239306, lon:102.99899, url:'https://p3.fgies.com/bucket-ece2/ECE2-34.jpg' },
    { desc:'LPT 2 near 37 Telemung Toll KM423.246 EXT', lat:5.239151, lon:102.999312, url:'https://p3.fgies.com/bucket-ece2/ECE2-35.jpg' },
    { desc:'LPT 2 near 38 Telemung Interchange KM423.2 SB', lat:5.243114, lon:103.008322, url:'https://p3.fgies.com/bucket-ece2/ECE2-36.jpg' },
    { desc:'LPT 2 near 39 Kuala Terengganu Interchange KM433.4 SB', lat:5.333321, lon:103.013192, url:'https://p3.fgies.com/bucket-ece2/ECE2-37.jpg' },
    { desc:'LPT 2 near 40 Kuala Terengganu Toll KM433.393 ENT', lat:5.336588, lon:103.021675, url:'https://p3.fgies.com/bucket-ece2/ECE2-38.jpg' },
    { desc:'LPT 2 near 41 Kuala Terengganu Toll KM433.393 EXT', lat:5.33675, lon:103.02144, url:'https://p3.fgies.com/bucket-ece2/ECE2-39.jpg' },
    { desc:'LPT 1 near Karak 77.8KM WB', lat:3.43293, lon:102.01483, url:'https://t2.fgies.com/bucket-lpt/LPT-05.jpg' },
    { desc:'LPT 1 near Karak Plaza Toll WB', lat:3.44353, lon:102.02744, url:'https://t2.fgies.com/bucket-lpt/LPT-09.jpg' },
    { desc:'LPT 1 near Lanchang Toll WB', lat:3.523, lon:102.17343, url:'https://t2.fgies.com/bucket-lpt/LPT-16.jpg' },
    { desc:'LPT 1 near Temerloh KM126.4 WB', lat:3.5093, lon:102.40761, url:'https://t2.fgies.com/bucket-lpt/LPT-14.jpg' },
    { desc:'LPT 1 near Temerloh Plaza Toll WB', lat:3.5042, lon:102.4039, url:'https://t2.fgies.com/bucket-lpt/LPT-12.jpg' },
    { desc:'LPT 1 near Chenor Plaza Toll WB', lat:3.54059, lon:102.51199, url:'https://t2.fgies.com/bucket-lpt/LPT-06.jpg' },
    { desc:'LPT 1 near Maran Toll WB', lat:3.60427, lon:102.78799, url:'https://t2.fgies.com/bucket-lpt/LPT-11.jpg' },
    { desc:'LPT 1 near Gambang Plaza Toll WB', lat:3.73803, lon:103.11618, url:'https://t2.fgies.com/bucket-lpt/LPT-07.jpg' },
    { desc:'LPT 1 near Kuantan KM238.4 WB', lat:3.87729, lon:103.23962, url:'https://t2.fgies.com/bucket-lpt/LPT-15.jpg' },
    { desc:'LPT 1 near Kuantan Plaza Toll WB', lat:3.86996, lon:103.24196, url:'https://t2.fgies.com/bucket-lpt/LPT-10.jpg' },
    { desc:'LPT 1 near Jabor Plaza Toll WB', lat:3.94561, lon:103.31752, url:'https://t2.fgies.com/bucket-lpt/LPT-08.jpg' },
    { desc:'KL - Karak near Gombak Plaza Toll KM19.8 EB toward Genting / Pahang', lat:3.242317, lon:101.727147, url:'https://p3.fgies.com/bucket-klk/KLK-12.jpg' },
    { desc:'KL - Karak near Gombak Plaza Toll KM19.8 WB towards Kuala Lumpur', lat:3.241761, lon:3.241761, url:'https://p3.fgies.com/bucket-klk/KLK-13.jpg' },
    { desc:'KL - Karak near Gombak Plaza Toll KM21.6 EB', lat:3.252596, lon:101.728328, url:'https://p3.fgies.com/bucket-klk/KLK-10.jpg' },
    { desc:'KL - Karak near Gombak Plaza Toll KM21.6 WB', lat:3.252681, lon:101.728282, url:'https://p3.fgies.com/bucket-klk/KLK-11.jpg' },
    { desc:'KL - Karak near Genting Sempah 35.3 EB', lat:3.339652, lon:101.77085, url:'https://p3.fgies.com/bucket-klk/KLK-05.jpg' },
    { desc:'KL - Karak near Genting Sempah 35.3 WB', lat:3.339587, lon:101.770852, url:'https://p3.fgies.com/bucket-klk/KLK-06.jpg' },
    { desc:'KL - Karak near Bentong KM55.5 EB', lat:3.421312, lon:101.89005, url:'https://p3.fgies.com/bucket-klk/KLK-01.jpg' },
    { desc:'KL - Karak near Bentong KM55.5 WB', lat:3.421275, lon:101.890057, url:'https://p3.fgies.com/bucket-klk/KLK-02.jpg' },
    { desc:'KL - Karak near Karak KM75 EB', lat:3.44862, lon:101.996145, url:'https://p3.fgies.com/bucket-klk/KLK-14.jpg' },
    { desc:'KL - Karak near Karak KM75 WB', lat:3.448618, lon:101.996143, url:'https://p3.fgies.com/bucket-klk/KLK-15.jpg' },
    { desc:'NKVE near Jalan Duta Toll KM28.71', lat:3.17635, lon:101.65583, url:'https://p3.fgies.com/bucket-nkve/NKVE-02.jpg' },
    { desc:'NKVE near Jalan Duta KM28.2 NB', lat:3.17516, lon:101.65013, url:'https://p3.fgies.com/bucket-nkve/NKVE-01.jpg?rnd=1659758916759' },
    { desc:'NKVE near Jalan Duta KM27.1 SB', lat:3.17868, lon:101.64035, url:'https://p3.fgies.com/bucket-nkve/NKVE-20.jpg' },
    { desc:'NKVE near Jalan Duta KM25.85 SB', lat:3.1816, lon:101.63035, url:'https://p3.fgies.com/bucket-nkve/NKVE-19.jpg' },
    { desc:'NKVE near Jalan Duta KM 24.9 SB', lat:3.18293, lon:101.62138, url:'https://p3.fgies.com/bucket-nkve/NKVE-03.jpg' },
    { desc:'NKVE near Jalan Duta KM23.85 SB', lat:3.18374, lon:101.61127, url:'https://p3.fgies.com/bucket-nkve/NKVE-23.jpg' },
    { desc:'NKVE near Bukit Lanjan KM22.4 NB', lat:3.18058, lon:101.59987, url:'https://p3.fgies.com/bucket-nkve/NKVE-17.jpg' },
    { desc:'NKVE near Bukit Lanjan KM21.9 SB', lat:3.18213, lon:101.60213, url:'https://p3.fgies.com/bucket-nkve/NKVE-04.jpg' },
    { desc:'NKVE near Kota Damansara KM19.75 SB', lat:3.15307, lon:101.59831, url:'https://p3.fgies.com/bucket-nkve/NKVE-22.jpg' },
    { desc:'NKVE near Damansara KM17.95 NB', lat:3.14151, lon:101.59637, url:'https://p3.fgies.com/bucket-nkve/NKVE-06.jpg' },
    { desc:'NKVE near Damansara I/C KM17.25 SB', lat:3.13608, lon:101.59683, url:'https://p3.fgies.com/bucket-nkve/NKVE-07.jpg' },
    { desc:'NKVE near Dataran Prima KM15.8 SB', lat:3.12263, lon:101.5947, url:'https://p3.fgies.com/bucket-nkve/NKVE-08.jpg' },
    { desc:'NKVE near Subang KM14.7 NB', lat:3.11275, lon:101.59243, url:'https://p3.fgies.com/bucket-nkve/NKVE-09.jpg' },
    { desc:'NKVE near Subang I/C KM14.0', lat:3.10611, lon:101.59055, url:'https://p3.fgies.com/bucket-nkve/NKVE-10.jpg' },
    { desc:'NKVE near Subang SB KM12.2 SB', lat:3.09997, lon:101.57684, url:'https://p3.fgies.com/bucket-nkve/NKVE-15.jpg' },
    { desc:'NKVE near Shah Alam KM11.35 NB', lat:3.0993, lon:101.56891, url:'https://p3.fgies.com/bucket-nkve/NKVE-11.jpg' },
    { desc:'NKVE near Shah Alam KM7.0 NB', lat:3.09485, lon:101.53211, url:'https://p3.fgies.com/bucket-nkve/NKVE-12.jpg' },
    { desc:'NKVE near Shah Alam KM10.3 SB', lat:3.09452, lon:101.56031, url:'https://p3.fgies.com/bucket-nkve/NKVE-13.jpg' },
    { desc:'NKVE near Shah Alam KM9.45 SB', lat:3.09295, lon:101.55141, url:'https://p3.fgies.com/bucket-nkve/NKVE-14.jpg' },
    { desc:'NKVE near Setia Alam KM3.3 NB', lat:3.0916, lon:101.49795, url:'https://p3.fgies.com/bucket-nkve/NKVE-16.jpg' },
    { desc:'PLUS-Utara near Sungai Buloh I/C KM453.9 SB', lat:3.224558, lon:101.575946, url:'https://p3.fgies.com/bucket-e1e2/E1E2-47.jpg' },
    { desc:'PLUS-Utara near Sungai Buloh I/C KM454.8 SB', lat:3.21692, lon:101.580448, url:'https://p3.fgies.com/bucket-e1e2/E1E2-27.jpg' },
    { desc:'PLUS-Utara near Sungai Buloh KM 456.4 SB', lat:3.203374, lon:101.582923, url:'https://p3.fgies.com/bucket-e1e2/E1E2-01.jpg' },
    { desc:'PLUS-Utara near Rawang Selatan IC KM446 SB', lat:3.279424, lon:101.556199, url:'https://p3.fgies.com/bucket-e1e2/E1E2-35.jpg' },
    { desc:'PLUS-Utara near Rawang KM444.9 NB', lat:3.291211, lon:101.549191, url:'https://p3.fgies.com/bucket-e1e2/E1E2-28.jpg' },
    { desc:'PLUS-Utara near Sungai Buaya IC KM434.7 NB', lat:3.373208, lon:101.559173, url:'https://p3.fgies.com/bucket-e1e2/E1E2-36.jpg' },
    { desc:'PLUS-Utara near Bukit Beruntung KM425.8 SB', lat:3.444298, lon:101.543011, url:'https://p3.fgies.com/bucket-e1e2/E1E2-03.jpg' },
    { desc:'PLUS-Utara near Bukit Tagar KM419.6 NB', lat:3.496848, lon:101.529987, url:'https://p3.fgies.com/bucket-e1e2/E1E2-04.jpg' },
    { desc:'PLUS-Utara near Tanjung Malim KM402.35 NB', lat:3.633005, lon:101.535, url:'https://p3.fgies.com/bucket-e1e2/E1E2-29.jpg' },
    { desc:'PLUS-Utara near Tanjung Malim KM396.4 NB', lat:3.67833, lon:101.499364, url:'https://p3.fgies.com/bucket-e1e2/E1E2-05.jpg' },
    { desc:'PLUS-Utara near Slim River KM373.9 NB', lat:3.841385, lon:101.407039, url:'https://p3.fgies.com/bucket-e1e2/E1E2-06.jpg' },
    { desc:'PLUS-Utara near Sungkai I/C KM354.4 NB', lat:3.983307, lon:101.324485, url:'https://p3.fgies.com/bucket-e1e2/E1E2-25.jpg' },
    { desc:'PLUS-Utara near Tapah KM324.4 SB', lat:4.236409, lon:101.255623, url:'https://p3.fgies.com/bucket-e1e2/E1E2-22.jpg' },
    { desc:'PLUS-Utara near Bidor I/C KM339.9 NB', lat:4.109615, lon:101.301479, url:'https://p3.fgies.com/bucket-e1e2/E1E2-08.jpg' },
    { desc:'PLUS-Utara near Tapah RSA KM333.6 SB', lat:4.164321, lon:101.299102, url:'https://p3.fgies.com/bucket-e1e2/E1E2-23.jpg' },
    { desc:'PLUS-Utara near Simpang Pulai KM290.55 SB', lat:4.500339, lon:101.151475, url:'https://p3.fgies.com/bucket-e1e2/E1E2-33.jpg' },
    { desc:'PLUS-Utara near Jelapang KM265 NB', lat:4.669918, lon:101.063508, url:'https://p3.fgies.com/bucket-e1e2/E1E2-30.jpg' },
    { desc:'PLUS-Utara near Vista Point KM263 NB', lat:4.679755, lon:101.043239, url:'https://p3.fgies.com/bucket-e1e2/E1E2-10.jpg' },
    { desc:'PLUS-Utara near Menora KM260.4 SB', lat:4.683454, lon:101.032149, url:'https://p3.fgies.com/bucket-e1e2/E1E2-41.jpg' },
    { desc:'PLUS-Utara near Menora KM260 NB', lat:4.688939, lon:101.022746, url:'https://p3.fgies.com/bucket-e1e2/E1E2-31.jpg' },
    { desc:'PLUS-Utara near Menora KM257 NB', lat:4.714621, lon:100.944392, url:'https://p3.fgies.com/bucket-e1e2/E1E2-11.jpg' },
    { desc:'PLUS-Utara near Sungai Perak RSA', lat:4.714621, lon:100.944392, url:'https://p3.fgies.com/bucket-e1e2/E1E2-13.jpg' },
    { desc:'PLUS-Utara near Bukit Gantang KM225.8 SB', lat:4.773383, lon:100.753231, url:'https://p3.fgies.com/bucket-e1e2/E1E2-12.jpg' },
    { desc:'PLUS-Utara near Changkat Jering KM219.8 NB', lat:4.787168, lon:100.703443, url:'https://p3.fgies.com/bucket-e1e2/E1E2-14.jpg' },
    { desc:'PLUS-Utara near Alor Pongsu IC KM181.5 SB', lat:5.067529, lon:100.591964, url:'https://p3.fgies.com/bucket-e1e2/E1E2-42.jpg' },
    { desc:'PLUS-Utara near Bandar Baharu Jawi KM165 NB', lat:5.173011, lon:100.503528, url:'https://p3.fgies.com/bucket-e1e2/E1E2-15.jpg' },
    { desc:'PLUS-Utara near Juru KM147.5', lat:5.308224, lon:100.440068, url:'https://p3.fgies.com/bucket-e1e2/E1E2-16.jpg' },
    { desc:'PLUS-Utara near Juru Toll Plaza KM145 NB', lat:5.324, lon:100.436105, url:'https://p3.fgies.com/bucket-e1e2/E1E2-38.jpg' },
    { desc:'PLUS-Utara near Seberang Jaya KM135.2 NB', lat:5.399455, lon:100.406655, url:'https://p3.fgies.com/bucket-e1e2/E1E2-17.jpg' },
    { desc:'PLUS-Utara near Sungai Dua Juru KM131.8 SB', lat:5.435692, lon:100.419001, url:'https://p3.fgies.com/bucket-e1e2/E1E2-18.jpg' },
    { desc:'PLUS-Utara near Sungai Dua KM130.95 SB', lat:5.435691, lon:100.419003, url:'https://p3.fgies.com/bucket-e1e2/E1E2-39.jpg' },
    { desc:'PLUS-Utara near Sungai Dua Toll Plaza KM128.6 NB', lat:5.458436, lon:100.419529, url:'https://p3.fgies.com/bucket-e1e2/E1E2-40.jpg' },
    { desc:'PLUS-Utara near Sungai Petani Bertam KM118.1 S', lat:5.539694, lon:100.435569, url:'https://p3.fgies.com/bucket-e1e2/E1E2-19.jpg' },
    { desc:'PLUS-Utara near Gurun KM65.4 NB', lat:5.962218, lon:100.446571, url:'https://p3.fgies.com/bucket-e1e2/E1E2-20.jpg' },
    { desc:'PLUS-Selatan near Sungai Besi KM310.8 NB', lat:3.04571, lon:101.70527, url:'https://p3.fgies.com/bucket-e2/E2-02.jpg' },
    { desc:'PLUS-Selatan near Kajang UPM KM303.7 NB', lat:2.99246, lon:101.73674, url:'https://p3.fgies.com/bucket-e2/E2-04.jpg' },
    { desc:'PLUS-Selatan near Kajang UPM KM303.7 NB', lat:2.99246, lon:101.73674, url:'https://p3.fgies.com/bucket-e2/E2-04.jpg' },
    { desc:'PLUS-Selatan near Southville City KM292.35 NB', lat:2.89885, lon:101.76684, url:'https://p3.fgies.com/bucket-e2/E2-35.jpg' },
    { desc:'PLUS-Selatan near Southville City KM295.4 SB', lat:2.92182, lon:101.75696, url:'https://p3.fgies.com/bucket-e2/E2-34.jpg' },
    { desc:'PLUS-Selatan near Bangi KM297.70 NB', lat:2.94458, lon:101.75216, url:'https://p3.fgies.com/bucket-e2/E2-21.jpg' },
    { desc:'PLUS-Selatan near Nilai Utara KM285.25 NB', lat:2.84574, lon:101.78719, url:'https://p3.fgies.com/bucket-e2/E2-23.jpg' },
    { desc:'PLUS-Selatan near Nilai KM285.8 NB', lat:2.85159, lon:101.78746, url:'https://p3.fgies.com/bucket-e2/E2-31.jpg' },
    { desc:'PLUS-Selatan near Nilai KM281.7 SB', lat:2.81977, lon:101.80262, url:'https://p3.fgies.com/bucket-e2/E2-22.jpg' },
    { desc:'PLUS-Selatan near Nilai IC KM283.6 NB', lat:2.83243, lon:101.79108, url:'https://p3.fgies.com/bucket-e2/E2-30.jpg' },
    { desc:'PLUS-Selatan near Seremban KM278.3 SB', lat:2.79398, lon:101.8116, url:'https://p3.fgies.com/bucket-e2/E2-32.jpg' },
    { desc:'PLUS-Selatan near Seremban KM276.1 NB', lat:2.77506, lon:101.81606, url:'https://p3.fgies.com/bucket-e2/E2-33.jpg' },
    { desc:'PLUS-Selatan near Seremban RSA KM274.3 NB', lat:2.7639, lon:101.82948, url:'https://p3.fgies.com/bucket-e2/E2-24.jpg' },
    { desc:'PLUS-Selatan near Seremban RSA KM272.15 SB', lat:2.75789, lon:101.84676, url:'https://p3.fgies.com/bucket-e2/E2-05.jpg' },
    { desc:'PLUS-Selatan near Bandar Ainsdale I/C KM267.65 NB', lat:2.74053, lon:101.8832, url:'https://p3.fgies.com/bucket-e2/E2-20.jpg' },
    { desc:'PLUS-Selatan near Seremban KM261.45 NB', lat:2.723897, lon:101.901342, url:'https://p3.fgies.com/bucket-e2/E2-26.jpg' },
    { desc:'PLUS-Selatan near Port Dickson KM258.5 NB', lat:2.685518, lon:101.940268, url:'https://p3.fgies.com/bucket-e2/E2-25.jpg' },
    { desc:'PLUS-Selatan near Pedas Linggi KM241.0 SB', lat:2.580998, lon:102.037725, url:'https://p3.fgies.com/bucket-e2/E2-07.jpg' },
    { desc:'PLUS-Selatan near Pedas Linggi KM238.75 NB', lat:2.560757, lon:102.04687, url:'https://p3.fgies.com/bucket-e2/E2-08.jpg' },
    { desc:'PLUS-Selatan near Jasin KM178 NB', lat:2.263596, lon:102.453241, url:'https://p3.fgies.com/bucket-e2/E2-10.jpg' },
    { desc:'PLUS-Selatan near Tangkak I/C KM170.7 SB', lat:2.24760176272261, lon:102.52303203708, url:'https://p3.fgies.com/bucket-e2/E2-29.jpg' },
    { desc:'PLUS-Selatan near Bukit Gambir I/C KM156.7 NB', lat:2.19764120478173, lon:102.625657241608, url:'https://p3.fgies.com/bucket-e2/E2-28.jpg' },
    { desc:'PLUS-Selatan near Pagoh RSA SB', lat:2.12149552398721, lon:102.793036625179, url:'https://p3.fgies.com/bucket-e2/E2-11.jpg' },
    { desc:'PLUS-Selatan near Yong Peng Selatan KM91.8 NB', lat:1.98370921224128, lon:103.103060571147, url:'https://p3.fgies.com/bucket-e2/E2-19.jpg' },
    { desc:'PLUS-Selatan near Ayer Hitam KM80.1 SB', lat:1.9273944110979, lon:103.187995462374, url:'https://p3.fgies.com/bucket-e2/E2-12.jpg' },
    { desc:'PLUS-Selatan near Kulai KM26.0 SB', lat:1.63742303425013, lon:103.563708208515, url:'https://p3.fgies.com/bucket-e2/E2-18.jpg' },
];

(function() {
    'use strict';
    var settings = {};

    function bootstrap(tries = 1) {
        if (W && W.map && W.model && W.loginManager.user &&
            $ && WazeWrap.Ready) {
            init();
        } else if (tries < 1000) {
            setTimeout(function () {bootstrap(++tries);}, 200);
        } else {
            WazeWrap.Alerts.error(GM_info.script.name, "Bootstrap timeout.")
        }
    }

    async function init() {
        let $section = $('<div>');
        $section.html([
            '<div>',
            'Version: <span id="wazemyVersion"></span><br>',
            '<span id="wazemyUsername"></span> (<span id="wazemyRank"></span>)',
            '</div><br>',
            '<div id="wazemySettings">',
            '<b>Settings</b><br>',
            '<input type="checkbox" id="wazemySettings_tooltip">',
            '<label for="wazemySettings_tooltip">Map tooltip</label><br>',
            '<input type="checkbox" id="wazemySettings_trafcam">',
            '<label for="wazemySettings_trafcam">Traffic cameras</label><br>',
            '</div><br>',
            '<div>',
            '<b>Shortcuts</b><br>',
            'Ctrl+Alt+C: Copy lat/lon of mouse position to clipboard.<br>',
            '</div>'
        ].join(' '));
        
        // Initialize features of WME WazeMY
        wazemyTooltip_init();
        wazemyTrafcam_init();

        new WazeWrap.Interface.Tab('WazeMY', $section.html(), initializeSettings);
        WazeWrap.Interface.ShowScriptUpdate("WME WazeMY", GM_info.script.version, 
            updateMessage, "https://greasyfork.org/en/scripts/404584-wazemy", null);

        // Initialize keyboard shortcuts
        new WazeWrap.Interface.Shortcut('WazeMY_latloncopy', 
            'Copies lat/lon of mouse position', 'wazemy', 'WazeMY', 'CA+c', 
            wazemyCopyLatLon, null).add();
    }

    /* ******* */
    /* Tooltip */
    /* ******* */
    function wazemyTooltip_init() {
        let $tooltip = $('<div/>');
        $tooltip.attr('id', 'wazemyTooltip');
        $tooltip.css({
            'height':'auto',
            'width':'auto',
            'background':'rgba(0,0,0,0.5)',
            'color':'white',
            'borderRadius':'5px',
            'padding':'5px',
            'position':'absolute',
            'top':'0px',
            'left':'0px',
            'visibility':'hidden',
            'zIndex':'10000'
        })
        $tooltip.appendTo('body');
    }

    function wazemyTooltip_initSettings() {
        setChecked('wazemySettings_tooltip', settings.tooltip);
        if (settings.tooltip) {
            WazeWrap.Events.register('mousemove', null, wazemyTooltip_show);
        }
        $('#wazemySettings_tooltip').change(function () {
            var settingName = $(this)[0].id.substr(15); // strip off the "wazemySettings_" prefix
            settings[settingName] = this.checked;
            saveSettings();
            if (this.checked) {
                WazeWrap.Events.register('mousemove', null, wazemyTooltip_show);
            }
            else {
                WazeWrap.Events.unregister('mousemove', null, wazemyTooltip_show);
            }
        });
    }

    function wazemyTooltip_show(e) { // from URO+
        var result = '';
        var showTooltip = false;

        let landmark = W.map.venueLayer.getFeatureBy('renderIntent', 'highlight');
        let segment = W.map.segmentLayer.getFeatureBy('renderIntent', 'highlight');

        if (landmark != null) {
            result = '<b>' + landmark.model.attributes.name + '</b><br>';
            let address = landmark.model.getAddress();
            try {
                result += address.attributes.houseNumber ? (address.attributes.houseNumber + ', ') : ''
                result += (address.attributes.street.name ? address.attributes.street.name : 'No street') + '<br>';
                result += address.attributes.city.attributes.name + ', ';
                result += address.attributes.state.name + '<br>';
            }
            catch {
                result += 'No address<br>';
            }
            result += '<b>Lock:</b> ' + (landmark.model.getLockRank() + 1);
            showTooltip = true;
        } else if (segment != null) {
            let segmentId = segment.model.attributes.id;
            // let primaryStreetId = WazeWrap.Model.getPrimaryStreetId(segmentId);
            let address = segment.model.getAddress();
            result = '<b>';
            result += address.attributes.street.name ? address.attributes.street.name : 'No street';
            result += '</b><br>';
            result += address.attributes.city.attributes.name + ', ' + address.attributes.state.name;
            result += '<br>';
            result += '<b>ID:</b> ' + segmentId + '<br>';
            result += '<b>Lock:</b> ' + (segment.model.getLockRank() + 1);
            showTooltip = true;
        }

        if (showTooltip == true) {
            let tw = $('#wazemyTooltip').width();
            let th = $('#wazemyTooltip').height();
            var tooltipX = e.clientX + window.scrollX + 15;
            var tooltipY = e.clientY + window.scrollY + 15;
            if ((tooltipX + tw) > W.map.$map.innerWidth()) {
                tooltipX -= tw + 20; // 20 = scroll bar size
                if (tooltipX < 0) tooltipX = 0;
            }
            if ((tooltipY + th) > W.map.$map.innerHeight()) {
                tooltipY -= th + 20;
                if (tooltipY < 0) tooltipY = 0;
            }
            $('#wazemyTooltip').html(result);
            $('#wazemyTooltip').css({
                'top':tooltipY + 'px',
                'left':tooltipX + 'px',
                'visibility':'visible'
            });
        } else {
            $('#wazemyTooltip').css('visibility', 'hidden');
        }
    }

    /* *************** */
    /* Traffic cameras */
    /* *************** */
    // Adapted from WME DOT Cameras
    var wazemyTrafcamLayer;

    function wazemyTrafcam_init() {
        if (!OpenLayers.Icon) {
            wazemyTrafcam_installIconClass();
        }
        wazemyTrafcamLayer = new OpenLayers.Layer.Markers("wazemyTrafcamLayer");
        W.map.addLayer(wazemyTrafcamLayer);
        wazemyTrafcam_show();
        wazemyTrafcamLayer.setVisibility(false);
    }

    function wazemyTrafcam_initSettings() {
        setChecked('wazemySettings_trafcam', settings.trafcam);
        if (settings.trafcam) {
            wazemyTrafcamLayer.setVisibility(true);
            // WazeWrap.Events.register('moveend', null, wazemyTrafcam_show);
        }
        $('#wazemySettings_trafcam').change(function () {
            var settingName = $(this)[0].id.substr(15); // strip off the "wazemySettings_" prefix
            settings[settingName] = this.checked;
            saveSettings();
            if (this.checked) {
                wazemyTrafcamLayer.setVisibility(true);
                // WazeWrap.Events.register('moveend', null, wazemyTrafcam_show);
            } else {
                // WazeWrap.Events.unregister('moveend', null, wazemyTrafcam_show);
               wazemyTrafcamLayer.setVisibility(false);
            }
        });
    }

    function wazemyTrafcam_show(e) {
        trafficCamsData.forEach(e => {
            wazemyTrafcam_drawCam({
                desc:e.desc,
                src:e.url,
                width:20,
                height:20,
                lat:e.lat,
                lon:e.lon
            });
        });
    }

    function wazemyTrafcam_drawCam(spec) {
        const camIcon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAAGXcA1uAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2ZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYxIDY0LjE0MDk0OSwgMjAxMC8xMi8wNy0xMDo1NzowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpBRDNGNTkwRTYzQThFMzExQTc4MDhDNjAwODdEMzdEQSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo2OUI0RUEyN0IwRjcxMUUzOERFM0E1OTJCRUY3NTFBOCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo2OUI0RUEyNkIwRjcxMUUzOERFM0E1OTJCRUY3NTFBOCIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1LjEgV2luZG93cyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjZGOEJBMzExNkZCMEUzMTFCOEY5QTU3QUQxM0M2MjI5IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkFEM0Y1OTBFNjNBOEUzMTFBNzgwOEM2MDA4N0QzN0RBIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+TV0cjwAABbhJREFUeNpiYIAAXiZGCIMPiP//f8DwnwnI+PT/HZD8y8AAEEBQVQzTwOSfuwz/u6qAyh4y/Gf8f4/hPwMnUJSZgQEggMCyzpZAmbsILMTHcAokPhPEWT8dqJoBgvetAtMMDBIiDCf/P4bqeMXwf+t8BiOAAGJAAqVA7A1iPH/+goFBT4OB8f9LJDueAzFQgOHGLoTZYEGgpJgww0+G/68ZQArAEsryEHpRN5BuK4FIcHMhjJORVTvBYG3MwPD2CkKwKAVI/3nBABBAYOcY6zKAjGSQEmP4cGkXxMlgK4BeaCll+B/lzzDh/yegmr8vIO4HGv/l/0eG/w4WDP9fnUM4Dhl/uMzwf/6CFQ4g9RUgE3ctRvgGGSvJMfw/tw3i7sY8hv8sQMGrQE8yuFoBZe8CeRwMDIKaDAyWRgwM2xYD+exA/AuIvwAV3kaE6sSPQCuBHv2vqczwf0YL0MR7SE4CsgsTGP5///aSCZQSGDRVGPJfv2dgNDNkcP30heHbB6BpyzYyMCRVMjCwqDIcOX+LgTEtioGRhfn/P4AAbJTfK0NhGMe/Z+ecpVkrScnIlCiWkoulpFyhxgXKXCGK3XGBG/4BJcoNN665tqsxo6XshiKtyQybn82vMZPF63nPOXKYi+fieU7P8z59P9/n6NlBVNrRRDFPMUlRIGhmM0gWzk5NSCFMuDE2MqAaUJGUhDgOgNmKkXmLwMRudA11diynI9lSKhEHG+oBu9q1mHkDf9AWWkM0dgHEb4H+PqqkKD51uxpJuSoDHpIfAowyohyUveJH+9pqUjigav/9UnIfzO/frkRvBxUuwcpK/gc3PkzfzynuwRoanYuStZDKaeAkwA8QEPJ/CYfpBUCmqxp1E7uXJ6u0tUNVQbvIR+DIBzgHgQMvrZ5LZWIiSuowh6N+nQ9ZYgnNcLTzdRBsz5Ot1socWCr1KipYulrJVDIQjqjwgqsESvcPQB5QWmP2nsWem5X80IeizhaadPfHQwTxnXJTDk5ZQgeOOCC0ScY0wtPdRrc4AzY7BVZuQ8bVDhcXJLyhNnwJUFj5hTQVhmH8mQ7H5nYYkRxJw8hqBWYsLIr+gisKYobdjKguClOKLiQvgrrwqogiIr1wECHdRCCjIopNiCKZIGkthysrrWSklg36M6O5fT3fzmk7C8kDL4zt2/neP8/ze01/b6XuceWsVmAJJR56gurObjSn0/DWrEY152SmIyFBNk1sxZhBZAQTyVmEDjeiy9eAQdm4FK1gLlHg8Y3CYlXzZW12A1+GYd1Yi1u1LogXQSYgmxdnjM8jsTFNZvLMxADE3h0QS8vxNNqLJWKa2ZMXBRXwaaNmL/XdoUct+hhtjF+MFBZ+zJq5Gw6ywoRyI/xs/JjJtCj38+XWo3rGdM6pI3nlqYshmmiGx7fJpLE8rAqGZQy+49o5CNeauoeplJZZPbWfztqSWurvmV/ixrCXQjRSFQE/xI8R/dK44VJae99OorWt/Xh2tZxp0Q+903zynX/q6YLwevgy28IXyiBYxCY3cXYeIvGGRL0Isc697Z5k0NRMQj8Grd92zuDALuAuIRm8CVSohe1uYZ+T74FwADjdBFBh6GgH+mm3ZuLDSb9Ocg9YLNYZOeSyUitevupFeWWVTlzjQ0dNfQJW1fOybulPWlmyZ85wpshQC43/m+9YsR2ZTn9wg5z955+z2FO3H0PRIIqcHHzgPpAgNukwOJzAwCB3NiFQxsyyjJ37J4lMXklpfnaRyidaO3xe7+6h3JmVy2CjkcInD3EO3/T1xsFn3mobX0z+RzkfNAxcpXrIjo+RkFKp0VLkk1hfwwqJr69RODxbcH05gem/wIEN62TV13XuMxNIvqYYqCT6R6x14UHsEarkwhBxJbtnC4wmS9fXDuT2stFkxIDsp4tfbZU5MCr0jnMbIMLoKy7Gc8WunU3rxHMoCmKxUaiqij/5alOWhMPoGAAAAABJRU5ErkJggg==';
        let size = new OpenLayers.Size(20,20);
        let icon = new OpenLayers.Icon(camIcon, size);
        let epsg4326 = new OpenLayers.Projection("EPSG:4326"); // WGS 1984 projection. Malaysia uses EPSG:900913
        let projectTo = W.map.getProjectionObject();
        let lonLat = new OpenLayers.LonLat(spec.lon, spec.lat).transform(epsg4326, projectTo);
        var newMarker = new OpenLayers.Marker(lonLat, icon);
        newMarker.title = spec.desc;
        newMarker.url = spec.src;
        newMarker.width = spec.width;
        newMarker.height = spec.height;
        newMarker.location = lonLat;
        newMarker.events.register('click', newMarker, wazemyTrafcam_popupCam);
        wazemyTrafcamLayer.addMarker(newMarker);
    }

    function wazemyTrafcam_popupCam(e) {
        console.log("wazemyTrafcam_popupCam");

        clearInterval(staticUpdateID);
        $("#gmPopupContainerCam").remove();
        $("#gmPopupContainerCam").hide();

        var popupHTML = ([`
            <div id="gmPopupContainerCam" style="margin: 1;text-align: center;padding: 5px;z-index: 1100; position: absolute; color: white; background: rgba(0,0,0,0.5)">
            <table border=0>
                <tr>
                    <td><div id="mycamdivheader" style="min-height: 20px;white-space: pre-wrap;white-space: -moz-pre-wrap; white-space: -pre-wrap;white-space: -o-pre-wrap;word-wrap: break-word;width:380px">${this.title}</div></td>
                    <td align="right"><a href="#close" id="gmCloseCamDlgBtn" title="Close" style="color:red">X</a></td>
                </tr>
                <tr><td colspan=2><img style="width:400px" id="staticimage"></td></tr>
            </table></div>
        `]);
        $("body").append(popupHTML);
        GM_xmlhttpRequest({
            method: 'GET',
            responseType: 'blob',
            headers: {
                "authority":"p4.fgies.com",
                "referer":'https://www.jalanow.com/',
                'accept':'image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8'
            },
            url: this.url,
            onload: function (response) {
                document.getElementById('staticimage').src = URL.createObjectURL(response.response);
            }
        });
        $("#gmPopupContainerCam").css({ left: e.clientX + window.scrollX + 15 });
        $("#gmPopupContainerCam").css({ top: e.clientY + window.scrollY + 15 });

        //Add listener for popup's "Close" button
        $("#gmCloseCamDlgBtn").click(function () {
            clearInterval(staticUpdateID);
            $("#gmPopupContainerCam").remove();
            $("#gmPopupContainerCam").hide();
        });
        wazemyTrafcam_dragElement(document.getElementById("gmPopupContainerCam"));
    }

    function wazemyTrafcam_installIconClass() {
        OpenLayers.Icon = OpenLayers.Class({
            url: null,
            size: null,
            offset: null,
            calculateOffset: null,
            imageDiv: null,
            px: null,
            initialize: function (a, b, c, d) {
                this.url = a;
                this.size = b || {
                    w: 20,
                    h: 20
                };
                this.offset = c || {
                    x: -(this.size.w / 2),
                    y: -(this.size.h / 2)
                };
                this.calculateOffset = d;
                a = OpenLayers.Util.createUniqueID("OL_Icon_");
                let div = this.imageDiv = OpenLayers.Util.createAlphaImageDiv(a);
                $(div.firstChild).removeClass('olAlphaImg'); // LEAVE THIS LINE TO PREVENT WME-HARDHATS SCRIPT FROM TURNING ALL ICONS INTO HARDHAT WAZERS --MAPOMATIC
            },
            destroy: function () {
                this.erase();
                OpenLayers.Event.stopObservingElement(this.imageDiv.firstChild);
                this.imageDiv.innerHTML = "";
                this.imageDiv = null;
            },
            clone: function () {
                return new OpenLayers.Icon(this.url, this.size, this.offset, this.calculateOffset);
            },
            setSize: function (a) {
                null !== a && (this.size = a);
                this.draw();
            },
            setUrl: function (a) {
                null !== a && (this.url = a);
                this.draw();
            },
            draw: function (a) {
                OpenLayers.Util.modifyAlphaImageDiv(this.imageDiv, null, null, this.size, this.url, "absolute");
                this.moveTo(a);
                return this.imageDiv;
            },
            erase: function () {
                null !== this.imageDiv && null !== this.imageDiv.parentNode && OpenLayers.Element.remove(this.imageDiv);
            },
            setOpacity: function (a) {
                OpenLayers.Util.modifyAlphaImageDiv(this.imageDiv, null, null, null, null, null, null, null, a);
            },
            moveTo: function (a) {
                null !== a && (this.px = a);
                null !== this.imageDiv && (null === this.px ? this.display(!1) : (
                    this.calculateOffset && (this.offset = this.calculateOffset(this.size)),
                    OpenLayers.Util.modifyAlphaImageDiv(this.imageDiv, null, {
                        x: this.px.x + this.offset.x,
                        y: this.px.y + this.offset.y
                    })
                ));
            },
            display: function (a) {
                this.imageDiv.style.display = a ? "" : "none";
            },
            isDrawn: function () {
                return this.imageDiv && this.imageDiv.parentNode && 11 != this.imageDiv.parentNode.nodeType;
            },
            CLASS_NAME: "OpenLayers.Icon"
        });
    }

    // Make the DIV element draggable:
    function wazemyTrafcam_dragElement(elmnt) {
        var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
        if (document.getElementById("mycamdivheader")) {
            // if present, the header is where you move the DIV from:
            document.getElementById("mycamdivheader").onmousedown = dragMouseDown;
        } else {
            // otherwise, move the DIV from anywhere inside the DIV:
            elmnt.onmousedown = dragMouseDown;
        }

        function dragMouseDown(e) {
            e = e || window.event;
            e.preventDefault();
            // get the mouse cursor position at startup:
            pos3 = e.clientX;
            pos4 = e.clientY;
            document.onmouseup = closeDragElement;
            // call a function whenever the cursor moves:
            document.onmousemove = elementDrag;
        }

        function elementDrag(e) {
            e = e || window.event;
            e.preventDefault();
            // calculate the new cursor position:
            pos1 = pos3 - e.clientX;
            pos2 = pos4 - e.clientY;
            pos3 = e.clientX;
            pos4 = e.clientY;
            // set the element's new position:
            elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
            elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
        }

        function closeDragElement() {
            // stop moving when mouse button is released:
            document.onmouseup = null;
            document.onmousemove = null;
        }
    }

    /* ************ */
    /* Copy lat/lon */
    /* ************ */
    function wazemyCopyLatLon(){
        copyToClipboard($('.mouse-position').text());
    }

    function initializeSettings() {
        loadSettings();

        $('#wazemyVersion').text(GM_info.script.version);
        $('#wazemyUsername').text(WazeWrap.User.Username());
        $('#wazemyRank').text(WazeWrap.User.Rank());

        wazemyTooltip_initSettings();
        wazemyTrafcam_initSettings();
    }

    function saveSettings() {
        if (localStorage) {
            var localsettings = {
                tooltip: settings.tooltip,
                trafcam: settings.trafcam
            };

            localStorage.setItem('WME_wazemySettings', JSON.stringify(localsettings));
        }
    }

    function loadSettings() {
        var loadedSettings = $.parseJSON(localStorage.getItem("WME_wazemySettings"));
        var defaultSettings = {
            tooltip: false,
        };
        settings = loadedSettings ? loadedSettings : defaultSettings;
        for (var prop in defaultSettings) {
            if (!settings.hasOwnProperty(prop)) {
                settings[prop] = defaultSettings[prop];
            }
        }
    }

    function setChecked(checkboxId, checked) {
        $('#' + checkboxId).prop('checked', checked);
    }

    // utility functions
    var copyToClipboard = function(str) { // from PIE
        var $temp = $('<input>');
        $('body').append($temp);
        $temp.val(str).select();
        document.execCommand('copy');
        $temp.remove();
    };

    bootstrap();
})();