├── .gitignore ├── src ├── images │ ├── icon-128.png │ ├── icon-16.png │ ├── icon-19.png │ ├── icon-48.png │ ├── active-19.png │ ├── active-38.png │ ├── inactive-19.png │ └── inactive-38.png ├── scripts │ ├── content │ │ ├── toggl.js │ │ ├── xero.js │ │ ├── todoist.js │ │ ├── teamweek.js │ │ ├── capsule.js │ │ ├── unfuddle.js │ │ ├── anydo.js │ │ ├── redbooth.js │ │ ├── pivotal.js │ │ ├── asana.js │ │ ├── worksection.js │ │ ├── redmine.js │ │ ├── bitbucket.js │ │ ├── gitlab.js │ │ ├── youtrack.js │ │ ├── github.js │ │ ├── producteev.js │ │ ├── sifterapp.js │ │ ├── google-docs.js │ │ ├── zendesk.js │ │ ├── teamweek_new.js │ │ ├── basecamp.js │ │ ├── podio.js │ │ ├── trac.js │ │ ├── trello.js │ │ ├── wunderlist.js │ │ └── jira.js │ ├── settings.js │ ├── popup.js │ ├── common.js │ └── background.js ├── html │ ├── settings.html │ └── popup.html ├── manifest.json └── styles │ ├── settings.css │ ├── popup.css │ └── style.css ├── Makefile ├── package.json ├── README.md ├── Gruntfile.js ├── CHANGES └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | tmp 4 | *.pem 5 | toggl-button.zip 6 | /.idea 7 | -------------------------------------------------------------------------------- /src/images/icon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outlandishideas/toggl-button/master/src/images/icon-128.png -------------------------------------------------------------------------------- /src/images/icon-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outlandishideas/toggl-button/master/src/images/icon-16.png -------------------------------------------------------------------------------- /src/images/icon-19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outlandishideas/toggl-button/master/src/images/icon-19.png -------------------------------------------------------------------------------- /src/images/icon-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outlandishideas/toggl-button/master/src/images/icon-48.png -------------------------------------------------------------------------------- /src/images/active-19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outlandishideas/toggl-button/master/src/images/active-19.png -------------------------------------------------------------------------------- /src/images/active-38.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outlandishideas/toggl-button/master/src/images/active-38.png -------------------------------------------------------------------------------- /src/images/inactive-19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outlandishideas/toggl-button/master/src/images/inactive-19.png -------------------------------------------------------------------------------- /src/images/inactive-38.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outlandishideas/toggl-button/master/src/images/inactive-38.png -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | default: lint 2 | 3 | lint: 4 | @node_modules/.bin/jslint src/scripts/*.js src/scripts/content/*.js 5 | 6 | dist: clean 7 | @if [ ! -d "out" ]; then mkdir -p out; fi 8 | @cp -R src/manifest.json src/images src/scripts src/styles src/html out/ 9 | @zip -q -r toggl-button out && rm -rf out 10 | 11 | clean: 12 | @if [ -f "toggl-button.zip" ]; then rm toggl-button.zip; fi 13 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "toggl-button", 3 | "version": "0.2.13", 4 | "description": "Add Toggl one-click time tracking to popular web tools.", 5 | "license": "BSD-3-Clause", 6 | "private": true, 7 | "devDependencies": { 8 | "grunt": "~0.4.4", 9 | "grunt-crx": "~0.3.3", 10 | "grunt-jslint": "~1.1.8", 11 | "grunt-contrib-compress": "~0.7.0", 12 | "jslint": "~0.5.2" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Toggl Button Chrome extension 2 | 3 | Add Toggl one-click time tracking to [YouTrack tracker](http://tracker.outlandish.com) (forked from [toggl's original](https://github.com/toggl/toggl-button)) 4 | 5 | ## Installing from the Web Store 6 | 7 | [https://chrome.google.com/webstore/detail/toggl-button/afeofloaalhffmmnafpcdbbcanlfajjn](https://chrome.google.com/webstore/detail/toggl-button/afeofloaalhffmmnafpcdbbcanlfajjn) 8 | -------------------------------------------------------------------------------- /src/scripts/content/toggl.js: -------------------------------------------------------------------------------- 1 | /*jslint indent: 2 */ 2 | /*global $: false, localStorage: false, chrome:false*/ 3 | 4 | 'use strict'; 5 | 6 | var userData, offlineUser; 7 | offlineUser = localStorage.getItem('offline_users'); 8 | 9 | if (offlineUser) { 10 | userData = JSON.parse(localStorage.getItem('offline_users-' + offlineUser)); 11 | if (userData && userData.offlineData) { 12 | chrome.extension.sendMessage({ 13 | type: 'userToken', 14 | apiToken: userData.offlineData.api_token 15 | }); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/scripts/content/xero.js: -------------------------------------------------------------------------------- 1 | /*jslint indent: 2, unparam: true*/ 2 | /*global $: false, createTag: false, togglbutton: false*/ 3 | 4 | 'use strict'; 5 | 6 | togglbutton.render('#frmMain', {}, function (elem) { 7 | var link, liTag; 8 | 9 | link = togglbutton.createTimerLink({ 10 | className: 'xero', 11 | projectName: 'Finance', 12 | description: $('#frmMain h1').innerText 13 | }); 14 | 15 | liTag = createTag("li", "xn-h-menu"); 16 | liTag.appendChild(link); 17 | $('.xn-h-header-tabs ul').appendChild(liTag); 18 | }); 19 | -------------------------------------------------------------------------------- /src/scripts/content/todoist.js: -------------------------------------------------------------------------------- 1 | /*jslint indent: 2 */ 2 | /*global $: false, togglbutton: false*/ 3 | 4 | 'use strict'; 5 | 6 | togglbutton.render('.task_item .content:not(.toggl)', {observe: true}, function (elem) { 7 | var link, container = $('.text', elem), 8 | projectElem = $('.project_link'); 9 | 10 | link = togglbutton.createTimerLink({ 11 | className: 'todoist', 12 | description: container.firstChild.textContent, 13 | projectName: projectElem && projectElem.textContent 14 | }); 15 | 16 | container.insertBefore(link, container.lastChild); 17 | }); 18 | -------------------------------------------------------------------------------- /src/html/settings.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Toggl Button - Settings 5 | 6 | 7 | 8 |
9 | 10 |
11 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/scripts/content/teamweek.js: -------------------------------------------------------------------------------- 1 | /*jslint indent: 2 */ 2 | /*global $: false, document: false, togglbutton: false*/ 3 | 4 | 'use strict'; 5 | 6 | togglbutton.render('.popup-content:not(.toggl)', {observe: true}, function (elem) { 7 | var link, titleElem = $('#event-description', elem); 8 | if (titleElem === null) { 9 | return; 10 | } 11 | 12 | link = togglbutton.createTimerLink({ 13 | className: 'teamweek', 14 | description: titleElem.value, 15 | projectId: $('#toggl-project-id', elem).value 16 | }); 17 | 18 | $('.task_done_buttons').appendChild(link); 19 | }); 20 | -------------------------------------------------------------------------------- /src/scripts/content/capsule.js: -------------------------------------------------------------------------------- 1 | /*jslint indent: 2 */ 2 | /*global $: false, document: false, togglbutton: false*/ 3 | 4 | 'use strict'; 5 | // observe: true 6 | togglbutton.render('body', {}, function (elem) { 7 | var link, liTag; 8 | 9 | link = togglbutton.createTimerLink({ 10 | className: 'capsule', 11 | description: $('.currentPage', elem).textContent, 12 | projectName: '' 13 | }); 14 | 15 | liTag = document.createElement("li"); 16 | liTag.className = 'item'; 17 | liTag.appendChild(link); 18 | $('ul.pageActions').insertBefore(liTag, $('ul.pageActions li')); 19 | }); 20 | -------------------------------------------------------------------------------- /src/scripts/content/unfuddle.js: -------------------------------------------------------------------------------- 1 | /*jslint indent: 2 */ 2 | /*global $: false, document: false, togglbutton: false*/ 3 | 4 | 'use strict'; 5 | 6 | togglbutton.render('.ticket-fields-panel:not(.toggl)', {observe: true}, function (elem) { 7 | var link, description, 8 | titleElem = $("h1.summary .number", elem), 9 | numElem = $("h1.summary .text-field-text", elem); 10 | 11 | description = titleElem.innerText + ": " + numElem.innerText; 12 | 13 | link = togglbutton.createTimerLink({ 14 | className: 'unfuddle', 15 | description: description, 16 | }); 17 | 18 | $(".primary-properties", elem).appendChild(link); 19 | }); 20 | -------------------------------------------------------------------------------- /src/scripts/content/anydo.js: -------------------------------------------------------------------------------- 1 | /*jslint indent: 2 */ 2 | /*global $: false, togglbutton: false, createTag:false*/ 3 | 4 | 'use strict'; 5 | 6 | togglbutton.render('.task-details:not(.toggl)', {observe: true}, function (elem) { 7 | var link, wrap = createTag('div'), 8 | container = $('.top-level-details', elem), 9 | titleElem = $('#quickTitle', elem), 10 | projectElem = $('.folderSelector', elem); 11 | 12 | link = togglbutton.createTimerLink({ 13 | className: 'anydo', 14 | description: titleElem.textContent, 15 | projectName: projectElem.textContent 16 | }); 17 | 18 | wrap.appendChild(link); 19 | container.appendChild(wrap); 20 | }); 21 | -------------------------------------------------------------------------------- /src/scripts/content/redbooth.js: -------------------------------------------------------------------------------- 1 | /*jslint indent: 2 */ 2 | /*global $: false, document: false, togglbutton: false*/ 3 | 4 | 'use strict'; 5 | 6 | togglbutton.render('.js-right-pane .tb-element-big:not(.toggl)', {observe: true}, function (elem) { 7 | var link, 8 | container = $('.tb-element-title', elem), 9 | projectElem = $('.tb-element-subtitle a', elem), 10 | titleElem = $('.js-element-title-inner a', container); 11 | 12 | link = togglbutton.createTimerLink({ 13 | className: 'redbooth', 14 | description: titleElem.textContent, 15 | projectName: projectElem && projectElem.textContent 16 | }); 17 | 18 | container.appendChild(link); 19 | }); 20 | -------------------------------------------------------------------------------- /src/scripts/content/pivotal.js: -------------------------------------------------------------------------------- 1 | /*jslint indent: 2 */ 2 | /*global $: false, document: false, togglbutton: false*/ 3 | 4 | "use strict"; 5 | 6 | togglbutton.render('form.story:not(.toggl)', {observe: true}, function (elem) { 7 | var link, 8 | titleElem = $('textarea', elem), 9 | container = $('.edit aside', elem), 10 | projectName = $('title').textContent; 11 | 12 | if (titleElem === null || container === null) { 13 | return; 14 | } 15 | 16 | link = togglbutton.createTimerLink({ 17 | className: 'pivotal', 18 | description: titleElem.value, 19 | projectName: projectName && projectName.split(' -').shift() 20 | }); 21 | 22 | container.appendChild(link); 23 | }); 24 | -------------------------------------------------------------------------------- /src/scripts/content/asana.js: -------------------------------------------------------------------------------- 1 | /*jslint indent: 2 */ 2 | /*global $: false, document: false, togglbutton: false*/ 3 | 4 | 'use strict'; 5 | 6 | togglbutton.render('.details-pane-body:not(.toggl)', {observe: true}, function (elem) { 7 | 8 | var link, 9 | container = $('.sticky-view-placeholder', elem), 10 | description = $('#details_property_sheet_title', elem), 11 | project = $('#details_pane_project_tokenizer .token_name', elem); 12 | 13 | link = togglbutton.createTimerLink({ 14 | className: 'asana', 15 | description: description.value, 16 | projectName: project && project.textContent 17 | }); 18 | 19 | container.parentNode.insertBefore(link, container.nextSibling); 20 | }); 21 | -------------------------------------------------------------------------------- /src/scripts/content/worksection.js: -------------------------------------------------------------------------------- 1 | /*jslint indent: 2 */ 2 | /*global $: false, document: false, togglbutton: false*/ 3 | 4 | 'use strict'; 5 | 6 | togglbutton.render('.task:not(.toggl)', {}, function (elem) { 7 | var link, 8 | projectElem = $('#client_name a'), 9 | taskElem = $('#tasks > .task > h1'); 10 | 11 | if (taskElem === null || taskElem.firstChild === null) { 12 | return; 13 | } 14 | 15 | link = togglbutton.createTimerLink({ 16 | className: 'worksection', 17 | description: taskElem.firstChild.textContent.trim(), 18 | projectName: projectElem && projectElem.innerText.trim() 19 | }); 20 | link.classList.add('norm'); 21 | 22 | $('#tmenu2', elem).appendChild(link); 23 | }); 24 | -------------------------------------------------------------------------------- /src/scripts/content/redmine.js: -------------------------------------------------------------------------------- 1 | /*jslint indent: 2, unparam: true*/ 2 | /*global $: false, document: false, togglbutton: false*/ 3 | 'use strict'; 4 | 5 | togglbutton.render('body.controller-issues.action-show h2', {}, function (elem) { 6 | var link, description, 7 | numElem = $('h2'), 8 | titleElem = $('.subject h3'), 9 | projectElem = $('h1'); 10 | 11 | description = titleElem.innerText; 12 | if (numElem !== null) { 13 | description = numElem.innerText + " " + description; 14 | } 15 | 16 | link = togglbutton.createTimerLink({ 17 | className: 'redmine', 18 | description: description, 19 | projectName: projectElem && projectElem.textContent 20 | }); 21 | 22 | $('h2').appendChild(link); 23 | }); 24 | -------------------------------------------------------------------------------- /src/scripts/content/bitbucket.js: -------------------------------------------------------------------------------- 1 | /*jslint indent: 2, unparam: true*/ 2 | /*global $: false, document: false, togglbutton: false*/ 3 | 'use strict'; 4 | 5 | togglbutton.render('#issue-header', {}, function (elem) { 6 | var link, description, 7 | numElem = $('.issue-id'), 8 | titleElem = $('#issue-title'), 9 | projectElem = $('.repo-link'); 10 | 11 | description = titleElem.innerText; 12 | if (numElem !== null) { 13 | description = numElem.innerText + " " + description; 14 | } 15 | 16 | link = togglbutton.createTimerLink({ 17 | className: 'bitbucket', 18 | description: description, 19 | projectName: projectElem && projectElem.textContent 20 | }); 21 | 22 | $('#issue-header').appendChild(link); 23 | }); 24 | -------------------------------------------------------------------------------- /src/scripts/content/gitlab.js: -------------------------------------------------------------------------------- 1 | /*jslint indent: 2, unparam: true*/ 2 | /*global $: false, document: false, togglbutton: false*/ 3 | 4 | 'use strict'; 5 | 6 | togglbutton.render('.content .page-title:not(.toggl)', {observe: true}, function (elem) { 7 | var link, description, 8 | numElem = $('.page-title'), 9 | titleElem = $(".issue-box .title"), 10 | projectElem = $('.title').firstChild; 11 | 12 | description = titleElem.textContent; 13 | description = numElem.firstChild.textContent.trim() + " " + description.trim(); 14 | 15 | link = togglbutton.createTimerLink({ 16 | className: 'gitlab', 17 | description: description, 18 | projectName: projectElem.textContent.split(' / ').pop() 19 | }); 20 | 21 | $('.content .page-title').appendChild(link); 22 | }); 23 | -------------------------------------------------------------------------------- /src/scripts/content/youtrack.js: -------------------------------------------------------------------------------- 1 | /*jslint indent: 2 */ 2 | /*global $: false, document: false, togglbutton: false*/ 3 | 4 | togglbutton.render('.toolbar_fsi .issue-summary:not(.toggl)', {observe: true}, function (elem) { 5 | 'use strict'; 6 | 7 | var link, description, 8 | numElem = $('a.issueId'), 9 | titleElem = $(".issue-summary"), 10 | projectElem = $('.fsi-properties a[title^="Project"]'); 11 | 12 | description = titleElem.textContent; 13 | description = numElem.firstChild.textContent.trim() + " " + description.trim(); 14 | 15 | link = togglbutton.createTimerLink({ 16 | className: 'youtrack', 17 | description: description, 18 | projectName: projectElem ? projectElem.textContent : '' 19 | }); 20 | 21 | elem.insertBefore(link, elem.firstChild); 22 | }); 23 | -------------------------------------------------------------------------------- /src/scripts/content/github.js: -------------------------------------------------------------------------------- 1 | /*jslint indent: 2 */ 2 | /*global $: false, document: false, togglbutton: false*/ 3 | 'use strict'; 4 | 5 | togglbutton.render('#partial-discussion-header:not(.toggl)', {observe: true}, function (elem) { 6 | var link, description, 7 | numElem = $('.gh-header-number', elem), 8 | titleElem = $('.js-issue-title', elem), 9 | projectElem = $('.js-current-repository'); 10 | 11 | description = titleElem.innerText; 12 | if (numElem !== null) { 13 | description = numElem.innerText + " " + description; 14 | } 15 | 16 | link = togglbutton.createTimerLink({ 17 | className: 'github', 18 | description: description, 19 | projectName: projectElem && projectElem.textContent 20 | }); 21 | 22 | $('.flex-table-item-primary').appendChild(link); 23 | }); 24 | -------------------------------------------------------------------------------- /src/scripts/content/producteev.js: -------------------------------------------------------------------------------- 1 | /*jslint indent: 2 */ 2 | /*global $: false, document: false, togglbutton: false*/ 3 | /*Created by lancelothk on 2/16/14.*/ 4 | 5 | "use strict"; 6 | 7 | togglbutton.render('.td-attributes:not(.toggl)', {observe: true}, function (elem) { 8 | var link, newDiv, 9 | taskActive = $('.task.active'), 10 | titleElem = $('.title > span', taskActive), 11 | projectElem = $('.project-value', taskActive); 12 | 13 | if (titleElem === null) { 14 | return; 15 | } 16 | 17 | link = togglbutton.createTimerLink({ 18 | className: 'producteev', 19 | description: titleElem.title, 20 | projectName: projectElem.title 21 | }); 22 | 23 | newDiv = document.createElement('div'); 24 | elem.insertBefore(newDiv.appendChild(link), elem.firstChild); 25 | }); 26 | -------------------------------------------------------------------------------- /src/scripts/content/sifterapp.js: -------------------------------------------------------------------------------- 1 | /*jslint indent: 2, unparam: true*/ 2 | /*global $: false, document: false, togglbutton: false*/ 3 | 'use strict'; 4 | 5 | togglbutton.render('.subheader-status .subheader-content', {}, function (elem) { 6 | var link, description, project, company, 7 | titleElem = $('.subheader-content h2'), 8 | projectElem = $('#header h1'), 9 | companyElem = $('#header h1 .company'); 10 | 11 | description = titleElem.innerText; 12 | project = projectElem.textContent; 13 | company = companyElem.textContent; 14 | project = project.substring(0, project.length - company.length - 1); 15 | 16 | link = togglbutton.createTimerLink({ 17 | className: 'sifterapp', 18 | description: description, 19 | projectName: project 20 | }); 21 | 22 | $('.subheader-content h2').appendChild(link); 23 | }); 24 | -------------------------------------------------------------------------------- /src/scripts/content/google-docs.js: -------------------------------------------------------------------------------- 1 | /*jslint indent: 2, unparam: true*/ 2 | /*global $: false, document: false, togglbutton: false*/ 3 | 'use strict'; 4 | 5 | togglbutton.render('#docs-toolbar-wrapper', {}, function (elem) { 6 | var link, description, titleElem = $('.docs-title-inner'); 7 | 8 | description = titleElem.innerText; 9 | 10 | link = togglbutton.createTimerLink({ 11 | className: 'google-docs', 12 | description: description 13 | }); 14 | if ($('#docs-menubars').style.display !== "none") { 15 | link = togglbutton.createTimerLink({ 16 | className: 'google-docs', 17 | description: description 18 | }); 19 | $('#docs-menubar').appendChild(link); 20 | } else { 21 | link = togglbutton.createTimerLink({ 22 | className: 'google-docs', 23 | buttonType: 'minimal', 24 | description: description 25 | }); 26 | $('#docs-toolbar').appendChild(link); 27 | } 28 | }); 29 | -------------------------------------------------------------------------------- /src/scripts/content/zendesk.js: -------------------------------------------------------------------------------- 1 | /*jslint indent: 2 */ 2 | /*global $: false, document: false, location: false, togglbutton: false*/ 3 | 4 | 'use strict'; 5 | 6 | togglbutton.render('.pane_header:not(.toggl)', {observe: true}, function (elem) { 7 | var link, titleFunc, 8 | projectName = $('title').textContent, 9 | divTag = document.createElement("div"); 10 | 11 | titleFunc = function () { 12 | var titleElem = $('.ticket-title'), 13 | description = titleElem.innerText, 14 | ticketNum = location.href.match(/tickets\/(\d+)/); 15 | 16 | if (ticketNum) { 17 | description = '#' + ticketNum[1] + " " + description; 18 | } 19 | return description; 20 | }; 21 | 22 | link = togglbutton.createTimerLink({ 23 | className: 'zendesk', 24 | description: titleFunc, 25 | projectName: projectName && projectName.split(' - ').shift() 26 | }); 27 | 28 | divTag.appendChild(link); 29 | elem.insertBefore(divTag, elem.previousChild); 30 | }); 31 | -------------------------------------------------------------------------------- /src/scripts/content/teamweek_new.js: -------------------------------------------------------------------------------- 1 | /*jslint indent: 2 */ 2 | /*global $: false, document: false, togglbutton: false*/ 3 | 4 | 'use strict'; 5 | 6 | togglbutton.render('.timeline-task-popup:not(.toggl)', {observe: true}, function (element) { 7 | var link, 8 | titleElement = $('input.title', element), 9 | projectNameElement = $('select[name=project_id]', element), 10 | container = $('footer.actions > .quick-actions', element); 11 | 12 | if (titleElement === null || container === null) { 13 | return; 14 | } 15 | 16 | link = togglbutton.createTimerLink({ 17 | className: 'teamweek-new', 18 | buttonType: 'minimal', 19 | description: function () { 20 | return titleElement.value; 21 | }, 22 | projectName: function () { 23 | var projectSelectedElem = $('option:checked', projectNameElement); 24 | return projectSelectedElem.value ? projectSelectedElem.text : null; 25 | } 26 | }); 27 | 28 | container.appendChild(link); 29 | }); 30 | -------------------------------------------------------------------------------- /src/scripts/settings.js: -------------------------------------------------------------------------------- 1 | /*jslint indent: 2, unparam: true*/ 2 | /*global document: false, window: false, XMLHttpRequest: false, chrome: false, btoa: false, localStorage:false */ 3 | "use strict"; 4 | 5 | var TogglButton = chrome.extension.getBackgroundPage().TogglButton; 6 | 7 | var Settings = { 8 | $postPopup: null, 9 | showPage: function () { 10 | Settings.toggleEditFormState(TogglButton.$showPostPopup); 11 | }, 12 | toggleEditFormState: function (state) { 13 | var request = { 14 | type: "toggle-popup", 15 | state: state 16 | }; 17 | Settings.$postPopup.checked = state; 18 | chrome.extension.sendMessage(request); 19 | } 20 | }; 21 | 22 | document.addEventListener('DOMContentLoaded', function () { 23 | Settings.$postPopup = document.querySelector("#show_post_start_popup"); 24 | Settings.showPage(); 25 | Settings.$postPopup.addEventListener('click', function () { 26 | Settings.toggleEditFormState(localStorage.getItem("showPostPopup") !== "true"); 27 | }); 28 | }); -------------------------------------------------------------------------------- /src/scripts/content/basecamp.js: -------------------------------------------------------------------------------- 1 | /*jslint indent: 2, unparam: true*/ 2 | /*global $: false, document: false, togglbutton: false*/ 3 | 4 | 'use strict'; 5 | 6 | togglbutton.render('section.todos li.todo:not(.toggl)', {observe: true}, function (elem) { 7 | var link, behavior = 'hover_content', 8 | container = $('.pill', elem), spanTag; 9 | 10 | if (container === null) { 11 | return; 12 | } 13 | 14 | link = togglbutton.createTimerLink({ 15 | className: 'basecamp', 16 | description: $('.content_for_perma', elem).textContent, 17 | projectName: ($(".project > title") || $(".project > header > h1 > a")).innerHTML 18 | }); 19 | 20 | link.setAttribute('data-behavior', behavior); 21 | link.addEventListener('click', function (e) { 22 | if (link.getAttribute('data-behavior') === '') { 23 | link.setAttribute('data-behavior', behavior); 24 | } else { 25 | link.setAttribute('data-behavior', ''); 26 | } 27 | }); 28 | 29 | spanTag = document.createElement("span"); 30 | container.parentNode.appendChild(spanTag.appendChild(link)); 31 | }); 32 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function( grunt ) { 2 | 'use strict'; 3 | 4 | grunt.loadNpmTasks('grunt-jslint'); 5 | grunt.loadNpmTasks('grunt-crx'); 6 | grunt.loadNpmTasks('grunt-contrib-compress'); 7 | 8 | var config = { 9 | app: 'src', 10 | dist: 'dist', 11 | package: grunt.file.readJSON('package.json') 12 | }; 13 | 14 | grunt.initConfig({ 15 | config: config, 16 | jslint: { 17 | app: { 18 | src: [ 19 | '<%= config.app %>/scripts/**/*.js' 20 | ] 21 | } 22 | }, 23 | crx: { 24 | toggl: { 25 | "src": "<%= config.app %>", 26 | "dest": "<%= config.dist %>", 27 | "privateKey": "toggl-button.pem" 28 | } 29 | }, 30 | compress: { 31 | dist: { 32 | options: { 33 | archive: '<%= config.dist %>/<%= config.package.name %>-<%= config.package.version %>.zip' 34 | }, 35 | files: [{ 36 | expand: true, 37 | cwd: '<%= config.app %>/', 38 | src: ['**'], 39 | dest: '' 40 | }] 41 | } 42 | } 43 | }); 44 | 45 | grunt.registerTask('default', ['jslint', 'crx', 'compress']); 46 | }; 47 | -------------------------------------------------------------------------------- /CHANGES: -------------------------------------------------------------------------------- 1 | [0.4.2] 2 | - outlandish.com fork 3 | [0.4.1] 4 | - Fixed packaging issue 5 | [0.4.0] 6 | - Convert from Page extension to Browser extension 7 | - Added post Start popup 8 | - Added Browser extension popup 9 | - Added Login and logout functionality 10 | - Added high resolution icons 11 | - Added offline/online and running/not running indicators to extension icon 12 | [0.3.9] 13 | - Github - fix content script for new issues layout 14 | - Todoist - add button after the notes and strip tags 15 | [0.3.8] 16 | - Added support for Todoist 17 | - Fixed button in new Github issues page 18 | [0.3.7] 19 | - Added support for Any.Do 20 | - Added support for ZenDesk 21 | - Time entry is marked as billable if the project is billable 22 | [0.3.6] 23 | - API requests refactoring 24 | - Save logged in user to extension localStorage 25 | - Resolve the 999.00 hours problem with incorrect date and/or time 26 | [0.3.5] 27 | - Fix toggl.com regexp to support push state 28 | [0.3.4] 29 | - fetchUser API urls corrected 30 | - Podio content script refactoring 31 | [0.3.3] 32 | - Added support for CapsuleCRM 33 | - Added support for YouTrack InCloud 34 | - Added support for Xero accountancy software 35 | - Fixed toggl-button's location for Teamweek's new design 36 | -------------------------------------------------------------------------------- /src/scripts/content/podio.js: -------------------------------------------------------------------------------- 1 | /*jslint indent: 2, unparam: true*/ 2 | /*global $: false, createTag: false, togglbutton: false*/ 3 | 4 | 'use strict'; 5 | 6 | togglbutton.render('.task-detail:not(.toggl)', {observe: true}, function (elem) { 7 | var link, wrapper, 8 | description = $('.task-link', elem.parentNode), 9 | container = $('.edit-task-reference-wrapper', elem); 10 | 11 | if (description === null || container === null) { 12 | return; 13 | } 14 | 15 | link = togglbutton.createTimerLink({ 16 | className: 'podio', 17 | description: description.innerText 18 | }); 19 | 20 | wrapper = createTag('div', 'task-via'); 21 | wrapper.appendChild(link); 22 | container.parentNode.insertBefore(wrapper, container.nextSibling); 23 | }); 24 | 25 | 26 | togglbutton.render('.task-header:not(.toggl)', {observe: true}, function (elem) { 27 | var link, wrapper, 28 | container = $('.action-bar ul', elem), 29 | description = $('.header-title', elem); 30 | 31 | if (description === null || container === null) { 32 | return; 33 | } 34 | 35 | link = togglbutton.createTimerLink({ 36 | className: 'podio', 37 | description: description.innerText 38 | }); 39 | 40 | wrapper = createTag("li", "float-left"); 41 | wrapper.appendChild(link); 42 | container.appendChild(wrapper); 43 | }); 44 | -------------------------------------------------------------------------------- /src/scripts/content/trac.js: -------------------------------------------------------------------------------- 1 | /*jslint indent: 2, unparam: true*/ 2 | /*global $: false, document: false, togglbutton: false*/ 3 | 4 | 'use strict'; 5 | 6 | togglbutton.render('#main > #content.ticket:not(.toggl)', {observe: true}, function (elem) { 7 | var 8 | link, 9 | tracTicketId = ( 10 | $('#main > #content.ticket > #ticket > h2 > .trac-id') || // Trac v1.x 11 | $('#main > #content.ticket > h1#trac-ticket-title > a') // Trac v0.x 12 | ).innerHTML, 13 | tracTicketDescription = $('#main > #content.ticket > #ticket .summary', elem).textContent, 14 | tracProjectName = ( 15 | $('title').textContent.split(' – ').pop() || // First try to get project name from title tag 16 | $('#banner > #header > #logo > img').attr('alt') // If can't find in title tag, get from logo alt attribute 17 | ), 18 | container = ( 19 | $('#main > #content.ticket > #ticket > h2 > .trac-type', elem) || // Trac v1.x 20 | $('#main > #content.ticket > h1#trac-ticket-title > a', elem) // Trac v0.x 21 | ), 22 | spanTag; 23 | 24 | link = togglbutton.createTimerLink({ 25 | className: 'trac', 26 | description: tracTicketId + " " + tracTicketDescription, 27 | projectName: tracProjectName 28 | }); 29 | 30 | spanTag = document.createElement("span"); 31 | container.parentNode.appendChild(spanTag.appendChild(link)); 32 | }); -------------------------------------------------------------------------------- /src/scripts/content/trello.js: -------------------------------------------------------------------------------- 1 | /*jslint indent: 2 */ 2 | /*global $: false, document: false, togglbutton: false, createTag:false*/ 3 | 4 | 'use strict'; 5 | 6 | togglbutton.render('.window-header:not(.toggl)', {observe: true}, function (elem) { 7 | var link, container = createTag('div', 'card-detail-item clear'), 8 | titleElem = $('.window-title-text', elem), 9 | projectElem = $('.board-header > a'), 10 | descriptionElem = $('.card-detail-item-block'); 11 | 12 | link = togglbutton.createTimerLink({ 13 | className: 'trello', 14 | description: titleElem.innerText, 15 | projectName: projectElem.innerText 16 | }); 17 | 18 | container.appendChild(link); 19 | descriptionElem.parentNode.insertBefore(container, descriptionElem); 20 | }); 21 | 22 | /* Checklist buttons */ 23 | togglbutton.render('.checklist-item-details:not(.toggl)', {observe: true}, function (elem) { 24 | var link, 25 | projectElem = $('.board-header > a'), 26 | titleElem = $('.window-title-text'), 27 | taskElem = $('.checklist-item-details-text', elem); 28 | 29 | link = togglbutton.createTimerLink({ 30 | className: 'trello', 31 | buttonType: 'minimal', 32 | projectName: projectElem.innerText, 33 | description: titleElem.innerText + ' - ' + taskElem.innerText, 34 | }); 35 | 36 | link.classList.add('checklist-item-button'); 37 | elem.parentNode.appendChild(link); 38 | }); 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, TOGGL LLC 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 5 | 6 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 7 | 8 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 9 | 10 | 3. Neither the name of the TOGGL LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 11 | 12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | -------------------------------------------------------------------------------- /src/scripts/content/wunderlist.js: -------------------------------------------------------------------------------- 1 | /*jslint indent: 2 */ 2 | /*global $: false, document: false, togglbutton: false, createTag:false*/ 3 | 4 | 'use strict'; 5 | 6 | togglbutton.render('.taskItem-titleWrapper:not(.toggl)', {observe: true}, function (elem) { 7 | var link, container = createTag('a', 'taskItem-toggl'), 8 | listElem = $('.lists-scroll'), 9 | titleElem = $('.taskItem-titleWrapper-title', elem), 10 | projectElem = $('.active', listElem), 11 | projectTitleElem = $('.title', projectElem); 12 | 13 | link = togglbutton.createTimerLink({ 14 | className: 'wunderlist', 15 | buttonType: 'minimal', 16 | description: titleElem.innerText, 17 | projectName: projectTitleElem.innerText 18 | }); 19 | 20 | container.appendChild(link); 21 | elem.insertBefore(container, titleElem); 22 | 23 | 24 | }); 25 | 26 | /* Checklist buttons */ 27 | togglbutton.render('.subtask:not(.toggl)', {observe: true}, function (elem) { 28 | var link, container = createTag('span', 'detailItem-toggl small'), 29 | listElem = $('.lists-scroll'), 30 | chkBxElem = $('.checkBox', elem), 31 | titleElem = $('.title-container'), 32 | projectElem = $('.active', listElem), 33 | projectTitleElem = $('.title', projectElem), 34 | taskElem = $('.display-view', elem); 35 | 36 | link = togglbutton.createTimerLink({ 37 | className: 'wunderlist', 38 | buttonType: 'minimal', 39 | description: titleElem.innerText + ' - ' + taskElem.innerText, 40 | projectName: projectTitleElem.innerText 41 | }); 42 | 43 | container.appendChild(link); 44 | chkBxElem.parentNode.insertBefore(container, chkBxElem); 45 | }); -------------------------------------------------------------------------------- /src/scripts/content/jira.js: -------------------------------------------------------------------------------- 1 | /*jslint indent: 2 */ 2 | /*global $: false, togglbutton: false, createTag: false*/ 3 | 4 | 'use strict'; 5 | 6 | togglbutton.render('#ghx-detail-issue:not(.toggl)', {observe: true}, function (elem) { 7 | var link, description, 8 | container = createTag('div', 'ghx-toggl-button'), 9 | titleElem = $('[data-field-id="summary"]', elem), 10 | numElem = $('.ghx-fieldname-issuekey a'), 11 | projectElem = $('.ghx-project', elem); 12 | 13 | description = titleElem.innerText; 14 | if (numElem !== null) { 15 | description = numElem.innerText + " " + description; 16 | } 17 | 18 | link = togglbutton.createTimerLink({ 19 | className: 'jira', 20 | description: description, 21 | projectName: projectElem && projectElem.innerText 22 | }); 23 | 24 | container.appendChild(link); 25 | $('#ghx-detail-head').appendChild(container); 26 | }); 27 | 28 | togglbutton.render('.issue-header-content:not(.toggl)', {observe: true}, function (elem) { 29 | var link, description, ul, li, 30 | numElem = $('#key-val', elem), 31 | titleElem = $('#summary-val', elem), 32 | projectElem = $('#project-name-val', elem); 33 | 34 | description = titleElem.innerText; 35 | if (numElem !== null) { 36 | description = numElem.innerText + " " + description; 37 | } 38 | 39 | link = togglbutton.createTimerLink({ 40 | className: 'jira', 41 | description: description, 42 | projectName: projectElem && projectElem.innerText 43 | }); 44 | 45 | ul = createTag('ul', 'toolbar-group'); 46 | li = createTag('li', 'toolbar-item'); 47 | li.appendChild(link); 48 | ul.appendChild(li); 49 | $('.toolbar-split-left').appendChild(ul); 50 | }); 51 | -------------------------------------------------------------------------------- /src/scripts/popup.js: -------------------------------------------------------------------------------- 1 | /*jslint indent: 2, unparam: true*/ 2 | /*global document: false, window: false, XMLHttpRequest: false, chrome: false, btoa: false, localStorage:false */ 3 | "use strict"; 4 | 5 | var TogglButton = chrome.extension.getBackgroundPage().TogglButton; 6 | 7 | var PopUp = { 8 | $postStartText: " post-start popup", 9 | $popUpButton: null, 10 | $stopButton: null, 11 | showPage: function () { 12 | if (TogglButton.$user !== null) { 13 | document.querySelector(".menu").style.display = 'block'; 14 | if (TogglButton.$curEntry === null) { 15 | PopUp.$stopButton.setAttribute("disabled", true); 16 | } 17 | } else { 18 | document.querySelector("#login-form").style.display = 'block'; 19 | } 20 | }, 21 | 22 | sendMessage: function (request) { 23 | chrome.extension.sendMessage(request, function (response) { 24 | if (!!response.success) { 25 | if (!!response.type && response.type === "Stop") { 26 | window.close(); 27 | } else { 28 | window.location.reload(); 29 | } 30 | } 31 | }); 32 | } 33 | }; 34 | 35 | document.addEventListener('DOMContentLoaded', function () { 36 | PopUp.$stopButton = document.querySelector(".stop-button"); 37 | PopUp.showPage(); 38 | 39 | PopUp.$stopButton.addEventListener('click', function () { 40 | var request = { 41 | type: "stop", 42 | respond: true 43 | }; 44 | PopUp.sendMessage(request); 45 | }); 46 | 47 | document.querySelector(".settings-button").addEventListener('click', function () { 48 | chrome.tabs.create({url: "html/settings.html"}); 49 | }); 50 | 51 | document.querySelector(".logout-button").addEventListener('click', function () { 52 | var request = { 53 | type: "logout", 54 | respond: true 55 | }; 56 | PopUp.sendMessage(request); 57 | }); 58 | 59 | document.querySelector(".login-btn").addEventListener('click', function () { 60 | var request = { 61 | type: "login", 62 | respond: true, 63 | username: document.querySelector("#login_email").value, 64 | password: document.querySelector("#login_password").value 65 | }; 66 | PopUp.sendMessage(request); 67 | }); 68 | }); -------------------------------------------------------------------------------- /src/html/popup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Toggl Button 5 | 6 | 7 | 8 |
9 | 10 | 22 | 23 |
24 |
25 |

26 | 27 | 28 |

29 |

30 | 31 | 32 |

33 |

34 | 35 |

36 |
37 |
38 | 39 | 56 | 57 |
Error
58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /src/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Toggl Button", 3 | "short_name": "Toggl Button", 4 | "version": "0.4.2", 5 | "manifest_version": 2, 6 | "description": "Add outlandish.com Toggl Online Timer to YouTrack", 7 | "background": { 8 | "scripts": [ 9 | "scripts/background.js" 10 | ] 11 | }, 12 | "browser_action": { 13 | "default_icon": { 14 | "19": "images/inactive-19.png", 15 | "38": "images/inactive-38.png" 16 | }, 17 | "default_popup": "html/popup.html", 18 | "default_title": "Toggl Time Tracker" 19 | }, 20 | "permissions": [ 21 | "tabs", 22 | "*://*.toggl.com/*", 23 | "*://*.teamweek.com/*", 24 | "*://*.pivotaltracker.com/*", 25 | "*://*.github.com/*", 26 | "*://*.gitlab.com/*", 27 | "*://app.asana.com/*", 28 | "*://*.unfuddle.com/*", 29 | "*://*.podio.com/*", 30 | "*://*.redbooth.com/*", 31 | "*://*.trello.com/*", 32 | "*://*.worksection.com/*", 33 | "*://*.basecamp.com/*", 34 | "*://*.atlassian.net/*", 35 | "*://*.jira.com/*", 36 | "*://*.producteev.com/*", 37 | "*://*.bitbucket.org/*", 38 | "*://*.sifterapp.com/*", 39 | "*://docs.google.com/*", 40 | "*://*.redmine.org/*", 41 | "*://*.myjetbrains.com/*", 42 | "*://tracker.outlandishideas.co.uk/*", 43 | "*://tracker.outlandish.com/*", 44 | "*://*.capsulecrm.com/*", 45 | "*://*.zendesk.com/*", 46 | "*://go.xero.com/*", 47 | "*://web.any.do/*", 48 | "*://*.todoist.com/*", 49 | "*://trac.edgewall.org/*", 50 | "*://trac-hacks.org/*", 51 | "*://*.trac.wordpress.org/*", 52 | "*://bugs.jquery.com/*", 53 | "*://*.wunderlist.com/*" 54 | ], 55 | "icons": { 56 | "16": "images/icon-16.png", 57 | "48": "images/icon-48.png", 58 | "128": "images/icon-128.png" 59 | }, 60 | "content_scripts": [ 61 | { 62 | "matches": [ 63 | "*://*.teamweek.com/*", 64 | "*://*.pivotaltracker.com/*", 65 | "*://*.github.com/*", 66 | "*://*.gitlab.com/*", 67 | "*://*.bitbucket.org/*", 68 | "*://app.asana.com/*", 69 | "*://*.unfuddle.com/*", 70 | "*://*.podio.com/*", 71 | "*://*.redbooth.com/*", 72 | "*://*.trello.com/*", 73 | "*://*.worksection.com/*", 74 | "*://*.basecamp.com/*", 75 | "*://*.atlassian.net/*", 76 | "*://*.jira.com/*", 77 | "*://*.producteev.com/*", 78 | "*://*.sifterapp.com/*", 79 | "*://docs.google.com/*", 80 | "*://*.redmine.org/*", 81 | "*://*.myjetbrains.com/*", 82 | "*://tracker.outlandishideas.co.uk/*", 83 | "*://tracker.outlandish.com/*", 84 | "*://*.capsulecrm.com/*", 85 | "*://*.zendesk.com/*", 86 | "*://go.xero.com/*", 87 | "*://web.any.do/*", 88 | "*://*.todoist.com/app*", 89 | "*://trac.edgewall.org/*", 90 | "*://trac-hacks.org/*", 91 | "*://*.trac.wordpress.org/*", 92 | "*://bugs.jquery.com/*", 93 | "*://*.wunderlist.com/*" 94 | ], 95 | "css": ["styles/style.css"], 96 | "js": ["scripts/common.js"] 97 | }, 98 | { 99 | "matches": ["*://www.toggl.com/app/timer", "*://www.toggl.com/"], 100 | "js": ["scripts/content/toggl.js"] 101 | }, 102 | { 103 | "matches": ["*://*.teamweek.com/*"], 104 | "js": ["scripts/content/teamweek.js"] 105 | }, 106 | { 107 | "matches": ["*://new.teamweek.com/*"], 108 | "js": ["scripts/content/teamweek_new.js"] 109 | }, 110 | { 111 | "matches": ["*://*.pivotaltracker.com/*"], 112 | "js": ["scripts/content/pivotal.js"] 113 | }, 114 | { 115 | "matches": ["*://*.producteev.com/*"], 116 | "js": ["scripts/content/producteev.js"] 117 | }, 118 | { 119 | "matches": ["*://*.bitbucket.org/*"], 120 | "js": ["scripts/content/bitbucket.js"] 121 | }, 122 | { 123 | "matches": ["*://*.github.com/*"], 124 | "js": ["scripts/content/github.js"] 125 | }, 126 | { 127 | "matches": ["*://*.gitlab.com/*"], 128 | "js": ["scripts/content/gitlab.js"] 129 | }, 130 | { 131 | "matches": ["*://app.asana.com/*"], 132 | "js": ["scripts/content/asana.js"] 133 | }, 134 | { 135 | "matches": ["*://*.unfuddle.com/*"], 136 | "js": ["scripts/content/unfuddle.js"] 137 | }, 138 | { 139 | "matches": ["*://*.podio.com/*"], 140 | "js": ["scripts/content/podio.js"] 141 | }, 142 | { 143 | "matches": ["*://*.redbooth.com/*"], 144 | "js": ["scripts/content/redbooth.js"] 145 | }, 146 | { 147 | "matches": ["*://*.trello.com/*"], 148 | "js": ["scripts/content/trello.js"] 149 | }, 150 | { 151 | "matches": ["*://*.worksection.com/*"], 152 | "js": ["scripts/content/worksection.js"] 153 | }, 154 | { 155 | "matches": ["*://*.basecamp.com/*"], 156 | "js": ["scripts/content/basecamp.js"] 157 | }, 158 | { 159 | "matches": ["*://*.atlassian.net/*"], 160 | "js": ["scripts/content/jira.js"] 161 | }, 162 | { 163 | "matches": ["*://*.jira.com/*"], 164 | "js": ["scripts/content/jira.js"] 165 | }, 166 | { 167 | "matches": ["*://*.sifterapp.com/*"], 168 | "js": ["scripts/content/sifterapp.js"] 169 | }, 170 | { 171 | "matches": ["*://docs.google.com/*"], 172 | "js": ["scripts/content/google-docs.js"] 173 | }, 174 | { 175 | "matches": ["*://*.redmine.org/*"], 176 | "js": ["scripts/content/redmine.js"] 177 | }, 178 | { 179 | "matches": [ 180 | "*://*.myjetbrains.com/*", 181 | "*://tracker.outlandishideas.co.uk/*", 182 | "*://tracker.outlandish.com/*" 183 | ], 184 | "js": ["scripts/content/youtrack.js"] 185 | }, 186 | { 187 | "matches": ["*://*.capsulecrm.com/*"], 188 | "js": ["scripts/content/capsule.js"] 189 | }, 190 | { 191 | "matches": ["*://*.zendesk.com/*"], 192 | "js": ["scripts/content/zendesk.js"] 193 | }, 194 | { 195 | "matches": ["https://go.xero.com/*"], 196 | "js": ["scripts/content/xero.js"] 197 | }, 198 | { 199 | "matches": ["https://web.any.do/*"], 200 | "js": ["scripts/content/anydo.js"] 201 | }, 202 | { 203 | "matches": ["https://*.todoist.com/app*"], 204 | "js": ["scripts/content/todoist.js"] 205 | }, 206 | { 207 | "matches": [ 208 | "*://trac.edgewall.org/*", 209 | "*://trac-hacks.org/*", 210 | "*://*.trac.wordpress.org/*", 211 | "*://bugs.jquery.com/*" 212 | ], 213 | "js": ["scripts/content/trac.js"] 214 | }, 215 | { 216 | "matches": ["https://*.wunderlist.com/*"], 217 | "js": ["scripts/content/wunderlist.js"] 218 | } 219 | ] 220 | } 221 | -------------------------------------------------------------------------------- /src/scripts/common.js: -------------------------------------------------------------------------------- 1 | /*jslint indent: 2, unparam: true*/ 2 | /*global document: false, MutationObserver: false, chrome: false*/ 3 | "use strict"; 4 | 5 | function $(s, elem) { 6 | elem = elem || document; 7 | return elem.querySelector(s); 8 | } 9 | 10 | function createTag(name, className, innerHTML) { 11 | var tag = document.createElement(name); 12 | tag.className = className; 13 | 14 | if (innerHTML) { 15 | tag.innerHTML = innerHTML; 16 | } 17 | 18 | return tag; 19 | } 20 | 21 | function createLink(className, tagName, linkHref) { 22 | var link; 23 | 24 | // Param defaults 25 | tagName = tagName || 'a'; 26 | linkHref = linkHref || '#'; 27 | link = createTag(tagName, className); 28 | 29 | if (tagName === 'a') { 30 | link.href = linkHref; 31 | } 32 | 33 | link.appendChild(document.createTextNode('Start timer')); 34 | return link; 35 | } 36 | 37 | function invokeIfFunction(trial) { 38 | if (trial instanceof Function) { 39 | return trial(); 40 | } 41 | return trial; 42 | } 43 | 44 | var togglbutton = { 45 | isStarted: false, 46 | editHtml: null, 47 | element: null, 48 | serviceName: '', 49 | render: function (selector, opts, renderer) { 50 | chrome.extension.sendMessage({type: 'activate'}, function (response) { 51 | if (response.success) { 52 | togglbutton.editHtml = response.html; 53 | if (opts.observe) { 54 | var observer = new MutationObserver(function (mutations) { 55 | togglbutton.renderTo(selector, renderer); 56 | }); 57 | observer.observe(document, {childList: true, subtree: true}); 58 | } 59 | togglbutton.renderTo(selector, renderer); 60 | } 61 | }); 62 | }, 63 | 64 | renderTo: function (selector, renderer) { 65 | var i, len, elems = document.querySelectorAll(selector); 66 | for (i = 0, len = elems.length; i < len; i += 1) { 67 | elems[i].classList.add('toggl'); 68 | } 69 | for (i = 0, len = elems.length; i < len; i += 1) { 70 | renderer(elems[i]); 71 | } 72 | }, 73 | 74 | addEditForm: function (response) { 75 | if (response === null || !response.showPostPopup) { 76 | return; 77 | } 78 | var pid = (!!response.entry.pid) ? response.entry.pid : 0, 79 | handler, 80 | elemRect, 81 | div = document.createElement('div'), 82 | editForm; 83 | 84 | elemRect = togglbutton.element.getBoundingClientRect(); 85 | editForm = $("#toggl-button-edit-form"); 86 | if (editForm !== null) { 87 | $("#toggl-button-description").value = response.entry.description; 88 | $("#toggl-button-project").value = pid; 89 | editForm.style.left = (elemRect.left - 10) + "px"; 90 | editForm.style.top = (elemRect.top - 10) + "px"; 91 | editForm.style.display = "block"; 92 | return; 93 | } 94 | 95 | div.innerHTML = togglbutton.editHtml.replace("{service}", togglbutton.serviceName); 96 | editForm = div.firstChild; 97 | 98 | editForm.style.left = (elemRect.left - 10) + "px"; 99 | editForm.style.top = (elemRect.top - 10) + "px"; 100 | document.body.appendChild(editForm); 101 | 102 | handler = function (e) { 103 | if (!/toggl-button/.test(e.target.className) && !/toggl-button/.test(e.target.parentElement.className)) { 104 | editForm.style.display = "none"; 105 | this.removeEventListener("click", handler); 106 | } 107 | }; 108 | 109 | $("#toggl-button-description", editForm).value = response.entry.description; 110 | $("#toggl-button-project", editForm).value = pid; 111 | $("#toggl-button-hide", editForm).addEventListener('click', function (e) { 112 | editForm.style.display = "none"; 113 | this.removeEventListener("click", handler); 114 | }); 115 | 116 | $("#toggl-button-update", editForm).addEventListener('click', function (e) { 117 | var request = { 118 | type: "update", 119 | description: $("#toggl-button-description").value, 120 | pid: $("#toggl-button-project").value 121 | }; 122 | chrome.extension.sendMessage(request); 123 | editForm.style.display = "none"; 124 | this.removeEventListener("click", handler); 125 | }); 126 | 127 | $(".toggl-button", editForm).addEventListener('click', function (e) { 128 | var link; 129 | e.preventDefault(); 130 | link = togglbutton.element; 131 | link.classList.remove('active'); 132 | link.style.color = ''; 133 | if (!link.classList.contains("min")) { 134 | link.innerHTML = 'Start timer'; 135 | } 136 | chrome.extension.sendMessage({type: 'stop'}, togglbutton.addEditForm); 137 | editForm.style.display = "none"; 138 | this.removeEventListener("click", handler); 139 | return false; 140 | }); 141 | 142 | document.addEventListener("click", handler); 143 | }, 144 | 145 | createTimerLink: function (params) { 146 | var link = createLink('toggl-button'); 147 | function activate() { 148 | link.classList.add('active'); 149 | link.style.color = '#1ab351'; 150 | if (params.buttonType !== 'minimal') { 151 | link.innerHTML = 'Stop timer'; 152 | } 153 | } 154 | 155 | function deactivate() { 156 | link.classList.remove('active'); 157 | link.style.color = ''; 158 | if (params.buttonType !== 'minimal') { 159 | link.innerHTML = 'Start timer'; 160 | } 161 | } 162 | 163 | link.classList.add(params.className); 164 | togglbutton.serviceName = params.className; 165 | 166 | if (params.buttonType === 'minimal') { 167 | link.classList.add('min'); 168 | link.removeChild(link.firstChild); 169 | } 170 | 171 | link.addEventListener('click', function (e) { 172 | var opts; 173 | e.preventDefault(); 174 | 175 | if (link.classList.contains('active')) { 176 | deactivate(); 177 | opts = {type: 'stop'}; 178 | } else { 179 | activate(); 180 | opts = { 181 | type: 'timeEntry', 182 | respond: true, 183 | projectId: invokeIfFunction(params.projectId), 184 | description: invokeIfFunction(params.description), 185 | projectName: invokeIfFunction(params.projectName), 186 | createdWith: 'TogglButton - ' + params.className 187 | }; 188 | } 189 | togglbutton.element = e.target; 190 | chrome.extension.sendMessage(opts, togglbutton.addEditForm); 191 | 192 | return false; 193 | }); 194 | 195 | // new button created - set state 196 | chrome.extension.sendMessage({type: 'currentEntry'}, function (response) { 197 | var description, currentEntry; 198 | if (response.success) { 199 | currentEntry = response.currentEntry; 200 | description = invokeIfFunction(params.description); 201 | if (description === currentEntry.description) { 202 | activate(link); 203 | } 204 | } 205 | }); 206 | 207 | return link; 208 | }, 209 | 210 | newMessage: function (request, sender, sendResponse) { 211 | if (request.type === 'stop-entry') { 212 | var linkText, color = '', 213 | link = $(".toggl-button"); 214 | if (/active/.test(link.className)) { 215 | link.classList.remove('active'); 216 | linkText = 'Start timer'; 217 | } else { 218 | link.classList.add('active'); 219 | color = '#1ab351'; 220 | linkText = 'Stop timer'; 221 | } 222 | link.style.color = color; 223 | link.innerHTML = linkText; 224 | } 225 | } 226 | }; 227 | 228 | chrome.extension.onMessage.addListener(togglbutton.newMessage); 229 | -------------------------------------------------------------------------------- /src/styles/settings.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; 5 | } 6 | 7 | .header { 8 | padding-top: 10px; 9 | padding-bottom: 10px; 10 | min-width: 1000px; 11 | background-color: #f5f5f5; 12 | border-bottom: 1px solid #e5e5e5; 13 | } 14 | 15 | .header .logo { 16 | background: url(data:image/png;base64,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) no-repeat left top; 17 | width: 890px; 18 | margin: 10px auto; 19 | height: 30px; 20 | display: block; 21 | line-height: 35px; 22 | vertical-align: middle; 23 | font-size: 18px; 24 | padding-left: 110px; 25 | } 26 | @media only screen and (-webkit-min-device-pixel-ratio: 2), 27 | only screen and (min-resolution: 192dpi), 28 | only screen and (min-resolution: 2dppx) { 29 | .header .logo{ 30 | background-image: url(data:image/png;base64,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); 31 | background-size: 95px 30px; 32 | } 33 | } 34 | 35 | .list { 36 | width: 1000px; 37 | margin: 40px auto; 38 | padding: 0; 39 | list-style: none; 40 | } 41 | 42 | .list li { 43 | padding: 10px 0; 44 | } 45 | 46 | .list li label { 47 | font-size: 14px; 48 | } 49 | 50 | .list li input[type="checkbox"]{ 51 | height: 1.3em; 52 | width: 1.3em; 53 | vertical-align: middle; 54 | margin: 0px 0.4em 0.3em 0px; 55 | border: 1px solid rgba(0, 0, 0, 0.3); 56 | -webkit-appearance: none; 57 | -webkit-transition: box-shadow 200ms; 58 | box-shadow: inset 1px 1px 0px #fff, 0 1px 1px rgba(0,0,0,0.1); 59 | outline: none; 60 | } 61 | 62 | .list li input[type="checkbox"]:checked:before { 63 | border-color: rgba(0,0,0,0.5); 64 | direction: ltr; 65 | color: rgba(0, 0, 0, 0.7); 66 | content: '\2713'; 67 | margin-left: 20%; 68 | font-size: 20px; 69 | position: relative; 70 | top: -7px; 71 | left: -3px; 72 | } -------------------------------------------------------------------------------- /src/scripts/background.js: -------------------------------------------------------------------------------- 1 | /*jslint indent: 2, unparam: true*/ 2 | /*global window: false, XMLHttpRequest: false, chrome: false, btoa: false, localStorage:false */ 3 | "use strict"; 4 | 5 | var TogglButton = { 6 | $user: null, 7 | $curEntry: null, 8 | $showPostPopup: true, 9 | $apiUrl: "https://old.toggl.com/api/v7", 10 | $newApiUrl: "https://www.toggl.com/api/v8", 11 | $sendResponse: null, 12 | $sites: new RegExp( 13 | [ 14 | 'asana\\.com', 15 | 'podio\\.com', 16 | 'trello\\.com', 17 | 'github\\.com', 18 | 'bitbucket\\.org', 19 | 'gitlab\\.com', 20 | 'redbooth\\.com', 21 | 'teamweek\\.com', 22 | 'basecamp\\.com', 23 | 'unfuddle\\.com', 24 | 'worksection\\.com', 25 | 'pivotaltracker\\.com', 26 | 'producteev\\.com', 27 | 'sifterapp\\.com', 28 | 'docs\\.google\\.com', 29 | 'drive\\.google\\.com', 30 | 'redmine\\.org', 31 | 'myjetbrains\\.com', 32 | 'zendesk\\.com', 33 | 'capsulecrm\\.com', 34 | 'web\\.any\\.do', 35 | 'todoist\\.com', 36 | 'trac\\.edgewall\\.org', 37 | 'trac-hacks\\.org', 38 | 'trac\\.wordpress\\.org', 39 | 'bugs\\.jquery\\.com', 40 | 'wunderlist\\.com' 41 | ].join('|') 42 | ), 43 | 44 | $editForm: '
' + 45 | 'Stop timer' + 46 | '

' + 47 | '' + 48 | '' + 49 | '

' + 50 | '

' + 51 | '' + 52 | '' + 53 | '

' + 54 | '

' + 55 | '' + 56 | '' + 57 | '

' + 58 | '
', 59 | 60 | checkUrl: function (tabId, changeInfo, tab) { 61 | if (changeInfo.status === 'complete') { 62 | if (/toggl\.com\/track/.test(tab.url)) { 63 | TogglButton.fetchUser(TogglButton.$apiUrl); 64 | } else if (/toggl\.com\/app\/index/.test(tab.url)) { 65 | TogglButton.fetchUser(TogglButton.$newApiUrl); 66 | } 67 | } 68 | }, 69 | 70 | fetchUser: function (apiUrl, token) { 71 | TogglButton.ajax('/me?with_related_data=true', { 72 | token: token || ' ', 73 | baseUrl: apiUrl, 74 | onLoad: function (xhr) { 75 | var resp, apiToken, projectMap = {}; 76 | if (xhr.status === 200) { 77 | resp = JSON.parse(xhr.responseText); 78 | if (resp.data.projects) { 79 | resp.data.projects.forEach(function (project) { 80 | projectMap[project.name] = project; 81 | }); 82 | } 83 | if (resp.data.time_entries) { 84 | resp.data.time_entries.some(function (entry) { 85 | if (entry.duration < 0) { 86 | TogglButton.$curEntry = entry; 87 | TogglButton.setBrowserAction(entry); 88 | return true; 89 | } 90 | return false; 91 | }); 92 | } 93 | TogglButton.$user = resp.data; 94 | TogglButton.$user.projectMap = projectMap; 95 | localStorage.removeItem('userToken'); 96 | localStorage.setItem('userToken', resp.data.api_token); 97 | if (TogglButton.$sendResponse !== null) { 98 | TogglButton.$sendResponse({success: (xhr.status === 200)}); 99 | TogglButton.$sendResponse = null; 100 | TogglButton.setBrowserActionBadge(); 101 | } 102 | } else if (apiUrl === TogglButton.$apiUrl) { 103 | TogglButton.fetchUser(TogglButton.$newApiUrl); 104 | } else if (apiUrl === TogglButton.$newApiUrl && !token) { 105 | apiToken = localStorage.getItem('userToken'); 106 | if (apiToken) { 107 | TogglButton.fetchUser(TogglButton.$newApiUrl, apiToken); 108 | } 109 | } 110 | } 111 | }); 112 | }, 113 | 114 | createTimeEntry: function (timeEntry, sendResponse) { 115 | var project, start = new Date(), 116 | entry = { 117 | time_entry: { 118 | start: start.toISOString(), 119 | description: timeEntry.description, 120 | wid: TogglButton.$user.default_wid, 121 | pid: timeEntry.projectId || null, 122 | billable: timeEntry.billable || false, 123 | duration: -(start.getTime() / 1000), 124 | created_with: timeEntry.createdWith || 'TogglButton' 125 | } 126 | }; 127 | 128 | if (timeEntry.projectName !== undefined) { 129 | project = TogglButton.$user.projectMap[timeEntry.projectName]; 130 | entry.time_entry.pid = project && project.id; 131 | entry.time_entry.billable = project && project.billable; 132 | } 133 | 134 | TogglButton.ajax('/time_entries', { 135 | method: 'POST', 136 | payload: entry, 137 | onLoad: function (xhr) { 138 | var responseData; 139 | responseData = JSON.parse(xhr.responseText); 140 | entry = responseData && responseData.data; 141 | TogglButton.$curEntry = entry; 142 | TogglButton.setBrowserAction(entry); 143 | if (!!timeEntry.respond) { 144 | sendResponse({success: (xhr.status === 200), type: "New Entry", entry: entry, showPostPopup: TogglButton.$showPostPopup}); 145 | } 146 | } 147 | }); 148 | }, 149 | 150 | ajax: function (url, opts) { 151 | var xhr = new XMLHttpRequest(), 152 | method = opts.method || 'GET', 153 | baseUrl = opts.baseUrl || TogglButton.$newApiUrl, 154 | token = opts.token || (TogglButton.$user && TogglButton.$user.api_token), 155 | credentials = opts.credentials || null; 156 | 157 | xhr.open(method, baseUrl + url, true); 158 | if (opts.onLoad) { 159 | xhr.addEventListener('load', function () { opts.onLoad(xhr); }); 160 | } 161 | if (token && token !== ' ') { 162 | xhr.setRequestHeader('Authorization', 'Basic ' + btoa(token + ':api_token')); 163 | } 164 | if (credentials) { 165 | xhr.setRequestHeader('Authorization', 'Basic ' + btoa(credentials.username + ':' + credentials.password)); 166 | } 167 | xhr.send(JSON.stringify(opts.payload)); 168 | }, 169 | 170 | stopTimeEntry: function (timeEntry, sendResponse) { 171 | if (!TogglButton.$curEntry) { return; } 172 | var stopTime = new Date(), 173 | startTime = new Date(-TogglButton.$curEntry.duration * 1000); 174 | 175 | TogglButton.ajax("/time_entries/" + TogglButton.$curEntry.id, { 176 | method: 'PUT', 177 | payload: { 178 | time_entry: { 179 | stop: stopTime.toISOString(), 180 | duration: Math.floor(((stopTime - startTime) / 1000)) 181 | } 182 | }, 183 | onLoad: function (xhr) { 184 | if (xhr.status === 200) { 185 | TogglButton.$curEntry = null; 186 | TogglButton.setBrowserAction(null); 187 | if (!!timeEntry.respond) { 188 | sendResponse({success: true, type: "Stop"}); 189 | chrome.tabs.query({active: true, currentWindow: true}, function (tabs) { 190 | chrome.tabs.sendMessage(tabs[0].id, {type: "stop-entry"}); 191 | }); 192 | } 193 | } 194 | } 195 | }); 196 | }, 197 | 198 | updateTimeEntry: function (timeEntry, sendResponse) { 199 | var entry; 200 | if (!TogglButton.$curEntry) { return; } 201 | TogglButton.ajax("/time_entries/" + TogglButton.$curEntry.id, { 202 | method: 'PUT', 203 | payload: { 204 | time_entry: { 205 | description: timeEntry.description, 206 | pid: timeEntry.pid 207 | } 208 | }, 209 | onLoad: function (xhr) { 210 | var responseData; 211 | responseData = JSON.parse(xhr.responseText); 212 | entry = responseData && responseData.data; 213 | TogglButton.$curEntry = entry; 214 | TogglButton.setBrowserAction(entry); 215 | if (!!timeEntry.respond) { 216 | sendResponse({success: (xhr.status === 200), type: "Update"}); 217 | } 218 | } 219 | }); 220 | }, 221 | 222 | setBrowserActionBadge: function () { 223 | var badge = ""; 224 | if (TogglButton.$user === null) { 225 | badge = "x"; 226 | TogglButton.setBrowserAction(null); 227 | } 228 | chrome.browserAction.setBadgeText( 229 | {text: badge} 230 | ); 231 | }, 232 | 233 | setBrowserAction: function (runningEntry) { 234 | var imagePath = {'19': 'images/inactive-19.png', '38': 'images/inactive-38.png'}, 235 | title = chrome.runtime.getManifest().browser_action.default_title; 236 | if (runningEntry !== null) { 237 | imagePath = {'19': 'images/active-19.png', '38': 'images/active-38.png'}; 238 | title = runningEntry.description + " - Toggl"; 239 | } 240 | chrome.browserAction.setTitle({ 241 | title: title 242 | }); 243 | chrome.browserAction.setIcon({ 244 | path: imagePath 245 | }); 246 | }, 247 | 248 | loginUser: function (request, sendResponse) { 249 | TogglButton.ajax("/sessions", { 250 | method: 'POST', 251 | onLoad: function (xhr) { 252 | TogglButton.$sendResponse = sendResponse; 253 | TogglButton.fetchUser(TogglButton.$newApiUrl); 254 | TogglButton.refreshPage(); 255 | }, 256 | credentials: { 257 | username: request.username, 258 | password: request.password 259 | } 260 | }); 261 | }, 262 | 263 | logoutUser: function (sendResponse) { 264 | TogglButton.ajax("/sessions?created_with=TogglButton", { 265 | method: 'DELETE', 266 | onLoad: function (xhr) { 267 | TogglButton.$user = null; 268 | sendResponse({success: (xhr.status === 200), xhr: xhr}); 269 | TogglButton.refreshPage(); 270 | } 271 | }); 272 | }, 273 | 274 | getEditForm: function () { 275 | if (TogglButton.$user === null) { 276 | return ""; 277 | } 278 | return TogglButton.$editForm.replace("{projects}", TogglButton.fillProjects()); 279 | }, 280 | 281 | fillProjects: function () { 282 | var html = "", 283 | projects = TogglButton.$user.projectMap, 284 | key = null; 285 | for (key in projects) { 286 | if (projects.hasOwnProperty(key)) { 287 | html += ""; 288 | } 289 | } 290 | return html; 291 | }, 292 | 293 | refreshPage: function () { 294 | chrome.tabs.query({active: true, currentWindow: true}, function (tabs) { 295 | chrome.tabs.reload(tabs[0].id); 296 | }); 297 | }, 298 | 299 | newMessage: function (request, sender, sendResponse) { 300 | if (request.type === 'activate') { 301 | TogglButton.setBrowserActionBadge(); 302 | sendResponse({success: TogglButton.$user !== null, user: TogglButton.$user, html: TogglButton.getEditForm()}); 303 | } else if (request.type === 'login') { 304 | TogglButton.loginUser(request, sendResponse); 305 | } else if (request.type === 'logout') { 306 | TogglButton.logoutUser(sendResponse); 307 | } else if (request.type === 'timeEntry') { 308 | TogglButton.createTimeEntry(request, sendResponse); 309 | } else if (request.type === 'update') { 310 | TogglButton.updateTimeEntry(request, sendResponse); 311 | } else if (request.type === 'stop') { 312 | TogglButton.stopTimeEntry(request, sendResponse); 313 | } else if (request.type === 'toggle-popup') { 314 | localStorage.setItem("showPostPopup", request.state); 315 | TogglButton.$showPostPopup = request.state; 316 | } else if (request.type === 'userToken') { 317 | if (!TogglButton.$user) { 318 | TogglButton.fetchUser(TogglButton.$newApiUrl, request.apiToken); 319 | } 320 | } else if (request.type === 'currentEntry') { 321 | sendResponse({success: TogglButton.$curEntry !== null, currentEntry: TogglButton.$curEntry}); 322 | } 323 | return true; 324 | } 325 | }; 326 | 327 | TogglButton.fetchUser(TogglButton.$apiUrl); 328 | TogglButton.$showPostPopup = (localStorage.getItem("showPostPopup") === null) ? true : localStorage.getItem("showPostPopup"); 329 | chrome.tabs.onUpdated.addListener(TogglButton.checkUrl); 330 | chrome.extension.onMessage.addListener(TogglButton.newMessage); 331 | -------------------------------------------------------------------------------- /src/styles/popup.css: -------------------------------------------------------------------------------- 1 | body { 2 | overflow: hidden; 3 | margin: 0px; 4 | padding: 0px; 5 | background: white; 6 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; 7 | background: white; 8 | } 9 | 10 | .view { 11 | position: relative; 12 | top: 0; 13 | right: 0; 14 | left: 0; 15 | bottom: 0; 16 | padding: 20px 20px 12px; 17 | display: none; 18 | } 19 | #login-form { 20 | margin-bottom: 30px; 21 | } 22 | #login-form .form-submit-row label.left { 23 | padding: 10px 0; 24 | } 25 | .form-row { 26 | margin: 0; 27 | padding: 0; 28 | } 29 | .form-row label { 30 | display: block; 31 | font-size: 13px; 32 | height: 20px; 33 | } 34 | p.form-row.first { 35 | margin-top: 0; 36 | margin-bottom: 0; 37 | } 38 | .text-input { 39 | background: #f5f5f5; 40 | border: 1px solid #e1e1e1; 41 | font-size: 0.7em; 42 | padding: 5px; 43 | width: 220px; 44 | } 45 | #entry_project { 46 | height: 25px; 47 | width: 230px; 48 | } 49 | .check { 50 | font-size: 13px; 51 | height: 30px; 52 | } 53 | .btn-small { 54 | font-size: 0.7em; 55 | text-transform: uppercase; 56 | padding: 10px 14px 8px; 57 | border: 1px solid #63b618; 58 | color: white; 59 | text-shadow: 0 1px 1px rgba(0,0,0,.25); 60 | font-weight: bold; 61 | font-size: 12px; 62 | display: inline-block; 63 | -webkit-box-shadow: 0 1px 1px rgba(0,0,0,.5); 64 | box-shadow: 0 1px 1px rgba(0,0,0,.5); 65 | background-color: #8dcc35; 66 | background-image: -webkit-gradient(linear, left top, left bottom, from(#8dcc35), to(#47a204)); 67 | background-image: -webkit-linear-gradient(top, #8dcc35, #47a204); 68 | background-image: -moz-linear-gradient(top, #8dcc35, #47a204); 69 | background-image: -o-linear-gradient(top, #8dcc35, #47a204); 70 | background-image: linear-gradient(to bottom, #8dcc35, #47a204); 71 | -webkit-border-radius: 3px; 72 | border-radius: 3px; 73 | border: none; 74 | cursor: pointer; 75 | font-family: inherit; 76 | } 77 | .btn { 78 | background-color: #f8f8f8 ; 79 | background-image: -webkit-gradient(linear, left top, left bottom, from(#f8f8f8 ), to(#e4e4e4)); 80 | background-image: -webkit-linear-gradient(top, #f8f8f8 , #e4e4e4); 81 | background-image: -moz-linear-gradient(top, #f8f8f8, #e4e4e4); 82 | background-image: -o-linear-gradient(top, #f8f8f8, #e4e4e4); 83 | background-image: linear-gradient(to bottom, #f8f8f8, #e4e4e4); 84 | } 85 | #error, .errorbox { 86 | background: #ffdada; 87 | text-align: center; 88 | color: #d41a28; 89 | font-weight: bold; 90 | -webkit-border-radius: 3px 3px 0 0; 91 | border-radius: 3px 3px 0 0; 92 | padding: 10px; 93 | display: none; 94 | position: absolute; 95 | bottom: 0; 96 | left: 0; 97 | right: 0; 98 | } 99 | .right { 100 | float: right 101 | } 102 | .left { 103 | float: left; 104 | } 105 | .header { 106 | background: url(data:image/png;base64,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) no-repeat left top; 107 | width: 95px; 108 | margin: 10px auto; 109 | height: 30px; 110 | } 111 | @media only screen and (-webkit-min-device-pixel-ratio: 2), 112 | only screen and (min-resolution: 192dpi), 113 | only screen and (min-resolution: 2dppx) { 114 | .header { 115 | background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAL4AAAA8CAYAAADYDABOAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH3gkLCxEH/xlr3QAAEeRJREFUeNrtnXu0F9V1xz+/H295GGyFDBDHEXyiEjRRYrRGDdRlTAgaHIdljVRixMQ2LqOtiholIaY11keJiRENMXQ4NSnK8pFIiS2CRVEB3yIyDgiDJajI5SJXuLd/nPMjwzi/OfP63Qurv73WXffeeZx95sz37LP3PnvvqdAg8g3LBCzgcOAE4HhgIDAA6A+0AduAFuBN4CVgpfq9ygy8baodzMCjSU0qkyolAr0C9AQuBqYDBxRs8lXgO8B/AZiB15wETdq7gO8b1pnAzUqqV0vu4ybgaeAyM/A2NMHfpC4Hvm9Y44FbgCM6qb+/AP7JDLw1zQnQpCJUzQj02u+BvmG9CjzUiaAH+Dbwlm9YM2p9r/WpSU1qCPBrEtY3rGnABuDILuz3NcDbvmENr+n+TWpS6cAPgf4uZbj23gv6/hlgtW9Yk5rgb1KpwK+BSQHrceC7e+EzzPEN64om+JsUJdt2ihm3vmG91sm6fB6abQbeRU2jt0kR8A8A7kW61x8Qwp1t20594IfUm1eAo/aR55xpBt53m+BvkgL9OcDvIodXAidVNaB/uGTQ7+DPu7XbgZ0lP+t3fMO6vDPUnnrLaNLy2qROpwdjjo0CplUSQH8bcEXJHTkHWKBsiyrwEfAGcFDJfE4HnmyU1LdtByFcbNs5CrgbGAHMEsK9oYm1vUbaG0jvYxzt6h49okB/ZQNAD9BiBl5LZKJtbwCfh4HBalVp1MDeDFwfOnS9bTuTgaOFcLc0odfldHjCuW7VGInfH7ipQZ3ZFXOsrQF8+gN/rK1gDaDuwNUxx4cBzzYxt1fQYUkn43T8x4C+DepMeycBH2CMb1gjG6TufAbolWfAm9Rp1Cc18H3DOg04uYGd6UzgAyzxDat7A6S+0cTVXk9V7ckQMKaXzPxV4EIz8CrAO3WA3w5coiToLOC9EvnvD0xsgNQfotH/uzVx1+VU0QJfGbSjgS+WyPgU4Bgz8B5Q/78IdMRc9zEy8aTNDLwpwKCI0ViUbmnAoA7RnO/dxN2+I/FvK4nhL4H+ZuAtNgOvPaLStNcB/vqwAWwG3g+BzwGtJfTnIN+wTi9Z3TE15/s2cbeXA18BogqMKYHZTDPwLkFuUEVpUB3g7wCG7kaUUkvMwHveDLy+wKoS+nVdyeqOFvh5N7Li7rNtp3ua6/JStC3bdnrattNHc03pSFV8Kxn7mkvVqSiJPx4ZW1+EbjUD76qIsbwbyL5hrQfGm4H3XOSa3ypV59roPaFrPlD6el76yAy8PiWAojaYa5Guy7q3seeu4W4VTwg3lofaEKv9ngycB4xEepBqttBq4GXgKiHcNUXBHuE5BfgJe6aMvo6Mc7lNCLejNha1+5CppqcATwFtcc+WxFcJ3L8DJgLHhVTEl4H5wJ3Au5F+1u47C3hGCHdTHT7XADN0wF8FHFpgHF8yA+/YCNBrtsMJyHiJYcDxZuC9EAH1r4G/ARaagffluInjG9ZQZRwXoZPNwFuSEyQnAzPVMwwkfebaNmWsbwTOEsL9UwIQhgC/BT6LxhWnyAPmCuFeW2sjx3MNRm72jVYgrketwPVCuLeFjPeVamLWaIEQ7rikvoSeta8az6+iz81eIIQ7LtTGfHVf2IEyDlgf5mvbzrXAj+oC3zesA4H/LQCoHcBAM/C2xwB2MnBf6NrPmYH3fATcc4BJ6t8W4Awz8J6NSn7fsL4J/KpAP+ebgTc+Bzi+gMz5LUVFEsJdGwOES5GhD3nodeB0Idwgo6T/HvAvGXktAi5XEn5AzPm7hXAv0/A9Axm2kiXttQX4K+CnwGkx51cI4Y4OTzrbdqaR4KWsIkuAFKHbw6APeYn+OQL6egZH2APSD3jGN6wTI6AH+I2ScnnpbN+w8rgZv1aiGntiDBDmFgA9yHDxDWqCJureIZ6/ygF6FPhW1gE9wFTbdoYl8J0E/CfZc737AS/UAT1qlYyuNFp3pllIhAXeP0aP+YZ1KfD9mMu7pXT9LfUNa3A4EcYMvF0Ujx8akuOeYSUCf2hY17dt52fKHiiDlti2YyapPIrnTcA3O9O9ovieC8xpFI+YCZcI/O7A5wvwuycG9PsBd2SwtHsnqCYnhtQmzMB72DesVmC/HH2tKAN5XUbDdhlwQUnv56WQRJ4ETC3x3VeA1Upvfy86ARTfMUCnR5Aqm2BWg9n0yuTOrC0TOWlOjH98RoKh1C0D8E/wDWtYyL1ZOz63ADD2zyqplLq2tYQX84oQ7kLVZkXpq2VTd+DBOKmvjs2ia+jhgl65NNQ7K/APLMBsTUQX7wv8vQZ8aYFPHePkhQL9HZFjmW4BPq08CfcrT00a2qS8NFcDpwLHhs7dqdrU0e+A8cgSjOcgd791dLptO8fF+LvHky6p6A/KvXiG4vmLApIe23Ys4CspLt+oDOdTlS1xN9niuHpmVXWKAH9zVOXXXF/NCPy4gLk3CvQ3b3BZqxDuI8AjwN/atvMEMDbh+mOFcF+qA4Y+6JP21wDjhHDfCh1bBsyzbWcs8Hid1bNGNwrhjg/xrKDfmW8BJgrh/j5yfJ5tOz8CngSG59DtJ6W49Boh3GhoyVO27VwBCDX5s6o6WuM2N/Cj3pwUy1m3jMA/JObYBwWAvyOvcRYhndTvSDiXRrU8DHirTl8WpLDLTgtJXJRN9Be6e2JAX+O5Tgh3RM7xu0xz/oYY0O9+X0K4X6d+JlUS8JPeQUeV/FlKcb7//iVL/A7fsKKbOa2dDfwY+khz/uOEczrP1FlCuLs0m0DL+WQS9R7vwbadEUK4tUnbXyOU7hDCfS5FHvGUjKrOCI0nbRPw43p8Q2MwQgPkOFVHC/w/5Xz5g2KOfai5p13ZAmmBH7eqFAn5bdsLgH+4pt0nk3zxoW372zV9CHuMztdce2/SjmvoeFZ35Ema87cL4e5McsGqfm0Hlmc0btuTgN9dGRXD87x937D6RXJodbmmE33DWgt08w3rU0i/dtIqsTrm2F8WAOyGkoC/vcAEG5S0igrh6iZVDYiLNYFi40J/X6hp7+WUKl+HbTsLNPZNmI7TnL81pZ0AsFDTXs8swK8iYx3yUhSEOh/5pciPQLwOLFXLdY+E65dHJhrk24SqLX3rSgpP1qlMSWVTBiecy+qqTZKCYYHSh/IoVSK9AmvS5t+7QrhtaaI81UTXOTV6Z1V1XikwCIeEgaSk/30lDXAH8sMQ4fZR7q687W0qKTxZJ5WTJH5FpwpmoH4J5wakbGNXRp4fprlIgbVXDsdBXQVDc76SYSzbq0r65qWJMcWbLqGcsh5PmIEXl4b4tSLA7yRVJ2+hrKMzXn9QRkdCHGW1mfpmHPPE/mWI6x+UUdhoJf6bBQBwaUgS18IKdlFO7u65UbXEN6xJGlUhidaovnW1xE+ikRmvT5KoK1KuMlnpU2kcGArQaxOuOzCtxFdtWRnHPFnHNwNvTQpXUZKB+7OwKqLA/2OKpTIeYQbetvCEUjSjQJuPlfjyPy6gPiRNmk/bttMzDRBs2/mG5rJwfZ8nNe0dnEHyfjnNsytAv6Xhe14GtemMjHaX1rjN46YK0wWqCFUU/FfmAOoa4Cgz8N6I6vbqKyhFIklvLBH4upUjadAf0UjwkTrQKyB8X9OHP4T+vkf3DkPekyTef51CNQo/+3zNtT+0baeSgm8VGbZRqqoDxcJ9+yM/0blHPX31+zpkhk2aGJObzMAbbgbea2EVxzcsfMM6FfkVlLy0wgy8LSUmnOt0+KRBf0Cj9y5M0n0VQA8nFNsfQ61CuAsjAiXJLplu284hSZtmin6eRSiokIskL9ChwJEp1J2nUtgW2SS+AsNm3bKkIdM3rLticmUxA+99M/BGqYe8ABmy/Bjwb8hShWOA/c3A+0F04oTcVPMLAvXXJZcO36VZmtsTALRY0/ZA23aWhDKJ9pgEKg1S53dfFvl/WwpvzKJaTHuNXyTHdiFwcIqxiT67zkW70radU+pMNGzbuRX9Rlic+pkI/EoIpNEiqHlohpLycbZALPDqJJfX1Jujgf8h2W2nn5WyoFVppBKzf5kAfF2lgLnoE1A6gKuQ+x07kUnnDjJiUkdnA49GclDvrjkjNPQD5LeFtyop+yWlEQxMOTwDhHC3RibqUynuux/pCt+hjPEjkdGax6fkO1oId0WIb1Jq5YfVEDjKSFC41jesRbUUv4iPvx4o9wB8SKcfq1SofgX7dCflU9G6/k4Kz1AFubO5WIH/wZSgXyKE+2hUfRDCnUq6OKca8J9H5tjenAH0n1gNhXAXky5ldLKaIM8CzyDzq4/PwDebVycC0H8oARSnAOt9wzovi2oRqdDwAPBESSCd2YDame15b1TGaQfx1ZbLoAsSdPTOyL6KG5sTO4FvVMffmHDttnAJQYB/TeGqS0ODAeEb1rO+YTm+YaWJrznGN6xpvmF1UF6q3ywz8FY1oHZmkPfGmiQWwr0LmFdyv8YJ4b6dwPOnFK+flEniq0m3iYRSHyVRFLdJ4TPvhFUdzMBrBc4ssTOfV0bsJt+wNvuGNdM3rBm+YV3jG9b3fMOa7RvWmwrsL1Ju0dr3zMCb0qD6+ElZYKl2wpXkP0epFWXQZUK4C3RVFpDZVXklwQ7g3YyqTu33NKU25V1FNmeU+El1mNZVouqG0i2XI78VtC/T+YAoW9or8FTUUhq3jX6xEO59Gdu8vKAtcoIQ7rK0haVU8vdNwHUZeKxQ3pWZSh/PZNhHqsRlGZ82ZB3VIcDvE647QAj3/QjPDcRn3V1SjRqaZuB1KEab9mHQ32sGnmhEwyq5owNZ4i+ahP4QMDtLXUkFiLuQW/IPkX4XfQdyd7yHEO6ysHRNo44oCfxFwNUY62uQqYGjVVx8z7zjpp71fmUs30NyEn8LsnyhodI4h2pYtMYIqPP5ZLbcfGBWNcFrcfY+CvqtwNRGfvJTDep/IyMgxwIXA0cI4U5QoMqs8wNvC+FOEMKtIhP2NyKz3DYD76vfG5EFmcYJ4fYWwr0yj4cpxPNpIdxJQrg9kAFvY5ERsVOQyfU9hHCHC+HeEprM3ygiNBR9IIT7bSHcAWrCn6l4XqjaP1AIt78Q7rf48/cSknZu24Vwd4QFjuK1SAi3H/JjgBcCI1UucntF42mZAPzHPgL4DgV60wy8D7qiA3lrWNa7XyWJd0MWBdglhPtxVz2TAtVgjbfkRSHcUQ3iv5r6CVOrhXAz1X6tJoAeM/Dmoa8IsLdQKzCqq0CfUdVIdb8QbodKzfuoKOjrlB/PoqKA3FBLokeTeNT7OwV/m+QswcxRB3WBHwo2m4k+U76rqQVZ8denSfWol207c23b6VA/NyKjQbvVA2MkZOFc4EoNjzvjHAG27dxi204H0GHbjmvbzjGEquEl1by3bWc0+rCHx7LW69du5YfCB8ZS3qZSmbQRGca8pZF6/b5MSmV6BRkGELXlWpDFm24Qwt0Zc+8wZG0bXbyMh6yG0B5R1+pVLW5FVlj7lhDutjr9/iMy406XVNNLCLetVOBHwH8YctPlqL3knc4GJitPVJPqA3+QEhC6970eGcy2BRkibaKvX1+jLwjhLo3hnebdbEcWAngHGaJiZeA7Pc8X5VOlp4Wk6Coz8EYi4/fbu/Bdvg+cZQbeRRRIovl/AvosQm6oWhXGKNUxLfjuEMJdWuDzQH2UDn8qMj4nLd/NwE/y8M0ctRjaCd0fGUB1dCe/y58Dl5uBt7Op2qQGfx8lzQc2oPl25XXqqPOZo8cpNxqgRm3AQCHcXAXGqllvCCWZbDED7xik73d5J7y/e4FDzMCbqnTTJujTe4u2AxMa0PRzyDDkeqAHGSLRUjLfrcBnhXBb864ypcWpK/1/ulquBpfUrIesODzNDLy2poTPr+4oz8xJyC/LFA1g2gnMEcK9KEMf5gFfL+Fxliph21LEfVwtCfSYgbcKmVwxBPl5mluVLp6V1iF3LvsCw83Au9oMvLamhC8k8Wvgf1rp0sOAJTmb+3el5l4UzQ7T2BgTkKXRf5OT70Jlf5ykSrcXokqjB903rAOQ2+G9kHEePUK/aylxu39UhGiTGiz91d/7IWt5jlJG5aHq/yHKC7RB2QZL1c9rQribS+DbV/EajiwFf7AyrIcpD89a9bMIWenvDSHc96LtFKH/Aw+bNOhnmcOsAAAAAElFTkSuQmCC); 116 | background-size: 95px 30px; 117 | } 118 | } 119 | 120 | .running, .stopped { 121 | display: none; 122 | } 123 | 124 | .menu { 125 | background: #fff; 126 | list-style: none; 127 | margin: 0; 128 | padding: 6px 0; 129 | min-width: 100%; 130 | font-weight: 400; 131 | } 132 | .menu li { 133 | white-space: nowrap; 134 | list-style: none; 135 | } 136 | .menu li:hover { 137 | background-color: #e6e6e6; 138 | color: #222; 139 | } 140 | .menu li>button { 141 | width: 100%; 142 | padding: 8px 36px 8px 30px; 143 | font-weight: 400; 144 | border: none; 145 | background-color: rgba(0, 0, 0, 0); 146 | text-align: left; 147 | width: 200px; 148 | } 149 | button:focus { 150 | outline: none; 151 | } 152 | hr { 153 | border: none; 154 | margin: 0 5px; 155 | border-top: 1px solid #ddd; 156 | } -------------------------------------------------------------------------------- /src/styles/style.css: -------------------------------------------------------------------------------- 1 | .toggl-button { 2 | display: inline-block !important; 3 | line-height: 20px; 4 | padding-left: 23px; 5 | font-size: 14px; 6 | background: url(data:image/png;base64,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/GMzLdsAAD93aVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjUtYzAxNCA3OS4xNTE0ODEsIDIwMTMvMDMvMTMtMTI6MDk6MTUgICAgICAgICI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgICAgICAgICB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIgogICAgICAgICAgICB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIgogICAgICAgICAgICB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIj4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5BZG9iZSBQaG90b3Nob3AgQ0MgKE1hY2ludG9zaCk8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgICAgPHhtcDpDcmVhdGVEYXRlPjIwMTMtMTAtMjRUMTE6MzQ6NTkrMDM6MDA8L3htcDpDcmVhdGVEYXRlPgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxMy0xMS0xOVQxNToyMToyMiswMjowMDwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6TWV0YWRhdGFEYXRlPjIwMTMtMTEtMTlUMTU6MjE6MjIrMDI6MDA8L3htcDpNZXRhZGF0YURhdGU+CiAgICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2UvcG5nPC9kYzpmb3JtYXQ+CiAgICAgICAgIDxwaG90b3Nob3A6Q29sb3JNb2RlPjM8L3Bob3Rvc2hvcDpDb2xvck1vZGU+CiAgICAgICAgIDxwaG90b3Nob3A6SUNDUHJvZmlsZT5zUkdCIElFQzYxOTY2LTIuMTwvcGhvdG9zaG9wOklDQ1Byb2ZpbGU+CiAgICAgICAgIDx4bXBNTTpJbnN0YW5jZUlEPnhtcC5paWQ6NDA5MWFhMzgtNjk2Yi00MTIzLTljODUtNjFmZDEwZGNjNmQyPC94bXBNTTpJbnN0YW5jZUlEPgogICAgICAgICA8eG1wTU06RG9jdW1lbnRJRD54bXAuZGlkOmUzNGJmNmMyLTg0NWEtNGY4MC1hY2IwLTNiYTMxNGE2Mjc3NTwveG1wTU06RG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD54bXAuZGlkOmUzNGJmNmMyLTg0NWEtNGY4MC1hY2IwLTNiYTMxNGE2Mjc3NTwveG1wTU06T3JpZ2luYWxEb2N1bWVudElEPgogICAgICAgICA8eG1wTU06SGlzdG9yeT4KICAgICAgICAgICAgPHJkZjpTZXE+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPmNyZWF0ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0Omluc3RhbmNlSUQ+eG1wLmlpZDplMzRiZjZjMi04NDVhLTRmODAtYWNiMC0zYmEzMTRhNjI3NzU8L3N0RXZ0Omluc3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMTMtMTAtMjRUMTE6MzQ6NTkrMDM6MDA8L3N0RXZ0OndoZW4+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDQyAoTWFjaW50b3NoKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPnNhdmVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDppbnN0YW5jZUlEPnhtcC5paWQ6ZWI1MmNjMmItYWFmYy00NDVjLTg3ODctM2RhNGIzYjYzNmJhPC9zdEV2dDppbnN0YW5jZUlEPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6d2hlbj4yMDEzLTExLTE5VDE1OjIxOjIyKzAyOjAwPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6c29mdHdhcmVBZ2VudD5BZG9iZSBQaG90b3Nob3AgQ0MgKE1hY2ludG9zaCk8L3N0RXZ0OnNvZnR3YXJlQWdlbnQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpjaGFuZ2VkPi88L3N0RXZ0OmNoYW5nZWQ+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5jb252ZXJ0ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnBhcmFtZXRlcnM+ZnJvbSBhcHBsaWNhdGlvbi92bmQuYWRvYmUucGhvdG9zaG9wIHRvIGltYWdlL3BuZzwvc3RFdnQ6cGFyYW1ldGVycz4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPmRlcml2ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnBhcmFtZXRlcnM+Y29udmVydGVkIGZyb20gYXBwbGljYXRpb24vdm5kLmFkb2JlLnBob3Rvc2hvcCB0byBpbWFnZS9wbmc8L3N0RXZ0OnBhcmFtZXRlcnM+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5zYXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOjQwOTFhYTM4LTY5NmItNDEyMy05Yzg1LTYxZmQxMGRjYzZkMjwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAxMy0xMS0xOVQxNToyMToyMiswMjowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9zaG9wIENDIChNYWNpbnRvc2gpPC9zdEV2dDpzb2Z0d2FyZUFnZW50PgogICAgICAgICAgICAgICAgICA8c3RFdnQ6Y2hhbmdlZD4vPC9zdEV2dDpjaGFuZ2VkPgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgPC9yZGY6U2VxPgogICAgICAgICA8L3htcE1NOkhpc3Rvcnk+CiAgICAgICAgIDx4bXBNTTpEZXJpdmVkRnJvbSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgIDxzdFJlZjppbnN0YW5jZUlEPnhtcC5paWQ6ZWI1MmNjMmItYWFmYy00NDVjLTg3ODctM2RhNGIzYjYzNmJhPC9zdFJlZjppbnN0YW5jZUlEPgogICAgICAgICAgICA8c3RSZWY6ZG9jdW1lbnRJRD54bXAuZGlkOmUzNGJmNmMyLTg0NWEtNGY4MC1hY2IwLTNiYTMxNGE2Mjc3NTwvc3RSZWY6ZG9jdW1lbnRJRD4KICAgICAgICAgICAgPHN0UmVmOm9yaWdpbmFsRG9jdW1lbnRJRD54bXAuZGlkOmUzNGJmNmMyLTg0NWEtNGY4MC1hY2IwLTNiYTMxNGE2Mjc3NTwvc3RSZWY6b3JpZ2luYWxEb2N1bWVudElEPgogICAgICAgICA8L3htcE1NOkRlcml2ZWRGcm9tPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICAgICA8dGlmZjpYUmVzb2x1dGlvbj43MjAwMDAvMTAwMDA8L3RpZmY6WFJlc29sdXRpb24+CiAgICAgICAgIDx0aWZmOllSZXNvbHV0aW9uPjcyMDAwMC8xMDAwMDwvdGlmZjpZUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6UmVzb2x1dGlvblVuaXQ+MjwvdGlmZjpSZXNvbHV0aW9uVW5pdD4KICAgICAgICAgPGV4aWY6Q29sb3JTcGFjZT4xPC9leGlmOkNvbG9yU3BhY2U+CiAgICAgICAgIDxleGlmOlBpeGVsWERpbWVuc2lvbj4xOTwvZXhpZjpQaXhlbFhEaW1lbnNpb24+CiAgICAgICAgIDxleGlmOlBpeGVsWURpbWVuc2lvbj4xOTwvZXhpZjpQaXhlbFlEaW1lbnNpb24+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIAo8P3hwYWNrZXQgZW5kPSJ3Ij8+BywqOQAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAABtElEQVR42pTUP2gUURDH8c8tpxHBKP5pTjaGi4d1CBjQFMIpgpJSsVULwd5CELUStUyIFv6pRatwWFhY2Ag2KtiIsKB3rCHEvwghooXNnCzLbtBv85jfvDc7O2/eNPqttgr24BSOYS924hMyPMYDfIA0z/4eapSCbcY1nMcG9fzCbVxM82y1KtguPMGkf+cVjqZ5tgJJiBvRqwn0HY9iLTOJ3mD3xEgx2A1M13y9j5OxVjGN68PfHIvCNivqcgtbcBb38KOmnr/RSXCmItAqurhUyD4Juxv+Ik2cTnC4IvUrke0bTIU2hZehX644cyRBuyLlO7iK8ZKvE/rd2FdkX4IdJXEpbq7uQvaHf6mkb0/wuSSOooGvYY/hYazwLfyjpXNfkqhBka2YwULBPhGr0GcK9pC3Sby1MjexiHNYDm057MXwl+k1+q12infYVHI+jbYZYFv8Xor70R5FfqLTjM3zuFDa0I0SPMdHtHCgoidhLs2zwfChj+DZOje4Hi9wKM2ztaSQ5mxMgf/hNWbTPFsrPnRYiVuaq2hIFY09j4PD8VM1HIeMx6Q9jomaSfu+PGn/DAC1Y3IADwOltQAAAABJRU5ErkJggg==) no-repeat left top; 7 | } 8 | .toggl-button.min { 9 | height: 19px; 10 | padding-left: 19px; 11 | } 12 | .toggl-button.min:not(.active) { 13 | background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAQAAADYWf5HAAABIklEQVR4AYWSu0qDURCEN80fkUCwSCPk8iJ5DF/BF1Aw1Ye2NhpLQSwFn8EiMd4qb6WNEDCkEdIETVLogDm7RyzMMvwzO8ue4eRY/GiyQ583ZsKleBNLlcgqh8z5yku6q342VuM+7LzUr6WxgrvMmHAuuJZX/hk7kIh6xoSsI9+MBotIo4QnmJAlld8ydl1OaVPhFBMq4lN39owrF9us87o89EV8y50bY+SrqxxHNvGqx3k3Zks6lP2UjT1iDNO+2DahRC+7kJ70JLYNPEGbjbgG8bbza6Pj4paCTcZiY30L6eR0jDofLi9oUGJNaIin7id1w9gXjavscyYsoiffDKMc/+nfkrfy/wt5kPfrvXX9oAhwFO8tqkWHASPmwkC8Fd430YaitSJltegAAAAASUVORK5CYII=) no-repeat left top; 14 | } 15 | 16 | @media only screen and (-webkit-min-device-pixel-ratio: 1.5), 17 | only screen and (min-resolution: 192dpi) { 18 | .toggl-button { 19 | background-image: url(data:image/png;base64,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); 20 | background-size: 19px 19px; 21 | } 22 | .toggl-button.min:not(.active) { 23 | background-image: url(data:image/png;base64,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); 24 | background-size: 19px 19px; 25 | } 26 | } 27 | 28 | #toggl-button-edit-form { 29 | position: absolute; 30 | width: 240px !important; 31 | height: 240px; 32 | padding: 10px !important; 33 | -webkit-box-shadow: 0 1px 3px rgba(128,128,128,.5); 34 | -moz-box-shadow: 0 1px 3px rgba(128,128,128,.5); 35 | box-shadow: 0 1px 3px rgba(128,128,128,.5); 36 | -webkit-border-radius: 3px; 37 | border-radius: 3px; 38 | background-color: #ffffff; 39 | z-index: 999999; 40 | } 41 | 42 | #toggl-button-edit-form .toggl-button{ 43 | margin: 0 !important; 44 | border: none !important; 45 | visibility: visible !important; 46 | } 47 | #toggl-button-edit-form .toggl-button:hover{ 48 | background-color: transparent; 49 | } 50 | 51 | .toggl-button-row { 52 | margin: 0; 53 | padding: 10px 0; 54 | } 55 | .toggl-button-row label { 56 | display: block; 57 | font-size: 13px; 58 | height: 20px; 59 | } 60 | p.toggl-button-row.first { 61 | margin-top: 0; 62 | margin-bottom: 0; 63 | } 64 | .toggl-button-input { 65 | background: #f5f5f5; 66 | border: 1px solid #e1e1e1; 67 | font-size: 0.7em; 68 | padding: 5px; 69 | width: 220px; 70 | } 71 | #toggl-button-description, #toggl-button-project { 72 | height: 35px !important; 73 | font-size: 13px !important; 74 | margin: 0 !important; 75 | padding: 0 10px !important; 76 | width: 220px !important; 77 | } 78 | #toggl-button-project { 79 | width: 100% !important; 80 | } 81 | 82 | #toggl-button-hide, #toggl-button-update { 83 | height: 34px; 84 | font-size: 0.7em; 85 | text-transform: uppercase; 86 | padding: 10px 14px 8px; 87 | border: 1px solid #63b618; 88 | color: white; 89 | text-shadow: 0 1px 1px rgba(0,0,0,.25); 90 | font-weight: bold; 91 | font-size: 12px; 92 | display: inline-block; 93 | -webkit-box-shadow: 0 1px 1px rgba(0,0,0,.5); 94 | box-shadow: 0 1px 1px rgba(0,0,0,.5); 95 | background-color: #8dcc35; 96 | background-image: -webkit-gradient(linear, left top, left bottom, from(#8dcc35), to(#47a204)); 97 | background-image: -webkit-linear-gradient(top, #8dcc35, #47a204); 98 | background-image: -moz-linear-gradient(top, #8dcc35, #47a204); 99 | background-image: -o-linear-gradient(top, #8dcc35, #47a204); 100 | background-image: linear-gradient(to bottom, #8dcc35, #47a204); 101 | -webkit-border-radius: 3px; 102 | border-radius: 3px; 103 | border: none; 104 | cursor: pointer; 105 | font-family: inherit; 106 | } 107 | #toggl-button-hide{ 108 | float: left; 109 | } 110 | #toggl-button-update { 111 | float: right; 112 | } 113 | #toggl-button-submit-row { 114 | position:absolute; 115 | left: 10px; 116 | right: 10px; 117 | bottom: 10px; 118 | margin: 0 !important; 119 | } 120 | 121 | /********* PIVOTAL *********/ 122 | .toggl-button.pivotal { 123 | margin-top: 10px; 124 | } 125 | 126 | /********* BITBUCKET *********/ 127 | .toggl-button.bitbucket { 128 | border-color: #ccc; 129 | margin-left:15px; 130 | } 131 | 132 | /********* GITHUB *********/ 133 | .toggl-button.github { 134 | padding-left: 21px; 135 | margin-left: 5px; 136 | } 137 | 138 | /********* YOUTRACK *********/ 139 | .toggl-button.youtrack { 140 | float: right; 141 | } 142 | 143 | /********* ASANA *********/ 144 | .toggl-button.asana { 145 | margin-left: 52px; 146 | margin-bottom: 5px; 147 | color: #596573; 148 | line-height: 22px; 149 | font-size: 12px; 150 | font-weight: 600; 151 | } 152 | 153 | /********* PODIO *********/ 154 | .toggl-button.podio { 155 | width: 65px; 156 | margin-left: 4px; 157 | } 158 | 159 | /********* GITLAB *********/ 160 | .toggl-button.gitlab { 161 | font-size: 75%; 162 | margin-left: 8px; 163 | padding-left: 21px; 164 | } 165 | 166 | /********* JIRA *********/ 167 | .toggl-button.jira { 168 | margin-top:.2em; 169 | } 170 | 171 | /********* UNFUDDLE *********/ 172 | .toggl-button.unfuddle { 173 | margin-left: 4px; 174 | line-height: 18px; 175 | padding-left: 18px; 176 | background-size: 16px; 177 | } 178 | 179 | /********* TRELLO *********/ 180 | .toggl-button.trello { 181 | text-decoration: none; 182 | cursor: pointer; 183 | color: #737373; 184 | } 185 | 186 | .checklist-item-button { 187 | position: absolute; 188 | top: 2px; 189 | right: 0; 190 | } 191 | 192 | .checklist-item-details-text { 193 | max-width: 94%; 194 | } 195 | 196 | /********* BASECAMP *********/ 197 | .toggl-button.basecamp { 198 | font-size: 12px; 199 | height: 14px; 200 | margin-left: 3px; 201 | line-height: 14px; 202 | padding-left: 19px; 203 | background-size: 17px; 204 | visibility: hidden; 205 | } 206 | 207 | /********* TEAMWEEK *********/ 208 | .toggl-button.teamweek-new { 209 | color: rgba(47,47,47,0.8); 210 | margin: 12px; 211 | margin-top: 18px; 212 | } 213 | 214 | /********* PRODUCTEEV *********/ 215 | .toggl-button.producteev { 216 | margin-left: 12px; 217 | margin-bottom: 2px; 218 | } 219 | 220 | /********* REDBOOTH *********/ 221 | .toggl-button.redbooth { 222 | font-size: 12px; 223 | line-height: 16px; 224 | padding-left: 18px; 225 | background-size: 16px; 226 | } 227 | 228 | /********* WORKSECTION *********/ 229 | #tmenu2 .toggl-button.worksection { 230 | margin-top: 9px; 231 | padding-top: 0px; 232 | line-height: 21px; 233 | padding-left: 21px; 234 | } 235 | 236 | /********* SIFTER *********/ 237 | .toggl-button.sifterapp { 238 | color: white; 239 | float: right; 240 | } 241 | 242 | .toggl-button.sifterapp.active { 243 | color: rgb(52, 255, 125) !important; 244 | } 245 | 246 | /********* GOOGLE DOCS *********/ 247 | .toggl-button.google-docs { 248 | background-size: 17px; 249 | padding-left: 19px; 250 | } 251 | 252 | .toggl-button.google-docs.min { 253 | margin-bottom: -10px; 254 | margin-left: 5px; 255 | } 256 | 257 | /********* REDMINE *********/ 258 | .toggl-button.redmine { 259 | float: right; 260 | font-size: .8em; 261 | font-weight: normal; 262 | margin-top: 4px; 263 | } 264 | 265 | /********* CAPSULECRM *********/ 266 | .toggl-button.capsule { 267 | line-height: 15px; 268 | background-position: 7% 40%; 269 | padding-left: 30px !important; 270 | } 271 | 272 | /****** Zendesk *********/ 273 | .toggl-button.zendesk { 274 | float: right; 275 | padding-right: 3em; 276 | margin-top: -1.5em; 277 | } 278 | 279 | /****** Anydo *********/ 280 | .toggl-button.anydo { 281 | color: #099acb; 282 | margin-left: 10px; 283 | } 284 | 285 | 286 | /********* wunderlist *********/ 287 | .toggl-button.wunderlist { 288 | text-decoration: none; 289 | cursor: pointer; 290 | color: #737373; 291 | margin: 0px; 292 | display: inline; 293 | } 294 | 295 | .taskItem-toggl { 296 | z-index: 1; 297 | display: inline; 298 | margin-bottom: -20px; 299 | padding-top: -5px; 300 | padding-right: 10px; 301 | line-height: 100%; 302 | position: absolute; 303 | top: 8px; 304 | bottom: 0; 305 | left: 0; 306 | } 307 | 308 | .detailItem-toggl { 309 | position: relative; 310 | left: 10px; 311 | top: 32px; 312 | } 313 | 314 | .toggl > .taskItem-titleWrapper-title, .toggl > .taskItem-titleMeta-info { 315 | margin-left: 25px; 316 | } 317 | 318 | 319 | 320 | /****** todoist *********/ 321 | .toggl-button.todoist { 322 | font-size: 12px; 323 | padding-left: 20px; 324 | background-size: 18px; 325 | margin-left: 7px; 326 | visibility: hidden; 327 | } 328 | 329 | .toggl-button.todoist.active { 330 | visibility: visible; 331 | } 332 | 333 | .task_content_item:hover .toggl-button { 334 | visibility: visible; 335 | } 336 | 337 | /********* XERO *********/ 338 | #xero-nav .xn-h-header-tabs a.toggl-button { 339 | background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAFa9AABWvQE1bkh1AAAAB3RJTUUH3QQeBxszNJufNAAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAANsSURBVDjLrZRPaFxVFMZ/57735s1LMzMxmca0nQRCqkmTmgZSUUs1BYM70YK4CCgKunTRvQsVXRZD92rdCEWKiyhoFWOKFRFsWg1pMW1jpyltJpNkJvMv781797pI86zSShfe1eWecz++7zt/4H88cr/ANNhd3f2dKmnlxEpkmhJpKzIra/XS0jdLS6V3QT8ImMwPDAwl7eRRUda4KOkzSItgtDGmHEVmrqmjrwrV9amxfP7WfcGmwe4ZHHnRcqy3RNSTiDgiEucYYwyA1rrqR9GXa74/eWhh/pd7gcnC4MhLtmO/o5TadzeIlduDrlYxpXKcbLSO6mF05maj/vb41cvnAazt4PzA8H43Yb+nlDV6N5CkU6ReexVJpQivXgO9ZZWIKEek1xZx9vrOuTP+RsPalpftyr1p2WpCRNkAKEXi4CjuwVESg/sQ28bavQtdq2HK5RhQRHKtLnMn14qXFUBXf3+nWDIO4mwzcg89ResrE6i2DIQhJghwHn2E1BuvY+X2xHITIh2enRg/Bp4CUFYyJ0LftjxJp/CeGye48Bu1019gggBdWKHyyaeIskgeGQOl7vggyrPUY93ZnjYFIEoygrTEhu/ciZXtYPPcT9DYBGPAGPSt2/gXLuLs7QPXjdkpkXbPjVptAB1F2ti2/tv1O7cowoQhjbM/Et1ejt9QChHBxC2DrosYBdAMddEYKW/3UVRcRZfKuE88DsDmd9/T/H0O1f4QieH9hIt/Ynw/ZrapdaEYBBUboNIo3/Bcd04puxfAlEo0pn9gxwvPI46DP3sRafHwnj6MeC1szpzdYghoo6NS0/91tlAoWQC5jQ1/MNuZsix1RIlyAcLreUy9TmLkAN4zh3GHhohWV6l9fppw4Uo8EZUwzM/Vyic+3Nj4I7Zppqdn18PpjuOebb8sSsXNLK2tqEwaE0Xo9XXwg1heEEX1xXrtxPsLlz6YgWr86WS5XJ3ItN+wldXtiPSKyFbtgwBTqWCqtViaMcY0tW4sNRqnpgrFyVN+bfkf4wTw0drKzaOplku2WI4IOQXJfy8DY0xYicLrS43Gx1OF4uRkuXDtP/fZ8XS6/UB291jGtZ91lT2sRNoN6E0dLa83g/OLfv3bz/L5n2eg+kDLEeAYeN3ZbFsimdzh+1CsB5XZWqH0Nfj3yv8LMvl8kMnBqycAAAAASUVORK5CYII=) no-repeat !important; 340 | background-position: 0px !important; 341 | padding-left: 22px; 342 | } 343 | 344 | /****** Trac v1.x *********/ 345 | #content .toggl-button.trac { 346 | display: inline; 347 | background-color: #eee; 348 | background-position: 0.1em 0.1em; 349 | color: #222; 350 | border: 1px outset #eee; 351 | border-radius: .3em; 352 | box-shadow: .1em .1em .4em 0 #888; 353 | text-shadow: .1em .1em #ddd; 354 | padding: .1em .3em 0 1.7em; 355 | margin: 0 0 0 0.2em; 356 | cursor: pointer; 357 | font-size: 13px; 358 | font-weight: normal; 359 | text-decoration: none; 360 | } 361 | 362 | #content .toggl-button.trac:hover { 363 | background-color: #f6f6f6; 364 | box-shadow: .1em .1em .6em 0 #999; 365 | text-shadow: .1em .1em #fcfcfc; 366 | } 367 | 368 | #content .toggl-button.trac:active { 369 | position: relative; 370 | top: .1em; 371 | left: .1em; 372 | } 373 | 374 | #content .toggl-button.trac.active { 375 | color: rgb(34, 34, 34) !important; 376 | background-color: rgb(26, 179, 81); 377 | border-color: rgb(26, 179, 81); 378 | text-shadow: rgb(180, 180, 180) .1em .1em; 379 | } 380 | 381 | #content .toggl-button.trac.active:hover { 382 | background-color: rgb(137, 224, 168); 383 | border-color: rgb(137, 224, 168); 384 | } 385 | 386 | /****** Trac v0.x *********/ 387 | #content > #trac-ticket-title > .toggl-button.trac { 388 | border: 1px outset #ccc; 389 | border-radius: 0; 390 | box-shadow: none; 391 | text-shadow: none; 392 | cursor: default; 393 | } 394 | 395 | #content > #trac-ticket-title > .toggl-button.trac:hover { 396 | background-color: #ccb; 397 | box-shadow: none; 398 | text-shadow: none; 399 | } 400 | 401 | #content > #trac-ticket-title > .toggl-button.trac:active { 402 | top: 0; 403 | left: 0; 404 | } 405 | 406 | #content > #trac-ticket-title > .toggl-button.trac.active { 407 | background-color: rgb(137, 224, 168); 408 | border-color: rgb(137, 224, 168); 409 | text-shadow: none; 410 | } 411 | 412 | #content > #trac-ticket-title > .toggl-button.trac.active:hover { 413 | background-color: rgb(26, 179, 81); 414 | border-color: rgb(26, 179, 81); 415 | } 416 | 417 | /****** WordPress Trac *********/ 418 | 419 | #wordpress-org #content .toggl-button.trac { 420 | border: 1px solid #eee; 421 | text-decoration: none; 422 | font-size: 12px; 423 | line-height: 23px; 424 | height: 24px; 425 | margin: 0; 426 | padding: 0 10px 1px 28px; 427 | cursor: pointer; 428 | -webkit-appearance: none; 429 | white-space: nowrap; 430 | box-sizing: border-box; 431 | background-color: #f3f3f3; 432 | border-color: #bbb; 433 | color: #333; 434 | border-radius: 3px; 435 | text-shadow: none; 436 | box-shadow: none; 437 | background-position: 7px 1px; 438 | } 439 | 440 | #wordpress-org #content .toggl-button.trac:hover { 441 | border-color: #999; 442 | color: #222; 443 | } 444 | 445 | #wordpress-org #content .toggl-button.trac:active { 446 | top: 0; 447 | left: 0; 448 | } 449 | 450 | #wordpress-org #content .toggl-button.trac.active { 451 | color: rgb(34, 34, 34) !important; 452 | background-color: rgb(137, 224, 168); 453 | border-color: rgb(26, 179, 81); 454 | } 455 | 456 | #wordpress-org #content .toggl-button.trac.active:hover { 457 | border-color: rgb(22, 148, 67); 458 | } 459 | --------------------------------------------------------------------------------