Including JS syntax with colons in a XSL template

I’m trying to create an XSL template (utilized by a Saxon processor) for embedded 360 photos using the Photo Sphere Viewer JS library. I’m running into an issue where part of the basic embed code causes a fatal error within the template:

My relevant part of my sample XSL:

<xsl:template name="myPanoramaTemplate">
<xsl:variable name="image" select="div/[@data-name='PanoImage']/img/@src"/>

<div id="viewer" style="width: 100vw; height: 100vh;"></div>
<script>
  var viewer = new PhotoSphereViewer.Viewer({
    container: document.querySelector('#viewer'),
    panorama: '{$image}'
  });
</script>
<xsl:template>

This has consistently cause the following:

Fatal Error: QName cannot end with colon: {container:}
Fatal Error: QName cannot end with colon: {panorama:}

I have tried to output the script text via xsl:text, xsl:value-of, and xsl:copy-of and have had no success. I need to either find a way for the XSL to process the colons successfully or find an alternative method to utilize the JS library that avoids using colons in this context. Has anyone encountered anything similar and any solutions or workarounds?

Edit: For a simpler example without any XSL variables, I tried a test template without any variables. The same fatal errors regarding colons were flagged.

<xsl:template name="myPanoramaTemplate">
<script>
  var viewer = new PhotoSphereViewer.Viewer({
    container: document.querySelector('#viewer'),
    panorama: 'path/to/panorama.jpg'
  });
</script>
</xsl:template>

Answer

As an alternative to Martin’s suggestion, escape the curly braces by doubling them.

What’s happening here is that the text between the curly braces is being parsed as an XPath expression, which fails because it’s not valid XPath syntax. You could write:

<script>
  var viewer = new PhotoSphereViewer.Viewer({{
    container: document.querySelector('#viewer'),
    panorama: '{$image}'
  }});
</script>