Compare commits
37 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1a9b860e68 | |||
| cede7d0f35 | |||
| fe26d383f1 | |||
| df4bc268dc | |||
| e49da6c13f | |||
| 67b7262764 | |||
| 88528ef979 | |||
| b6175b1ca9 | |||
| aa20ebaa9c | |||
| 779e45c11b | |||
| 5d5a6eabaa | |||
| 03c9b53232 | |||
| ebaded66b4 | |||
| c232eb2478 | |||
| 7559cc6897 | |||
| 69d0d6d7ee | |||
| 3e9336b15d | |||
| 5c78ecc15d | |||
| 06db3f702d | |||
| a2a82a96a6 | |||
| a86bbae851 | |||
| fac134dd95 | |||
| 515ae32160 | |||
| df8f040795 | |||
| 64a23992f0 | |||
| f5baff6e6b | |||
| 8bdd90a2a8 | |||
| 5536e97482 | |||
| de47071256 | |||
| 87072cb690 | |||
| d9565e9250 | |||
| f80b568e67 | |||
| 7fed689f9a | |||
| 3f48df8f10 | |||
| cc55092ca6 | |||
| 3331d9d01d | |||
| 62d80e6b76 |
@@ -1,3 +1,21 @@
|
||||
# v3.4.6
|
||||
|
||||
- Added picture-in-picture support for Chrome 70+
|
||||
- Fixed issue with versioning the SVG sprite in the gulp build script
|
||||
|
||||
# v3.4.5
|
||||
|
||||
- Added download button option to download either current source or a custom URL you specify in options
|
||||
- Prevent immediate hiding of controls on mobile (thanks @jamesoflol)
|
||||
- Don't hide controls on focusout event (fixes #1122) (thanks @jamesoflol)
|
||||
- Fix HTML5 quality settings being incorrectly set in local storage (thanks @TechGuard)
|
||||
|
||||
# v3.4.4
|
||||
|
||||
- Fixed issue with double binding for `click` and `touchstart` for `clickToPlay` option
|
||||
- Improved "faux" fullscreen on iPhone X/XS phones with notch
|
||||
- Babel 7 upgrade (which reduced the polyfilled build by ~10kb!)
|
||||
|
||||
# v3.4.3
|
||||
|
||||
- Fixed issue with nodeList for custom playback controls
|
||||
|
||||
@@ -28,6 +28,7 @@ controls: [
|
||||
'settings', // Settings menu
|
||||
'pip', // Picture-in-picture (currently Safari only)
|
||||
'airplay', // Airplay (currently Safari only)
|
||||
'download', // Show a download button with a link to either the current source or a custom URL you specify in your options
|
||||
'fullscreen', // Toggle fullscreen
|
||||
];
|
||||
```
|
||||
|
||||
@@ -1833,7 +1833,6 @@ typeof navigator === "object" && (function () {
|
||||
};
|
||||
this._fetchDefaults = {
|
||||
method: 'POST',
|
||||
keepalive: true,
|
||||
// Despite all stars in the sky saying that Edge supports old draft syntax, aka 'never', 'always', 'origin' and 'default
|
||||
// https://caniuse.com/#feat=referrer-policy
|
||||
// It doesn't. And it throw exception instead of ignoring this parameter...
|
||||
@@ -1874,7 +1873,7 @@ typeof navigator === "object" && (function () {
|
||||
// webpack (using a build step causes webpack #1617). Grunt verifies that
|
||||
// this value matches package.json during build.
|
||||
// See: https://github.com/getsentry/raven-js/issues/465
|
||||
VERSION: '3.26.4',
|
||||
VERSION: '3.27.0',
|
||||
|
||||
debug: false,
|
||||
|
||||
@@ -2612,7 +2611,7 @@ typeof navigator === "object" && (function () {
|
||||
)
|
||||
return;
|
||||
|
||||
options = Object.assign(
|
||||
options = objectMerge$1(
|
||||
{
|
||||
eventId: this.lastEventId(),
|
||||
dsn: this._dsn,
|
||||
@@ -4093,276 +4092,263 @@ typeof navigator === "object" && (function () {
|
||||
// ==========================================================================
|
||||
|
||||
(function () {
|
||||
var host = window.location.host;
|
||||
var host = window.location.host;
|
||||
var env = {
|
||||
prod: host === 'plyr.io',
|
||||
dev: host === 'dev.plyr.io'
|
||||
};
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
singleton.context(function () {
|
||||
var selector = '#player';
|
||||
var container = document.getElementById('container');
|
||||
|
||||
var env = {
|
||||
prod: host === 'plyr.io',
|
||||
dev: host === 'dev.plyr.io'
|
||||
};
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
singleton.context(function () {
|
||||
var selector = '#player';
|
||||
var container = document.getElementById('container');
|
||||
|
||||
if (window.shr) {
|
||||
window.shr.setup({
|
||||
count: {
|
||||
classname: 'button__count'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Setup tab focus
|
||||
var tabClassName = 'tab-focus';
|
||||
|
||||
// Remove class on blur
|
||||
document.addEventListener('focusout', function (event) {
|
||||
if (!event.target.classList || container.contains(event.target)) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.target.classList.remove(tabClassName);
|
||||
});
|
||||
|
||||
// Add classname to tabbed elements
|
||||
document.addEventListener('keydown', function (event) {
|
||||
if (event.keyCode !== 9) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Delay the adding of classname until the focus has changed
|
||||
// This event fires before the focusin event
|
||||
setTimeout(function () {
|
||||
var focused = document.activeElement;
|
||||
|
||||
if (!focused || !focused.classList || container.contains(focused)) {
|
||||
return;
|
||||
}
|
||||
|
||||
focused.classList.add(tabClassName);
|
||||
}, 10);
|
||||
});
|
||||
|
||||
// Setup the player
|
||||
var player = new Plyr(selector, {
|
||||
debug: true,
|
||||
title: 'View From A Blue Moon',
|
||||
iconUrl: '../dist/plyr.svg',
|
||||
keyboard: {
|
||||
global: true
|
||||
},
|
||||
tooltips: {
|
||||
controls: true
|
||||
},
|
||||
captions: {
|
||||
active: true
|
||||
},
|
||||
keys: {
|
||||
google: 'AIzaSyDrNwtN3nLH_8rjCmu5Wq3ZCm4MNAVdc0c'
|
||||
},
|
||||
ads: {
|
||||
enabled: env.prod || env.dev,
|
||||
publisherId: '918848828995742'
|
||||
}
|
||||
});
|
||||
|
||||
// Expose for tinkering in the console
|
||||
window.player = player;
|
||||
|
||||
// Setup type toggle
|
||||
var buttons = document.querySelectorAll('[data-source]');
|
||||
var types = {
|
||||
video: 'video',
|
||||
audio: 'audio',
|
||||
youtube: 'youtube',
|
||||
vimeo: 'vimeo'
|
||||
};
|
||||
var currentType = window.location.hash.replace('#', '');
|
||||
var historySupport = window.history && window.history.pushState;
|
||||
|
||||
// Toggle class on an element
|
||||
function toggleClass(element, className, state) {
|
||||
if (element) {
|
||||
element.classList[state ? 'add' : 'remove'](className);
|
||||
}
|
||||
}
|
||||
|
||||
// Set a new source
|
||||
function newSource(type, init) {
|
||||
// Bail if new type isn't known, it's the current type, or current type is empty (video is default) and new type is video
|
||||
if (!(type in types) || !init && type === currentType || !currentType.length && type === types.video) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case types.video:
|
||||
player.source = {
|
||||
type: 'video',
|
||||
title: 'View From A Blue Moon',
|
||||
sources: [{
|
||||
src: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-576p.mp4',
|
||||
type: 'video/mp4',
|
||||
size: 576
|
||||
}, {
|
||||
src: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-720p.mp4',
|
||||
type: 'video/mp4',
|
||||
size: 720
|
||||
}, {
|
||||
src: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-1080p.mp4',
|
||||
type: 'video/mp4',
|
||||
size: 1080
|
||||
}, {
|
||||
src: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-1440p.mp4',
|
||||
type: 'video/mp4',
|
||||
size: 1440
|
||||
}],
|
||||
poster: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.jpg',
|
||||
tracks: [{
|
||||
kind: 'captions',
|
||||
label: 'English',
|
||||
srclang: 'en',
|
||||
src: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.en.vtt',
|
||||
default: true
|
||||
}, {
|
||||
kind: 'captions',
|
||||
label: 'French',
|
||||
srclang: 'fr',
|
||||
src: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.fr.vtt'
|
||||
}]
|
||||
};
|
||||
|
||||
break;
|
||||
|
||||
case types.audio:
|
||||
player.source = {
|
||||
type: 'audio',
|
||||
title: 'Kishi Bashi – “It All Began With A Burst”',
|
||||
sources: [{
|
||||
src: 'https://cdn.plyr.io/static/demo/Kishi_Bashi_-_It_All_Began_With_a_Burst.mp3',
|
||||
type: 'audio/mp3'
|
||||
}, {
|
||||
src: 'https://cdn.plyr.io/static/demo/Kishi_Bashi_-_It_All_Began_With_a_Burst.ogg',
|
||||
type: 'audio/ogg'
|
||||
}]
|
||||
};
|
||||
|
||||
break;
|
||||
|
||||
case types.youtube:
|
||||
player.source = {
|
||||
type: 'video',
|
||||
sources: [{
|
||||
src: 'https://youtube.com/watch?v=bTqVqk7FSmY',
|
||||
provider: 'youtube'
|
||||
}]
|
||||
};
|
||||
|
||||
break;
|
||||
|
||||
case types.vimeo:
|
||||
player.source = {
|
||||
type: 'video',
|
||||
sources: [{
|
||||
src: 'https://vimeo.com/76979871',
|
||||
provider: 'vimeo'
|
||||
}]
|
||||
};
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Set the current type for next time
|
||||
currentType = type;
|
||||
|
||||
// Remove active classes
|
||||
Array.from(buttons).forEach(function (button) {
|
||||
return toggleClass(button.parentElement, 'active', false);
|
||||
});
|
||||
|
||||
// Set active on parent
|
||||
toggleClass(document.querySelector('[data-source="' + type + '"]'), 'active', true);
|
||||
|
||||
// Show cite
|
||||
Array.from(document.querySelectorAll('.plyr__cite')).forEach(function (cite) {
|
||||
cite.setAttribute('hidden', '');
|
||||
});
|
||||
document.querySelector('.plyr__cite--' + type).removeAttribute('hidden');
|
||||
}
|
||||
|
||||
// Bind to each button
|
||||
Array.from(buttons).forEach(function (button) {
|
||||
button.addEventListener('click', function () {
|
||||
var type = button.getAttribute('data-source');
|
||||
|
||||
newSource(type);
|
||||
|
||||
if (historySupport) {
|
||||
window.history.pushState({ type: type }, '', '#' + type);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// List for backwards/forwards
|
||||
window.addEventListener('popstate', function (event) {
|
||||
if (event.state && 'type' in event.state) {
|
||||
newSource(event.state.type);
|
||||
}
|
||||
});
|
||||
|
||||
// On load
|
||||
if (historySupport) {
|
||||
var video = !currentType.length;
|
||||
|
||||
// If there's no current type set, assume video
|
||||
if (video) {
|
||||
currentType = types.video;
|
||||
}
|
||||
|
||||
// Replace current history state
|
||||
if (currentType in types) {
|
||||
window.history.replaceState({
|
||||
type: currentType
|
||||
}, '', video ? '' : '#' + currentType);
|
||||
}
|
||||
|
||||
// If it's not video, load the source
|
||||
if (currentType !== types.video) {
|
||||
newSource(currentType, true);
|
||||
}
|
||||
}
|
||||
if (window.shr) {
|
||||
window.shr.setup({
|
||||
count: {
|
||||
classname: 'button__count'
|
||||
}
|
||||
});
|
||||
});
|
||||
} // Setup tab focus
|
||||
|
||||
// Raven / Sentry
|
||||
// For demo site (https://plyr.io) only
|
||||
if (env.prod) {
|
||||
singleton.config('https://d4ad9866ad834437a4754e23937071e4@sentry.io/305555').install();
|
||||
}
|
||||
|
||||
// Google analytics
|
||||
// For demo site (https://plyr.io) only
|
||||
/* eslint-disable */
|
||||
if (env.prod) {
|
||||
(function (i, s, o, g, r, a, m) {
|
||||
i.GoogleAnalyticsObject = r;
|
||||
i[r] = i[r] || function () {
|
||||
(i[r].q = i[r].q || []).push(arguments);
|
||||
var tabClassName = 'tab-focus'; // Remove class on blur
|
||||
|
||||
document.addEventListener('focusout', function (event) {
|
||||
if (!event.target.classList || container.contains(event.target)) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.target.classList.remove(tabClassName);
|
||||
}); // Add classname to tabbed elements
|
||||
|
||||
document.addEventListener('keydown', function (event) {
|
||||
if (event.keyCode !== 9) {
|
||||
return;
|
||||
} // Delay the adding of classname until the focus has changed
|
||||
// This event fires before the focusin event
|
||||
|
||||
|
||||
setTimeout(function () {
|
||||
var focused = document.activeElement;
|
||||
|
||||
if (!focused || !focused.classList || container.contains(focused)) {
|
||||
return;
|
||||
}
|
||||
|
||||
focused.classList.add(tabClassName);
|
||||
}, 10);
|
||||
}); // Setup the player
|
||||
|
||||
var player = new Plyr(selector, {
|
||||
debug: true,
|
||||
title: 'View From A Blue Moon',
|
||||
iconUrl: '../dist/plyr.svg',
|
||||
keyboard: {
|
||||
global: true
|
||||
},
|
||||
tooltips: {
|
||||
controls: true
|
||||
},
|
||||
captions: {
|
||||
active: true
|
||||
},
|
||||
keys: {
|
||||
google: 'AIzaSyDrNwtN3nLH_8rjCmu5Wq3ZCm4MNAVdc0c'
|
||||
},
|
||||
ads: {
|
||||
enabled: env.prod || env.dev,
|
||||
publisherId: '918848828995742'
|
||||
}
|
||||
}); // Expose for tinkering in the console
|
||||
|
||||
window.player = player; // Setup type toggle
|
||||
|
||||
var buttons = document.querySelectorAll('[data-source]');
|
||||
var types = {
|
||||
video: 'video',
|
||||
audio: 'audio',
|
||||
youtube: 'youtube',
|
||||
vimeo: 'vimeo'
|
||||
};
|
||||
var currentType = window.location.hash.replace('#', '');
|
||||
var historySupport = window.history && window.history.pushState; // Toggle class on an element
|
||||
|
||||
function toggleClass(element, className, state) {
|
||||
if (element) {
|
||||
element.classList[state ? 'add' : 'remove'](className);
|
||||
}
|
||||
} // Set a new source
|
||||
|
||||
|
||||
function newSource(type, init) {
|
||||
// Bail if new type isn't known, it's the current type, or current type is empty (video is default) and new type is video
|
||||
if (!(type in types) || !init && type === currentType || !currentType.length && type === types.video) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case types.video:
|
||||
player.source = {
|
||||
type: 'video',
|
||||
title: 'View From A Blue Moon',
|
||||
sources: [{
|
||||
src: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-576p.mp4',
|
||||
type: 'video/mp4',
|
||||
size: 576
|
||||
}, {
|
||||
src: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-720p.mp4',
|
||||
type: 'video/mp4',
|
||||
size: 720
|
||||
}, {
|
||||
src: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-1080p.mp4',
|
||||
type: 'video/mp4',
|
||||
size: 1080
|
||||
}, {
|
||||
src: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-1440p.mp4',
|
||||
type: 'video/mp4',
|
||||
size: 1440
|
||||
}],
|
||||
poster: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.jpg',
|
||||
tracks: [{
|
||||
kind: 'captions',
|
||||
label: 'English',
|
||||
srclang: 'en',
|
||||
src: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.en.vtt',
|
||||
default: true
|
||||
}, {
|
||||
kind: 'captions',
|
||||
label: 'French',
|
||||
srclang: 'fr',
|
||||
src: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.fr.vtt'
|
||||
}]
|
||||
};
|
||||
i[r].l = 1 * new Date();
|
||||
a = s.createElement(o);
|
||||
m = s.getElementsByTagName(o)[0];
|
||||
a.async = 1;
|
||||
a.src = g;
|
||||
m.parentNode.insertBefore(a, m);
|
||||
})(window, document, 'script', 'https://www.google-analytics.com/analytics.js', 'ga');
|
||||
window.ga('create', 'UA-40881672-11', 'auto');
|
||||
window.ga('send', 'pageview');
|
||||
}
|
||||
/* eslint-enable */
|
||||
break;
|
||||
|
||||
case types.audio:
|
||||
player.source = {
|
||||
type: 'audio',
|
||||
title: 'Kishi Bashi – “It All Began With A Burst”',
|
||||
sources: [{
|
||||
src: 'https://cdn.plyr.io/static/demo/Kishi_Bashi_-_It_All_Began_With_a_Burst.mp3',
|
||||
type: 'audio/mp3'
|
||||
}, {
|
||||
src: 'https://cdn.plyr.io/static/demo/Kishi_Bashi_-_It_All_Began_With_a_Burst.ogg',
|
||||
type: 'audio/ogg'
|
||||
}]
|
||||
};
|
||||
break;
|
||||
|
||||
case types.youtube:
|
||||
player.source = {
|
||||
type: 'video',
|
||||
sources: [{
|
||||
src: 'https://youtube.com/watch?v=bTqVqk7FSmY',
|
||||
provider: 'youtube'
|
||||
}]
|
||||
};
|
||||
break;
|
||||
|
||||
case types.vimeo:
|
||||
player.source = {
|
||||
type: 'video',
|
||||
sources: [{
|
||||
src: 'https://vimeo.com/76979871',
|
||||
provider: 'vimeo'
|
||||
}]
|
||||
};
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
} // Set the current type for next time
|
||||
|
||||
|
||||
currentType = type; // Remove active classes
|
||||
|
||||
Array.from(buttons).forEach(function (button) {
|
||||
return toggleClass(button.parentElement, 'active', false);
|
||||
}); // Set active on parent
|
||||
|
||||
toggleClass(document.querySelector("[data-source=\"".concat(type, "\"]")), 'active', true); // Show cite
|
||||
|
||||
Array.from(document.querySelectorAll('.plyr__cite')).forEach(function (cite) {
|
||||
cite.setAttribute('hidden', '');
|
||||
});
|
||||
document.querySelector(".plyr__cite--".concat(type)).removeAttribute('hidden');
|
||||
} // Bind to each button
|
||||
|
||||
|
||||
Array.from(buttons).forEach(function (button) {
|
||||
button.addEventListener('click', function () {
|
||||
var type = button.getAttribute('data-source');
|
||||
newSource(type);
|
||||
|
||||
if (historySupport) {
|
||||
window.history.pushState({
|
||||
type: type
|
||||
}, '', "#".concat(type));
|
||||
}
|
||||
});
|
||||
}); // List for backwards/forwards
|
||||
|
||||
window.addEventListener('popstate', function (event) {
|
||||
if (event.state && 'type' in event.state) {
|
||||
newSource(event.state.type);
|
||||
}
|
||||
}); // On load
|
||||
|
||||
if (historySupport) {
|
||||
var video = !currentType.length; // If there's no current type set, assume video
|
||||
|
||||
if (video) {
|
||||
currentType = types.video;
|
||||
} // Replace current history state
|
||||
|
||||
|
||||
if (currentType in types) {
|
||||
window.history.replaceState({
|
||||
type: currentType
|
||||
}, '', video ? '' : "#".concat(currentType));
|
||||
} // If it's not video, load the source
|
||||
|
||||
|
||||
if (currentType !== types.video) {
|
||||
newSource(currentType, true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}); // Raven / Sentry
|
||||
// For demo site (https://plyr.io) only
|
||||
|
||||
if (env.prod) {
|
||||
singleton.config('https://d4ad9866ad834437a4754e23937071e4@sentry.io/305555').install();
|
||||
} // Google analytics
|
||||
// For demo site (https://plyr.io) only
|
||||
|
||||
/* eslint-disable */
|
||||
|
||||
|
||||
if (env.prod) {
|
||||
(function (i, s, o, g, r, a, m) {
|
||||
i.GoogleAnalyticsObject = r;
|
||||
|
||||
i[r] = i[r] || function () {
|
||||
(i[r].q = i[r].q || []).push(arguments);
|
||||
};
|
||||
|
||||
i[r].l = 1 * new Date();
|
||||
a = s.createElement(o);
|
||||
m = s.getElementsByTagName(o)[0];
|
||||
a.async = 1;
|
||||
a.src = g;
|
||||
m.parentNode.insertBefore(a, m);
|
||||
})(window, document, 'script', 'https://www.google-analytics.com/analytics.js', 'ga');
|
||||
|
||||
window.ga('create', 'UA-40881672-11', 'auto');
|
||||
window.ga('send', 'pageview');
|
||||
}
|
||||
/* eslint-enable */
|
||||
|
||||
})();
|
||||
|
||||
}());
|
||||
|
||||
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 5.3 KiB |
@@ -88,29 +88,26 @@ const sizeOptions = { showFiles: true, gzip: true };
|
||||
const browsers = ['> 1%'];
|
||||
|
||||
// Babel config
|
||||
const babelrc = {
|
||||
const babelrc = (polyfill = false) => ({
|
||||
presets: [
|
||||
[
|
||||
'env',
|
||||
'@babel/preset-env',
|
||||
{
|
||||
targets: {
|
||||
browsers,
|
||||
},
|
||||
useBuiltIns: true,
|
||||
useBuiltIns: polyfill ? 'usage' : false,
|
||||
modules: false,
|
||||
},
|
||||
],
|
||||
],
|
||||
plugins: ['external-helpers'],
|
||||
babelrc: false,
|
||||
exclude: 'node_modules/**',
|
||||
};
|
||||
});
|
||||
|
||||
// Clean out /dist
|
||||
gulp.task('clean', () => {
|
||||
const dirs = [paths.plyr.output, paths.demo.output].map(dir =>
|
||||
path.join(dir, '**/*'),
|
||||
);
|
||||
const dirs = [paths.plyr.output, paths.demo.output].map(dir => path.join(dir, '**/*'));
|
||||
|
||||
// Don't delete the mp4
|
||||
dirs.push(`!${path.join(paths.plyr.output, '**/*.mp4')}`);
|
||||
@@ -124,6 +121,7 @@ const build = {
|
||||
const name = `js:${key}`;
|
||||
tasks.js.push(name);
|
||||
const { output } = paths[bundle];
|
||||
const polyfill = name.includes('polyfilled');
|
||||
|
||||
return gulp.task(name, () =>
|
||||
gulp
|
||||
@@ -133,11 +131,7 @@ const build = {
|
||||
.pipe(
|
||||
rollup(
|
||||
{
|
||||
plugins: [
|
||||
resolve(),
|
||||
commonjs(),
|
||||
babel(babelrc),
|
||||
],
|
||||
plugins: [resolve(), commonjs(), babel(babelrc(polyfill))],
|
||||
},
|
||||
options,
|
||||
),
|
||||
@@ -244,10 +238,7 @@ try {
|
||||
}
|
||||
|
||||
// If deployment is setup
|
||||
if (
|
||||
Object.keys(credentials).includes('aws') &&
|
||||
Object.keys(credentials).includes('fastly')
|
||||
) {
|
||||
if (Object.keys(credentials).includes('aws') && Object.keys(credentials).includes('fastly')) {
|
||||
const { version } = pkg;
|
||||
const { aws, fastly } = credentials;
|
||||
|
||||
@@ -269,8 +260,7 @@ if (
|
||||
demo: {
|
||||
uploadPath: branch.current === branch.develop ? 'beta/' : null,
|
||||
headers: {
|
||||
'Cache-Control':
|
||||
'no-cache, no-store, must-revalidate, max-age=0',
|
||||
'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0',
|
||||
Vary: 'Accept-Encoding',
|
||||
},
|
||||
},
|
||||
@@ -279,8 +269,7 @@ if (
|
||||
headers: {
|
||||
// http://stackoverflow.com/questions/2272835/amazon-s3-object-redirect
|
||||
'x-amz-website-redirect-location': `/${ver}/${filename}`,
|
||||
'Cache-Control':
|
||||
'no-cache, no-store, must-revalidate, max-age=0',
|
||||
'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0',
|
||||
},
|
||||
};
|
||||
},
|
||||
@@ -303,11 +292,7 @@ if (
|
||||
const allowed = [branch.master, branch.develop];
|
||||
|
||||
if (!allowed.includes(branch.current)) {
|
||||
console.error(
|
||||
`Must be on ${allowed.join(', ')} to publish! (current: ${
|
||||
branch.current
|
||||
})`,
|
||||
);
|
||||
console.error(`Must be on ${allowed.join(', ')} to publish! (current: ${branch.current})`);
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -323,13 +308,13 @@ if (
|
||||
console.log(`Updating versions to '${version}'...`);
|
||||
|
||||
// Replace versioned URLs in source
|
||||
const files = ['plyr.js', 'plyr.polyfilled.js', 'defaults.js'];
|
||||
const files = ['plyr.js', 'plyr.polyfilled.js', 'config/defaults.js'];
|
||||
|
||||
return gulp
|
||||
.src(files.map(file => path.join(root, `src/js/${file}`)))
|
||||
.src(files.map(file => path.join(root, `src/js/${file}`)), { base: '.' })
|
||||
.pipe(replace(semver, `v${version}`))
|
||||
.pipe(replace(cdnpath, `${aws.cdn.domain}/${version}/`))
|
||||
.pipe(gulp.dest(path.join(root, 'src/js/')));
|
||||
.pipe(gulp.dest('./'));
|
||||
});
|
||||
|
||||
// Publish version to CDN bucket
|
||||
@@ -349,8 +334,7 @@ if (
|
||||
.pipe(
|
||||
replace(
|
||||
/sourceMappingURL=([\w-?.]+)/,
|
||||
(match, p1) =>
|
||||
`sourceMappingURL=${p1.replace(minSuffix, '')}`,
|
||||
(match, p1) => `sourceMappingURL=${p1.replace(minSuffix, '')}`,
|
||||
),
|
||||
)
|
||||
.pipe(
|
||||
@@ -368,27 +352,30 @@ if (
|
||||
gulp.task('purge', () => {
|
||||
const list = [];
|
||||
|
||||
return gulp.src(paths.upload).pipe(
|
||||
through.obj((file, enc, cb) => {
|
||||
const filename = file.path.split('/').pop();
|
||||
list.push(`${versionPath}/${filename}`);
|
||||
cb(null);
|
||||
}),
|
||||
).on('end', () => {
|
||||
const purge = new FastlyPurge(fastly.token);
|
||||
return gulp
|
||||
.src(paths.upload)
|
||||
.pipe(
|
||||
through.obj((file, enc, cb) => {
|
||||
const filename = file.path.split('/').pop();
|
||||
list.push(`${versionPath}/${filename}`);
|
||||
cb(null);
|
||||
}),
|
||||
)
|
||||
.on('end', () => {
|
||||
const purge = new FastlyPurge(fastly.token);
|
||||
|
||||
list.forEach(url => {
|
||||
console.log(`Purging ${url}...`);
|
||||
list.forEach(url => {
|
||||
console.log(`Purging ${url}...`);
|
||||
|
||||
purge.url(url, (error, result) => {
|
||||
if (error) {
|
||||
console.log(error);
|
||||
} else if (result) {
|
||||
console.log(result);
|
||||
}
|
||||
purge.url(url, (error, result) => {
|
||||
if (error) {
|
||||
console.log(error);
|
||||
} else if (result) {
|
||||
console.log(result);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Publish to demo bucket
|
||||
@@ -400,8 +387,7 @@ if (
|
||||
console.log(`Uploading '${version}' demo to ${aws.demo.domain}...`);
|
||||
|
||||
// Replace versioned files in readme.md
|
||||
gulp
|
||||
.src([`${root}/readme.md`])
|
||||
gulp.src([`${root}/readme.md`])
|
||||
.pipe(replace(cdnpath, `${aws.cdn.domain}/${version}/`))
|
||||
.pipe(gulp.dest(root));
|
||||
|
||||
@@ -415,8 +401,7 @@ if (
|
||||
pages.push(error);
|
||||
}
|
||||
|
||||
gulp
|
||||
.src(pages)
|
||||
gulp.src(pages)
|
||||
.pipe(replace(localPath, versionPath))
|
||||
.pipe(s3(aws.demo, options.demo));
|
||||
|
||||
@@ -468,16 +453,6 @@ if (
|
||||
|
||||
// Do everything
|
||||
gulp.task('deploy', () =>
|
||||
run(
|
||||
'version',
|
||||
tasks.clean,
|
||||
tasks.js,
|
||||
tasks.sass,
|
||||
tasks.sprite,
|
||||
'cdn',
|
||||
'purge',
|
||||
'demo',
|
||||
'open',
|
||||
),
|
||||
run('version', tasks.clean, tasks.js, tasks.sass, tasks.sprite, 'cdn', 'purge', 'demo', 'open'),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,18 @@
|
||||
{
|
||||
"name": "plyr",
|
||||
"version": "3.4.3",
|
||||
"version": "3.4.6",
|
||||
"description": "A simple, accessible and customizable HTML5, YouTube and Vimeo media player",
|
||||
"homepage": "https://plyr.io",
|
||||
"author": "Sam Potts <sam@potts.es>",
|
||||
"keywords": ["HTML5 Video", "HTML5 Audio", "Media Player", "DASH", "Shaka", "WordPress", "HLS"],
|
||||
"keywords": [
|
||||
"HTML5 Video",
|
||||
"HTML5 Audio",
|
||||
"Media Player",
|
||||
"DASH",
|
||||
"Shaka",
|
||||
"WordPress",
|
||||
"HLS"
|
||||
],
|
||||
"main": "./dist/plyr.js",
|
||||
"browser": "./dist/plyr.min.js",
|
||||
"sass": "./src/sass/plyr.scss",
|
||||
@@ -28,18 +36,17 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-core": "^6.26.3",
|
||||
"babel-eslint": "^8.2.6",
|
||||
"babel-plugin-external-helpers": "^6.22.0",
|
||||
"babel-preset-env": "^1.7.0",
|
||||
"babel-eslint": "^10.0.1",
|
||||
"@babel/preset-env": "^7.1.0",
|
||||
"del": "^3.0.0",
|
||||
"eslint": "^5.3.0",
|
||||
"eslint": "^5.7.0",
|
||||
"eslint-config-airbnb-base": "^13.1.0",
|
||||
"eslint-config-prettier": "^3.0.1",
|
||||
"eslint-config-prettier": "^3.1.0",
|
||||
"eslint-plugin-import": "^2.14.0",
|
||||
"fastly-purge": "^1.0.1",
|
||||
"git-branch": "^2.0.1",
|
||||
"gulp": "^3.9.1",
|
||||
"gulp-autoprefixer": "^5.0.0",
|
||||
"gulp-autoprefixer": "^6.0.0",
|
||||
"gulp-better-rollup": "^3.3.0",
|
||||
"gulp-clean-css": "^3.10.0",
|
||||
"gulp-concat": "^2.6.1",
|
||||
@@ -50,36 +57,36 @@
|
||||
"gulp-rename": "^1.4.0",
|
||||
"gulp-replace": "^1.0.0",
|
||||
"gulp-s3": "^0.11.0",
|
||||
"gulp-sass": "^4.0.1",
|
||||
"gulp-sass": "^4.0.2",
|
||||
"gulp-size": "^3.0.0",
|
||||
"gulp-sourcemaps": "^2.6.4",
|
||||
"gulp-svgmin": "^1.2.4",
|
||||
"gulp-svgstore": "^6.1.1",
|
||||
"gulp-svgmin": "^2.1.0",
|
||||
"gulp-svgstore": "^7.0.0",
|
||||
"gulp-uglify-es": "^1.0.4",
|
||||
"gulp-util": "^3.0.8",
|
||||
"postcss-custom-properties": "^7.0.0",
|
||||
"postcss-custom-properties": "^8.0.8",
|
||||
"prettier-eslint": "^8.8.2",
|
||||
"prettier-stylelint": "^0.4.2",
|
||||
"remark-cli": "^5.0.0",
|
||||
"remark-validate-links": "^7.1.0",
|
||||
"rollup-plugin-babel": "^3.0.7",
|
||||
"rollup-plugin-commonjs": "^9.1.5",
|
||||
"rollup-plugin-node-resolve": "^3.3.0",
|
||||
"rollup-plugin-babel": "^4.0.3",
|
||||
"rollup-plugin-commonjs": "^9.2.0",
|
||||
"rollup-plugin-node-resolve": "^3.4.0",
|
||||
"run-sequence": "^2.2.1",
|
||||
"stylelint": "^9.4.0",
|
||||
"stylelint": "^9.6.0",
|
||||
"stylelint-config-prettier": "^4.0.0",
|
||||
"stylelint-config-recommended": "^2.1.0",
|
||||
"stylelint-config-sass-guidelines": "^5.0.0",
|
||||
"stylelint-config-sass-guidelines": "^5.2.0",
|
||||
"stylelint-order": "^1.0.0",
|
||||
"stylelint-scss": "^3.3.0",
|
||||
"stylelint-scss": "^3.3.2",
|
||||
"stylelint-selector-bem-pattern": "^2.0.0",
|
||||
"through2": "^2.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"babel-polyfill": "^6.26.0",
|
||||
"core-js": "^2.5.7",
|
||||
"custom-event-polyfill": "^1.0.6",
|
||||
"loadjs": "^3.5.4",
|
||||
"raven-js": "^3.26.4",
|
||||
"url-polyfill": "^1.0.14"
|
||||
"raven-js": "^3.27.0",
|
||||
"url-polyfill": "^1.1.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,13 +132,13 @@ See [initialising](#initialising) for more information on advanced setups.
|
||||
You can use our CDN (provided by [Fastly](https://www.fastly.com/)) for the JavaScript. There's 2 versions; one with and one without [polyfills](#polyfills). My recommendation would be to manage polyfills seperately as part of your application but to make life easier you can use the polyfilled build.
|
||||
|
||||
```html
|
||||
<script src="https://cdn.plyr.io/3.4.3/plyr.js"></script>
|
||||
<script src="https://cdn.plyr.io/3.4.6/plyr.js"></script>
|
||||
```
|
||||
|
||||
...or...
|
||||
|
||||
```html
|
||||
<script src="https://cdn.plyr.io/3.4.3/plyr.polyfilled.js"></script>
|
||||
<script src="https://cdn.plyr.io/3.4.6/plyr.polyfilled.js"></script>
|
||||
```
|
||||
|
||||
### CSS
|
||||
@@ -152,13 +152,13 @@ Include the `plyr.css` stylsheet into your `<head>`
|
||||
If you want to use our CDN (provided by [Fastly](https://www.fastly.com/)) for the default CSS, you can use the following:
|
||||
|
||||
```html
|
||||
<link rel="stylesheet" href="https://cdn.plyr.io/3.4.3/plyr.css">
|
||||
<link rel="stylesheet" href="https://cdn.plyr.io/3.4.6/plyr.css">
|
||||
```
|
||||
|
||||
### SVG Sprite
|
||||
|
||||
The SVG sprite is loaded automatically from our CDN (provided by [Fastly](https://www.fastly.com/)). To change this, see the [options](#options) below. For
|
||||
reference, the CDN hosted SVG sprite can be found at `https://cdn.plyr.io/3.4.3/plyr.svg`.
|
||||
reference, the CDN hosted SVG sprite can be found at `https://cdn.plyr.io/3.4.6/plyr.svg`.
|
||||
|
||||
## Ads
|
||||
|
||||
@@ -175,7 +175,7 @@ Any questions regarding the ads can be sent straight to vi.ai and any issues wit
|
||||
### SASS
|
||||
|
||||
You can use `bundle.scss` file included in `/src` as part of your build and change variables to suit your design. The SASS require you to
|
||||
use the [autoprefixer](https://www.npmjs.com/package/gulp-autoprefixer) plugin (you be should already!) as all declarations use the W3C definitions.
|
||||
use the [autoprefixer](https://www.npmjs.com/package/gulp-autoprefixer) plugin (you should be already!) as all declarations use the W3C definitions.
|
||||
|
||||
The HTML markup uses the BEM methodology with `plyr` as the block, e.g. `.plyr__controls`. You can change the class hooks in the options to match any custom CSS
|
||||
you write. Check out the JavaScript source for more on this.
|
||||
@@ -315,6 +315,7 @@ Note the single quotes encapsulating the JSON and double quotes on the object ke
|
||||
| `quality` | Object | `{ default: 'default', options: ['hd2160', 'hd1440', 'hd1080', 'hd720', 'large', 'medium', 'small', 'tiny', 'default'] }` | Currently only supported by YouTube. `default` is the default quality level, determined by YouTube. `options` are the options to display. |
|
||||
| `loop` | Object | `{ active: false }` | `active`: Whether to loop the current video. If the `loop` attribute is present on a `<video>` or `<audio>` element, this will be automatically set to true This is an object to support future functionality. |
|
||||
| `ads` | Object | `{ enabled: false, publisherId: '' }` | `enabled`: Whether to enable vi.ai ads. `publisherId`: Your unique vi.ai publisher ID. |
|
||||
| `urls` | Object | See source. | If you wish to override any API URLs then you can do so here. You can also set a custom download URL for the download button. |
|
||||
|
||||
1. Vimeo only
|
||||
|
||||
@@ -416,7 +417,7 @@ player.fullscreen.active; // false;
|
||||
| `language` | ✓ | ✓ | Gets or sets the preferred captions language for the player. The setter accepts an ISO two-letter language code. Support for the languages is dependent on the captions you include. If your captions don't have any language data, or if you have multiple tracks with the same language, you may want to use `currentTrack` instead. |
|
||||
| `fullscreen.active` | ✓ | - | Returns a boolean indicating if the current player is in fullscreen mode. |
|
||||
| `fullscreen.enabled` | ✓ | - | Returns a boolean indicating if the current player has fullscreen enabled. |
|
||||
| `pip` | ✓ | ✓ | Gets or sets the picture-in-picture state of the player. The setter accepts a boolean. This currently only supported on Safari 10+ on MacOS Sierra+ and iOS 10+. |
|
||||
| `pip` | ✓ | ✓ | Gets or sets the picture-in-picture state of the player. The setter accepts a boolean. This currently only supported on Safari 10+ (on MacOS Sierra+ and iOS 10+) and Chrome 70+. |
|
||||
|
||||
1. YouTube only. HTML5 will follow.
|
||||
2. HTML5 only
|
||||
|
||||
@@ -60,7 +60,7 @@ const defaults = {
|
||||
// Sprite (for icons)
|
||||
loadSprite: true,
|
||||
iconPrefix: 'plyr',
|
||||
iconUrl: 'https://cdn.plyr.io/3.3.12/plyr.svg',
|
||||
iconUrl: 'https://cdn.plyr.io/3.4.6/plyr.svg',
|
||||
|
||||
// Blank video (used to prevent errors on source change)
|
||||
blankVideo: 'https://cdn.plyr.io/static/blank.mp4',
|
||||
@@ -133,6 +133,7 @@ const defaults = {
|
||||
'settings',
|
||||
'pip',
|
||||
'airplay',
|
||||
// 'download',
|
||||
'fullscreen',
|
||||
],
|
||||
settings: ['captions', 'quality', 'speed'],
|
||||
@@ -155,6 +156,7 @@ const defaults = {
|
||||
unmute: 'Unmute',
|
||||
enableCaptions: 'Enable captions',
|
||||
disableCaptions: 'Disable captions',
|
||||
download: 'Download',
|
||||
enterFullscreen: 'Enter fullscreen',
|
||||
exitFullscreen: 'Exit fullscreen',
|
||||
frameTitle: 'Player for {title}',
|
||||
@@ -184,6 +186,7 @@ const defaults = {
|
||||
|
||||
// URLs
|
||||
urls: {
|
||||
download: null,
|
||||
vimeo: {
|
||||
sdk: 'https://player.vimeo.com/api/player.js',
|
||||
iframe: 'https://player.vimeo.com/video/{0}?{1}',
|
||||
@@ -210,6 +213,7 @@ const defaults = {
|
||||
mute: null,
|
||||
volume: null,
|
||||
captions: null,
|
||||
download: null,
|
||||
fullscreen: null,
|
||||
pip: null,
|
||||
airplay: null,
|
||||
@@ -245,6 +249,7 @@ const defaults = {
|
||||
'cuechange',
|
||||
|
||||
// Custom events
|
||||
'download',
|
||||
'enterfullscreen',
|
||||
'exitfullscreen',
|
||||
'captionsenabled',
|
||||
@@ -290,6 +295,7 @@ const defaults = {
|
||||
fastForward: '[data-plyr="fast-forward"]',
|
||||
mute: '[data-plyr="mute"]',
|
||||
captions: '[data-plyr="captions"]',
|
||||
download: '[data-plyr="download"]',
|
||||
fullscreen: '[data-plyr="fullscreen"]',
|
||||
pip: '[data-plyr="pip"]',
|
||||
airplay: '[data-plyr="airplay"]',
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
// ==========================================================================
|
||||
// Plyr states
|
||||
// ==========================================================================
|
||||
|
||||
export const pip = {
|
||||
active: 'picture-in-picture',
|
||||
inactive: 'inline',
|
||||
};
|
||||
|
||||
export default { pip };
|
||||
@@ -15,7 +15,7 @@ export const types = {
|
||||
|
||||
/**
|
||||
* Get provider by URL
|
||||
* @param {string} url
|
||||
* @param {String} url
|
||||
*/
|
||||
export function getProviderByUrl(url) {
|
||||
// YouTube
|
||||
|
||||
@@ -111,10 +111,11 @@ const controls = {
|
||||
// https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/xlink:href
|
||||
if ('href' in use) {
|
||||
use.setAttributeNS('http://www.w3.org/1999/xlink', 'href', path);
|
||||
} else {
|
||||
use.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', path);
|
||||
}
|
||||
|
||||
// Always set the older attribute even though it's "deprecated" (it'll be around for ages)
|
||||
use.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', path);
|
||||
|
||||
// Add <use> to <svg>
|
||||
icon.appendChild(use);
|
||||
|
||||
@@ -122,17 +123,13 @@ const controls = {
|
||||
},
|
||||
|
||||
// Create hidden text label
|
||||
createLabel(type, attr = {}) {
|
||||
// Skip i18n for abbreviations and brand names
|
||||
const universals = {
|
||||
pip: 'PIP',
|
||||
airplay: 'AirPlay',
|
||||
};
|
||||
const text = universals[type] || i18n.get(type, this.config);
|
||||
createLabel(key, attr = {}) {
|
||||
const text = i18n.get(key, this.config);
|
||||
|
||||
const attributes = Object.assign({}, attr, {
|
||||
class: [attr.class, this.config.classNames.hidden].filter(Boolean).join(' '),
|
||||
});
|
||||
|
||||
return createElement('span', attributes, text);
|
||||
},
|
||||
|
||||
@@ -161,21 +158,32 @@ const controls = {
|
||||
|
||||
// Create a <button>
|
||||
createButton(buttonType, attr) {
|
||||
const button = createElement('button');
|
||||
const attributes = Object.assign({}, attr);
|
||||
let type = toCamelCase(buttonType);
|
||||
|
||||
let toggle = false;
|
||||
let label;
|
||||
let icon;
|
||||
let labelPressed;
|
||||
let iconPressed;
|
||||
const props = {
|
||||
element: 'button',
|
||||
toggle: false,
|
||||
label: null,
|
||||
icon: null,
|
||||
labelPressed: null,
|
||||
iconPressed: null,
|
||||
};
|
||||
|
||||
if (!('type' in attributes)) {
|
||||
['element', 'icon', 'label'].forEach(key => {
|
||||
if (Object.keys(attributes).includes(key)) {
|
||||
props[key] = attributes[key];
|
||||
delete attributes[key];
|
||||
}
|
||||
});
|
||||
|
||||
// Default to 'button' type to prevent form submission
|
||||
if (props.element === 'button' && !Object.keys(attributes).includes('type')) {
|
||||
attributes.type = 'button';
|
||||
}
|
||||
|
||||
if ('class' in attributes) {
|
||||
// Set class name
|
||||
if (Object.keys(attributes).includes('class')) {
|
||||
if (!attributes.class.includes(this.config.classNames.control)) {
|
||||
attributes.class += ` ${this.config.classNames.control}`;
|
||||
}
|
||||
@@ -186,82 +194,87 @@ const controls = {
|
||||
// Large play button
|
||||
switch (buttonType) {
|
||||
case 'play':
|
||||
toggle = true;
|
||||
label = 'play';
|
||||
labelPressed = 'pause';
|
||||
icon = 'play';
|
||||
iconPressed = 'pause';
|
||||
props.toggle = true;
|
||||
props.label = 'play';
|
||||
props.labelPressed = 'pause';
|
||||
props.icon = 'play';
|
||||
props.iconPressed = 'pause';
|
||||
break;
|
||||
|
||||
case 'mute':
|
||||
toggle = true;
|
||||
label = 'mute';
|
||||
labelPressed = 'unmute';
|
||||
icon = 'volume';
|
||||
iconPressed = 'muted';
|
||||
props.toggle = true;
|
||||
props.label = 'mute';
|
||||
props.labelPressed = 'unmute';
|
||||
props.icon = 'volume';
|
||||
props.iconPressed = 'muted';
|
||||
break;
|
||||
|
||||
case 'captions':
|
||||
toggle = true;
|
||||
label = 'enableCaptions';
|
||||
labelPressed = 'disableCaptions';
|
||||
icon = 'captions-off';
|
||||
iconPressed = 'captions-on';
|
||||
props.toggle = true;
|
||||
props.label = 'enableCaptions';
|
||||
props.labelPressed = 'disableCaptions';
|
||||
props.icon = 'captions-off';
|
||||
props.iconPressed = 'captions-on';
|
||||
break;
|
||||
|
||||
case 'fullscreen':
|
||||
toggle = true;
|
||||
label = 'enterFullscreen';
|
||||
labelPressed = 'exitFullscreen';
|
||||
icon = 'enter-fullscreen';
|
||||
iconPressed = 'exit-fullscreen';
|
||||
props.toggle = true;
|
||||
props.label = 'enterFullscreen';
|
||||
props.labelPressed = 'exitFullscreen';
|
||||
props.icon = 'enter-fullscreen';
|
||||
props.iconPressed = 'exit-fullscreen';
|
||||
break;
|
||||
|
||||
case 'play-large':
|
||||
attributes.class += ` ${this.config.classNames.control}--overlaid`;
|
||||
type = 'play';
|
||||
label = 'play';
|
||||
icon = 'play';
|
||||
props.label = 'play';
|
||||
props.icon = 'play';
|
||||
break;
|
||||
|
||||
default:
|
||||
label = type;
|
||||
icon = buttonType;
|
||||
if (is.empty(props.label)) {
|
||||
props.label = type;
|
||||
}
|
||||
if (is.empty(props.icon)) {
|
||||
props.icon = buttonType;
|
||||
}
|
||||
}
|
||||
|
||||
const button = createElement(props.element);
|
||||
|
||||
// Setup toggle icon and labels
|
||||
if (toggle) {
|
||||
if (props.toggle) {
|
||||
// Icon
|
||||
button.appendChild(
|
||||
controls.createIcon.call(this, iconPressed, {
|
||||
controls.createIcon.call(this, props.iconPressed, {
|
||||
class: 'icon--pressed',
|
||||
}),
|
||||
);
|
||||
button.appendChild(
|
||||
controls.createIcon.call(this, icon, {
|
||||
controls.createIcon.call(this, props.icon, {
|
||||
class: 'icon--not-pressed',
|
||||
}),
|
||||
);
|
||||
|
||||
// Label/Tooltip
|
||||
button.appendChild(
|
||||
controls.createLabel.call(this, labelPressed, {
|
||||
controls.createLabel.call(this, props.labelPressed, {
|
||||
class: 'label--pressed',
|
||||
}),
|
||||
);
|
||||
button.appendChild(
|
||||
controls.createLabel.call(this, label, {
|
||||
controls.createLabel.call(this, props.label, {
|
||||
class: 'label--not-pressed',
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
button.appendChild(controls.createIcon.call(this, icon));
|
||||
button.appendChild(controls.createLabel.call(this, label));
|
||||
button.appendChild(controls.createIcon.call(this, props.icon));
|
||||
button.appendChild(controls.createLabel.call(this, props.label));
|
||||
}
|
||||
|
||||
// Merge attributes
|
||||
// Merge and set attributes
|
||||
extend(attributes, getAttributesFromSelector(this.config.selectors.buttons[type], attributes));
|
||||
|
||||
setAttributes(button, attributes);
|
||||
|
||||
// We have multiple play buttons
|
||||
@@ -1214,6 +1227,19 @@ const controls = {
|
||||
controls.focusFirstMenuItem.call(this, target, tabFocus);
|
||||
},
|
||||
|
||||
// Set the download link
|
||||
setDownloadLink() {
|
||||
const button = this.elements.buttons.download;
|
||||
|
||||
// Bail if no button
|
||||
if (!is.element(button)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set download link
|
||||
button.setAttribute('href', this.download);
|
||||
},
|
||||
|
||||
// Build the default HTML
|
||||
// TODO: Set order based on order in the config.controls array?
|
||||
create(data) {
|
||||
@@ -1490,6 +1516,26 @@ const controls = {
|
||||
container.appendChild(controls.createButton.call(this, 'airplay'));
|
||||
}
|
||||
|
||||
// Download button
|
||||
if (this.config.controls.includes('download')) {
|
||||
const attributes = {
|
||||
element: 'a',
|
||||
href: this.download,
|
||||
target: '_blank',
|
||||
};
|
||||
|
||||
const { download } = this.config.urls;
|
||||
|
||||
if (!is.url(download) && this.isEmbed) {
|
||||
extend(attributes, {
|
||||
icon: `logo-${this.provider}`,
|
||||
label: this.provider,
|
||||
});
|
||||
}
|
||||
|
||||
container.appendChild(controls.createButton.call(this, 'download', attributes));
|
||||
}
|
||||
|
||||
// Toggle fullscreen button
|
||||
if (this.config.controls.includes('fullscreen')) {
|
||||
container.appendChild(controls.createButton.call(this, 'fullscreen'));
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
// ==========================================================================
|
||||
// Fullscreen wrapper
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API#prefixing
|
||||
// https://webkit.org/blog/7929/designing-websites-for-iphone-x/
|
||||
// ==========================================================================
|
||||
|
||||
import { repaint } from './utils/animation';
|
||||
import browser from './utils/browser';
|
||||
import { hasClass, toggleClass, trapFocus } from './utils/elements';
|
||||
import { on, triggerEvent } from './utils/events';
|
||||
@@ -45,6 +47,37 @@ function toggleFallback(toggle = false) {
|
||||
// Toggle class hook
|
||||
toggleClass(this.target, this.player.config.classNames.fullscreen.fallback, toggle);
|
||||
|
||||
// Force full viewport on iPhone X+
|
||||
if (browser.isIos) {
|
||||
let viewport = document.head.querySelector('meta[name="viewport"]');
|
||||
const property = 'viewport-fit=cover';
|
||||
|
||||
// Inject the viewport meta if required
|
||||
if (!viewport) {
|
||||
viewport = document.createElement('meta');
|
||||
viewport.setAttribute('name', 'viewport');
|
||||
}
|
||||
|
||||
// Check if the property already exists
|
||||
const hasProperty = is.string(viewport.content) && viewport.content.includes(property);
|
||||
|
||||
if (toggle) {
|
||||
this.cleanupViewport = !hasProperty;
|
||||
|
||||
if (!hasProperty) {
|
||||
viewport.content += `,${property}`;
|
||||
}
|
||||
} else if (this.cleanupViewport) {
|
||||
viewport.content = viewport.content
|
||||
.split(',')
|
||||
.filter(part => part.trim() !== property)
|
||||
.join(',');
|
||||
}
|
||||
|
||||
// Force a repaint as sometimes Safari doesn't want to fill the screen
|
||||
setTimeout(() => repaint(this.target), 100);
|
||||
}
|
||||
|
||||
// Toggle button and fire events
|
||||
onChange.call(this);
|
||||
}
|
||||
|
||||
@@ -82,9 +82,6 @@ const html5 = {
|
||||
triggerEvent.call(player, player.media, 'qualitychange', false, {
|
||||
quality: input,
|
||||
});
|
||||
|
||||
// Save to storage
|
||||
player.storage.set({ quality: input });
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
@@ -6,7 +6,7 @@ import controls from './controls';
|
||||
import ui from './ui';
|
||||
import { repaint } from './utils/animation';
|
||||
import browser from './utils/browser';
|
||||
import { getElement, getElements, hasClass, matches, toggleClass, toggleHidden } from './utils/elements';
|
||||
import { getElement, getElements, matches, toggleClass, toggleHidden } from './utils/elements';
|
||||
import { on, once, toggleListener, triggerEvent } from './utils/events';
|
||||
import is from './utils/is';
|
||||
|
||||
@@ -45,7 +45,7 @@ class Listeners {
|
||||
// Seek by the number keys
|
||||
const seekByKey = () => {
|
||||
// Divide the max duration into 10th's and times by the number value
|
||||
player.currentTime = player.duration / 10 * (code - 48);
|
||||
player.currentTime = (player.duration / 10) * (code - 48);
|
||||
};
|
||||
|
||||
// Handle the key on keydown
|
||||
@@ -146,7 +146,7 @@ class Listeners {
|
||||
player.loop = !player.loop;
|
||||
break;
|
||||
|
||||
/* case 73:
|
||||
/* case 73:
|
||||
this.setLoop('start');
|
||||
break;
|
||||
|
||||
@@ -371,8 +371,8 @@ class Listeners {
|
||||
return;
|
||||
}
|
||||
|
||||
// On click play, pause ore restart
|
||||
on.call(player, elements.container, 'click touchstart', event => {
|
||||
// On click play, pause or restart
|
||||
on.call(player, elements.container, 'click', event => {
|
||||
const targets = [elements.container, wrapper];
|
||||
|
||||
// Ignore if click if not container or in video wrapper
|
||||
@@ -380,13 +380,8 @@ class Listeners {
|
||||
return;
|
||||
}
|
||||
|
||||
// First touch on touch devices will just show controls (if we're hiding controls)
|
||||
// If controls are shown then it'll toggle like a pointer device
|
||||
if (
|
||||
player.config.hideControls &&
|
||||
player.touch &&
|
||||
hasClass(elements.container, player.config.classNames.hideControls)
|
||||
) {
|
||||
// Touch devices will just show controls (if hidden)
|
||||
if (player.touch && player.config.hideControls) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -436,6 +431,11 @@ class Listeners {
|
||||
controls.updateSetting.call(player, 'quality', null, event.detail.quality);
|
||||
});
|
||||
|
||||
// Update download link when ready and if quality changes
|
||||
on.call(player, player.media, 'ready qualitychange', () => {
|
||||
controls.setDownloadLink.call(player);
|
||||
});
|
||||
|
||||
// Proxy events to container
|
||||
// Bubble up key events for Edge
|
||||
const proxyEvents = player.config.events.concat(['keyup', 'keydown']).join(' ');
|
||||
@@ -522,6 +522,16 @@ class Listeners {
|
||||
// Captions toggle
|
||||
this.bind(elements.buttons.captions, 'click', () => player.toggleCaptions());
|
||||
|
||||
// Download
|
||||
this.bind(
|
||||
elements.buttons.download,
|
||||
'click',
|
||||
() => {
|
||||
triggerEvent.call(player, player.media, 'download');
|
||||
},
|
||||
'download',
|
||||
);
|
||||
|
||||
// Fullscreen toggle
|
||||
this.bind(
|
||||
elements.buttons.fullscreen,
|
||||
@@ -596,7 +606,7 @@ class Listeners {
|
||||
// Set range input alternative "value", which matches the tooltip time (#954)
|
||||
this.bind(elements.inputs.seek, 'mousedown mousemove', event => {
|
||||
const rect = elements.progress.getBoundingClientRect();
|
||||
const percent = 100 / rect.width * (event.pageX - rect.left);
|
||||
const percent = (100 / rect.width) * (event.pageX - rect.left);
|
||||
event.currentTarget.setAttribute('seek-value', percent);
|
||||
});
|
||||
|
||||
@@ -610,6 +620,9 @@ class Listeners {
|
||||
return;
|
||||
}
|
||||
|
||||
// Record seek time so we can prevent hiding controls for a few seconds after seek
|
||||
player.lastSeekTime = Date.now();
|
||||
|
||||
// Was playing before?
|
||||
const play = seek.hasAttribute(attribute);
|
||||
|
||||
@@ -650,7 +663,7 @@ class Listeners {
|
||||
|
||||
seek.removeAttribute('seek-value');
|
||||
|
||||
player.currentTime = seekTo / seek.max * player.duration;
|
||||
player.currentTime = (seekTo / seek.max) * player.duration;
|
||||
},
|
||||
'seek',
|
||||
);
|
||||
@@ -702,33 +715,29 @@ class Listeners {
|
||||
elements.controls.pressed = ['mousedown', 'touchstart'].includes(event.type);
|
||||
});
|
||||
|
||||
// Focus in/out on controls
|
||||
this.bind(elements.controls, 'focusin focusout', event => {
|
||||
// Show controls when they receive focus (e.g., when using keyboard tab key)
|
||||
this.bind(elements.controls, 'focusin', () => {
|
||||
const { config, elements, timers } = player;
|
||||
const isFocusIn = event.type === 'focusin';
|
||||
|
||||
// Skip transition to prevent focus from scrolling the parent element
|
||||
toggleClass(elements.controls, config.classNames.noTransition, isFocusIn);
|
||||
toggleClass(elements.controls, config.classNames.noTransition, true);
|
||||
|
||||
// Toggle
|
||||
ui.toggleControls.call(player, isFocusIn);
|
||||
ui.toggleControls.call(player, true);
|
||||
|
||||
// If focusin, hide again after delay
|
||||
if (isFocusIn) {
|
||||
// Restore transition
|
||||
setTimeout(() => {
|
||||
toggleClass(elements.controls, config.classNames.noTransition, false);
|
||||
}, 0);
|
||||
// Restore transition
|
||||
setTimeout(() => {
|
||||
toggleClass(elements.controls, config.classNames.noTransition, false);
|
||||
}, 0);
|
||||
|
||||
// Delay a little more for keyboard users
|
||||
const delay = this.touch ? 3000 : 4000;
|
||||
// Delay a little more for mouse users
|
||||
const delay = this.touch ? 3000 : 4000;
|
||||
|
||||
// Clear timer
|
||||
clearTimeout(timers.controls);
|
||||
// Clear timer
|
||||
clearTimeout(timers.controls);
|
||||
|
||||
// Hide
|
||||
timers.controls = setTimeout(() => ui.toggleControls.call(player, false), delay);
|
||||
}
|
||||
// Hide again after delay
|
||||
timers.controls = setTimeout(() => ui.toggleControls.call(player, false), delay);
|
||||
});
|
||||
|
||||
// Mouse wheel for volume
|
||||
|
||||
@@ -71,7 +71,7 @@ const vimeo = {
|
||||
// For Vimeo we have an extra 300% height <div> to hide the standard controls and UI
|
||||
setAspectRatio(input) {
|
||||
const [x, y] = (is.string(input) ? input : this.config.ratio).split(':');
|
||||
const padding = 100 / x * y;
|
||||
const padding = (100 / x) * y;
|
||||
this.elements.wrapper.style.paddingBottom = `${padding}%`;
|
||||
|
||||
if (this.supported.ui) {
|
||||
@@ -278,6 +278,7 @@ const vimeo = {
|
||||
.getVideoUrl()
|
||||
.then(value => {
|
||||
currentSrc = value;
|
||||
controls.setDownloadLink.call(player);
|
||||
})
|
||||
.catch(error => {
|
||||
this.debug.warn(error);
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
// ==========================================================================
|
||||
// Plyr
|
||||
// plyr.js v3.4.3
|
||||
// plyr.js v3.4.6
|
||||
// https://github.com/sampotts/plyr
|
||||
// License: The MIT License (MIT)
|
||||
// ==========================================================================
|
||||
|
||||
import captions from './captions';
|
||||
import defaults from './config/defaults';
|
||||
import { pip } from './config/states';
|
||||
import { getProviderByUrl, providers, types } from './config/types';
|
||||
import Console from './console';
|
||||
import controls from './controls';
|
||||
@@ -302,6 +303,9 @@ class Plyr {
|
||||
if (this.config.autoplay) {
|
||||
this.play();
|
||||
}
|
||||
|
||||
// Seek time will be recorded (in listeners.js) so we can prevent hiding controls for a few seconds after seek
|
||||
this.lastSeekTime = 0;
|
||||
}
|
||||
|
||||
// ---------------------------------------
|
||||
@@ -692,10 +696,15 @@ class Plyr {
|
||||
config.default,
|
||||
].find(is.number);
|
||||
|
||||
let updateStorage = true;
|
||||
|
||||
if (!options.includes(quality)) {
|
||||
const value = closest(options, quality);
|
||||
this.debug.warn(`Unsupported quality option: ${quality}, using ${value} instead`);
|
||||
quality = value;
|
||||
|
||||
// Don't update storage if quality is not supported
|
||||
updateStorage = false;
|
||||
}
|
||||
|
||||
// Update config
|
||||
@@ -703,6 +712,11 @@ class Plyr {
|
||||
|
||||
// Set quality
|
||||
this.media.quality = quality;
|
||||
|
||||
// Save to storage
|
||||
if (updateStorage) {
|
||||
this.storage.set({ quality });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -788,6 +802,15 @@ class Plyr {
|
||||
return this.media.currentSrc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a download URL (either source or custom)
|
||||
*/
|
||||
get download() {
|
||||
const { download } = this.config.urls;
|
||||
|
||||
return is.url(download) ? download : this.source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the poster image for a video
|
||||
* @param {input} - the URL for the new poster image
|
||||
@@ -874,21 +897,28 @@ class Plyr {
|
||||
* TODO: detect outside changes
|
||||
*/
|
||||
set pip(input) {
|
||||
const states = {
|
||||
pip: 'picture-in-picture',
|
||||
inline: 'inline',
|
||||
};
|
||||
|
||||
// Bail if no support
|
||||
if (!support.pip) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Toggle based on current state if not passed
|
||||
const toggle = is.boolean(input) ? input : this.pip === states.inline;
|
||||
const toggle = is.boolean(input) ? input : !this.pip;
|
||||
|
||||
// Toggle based on current state
|
||||
this.media.webkitSetPresentationMode(toggle ? states.pip : states.inline);
|
||||
// Safari
|
||||
if (is.function(this.media.webkitSetPresentationMode)) {
|
||||
this.media.webkitSetPresentationMode(toggle ? pip.active : pip.inactive);
|
||||
}
|
||||
|
||||
// Chrome
|
||||
if (is.function(this.media.requestPictureInPicture)) {
|
||||
if (!this.pip && toggle) {
|
||||
this.media.requestPictureInPicture();
|
||||
} else if (this.pip && !toggle) {
|
||||
document.exitPictureInPicture();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -899,7 +929,13 @@ class Plyr {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.media.webkitPresentationMode;
|
||||
// Safari
|
||||
if (!is.empty(this.media.webkitPresentationMode)) {
|
||||
return this.media.webkitPresentationMode === pip.active;
|
||||
}
|
||||
|
||||
// Chrome
|
||||
return this.media === document.pictureInPictureElement;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
// ==========================================================================
|
||||
// Plyr Polyfilled Build
|
||||
// plyr.js v3.4.3
|
||||
// plyr.js v3.4.6
|
||||
// https://github.com/sampotts/plyr
|
||||
// License: The MIT License (MIT)
|
||||
// ==========================================================================
|
||||
|
||||
import 'babel-polyfill';
|
||||
import 'custom-event-polyfill';
|
||||
import 'url-polyfill';
|
||||
import Plyr from './plyr';
|
||||
|
||||
@@ -36,8 +36,26 @@ const support = {
|
||||
},
|
||||
|
||||
// Picture-in-picture support
|
||||
// Safari only currently
|
||||
pip: (() => !browser.isIPhone && is.function(createElement('video').webkitSetPresentationMode))(),
|
||||
// Safari & Chrome only currently
|
||||
pip: (() => {
|
||||
if (browser.isIPhone) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Safari
|
||||
// https://developer.apple.com/documentation/webkitjs/adding_picture_in_picture_to_your_safari_media_controls
|
||||
if (is.function(createElement('video').webkitSetPresentationMode)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Chrome
|
||||
// https://developers.google.com/web/updates/2018/10/watch-video-using-picture-in-picture
|
||||
if (document.pictureInPictureEnabled && !createElement('video').disablePictureInPicture) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
})(),
|
||||
|
||||
// Airplay support
|
||||
// Safari only currently
|
||||
|
||||
@@ -247,8 +247,11 @@ const ui = {
|
||||
const { controls } = this.elements;
|
||||
|
||||
if (controls && this.config.hideControls) {
|
||||
// Show controls if force, loading, paused, or button interaction, otherwise hide
|
||||
this.toggleControls(Boolean(force || this.loading || this.paused || controls.pressed || controls.hover));
|
||||
// Don't hide controls if a touch-device user recently seeked. (Must be limited to touch devices, or it occasionally prevents desktop controls from hiding.)
|
||||
const recentTouchSeek = (this.touch && this.lastSeekTime + 2000 > Date.now());
|
||||
|
||||
// Show controls if force, loading, paused, button interaction, or recent seek, otherwise hide
|
||||
this.toggleControls(Boolean(force || this.loading || this.paused || controls.pressed || controls.hover || recentTouchSeek));
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@@ -15,9 +15,7 @@ export const transitionEndEvent = (() => {
|
||||
transition: 'transitionend',
|
||||
};
|
||||
|
||||
const type = Object.keys(events).find(
|
||||
event => element.style[event] !== undefined,
|
||||
);
|
||||
const type = Object.keys(events).find(event => element.style[event] !== undefined);
|
||||
|
||||
return is.string(type) ? events[type] : false;
|
||||
})();
|
||||
|
||||
@@ -6,6 +6,15 @@ import is from './is';
|
||||
import { getDeep } from './objects';
|
||||
import { replaceAll } from './strings';
|
||||
|
||||
// Skip i18n for abbreviations and brand names
|
||||
const resources = {
|
||||
pip: 'PIP',
|
||||
airplay: 'AirPlay',
|
||||
html5: 'HTML5',
|
||||
vimeo: 'Vimeo',
|
||||
youtube: 'YouTube',
|
||||
};
|
||||
|
||||
const i18n = {
|
||||
get(key = '', config = {}) {
|
||||
if (is.empty(key) || is.empty(config)) {
|
||||
@@ -15,6 +24,10 @@ const i18n = {
|
||||
let string = getDeep(config.i18n, key);
|
||||
|
||||
if (is.empty(string)) {
|
||||
if (Object.keys(resources).includes(key)) {
|
||||
return resources[key];
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,11 @@ const isUrl = input => {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Must be string from here
|
||||
if (!isString(input)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Add the protocol if required
|
||||
let string = input;
|
||||
if (!input.startsWith('http://') || !input.startsWith('https://')) {
|
||||
|
||||
@@ -24,7 +24,7 @@ export function getPercentage(current, max) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (current / max * 100).toFixed(2);
|
||||
return ((current / max) * 100).toFixed(2);
|
||||
}
|
||||
|
||||
// Replace all occurances of a string in a string
|
||||
|
||||
@@ -33,6 +33,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Remove any link styling
|
||||
a.plyr__control {
|
||||
text-decoration: none;
|
||||
|
||||
&::after,
|
||||
&::before {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
// Change icons on state change
|
||||
.plyr__control:not(.plyr__control--pressed) .icon--pressed,
|
||||
.plyr__control.plyr__control--pressed .icon--not-pressed,
|
||||
@@ -81,11 +91,10 @@
|
||||
transform: translate(-50%, -50%);
|
||||
z-index: 2;
|
||||
|
||||
// Offset icon to make the play button look right
|
||||
svg {
|
||||
height: $plyr-control-icon-size-large;
|
||||
left: 2px; // Offset to make the play button look right
|
||||
left: 2px;
|
||||
position: relative;
|
||||
width: $plyr-control-icon-size-large;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
// ==========================================================================
|
||||
|
||||
$plyr-control-icon-size: 18px !default;
|
||||
$plyr-control-icon-size-large: 20px !default;
|
||||
$plyr-control-spacing: 10px !default;
|
||||
$plyr-control-padding: ($plyr-control-spacing * 0.7) !default;
|
||||
$plyr-control-radius: 3px !default;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<svg width="18px" height="18px" viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
|
||||
<g>
|
||||
<path d="M16,1 L2,1 C1.447,1 1,1.447 1,2 L1,12 C1,12.553 1.447,13 2,13 L5,13 L5,11 L3,11 L3,3 L15,3 L15,11 L13,11 L13,13 L16,13 C16.553,13 17,12.553 17,12 L17,2 C17,1.447 16.553,1 16,1 L16,1 Z"></path>
|
||||
<polygon points="4 17 14 17 9 11"></polygon>
|
||||
|
||||
|
Before Width: | Height: | Size: 486 B After Width: | Height: | Size: 374 B |
@@ -1,6 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 3.7.2 (28276) - http://www.bohemiancoding.com/sketch -->
|
||||
<svg width="18px" height="18px" viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill-rule="evenodd" fill-opacity="0.5">
|
||||
<path d="M1,1 C0.4,1 0,1.4 0,2 L0,13 C0,13.6 0.4,14 1,14 L5.6,14 L8.3,16.7 C8.5,16.9 8.7,17 9,17 C9.3,17 9.5,16.9 9.7,16.7 L12.4,14 L17,14 C17.6,14 18,13.6 18,13 L18,2 C18,1.4 17.6,1 17,1 L1,1 Z M5.52,11.15 C7.51,11.15 8.53,9.83 8.8,8.74 L7.51,8.35 C7.32,9.01 6.73,9.8 5.52,9.8 C4.38,9.8 3.32,8.97 3.32,7.46 C3.32,5.85 4.44,5.09 5.5,5.09 C6.73,5.09 7.28,5.84 7.45,6.52 L8.75,6.11 C8.47,4.96 7.46,3.76 5.5,3.76 C3.6,3.76 1.89,5.2 1.89,7.46 C1.89,9.72 3.54,11.15 5.52,11.15 Z M13.09,11.15 C15.08,11.15 16.1,9.83 16.37,8.74 L15.08,8.35 C14.89,9.01 14.3,9.8 13.09,9.8 C11.95,9.8 10.89,8.97 10.89,7.46 C10.89,5.85 12.01,5.09 13.07,5.09 C14.3,5.09 14.85,5.84 15.02,6.52 L16.32,6.11 C16.04,4.96 15.03,3.76 13.07,3.76 C11.17,3.76 9.46,5.2 9.46,7.46 C9.46,9.72 11.11,11.15 13.09,11.15 Z"></path>
|
||||
</g>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 945 B |
@@ -1,6 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 3.7.2 (28276) - http://www.bohemiancoding.com/sketch -->
|
||||
<svg width="18px" height="18px" viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill-rule="evenodd">
|
||||
<path d="M1,1 C0.4,1 0,1.4 0,2 L0,13 C0,13.6 0.4,14 1,14 L5.6,14 L8.3,16.7 C8.5,16.9 8.7,17 9,17 C9.3,17 9.5,16.9 9.7,16.7 L12.4,14 L17,14 C17.6,14 18,13.6 18,13 L18,2 C18,1.4 17.6,1 17,1 L1,1 Z M5.52,11.15 C7.51,11.15 8.53,9.83 8.8,8.74 L7.51,8.35 C7.32,9.01 6.73,9.8 5.52,9.8 C4.38,9.8 3.32,8.97 3.32,7.46 C3.32,5.85 4.44,5.09 5.5,5.09 C6.73,5.09 7.28,5.84 7.45,6.52 L8.75,6.11 C8.47,4.96 7.46,3.76 5.5,3.76 C3.6,3.76 1.89,5.2 1.89,7.46 C1.89,9.72 3.54,11.15 5.52,11.15 Z M13.09,11.15 C15.08,11.15 16.1,9.83 16.37,8.74 L15.08,8.35 C14.89,9.01 14.3,9.8 13.09,9.8 C11.95,9.8 10.89,8.97 10.89,7.46 C10.89,5.85 12.01,5.09 13.07,5.09 C14.3,5.09 14.85,5.84 15.02,6.52 L16.32,6.11 C16.04,4.96 15.03,3.76 13.07,3.76 C11.17,3.76 9.46,5.2 9.46,7.46 C9.46,9.72 11.11,11.15 13.09,11.15 Z"></path>
|
||||
</g>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 926 B |
@@ -0,0 +1,6 @@
|
||||
<svg width="18px" height="18px" viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
|
||||
<g transform="translate(2 1)">
|
||||
<path d="M7,12 C7.3,12 7.5,11.9 7.7,11.7 L13.4,6 L12,4.6 L8,8.6 L8,0 L6,0 L6,8.6 L2,4.6 L0.6,6 L6.3,11.7 C6.5,11.9 6.7,12 7,12 Z" />
|
||||
<rect width="14" height="2" y="14" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 325 B |
@@ -1,7 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g>
|
||||
<polygon points="10 3 13.6 3 9.6 7 11 8.4 15 4.4 15 8 17 8 17 1 10 1"></polygon>
|
||||
<polygon points="7 9.6 3 13.6 3 10 1 10 1 17 8 17 8 15 4.4 15 8.4 11"></polygon>
|
||||
</g>
|
||||
<svg width="18px" height="18px" viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
|
||||
<polygon points="10 3 13.6 3 9.6 7 11 8.4 15 4.4 15 8 17 8 17 1 10 1"></polygon>
|
||||
<polygon points="7 9.6 3 13.6 3 10 1 10 1 17 8 17 8 15 4.4 15 8.4 11"></polygon>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 401 B After Width: | Height: | Size: 264 B |
@@ -1,7 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g>
|
||||
<polygon points="1 12 4.6 12 0.6 16 2 17.4 6 13.4 6 17 8 17 8 10 1 10"></polygon>
|
||||
<polygon points="16 0.6 12 4.6 12 1 10 1 10 8 17 8 17 6 13.4 6 17.4 2"></polygon>
|
||||
</g>
|
||||
<svg width="18px" height="18px" viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
|
||||
<polygon points="1 12 4.6 12 0.6 16 2 17.4 6 13.4 6 17 8 17 8 10 1 10"></polygon>
|
||||
<polygon points="16 0.6 12 4.6 12 1 10 1 10 8 17 8 17 6 13.4 6 17.4 2"></polygon>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 403 B After Width: | Height: | Size: 266 B |
@@ -1,6 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g>
|
||||
<polygon points="7.875 7.17142857 0 1 0 17 7.875 10.8285714 7.875 17 18 9 7.875 1"></polygon>
|
||||
</g>
|
||||
<svg width="18px" height="18px" viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
|
||||
<polygon points="7.875 7.17142857 0 1 0 17 7.875 10.8285714 7.875 17 18 9 7.875 1"></polygon>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 325 B After Width: | Height: | Size: 192 B |
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18">
|
||||
<path d="M16,3.3 C15.9,4.9 14.8,7 12.7,9.7 C10.5,12.5 8.7,13.9 7.2,13.9 C6.3,13.9 5.5,13 4.8,11.3 C4,8.9 3.4,4 2,4 C1.9,4 1.5,4.3 0.8,4.8 L0,3.8 C0.8,3.1 3.5,0.4 4.7,0.3 C5.9,0.2 6.7,1 7,2.8 C7.3,4.8 7.8,8.9 8.8,8.9 C9.7,8.9 11.3,5.5 11.4,4.9 C11.5,4 11.1,3 9.1,3.8 C9.9,1.2 11.4,-8.8817842e-16 13.6,-8.8817842e-16 C15.3,0.1 16.1,1.2 16,3.3 Z"
|
||||
transform="translate(1 2)" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 470 B |
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18">
|
||||
<path d="M15.8,2.8 C15.6,1.5 15,0.6 13.6,0.4 C11.4,0 8,0 8,0 C8,0 4.6,0 2.4,0.4 C1,0.6 0.3,1.5 0.2,2.8 C0,4.1 0,6 0,6 C0,6 0,7.9 0.2,9.2 C0.4,10.5 1,11.4 2.4,11.6 C4.6,12 8,12 8,12 C8,12 11.4,12 13.6,11.6 C15,11.3 15.6,10.5 15.8,9.2 C16,7.9 16,6 16,6 C16,6 16,4.1 15.8,2.8 Z M6,9 L6,3 L11,6 L6,9 Z"
|
||||
transform="translate(1 3)" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 425 B |
@@ -1,7 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g>
|
||||
<polygon points="12.4 12.5 14.5 10.4 16.6 12.5 18 11.1 15.9 9 18 6.9 16.6 5.5 14.5 7.6 12.4 5.5 11 6.9 13.1 9 11 11.1"></polygon>
|
||||
<path d="M3.78571429,6.00820648 L0.714285714,6.00820648 C0.285714286,6.00820648 0,6.30901277 0,6.76022222 L0,11.2723167 C0,11.7235261 0.285714286,12.0243324 0.714285714,12.0243324 L3.78571429,12.0243324 L7.85714286,15.8819922 C8.35714286,16.1827985 9,15.8819922 9,15.2803796 L9,2.75215925 C9,2.15054666 8.35714286,1.77453879 7.85714286,2.15054666 L3.78571429,6.00820648 Z"></path>
|
||||
</g>
|
||||
<svg width="18px" height="18px" viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
|
||||
<polygon points="12.4 12.5 14.5 10.4 16.6 12.5 18 11.1 15.9 9 18 6.9 16.6 5.5 14.5 7.6 12.4 5.5 11 6.9 13.1 9 11 11.1"></polygon>
|
||||
<path d="M3.78571429,6.00820648 L0.714285714,6.00820648 C0.285714286,6.00820648 0,6.30901277 0,6.76022222 L0,11.2723167 C0,11.7235261 0.285714286,12.0243324 0.714285714,12.0243324 L3.78571429,12.0243324 L7.85714286,15.8819922 C8.35714286,16.1827985 9,15.8819922 9,15.2803796 L9,2.75215925 C9,2.15054666 8.35714286,1.77453879 7.85714286,2.15054666 L3.78571429,6.00820648 Z"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 750 B After Width: | Height: | Size: 613 B |
@@ -1,7 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g>
|
||||
<path d="M6,1 L3,1 C2.4,1 2,1.4 2,2 L2,16 C2,16.6 2.4,17 3,17 L6,17 C6.6,17 7,16.6 7,16 L7,2 C7,1.4 6.6,1 6,1 L6,1 Z"></path>
|
||||
<path d="M12,1 C11.4,1 11,1.4 11,2 L11,16 C11,16.6 11.4,17 12,17 L15,17 C15.6,17 16,16.6 16,16 L16,2 C16,1.4 15.6,1 15,1 L12,1 Z"></path>
|
||||
</g>
|
||||
<svg width="18px" height="18px" viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6,1 L3,1 C2.4,1 2,1.4 2,2 L2,16 C2,16.6 2.4,17 3,17 L6,17 C6.6,17 7,16.6 7,16 L7,2 C7,1.4 6.6,1 6,1 L6,1 Z"></path>
|
||||
<path d="M12,1 C11.4,1 11,1.4 11,2 L11,16 C11,16.6 11.4,17 12,17 L15,17 C15.6,17 16,16.6 16,16 L16,2 C16,1.4 15.6,1 15,1 L12,1 Z"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 503 B After Width: | Height: | Size: 366 B |
@@ -1,7 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g>
|
||||
<polygon points="13.293 3.293 7.022 9.564 8.436 10.978 14.707 4.707 17 7 17 1 11 1"></polygon>
|
||||
<path d="M13,15 L3,15 L3,5 L8,5 L8,3 L2,3 C1.448,3 1,3.448 1,4 L1,16 C1,16.552 1.448,17 2,17 L14,17 C14.552,17 15,16.552 15,16 L15,10 L13,10 L13,15 L13,15 Z"></path>
|
||||
</g>
|
||||
<svg width="18px" height="18px" viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
|
||||
<polygon points="13.293 3.293 7.022 9.564 8.436 10.978 14.707 4.707 17 7 17 1 11 1"></polygon>
|
||||
<path d="M13,15 L3,15 L3,5 L8,5 L8,3 L2,3 C1.448,3 1,3.448 1,4 L1,16 C1,16.552 1.448,17 2,17 L14,17 C14.552,17 15,16.552 15,16 L15,10 L13,10 L13,15 L13,15 Z"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 500 B After Width: | Height: | Size: 363 B |
@@ -1,6 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g>
|
||||
<path d="M15.5615866,8.10002147 L3.87056367,0.225209313 C3.05219207,-0.33727727 2,0.225209313 2,1.12518784 L2,16.8748122 C2,17.7747907 3.05219207,18.3372773 3.87056367,17.7747907 L15.5615866,9.89997853 C16.1461378,9.44998927 16.1461378,8.55001073 15.5615866,8.10002147 L15.5615866,8.10002147 Z"></path>
|
||||
</g>
|
||||
<svg width="18px" height="18px" viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M15.5615866,8.10002147 L3.87056367,0.225209313 C3.05219207,-0.33727727 2,0.225209313 2,1.12518784 L2,16.8748122 C2,17.7747907 3.05219207,18.3372773 3.87056367,17.7747907 L15.5615866,9.89997853 C16.1461378,9.44998927 16.1461378,8.55001073 15.5615866,8.10002147 L15.5615866,8.10002147 Z"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 534 B After Width: | Height: | Size: 401 B |
@@ -1,6 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g>
|
||||
<path d="M9.7,1.2 L10.4,7.6 L12.5,5.5 C14.4,7.4 14.4,10.6 12.5,12.5 C11.6,13.5 10.3,14 9,14 C7.7,14 6.4,13.5 5.5,12.5 C3.6,10.6 3.6,7.4 5.5,5.5 C6.1,4.9 6.9,4.4 7.8,4.2 L7.2,2.3 C6,2.6 4.9,3.2 4,4.1 C1.3,6.8 1.3,11.2 4,14 C5.3,15.3 7.1,16 8.9,16 C10.8,16 12.5,15.3 13.8,14 C16.5,11.3 16.5,6.9 13.8,4.1 L16,1.9 L9.7,1.2 L9.7,1.2 Z"></path>
|
||||
</g>
|
||||
<svg width="18px" height="18px" viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M9.7,1.2 L10.4,7.6 L12.5,5.5 C14.4,7.4 14.4,10.6 12.5,12.5 C11.6,13.5 10.3,14 9,14 C7.7,14 6.4,13.5 5.5,12.5 C3.6,10.6 3.6,7.4 5.5,5.5 C6.1,4.9 6.9,4.4 7.8,4.2 L7.2,2.3 C6,2.6 4.9,3.2 4,4.1 C1.3,6.8 1.3,11.2 4,14 C5.3,15.3 7.1,16 8.9,16 C10.8,16 12.5,15.3 13.8,14 C16.5,11.3 16.5,6.9 13.8,4.1 L16,1.9 L9.7,1.2 L9.7,1.2 Z"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 570 B After Width: | Height: | Size: 437 B |
@@ -1,6 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g>
|
||||
<polygon points="10.125 1 0 9 10.125 17 10.125 10.8285714 18 17 18 1 10.125 7.17142857"></polygon>
|
||||
</g>
|
||||
<svg width="18px" height="18px" viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
|
||||
<polygon points="10.125 1 0 9 10.125 17 10.125 10.8285714 18 17 18 1 10.125 7.17142857"></polygon>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 330 B After Width: | Height: | Size: 197 B |
@@ -1,6 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g>
|
||||
<path d="M16.135,7.784 C14.832,7.458 14.214,5.966 14.905,4.815 C15.227,4.279 15.13,3.817 14.811,3.499 L14.501,3.189 C14.183,2.871 13.721,2.774 13.185,3.095 C12.033,3.786 10.541,3.168 10.216,1.865 C10.065,1.258 9.669,1 9.219,1 L8.781,1 C8.331,1 7.936,1.258 7.784,1.865 C7.458,3.168 5.966,3.786 4.815,3.095 C4.279,2.773 3.816,2.87 3.498,3.188 L3.188,3.498 C2.87,3.816 2.773,4.279 3.095,4.815 C3.786,5.967 3.168,7.459 1.865,7.784 C1.26,7.935 1,8.33 1,8.781 L1,9.219 C1,9.669 1.258,10.064 1.865,10.216 C3.168,10.542 3.786,12.034 3.095,13.185 C2.773,13.721 2.87,14.183 3.189,14.501 L3.499,14.811 C3.818,15.13 4.281,15.226 4.815,14.905 C5.967,14.214 7.459,14.832 7.784,16.135 C7.935,16.742 8.331,17 8.781,17 L9.219,17 C9.669,17 10.064,16.742 10.216,16.135 C10.542,14.832 12.034,14.214 13.185,14.905 C13.72,15.226 14.182,15.13 14.501,14.811 L14.811,14.501 C15.129,14.183 15.226,13.72 14.905,13.185 C14.214,12.033 14.832,10.541 16.135,10.216 C16.742,10.065 17,9.669 17,9.219 L17,8.781 C17,8.33 16.74,7.935 16.135,7.784 L16.135,7.784 Z M9,12 C7.343,12 6,10.657 6,9 C6,7.343 7.343,6 9,6 C10.657,6 12,7.343 12,9 C12,10.657 10.657,12 9,12 L9,12 Z"></path>
|
||||
</g>
|
||||
<svg width="18px" height="18px" viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M16.135,7.784 C14.832,7.458 14.214,5.966 14.905,4.815 C15.227,4.279 15.13,3.817 14.811,3.499 L14.501,3.189 C14.183,2.871 13.721,2.774 13.185,3.095 C12.033,3.786 10.541,3.168 10.216,1.865 C10.065,1.258 9.669,1 9.219,1 L8.781,1 C8.331,1 7.936,1.258 7.784,1.865 C7.458,3.168 5.966,3.786 4.815,3.095 C4.279,2.773 3.816,2.87 3.498,3.188 L3.188,3.498 C2.87,3.816 2.773,4.279 3.095,4.815 C3.786,5.967 3.168,7.459 1.865,7.784 C1.26,7.935 1,8.33 1,8.781 L1,9.219 C1,9.669 1.258,10.064 1.865,10.216 C3.168,10.542 3.786,12.034 3.095,13.185 C2.773,13.721 2.87,14.183 3.189,14.501 L3.499,14.811 C3.818,15.13 4.281,15.226 4.815,14.905 C5.967,14.214 7.459,14.832 7.784,16.135 C7.935,16.742 8.331,17 8.781,17 L9.219,17 C9.669,17 10.064,16.742 10.216,16.135 C10.542,14.832 12.034,14.214 13.185,14.905 C13.72,15.226 14.182,15.13 14.501,14.811 L14.811,14.501 C15.129,14.183 15.226,13.72 14.905,13.185 C14.214,12.033 14.832,10.541 16.135,10.216 C16.742,10.065 17,9.669 17,9.219 L17,8.781 C17,8.33 16.74,7.935 16.135,7.784 L16.135,7.784 Z M9,12 C7.343,12 6,10.657 6,9 C6,7.343 7.343,6 9,6 C10.657,6 12,7.343 12,9 C12,10.657 10.657,12 9,12 L9,12 Z"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.2 KiB |
@@ -1,8 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g>
|
||||
<path d="M15.5999996,3.3 C15.1999996,2.9 14.5999996,2.9 14.1999996,3.3 C13.7999996,3.7 13.7999996,4.3 14.1999996,4.7 C15.3999996,5.9 15.9999996,7.4 15.9999996,9 C15.9999996,10.6 15.3999996,12.1 14.1999996,13.3 C13.7999996,13.7 13.7999996,14.3 14.1999996,14.7 C14.3999996,14.9 14.6999996,15 14.8999996,15 C15.1999996,15 15.3999996,14.9 15.5999996,14.7 C17.0999996,13.2 17.9999996,11.2 17.9999996,9 C17.9999996,6.8 17.0999996,4.8 15.5999996,3.3 L15.5999996,3.3 Z"></path>
|
||||
<path d="M11.2819745,5.28197449 C10.9060085,5.65794047 10.9060085,6.22188944 11.2819745,6.59785542 C12.0171538,7.33303477 12.2772954,8.05605449 12.2772954,9.00000021 C12.2772954,9.93588462 11.851678,10.9172014 11.2819745,11.4869049 C10.9060085,11.8628709 10.9060085,12.4268199 11.2819745,12.8027859 C11.4271642,12.9479755 11.9176724,13.0649528 12.2998149,12.9592565 C12.4124479,12.9281035 12.5156669,12.8776063 12.5978555,12.8027859 C13.773371,11.732654 14.1311161,10.1597914 14.1312523,9.00000021 C14.1312723,8.8299555 14.1286311,8.66015647 14.119665,8.4897429 C14.0674781,7.49784946 13.8010171,6.48513613 12.5978554,5.28197449 C12.2218894,4.9060085 11.6579405,4.9060085 11.2819745,5.28197449 Z"></path>
|
||||
<path d="M3.78571429,6.00820648 L0.714285714,6.00820648 C0.285714286,6.00820648 0,6.30901277 0,6.76022222 L0,11.2723167 C0,11.7235261 0.285714286,12.0243324 0.714285714,12.0243324 L3.78571429,12.0243324 L7.85714286,15.8819922 C8.35714286,16.1827985 9,15.8819922 9,15.2803796 L9,2.75215925 C9,2.15054666 8.35714286,1.77453879 7.85714286,2.15054666 L3.78571429,6.00820648 Z"></path>
|
||||
</g>
|
||||
<svg width="18px" height="18px" viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M15.5999996,3.3 C15.1999996,2.9 14.5999996,2.9 14.1999996,3.3 C13.7999996,3.7 13.7999996,4.3 14.1999996,4.7 C15.3999996,5.9 15.9999996,7.4 15.9999996,9 C15.9999996,10.6 15.3999996,12.1 14.1999996,13.3 C13.7999996,13.7 13.7999996,14.3 14.1999996,14.7 C14.3999996,14.9 14.6999996,15 14.8999996,15 C15.1999996,15 15.3999996,14.9 15.5999996,14.7 C17.0999996,13.2 17.9999996,11.2 17.9999996,9 C17.9999996,6.8 17.0999996,4.8 15.5999996,3.3 L15.5999996,3.3 Z"></path>
|
||||
<path d="M11.2819745,5.28197449 C10.9060085,5.65794047 10.9060085,6.22188944 11.2819745,6.59785542 C12.0171538,7.33303477 12.2772954,8.05605449 12.2772954,9.00000021 C12.2772954,9.93588462 11.851678,10.9172014 11.2819745,11.4869049 C10.9060085,11.8628709 10.9060085,12.4268199 11.2819745,12.8027859 C11.4271642,12.9479755 11.9176724,13.0649528 12.2998149,12.9592565 C12.4124479,12.9281035 12.5156669,12.8776063 12.5978555,12.8027859 C13.773371,11.732654 14.1311161,10.1597914 14.1312523,9.00000021 C14.1312723,8.8299555 14.1286311,8.66015647 14.119665,8.4897429 C14.0674781,7.49784946 13.8010171,6.48513613 12.5978554,5.28197449 C12.2218894,4.9060085 11.6579405,4.9060085 11.2819745,5.28197449 Z"></path>
|
||||
<path d="M3.78571429,6.00820648 L0.714285714,6.00820648 C0.285714286,6.00820648 0,6.30901277 0,6.76022222 L0,11.2723167 C0,11.7235261 0.285714286,12.0243324 0.714285714,12.0243324 L3.78571429,12.0243324 L7.85714286,15.8819922 C8.35714286,16.1827985 9,15.8819922 9,15.2803796 L9,2.75215925 C9,2.15054666 8.35714286,1.77453879 7.85714286,2.15054666 L3.78571429,6.00820648 Z"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.6 KiB |