2204 lines
206 KiB
HTML
2204 lines
206 KiB
HTML
|
<!DOCTYPE html><html lang="fr">
|
|||
|
<head><meta charset="utf-8">
|
|||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|||
|
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"><title>VPN Surfshark - YannStatic</title>
|
|||
|
|
|||
|
<meta name="description" content="VPN Surfshark, offre du 17 août 2020 : 1.69€/mois → 40.56€ HT tous les 24 mois (48.67€ TTC)">
|
|||
|
<link rel="canonical" href="https://static.rnmkcy.eu/2020/08/17/VPN_Surfshark.html"><link rel="alternate" type="application/rss+xml" title="YannStatic" href="/feed.xml">
|
|||
|
|
|||
|
<!-- - include head/favicon.html - -->
|
|||
|
<link rel="shortcut icon" type="image/png" href="/assets/favicon/favicon.png"><link rel="stylesheet" href="/assets/css/main.css"><link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.13/css/all.css" ><!-- start custom head snippets --><link rel="stylesheet" href="/assets/css/expand.css">
|
|||
|
<!-- end custom head snippets --><script>(function() {
|
|||
|
window.isArray = function(val) {
|
|||
|
return Object.prototype.toString.call(val) === '[object Array]';
|
|||
|
};
|
|||
|
window.isString = function(val) {
|
|||
|
return typeof val === 'string';
|
|||
|
};
|
|||
|
|
|||
|
window.hasEvent = function(event) {
|
|||
|
return 'on'.concat(event) in window.document;
|
|||
|
};
|
|||
|
|
|||
|
window.isOverallScroller = function(node) {
|
|||
|
return node === document.documentElement || node === document.body || node === window;
|
|||
|
};
|
|||
|
|
|||
|
window.isFormElement = function(node) {
|
|||
|
var tagName = node.tagName;
|
|||
|
return tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA';
|
|||
|
};
|
|||
|
|
|||
|
window.pageLoad = (function () {
|
|||
|
var loaded = false, cbs = [];
|
|||
|
window.addEventListener('load', function () {
|
|||
|
var i;
|
|||
|
loaded = true;
|
|||
|
if (cbs.length > 0) {
|
|||
|
for (i = 0; i < cbs.length; i++) {
|
|||
|
cbs[i]();
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
return {
|
|||
|
then: function(cb) {
|
|||
|
cb && (loaded ? cb() : (cbs.push(cb)));
|
|||
|
}
|
|||
|
};
|
|||
|
})();
|
|||
|
})();
|
|||
|
(function() {
|
|||
|
window.throttle = function(func, wait) {
|
|||
|
var args, result, thisArg, timeoutId, lastCalled = 0;
|
|||
|
|
|||
|
function trailingCall() {
|
|||
|
lastCalled = new Date;
|
|||
|
timeoutId = null;
|
|||
|
result = func.apply(thisArg, args);
|
|||
|
}
|
|||
|
return function() {
|
|||
|
var now = new Date,
|
|||
|
remaining = wait - (now - lastCalled);
|
|||
|
|
|||
|
args = arguments;
|
|||
|
thisArg = this;
|
|||
|
|
|||
|
if (remaining <= 0) {
|
|||
|
clearTimeout(timeoutId);
|
|||
|
timeoutId = null;
|
|||
|
lastCalled = now;
|
|||
|
result = func.apply(thisArg, args);
|
|||
|
} else if (!timeoutId) {
|
|||
|
timeoutId = setTimeout(trailingCall, remaining);
|
|||
|
}
|
|||
|
return result;
|
|||
|
};
|
|||
|
};
|
|||
|
})();
|
|||
|
(function() {
|
|||
|
var Set = (function() {
|
|||
|
var add = function(item) {
|
|||
|
var i, data = this._data;
|
|||
|
for (i = 0; i < data.length; i++) {
|
|||
|
if (data[i] === item) {
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
this.size ++;
|
|||
|
data.push(item);
|
|||
|
return data;
|
|||
|
};
|
|||
|
|
|||
|
var Set = function(data) {
|
|||
|
this.size = 0;
|
|||
|
this._data = [];
|
|||
|
var i;
|
|||
|
if (data.length > 0) {
|
|||
|
for (i = 0; i < data.length; i++) {
|
|||
|
add.call(this, data[i]);
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
Set.prototype.add = add;
|
|||
|
Set.prototype.get = function(index) { return this._data[index]; };
|
|||
|
Set.prototype.has = function(item) {
|
|||
|
var i, data = this._data;
|
|||
|
for (i = 0; i < data.length; i++) {
|
|||
|
if (this.get(i) === item) {
|
|||
|
return true;
|
|||
|
}
|
|||
|
}
|
|||
|
return false;
|
|||
|
};
|
|||
|
Set.prototype.is = function(map) {
|
|||
|
if (map._data.length !== this._data.length) { return false; }
|
|||
|
var i, j, flag, tData = this._data, mData = map._data;
|
|||
|
for (i = 0; i < tData.length; i++) {
|
|||
|
for (flag = false, j = 0; j < mData.length; j++) {
|
|||
|
if (tData[i] === mData[j]) {
|
|||
|
flag = true;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
if (!flag) { return false; }
|
|||
|
}
|
|||
|
return true;
|
|||
|
};
|
|||
|
Set.prototype.values = function() {
|
|||
|
return this._data;
|
|||
|
};
|
|||
|
return Set;
|
|||
|
})();
|
|||
|
|
|||
|
window.Lazyload = (function(doc) {
|
|||
|
var queue = {js: [], css: []}, sources = {js: {}, css: {}}, context = this;
|
|||
|
var createNode = function(name, attrs) {
|
|||
|
var node = doc.createElement(name), attr;
|
|||
|
for (attr in attrs) {
|
|||
|
if (attrs.hasOwnProperty(attr)) {
|
|||
|
node.setAttribute(attr, attrs[attr]);
|
|||
|
}
|
|||
|
}
|
|||
|
return node;
|
|||
|
};
|
|||
|
var end = function(type, url) {
|
|||
|
var s, q, qi, cbs, i, j, cur, val, flag;
|
|||
|
if (type === 'js' || type ==='css') {
|
|||
|
s = sources[type], q = queue[type];
|
|||
|
s[url] = true;
|
|||
|
for (i = 0; i < q.length; i++) {
|
|||
|
cur = q[i];
|
|||
|
if (cur.urls.has(url)) {
|
|||
|
qi = cur, val = qi.urls.values();
|
|||
|
qi && (cbs = qi.callbacks);
|
|||
|
for (flag = true, j = 0; j < val.length; j++) {
|
|||
|
cur = val[j];
|
|||
|
if (!s[cur]) {
|
|||
|
flag = false;
|
|||
|
}
|
|||
|
}
|
|||
|
if (flag && cbs && cbs.length > 0) {
|
|||
|
for (j = 0; j < cbs.length; j++) {
|
|||
|
cbs[j].call(context);
|
|||
|
}
|
|||
|
qi.load = true;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
var load = function(type, urls, callback) {
|
|||
|
var s, q, qi, node, i, cur,
|
|||
|
_urls = typeof urls === 'string' ? new Set([urls]) : new Set(urls), val, url;
|
|||
|
if (type === 'js' || type ==='css') {
|
|||
|
s = sources[type], q = queue[type];
|
|||
|
for (i = 0; i < q.length; i++) {
|
|||
|
cur = q[i];
|
|||
|
if (_urls.is(cur.urls)) {
|
|||
|
qi = cur;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
val = _urls.values();
|
|||
|
if (qi) {
|
|||
|
callback && (qi.load || qi.callbacks.push(callback));
|
|||
|
callback && (qi.load && callback());
|
|||
|
} else {
|
|||
|
q.push({
|
|||
|
urls: _urls,
|
|||
|
callbacks: callback ? [callback] : [],
|
|||
|
load: false
|
|||
|
});
|
|||
|
for (i = 0; i < val.length; i++) {
|
|||
|
node = null, url = val[i];
|
|||
|
if (s[url] === undefined) {
|
|||
|
(type === 'js' ) && (node = createNode('script', { src: url }));
|
|||
|
(type === 'css') && (node = createNode('link', { rel: 'stylesheet', href: url }));
|
|||
|
if (node) {
|
|||
|
node.onload = (function(type, url) {
|
|||
|
return function() {
|
|||
|
end(type, url);
|
|||
|
};
|
|||
|
})(type, url);
|
|||
|
(doc.head || doc.body).appendChild(node);
|
|||
|
s[url] = false;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
return {
|
|||
|
js: function(url, callback) {
|
|||
|
load('js', url, callback);
|
|||
|
},
|
|||
|
css: function(url, callback) {
|
|||
|
load('css', url, callback);
|
|||
|
}
|
|||
|
};
|
|||
|
})(this.document);
|
|||
|
})();
|
|||
|
</script><script>
|
|||
|
(function() {
|
|||
|
var TEXT_VARIABLES = {
|
|||
|
version: '2.2.6',
|
|||
|
sources: {
|
|||
|
font_awesome: 'https://use.fontawesome.com/releases/v5.0.13/css/all.css',
|
|||
|
jquery: '/assets/js/jquery.min.js',
|
|||
|
leancloud_js_sdk: '//cdn.jsdelivr.net/npm/leancloud-storage@3.13.2/dist/av-min.js',
|
|||
|
chart: 'https://cdn.bootcss.com/Chart.js/2.7.2/Chart.bundle.min.js',
|
|||
|
gitalk: {
|
|||
|
js: 'https://cdn.bootcss.com/gitalk/1.2.2/gitalk.min.js',
|
|||
|
css: 'https://cdn.bootcss.com/gitalk/1.2.2/gitalk.min.css'
|
|||
|
},
|
|||
|
valine: 'https://unpkg.com/valine/dist/Valine.min.js'
|
|||
|
},
|
|||
|
site: {
|
|||
|
toc: {
|
|||
|
selectors: 'h1,h2,h3'
|
|||
|
}
|
|||
|
},
|
|||
|
paths: {
|
|||
|
search_js: '/assets/search.js'
|
|||
|
}
|
|||
|
};
|
|||
|
window.TEXT_VARIABLES = TEXT_VARIABLES;
|
|||
|
})();
|
|||
|
</script>
|
|||
|
</head>
|
|||
|
<body>
|
|||
|
<div class="root" data-is-touch="false">
|
|||
|
<div class="layout--page js-page-root"><!----><div class="page__main js-page-main page__viewport hide-footer has-aside has-aside cell cell--auto">
|
|||
|
|
|||
|
<div class="page__main-inner"><div class="page__header d-print-none"><header class="header"><div class="main">
|
|||
|
<div class="header__title">
|
|||
|
<div class="header__brand"><svg id="svg" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="478.9473684210526" viewBox="0, 0, 400,478.9473684210526"><g id="svgg"><path id="path0" d="M308.400 56.805 C 306.970 56.966,303.280 57.385,300.200 57.738 C 290.906 58.803,278.299 59.676,269.200 59.887 L 260.600 60.085 259.400 61.171 C 258.010 62.428,256.198 63.600,255.645 63.600 C 255.070 63.600,252.887 65.897,252.598 66.806 C 252.460 67.243,252.206 67.600,252.034 67.600 C 251.397 67.600,247.206 71.509,247.202 72.107 C 247.201 72.275,246.390 73.190,245.400 74.138 C 243.961 75.517,243.598 76.137,243.592 77.231 C 243.579 79.293,241.785 83.966,240.470 85.364 C 239.176 86.740,238.522 88.365,237.991 91.521 C 237.631 93.665,236.114 97.200,235.554 97.200 C 234.938 97.200,232.737 102.354,232.450 104.472 C 232.158 106.625,230.879 109.226,229.535 110.400 C 228.933 110.926,228.171 113.162,226.434 119.500 C 226.178 120.435,225.795 121.200,225.584 121.200 C 225.373 121.200,225.200 121.476,225.200 121.813 C 225.200 122.149,224.885 122.541,224.500 122.683 C 223.606 123.013,223.214 123.593,223.204 124.600 C 223.183 126.555,220.763 132.911,219.410 134.562 C 218.443 135.742,217.876 136.956,217.599 138.440 C 217.041 141.424,215.177 146.434,214.532 146.681 C 214.240 146.794,214.000 147.055,214.000 147.261 C 214.000 147.467,213.550 148.086,213.000 148.636 C 212.450 149.186,212.000 149.893,212.000 150.208 C 212.000 151.386,208.441 154.450,207.597 153.998 C 206.319 153.315,204.913 150.379,204.633 147.811 C 204.365 145.357,202.848 142.147,201.759 141.729 C 200.967 141.425,199.200 137.451,199.200 135.974 C 199.200 134.629,198.435 133.224,196.660 131.311 C 195.363 129.913,194.572 128.123,193.870 125.000 C 193.623 123.900,193.236 122.793,193.010 122.540 C 190.863 120.133,190.147 118.880,188.978 115.481 C 188.100 112.928,187.151 111.003,186.254 109.955 C 185.358 108.908,184.518 107.204,183.847 105.073 C 183.280 103.273,182.497 101.329,182.108 100.753 C 181.719 100.177,180.904 98.997,180.298 98.131 C 179.693 97.265,178.939 95.576,178.624 94.378 C 178.041 92.159,177.125 90.326,175.023 87.168 C 174.375 86.196,173.619 84.539,173.342 83.486 C 172.800 81.429,171.529 79.567,170.131 78.785 C 169.654 78.517,168.697 77.511,168.006 76.549 C 167.316 75.587,166.594 74.800,166.402 74.800 C 166.210 74.800,164.869 73.633,163.421 72.206 C 160.103 68.936,161.107 69.109,146.550 69.301 C 133.437 69.474,128.581 70.162,126.618 72.124 C 126.248 72.495,125.462 72.904,124.872 73.033 C 124.282 73.163,123.088 73.536,122.219 73.863 C 121.349 74.191,119.028 74.638,117.061 74.858 C 113.514 75.254,109.970 76.350,108.782 77.419 C 107.652 78.436,100.146 80.400,97.388 80.400 C 95.775 80.400,93.167 81.360,91.200 82.679 C 90.430 83.195,89.113 83.804,88.274 84.031 C 85.875 84.681,78.799 90.910,74.400 96.243 L 73.400 97.456 73.455 106.028 C 73.526 117.055,74.527 121.238,77.820 124.263 C 78.919 125.273,80.400 127.902,80.400 128.842 C 80.400 129.202,81.075 130.256,81.900 131.186 C 83.563 133.059,85.497 136.346,86.039 138.216 C 86.233 138.886,87.203 140.207,88.196 141.153 C 89.188 142.098,90.000 143.104,90.000 143.388 C 90.000 144.337,92.129 148.594,92.869 149.123 C 93.271 149.410,93.600 149.831,93.600 150.059 C 93.600 150.286,93.932 150.771,94.337 151.136 C 94.743 151.501,95.598 153.004,96.237 154.475 C 96.877 155.947,97.760 157.351,98.200 157.596 C 98.640 157.841,99.900 159.943,101.000 162.267 C 102.207 164.817,103.327 166.644,103.825 166.876 C 104.278 167.087,105.065 168.101,105.573 169.130 C 107.658 173.348,108.097 174.093,110.006 176.647 C 111.103 178.114,112.000 179.725,112.000 180.227 C 112.000 181.048,113.425 183.163,114.678 184.200 C 115.295 184.711,117.396 188.733,117.720 190.022 C 117.855 190.562,118.603 191.633,119.381 192.402 C 120.160 193.171,121.496 195.258,122.351 197.039 C 123.206 198.820,124.167 200.378,124.487 200.501 C 124.807 200.624,125.953 202.496,127.034 204.662 C 128.114 206.828,129.676 209.299,130.505 210.153 C 131.333 211.007,132.124 212.177,132.262 212.753 C 132.618 214.239,134.291 217.048,136.288 219.5
|
|||
|
" href="/">YannStatic</a></div><!--<button class="button button--secondary button--circle search-button js-search-toggle"><i class="fas fa-search"></i></button>--><!-- <li><button class="button button--secondary button--circle search-button js-search-toggle"><i class="fas fa-search"></i></button></li> -->
|
|||
|
<!-- Champ de recherche -->
|
|||
|
<div id="searchbox" class="search search--dark" style="visibility: visible">
|
|||
|
<div class="main">
|
|||
|
<div class="search__header"></div>
|
|||
|
<div class="search-bar">
|
|||
|
<div class="search-box js-search-box">
|
|||
|
<div class="search-box__icon-search"><i class="fas fa-search"></i></div>
|
|||
|
<input id="search-input" type="text" />
|
|||
|
<!-- <div class="search-box__icon-clear js-icon-clear">
|
|||
|
<a><i class="fas fa-times"></i></a>
|
|||
|
</div> -->
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
<!-- Script pointing to search-script.js -->
|
|||
|
<script>/*!
|
|||
|
* Simple-Jekyll-Search
|
|||
|
* Copyright 2015-2020, Christian Fei
|
|||
|
* Licensed under the MIT License.
|
|||
|
*/
|
|||
|
|
|||
|
(function(){
|
|||
|
'use strict'
|
|||
|
|
|||
|
var _$Templater_7 = {
|
|||
|
compile: compile,
|
|||
|
setOptions: setOptions
|
|||
|
}
|
|||
|
|
|||
|
const options = {}
|
|||
|
options.pattern = /\{(.*?)\}/g
|
|||
|
options.template = ''
|
|||
|
options.middleware = function () {}
|
|||
|
|
|||
|
function setOptions (_options) {
|
|||
|
options.pattern = _options.pattern || options.pattern
|
|||
|
options.template = _options.template || options.template
|
|||
|
if (typeof _options.middleware === 'function') {
|
|||
|
options.middleware = _options.middleware
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function compile (data) {
|
|||
|
return options.template.replace(options.pattern, function (match, prop) {
|
|||
|
const value = options.middleware(prop, data[prop], options.template)
|
|||
|
if (typeof value !== 'undefined') {
|
|||
|
return value
|
|||
|
}
|
|||
|
return data[prop] || match
|
|||
|
})
|
|||
|
}
|
|||
|
|
|||
|
'use strict';
|
|||
|
|
|||
|
function fuzzysearch (needle, haystack) {
|
|||
|
var tlen = haystack.length;
|
|||
|
var qlen = needle.length;
|
|||
|
if (qlen > tlen) {
|
|||
|
return false;
|
|||
|
}
|
|||
|
if (qlen === tlen) {
|
|||
|
return needle === haystack;
|
|||
|
}
|
|||
|
outer: for (var i = 0, j = 0; i < qlen; i++) {
|
|||
|
var nch = needle.charCodeAt(i);
|
|||
|
while (j < tlen) {
|
|||
|
if (haystack.charCodeAt(j++) === nch) {
|
|||
|
continue outer;
|
|||
|
}
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
var _$fuzzysearch_1 = fuzzysearch;
|
|||
|
|
|||
|
'use strict'
|
|||
|
|
|||
|
/* removed: const _$fuzzysearch_1 = require('fuzzysearch') */;
|
|||
|
|
|||
|
var _$FuzzySearchStrategy_5 = new FuzzySearchStrategy()
|
|||
|
|
|||
|
function FuzzySearchStrategy () {
|
|||
|
this.matches = function (string, crit) {
|
|||
|
return _$fuzzysearch_1(crit.toLowerCase(), string.toLowerCase())
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
'use strict'
|
|||
|
|
|||
|
var _$LiteralSearchStrategy_6 = new LiteralSearchStrategy()
|
|||
|
|
|||
|
function LiteralSearchStrategy () {
|
|||
|
this.matches = function (str, crit) {
|
|||
|
if (!str) return false
|
|||
|
|
|||
|
str = str.trim().toLowerCase()
|
|||
|
crit = crit.trim().toLowerCase()
|
|||
|
|
|||
|
return crit.split(' ').filter(function (word) {
|
|||
|
return str.indexOf(word) >= 0
|
|||
|
}).length === crit.split(' ').length
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
'use strict'
|
|||
|
|
|||
|
var _$Repository_4 = {
|
|||
|
put: put,
|
|||
|
clear: clear,
|
|||
|
search: search,
|
|||
|
setOptions: __setOptions_4
|
|||
|
}
|
|||
|
|
|||
|
/* removed: const _$FuzzySearchStrategy_5 = require('./SearchStrategies/FuzzySearchStrategy') */;
|
|||
|
/* removed: const _$LiteralSearchStrategy_6 = require('./SearchStrategies/LiteralSearchStrategy') */;
|
|||
|
|
|||
|
function NoSort () {
|
|||
|
return 0
|
|||
|
}
|
|||
|
|
|||
|
const data = []
|
|||
|
let opt = {}
|
|||
|
|
|||
|
opt.fuzzy = false
|
|||
|
opt.limit = 10
|
|||
|
opt.searchStrategy = opt.fuzzy ? _$FuzzySearchStrategy_5 : _$LiteralSearchStrategy_6
|
|||
|
opt.sort = NoSort
|
|||
|
opt.exclude = []
|
|||
|
|
|||
|
function put (data) {
|
|||
|
if (isObject(data)) {
|
|||
|
return addObject(data)
|
|||
|
}
|
|||
|
if (isArray(data)) {
|
|||
|
return addArray(data)
|
|||
|
}
|
|||
|
return undefined
|
|||
|
}
|
|||
|
function clear () {
|
|||
|
data.length = 0
|
|||
|
return data
|
|||
|
}
|
|||
|
|
|||
|
function isObject (obj) {
|
|||
|
return Boolean(obj) && Object.prototype.toString.call(obj) === '[object Object]'
|
|||
|
}
|
|||
|
|
|||
|
function isArray (obj) {
|
|||
|
return Boolean(obj) && Object.prototype.toString.call(obj) === '[object Array]'
|
|||
|
}
|
|||
|
|
|||
|
function addObject (_data) {
|
|||
|
data.push(_data)
|
|||
|
return data
|
|||
|
}
|
|||
|
|
|||
|
function addArray (_data) {
|
|||
|
const added = []
|
|||
|
clear()
|
|||
|
for (let i = 0, len = _data.length; i < len; i++) {
|
|||
|
if (isObject(_data[i])) {
|
|||
|
added.push(addObject(_data[i]))
|
|||
|
}
|
|||
|
}
|
|||
|
return added
|
|||
|
}
|
|||
|
|
|||
|
function search (crit) {
|
|||
|
if (!crit) {
|
|||
|
return []
|
|||
|
}
|
|||
|
return findMatches(data, crit, opt.searchStrategy, opt).sort(opt.sort)
|
|||
|
}
|
|||
|
|
|||
|
function __setOptions_4 (_opt) {
|
|||
|
opt = _opt || {}
|
|||
|
|
|||
|
opt.fuzzy = _opt.fuzzy || false
|
|||
|
opt.limit = _opt.limit || 10
|
|||
|
opt.searchStrategy = _opt.fuzzy ? _$FuzzySearchStrategy_5 : _$LiteralSearchStrategy_6
|
|||
|
opt.sort = _opt.sort || NoSort
|
|||
|
opt.exclude = _opt.exclude || []
|
|||
|
}
|
|||
|
|
|||
|
function findMatches (data, crit, strategy, opt) {
|
|||
|
const matches = []
|
|||
|
for (let i = 0; i < data.length && matches.length < opt.limit; i++) {
|
|||
|
const match = findMatchesInObject(data[i], crit, strategy, opt)
|
|||
|
if (match) {
|
|||
|
matches.push(match)
|
|||
|
}
|
|||
|
}
|
|||
|
return matches
|
|||
|
}
|
|||
|
|
|||
|
function findMatchesInObject (obj, crit, strategy, opt) {
|
|||
|
for (const key in obj) {
|
|||
|
if (!isExcluded(obj[key], opt.exclude) && strategy.matches(obj[key], crit)) {
|
|||
|
return obj
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function isExcluded (term, excludedTerms) {
|
|||
|
for (let i = 0, len = excludedTerms.length; i < len; i++) {
|
|||
|
const excludedTerm = excludedTerms[i]
|
|||
|
if (new RegExp(excludedTerm).test(term)) {
|
|||
|
return true
|
|||
|
}
|
|||
|
}
|
|||
|
return false
|
|||
|
}
|
|||
|
|
|||
|
/* globals ActiveXObject:false */
|
|||
|
|
|||
|
'use strict'
|
|||
|
|
|||
|
var _$JSONLoader_2 = {
|
|||
|
load: load
|
|||
|
}
|
|||
|
|
|||
|
function load (location, callback) {
|
|||
|
const xhr = getXHR()
|
|||
|
xhr.open('GET', location, true)
|
|||
|
xhr.onreadystatechange = createStateChangeListener(xhr, callback)
|
|||
|
xhr.send()
|
|||
|
}
|
|||
|
|
|||
|
function createStateChangeListener (xhr, callback) {
|
|||
|
return function () {
|
|||
|
if (xhr.readyState === 4 && xhr.status === 200) {
|
|||
|
try {
|
|||
|
callback(null, JSON.parse(xhr.responseText))
|
|||
|
} catch (err) {
|
|||
|
callback(err, null)
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function getXHR () {
|
|||
|
return window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP')
|
|||
|
}
|
|||
|
|
|||
|
'use strict'
|
|||
|
|
|||
|
var _$OptionsValidator_3 = function OptionsValidator (params) {
|
|||
|
if (!validateParams(params)) {
|
|||
|
throw new Error('-- OptionsValidator: required options missing')
|
|||
|
}
|
|||
|
|
|||
|
if (!(this instanceof OptionsValidator)) {
|
|||
|
return new OptionsValidator(params)
|
|||
|
}
|
|||
|
|
|||
|
const requiredOptions = params.required
|
|||
|
|
|||
|
this.getRequiredOptions = function () {
|
|||
|
return requiredOptions
|
|||
|
}
|
|||
|
|
|||
|
this.validate = function (parameters) {
|
|||
|
const errors = []
|
|||
|
requiredOptions.forEach(function (requiredOptionName) {
|
|||
|
if (typeof parameters[requiredOptionName] === 'undefined') {
|
|||
|
errors.push(requiredOptionName)
|
|||
|
}
|
|||
|
})
|
|||
|
return errors
|
|||
|
}
|
|||
|
|
|||
|
function validateParams (params) {
|
|||
|
if (!params) {
|
|||
|
return false
|
|||
|
}
|
|||
|
return typeof params.required !== 'undefined' && params.required instanceof Array
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
'use strict'
|
|||
|
|
|||
|
var _$utils_9 = {
|
|||
|
merge: merge,
|
|||
|
isJSON: isJSON
|
|||
|
}
|
|||
|
|
|||
|
function merge (defaultParams, mergeParams) {
|
|||
|
const mergedOptions = {}
|
|||
|
for (const option in defaultParams) {
|
|||
|
mergedOptions[option] = defaultParams[option]
|
|||
|
if (typeof mergeParams[option] !== 'undefined') {
|
|||
|
mergedOptions[option] = mergeParams[option]
|
|||
|
}
|
|||
|
}
|
|||
|
return mergedOptions
|
|||
|
}
|
|||
|
|
|||
|
function isJSON (json) {
|
|||
|
try {
|
|||
|
if (json instanceof Object && JSON.parse(JSON.stringify(json))) {
|
|||
|
return true
|
|||
|
}
|
|||
|
return false
|
|||
|
} catch (err) {
|
|||
|
return false
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
var _$src_8 = {};
|
|||
|
(function (window) {
|
|||
|
'use strict'
|
|||
|
|
|||
|
let options = {
|
|||
|
searchInput: null,
|
|||
|
resultsContainer: null,
|
|||
|
json: [],
|
|||
|
success: Function.prototype,
|
|||
|
searchResultTemplate: '<li><a href="{url}" title="{desc}">{title}</a></li>',
|
|||
|
templateMiddleware: Function.prototype,
|
|||
|
sortMiddleware: function () {
|
|||
|
return 0
|
|||
|
},
|
|||
|
noResultsText: 'No results found',
|
|||
|
limit: 10,
|
|||
|
fuzzy: false,
|
|||
|
debounceTime: null,
|
|||
|
exclude: []
|
|||
|
}
|
|||
|
|
|||
|
let debounceTimerHandle
|
|||
|
const debounce = function (func, delayMillis) {
|
|||
|
if (delayMillis) {
|
|||
|
clearTimeout(debounceTimerHandle)
|
|||
|
debounceTimerHandle = setTimeout(func, delayMillis)
|
|||
|
} else {
|
|||
|
func.call()
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
const requiredOptions = ['searchInput', 'resultsContainer', 'json']
|
|||
|
|
|||
|
/* removed: const _$Templater_7 = require('./Templater') */;
|
|||
|
/* removed: const _$Repository_4 = require('./Repository') */;
|
|||
|
/* removed: const _$JSONLoader_2 = require('./JSONLoader') */;
|
|||
|
const optionsValidator = _$OptionsValidator_3({
|
|||
|
required: requiredOptions
|
|||
|
})
|
|||
|
/* removed: const _$utils_9 = require('./utils') */;
|
|||
|
|
|||
|
window.SimpleJekyllSearch = function (_options) {
|
|||
|
const errors = optionsValidator.validate(_options)
|
|||
|
if (errors.length > 0) {
|
|||
|
throwError('You must specify the following required options: ' + requiredOptions)
|
|||
|
}
|
|||
|
|
|||
|
options = _$utils_9.merge(options, _options)
|
|||
|
|
|||
|
_$Templater_7.setOptions({
|
|||
|
template: options.searchResultTemplate,
|
|||
|
middleware: options.templateMiddleware
|
|||
|
})
|
|||
|
|
|||
|
_$Repository_4.setOptions({
|
|||
|
fuzzy: options.fuzzy,
|
|||
|
limit: options.limit,
|
|||
|
sort: options.sortMiddleware,
|
|||
|
exclude: options.exclude
|
|||
|
})
|
|||
|
|
|||
|
if (_$utils_9.isJSON(options.json)) {
|
|||
|
initWithJSON(options.json)
|
|||
|
} else {
|
|||
|
initWithURL(options.json)
|
|||
|
}
|
|||
|
|
|||
|
const rv = {
|
|||
|
search: search
|
|||
|
}
|
|||
|
|
|||
|
typeof options.success === 'function' && options.success.call(rv)
|
|||
|
return rv
|
|||
|
}
|
|||
|
|
|||
|
function initWithJSON (json) {
|
|||
|
_$Repository_4.put(json)
|
|||
|
registerInput()
|
|||
|
}
|
|||
|
|
|||
|
function initWithURL (url) {
|
|||
|
_$JSONLoader_2.load(url, function (err, json) {
|
|||
|
if (err) {
|
|||
|
throwError('failed to get JSON (' + url + ')')
|
|||
|
}
|
|||
|
initWithJSON(json)
|
|||
|
})
|
|||
|
}
|
|||
|
|
|||
|
function emptyResultsContainer () {
|
|||
|
options.resultsContainer.innerHTML = ''
|
|||
|
}
|
|||
|
|
|||
|
function appendToResultsContainer (text) {
|
|||
|
options.resultsContainer.innerHTML += text
|
|||
|
}
|
|||
|
|
|||
|
function registerInput () {
|
|||
|
options.searchInput.addEventListener('input', function (e) {
|
|||
|
if (isWhitelistedKey(e.which)) {
|
|||
|
emptyResultsContainer()
|
|||
|
debounce(function () { search(e.target.value) }, options.debounceTime)
|
|||
|
}
|
|||
|
})
|
|||
|
}
|
|||
|
|
|||
|
function search (query) {
|
|||
|
if (isValidQuery(query)) {
|
|||
|
emptyResultsContainer()
|
|||
|
render(_$Repository_4.search(query), query)
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function render (results, query) {
|
|||
|
const len = results.length
|
|||
|
if (len === 0) {
|
|||
|
return appendToResultsContainer(options.noResultsText)
|
|||
|
}
|
|||
|
for (let i = 0; i < len; i++) {
|
|||
|
results[i].query = query
|
|||
|
appendToResultsContainer(_$Templater_7.compile(results[i]))
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function isValidQuery (query) {
|
|||
|
return query && query.length > 0
|
|||
|
}
|
|||
|
|
|||
|
function isWhitelistedKey (key) {
|
|||
|
return [13, 16, 20, 37, 38, 39, 40, 91].indexOf(key) === -1
|
|||
|
}
|
|||
|
|
|||
|
function throwError (message) {
|
|||
|
throw new Error('SimpleJekyllSearch --- ' + message)
|
|||
|
}
|
|||
|
})(window)
|
|||
|
|
|||
|
}());
|
|||
|
</script>
|
|||
|
|
|||
|
<!-- Configuration -->
|
|||
|
<script>
|
|||
|
SimpleJekyllSearch({
|
|||
|
searchInput: document.getElementById('search-input'),
|
|||
|
resultsContainer: document.getElementById('results-container'),
|
|||
|
json: '/search.json',
|
|||
|
//searchResultTemplate: '<li><a href="https://static.rnmkcy.eu{url}">{date} {title}</a></li>'
|
|||
|
searchResultTemplate: '<li><a href="{url}">{date} {title}</a></li>'
|
|||
|
})
|
|||
|
</script>
|
|||
|
<!-- Fin déclaration champ de recherche --></div><nav class="navigation">
|
|||
|
<ul><li class="navigation__item"><a href="/archive.html">Etiquettes</a></li><li class="navigation__item"><a href="/htmldoc.html">Documents</a></li><li class="navigation__item"><a href="/liens_ttrss.html">Liens</a></li><li class="navigation__item"><a href="/aide-jekyll-text-theme.html">Aide</a></li></ul>
|
|||
|
</nav></div>
|
|||
|
</header>
|
|||
|
|
|||
|
</div><div class="page__content"><div class ="main"><div class="grid grid--reverse">
|
|||
|
<div class="col-main cell cell--auto"><!-- start custom main top snippet --><div id="results-container" class="search-result js-search-result"></div><!-- end custom main top snippet -->
|
|||
|
<article itemscope itemtype="http://schema.org/Article"><div class="article__header"><header><h1 style="color:Tomato;">VPN Surfshark</h1></header></div><meta itemprop="headline" content="VPN Surfshark"><div class="article__info clearfix"><ul class="left-col menu"><li>
|
|||
|
<a class="button button--secondary button--pill button--sm"
|
|||
|
href="/archive.html?tag=vpn">vpn</a>
|
|||
|
</li></ul><ul class="right-col menu"><li>
|
|||
|
<i class="far fa-calendar-alt"></i> <span title="Création" style="color:#FF00FF">17 août 2020</span>
|
|||
|
|
|||
|
<span title="Modification" style="color:#00FF7F">16 févr. 2021</span></li></ul></div><meta itemprop="datePublished" content="2021-02-16T00:00:00+01:00">
|
|||
|
<meta itemprop="keywords" content="vpn"><div class="js-article-content">
|
|||
|
<div class="layout--article"><!-- start custom article top snippet -->
|
|||
|
<style>
|
|||
|
#myBtn {
|
|||
|
display: none;
|
|||
|
position: fixed;
|
|||
|
bottom: 10px;
|
|||
|
right: 10px;
|
|||
|
z-index: 99;
|
|||
|
font-size: 12px;
|
|||
|
font-weight: bold;
|
|||
|
border: none;
|
|||
|
outline: none;
|
|||
|
background-color: white;
|
|||
|
color: black;
|
|||
|
cursor: pointer;
|
|||
|
padding: 5px;
|
|||
|
border-radius: 4px;
|
|||
|
}
|
|||
|
|
|||
|
#myBtn:hover {
|
|||
|
background-color: #555;
|
|||
|
}
|
|||
|
</style>
|
|||
|
|
|||
|
<button onclick="topFunction()" id="myBtn" title="Haut de page">⇧</button>
|
|||
|
|
|||
|
<script>
|
|||
|
//Get the button
|
|||
|
var mybutton = document.getElementById("myBtn");
|
|||
|
|
|||
|
// When the user scrolls down 20px from the top of the document, show the button
|
|||
|
window.onscroll = function() {scrollFunction()};
|
|||
|
|
|||
|
function scrollFunction() {
|
|||
|
if (document.body.scrollTop > 20 || document.documentElement.scrollTop > 20) {
|
|||
|
mybutton.style.display = "block";
|
|||
|
} else {
|
|||
|
mybutton.style.display = "none";
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// When the user clicks on the button, scroll to the top of the document
|
|||
|
function topFunction() {
|
|||
|
document.body.scrollTop = 0;
|
|||
|
document.documentElement.scrollTop = 0;
|
|||
|
}
|
|||
|
</script>
|
|||
|
|
|||
|
|
|||
|
<!-- end custom article top snippet -->
|
|||
|
<div class="article__content" itemprop="articleBody"><details>
|
|||
|
<summary><b>Afficher/cacher Sommaire</b></summary>
|
|||
|
<!-- affichage sommaire -->
|
|||
|
<div class="toc-aside js-toc-root"></div>
|
|||
|
</details><p><img src="/images/surfshark.svg" alt="Surfshark" /><br />
|
|||
|
<a href="https://surfshark.com/fr/">VPN Surfshark</a>, offre du 17 août 2020 : <strong>1.69€/mois</strong> → 40.56€ HT tous les 24 mois (48.67€ TTC)<br />
|
|||
|
<img src="/images/surfshark002.png" alt="Surfshark" width="200" /></p>
|
|||
|
|
|||
|
<h2 id="surfshark">Surfshark</h2>
|
|||
|
|
|||
|
<p><em>Comment configurer le module complémentaire du navigateur Surfshark sur Firefox ?</em></p>
|
|||
|
|
|||
|
<p>Installer et utiliser le module complémentaire VPN de <strong>Surfshark</strong> pour les navigateurs <strong>Firefox</strong>.</p>
|
|||
|
|
|||
|
<p>Il s’agit d’un moyen rapide et pratique d’utiliser <strong>Surfshark VPN</strong> sans avoir à installer l’application de bureau.<br />
|
|||
|
Il convient de mentionner que le module complémentaire pour navigateur Surfshark ne couvre que le trafic du navigateur.<br />
|
|||
|
En d’autres termes, les autres navigateurs et applications en dehors de Firefox utiliseront votre connexion réseau habituelle.</p>
|
|||
|
|
|||
|
<p>Pour suivre les instructions, vous aurez besoin d’un ordinateur équipé d’un navigateur Mozilla Firefox et d’un abonnement VPN Surfshark actif.</p>
|
|||
|
|
|||
|
<h2 id="surfshark-firefox">Surfshark Firefox</h2>
|
|||
|
|
|||
|
<p>Pour commencer, trouvez l’extension Surfshark sur le magasin d’extensions de Firefox. Vous le trouverez <a href="https://surfshark.com/fr/download/firefox">ici</a>.</p>
|
|||
|
|
|||
|
<p>Cliquez sur Add to Firefox.<br />
|
|||
|
<img src="/images/surfshark001.png" alt="" width="400" /></p>
|
|||
|
|
|||
|
<p>Une fenêtre pop-up vous demandera de confirmer l’installation.</p>
|
|||
|
|
|||
|
<p>Cliquez sur Ajouter.<br />
|
|||
|
<img src="/images/click_add.png" alt="" width="300" /></p>
|
|||
|
|
|||
|
<p>Le logo Surfshark apparaîtra désormais sur votre barre d’outils dans le coin supérieur droit de votre navigateur.<br />
|
|||
|
<img src="/images/installedff.png" alt="" width="300" /></p>
|
|||
|
|
|||
|
<h3 id="connectez-vous-à-ladd-on">Connectez-vous à l’add-on</h3>
|
|||
|
|
|||
|
<p>Cliquez sur l’icône Surfshark en haut à droite de votre navigateur.<br />
|
|||
|
<img src="/images/loginsurfshark.png" alt="" height="300" /></p>
|
|||
|
|
|||
|
<p>Saisissez l’adresse électronique que vous avez utilisée lors de votre inscription et votre mot de passe. Cliquez sur Connexion.<br />
|
|||
|
<img src="/images/loginsurfshark1.png" alt="" height="300" /></p>
|
|||
|
|
|||
|
<h3 id="se-connecter-à-un-vpn">Se connecter à un VPN</h3>
|
|||
|
|
|||
|
<p>Juste après vous être connecté, vous verrez la page d’accueil du module complémentaire du navigateur Surfshark. Elle indique l’état de la connexion, les emplacements récemment utilisés et le bouton “Connexion rapide”(Quick connect).</p>
|
|||
|
|
|||
|
<p>Appuyez sur le bouton <strong>Connexion rapide</strong> et le module complémentaire Surfshark se connectera instantanément au serveur le plus rapide disponible.</p>
|
|||
|
|
|||
|
<p><img src="/images/Screenshot_1.png" alt="" height="300" /></p>
|
|||
|
|
|||
|
<p>Dès que vous vous connectez, le statut de la connexion passe à CONNECTÉ (CONNECTED).<br />
|
|||
|
Vous pouvez vous déconnecter rapidement en appuyant sur le bouton Déconnecter.</p>
|
|||
|
|
|||
|
<p><img src="/images/connected.png" alt="" height="300" /></p>
|
|||
|
|
|||
|
<h3 id="choisir-et-gérer-les-lieux">Choisir et gérer les lieux</h3>
|
|||
|
|
|||
|
<p>Plus de 1700 serveurs dans plus de 63 pays sont disponibles sur Surfshark. Vous pouvez vous connecter à l’endroit de votre choix.</p>
|
|||
|
|
|||
|
<p>Allez dans l’onglet <strong>“Positions”</strong> (Locations) de votre module complémentaire Surfshark.<br />
|
|||
|
<img src="/images/choose_country.png" alt="" height="300" /></p>
|
|||
|
|
|||
|
<p>Utilisez la barre de recherche en haut ou faites simplement défiler la liste jusqu’à ce que vous trouviez votre pays préféré.</p>
|
|||
|
|
|||
|
<p>Il y a plusieurs lieux disponibles dans certains pays. Vous trouverez la liste complète des lieux dans un pays spécifique en cliquant sur l’icône du drapeau du pays choisi.<br />
|
|||
|
<img src="/images/choose_location_gif.gif" alt="" height="300" /></p>
|
|||
|
|
|||
|
<p>Cliquez sur l’icône du drapeau et le module complémentaire se connectera instantanément à l’endroit que vous avez choisi.</p>
|
|||
|
|
|||
|
<h3 id="gérer-les-fonctionnalités-et-les-paramètres">Gérer les fonctionnalités et les paramètres</h3>
|
|||
|
|
|||
|
<p>Le troisième onglet concerne <strong>“CleanWeb”</strong>, une fonction intelligente qui bloque les publicités et les sites malveillants avant qu’ils ne puissent vous nuire. Utilisez le bouton de basculement pour activer cette fonction.<br />
|
|||
|
<img src="/images/cleanweb.png" alt="" height="300" /></p>
|
|||
|
|
|||
|
<p>Le dernier onglet est celui des <strong>Réglages</strong>(Settings).</p>
|
|||
|
|
|||
|
<p>Vous pouvez y trouver les détails de votre abonnement, modifier le mot de passe ou définir votre langue préférée pour l’extension. Cliquez sur Aide pour trouver les réponses aux questions les plus courantes ou contactez l’équipe d’assistance de Surfshark.<br />
|
|||
|
<img src="/images/settings.png" alt="" height="300" /></p>
|
|||
|
|
|||
|
<blockquote>
|
|||
|
<p>Vous avez installé et configuré avec succès votre module complémentaire <strong>VPN Surfshark</strong> !<br />
|
|||
|
Désormais, votre emplacement est privé et vos données sensibles sont sécurisées, tant que vous êtes connecté.</p>
|
|||
|
</blockquote>
|
|||
|
|
|||
|
<p>Si vous avez d’autres questions, notre équipe chargée de la réussite des clients est là pour vous aider 24 heures sur 24, 7 jours sur 7, par le biais d’un chat en direct ou d’un e-mail.</p>
|
|||
|
|
|||
|
<h2 id="surfshark-android">Surfshark Android</h2>
|
|||
|
|
|||
|
<p><em>avoir un appareil Android fonctionnant sous OS 5.0 ou supérieur et un abonnement actif à Surfshark</em></p>
|
|||
|
|
|||
|
<p>Pour cela, il vous suffit d’avoir un appareil Android fonctionnant sous OS 5.0 ou plus récent et un abonnement actif à Surfshark. Pas encore d’abonnement ? Pas de soucis, vous pouvez l’obtenir ici.</p>
|
|||
|
|
|||
|
<h3 id="installer-lapplication-surfshark">Installer l’application Surfshark</h3>
|
|||
|
|
|||
|
<p>Option A : Télécharger l’application depuis le site et installation <code class="language-plaintext highlighter-rouge">adb install Surfshark.apk</code></p>
|
|||
|
|
|||
|
<p>Option B : Commencez par trouver l’application <strong>Play Store</strong> sur votre appareil et ouvrez-la.
|
|||
|
Tapez Surfshark dans la barre de recherche et choisissez le premier résultat qui apparaît dans la liste.<br />
|
|||
|
La page de l’application VPN Surfshark s’ouvrira. Cliquez sur Télécharger ou Installer et l’installation sera terminée dans quelques instants.</p>
|
|||
|
|
|||
|
<h3 id="connectez-vous-à-lapplication">Connectez-vous à l’application</h3>
|
|||
|
|
|||
|
<p>Une fois l’installation terminée, recherchez l’application</p>
|
|||
|
|
|||
|
<p><img src="/images/surfshark010.png" alt="Surfshark Android" height="400" /></p>
|
|||
|
|
|||
|
<p>Ouvrez l’application.</p>
|
|||
|
|
|||
|
<p><img src="/images/surfshark011.png" alt="Surfshark Android" height="400" /></p>
|
|||
|
|
|||
|
<ul>
|
|||
|
<li>Si vous avez déjà acheté votre abonnement VPN Surfshark, connectez-vous en tant qu’<strong>utilisateur existant</strong>.</li>
|
|||
|
<li>Si vous n’avez pas encore d’abonnement, n’hésitez pas à vous inscrire pour un essai gratuit de 7 jours.</li>
|
|||
|
</ul>
|
|||
|
|
|||
|
<p>Connectez-vous ou démarrez une période d’essai gratuite.<br />
|
|||
|
Saisissez l’adresse électronique que vous avez utilisée lors de votre inscription et votre mot de passe.<br />
|
|||
|
<img src="/images/surfshark012.png" alt="Surfshark Android" height="400" /><br />
|
|||
|
Cliquez sur Connexion.</p>
|
|||
|
|
|||
|
<h3 id="se-connecter-à-un-vpn-1">Se connecter à un VPN</h3>
|
|||
|
|
|||
|
<p>Dès que vous vous connectez, vous verrez la page d’accueil de votre application Surfshark. Elle indique l’état de la connexion VPN.</p>
|
|||
|
|
|||
|
<p>Il ne vous reste plus qu’à vous connecter aux serveurs de Surfshark. Cliquez sur le bouton bleu “CONNECTER” et votre application se connectera au serveur le plus rapide disponible.<br />
|
|||
|
<img src="/images/surfshark013.png" alt="Surfshark Android" height="400" /> <br />
|
|||
|
Vous pouvez régler votre connexion VPN par défaut sur le serveur le plus rapide ou sur le pays le plus proche. Pour ce faire, cliquez sur le bouton comme dans l’image ci-dessous.</p>
|
|||
|
|
|||
|
<p><img src="/images/surfshark014.png" alt="Surfshark Android" height="400" /> <br />
|
|||
|
Cliquez sur ce bouton pour modifier votre emplacement par défaut.</p>
|
|||
|
|
|||
|
<p><img src="/images/surfshark015.png" alt="Surfshark Android" height="400" /> <br />
|
|||
|
Choisissez <strong>serveur le plus rapide</strong> ou le <strong>pays le plus proche</strong></p>
|
|||
|
|
|||
|
<p>Une fois que vous aurez cliqué sur le bouton de connexion, il vous sera demandé d’autoriser Surfshark VPN à établir une connexion VPN.<br />
|
|||
|
Cela est nécessaire pour que Surfshark puisse créer et gérer le tunnel VPN.<br />
|
|||
|
<img src="/images/surfshark016.png" alt="Surfshark Android" height="400" /> <br />
|
|||
|
Cliquez sur OK.</p>
|
|||
|
|
|||
|
<p>Lorsque votre application se connecte avec succès à un VPN, vous verrez l’état de la connexion sur l’écran principal.<br />
|
|||
|
<img src="/images/surfshark017.png" alt="Surfshark Android" height="400" /> <br />
|
|||
|
Vous pouvez également remarquer un logo Surfshark et l’icône d’une clé en haut de votre écran. Cela indique que vous êtes toujours connecté au VPN Surfshark.<br />
|
|||
|
Pour vous déconnecter du VPN, cliquez sur le bouton <strong>Se Déconnecter</strong>.</p>
|
|||
|
|
|||
|
<p>Appuyez sur la flèche blanche de la barre d’état verte pour obtenir des informations détaillées sur votre connexion VPN.<br />
|
|||
|
Vous pouvez y voir votre nouvelle adresse IP, la quantité de données transférées en toute sécurité et une option permettant d’activer la fonction <strong>Kill Switch</strong>.<br />
|
|||
|
<img src="/images/surfshark018.png" alt="Surfshark Android" height="400" /></p>
|
|||
|
|
|||
|
<h3 id="choisir-et-gérer-les-lieux-1">Choisir et gérer les lieux</h3>
|
|||
|
|
|||
|
<p>Vous souhaitez vous connecter à un lieu spécifique ? Surfshark dispose de plus de 1700 serveurs dans plus de 60 pays, et vous pouvez vous connecter à n’importe lequel d’entre eux.</p>
|
|||
|
|
|||
|
<p>Rendez-vous dans la section <strong>Positions</strong> de votre application Surfshark et choisissez n’importe quel lieu.</p>
|
|||
|
|
|||
|
<p><img src="/images/surfshark019.png" alt="Surfshark Android" height="400" /></p>
|
|||
|
|
|||
|
<p>Appuyez sur l’icône du drapeau de votre pays préféré et l’application se connectera instantanément à cet endroit.</p>
|
|||
|
|
|||
|
<p>L’icône en forme de bulle à côté de l’étoile indique le niveau de charge des serveurs Surfshark dans un endroit spécifique, en d’autres termes, combien de personnes sont connectées aux serveurs dans cet endroit.</p>
|
|||
|
|
|||
|
<p>La première bulle sur cette image indique que les serveurs de Surfshark en France sont plus sollicités que ceux de la deuxième bulle Grèce<br />
|
|||
|
<img src="/images/surfshark020.png" alt="Surfshark Android" height="400" /></p>
|
|||
|
|
|||
|
<p>Vous avez peut-être remarqué les onglets <strong>STATIQUE</strong> et <strong>MULTIHOP</strong> en haut de votre application Surfshark.<br />
|
|||
|
<img src="/images/surfshark021.png" alt="Surfshark Android" height="90" /> <br />
|
|||
|
<strong>IP STATIQUE</strong> - vous obtenez la même adresse IP chaque fois que vous vous connectez<br />
|
|||
|
<strong>MULTIHOP</strong> - vous vous connecterez via deux serveurs VPN différents dans des pays différents et ajouterez une couche de sécurité supplémentaire</p>
|
|||
|
|
|||
|
<p>Si vous voulez que Surfshark se souvienne de vos endroits préférés, appuyez sur l’étoile sur le côté droit. Ce serveur apparaîtra alors dans la liste de vos serveurs préférés.</p>
|
|||
|
|
|||
|
<p><img src="/images/surfshark022.png" alt="Surfshark Android" height="400" /></p>
|
|||
|
|
|||
|
<h3 id="gérer-les-fonctionnalités-de-surfshark">Gérer les fonctionnalités de Surfshark</h3>
|
|||
|
|
|||
|
<p>Ouvrez la section <strong>“Caractéristiques”</strong> dans votre application Surfshark. Vous y trouverez 4 fonctionnalités :</p>
|
|||
|
|
|||
|
<p><strong>CleanWeb</strong> - c’est une fonctionnalité intelligente qui bloque les publicités et les sites malveillants sur le web. Pour en savoir plus, cliquez ici.</p>
|
|||
|
|
|||
|
<p><strong>Whitelister</strong> - il vous permet de choisir les applications ou les sites web à exclure de la connexion via le tunnel VPN, et vice versa - ceux à faire passer par celui-ci. Pour savoir comment l’utiliser, cliquez ici.</p>
|
|||
|
|
|||
|
<p><strong>HackLock</strong> - envoie des alertes en temps réel lorsque vos e-mails et mots de passe risquent d’être piratés. Apprenez comment l’utiliser ici.</p>
|
|||
|
|
|||
|
<p><strong>BlindSearch</strong> - un outil de navigation qui vous permet d’effectuer des recherches sur le web en toute confidentialité, sans publicité, sans journal, sans historique et sans traqueur. Apprenez à l’utiliser ici.</p>
|
|||
|
|
|||
|
<p><img src="/images/surfshark023.png" alt="Surfshark Android" height="400" /></p>
|
|||
|
|
|||
|
<h3 id="gérer-les-paramètres-de-surfshark">Gérer les paramètres de Surfshark</h3>
|
|||
|
|
|||
|
<p>Vous pouvez adapter votre application Surfshark à vos préférences personnelles. Vous pouvez trouver tous les paramètres nécessaires qui vous permettent de personnaliser et de dépanner votre connexion VPN.</p>
|
|||
|
|
|||
|
<p>Ouvrez la page des <strong>paramètres</strong> de l’application Surfshark.<br />
|
|||
|
<img src="/images/surfshark024.png" alt="Surfshark Android" height="400" /></p>
|
|||
|
|
|||
|
<p>Dans l’onglet <strong>Application</strong>, vous pouvez voir la version de votre application Surfshark, changer la langue de l’application et activer et désactiver le mode Dark. <br />
|
|||
|
<img src="/images/surfshark025.png" alt="Surfshark Android" height="200" /></p>
|
|||
|
|
|||
|
<p>Allez à l’onglet <strong>Connectivité</strong> pour activer et définir les préférences de la connexion automatique. Vous pouvez choisir sur quels réseaux Surfhsark doit se connecter automatiquement à un VPN. Vous pouvez également y activer et désactiver la fonction KillSwitch. KillSwitch est une fonction de sécurité qui vous déconnectera d’internet si la connexion VPN tombe inopinément.<br />
|
|||
|
<img src="/images/surfshark026.png" alt="Surfshark Android" height="250" /></p>
|
|||
|
|
|||
|
<p>Dans l’onglet <strong>Rapports</strong>, vous pouvez décider si vous souhaitez fournir à nos développeurs des données anonymes sur les performances techniques de votre application Surfshark et les aider à l’améliorer plus efficacement.<br />
|
|||
|
<img src="/images/surfshark027.png" alt="Surfshark Android" height="170" /></p>
|
|||
|
|
|||
|
<p>L’onglet <strong>Paramètres avancés</strong> est l’endroit où vous pouvez dépanner et ajuster les performances de Surfshark VPN. Vous pouvez le trouver ici :</p>
|
|||
|
|
|||
|
<p><strong>Cryptage des données</strong> - déterminez si vous souhaitez utiliser un cryptage plus ou moins lourd pour protéger vos données. Un cryptage plus léger (ChaCha20Poly1305) devrait permettre d’obtenir une meilleure vitesse.</p>
|
|||
|
|
|||
|
<p><strong>Protocole</strong> - choisissez le protocole que vous souhaitez utiliser pour vous connecter au VPN. En savoir plus sur ce qu’est un protocole et sur les différences entre les protocoles.</p>
|
|||
|
|
|||
|
<p>**Mode “NoBorders” **- il permet de contourner les restrictions de l’internet dans les pays où une forte censure est en place.</p>
|
|||
|
|
|||
|
<p>**Override GPS location **- une fonction unique à Surfshark qui vous permet de faire correspondre votre position GPS à l’emplacement de votre connexion VPN. Pour en savoir plus, cliquez ici.</p>
|
|||
|
|
|||
|
<p><strong>Invisible pour les appareils</strong> - activez cette fonction si vous souhaitez que votre appareil soit invisible pour les autres appareils du même réseau.</p>
|
|||
|
|
|||
|
<p><strong>Utilisez de petits paquets</strong> - allumez-le et vos données seront transférées en plus petits morceaux. Cela peut se traduire par une meilleure vitesse de connexion.</p>
|
|||
|
|
|||
|
<p>L’onglet Gagner des mois gratuits vous permet d’obtenir des mois gratuits de Surfshark en le recommandant à vos amis ou à toute personne que vous connaissez. Ouvrez-le pour obtenir un lien unique vous permettant de partager ou d’en savoir plus sur les récompenses. En savoir plus sur la façon de rejoindre le programme de parrainage de Surfshark.</p>
|
|||
|
|
|||
|
<p>Passez à l’onglet <strong>COMPTE</strong>.<br />
|
|||
|
<img src="/images/surfshark028.png" alt="Surfshark Android" height="400" /><br />
|
|||
|
Vous trouverez ici les détails de votre abonnement, une option pour changer le mot de passe et un identifiant de télévision qui vous aidera à vous connecter facilement à l’application Surfshark sur votre télévision.</p>
|
|||
|
|
|||
|
<p>Le dernier onglet est destiné à l’<strong>AIDE</strong>.<br />
|
|||
|
<img src="/images/surfshark029.png" alt="Surfshark Android" height="400" /><br />
|
|||
|
Dans cet onglet, vous pouvez gérer vos précédentes interactions avec les agents de support de Surfshark, nous fournir des diagnostics à partir de votre application Surfhark si quelque chose ne fonctionne pas correctement, et consulter les conditions d’utilisation de Surfshark et notre politique de confidentialité.</p>
|
|||
|
|
|||
|
<h2 id="application-surfshark-linux">Application Surfshark Linux</h2>
|
|||
|
|
|||
|
<p><strong>Via paquet AUR</strong><br />
|
|||
|
<a href="https://support.surfshark.com/hc/en-us/articles/360017418334#h_0e104abc-1b39-447b-b32f-5414752ebf74">How to set up Surfshark VPN on Debian/Ubuntu Linux?</a></p>
|
|||
|
|
|||
|
<p>Archlinux</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yay -S surfshark-vpn
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p><strong>Se connecter au VPN</strong></p>
|
|||
|
|
|||
|
<p>Pour lancer le VPN Surfshark, tapez cette commande dans le Terminal :</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo surfshark-vpn # entrer le mot de passe de l'utilisateur root de votre ordinateur, ceci est nécessaire pour que Surfshark puisse créer et gérer le tunnel VPN.
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p><em>Surfshark aimerait envoyer des rapports d’erreur aux serveurs de Surfshark afin d’améliorer notre service et l’expérience des utilisateurs. Pour désactiver les rapports d’erreur, saisissez le mot (“NO”) et appuyez sur la touche ENTRÉE.</em></p>
|
|||
|
|
|||
|
<p><img src="/images/surfshark100.png" alt="surfshark-vpn" /><br />
|
|||
|
Ensuite, saisissez l’adresse électronique que vous avez utilisée lors de votre inscription et cliquez sur “Entrée”. Ensuite, saisissez votre mot de passe et appuyez à nouveau sur Entrée.</p>
|
|||
|
|
|||
|
<p>Vous trouverez la liste complète des sites de Surfshark. Un numéro identifie chaque emplacement.<br />
|
|||
|
<img src="/images/surfshark101.png" alt="surfshark-vpn" /> <img src="/images/surfshark102.png" alt="surfshark-vpn" /> <img src="/images/surfshark103.png" alt="surfshark-vpn" /><br />
|
|||
|
<img src="/images/surfshark104.png" alt="surfshark-vpn" /> <img src="/images/surfshark105.png" alt="surfshark-vpn" /><br />
|
|||
|
Pour sélectionner un lieu, tapez le numéro à côté de celui-ci sur le terminal et appuyez sur la touche Entrée.<br />
|
|||
|
<img src="/images/surfshark106.png" alt="surfshark-vpn" /></p>
|
|||
|
|
|||
|
<p>Surfshark pour Linux utilise le protocole OpenVPN. Vous pouvez choisir entre deux options : UDP et TCP. Nous recommandons UDP pour de meilleures vitesses et il est suggéré par défaut, vous pouvez donc continuer en appuyant sur Entrée.</p>
|
|||
|
|
|||
|
<p><img src="/images/surfshark107.png" alt="surfshark-vpn" /></p>
|
|||
|
|
|||
|
<p>Succès, vous êtes maintenant connectés ! Vous pouvez voir l’état de la connexion et votre nouvelle adresse IP.</p>
|
|||
|
|
|||
|
<p><img src="/images/surfshark108.png" alt="surfshark-vpn" /></p>
|
|||
|
|
|||
|
<p>Vous pouvez maintenant fermer le terminal ou le réduire au minimum. Il n’est pas nécessaire qu’il soit ouvert pour que Surfshark fonctionne en arrière-plan.</p>
|
|||
|
|
|||
|
<p>Pour vous déconnecter, ouvrez le terminal et entrez cette commande :</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo surfshark-vpn down
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Les commandes qui vous permettront de contrôler votre client Surfshark :</p>
|
|||
|
|
|||
|
<p>Utilisez cette commande pour imprimer toutes les commandes de Surfshark dans le terminal :</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo surfshark-vpn help
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Vérifiez votre état de connectivité :</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo surfshark-vpn status
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Déconnectez-vous du VPN de Surfshark :</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo surfshark-vpn down
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Connexion rapide à votre emplacement Optimal :</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo surfshark-vpn attack
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Pour se déconnecter du client :</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo surfshark-vpn forget
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Pour se connecter à un site MultiHop :</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo surfshark-vpn multi
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Pour désinstaller Surfshark :</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo apt-get remove surfshark-vpn
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h2 id="openvpn-surfshark">OpenVPN Surfshark</h2>
|
|||
|
|
|||
|
<p><a href="https://support.surfshark.com/hc/en-us/articles/360011051133-How-to-set-up-OpenVPN-using-Linux-Terminal">How to set up manual OpenVPN connection using Linux Terminal?</a></p>
|
|||
|
|
|||
|
<p><strong>Comment établir une connexion OpenVPN manuelle à l’aide d’un terminal Linux ?</strong></p>
|
|||
|
|
|||
|
<p>Dans ce tutoriel, vous apprendrez comment établir une connexion OpenVPN sur votre appareil Linux. Il s’agit d’une autre façon de se connecter aux serveurs Surfshark qui s’avérera pratique si l’application VPN Surfshark ne peut pas être installée sur votre appareil ou si elle ne fonctionne pas comme prévu.<br />
|
|||
|
Vous aurez besoin d’un appareil fonctionnant avec le système d’exploitation Linux et d’un abonnement Surfshark actif.</p>
|
|||
|
|
|||
|
<p><strong>les paramètres</strong><br />
|
|||
|
Vous aurez besoin des identifiants du service Surfshark pour vous connecter au VPN en utilisant une connexion manuelle OpenVPN. Ne les confondez pas avec vos identifiants habituels, à savoir votre adresse électronique et votre mot de passe.</p>
|
|||
|
|
|||
|
<p>Voici comment vous pouvez obtenir les identifiants du service Surfshark :</p>
|
|||
|
|
|||
|
<ol>
|
|||
|
<li>Allez sur <a href="https://my.surfshark.com/vpn/manual-setup/main">cette page</a> où sont stockées toutes les informations nécessaires pour une connexion manuelle.<br />
|
|||
|
Vous devrez peut-être vous connecter avant de passer à cette page. Dans ce cas, saisissez votre adresse électronique et votre mot de passe, puis cliquez sur Connexion.</li>
|
|||
|
<li>Cliquez sur l’onglet “Identifiants”. Vous y trouverez les références du service Surfshark.<br />
|
|||
|
<img src="/images/surfshark120.png" alt="surfshark" width="400" /><br />
|
|||
|
Il est conseillé de garder cette page ouverte pour l’instant. Vous en aurez besoin un peu plus tard.</li>
|
|||
|
</ol>
|
|||
|
|
|||
|
<p><strong>Installer le paquet OpenVPN</strong><br />
|
|||
|
Ouvrez la fenêtre du terminal.Vous pouvez le faire en appuyant sur les touches Ctrl+Alt+T ou en y accédant dans le menu de vos applications. <br />
|
|||
|
Entrez la commande suivante pour installer tous les paquets nécessaires :</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo apt-get install openvpn unzip # debian/ubuntu
|
|||
|
sudo pacman -S openvpn unzip # archlinux/manjaro
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p><em>Vous devrez peut-être entrer le mot de passe de votre ordinateur pour confirmer ce processus. Dans ce cas, entrez le mot de passe et appuyez sur la touche Entrée.</em></p>
|
|||
|
|
|||
|
<p><img src="/images/surfshark121.png" alt="surfshark" width="400" /></p>
|
|||
|
|
|||
|
<p><strong>Télécharger les fichiers de configuration surfshark</strong></p>
|
|||
|
|
|||
|
<p>En mode su</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -s
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Naviguez vers le répertoire OpenVPN. Vous pouvez le faire en entrant cette commande :</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cd /etc/openvpn/client
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Téléchargez la configuration de Surfshark OpenVPN en entrant la commande suivante :</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>wget https://my.surfshark.com/vpn/api/v1/server/configurations
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Décompresser le fichier configurations.zip en entrant cette commande :</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>unzip configurations
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Entrez la commande suivante pour voir la liste de tous les serveurs disponibles :</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ls
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>es-bcn.prod.surfshark.com_tcp.ovpn uk-lon-st002.prod.surfshark.com_udp.ovpn
|
|||
|
es-bcn.prod.surfshark.com_udp.ovpn uk-lon-st003.prod.surfshark.com_tcp.ovpn
|
|||
|
es-mad.prod.surfshark.com_tcp.ovpn uk-lon-st003.prod.surfshark.com_udp.ovpn
|
|||
|
es-mad.prod.surfshark.com_udp.ovpn uk-lon-st004.prod.surfshark.com_tcp.ovpn
|
|||
|
es-vlc.prod.surfshark.com_tcp.ovpn uk-lon-st004.prod.surfshark.com_udp.ovpn
|
|||
|
es-vlc.prod.surfshark.com_udp.ovpn uk-lon-st005.prod.surfshark.com_tcp.ovpn
|
|||
|
fi-hel.prod.surfshark.com_tcp.ovpn uk-lon-st005.prod.surfshark.com_udp.ovpn
|
|||
|
fi-hel.prod.surfshark.com_udp.ovpn uk-man.prod.surfshark.com_tcp.ovpn
|
|||
|
fr-bod.prod.surfshark.com_tcp.ovpn uk-man.prod.surfshark.com_udp.ovpn
|
|||
|
fr-bod.prod.surfshark.com_udp.ovpn us-atl.prod.surfshark.com_tcp.ovpn
|
|||
|
fr-mrs.prod.surfshark.com_tcp.ovpn us-atl.prod.surfshark.com_udp.ovpn
|
|||
|
fr-mrs.prod.surfshark.com_udp.ovpn us-bdn.prod.surfshark.com_tcp.ovpn
|
|||
|
fr-par.prod.surfshark.com_tcp.ovpn us-bdn.prod.surfshark.com_udp.ovpn
|
|||
|
fr-par.prod.surfshark.com_udp.ovpn us-bos.prod.surfshark.com_tcp.ovpn
|
|||
|
gr-ath.prod.surfshark.com_tcp.ovpn us-bos.prod.surfshark.com_udp.ovpn
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p><strong>Connexion au VPN</strong><br />
|
|||
|
Choisir un serveur dans la liste et copiez le nom d’hôte (clic-droit - copier)<br />
|
|||
|
Connectez-vous au serveur de votre choix en entrant cette commande : <code class="language-plaintext highlighter-rouge">sudo openvpn <coller le nom du serveur ici></code><br />
|
|||
|
Par exemple, si vous souhaitez vous connecter au serveur fr-bod, voici la commande :</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>openvpn fr-bod.prod.surfshark.com_udp.ovpn
|
|||
|
|
|||
|
connect_to_this_server.png
|
|||
|
|
|||
|
Avant de pouvoir vous connecter au serveur, vous devez saisir les informations d'identification du service Surfshark.
|
|||
|
|
|||
|
Saisissez les informations d'identification que vous avez recueillies dans la partie "Obtenez vos informations d'identification", puis appuyez sur la touche Entrée.
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[root@archyan client]# openvpn fr-bod.prod.surfshark.com_udp.ovpn
|
|||
|
2021-02-16 15:11:58 DEPRECATED OPTION: --cipher set to 'AES-256-CBC' but missing in --data-ciphers (AES-256-GCM:AES-128-GCM). Future OpenVPN version will ignore --cipher for cipher negotiations. Add 'AES-256-CBC' to --data-ciphers or change --cipher 'AES-256-CBC' to --data-ciphers-fallback 'AES-256-CBC' to silence this warning.
|
|||
|
2021-02-16 15:11:58 OpenVPN 2.5.0 [git:makepkg/a73072d8f780e888+] x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [PKCS11] [MH/PKTINFO] [AEAD] built on Nov 6 2020
|
|||
|
2021-02-16 15:11:58 library versions: OpenSSL 1.1.1i 8 Dec 2020, LZO 2.10
|
|||
|
🔐 Enter Auth Username:
|
|||
|
🔐 Enter Auth Password: ************************
|
|||
|
|
|||
|
[...]
|
|||
|
2021-02-16 15:13:25 TUN/TAP device tun0 opened
|
|||
|
2021-02-16 15:13:25 net_iface_mtu_set: mtu 1500 for tun0
|
|||
|
2021-02-16 15:13:25 net_iface_up: set tun0 up
|
|||
|
2021-02-16 15:13:25 net_addr_v4_add: 10.8.8.7/24 dev tun0
|
|||
|
2021-02-16 15:13:25 net_route_v4_add: 185.108.106.144/32 via 192.168.0.254 dev [NULL] table 0 metric -1
|
|||
|
2021-02-16 15:13:25 net_route_v4_add: 0.0.0.0/1 via 10.8.8.1 dev [NULL] table 0 metric -1
|
|||
|
2021-02-16 15:13:25 net_route_v4_add: 128.0.0.0/1 via 10.8.8.1 dev [NULL] table 0 metric -1
|
|||
|
2021-02-16 15:13:25 Initialization Sequence Completed
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Si vous pouvez voir la ligne “Initialization Sequence Completed” sur votre terminal, c’est que vous avez réussi à vous connecter à Surfshark !</p>
|
|||
|
|
|||
|
<p>Pour vous déconnecter de la connexion OpenVPN, ouvrez le terminal et appuyez sur Ctrl + C.<br />
|
|||
|
Vous avez configuré avec succès la connexion manuelle d’OpenVPN ! Tant que vous êtes connecté, votre emplacement est privé et vos données sensibles sont sécurisées.</p>
|
|||
|
|
|||
|
<p><strong>Vérifications</strong><br />
|
|||
|
Adresse IP <a href="https://surfshark.com/what-is-my-ip">https://surfshark.com/what-is-my-ip</a><br />
|
|||
|
<img src="/images/surfshark122.png" alt="surfshark" width="600" /></p>
|
|||
|
|
|||
|
<p>DNS leaks <a href="https://surfshark.com/dns-leak-test">https://surfshark.com/dns-leak-test</a><br />
|
|||
|
<img src="/images/surfshark123.png" alt="surfshark" width="600" /></p>
|
|||
|
|
|||
|
<p><a href="https://ipleak.net/">https://ipleak.net/</a><br />
|
|||
|
<img src="/images/surfshark124.png" alt="surfshark" width="600" /></p>
|
|||
|
|
|||
|
<h2 id="options-dassistance">Options d’assistance</h2>
|
|||
|
|
|||
|
<p><strong>Assistance technique et liée aux produits</strong><br />
|
|||
|
Si vous avez des questions techniques ou concernant les produits, vous pouvez contacter Surfshark en utilisant les informations suivantes :</p>
|
|||
|
|
|||
|
<ul>
|
|||
|
<li>Adresse e-mail : <a href="mailto:support@surfshark.com">support@surfshark.com</a></li>
|
|||
|
<li>Online Contact Form: <a href="https://account.surfshark.com/contact">https://account.surfshark.com/contact</a></li>
|
|||
|
<li>Online Faqs: <a href="https://support.surfshark.com/hc/en-us/categories/360000185553-FAQ">https://support.surfshark.com/hc/en-us/categories/360000185553-FAQ</a></li>
|
|||
|
</ul>
|
|||
|
|
|||
|
<p><strong>Assistance relative au paiement et aux commandes</strong><br />
|
|||
|
Si vous avez des questions concernant le paiement ou une commande, veuillez contacter le <a href="https://www.cleverbridge.com/1622/?scope=cuseco&id=7YozGA1ibD&cfg=surfshark">service client cleverbridge</a>.</p>
|
|||
|
|
|||
|
</div>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<div class="d-print-none"><footer class="article__footer"><meta itemprop="dateModified" content="2020-08-17T00:00:00+02:00"><!-- start custom article footer snippet -->
|
|||
|
|
|||
|
<!-- end custom article footer snippet -->
|
|||
|
<!--
|
|||
|
<div align="right"><a type="application/rss+xml" href="/feed.xml" title="S'abonner"><i class="fa fa-rss fa-2x"></i></a>
|
|||
|
|
|||
|
 </div>
|
|||
|
-->
|
|||
|
</footer>
|
|||
|
<div class="article__section-navigator clearfix"><div class="previous"><span>PRÉCÉDENT</span><a href="/2020/08/16/Raspbian-Desktop-Buster-RaspberryPI-FlashDriveUSB.html">RPI3B - Raspbian Desktop Buster, client Wireguard, Kodi (INACTIF)</a></div><div class="next"><span>SUIVANT</span><a href="/2020/08/21/Applications-Archlinux-Manjaro.html">Applications Archlinux/Manjaro</a></div></div></div>
|
|||
|
|
|||
|
</div>
|
|||
|
|
|||
|
<script>(function() {
|
|||
|
var SOURCES = window.TEXT_VARIABLES.sources;
|
|||
|
window.Lazyload.js(SOURCES.jquery, function() {
|
|||
|
$(function() {
|
|||
|
var $this ,$scroll;
|
|||
|
var $articleContent = $('.js-article-content');
|
|||
|
var hasSidebar = $('.js-page-root').hasClass('layout--page--sidebar');
|
|||
|
var scroll = hasSidebar ? '.js-page-main' : 'html, body';
|
|||
|
$scroll = $(scroll);
|
|||
|
|
|||
|
$articleContent.find('.highlight').each(function() {
|
|||
|
$this = $(this);
|
|||
|
$this.attr('data-lang', $this.find('code').attr('data-lang'));
|
|||
|
});
|
|||
|
$articleContent.find('h1[id], h2[id], h3[id], h4[id], h5[id], h6[id]').each(function() {
|
|||
|
$this = $(this);
|
|||
|
$this.append($('<a class="anchor d-print-none" aria-hidden="true"></a>').html('<i class="fas fa-anchor"></i>'));
|
|||
|
});
|
|||
|
$articleContent.on('click', '.anchor', function() {
|
|||
|
$scroll.scrollToAnchor('#' + $(this).parent().attr('id'), 400);
|
|||
|
});
|
|||
|
});
|
|||
|
});
|
|||
|
})();
|
|||
|
</script>
|
|||
|
|
|||
|
</div><section class="page__comments d-print-none"></section></article><!-- start custom main bottom snippet -->
|
|||
|
<!-- end custom main bottom snippet -->
|
|||
|
</div>
|
|||
|
</div></div></div></div>
|
|||
|
</div><script>(function() {
|
|||
|
var SOURCES = window.TEXT_VARIABLES.sources;
|
|||
|
window.Lazyload.js(SOURCES.jquery, function() {
|
|||
|
var $body = $('body'), $window = $(window);
|
|||
|
var $pageRoot = $('.js-page-root'), $pageMain = $('.js-page-main');
|
|||
|
var activeCount = 0;
|
|||
|
function modal(options) {
|
|||
|
var $root = this, visible, onChange, hideWhenWindowScroll = false;
|
|||
|
var scrollTop;
|
|||
|
function setOptions(options) {
|
|||
|
var _options = options || {};
|
|||
|
visible = _options.initialVisible === undefined ? false : show;
|
|||
|
onChange = _options.onChange;
|
|||
|
hideWhenWindowScroll = _options.hideWhenWindowScroll;
|
|||
|
}
|
|||
|
function init() {
|
|||
|
setState(visible);
|
|||
|
}
|
|||
|
function setState(isShow) {
|
|||
|
if (isShow === visible) {
|
|||
|
return;
|
|||
|
}
|
|||
|
visible = isShow;
|
|||
|
if (visible) {
|
|||
|
activeCount++;
|
|||
|
scrollTop = $(window).scrollTop() || $pageMain.scrollTop();
|
|||
|
$root.addClass('modal--show');
|
|||
|
$pageMain.scrollTop(scrollTop);
|
|||
|
activeCount === 1 && ($pageRoot.addClass('show-modal'), $body.addClass('of-hidden'));
|
|||
|
hideWhenWindowScroll && window.hasEvent('touchstart') && $window.on('scroll', hide);
|
|||
|
$window.on('keyup', handleKeyup);
|
|||
|
} else {
|
|||
|
activeCount > 0 && activeCount--;
|
|||
|
$root.removeClass('modal--show');
|
|||
|
$window.scrollTop(scrollTop);
|
|||
|
activeCount === 0 && ($pageRoot.removeClass('show-modal'), $body.removeClass('of-hidden'));
|
|||
|
hideWhenWindowScroll && window.hasEvent('touchstart') && $window.off('scroll', hide);
|
|||
|
$window.off('keyup', handleKeyup);
|
|||
|
}
|
|||
|
onChange && onChange(visible);
|
|||
|
}
|
|||
|
function show() {
|
|||
|
setState(true);
|
|||
|
}
|
|||
|
function hide() {
|
|||
|
setState(false);
|
|||
|
}
|
|||
|
function handleKeyup(e) {
|
|||
|
// Char Code: 27 ESC
|
|||
|
if (e.which === 27) {
|
|||
|
hide();
|
|||
|
}
|
|||
|
}
|
|||
|
setOptions(options);
|
|||
|
init();
|
|||
|
return {
|
|||
|
show: show,
|
|||
|
hide: hide,
|
|||
|
$el: $root
|
|||
|
};
|
|||
|
}
|
|||
|
$.fn.modal = modal;
|
|||
|
});
|
|||
|
})();
|
|||
|
</script><div class="modal modal--overflow page__search-modal d-print-none js-page-search-modal"><script>
|
|||
|
(function () {
|
|||
|
var SOURCES = window.TEXT_VARIABLES.sources;
|
|||
|
window.Lazyload.js(SOURCES.jquery, function() {
|
|||
|
// search panel
|
|||
|
var search = (window.search || (window.search = {}));
|
|||
|
var useDefaultSearchBox = window.useDefaultSearchBox === undefined ?
|
|||
|
true : window.useDefaultSearchBox ;
|
|||
|
|
|||
|
var $searchModal = $('.js-page-search-modal');
|
|||
|
var $searchToggle = $('.js-search-toggle');
|
|||
|
var searchModal = $searchModal.modal({ onChange: handleModalChange, hideWhenWindowScroll: true });
|
|||
|
var modalVisible = false;
|
|||
|
search.searchModal = searchModal;
|
|||
|
|
|||
|
var $searchBox = null;
|
|||
|
var $searchInput = null;
|
|||
|
var $searchClear = null;
|
|||
|
|
|||
|
function getModalVisible() {
|
|||
|
return modalVisible;
|
|||
|
}
|
|||
|
search.getModalVisible = getModalVisible;
|
|||
|
|
|||
|
function handleModalChange(visible) {
|
|||
|
modalVisible = visible;
|
|||
|
if (visible) {
|
|||
|
search.onShow && search.onShow();
|
|||
|
useDefaultSearchBox && $searchInput[0] && $searchInput[0].focus();
|
|||
|
} else {
|
|||
|
search.onShow && search.onHide();
|
|||
|
useDefaultSearchBox && $searchInput[0] && $searchInput[0].blur();
|
|||
|
setTimeout(function() {
|
|||
|
useDefaultSearchBox && ($searchInput.val(''), $searchBox.removeClass('not-empty'));
|
|||
|
search.clear && search.clear();
|
|||
|
window.pageAsideAffix && window.pageAsideAffix.refresh();
|
|||
|
}, 400);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
$searchToggle.on('click', function() {
|
|||
|
modalVisible ? searchModal.hide() : searchModal.show();
|
|||
|
});
|
|||
|
// Char Code: 83 S, 191 /
|
|||
|
$(window).on('keyup', function(e) {
|
|||
|
if (!modalVisible && !window.isFormElement(e.target || e.srcElement) && (e.which === 83 || e.which === 191)) {
|
|||
|
modalVisible || searchModal.show();
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
if (useDefaultSearchBox) {
|
|||
|
$searchBox = $('.js-search-box');
|
|||
|
$searchInput = $searchBox.children('input');
|
|||
|
$searchClear = $searchBox.children('.js-icon-clear');
|
|||
|
search.getSearchInput = function() {
|
|||
|
return $searchInput.get(0);
|
|||
|
};
|
|||
|
search.getVal = function() {
|
|||
|
return $searchInput.val();
|
|||
|
};
|
|||
|
search.setVal = function(val) {
|
|||
|
$searchInput.val(val);
|
|||
|
};
|
|||
|
|
|||
|
$searchInput.on('focus', function() {
|
|||
|
$(this).addClass('focus');
|
|||
|
});
|
|||
|
$searchInput.on('blur', function() {
|
|||
|
$(this).removeClass('focus');
|
|||
|
});
|
|||
|
$searchInput.on('input', window.throttle(function() {
|
|||
|
var val = $(this).val();
|
|||
|
if (val === '' || typeof val !== 'string') {
|
|||
|
search.clear && search.clear();
|
|||
|
} else {
|
|||
|
$searchBox.addClass('not-empty');
|
|||
|
search.onInputNotEmpty && search.onInputNotEmpty(val);
|
|||
|
}
|
|||
|
}, 400));
|
|||
|
$searchClear.on('click', function() {
|
|||
|
$searchInput.val(''); $searchBox.removeClass('not-empty');
|
|||
|
search.clear && search.clear();
|
|||
|
});
|
|||
|
}
|
|||
|
});
|
|||
|
})();
|
|||
|
</script><div class="search search--dark">
|
|||
|
<div class="main">
|
|||
|
<div class="search__header">Recherche</div>
|
|||
|
<div class="search-bar">
|
|||
|
<div class="search-box js-search-box">
|
|||
|
<div class="search-box__icon-search"><i class="fas fa-search"></i></div>
|
|||
|
<input id="search-input" type="text" />
|
|||
|
<div class="search-box__icon-clear js-icon-clear">
|
|||
|
<a><i class="fas fa-times"></i></a>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
<button class="button button--theme-dark button--pill search__cancel js-search-toggle">
|
|||
|
Annuler</button>
|
|||
|
</div>
|
|||
|
<div id="results-container" class="search-result js-search-result"></div>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
<!-- Script pointing to search-script.js -->
|
|||
|
<script>/*!
|
|||
|
* Simple-Jekyll-Search
|
|||
|
* Copyright 2015-2020, Christian Fei
|
|||
|
* Licensed under the MIT License.
|
|||
|
*/
|
|||
|
|
|||
|
(function(){
|
|||
|
'use strict'
|
|||
|
|
|||
|
var _$Templater_7 = {
|
|||
|
compile: compile,
|
|||
|
setOptions: setOptions
|
|||
|
}
|
|||
|
|
|||
|
const options = {}
|
|||
|
options.pattern = /\{(.*?)\}/g
|
|||
|
options.template = ''
|
|||
|
options.middleware = function () {}
|
|||
|
|
|||
|
function setOptions (_options) {
|
|||
|
options.pattern = _options.pattern || options.pattern
|
|||
|
options.template = _options.template || options.template
|
|||
|
if (typeof _options.middleware === 'function') {
|
|||
|
options.middleware = _options.middleware
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function compile (data) {
|
|||
|
return options.template.replace(options.pattern, function (match, prop) {
|
|||
|
const value = options.middleware(prop, data[prop], options.template)
|
|||
|
if (typeof value !== 'undefined') {
|
|||
|
return value
|
|||
|
}
|
|||
|
return data[prop] || match
|
|||
|
})
|
|||
|
}
|
|||
|
|
|||
|
'use strict';
|
|||
|
|
|||
|
function fuzzysearch (needle, haystack) {
|
|||
|
var tlen = haystack.length;
|
|||
|
var qlen = needle.length;
|
|||
|
if (qlen > tlen) {
|
|||
|
return false;
|
|||
|
}
|
|||
|
if (qlen === tlen) {
|
|||
|
return needle === haystack;
|
|||
|
}
|
|||
|
outer: for (var i = 0, j = 0; i < qlen; i++) {
|
|||
|
var nch = needle.charCodeAt(i);
|
|||
|
while (j < tlen) {
|
|||
|
if (haystack.charCodeAt(j++) === nch) {
|
|||
|
continue outer;
|
|||
|
}
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
var _$fuzzysearch_1 = fuzzysearch;
|
|||
|
|
|||
|
'use strict'
|
|||
|
|
|||
|
/* removed: const _$fuzzysearch_1 = require('fuzzysearch') */;
|
|||
|
|
|||
|
var _$FuzzySearchStrategy_5 = new FuzzySearchStrategy()
|
|||
|
|
|||
|
function FuzzySearchStrategy () {
|
|||
|
this.matches = function (string, crit) {
|
|||
|
return _$fuzzysearch_1(crit.toLowerCase(), string.toLowerCase())
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
'use strict'
|
|||
|
|
|||
|
var _$LiteralSearchStrategy_6 = new LiteralSearchStrategy()
|
|||
|
|
|||
|
function LiteralSearchStrategy () {
|
|||
|
this.matches = function (str, crit) {
|
|||
|
if (!str) return false
|
|||
|
|
|||
|
str = str.trim().toLowerCase()
|
|||
|
crit = crit.trim().toLowerCase()
|
|||
|
|
|||
|
return crit.split(' ').filter(function (word) {
|
|||
|
return str.indexOf(word) >= 0
|
|||
|
}).length === crit.split(' ').length
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
'use strict'
|
|||
|
|
|||
|
var _$Repository_4 = {
|
|||
|
put: put,
|
|||
|
clear: clear,
|
|||
|
search: search,
|
|||
|
setOptions: __setOptions_4
|
|||
|
}
|
|||
|
|
|||
|
/* removed: const _$FuzzySearchStrategy_5 = require('./SearchStrategies/FuzzySearchStrategy') */;
|
|||
|
/* removed: const _$LiteralSearchStrategy_6 = require('./SearchStrategies/LiteralSearchStrategy') */;
|
|||
|
|
|||
|
function NoSort () {
|
|||
|
return 0
|
|||
|
}
|
|||
|
|
|||
|
const data = []
|
|||
|
let opt = {}
|
|||
|
|
|||
|
opt.fuzzy = false
|
|||
|
opt.limit = 10
|
|||
|
opt.searchStrategy = opt.fuzzy ? _$FuzzySearchStrategy_5 : _$LiteralSearchStrategy_6
|
|||
|
opt.sort = NoSort
|
|||
|
opt.exclude = []
|
|||
|
|
|||
|
function put (data) {
|
|||
|
if (isObject(data)) {
|
|||
|
return addObject(data)
|
|||
|
}
|
|||
|
if (isArray(data)) {
|
|||
|
return addArray(data)
|
|||
|
}
|
|||
|
return undefined
|
|||
|
}
|
|||
|
function clear () {
|
|||
|
data.length = 0
|
|||
|
return data
|
|||
|
}
|
|||
|
|
|||
|
function isObject (obj) {
|
|||
|
return Boolean(obj) && Object.prototype.toString.call(obj) === '[object Object]'
|
|||
|
}
|
|||
|
|
|||
|
function isArray (obj) {
|
|||
|
return Boolean(obj) && Object.prototype.toString.call(obj) === '[object Array]'
|
|||
|
}
|
|||
|
|
|||
|
function addObject (_data) {
|
|||
|
data.push(_data)
|
|||
|
return data
|
|||
|
}
|
|||
|
|
|||
|
function addArray (_data) {
|
|||
|
const added = []
|
|||
|
clear()
|
|||
|
for (let i = 0, len = _data.length; i < len; i++) {
|
|||
|
if (isObject(_data[i])) {
|
|||
|
added.push(addObject(_data[i]))
|
|||
|
}
|
|||
|
}
|
|||
|
return added
|
|||
|
}
|
|||
|
|
|||
|
function search (crit) {
|
|||
|
if (!crit) {
|
|||
|
return []
|
|||
|
}
|
|||
|
return findMatches(data, crit, opt.searchStrategy, opt).sort(opt.sort)
|
|||
|
}
|
|||
|
|
|||
|
function __setOptions_4 (_opt) {
|
|||
|
opt = _opt || {}
|
|||
|
|
|||
|
opt.fuzzy = _opt.fuzzy || false
|
|||
|
opt.limit = _opt.limit || 10
|
|||
|
opt.searchStrategy = _opt.fuzzy ? _$FuzzySearchStrategy_5 : _$LiteralSearchStrategy_6
|
|||
|
opt.sort = _opt.sort || NoSort
|
|||
|
opt.exclude = _opt.exclude || []
|
|||
|
}
|
|||
|
|
|||
|
function findMatches (data, crit, strategy, opt) {
|
|||
|
const matches = []
|
|||
|
for (let i = 0; i < data.length && matches.length < opt.limit; i++) {
|
|||
|
const match = findMatchesInObject(data[i], crit, strategy, opt)
|
|||
|
if (match) {
|
|||
|
matches.push(match)
|
|||
|
}
|
|||
|
}
|
|||
|
return matches
|
|||
|
}
|
|||
|
|
|||
|
function findMatchesInObject (obj, crit, strategy, opt) {
|
|||
|
for (const key in obj) {
|
|||
|
if (!isExcluded(obj[key], opt.exclude) && strategy.matches(obj[key], crit)) {
|
|||
|
return obj
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function isExcluded (term, excludedTerms) {
|
|||
|
for (let i = 0, len = excludedTerms.length; i < len; i++) {
|
|||
|
const excludedTerm = excludedTerms[i]
|
|||
|
if (new RegExp(excludedTerm).test(term)) {
|
|||
|
return true
|
|||
|
}
|
|||
|
}
|
|||
|
return false
|
|||
|
}
|
|||
|
|
|||
|
/* globals ActiveXObject:false */
|
|||
|
|
|||
|
'use strict'
|
|||
|
|
|||
|
var _$JSONLoader_2 = {
|
|||
|
load: load
|
|||
|
}
|
|||
|
|
|||
|
function load (location, callback) {
|
|||
|
const xhr = getXHR()
|
|||
|
xhr.open('GET', location, true)
|
|||
|
xhr.onreadystatechange = createStateChangeListener(xhr, callback)
|
|||
|
xhr.send()
|
|||
|
}
|
|||
|
|
|||
|
function createStateChangeListener (xhr, callback) {
|
|||
|
return function () {
|
|||
|
if (xhr.readyState === 4 && xhr.status === 200) {
|
|||
|
try {
|
|||
|
callback(null, JSON.parse(xhr.responseText))
|
|||
|
} catch (err) {
|
|||
|
callback(err, null)
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function getXHR () {
|
|||
|
return window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP')
|
|||
|
}
|
|||
|
|
|||
|
'use strict'
|
|||
|
|
|||
|
var _$OptionsValidator_3 = function OptionsValidator (params) {
|
|||
|
if (!validateParams(params)) {
|
|||
|
throw new Error('-- OptionsValidator: required options missing')
|
|||
|
}
|
|||
|
|
|||
|
if (!(this instanceof OptionsValidator)) {
|
|||
|
return new OptionsValidator(params)
|
|||
|
}
|
|||
|
|
|||
|
const requiredOptions = params.required
|
|||
|
|
|||
|
this.getRequiredOptions = function () {
|
|||
|
return requiredOptions
|
|||
|
}
|
|||
|
|
|||
|
this.validate = function (parameters) {
|
|||
|
const errors = []
|
|||
|
requiredOptions.forEach(function (requiredOptionName) {
|
|||
|
if (typeof parameters[requiredOptionName] === 'undefined') {
|
|||
|
errors.push(requiredOptionName)
|
|||
|
}
|
|||
|
})
|
|||
|
return errors
|
|||
|
}
|
|||
|
|
|||
|
function validateParams (params) {
|
|||
|
if (!params) {
|
|||
|
return false
|
|||
|
}
|
|||
|
return typeof params.required !== 'undefined' && params.required instanceof Array
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
'use strict'
|
|||
|
|
|||
|
var _$utils_9 = {
|
|||
|
merge: merge,
|
|||
|
isJSON: isJSON
|
|||
|
}
|
|||
|
|
|||
|
function merge (defaultParams, mergeParams) {
|
|||
|
const mergedOptions = {}
|
|||
|
for (const option in defaultParams) {
|
|||
|
mergedOptions[option] = defaultParams[option]
|
|||
|
if (typeof mergeParams[option] !== 'undefined') {
|
|||
|
mergedOptions[option] = mergeParams[option]
|
|||
|
}
|
|||
|
}
|
|||
|
return mergedOptions
|
|||
|
}
|
|||
|
|
|||
|
function isJSON (json) {
|
|||
|
try {
|
|||
|
if (json instanceof Object && JSON.parse(JSON.stringify(json))) {
|
|||
|
return true
|
|||
|
}
|
|||
|
return false
|
|||
|
} catch (err) {
|
|||
|
return false
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
var _$src_8 = {};
|
|||
|
(function (window) {
|
|||
|
'use strict'
|
|||
|
|
|||
|
let options = {
|
|||
|
searchInput: null,
|
|||
|
resultsContainer: null,
|
|||
|
json: [],
|
|||
|
success: Function.prototype,
|
|||
|
searchResultTemplate: '<li><a href="{url}" title="{desc}">{title}</a></li>',
|
|||
|
templateMiddleware: Function.prototype,
|
|||
|
sortMiddleware: function () {
|
|||
|
return 0
|
|||
|
},
|
|||
|
noResultsText: 'No results found',
|
|||
|
limit: 10,
|
|||
|
fuzzy: false,
|
|||
|
debounceTime: null,
|
|||
|
exclude: []
|
|||
|
}
|
|||
|
|
|||
|
let debounceTimerHandle
|
|||
|
const debounce = function (func, delayMillis) {
|
|||
|
if (delayMillis) {
|
|||
|
clearTimeout(debounceTimerHandle)
|
|||
|
debounceTimerHandle = setTimeout(func, delayMillis)
|
|||
|
} else {
|
|||
|
func.call()
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
const requiredOptions = ['searchInput', 'resultsContainer', 'json']
|
|||
|
|
|||
|
/* removed: const _$Templater_7 = require('./Templater') */;
|
|||
|
/* removed: const _$Repository_4 = require('./Repository') */;
|
|||
|
/* removed: const _$JSONLoader_2 = require('./JSONLoader') */;
|
|||
|
const optionsValidator = _$OptionsValidator_3({
|
|||
|
required: requiredOptions
|
|||
|
})
|
|||
|
/* removed: const _$utils_9 = require('./utils') */;
|
|||
|
|
|||
|
window.SimpleJekyllSearch = function (_options) {
|
|||
|
const errors = optionsValidator.validate(_options)
|
|||
|
if (errors.length > 0) {
|
|||
|
throwError('You must specify the following required options: ' + requiredOptions)
|
|||
|
}
|
|||
|
|
|||
|
options = _$utils_9.merge(options, _options)
|
|||
|
|
|||
|
_$Templater_7.setOptions({
|
|||
|
template: options.searchResultTemplate,
|
|||
|
middleware: options.templateMiddleware
|
|||
|
})
|
|||
|
|
|||
|
_$Repository_4.setOptions({
|
|||
|
fuzzy: options.fuzzy,
|
|||
|
limit: options.limit,
|
|||
|
sort: options.sortMiddleware,
|
|||
|
exclude: options.exclude
|
|||
|
})
|
|||
|
|
|||
|
if (_$utils_9.isJSON(options.json)) {
|
|||
|
initWithJSON(options.json)
|
|||
|
} else {
|
|||
|
initWithURL(options.json)
|
|||
|
}
|
|||
|
|
|||
|
const rv = {
|
|||
|
search: search
|
|||
|
}
|
|||
|
|
|||
|
typeof options.success === 'function' && options.success.call(rv)
|
|||
|
return rv
|
|||
|
}
|
|||
|
|
|||
|
function initWithJSON (json) {
|
|||
|
_$Repository_4.put(json)
|
|||
|
registerInput()
|
|||
|
}
|
|||
|
|
|||
|
function initWithURL (url) {
|
|||
|
_$JSONLoader_2.load(url, function (err, json) {
|
|||
|
if (err) {
|
|||
|
throwError('failed to get JSON (' + url + ')')
|
|||
|
}
|
|||
|
initWithJSON(json)
|
|||
|
})
|
|||
|
}
|
|||
|
|
|||
|
function emptyResultsContainer () {
|
|||
|
options.resultsContainer.innerHTML = ''
|
|||
|
}
|
|||
|
|
|||
|
function appendToResultsContainer (text) {
|
|||
|
options.resultsContainer.innerHTML += text
|
|||
|
}
|
|||
|
|
|||
|
function registerInput () {
|
|||
|
options.searchInput.addEventListener('input', function (e) {
|
|||
|
if (isWhitelistedKey(e.which)) {
|
|||
|
emptyResultsContainer()
|
|||
|
debounce(function () { search(e.target.value) }, options.debounceTime)
|
|||
|
}
|
|||
|
})
|
|||
|
}
|
|||
|
|
|||
|
function search (query) {
|
|||
|
if (isValidQuery(query)) {
|
|||
|
emptyResultsContainer()
|
|||
|
render(_$Repository_4.search(query), query)
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function render (results, query) {
|
|||
|
const len = results.length
|
|||
|
if (len === 0) {
|
|||
|
return appendToResultsContainer(options.noResultsText)
|
|||
|
}
|
|||
|
for (let i = 0; i < len; i++) {
|
|||
|
results[i].query = query
|
|||
|
appendToResultsContainer(_$Templater_7.compile(results[i]))
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function isValidQuery (query) {
|
|||
|
return query && query.length > 0
|
|||
|
}
|
|||
|
|
|||
|
function isWhitelistedKey (key) {
|
|||
|
return [13, 16, 20, 37, 38, 39, 40, 91].indexOf(key) === -1
|
|||
|
}
|
|||
|
|
|||
|
function throwError (message) {
|
|||
|
throw new Error('SimpleJekyllSearch --- ' + message)
|
|||
|
}
|
|||
|
})(window)
|
|||
|
|
|||
|
}());
|
|||
|
</script>
|
|||
|
|
|||
|
<!-- Configuration -->
|
|||
|
<script>
|
|||
|
SimpleJekyllSearch({
|
|||
|
searchInput: document.getElementById('search-input'),
|
|||
|
resultsContainer: document.getElementById('results-container'),
|
|||
|
noResultsText: '<p>Aucun résultat!</p>',
|
|||
|
json: '/search.json',
|
|||
|
searchResultTemplate: '<li><a href="{url}">{date} {title}</a> (Création {create})</li>'
|
|||
|
})
|
|||
|
</script>
|
|||
|
|
|||
|
</div></div>
|
|||
|
|
|||
|
|
|||
|
<script>(function() {
|
|||
|
var SOURCES = window.TEXT_VARIABLES.sources;
|
|||
|
window.Lazyload.js(SOURCES.jquery, function() {
|
|||
|
function scrollToAnchor(anchor, duration, callback) {
|
|||
|
var $root = this;
|
|||
|
$root.animate({ scrollTop: $(anchor).position().top }, duration, function() {
|
|||
|
window.history.replaceState(null, '', window.location.href.split('#')[0] + anchor);
|
|||
|
callback && callback();
|
|||
|
});
|
|||
|
}
|
|||
|
$.fn.scrollToAnchor = scrollToAnchor;
|
|||
|
});
|
|||
|
})();
|
|||
|
(function() {
|
|||
|
var SOURCES = window.TEXT_VARIABLES.sources;
|
|||
|
window.Lazyload.js(SOURCES.jquery, function() {
|
|||
|
function affix(options) {
|
|||
|
var $root = this, $window = $(window), $scrollTarget, $scroll,
|
|||
|
offsetBottom = 0, scrollTarget = window, scroll = window.document, disabled = false, isOverallScroller = true,
|
|||
|
rootTop, rootLeft, rootHeight, scrollBottom, rootBottomTop,
|
|||
|
hasInit = false, curState;
|
|||
|
|
|||
|
function setOptions(options) {
|
|||
|
var _options = options || {};
|
|||
|
_options.offsetBottom && (offsetBottom = _options.offsetBottom);
|
|||
|
_options.scrollTarget && (scrollTarget = _options.scrollTarget);
|
|||
|
_options.scroll && (scroll = _options.scroll);
|
|||
|
_options.disabled !== undefined && (disabled = _options.disabled);
|
|||
|
$scrollTarget = $(scrollTarget);
|
|||
|
isOverallScroller = window.isOverallScroller($scrollTarget[0]);
|
|||
|
$scroll = $(scroll);
|
|||
|
}
|
|||
|
function preCalc() {
|
|||
|
top();
|
|||
|
rootHeight = $root.outerHeight();
|
|||
|
rootTop = $root.offset().top + (isOverallScroller ? 0 : $scrollTarget.scrollTop());
|
|||
|
rootLeft = $root.offset().left;
|
|||
|
}
|
|||
|
function calc(needPreCalc) {
|
|||
|
needPreCalc && preCalc();
|
|||
|
scrollBottom = $scroll.outerHeight() - offsetBottom - rootHeight;
|
|||
|
rootBottomTop = scrollBottom - rootTop;
|
|||
|
}
|
|||
|
function top() {
|
|||
|
if (curState !== 'top') {
|
|||
|
$root.removeClass('fixed').css({
|
|||
|
left: 0,
|
|||
|
top: 0
|
|||
|
});
|
|||
|
curState = 'top';
|
|||
|
}
|
|||
|
}
|
|||
|
function fixed() {
|
|||
|
if (curState !== 'fixed') {
|
|||
|
$root.addClass('fixed').css({
|
|||
|
left: rootLeft + 'px',
|
|||
|
top: 0
|
|||
|
});
|
|||
|
curState = 'fixed';
|
|||
|
}
|
|||
|
}
|
|||
|
function bottom() {
|
|||
|
if (curState !== 'bottom') {
|
|||
|
$root.removeClass('fixed').css({
|
|||
|
left: 0,
|
|||
|
top: rootBottomTop + 'px'
|
|||
|
});
|
|||
|
curState = 'bottom';
|
|||
|
}
|
|||
|
}
|
|||
|
function setState() {
|
|||
|
var scrollTop = $scrollTarget.scrollTop();
|
|||
|
if (scrollTop >= rootTop && scrollTop <= scrollBottom) {
|
|||
|
fixed();
|
|||
|
} else if (scrollTop < rootTop) {
|
|||
|
top();
|
|||
|
} else {
|
|||
|
bottom();
|
|||
|
}
|
|||
|
}
|
|||
|
function init() {
|
|||
|
if(!hasInit) {
|
|||
|
var interval, timeout;
|
|||
|
calc(true); setState();
|
|||
|
// run calc every 100 millisecond
|
|||
|
interval = setInterval(function() {
|
|||
|
calc();
|
|||
|
}, 100);
|
|||
|
timeout = setTimeout(function() {
|
|||
|
clearInterval(interval);
|
|||
|
}, 45000);
|
|||
|
window.pageLoad.then(function() {
|
|||
|
setTimeout(function() {
|
|||
|
clearInterval(interval);
|
|||
|
clearTimeout(timeout);
|
|||
|
}, 3000);
|
|||
|
});
|
|||
|
$scrollTarget.on('scroll', function() {
|
|||
|
disabled || setState();
|
|||
|
});
|
|||
|
$window.on('resize', function() {
|
|||
|
disabled || (calc(true), setState());
|
|||
|
});
|
|||
|
hasInit = true;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
setOptions(options);
|
|||
|
if (!disabled) {
|
|||
|
init();
|
|||
|
}
|
|||
|
$window.on('resize', window.throttle(function() {
|
|||
|
init();
|
|||
|
}, 200));
|
|||
|
return {
|
|||
|
setOptions: setOptions,
|
|||
|
refresh: function() {
|
|||
|
calc(true, { animation: false }); setState();
|
|||
|
}
|
|||
|
};
|
|||
|
}
|
|||
|
$.fn.affix = affix;
|
|||
|
});
|
|||
|
})();
|
|||
|
(function() {
|
|||
|
var SOURCES = window.TEXT_VARIABLES.sources;
|
|||
|
window.Lazyload.js(SOURCES.jquery, function() {
|
|||
|
function toc(options) {
|
|||
|
var $root = this, $window = $(window), $scrollTarget, $scroller, $tocUl = $('<ul class="toc toc--ellipsis"></ul>'), $tocLi, $headings, $activeLast, $activeCur,
|
|||
|
selectors = 'h1,h2,h3', container = 'body', scrollTarget = window, scroller = 'html, body', disabled = false,
|
|||
|
headingsPos, scrolling = false, hasRendered = false, hasInit = false;
|
|||
|
|
|||
|
function setOptions(options) {
|
|||
|
var _options = options || {};
|
|||
|
_options.selectors && (selectors = _options.selectors);
|
|||
|
_options.container && (container = _options.container);
|
|||
|
_options.scrollTarget && (scrollTarget = _options.scrollTarget);
|
|||
|
_options.scroller && (scroller = _options.scroller);
|
|||
|
_options.disabled !== undefined && (disabled = _options.disabled);
|
|||
|
$headings = $(container).find(selectors).filter('[id]');
|
|||
|
$scrollTarget = $(scrollTarget);
|
|||
|
$scroller = $(scroller);
|
|||
|
}
|
|||
|
function calc() {
|
|||
|
headingsPos = [];
|
|||
|
$headings.each(function() {
|
|||
|
headingsPos.push(Math.floor($(this).position().top));
|
|||
|
});
|
|||
|
}
|
|||
|
function setState(element, disabled) {
|
|||
|
var scrollTop = $scrollTarget.scrollTop(), i;
|
|||
|
if (disabled || !headingsPos || headingsPos.length < 1) { return; }
|
|||
|
if (element) {
|
|||
|
$activeCur = element;
|
|||
|
} else {
|
|||
|
for (i = 0; i < headingsPos.length; i++) {
|
|||
|
if (scrollTop >= headingsPos[i]) {
|
|||
|
$activeCur = $tocLi.eq(i);
|
|||
|
} else {
|
|||
|
$activeCur || ($activeCur = $tocLi.eq(i));
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
$activeLast && $activeLast.removeClass('active');
|
|||
|
($activeLast = $activeCur).addClass('active');
|
|||
|
}
|
|||
|
function render() {
|
|||
|
if(!hasRendered) {
|
|||
|
$root.append($tocUl);
|
|||
|
$headings.each(function() {
|
|||
|
var $this = $(this);
|
|||
|
$tocUl.append($('<li></li>').addClass('toc-' + $this.prop('tagName').toLowerCase())
|
|||
|
.append($('<a></a>').text($this.text()).attr('href', '#' + $this.prop('id'))));
|
|||
|
});
|
|||
|
$tocLi = $tocUl.children('li');
|
|||
|
$tocUl.on('click', 'a', function(e) {
|
|||
|
e.preventDefault();
|
|||
|
var $this = $(this);
|
|||
|
scrolling = true;
|
|||
|
setState($this.parent());
|
|||
|
$scroller.scrollToAnchor($this.attr('href'), 400, function() {
|
|||
|
scrolling = false;
|
|||
|
});
|
|||
|
});
|
|||
|
}
|
|||
|
hasRendered = true;
|
|||
|
}
|
|||
|
function init() {
|
|||
|
var interval, timeout;
|
|||
|
if(!hasInit) {
|
|||
|
render(); calc(); setState(null, scrolling);
|
|||
|
// run calc every 100 millisecond
|
|||
|
interval = setInterval(function() {
|
|||
|
calc();
|
|||
|
}, 100);
|
|||
|
timeout = setTimeout(function() {
|
|||
|
clearInterval(interval);
|
|||
|
}, 45000);
|
|||
|
window.pageLoad.then(function() {
|
|||
|
setTimeout(function() {
|
|||
|
clearInterval(interval);
|
|||
|
clearTimeout(timeout);
|
|||
|
}, 3000);
|
|||
|
});
|
|||
|
$scrollTarget.on('scroll', function() {
|
|||
|
disabled || setState(null, scrolling);
|
|||
|
});
|
|||
|
$window.on('resize', window.throttle(function() {
|
|||
|
if (!disabled) {
|
|||
|
render(); calc(); setState(null, scrolling);
|
|||
|
}
|
|||
|
}, 100));
|
|||
|
}
|
|||
|
hasInit = true;
|
|||
|
}
|
|||
|
|
|||
|
setOptions(options);
|
|||
|
if (!disabled) {
|
|||
|
init();
|
|||
|
}
|
|||
|
$window.on('resize', window.throttle(function() {
|
|||
|
init();
|
|||
|
}, 200));
|
|||
|
return {
|
|||
|
setOptions: setOptions
|
|||
|
};
|
|||
|
}
|
|||
|
$.fn.toc = toc;
|
|||
|
});
|
|||
|
})();
|
|||
|
/*(function () {
|
|||
|
|
|||
|
})();*/
|
|||
|
</script><script>
|
|||
|
/* toc must before affix, since affix need to konw toc' height. */(function() {
|
|||
|
var SOURCES = window.TEXT_VARIABLES.sources;
|
|||
|
var TOC_SELECTOR = window.TEXT_VARIABLES.site.toc.selectors;
|
|||
|
window.Lazyload.js(SOURCES.jquery, function() {
|
|||
|
var $window = $(window);
|
|||
|
var $articleContent = $('.js-article-content');
|
|||
|
var $tocRoot = $('.js-toc-root'), $col2 = $('.js-col-aside');
|
|||
|
var toc;
|
|||
|
var tocDisabled = false;
|
|||
|
var hasSidebar = $('.js-page-root').hasClass('layout--page--sidebar');
|
|||
|
var hasToc = $articleContent.find(TOC_SELECTOR).length > 0;
|
|||
|
|
|||
|
function disabled() {
|
|||
|
return $col2.css('display') === 'none' || !hasToc;
|
|||
|
}
|
|||
|
|
|||
|
tocDisabled = disabled();
|
|||
|
|
|||
|
toc = $tocRoot.toc({
|
|||
|
selectors: TOC_SELECTOR,
|
|||
|
container: $articleContent,
|
|||
|
scrollTarget: hasSidebar ? '.js-page-main' : null,
|
|||
|
scroller: hasSidebar ? '.js-page-main' : null,
|
|||
|
disabled: tocDisabled
|
|||
|
});
|
|||
|
|
|||
|
$window.on('resize', window.throttle(function() {
|
|||
|
tocDisabled = disabled();
|
|||
|
toc && toc.setOptions({
|
|||
|
disabled: tocDisabled
|
|||
|
});
|
|||
|
}, 100));
|
|||
|
|
|||
|
});
|
|||
|
})();
|
|||
|
(function() {
|
|||
|
var SOURCES = window.TEXT_VARIABLES.sources;
|
|||
|
window.Lazyload.js(SOURCES.jquery, function() {
|
|||
|
var $window = $(window), $pageFooter = $('.js-page-footer');
|
|||
|
var $pageAside = $('.js-page-aside');
|
|||
|
var affix;
|
|||
|
var tocDisabled = false;
|
|||
|
var hasSidebar = $('.js-page-root').hasClass('layout--page--sidebar');
|
|||
|
|
|||
|
affix = $pageAside.affix({
|
|||
|
offsetBottom: $pageFooter.outerHeight(),
|
|||
|
scrollTarget: hasSidebar ? '.js-page-main' : null,
|
|||
|
scroller: hasSidebar ? '.js-page-main' : null,
|
|||
|
scroll: hasSidebar ? $('.js-page-main').children() : null,
|
|||
|
disabled: tocDisabled
|
|||
|
});
|
|||
|
|
|||
|
$window.on('resize', window.throttle(function() {
|
|||
|
affix && affix.setOptions({
|
|||
|
disabled: tocDisabled
|
|||
|
});
|
|||
|
}, 100));
|
|||
|
|
|||
|
window.pageAsideAffix = affix;
|
|||
|
});
|
|||
|
})();
|
|||
|
</script><!---->
|
|||
|
|
|||
|
</div>
|
|||
|
<script>(function () {
|
|||
|
var $root = document.getElementsByClassName('root')[0];
|
|||
|
if (window.hasEvent('touchstart')) {
|
|||
|
$root.dataset.isTouch = true;
|
|||
|
document.addEventListener('touchstart', function(){}, false);
|
|||
|
}
|
|||
|
})();
|
|||
|
</script>
|
|||
|
</body>
|
|||
|
</html>
|
|||
|
|