[PATCH v2 0/5] qemu_passt: Fix issues with PID file
by Michal Privoznik
This is a v2 of:
https://listman.redhat.com/archives/libvir-list/2023-February/237731.html
diff to v1:
- Merged patches that were ACKed in v1,
- Dropped 4/4 from the original series (the one that sets --foreground),
and implemented a different approach
Michal Prívozník (5):
qemu_passt: Avoid double daemonizing passt
qemu_passt: Report passt's error on failed start
qemu_passt: Make passt report errors to stderr whenever possible
qemu_passt: Deduplicate passt killing code
qemu_passt: Let passt write the PID file
src/qemu/qemu_passt.c | 61 +++++++++++++++++++++++++++++--------------
1 file changed, 41 insertions(+), 20 deletions(-)
--
2.39.1
1 year, 9 months
[PATCH 1/1] WIP: allow update more disk properties
by jshen28
From: ushen <yshxxsjt715(a)gmail.com>
---
src/qemu/qemu_block.c | 2 +-
src/qemu/qemu_block.h | 5 +++++
src/qemu/qemu_domain.c | 2 --
src/qemu/qemu_driver.c | 17 +++++++++++++++++
4 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
index 5e700eff99..778aeebb8f 100644
--- a/src/qemu/qemu_block.c
+++ b/src/qemu/qemu_block.c
@@ -2981,7 +2981,7 @@ qemuBlockReopenFormatMon(qemuMonitor *mon,
* that @src must be already properly configured for the desired outcome. The
* nodenames of @src are used to identify the specific image in qemu.
*/
-static int
+int
qemuBlockReopenFormat(virDomainObj *vm,
virStorageSource *src,
virDomainAsyncJob asyncJob)
diff --git a/src/qemu/qemu_block.h b/src/qemu/qemu_block.h
index 5a61a19da2..9ef692278d 100644
--- a/src/qemu/qemu_block.h
+++ b/src/qemu/qemu_block.h
@@ -245,6 +245,11 @@ int
qemuBlockReopenFormatMon(qemuMonitor *mon,
virStorageSource *src);
+int
+qemuBlockReopenFormat(virDomainObj *vm,
+ virStorageSource *src,
+ virDomainAsyncJob asyncJob);
+
int
qemuBlockReopenReadWrite(virDomainObj *vm,
virStorageSource *src,
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index e9bc0f375d..e5b5fef87e 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -8239,7 +8239,6 @@ qemuDomainDiskChangeSupported(virDomainDiskDef *disk,
CHECK_STREQ_NULLABLE(product,
"product");
- CHECK_EQ(cachemode, "cache", true);
CHECK_EQ(error_policy, "error_policy", true);
CHECK_EQ(rerror_policy, "rerror_policy", true);
CHECK_EQ(iomode, "io", true);
@@ -8267,7 +8266,6 @@ qemuDomainDiskChangeSupported(virDomainDiskDef *disk,
CHECK_EQ(info.bootIndex, "boot order", true);
CHECK_EQ(rawio, "rawio", true);
CHECK_EQ(sgio, "sgio", true);
- CHECK_EQ(discard, "discard", true);
CHECK_EQ(iothread, "iothread", true);
CHECK_STREQ_NULLABLE(domain_name,
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 6154fe9bfe..bcb68d6c66 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6802,6 +6802,7 @@ qemuDomainChangeDiskLive(virDomainObj *vm,
virDomainDiskDef *orig_disk = NULL;
virDomainStartupPolicy origStartupPolicy;
virDomainDeviceDef oldDev = { .type = dev->type };
+ int ret;
if (!(orig_disk = virDomainDiskByTarget(vm->def, disk->dst))) {
virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -6840,6 +6841,22 @@ qemuDomainChangeDiskLive(virDomainObj *vm,
}
dev->data.disk->src = NULL;
+ } else {
+ // reopen disk device with more parameters
+ disk->src->backingStore = orig_disk->src->backingStore;
+ ret = qemuBlockReopenFormat(vm, disk->src, false);
+ disk->src->backingStore = NULL;
+ if (!ret) {
+ orig_disk->cachemode = disk->cachemode;
+ orig_disk->src->cachemode = disk->src->cachemode;
+ orig_disk->detect_zeroes = disk->detect_zeroes;
+ orig_disk->src->detect_zeroes = disk->src->detect_zeroes;
+ orig_disk->discard = disk->discard;
+ orig_disk->src->discard = disk->src->discard;
+ disk->src->backingStore = NULL;
+ } else {
+ return ret;
+ }
}
/* in case when we aren't updating disk source we update startup policy here */
--
2.17.1
1 year, 9 months
[PATCH] docs: ACL: Mention the ACL object name along with the corresponding libvirt object name
by Peter Krempa
It's not trivial to figure out the ACL object name from our
documentation. Add it above the table outlining existing permissions.
Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
scripts/genaclperms.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/scripts/genaclperms.py b/scripts/genaclperms.py
index e228b3ef60..e635dae50b 100755
--- a/scripts/genaclperms.py
+++ b/scripts/genaclperms.py
@@ -91,6 +91,7 @@ for obj in sorted(perms.keys()):
olink = "object_" + obj.lower()
print(' <h3><a id="%s">%s</a></h3>' % (olink, klass))
+ print(' <p>The <b>%s</b> libvirt object is represented as <code>%s</code>.</p>' % (klass, obj.lower()))
print(' <table>')
print(' <thead>')
print(' <tr>')
--
2.39.1
1 year, 9 months
[PATCH] docs: ACL: Show which permissions are allowed for unauthenticated connections
by Peter Krempa
Certain APIs are allowed also without authentication but the ACL page
didn't outline which. Generate a new column with the information.
Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
docs/acl.html.in | 3 ++-
scripts/genaclperms.py | 7 +++++++
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/docs/acl.html.in b/docs/acl.html.in
index 3d0f651864..268d3aebd3 100644
--- a/docs/acl.html.in
+++ b/docs/acl.html.in
@@ -20,7 +20,8 @@
state, where the only API operations allowed are those required
to complete authentication. After successful authentication, a
connection either has full, unrestricted access to all libvirt
- API calls, or is locked down to only "read only" operations,
+ API calls, or is locked down to only "read only" (see 'Anonymous'
+ in the table below) operations,
according to what socket a client connection originated on.
</p>
diff --git a/scripts/genaclperms.py b/scripts/genaclperms.py
index e228b3ef60..43616dad04 100755
--- a/scripts/genaclperms.py
+++ b/scripts/genaclperms.py
@@ -96,6 +96,7 @@ for obj in sorted(perms.keys()):
print(' <tr>')
print(' <th>Permission</th>')
print(' <th>Description</th>')
+ print(' <th>Anonymous</th>')
print(' </tr>')
print(' </thead>')
print(' <tbody>')
@@ -103,6 +104,11 @@ for obj in sorted(perms.keys()):
for perm in sorted(perms[obj].keys()):
description = perms[obj][perm]["desc"]
+ if perms[obj][perm]["anonymous"]:
+ anonymous = 'yes'
+ else:
+ anonymous = ''
+
if description is None:
raise Exception("missing description for %s.%s" % (obj, perm))
@@ -112,6 +118,7 @@ for obj in sorted(perms.keys()):
print(' <tr>')
print(' <td><a id="%s">%s</a></td>' % (plink, perm))
print(' <td>%s</td>' % description)
+ print(' <td>%s</td>' % anonymous)
print(' </tr>')
print(' </tbody>')
--
2.39.1
1 year, 9 months
[PATCH 0/2] Read-only access to node devices
by Peter Krempa
See individual patches.
Peter Krempa (2):
access: Allow 'node-device.read' permission for anonymous users
libvirt-nodedev: Allow read-only access to virNodeDeviceGetAutostart
src/access/viraccessperm.h | 1 +
src/libvirt-nodedev.c | 1 -
2 files changed, 1 insertion(+), 1 deletion(-)
--
2.39.1
1 year, 9 months
[libvirt PATCH] docs: introduce a more interesting 404 error page
by Daniel P. Berrangé
Our 404 error page is a little bit too boring. The solution is to
add more penguins !
This relies on MIT licensed javascript code imported from
https://github.com/VincentGarreau/particles.js
The image is extracted from the existing libvirt logo SVG file.
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
---
docs/404.html.in | 7 +-
docs/css/libvirt.css | 12 +
docs/js/app.js | 108 +++
docs/js/meson.build | 2 +
docs/js/particles.js | 1541 ++++++++++++++++++++++++++++++++++++++++
docs/logos/meson.build | 2 +
docs/logos/penguin.png | Bin 0 -> 4236 bytes
docs/logos/penguin.svg | 358 ++++++++++
docs/page.xsl | 8 +
9 files changed, 2035 insertions(+), 3 deletions(-)
create mode 100644 docs/js/app.js
create mode 100644 docs/js/particles.js
create mode 100644 docs/logos/penguin.png
create mode 100644 docs/logos/penguin.svg
Yes, this could easily be considered an April Fools' joke, but at
the same time it is common to have a bit of fun with 404 error
pages, so it is also a real suggestion :-)
Live example rendering is at:
https://berrange.gitlab.io/-/libvirt/-/jobs/3749944370/artifacts/website/...
The main "cost" of the fun is a few 10's of KB more in the dist
from the JS/SVG/PNG
diff --git a/docs/404.html.in b/docs/404.html.in
index 0ac76f125a..39cded58f6 100644
--- a/docs/404.html.in
+++ b/docs/404.html.in
@@ -5,15 +5,16 @@
<h1>404 page not found</h1>
<p>
- Someone appears to have eaten the <del>penguin</del>
- page you were looking for. You might want to try
+ We can't figure out which <del>penguin</del> page you were
+ looking for. You might want to try
</p>
<ul>
<li>going back to the <a href="https://libvirt.org/">home page</a> to find
a collection of links to interesting pages on this site</li>
<li>using the search box at the top right corner of the screen to
locate the content on this site or mailing list archives</li>
+ <li>selecting the right penguin swimming in the pool below</li>
</ul>
-
+ <div id="particles-js"><!-- preserve --></div>
</body>
</html>
diff --git a/docs/css/libvirt.css b/docs/css/libvirt.css
index 097dfcbe8e..fbd193da74 100644
--- a/docs/css/libvirt.css
+++ b/docs/css/libvirt.css
@@ -636,3 +636,15 @@ th p, td p {
#contents p.topic-title {
display: none;
}
+
+canvas {
+ display: block;
+ vertical-align: bottom;
+}
+
+#particles-js {
+ background-color: rgb(230,250,255);
+ border: 2px solid rgb(150,180,255);
+ width: 100%;
+ height: 100%;
+}
diff --git a/docs/js/app.js b/docs/js/app.js
new file mode 100644
index 0000000000..79fae27c2e
--- /dev/null
+++ b/docs/js/app.js
@@ -0,0 +1,108 @@
+particlesJS('particles-js',
+ {
+ "particles": {
+ "number": {
+ "value": 20,
+ "density": {
+ "enable": true,
+ "value_area": 800
+ }
+ },
+ "color": {
+ "value": "#ff0000"
+ },
+ "shape": {
+ "type": "image",
+ "image": {
+ "src": "logos/penguin.png",
+ "width": 73,
+ "height": 138
+ }
+ },
+ "opacity": {
+ "value": 0.5,
+ "random": true,
+ "anim": {
+ "enable": true,
+ "speed": 1,
+ "opacity_min": 0.1,
+ "sync": false
+ }
+ },
+ "size": {
+ "value": 50,
+ "random": true,
+ "anim": {
+ "enable": false,
+ "speed": 40,
+ "size_min": 0.1,
+ "sync": false
+ }
+ },
+ "line_linked": {
+ "enable": false,
+ },
+ "move": {
+ "enable": true,
+ "speed": 6,
+ "direction": "none",
+ "random": false,
+ "straight": false,
+ "out_mode": "bounce",
+ "attract": {
+ "enable": true,
+ "rotateX": 600,
+ "rotateY": 1200
+ }
+ }
+ },
+ "interactivity": {
+ "detect_on": "canvas",
+ "events": {
+ "onhover": {
+ "enable": true,
+ "mode": "repulse"
+ },
+ "onclick": {
+ "enable": true,
+ "mode": "push"
+ },
+ "resize": true
+ },
+ "modes": {
+ "grab": {
+ "distance": 400,
+ "line_linked": {
+ "opacity": 1
+ }
+ },
+ "bubble": {
+ "distance": 400,
+ "size": 40,
+ "duration": 2,
+ "opacity": 8,
+ "speed": 3
+ },
+ "repulse": {
+ "distance": 200
+ },
+ "push": {
+ "particles_nb": 4
+ },
+ "remove": {
+ "particles_nb": 2
+ }
+ }
+ },
+ "retina_detect": true,
+ "config_demo": {
+ "hide_card": false,
+ "background_color": "#b61924",
+ "background_image": "",
+ "background_position": "50% 50%",
+ "background_repeat": "no-repeat",
+ "background_size": "cover"
+ }
+ }
+
+);
diff --git a/docs/js/meson.build b/docs/js/meson.build
index cbf2dc2633..4e3e05bf89 100644
--- a/docs/js/meson.build
+++ b/docs/js/meson.build
@@ -1,5 +1,7 @@
docs_js_files = [
'main.js',
+ 'particles.js',
+ 'app.js'
]
install_data(docs_js_files, install_dir: docs_html_dir / 'js')
diff --git a/docs/js/particles.js b/docs/js/particles.js
new file mode 100644
index 0000000000..ef3917fab7
--- /dev/null
+++ b/docs/js/particles.js
@@ -0,0 +1,1541 @@
+/* -----------------------------------------------
+/* Author : Vincent Garreau - vincentgarreau.com
+/* MIT license: https://opensource.org/licenses/MIT
+/* Demo / Generator : vincentgarreau.com/particles.js
+/* GitHub : github.com/VincentGarreau/particles.js
+/* How to use? : Check the GitHub README
+/* v2.0.0
+/* ----------------------------------------------- */
+
+var pJS = function(tag_id, params){
+
+ var canvas_el = document.querySelector('#'+tag_id+' > .particles-js-canvas-el');
+
+ /* particles.js variables with default values */
+ this.pJS = {
+ canvas: {
+ el: canvas_el,
+ w: canvas_el.offsetWidth,
+ h: canvas_el.offsetHeight
+ },
+ particles: {
+ number: {
+ value: 400,
+ density: {
+ enable: true,
+ value_area: 800
+ }
+ },
+ color: {
+ value: '#fff'
+ },
+ shape: {
+ type: 'circle',
+ stroke: {
+ width: 0,
+ color: '#ff0000'
+ },
+ polygon: {
+ nb_sides: 5
+ },
+ image: {
+ src: '',
+ width: 100,
+ height: 100
+ }
+ },
+ opacity: {
+ value: 1,
+ random: false,
+ anim: {
+ enable: false,
+ speed: 2,
+ opacity_min: 0,
+ sync: false
+ }
+ },
+ size: {
+ value: 20,
+ random: false,
+ anim: {
+ enable: false,
+ speed: 20,
+ size_min: 0,
+ sync: false
+ }
+ },
+ line_linked: {
+ enable: true,
+ distance: 100,
+ color: '#fff',
+ opacity: 1,
+ width: 1
+ },
+ move: {
+ enable: true,
+ speed: 2,
+ direction: 'none',
+ random: false,
+ straight: false,
+ out_mode: 'out',
+ bounce: false,
+ attract: {
+ enable: false,
+ rotateX: 3000,
+ rotateY: 3000
+ }
+ },
+ array: []
+ },
+ interactivity: {
+ detect_on: 'canvas',
+ events: {
+ onhover: {
+ enable: true,
+ mode: 'grab'
+ },
+ onclick: {
+ enable: true,
+ mode: 'push'
+ },
+ resize: true
+ },
+ modes: {
+ grab:{
+ distance: 100,
+ line_linked:{
+ opacity: 1
+ }
+ },
+ bubble:{
+ distance: 200,
+ size: 80,
+ duration: 0.4
+ },
+ repulse:{
+ distance: 200,
+ duration: 0.4
+ },
+ push:{
+ particles_nb: 4
+ },
+ remove:{
+ particles_nb: 2
+ }
+ },
+ mouse:{}
+ },
+ retina_detect: false,
+ fn: {
+ interact: {},
+ modes: {},
+ vendors:{}
+ },
+ tmp: {}
+ };
+
+ var pJS = this.pJS;
+
+ /* params settings */
+ if(params){
+ Object.deepExtend(pJS, params);
+ }
+
+ pJS.tmp.obj = {
+ size_value: pJS.particles.size.value,
+ size_anim_speed: pJS.particles.size.anim.speed,
+ move_speed: pJS.particles.move.speed,
+ line_linked_distance: pJS.particles.line_linked.distance,
+ line_linked_width: pJS.particles.line_linked.width,
+ mode_grab_distance: pJS.interactivity.modes.grab.distance,
+ mode_bubble_distance: pJS.interactivity.modes.bubble.distance,
+ mode_bubble_size: pJS.interactivity.modes.bubble.size,
+ mode_repulse_distance: pJS.interactivity.modes.repulse.distance
+ };
+
+
+ pJS.fn.retinaInit = function(){
+
+ if(pJS.retina_detect && window.devicePixelRatio > 1){
+ pJS.canvas.pxratio = window.devicePixelRatio;
+ pJS.tmp.retina = true;
+ }
+ else{
+ pJS.canvas.pxratio = 1;
+ pJS.tmp.retina = false;
+ }
+
+ pJS.canvas.w = pJS.canvas.el.offsetWidth * pJS.canvas.pxratio;
+ pJS.canvas.h = pJS.canvas.el.offsetHeight * pJS.canvas.pxratio;
+
+ pJS.particles.size.value = pJS.tmp.obj.size_value * pJS.canvas.pxratio;
+ pJS.particles.size.anim.speed = pJS.tmp.obj.size_anim_speed * pJS.canvas.pxratio;
+ pJS.particles.move.speed = pJS.tmp.obj.move_speed * pJS.canvas.pxratio;
+ pJS.particles.line_linked.distance = pJS.tmp.obj.line_linked_distance * pJS.canvas.pxratio;
+ pJS.interactivity.modes.grab.distance = pJS.tmp.obj.mode_grab_distance * pJS.canvas.pxratio;
+ pJS.interactivity.modes.bubble.distance = pJS.tmp.obj.mode_bubble_distance * pJS.canvas.pxratio;
+ pJS.particles.line_linked.width = pJS.tmp.obj.line_linked_width * pJS.canvas.pxratio;
+ pJS.interactivity.modes.bubble.size = pJS.tmp.obj.mode_bubble_size * pJS.canvas.pxratio;
+ pJS.interactivity.modes.repulse.distance = pJS.tmp.obj.mode_repulse_distance * pJS.canvas.pxratio;
+
+ };
+
+
+
+ /* ---------- pJS functions - canvas ------------ */
+
+ pJS.fn.canvasInit = function(){
+ pJS.canvas.ctx = pJS.canvas.el.getContext('2d');
+ };
+
+ pJS.fn.canvasSize = function(){
+
+ pJS.canvas.el.width = pJS.canvas.w;
+ pJS.canvas.el.height = pJS.canvas.h;
+
+ if(pJS && pJS.interactivity.events.resize){
+
+ window.addEventListener('resize', function(){
+
+ pJS.canvas.w = pJS.canvas.el.offsetWidth;
+ pJS.canvas.h = pJS.canvas.el.offsetHeight;
+
+ /* resize canvas */
+ if(pJS.tmp.retina){
+ pJS.canvas.w *= pJS.canvas.pxratio;
+ pJS.canvas.h *= pJS.canvas.pxratio;
+ }
+
+ pJS.canvas.el.width = pJS.canvas.w;
+ pJS.canvas.el.height = pJS.canvas.h;
+
+ /* repaint canvas on anim disabled */
+ if(!pJS.particles.move.enable){
+ pJS.fn.particlesEmpty();
+ pJS.fn.particlesCreate();
+ pJS.fn.particlesDraw();
+ pJS.fn.vendors.densityAutoParticles();
+ }
+
+ /* density particles enabled */
+ pJS.fn.vendors.densityAutoParticles();
+
+ });
+
+ }
+
+ };
+
+
+ pJS.fn.canvasPaint = function(){
+ pJS.canvas.ctx.fillRect(0, 0, pJS.canvas.w, pJS.canvas.h);
+ };
+
+ pJS.fn.canvasClear = function(){
+ pJS.canvas.ctx.clearRect(0, 0, pJS.canvas.w, pJS.canvas.h);
+ };
+
+
+ /* --------- pJS functions - particles ----------- */
+
+ pJS.fn.particle = function(color, opacity, position){
+
+ /* size */
+ this.radius = (pJS.particles.size.random ? Math.random() : 1) * pJS.particles.size.value;
+ if(pJS.particles.size.anim.enable){
+ this.size_status = false;
+ this.vs = pJS.particles.size.anim.speed / 100;
+ if(!pJS.particles.size.anim.sync){
+ this.vs = this.vs * Math.random();
+ }
+ }
+
+ /* position */
+ this.x = position ? position.x : Math.random() * pJS.canvas.w;
+ this.y = position ? position.y : Math.random() * pJS.canvas.h;
+
+ /* check position - into the canvas */
+ if(this.x > pJS.canvas.w - this.radius*2) this.x = this.x - this.radius;
+ else if(this.x < this.radius*2) this.x = this.x + this.radius;
+ if(this.y > pJS.canvas.h - this.radius*2) this.y = this.y - this.radius;
+ else if(this.y < this.radius*2) this.y = this.y + this.radius;
+
+ /* check position - avoid overlap */
+ if(pJS.particles.move.bounce){
+ pJS.fn.vendors.checkOverlap(this, position);
+ }
+
+ /* color */
+ this.color = {};
+ if(typeof(color.value) == 'object'){
+
+ if(color.value instanceof Array){
+ var color_selected = color.value[Math.floor(Math.random() * pJS.particles.color.value.length)];
+ this.color.rgb = hexToRgb(color_selected);
+ }else{
+ if(color.value.r != undefined && color.value.g != undefined && color.value.b != undefined){
+ this.color.rgb = {
+ r: color.value.r,
+ g: color.value.g,
+ b: color.value.b
+ }
+ }
+ if(color.value.h != undefined && color.value.s != undefined && color.value.l != undefined){
+ this.color.hsl = {
+ h: color.value.h,
+ s: color.value.s,
+ l: color.value.l
+ }
+ }
+ }
+
+ }
+ else if(color.value == 'random'){
+ this.color.rgb = {
+ r: (Math.floor(Math.random() * (255 - 0 + 1)) + 0),
+ g: (Math.floor(Math.random() * (255 - 0 + 1)) + 0),
+ b: (Math.floor(Math.random() * (255 - 0 + 1)) + 0)
+ }
+ }
+ else if(typeof(color.value) == 'string'){
+ this.color = color;
+ this.color.rgb = hexToRgb(this.color.value);
+ }
+
+ /* opacity */
+ this.opacity = (pJS.particles.opacity.random ? Math.random() : 1) * pJS.particles.opacity.value;
+ if(pJS.particles.opacity.anim.enable){
+ this.opacity_status = false;
+ this.vo = pJS.particles.opacity.anim.speed / 100;
+ if(!pJS.particles.opacity.anim.sync){
+ this.vo = this.vo * Math.random();
+ }
+ }
+
+ /* animation - velocity for speed */
+ var velbase = {}
+ switch(pJS.particles.move.direction){
+ case 'top':
+ velbase = { x:0, y:-1 };
+ break;
+ case 'top-right':
+ velbase = { x:0.5, y:-0.5 };
+ break;
+ case 'right':
+ velbase = { x:1, y:-0 };
+ break;
+ case 'bottom-right':
+ velbase = { x:0.5, y:0.5 };
+ break;
+ case 'bottom':
+ velbase = { x:0, y:1 };
+ break;
+ case 'bottom-left':
+ velbase = { x:-0.5, y:1 };
+ break;
+ case 'left':
+ velbase = { x:-1, y:0 };
+ break;
+ case 'top-left':
+ velbase = { x:-0.5, y:-0.5 };
+ break;
+ default:
+ velbase = { x:0, y:0 };
+ break;
+ }
+
+ if(pJS.particles.move.straight){
+ this.vx = velbase.x;
+ this.vy = velbase.y;
+ if(pJS.particles.move.random){
+ this.vx = this.vx * (Math.random());
+ this.vy = this.vy * (Math.random());
+ }
+ }else{
+ this.vx = velbase.x + Math.random()-0.5;
+ this.vy = velbase.y + Math.random()-0.5;
+ }
+
+ // var theta = 2.0 * Math.PI * Math.random();
+ // this.vx = Math.cos(theta);
+ // this.vy = Math.sin(theta);
+
+ this.vx_i = this.vx;
+ this.vy_i = this.vy;
+
+
+
+ /* if shape is image */
+
+ var shape_type = pJS.particles.shape.type;
+ if(typeof(shape_type) == 'object'){
+ if(shape_type instanceof Array){
+ var shape_selected = shape_type[Math.floor(Math.random() * shape_type.length)];
+ this.shape = shape_selected;
+ }
+ }else{
+ this.shape = shape_type;
+ }
+
+ if(this.shape == 'image'){
+ var sh = pJS.particles.shape;
+ this.img = {
+ src: sh.image.src,
+ ratio: sh.image.width / sh.image.height
+ }
+ if(!this.img.ratio) this.img.ratio = 1;
+ if(pJS.tmp.img_type == 'svg' && pJS.tmp.source_svg != undefined){
+ pJS.fn.vendors.createSvgImg(this);
+ if(pJS.tmp.pushing){
+ this.img.loaded = false;
+ }
+ }
+ }
+
+
+
+ };
+
+
+ pJS.fn.particle.prototype.draw = function() {
+
+ var p = this;
+
+ if(p.radius_bubble != undefined){
+ var radius = p.radius_bubble;
+ }else{
+ var radius = p.radius;
+ }
+
+ if(p.opacity_bubble != undefined){
+ var opacity = p.opacity_bubble;
+ }else{
+ var opacity = p.opacity;
+ }
+
+ if(p.color.rgb){
+ var color_value = 'rgba('+p.color.rgb.r+','+p.color.rgb.g+','+p.color.rgb.b+','+opacity+')';
+ }else{
+ var color_value = 'hsla('+p.color.hsl.h+','+p.color.hsl.s+'%,'+p.color.hsl.l+'%,'+opacity+')';
+ }
+
+ pJS.canvas.ctx.fillStyle = color_value;
+ pJS.canvas.ctx.beginPath();
+
+ switch(p.shape){
+
+ case 'circle':
+ pJS.canvas.ctx.arc(p.x, p.y, radius, 0, Math.PI * 2, false);
+ break;
+
+ case 'edge':
+ pJS.canvas.ctx.rect(p.x-radius, p.y-radius, radius*2, radius*2);
+ break;
+
+ case 'triangle':
+ pJS.fn.vendors.drawShape(pJS.canvas.ctx, p.x-radius, p.y+radius / 1.66, radius*2, 3, 2);
+ break;
+
+ case 'polygon':
+ pJS.fn.vendors.drawShape(
+ pJS.canvas.ctx,
+ p.x - radius / (pJS.particles.shape.polygon.nb_sides/3.5), // startX
+ p.y - radius / (2.66/3.5), // startY
+ radius*2.66 / (pJS.particles.shape.polygon.nb_sides/3), // sideLength
+ pJS.particles.shape.polygon.nb_sides, // sideCountNumerator
+ 1 // sideCountDenominator
+ );
+ break;
+
+ case 'star':
+ pJS.fn.vendors.drawShape(
+ pJS.canvas.ctx,
+ p.x - radius*2 / (pJS.particles.shape.polygon.nb_sides/4), // startX
+ p.y - radius / (2*2.66/3.5), // startY
+ radius*2*2.66 / (pJS.particles.shape.polygon.nb_sides/3), // sideLength
+ pJS.particles.shape.polygon.nb_sides, // sideCountNumerator
+ 2 // sideCountDenominator
+ );
+ break;
+
+ case 'image':
+
+ function draw(){
+ pJS.canvas.ctx.drawImage(
+ img_obj,
+ p.x-radius,
+ p.y-radius,
+ radius*2,
+ radius*2 / p.img.ratio
+ );
+ }
+
+ if(pJS.tmp.img_type == 'svg'){
+ var img_obj = p.img.obj;
+ }else{
+ var img_obj = pJS.tmp.img_obj;
+ }
+
+ if(img_obj){
+ draw();
+ }
+
+ break;
+
+ }
+
+ pJS.canvas.ctx.closePath();
+
+ if(pJS.particles.shape.stroke.width > 0){
+ pJS.canvas.ctx.strokeStyle = pJS.particles.shape.stroke.color;
+ pJS.canvas.ctx.lineWidth = pJS.particles.shape.stroke.width;
+ pJS.canvas.ctx.stroke();
+ }
+
+ pJS.canvas.ctx.fill();
+
+ };
+
+
+ pJS.fn.particlesCreate = function(){
+ for(var i = 0; i < pJS.particles.number.value; i++) {
+ pJS.particles.array.push(new pJS.fn.particle(pJS.particles.color, pJS.particles.opacity.value));
+ }
+ };
+
+ pJS.fn.particlesUpdate = function(){
+
+ for(var i = 0; i < pJS.particles.array.length; i++){
+
+ /* the particle */
+ var p = pJS.particles.array[i];
+
+ // var d = ( dx = pJS.interactivity.mouse.click_pos_x - p.x ) * dx + ( dy = pJS.interactivity.mouse.click_pos_y - p.y ) * dy;
+ // var f = -BANG_SIZE / d;
+ // if ( d < BANG_SIZE ) {
+ // var t = Math.atan2( dy, dx );
+ // p.vx = f * Math.cos(t);
+ // p.vy = f * Math.sin(t);
+ // }
+
+ /* move the particle */
+ if(pJS.particles.move.enable){
+ var ms = pJS.particles.move.speed/2;
+ p.x += p.vx * ms;
+ p.y += p.vy * ms;
+ }
+
+ /* change opacity status */
+ if(pJS.particles.opacity.anim.enable) {
+ if(p.opacity_status == true) {
+ if(p.opacity >= pJS.particles.opacity.value) p.opacity_status = false;
+ p.opacity += p.vo;
+ }else {
+ if(p.opacity <= pJS.particles.opacity.anim.opacity_min) p.opacity_status = true;
+ p.opacity -= p.vo;
+ }
+ if(p.opacity < 0) p.opacity = 0;
+ }
+
+ /* change size */
+ if(pJS.particles.size.anim.enable){
+ if(p.size_status == true){
+ if(p.radius >= pJS.particles.size.value) p.size_status = false;
+ p.radius += p.vs;
+ }else{
+ if(p.radius <= pJS.particles.size.anim.size_min) p.size_status = true;
+ p.radius -= p.vs;
+ }
+ if(p.radius < 0) p.radius = 0;
+ }
+
+ /* change particle position if it is out of canvas */
+ if(pJS.particles.move.out_mode == 'bounce'){
+ var new_pos = {
+ x_left: p.radius,
+ x_right: pJS.canvas.w,
+ y_top: p.radius,
+ y_bottom: pJS.canvas.h
+ }
+ }else{
+ var new_pos = {
+ x_left: -p.radius,
+ x_right: pJS.canvas.w + p.radius,
+ y_top: -p.radius,
+ y_bottom: pJS.canvas.h + p.radius
+ }
+ }
+
+ if(p.x - p.radius > pJS.canvas.w){
+ p.x = new_pos.x_left;
+ p.y = Math.random() * pJS.canvas.h;
+ }
+ else if(p.x + p.radius < 0){
+ p.x = new_pos.x_right;
+ p.y = Math.random() * pJS.canvas.h;
+ }
+ if(p.y - p.radius > pJS.canvas.h){
+ p.y = new_pos.y_top;
+ p.x = Math.random() * pJS.canvas.w;
+ }
+ else if(p.y + p.radius < 0){
+ p.y = new_pos.y_bottom;
+ p.x = Math.random() * pJS.canvas.w;
+ }
+
+ /* out of canvas modes */
+ switch(pJS.particles.move.out_mode){
+ case 'bounce':
+ if (p.x + p.radius > pJS.canvas.w) p.vx = -p.vx;
+ else if (p.x - p.radius < 0) p.vx = -p.vx;
+ if (p.y + p.radius > pJS.canvas.h) p.vy = -p.vy;
+ else if (p.y - p.radius < 0) p.vy = -p.vy;
+ break;
+ }
+
+ /* events */
+ if(isInArray('grab', pJS.interactivity.events.onhover.mode)){
+ pJS.fn.modes.grabParticle(p);
+ }
+
+ if(isInArray('bubble', pJS.interactivity.events.onhover.mode) || isInArray('bubble', pJS.interactivity.events.onclick.mode)){
+ pJS.fn.modes.bubbleParticle(p);
+ }
+
+ if(isInArray('repulse', pJS.interactivity.events.onhover.mode) || isInArray('repulse', pJS.interactivity.events.onclick.mode)){
+ pJS.fn.modes.repulseParticle(p);
+ }
+
+ /* interaction auto between particles */
+ if(pJS.particles.line_linked.enable || pJS.particles.move.attract.enable){
+ for(var j = i + 1; j < pJS.particles.array.length; j++){
+ var p2 = pJS.particles.array[j];
+
+ /* link particles */
+ if(pJS.particles.line_linked.enable){
+ pJS.fn.interact.linkParticles(p,p2);
+ }
+
+ /* attract particles */
+ if(pJS.particles.move.attract.enable){
+ pJS.fn.interact.attractParticles(p,p2);
+ }
+
+ /* bounce particles */
+ if(pJS.particles.move.bounce){
+ pJS.fn.interact.bounceParticles(p,p2);
+ }
+
+ }
+ }
+
+
+ }
+
+ };
+
+ pJS.fn.particlesDraw = function(){
+
+ /* clear canvas */
+ pJS.canvas.ctx.clearRect(0, 0, pJS.canvas.w, pJS.canvas.h);
+
+ /* update each particles param */
+ pJS.fn.particlesUpdate();
+
+ /* draw each particle */
+ for(var i = 0; i < pJS.particles.array.length; i++){
+ var p = pJS.particles.array[i];
+ p.draw();
+ }
+
+ };
+
+ pJS.fn.particlesEmpty = function(){
+ pJS.particles.array = [];
+ };
+
+ pJS.fn.particlesRefresh = function(){
+
+ /* init all */
+ cancelRequestAnimFrame(pJS.fn.checkAnimFrame);
+ cancelRequestAnimFrame(pJS.fn.drawAnimFrame);
+ pJS.tmp.source_svg = undefined;
+ pJS.tmp.img_obj = undefined;
+ pJS.tmp.count_svg = 0;
+ pJS.fn.particlesEmpty();
+ pJS.fn.canvasClear();
+
+ /* restart */
+ pJS.fn.vendors.start();
+
+ };
+
+
+ /* ---------- pJS functions - particles interaction ------------ */
+
+ pJS.fn.interact.linkParticles = function(p1, p2){
+
+ var dx = p1.x - p2.x,
+ dy = p1.y - p2.y,
+ dist = Math.sqrt(dx*dx + dy*dy);
+
+ /* draw a line between p1 and p2 if the distance between them is under the config distance */
+ if(dist <= pJS.particles.line_linked.distance){
+
+ var opacity_line = pJS.particles.line_linked.opacity - (dist / (1/pJS.particles.line_linked.opacity)) / pJS.particles.line_linked.distance;
+
+ if(opacity_line > 0){
+
+ /* style */
+ var color_line = pJS.particles.line_linked.color_rgb_line;
+ pJS.canvas.ctx.strokeStyle = 'rgba('+color_line.r+','+color_line.g+','+color_line.b+','+opacity_line+')';
+ pJS.canvas.ctx.lineWidth = pJS.particles.line_linked.width;
+ //pJS.canvas.ctx.lineCap = 'round'; /* performance issue */
+
+ /* path */
+ pJS.canvas.ctx.beginPath();
+ pJS.canvas.ctx.moveTo(p1.x, p1.y);
+ pJS.canvas.ctx.lineTo(p2.x, p2.y);
+ pJS.canvas.ctx.stroke();
+ pJS.canvas.ctx.closePath();
+
+ }
+
+ }
+
+ };
+
+
+ pJS.fn.interact.attractParticles = function(p1, p2){
+
+ /* condensed particles */
+ var dx = p1.x - p2.x,
+ dy = p1.y - p2.y,
+ dist = Math.sqrt(dx*dx + dy*dy);
+
+ if(dist <= pJS.particles.line_linked.distance){
+
+ var ax = dx/(pJS.particles.move.attract.rotateX*1000),
+ ay = dy/(pJS.particles.move.attract.rotateY*1000);
+
+ p1.vx -= ax;
+ p1.vy -= ay;
+
+ p2.vx += ax;
+ p2.vy += ay;
+
+ }
+
+
+ }
+
+
+ pJS.fn.interact.bounceParticles = function(p1, p2){
+
+ var dx = p1.x - p2.x,
+ dy = p1.y - p2.y,
+ dist = Math.sqrt(dx*dx + dy*dy),
+ dist_p = p1.radius+p2.radius;
+
+ if(dist <= dist_p){
+ p1.vx = -p1.vx;
+ p1.vy = -p1.vy;
+
+ p2.vx = -p2.vx;
+ p2.vy = -p2.vy;
+ }
+
+ }
+
+
+ /* ---------- pJS functions - modes events ------------ */
+
+ pJS.fn.modes.pushParticles = function(nb, pos){
+
+ pJS.tmp.pushing = true;
+
+ for(var i = 0; i < nb; i++){
+ pJS.particles.array.push(
+ new pJS.fn.particle(
+ pJS.particles.color,
+ pJS.particles.opacity.value,
+ {
+ 'x': pos ? pos.pos_x : Math.random() * pJS.canvas.w,
+ 'y': pos ? pos.pos_y : Math.random() * pJS.canvas.h
+ }
+ )
+ )
+ if(i == nb-1){
+ if(!pJS.particles.move.enable){
+ pJS.fn.particlesDraw();
+ }
+ pJS.tmp.pushing = false;
+ }
+ }
+
+ };
+
+
+ pJS.fn.modes.removeParticles = function(nb){
+
+ pJS.particles.array.splice(0, nb);
+ if(!pJS.particles.move.enable){
+ pJS.fn.particlesDraw();
+ }
+
+ };
+
+
+ pJS.fn.modes.bubbleParticle = function(p){
+
+ /* on hover event */
+ if(pJS.interactivity.events.onhover.enable && isInArray('bubble', pJS.interactivity.events.onhover.mode)){
+
+ var dx_mouse = p.x - pJS.interactivity.mouse.pos_x,
+ dy_mouse = p.y - pJS.interactivity.mouse.pos_y,
+ dist_mouse = Math.sqrt(dx_mouse*dx_mouse + dy_mouse*dy_mouse),
+ ratio = 1 - dist_mouse / pJS.interactivity.modes.bubble.distance;
+
+ function init(){
+ p.opacity_bubble = p.opacity;
+ p.radius_bubble = p.radius;
+ }
+
+ /* mousemove - check ratio */
+ if(dist_mouse <= pJS.interactivity.modes.bubble.distance){
+
+ if(ratio >= 0 && pJS.interactivity.status == 'mousemove'){
+
+ /* size */
+ if(pJS.interactivity.modes.bubble.size != pJS.particles.size.value){
+
+ if(pJS.interactivity.modes.bubble.size > pJS.particles.size.value){
+ var size = p.radius + (pJS.interactivity.modes.bubble.size*ratio);
+ if(size >= 0){
+ p.radius_bubble = size;
+ }
+ }else{
+ var dif = p.radius - pJS.interactivity.modes.bubble.size,
+ size = p.radius - (dif*ratio);
+ if(size > 0){
+ p.radius_bubble = size;
+ }else{
+ p.radius_bubble = 0;
+ }
+ }
+
+ }
+
+ /* opacity */
+ if(pJS.interactivity.modes.bubble.opacity != pJS.particles.opacity.value){
+
+ if(pJS.interactivity.modes.bubble.opacity > pJS.particles.opacity.value){
+ var opacity = pJS.interactivity.modes.bubble.opacity*ratio;
+ if(opacity > p.opacity && opacity <= pJS.interactivity.modes.bubble.opacity){
+ p.opacity_bubble = opacity;
+ }
+ }else{
+ var opacity = p.opacity - (pJS.particles.opacity.value-pJS.interactivity.modes.bubble.opacity)*ratio;
+ if(opacity < p.opacity && opacity >= pJS.interactivity.modes.bubble.opacity){
+ p.opacity_bubble = opacity;
+ }
+ }
+
+ }
+
+ }
+
+ }else{
+ init();
+ }
+
+
+ /* mouseleave */
+ if(pJS.interactivity.status == 'mouseleave'){
+ init();
+ }
+
+ }
+
+ /* on click event */
+ else if(pJS.interactivity.events.onclick.enable && isInArray('bubble', pJS.interactivity.events.onclick.mode)){
+
+
+ if(pJS.tmp.bubble_clicking){
+ var dx_mouse = p.x - pJS.interactivity.mouse.click_pos_x,
+ dy_mouse = p.y - pJS.interactivity.mouse.click_pos_y,
+ dist_mouse = Math.sqrt(dx_mouse*dx_mouse + dy_mouse*dy_mouse),
+ time_spent = (new Date().getTime() - pJS.interactivity.mouse.click_time)/1000;
+
+ if(time_spent > pJS.interactivity.modes.bubble.duration){
+ pJS.tmp.bubble_duration_end = true;
+ }
+
+ if(time_spent > pJS.interactivity.modes.bubble.duration*2){
+ pJS.tmp.bubble_clicking = false;
+ pJS.tmp.bubble_duration_end = false;
+ }
+ }
+
+
+ function process(bubble_param, particles_param, p_obj_bubble, p_obj, id){
+
+ if(bubble_param != particles_param){
+
+ if(!pJS.tmp.bubble_duration_end){
+ if(dist_mouse <= pJS.interactivity.modes.bubble.distance){
+ if(p_obj_bubble != undefined) var obj = p_obj_bubble;
+ else var obj = p_obj;
+ if(obj != bubble_param){
+ var value = p_obj - (time_spent * (p_obj - bubble_param) / pJS.interactivity.modes.bubble.duration);
+ if(id == 'size') p.radius_bubble = value;
+ if(id == 'opacity') p.opacity_bubble = value;
+ }
+ }else{
+ if(id == 'size') p.radius_bubble = undefined;
+ if(id == 'opacity') p.opacity_bubble = undefined;
+ }
+ }else{
+ if(p_obj_bubble != undefined){
+ var value_tmp = p_obj - (time_spent * (p_obj - bubble_param) / pJS.interactivity.modes.bubble.duration),
+ dif = bubble_param - value_tmp;
+ value = bubble_param + dif;
+ if(id == 'size') p.radius_bubble = value;
+ if(id == 'opacity') p.opacity_bubble = value;
+ }
+ }
+
+ }
+
+ }
+
+ if(pJS.tmp.bubble_clicking){
+ /* size */
+ process(pJS.interactivity.modes.bubble.size, pJS.particles.size.value, p.radius_bubble, p.radius, 'size');
+ /* opacity */
+ process(pJS.interactivity.modes.bubble.opacity, pJS.particles.opacity.value, p.opacity_bubble, p.opacity, 'opacity');
+ }
+
+ }
+
+ };
+
+
+ pJS.fn.modes.repulseParticle = function(p){
+
+ if(pJS.interactivity.events.onhover.enable && isInArray('repulse', pJS.interactivity.events.onhover.mode) && pJS.interactivity.status == 'mousemove') {
+
+ var dx_mouse = p.x - pJS.interactivity.mouse.pos_x,
+ dy_mouse = p.y - pJS.interactivity.mouse.pos_y,
+ dist_mouse = Math.sqrt(dx_mouse*dx_mouse + dy_mouse*dy_mouse);
+
+ var normVec = {x: dx_mouse/dist_mouse, y: dy_mouse/dist_mouse},
+ repulseRadius = pJS.interactivity.modes.repulse.distance,
+ velocity = 100,
+ repulseFactor = clamp((1/repulseRadius)*(-1*Math.pow(dist_mouse/repulseRadius,2)+1)*repulseRadius*velocity, 0, 50);
+
+ var pos = {
+ x: p.x + normVec.x * repulseFactor,
+ y: p.y + normVec.y * repulseFactor
+ }
+
+ if(pJS.particles.move.out_mode == 'bounce'){
+ if(pos.x - p.radius > 0 && pos.x + p.radius < pJS.canvas.w) p.x = pos.x;
+ if(pos.y - p.radius > 0 && pos.y + p.radius < pJS.canvas.h) p.y = pos.y;
+ }else{
+ p.x = pos.x;
+ p.y = pos.y;
+ }
+
+ }
+
+
+ else if(pJS.interactivity.events.onclick.enable && isInArray('repulse', pJS.interactivity.events.onclick.mode)) {
+
+ if(!pJS.tmp.repulse_finish){
+ pJS.tmp.repulse_count++;
+ if(pJS.tmp.repulse_count == pJS.particles.array.length){
+ pJS.tmp.repulse_finish = true;
+ }
+ }
+
+ if(pJS.tmp.repulse_clicking){
+
+ var repulseRadius = Math.pow(pJS.interactivity.modes.repulse.distance/6, 3);
+
+ var dx = pJS.interactivity.mouse.click_pos_x - p.x,
+ dy = pJS.interactivity.mouse.click_pos_y - p.y,
+ d = dx*dx + dy*dy;
+
+ var force = -repulseRadius / d * 1;
+
+ function process(){
+
+ var f = Math.atan2(dy,dx);
+ p.vx = force * Math.cos(f);
+ p.vy = force * Math.sin(f);
+
+ if(pJS.particles.move.out_mode == 'bounce'){
+ var pos = {
+ x: p.x + p.vx,
+ y: p.y + p.vy
+ }
+ if (pos.x + p.radius > pJS.canvas.w) p.vx = -p.vx;
+ else if (pos.x - p.radius < 0) p.vx = -p.vx;
+ if (pos.y + p.radius > pJS.canvas.h) p.vy = -p.vy;
+ else if (pos.y - p.radius < 0) p.vy = -p.vy;
+ }
+
+ }
+
+ // default
+ if(d <= repulseRadius){
+ process();
+ }
+
+ // bang - slow motion mode
+ // if(!pJS.tmp.repulse_finish){
+ // if(d <= repulseRadius){
+ // process();
+ // }
+ // }else{
+ // process();
+ // }
+
+
+ }else{
+
+ if(pJS.tmp.repulse_clicking == false){
+
+ p.vx = p.vx_i;
+ p.vy = p.vy_i;
+
+ }
+
+ }
+
+ }
+
+ }
+
+
+ pJS.fn.modes.grabParticle = function(p){
+
+ if(pJS.interactivity.events.onhover.enable && pJS.interactivity.status == 'mousemove'){
+
+ var dx_mouse = p.x - pJS.interactivity.mouse.pos_x,
+ dy_mouse = p.y - pJS.interactivity.mouse.pos_y,
+ dist_mouse = Math.sqrt(dx_mouse*dx_mouse + dy_mouse*dy_mouse);
+
+ /* draw a line between the cursor and the particle if the distance between them is under the config distance */
+ if(dist_mouse <= pJS.interactivity.modes.grab.distance){
+
+ var opacity_line = pJS.interactivity.modes.grab.line_linked.opacity - (dist_mouse / (1/pJS.interactivity.modes.grab.line_linked.opacity)) / pJS.interactivity.modes.grab.distance;
+
+ if(opacity_line > 0){
+
+ /* style */
+ var color_line = pJS.particles.line_linked.color_rgb_line;
+ pJS.canvas.ctx.strokeStyle = 'rgba('+color_line.r+','+color_line.g+','+color_line.b+','+opacity_line+')';
+ pJS.canvas.ctx.lineWidth = pJS.particles.line_linked.width;
+ //pJS.canvas.ctx.lineCap = 'round'; /* performance issue */
+
+ /* path */
+ pJS.canvas.ctx.beginPath();
+ pJS.canvas.ctx.moveTo(p.x, p.y);
+ pJS.canvas.ctx.lineTo(pJS.interactivity.mouse.pos_x, pJS.interactivity.mouse.pos_y);
+ pJS.canvas.ctx.stroke();
+ pJS.canvas.ctx.closePath();
+
+ }
+
+ }
+
+ }
+
+ };
+
+
+
+ /* ---------- pJS functions - vendors ------------ */
+
+ pJS.fn.vendors.eventsListeners = function(){
+
+ /* events target element */
+ if(pJS.interactivity.detect_on == 'window'){
+ pJS.interactivity.el = window;
+ }else{
+ pJS.interactivity.el = pJS.canvas.el;
+ }
+
+
+ /* detect mouse pos - on hover / click event */
+ if(pJS.interactivity.events.onhover.enable || pJS.interactivity.events.onclick.enable){
+
+ /* el on mousemove */
+ pJS.interactivity.el.addEventListener('mousemove', function(e){
+
+ if(pJS.interactivity.el == window){
+ var pos_x = e.clientX,
+ pos_y = e.clientY;
+ }
+ else{
+ var pos_x = e.offsetX || e.clientX,
+ pos_y = e.offsetY || e.clientY;
+ }
+
+ pJS.interactivity.mouse.pos_x = pos_x;
+ pJS.interactivity.mouse.pos_y = pos_y;
+
+ if(pJS.tmp.retina){
+ pJS.interactivity.mouse.pos_x *= pJS.canvas.pxratio;
+ pJS.interactivity.mouse.pos_y *= pJS.canvas.pxratio;
+ }
+
+ pJS.interactivity.status = 'mousemove';
+
+ });
+
+ /* el on onmouseleave */
+ pJS.interactivity.el.addEventListener('mouseleave', function(e){
+
+ pJS.interactivity.mouse.pos_x = null;
+ pJS.interactivity.mouse.pos_y = null;
+ pJS.interactivity.status = 'mouseleave';
+
+ });
+
+ }
+
+ /* on click event */
+ if(pJS.interactivity.events.onclick.enable){
+
+ pJS.interactivity.el.addEventListener('click', function(){
+
+ pJS.interactivity.mouse.click_pos_x = pJS.interactivity.mouse.pos_x;
+ pJS.interactivity.mouse.click_pos_y = pJS.interactivity.mouse.pos_y;
+ pJS.interactivity.mouse.click_time = new Date().getTime();
+
+ if(pJS.interactivity.events.onclick.enable){
+
+ switch(pJS.interactivity.events.onclick.mode){
+
+ case 'push':
+ if(pJS.particles.move.enable){
+ pJS.fn.modes.pushParticles(pJS.interactivity.modes.push.particles_nb, pJS.interactivity.mouse);
+ }else{
+ if(pJS.interactivity.modes.push.particles_nb == 1){
+ pJS.fn.modes.pushParticles(pJS.interactivity.modes.push.particles_nb, pJS.interactivity.mouse);
+ }
+ else if(pJS.interactivity.modes.push.particles_nb > 1){
+ pJS.fn.modes.pushParticles(pJS.interactivity.modes.push.particles_nb);
+ }
+ }
+ break;
+
+ case 'remove':
+ pJS.fn.modes.removeParticles(pJS.interactivity.modes.remove.particles_nb);
+ break;
+
+ case 'bubble':
+ pJS.tmp.bubble_clicking = true;
+ break;
+
+ case 'repulse':
+ pJS.tmp.repulse_clicking = true;
+ pJS.tmp.repulse_count = 0;
+ pJS.tmp.repulse_finish = false;
+ setTimeout(function(){
+ pJS.tmp.repulse_clicking = false;
+ }, pJS.interactivity.modes.repulse.duration*1000)
+ break;
+
+ }
+
+ }
+
+ });
+
+ }
+
+
+ };
+
+ pJS.fn.vendors.densityAutoParticles = function(){
+
+ if(pJS.particles.number.density.enable){
+
+ /* calc area */
+ var area = pJS.canvas.el.width * pJS.canvas.el.height / 1000;
+ if(pJS.tmp.retina){
+ area = area/(pJS.canvas.pxratio*2);
+ }
+
+ /* calc number of particles based on density area */
+ var nb_particles = area * pJS.particles.number.value / pJS.particles.number.density.value_area;
+
+ /* add or remove X particles */
+ var missing_particles = pJS.particles.array.length - nb_particles;
+ if(missing_particles < 0) pJS.fn.modes.pushParticles(Math.abs(missing_particles));
+ else pJS.fn.modes.removeParticles(missing_particles);
+
+ }
+
+ };
+
+
+ pJS.fn.vendors.checkOverlap = function(p1, position){
+ for(var i = 0; i < pJS.particles.array.length; i++){
+ var p2 = pJS.particles.array[i];
+
+ var dx = p1.x - p2.x,
+ dy = p1.y - p2.y,
+ dist = Math.sqrt(dx*dx + dy*dy);
+
+ if(dist <= p1.radius + p2.radius){
+ p1.x = position ? position.x : Math.random() * pJS.canvas.w;
+ p1.y = position ? position.y : Math.random() * pJS.canvas.h;
+ pJS.fn.vendors.checkOverlap(p1);
+ }
+ }
+ };
+
+
+ pJS.fn.vendors.createSvgImg = function(p){
+
+ /* set color to svg element */
+ var svgXml = pJS.tmp.source_svg,
+ rgbHex = /#([0-9A-F]{3,6})/gi,
+ coloredSvgXml = svgXml.replace(rgbHex, function (m, r, g, b) {
+ if(p.color.rgb){
+ var color_value = 'rgba('+p.color.rgb.r+','+p.color.rgb.g+','+p.color.rgb.b+','+p.opacity+')';
+ }else{
+ var color_value = 'hsla('+p.color.hsl.h+','+p.color.hsl.s+'%,'+p.color.hsl.l+'%,'+p.opacity+')';
+ }
+ return color_value;
+ });
+
+ /* prepare to create img with colored svg */
+ var svg = new Blob([coloredSvgXml], {type: 'image/svg+xml;charset=utf-8'}),
+ DOMURL = window.URL || window.webkitURL || window,
+ url = DOMURL.createObjectURL(svg);
+
+ /* create particle img obj */
+ var img = new Image();
+ img.addEventListener('load', function(){
+ p.img.obj = img;
+ p.img.loaded = true;
+ DOMURL.revokeObjectURL(url);
+ pJS.tmp.count_svg++;
+ });
+ img.src = url;
+
+ };
+
+
+ pJS.fn.vendors.destroypJS = function(){
+ cancelAnimationFrame(pJS.fn.drawAnimFrame);
+ canvas_el.remove();
+ pJSDom = null;
+ };
+
+
+ pJS.fn.vendors.drawShape = function(c, startX, startY, sideLength, sideCountNumerator, sideCountDenominator){
+
+ // By Programming Thomas - https://programmingthomas.wordpress.com/2013/04/03/n-sided-shapes/
+ var sideCount = sideCountNumerator * sideCountDenominator;
+ var decimalSides = sideCountNumerator / sideCountDenominator;
+ var interiorAngleDegrees = (180 * (decimalSides - 2)) / decimalSides;
+ var interiorAngle = Math.PI - Math.PI * interiorAngleDegrees / 180; // convert to radians
+ c.save();
+ c.beginPath();
+ c.translate(startX, startY);
+ c.moveTo(0,0);
+ for (var i = 0; i < sideCount; i++) {
+ c.lineTo(sideLength,0);
+ c.translate(sideLength,0);
+ c.rotate(interiorAngle);
+ }
+ //c.stroke();
+ c.fill();
+ c.restore();
+
+ };
+
+ pJS.fn.vendors.exportImg = function(){
+ window.open(pJS.canvas.el.toDataURL('image/png'), '_blank');
+ };
+
+
+ pJS.fn.vendors.loadImg = function(type){
+
+ pJS.tmp.img_error = undefined;
+
+ if(pJS.particles.shape.image.src != ''){
+
+ if(type == 'svg'){
+
+ var xhr = new XMLHttpRequest();
+ xhr.open('GET', pJS.particles.shape.image.src);
+ xhr.onreadystatechange = function (data) {
+ if(xhr.readyState == 4){
+ if(xhr.status == 200){
+ pJS.tmp.source_svg = data.currentTarget.response;
+ pJS.fn.vendors.checkBeforeDraw();
+ }else{
+ console.log('Error pJS - Image not found');
+ pJS.tmp.img_error = true;
+ }
+ }
+ }
+ xhr.send();
+
+ }else{
+
+ var img = new Image();
+ img.addEventListener('load', function(){
+ pJS.tmp.img_obj = img;
+ pJS.fn.vendors.checkBeforeDraw();
+ });
+ img.src = pJS.particles.shape.image.src;
+
+ }
+
+ }else{
+ console.log('Error pJS - No image.src');
+ pJS.tmp.img_error = true;
+ }
+
+ };
+
+
+ pJS.fn.vendors.draw = function(){
+
+ if(pJS.particles.shape.type == 'image'){
+
+ if(pJS.tmp.img_type == 'svg'){
+
+ if(pJS.tmp.count_svg >= pJS.particles.number.value){
+ pJS.fn.particlesDraw();
+ if(!pJS.particles.move.enable) cancelRequestAnimFrame(pJS.fn.drawAnimFrame);
+ else pJS.fn.drawAnimFrame = requestAnimFrame(pJS.fn.vendors.draw);
+ }else{
+ //console.log('still loading...');
+ if(!pJS.tmp.img_error) pJS.fn.drawAnimFrame = requestAnimFrame(pJS.fn.vendors.draw);
+ }
+
+ }else{
+
+ if(pJS.tmp.img_obj != undefined){
+ pJS.fn.particlesDraw();
+ if(!pJS.particles.move.enable) cancelRequestAnimFrame(pJS.fn.drawAnimFrame);
+ else pJS.fn.drawAnimFrame = requestAnimFrame(pJS.fn.vendors.draw);
+ }else{
+ if(!pJS.tmp.img_error) pJS.fn.drawAnimFrame = requestAnimFrame(pJS.fn.vendors.draw);
+ }
+
+ }
+
+ }else{
+ pJS.fn.particlesDraw();
+ if(!pJS.particles.move.enable) cancelRequestAnimFrame(pJS.fn.drawAnimFrame);
+ else pJS.fn.drawAnimFrame = requestAnimFrame(pJS.fn.vendors.draw);
+ }
+
+ };
+
+
+ pJS.fn.vendors.checkBeforeDraw = function(){
+
+ // if shape is image
+ if(pJS.particles.shape.type == 'image'){
+
+ if(pJS.tmp.img_type == 'svg' && pJS.tmp.source_svg == undefined){
+ pJS.tmp.checkAnimFrame = requestAnimFrame(check);
+ }else{
+ //console.log('images loaded! cancel check');
+ cancelRequestAnimFrame(pJS.tmp.checkAnimFrame);
+ if(!pJS.tmp.img_error){
+ pJS.fn.vendors.init();
+ pJS.fn.vendors.draw();
+ }
+
+ }
+
+ }else{
+ pJS.fn.vendors.init();
+ pJS.fn.vendors.draw();
+ }
+
+ };
+
+
+ pJS.fn.vendors.init = function(){
+
+ /* init canvas + particles */
+ pJS.fn.retinaInit();
+ pJS.fn.canvasInit();
+ pJS.fn.canvasSize();
+ pJS.fn.canvasPaint();
+ pJS.fn.particlesCreate();
+ pJS.fn.vendors.densityAutoParticles();
+
+ /* particles.line_linked - convert hex colors to rgb */
+ pJS.particles.line_linked.color_rgb_line = hexToRgb(pJS.particles.line_linked.color);
+
+ };
+
+
+ pJS.fn.vendors.start = function(){
+
+ if(isInArray('image', pJS.particles.shape.type)){
+ pJS.tmp.img_type = pJS.particles.shape.image.src.substr(pJS.particles.shape.image.src.length - 3);
+ pJS.fn.vendors.loadImg(pJS.tmp.img_type);
+ }else{
+ pJS.fn.vendors.checkBeforeDraw();
+ }
+
+ };
+
+
+
+
+ /* ---------- pJS - start ------------ */
+
+
+ pJS.fn.vendors.eventsListeners();
+
+ pJS.fn.vendors.start();
+
+
+
+};
+
+/* ---------- global functions - vendors ------------ */
+
+Object.deepExtend = function(destination, source) {
+ for (var property in source) {
+ if (source[property] && source[property].constructor &&
+ source[property].constructor === Object) {
+ destination[property] = destination[property] || {};
+ arguments.callee(destination[property], source[property]);
+ } else {
+ destination[property] = source[property];
+ }
+ }
+ return destination;
+};
+
+window.requestAnimFrame = (function(){
+ return window.requestAnimationFrame ||
+ window.webkitRequestAnimationFrame ||
+ window.mozRequestAnimationFrame ||
+ window.oRequestAnimationFrame ||
+ window.msRequestAnimationFrame ||
+ function(callback){
+ window.setTimeout(callback, 1000 / 60);
+ };
+})();
+
+window.cancelRequestAnimFrame = ( function() {
+ return window.cancelAnimationFrame ||
+ window.webkitCancelRequestAnimationFrame ||
+ window.mozCancelRequestAnimationFrame ||
+ window.oCancelRequestAnimationFrame ||
+ window.msCancelRequestAnimationFrame ||
+ clearTimeout
+} )();
+
+function hexToRgb(hex){
+ // By Tim Down - https://stackoverflow.com/a/5624139/3493650
+ // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
+ var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
+ hex = hex.replace(shorthandRegex, function(m, r, g, b) {
+ return r + r + g + g + b + b;
+ });
+ var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
+ return result ? {
+ r: parseInt(result[1], 16),
+ g: parseInt(result[2], 16),
+ b: parseInt(result[3], 16)
+ } : null;
+};
+
+function clamp(number, min, max) {
+ return Math.min(Math.max(number, min), max);
+};
+
+function isInArray(value, array) {
+ return array.indexOf(value) > -1;
+}
+
+
+/* ---------- particles.js functions - start ------------ */
+
+window.pJSDom = [];
+
+window.particlesJS = function(tag_id, params){
+
+ //console.log(params);
+
+ /* no string id? so it's object params, and set the id with default id */
+ if(typeof(tag_id) != 'string'){
+ params = tag_id;
+ tag_id = 'particles-js';
+ }
+
+ /* no id? set the id to default id */
+ if(!tag_id){
+ tag_id = 'particles-js';
+ }
+
+ /* pJS elements */
+ var pJS_tag = document.getElementById(tag_id),
+ pJS_canvas_class = 'particles-js-canvas-el',
+ exist_canvas = pJS_tag.getElementsByClassName(pJS_canvas_class);
+
+ /* remove canvas if exists into the pJS target tag */
+ if(exist_canvas.length){
+ while(exist_canvas.length > 0){
+ pJS_tag.removeChild(exist_canvas[0]);
+ }
+ }
+
+ /* create canvas element */
+ var canvas_el = document.createElement('canvas');
+ canvas_el.className = pJS_canvas_class;
+
+ /* set size canvas */
+ canvas_el.style.width = "100%";
+ canvas_el.style.height = "100%";
+
+ /* append canvas */
+ var canvas = document.getElementById(tag_id).appendChild(canvas_el);
+
+ /* launch particle.js */
+ if(canvas != null){
+ pJSDom.push(new pJS(tag_id, params));
+ }
+
+};
+
+window.particlesJS.load = function(tag_id, path_config_json, callback){
+
+ /* load json config */
+ var xhr = new XMLHttpRequest();
+ xhr.open('GET', path_config_json);
+ xhr.onreadystatechange = function (data) {
+ if(xhr.readyState == 4){
+ if(xhr.status == 200){
+ var params = JSON.parse(data.currentTarget.response);
+ window.particlesJS(tag_id, params);
+ if(callback) callback();
+ }else{
+ console.log('Error pJS - XMLHttpRequest status: '+xhr.status);
+ console.log('Error pJS - File config not found');
+ }
+ }
+ };
+ xhr.send();
+
+};
diff --git a/docs/logos/meson.build b/docs/logos/meson.build
index 70ba67d71c..0038d4fa42 100644
--- a/docs/logos/meson.build
+++ b/docs/logos/meson.build
@@ -18,6 +18,8 @@ docs_logo_files = [
'logo-square.svg',
'logo-sticker-hexagon.svg',
'logo-sticker-square.svg',
+ 'penguin.svg',
+ 'penguin.png',
]
install_data(docs_logo_files, install_dir: docs_html_dir / 'logos')
diff --git a/docs/logos/penguin.png b/docs/logos/penguin.png
new file mode 100644
index 0000000000000000000000000000000000000000..48a481c54b6a71f2d43f5ebdf1d4455202c27d8a
GIT binary patch
literal 4236
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
literal 0
HcmV?d00001
diff --git a/docs/logos/penguin.svg b/docs/logos/penguin.svg
new file mode 100644
index 0000000000..9938dc35ab
--- /dev/null
+++ b/docs/logos/penguin.svg
@@ -0,0 +1,358 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="46.727402"
+ height="88.205261"
+ viewBox="0 0 12.363292 23.337642"
+ version="1.1"
+ id="svg2754"
+ inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
+ sodipodi:docname="penguin.svg"
+ inkscape:export-filename="../logo-square.png"
+ inkscape:export-xdpi="150"
+ inkscape:export-ydpi="150"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/">
+ <defs
+ id="defs2748">
+ <filter
+ style="color-interpolation-filters:sRGB"
+ inkscape:label="Drop Shadow"
+ id="filter5799-3"
+ x="-0.042427354"
+ y="-0.049351394"
+ width="1.1025327"
+ height="1.1192659">
+ <feFlood
+ flood-opacity="1"
+ flood-color="rgb(0,0,0)"
+ result="flood"
+ id="feFlood5801-7" />
+ <feComposite
+ in="flood"
+ in2="SourceGraphic"
+ operator="in"
+ result="composite1"
+ id="feComposite5803-4" />
+ <feGaussianBlur
+ in="composite1"
+ stdDeviation="6"
+ result="blur"
+ id="feGaussianBlur5805-3" />
+ <feOffset
+ dx="6"
+ dy="6"
+ result="offset"
+ id="feOffset5807-7" />
+ <feComposite
+ in="SourceGraphic"
+ in2="offset"
+ operator="over"
+ result="composite2"
+ id="feComposite5809-1" />
+ </filter>
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask3913-3">
+ <path
+ style="fill:#2f6962"
+ id="path3915-9"
+ d="M 95.108,61.776 244.59,10.309 c 15.666,-5.394 32.738,2.933 38.132,18.599 l 39.799,115.58 c 5.394,15.666 -2.932,32.738 -18.598,38.131 l -103.98,35.801 z"
+ inkscape:connector-curvature="0" />
+ </mask>
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask4168-6">
+ <path
+ style="fill:#7c858c"
+ id="path4170-4"
+ d="m 113.124,36.661 c 17.233,36.62 75.371,131.675 105.366,171.054 -4.069,13.505 -18.428,20.812 -30.299,17.44 L 72.849,58.555 C 72.779,46.208 95.748,31.956 113.124,36.661 Z"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </mask>
+ <filter
+ inkscape:label="Ridged Border"
+ inkscape:menu="Bevels"
+ inkscape:menu-tooltip="Ridged border with inner bevel"
+ style="color-interpolation-filters:sRGB"
+ id="filter5576-4"
+ x="0"
+ y="0"
+ width="1"
+ height="1">
+ <feMorphology
+ radius="4.3"
+ in="SourceAlpha"
+ result="result91"
+ id="feMorphology5578-9" />
+ <feComposite
+ operator="out"
+ in="SourceGraphic"
+ in2="result91"
+ id="feComposite5580-1" />
+ <feGaussianBlur
+ result="result0"
+ stdDeviation="1.2"
+ id="feGaussianBlur5582-2" />
+ <feDiffuseLighting
+ diffuseConstant="1"
+ id="feDiffuseLighting5584-3">
+ <feDistantLight
+ elevation="66"
+ azimuth="225"
+ id="feDistantLight5586-1" />
+ </feDiffuseLighting>
+ <feBlend
+ mode="multiply"
+ in2="SourceGraphic"
+ id="feBlend5588-8" />
+ <feComposite
+ operator="in"
+ in2="SourceAlpha"
+ id="feComposite5590-1" />
+ </filter>
+ <linearGradient
+ id="linearGradient3301">
+ <stop
+ id="stop3303"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop3305"
+ offset="1"
+ style="stop-color:#868686;stop-opacity:1;" />
+ </linearGradient>
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask4481-9">
+ <path
+ style="clip-rule:evenodd;fill:#aaaaaa;fill-rule:evenodd"
+ id="path4483-2"
+ d="m 213.96734,236.83626 c -1.97572,1.50086 -5.71734,14.75814 -3.57441,17.84065 3.18643,4.58465 22.42412,-12.69851 20.66112,-17.24646 -1.81294,-4.67518 -15.35694,-1.41227 -17.08671,-0.59419 z m -9.6286,-7.34722 2.48938,3.78195 c 0,0 0.69017,1.04372 0.29628,3.40302 -0.6156,3.68976 -3.17495,13.25876 -3.32578,21.12255 -0.0183,0.94976 -0.91914,9.5039 7.21943,7.07006 8.1393,-2.43309 24.96824,-17.85854 28.33195,-24.69252 3.36372,-6.83399 -0.96483,-10.63865 -6.21591,-10.98709 -5.2511,-0.34921 -13.3456,0.21962 -17.06874,0.84795 -3.72313,0.62832 -3.49361,-0.75818 -6.67723,-4.3506 -0.23896,-0.26961 -5.04938,3.80468 -5.04938,3.80468 z"
+ inkscape:connector-curvature="0" />
+ </mask>
+ <filter
+ style="color-interpolation-filters:sRGB"
+ inkscape:label="Drop Shadow"
+ id="filter6162"
+ x="-0.23894344"
+ y="-0.15139444"
+ width="1.4778869"
+ height="1.3658699">
+ <feFlood
+ flood-opacity="1"
+ flood-color="rgb(0,0,0)"
+ result="flood"
+ id="feFlood6164" />
+ <feComposite
+ in="flood"
+ in2="SourceGraphic"
+ operator="in"
+ result="composite1"
+ id="feComposite6166" />
+ <feGaussianBlur
+ in="composite1"
+ stdDeviation="6"
+ result="blur"
+ id="feGaussianBlur6168" />
+ <feOffset
+ dx="6"
+ dy="6"
+ result="offset"
+ id="feOffset6170" />
+ <feComposite
+ in="SourceGraphic"
+ in2="offset"
+ operator="over"
+ result="fbSourceGraphic"
+ id="feComposite6172" />
+ <feColorMatrix
+ result="fbSourceGraphicAlpha"
+ in="fbSourceGraphic"
+ values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
+ id="feColorMatrix6174" />
+ <feFlood
+ id="feFlood6176"
+ flood-opacity="1"
+ flood-color="rgb(0,0,0)"
+ result="flood"
+ in="fbSourceGraphic" />
+ <feComposite
+ id="feComposite6178"
+ in2="fbSourceGraphic"
+ in="flood"
+ operator="in"
+ result="composite1" />
+ <feGaussianBlur
+ id="feGaussianBlur6180"
+ in="composite1"
+ stdDeviation="6"
+ result="blur" />
+ <feOffset
+ id="feOffset6182"
+ dx="-6"
+ dy="6"
+ result="offset" />
+ <feComposite
+ id="feComposite6184"
+ in2="offset"
+ in="fbSourceGraphic"
+ operator="over"
+ result="composite2" />
+ </filter>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="2.5027778"
+ inkscape:cx="103.28524"
+ inkscape:cy="68.324084"
+ inkscape:document-units="mm"
+ inkscape:current-layer="g2753-0"
+ showgrid="false"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0"
+ inkscape:window-width="1920"
+ inkscape:window-height="1131"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ units="px"
+ inkscape:showpageshadow="2"
+ inkscape:pagecheckerboard="0"
+ inkscape:deskcolor="#d1d1d1" />
+ <metadata
+ id="metadata2751">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(15.314622,-233.97731)">
+ <g
+ id="g4944"
+ transform="matrix(0.24862701,-0.09049283,0.09049283,0.24862701,-92.040544,272.60195)">
+ <g
+ transform="rotate(19,545.20406,769.86173)"
+ id="g4988-0">
+ <g
+ id="g5736-0">
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="137.92564"
+ y="176.00142"
+ id="text5724-0"
+ transform="rotate(1.0000002)"><tspan
+ sodipodi:role="line"
+ id="tspan5726-6"
+ x="137.92564"
+ y="176.00142"
+ style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:180px;font-family:Overpass;-inkscape-font-specification:'Overpass Bold';letter-spacing:-10px;fill:#e6e6e6;fill-opacity:1" /></text>
+ <g
+ id="g2753-0"
+ transform="translate(-18.749067,-72.815807)">
+ <path
+ d="m 122.88954,229.92364 c 3.341,7.154 7.81,5.77 7.88,5.746 1.371,-0.472 5.829,-2.582 4.696,-5.873 -1.025,-2.977 -8.385,-3.373 -13.437,-1.633 -5.015,1.727 -10.665,6.602 -9.64,9.579 1.133,3.291 5.946,2.208 7.316,1.737 0.069,-0.024 4.799,-0.91 2.672,-9.379 -0.078,-0.312 0.404,-0.412 0.513,-0.177 z"
+ id="path2755-8"
+ style="clip-rule:evenodd;fill:#ffe600;fill-rule:evenodd"
+ inkscape:connector-curvature="0"
+ inkscape:export-filename="../penguin.png"
+ inkscape:export-xdpi="150"
+ inkscape:export-ydpi="150" />
+ <path
+ d="m 93.013543,187.02664 c -4.764,-17.913 -3.791,-32.973 2.812,-35.247 6.601997,-2.273 16.640997,8.995 23.914997,26.044 1.745,2.829 5.157,8.08 7.865,10.513 1.976,1.775 1.993,2.732 -1.079,2.212 -0.927,-0.157 -1.726,-0.358 -2.438,-0.662 5.736,19.254 5.048,35.957 -1.934,38.36 -6.981,2.404 -17.806,-10.334 -25.140997,-29.038 -0.374,0.678 -0.879,1.328 -1.513,2.022 -2.1,2.301 -2.676,1.537 -2.212,-1.079 0.636,-3.584 0.092,-9.822 -0.275,-13.125 z"
+ id="path2757-1"
+ style="fill:#000000;fill-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 100.36354,200.08264 c -5.497997,-15.966 -5.113997,-30.576 0.857,-32.632 5.971,-2.056 15.268,9.22 20.766,25.187 5.498,15.966 5.114,30.576 -0.857,32.632 -5.971,2.056 -15.268,-9.22 -20.766,-25.187 z m 0.699,-36.784 c -0.536,-1.558 -0.428,-3.008 0.243,-3.239 0.671,-0.231 1.649,0.845 2.186,2.402 0.536,1.558 0.427,3.008 -0.243,3.239 -0.671,0.231 -1.65,-0.845 -2.186,-2.402 z m -4.700997,1.618 c -0.536,-1.558 -0.427,-3.008 0.243,-3.239 0.67,-0.231 1.649,0.845 2.185,2.402 0.536,1.557 0.428,3.008 -0.243,3.239 -0.671,0.231 -1.649,-0.844 -2.185,-2.402 z"
+ id="path2759-9"
+ style="clip-rule:evenodd;fill:#ffffff;fill-opacity:1;fill-rule:evenodd"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g2761-8"
+ transform="translate(-7.9684573,2.7456446)">
+ <ellipse
+ transform="matrix(-0.9455,0.3255,-0.3255,-0.9455,267.4128,287.6192)"
+ cx="109.643"
+ cy="166.18201"
+ rx="4.428"
+ ry="2.142"
+ id="ellipse2763-1"
+ style="fill:#ffe600" />
+ <path
+ d=""
+ id="path2765-6"
+ style="fill:#ffe600"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <text
+ transform="rotate(1.0000002)"
+ id="text5053-7"
+ y="53.587437"
+ x="-408.52026"
+ style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ y="53.587437"
+ x="-408.52026"
+ id="tspan5055-2"
+ sodipodi:role="line" /></text>
+ <text
+ transform="rotate(1.0000002)"
+ id="text5057-8"
+ y="-232.88652"
+ x="-525.88629"
+ style="font-style:normal;font-weight:normal;font-size:90px;line-height:125%;font-family:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ y="-232.88652"
+ x="-525.88629"
+ id="tspan5059-1"
+ sodipodi:role="line" /></text>
+ <text
+ transform="rotate(1.0000002)"
+ id="text5069-7"
+ y="-200.07454"
+ x="543.02759"
+ style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ y="-200.07454"
+ x="543.02759"
+ id="tspan5071-7"
+ sodipodi:role="line" /></text>
+ </g>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-weight:normal;font-size:40px;line-height:25px;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="582.63574"
+ y="-37.070248"
+ id="text4950"><tspan
+ sodipodi:role="line"
+ id="tspan4948"
+ x="582.63574"
+ y="-37.070248" /></text>
+ </g>
+ </g>
+</svg>
diff --git a/docs/page.xsl b/docs/page.xsl
index 548d5a11c4..7c4f295053 100644
--- a/docs/page.xsl
+++ b/docs/page.xsl
@@ -116,6 +116,9 @@
<script type="text/javascript" src="{$href_base}js/main.js">
<xsl:comment>// forces non-empty element</xsl:comment>
</script>
+ <script type="text/javascript" src="{$href_base}js/particles.js">
+ <xsl:comment>// forces non-empty element</xsl:comment>
+ </script>
</head>
<body onload="pageload()">
<div id="body">
@@ -197,6 +200,11 @@
</div>
<br class="clear"/>
</div>
+ <xsl:if test="$pagesrc = 'docs/404.html.in'">
+ <script src="{$href_base}js/app.js">
+ <xsl:comment>// forces non-empty element</xsl:comment>
+ </script>
+ </xsl:if>
</body>
</html>
</xsl:template>
--
2.39.1
1 year, 9 months
[PULL 0/5] Misc next patches
by Daniel P. Berrangé
The following changes since commit 6a50f64ca01d0a7b97f14f069762bfd88160f31e:
Merge tag 'pull-request-2023-02-14' of https://gitlab.com/thuth/qemu into staging (2023-02-14 14:46:10 +0000)
are available in the Git repository at:
https://gitlab.com/berrange/qemu tags/misc-next-pull-request
for you to fetch changes up to 36debafddd788066be10b33c5f11b984a08e5c85:
ui: remove deprecated 'password' option for SPICE (2023-02-15 11:14:58 -0500)
----------------------------------------------------------------
* Document 'password-secret' option for -iscsi
* Deprecate iSCSI 'password' in favour of 'password-secret'
* Remove deprecated 'password' option for SPICE
* Fix handling of cached read buffers with TLS
----------------------------------------------------------------
Antoine Damhet (2):
crypto: TLS: introduce `check_pending`
io/channel-tls: fix handling of bigger read buffers
Daniel P. Berrangé (3):
block: mention 'password-secret' option for -iscsi
block: deprecate iSCSI 'password' in favour of 'password-secret'
ui: remove deprecated 'password' option for SPICE
block/iscsi.c | 3 ++
crypto/tlssession.c | 14 +++++++
docs/about/deprecated.rst | 16 ++++----
docs/about/removed-features.rst | 7 ++++
include/crypto/tlssession.h | 11 ++++++
io/channel-tls.c | 66 ++++++++++++++++++++++++++++++++-
qemu-options.hx | 13 ++-----
ui/spice-core.c | 15 --------
8 files changed, 111 insertions(+), 34 deletions(-)
--
2.39.1
1 year, 9 months
[PATCH 0/4] qemu_passt: Don't let passt fork off
by Michal Privoznik
Here are some cleanup, as promised here:
https://listman.redhat.com/archives/libvir-list/2023-February/237721.html
Now, there are still some patches missing.
Firstly, we still don't really capture error from passt. My suggestion
was to wait for socket to show up with errfd open. But active wait is
viewed as undesirable [1].
Secondly, Laine reported SELinux issues. Yeah, I don't see us setting
SELinux label on nor socket that passt and QEMU talk to each other, nor
on the log file. Speaking of which - we usually have per domain (or per
helper daemon instance even) log file, while for passt we have a global
one (/var/log/passt.log). I don't think that will fly if two or more
SELinux enabled domains want to use passt.
Thirdly, Stefano suggested a graceful shutdown for passt: have libvirt
connect to the socket and close it. Since we pass --one-off, this should
singal passt to exit. But I haven't implemented that because it's
redundant. We can't rely on passt quitting itself and thus use the big
gun (virPidFileForceCleanupPath()) at which point, the socket way is
just an optimization.
I might look into the first two, at some point. But not today.
1: https://listman.redhat.com/archives/libvir-list/2023-February/237663.html
Michal Prívozník (4):
Revert "qemu: allow passt to self-daemonize"
qemu_extdevice: Make qemuExtDevicesHasDevice() check def->nets
qemu_passt: Report error when getting passt PID failed
qemu_passt: Don't let passt fork off
src/qemu/qemu_extdevice.c | 11 +++++++++++
src/qemu/qemu_passt.c | 15 ++++++++++-----
2 files changed, 21 insertions(+), 5 deletions(-)
--
2.39.1
1 year, 9 months
[PATCH v4 14/16] qapi: deprecate "device" field of DEVICE_* events
by Vladimir Sementsov-Ogievskiy
The device field is redundant, because QOM path always include device
ID when this ID exist.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov(a)yandex-team.ru>
---
docs/about/deprecated.rst | 9 +++++++++
qapi/qdev.json | 12 ++++++++++--
2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
index da2e6fe63d..b389934691 100644
--- a/docs/about/deprecated.rst
+++ b/docs/about/deprecated.rst
@@ -171,6 +171,15 @@ accepted incorrect commands will return an error. Users should make sure that
all arguments passed to ``device_add`` are consistent with the documented
property types.
+QEMU Machine Protocol (QMP) events
+----------------------------------
+
+``DEVICE_DELETED`` & ``DEVICE_UNPLUG_GUEST_ERROR`` field ``device`` (since 8.0)
+'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+
+Devices that has ``ID`` always has QOM path `/machine/peripheral/ID`. So, the
+``device`` field is redundant and deprecated. Use the ``path`` field instead.
+
Host Architectures
------------------
diff --git a/qapi/qdev.json b/qapi/qdev.json
index 2708fb4e99..325ef554f9 100644
--- a/qapi/qdev.json
+++ b/qapi/qdev.json
@@ -124,6 +124,9 @@
#
# @path: the device's QOM path
#
+# Features:
+# @deprecated: Member @device is deprecated as redundant. Use @path instead.
+#
# Since: 1.5
#
# Example:
@@ -135,7 +138,8 @@
#
##
{ 'event': 'DEVICE_DELETED',
- 'data': { '*device': 'str', 'path': 'str' } }
+ 'data': { '*device': { 'type': 'str', 'features': [ 'deprecated' ] },
+ 'path': 'str' } }
##
# @DEVICE_UNPLUG_GUEST_ERROR:
@@ -146,6 +150,9 @@
#
# @path: the device's QOM path
#
+# Features:
+# @deprecated: Member @device is deprecated as redundant. Use @path instead.
+#
# Since: 6.2
#
# Example:
@@ -157,4 +164,5 @@
#
##
{ 'event': 'DEVICE_UNPLUG_GUEST_ERROR',
- 'data': { '*device': 'str', 'path': 'str' } }
+ 'data': { '*device': { 'type': 'str', 'features': [ 'deprecated' ] },
+ 'path': 'str' } }
--
2.34.1
1 year, 9 months