Skip to content

Commit

Permalink
Update map-feature.getFallbackCS()
Browse files Browse the repository at this point in the history
Remove 'meta' option for showPaginationFeature.
Add meta array property to each feature that is
returned by a query.  The meta array points
to an array of <map-meta> elements that were
retrieved from the query response document.
These are appended to the <map-link> shadow root
for each pagination feature, which might be a
bit inefficient but will not give incorrect results.

Make it so that <map-extent>.getMeta looks for
name=cs type metas.

Add queryFeatureCSFallback test
  • Loading branch information
prushforth committed Apr 26, 2024
1 parent ed7a763 commit b6bfbe1
Show file tree
Hide file tree
Showing 12 changed files with 195 additions and 31 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/map-extent.js
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ export class MapExtent extends HTMLElement {
}
getMeta(metaName) {
let name = metaName.toLowerCase();
if (name !== 'extent' && name !== 'zoom') return;
if (name !== 'extent' && name !== 'zoom' && name !== 'cs') return;
return this.parentLayer.src
? this.querySelector(`:scope > map-meta[name=${name}]`) ||
this.parentLayer.shadowRoot.querySelector(
Expand Down
23 changes: 11 additions & 12 deletions src/map-feature.js
Original file line number Diff line number Diff line change
Expand Up @@ -287,24 +287,23 @@ export class MapFeature extends HTMLElement {
_getFallbackCS() {
let csMeta;
if (this._parentEl.nodeName === 'MAP-LINK') {
// feature attaches to link's shadow
// feature attaches to link's shadow root
csMeta =
this._parentEl.shadowRoot.querySelector('map-meta[name=cs]') ||
this._parentEl.shadowRoot.querySelector('map-meta[name=cs][content]') ||
this._parentEl.parentElement.getMeta('cs');
} else {
let layerEl = this.getLayerEl();
csMeta = layerEl.src
? layerEl.shadowRoot.querySelector('map-meta[name=cs]')
: layerEl.querySelector('map-meta[name=cs]');
}
if (csMeta) {
// M._metaContentObject("gcrs") -> {content: "gcrs"}
return (
M._metaContentToObject(csMeta.getAttribute('content')).content || 'gcrs'
);
} else {
return 'gcrs';
? layerEl.shadowRoot.querySelector('map-meta[name=cs][content]')
: layerEl.querySelector('map-meta[name=cs][content]');
}
// even here we could make an effort to use the tref variables to determine
// the coordinate system of the response - would only work with WMS, I think
// the fallback 'gcrs' SHOULD be specified by the MapML spec
// per https://github.com/Maps4HTML/MapML/issues/257
return csMeta
? M._metaContentToObject(csMeta.getAttribute('content')).content
: 'gcrs';
}

// Util functions:
Expand Down
14 changes: 11 additions & 3 deletions src/mapml/handlers/QueryHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ export var QueryHandler = L.Handler.extend({
})
.then((response) => {
let features = [];
let queryMetas = [];
let geom =
"<map-geometry cs='gcrs'><map-point><map-coordinates>" +
e.latlng.lng +
Expand Down Expand Up @@ -129,11 +130,13 @@ export var QueryHandler = L.Handler.extend({
mapmldoc.querySelectorAll('map-feature')
);
// <map-meta> elements for this query
layer.queryMetas = Array.prototype.slice.call(
queryMetas = Array.prototype.slice.call(
mapmldoc.querySelectorAll(
'map-meta[name=cs], map-meta[name=zoom], map-meta[name=projection]'
)
);
if (queryMetas.length)
features.forEach((f) => (f.meta = queryMetas));
} else {
try {
let featureDocument = parser.parseFromString(
Expand All @@ -149,10 +152,16 @@ export var QueryHandler = L.Handler.extend({
throw new Error('parsererror');
}
let g = parser.parseFromString(geom, 'application/xml');
queryMetas = Array.prototype.slice.call(
featureDocument.querySelectorAll(
'map-meta[name=cs], map-meta[name=zoom], map-meta[name=projection]'
)
);
for (let feature of featureCollection) {
if (!feature.querySelector('map-geometry')) {
feature.appendChild(g.firstElementChild.cloneNode(true));
}
feature.meta = queryMetas;
features.push(feature);
}
} catch (err) {
Expand Down Expand Up @@ -339,8 +348,7 @@ export var QueryHandler = L.Handler.extend({
});
f.showPaginationFeature({
i: 0,
popup: layer._popup,
meta: layer.queryMetas
popup: layer._popup
});
}
}
Expand Down
10 changes: 8 additions & 2 deletions src/mapml/layers/ExtentLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,20 @@ export var ExtentLayer = L.LayerGroup.extend({
_previousFeature: function (e) {
if (this._count + -1 >= 0) {
this._count--;
this._map.fire('featurepagination', { i: this._count, popup: this });
this._map.fire('featurepagination', {
i: this._count,
popup: this
});
}
},

_nextFeature: function (e) {
if (this._count + 1 < this._source._totalFeatureCount) {
this._count++;
this._map.fire('featurepagination', { i: this._count, popup: this });
this._map.fire('featurepagination', {
i: this._count,
popup: this
});
}
},

Expand Down
15 changes: 4 additions & 11 deletions src/mapml/layers/FeatureLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -259,19 +259,12 @@ export var FeatureLayer = L.FeatureGroup.extend({
showPaginationFeature: function (e) {
if (this.options.query && this._queryFeatures[e.i]) {
let feature = this._queryFeatures[e.i];
if (e.type === 'featurepagination') {
// remove map-feature only (keep meta's) when paginating
feature._linkEl.shadowRoot.querySelector('map-feature')?.remove();
} else {
// empty the map-extent shadowRoot
// remove the prev / next one <map-feature> and <map-meta>'s from shadow if there is any
feature._linkEl.shadowRoot.replaceChildren();
}
feature._linkEl.shadowRoot.replaceChildren();
this.clearLayers();
// append all map-meta from mapml document
if (e.meta) {
for (let i = 0; i < e.meta.length; i++) {
feature._linkEl.shadowRoot.appendChild(e.meta[i]);
if (feature.meta) {
for (let i = 0; i < feature.meta.length; i++) {
feature._linkEl.shadowRoot.appendChild(feature.meta[i]);
}
}
feature._linkEl.shadowRoot.appendChild(feature);
Expand Down
29 changes: 29 additions & 0 deletions test/e2e/data/tiles/cbmt/query-response-fallback-cs-meta.mapml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<mapml- xmlns="http://www.w3.org/1999/xhtml">
<map-head>
<map-title>Query response with non-default cs specified by map-meta</map-title>
<map-meta http-equiv="Content-Type" content="text/mapml"></map-meta>
<map-meta charset="utf-8"></map-meta>
<map-meta name="projection" content="CBMTILE"></map-meta>
<map-meta name="cs" content="pcrs"></map-meta>
<map-link rel="license" href="https://leafletjs.com/examples/choropleth/" title=" CC-BY-SA Vladimir Agafonkin"></map-link>
<map-style> .all { fill-opacity: 0.7; stroke-width: 2; stroke: white; stroke-opacity: 1; stroke-dasharray: 3; } ._1000plus { fill: #800026; } ._500-1000 { fill: #BD0026; } ._200-500 { fill: #E31A1C; } ._100-200 { fill: #FC4E2A; } ._50-100 { fill: #FD8D3C; } ._20-50 { fill: #FEB24C; } ._10-20 { fill: #FED976; } ._0-10 { fill: #FFEDA0; } </map-style>
</map-head>
<map-body>
<map-feature id="states.18" class="refDiff">
<map-featurecaption>Mississippi</map-featurecaption>
<!-- prior to fixing issue #958, this would not throw coordinate projection errors,
but only due to an accident: the system would include the last
map-meta elements loaded into the first map-link shadow root which
could be from different origins even -->
<map-geometry>
<map-polygon>
<map-coordinates>688228.3 -2006275.6 693915 -2044584.4 696005.9 -2059245.5 700633.9 -2091524.2 706701.1 -2133505.9 707456.2 -2138488.4 700853.7 -2142509.9 688040.3 -2137015.6 677246.9 -2142881.1 655838.5 -2134043.1 649974.2 -2136282.2 654944.1 -2138106.3 614173 -2152286.9 613810 -2145165.7 607145.3 -2144765.2 604908 -2146846 609589.2 -2152200 599878.8 -2160817.9 598068.2 -2167883.7 583569.8 -2169889.5 579207.3 -2164479.2 579535.8 -2163654.3 577794.8 -2162666.1 576987 -2158583.1 575513 -2158027.3 575569.8 -2156032.1 577425.2 -2154394 577047.1 -2151981.8 575505.1 -2150636.4 574089.2 -2150758.1 572988.3 -2147897.4 570557.4 -2145492.4 570079.1 -2139910.1 569046.5 -2137840.9 567799.9 -2137266.4 567580.5 -2136036.2 565679.5 -2135801.4 564902.5 -2134051.5 563468.9 -2133947.3 560848.3 -2131957.7 558607.3 -2127723.2 556655.4 -2127549.2 552807.6 -2119144.2 554126.6 -2115914.8 552638 -2115814.8 551358.7 -2113486.7 549710.8 -2114193.5 550684.2 -2112921 549967.7 -2112528.6 549804.5 -2109936.6 550901.4 -2109447.1 549397.7 -2108498.6 550125.2 -2106341.6 551386.4 -2105781.6 551059.9 -2104620.1 552302.4 -2103835.1 550681 -2098822 551920.4 -2096000.6 553435.4 -2095758.5 553319.7 -2093731.8 555564.3 -2093370.7 554166.2 -2089643.6 556193.7 -2089414.2 556073.9 -2084674.8 557799.4 -2084244.9 557835.8 -2083337.3 556422.1 -2082101.5 558232.1 -2081325.2 557136.9 -2078480.2 557933 -2076491.2 559914.5 -2075078.7 559085.3 -2074019.8 559246.7 -2071916.2 558224.7 -2071269.3 547564.5 -2072177.6 502522 -2075669.3 493621.9 -2076572.5 472589 -2078459.9 470731.3 -2078666.9 442206.1 -2080620.3 418145.3 -2082296.2 405202.9 -2083081.7 357196.4 -2085686.1 357606.6 -2084357.3 363294.4 -2081501.2 365316.9 -2078245.6 363792.8 -2075371.9 357661.2 -2070084.9 360352.6 -2063683.1 359119 -2059382.8 355139 -2056248.2 354239.3 -2052600.5 355194.9 -2051740.5 363391.6 -2052190.5 367507.4 -2050414.8 368940 -2048392.5 368428.2 -2045393 364370.5 -2042719.6 364054.1 -2040043.8 364996.3 -2038285.5 362350.1 -2037755.2 361251.4 -2033734.5 362778.1 -2032213.9 364627.3 -2031961.3 364861.7 -2035034.8 366149.7 -2037073.4 369241.3 -2038975.3 370683.6 -2038584.2 372073.8 -2035273.2 371187.7 -2033317 367328.7 -2029508.1 366988.6 -2020602.7 367296.6 -2019456.1 371279.7 -2018254.4 375432.4 -2015579.5 377295.2 -2012574.4 376016.3 -2010651.9 367436.6 -2010913.6 366089.5 -2008828 366054 -2006138 367057.9 -2005220.3 371449.8 -2007914.8 376589.1 -2007802.7 378399.7 -2004130 378097.3 -1996527.5 380243.6 -1992103.3 379664.7 -1991923.6 382824.8 -1991120.6 388871.9 -1991831.5 390747.6 -1990509.6 390782 -1988769.9 383170.9 -1990477.5 379894.6 -1989776.8 381797.5 -1986605.4 382755.1 -1980707.5 385887.7 -1978114.8 387028.4 -1978250.9 388923.8 -1982303.9 391706.7 -1983208.7 392562.2 -1981126.5 389913.8 -1977580.1 391926.4 -1975857.3 396140.8 -1971221.4 399594.8 -1961946.8 405292.3 -1961167.1 408776.6 -1957372.4 408615.6 -1956042.9 407099.2 -1954708.6 401100.7 -1952326.7 400688.9 -1949956.1 402742.8 -1949516.5 406748.9 -1953115.3 409259.4 -1952751 408077.7 -1948485.2 411371.3 -1946606.8 414261.7 -1943196.2 414765 -1938857.2 412626.5 -1938913.4 409399.8 -1937324.5 410545.6 -1940416.9 409823.7 -1943432.7 406713 -1941889.3 404149 -1943709.5 399115.3 -1942817.8 397846.2 -1939566.1 398589.8 -1935378 402722.7 -1932712.5 404395.6 -1933920.8 405575.3 -1931708 408207.9 -1931502.1 410236.1 -1929334.4 417105.5 -1932086.6 417395.1 -1926484.6 415931.5 -1924368.7 416166.1 -1923067.8 417061.4 -1922272.1 421495.5 -1922758.7 422764.4 -1921710.1 426418.1 -1912390.3 425392.5 -1912248.5 422596.6 -1916761.3 415321.2 -1915942.4 413769 -1914838.4 412464.7 -1911152.1 416343.8 -1908228.2 416645.8 -1905642.2 414281.2 -1904213.5 410292.8 -1905752.1 406999 -1905397.8 400513.2 -1899502.4 400214.5 -1896409.2 403116.2 -1893233.6 408817.6 -1899186.5 410669.1 -1899820.3 413482.3 -1899098.2 413045.6 -1897129 405810 -1893857.4 404616.1 -1891558.4 405986.2 -1889670.9 408669.2 -1888737.5 411881.6 -1884536.3 412060.7 -1883243.4 410725.7 -1881291.7 408722.2 -1881560.1 406855.4 -1884986.8 405251.8 -1886057.7 400466.3 -1887433 396490 -1881905.2 397043.9 -1879638.2 404861.2 -1871804.3 400699.5 -1868908.4 396712 -1868941.6 394588.9 -1867663 395465.3 -1858047.4 401607.6 -1853295.6 401437.2 -1843992.2 399439.3 -1839991.3 397486.9 -1840144 395479.3 -1841741.2 396005 -1846301.7 395410.1 -1848732.1 392178.1 -1850480.7 389186 -1849548.4 387919.8 -1846985.5 392281.9 -1838886.6 392161.4 -1837344.3 392246.6 -1836285.2 392516.6 -1833992.8 395801.6 -1832961.9 396298 -1830707.4 393157.1 -1827850.7 388535.1 -1825387 387831.6 -1822120.1 389580.1 -1820822.1 395453 -1822800.6 397942.7 -1820945.6 398790.4 -1818887.2 397735 -1811169.3 401391.8 -1808505.2 402553.6 -1804046.6 401105 -1802722.5 398830.9 -1803011 396452.4 -1808393.9 394318.6 -1806182.7 391968.6 -1799788.4 392845 -1795245.1 394974.3 -1790991.5 397711.9 -1788789.5 399289.7 -1786071.1 399132.5 -1782660.9 397793 -1781993.1 396599.7 -1782472.7 395606.5 -1788347 391897.5 -1791728.3 387077.6 -1791661.6 384971.7 -1789063.8 385455.4 -1788087.8 392219.7 -1785132.7 393241.8 -1783893.7 393194 -1781855.5 392025.2 -1779077.1 388230.5 -1777055.1 387354 -1778005.9 387876.1 -1782545.2 386999.8 -1784931.6 381857 -1785716.7 382319.2 -1783748.9 384193.2 -1781947.9 386668.9 -1777121.1 386339.9 -1775767.4 384081.8 -1774067 383127.9 -1774030.6 381576 -1772055.1 381422.4 -1767931.6 385466.9 -1769603.3 387446.2 -1769173.8 388916 -1764373.2 388384.8 -1761879.1 383013 -1758219 381872.3 -1755773 382090.2 -1753553.2 386895.7 -1752133.8 391451.3 -1756791.8 395319.5 -1758362.6 399795.5 -1755588.5 399528.1 -1752910 397672.9 -1751347.7 392885.4 -1752988.9 390399 -1752631.9 389407.8 -1751387.6 388559.8 -1745561.9 389093.3 -1744529.8 392296.2 -1744775.3 396146.8 -1743318.4 398586.2 -1745219.3 401140.6 -1745734.6 403402.9 -1744676.2 404438.5 -1742943.1 403698.5 -1741350.4 399695.9 -1739463.1 396884.6 -1736381.7 396050.3 -1733586.5 399837.1 -1724986.4 393811 -1720731 392346.6 -1718427.4 394179.4 -1716910.5 398202.5 -1719123.2 400321.8 -1718407.3 401419.9 -1721013.8 402824.7 -1721837.9 404981.8 -1720898.6 405261.5 -1719502.4 403724.2 -1717700.2 403790.3 -1715716.7 405927.7 -1713131.2 412273.4 -1711585.9 413804.9 -1704215.2 409794.5 -1704258.1 406024.3 -1701701.6 404686.4 -1698184.6 406896.3 -1694443.7 415410.4 -1698488.7 417173.9 -1698238.7 419167.8 -1695994.7 417436.6 -1693169.1 407490.1 -1692092.7 406041.3 -1688587 406447.6 -1686690.2 413172.3 -1689997 416287.3 -1688542.8 416660.2 -1682755.1 418221.1 -1679999.8 419599.8 -1679835.1 423180.6 -1682125.8 423915.2 -1677407.1 422141.9 -1671959.6 422726.8 -1670926.5 429424.8 -1669787.9 430173.9 -1671480.5 429706.6 -1676724.4 430723.6 -1676916.9 432767.2 -1675327.5 432529.7 -1671017.4 437523.9 -1666013.1 439737.7 -1662438.6 440031.7 -1659895.7 438124.2 -1654904 438889.1 -1651996.1 440240.2 -1650423 442977.3 -1648929.3 443520.6 -1647408.2 438455 -1641855.9 437236.1 -1639165.6 437947.6 -1636975.8 439294.6 -1630307.7 441588.3 -1631871 441036.3 -1636015 442010.5 -1637740.1 444983.1 -1637389.7 448905.2 -1633025.1 448259.3 -1629197.7 443971.9 -1629764.9 441930.1 -1628564.2 439854.9 -1619446.2 441732.3 -1617273.5 442852.6 -1617401.2 444441.8 -1619183.4 444896.9 -1622040.8 443244.7 -1624250.5 444640.3 -1626377.3 446492 -1626609.2 449774.9 -1624648.1 449860.3 -1622292.1 447768.1 -1617765.7 449008.8 -1614606.9 446483.6 -1610882.5 446698.4 -1608081.5 449847.2 -1607224.8 450972.2 -1608769.6 450730.7 -1613265.7 451864.6 -1613554.8 453599.8 -1612376 459586.7 -1609592.6 461509.1 -1610689.9 463590.8 -1610354.8 463681.6 -1608764.3 463837.2 -1606623.3 466624.1 -1604756.2 468755.6 -1601688.4 468686 -1599511.5 467972.4 -1598261.6 462671.9 -1595208.5 461901.7 -1592599.5 519660.1 -1588243.3 526584.5 -1587486.1 556437.1 -1585007 570571.8 -1583600.6 589399.1 -1581927.7 608355.8 -1579841.8 611042.8 -1579489.6 650393.7 -1575282.9 653485.6 -1575104.7 668923 -1573391.1 674860.1 -1581677.8 678607.9 -1584930 680470.4 -1585246 680034.1 -1623299.4 680054.8 -1637213.2 680255.3 -1654250.6 680108.5 -1682551 680182.6 -1686337.7 679683.9 -1724763.8 679637.5 -1749544.8 679769.9 -1779941 680085.7 -1816654 680008.5 -1824321.1 679684.2 -1866444.3 679818.1 -1899662.8 679612.3 -1909678 680218.8 -1951250 683377.8 -1973898.5 688228.3 -2006275.6</map-coordinates>
</map-polygon>
</map-geometry>
<map-properties>
<h1>PCRS geometry cs not specified by map-geometry cs attribute, but by map-meta</h1>
</map-properties>
</map-feature>

</map-body>
</mapml->
25 changes: 25 additions & 0 deletions test/e2e/data/tiles/cbmt/query-response-fallback-cs-no-meta.mapml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<mapml- xmlns="http://www.w3.org/1999/xhtml">
<map-head>
<map-title>Query response with default / fallback cs of 'gcrs'</map-title>
<map-meta http-equiv="Content-Type" content="text/mapml"></map-meta>
<map-meta charset="utf-8"></map-meta>
<map-meta name="projection" content="CBMTILE"></map-meta>
<map-meta name="cs" content="pcrs"></map-meta>
<map-link rel="license" href="https://leafletjs.com/examples/choropleth/" title=" CC-BY-SA Vladimir Agafonkin"></map-link>
<map-style> .all { fill-opacity: 0.7; stroke-width: 2; stroke: white; stroke-opacity: 1; stroke-dasharray: 3; } ._1000plus { fill: #800026; } ._500-1000 { fill: #BD0026; } ._200-500 { fill: #E31A1C; } ._100-200 { fill: #FC4E2A; } ._50-100 { fill: #FD8D3C; } ._20-50 { fill: #FEB24C; } ._10-20 { fill: #FED976; } ._0-10 { fill: #FFEDA0; } </map-style>
</map-head>
<map-body>
<map-feature zoom="0" class="all _50-100">
<map-properties>
<h1>PCRS geometry cs not specified by map-geometry cs attribute, but by map-meta</h1>
</map-properties>
<map-geometry>
<!-- before fixing issue #958 this would throw because the map-meta
elements above would not be included in the (correct) map-link
shadow root -->
<map-polygon>
<map-coordinates>-1439979.3 -1758949.3 -1431164.7 -1718827 -1419763.8 -1668441.6 -1404426.5 -1600224.3 -1382942.6 -1505323.2 -1373220.3 -1462927.4 -1346103.5 -1341605.7 -1320202.9 -1225969.1 -1257567.3 -1239340.4 -1174071.5 -1256624.9 -1168371.8 -1257904.9 -1119925.2 -1267086.5 -1117424 -1268710.9 -1081131.5 -1275202.5 -1036324.3 -1283103.9 -1010270 -1287321.2 -963537.4 -1295313.3 -957266.3 -1296253.3 -849276 -1312473 -763210.2 -1323460.8 -755695.1 -1324562.6 -763175.8 -1383979.1 -766024.2 -1383711.3 -772219.2 -1435026.6 -776776 -1472071.3 -778523.5 -1486102.1 -785600.5 -1538912.4 -788711.3 -1564140.2 -791764.7 -1590253.5 -799064.4 -1642281 -806729.8 -1699789.4 -811239.8 -1730909.9 -814545.7 -1753414.3 -821663.3 -1804345.1 -829483.1 -1857053.1 -835669.1 -1909197.2 -837238.8 -1919235.1 -865524.4 -1915292.7 -906466 -1909528.1 -932459.2 -1905912.3 -936345.7 -1905187.3 -1022114.9 -1892881.1 -1029425.4 -1891597.3 -1140566 -1873486.2 -1179064.8 -1866755.1 -1204189.5 -1862119.6 -1207360 -1864114.4 -1205751.4 -1865420.6 -1207161.7 -1872389.1 -1208642.5 -1874466.1 -1206894.7 -1881070 -1207376 -1884330.6 -1200313.6 -1889555.8 -1276802.9 -1875214.1 -1371026.7 -1855852.9 -1382989.8 -1908870.6 -1469030.7 -1890198.6 -1439979.3 -1758949.3</map-coordinates> </map-polygon>
</map-geometry>
</map-feature>
</map-body>
</mapml->
18 changes: 18 additions & 0 deletions test/e2e/layers/queryFeatureCSFallback.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<!doctype html>
<html lang="en">
<!-- queryFeatureCSFallback.html -->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Remote queryable map extents in mapml document</title>
<script type="module" src="mapml-viewer.js"></script>
</head>

<body>
<mapml-viewer style="width: 500px;height: 500px;" projection="CBMTILE" zoom="2" lat="35" lon="-90" controls>

<layer- label="remote queryable mapml document with multiple queryable extents" src="queryFeatureCSFallback.mapml" checked></layer->
</mapml-viewer>
</body>

</html>
Loading

0 comments on commit b6bfbe1

Please sign in to comment.