Quantcast
Channel: Daz Script Developer Discussion - Daz 3D Forums
Viewing all 1036 articles
Browse latest View live

Detecting if System has Iray Available

$
0
0

Via a script, is there a way of detecting if the current system has Iray available to use / is the currently set renderer?

I found this thread,which seems to have a solution, but was wondering if there was another way.

Thanks,


Find 3D point projection in rendered image.

$
0
0

Hi everyone,

I need to find out locations of some facial points (nose tip, eyes, etc) in final rendered image.

I found that I can access character mesh by using node.getSkeleton().getObject().getCachedGeom() API. I want to find out indexes of interesting points in the mesh, however I can't find any way to show the indexes.

I managed to find out some of the points by iterating through the mesh and placing sphere at vertex's location, but this is very unconvinient and time consuming task. Is there a better alternative?

Is there some API to find out location of these points at final image or at least to get projection matrix of the camera?

Rescaling poses using scripts?

$
0
0

All DAZ figure poses people sell assume that both figures are the same height.

But what to do if I have a male which is 190 cm and female which is 165 cm?

What I need is a way to scale a higher figure pose to match lower figure -- in other words, to apply some sort of "multiplier" to pose preset to correct for height/size difference.

Would this be possible using a script and how?

Any advice is much appreciated.

After Effects camera track to Daz Studio camera.

$
0
0

Hi everbody,

I’ve been working on a simple match move thing to get After Effects camera solve data to Daz Studio. I’ve gotten the main data parsing and keyframe matching solved, and i also have the movement solved (with setWSPos()), but i keep hitting my head to the brickwall when it comes to DAZ studios setWSRot(). 

Not being a familiar with 3d programming in general, i have trouble of figuring out how to go about doing the proper rotation values for the camera, and also, how about doing the focal length solving.

Anybody out there to help me out with this? I can share you the script that i now have, if need be. Or if you guys have written something that would do the match move trick, i’d be really interested to check it out.

Personally, i think it’s a shame that we don’t have a decent match move script between daz studio and afte effects. 

Cheers, and thanks

Dial Group Focus

$
0
0

I was wondering if there's a way of making a particular group of dials in the Parameters Pane current or focused?

For example, if I have the left thigh of a figure selected in the Scene Pane, and I want the dials found in General / Transforms / Rotation to be displayed or to have the input focus, is there a scriptable way of doing this?

 

Can you create a morph slider that adjusts surface settings?

$
0
0

Hopefully this is the right place to ask. I saw a product suggestion for a tool for applying a red-faced blush to characters and it got me thinking about having a dial that increases / decreases the opacity of a "blush" layer. Seems like it would be a simple way to dip my feet into scripting for DS.

Scripted Renderer Default Display - how to override?

$
0
0

From within a Scripted Renderer script, how could one convince DAZ Studio to display the output of a

DzScriptedRenderer.riDisplay()

call in the Render window?

I suspect it happens under the hood of:

DzScriptedRenderer.doDefaultDisplay()

But I am clueless as to what that method does.

 

Scenario: In a render script I am rendering out multiple files: outlines, subsets, etc.

I would like to have control over what the Render window shows when Render Settings > General > Render Target is set to New Window. Is this possible?

 

Edit: I would think it should be something to the effect of:

var oRenderHandler = DzScriptedRenderer.getHandler();

oRenderHandler.addRenderFiles(["filename.png"]);

But I haven't quite gotten that to work.

Explanation of Bounding, Oriented and Preview Box

$
0
0

Has anyone a short description of these three box types and and an explanation of their differences for me?

Thank in advance.


File-Path of a Script

$
0
0

This has probably been answered hundreds of times, but I can't seem to find the answer:

Is there a built-in Daz function that will tell me exactly where my script is located, file-path-wise (absolute or relative path); it could be where it's supposed to be in the Daz folder system, or on a networked-drive, or anywhere.

I've seen quite a few functions in the DzApp object (I think), but searching through the object reference docs doesn't seem to turn up anything (could be totally wrong, of course).

Thanks,

Setting a controlled dial's value

$
0
0

Hi,

Can someone explain what's wrong with the following code.  I'm trying
to set the value of the Z Rotation in the lMetatarsals bone in a G3F figure.
In the example below, I want to set it to 2.0 but it always ends up as 5.0.

Now I've realized that the lMetatarsals are controlled by the lToe bone,
so when the lToe twists, the lMetatarsals twists by the same amount.  But I
can manually adjust the Z Rotate dial of the lMetatarsals to any value I
want.  So does the method 'setValue()' do exactly the same as adjusting the
dial manually?  It doesn't look like it.  How can I set the rotation value to
the value I want, in a script?  Or do I have to somehow unlink the 2 bones?


(function(){
  var lToeValue, lMetaValue,
      lMetaBone, lToeBone,
      lMetaCtrl, lToeCtrl;
  
  var fig = Scene.getPrimarySelection().getSkeleton();
  
  lMetaBone = fig.findBone("lMetatarsals");
  lToeBone = fig.findBone("lToe");
    
  lMetaCtrl = lMetaBone.getZRotControl();
  lToeCtrl = lToeBone.getZRotControl();
  
  lMetaValue = lMetaCtrl.getValue();
  lToeValue = lToeCtrl.getValue();  
  
  print("Values Before:  " +
        "lMetatarsals = " + lMetaValue + ",  " +
        "lToe = " + lToeValue);  
  
  lToeCtrl.setValue(3.0);
  lMetaCtrl.setValue(2.0);
  
  lToeValue = lToeCtrl.getValue();
  lMetaValue = lMetaCtrl.getValue();
  
  print("Values After:  " +
        "lMetatarsals = " + lMetaValue + ",  " +
        "lToe = " + lToeValue);  
  
})();

// Output:

// Values Before:  lMetatarsals = 0,  lToe = 0
// Values After:  lMetatarsals = 5,  lToe = 3

 

Adding a Smoothing modifier

$
0
0

Do anyone know if there is a way to add a smoothing modifier by script?

Merging objects

$
0
0

I was wondering about a limitation of the smoothing modifier... You can calculate collisions with one single object, but what if you need to collide with two objects? For example one guy getting punched and colliding with a piece of furniture. Manually, I suppose you could export the two props/figures as an obj (hiding all useless objects in the scene) and re-import them as a single one, to be kept hidden only for colliding computations. It's a bit tedious to do, do you know if merging 'posed' duplicates of objects could be done by script? Surely hiding/unhiding, exporting and re-importing can be done by script, but I mean, maybe there is something more straightforward?

Setting Camera Display Persistence

$
0
0

How do I toggle the 'display persistence' property of a DzCamera -- it doesn't appear in the API reference.

I'm guessing there's some object that I can iterate through that contains all properties of the selected camera, and I vaguely recall a post to this effect, but didn't bookmark it (of course ;) ).

Help :D

Identifying assets in DSON files

$
0
0

I'm trying to import DSON files in my own (Python) software, but I can't figure out how asset IDs work in advanced cases.

I have a scene with two G8M figures using the same Modifier, but although the modifiers' parent is overridden to be assigned to the right NodeInstances (of both the figures), the SkinBinding it contains still references the base Node and Geometry. I'm not sure how to translate that to the NodeInstance and GeometryInstance of the figures they belong to.

To illustrate this, I copied the relevant parts of the DSON file below.

So my example scene has only two G8M figures, labeled "JOHN" and "ROBIN". In the DSON file, both of them are NodeInstances based on the Genesis8Male.dsf#Genesis8Male figure and Genesis8Male.dsf#geometry geometry. No problems there. Both figures them have a SkinBinding modifier based on Genesis8Male.dsf#SkinBinding. The parent values (Genesis8Male.dsf#geometry by default) are overridden to #geometry (for John) and #geometry-1 (for Robin). Thats where my question starts.

In both cases, the inherited skin binding modifier still references the #Genesis8Male node and the #geometry geometry from the Genesis8Male.dsf file. These URLS are not overridden in the example.duf file. So how would I use those Uris to reference the NodeInstance and Geometry of "John" and "Robin"? 

Relevant parts from my example.duf file:

{
    "asset_info": {
        "id": "/C%3A/Example.duf"
    },
    "scene": {
        "nodes": [
            {
                "id": "Genesis8Male",
                "url": "/data/DAZ%203D/Genesis%208/Male/Genesis8Male.dsf#Genesis8Male",
                "name": "Genesis8Male",
                "label": "JOHN",
                "geometries": [
                    {
                        "id": "geometry",
                        "url": "/data/DAZ%203D/Genesis%208/Male/Genesis8Male.dsf#geometry",
                        "name": "Genesis8Male"
                    }
                ]
            },
            {
                "id": "Genesis8Male-1",
                "url": "/data/DAZ%203D/Genesis%208/Male/Genesis8Male.dsf#Genesis8Male",
                "name": "Genesis8Male",
                "label": "ROBIN",
                "geometries": [
                    {
                        "id": "geometry-1",
                        "url": "/data/DAZ%203D/Genesis%208/Male/Genesis8Male.dsf#geometry",
                        "name": "Genesis8Male"
                    }
                ]
            }  
        ],
        "modifiers": [
            {
                "id": "SkinBinding",
                "url": "/data/DAZ%203D/Genesis%208/Male/Genesis8Male.dsf#SkinBinding",
                "parent": "#geometry"    (--> Overrides the parent from the referenced file)
            },
            {
                "id": "SkinBinding-1",
                "url": "/data/DAZ%203D/Genesis%208/Male/Genesis8Male.dsf#SkinBinding",
                "parent": "#geometry-1"  (--> Overrides the parent from the referenced file)
            }
        ]
    }
}

Relevant parts from the Genesis8Male.dsf file:

{
    "asset_info": {
        "id": "/data/DAZ%203D/Genesis%208/Male/Genesis8Male.dsf"
    },
    "geometry_library": [
        {
            "id": "geometry",
            "name": "geometry"
        }
    ],
    "node_library": [
        {
            "id": "Genesis8Male",
            "name": "Genesis8Male",
            "type": "figure",
            "label": "Genesis 8 Male"
        }
    ],
    "modifier_library": [
        {
            "id": "SkinBinding",
            "name": "SkinBinding",
            "parent": "#geometry",  (--> Overriden in the example file, see above)
            "skin": {
                "node": "#Genesis8Male",  (--> NOT overridden. How to interpret this to link to Johns/Robins figure?)
                "geometry": "#geometry",  (--> NOT overridden. How to interpret this to link to Johns/Robins geometry?)
                "joints": [
                    {
                        "id": "lIndex3",
                        "node": "#lIndex3" (--> NOT overridden. How to look in Johns / Robins armature?)
                    },
                ]
            }
        }
    ]
}

 

Seeking DzUberIrayMaterial

$
0
0

I keep seeing a term in the DAZ Studio Beta release notes and I don't know what to make of it: Public API.

I know (and have) the SDK and I know (and have bookmarked) the Scripting API documentation, but I don't know what or where to find the Public API documentation the release notse mention updating once in a while.

Specifically I am looking for more information on DzUberIrayMaterial which is metioned repeatedly, however any other documentation or information could be helpful in my quest to learn more about scritping.


Making new Selection Sets via FaceGroups and Regions

$
0
0

Hey Everyone,

So I'm fairly new at scripting in DAZ, though I have plenty of experience with Javascript. I'm trying to figure out how to write the scripting equivalent of doing this: selecting several groups of polygons by both FaceGroup and Region, then creating a SelectionSet from them, then deleting all of the remaining (unselected) polygons. It seems like a good deal of what I want to do is not really covered in the API reference. I did find this thread https://www.daz3d.com/forums/discussion/44187/accessing-face-selection-sets-via-the-sdk which illuminates how to access SelectionSets, but I'm still unsure how to access polygon selections by Region (as well as delete polygons for that matter, but that's the next step). 

If anyone can share any insight about this that'd be wonderful. Thank you!

 

-L.

Bug in DS v4.11.0.383 DzSIReloadAction: Sets getScriptFileName() == ""

$
0
0

A Heads-Up in case you are suddenly getting wierd problems in your scripts with v4.11.0.383:

Here's the  test script (also attached as test_01.dsa):

// test_01.dsa
// Script to illustrate a bug in DAZ Studio v4.11.0.383 DzSIReloadAction
//  DzSIReloadAction can be triggered e.g. by menu: Script IDE Pane > File > Reload Script

print( App.longVersionString );

print( ' ' );
var sFileSpec = getScriptFileName();
print( sFileSpec );

print( ' ' );
if( sFileSpec == '' ) {
  print( '### BUG ###: getScriptFileName() == ""' );
} else {
  print( 'OK' );
}
//
// In v4.10.0.123:
//    Works OK, including after executing DzSIReloadAction
//
// In v4.11.0.383:
//    Works OK, until after executing DzSIReloadAction
//      then getScriptFileName() always == ''

print( ' ' );

In the v4.11.0.383 Script IDE Pane:

  1. File > Open Script...        // Open test_01.dsa
  2. [Execute]                       // It works OK: getScriptFilename() != ""
  3. File > Reload Script
  4. [Execute]                       // BUG: getScriptFilename() == ""
  5. File > Open Script...        // Open test_01.dsa
  6. [Execute]                       // BUG: getScriptFilename() == ""
  7. File > Close Script
  8. File > Open Script...        // Open test_01.dsa
  9. [Execute]                       // It works OK: getScriptFilename != ""
  10. File > Reload Script
  11. [Execute]                       // BUG: getScriptFilename() == ""

Request #293041 submitted 03-March-2019

 

How to subdivide and multiply numbers?

$
0
0

It appears to me that just recently I tried to do some math with scripting for the first time and I realized that you can't write just asterisk or slash. I know there must be some method to simply subdivide and multiply numeric values to express equasions but I searched the whole API Reference for way to long and the only ones I found was the higher math methods in the object index like sinus, cosinus and logarithmic.

Can someone please give me a script example with subdivide and multiply?

PowerPose Templates generator script

$
0
0

Hi, once again I started a script project to solve a specific issue I had. Read How to Get PowerPose to Work with Genesis 3?

I want to create a simple PowerPose template but I'm too lazy to write all the boring stuff myself even with copy-paste this takes some time and is prone to typos. So yesterday I started to write this script that generates all these lines for me that look like HTML tags based on the selected figure to have at least something to work with while creating the actual tamplate.

For me it is meant to be used to create a face rig template for genesis 3 figures and there are 64 control points in the template that need to get defined for PowerPose with a bone label and a position on the pane.

Here is my first version that does at least something usable. I can imagine this script could also serve others that want to create PowerPose templates for their custom figures. Maybe I should add some kind exclude bones check so you can run it from the root node of the figure without having everything included.

It generated 640 lines of PowerPose template code in a few milliseconds and includes all control points that I wanted for my PowerPose template.

It is far from beeing perfect and I need to find some other way to positioning the control points currently that isn't working at all. I post this script anyway even if I dircracing myself for not getting such a simple thing like one dimensinal offsets to work. I will have a look at it again after some sleep.

But that's why I post this becasue I need some help getting it right. So please can someone have a look and find out why I have commas in a few lines of the string / array output in the console. Must be some issue with the array index or the line break "\n" I've added everywhere. I wonder why I can print out the aTemplate array without joining it. Also I need to test if I have to choose inverted control settings depending on if its a left or right side bone.

I hope you don't mind that I borrowed the upper part of the script from the script example "Adjust Rigging to Shape"

Source: http://docs.daz3d.com/doku.php/public/software/dazstudio/4/referenceguide/scripting/api_reference/samples/nodes/adjust_rigging_to_shape/start

That example just got the right checks and error messages for working with figure bones. I've included the Creative Commons Attribution 3.0 information in the header comment and included infromation that this is a modification of the original script example.

Download link: GeneratePowerPoseTemplateFile.dsa 8K

Screenshots of the console output.

// DAZ Studio version 4.10.0.123 filetype DAZ Script
/**********************************************************************
 
	Copyright (C) 2002-2019 Daz 3D, Inc. All Rights Reserved.
	Script code: MODIFIED! No warranty of any kind.
 
	This script is provided as part of the >> Daz Script Developer Discussion
	
	Creative Commons Attribution 3.0 Unported (CC BY 3.0)
	- http://creativecommons.org/licenses/by/3.0
 
	To contact Daz 3D or for more information about Daz Script visit the
	Daz 3D website:
 
	- http://www.daz3d.com
	
**********************************************************************
GeneratePowerPoseTemplateFile.dsa
**********************************************************************
- select a genesis 3 or 8 figure
- the script searches for two bones labeled "Upper/Lower Face Rig"
- based on the child bones the script will then print out a few informations
- finaly the PowerPose template code gets printed to the Script IDE console

This script includes parts of the Scripting example:
	Adjust Rigging to Shape
	Source:
	http://docs.daz3d.com/doku.php/public/software/dazstudio/4/referenceguide/scripting/api_reference/samples/nodes/adjust_rigging_to_shape/start
	created: 2019-06-20 by Syrus_Dante
	edited:  2019-06-21 by Syrus_Dante
	P.S. Sorry I was lazy again I just copied the upper part of the script example because it got all checks and error messages that I wanted.
*********************************************************************/
(function( oNode ){
 
	/*********************************************************************/
	// String : A function for retrieving a translation if one exists
	function text( sText )
	{
		// If the version of the application supports qsTr()
		if( typeof( qsTr ) != "undefined" ){
			// Return the translated (if any) text
			return qsTr( sText );
		}
 
		// Return the original text
		return sText;
	};
 
	/*********************************************************************/
	// Define message components
	var sTitle = text("Resource Error");
	var sMessage = text("This script requires version 4.9.3.93 or newer.");
	var sOk = text("&OK");
	
	// If the application is less than 4.9.3.93
	if( App.version64 < 0x000400090003005d ){
		// Inform the user
		MessageBox.information( sMessage, sTitle, sOk );
		// We're done...
		return;
	}
	
	// Initialize
	var oFigure = undefined;
	// If we have a bone
	if( oNode.inherits( "DzBone" ) ){
		// Get its skeleton
		oFigure = oNode.getSkeleton();
	// If we have a figure
	} else if( oNode.inherits( "DzFigure" ) ){
		// We have what we want
		oFigure = oNode;
	}
 
	// If we don't have a weight mapped figure
	if( !oFigure || !oFigure.inherits( "DzFigure" ) ){
		// Define message components
		sTitle = text("Selection Error");
		sMessage = text("This script requires a weight mapped figure to be selected.");
		// Inform the user
		MessageBox.information( sMessage, sTitle, sOk );
		// We're done...
		return;
	}
 
	// Get the object
	var oObject = oFigure.getObject();
	// If the node doesn't have an object
	if( !oObject ){
		// Define message components
		sTitle = text("Selection Error Object");
		sMessage = text("This script requires an object with geometry to be selected.");
		// Inform the user
		MessageBox.information( sMessage, sTitle, sOk );
		// We're done...
		return;
	}

	/*********************************************************************
	Start Script Modification
	*********************************************************************/	
	var aNodes = oFigure.getAllBones ();
	var sLabel = oFigure.getLabel();
	var aChildBones = [];
	var nBkrndResX = 480;
	var nBkrndResY = 720;
	var nXoffset = 0;
	var nXoffsetLeft = 10;	//offsets are related to the x/y pixel coordinates on the backround image
	var nXoffsetRight = 10;	
	var nYoffset = 265; //I just gave some values here so the points don't end up all on the same spot
	var sText;
	var aTemplate = [""]; //the actual template text that can later get written do a DSX file 

	//you can choose which controls you want to have in the lower PowerPose pane - currently only sControlSet01 is used
	var sControlSet01 =
		  "\t<lmb_horiz_prop>ytran</lmb_horiz_prop>\n"
		+ "\t<lmb_vert_prop>xtran</lmb_vert_prop>\n"
		+ "\t<rmb_horiz_prop>zrot</rmb_horiz_prop>\n"
		+ "\t<rmb_horiz_sign>neg</rmb_horiz_sign>\n"
		+ "\t<rmb_vert_prop>xrot</rmb_vert_prop>\n";
	var sControlSet02 =
		  "\t<lmb_horiz_prop>ytran</lmb_horiz_prop>\n"
		+ "\t<lmb_vert_prop>xtran</lmb_vert_prop>\n"
		+ "\t<rmb_horiz_prop>zrot</rmb_horiz_prop>\n"
		+ "\t<rmb_horiz_sign>neg</rmb_horiz_sign>\n"
		+ "\t<rmb_vert_prop>xrot</rmb_vert_prop>\n";
			
	print("The selected figure [%1] got that many bones: [%2]"
	.arg(sLabel)
 	.arg(aNodes.length));

/*	this was for testing and was printing out all bones at once
	for ( var n = 0 ; n < aNodes.length ; n++ ) {
		oObject = aNodes[n];
		sLabel = aNodes[n].getLabel();
	 	print("Node Nr: %1 Label: %2"
	 	.arg(n+1) 		
	 	.arg(sLabel));
	}
*/
	/*********************************************************************
	generateTemplate constructs a strig based on the bone label you give and the child bones on the figure
	*********************************************************************/
	function generateTemplate( sStartWithBoneLabel ) {
		var oBone = oFigure.findBoneByLabel(sStartWithBoneLabel);
		print("\n\nSearch for a bone with the label: %1" .arg(sStartWithBoneLabel));
		if( !oBone ){
			print("> Didn't found a bone with the label '%1'!\nThe selected figure should be Genesis 3 or 8."
			.arg(sStartWithBoneLabel));
			return null; //finished with error
		}else{
			print("> found '%1' - it includes [%2] child bones.\n"
			.arg(sStartWithBoneLabel)
			.arg(oBone.getNumNodeChildren(false)));
			
			aChildBones = oBone.getNodeChildren (false);

			for ( var n = 0 ; n < aChildBones.length ; n++ ) {
				sLabel = aChildBones[n].getLabel();
			 	print("Node Nr: %1\t\tLabel: %2"
			 		.arg(aTemplate.length)
			 		.arg(sLabel));

				//set the x offset by the bone label dosn't work - I will have a look another day
				//I want to have all "left" labeled bones on the left side and all "right" labeled on the right side
				//sounds simple but I have my issues with getting it right
				if(sLabel.search("Left") != -1){
					//print("> left bone detected");
					//if(nXoffset >= -1) {nXoffset*=-1;} //Invert number if not already negative
					nXoffset = ((nXoffsetLeft -= 10) + (nBkrndResX / 2));
				}
				if(sLabel.search("Right") != -1){
					//print("> right bone detected");
					//if(nXoffset <= -1) {nXoffset*=-1;} //Invert number if not already positive
					nXoffset = ((nXoffsetRight += 10) + (nBkrndResX / 2));
				}
				if((sLabel.search("Middle") != -1)
					|| (sLabel.search("Center") != -1)
					|| (sLabel.search("Nose") != -1)){
					//print("> middle bone detected");
					nXoffset = nBkrndResX / 2;
				}

				aTemplate[aTemplate.length ++ ] =
					("<node_data>\n"
					+ "\t<x>%1</x>\n"
				 	+ "\t<y>%2</y>\n"
				 	+ "\t<node_label>%3</node_label>\n"
				 	+ "%4"
				 	+ "</node_data>\n")
//			 	.arg(nXoffset += 10) // add increment of 10
			 	.arg(nXoffset)
			 	.arg(nYoffset)
			 	.arg(sLabel)
				.arg(sControlSet01);
			}
		} return true; //finished with success
	}

	if( generateTemplate("Upper Face Rig")){
		nYoffset += 40;
	}else{ return null; }
	
	if( generateTemplate("Lower Face Rig")){

	}else{ return null; }
	
/*  obsolete loop? the aTemplate array gets printed out anyway
	var sTemplate;
	for (var i = 0; i < aTemplate.length; i++){
		sTemplate = aTemplate[i].join ( "\n" );
	}
*/
	print("\n\nThe generated PowerPose template:\n\n%1"	
	.arg(aTemplate));

// Finalize the function and invoke
})( Scene.getPrimarySelection() );

 

Questions about calculations involving bones

$
0
0

Just starting with Daz scripting, so expect a whole sequence of newbie questions from me.

I'm trying to do some calculations involving bone positions.  I've read the documentation on DzBone and its base classes, and I do understand the difference between "local space" and "world space" when it comes to positions, rotations, etc.

Questions (all in the context of DzBone, even though many of the methods are in DzNode):

  1. I assume that the "location" of a bone refers to its root (for lack of a better term).  Given the location and rotation or transform for the bone, how does one calculate the position of the bone's tip?  I see the DzNode.getEndpoint() method, but uncertain what space that is in and how it relates to getLocalPos()./ getWSPos()
  2. How does the return value of DzNode.getOrientation() differ from the return value of DzNode getLocalRot()?  
  3. For items that take a Boolean defaultVal=false  argument, if one passes in "true" for that, does this give you the value as if the bone's "positioning controls" were all set to zero?  (i.e. as if the bone in the figure is in the default pose's position)?

Thanks in advance!

Viewing all 1036 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>