xwikisas / xwiki-pro-macros

XWiki rendering macros useful when migrating content from Confluence
GNU Lesser General Public License v2.1
3 stars 12 forks source link

Can't save a page with 2 Excerpt macros #257

Closed ane-gabriela closed 2 months ago

ane-gabriela commented 5 months ago

Steps to reproduce:

  1. Edit a page
  2. Click on Insert > Other macros
  3. Search and select Excerpt Macro
  4. Add desired Content eg. "Not hidden text"
  5. Click on Submit
  6. Add another empty row
  7. Search and select Excerpt Macro again
  8. Add desired Content eg. "Hidden text"
  9. Select the Hidden box
  10. Click on Submit

Expected results: One text appears and the other is hidden.

Actual results: Can't save the page with the 2 Excerpt macros

Excerpt2

Environment: Windows 11, XWiki Cloud 15.10.8, Chrome 124, Pro Macros 1.16.5

2024-05-09 17:18:26,584 [qtp1413246829-608 - http://localhost:8080/xwiki/bin/save/Excerpt%20Macro/] ERROR o.x.w.i.c.DefaultHTMLConverter - Failed to parse input source
org.xwiki.rendering.parser.ParseException: Failed to parse input source
        at org.xwiki.rendering.internal.parser.wikimodel.AbstractWikiModelParser.parse(AbstractWikiModelParser.java:147)
        at org.xwiki.rendering.internal.parser.xhtml.XHTMLParser.parse(XHTMLParser.java:219)
        at org.xwiki.rendering.internal.parser.wikimodel.AbstractWikiModelParser.parse(AbstractWikiModelParser.java:121)
        at org.xwiki.rendering.internal.parser.xhtml.XHTMLParser.parse(XHTMLParser.java:210)
        at org.xwiki.wysiwyg.internal.converter.DefaultHTMLConverter.fromHTML(DefaultHTMLConverter.java:145)
        at org.xwiki.wysiwyg.internal.converter.DefaultRequestParameterConverter.convertHTML(DefaultRequestParameterConverter.java:128)
        at org.xwiki.wysiwyg.internal.converter.DefaultRequestParameterConverter.convert(DefaultRequestParameterConverter.java:111)
        at org.xwiki.wysiwyg.internal.converter.DefaultRequestParameterConverter.convert(DefaultRequestParameterConverter.java:90)
        at org.xwiki.wysiwyg.filter.ConversionFilter.doFilter(ConversionFilter.java:58)
        at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:202)
        at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1635)
        at org.xwiki.container.servlet.filters.internal.SetHTTPHeaderFilter.doFilter(SetHTTPHeaderFilter.java:63)
        at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:202)
        at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1635)
        at org.xwiki.resource.servlet.RoutingFilter.doFilter(RoutingFilter.java:132)
        at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:202)
        at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1635)
        at org.xwiki.container.servlet.filters.internal.SavedRequestRestorerFilter.doFilter(SavedRequestRestorerFilter.java:208)
        at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:202)
        at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1635)
        at org.xwiki.container.servlet.filters.internal.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:111)
        at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:210)
        at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1635)
        at org.eclipse.jetty.websocket.servlet.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:170)
        at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:202)
        at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1635)
        at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:527)
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:131)
        at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:598)
        at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)
        at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:223)
        at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1580)
        at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:221)
        at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1384)
        at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:176)
        at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:484)
        at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1553)
        at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:174)
        at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1306)
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:129)
        at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:192)
        at org.eclipse.jetty.server.handler.HandlerList.handle(HandlerList.java:51)
        at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)
        at org.eclipse.jetty.server.Server.handle(Server.java:563)
        at org.eclipse.jetty.server.HttpChannel$RequestDispatchable.dispatch(HttpChannel.java:1598)
        at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:753)
        at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:501)
        at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:287)
        at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:314)
        at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:100)
        at org.eclipse.jetty.io.SelectableChannelEndPoint$1.run(SelectableChannelEndPoint.java:53)
        at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.runTask(AdaptiveExecutionStrategy.java:421)
        at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.consumeTask(AdaptiveExecutionStrategy.java:390)
        at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.tryProduce(AdaptiveExecutionStrategy.java:277)
        at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.run(AdaptiveExecutionStrategy.java:199)
        at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:411)
        at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:969)
        at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.doRunJob(QueuedThreadPool.java:1194)
        at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1149)
        at java.base/java.lang.Thread.run(Thread.java:842)
Caused by: org.xwiki.rendering.wikimodel.WikiParserException: java.lang.NullPointerException: Cannot invoke "org.xwiki.rendering.wikimodel.xhtml.impl.MacroInfo.getContentScannerContext()" because "macroInfo" is null
        at org.xwiki.rendering.wikimodel.xhtml.XhtmlParser.parse(XhtmlParser.java:136)
        at org.xwiki.rendering.internal.parser.wikimodel.AbstractWikiModelParser.parse(AbstractWikiModelParser.java:141)
        ... 59 common frames omitted
Caused by: java.lang.NullPointerException: Cannot invoke "org.xwiki.rendering.wikimodel.xhtml.impl.MacroInfo.getContentScannerContext()" because "macroInfo" is null
        at org.xwiki.rendering.internal.parser.xhtml.wikimodel.XWikiMacroHandler.handleBegin(XWikiMacroHandler.java:153)
        at org.xwiki.rendering.internal.parser.xhtml.wikimodel.XWikiSpanTagHandler.begin(XWikiSpanTagHandler.java:57)
        at org.xwiki.rendering.internal.parser.xhtml5.wikimodel.XHTML5SpanTagHandler.begin(XHTML5SpanTagHandler.java:70)
        at org.xwiki.rendering.wikimodel.xhtml.handler.TagHandler.beginElement(TagHandler.java:67)
        at org.xwiki.rendering.wikimodel.xhtml.impl.TagContext.beginElement(TagContext.java:74)
        at org.xwiki.rendering.wikimodel.xhtml.impl.TagStack.beginElement(TagStack.java:114)
        at org.xwiki.rendering.wikimodel.xhtml.impl.XhtmlHandler.startElement(XhtmlHandler.java:222)
        at java.xml/org.xml.sax.helpers.XMLFilterImpl.startElement(XMLFilterImpl.java:539)
        at org.xwiki.rendering.wikimodel.xhtml.filter.XHTMLWhitespaceXMLFilter.sendInlineEvent(XHTMLWhitespaceXMLFilter.java:299)
        at org.xwiki.rendering.wikimodel.xhtml.filter.XHTMLWhitespaceXMLFilter.appendInlineEvent(XHTMLWhitespaceXMLFilter.java:370)
        at org.xwiki.rendering.wikimodel.xhtml.filter.XHTMLWhitespaceXMLFilter.startElement(XHTMLWhitespaceXMLFilter.java:162)
        at java.xml/org.xml.sax.helpers.XMLFilterImpl.startElement(XMLFilterImpl.java:539)
        at org.xwiki.rendering.wikimodel.xhtml.filter.AccumulationXMLFilter.startElement(AccumulationXMLFilter.java:74)
        at java.xml/org.xml.sax.helpers.XMLFilterImpl.startElement(XMLFilterImpl.java:539)
        at org.xwiki.rendering.wikimodel.xhtml.filter.DTDXMLFilter.startElement(DTDXMLFilter.java:73)
        at org.apache.xerces.parsers.AbstractSAXParser.startElement(Unknown Source)
        at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
        at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
        at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
        at org.apache.xerces.parsers.XML11NonValidatingConfiguration.parse(Unknown Source)
        at org.apache.xerces.parsers.XML11NonValidatingConfiguration.parse(Unknown Source)
        at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
        at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
        at java.xml/org.xml.sax.helpers.XMLFilterImpl.parse(XMLFilterImpl.java:345)
        at org.xwiki.rendering.wikimodel.xhtml.filter.DefaultXMLFilter.parse(DefaultXMLFilter.java:58)
        at java.xml/org.xml.sax.helpers.XMLFilterImpl.parse(XMLFilterImpl.java:345)
        at org.xwiki.rendering.wikimodel.xhtml.filter.DefaultXMLFilter.parse(DefaultXMLFilter.java:58)
        at java.xml/org.xml.sax.helpers.XMLFilterImpl.parse(XMLFilterImpl.java:345)
        at org.xwiki.rendering.wikimodel.xhtml.filter.DefaultXMLFilter.parse(DefaultXMLFilter.java:58)
        at org.xwiki.rendering.wikimodel.xhtml.XhtmlParser.parse(XhtmlParser.java:134)
        ... 60 common frames omitted
2024-05-09 17:18:26,586 [qtp1413246829-608 - http://localhost:8080/xwiki/bin/save/Excerpt%20Macro/] ERROR faultRequestParameterConverter - Exception while parsing HTML
java.lang.RuntimeException: Exception while parsing HTML
        at org.xwiki.wysiwyg.internal.converter.DefaultHTMLConverter.fromHTML(DefaultHTMLConverter.java:150)
        at org.xwiki.wysiwyg.internal.converter.DefaultRequestParameterConverter.convertHTML(DefaultRequestParameterConverter.java:128)
        at org.xwiki.wysiwyg.internal.converter.DefaultRequestParameterConverter.convert(DefaultRequestParameterConverter.java:111)
        at org.xwiki.wysiwyg.internal.converter.DefaultRequestParameterConverter.convert(DefaultRequestParameterConverter.java:90)
        at org.xwiki.wysiwyg.filter.ConversionFilter.doFilter(ConversionFilter.java:58)
        at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:202)
        at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1635)
        at org.xwiki.container.servlet.filters.internal.SetHTTPHeaderFilter.doFilter(SetHTTPHeaderFilter.java:63)
        at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:202)
        at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1635)
        at org.xwiki.resource.servlet.RoutingFilter.doFilter(RoutingFilter.java:132)
        at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:202)
        at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1635)
        at org.xwiki.container.servlet.filters.internal.SavedRequestRestorerFilter.doFilter(SavedRequestRestorerFilter.java:208)
        at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:202)
        at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1635)
        at org.xwiki.container.servlet.filters.internal.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:111)
        at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:210)
        at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1635)
        at org.eclipse.jetty.websocket.servlet.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:170)
        at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:202)
        at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1635)
        at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:527)
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:131)
        at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:598)
        at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)
        at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:223)
        at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1580)
        at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:221)
        at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1384)
        at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:176)
        at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:484)
        at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1553)
        at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:174)
        at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1306)
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:129)
        at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:192)
        at org.eclipse.jetty.server.handler.HandlerList.handle(HandlerList.java:51)
        at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)
        at org.eclipse.jetty.server.Server.handle(Server.java:563)
        at org.eclipse.jetty.server.HttpChannel$RequestDispatchable.dispatch(HttpChannel.java:1598)
        at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:753)
        at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:501)
        at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:287)
        at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:314)
        at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:100)
        at org.eclipse.jetty.io.SelectableChannelEndPoint$1.run(SelectableChannelEndPoint.java:53)
        at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.runTask(AdaptiveExecutionStrategy.java:421)
        at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.consumeTask(AdaptiveExecutionStrategy.java:390)
        at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.tryProduce(AdaptiveExecutionStrategy.java:277)
        at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.run(AdaptiveExecutionStrategy.java:199)
        at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:411)
        at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:969)
        at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.doRunJob(QueuedThreadPool.java:1194)
        at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1149)
        at java.base/java.lang.Thread.run(Thread.java:842)
Caused by: org.xwiki.rendering.parser.ParseException: Failed to parse input source
        at org.xwiki.rendering.internal.parser.wikimodel.AbstractWikiModelParser.parse(AbstractWikiModelParser.java:147)
        at org.xwiki.rendering.internal.parser.xhtml.XHTMLParser.parse(XHTMLParser.java:219)
        at org.xwiki.rendering.internal.parser.wikimodel.AbstractWikiModelParser.parse(AbstractWikiModelParser.java:121)
        at org.xwiki.rendering.internal.parser.xhtml.XHTMLParser.parse(XHTMLParser.java:210)
        at org.xwiki.wysiwyg.internal.converter.DefaultHTMLConverter.fromHTML(DefaultHTMLConverter.java:145)
        ... 55 common frames omitted
Caused by: org.xwiki.rendering.wikimodel.WikiParserException: java.lang.NullPointerException: Cannot invoke "org.xwiki.rendering.wikimodel.xhtml.impl.MacroInfo.getContentScannerContext()" because "macroInfo" is null
        at org.xwiki.rendering.wikimodel.xhtml.XhtmlParser.parse(XhtmlParser.java:136)
        at org.xwiki.rendering.internal.parser.wikimodel.AbstractWikiModelParser.parse(AbstractWikiModelParser.java:141)
        ... 59 common frames omitted
Caused by: java.lang.NullPointerException: Cannot invoke "org.xwiki.rendering.wikimodel.xhtml.impl.MacroInfo.getContentScannerContext()" because "macroInfo" is null
        at org.xwiki.rendering.internal.parser.xhtml.wikimodel.XWikiMacroHandler.handleBegin(XWikiMacroHandler.java:153)
        at org.xwiki.rendering.internal.parser.xhtml.wikimodel.XWikiSpanTagHandler.begin(XWikiSpanTagHandler.java:57)
        at org.xwiki.rendering.internal.parser.xhtml5.wikimodel.XHTML5SpanTagHandler.begin(XHTML5SpanTagHandler.java:70)
        at org.xwiki.rendering.wikimodel.xhtml.handler.TagHandler.beginElement(TagHandler.java:67)
        at org.xwiki.rendering.wikimodel.xhtml.impl.TagContext.beginElement(TagContext.java:74)
        at org.xwiki.rendering.wikimodel.xhtml.impl.TagStack.beginElement(TagStack.java:114)
        at org.xwiki.rendering.wikimodel.xhtml.impl.XhtmlHandler.startElement(XhtmlHandler.java:222)
        at java.xml/org.xml.sax.helpers.XMLFilterImpl.startElement(XMLFilterImpl.java:539)
        at org.xwiki.rendering.wikimodel.xhtml.filter.XHTMLWhitespaceXMLFilter.sendInlineEvent(XHTMLWhitespaceXMLFilter.java:299)
        at org.xwiki.rendering.wikimodel.xhtml.filter.XHTMLWhitespaceXMLFilter.appendInlineEvent(XHTMLWhitespaceXMLFilter.java:370)
        at org.xwiki.rendering.wikimodel.xhtml.filter.XHTMLWhitespaceXMLFilter.startElement(XHTMLWhitespaceXMLFilter.java:162)
        at java.xml/org.xml.sax.helpers.XMLFilterImpl.startElement(XMLFilterImpl.java:539)
        at org.xwiki.rendering.wikimodel.xhtml.filter.AccumulationXMLFilter.startElement(AccumulationXMLFilter.java:74)
        at java.xml/org.xml.sax.helpers.XMLFilterImpl.startElement(XMLFilterImpl.java:539)
        at org.xwiki.rendering.wikimodel.xhtml.filter.DTDXMLFilter.startElement(DTDXMLFilter.java:73)
        at org.apache.xerces.parsers.AbstractSAXParser.startElement(Unknown Source)
        at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
        at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
        at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
        at org.apache.xerces.parsers.XML11NonValidatingConfiguration.parse(Unknown Source)
        at org.apache.xerces.parsers.XML11NonValidatingConfiguration.parse(Unknown Source)
        at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
        at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
        at java.xml/org.xml.sax.helpers.XMLFilterImpl.parse(XMLFilterImpl.java:345)
        at org.xwiki.rendering.wikimodel.xhtml.filter.DefaultXMLFilter.parse(DefaultXMLFilter.java:58)
        at java.xml/org.xml.sax.helpers.XMLFilterImpl.parse(XMLFilterImpl.java:345)
        at org.xwiki.rendering.wikimodel.xhtml.filter.DefaultXMLFilter.parse(DefaultXMLFilter.java:58)
        at java.xml/org.xml.sax.helpers.XMLFilterImpl.parse(XMLFilterImpl.java:345)
        at org.xwiki.rendering.wikimodel.xhtml.filter.DefaultXMLFilter.parse(DefaultXMLFilter.java:58)
        at org.xwiki.rendering.wikimodel.xhtml.XhtmlParser.parse(XhtmlParser.java:134)
        ... 60 common frames omitted
petrenkonikita112263 commented 5 months ago

This is similar to the previous one, as @michitux discovered in here. And XRENDERING-745 was fixed; I assume after the release of 15.10.9, this issue shouldn't occur.

michitux commented 5 months ago

But even after my bugfix, the content will be broken after saving. To properly fix this, the excerpt macro needs to be changed to not support inline mode anymore.