callback () {
        // Add the button and its handler(s)
        // Note: the star extension needs to be loaded before the polygon extension
        const fbtitle = `${name}:title`
        const titleStar = `${name}:buttons.0.title`
        const titlePolygon = `${name}:buttons.1.title`
        const buttonTemplate = `
            <se-flyingbutton id="tools_polygon" title="${fbtitle}">
              <se-button id="tool_star" title="${titleStar}" src="star.svg">
              </se-button>
              <se-button id="tool_polygon" title="${titlePolygon}" src="polygon.svg">
              </se-button>
            </se-flyingbutton>
          `
        svgCanvas.insertChildAtIndex($id('tools_left'), buttonTemplate, 10)
        // handler
        $click($id('tool_star'), () => {
          if (this.leftPanel.updateLeftPanel('tool_star')) {
            svgCanvas.setMode('star')
            showPanel(true, 'star')
            showPanel(false, 'polygon')
          }
        })
        $click($id('tool_polygon'), () => {
          if (this.leftPanel.updateLeftPanel('tool_polygon')) {
            svgCanvas.setMode('polygon')
            showPanel(true, 'polygon')
            showPanel(false, 'star')
          }
        })
        const label0 = `${name}:contextTools.0.label`
        const title0 = `${name}:contextTools.0.title`
        const label1 = `${name}:contextTools.1.label`
        const title1 = `${name}:contextTools.1.title`
        const label2 = `${name}:contextTools.2.label`
        const title2 = `${name}:contextTools.2.title`
        const label3 = `${name}:contextTools.3.label`
        const title3 = `${name}:contextTools.3.title`
        // Add the context panel and its handler(s)
        const panelTemplate = document.createElement('template')
        panelTemplate.innerHTML = `
          <div id="star_panel">
            <se-spin-input id="starNumPoints" label="${label0}" min=1 step=1 value=5 title="${title0}">
            </se-spin-input>
            <se-spin-input id="RadiusMultiplier" label="${label1}" min=1 step=2.5 value=3 title="${title1}">
            </se-spin-input>
            <se-spin-input id="radialShift" min=0 step=1 value=0 label="${label2}" title="${title2}">
            </se-spin-input>
          </div>
          <div id="polygon_panel">
            <se-spin-input size="3" id="polySides" min=1 step=1 value=5 label="${label3}" title="${title3}">
            </se-spin-input>
          </div>
        `
        // add handlers for the panel
        $id('tools_top').appendChild(panelTemplate.content.cloneNode(true))
        // don't display the panels on start
        showPanel(false, 'star')
        showPanel(false, 'polygon')
        $id('starNumPoints').addEventListener('change', (event) => {
          setAttr('point', event.target.value)
          const orient = 'point'
          const point = event.target.value
          let i = selElems.length
          while (i--) {
            const elem = selElems[i]
            if (elem.hasAttribute('r')) {
              const oldPoint = elem.getAttribute('point')
              const oldPoints = elem.getAttribute('points')
              const radialshift = elem.getAttribute('radialshift')
              let xpos = 0
              let ypos = 0
              if (elem.points) {
                const list = elem.points
                const len = list.numberOfItems
                for (let i = 0; i < len; ++i) {
                  const pt = list.getItem(i)
                  xpos += parseFloat(pt.x)
                  ypos += parseFloat(pt.y)
                }
                const cx = xpos / len
                const cy = ypos / len
                const circumradius = Number(elem.getAttribute('r'))
                const inradius = circumradius / elem.getAttribute('starRadiusMultiplier')

                let polyPoints = ''
                for (let s = 0; point >= s; s++) {
                  let angle = 2.0 * Math.PI * (s / point)
                  if (orient === 'point') {
                    angle -= Math.PI / 2
                  } else if (orient === 'edge') {
                    angle = angle + Math.PI / point - Math.PI / 2
                  }

                  let x = circumradius * Math.cos(angle) + cx
                  let y = circumradius * Math.sin(angle) + cy

                  polyPoints += x + ',' + y + ' '

                  if (!isNaN(inradius)) {
                    angle = 2.0 * Math.PI * (s / point) + Math.PI / point
                    if (orient === 'point') {
                      angle -= Math.PI / 2
                    } else if (orient === 'edge') {
                      angle = angle + Math.PI / point - Math.PI / 2
                    }
                    angle += radialshift

                    x = inradius * Math.cos(angle) + cx
                    y = inradius * Math.sin(angle) + cy

                    polyPoints += x + ',' + y + ' '
                  }
                }
                elem.setAttribute('points', polyPoints)
                addToHistory(new ChangeElementCommand(elem, { point: oldPoint, points: oldPoints }))
              }
            }
          }
        })
        $id('RadiusMultiplier').addEventListener('change', (event) => {
          setAttr('starRadiusMultiplier', event.target.value)
        })
        $id('radialShift').addEventListener('change', (event) => {
          setAttr('radialshift', event.target.value)
        })
        $id('polySides').addEventListener('change', (event) => {
          setAttr('sides', event.target.value)
          const sides = event.target.value
          let i = selElems.length
          while (i--) {
            const elem = selElems[i]
            if (elem.hasAttribute('edge')) {
              const oldSides = elem.getAttribute('sides')
              const oldPoints = elem.getAttribute('points')
              let xpos = 0
              let ypos = 0
              if (elem.points) {
                const list = elem.points
                const len = list.numberOfItems
                for (let i = 0; i < len; ++i) {
                  const pt = list.getItem(i)
                  xpos += parseFloat(pt.x)
                  ypos += parseFloat(pt.y)
                }
                const cx = xpos / len
                const cy = ypos / len
                const edg = elem.getAttribute('edge')
                const inradius = (edg / 2) * cot(Math.PI / sides)
                const circumradius = inradius * sec(Math.PI / sides)
                let points = ''
                for (let s = 0; sides >= s; s++) {
                  const angle = (2.0 * Math.PI * s) / sides
                  const x = circumradius * Math.cos(angle) + cx
                  const y = circumradius * Math.sin(angle) + cy
                  points += x + ',' + y + ' '
                }
                elem.setAttribute('points', points)
                addToHistory(new ChangeElementCommand(elem, { sides: oldSides, points: oldPoints }))
              }
            }
          }
        })
      }
@param {Float} n angle
@returns {Float} sec