diff --git a/404.html b/404.html new file mode 100644 index 000000000..8b8a1fcad --- /dev/null +++ b/404.html @@ -0,0 +1,8 @@ +404: Not found | ICAT Project

ICAT Project

Search

NOT FOUND

It looks like nothing was found at this location. Maybe try a search?

+ + \ No newline at end of file diff --git a/404/index.html b/404/index.html new file mode 100644 index 000000000..f7e224657 --- /dev/null +++ b/404/index.html @@ -0,0 +1,8 @@ +404: Not found | ICAT Project

ICAT Project

Search

NOT FOUND

It looks like nothing was found at this location. Maybe try a search?

+ + \ No newline at end of file diff --git a/8012977a377924786019d370dc1adc53/apis.md b/8012977a377924786019d370dc1adc53/apis.md new file mode 100644 index 000000000..3d6341bbd --- /dev/null +++ b/8012977a377924786019d370dc1adc53/apis.md @@ -0,0 +1,12 @@ +--- +title: apis +--- + +TODO: Include summary of content [here](https://repo.icatproject.org/site/icat/server/4.8.0/user.html) and at the links below. + +- [IDS Restful API](https://repo.icatproject.org/site/ids/server/1.7.0/miredot/index.html) +- [ICAT Restful API](https://repo.icatproject.org/site/icat/server/4.8.0/miredot/index.html) +- [ICAT SOAP Manual](https://repo.icatproject.org/site/icat/server/4.8.0/soap.html) + +TODO: Describe and recommend the ICAT client APIs such as [python-icat](https://github.com/icatproject/python-icat) and [icat.client](https://github.com/icatproject/icat.client) + diff --git a/CNAME b/CNAME new file mode 100644 index 000000000..6b9c9d5f7 --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +icatproject.org \ No newline at end of file diff --git a/_gatsby/slices/_gatsby-scripts-1.html b/_gatsby/slices/_gatsby-scripts-1.html new file mode 100644 index 000000000..6efc36db5 --- /dev/null +++ b/_gatsby/slices/_gatsby-scripts-1.html @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/about/components-of-the-icat-project/index.html b/about/components-of-the-icat-project/index.html new file mode 100644 index 000000000..e3d1c543b --- /dev/null +++ b/about/components-of-the-icat-project/index.html @@ -0,0 +1,80 @@ +Components of the ICAT Project | ICAT Project

ICAT Project

Search

Components of the ICAT Project

Each components of the ICAT project has its own GitHub repository within +an icatproject organisation with the +code, a small Wiki and the Issue (bug/ feature request) List for that +component. If you simply want to install components then go to +Installation.

+

+ + + + ICAT Components + + +
ICAT Components
+

+
    +
  • ICAT server and client : the metadata catalogue provides  a SOAP web +service interface to the underlying database with an easy to use +API. Authentication makes use of plugins and authorization is rule +based. The icat-setup tool is provided for initial configuration of +an ICAT for a facility and a simple editor, ice, is also available. +Though ice is convenient as a web interface the +IcatManager, which +is a stand-alone application, provides similar functionality but is +much more pleasant to use.
  • +
  • IDS: the ICAT Data Service provides a uniform interface to data +catalogued by ICAT. It exposes a RESTful web service and provides +the ability to upload individual files and to download one or more +files. When a file is uploaded the metadata are stored in ICAT. ICAT +authorization rules for the "Datafile" ICAT are applied to control +read/write access to the files in the IDS. If multiple files are +requested they are packaged in zip format. The interface has some +calls which assume two level storage (with all data available on a +possibly slow system and recently used data on another) however it +will work fine with only one level. The server makes use of a plugin +mechanism so that a facility can choose its own directory structure +for file storage. A two level file storage example plugin is +provided as is an interface to which a plugin must conform if you +choose to write your own.
  • +
  • TopCAT: a web-based GUI able to search across multiple ICAT +instances, to download data and soon it will be able to upload data +as well. It makes use of both ICAT core and the IDS.
  • +
  • IJP: the ICAT Job Portal to allow submission of jobs where data +selection is based on ICAT information.  Both batch and interactive +jobs are supported. It makes use of both ICAT core and the IDS. It +is not currently shown on the diagram above.
  • +
  • To see the structure of ICAT you can use the ICAT +Manager.
  • +
+ + \ No newline at end of file diff --git a/about/index.html b/about/index.html new file mode 100644 index 000000000..fa1c6a80e --- /dev/null +++ b/about/index.html @@ -0,0 +1,15 @@ +About | ICAT Project

ICAT Project

Search

About

The ICAT software takes data from large scientific facilities - such as particle accelerators - and catalogues and indexes it so scientists can find the data they need and share it with their team. A simple REST interface allows scientific instrument designers to quickly upload their data to the system for indexing and cataloguing. TopCat, ICAT's easy to use web interface, allows scientists and collaborators to effortlessly search and download their data. ICAT's secure authentication system allows principal investigators to control their data and ensures users can only access data which they are allowed to access.

+

ICAT is in use at some of the world's largest scientific facilities enabling access to millions of datasets. The software is free & open-source and has been developed and maintained by an international collaboration for over 10 years.

+

What does ICAT do?

+

For a more detailed explanation of what ICAT does and the actors, entities and workflows it models, see the ICAT Schema page.

+

Who uses ICAT?

+

ICAT is used at many large scientific facilities. To find out how ICAT is supporting great science, see our case studies.

+

Who develops ICAT?

+

ICAT is developed by an international collaboration. There are monthly meetings to discuss development, yearly face-to-face meetings and a steering committee which agrees the roadmap. To find out more, see our Collaboration page.

+ + \ No newline at end of file diff --git a/about/useful-links/index.html b/about/useful-links/index.html new file mode 100644 index 000000000..df07691b3 --- /dev/null +++ b/about/useful-links/index.html @@ -0,0 +1,19 @@ +Useful Links | ICAT Project

ICAT Project

Search

Useful Links

This page exists to give direct access to a number of useful pages:

+

Using these web pages

+

Java ICAT Client SOAP API (5.0.0)

+

Java ICAT Client Rest API (5.0.0)

+

ICAT Server Rest Calls (5.0.0) – this shows the actual Rest interface offered by the server and is therefore language independent

+

Current (5.0.0) schema

+

icatgroup to which those interested in ICAT should subscribe.

+

Top of “site” leads to documentation for all components

+

ICAT Manager allows the data inside an ICAT to be viewed and manipulated from a simple table oriented GUI.

+

Maven repository for icatproject

+

Installation

+

Contributions to ICAT which may not necessarily be supported

+ + \ No newline at end of file diff --git a/app-e5500d896c7951a9bdcd.js b/app-e5500d896c7951a9bdcd.js new file mode 100644 index 000000000..cd6eff6cb --- /dev/null +++ b/app-e5500d896c7951a9bdcd.js @@ -0,0 +1,3 @@ +/*! For license information please see app-e5500d896c7951a9bdcd.js.LICENSE.txt */ +(self.webpackChunkicatproject_github_io=self.webpackChunkicatproject_github_io||[]).push([[143],{6298:function(t,e,n){"use strict";n.d(e,{iv:function(){return jt},tZ:function(){return Rt}});var r=n(7294),a=n.t(r,2);var o=function(){function t(t){var e=this;this._insertTag=function(t){var n;n=0===e.tags.length?e.insertionPoint?e.insertionPoint.nextSibling:e.prepend?e.container.firstChild:e.before:e.tags[e.tags.length-1].nextSibling,e.container.insertBefore(t,n),e.tags.push(t)},this.isSpeedy=void 0===t.speedy||t.speedy,this.tags=[],this.ctr=0,this.nonce=t.nonce,this.key=t.key,this.container=t.container,this.prepend=t.prepend,this.insertionPoint=t.insertionPoint,this.before=null}var e=t.prototype;return e.hydrate=function(t){t.forEach(this._insertTag)},e.insert=function(t){this.ctr%(this.isSpeedy?65e3:1)==0&&this._insertTag(function(t){var e=document.createElement("style");return e.setAttribute("data-emotion",t.key),void 0!==t.nonce&&e.setAttribute("nonce",t.nonce),e.appendChild(document.createTextNode("")),e.setAttribute("data-s",""),e}(this));var e=this.tags[this.tags.length-1];if(this.isSpeedy){var n=function(t){if(t.sheet)return t.sheet;for(var e=0;e0?d(x,--w):0,b--,10===k&&(b=1,v--),k}function E(){return k=w2||j(k)>3?"":" "}function M(t,e){for(;--e&&E()&&!(k<48||k>102||k>57&&k<65||k>70&&k<97););return R(t,_()+(e<6&&32==O()&&32==E()))}function L(t){for(;E();)switch(k){case t:return w;case 34:case 39:34!==t&&39!==t&&L(k);break;case 40:41===t&&L(t);break;case 92:E()}return w}function I(t,e){for(;E()&&t+k!==57&&(t+k!==84||47!==O()););return"/*"+R(e,w-1)+"*"+s(47===t?t:E())}function Z(t){for(;!j(O());)E();return R(t,w)}var z="-ms-",$="-moz-",F="-webkit-",H="comm",W="rule",U="decl",q="@keyframes";function B(t,e){for(var n="",r=h(t),a=0;a0&&m(L)-v&&g(y>32?K(L+";",r,n,v-1):K(u(L," ","")+";",r,n,v-2),l);break;case 59:L+=";";default:if(g(N=G(L,e,n,p,h,a,c,R,j=[],A=[],v),o),123===C)if(0===h)J(L,e,N,N,j,o,v,c,A);else switch(99===b&&110===d(L,3)?100:b){case 100:case 108:case 109:case 115:J(t,N,N,r&&g(G(t,N,N,0,0,a,c,R,a,j=[],v),A),a,A,v,c,r?j:A);break;default:J(L,N,N,N,[""],A,0,c,A)}}p=h=y=0,k=S=1,R=L="",v=i;break;case 58:v=1+m(L),y=w;default:if(k<1)if(123==C)--k;else if(125==C&&0==k++&&125==P())continue;switch(L+=s(C),C*k){case 38:S=h>0?1:(L+="\f",-1);break;case 44:c[p++]=(m(L)-1)*S,S=1;break;case 64:45===O()&&(L+=T(E())),b=O(),h=v=m(R=L+=Z(_())),C++;break;case 45:45===w&&2==m(L)&&(k=0)}}return o}function G(t,e,n,r,a,o,s,c,f,d,m){for(var g=a-1,v=0===a?o:[""],b=h(v),y=0,w=0,k=0;y0?v[x]+" "+C:u(C,/&\f/g,v[x])))&&(f[k++]=P);return S(t,e,n,0===a?W:c,f,d,m)}function V(t,e,n){return S(t,e,n,H,s(k),p(t,2,-2),0)}function K(t,e,n,r){return S(t,e,n,U,p(t,0,r),p(t,r+1,-1),r)}var X=function(t,e,n){for(var r=0,a=0;r=a,a=O(),38===r&&12===a&&(e[n]=1),!j(a);)E();return R(t,w)},tt=function(t,e){return N(function(t,e){var n=-1,r=44;do{switch(j(r)){case 0:38===r&&12===O()&&(e[n]=1),t[n]+=X(w-1,e,n);break;case 2:t[n]+=T(r);break;case 4:if(44===r){t[++n]=58===O()?"&\f":"",e[n]=t[n].length;break}default:t[n]+=s(r)}}while(r=E());return t}(A(t),e))},et=new WeakMap,nt=function(t){if("rule"===t.type&&t.parent&&!(t.length<1)){for(var e=t.value,n=t.parent,r=t.column===n.column&&t.line===n.line;"rule"!==n.type;)if(!(n=n.parent))return;if((1!==t.props.length||58===e.charCodeAt(0)||et.get(n))&&!r){et.set(t,!0);for(var a=[],o=tt(e,a),i=n.props,s=0,c=0;s6)switch(d(t,e+1)){case 109:if(45!==d(t,e+4))break;case 102:return u(t,/(.+:)(.+)-([^]+)/,"$1"+F+"$2-$3$1"+$+(108==d(t,e+3)?"$3":"$2-$3"))+t;case 115:return~f(t,"stretch")?at(u(t,"stretch","fill-available"),e)+t:t}break;case 4949:if(115!==d(t,e+1))break;case 6444:switch(d(t,m(t)-3-(~f(t,"!important")&&10))){case 107:return u(t,":",":"+F)+t;case 101:return u(t,/(.+:)([^;!]+)(;|!.+)?/,"$1"+F+(45===d(t,14)?"inline-":"")+"box$3$1"+F+"$2$3$1"+z+"$2box$3")+t}break;case 5936:switch(d(t,e+11)){case 114:return F+t+z+u(t,/[svh]\w+-[tblr]{2}/,"tb")+t;case 108:return F+t+z+u(t,/[svh]\w+-[tblr]{2}/,"tb-rl")+t;case 45:return F+t+z+u(t,/[svh]\w+-[tblr]{2}/,"lr")+t}return F+t+z+t+t}return t}var ot=[function(t,e,n,r){if(t.length>-1&&!t.return)switch(t.type){case U:t.return=at(t.value,t.length);break;case q:return B([C(t,{value:u(t.value,"@","@"+F)})],r);case W:if(t.length)return function(t,e){return t.map(e).join("")}(t.props,(function(e){switch(function(t,e){return(t=e.exec(t))?t[0]:t}(e,/(::plac\w+|:read-\w+)/)){case":read-only":case":read-write":return B([C(t,{props:[u(e,/:(read-\w+)/,":-moz-$1")]})],r);case"::placeholder":return B([C(t,{props:[u(e,/:(plac\w+)/,":"+F+"input-$1")]}),C(t,{props:[u(e,/:(plac\w+)/,":-moz-$1")]}),C(t,{props:[u(e,/:(plac\w+)/,z+"input-$1")]})],r)}return""}))}}],it=function(t){var e=t.key;if("css"===e){var n=document.querySelectorAll("style[data-emotion]:not([data-s])");Array.prototype.forEach.call(n,(function(t){-1!==t.getAttribute("data-emotion").indexOf(" ")&&(document.head.appendChild(t),t.setAttribute("data-s",""))}))}var r=t.stylisPlugins||ot;var a,i,s={},c=[];a=t.container||document.head,Array.prototype.forEach.call(document.querySelectorAll('style[data-emotion^="'+e+' "]'),(function(t){for(var e=t.getAttribute("data-emotion").split(" "),n=1;n=4;++r,a-=4)e=1540483477*(65535&(e=255&t.charCodeAt(r)|(255&t.charCodeAt(++r))<<8|(255&t.charCodeAt(++r))<<16|(255&t.charCodeAt(++r))<<24))+(59797*(e>>>16)<<16),n=1540483477*(65535&(e^=e>>>24))+(59797*(e>>>16)<<16)^1540483477*(65535&n)+(59797*(n>>>16)<<16);switch(a){case 3:n^=(255&t.charCodeAt(r+2))<<16;case 2:n^=(255&t.charCodeAt(r+1))<<8;case 1:n=1540483477*(65535&(n^=255&t.charCodeAt(r)))+(59797*(n>>>16)<<16)}return(((n=1540483477*(65535&(n^=n>>>13))+(59797*(n>>>16)<<16))^n>>>15)>>>0).toString(36)}(a)+c;return{name:l,styles:a,next:vt}},wt=!!a.useInsertionEffect&&a.useInsertionEffect,kt=wt||function(t){return t()},xt=(wt||r.useLayoutEffect,{}.hasOwnProperty),St=r.createContext("undefined"!=typeof HTMLElement?it({key:"css"}):null);St.Provider;var Ct=function(t){return(0,r.forwardRef)((function(e,n){var a=(0,r.useContext)(St);return t(e,a,n)}))};var Pt=r.createContext({});var Et="__EMOTION_TYPE_PLEASE_DO_NOT_USE__",Ot=function(t){var e=t.cache,n=t.serialized,r=t.isStringTag;return st(e,n,r),kt((function(){return function(t,e,n){st(t,e,n);var r=t.key+"-"+e.name;if(void 0===t.inserted[e.name]){var a=e;do{t.insert(e===a?"."+r:"",a,t.sheet,!0),a=a.next}while(void 0!==a)}}(e,n,r)})),null};var _t=Ct((function(t,e,n){var a=t.css;"string"==typeof a&&void 0!==e.registered[a]&&(a=e.registered[a]);var o=t[Et],i=[a],s="";"string"==typeof t.className?s=function(t,e,n){var r="";return n.split(" ").forEach((function(n){void 0!==t[n]?e.push(t[n]+";"):r+=n+" "})),r}(e.registered,i,t.className):null!=t.className&&(s=t.className+" ");var c=yt(i,void 0,r.useContext(Pt));s+=e.key+"-"+c.name;var l={};for(var u in t)xt.call(t,u)&&"css"!==u&&u!==Et&&(l[u]=t[u]);return l.ref=n,l.className=s,r.createElement(r.Fragment,null,r.createElement(Ot,{cache:e,serialized:c,isStringTag:"string"==typeof o}),r.createElement(o,l))})),Rt=(n(434),n(8679),function(t,e){var n=arguments;if(null==e||!xt.call(e,"css"))return r.createElement.apply(void 0,n);var a=n.length,o=new Array(a);o[0]=_t,o[1]=function(t,e){var n={};for(var r in e)xt.call(e,r)&&(n[r]=e[r]);return n[Et]=t,n}(t,e);for(var i=2;i{const n=t.endsWith(".html"),r=t.endsWith(".xml"),a=t.endsWith(".pdf");return"/"===t?t:((n||r||a)&&(e="never"),"always"===e?t.endsWith("/")?t:`${t}/`:"never"===e&&t.endsWith("/")?t.slice(0,-1):t)}},9679:function(t,e,n){"use strict";e.p2=e.$C=void 0;var r=n(1432);e.$C=r.ScrollHandler;var a=n(4855);e.p2=a.useScrollRestoration},1432:function(t,e,n){"use strict";var r=n(4836);e.__esModule=!0,e.ScrollHandler=e.ScrollContext=void 0;var a=r(n(6115)),o=r(n(7867)),i=function(t,e){if(!e&&t&&t.__esModule)return t;if(null===t||"object"!=typeof t&&"function"!=typeof t)return{default:t};var n=l(e);if(n&&n.has(t))return n.get(t);var r={},a=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var o in t)if("default"!==o&&Object.prototype.hasOwnProperty.call(t,o)){var i=a?Object.getOwnPropertyDescriptor(t,o):null;i&&(i.get||i.set)?Object.defineProperty(r,o,i):r[o]=t[o]}r.default=t,n&&n.set(t,r);return r}(n(7294)),s=r(n(5697)),c=n(1142);function l(t){if("function"!=typeof WeakMap)return null;var e=new WeakMap,n=new WeakMap;return(l=function(t){return t?n:e})(t)}var u=i.createContext(new c.SessionStorage);e.ScrollContext=u,u.displayName="GatsbyScrollContext";var f=function(t){function e(){for(var e,n=arguments.length,r=new Array(n),o=0;o{}},7730:function(t,e){"use strict";e.__esModule=!0,e.getForwards=function(t){return null==t?void 0:t.flatMap((t=>(null==t?void 0:t.forward)||[]))}},2731:function(t,e,n){"use strict";e.__esModule=!0,e.injectPartytownSnippet=function(t){if(!t.length)return;const e=document.querySelector("script[data-partytown]"),n=document.querySelector('iframe[src*="~partytown/partytown-sandbox-sw"]');e&&e.remove();n&&n.remove();const o=(0,a.getForwards)(t),i=document.createElement("script");i.dataset.partytown="",i.innerHTML=(0,r.partytownSnippet)({forward:o}),document.head.appendChild(i)};var r=n(2911),a=n(7730)},5418:function(t,e,n){e.components={"component---src-pages-404-jsx":()=>n.e(256).then(n.bind(n,7291)),"component---src-pages-search-jsx":()=>n.e(995).then(n.bind(n,6093)),"component---src-templates-default-jsx":()=>n.e(993).then(n.bind(n,6884))}},4741:function(t,e,n){t.exports=[{plugin:n(5688),options:{plugins:[],component:"/home/runner/work/icatproject.github.io/icatproject.github.io/src/components/layout.jsx"}},{plugin:n(436),options:{plugins:[]}},{plugin:n(2154),options:{plugins:[],maxWidth:700,showCaptions:!0,wrapperStyle:"margin-left: 0 !important; margin-right: 0 !important;",linkImagesToOriginal:!0,markdownCaptions:!1,backgroundColor:"white",quality:50,withWebp:!1,withAvif:!1,loading:"lazy",decoding:"async",disableBgImageOnAlpha:!1,disableBgImage:!1}},{plugin:n(9608),options:{plugins:[],name:"ICAT project website",short_name:"ICAT project",start_url:"/",background_color:"#ffffff",theme_color:"#000000",display:"browser",icon:"src/images/favicon.ico",legacy:!0,theme_color_in_head:!0,cache_busting_mode:"query",crossOrigin:"anonymous",include_favicon:!0,cacheDigest:"ff9257ddcf8e692608ae9f7a0c4c4455"}},{plugin:n(4094),options:{plugins:[]}}]},3092:function(t,e,n){const r=n(4741),{getResourceURLsForPathname:a,loadPage:o,loadPageSync:i}=n(1975).jN;e.h=function(t,e,n,s){void 0===e&&(e={});let c=r.map((n=>{if(!n.plugin[t])return;e.getResourceURLsForPathname=a,e.loadPage=o,e.loadPageSync=i;const r=n.plugin[t](e,n.options);return r&&s&&(e=s({args:e,result:r,plugin:n})),r}));return c=c.filter((t=>void 0!==t)),c.length>0?c:n?[n]:[]},e.I=(t,e,n)=>r.reduce(((n,r)=>r.plugin[t]?n.then((()=>r.plugin[t](e,r.options))):n),Promise.resolve())},4004:function(t,e){e.M=()=>""},8299:function(t,e,n){"use strict";n.d(e,{Z:function(){return r}});var r=function(t){return t=t||Object.create(null),{on:function(e,n){(t[e]||(t[e]=[])).push(n)},off:function(e,n){t[e]&&t[e].splice(t[e].indexOf(n)>>>0,1)},emit:function(e,n){(t[e]||[]).slice().map((function(t){t(n)})),(t["*"]||[]).slice().map((function(t){t(e,n)}))}}}()},7802:function(t,e,n){"use strict";n.d(e,{UD:function(){return d},Cj:function(){return m},GA:function(){return p},DS:function(){return f}});var r=n(7896),a=n(1505),o=t=>{if(void 0===t)return t;let[e,n=""]=t.split("?");return n&&(n="?"+n),"/"===e?"/"+n:"/"===e.charAt(e.length-1)?e.slice(0,-1)+n:e+n},i=n(6073);const s=new Map;let c=[];const l=t=>{let e=t;if(-1!==t.indexOf("?")){const[n,r]=t.split("?");e=n+"?"+encodeURIComponent(r)}const n=decodeURIComponent(e);return(0,a.Z)(n,decodeURIComponent("")).split("#")[0]};function u(t){return t.startsWith("/")||t.startsWith("https://")||t.startsWith("http://")?t:new URL(t,window.location.href+(window.location.href.endsWith("/")?"":"/")).pathname}const f=t=>{c=t},d=t=>{const e=h(t),n=c.map((t=>{let{path:e,matchPath:n}=t;return{path:n,originalPath:e}})),a=(0,r.pick)(n,e);return a?o(a.route.originalPath):null},p=t=>{const e=h(t),n=c.map((t=>{let{path:e,matchPath:n}=t;return{path:n,originalPath:e}})),a=(0,r.pick)(n,e);return a?a.params:{}},m=t=>{const e=l(u(t));if(s.has(e))return s.get(e);const n=(0,i.J)(t);if(n)return m(n.toPath);let r=d(e);return r||(r=h(t)),s.set(e,r),r},h=t=>{let e=l(u(t));return"/index.html"===e&&(e="/"),e=o(e),e}},4854:function(t,e,n){"use strict";n.r(e),n.d(e,{Link:function(){return s.rU},PageRenderer:function(){return o()},Script:function(){return E.Script},ScriptStrategy:function(){return E.ScriptStrategy},Slice:function(){return S},StaticQuery:function(){return c.i1},StaticQueryContext:function(){return c.B9},collectedScriptsByPage:function(){return E.collectedScriptsByPage},graphql:function(){return _},navigate:function(){return s.c4},parsePath:function(){return s.cP},prefetchPathname:function(){return O},scriptCache:function(){return E.scriptCache},scriptCallbackCache:function(){return E.scriptCallbackCache},useScrollRestoration:function(){return i.p2},useStaticQuery:function(){return c.K2},withAssetPrefix:function(){return s.mc},withPrefix:function(){return s.dq}});var r=n(1975),a=n(2743),o=n.n(a),i=n(9679),s=n(1562),c=n(1757),l=n(7326),u=n(4578);function f(t){return f=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(t){return t.__proto__||Object.getPrototypeOf(t)},f(t)}var d=n(9611);function p(t,e,n){return p=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(t){return!1}}()?Reflect.construct.bind():function(t,e,n){var r=[null];r.push.apply(r,e);var a=new(Function.bind.apply(t,r));return n&&(0,d.Z)(a,n.prototype),a},p.apply(null,arguments)}function m(t){var e="function"==typeof Map?new Map:void 0;return m=function(t){if(null===t||(n=t,-1===Function.toString.call(n).indexOf("[native code]")))return t;var n;if("function"!=typeof t)throw new TypeError("Super expression must either be null or a function");if(void 0!==e){if(e.has(t))return e.get(t);e.set(t,r)}function r(){return p(t,arguments,f(this).constructor)}return r.prototype=Object.create(t.prototype,{constructor:{value:r,enumerable:!1,writable:!0,configurable:!0}}),(0,d.Z)(r,t)},m(t)}var h=n(7294),g=n(4004),v=n(8995);const b=t=>{let{sliceId:e,children:n}=t;const r=[h.createElement("slice-start",{id:e+"-1"}),h.createElement("slice-end",{id:e+"-1"})];return n&&(r.push(n),r.push(h.createElement("slice-start",{id:e+"-2"}),h.createElement("slice-end",{id:e+"-2"}))),r};var y=n(6298);const w=t=>{let{sliceName:e,allowEmpty:n,children:r,...a}=t;const o=(0,h.useContext)(v.u0),i=(0,h.useContext)(v.Db),s=o[e];if(!s){if(n)return null;throw new Error('Slice "'+s+'" for "'+e+'" slot not found')}const c=((t,e)=>Object.keys(e).length?t+"-"+(0,g.M)(e):t)(s,a);let l=i[c];return l?r&&(l.hasChildren=!0):i[c]=l={props:a,sliceName:s,hasChildren:!!r},(0,y.tZ)(b,{sliceId:c},r)};var k=n(7462);const x=t=>{let{sliceName:e,allowEmpty:n,children:r,...a}=t;const o=(0,h.useContext)(v.u0),i=(0,h.useContext)(v.m3),s=o[e],c=i.get(s);if(!c){if(n)return null;throw new Error('Slice "'+s+'" for "'+e+'" slot not found')}return(0,y.tZ)(c.component,(0,k.Z)({sliceContext:c.sliceContext,data:c.data},a),r)};function S(t){{const e={...t,sliceName:t.alias};delete e.alias,delete e.__renderedByLocation;const n=(0,h.useContext)(v.Bs),r=P(t);if(Object.keys(r).length)throw new C("browser"===n.renderEnvironment,e.sliceName,r,t.__renderedByLocation);if("server"===n.renderEnvironment)return(0,y.tZ)(w,e);if("browser"===n.renderEnvironment)return(0,y.tZ)(x,e);if("engines"===n.renderEnvironment||"dev-ssr"===n.renderEnvironment)return(0,y.tZ)(x,e);if("slices"===n.renderEnvironment){let e="";try{e='\n\nSlice component "'+n.sliceRoot.name+'" ('+n.sliceRoot.componentPath+') tried to render '}catch{}throw new Error("Nested slices are not supported."+e+"\n\nSee https://gatsbyjs.com/docs/reference/built-in-components/gatsby-slice#nested-slices")}throw new Error('Slice context "'+n.renderEnvironment+'" is not supported.')}}let C=function(t){function e(n,r,a,o){var i;const s=Object.entries(a).map((t=>{let[e,n]=t;return'not serializable "'+n+'" type passed to "'+e+'" prop'})).join(", "),c="SlicePropsError";let u="",f="";if(n){const t=h.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactDebugCurrentFrame.getCurrentStack().trim().split("\n").slice(1);t[0]=t[0].trim(),u="\n"+t.join("\n"),f='Slice "'+r+'" was passed props that are not serializable ('+s+")."}else{f=c+': Slice "'+r+'" was passed props that are not serializable ('+s+").";u=f+"\n"+(new Error).stack.trim().split("\n").slice(2).join("\n")}return(i=t.call(this,f)||this).name=c,u?i.stack=u:Error.captureStackTrace((0,l.Z)(i),e),o&&(i.forcedLocation={...o,functionName:"Slice"}),i}return(0,u.Z)(e,t),e}(m(Error));const P=function(t,e,n,r){void 0===e&&(e={}),void 0===n&&(n=[]),void 0===r&&(r=null);for(const[a,o]of Object.entries(t)){if(null==o||!r&&"children"===a)continue;const t=r?r+"."+a:a;"function"==typeof o?e[t]=typeof o:"object"==typeof o&&n.indexOf(o)<=0&&(n.push(o),P(o,e,n,t))}return e};var E=n(3521);const O=r.ZP.enqueue;function _(){throw new Error("It appears like Gatsby is misconfigured. Gatsby related `graphql` calls are supposed to only be evaluated at compile time, and then compiled away. Unfortunately, something went wrong and the query was left in the compiled code.\n\nUnless your site has a complex or custom babel/Gatsby configuration this is likely a bug in Gatsby.")}},1975:function(t,e,n){"use strict";n.d(e,{uQ:function(){return f},kL:function(){return k},ZP:function(){return C},Nt:function(){return E},hs:function(){return P},jN:function(){return S},N1:function(){return x}});var r=n(4578),a=n(5785),o=n(904);const i=function(t){if("undefined"==typeof document)return!1;const e=document.createElement("link");try{if(e.relList&&"function"==typeof e.relList.supports)return e.relList.supports(t)}catch(n){return!1}return!1}("prefetch")?function(t,e){return new Promise(((n,r)=>{if("undefined"==typeof document)return void r();const a=document.createElement("link");a.setAttribute("rel","prefetch"),a.setAttribute("href",t),Object.keys(e).forEach((t=>{a.setAttribute(t,e[t])})),a.onload=n,a.onerror=r;(document.getElementsByTagName("head")[0]||document.getElementsByName("script")[0].parentNode).appendChild(a)}))}:function(t){return new Promise(((e,n)=>{const r=new XMLHttpRequest;r.open("GET",t,!0),r.onload=()=>{200===r.status?e():n()},r.send(null)}))},s={};var c=function(t,e){return new Promise((n=>{s[t]?n():i(t,e).then((()=>{n(),s[t]=!0})).catch((()=>{}))}))},l=n(8299),u=n(7802);const f={Error:"error",Success:"success"},d=t=>{const[e,n]=t.split("?");var r;return"/page-data/"+("/"===e?"index":(r="/"===(r=e)[0]?r.slice(1):r).endsWith("/")?r.slice(0,-1):r)+"/page-data.json"+(n?"?"+n:"")},p=t=>t.startsWith("//");function m(t,e){return void 0===e&&(e="GET"),new Promise((n=>{const r=new XMLHttpRequest;r.open(e,t,!0),r.onreadystatechange=()=>{4==r.readyState&&n(r)},r.send(null)}))}const h=/bot|crawler|spider|crawling/i,g=function(t,e,n){var r;void 0===e&&(e=null);const a={componentChunkName:t.componentChunkName,path:t.path,webpackCompilationHash:t.webpackCompilationHash,matchPath:t.matchPath,staticQueryHashes:t.staticQueryHashes,getServerDataError:t.getServerDataError,slicesMap:null!==(r=t.slicesMap)&&void 0!==r?r:{}};return{component:e,head:n,json:t.result,page:a}};function v(t){return new Promise((e=>{try{const n=t.readRoot();e(n)}catch(n){if(!Object.hasOwnProperty.call(n,"_response")||!Object.hasOwnProperty.call(n,"_status"))throw n;setTimeout((()=>{v(t).then(e)}),200)}}))}let b=function(){function t(t,e){this.inFlightNetworkRequests=new Map,this.pageDb=new Map,this.inFlightDb=new Map,this.staticQueryDb={},this.pageDataDb=new Map,this.partialHydrationDb=new Map,this.slicesDataDb=new Map,this.sliceInflightDb=new Map,this.slicesDb=new Map,this.isPrefetchQueueRunning=!1,this.prefetchQueued=[],this.prefetchTriggered=new Set,this.prefetchCompleted=new Set,this.loadComponent=t,(0,u.DS)(e)}var e=t.prototype;return e.memoizedGet=function(t){let e=this.inFlightNetworkRequests.get(t);return e||(e=m(t,"GET"),this.inFlightNetworkRequests.set(t,e)),e.then((e=>(this.inFlightNetworkRequests.delete(t),e))).catch((e=>{throw this.inFlightNetworkRequests.delete(t),e}))},e.setApiRunner=function(t){this.apiRunner=t,this.prefetchDisabled=t("disableCorePrefetching").some((t=>t))},e.fetchPageDataJson=function(t){const{pagePath:e,retries:n=0}=t,r=d(e);return this.memoizedGet(r).then((r=>{const{status:a,responseText:o}=r;if(200===a)try{const n=JSON.parse(o);if(void 0===n.path)throw new Error("not a valid pageData response");const r=e.split("?")[1];return r&&!n.path.includes(r)&&(n.path+="?"+r),Object.assign(t,{status:f.Success,payload:n})}catch(i){}return 404===a||200===a?"/404.html"===e||"/500.html"===e?Object.assign(t,{status:f.Error}):this.fetchPageDataJson(Object.assign(t,{pagePath:"/404.html",notFound:!0})):500===a?this.fetchPageDataJson(Object.assign(t,{pagePath:"/500.html",internalServerError:!0})):n<3?this.fetchPageDataJson(Object.assign(t,{retries:n+1})):Object.assign(t,{status:f.Error})}))},e.fetchPartialHydrationJson=function(t){const{pagePath:e,retries:n=0}=t,r=d(e).replace(".json","-rsc.json");return this.memoizedGet(r).then((r=>{const{status:a,responseText:o}=r;if(200===a)try{return Object.assign(t,{status:f.Success,payload:o})}catch(i){}return 404===a||200===a?"/404.html"===e||"/500.html"===e?Object.assign(t,{status:f.Error}):this.fetchPartialHydrationJson(Object.assign(t,{pagePath:"/404.html",notFound:!0})):500===a?this.fetchPartialHydrationJson(Object.assign(t,{pagePath:"/500.html",internalServerError:!0})):n<3?this.fetchPartialHydrationJson(Object.assign(t,{retries:n+1})):Object.assign(t,{status:f.Error})}))},e.loadPageDataJson=function(t){const e=(0,u.Cj)(t);if(this.pageDataDb.has(e)){const t=this.pageDataDb.get(e);return Promise.resolve(t)}return this.fetchPageDataJson({pagePath:e}).then((t=>(this.pageDataDb.set(e,t),t)))},e.loadPartialHydrationJson=function(t){const e=(0,u.Cj)(t);if(this.partialHydrationDb.has(e)){const t=this.partialHydrationDb.get(e);return Promise.resolve(t)}return this.fetchPartialHydrationJson({pagePath:e}).then((t=>(this.partialHydrationDb.set(e,t),t)))},e.loadSliceDataJson=function(t){if(this.slicesDataDb.has(t)){const e=this.slicesDataDb.get(t);return Promise.resolve({sliceName:t,jsonPayload:e})}return m("/slice-data/"+t+".json","GET").then((e=>{const n=JSON.parse(e.responseText);return this.slicesDataDb.set(t,n),{sliceName:t,jsonPayload:n}}))},e.findMatchPath=function(t){return(0,u.UD)(t)},e.loadPage=function(t){const e=(0,u.Cj)(t);if(this.pageDb.has(e)){const t=this.pageDb.get(e);return t.error?Promise.resolve({error:t.error,status:t.status}):Promise.resolve(t.payload)}if(this.inFlightDb.has(e))return this.inFlightDb.get(e);const n=[this.loadAppData(),this.loadPageDataJson(e)];const r=Promise.all(n).then((t=>{const[n,r,i]=t;if(r.status===f.Error||(null==i?void 0:i.status)===f.Error)return{status:f.Error};let s=r.payload;const{componentChunkName:c,staticQueryHashes:u=[],slicesMap:d={}}=s,p={},m=Array.from(new Set(Object.values(d))),h=t=>{if(this.slicesDb.has(t.name))return this.slicesDb.get(t.name);if(this.sliceInflightDb.has(t.name))return this.sliceInflightDb.get(t.name);const e=this.loadComponent(t.componentChunkName).then((e=>{return{component:(n=e,n&&n.default||n),sliceContext:t.result.sliceContext,data:t.result.data};var n}));return this.sliceInflightDb.set(t.name,e),e.then((e=>{this.slicesDb.set(t.name,e),this.sliceInflightDb.delete(t.name)})),e};return Promise.all(m.map((t=>this.loadSliceDataJson(t)))).then((t=>{const d=[],m=(0,a.Z)(u);for(const{jsonPayload:e,sliceName:n}of Object.values(t)){d.push({name:n,...e});for(const t of e.staticQueryHashes)m.includes(t)||m.push(t)}const b=[Promise.all(d.map(h)),this.loadComponent(c,"head")];b.push(this.loadComponent(c));const y=Promise.all(b).then((t=>{const[e,a,c]=t;p.createdAt=new Date;for(const n of e)(!n||n instanceof Error)&&(p.status=f.Error,p.error=n);let l;if((!c||c instanceof Error)&&(p.status=f.Error,p.error=c),p.status!==f.Error){if(p.status=f.Success,!0!==r.notFound&&!0!==(null==i?void 0:i.notFound)||(p.notFound=!0),s=Object.assign(s,{webpackCompilationHash:n?n.webpackCompilationHash:""}),"string"==typeof(null==i?void 0:i.payload)){l=g(s,null,a),l.partialHydration=i.payload;const t=new ReadableStream({start(t){const e=new TextEncoder;t.enqueue(e.encode(i.payload))},pull(t){t.close()},cancel(){}});return v((0,o.createFromReadableStream)(t)).then((t=>(l.partialHydration=t,l)))}l=g(s,c,a)}return l})),w=Promise.all(m.map((t=>{if(this.staticQueryDb[t]){const e=this.staticQueryDb[t];return{staticQueryHash:t,jsonPayload:e}}return this.memoizedGet("/page-data/sq/d/"+t+".json").then((e=>{const n=JSON.parse(e.responseText);return{staticQueryHash:t,jsonPayload:n}})).catch((()=>{throw new Error("We couldn't load \"/page-data/sq/d/"+t+'.json"')}))}))).then((t=>{const e={};return t.forEach((t=>{let{staticQueryHash:n,jsonPayload:r}=t;e[n]=r,this.staticQueryDb[n]=r})),e}));return Promise.all([y,w]).then((t=>{let n,[r,a]=t;return r&&(n={...r,staticQueryResults:a},p.payload=n,l.Z.emit("onPostLoadPageResources",{page:n,pageResources:n})),this.pageDb.set(e,p),p.error?{error:p.error,status:p.status}:n})).catch((t=>({error:t,status:f.Error})))}))}));return r.then((()=>{this.inFlightDb.delete(e)})).catch((t=>{throw this.inFlightDb.delete(e),t})),this.inFlightDb.set(e,r),r},e.loadPageSync=function(t,e){void 0===e&&(e={});const n=(0,u.Cj)(t);if(this.pageDb.has(n)){var r;const t=this.pageDb.get(n);if(t.payload)return t.payload;if(null!==(r=e)&&void 0!==r&&r.withErrorDetails)return{error:t.error,status:t.status}}},e.shouldPrefetch=function(t){return!!(()=>{if("connection"in navigator&&void 0!==navigator.connection){if((navigator.connection.effectiveType||"").includes("2g"))return!1;if(navigator.connection.saveData)return!1}return!0})()&&((!navigator.userAgent||!h.test(navigator.userAgent))&&!this.pageDb.has(t))},e.prefetch=function(t){if(!this.shouldPrefetch(t))return{then:t=>t(!1),abort:()=>{}};if(this.prefetchTriggered.has(t))return{then:t=>t(!0),abort:()=>{}};const e={resolve:null,reject:null,promise:null};e.promise=new Promise(((t,n)=>{e.resolve=t,e.reject=n})),this.prefetchQueued.push([t,e]);const n=new AbortController;return n.signal.addEventListener("abort",(()=>{const e=this.prefetchQueued.findIndex((e=>{let[n]=e;return n===t}));-1!==e&&this.prefetchQueued.splice(e,1)})),this.isPrefetchQueueRunning||(this.isPrefetchQueueRunning=!0,setTimeout((()=>{this._processNextPrefetchBatch()}),3e3)),{then:(t,n)=>e.promise.then(t,n),abort:n.abort.bind(n)}},e._processNextPrefetchBatch=function(){(window.requestIdleCallback||(t=>setTimeout(t,0)))((()=>{const t=this.prefetchQueued.splice(0,4),e=Promise.all(t.map((t=>{let[e,n]=t;return this.prefetchTriggered.has(e)||(this.apiRunner("onPrefetchPathname",{pathname:e}),this.prefetchTriggered.add(e)),this.prefetchDisabled?n.resolve(!1):this.doPrefetch((0,u.Cj)(e)).then((()=>{this.prefetchCompleted.has(e)||(this.apiRunner("onPostPrefetchPathname",{pathname:e}),this.prefetchCompleted.add(e)),n.resolve(!0)}))})));this.prefetchQueued.length?e.then((()=>{setTimeout((()=>{this._processNextPrefetchBatch()}),3e3)})):this.isPrefetchQueueRunning=!1}))},e.doPrefetch=function(t){const e=d(t);return c(e,{crossOrigin:"anonymous",as:"fetch"}).then((()=>this.loadPageDataJson(t)))},e.hovering=function(t){this.loadPage(t)},e.getResourceURLsForPathname=function(t){const e=(0,u.Cj)(t),n=this.pageDataDb.get(e);if(n){const t=g(n.payload);return[].concat((0,a.Z)(y(t.page.componentChunkName)),[d(e)])}return null},e.isPageNotFound=function(t){const e=(0,u.Cj)(t),n=this.pageDb.get(e);return!n||n.notFound},e.loadAppData=function(t){return void 0===t&&(t=0),this.memoizedGet("/page-data/app-data.json").then((e=>{const{status:n,responseText:r}=e;let a;if(200!==n&&t<3)return this.loadAppData(t+1);if(200===n)try{const t=JSON.parse(r);if(void 0===t.webpackCompilationHash)throw new Error("not a valid app-data response");a=t}catch(o){}return a}))},t}();const y=t=>(window.___chunkMapping[t]||[]).map((t=>""+t));let w,k=function(t){function e(e,n,r){var a;return a=t.call(this,(function(t,n){if(void 0===n&&(n="components"),!e[n="components"][t])throw new Error("We couldn't find the correct component chunk with the name \""+t+'"');return e[n][t]().catch((t=>t))}),n)||this,r&&a.pageDataDb.set((0,u.Cj)(r.path),{pagePath:r.path,payload:r,status:"success"}),a}(0,r.Z)(e,t);var n=e.prototype;return n.doPrefetch=function(e){return t.prototype.doPrefetch.call(this,e).then((t=>{if(t.status!==f.Success)return Promise.resolve();const e=t.payload,n=e.componentChunkName,r=y(n);return Promise.all(r.map(c)).then((()=>e))}))},n.loadPageDataJson=function(e){return t.prototype.loadPageDataJson.call(this,e).then((t=>t.notFound?p(e)?t:m(e,"HEAD").then((e=>200===e.status?{status:f.Error}:t)):t))},n.loadPartialHydrationJson=function(e){return t.prototype.loadPartialHydrationJson.call(this,e).then((t=>t.notFound?p(e)?t:m(e,"HEAD").then((e=>200===e.status?{status:f.Error}:t)):t))},e}(b);const x=t=>{w=t},S={enqueue:t=>w.prefetch(t),getResourceURLsForPathname:t=>w.getResourceURLsForPathname(t),loadPage:t=>w.loadPage(t),loadPageSync:function(t,e){return void 0===e&&(e={}),w.loadPageSync(t,e)},prefetch:t=>w.prefetch(t),isPageNotFound:t=>w.isPageNotFound(t),hovering:t=>w.hovering(t),loadAppData:()=>w.loadAppData()};var C=S;function P(){return w?w.staticQueryDb:{}}function E(){return w?w.slicesDb:{}}},4779:function(t,e,n){"use strict";n.d(e,{Z:function(){return P}});var r=n(7294),a=n(5697),o=n.n(a),i=n(3092),s=n(7802),c=n(5785),l=n(4854),u=n(7896),f=n(4941);function d(t){let{children:e,callback:n}=t;return(0,r.useEffect)((()=>{n()})),e}const p=["link","meta","style","title","base","noscript","script","html","body"];function m(t,e){if(t instanceof HTMLElement&&e instanceof HTMLElement){const n=e.getAttribute("nonce");if(n&&!t.getAttribute("nonce")){const r=e.cloneNode(!0);return r.setAttribute("nonce",""),r.nonce=n,n===t.nonce&&t.isEqualNode(r)}}return t.isEqualNode(e)}function h(t,e){void 0===e&&(e={html:{},body:{}});const n=new Map,r=[];for(const s of t.childNodes){var a,o;const t=s.nodeName.toLowerCase(),l=null===(a=s.attributes)||void 0===a||null===(o=a.id)||void 0===o?void 0:o.value;if(b(s)){if(v(t))if("html"===t||"body"===t)for(const n of s.attributes)e[t]={...e[t],[n.name]:n.value};else{let t=s.cloneNode(!0);if(t.setAttribute("data-gatsby-head",!0),"script"===t.nodeName.toLowerCase()&&(t=g(t)),l)if(n.has(l)){var i;const e=n.get(l);null===(i=r[e].parentNode)||void 0===i||i.removeChild(r[e]),r[e]=t}else r.push(t),n.set(l,r.length-1);else r.push(t)}s.childNodes.length&&r.push.apply(r,(0,c.Z)(h(s,e).validHeadNodes))}}return{validHeadNodes:r,htmlAndBodyAttributes:e}}function g(t){const e=document.createElement("script");for(const n of t.attributes)e.setAttribute(n.name,n.value);return e.innerHTML=t.innerHTML,e}function v(t){return p.includes(t)}function b(t){return 1===t.nodeType}var y=n(6298);const w=document.createElement("div"),k={html:[],body:[]},x=()=>{var t;const{validHeadNodes:e,htmlAndBodyAttributes:n}=h(w);k.html=Object.keys(n.html),k.body=Object.keys(n.body),function(t){if(!t)return;const{html:e,body:n}=t,r=document.querySelector("html");r&&Object.entries(e).forEach((t=>{let[e,n]=t;r.setAttribute(e,n)}));const a=document.querySelector("body");a&&Object.entries(n).forEach((t=>{let[e,n]=t;a.setAttribute(e,n)}))}(n);const r=document.querySelectorAll("[data-gatsby-head]");var a;if(0===r.length)return void(a=document.head).append.apply(a,(0,c.Z)(e));const o=[];!function(t){let{oldNodes:e,newNodes:n,onStale:r,onNew:a}=t;for(const o of e){const t=n.findIndex((t=>m(t,o)));-1===t?r(o):n.splice(t,1)}for(const o of n)a(o)}({oldNodes:r,newNodes:e,onStale:t=>t.parentNode.removeChild(t),onNew:t=>o.push(t)}),(t=document.head).append.apply(t,o)};function S(t){let{pageComponent:e,staticQueryResults:n,pageComponentProps:a}=t;(0,r.useEffect)((()=>{if(null!=e&&e.Head){!function(t){if("function"!=typeof t)throw new Error('Expected "Head" export to be a function got "'+typeof t+'".')}(e.Head);const{render:r}=(0,f.U)(),o=(0,y.tZ)(e.Head,{location:{pathname:(t=a).location.pathname},params:t.params,data:t.data||{},serverData:t.serverData,pageContext:t.pageContext}),s=(0,i.h)("wrapRootElement",{element:o},o,(t=>{let{result:e}=t;return{element:e}})).pop();r((0,y.tZ)(d,{callback:x},(0,y.tZ)(l.StaticQueryContext.Provider,{value:n},(0,y.tZ)(u.LocationProvider,null,s))),w)}var t;return()=>{!function(){const t=document.querySelectorAll("[data-gatsby-head]");for(const e of t)e.parentNode.removeChild(e)}(),function(t){if(!t)return;const{html:e,body:n}=t;if(e){const t=document.querySelector("html");e.forEach((e=>{t&&t.removeAttribute(e)}))}if(n){const t=document.querySelector("body");n.forEach((e=>{t&&t.removeAttribute(e)}))}}(k)}}))}function C(t){const e={...t,params:{...(0,s.GA)(t.location.pathname),...t.pageResources.json.pageContext.__params}};let n;var a;n=t.pageResources.partialHydration?t.pageResources.partialHydration:(0,r.createElement)((a=t.pageResources.component)&&a.default||a,{...e,key:t.path||t.pageResources.page.path});S({pageComponent:t.pageResources.head,staticQueryResults:t.pageResources.staticQueryResults,pageComponentProps:e});return(0,i.h)("wrapPageElement",{element:n,props:e},n,(t=>{let{result:n}=t;return{element:n,props:e}})).pop()}C.propTypes={location:o().object.isRequired,pageResources:o().object.isRequired,data:o().object,pageContext:o().object.isRequired};var P=C},5824:function(t,e,n){"use strict";var r=n(7462),a=n(4578),o=n(3092),i=n(7294),s=n(7896),c=n(9679),l=n(1757),u=n(8995),f=n(1975),d=n(6073),p=n(8299);const m={id:"gatsby-announcer",style:{position:"absolute",top:0,width:1,height:1,padding:0,overflow:"hidden",clip:"rect(0, 0, 0, 0)",whiteSpace:"nowrap",border:0},"aria-live":"assertive","aria-atomic":"true"};var h=n(1562),g=n(6298);function v(t){const e=(0,d.J)(t),{hash:n,search:r}=window.location;return null!=e&&(window.___replace(e.toPath+r+n),!0)}let b="";window.addEventListener("unhandledrejection",(t=>{/loading chunk \d* failed./i.test(t.reason)&&b&&(window.location.pathname=b)}));const y=(t,e)=>{v(t.pathname)||(b=t.pathname,(0,o.h)("onPreRouteUpdate",{location:t,prevLocation:e}))},w=(t,e)=>{v(t.pathname)||(0,o.h)("onRouteUpdate",{location:t,prevLocation:e})},k=function(t,e){if(void 0===e&&(e={}),"number"==typeof t)return void s.globalHistory.navigate(t);const{pathname:n,search:r,hash:a}=(0,h.cP)(t),i=(0,d.J)(n);if(i&&(t=i.toPath+r+a),window.___swUpdated)return void(window.location=n+r+a);const c=setTimeout((()=>{p.Z.emit("onDelayedLoadPageResources",{pathname:n}),(0,o.h)("onRouteUpdateDelayed",{location:window.location})}),1e3);f.ZP.loadPage(n+r).then((o=>{if(!o||o.status===f.uQ.Error)return window.history.replaceState({},"",location.href),window.location=n,void clearTimeout(c);o&&o.page.webpackCompilationHash!==window.___webpackCompilationHash&&("serviceWorker"in navigator&&null!==navigator.serviceWorker.controller&&"activated"===navigator.serviceWorker.controller.state&&navigator.serviceWorker.controller.postMessage({gatsbyApi:"clearPathResources"}),window.location=n+r+a),(0,s.navigate)(t,e),clearTimeout(c)}))};function x(t,e){let{location:n}=e;const{pathname:r,hash:a}=n,i=(0,o.h)("shouldUpdateScroll",{prevRouterProps:t,pathname:r,routerProps:{location:n},getSavedScrollPosition:t=>[0,this._stateStorage.read(t,t.key)]});if(i.length>0)return i[i.length-1];if(t){const{location:{pathname:e}}=t;if(e===r)return a?decodeURI(a.slice(1)):[0,0]}return!0}let S=function(t){function e(e){var n;return(n=t.call(this,e)||this).announcementRef=i.createRef(),n}(0,a.Z)(e,t);var n=e.prototype;return n.componentDidUpdate=function(t,e){requestAnimationFrame((()=>{let t="new page at "+this.props.location.pathname;document.title&&(t=document.title);const e=document.querySelectorAll("#gatsby-focus-wrapper h1");e&&e.length&&(t=e[0].textContent);const n="Navigated to "+t;if(this.announcementRef.current){this.announcementRef.current.innerText!==n&&(this.announcementRef.current.innerText=n)}}))},n.render=function(){return(0,g.tZ)("div",(0,r.Z)({},m,{ref:this.announcementRef}))},e}(i.Component);const C=(t,e)=>{var n,r;return t.href!==e.href||(null==t||null===(n=t.state)||void 0===n?void 0:n.key)!==(null==e||null===(r=e.state)||void 0===r?void 0:r.key)};let P=function(t){function e(e){var n;return n=t.call(this,e)||this,y(e.location,null),n}(0,a.Z)(e,t);var n=e.prototype;return n.componentDidMount=function(){w(this.props.location,null)},n.shouldComponentUpdate=function(t){return!!C(this.props.location,t.location)&&(y(t.location,this.props.location),!0)},n.componentDidUpdate=function(t){C(t.location,this.props.location)&&w(this.props.location,t.location)},n.render=function(){return(0,g.tZ)(i.Fragment,null,this.props.children,(0,g.tZ)(S,{location:location}))},e}(i.Component);var E=n(4779),O=n(5418);function _(t,e){for(var n in t)if(!(n in e))return!0;for(var r in e)if(t[r]!==e[r])return!0;return!1}var R=function(t){function e(e){var n;n=t.call(this)||this;const{location:r,pageResources:a}=e;return n.state={location:{...r},pageResources:a||f.ZP.loadPageSync(r.pathname+r.search,{withErrorDetails:!0})},n}(0,a.Z)(e,t),e.getDerivedStateFromProps=function(t,e){let{location:n}=t;if(e.location.href!==n.href){return{pageResources:f.ZP.loadPageSync(n.pathname+n.search,{withErrorDetails:!0}),location:{...n}}}return{location:{...n}}};var n=e.prototype;return n.loadResources=function(t){f.ZP.loadPage(t).then((e=>{e&&e.status!==f.uQ.Error?this.setState({location:{...window.location},pageResources:e}):(window.history.replaceState({},"",location.href),window.location=t)}))},n.shouldComponentUpdate=function(t,e){return e.pageResources?this.state.pageResources!==e.pageResources||(this.state.pageResources.component!==e.pageResources.component||(this.state.pageResources.json!==e.pageResources.json||(!(this.state.location.key===e.location.key||!e.pageResources.page||!e.pageResources.page.matchPath&&!e.pageResources.page.path)||function(t,e,n){return _(t.props,e)||_(t.state,n)}(this,t,e)))):(this.loadResources(t.location.pathname+t.location.search),!1)},n.render=function(){return this.props.children(this.state)},e}(i.Component),j=n(1505),A=n(4941);const N=new f.kL(O,[],window.pageData);(0,f.N1)(N),N.setApiRunner(o.h);const{render:T,hydrate:D}=(0,A.U)();window.asyncRequires=O,window.___emitter=p.Z,window.___loader=f.jN,s.globalHistory.listen((t=>{t.location.action=t.action})),window.___push=t=>k(t,{replace:!1}),window.___replace=t=>k(t,{replace:!0}),window.___navigate=(t,e)=>k(t,e);const M="gatsby-reload-compilation-hash-match";(0,o.I)("onClientEntry").then((()=>{(0,o.h)("registerServiceWorker").filter(Boolean).length>0&&n(9939);const t=t=>(0,g.tZ)(s.BaseContext.Provider,{value:{baseuri:"/",basepath:"/"}},(0,g.tZ)(E.Z,t)),e=i.createContext({}),d={renderEnvironment:"browser"};let p=function(t){function n(){return t.apply(this,arguments)||this}return(0,a.Z)(n,t),n.prototype.render=function(){const{children:t}=this.props;return(0,g.tZ)(s.Location,null,(n=>{let{location:r}=n;return(0,g.tZ)(R,{location:r},(n=>{let{pageResources:r,location:a}=n;const o=(0,f.hs)(),i=(0,f.Nt)();return(0,g.tZ)(l.B9.Provider,{value:o},(0,g.tZ)(u.Bs.Provider,{value:d},(0,g.tZ)(u.m3.Provider,{value:i},(0,g.tZ)(u.u0.Provider,{value:r.page.slicesMap},(0,g.tZ)(e.Provider,{value:{pageResources:r,location:a}},t)))))}))}))},n}(i.Component),m=function(n){function o(){return n.apply(this,arguments)||this}return(0,a.Z)(o,n),o.prototype.render=function(){return(0,g.tZ)(e.Consumer,null,(e=>{let{pageResources:n,location:a}=e;return(0,g.tZ)(P,{location:a},(0,g.tZ)(c.$C,{location:a,shouldUpdateScroll:x},(0,g.tZ)(s.Router,{basepath:"",location:a,id:"gatsby-focus-wrapper"},(0,g.tZ)(t,(0,r.Z)({path:"/404.html"===n.page.path||"/500.html"===n.page.path?(0,j.Z)(a.pathname,""):encodeURI((n.page.matchPath||n.page.path).split("?")[0])},this.props,{location:a,pageResources:n},n.json)))))}))},o}(i.Component);const{pagePath:h,location:v}=window;h&&""+h!==v.pathname+(h.includes("?")?v.search:"")&&!(N.findMatchPath((0,j.Z)(v.pathname,""))||h.match(/^\/(404|500)(\/?|.html)$/)||h.match(/^\/offline-plugin-app-shell-fallback\/?$/))&&(0,s.navigate)(""+h+(h.includes("?")?"":v.search)+v.hash,{replace:!0});const b=()=>{try{return sessionStorage}catch{return null}};f.jN.loadPage(v.pathname+v.search).then((t=>{var e;const n=b();if(null!=t&&null!==(e=t.page)&&void 0!==e&&e.webpackCompilationHash&&t.page.webpackCompilationHash!==window.___webpackCompilationHash&&("serviceWorker"in navigator&&null!==navigator.serviceWorker.controller&&"activated"===navigator.serviceWorker.controller.state&&navigator.serviceWorker.controller.postMessage({gatsbyApi:"clearPathResources"}),n)){if(!("1"===n.getItem(M)))return n.setItem(M,"1"),void window.location.reload(!0)}if(n&&n.removeItem(M),!t||t.status===f.uQ.Error){const e="page resources for "+v.pathname+" not found. Not rendering React";if(t&&t.error)throw console.error(e),t.error;throw new Error(e)}const r=(0,o.h)("wrapRootElement",{element:(0,g.tZ)(m,null)},(0,g.tZ)(m,null),(t=>{let{result:e}=t;return{element:e}})).pop(),a=function(){const t=i.useRef(!1);return i.useEffect((()=>{t.current||(t.current=!0,performance.mark&&performance.mark("onInitialClientRender"),(0,o.h)("onInitialClientRender"))}),[]),(0,g.tZ)(p,null,r)},s=document.getElementById("gatsby-focus-wrapper");let c=T;s&&s.children.length&&(c=D);const l=(0,o.h)("replaceHydrateFunction",void 0,c)[0];function u(){const t="undefined"!=typeof window?document.getElementById("___gatsby"):null;l((0,g.tZ)(a,null),t)}const d=document;if("complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll)setTimeout((function(){u()}),0);else{const t=function(){d.removeEventListener("DOMContentLoaded",t,!1),window.removeEventListener("load",t,!1),u()};d.addEventListener("DOMContentLoaded",t,!1),window.addEventListener("load",t,!1)}}))}))},224:function(t,e,n){"use strict";n.r(e);var r=n(7294),a=n(1975),o=n(4779);e.default=t=>{let{location:e}=t;const n=a.ZP.loadPageSync(e.pathname);return n?r.createElement(o.Z,{location:e,pageResources:n,...n.json}):null}},2743:function(t,e,n){var r;t.exports=(r=n(224))&&r.default||r},4941:function(t,e,n){"use strict";n.d(e,{U:function(){return a}});const r=new WeakMap;function a(){const t=n(745);return{render:(e,n)=>{let a=r.get(n);a||r.set(n,a=t.createRoot(n)),a.render(e)},hydrate:(e,n)=>t.hydrateRoot(n,e)}}},6073:function(t,e,n){"use strict";n.d(e,{J:function(){return o}});const r=new Map,a=new Map;function o(t){let e=r.get(t);return e||(e=a.get(t.toLowerCase())),e}[].forEach((t=>{t.ignoreCase?a.set(t.fromPath,t):r.set(t.fromPath,t)}))},9939:function(t,e,n){"use strict";n.r(e);var r=n(3092);"https:"!==window.location.protocol&&"localhost"!==window.location.hostname?console.error("Service workers can only be used over HTTPS, or on localhost for development"):"serviceWorker"in navigator&&navigator.serviceWorker.register("/sw.js").then((function(t){t.addEventListener("updatefound",(()=>{(0,r.h)("onServiceWorkerUpdateFound",{serviceWorker:t});const e=t.installing;console.log("installingWorker",e),e.addEventListener("statechange",(()=>{switch(e.state){case"installed":navigator.serviceWorker.controller?(window.___swUpdated=!0,(0,r.h)("onServiceWorkerUpdateReady",{serviceWorker:t}),window.___failedResources&&(console.log("resources failed, SW updated - reloading"),window.location.reload())):(console.log("Content is now available offline!"),(0,r.h)("onServiceWorkerInstalled",{serviceWorker:t}));break;case"redundant":console.error("The installing service worker became redundant."),(0,r.h)("onServiceWorkerRedundant",{serviceWorker:t});break;case"activated":(0,r.h)("onServiceWorkerActive",{serviceWorker:t})}}))}))})).catch((function(t){console.error("Error during service worker registration:",t)}))},8995:function(t,e,n){"use strict";n.d(e,{Bs:function(){return o},Db:function(){return s},m3:function(){return a},u0:function(){return i}});var r=n(7294);const a=r.createContext({}),o=r.createContext({}),i=r.createContext({}),s=r.createContext({})},1757:function(t,e,n){"use strict";n.d(e,{i1:function(){return l},B9:function(){return o},K2:function(){return u}});var r=n(7294);var a=n(6298);const o=(i="StaticQuery",s={},r.createServerContext?function(t,e){return void 0===e&&(e=null),globalThis.__SERVER_CONTEXT||(globalThis.__SERVER_CONTEXT={}),globalThis.__SERVER_CONTEXT[t]||(globalThis.__SERVER_CONTEXT[t]=r.createServerContext(t,e)),globalThis.__SERVER_CONTEXT[t]}(i,s):r.createContext(s));var i,s;function c(t){let{staticQueryData:e,data:n,query:o,render:i}=t;const s=n?n.data:e[o]&&e[o].data;return(0,a.tZ)(r.Fragment,null,s&&i(s),!s&&(0,a.tZ)("div",null,"Loading (StaticQuery)"))}const l=t=>{const{data:e,query:n,render:r,children:i}=t;return(0,a.tZ)(o.Consumer,null,(t=>(0,a.tZ)(c,{data:e,query:n,render:r||i,staticQueryData:t})))},u=t=>{var e;r.useContext;const n=r.useContext(o);if(isNaN(Number(t)))throw new Error("useStaticQuery was called with a string but expects to be called using `graphql`. Try this:\n\nimport { useStaticQuery, graphql } from 'gatsby';\n\nuseStaticQuery(graphql`"+t+"`);\n");if(null!==(e=n[t])&&void 0!==e&&e.data)return n[t].data;throw new Error("The result of this StaticQuery could not be fetched.\n\nThis is likely a bug in Gatsby and if refreshing the page does not fix it, please open an issue in https://github.com/gatsbyjs/gatsby/issues")}},1505:function(t,e,n){"use strict";function r(t,e){return void 0===e&&(e=""),e?t===e?"/":t.startsWith(e+"/")?t.slice(e.length):t:t}n.d(e,{Z:function(){return r}})},436:function(t,e,n){"use strict";n.r(e),n.d(e,{onClientEntry:function(){return c}});var r=n(4854),a=n(481),o=n.n(a);const i=t=>"/"===t[0]?t:"/"+t,s=(t,e)=>n=>{if(window.___failedResources)return!0;if((t=>0!==t.button||t.altKey||t.ctrlKey||t.metaKey||t.shiftKey)(n))return!0;if((t=>t.defaultPrevented)(n))return!0;const a=(t=>{for(;t.parentNode;t=t.parentNode)if("a"===t.nodeName.toLowerCase())return t;return null})(n.target);if(null==a)return!0;if(!0===(s=a).hasAttribute("download")||!1===(t=>!1===t.hasAttribute("target")||null==t.target||["_self",""].includes(t.target)||"_parent"===t.target&&(!t.ownerDocument.defaultView.parent||t.ownerDocument.defaultView.parent===t.ownerDocument.defaultView)||"_top"===t.target&&(!t.ownerDocument.defaultView.top||t.ownerDocument.defaultView.top===t.ownerDocument.defaultView))(s))return!0;var s;const c=document.createElement("a");""!==a.href&&(c.href=a.href),"SVGAnimatedString"in window&&a.href instanceof SVGAnimatedString&&(c.href=a.href.animVal);const l=document.createElement("a");if(l.href=window.location.href,!1===((t,e)=>t.protocol===e.protocol&&t.host===e.host)(l,c))return!0;const u=new RegExp("^"+o()((0,r.withPrefix)("/")));if(((t,e)=>!1===e.test(i(t.pathname))||-1!==t.pathname.search(/^.*\.((?!htm)[a-z0-9]{1,5})$/i))(c,u))return!0;if(((t,e)=>""!==e.hash&&(""===e.pathname||e.pathname===t.pathname))(l,c))return!0;if(e.excludePattern){if(new RegExp(e.excludePattern).test(c.pathname))return!0}n.preventDefault();const f=i(c.pathname).replace(u,"/");return t(""+f+c.search+c.hash),!1};const c=function(t,e){void 0===e&&(e={}),function(t,e,n){const r=s(n,e);t.addEventListener("click",r)}(window,e,(t=>{(0,r.navigate)(t)}))}},481:function(t){"use strict";var e=/[|\\{}()[\]^$+*?.]/g;t.exports=function(t){if("string"!=typeof t)throw new TypeError("Expected a string");return t.replace(e,"\\$&")}},5688:function(t,e,n){"use strict";e.wrapPageElement=n(4184)},4184:function(t,e,n){"use strict";var r,a,o=n(7294);try{a=n(7102),r=a&&a.default||a}catch(i){throw-1!==i.toString().indexOf("Error: Cannot find module")?new Error("Couldn't find layout component at \"/home/runner/work/icatproject.github.io/icatproject.github.io/src/components/layout.jsx.\n\nPlease create layout component in that location or specify path to layout component in gatsby-config.js"):(console.error(i),i)}t.exports=function(t){var e=t.element,n=t.props;return o.createElement(r,n,e)}},9608:function(t,e,n){"use strict";n.r(e),n.d(e,{onRouteUpdate:function(){return r}});n(4854),n(292);const r=function(t,e){let{location:n}=t}},292:function(t,e,n){"use strict";var r=n(4854)},855:function(t,e){"use strict";e.DEFAULT_OPTIONS={maxWidth:650,wrapperStyle:"",backgroundColor:"white",linkImagesToOriginal:!0,showCaptions:!1,markdownCaptions:!1,withWebp:!1,withAvif:!1,tracedSVG:!1,loading:"lazy",decoding:"async",disableBgImageOnAlpha:!1,disableBgImage:!1},e.EMPTY_ALT="GATSBY_EMPTY_ALT",e.imageClass="gatsby-resp-image-image",e.imageWrapperClass="gatsby-resp-image-wrapper",e.imageBackgroundClass="gatsby-resp-image-background-image"},2154:function(t,e,n){"use strict";var r=n(855),a=r.DEFAULT_OPTIONS,o=r.imageClass,i=r.imageBackgroundClass,s=r.imageWrapperClass;e.onRouteUpdate=function(t,e){for(var n=Object.assign({},a,e),r=document.querySelectorAll("."+s),c=function(){var t=r[l],e=t.querySelector("."+i),a=t.querySelector("."+o),s=function(){e.style.transition="opacity 0.5s 0.5s",a.style.transition="opacity 0.5s",c()},c=function t(){e.style.opacity=0,a.style.opacity=1,a.style.color="inherit",a.style.boxShadow="inset 0px 0px 0px 400px "+n.backgroundColor,a.removeEventListener("load",s),a.removeEventListener("error",t)};a.style.opacity=0,a.addEventListener("load",s),a.addEventListener("error",c),a.complete&&c()},l=0;lt.length)&&(e=t.length);for(var n=0,r=new Array(e);n0;)e+=gt[62*Math.random()|0];return e}function bt(t){for(var e=[],n=(t||[]).length>>>0;n--;)e[n]=t[n];return e}function yt(t){return t.classList?bt(t.classList):(t.getAttribute("class")||"").split(" ").filter((function(t){return t}))}function wt(t){return"".concat(t).replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(//g,">")}function kt(t){return Object.keys(t||{}).reduce((function(e,n){return e+"".concat(n,": ").concat(t[n].trim(),";")}),"")}function xt(t){return t.size!==ht.size||t.x!==ht.x||t.y!==ht.y||t.rotate!==ht.rotate||t.flipX||t.flipY}var St=':root, :host {\n --fa-font-solid: normal 900 1em/1 "Font Awesome 6 Solid";\n --fa-font-regular: normal 400 1em/1 "Font Awesome 6 Regular";\n --fa-font-light: normal 300 1em/1 "Font Awesome 6 Light";\n --fa-font-thin: normal 100 1em/1 "Font Awesome 6 Thin";\n --fa-font-duotone: normal 900 1em/1 "Font Awesome 6 Duotone";\n --fa-font-sharp-solid: normal 900 1em/1 "Font Awesome 6 Sharp";\n --fa-font-sharp-regular: normal 400 1em/1 "Font Awesome 6 Sharp";\n --fa-font-sharp-light: normal 300 1em/1 "Font Awesome 6 Sharp";\n --fa-font-brands: normal 400 1em/1 "Font Awesome 6 Brands";\n}\n\nsvg:not(:root).svg-inline--fa, svg:not(:host).svg-inline--fa {\n overflow: visible;\n box-sizing: content-box;\n}\n\n.svg-inline--fa {\n display: var(--fa-display, inline-block);\n height: 1em;\n overflow: visible;\n vertical-align: -0.125em;\n}\n.svg-inline--fa.fa-2xs {\n vertical-align: 0.1em;\n}\n.svg-inline--fa.fa-xs {\n vertical-align: 0em;\n}\n.svg-inline--fa.fa-sm {\n vertical-align: -0.0714285705em;\n}\n.svg-inline--fa.fa-lg {\n vertical-align: -0.2em;\n}\n.svg-inline--fa.fa-xl {\n vertical-align: -0.25em;\n}\n.svg-inline--fa.fa-2xl {\n vertical-align: -0.3125em;\n}\n.svg-inline--fa.fa-pull-left {\n margin-right: var(--fa-pull-margin, 0.3em);\n width: auto;\n}\n.svg-inline--fa.fa-pull-right {\n margin-left: var(--fa-pull-margin, 0.3em);\n width: auto;\n}\n.svg-inline--fa.fa-li {\n width: var(--fa-li-width, 2em);\n top: 0.25em;\n}\n.svg-inline--fa.fa-fw {\n width: var(--fa-fw-width, 1.25em);\n}\n\n.fa-layers svg.svg-inline--fa {\n bottom: 0;\n left: 0;\n margin: auto;\n position: absolute;\n right: 0;\n top: 0;\n}\n\n.fa-layers-counter, .fa-layers-text {\n display: inline-block;\n position: absolute;\n text-align: center;\n}\n\n.fa-layers {\n display: inline-block;\n height: 1em;\n position: relative;\n text-align: center;\n vertical-align: -0.125em;\n width: 1em;\n}\n.fa-layers svg.svg-inline--fa {\n -webkit-transform-origin: center center;\n transform-origin: center center;\n}\n\n.fa-layers-text {\n left: 50%;\n top: 50%;\n -webkit-transform: translate(-50%, -50%);\n transform: translate(-50%, -50%);\n -webkit-transform-origin: center center;\n transform-origin: center center;\n}\n\n.fa-layers-counter {\n background-color: var(--fa-counter-background-color, #ff253a);\n border-radius: var(--fa-counter-border-radius, 1em);\n box-sizing: border-box;\n color: var(--fa-inverse, #fff);\n line-height: var(--fa-counter-line-height, 1);\n max-width: var(--fa-counter-max-width, 5em);\n min-width: var(--fa-counter-min-width, 1.5em);\n overflow: hidden;\n padding: var(--fa-counter-padding, 0.25em 0.5em);\n right: var(--fa-right, 0);\n text-overflow: ellipsis;\n top: var(--fa-top, 0);\n -webkit-transform: scale(var(--fa-counter-scale, 0.25));\n transform: scale(var(--fa-counter-scale, 0.25));\n -webkit-transform-origin: top right;\n transform-origin: top right;\n}\n\n.fa-layers-bottom-right {\n bottom: var(--fa-bottom, 0);\n right: var(--fa-right, 0);\n top: auto;\n -webkit-transform: scale(var(--fa-layers-scale, 0.25));\n transform: scale(var(--fa-layers-scale, 0.25));\n -webkit-transform-origin: bottom right;\n transform-origin: bottom right;\n}\n\n.fa-layers-bottom-left {\n bottom: var(--fa-bottom, 0);\n left: var(--fa-left, 0);\n right: auto;\n top: auto;\n -webkit-transform: scale(var(--fa-layers-scale, 0.25));\n transform: scale(var(--fa-layers-scale, 0.25));\n -webkit-transform-origin: bottom left;\n transform-origin: bottom left;\n}\n\n.fa-layers-top-right {\n top: var(--fa-top, 0);\n right: var(--fa-right, 0);\n -webkit-transform: scale(var(--fa-layers-scale, 0.25));\n transform: scale(var(--fa-layers-scale, 0.25));\n -webkit-transform-origin: top right;\n transform-origin: top right;\n}\n\n.fa-layers-top-left {\n left: var(--fa-left, 0);\n right: auto;\n top: var(--fa-top, 0);\n -webkit-transform: scale(var(--fa-layers-scale, 0.25));\n transform: scale(var(--fa-layers-scale, 0.25));\n -webkit-transform-origin: top left;\n transform-origin: top left;\n}\n\n.fa-1x {\n font-size: 1em;\n}\n\n.fa-2x {\n font-size: 2em;\n}\n\n.fa-3x {\n font-size: 3em;\n}\n\n.fa-4x {\n font-size: 4em;\n}\n\n.fa-5x {\n font-size: 5em;\n}\n\n.fa-6x {\n font-size: 6em;\n}\n\n.fa-7x {\n font-size: 7em;\n}\n\n.fa-8x {\n font-size: 8em;\n}\n\n.fa-9x {\n font-size: 9em;\n}\n\n.fa-10x {\n font-size: 10em;\n}\n\n.fa-2xs {\n font-size: 0.625em;\n line-height: 0.1em;\n vertical-align: 0.225em;\n}\n\n.fa-xs {\n font-size: 0.75em;\n line-height: 0.0833333337em;\n vertical-align: 0.125em;\n}\n\n.fa-sm {\n font-size: 0.875em;\n line-height: 0.0714285718em;\n vertical-align: 0.0535714295em;\n}\n\n.fa-lg {\n font-size: 1.25em;\n line-height: 0.05em;\n vertical-align: -0.075em;\n}\n\n.fa-xl {\n font-size: 1.5em;\n line-height: 0.0416666682em;\n vertical-align: -0.125em;\n}\n\n.fa-2xl {\n font-size: 2em;\n line-height: 0.03125em;\n vertical-align: -0.1875em;\n}\n\n.fa-fw {\n text-align: center;\n width: 1.25em;\n}\n\n.fa-ul {\n list-style-type: none;\n margin-left: var(--fa-li-margin, 2.5em);\n padding-left: 0;\n}\n.fa-ul > li {\n position: relative;\n}\n\n.fa-li {\n left: calc(var(--fa-li-width, 2em) * -1);\n position: absolute;\n text-align: center;\n width: var(--fa-li-width, 2em);\n line-height: inherit;\n}\n\n.fa-border {\n border-color: var(--fa-border-color, #eee);\n border-radius: var(--fa-border-radius, 0.1em);\n border-style: var(--fa-border-style, solid);\n border-width: var(--fa-border-width, 0.08em);\n padding: var(--fa-border-padding, 0.2em 0.25em 0.15em);\n}\n\n.fa-pull-left {\n float: left;\n margin-right: var(--fa-pull-margin, 0.3em);\n}\n\n.fa-pull-right {\n float: right;\n margin-left: var(--fa-pull-margin, 0.3em);\n}\n\n.fa-beat {\n -webkit-animation-name: fa-beat;\n animation-name: fa-beat;\n -webkit-animation-delay: var(--fa-animation-delay, 0s);\n animation-delay: var(--fa-animation-delay, 0s);\n -webkit-animation-direction: var(--fa-animation-direction, normal);\n animation-direction: var(--fa-animation-direction, normal);\n -webkit-animation-duration: var(--fa-animation-duration, 1s);\n animation-duration: var(--fa-animation-duration, 1s);\n -webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n -webkit-animation-timing-function: var(--fa-animation-timing, ease-in-out);\n animation-timing-function: var(--fa-animation-timing, ease-in-out);\n}\n\n.fa-bounce {\n -webkit-animation-name: fa-bounce;\n animation-name: fa-bounce;\n -webkit-animation-delay: var(--fa-animation-delay, 0s);\n animation-delay: var(--fa-animation-delay, 0s);\n -webkit-animation-direction: var(--fa-animation-direction, normal);\n animation-direction: var(--fa-animation-direction, normal);\n -webkit-animation-duration: var(--fa-animation-duration, 1s);\n animation-duration: var(--fa-animation-duration, 1s);\n -webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n -webkit-animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.28, 0.84, 0.42, 1));\n animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.28, 0.84, 0.42, 1));\n}\n\n.fa-fade {\n -webkit-animation-name: fa-fade;\n animation-name: fa-fade;\n -webkit-animation-delay: var(--fa-animation-delay, 0s);\n animation-delay: var(--fa-animation-delay, 0s);\n -webkit-animation-direction: var(--fa-animation-direction, normal);\n animation-direction: var(--fa-animation-direction, normal);\n -webkit-animation-duration: var(--fa-animation-duration, 1s);\n animation-duration: var(--fa-animation-duration, 1s);\n -webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n -webkit-animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1));\n animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1));\n}\n\n.fa-beat-fade {\n -webkit-animation-name: fa-beat-fade;\n animation-name: fa-beat-fade;\n -webkit-animation-delay: var(--fa-animation-delay, 0s);\n animation-delay: var(--fa-animation-delay, 0s);\n -webkit-animation-direction: var(--fa-animation-direction, normal);\n animation-direction: var(--fa-animation-direction, normal);\n -webkit-animation-duration: var(--fa-animation-duration, 1s);\n animation-duration: var(--fa-animation-duration, 1s);\n -webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n -webkit-animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1));\n animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1));\n}\n\n.fa-flip {\n -webkit-animation-name: fa-flip;\n animation-name: fa-flip;\n -webkit-animation-delay: var(--fa-animation-delay, 0s);\n animation-delay: var(--fa-animation-delay, 0s);\n -webkit-animation-direction: var(--fa-animation-direction, normal);\n animation-direction: var(--fa-animation-direction, normal);\n -webkit-animation-duration: var(--fa-animation-duration, 1s);\n animation-duration: var(--fa-animation-duration, 1s);\n -webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n -webkit-animation-timing-function: var(--fa-animation-timing, ease-in-out);\n animation-timing-function: var(--fa-animation-timing, ease-in-out);\n}\n\n.fa-shake {\n -webkit-animation-name: fa-shake;\n animation-name: fa-shake;\n -webkit-animation-delay: var(--fa-animation-delay, 0s);\n animation-delay: var(--fa-animation-delay, 0s);\n -webkit-animation-direction: var(--fa-animation-direction, normal);\n animation-direction: var(--fa-animation-direction, normal);\n -webkit-animation-duration: var(--fa-animation-duration, 1s);\n animation-duration: var(--fa-animation-duration, 1s);\n -webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n -webkit-animation-timing-function: var(--fa-animation-timing, linear);\n animation-timing-function: var(--fa-animation-timing, linear);\n}\n\n.fa-spin {\n -webkit-animation-name: fa-spin;\n animation-name: fa-spin;\n -webkit-animation-delay: var(--fa-animation-delay, 0s);\n animation-delay: var(--fa-animation-delay, 0s);\n -webkit-animation-direction: var(--fa-animation-direction, normal);\n animation-direction: var(--fa-animation-direction, normal);\n -webkit-animation-duration: var(--fa-animation-duration, 2s);\n animation-duration: var(--fa-animation-duration, 2s);\n -webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n -webkit-animation-timing-function: var(--fa-animation-timing, linear);\n animation-timing-function: var(--fa-animation-timing, linear);\n}\n\n.fa-spin-reverse {\n --fa-animation-direction: reverse;\n}\n\n.fa-pulse,\n.fa-spin-pulse {\n -webkit-animation-name: fa-spin;\n animation-name: fa-spin;\n -webkit-animation-direction: var(--fa-animation-direction, normal);\n animation-direction: var(--fa-animation-direction, normal);\n -webkit-animation-duration: var(--fa-animation-duration, 1s);\n animation-duration: var(--fa-animation-duration, 1s);\n -webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n -webkit-animation-timing-function: var(--fa-animation-timing, steps(8));\n animation-timing-function: var(--fa-animation-timing, steps(8));\n}\n\n@media (prefers-reduced-motion: reduce) {\n .fa-beat,\n.fa-bounce,\n.fa-fade,\n.fa-beat-fade,\n.fa-flip,\n.fa-pulse,\n.fa-shake,\n.fa-spin,\n.fa-spin-pulse {\n -webkit-animation-delay: -1ms;\n animation-delay: -1ms;\n -webkit-animation-duration: 1ms;\n animation-duration: 1ms;\n -webkit-animation-iteration-count: 1;\n animation-iteration-count: 1;\n -webkit-transition-delay: 0s;\n transition-delay: 0s;\n -webkit-transition-duration: 0s;\n transition-duration: 0s;\n }\n}\n@-webkit-keyframes fa-beat {\n 0%, 90% {\n -webkit-transform: scale(1);\n transform: scale(1);\n }\n 45% {\n -webkit-transform: scale(var(--fa-beat-scale, 1.25));\n transform: scale(var(--fa-beat-scale, 1.25));\n }\n}\n@keyframes fa-beat {\n 0%, 90% {\n -webkit-transform: scale(1);\n transform: scale(1);\n }\n 45% {\n -webkit-transform: scale(var(--fa-beat-scale, 1.25));\n transform: scale(var(--fa-beat-scale, 1.25));\n }\n}\n@-webkit-keyframes fa-bounce {\n 0% {\n -webkit-transform: scale(1, 1) translateY(0);\n transform: scale(1, 1) translateY(0);\n }\n 10% {\n -webkit-transform: scale(var(--fa-bounce-start-scale-x, 1.1), var(--fa-bounce-start-scale-y, 0.9)) translateY(0);\n transform: scale(var(--fa-bounce-start-scale-x, 1.1), var(--fa-bounce-start-scale-y, 0.9)) translateY(0);\n }\n 30% {\n -webkit-transform: scale(var(--fa-bounce-jump-scale-x, 0.9), var(--fa-bounce-jump-scale-y, 1.1)) translateY(var(--fa-bounce-height, -0.5em));\n transform: scale(var(--fa-bounce-jump-scale-x, 0.9), var(--fa-bounce-jump-scale-y, 1.1)) translateY(var(--fa-bounce-height, -0.5em));\n }\n 50% {\n -webkit-transform: scale(var(--fa-bounce-land-scale-x, 1.05), var(--fa-bounce-land-scale-y, 0.95)) translateY(0);\n transform: scale(var(--fa-bounce-land-scale-x, 1.05), var(--fa-bounce-land-scale-y, 0.95)) translateY(0);\n }\n 57% {\n -webkit-transform: scale(1, 1) translateY(var(--fa-bounce-rebound, -0.125em));\n transform: scale(1, 1) translateY(var(--fa-bounce-rebound, -0.125em));\n }\n 64% {\n -webkit-transform: scale(1, 1) translateY(0);\n transform: scale(1, 1) translateY(0);\n }\n 100% {\n -webkit-transform: scale(1, 1) translateY(0);\n transform: scale(1, 1) translateY(0);\n }\n}\n@keyframes fa-bounce {\n 0% {\n -webkit-transform: scale(1, 1) translateY(0);\n transform: scale(1, 1) translateY(0);\n }\n 10% {\n -webkit-transform: scale(var(--fa-bounce-start-scale-x, 1.1), var(--fa-bounce-start-scale-y, 0.9)) translateY(0);\n transform: scale(var(--fa-bounce-start-scale-x, 1.1), var(--fa-bounce-start-scale-y, 0.9)) translateY(0);\n }\n 30% {\n -webkit-transform: scale(var(--fa-bounce-jump-scale-x, 0.9), var(--fa-bounce-jump-scale-y, 1.1)) translateY(var(--fa-bounce-height, -0.5em));\n transform: scale(var(--fa-bounce-jump-scale-x, 0.9), var(--fa-bounce-jump-scale-y, 1.1)) translateY(var(--fa-bounce-height, -0.5em));\n }\n 50% {\n -webkit-transform: scale(var(--fa-bounce-land-scale-x, 1.05), var(--fa-bounce-land-scale-y, 0.95)) translateY(0);\n transform: scale(var(--fa-bounce-land-scale-x, 1.05), var(--fa-bounce-land-scale-y, 0.95)) translateY(0);\n }\n 57% {\n -webkit-transform: scale(1, 1) translateY(var(--fa-bounce-rebound, -0.125em));\n transform: scale(1, 1) translateY(var(--fa-bounce-rebound, -0.125em));\n }\n 64% {\n -webkit-transform: scale(1, 1) translateY(0);\n transform: scale(1, 1) translateY(0);\n }\n 100% {\n -webkit-transform: scale(1, 1) translateY(0);\n transform: scale(1, 1) translateY(0);\n }\n}\n@-webkit-keyframes fa-fade {\n 50% {\n opacity: var(--fa-fade-opacity, 0.4);\n }\n}\n@keyframes fa-fade {\n 50% {\n opacity: var(--fa-fade-opacity, 0.4);\n }\n}\n@-webkit-keyframes fa-beat-fade {\n 0%, 100% {\n opacity: var(--fa-beat-fade-opacity, 0.4);\n -webkit-transform: scale(1);\n transform: scale(1);\n }\n 50% {\n opacity: 1;\n -webkit-transform: scale(var(--fa-beat-fade-scale, 1.125));\n transform: scale(var(--fa-beat-fade-scale, 1.125));\n }\n}\n@keyframes fa-beat-fade {\n 0%, 100% {\n opacity: var(--fa-beat-fade-opacity, 0.4);\n -webkit-transform: scale(1);\n transform: scale(1);\n }\n 50% {\n opacity: 1;\n -webkit-transform: scale(var(--fa-beat-fade-scale, 1.125));\n transform: scale(var(--fa-beat-fade-scale, 1.125));\n }\n}\n@-webkit-keyframes fa-flip {\n 50% {\n -webkit-transform: rotate3d(var(--fa-flip-x, 0), var(--fa-flip-y, 1), var(--fa-flip-z, 0), var(--fa-flip-angle, -180deg));\n transform: rotate3d(var(--fa-flip-x, 0), var(--fa-flip-y, 1), var(--fa-flip-z, 0), var(--fa-flip-angle, -180deg));\n }\n}\n@keyframes fa-flip {\n 50% {\n -webkit-transform: rotate3d(var(--fa-flip-x, 0), var(--fa-flip-y, 1), var(--fa-flip-z, 0), var(--fa-flip-angle, -180deg));\n transform: rotate3d(var(--fa-flip-x, 0), var(--fa-flip-y, 1), var(--fa-flip-z, 0), var(--fa-flip-angle, -180deg));\n }\n}\n@-webkit-keyframes fa-shake {\n 0% {\n -webkit-transform: rotate(-15deg);\n transform: rotate(-15deg);\n }\n 4% {\n -webkit-transform: rotate(15deg);\n transform: rotate(15deg);\n }\n 8%, 24% {\n -webkit-transform: rotate(-18deg);\n transform: rotate(-18deg);\n }\n 12%, 28% {\n -webkit-transform: rotate(18deg);\n transform: rotate(18deg);\n }\n 16% {\n -webkit-transform: rotate(-22deg);\n transform: rotate(-22deg);\n }\n 20% {\n -webkit-transform: rotate(22deg);\n transform: rotate(22deg);\n }\n 32% {\n -webkit-transform: rotate(-12deg);\n transform: rotate(-12deg);\n }\n 36% {\n -webkit-transform: rotate(12deg);\n transform: rotate(12deg);\n }\n 40%, 100% {\n -webkit-transform: rotate(0deg);\n transform: rotate(0deg);\n }\n}\n@keyframes fa-shake {\n 0% {\n -webkit-transform: rotate(-15deg);\n transform: rotate(-15deg);\n }\n 4% {\n -webkit-transform: rotate(15deg);\n transform: rotate(15deg);\n }\n 8%, 24% {\n -webkit-transform: rotate(-18deg);\n transform: rotate(-18deg);\n }\n 12%, 28% {\n -webkit-transform: rotate(18deg);\n transform: rotate(18deg);\n }\n 16% {\n -webkit-transform: rotate(-22deg);\n transform: rotate(-22deg);\n }\n 20% {\n -webkit-transform: rotate(22deg);\n transform: rotate(22deg);\n }\n 32% {\n -webkit-transform: rotate(-12deg);\n transform: rotate(-12deg);\n }\n 36% {\n -webkit-transform: rotate(12deg);\n transform: rotate(12deg);\n }\n 40%, 100% {\n -webkit-transform: rotate(0deg);\n transform: rotate(0deg);\n }\n}\n@-webkit-keyframes fa-spin {\n 0% {\n -webkit-transform: rotate(0deg);\n transform: rotate(0deg);\n }\n 100% {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n@keyframes fa-spin {\n 0% {\n -webkit-transform: rotate(0deg);\n transform: rotate(0deg);\n }\n 100% {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n.fa-rotate-90 {\n -webkit-transform: rotate(90deg);\n transform: rotate(90deg);\n}\n\n.fa-rotate-180 {\n -webkit-transform: rotate(180deg);\n transform: rotate(180deg);\n}\n\n.fa-rotate-270 {\n -webkit-transform: rotate(270deg);\n transform: rotate(270deg);\n}\n\n.fa-flip-horizontal {\n -webkit-transform: scale(-1, 1);\n transform: scale(-1, 1);\n}\n\n.fa-flip-vertical {\n -webkit-transform: scale(1, -1);\n transform: scale(1, -1);\n}\n\n.fa-flip-both,\n.fa-flip-horizontal.fa-flip-vertical {\n -webkit-transform: scale(-1, -1);\n transform: scale(-1, -1);\n}\n\n.fa-rotate-by {\n -webkit-transform: rotate(var(--fa-rotate-angle, none));\n transform: rotate(var(--fa-rotate-angle, none));\n}\n\n.fa-stack {\n display: inline-block;\n vertical-align: middle;\n height: 2em;\n position: relative;\n width: 2.5em;\n}\n\n.fa-stack-1x,\n.fa-stack-2x {\n bottom: 0;\n left: 0;\n margin: auto;\n position: absolute;\n right: 0;\n top: 0;\n z-index: var(--fa-stack-z-index, auto);\n}\n\n.svg-inline--fa.fa-stack-1x {\n height: 1em;\n width: 1.25em;\n}\n.svg-inline--fa.fa-stack-2x {\n height: 2em;\n width: 2.5em;\n}\n\n.fa-inverse {\n color: var(--fa-inverse, #fff);\n}\n\n.sr-only,\n.fa-sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border-width: 0;\n}\n\n.sr-only-focusable:not(:focus),\n.fa-sr-only-focusable:not(:focus) {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border-width: 0;\n}\n\n.svg-inline--fa .fa-primary {\n fill: var(--fa-primary-color, currentColor);\n opacity: var(--fa-primary-opacity, 1);\n}\n\n.svg-inline--fa .fa-secondary {\n fill: var(--fa-secondary-color, currentColor);\n opacity: var(--fa-secondary-opacity, 0.4);\n}\n\n.svg-inline--fa.fa-swap-opacity .fa-primary {\n opacity: var(--fa-secondary-opacity, 0.4);\n}\n\n.svg-inline--fa.fa-swap-opacity .fa-secondary {\n opacity: var(--fa-primary-opacity, 1);\n}\n\n.svg-inline--fa mask .fa-primary,\n.svg-inline--fa mask .fa-secondary {\n fill: black;\n}\n\n.fad.fa-inverse,\n.fa-duotone.fa-inverse {\n color: var(--fa-inverse, #fff);\n}';function Ct(){var t=D,e=M,n=dt.cssPrefix,r=dt.replacementClass,a=St;if(n!==t||r!==e){var o=new RegExp("\\.".concat(t,"\\-"),"g"),i=new RegExp("\\--".concat(t,"\\-"),"g"),s=new RegExp("\\.".concat(e),"g");a=a.replace(o,".".concat(n,"-")).replace(i,"--".concat(n,"-")).replace(s,".".concat(r))}return a}var Pt=!1;function Et(){dt.autoAddCss&&!Pt&&(!function(t){if(t&&j){var e=O.createElement("style");e.setAttribute("type","text/css"),e.innerHTML=t;for(var n=O.head.childNodes,r=null,a=n.length-1;a>-1;a--){var o=n[a],i=(o.tagName||"").toUpperCase();["STYLE","LINK"].indexOf(i)>-1&&(r=o)}O.head.insertBefore(e,r)}}(Ct()),Pt=!0)}var Ot={mixout:function(){return{dom:{css:Ct,insertCss:Et}}},hooks:function(){return{beforeDOMElementCreation:function(){Et()},beforeI2svg:function(){Et()}}}},_t=E||{};_t[N]||(_t[N]={}),_t[N].styles||(_t[N].styles={}),_t[N].hooks||(_t[N].hooks={}),_t[N].shims||(_t[N].shims=[]);var Rt=_t[N],jt=[],At=!1;function Nt(t){var e=t.tag,n=t.attributes,r=void 0===n?{}:n,a=t.children,o=void 0===a?[]:a;return"string"==typeof t?wt(t):"<".concat(e," ").concat(function(t){return Object.keys(t||{}).reduce((function(e,n){return e+"".concat(n,'="').concat(wt(t[n]),'" ')}),"").trim()}(r),">").concat(o.map(Nt).join(""),"")}function Tt(t,e,n){if(t&&t[e]&&t[e][n])return{prefix:e,iconName:n,icon:t[e][n]}}j&&((At=(O.documentElement.doScroll?/^loaded|^c/:/^loaded|^i|^c/).test(O.readyState))||O.addEventListener("DOMContentLoaded",(function t(){O.removeEventListener("DOMContentLoaded",t),At=1,jt.map((function(t){return t()}))})));var Dt=function(t,e,n,r){var a,o,i,s=Object.keys(t),c=s.length,l=void 0!==r?function(t,e){return function(n,r,a,o){return t.call(e,n,r,a,o)}}(e,r):e;for(void 0===n?(a=1,i=t[s[0]]):(a=0,i=n);a=55296&&a<=56319&&n2&&void 0!==arguments[2]?arguments[2]:{}).skipHooks,r=void 0!==n&&n,a=Lt(e);"function"!=typeof Rt.hooks.addPack||r?Rt.styles[t]=i(i({},Rt.styles[t]||{}),a):Rt.hooks.addPack(t,Lt(e)),"fas"===t&&It("fa",e)}var Zt,zt,$t,Ft=Rt.styles,Ht=Rt.shims,Wt=(l(Zt={},q,Object.values(V[q])),l(Zt,B,Object.values(V[B])),Zt),Ut=null,qt={},Bt={},Yt={},Qt={},Jt={},Gt=(l(zt={},q,Object.keys(J[q])),l(zt,B,Object.keys(J[B])),zt);function Vt(t,e){var n,r=e.split("-"),a=r[0],o=r.slice(1).join("-");return a!==t||""===o||(n=o,~ct.indexOf(n))?null:o}var Kt,Xt=function(){var t=function(t){return Dt(Ft,(function(e,n,r){return e[r]=Dt(n,t,{}),e}),{})};qt=t((function(t,e,n){(e[3]&&(t[e[3]]=n),e[2])&&e[2].filter((function(t){return"number"==typeof t})).forEach((function(e){t[e.toString(16)]=n}));return t})),Bt=t((function(t,e,n){(t[n]=n,e[2])&&e[2].filter((function(t){return"string"==typeof t})).forEach((function(e){t[e]=n}));return t})),Jt=t((function(t,e,n){var r=e[2];return t[n]=n,r.forEach((function(e){t[e]=n})),t}));var e="far"in Ft||dt.autoFetchSvg,n=Dt(Ht,(function(t,n){var r=n[0],a=n[1],o=n[2];return"far"!==a||e||(a="fas"),"string"==typeof r&&(t.names[r]={prefix:a,iconName:o}),"number"==typeof r&&(t.unicodes[r.toString(16)]={prefix:a,iconName:o}),t}),{names:{},unicodes:{}});Yt=n.names,Qt=n.unicodes,Ut=oe(dt.styleDefault,{family:dt.familyDefault})};function te(t,e){return(qt[t]||{})[e]}function ee(t,e){return(Jt[t]||{})[e]}function ne(t){return Yt[t]||{prefix:null,iconName:null}}function re(){return Ut}Kt=function(t){Ut=oe(t.styleDefault,{family:dt.familyDefault})},pt.push(Kt),Xt();var ae=function(){return{prefix:null,iconName:null,rest:[]}};function oe(t){var e=(arguments.length>1&&void 0!==arguments[1]?arguments[1]:{}).family,n=void 0===e?q:e,r=J[n][t],a=G[n][t]||G[n][r],o=t in Rt.styles?t:null;return a||o||null}var ie=(l($t={},q,Object.keys(V[q])),l($t,B,Object.keys(V[B])),$t);function se(t){var e,n=(arguments.length>1&&void 0!==arguments[1]?arguments[1]:{}).skipLookups,r=void 0!==n&&n,a=(l(e={},q,"".concat(dt.cssPrefix,"-").concat(q)),l(e,B,"".concat(dt.cssPrefix,"-").concat(B)),e),o=null,i=q;(t.includes(a[q])||t.some((function(t){return ie[q].includes(t)})))&&(i=q),(t.includes(a[B])||t.some((function(t){return ie[B].includes(t)})))&&(i=B);var s=t.reduce((function(t,e){var n=Vt(dt.cssPrefix,e);if(Ft[e]?(e=Wt[i].includes(e)?K[i][e]:e,o=e,t.prefix=e):Gt[i].indexOf(e)>-1?(o=e,t.prefix=oe(e,{family:i})):n?t.iconName=n:e!==dt.replacementClass&&e!==a[q]&&e!==a[B]&&t.rest.push(e),!r&&t.prefix&&t.iconName){var s="fa"===o?ne(t.iconName):{},c=ee(t.prefix,t.iconName);s.prefix&&(o=null),t.iconName=s.iconName||c||t.iconName,t.prefix=s.prefix||t.prefix,"far"!==t.prefix||Ft.far||!Ft.fas||dt.autoFetchSvg||(t.prefix="fas")}return t}),ae());return(t.includes("fa-brands")||t.includes("fab"))&&(s.prefix="fab"),(t.includes("fa-duotone")||t.includes("fad"))&&(s.prefix="fad"),s.prefix||i!==B||!Ft.fass&&!dt.autoFetchSvg||(s.prefix="fass",s.iconName=ee(s.prefix,s.iconName)||s.iconName),"fa"!==s.prefix&&"fa"!==o||(s.prefix=re()||"fas"),s}var ce=function(){function t(){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.definitions={}}var e,n,r;return e=t,n=[{key:"add",value:function(){for(var t=this,e=arguments.length,n=new Array(e),r=0;r0&&s.forEach((function(e){"string"==typeof e&&(t[a][e]=i)})),t[a][o]=i})),t}}],n&&c(e.prototype,n),r&&c(e,r),Object.defineProperty(e,"prototype",{writable:!1}),t}(),le=[],ue={},fe={},de=Object.keys(fe);function pe(t,e){for(var n=arguments.length,r=new Array(n>2?n-2:0),a=2;a1?e-1:0),r=1;r0&&void 0!==arguments[0]?arguments[0]:{};return j?(me("beforeI2svg",t),he("pseudoElements2svg",t),he("i2svg",t)):Promise.reject("Operation requires a DOM of some kind.")},watch:function(){var t,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.autoReplaceSvgRoot;!1===dt.autoReplaceSvg&&(dt.autoReplaceSvg=!0),dt.observeMutations=!0,t=function(){we({autoReplaceSvgRoot:n}),me("watch",e)},j&&(At?setTimeout(t,0):jt.push(t))}},ye={noAuto:function(){dt.autoReplaceSvg=!1,dt.observeMutations=!1,me("noAuto")},config:dt,dom:be,parse:{icon:function(t){if(null===t)return null;if("object"===s(t)&&t.prefix&&t.iconName)return{prefix:t.prefix,iconName:ee(t.prefix,t.iconName)||t.iconName};if(Array.isArray(t)&&2===t.length){var e=0===t[1].indexOf("fa-")?t[1].slice(3):t[1],n=oe(t[0]);return{prefix:n,iconName:ee(n,e)||e}}if("string"==typeof t&&(t.indexOf("".concat(dt.cssPrefix,"-"))>-1||t.match(X))){var r=se(t.split(" "),{skipLookups:!0});return{prefix:r.prefix||re(),iconName:ee(r.prefix,r.iconName)||r.iconName}}if("string"==typeof t){var a=re();return{prefix:a,iconName:ee(a,t)||t}}}},library:ve,findIconDefinition:ge,toHtml:Nt},we=function(){var t=(arguments.length>0&&void 0!==arguments[0]?arguments[0]:{}).autoReplaceSvgRoot,e=void 0===t?O:t;(Object.keys(Rt.styles).length>0||dt.autoFetchSvg)&&j&&dt.autoReplaceSvg&&ye.dom.i2svg({node:e})};function ke(t,e){return Object.defineProperty(t,"abstract",{get:e}),Object.defineProperty(t,"html",{get:function(){return t.abstract.map((function(t){return Nt(t)}))}}),Object.defineProperty(t,"node",{get:function(){if(j){var e=O.createElement("div");return e.innerHTML=t.html,e.children}}}),t}function xe(t){var e=t.icons,n=e.main,r=e.mask,a=t.prefix,o=t.iconName,s=t.transform,c=t.symbol,l=t.title,u=t.maskId,f=t.titleId,d=t.extra,p=t.watchable,m=void 0!==p&&p,h=r.found?r:n,g=h.width,v=h.height,b="fak"===a,y=[dt.replacementClass,o?"".concat(dt.cssPrefix,"-").concat(o):""].filter((function(t){return-1===d.classes.indexOf(t)})).filter((function(t){return""!==t||!!t})).concat(d.classes).join(" "),w={children:[],attributes:i(i({},d.attributes),{},{"data-prefix":a,"data-icon":o,class:y,role:d.attributes.role||"img",xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 ".concat(g," ").concat(v)})},k=b&&!~d.classes.indexOf("fa-fw")?{width:"".concat(g/v*16*.0625,"em")}:{};m&&(w.attributes[L]=""),l&&(w.children.push({tag:"title",attributes:{id:w.attributes["aria-labelledby"]||"title-".concat(f||vt())},children:[l]}),delete w.attributes.title);var x=i(i({},w),{},{prefix:a,iconName:o,main:n,mask:r,maskId:u,transform:s,symbol:c,styles:i(i({},k),d.styles)}),S=r.found&&n.found?he("generateAbstractMask",x)||{children:[],attributes:{}}:he("generateAbstractIcon",x)||{children:[],attributes:{}},C=S.children,P=S.attributes;return x.children=C,x.attributes=P,c?function(t){var e=t.prefix,n=t.iconName,r=t.children,a=t.attributes,o=t.symbol,s=!0===o?"".concat(e,"-").concat(dt.cssPrefix,"-").concat(n):o;return[{tag:"svg",attributes:{style:"display: none;"},children:[{tag:"symbol",attributes:i(i({},a),{},{id:s}),children:r}]}]}(x):function(t){var e=t.children,n=t.main,r=t.mask,a=t.attributes,o=t.styles,s=t.transform;if(xt(s)&&n.found&&!r.found){var c={x:n.width/n.height/2,y:.5};a.style=kt(i(i({},o),{},{"transform-origin":"".concat(c.x+s.x/16,"em ").concat(c.y+s.y/16,"em")}))}return[{tag:"svg",attributes:a,children:e}]}(x)}function Se(t){var e=t.content,n=t.width,r=t.height,a=t.transform,o=t.title,s=t.extra,c=t.watchable,l=void 0!==c&&c,u=i(i(i({},s.attributes),o?{title:o}:{}),{},{class:s.classes.join(" ")});l&&(u[L]="");var f=i({},s.styles);xt(a)&&(f.transform=function(t){var e=t.transform,n=t.width,r=void 0===n?T:n,a=t.height,o=void 0===a?T:a,i=t.startCentered,s=void 0!==i&&i,c="";return c+=s&&A?"translate(".concat(e.x/mt-r/2,"em, ").concat(e.y/mt-o/2,"em) "):s?"translate(calc(-50% + ".concat(e.x/mt,"em), calc(-50% + ").concat(e.y/mt,"em)) "):"translate(".concat(e.x/mt,"em, ").concat(e.y/mt,"em) "),c+="scale(".concat(e.size/mt*(e.flipX?-1:1),", ").concat(e.size/mt*(e.flipY?-1:1),") "),c+"rotate(".concat(e.rotate,"deg) ")}({transform:a,startCentered:!0,width:n,height:r}),f["-webkit-transform"]=f.transform);var d=kt(f);d.length>0&&(u.style=d);var p=[];return p.push({tag:"span",attributes:u,children:[e]}),o&&p.push({tag:"span",attributes:{class:"sr-only"},children:[o]}),p}var Ce=Rt.styles;function Pe(t){var e=t[0],n=t[1],r=u(t.slice(4),1)[0];return{found:!0,width:e,height:n,icon:Array.isArray(r)?{tag:"g",attributes:{class:"".concat(dt.cssPrefix,"-").concat(it.GROUP)},children:[{tag:"path",attributes:{class:"".concat(dt.cssPrefix,"-").concat(it.SECONDARY),fill:"currentColor",d:r[0]}},{tag:"path",attributes:{class:"".concat(dt.cssPrefix,"-").concat(it.PRIMARY),fill:"currentColor",d:r[1]}}]}:{tag:"path",attributes:{fill:"currentColor",d:r}}}}var Ee={found:!1,width:512,height:512};function Oe(t,e){var n=e;return"fa"===e&&null!==dt.styleDefault&&(e=re()),new Promise((function(r,a){he("missingIconAbstract");if("fa"===n){var o=ne(t)||{};t=o.iconName||t,e=o.prefix||e}if(t&&e&&Ce[e]&&Ce[e][t])return r(Pe(Ce[e][t]));!function(t,e){U||dt.showMissingIcons||!t||console.error('Icon with name "'.concat(t,'" and prefix "').concat(e,'" is missing.'))}(t,e),r(i(i({},Ee),{},{icon:dt.showMissingIcons&&t&&he("missingIconAbstract")||{}}))}))}var _e=function(){},Re=dt.measurePerformance&&R&&R.mark&&R.measure?R:{mark:_e,measure:_e},je='FA "6.4.0"',Ae=function(t){Re.mark("".concat(je," ").concat(t," ends")),Re.measure("".concat(je," ").concat(t),"".concat(je," ").concat(t," begins"),"".concat(je," ").concat(t," ends"))},Ne={begin:function(t){return Re.mark("".concat(je," ").concat(t," begins")),function(){return Ae(t)}},end:Ae},Te=function(){};function De(t){return"string"==typeof(t.getAttribute?t.getAttribute(L):null)}function Me(t){return O.createElementNS("http://www.w3.org/2000/svg",t)}function Le(t){return O.createElement(t)}function Ie(t){var e=(arguments.length>1&&void 0!==arguments[1]?arguments[1]:{}).ceFn,n=void 0===e?"svg"===t.tag?Me:Le:e;if("string"==typeof t)return O.createTextNode(t);var r=n(t.tag);return Object.keys(t.attributes||[]).forEach((function(e){r.setAttribute(e,t.attributes[e])})),(t.children||[]).forEach((function(t){r.appendChild(Ie(t,{ceFn:n}))})),r}var Ze={replace:function(t){var e=t[0];if(e.parentNode)if(t[1].forEach((function(t){e.parentNode.insertBefore(Ie(t),e)})),null===e.getAttribute(L)&&dt.keepOriginalSource){var n=O.createComment(function(t){var e=" ".concat(t.outerHTML," ");return"".concat(e,"Font Awesome fontawesome.com ")}(e));e.parentNode.replaceChild(n,e)}else e.remove()},nest:function(t){var e=t[0],n=t[1];if(~yt(e).indexOf(dt.replacementClass))return Ze.replace(t);var r=new RegExp("".concat(dt.cssPrefix,"-.*"));if(delete n[0].attributes.id,n[0].attributes.class){var a=n[0].attributes.class.split(" ").reduce((function(t,e){return e===dt.replacementClass||e.match(r)?t.toSvg.push(e):t.toNode.push(e),t}),{toNode:[],toSvg:[]});n[0].attributes.class=a.toSvg.join(" "),0===a.toNode.length?e.removeAttribute("class"):e.setAttribute("class",a.toNode.join(" "))}var o=n.map((function(t){return Nt(t)})).join("\n");e.setAttribute(L,""),e.innerHTML=o}};function ze(t){t()}function $e(t,e){var n="function"==typeof e?e:Te;if(0===t.length)n();else{var r=ze;dt.mutateApproach===H&&(r=E.requestAnimationFrame||ze),r((function(){var e=!0===dt.autoReplaceSvg?Ze.replace:Ze[dt.autoReplaceSvg]||Ze.replace,r=Ne.begin("mutate");t.map(e),r(),n()}))}}var Fe=!1;function He(){Fe=!0}function We(){Fe=!1}var Ue=null;function qe(t){if(_&&dt.observeMutations){var e=t.treeCallback,n=void 0===e?Te:e,r=t.nodeCallback,a=void 0===r?Te:r,o=t.pseudoElementsCallback,i=void 0===o?Te:o,s=t.observeMutationsRoot,c=void 0===s?O:s;Ue=new _((function(t){if(!Fe){var e=re();bt(t).forEach((function(t){if("childList"===t.type&&t.addedNodes.length>0&&!De(t.addedNodes[0])&&(dt.searchPseudoElements&&i(t.target),n(t.target)),"attributes"===t.type&&t.target.parentNode&&dt.searchPseudoElements&&i(t.target.parentNode),"attributes"===t.type&&De(t.target)&&~ot.indexOf(t.attributeName))if("class"===t.attributeName&&function(t){var e=t.getAttribute?t.getAttribute(z):null,n=t.getAttribute?t.getAttribute($):null;return e&&n}(t.target)){var r=se(yt(t.target)),o=r.prefix,s=r.iconName;t.target.setAttribute(z,o||e),s&&t.target.setAttribute($,s)}else(c=t.target)&&c.classList&&c.classList.contains&&c.classList.contains(dt.replacementClass)&&a(t.target);var c}))}})),j&&Ue.observe(c,{childList:!0,attributes:!0,characterData:!0,subtree:!0})}}function Be(t){var e=t.getAttribute("data-prefix"),n=t.getAttribute("data-icon"),r=void 0!==t.innerText?t.innerText.trim():"",a=se(yt(t));return a.prefix||(a.prefix=re()),e&&n&&(a.prefix=e,a.iconName=n),a.iconName&&a.prefix||(a.prefix&&r.length>0&&(a.iconName=function(t,e){return(Bt[t]||{})[e]}(a.prefix,t.innerText)||te(a.prefix,Mt(t.innerText))),!a.iconName&&dt.autoFetchSvg&&t.firstChild&&t.firstChild.nodeType===Node.TEXT_NODE&&(a.iconName=t.firstChild.data)),a}function Ye(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{styleParser:!0},n=Be(t),r=n.iconName,a=n.prefix,o=n.rest,s=function(t){var e=bt(t.attributes).reduce((function(t,e){return"class"!==t.name&&"style"!==t.name&&(t[e.name]=e.value),t}),{}),n=t.getAttribute("title"),r=t.getAttribute("data-fa-title-id");return dt.autoA11y&&(n?e["aria-labelledby"]="".concat(dt.replacementClass,"-title-").concat(r||vt()):(e["aria-hidden"]="true",e.focusable="false")),e}(t),c=pe("parseNodeAttributes",{},t),l=e.styleParser?function(t){var e=t.getAttribute("style"),n=[];return e&&(n=e.split(";").reduce((function(t,e){var n=e.split(":"),r=n[0],a=n.slice(1);return r&&a.length>0&&(t[r]=a.join(":").trim()),t}),{})),n}(t):[];return i({iconName:r,title:t.getAttribute("title"),titleId:t.getAttribute("data-fa-title-id"),prefix:a,transform:ht,mask:{iconName:null,prefix:null,rest:[]},maskId:null,symbol:!1,extra:{classes:o,styles:l,attributes:s}},c)}var Qe=Rt.styles;function Je(t){var e="nest"===dt.autoReplaceSvg?Ye(t,{styleParser:!1}):Ye(t);return~e.extra.classes.indexOf(tt)?he("generateLayersText",t,e):he("generateSvgReplacementMutation",t,e)}var Ge=new Set;function Ve(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;if(!j)return Promise.resolve();var n=O.documentElement.classList,r=function(t){return n.add("".concat(F,"-").concat(t))},a=function(t){return n.remove("".concat(F,"-").concat(t))},o=dt.autoFetchSvg?Ge:Y.map((function(t){return"fa-".concat(t)})).concat(Object.keys(Qe));o.includes("fa")||o.push("fa");var i=[".".concat(tt,":not([").concat(L,"])")].concat(o.map((function(t){return".".concat(t,":not([").concat(L,"])")}))).join(", ");if(0===i.length)return Promise.resolve();var s=[];try{s=bt(t.querySelectorAll(i))}catch(Or){}if(!(s.length>0))return Promise.resolve();r("pending"),a("complete");var c=Ne.begin("onTree"),l=s.reduce((function(t,e){try{var n=Je(e);n&&t.push(n)}catch(Or){U||"MissingIcon"===Or.name&&console.error(Or)}return t}),[]);return new Promise((function(t,n){Promise.all(l).then((function(n){$e(n,(function(){r("active"),r("complete"),a("pending"),"function"==typeof e&&e(),c(),t()}))})).catch((function(t){c(),n(t)}))}))}function Ke(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;Je(t).then((function(t){t&&$e([t],e)}))}Y.map((function(t){Ge.add("fa-".concat(t))})),Object.keys(J[q]).map(Ge.add.bind(Ge)),Object.keys(J[B]).map(Ge.add.bind(Ge)),Ge=f(Ge);var Xe=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=e.transform,r=void 0===n?ht:n,a=e.symbol,o=void 0!==a&&a,s=e.mask,c=void 0===s?null:s,l=e.maskId,u=void 0===l?null:l,f=e.title,d=void 0===f?null:f,p=e.titleId,m=void 0===p?null:p,h=e.classes,g=void 0===h?[]:h,v=e.attributes,b=void 0===v?{}:v,y=e.styles,w=void 0===y?{}:y;if(t){var k=t.prefix,x=t.iconName,S=t.icon;return ke(i({type:"icon"},t),(function(){return me("beforeDOMElementCreation",{iconDefinition:t,params:e}),dt.autoA11y&&(d?b["aria-labelledby"]="".concat(dt.replacementClass,"-title-").concat(m||vt()):(b["aria-hidden"]="true",b.focusable="false")),xe({icons:{main:Pe(S),mask:c?Pe(c.icon):{found:!1,width:null,height:null,icon:{}}},prefix:k,iconName:x,transform:i(i({},ht),r),symbol:o,title:d,maskId:u,titleId:m,extra:{attributes:b,styles:w,classes:g}})}))}},tn={mixout:function(){return{icon:(t=Xe,function(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=(e||{}).icon?e:ge(e||{}),a=n.mask;return a&&(a=(a||{}).icon?a:ge(a||{})),t(r,i(i({},n),{},{mask:a}))})};var t},hooks:function(){return{mutationObserverCallbacks:function(t){return t.treeCallback=Ve,t.nodeCallback=Ke,t}}},provides:function(t){t.i2svg=function(t){var e=t.node,n=void 0===e?O:e,r=t.callback;return Ve(n,void 0===r?function(){}:r)},t.generateSvgReplacementMutation=function(t,e){var n=e.iconName,r=e.title,a=e.titleId,o=e.prefix,i=e.transform,s=e.symbol,c=e.mask,l=e.maskId,f=e.extra;return new Promise((function(e,d){Promise.all([Oe(n,o),c.iconName?Oe(c.iconName,c.prefix):Promise.resolve({found:!1,width:512,height:512,icon:{}})]).then((function(c){var d=u(c,2),p=d[0],m=d[1];e([t,xe({icons:{main:p,mask:m},prefix:o,iconName:n,transform:i,symbol:s,maskId:l,title:r,titleId:a,extra:f,watchable:!0})])})).catch(d)}))},t.generateAbstractIcon=function(t){var e,n=t.children,r=t.attributes,a=t.main,o=t.transform,i=kt(t.styles);return i.length>0&&(r.style=i),xt(o)&&(e=he("generateAbstractTransformGrouping",{main:a,transform:o,containerWidth:a.width,iconWidth:a.width})),n.push(e||a.icon),{children:n,attributes:r}}}},en={mixout:function(){return{layer:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=e.classes,r=void 0===n?[]:n;return ke({type:"layer"},(function(){me("beforeDOMElementCreation",{assembler:t,params:e});var n=[];return t((function(t){Array.isArray(t)?t.map((function(t){n=n.concat(t.abstract)})):n=n.concat(t.abstract)})),[{tag:"span",attributes:{class:["".concat(dt.cssPrefix,"-layers")].concat(f(r)).join(" ")},children:n}]}))}}}},nn={mixout:function(){return{counter:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=e.title,r=void 0===n?null:n,a=e.classes,o=void 0===a?[]:a,s=e.attributes,c=void 0===s?{}:s,l=e.styles,u=void 0===l?{}:l;return ke({type:"counter",content:t},(function(){return me("beforeDOMElementCreation",{content:t,params:e}),function(t){var e=t.content,n=t.title,r=t.extra,a=i(i(i({},r.attributes),n?{title:n}:{}),{},{class:r.classes.join(" ")}),o=kt(r.styles);o.length>0&&(a.style=o);var s=[];return s.push({tag:"span",attributes:a,children:[e]}),n&&s.push({tag:"span",attributes:{class:"sr-only"},children:[n]}),s}({content:t.toString(),title:r,extra:{attributes:c,styles:u,classes:["".concat(dt.cssPrefix,"-layers-counter")].concat(f(o))}})}))}}}},rn={mixout:function(){return{text:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=e.transform,r=void 0===n?ht:n,a=e.title,o=void 0===a?null:a,s=e.classes,c=void 0===s?[]:s,l=e.attributes,u=void 0===l?{}:l,d=e.styles,p=void 0===d?{}:d;return ke({type:"text",content:t},(function(){return me("beforeDOMElementCreation",{content:t,params:e}),Se({content:t,transform:i(i({},ht),r),title:o,extra:{attributes:u,styles:p,classes:["".concat(dt.cssPrefix,"-layers-text")].concat(f(c))}})}))}}},provides:function(t){t.generateLayersText=function(t,e){var n=e.title,r=e.transform,a=e.extra,o=null,i=null;if(A){var s=parseInt(getComputedStyle(t).fontSize,10),c=t.getBoundingClientRect();o=c.width/s,i=c.height/s}return dt.autoA11y&&!n&&(a.attributes["aria-hidden"]="true"),Promise.resolve([t,Se({content:t.innerHTML,width:o,height:i,transform:r,title:n,extra:a,watchable:!0})])}}},an=new RegExp('"',"ug"),on=[1105920,1112319];function sn(t,e){var n="".concat(Z).concat(e.replace(":","-"));return new Promise((function(r,a){if(null!==t.getAttribute(n))return r();var o,s,c,l=bt(t.children).filter((function(t){return t.getAttribute(I)===e}))[0],u=E.getComputedStyle(t,e),f=u.getPropertyValue("font-family").match(et),d=u.getPropertyValue("font-weight"),p=u.getPropertyValue("content");if(l&&!f)return t.removeChild(l),r();if(f&&"none"!==p&&""!==p){var m=u.getPropertyValue("content"),h=~["Sharp"].indexOf(f[2])?B:q,g=~["Solid","Regular","Light","Thin","Duotone","Brands","Kit"].indexOf(f[2])?G[h][f[2].toLowerCase()]:nt[h][d],v=function(t){var e,n,r,a,o,i=t.replace(an,""),s=(n=0,a=(e=i).length,(o=e.charCodeAt(n))>=55296&&o<=56319&&a>n+1&&(r=e.charCodeAt(n+1))>=56320&&r<=57343?1024*(o-55296)+r-56320+65536:o),c=s>=on[0]&&s<=on[1],l=2===i.length&&i[0]===i[1];return{value:Mt(l?i[0]:i),isSecondary:c||l}}(m),b=v.value,y=v.isSecondary,w=f[0].startsWith("FontAwesome"),k=te(g,b),x=k;if(w){var S=(s=Qt[o=b],c=te("fas",o),s||(c?{prefix:"fas",iconName:c}:null)||{prefix:null,iconName:null});S.iconName&&S.prefix&&(k=S.iconName,g=S.prefix)}if(!k||y||l&&l.getAttribute(z)===g&&l.getAttribute($)===x)r();else{t.setAttribute(n,x),l&&t.removeChild(l);var C={iconName:null,title:null,titleId:null,prefix:null,transform:ht,symbol:!1,mask:{iconName:null,prefix:null,rest:[]},maskId:null,extra:{classes:[],styles:{},attributes:{}}},P=C.extra;P.attributes[I]=e,Oe(k,g).then((function(a){var o=xe(i(i({},C),{},{icons:{main:a,mask:ae()},prefix:g,iconName:x,extra:P,watchable:!0})),s=O.createElement("svg");"::before"===e?t.insertBefore(s,t.firstChild):t.appendChild(s),s.outerHTML=o.map((function(t){return Nt(t)})).join("\n"),t.removeAttribute(n),r()})).catch(a)}}else r()}))}function cn(t){return Promise.all([sn(t,"::before"),sn(t,"::after")])}function ln(t){return!(t.parentNode===document.head||~W.indexOf(t.tagName.toUpperCase())||t.getAttribute(I)||t.parentNode&&"svg"===t.parentNode.tagName)}function un(t){if(j)return new Promise((function(e,n){var r=bt(t.querySelectorAll("*")).filter(ln).map(cn),a=Ne.begin("searchPseudoElements");He(),Promise.all(r).then((function(){a(),We(),e()})).catch((function(){a(),We(),n()}))}))}var fn=!1,dn=function(t){return t.toLowerCase().split(" ").reduce((function(t,e){var n=e.toLowerCase().split("-"),r=n[0],a=n.slice(1).join("-");if(r&&"h"===a)return t.flipX=!0,t;if(r&&"v"===a)return t.flipY=!0,t;if(a=parseFloat(a),isNaN(a))return t;switch(r){case"grow":t.size=t.size+a;break;case"shrink":t.size=t.size-a;break;case"left":t.x=t.x-a;break;case"right":t.x=t.x+a;break;case"up":t.y=t.y-a;break;case"down":t.y=t.y+a;break;case"rotate":t.rotate=t.rotate+a}return t}),{size:16,x:0,y:0,flipX:!1,flipY:!1,rotate:0})},pn={mixout:function(){return{parse:{transform:function(t){return dn(t)}}}},hooks:function(){return{parseNodeAttributes:function(t,e){var n=e.getAttribute("data-fa-transform");return n&&(t.transform=dn(n)),t}}},provides:function(t){t.generateAbstractTransformGrouping=function(t){var e=t.main,n=t.transform,r=t.containerWidth,a=t.iconWidth,o={transform:"translate(".concat(r/2," 256)")},s="translate(".concat(32*n.x,", ").concat(32*n.y,") "),c="scale(".concat(n.size/16*(n.flipX?-1:1),", ").concat(n.size/16*(n.flipY?-1:1),") "),l="rotate(".concat(n.rotate," 0 0)"),u={outer:o,inner:{transform:"".concat(s," ").concat(c," ").concat(l)},path:{transform:"translate(".concat(a/2*-1," -256)")}};return{tag:"g",attributes:i({},u.outer),children:[{tag:"g",attributes:i({},u.inner),children:[{tag:e.icon.tag,children:e.icon.children,attributes:i(i({},e.icon.attributes),u.path)}]}]}}}},mn={x:0,y:0,width:"100%",height:"100%"};function hn(t){var e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];return t.attributes&&(t.attributes.fill||e)&&(t.attributes.fill="black"),t}var gn={hooks:function(){return{parseNodeAttributes:function(t,e){var n=e.getAttribute("data-fa-mask"),r=n?se(n.split(" ").map((function(t){return t.trim()}))):ae();return r.prefix||(r.prefix=re()),t.mask=r,t.maskId=e.getAttribute("data-fa-mask-id"),t}}},provides:function(t){t.generateAbstractMask=function(t){var e,n=t.children,r=t.attributes,a=t.main,o=t.mask,s=t.maskId,c=t.transform,l=a.width,u=a.icon,f=o.width,d=o.icon,p=function(t){var e=t.transform,n=t.containerWidth,r=t.iconWidth,a={transform:"translate(".concat(n/2," 256)")},o="translate(".concat(32*e.x,", ").concat(32*e.y,") "),i="scale(".concat(e.size/16*(e.flipX?-1:1),", ").concat(e.size/16*(e.flipY?-1:1),") "),s="rotate(".concat(e.rotate," 0 0)");return{outer:a,inner:{transform:"".concat(o," ").concat(i," ").concat(s)},path:{transform:"translate(".concat(r/2*-1," -256)")}}}({transform:c,containerWidth:f,iconWidth:l}),m={tag:"rect",attributes:i(i({},mn),{},{fill:"white"})},h=u.children?{children:u.children.map(hn)}:{},g={tag:"g",attributes:i({},p.inner),children:[hn(i({tag:u.tag,attributes:i(i({},u.attributes),p.path)},h))]},v={tag:"g",attributes:i({},p.outer),children:[g]},b="mask-".concat(s||vt()),y="clip-".concat(s||vt()),w={tag:"mask",attributes:i(i({},mn),{},{id:b,maskUnits:"userSpaceOnUse",maskContentUnits:"userSpaceOnUse"}),children:[m,v]},k={tag:"defs",children:[{tag:"clipPath",attributes:{id:y},children:(e=d,"g"===e.tag?e.children:[e])},w]};return n.push(k,{tag:"rect",attributes:i({fill:"currentColor","clip-path":"url(#".concat(y,")"),mask:"url(#".concat(b,")")},mn)}),{children:n,attributes:r}}}},vn={provides:function(t){var e=!1;E.matchMedia&&(e=E.matchMedia("(prefers-reduced-motion: reduce)").matches),t.missingIconAbstract=function(){var t=[],n={fill:"currentColor"},r={attributeType:"XML",repeatCount:"indefinite",dur:"2s"};t.push({tag:"path",attributes:i(i({},n),{},{d:"M156.5,447.7l-12.6,29.5c-18.7-9.5-35.9-21.2-51.5-34.9l22.7-22.7C127.6,430.5,141.5,440,156.5,447.7z M40.6,272H8.5 c1.4,21.2,5.4,41.7,11.7,61.1L50,321.2C45.1,305.5,41.8,289,40.6,272z M40.6,240c1.4-18.8,5.2-37,11.1-54.1l-29.5-12.6 C14.7,194.3,10,216.7,8.5,240H40.6z M64.3,156.5c7.8-14.9,17.2-28.8,28.1-41.5L69.7,92.3c-13.7,15.6-25.5,32.8-34.9,51.5 L64.3,156.5z M397,419.6c-13.9,12-29.4,22.3-46.1,30.4l11.9,29.8c20.7-9.9,39.8-22.6,56.9-37.6L397,419.6z M115,92.4 c13.9-12,29.4-22.3,46.1-30.4l-11.9-29.8c-20.7,9.9-39.8,22.6-56.8,37.6L115,92.4z M447.7,355.5c-7.8,14.9-17.2,28.8-28.1,41.5 l22.7,22.7c13.7-15.6,25.5-32.9,34.9-51.5L447.7,355.5z M471.4,272c-1.4,18.8-5.2,37-11.1,54.1l29.5,12.6 c7.5-21.1,12.2-43.5,13.6-66.8H471.4z M321.2,462c-15.7,5-32.2,8.2-49.2,9.4v32.1c21.2-1.4,41.7-5.4,61.1-11.7L321.2,462z M240,471.4c-18.8-1.4-37-5.2-54.1-11.1l-12.6,29.5c21.1,7.5,43.5,12.2,66.8,13.6V471.4z M462,190.8c5,15.7,8.2,32.2,9.4,49.2h32.1 c-1.4-21.2-5.4-41.7-11.7-61.1L462,190.8z M92.4,397c-12-13.9-22.3-29.4-30.4-46.1l-29.8,11.9c9.9,20.7,22.6,39.8,37.6,56.9 L92.4,397z M272,40.6c18.8,1.4,36.9,5.2,54.1,11.1l12.6-29.5C317.7,14.7,295.3,10,272,8.5V40.6z M190.8,50 c15.7-5,32.2-8.2,49.2-9.4V8.5c-21.2,1.4-41.7,5.4-61.1,11.7L190.8,50z M442.3,92.3L419.6,115c12,13.9,22.3,29.4,30.5,46.1 l29.8-11.9C470,128.5,457.3,109.4,442.3,92.3z M397,92.4l22.7-22.7c-15.6-13.7-32.8-25.5-51.5-34.9l-12.6,29.5 C370.4,72.1,384.4,81.5,397,92.4z"})});var a=i(i({},r),{},{attributeName:"opacity"}),o={tag:"circle",attributes:i(i({},n),{},{cx:"256",cy:"364",r:"28"}),children:[]};return e||o.children.push({tag:"animate",attributes:i(i({},r),{},{attributeName:"r",values:"28;14;28;28;14;28;"})},{tag:"animate",attributes:i(i({},a),{},{values:"1;0;1;1;0;1;"})}),t.push(o),t.push({tag:"path",attributes:i(i({},n),{},{opacity:"1",d:"M263.7,312h-16c-6.6,0-12-5.4-12-12c0-71,77.4-63.9,77.4-107.8c0-20-17.8-40.2-57.4-40.2c-29.1,0-44.3,9.6-59.2,28.7 c-3.9,5-11.1,6-16.2,2.4l-13.1-9.2c-5.6-3.9-6.9-11.8-2.6-17.2c21.2-27.2,46.4-44.7,91.2-44.7c52.3,0,97.4,29.8,97.4,80.2 c0,67.6-77.4,63.5-77.4,107.8C275.7,306.6,270.3,312,263.7,312z"}),children:e?[]:[{tag:"animate",attributes:i(i({},a),{},{values:"1;0;0;0;0;1;"})}]}),e||t.push({tag:"path",attributes:i(i({},n),{},{opacity:"0",d:"M232.5,134.5l7,168c0.3,6.4,5.6,11.5,12,11.5h9c6.4,0,11.7-5.1,12-11.5l7-168c0.3-6.8-5.2-12.5-12-12.5h-23 C237.7,122,232.2,127.7,232.5,134.5z"}),children:[{tag:"animate",attributes:i(i({},a),{},{values:"0;0;1;1;0;0;"})}]}),{tag:"g",attributes:{class:"missing"},children:t}}}};!function(t,e){var n=e.mixoutsTo;le=t,ue={},Object.keys(fe).forEach((function(t){-1===de.indexOf(t)&&delete fe[t]})),le.forEach((function(t){var e=t.mixout?t.mixout():{};if(Object.keys(e).forEach((function(t){"function"==typeof e[t]&&(n[t]=e[t]),"object"===s(e[t])&&Object.keys(e[t]).forEach((function(r){n[t]||(n[t]={}),n[t][r]=e[t][r]}))})),t.hooks){var r=t.hooks();Object.keys(r).forEach((function(t){ue[t]||(ue[t]=[]),ue[t].push(r[t])}))}t.provides&&t.provides(fe)}))}([Ot,tn,en,nn,rn,{hooks:function(){return{mutationObserverCallbacks:function(t){return t.pseudoElementsCallback=un,t}}},provides:function(t){t.pseudoElements2svg=function(t){var e=t.node,n=void 0===e?O:e;dt.searchPseudoElements&&un(n)}}},{mixout:function(){return{dom:{unwatch:function(){He(),fn=!0}}}},hooks:function(){return{bootstrap:function(){qe(pe("mutationObserverCallbacks",{}))},noAuto:function(){Ue&&Ue.disconnect()},watch:function(t){var e=t.observeMutationsRoot;fn?We():qe(pe("mutationObserverCallbacks",{observeMutationsRoot:e}))}}}},pn,gn,vn,{hooks:function(){return{parseNodeAttributes:function(t,e){var n=e.getAttribute("data-fa-symbol"),r=null!==n&&(""===n||n);return t.symbol=r,t}}}}],{mixoutsTo:ye});var bn=ye.library,yn=ye.parse,wn=ye.icon,kn=n(9417),xn=n(7326),Sn=n(4578),Cn=n(5697),Pn=n.n(Cn);function En(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,r)}return n}function On(t){for(var e=1;e=0||(a[n]=t[n]);return a}(t,e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(t);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(a[n]=t[n])}return a}function An(t){return function(t){if(Array.isArray(t))return Nn(t)}(t)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(t)||function(t,e){if(!t)return;if("string"==typeof t)return Nn(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);"Object"===n&&t.constructor&&(n=t.constructor.name);if("Map"===n||"Set"===n)return Array.from(t);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return Nn(t,e)}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function Nn(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,r=new Array(e);n0||!Array.isArray(e)&&e?Rn({},t,e):{}}var Zn=r.forwardRef((function(t,e){var n=t.icon,r=t.mask,a=t.symbol,o=t.className,i=t.title,s=t.titleId,c=t.maskId,l=Ln(n),u=In("classes",[].concat(An(function(t){var e,n=t.beat,r=t.fade,a=t.beatFade,o=t.bounce,i=t.shake,s=t.flash,c=t.spin,l=t.spinPulse,u=t.spinReverse,f=t.pulse,d=t.fixedWidth,p=t.inverse,m=t.border,h=t.listItem,g=t.flip,v=t.size,b=t.rotation,y=t.pull,w=(Rn(e={"fa-beat":n,"fa-fade":r,"fa-beat-fade":a,"fa-bounce":o,"fa-shake":i,"fa-flash":s,"fa-spin":c,"fa-spin-reverse":u,"fa-spin-pulse":l,"fa-pulse":f,"fa-fw":d,"fa-inverse":p,"fa-border":m,"fa-li":h,"fa-flip":!0===g,"fa-flip-horizontal":"horizontal"===g||"both"===g,"fa-flip-vertical":"vertical"===g||"both"===g},"fa-".concat(v),null!=v),Rn(e,"fa-rotate-".concat(b),null!=b&&0!==b),Rn(e,"fa-pull-".concat(y),null!=y),Rn(e,"fa-swap-opacity",t.swapOpacity),e);return Object.keys(w).map((function(t){return w[t]?t:null})).filter((function(t){return t}))}(t)),An(o.split(" ")))),f=In("transform","string"==typeof t.transform?yn.transform(t.transform):t.transform),d=In("mask",Ln(r)),p=wn(l,On(On(On(On({},u),f),d),{},{symbol:a,title:i,titleId:s,maskId:c}));if(!p)return function(){var t;!Mn&&console&&"function"==typeof console.error&&(t=console).error.apply(t,arguments)}("Could not find icon",l),null;var m=p.abstract,h={ref:e};return Object.keys(t).forEach((function(e){Zn.defaultProps.hasOwnProperty(e)||(h[e]=t[e])})),zn(m[0],h)}));Zn.displayName="FontAwesomeIcon",Zn.propTypes={beat:Pn().bool,border:Pn().bool,beatFade:Pn().bool,bounce:Pn().bool,className:Pn().string,fade:Pn().bool,flash:Pn().bool,mask:Pn().oneOfType([Pn().object,Pn().array,Pn().string]),maskId:Pn().string,fixedWidth:Pn().bool,inverse:Pn().bool,flip:Pn().oneOf([!0,!1,"horizontal","vertical","both"]),icon:Pn().oneOfType([Pn().object,Pn().array,Pn().string]),listItem:Pn().bool,pull:Pn().oneOf(["right","left"]),pulse:Pn().bool,rotation:Pn().oneOf([0,90,180,270]),shake:Pn().bool,size:Pn().oneOf(["2xs","xs","sm","lg","xl","2xl","1x","2x","3x","4x","5x","6x","7x","8x","9x","10x"]),spin:Pn().bool,spinPulse:Pn().bool,spinReverse:Pn().bool,symbol:Pn().oneOfType([Pn().bool,Pn().string]),title:Pn().string,titleId:Pn().string,transform:Pn().oneOfType([Pn().string,Pn().object]),swapOpacity:Pn().bool},Zn.defaultProps={border:!1,className:"",mask:null,maskId:null,fixedWidth:!1,inverse:!1,flip:!1,icon:null,listItem:!1,pull:null,pulse:!1,rotation:null,size:null,spin:!1,spinPulse:!1,spinReverse:!1,beat:!1,fade:!1,beatFade:!1,bounce:!1,shake:!1,symbol:!1,title:"",titleId:null,transform:null,swapOpacity:!1};var zn=function t(e,n){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};if("string"==typeof n)return n;var a=(n.children||[]).map((function(n){return t(e,n)})),o=Object.keys(n.attributes||{}).reduce((function(t,e){var r=n.attributes[e];switch(e){case"class":t.attrs.className=r,delete n.attributes.class;break;case"style":t.attrs.style=r.split(";").map((function(t){return t.trim()})).filter((function(t){return t})).reduce((function(t,e){var n,r=e.indexOf(":"),a=Tn(e.slice(0,r)),o=e.slice(r+1).trim();return a.startsWith("webkit")?t[(n=a,n.charAt(0).toUpperCase()+n.slice(1))]=o:t[a]=o,t}),{});break;default:0===e.indexOf("aria-")||0===e.indexOf("data-")?t.attrs[e.toLowerCase()]=r:t.attrs[Tn(e)]=r}return t}),{attrs:{}}),i=r.style,s=void 0===i?{}:i,c=jn(r,Dn);return o.attrs.style=On(On({},o.attrs.style),s),e.apply(void 0,[n.tag,On(On({},o.attrs),c)].concat(An(a)))}.bind(null,r.createElement),$n=n(6298);var Fn={name:"1cgv0ov",styles:"text-decoration:none;display:block;color:white;padding:0 0.5rem;text-transform:uppercase;font-size:11px;@media (min-width: 768px){&:hover,&:focus{background-color:#24890d;}}@media (max-width: 768px){&:hover,&:focus{color:#24890d;}}"},Hn={name:"1b17urv",styles:"float:left;background-color:black;@media (min-width: 768px){&:hover,&:focus{background-color:#24890d;}margin-right:1px;line-height:2.5rem;}@media (max-width: 768px){text-align:left;width:100%;margin:0;line-height:1rem;}"},Wn={name:"r23kmy",styles:"top:-9999px;left:-9999px"},Un={name:"1hwvnek",styles:"left:inherit;top:inherit"},qn={name:"le8hk",styles:"color:white;text-decoration:none;display:block;padding:12px 0.5rem;font-size:11px;text-transform:uppercase;@media (min-width: 768px){&:focus,&:hover{background-color:#41a62a;}}@media (max-width: 768px){padding:0.5rem 2rem;text-align:left;&:hover,&:focus{color:#24890d;}}"},Bn={name:"1ujf2y4",styles:"@media (min-width: 768px){line-height:12px;}line-height:6px"};function Yn(t){const{directoryName:e,data:n,menuExpanded:o}=t,[i,s]=r.useState(!1),[c,l]=r.useState(!1),u=r.useCallback((t=>{l(t.matches)}),[]),f=r.useCallback((()=>{s(!1)}),[]),d=r.useCallback((()=>{s(!0)}),[]);r.useEffect((()=>{const t=window.matchMedia("(max-width: 768px)");return u(t),t.addEventListener("change",u),()=>{t.removeEventListener("change",u)}}),[]);const p=r.useCallback(((t,e)=>e?(0,$n.tZ)("li",{key:t.id,css:Bn},(0,$n.tZ)(a.Link,{onFocus:d,onBlur:f,to:t.fields.slug,tabIndex:c&&!o?-1:0,css:qn},t.frontmatter.title)):null),[c,o,f,d]),m=i?Un:Wn;return(0,$n.tZ)("li",{onMouseEnter:d,onMouseLeave:f,css:Hn},(0,$n.tZ)(a.Link,{to:"/"+e,onFocus:d,onBlur:f,tabIndex:c&&!o?-1:0,"aria-haspopup":"true",css:Fn},e.replace(/-/g," ")),(0,$n.tZ)("ul",{css:(0,$n.iv)(m," width:10rem;list-style:none;padding:0;margin:0;background-color:#24890d;position:absolute;@media (max-width: 768px){background-color:black;position:static;display:block;text-align:center;width:100%;padding:10px 0;margin:0;line-height:1rem;}",""),"aria-label":e.replace(/-/g," ")+"-sub-menu"},n.allMarkdownRemark.edges.map((t=>{let{node:n}=t;return p(n,!n.fileAbsolutePath.includes(e+"/index.md")&&(n.fileAbsolutePath.includes(e+"/"+n.fileAbsolutePath.split("/").pop())||-1!==n.fileAbsolutePath.search(new RegExp("/"+e+"/[^/]+/index.md"))))}))))}var Qn=function(t){let{directoryName:e,menuExpanded:n}=t;const r=(0,a.useStaticQuery)("2186722355");return(0,$n.tZ)(Yn,{directoryName:e,data:r,menuExpanded:n})};var Jn={name:"15d84sg",styles:"border:none;background:none;cursor:pointer;display:none;width:2.5rem;height:2.5rem;text-align:center;color:white;line-height:2.5rem;@media (max-width: 768px){display:inline-block;}&:hover,&:focus{background-color:#939393;}"},Gn={name:"1tumana",styles:"position:absolute;top:-9999px;left:-9999px;&:focus{left:5px;top:5px;}background-color:#f1f1f1;color:#21759b;border-radius:3px;padding:15px;text-decoration:none;z-index:10000"},Vn={name:"15ly58l",styles:"float:right;margin:0;height:inherit"},Kn={name:"r23kmy",styles:"top:-9999px;left:-9999px"},Xn={name:"1ey6w9y",styles:"left:inherit;top:1.5rem"};let tr=function(t){function e(e){var n;return(n=t.call(this,e)||this).state={expanded:!1},n.handleClick=n.handleClick.bind((0,xn.Z)(n)),n.handleBlur=n.handleBlur.bind((0,xn.Z)(n)),n.handleFocus=n.handleFocus.bind((0,xn.Z)(n)),n}(0,Sn.Z)(e,t);var n=e.prototype;return n.handleBlur=function(){this.setState({expanded:!1})},n.handleFocus=function(){this.setState({expanded:!0})},n.handleClick=function(){this.setState((t=>({expanded:!t.expanded})))},n.render=function(){const{data:t}=this.props,{expanded:e}=this.state,n=e?Xn:Kn;return(0,$n.tZ)("nav",{css:Vn},(0,$n.tZ)("a",{href:"#content",css:Gn},"Skip to content"),(0,$n.tZ)("button",{onClick:this.handleClick,type:"button","aria-haspopup":"true","aria-expanded":e,css:Jn,"aria-controls":"main-menu"},(0,$n.tZ)(Zn,{icon:"bars",title:"Menu"})),(0,$n.tZ)("ul",{onBlur:this.handleBlur,onFocus:this.handleFocus,onMouseLeave:this.handleBlur,css:(0,$n.iv)("padding:0 0;list-style:none;display:inline;@media (max-width: 768px){",n," right:0px;position:absolute;padding:1px;background:#000;width:100%;}",""),"aria-label":"main-menu",id:"main-menu"},t.allDirectory.edges.map((t=>{let{node:n}=t;return(0,$n.tZ)(Qn,{directoryName:n.name,key:n.id,menuExpanded:e})}))))},e}(r.Component);function er(){const t=(0,a.useStaticQuery)("3212510956");return(0,$n.tZ)(tr,{data:t})}var nr=n(9463);var rr={name:"muocoq",styles:"width:350px;@media only screen and (max-width: 768px){width:100%;}"},ar={name:"6z3x9m",styles:"@media only screen and (min-width: 768px){float:right;}padding:0.5rem 1rem"},or={name:"1wzfm7",styles:"position:absolute;top:2.5em;left:185px;right:0;background-color:#41a62a;@media only screen and (max-width: 768px){left:0;}"},ir={name:"1wgt7nv",styles:"background-color:#24890d;float:right;&:hover,&:focus{background-color:#41a62a;}@media only screen and (max-width: 768px){margin-right:0;}border:none;cursor:pointer;display:inline-block;text-align:center;color:white;line-height:2.5rem;width:2.5rem;padding:0"},sr={name:"azezln",styles:"margin:0.3rem 1rem;color:white;float:left;text-decoration:none"},cr={name:"4ayqb",styles:"background:black;display:inline-block;width:100%;position:fixed;z-index:5;height:2.5rem;@media only screen and (max-width: 768px){position:absolute;}"};let lr=function(t){function e(e){var n;return(n=t.call(this,e)||this).state={searchVisible:!1},n.toggleSearch=n.toggleSearch.bind((0,xn.Z)(n)),n}(0,Sn.Z)(e,t);var n=e.prototype;return n.toggleSearch=function(t){t.preventDefault(),this.setState((t=>({searchVisible:!t.searchVisible})))},n.render=function(){const{siteTitle:t}=this.props,{searchVisible:e}=this.state;return(0,$n.tZ)("header",{css:cr},(0,$n.tZ)("h1",{style:{margin:0}},(0,$n.tZ)(a.Link,{to:"/",css:sr,"aria-label":"home"},t)),(0,$n.tZ)("button",{type:"button",css:ir,onClick:this.toggleSearch,"aria-label":"search","aria-haspopup":"true","aria-controls":"search-banner"},(0,$n.tZ)(Zn,{icon:"search",title:"Search"})),(0,$n.tZ)(er,null),e?(0,$n.tZ)("div",{id:"search-banner","aria-expanded":e,css:or},(0,$n.tZ)("form",{name:"header search form",role:"search",onSubmit:t=>{t.preventDefault()},css:ar},(0,$n.tZ)(nr.Z,{id:"header-search",inputCSS:rr}))):null)},e}(r.Component);lr.defaultProps={siteTitle:""};var ur=lr;function fr(t){let{styles:{ulStyle:e,liStyle:n,linkStyle:r,headerStyle:o}}=t;const i=(0,a.useStaticQuery)("4121107168");return(0,$n.tZ)("nav",{"aria-label":"recent meetings"},(0,$n.tZ)("h5",{css:(0,$n.iv)(o,";","")},"Recent Meetings"),(0,$n.tZ)("ul",{css:(0,$n.iv)(e,";","")},i.allMarkdownRemark.edges.map((t=>{let{node:e}=t;return(0,$n.tZ)("li",{key:e.id,css:(0,$n.iv)(n,";","")},(0,$n.tZ)(a.Link,{css:(0,$n.iv)(r,";",""),to:e.fields.slug},e.frontmatter.title))}))))}var dr=fr;async function pr(){const t=[];return await fetch("https://api.github.com/orgs/icatproject/repos?sort=updated").then((async e=>{const n=(await e.json()).map((e=>async function(t){const e=t.commits_url.split("{");return fetch(e[0]).then((async e=>{const n=await e.json();if(0===n.length)return null;const r=n[0];return{name:t.name,url:r.html_url,date:r.commit.author.date}})).catch((t=>(console.warn("Error "+t),null)))}(e).then((e=>{null!==e&&t.push(e)})).catch((()=>console.warn("Failed to retrieve commit for "+e)))));await Promise.all(n)})).catch((t=>(console.warn("Error "+t),[]))),t}fr.defaultProps={styles:{liStyle:{},ulStyle:{},linkStyle:{},headerStyle:{}}};const mr=36e5;function hr(t){let{styles:{ulStyle:e,liStyle:n,linkStyle:a,headerStyle:o}}=t;const[i,s]=r.useState(null);return r.useEffect((()=>{!async function(){const t=localStorage.getItem("recentCommitsFetchTime"),e=localStorage.getItem("recentCommits");var n;if(null!==t&&null!==e&&(n=new Date(t),(new Date).valueOf()-n.valueOf()new Date(e.date)-new Date(t.date))),localStorage.setItem("recentCommits",JSON.stringify(t)),localStorage.setItem("recentCommitsFetchTime",new Date),s(t)}}()}),[]),(0,$n.tZ)("div",null,(0,$n.tZ)("nav",{"aria-label":"recent commits"},(0,$n.tZ)("h5",{css:(0,$n.iv)(o,";","")},"Recent Commits"),(0,$n.tZ)("ul",{css:(0,$n.iv)(e,";","")},null===i?(0,$n.tZ)("li",{css:(0,$n.iv)(n,";","")},"Loading..."):i.slice(0,10).map((t=>(0,$n.tZ)("li",{css:(0,$n.iv)(n,";",""),key:t.name},(0,$n.tZ)("a",{css:(0,$n.iv)(a,";",""),href:t.url},t.name)))))))}var gr=hr;hr.defaultProps={styles:{liStyle:{},ulStyle:{},linkStyle:{},headerStyle:{}}};const vr={name:"1fblz9e",styles:"text-decoration:none;color:white;&:hover{color:green;}"},br={name:"vqx3x2",styles:"margin-bottom:5px"},yr={name:"w9mbx4",styles:"list-style:none;padding:0;margin:0;font-size:11px"},wr={name:"1ee42c1",styles:"margin:12px 0"};var kr={name:"1k0t4vh",styles:"width:90%"},xr={name:"1mvc4ia",styles:"background-color:black;color:white;width:175px;float:left;margin-top:2rem;margin-bottom:-100%;min-height:100vh;position:fixed;z-index:3;padding-left:10px;@media only screen and (max-width: 768px){display:none;}"};function Sr(){return(0,$n.tZ)("div",{css:xr},(0,$n.tZ)("form",{name:"sidebar search form",role:"search",onSubmit:t=>{t.preventDefault()}},(0,$n.tZ)("h5",{css:(0,$n.iv)(wr,";","")},"Search"),(0,$n.tZ)(nr.Z,{id:"sidebar-search",inputCSS:kr})),(0,$n.tZ)(dr,{styles:{linkStyle:vr,liStyle:br,ulStyle:yr,headerStyle:wr}}),(0,$n.tZ)("nav",{"aria-label":"quick links"},(0,$n.tZ)("h5",{css:(0,$n.iv)(wr,";","")},"Links"),(0,$n.tZ)("ul",{css:(0,$n.iv)(yr,";","")},(0,$n.tZ)("li",{css:(0,$n.iv)(br,";","")},(0,$n.tZ)("a",{css:(0,$n.iv)(vr,";",""),href:"http://groups.google.com/group/icatgroup"},"icatgroup")),(0,$n.tZ)("li",{css:(0,$n.iv)(br,";","")},(0,$n.tZ)("a",{css:(0,$n.iv)(vr,";",""),href:"https://repo.icatproject.org/"},"repo.icatproject.org")),(0,$n.tZ)("li",{css:(0,$n.iv)(br,";","")},(0,$n.tZ)(a.Link,{to:"/about/useful-links",css:(0,$n.iv)(vr,";","")},"Useful Links")),(0,$n.tZ)("li",{css:(0,$n.iv)(br,";","")},(0,$n.tZ)("a",{css:(0,$n.iv)(vr,";",""),href:"https://github.com/icatproject"},"Github for icatproject")),(0,$n.tZ)("li",{css:(0,$n.iv)(br,";","")},(0,$n.tZ)("a",{css:(0,$n.iv)(vr,";",""),href:"https://github.com/icatproject-contrib"},"Github for icatproject-contrib")))),(0,$n.tZ)(gr,{styles:{linkStyle:vr,liStyle:br,ulStyle:yr,headerStyle:wr}}))}bn.add(kn.wn1),bn.add(kn.xiG);var Cr={name:"18r85yc",styles:"margin-top:70px;margin-left:300px;margin-bottom:1.5em;margin-right:100px;float:left;@media only screen and (max-width: 768px){margin-right:10px;margin-left:10px;}"},Pr={name:"ti75j2",styles:"margin:0"};var Er=function(t){let{children:e}=t;const n=(0,a.useStaticQuery)("3649515864");return(0,$n.tZ)(r.Fragment,null,(0,$n.tZ)(ur,{siteTitle:n.site.siteMetadata.title}),(0,$n.tZ)("div",{css:Pr},(0,$n.tZ)(Sr,null),(0,$n.tZ)("main",{id:"content",css:Cr},e)))}},9463:function(t,e,n){"use strict";n.d(e,{Z:function(){return c}});var r=n(7326),a=n(4578),o=n(7294),i=n(4854),s=n(6298);let c=function(t){function e(e){var n;return(n=t.call(this,e)||this).state={query:""},n.handleChange=n.handleChange.bind((0,r.Z)(n)),n}(0,a.Z)(e,t),e.handleKeyPress=function(t){if("Enter"===t.key){const e=t.target.value;(0,i.navigate)("/search?query="+e)}};var n=e.prototype;return n.handleChange=function(t){this.setState({query:t.target.value})},n.render=function(){const{id:t,inputCSS:n}=this.props,{query:r}=this.state;return(0,s.tZ)("label",{htmlFor:t},(0,s.tZ)("span",{className:"screen-reader-text"},"Search: "),(0,s.tZ)("input",{id:t,title:"Search",type:"search",role:"searchbox",value:r,onKeyPress:e.handleKeyPress,onChange:this.handleChange,placeholder:"Search...",css:n}))},e}(o.Component);c.defaultProps={inputCSS:{name:"searchbar",styles:""}}},8679:function(t,e,n){"use strict";var r=n(9864),a={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},o={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},i={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},s={};function c(t){return r.isMemo(t)?i:s[t.$$typeof]||a}s[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},s[r.Memo]=i;var l=Object.defineProperty,u=Object.getOwnPropertyNames,f=Object.getOwnPropertySymbols,d=Object.getOwnPropertyDescriptor,p=Object.getPrototypeOf,m=Object.prototype;t.exports=function t(e,n,r){if("string"!=typeof n){if(m){var a=p(n);a&&a!==m&&t(e,a,r)}var i=u(n);f&&(i=i.concat(f(n)));for(var s=c(e),h=c(n),g=0;g((t,e)=>{const{forward:n=[],...r}=t||{},a=JSON.stringify(r,((t,e)=>("function"==typeof e&&(e=String(e)).startsWith(t+"(")&&(e="function "+e),e)));return["!(function(w,p,f,c){",Object.keys(r).length>0?`c=w[p]=Object.assign(w[p]||{},${a});`:"c=w[p]=w[p]||{};","c[f]=(c[f]||[])",n.length>0?`.concat(${JSON.stringify(n)})`:"","})(window,'partytown','forward');",e].join("")})(t,'/* Partytown 0.7.6 - MIT builder.io */\n!function(t,e,n,i,r,o,a,d,s,c,p,l){function u(){l||(l=1,"/"==(a=(o.lib||"/~partytown/")+(o.debug?"debug/":""))[0]&&(s=e.querySelectorAll(\'script[type="text/partytown"]\'),i!=t?i.dispatchEvent(new CustomEvent("pt1",{detail:t})):(d=setTimeout(f,1e4),e.addEventListener("pt0",w),r?h(1):n.serviceWorker?n.serviceWorker.register(a+(o.swPath||"partytown-sw.js"),{scope:a}).then((function(t){t.active?h():t.installing&&t.installing.addEventListener("statechange",(function(t){"activated"==t.target.state&&h()}))}),console.error):f())))}function h(t){c=e.createElement(t?"script":"iframe"),t||(c.setAttribute("style","display:block;width:0;height:0;border:0;visibility:hidden"),c.setAttribute("aria-hidden",!0)),c.src=a+"partytown-"+(t?"atomics.js?v=0.7.6":"sandbox-sw.html?"+Date.now()),e.body.appendChild(c)}function f(n,r){for(w(),i==t&&(o.forward||[]).map((function(e){delete t[e.split(".")[0]]})),n=0;nt.length)&&(e=t.length);for(var n=0,r=new Array(e);n=0||(a[n]=t[n]);return a}const l=t=>{const{search:e,hash:n,href:r,origin:a,protocol:o,host:i,hostname:s,port:c}=t.location;let{pathname:l}=t.location;return!l&&r&&d&&(l=new URL(r).pathname),{pathname:encodeURI(decodeURI(l)),search:e,hash:n,href:r,origin:a,protocol:o,host:i,hostname:s,port:c,state:t.history.state,key:t.history.state&&t.history.state.key||"initial"}},u=(t,e)=>{let n=[],r=l(t),a=!1,o=()=>{};return{get location(){return r},get transitioning(){return a},_onTransitionComplete(){a=!1,o()},listen(e){n.push(e);const a=()=>{r=l(t),e({location:r,action:"POP"})};return t.addEventListener("popstate",a),()=>{t.removeEventListener("popstate",a),n=n.filter((t=>t!==e))}},navigate(e,{state:i,replace:c=!1}={}){if("number"==typeof e)t.history.go(e);else{i=s({},i,{key:Date.now()+""});try{a||c?t.history.replaceState(i,null,e):t.history.pushState(i,null,e)}catch(n){t.location[c?"replace":"assign"](e)}}r=l(t),a=!0;const u=new Promise((t=>o=t));return n.forEach((t=>t({location:r,action:"PUSH"}))),u}}},f=(t="/")=>{const e=t.indexOf("?"),n={pathname:e>-1?t.substr(0,e):t,search:e>-1?t.substr(e):""};let r=0;const a=[n],o=[null];return{get location(){return a[r]},addEventListener(t,e){},removeEventListener(t,e){},history:{get entries(){return a},get index(){return r},get state(){return o[r]},pushState(t,e,n){const[i,s=""]=n.split("?");r++,a.push({pathname:i,search:s.length?`?${s}`:s}),o.push(t)},replaceState(t,e,n){const[i,s=""]=n.split("?");a[r]={pathname:i,search:s},o[r]=t},go(t){const e=r+t;e<0||e>o.length-1||(r=e)}}}},d=!("undefined"==typeof window||!window.document||!window.document.createElement),p=u(d?window:f()),{navigate:m}=p;function h(t,e){return a.createServerContext?((t,e=null)=>(globalThis.__SERVER_CONTEXT||(globalThis.__SERVER_CONTEXT={}),globalThis.__SERVER_CONTEXT[t]||(globalThis.__SERVER_CONTEXT[t]=a.createServerContext(t,e)),globalThis.__SERVER_CONTEXT[t]))(t,e):a.createContext(e)}const g=h("Base",{baseuri:"/",basepath:"/"}),v=h("Location"),b=()=>a.useContext(g),y=()=>a.useContext(v);function w(t){this.uri=t}const k=t=>t instanceof w,x=t=>{throw new w(t)};function S(t){const{to:e,replace:n=!0,state:r,noThrow:o,baseuri:i}=t;a.useEffect((()=>{Promise.resolve().then((()=>{const a=_(e,i);m(R(a,t),{replace:n,state:r})}))}),[]);const s=_(e,i);return o||x(R(s,t)),null}const C=t=>{const e=y(),{baseuri:n}=b();return a.createElement(S,s({},e,{baseuri:n},t))};C.propTypes={from:o.string,to:o.string.isRequired};const P=(t,e)=>t.substr(0,e.length)===e,E=(t,e)=>{let n,r;const[a]=e.split("?"),o=L(a),s=""===o[0],c=M(t);for(let l=0,u=c.length;l dynamic segment "${r[1]}" is a reserved name. Please use a different name in path "${a.path}".`);const e=decodeURIComponent(n);f[r[1]]=e}else if(e!==n){t=!0;break}}if(!t){n={route:a,params:f,uri:"/"+o.slice(0,p).join("/")};break}}return n||r||null},O=(t,e)=>E([{path:t}],e),_=(t,e)=>{if(P(t,"/"))return t;const[n,r]=t.split("?"),[a]=e.split("?"),o=L(n),i=L(a);if(""===o[0])return I(a,r);if(!P(o[0],".")){const t=i.concat(o).join("/");return I(("/"===a?"":"/")+t,r)}const s=i.concat(o),c=[];for(let l=0,u=s.length;l{const[n,r=""]=t.split("?");let a="/"+L(n).map((t=>{const n=A.exec(t);return n?e[n[1]]:t})).join("/");const{location:{search:o=""}={}}=e,i=o.split("?")[1]||"";return a=I(a,r,i),a},j=(t,e)=>{const n=t=>N(t);return L(t).filter(n).sort().join("/")===L(e).filter(n).sort().join("/")},A=/^:(.+)/,N=t=>A.test(t),T=t=>t&&"*"===t[0],D=(t,e)=>({route:t,score:t.default?0:L(t.path).reduce(((t,e)=>(t+=4,(t=>""===t)(e)?t+=1:N(e)?t+=2:T(e)?t-=5:t+=3,t)),0),index:e}),M=t=>t.map(D).sort(((t,e)=>t.scoree.score?-1:t.index-e.index)),L=t=>t.replace(/(^\/+|\/+$)/g,"").split("/"),I=(t,...e)=>t+((e=e.filter((t=>t&&t.length>0)))&&e.length>0?`?${e.join("&")}`:""),Z=["uri","path"],z=(t,e)=>{const n=Object.keys(t);return n.length===Object.keys(e).length&&n.every((n=>e.hasOwnProperty(n)&&t[n]===e[n]))},$=t=>t.replace(/(^\/+|\/+$)/g,""),F=t=>e=>{if(!e)return null;if(e.type===a.Fragment&&e.props.children)return a.Children.map(e.props.children,F(t));if(i(e.props.path||e.props.default||e.type===C,`: Children of must have a \`path\` or \`default\` prop, or be a \`\`. None found on element type \`${e.type}\``),i(!!(e.type!==C||e.props.from&&e.props.to),` requires both "from" and "to" props when inside a .`),i(!(e.type===C&&!j(e.props.from,e.props.to)),` has mismatched dynamic segments, ensure both paths have the exact same dynamic segments.`),e.props.default)return{value:e,default:!0};const n=e.type===C?e.props.from:e.props.path,r="/"===n?t:`${$(t)}/${$(n)}`;return{value:e,default:e.props.default,path:e.props.children?`${$(r)}/*`:r}},H=["innerRef"],W=["to","state","replace","getProps"],U=["key"];let{forwardRef:q}=r||(r=n.t(a,2));void 0===q&&(q=t=>t);const B=()=>{},Y=q(((t,e)=>{let{innerRef:n}=t,r=c(t,H);const{baseuri:o}=b(),{location:i}=y(),{to:l,state:u,replace:f,getProps:d=B}=r,p=c(r,W),h=_(l,o),g=encodeURI(h),v=i.pathname===g,w=P(i.pathname,g);return a.createElement("a",s({ref:e||n,"aria-current":v?"page":void 0},p,d({isCurrent:v,isPartiallyCurrent:w,href:h,location:i}),{href:h,onClick:t=>{if(p.onClick&&p.onClick(t),(t=>!t.defaultPrevented&&0===t.button&&!(t.metaKey||t.altKey||t.ctrlKey||t.shiftKey))(t)){t.preventDefault();let e=f;if("boolean"!=typeof f&&v){const t=c(s({},i.state),U);e=z(s({},u),t)}m(h,{state:u,replace:e})}}}))}));Y.displayName="Link",Y.propTypes={to:o.string.isRequired};class Q extends a.Component{constructor(...t){super(...t),this.displayName="ReactUseErrorBoundary"}componentDidCatch(...t){this.setState({}),this.props.onError(...t)}render(){return this.props.children}}const J=a.createContext({componentDidCatch:{current:void 0},error:void 0,setError:()=>!1});function G({children:t}){const[e,n]=a.useState(),r=a.useRef(),o=a.useMemo((()=>({componentDidCatch:r,error:e,setError:n})),[e]);return a.createElement(J.Provider,{value:o},a.createElement(Q,{error:e,onError:(t,e)=>{n(t),null==r.current||r.current(t,e)}},t))}G.displayName="ReactUseErrorBoundaryContext";const V=function(t){var e,n;function r(e){return a.createElement(G,null,a.createElement(t,s({key:"WrappedComponent"},e)))}return r.displayName=`WithErrorBoundary(${null!=(e=null!=(n=t.displayName)?n:t.name)?e:"Component"})`,r}((({history:t=p,children:e})=>{const{location:n}=t,[r,o]=a.useState({location:n}),[i]=function(t){const e=a.useContext(J);e.componentDidCatch.current=void 0;const n=a.useCallback((()=>{e.setError(void 0)}),[]);return[e.error,n]}();if(a.useEffect((()=>{t._onTransitionComplete()}),[r.location]),a.useEffect((()=>{let e=!1;const n=t.listen((({location:t})=>{Promise.resolve().then((()=>{requestAnimationFrame((()=>{e||o({location:t})}))}))}));return()=>{e=!0,n()}}),[]),i){if(!k(i))throw i;m(i.uri,{replace:!0})}return a.createElement(v.Provider,{value:r},"function"==typeof e?e(r):e||null)})),K=({children:t})=>{const e=y();return e?t(e):a.createElement(V,null,t)},X=({url:t,children:e})=>{const n=t.indexOf("?");let r,o="";return n>-1?(r=t.substring(0,n),o=t.substring(n)):r=t,a.createElement(v.Provider,{value:{location:{pathname:r,search:o,hash:""}}},e)},tt=({path:t,children:e})=>{const{baseuri:n}=b(),{location:r}=y(),a=_(t,n),o=O(a,r.pathname);return e({location:r,match:o?s({},o.params,{uri:o.uri,path:t}):null})},et=["uri","location","component"],nt=["children","style","component","uri","location"],rt=t=>{let{uri:e,location:n,component:r}=t,o=c(t,et);return a.createElement(ot,s({},o,{component:r,uri:e,location:n}))};let at=0;const ot=t=>{let{children:e,style:n,component:r="div",uri:o,location:i}=t,l=c(t,nt);const u=a.useRef(),f=a.useRef(!0),d=a.useRef(o),p=a.useRef(i.pathname),m=a.useRef(!1);a.useEffect((()=>(at++,h(),()=>{at--,0===at&&(f.current=!0)})),[]),a.useEffect((()=>{let t=!1,e=!1;o!==d.current&&(d.current=o,t=!0),i.pathname!==p.current&&(p.current=i.pathname,e=!0),m.current=t||e&&i.pathname===o,m.current&&h()}),[o,i]);const h=a.useCallback((()=>{var t;f.current?f.current=!1:(t=u.current,m.current&&t&&t.focus())}),[]);return a.createElement(r,s({style:s({outline:"none"},n),tabIndex:"-1",ref:u},l),e)},it=["location","primary","children","basepath","baseuri","component"],st=t=>{const e=b(),n=y();return a.createElement(ct,s({},e,n,t))};function ct(t){const{location:e,primary:n=!0,children:r,basepath:o,component:i="div"}=t,l=c(t,it),u=a.Children.toArray(r).reduce(((t,e)=>{const n=F(o)(e);return t.concat(n)}),[]),{pathname:f}=e,d=E(u,f);if(d){const{params:t,uri:r,route:c,route:{value:u}}=d,f=c.default?o:c.path.replace(/\*$/,""),p=s({},t,{uri:r,location:e}),m=a.cloneElement(u,p,u.props.children?a.createElement(st,{location:e,primary:n},u.props.children):void 0),h=n?rt:i,v=n?s({uri:r,location:e,component:i},l):l;return a.createElement(g.Provider,{value:{baseuri:r,basepath:f}},a.createElement(h,v,m))}return null}const lt=()=>{const t=y();if(!t)throw new Error("useLocation hook was used but a LocationContext.Provider was not found in the parent tree. Make sure this is used in a component that is a child of Router");return t.location},ut=()=>{throw new Error("useNavigate is removed. Use import { navigate } from 'gatsby' instead")},ft=()=>{const t=b();if(!t)throw new Error("useParams hook was used but a LocationContext.Provider was not found in the parent tree. Make sure this is used in a component that is a child of Router");const e=lt(),n=O(t.basepath,e.pathname);return n?n.params:null},dt=t=>{if(!t)throw new Error("useMatch(path: string) requires an argument of a string to match against");const e=b();if(!e)throw new Error("useMatch hook was used but a LocationContext.Provider was not found in the parent tree. Make sure this is used in a component that is a child of Router");const n=lt(),r=_(t,e.baseuri),a=O(r,n.pathname);return a?s({},a.params,{uri:a.uri,path:t}):null}},1562:function(t,e,n){"use strict";n.d(e,{c4:function(){return S},cP:function(){return c},dq:function(){return p},mc:function(){return b},rU:function(){return x}});var r=n(5697),a=n(7294),o=n(7896),i=n(4506);function s(){return s=Object.assign?Object.assign.bind():function(t){for(var e=1;e{if("string"==typeof t)return!(t=>l.test(t))(t)},f=()=>"",d=()=>"";function p(t,e=f()){var n;if(!u(t))return t;if(t.startsWith("./")||t.startsWith("../"))return t;const r=null!=(n=null!=e?e:d())?n:"/";return`${null!=r&&r.endsWith("/")?r.slice(0,-1):r}${t.startsWith("/")?t:`/${t}`}`}const m=t=>null==t?void 0:t.startsWith("/");function h(t,e){const{pathname:n,search:r,hash:a}=c(t);return`${(0,i.H)(n,e)}${r}${a}`}const g=(t,e)=>"number"==typeof t?t:u(t)?m(t)?function(t){const e=p(t),n="always";return h(e,n)}(t):function(t,e){if(m(t))return t;const n="always",r=(0,o.resolve)(t,e);return h(r,n)}(t,e):t,v=["to","getProps","onClick","onMouseEnter","activeClassName","activeStyle","innerRef","partiallyActive","state","replace","_location"];function b(t){return p(t,d())}const y={activeClassName:r.string,activeStyle:r.object,partiallyActive:r.bool};function w(t){return a.createElement(o.Location,null,(({location:e})=>a.createElement(k,s({},t,{_location:e}))))}class k extends a.Component{constructor(t){super(t),this.defaultGetProps=({isPartiallyCurrent:t,isCurrent:e})=>(this.props.partiallyActive?t:e)?{className:[this.props.className,this.props.activeClassName].filter(Boolean).join(" "),style:s({},this.props.style,this.props.activeStyle)}:null;let e=!1;"undefined"!=typeof window&&window.IntersectionObserver&&(e=!0),this.state={IOSupported:e},this.abortPrefetch=null,this.handleRef=this.handleRef.bind(this)}_prefetch(){let t=window.location.pathname+window.location.search;this.props._location&&this.props._location.pathname&&(t=this.props._location.pathname+this.props._location.search);const e=c(g(this.props.to,t)),n=e.pathname+e.search;if(t!==n)return ___loader.enqueue(n)}componentWillUnmount(){if(!this.io)return;const{instance:t,el:e}=this.io;this.abortPrefetch&&this.abortPrefetch.abort(),t.unobserve(e),t.disconnect()}handleRef(t){this.props.innerRef&&Object.prototype.hasOwnProperty.call(this.props.innerRef,"current")?this.props.innerRef.current=t:this.props.innerRef&&this.props.innerRef(t),this.state.IOSupported&&t&&(this.io=((t,e)=>{const n=new window.IntersectionObserver((n=>{n.forEach((n=>{t===n.target&&e(n.isIntersecting||n.intersectionRatio>0)}))}));return n.observe(t),{instance:n,el:t}})(t,(t=>{t?this.abortPrefetch=this._prefetch():this.abortPrefetch&&this.abortPrefetch.abort()})))}render(){const t=this.props,{to:e,getProps:n=this.defaultGetProps,onClick:r,onMouseEnter:i,state:l,replace:f,_location:d}=t,p=function(t,e){if(null==t)return{};var n,r,a={},o=Object.keys(t);for(r=0;r=0||(a[n]=t[n]);return a}(t,v),m=g(e,d.pathname);return u(m)?a.createElement(o.Link,s({to:m,state:l,getProps:n,innerRef:this.handleRef,onMouseEnter:t=>{i&&i(t);const e=c(m);___loader.hovering(e.pathname+e.search)},onClick:t=>{if(r&&r(t),!(0!==t.button||this.props.target||t.defaultPrevented||t.metaKey||t.altKey||t.ctrlKey||t.shiftKey)){t.preventDefault();let e=f;const n=encodeURI(m)===d.pathname;"boolean"!=typeof f&&n&&(e=!0),window.___navigate(m,{state:l,replace:e})}return!0}},p)):a.createElement("a",s({href:m},p))}}k.propTypes=s({},y,{onClick:r.func,to:r.string.isRequired,replace:r.bool,state:r.object});const x=a.forwardRef(((t,e)=>a.createElement(w,s({innerRef:e},t)))),S=(t,e)=>{window.___navigate(g(t,window.location.pathname),e)}},3521:function(t,e,n){"use strict";n.r(e),n.d(e,{Script:function(){return m},ScriptStrategy:function(){return l},collectedScriptsByPage:function(){return s},scriptCache:function(){return d},scriptCallbackCache:function(){return p}});var r=n(7294),a=n(7896);function o(){return o=Object.assign?Object.assign.bind():function(t){for(var e=1;ei.get(t)||[],set(t,e){const n=i.get(t)||[];n.push(e),i.set(t,n)},delete(t){i.delete(t)}},c="undefined"!=typeof self&&self.requestIdleCallback&&self.requestIdleCallback.bind(window)||function(t){const e=Date.now();return setTimeout((function(){t({didTimeout:!1,timeRemaining:function(){return Math.max(0,50-(Date.now()-e))}})}),1)};var l,u;(u=l||(l={})).postHydrate="post-hydrate",u.idle="idle",u.offMainThread="off-main-thread";const f=new Set(["src","strategy","dangerouslySetInnerHTML","children","onLoad","onError"]),d=new Set,p=new Map;function m(t){return r.createElement(a.Location,null,(()=>r.createElement(h,t)))}function h(t){const{src:e,strategy:n=l.postHydrate}=t||{},{pathname:i}=(0,a.useLocation)();if((0,r.useEffect)((()=>{let e;switch(n){case l.postHydrate:e=g(t);break;case l.idle:c((()=>{e=g(t)}));break;case l.offMainThread:{const e=b(t);s.set(i,e)}}return()=>{const{script:t,loadCallback:n,errorCallback:r}=e||{};n&&(null==t||t.removeEventListener("load",n)),r&&(null==t||t.removeEventListener("error",r)),null==t||t.remove()}}),[]),n===l.offMainThread){const a=v(t),c=b(t);return"undefined"==typeof window&&s.set(i,c),r.createElement("script",a?o({type:"text/partytown","data-strategy":n,crossOrigin:"anonymous"},c,{dangerouslySetInnerHTML:{__html:v(t)}}):o({type:"text/partytown",src:y(e),"data-strategy":n,crossOrigin:"anonymous"},c))}return null}function g(t){const{id:e,src:n,strategy:r=l.postHydrate,onLoad:a,onError:i}=t||{},s=e||n,c=["load","error"],u={load:a,error:i};if(s){for(const t of c)if(null!=u&&u[t]){var f;const e=p.get(s)||{},{callbacks:n=[]}=(null==e?void 0:e[t])||{};var m,h;n.push(null==u?void 0:u[t]),null!=e&&null!=(f=e[t])&&f.event?null==u||null==(m=u[t])||m.call(u,null==e||null==(h=e[t])?void 0:h.event):p.set(s,o({},e,{[t]:{callbacks:n}}))}if(d.has(s))return null}const g=v(t),y=b(t),k=document.createElement("script");e&&(k.id=e),k.dataset.strategy=r;for(const[o,l]of Object.entries(y))k.setAttribute(o,l);g&&(k.textContent=g),n&&(k.src=n);const x={};if(s){for(const t of c){const e=e=>w(e,s,t);k.addEventListener(t,e),x[`${t}Callback`]=e}d.add(s)}return document.body.appendChild(k),{script:k,loadCallback:x.loadCallback,errorCallback:x.errorCallback}}function v(t){const{dangerouslySetInnerHTML:e,children:n=""}=t||{},{__html:r=""}=e||{};return r||n}function b(t){const e={};for(const[n,r]of Object.entries(t))f.has(n)||(e[n]=r);return e}function y(t){if(t)return`/__third-party-proxy?url=${encodeURIComponent(t)}`}function w(t,e,n){const r=p.get(e)||{};for(const o of(null==r||null==(a=r[n])?void 0:a.callbacks)||[]){var a;o(t)}p.set(e,{[n]:{event:t}})}}},function(t){t.O(0,[774,532,976],(function(){return e=5824,t(t.s=e);var e}));t.O()}]); +//# sourceMappingURL=app-e5500d896c7951a9bdcd.js.map \ No newline at end of file diff --git a/app-e5500d896c7951a9bdcd.js.LICENSE.txt b/app-e5500d896c7951a9bdcd.js.LICENSE.txt new file mode 100644 index 000000000..ef4a917d0 --- /dev/null +++ b/app-e5500d896c7951a9bdcd.js.LICENSE.txt @@ -0,0 +1,18 @@ +/** + * @license React + * react-server-dom-webpack.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** @license React v16.13.1 + * react-is.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ diff --git a/app-e5500d896c7951a9bdcd.js.map b/app-e5500d896c7951a9bdcd.js.map new file mode 100644 index 000000000..b0c2ff85f --- /dev/null +++ b/app-e5500d896c7951a9bdcd.js.map @@ -0,0 +1 @@ +{"version":3,"file":"app-e5500d896c7951a9bdcd.js","mappings":"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","sources":["webpack://icatproject.github.io/./node_modules/@emotion/sheet/dist/emotion-sheet.browser.esm.js","webpack://icatproject.github.io/./node_modules/stylis/src/Utility.js","webpack://icatproject.github.io/./node_modules/stylis/src/Tokenizer.js","webpack://icatproject.github.io/./node_modules/stylis/src/Enum.js","webpack://icatproject.github.io/./node_modules/stylis/src/Serializer.js","webpack://icatproject.github.io/./node_modules/stylis/src/Parser.js","webpack://icatproject.github.io/./node_modules/@emotion/cache/dist/emotion-cache.browser.esm.js","webpack://icatproject.github.io/./node_modules/stylis/src/Middleware.js","webpack://icatproject.github.io/./node_modules/@emotion/utils/dist/emotion-utils.browser.esm.js","webpack://icatproject.github.io/./node_modules/@emotion/unitless/dist/emotion-unitless.esm.js","webpack://icatproject.github.io/./node_modules/@emotion/memoize/dist/emotion-memoize.esm.js","webpack://icatproject.github.io/./node_modules/@emotion/serialize/dist/emotion-serialize.browser.esm.js","webpack://icatproject.github.io/./node_modules/@emotion/hash/dist/emotion-hash.esm.js","webpack://icatproject.github.io/./node_modules/@emotion/use-insertion-effect-with-fallbacks/dist/emotion-use-insertion-effect-with-fallbacks.browser.esm.js","webpack://icatproject.github.io/./node_modules/@emotion/react/dist/emotion-element-c39617d8.browser.esm.js","webpack://icatproject.github.io/./node_modules/@emotion/react/dist/emotion-react.browser.esm.js","webpack://icatproject.github.io/./node_modules/gatsby-page-utils/dist/apply-trailing-slash-option.js","webpack://icatproject.github.io/./node_modules/gatsby-react-router-scroll/index.js","webpack://icatproject.github.io/./node_modules/gatsby-react-router-scroll/scroll-handler.js","webpack://icatproject.github.io/./node_modules/gatsby-react-router-scroll/session-storage.js","webpack://icatproject.github.io/./node_modules/gatsby-react-router-scroll/use-scroll-restoration.js","webpack://icatproject.github.io/./node_modules/gatsby/dist/internal-plugins/partytown/gatsby-browser.js","webpack://icatproject.github.io/./node_modules/gatsby/dist/internal-plugins/partytown/utils/get-forwards.js","webpack://icatproject.github.io/./node_modules/gatsby/dist/internal-plugins/partytown/utils/inject-partytown-snippet.js","webpack://icatproject.github.io/./.cache/_this_is_virtual_fs_path_/$virtual/async-requires.js","webpack://icatproject.github.io/./.cache/api-runner-browser-plugins.js","webpack://icatproject.github.io/./.cache/api-runner-browser.js","webpack://icatproject.github.io/./.cache/create-content-digest-browser-shim.js","webpack://icatproject.github.io/./.cache/emitter.js","webpack://icatproject.github.io/./node_modules/mitt/dist/mitt.es.js","webpack://icatproject.github.io/./.cache/normalize-page-path.js","webpack://icatproject.github.io/./.cache/find-path.js","webpack://icatproject.github.io/./node_modules/@babel/runtime/helpers/esm/getPrototypeOf.js","webpack://icatproject.github.io/./node_modules/@babel/runtime/helpers/esm/construct.js","webpack://icatproject.github.io/./node_modules/@babel/runtime/helpers/esm/isNativeReflectConstruct.js","webpack://icatproject.github.io/./node_modules/@babel/runtime/helpers/esm/wrapNativeSuper.js","webpack://icatproject.github.io/./node_modules/@babel/runtime/helpers/esm/isNativeFunction.js","webpack://icatproject.github.io/./.cache/slice/server-slice-renderer.js","webpack://icatproject.github.io/./.cache/slice/server-slice.js","webpack://icatproject.github.io/./.cache/slice/inline-slice.js","webpack://icatproject.github.io/./.cache/slice.js","webpack://icatproject.github.io/./.cache/gatsby-browser-entry.js","webpack://icatproject.github.io/./.cache/prefetch.js","webpack://icatproject.github.io/./.cache/loader.js","webpack://icatproject.github.io/./.cache/head/components/fire-callback-in-effect.js","webpack://icatproject.github.io/./.cache/head/constants.js","webpack://icatproject.github.io/./.cache/head/utils.js","webpack://icatproject.github.io/./.cache/head/head-export-handler-for-browser.js","webpack://icatproject.github.io/./.cache/page-renderer.js","webpack://icatproject.github.io/./.cache/route-announcer-props.js","webpack://icatproject.github.io/./.cache/navigation.js","webpack://icatproject.github.io/./node_modules/shallow-compare/es/index.js","webpack://icatproject.github.io/./.cache/ensure-resources.js","webpack://icatproject.github.io/./.cache/production-app.js","webpack://icatproject.github.io/./.cache/public-page-renderer-prod.js","webpack://icatproject.github.io/./.cache/public-page-renderer.js","webpack://icatproject.github.io/./.cache/react-dom-utils.js","webpack://icatproject.github.io/./.cache/redirect-utils.js","webpack://icatproject.github.io/./.cache/register-service-worker.js","webpack://icatproject.github.io/./.cache/slice/context.js","webpack://icatproject.github.io/./.cache/static-query.js","webpack://icatproject.github.io/./.cache/context-utils.js","webpack://icatproject.github.io/./.cache/strip-prefix.js","webpack://icatproject.github.io/./node_modules/gatsby-plugin-catch-links/catch-links.js","webpack://icatproject.github.io/./node_modules/gatsby-plugin-catch-links/gatsby-browser.js","webpack://icatproject.github.io/./node_modules/gatsby-plugin-catch-links/node_modules/escape-string-regexp/index.js","webpack://icatproject.github.io/./node_modules/gatsby-plugin-layout/gatsby-browser.js","webpack://icatproject.github.io/./node_modules/gatsby-plugin-layout/wrap-page.js","webpack://icatproject.github.io/./node_modules/gatsby-plugin-manifest/gatsby-browser.js","webpack://icatproject.github.io/./node_modules/gatsby-plugin-manifest/get-manifest-pathname.js","webpack://icatproject.github.io/./node_modules/gatsby-remark-images/constants.js","webpack://icatproject.github.io/./node_modules/gatsby-remark-images/gatsby-browser.js","webpack://icatproject.github.io/./node_modules/@fortawesome/fontawesome-svg-core/index.mjs","webpack://icatproject.github.io/./node_modules/@fortawesome/react-fontawesome/index.es.js","webpack://icatproject.github.io/./src/components/dropdown.jsx","webpack://icatproject.github.io/./src/components/navbar.jsx","webpack://icatproject.github.io/./src/components/header.jsx","webpack://icatproject.github.io/./src/components/recentMeetings.jsx","webpack://icatproject.github.io/./src/components/recentCommits.jsx","webpack://icatproject.github.io/./src/components/sidebar.jsx","webpack://icatproject.github.io/./src/components/layout.jsx","webpack://icatproject.github.io/./src/components/searchbar.jsx","webpack://icatproject.github.io/./node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js","webpack://icatproject.github.io/./node_modules/invariant/browser.js","webpack://icatproject.github.io/./node_modules/react-is/cjs/react-is.production.min.js","webpack://icatproject.github.io/./node_modules/react-is/index.js","webpack://icatproject.github.io/./node_modules/react-server-dom-webpack/cjs/react-server-dom-webpack.production.min.js","webpack://icatproject.github.io/./node_modules/react-server-dom-webpack/index.js","webpack://icatproject.github.io/./node_modules/@babel/runtime/helpers/assertThisInitialized.js","webpack://icatproject.github.io/./node_modules/@babel/runtime/helpers/extends.js","webpack://icatproject.github.io/./node_modules/@babel/runtime/helpers/inheritsLoose.js","webpack://icatproject.github.io/./node_modules/@babel/runtime/helpers/interopRequireDefault.js","webpack://icatproject.github.io/./node_modules/@babel/runtime/helpers/setPrototypeOf.js","webpack://icatproject.github.io/./node_modules/@builder.io/partytown/integration/index.cjs","webpack://icatproject.github.io/./node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js","webpack://icatproject.github.io/./node_modules/@babel/runtime/helpers/esm/extends.js","webpack://icatproject.github.io/./node_modules/@babel/runtime/helpers/esm/inheritsLoose.js","webpack://icatproject.github.io/./node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js","webpack://icatproject.github.io/./node_modules/@babel/runtime/helpers/esm/arrayLikeToArray.js","webpack://icatproject.github.io/./node_modules/@babel/runtime/helpers/esm/toConsumableArray.js","webpack://icatproject.github.io/./node_modules/@babel/runtime/helpers/esm/arrayWithoutHoles.js","webpack://icatproject.github.io/./node_modules/@babel/runtime/helpers/esm/iterableToArray.js","webpack://icatproject.github.io/./node_modules/@babel/runtime/helpers/esm/unsupportedIterableToArray.js","webpack://icatproject.github.io/./node_modules/@babel/runtime/helpers/esm/nonIterableSpread.js","webpack://icatproject.github.io/./node_modules/@gatsbyjs/reach-router/dist/index.modern.mjs","webpack://icatproject.github.io/./node_modules/gatsby-link/dist/index.modern.mjs","webpack://icatproject.github.io/./node_modules/gatsby-script/dist/index.modern.mjs"],"sourcesContent":["/*\n\nBased off glamor's StyleSheet, thanks Sunil ❤️\n\nhigh performance StyleSheet for css-in-js systems\n\n- uses multiple style tags behind the scenes for millions of rules\n- uses `insertRule` for appending in production for *much* faster performance\n\n// usage\n\nimport { StyleSheet } from '@emotion/sheet'\n\nlet styleSheet = new StyleSheet({ key: '', container: document.head })\n\nstyleSheet.insert('#box { border: 1px solid red; }')\n- appends a css rule into the stylesheet\n\nstyleSheet.flush()\n- empties the stylesheet of all its contents\n\n*/\n// $FlowFixMe\nfunction sheetForTag(tag) {\n if (tag.sheet) {\n // $FlowFixMe\n return tag.sheet;\n } // this weirdness brought to you by firefox\n\n /* istanbul ignore next */\n\n\n for (var i = 0; i < document.styleSheets.length; i++) {\n if (document.styleSheets[i].ownerNode === tag) {\n // $FlowFixMe\n return document.styleSheets[i];\n }\n }\n}\n\nfunction createStyleElement(options) {\n var tag = document.createElement('style');\n tag.setAttribute('data-emotion', options.key);\n\n if (options.nonce !== undefined) {\n tag.setAttribute('nonce', options.nonce);\n }\n\n tag.appendChild(document.createTextNode(''));\n tag.setAttribute('data-s', '');\n return tag;\n}\n\nvar StyleSheet = /*#__PURE__*/function () {\n // Using Node instead of HTMLElement since container may be a ShadowRoot\n function StyleSheet(options) {\n var _this = this;\n\n this._insertTag = function (tag) {\n var before;\n\n if (_this.tags.length === 0) {\n if (_this.insertionPoint) {\n before = _this.insertionPoint.nextSibling;\n } else if (_this.prepend) {\n before = _this.container.firstChild;\n } else {\n before = _this.before;\n }\n } else {\n before = _this.tags[_this.tags.length - 1].nextSibling;\n }\n\n _this.container.insertBefore(tag, before);\n\n _this.tags.push(tag);\n };\n\n this.isSpeedy = options.speedy === undefined ? process.env.NODE_ENV === 'production' : options.speedy;\n this.tags = [];\n this.ctr = 0;\n this.nonce = options.nonce; // key is the value of the data-emotion attribute, it's used to identify different sheets\n\n this.key = options.key;\n this.container = options.container;\n this.prepend = options.prepend;\n this.insertionPoint = options.insertionPoint;\n this.before = null;\n }\n\n var _proto = StyleSheet.prototype;\n\n _proto.hydrate = function hydrate(nodes) {\n nodes.forEach(this._insertTag);\n };\n\n _proto.insert = function insert(rule) {\n // the max length is how many rules we have per style tag, it's 65000 in speedy mode\n // it's 1 in dev because we insert source maps that map a single rule to a location\n // and you can only have one source map per style tag\n if (this.ctr % (this.isSpeedy ? 65000 : 1) === 0) {\n this._insertTag(createStyleElement(this));\n }\n\n var tag = this.tags[this.tags.length - 1];\n\n if (process.env.NODE_ENV !== 'production') {\n var isImportRule = rule.charCodeAt(0) === 64 && rule.charCodeAt(1) === 105;\n\n if (isImportRule && this._alreadyInsertedOrderInsensitiveRule) {\n // this would only cause problem in speedy mode\n // but we don't want enabling speedy to affect the observable behavior\n // so we report this error at all times\n console.error(\"You're attempting to insert the following rule:\\n\" + rule + '\\n\\n`@import` rules must be before all other types of rules in a stylesheet but other rules have already been inserted. Please ensure that `@import` rules are before all other rules.');\n }\n this._alreadyInsertedOrderInsensitiveRule = this._alreadyInsertedOrderInsensitiveRule || !isImportRule;\n }\n\n if (this.isSpeedy) {\n var sheet = sheetForTag(tag);\n\n try {\n // this is the ultrafast version, works across browsers\n // the big drawback is that the css won't be editable in devtools\n sheet.insertRule(rule, sheet.cssRules.length);\n } catch (e) {\n if (process.env.NODE_ENV !== 'production' && !/:(-moz-placeholder|-moz-focus-inner|-moz-focusring|-ms-input-placeholder|-moz-read-write|-moz-read-only|-ms-clear|-ms-expand|-ms-reveal){/.test(rule)) {\n console.error(\"There was a problem inserting the following rule: \\\"\" + rule + \"\\\"\", e);\n }\n }\n } else {\n tag.appendChild(document.createTextNode(rule));\n }\n\n this.ctr++;\n };\n\n _proto.flush = function flush() {\n // $FlowFixMe\n this.tags.forEach(function (tag) {\n return tag.parentNode && tag.parentNode.removeChild(tag);\n });\n this.tags = [];\n this.ctr = 0;\n\n if (process.env.NODE_ENV !== 'production') {\n this._alreadyInsertedOrderInsensitiveRule = false;\n }\n };\n\n return StyleSheet;\n}();\n\nexport { StyleSheet };\n","/**\n * @param {number}\n * @return {number}\n */\nexport var abs = Math.abs\n\n/**\n * @param {number}\n * @return {string}\n */\nexport var from = String.fromCharCode\n\n/**\n * @param {object}\n * @return {object}\n */\nexport var assign = Object.assign\n\n/**\n * @param {string} value\n * @param {number} length\n * @return {number}\n */\nexport function hash (value, length) {\n\treturn charat(value, 0) ^ 45 ? (((((((length << 2) ^ charat(value, 0)) << 2) ^ charat(value, 1)) << 2) ^ charat(value, 2)) << 2) ^ charat(value, 3) : 0\n}\n\n/**\n * @param {string} value\n * @return {string}\n */\nexport function trim (value) {\n\treturn value.trim()\n}\n\n/**\n * @param {string} value\n * @param {RegExp} pattern\n * @return {string?}\n */\nexport function match (value, pattern) {\n\treturn (value = pattern.exec(value)) ? value[0] : value\n}\n\n/**\n * @param {string} value\n * @param {(string|RegExp)} pattern\n * @param {string} replacement\n * @return {string}\n */\nexport function replace (value, pattern, replacement) {\n\treturn value.replace(pattern, replacement)\n}\n\n/**\n * @param {string} value\n * @param {string} search\n * @return {number}\n */\nexport function indexof (value, search) {\n\treturn value.indexOf(search)\n}\n\n/**\n * @param {string} value\n * @param {number} index\n * @return {number}\n */\nexport function charat (value, index) {\n\treturn value.charCodeAt(index) | 0\n}\n\n/**\n * @param {string} value\n * @param {number} begin\n * @param {number} end\n * @return {string}\n */\nexport function substr (value, begin, end) {\n\treturn value.slice(begin, end)\n}\n\n/**\n * @param {string} value\n * @return {number}\n */\nexport function strlen (value) {\n\treturn value.length\n}\n\n/**\n * @param {any[]} value\n * @return {number}\n */\nexport function sizeof (value) {\n\treturn value.length\n}\n\n/**\n * @param {any} value\n * @param {any[]} array\n * @return {any}\n */\nexport function append (value, array) {\n\treturn array.push(value), value\n}\n\n/**\n * @param {string[]} array\n * @param {function} callback\n * @return {string}\n */\nexport function combine (array, callback) {\n\treturn array.map(callback).join('')\n}\n","import {from, trim, charat, strlen, substr, append, assign} from './Utility.js'\n\nexport var line = 1\nexport var column = 1\nexport var length = 0\nexport var position = 0\nexport var character = 0\nexport var characters = ''\n\n/**\n * @param {string} value\n * @param {object | null} root\n * @param {object | null} parent\n * @param {string} type\n * @param {string[] | string} props\n * @param {object[] | string} children\n * @param {number} length\n */\nexport function node (value, root, parent, type, props, children, length) {\n\treturn {value: value, root: root, parent: parent, type: type, props: props, children: children, line: line, column: column, length: length, return: ''}\n}\n\n/**\n * @param {object} root\n * @param {object} props\n * @return {object}\n */\nexport function copy (root, props) {\n\treturn assign(node('', null, null, '', null, null, 0), root, {length: -root.length}, props)\n}\n\n/**\n * @return {number}\n */\nexport function char () {\n\treturn character\n}\n\n/**\n * @return {number}\n */\nexport function prev () {\n\tcharacter = position > 0 ? charat(characters, --position) : 0\n\n\tif (column--, character === 10)\n\t\tcolumn = 1, line--\n\n\treturn character\n}\n\n/**\n * @return {number}\n */\nexport function next () {\n\tcharacter = position < length ? charat(characters, position++) : 0\n\n\tif (column++, character === 10)\n\t\tcolumn = 1, line++\n\n\treturn character\n}\n\n/**\n * @return {number}\n */\nexport function peek () {\n\treturn charat(characters, position)\n}\n\n/**\n * @return {number}\n */\nexport function caret () {\n\treturn position\n}\n\n/**\n * @param {number} begin\n * @param {number} end\n * @return {string}\n */\nexport function slice (begin, end) {\n\treturn substr(characters, begin, end)\n}\n\n/**\n * @param {number} type\n * @return {number}\n */\nexport function token (type) {\n\tswitch (type) {\n\t\t// \\0 \\t \\n \\r \\s whitespace token\n\t\tcase 0: case 9: case 10: case 13: case 32:\n\t\t\treturn 5\n\t\t// ! + , / > @ ~ isolate token\n\t\tcase 33: case 43: case 44: case 47: case 62: case 64: case 126:\n\t\t// ; { } breakpoint token\n\t\tcase 59: case 123: case 125:\n\t\t\treturn 4\n\t\t// : accompanied token\n\t\tcase 58:\n\t\t\treturn 3\n\t\t// \" ' ( [ opening delimit token\n\t\tcase 34: case 39: case 40: case 91:\n\t\t\treturn 2\n\t\t// ) ] closing delimit token\n\t\tcase 41: case 93:\n\t\t\treturn 1\n\t}\n\n\treturn 0\n}\n\n/**\n * @param {string} value\n * @return {any[]}\n */\nexport function alloc (value) {\n\treturn line = column = 1, length = strlen(characters = value), position = 0, []\n}\n\n/**\n * @param {any} value\n * @return {any}\n */\nexport function dealloc (value) {\n\treturn characters = '', value\n}\n\n/**\n * @param {number} type\n * @return {string}\n */\nexport function delimit (type) {\n\treturn trim(slice(position - 1, delimiter(type === 91 ? type + 2 : type === 40 ? type + 1 : type)))\n}\n\n/**\n * @param {string} value\n * @return {string[]}\n */\nexport function tokenize (value) {\n\treturn dealloc(tokenizer(alloc(value)))\n}\n\n/**\n * @param {number} type\n * @return {string}\n */\nexport function whitespace (type) {\n\twhile (character = peek())\n\t\tif (character < 33)\n\t\t\tnext()\n\t\telse\n\t\t\tbreak\n\n\treturn token(type) > 2 || token(character) > 3 ? '' : ' '\n}\n\n/**\n * @param {string[]} children\n * @return {string[]}\n */\nexport function tokenizer (children) {\n\twhile (next())\n\t\tswitch (token(character)) {\n\t\t\tcase 0: append(identifier(position - 1), children)\n\t\t\t\tbreak\n\t\t\tcase 2: append(delimit(character), children)\n\t\t\t\tbreak\n\t\t\tdefault: append(from(character), children)\n\t\t}\n\n\treturn children\n}\n\n/**\n * @param {number} index\n * @param {number} count\n * @return {string}\n */\nexport function escaping (index, count) {\n\twhile (--count && next())\n\t\t// not 0-9 A-F a-f\n\t\tif (character < 48 || character > 102 || (character > 57 && character < 65) || (character > 70 && character < 97))\n\t\t\tbreak\n\n\treturn slice(index, caret() + (count < 6 && peek() == 32 && next() == 32))\n}\n\n/**\n * @param {number} type\n * @return {number}\n */\nexport function delimiter (type) {\n\twhile (next())\n\t\tswitch (character) {\n\t\t\t// ] ) \" '\n\t\t\tcase type:\n\t\t\t\treturn position\n\t\t\t// \" '\n\t\t\tcase 34: case 39:\n\t\t\t\tif (type !== 34 && type !== 39)\n\t\t\t\t\tdelimiter(character)\n\t\t\t\tbreak\n\t\t\t// (\n\t\t\tcase 40:\n\t\t\t\tif (type === 41)\n\t\t\t\t\tdelimiter(type)\n\t\t\t\tbreak\n\t\t\t// \\\n\t\t\tcase 92:\n\t\t\t\tnext()\n\t\t\t\tbreak\n\t\t}\n\n\treturn position\n}\n\n/**\n * @param {number} type\n * @param {number} index\n * @return {number}\n */\nexport function commenter (type, index) {\n\twhile (next())\n\t\t// //\n\t\tif (type + character === 47 + 10)\n\t\t\tbreak\n\t\t// /*\n\t\telse if (type + character === 42 + 42 && peek() === 47)\n\t\t\tbreak\n\n\treturn '/*' + slice(index, position - 1) + '*' + from(type === 47 ? type : next())\n}\n\n/**\n * @param {number} index\n * @return {string}\n */\nexport function identifier (index) {\n\twhile (!token(peek()))\n\t\tnext()\n\n\treturn slice(index, position)\n}\n","export var MS = '-ms-'\nexport var MOZ = '-moz-'\nexport var WEBKIT = '-webkit-'\n\nexport var COMMENT = 'comm'\nexport var RULESET = 'rule'\nexport var DECLARATION = 'decl'\n\nexport var PAGE = '@page'\nexport var MEDIA = '@media'\nexport var IMPORT = '@import'\nexport var CHARSET = '@charset'\nexport var VIEWPORT = '@viewport'\nexport var SUPPORTS = '@supports'\nexport var DOCUMENT = '@document'\nexport var NAMESPACE = '@namespace'\nexport var KEYFRAMES = '@keyframes'\nexport var FONT_FACE = '@font-face'\nexport var COUNTER_STYLE = '@counter-style'\nexport var FONT_FEATURE_VALUES = '@font-feature-values'\nexport var LAYER = '@layer'\n","import {IMPORT, LAYER, COMMENT, RULESET, DECLARATION, KEYFRAMES} from './Enum.js'\nimport {strlen, sizeof} from './Utility.js'\n\n/**\n * @param {object[]} children\n * @param {function} callback\n * @return {string}\n */\nexport function serialize (children, callback) {\n\tvar output = ''\n\tvar length = sizeof(children)\n\n\tfor (var i = 0; i < length; i++)\n\t\toutput += callback(children[i], i, children, callback) || ''\n\n\treturn output\n}\n\n/**\n * @param {object} element\n * @param {number} index\n * @param {object[]} children\n * @param {function} callback\n * @return {string}\n */\nexport function stringify (element, index, children, callback) {\n\tswitch (element.type) {\n\t\tcase LAYER: if (element.children.length) break\n\t\tcase IMPORT: case DECLARATION: return element.return = element.return || element.value\n\t\tcase COMMENT: return ''\n\t\tcase KEYFRAMES: return element.return = element.value + '{' + serialize(element.children, callback) + '}'\n\t\tcase RULESET: element.value = element.props.join(',')\n\t}\n\n\treturn strlen(children = serialize(element.children, callback)) ? element.return = element.value + '{' + children + '}' : ''\n}\n","import {COMMENT, RULESET, DECLARATION} from './Enum.js'\nimport {abs, charat, trim, from, sizeof, strlen, substr, append, replace, indexof} from './Utility.js'\nimport {node, char, prev, next, peek, caret, alloc, dealloc, delimit, whitespace, escaping, identifier, commenter} from './Tokenizer.js'\n\n/**\n * @param {string} value\n * @return {object[]}\n */\nexport function compile (value) {\n\treturn dealloc(parse('', null, null, null, [''], value = alloc(value), 0, [0], value))\n}\n\n/**\n * @param {string} value\n * @param {object} root\n * @param {object?} parent\n * @param {string[]} rule\n * @param {string[]} rules\n * @param {string[]} rulesets\n * @param {number[]} pseudo\n * @param {number[]} points\n * @param {string[]} declarations\n * @return {object}\n */\nexport function parse (value, root, parent, rule, rules, rulesets, pseudo, points, declarations) {\n\tvar index = 0\n\tvar offset = 0\n\tvar length = pseudo\n\tvar atrule = 0\n\tvar property = 0\n\tvar previous = 0\n\tvar variable = 1\n\tvar scanning = 1\n\tvar ampersand = 1\n\tvar character = 0\n\tvar type = ''\n\tvar props = rules\n\tvar children = rulesets\n\tvar reference = rule\n\tvar characters = type\n\n\twhile (scanning)\n\t\tswitch (previous = character, character = next()) {\n\t\t\t// (\n\t\t\tcase 40:\n\t\t\t\tif (previous != 108 && charat(characters, length - 1) == 58) {\n\t\t\t\t\tif (indexof(characters += replace(delimit(character), '&', '&\\f'), '&\\f') != -1)\n\t\t\t\t\t\tampersand = -1\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t// \" ' [\n\t\t\tcase 34: case 39: case 91:\n\t\t\t\tcharacters += delimit(character)\n\t\t\t\tbreak\n\t\t\t// \\t \\n \\r \\s\n\t\t\tcase 9: case 10: case 13: case 32:\n\t\t\t\tcharacters += whitespace(previous)\n\t\t\t\tbreak\n\t\t\t// \\\n\t\t\tcase 92:\n\t\t\t\tcharacters += escaping(caret() - 1, 7)\n\t\t\t\tcontinue\n\t\t\t// /\n\t\t\tcase 47:\n\t\t\t\tswitch (peek()) {\n\t\t\t\t\tcase 42: case 47:\n\t\t\t\t\t\tappend(comment(commenter(next(), caret()), root, parent), declarations)\n\t\t\t\t\t\tbreak\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tcharacters += '/'\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t// {\n\t\t\tcase 123 * variable:\n\t\t\t\tpoints[index++] = strlen(characters) * ampersand\n\t\t\t// } ; \\0\n\t\t\tcase 125 * variable: case 59: case 0:\n\t\t\t\tswitch (character) {\n\t\t\t\t\t// \\0 }\n\t\t\t\t\tcase 0: case 125: scanning = 0\n\t\t\t\t\t// ;\n\t\t\t\t\tcase 59 + offset: if (ampersand == -1) characters = replace(characters, /\\f/g, '')\n\t\t\t\t\t\tif (property > 0 && (strlen(characters) - length))\n\t\t\t\t\t\t\tappend(property > 32 ? declaration(characters + ';', rule, parent, length - 1) : declaration(replace(characters, ' ', '') + ';', rule, parent, length - 2), declarations)\n\t\t\t\t\t\tbreak\n\t\t\t\t\t// @ ;\n\t\t\t\t\tcase 59: characters += ';'\n\t\t\t\t\t// { rule/at-rule\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tappend(reference = ruleset(characters, root, parent, index, offset, rules, points, type, props = [], children = [], length), rulesets)\n\n\t\t\t\t\t\tif (character === 123)\n\t\t\t\t\t\t\tif (offset === 0)\n\t\t\t\t\t\t\t\tparse(characters, root, reference, reference, props, rulesets, length, points, children)\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tswitch (atrule === 99 && charat(characters, 3) === 110 ? 100 : atrule) {\n\t\t\t\t\t\t\t\t\t// d l m s\n\t\t\t\t\t\t\t\t\tcase 100: case 108: case 109: case 115:\n\t\t\t\t\t\t\t\t\t\tparse(value, reference, reference, rule && append(ruleset(value, reference, reference, 0, 0, rules, points, type, rules, props = [], length), children), rules, children, length, points, rule ? props : children)\n\t\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t\t\tparse(characters, reference, reference, reference, [''], children, 0, points, children)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tindex = offset = property = 0, variable = ampersand = 1, type = characters = '', length = pseudo\n\t\t\t\tbreak\n\t\t\t// :\n\t\t\tcase 58:\n\t\t\t\tlength = 1 + strlen(characters), property = previous\n\t\t\tdefault:\n\t\t\t\tif (variable < 1)\n\t\t\t\t\tif (character == 123)\n\t\t\t\t\t\t--variable\n\t\t\t\t\telse if (character == 125 && variable++ == 0 && prev() == 125)\n\t\t\t\t\t\tcontinue\n\n\t\t\t\tswitch (characters += from(character), character * variable) {\n\t\t\t\t\t// &\n\t\t\t\t\tcase 38:\n\t\t\t\t\t\tampersand = offset > 0 ? 1 : (characters += '\\f', -1)\n\t\t\t\t\t\tbreak\n\t\t\t\t\t// ,\n\t\t\t\t\tcase 44:\n\t\t\t\t\t\tpoints[index++] = (strlen(characters) - 1) * ampersand, ampersand = 1\n\t\t\t\t\t\tbreak\n\t\t\t\t\t// @\n\t\t\t\t\tcase 64:\n\t\t\t\t\t\t// -\n\t\t\t\t\t\tif (peek() === 45)\n\t\t\t\t\t\t\tcharacters += delimit(next())\n\n\t\t\t\t\t\tatrule = peek(), offset = length = strlen(type = characters += identifier(caret())), character++\n\t\t\t\t\t\tbreak\n\t\t\t\t\t// -\n\t\t\t\t\tcase 45:\n\t\t\t\t\t\tif (previous === 45 && strlen(characters) == 2)\n\t\t\t\t\t\t\tvariable = 0\n\t\t\t\t}\n\t\t}\n\n\treturn rulesets\n}\n\n/**\n * @param {string} value\n * @param {object} root\n * @param {object?} parent\n * @param {number} index\n * @param {number} offset\n * @param {string[]} rules\n * @param {number[]} points\n * @param {string} type\n * @param {string[]} props\n * @param {string[]} children\n * @param {number} length\n * @return {object}\n */\nexport function ruleset (value, root, parent, index, offset, rules, points, type, props, children, length) {\n\tvar post = offset - 1\n\tvar rule = offset === 0 ? rules : ['']\n\tvar size = sizeof(rule)\n\n\tfor (var i = 0, j = 0, k = 0; i < index; ++i)\n\t\tfor (var x = 0, y = substr(value, post + 1, post = abs(j = points[i])), z = value; x < size; ++x)\n\t\t\tif (z = trim(j > 0 ? rule[x] + ' ' + y : replace(y, /&\\f/g, rule[x])))\n\t\t\t\tprops[k++] = z\n\n\treturn node(value, root, parent, offset === 0 ? RULESET : type, props, children, length)\n}\n\n/**\n * @param {number} value\n * @param {object} root\n * @param {object?} parent\n * @return {object}\n */\nexport function comment (value, root, parent) {\n\treturn node(value, root, parent, COMMENT, from(char()), substr(value, 2, -2), 0)\n}\n\n/**\n * @param {string} value\n * @param {object} root\n * @param {object?} parent\n * @param {number} length\n * @return {object}\n */\nexport function declaration (value, root, parent, length) {\n\treturn node(value, root, parent, DECLARATION, substr(value, 0, length), substr(value, length + 1, -1), length)\n}\n","import { StyleSheet } from '@emotion/sheet';\nimport { dealloc, alloc, next, token, from, peek, delimit, slice, position, RULESET, combine, match, serialize, copy, replace, WEBKIT, MOZ, MS, KEYFRAMES, DECLARATION, hash, charat, strlen, indexof, stringify, COMMENT, rulesheet, middleware, compile } from 'stylis';\nimport '@emotion/weak-memoize';\nimport '@emotion/memoize';\n\nvar identifierWithPointTracking = function identifierWithPointTracking(begin, points, index) {\n var previous = 0;\n var character = 0;\n\n while (true) {\n previous = character;\n character = peek(); // &\\f\n\n if (previous === 38 && character === 12) {\n points[index] = 1;\n }\n\n if (token(character)) {\n break;\n }\n\n next();\n }\n\n return slice(begin, position);\n};\n\nvar toRules = function toRules(parsed, points) {\n // pretend we've started with a comma\n var index = -1;\n var character = 44;\n\n do {\n switch (token(character)) {\n case 0:\n // &\\f\n if (character === 38 && peek() === 12) {\n // this is not 100% correct, we don't account for literal sequences here - like for example quoted strings\n // stylis inserts \\f after & to know when & where it should replace this sequence with the context selector\n // and when it should just concatenate the outer and inner selectors\n // it's very unlikely for this sequence to actually appear in a different context, so we just leverage this fact here\n points[index] = 1;\n }\n\n parsed[index] += identifierWithPointTracking(position - 1, points, index);\n break;\n\n case 2:\n parsed[index] += delimit(character);\n break;\n\n case 4:\n // comma\n if (character === 44) {\n // colon\n parsed[++index] = peek() === 58 ? '&\\f' : '';\n points[index] = parsed[index].length;\n break;\n }\n\n // fallthrough\n\n default:\n parsed[index] += from(character);\n }\n } while (character = next());\n\n return parsed;\n};\n\nvar getRules = function getRules(value, points) {\n return dealloc(toRules(alloc(value), points));\n}; // WeakSet would be more appropriate, but only WeakMap is supported in IE11\n\n\nvar fixedElements = /* #__PURE__ */new WeakMap();\nvar compat = function compat(element) {\n if (element.type !== 'rule' || !element.parent || // positive .length indicates that this rule contains pseudo\n // negative .length indicates that this rule has been already prefixed\n element.length < 1) {\n return;\n }\n\n var value = element.value,\n parent = element.parent;\n var isImplicitRule = element.column === parent.column && element.line === parent.line;\n\n while (parent.type !== 'rule') {\n parent = parent.parent;\n if (!parent) return;\n } // short-circuit for the simplest case\n\n\n if (element.props.length === 1 && value.charCodeAt(0) !== 58\n /* colon */\n && !fixedElements.get(parent)) {\n return;\n } // if this is an implicitly inserted rule (the one eagerly inserted at the each new nested level)\n // then the props has already been manipulated beforehand as they that array is shared between it and its \"rule parent\"\n\n\n if (isImplicitRule) {\n return;\n }\n\n fixedElements.set(element, true);\n var points = [];\n var rules = getRules(value, points);\n var parentRules = parent.props;\n\n for (var i = 0, k = 0; i < rules.length; i++) {\n for (var j = 0; j < parentRules.length; j++, k++) {\n element.props[k] = points[i] ? rules[i].replace(/&\\f/g, parentRules[j]) : parentRules[j] + \" \" + rules[i];\n }\n }\n};\nvar removeLabel = function removeLabel(element) {\n if (element.type === 'decl') {\n var value = element.value;\n\n if ( // charcode for l\n value.charCodeAt(0) === 108 && // charcode for b\n value.charCodeAt(2) === 98) {\n // this ignores label\n element[\"return\"] = '';\n element.value = '';\n }\n }\n};\nvar ignoreFlag = 'emotion-disable-server-rendering-unsafe-selector-warning-please-do-not-use-this-the-warning-exists-for-a-reason';\n\nvar isIgnoringComment = function isIgnoringComment(element) {\n return element.type === 'comm' && element.children.indexOf(ignoreFlag) > -1;\n};\n\nvar createUnsafeSelectorsAlarm = function createUnsafeSelectorsAlarm(cache) {\n return function (element, index, children) {\n if (element.type !== 'rule' || cache.compat) return;\n var unsafePseudoClasses = element.value.match(/(:first|:nth|:nth-last)-child/g);\n\n if (unsafePseudoClasses) {\n var isNested = !!element.parent; // in nested rules comments become children of the \"auto-inserted\" rule and that's always the `element.parent`\n //\n // considering this input:\n // .a {\n // .b /* comm */ {}\n // color: hotpink;\n // }\n // we get output corresponding to this:\n // .a {\n // & {\n // /* comm */\n // color: hotpink;\n // }\n // .b {}\n // }\n\n var commentContainer = isNested ? element.parent.children : // global rule at the root level\n children;\n\n for (var i = commentContainer.length - 1; i >= 0; i--) {\n var node = commentContainer[i];\n\n if (node.line < element.line) {\n break;\n } // it is quite weird but comments are *usually* put at `column: element.column - 1`\n // so we seek *from the end* for the node that is earlier than the rule's `element` and check that\n // this will also match inputs like this:\n // .a {\n // /* comm */\n // .b {}\n // }\n //\n // but that is fine\n //\n // it would be the easiest to change the placement of the comment to be the first child of the rule:\n // .a {\n // .b { /* comm */ }\n // }\n // with such inputs we wouldn't have to search for the comment at all\n // TODO: consider changing this comment placement in the next major version\n\n\n if (node.column < element.column) {\n if (isIgnoringComment(node)) {\n return;\n }\n\n break;\n }\n }\n\n unsafePseudoClasses.forEach(function (unsafePseudoClass) {\n console.error(\"The pseudo class \\\"\" + unsafePseudoClass + \"\\\" is potentially unsafe when doing server-side rendering. Try changing it to \\\"\" + unsafePseudoClass.split('-child')[0] + \"-of-type\\\".\");\n });\n }\n };\n};\n\nvar isImportRule = function isImportRule(element) {\n return element.type.charCodeAt(1) === 105 && element.type.charCodeAt(0) === 64;\n};\n\nvar isPrependedWithRegularRules = function isPrependedWithRegularRules(index, children) {\n for (var i = index - 1; i >= 0; i--) {\n if (!isImportRule(children[i])) {\n return true;\n }\n }\n\n return false;\n}; // use this to remove incorrect elements from further processing\n// so they don't get handed to the `sheet` (or anything else)\n// as that could potentially lead to additional logs which in turn could be overhelming to the user\n\n\nvar nullifyElement = function nullifyElement(element) {\n element.type = '';\n element.value = '';\n element[\"return\"] = '';\n element.children = '';\n element.props = '';\n};\n\nvar incorrectImportAlarm = function incorrectImportAlarm(element, index, children) {\n if (!isImportRule(element)) {\n return;\n }\n\n if (element.parent) {\n console.error(\"`@import` rules can't be nested inside other rules. Please move it to the top level and put it before regular rules. Keep in mind that they can only be used within global styles.\");\n nullifyElement(element);\n } else if (isPrependedWithRegularRules(index, children)) {\n console.error(\"`@import` rules can't be after other rules. Please put your `@import` rules before your other rules.\");\n nullifyElement(element);\n }\n};\n\n/* eslint-disable no-fallthrough */\n\nfunction prefix(value, length) {\n switch (hash(value, length)) {\n // color-adjust\n case 5103:\n return WEBKIT + 'print-' + value + value;\n // animation, animation-(delay|direction|duration|fill-mode|iteration-count|name|play-state|timing-function)\n\n case 5737:\n case 4201:\n case 3177:\n case 3433:\n case 1641:\n case 4457:\n case 2921: // text-decoration, filter, clip-path, backface-visibility, column, box-decoration-break\n\n case 5572:\n case 6356:\n case 5844:\n case 3191:\n case 6645:\n case 3005: // mask, mask-image, mask-(mode|clip|size), mask-(repeat|origin), mask-position, mask-composite,\n\n case 6391:\n case 5879:\n case 5623:\n case 6135:\n case 4599:\n case 4855: // background-clip, columns, column-(count|fill|gap|rule|rule-color|rule-style|rule-width|span|width)\n\n case 4215:\n case 6389:\n case 5109:\n case 5365:\n case 5621:\n case 3829:\n return WEBKIT + value + value;\n // appearance, user-select, transform, hyphens, text-size-adjust\n\n case 5349:\n case 4246:\n case 4810:\n case 6968:\n case 2756:\n return WEBKIT + value + MOZ + value + MS + value + value;\n // flex, flex-direction\n\n case 6828:\n case 4268:\n return WEBKIT + value + MS + value + value;\n // order\n\n case 6165:\n return WEBKIT + value + MS + 'flex-' + value + value;\n // align-items\n\n case 5187:\n return WEBKIT + value + replace(value, /(\\w+).+(:[^]+)/, WEBKIT + 'box-$1$2' + MS + 'flex-$1$2') + value;\n // align-self\n\n case 5443:\n return WEBKIT + value + MS + 'flex-item-' + replace(value, /flex-|-self/, '') + value;\n // align-content\n\n case 4675:\n return WEBKIT + value + MS + 'flex-line-pack' + replace(value, /align-content|flex-|-self/, '') + value;\n // flex-shrink\n\n case 5548:\n return WEBKIT + value + MS + replace(value, 'shrink', 'negative') + value;\n // flex-basis\n\n case 5292:\n return WEBKIT + value + MS + replace(value, 'basis', 'preferred-size') + value;\n // flex-grow\n\n case 6060:\n return WEBKIT + 'box-' + replace(value, '-grow', '') + WEBKIT + value + MS + replace(value, 'grow', 'positive') + value;\n // transition\n\n case 4554:\n return WEBKIT + replace(value, /([^-])(transform)/g, '$1' + WEBKIT + '$2') + value;\n // cursor\n\n case 6187:\n return replace(replace(replace(value, /(zoom-|grab)/, WEBKIT + '$1'), /(image-set)/, WEBKIT + '$1'), value, '') + value;\n // background, background-image\n\n case 5495:\n case 3959:\n return replace(value, /(image-set\\([^]*)/, WEBKIT + '$1' + '$`$1');\n // justify-content\n\n case 4968:\n return replace(replace(value, /(.+:)(flex-)?(.*)/, WEBKIT + 'box-pack:$3' + MS + 'flex-pack:$3'), /s.+-b[^;]+/, 'justify') + WEBKIT + value + value;\n // (margin|padding)-inline-(start|end)\n\n case 4095:\n case 3583:\n case 4068:\n case 2532:\n return replace(value, /(.+)-inline(.+)/, WEBKIT + '$1$2') + value;\n // (min|max)?(width|height|inline-size|block-size)\n\n case 8116:\n case 7059:\n case 5753:\n case 5535:\n case 5445:\n case 5701:\n case 4933:\n case 4677:\n case 5533:\n case 5789:\n case 5021:\n case 4765:\n // stretch, max-content, min-content, fill-available\n if (strlen(value) - 1 - length > 6) switch (charat(value, length + 1)) {\n // (m)ax-content, (m)in-content\n case 109:\n // -\n if (charat(value, length + 4) !== 45) break;\n // (f)ill-available, (f)it-content\n\n case 102:\n return replace(value, /(.+:)(.+)-([^]+)/, '$1' + WEBKIT + '$2-$3' + '$1' + MOZ + (charat(value, length + 3) == 108 ? '$3' : '$2-$3')) + value;\n // (s)tretch\n\n case 115:\n return ~indexof(value, 'stretch') ? prefix(replace(value, 'stretch', 'fill-available'), length) + value : value;\n }\n break;\n // position: sticky\n\n case 4949:\n // (s)ticky?\n if (charat(value, length + 1) !== 115) break;\n // display: (flex|inline-flex)\n\n case 6444:\n switch (charat(value, strlen(value) - 3 - (~indexof(value, '!important') && 10))) {\n // stic(k)y\n case 107:\n return replace(value, ':', ':' + WEBKIT) + value;\n // (inline-)?fl(e)x\n\n case 101:\n return replace(value, /(.+:)([^;!]+)(;|!.+)?/, '$1' + WEBKIT + (charat(value, 14) === 45 ? 'inline-' : '') + 'box$3' + '$1' + WEBKIT + '$2$3' + '$1' + MS + '$2box$3') + value;\n }\n\n break;\n // writing-mode\n\n case 5936:\n switch (charat(value, length + 11)) {\n // vertical-l(r)\n case 114:\n return WEBKIT + value + MS + replace(value, /[svh]\\w+-[tblr]{2}/, 'tb') + value;\n // vertical-r(l)\n\n case 108:\n return WEBKIT + value + MS + replace(value, /[svh]\\w+-[tblr]{2}/, 'tb-rl') + value;\n // horizontal(-)tb\n\n case 45:\n return WEBKIT + value + MS + replace(value, /[svh]\\w+-[tblr]{2}/, 'lr') + value;\n }\n\n return WEBKIT + value + MS + value + value;\n }\n\n return value;\n}\n\nvar prefixer = function prefixer(element, index, children, callback) {\n if (element.length > -1) if (!element[\"return\"]) switch (element.type) {\n case DECLARATION:\n element[\"return\"] = prefix(element.value, element.length);\n break;\n\n case KEYFRAMES:\n return serialize([copy(element, {\n value: replace(element.value, '@', '@' + WEBKIT)\n })], callback);\n\n case RULESET:\n if (element.length) return combine(element.props, function (value) {\n switch (match(value, /(::plac\\w+|:read-\\w+)/)) {\n // :read-(only|write)\n case ':read-only':\n case ':read-write':\n return serialize([copy(element, {\n props: [replace(value, /:(read-\\w+)/, ':' + MOZ + '$1')]\n })], callback);\n // :placeholder\n\n case '::placeholder':\n return serialize([copy(element, {\n props: [replace(value, /:(plac\\w+)/, ':' + WEBKIT + 'input-$1')]\n }), copy(element, {\n props: [replace(value, /:(plac\\w+)/, ':' + MOZ + '$1')]\n }), copy(element, {\n props: [replace(value, /:(plac\\w+)/, MS + 'input-$1')]\n })], callback);\n }\n\n return '';\n });\n }\n};\n\nvar defaultStylisPlugins = [prefixer];\n\nvar createCache = function createCache(options) {\n var key = options.key;\n\n if (process.env.NODE_ENV !== 'production' && !key) {\n throw new Error(\"You have to configure `key` for your cache. Please make sure it's unique (and not equal to 'css') as it's used for linking styles to your cache.\\n\" + \"If multiple caches share the same key they might \\\"fight\\\" for each other's style elements.\");\n }\n\n if (key === 'css') {\n var ssrStyles = document.querySelectorAll(\"style[data-emotion]:not([data-s])\"); // get SSRed styles out of the way of React's hydration\n // document.head is a safe place to move them to(though note document.head is not necessarily the last place they will be)\n // note this very very intentionally targets all style elements regardless of the key to ensure\n // that creating a cache works inside of render of a React component\n\n Array.prototype.forEach.call(ssrStyles, function (node) {\n // we want to only move elements which have a space in the data-emotion attribute value\n // because that indicates that it is an Emotion 11 server-side rendered style elements\n // while we will already ignore Emotion 11 client-side inserted styles because of the :not([data-s]) part in the selector\n // Emotion 10 client-side inserted styles did not have data-s (but importantly did not have a space in their data-emotion attributes)\n // so checking for the space ensures that loading Emotion 11 after Emotion 10 has inserted some styles\n // will not result in the Emotion 10 styles being destroyed\n var dataEmotionAttribute = node.getAttribute('data-emotion');\n\n if (dataEmotionAttribute.indexOf(' ') === -1) {\n return;\n }\n document.head.appendChild(node);\n node.setAttribute('data-s', '');\n });\n }\n\n var stylisPlugins = options.stylisPlugins || defaultStylisPlugins;\n\n if (process.env.NODE_ENV !== 'production') {\n // $FlowFixMe\n if (/[^a-z-]/.test(key)) {\n throw new Error(\"Emotion key must only contain lower case alphabetical characters and - but \\\"\" + key + \"\\\" was passed\");\n }\n }\n\n var inserted = {};\n var container;\n var nodesToHydrate = [];\n\n {\n container = options.container || document.head;\n Array.prototype.forEach.call( // this means we will ignore elements which don't have a space in them which\n // means that the style elements we're looking at are only Emotion 11 server-rendered style elements\n document.querySelectorAll(\"style[data-emotion^=\\\"\" + key + \" \\\"]\"), function (node) {\n var attrib = node.getAttribute(\"data-emotion\").split(' '); // $FlowFixMe\n\n for (var i = 1; i < attrib.length; i++) {\n inserted[attrib[i]] = true;\n }\n\n nodesToHydrate.push(node);\n });\n }\n\n var _insert;\n\n var omnipresentPlugins = [compat, removeLabel];\n\n if (process.env.NODE_ENV !== 'production') {\n omnipresentPlugins.push(createUnsafeSelectorsAlarm({\n get compat() {\n return cache.compat;\n }\n\n }), incorrectImportAlarm);\n }\n\n {\n var currentSheet;\n var finalizingPlugins = [stringify, process.env.NODE_ENV !== 'production' ? function (element) {\n if (!element.root) {\n if (element[\"return\"]) {\n currentSheet.insert(element[\"return\"]);\n } else if (element.value && element.type !== COMMENT) {\n // insert empty rule in non-production environments\n // so @emotion/jest can grab `key` from the (JS)DOM for caches without any rules inserted yet\n currentSheet.insert(element.value + \"{}\");\n }\n }\n } : rulesheet(function (rule) {\n currentSheet.insert(rule);\n })];\n var serializer = middleware(omnipresentPlugins.concat(stylisPlugins, finalizingPlugins));\n\n var stylis = function stylis(styles) {\n return serialize(compile(styles), serializer);\n };\n\n _insert = function insert(selector, serialized, sheet, shouldCache) {\n currentSheet = sheet;\n\n if (process.env.NODE_ENV !== 'production' && serialized.map !== undefined) {\n currentSheet = {\n insert: function insert(rule) {\n sheet.insert(rule + serialized.map);\n }\n };\n }\n\n stylis(selector ? selector + \"{\" + serialized.styles + \"}\" : serialized.styles);\n\n if (shouldCache) {\n cache.inserted[serialized.name] = true;\n }\n };\n }\n\n var cache = {\n key: key,\n sheet: new StyleSheet({\n key: key,\n container: container,\n nonce: options.nonce,\n speedy: options.speedy,\n prepend: options.prepend,\n insertionPoint: options.insertionPoint\n }),\n nonce: options.nonce,\n inserted: inserted,\n registered: {},\n insert: _insert\n };\n cache.sheet.hydrate(nodesToHydrate);\n return cache;\n};\n\nexport { createCache as default };\n","import {MS, MOZ, WEBKIT, RULESET, KEYFRAMES, DECLARATION} from './Enum.js'\nimport {match, charat, substr, strlen, sizeof, replace, combine} from './Utility.js'\nimport {copy, tokenize} from './Tokenizer.js'\nimport {serialize} from './Serializer.js'\nimport {prefix} from './Prefixer.js'\n\n/**\n * @param {function[]} collection\n * @return {function}\n */\nexport function middleware (collection) {\n\tvar length = sizeof(collection)\n\n\treturn function (element, index, children, callback) {\n\t\tvar output = ''\n\n\t\tfor (var i = 0; i < length; i++)\n\t\t\toutput += collection[i](element, index, children, callback) || ''\n\n\t\treturn output\n\t}\n}\n\n/**\n * @param {function} callback\n * @return {function}\n */\nexport function rulesheet (callback) {\n\treturn function (element) {\n\t\tif (!element.root)\n\t\t\tif (element = element.return)\n\t\t\t\tcallback(element)\n\t}\n}\n\n/**\n * @param {object} element\n * @param {number} index\n * @param {object[]} children\n * @param {function} callback\n */\nexport function prefixer (element, index, children, callback) {\n\tif (element.length > -1)\n\t\tif (!element.return)\n\t\t\tswitch (element.type) {\n\t\t\t\tcase DECLARATION: element.return = prefix(element.value, element.length, children)\n\t\t\t\t\treturn\n\t\t\t\tcase KEYFRAMES:\n\t\t\t\t\treturn serialize([copy(element, {value: replace(element.value, '@', '@' + WEBKIT)})], callback)\n\t\t\t\tcase RULESET:\n\t\t\t\t\tif (element.length)\n\t\t\t\t\t\treturn combine(element.props, function (value) {\n\t\t\t\t\t\t\tswitch (match(value, /(::plac\\w+|:read-\\w+)/)) {\n\t\t\t\t\t\t\t\t// :read-(only|write)\n\t\t\t\t\t\t\t\tcase ':read-only': case ':read-write':\n\t\t\t\t\t\t\t\t\treturn serialize([copy(element, {props: [replace(value, /:(read-\\w+)/, ':' + MOZ + '$1')]})], callback)\n\t\t\t\t\t\t\t\t// :placeholder\n\t\t\t\t\t\t\t\tcase '::placeholder':\n\t\t\t\t\t\t\t\t\treturn serialize([\n\t\t\t\t\t\t\t\t\t\tcopy(element, {props: [replace(value, /:(plac\\w+)/, ':' + WEBKIT + 'input-$1')]}),\n\t\t\t\t\t\t\t\t\t\tcopy(element, {props: [replace(value, /:(plac\\w+)/, ':' + MOZ + '$1')]}),\n\t\t\t\t\t\t\t\t\t\tcopy(element, {props: [replace(value, /:(plac\\w+)/, MS + 'input-$1')]})\n\t\t\t\t\t\t\t\t\t], callback)\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\treturn ''\n\t\t\t\t\t\t})\n\t\t\t}\n}\n\n/**\n * @param {object} element\n * @param {number} index\n * @param {object[]} children\n */\nexport function namespace (element) {\n\tswitch (element.type) {\n\t\tcase RULESET:\n\t\t\telement.props = element.props.map(function (value) {\n\t\t\t\treturn combine(tokenize(value), function (value, index, children) {\n\t\t\t\t\tswitch (charat(value, 0)) {\n\t\t\t\t\t\t// \\f\n\t\t\t\t\t\tcase 12:\n\t\t\t\t\t\t\treturn substr(value, 1, strlen(value))\n\t\t\t\t\t\t// \\0 ( + > ~\n\t\t\t\t\t\tcase 0: case 40: case 43: case 62: case 126:\n\t\t\t\t\t\t\treturn value\n\t\t\t\t\t\t// :\n\t\t\t\t\t\tcase 58:\n\t\t\t\t\t\t\tif (children[++index] === 'global')\n\t\t\t\t\t\t\t\tchildren[index] = '', children[++index] = '\\f' + substr(children[index], index = 1, -1)\n\t\t\t\t\t\t// \\s\n\t\t\t\t\t\tcase 32:\n\t\t\t\t\t\t\treturn index === 1 ? '' : value\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tswitch (index) {\n\t\t\t\t\t\t\t\tcase 0: element = value\n\t\t\t\t\t\t\t\t\treturn sizeof(children) > 1 ? '' : value\n\t\t\t\t\t\t\t\tcase index = sizeof(children) - 1: case 2:\n\t\t\t\t\t\t\t\t\treturn index === 2 ? value + element + element : value + element\n\t\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t\treturn value\n\t\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t})\n\t}\n}\n","var isBrowser = \"object\" !== 'undefined';\nfunction getRegisteredStyles(registered, registeredStyles, classNames) {\n var rawClassName = '';\n classNames.split(' ').forEach(function (className) {\n if (registered[className] !== undefined) {\n registeredStyles.push(registered[className] + \";\");\n } else {\n rawClassName += className + \" \";\n }\n });\n return rawClassName;\n}\nvar registerStyles = function registerStyles(cache, serialized, isStringTag) {\n var className = cache.key + \"-\" + serialized.name;\n\n if ( // we only need to add the styles to the registered cache if the\n // class name could be used further down\n // the tree but if it's a string tag, we know it won't\n // so we don't have to add it to registered cache.\n // this improves memory usage since we can avoid storing the whole style string\n (isStringTag === false || // we need to always store it if we're in compat mode and\n // in node since emotion-server relies on whether a style is in\n // the registered cache to know whether a style is global or not\n // also, note that this check will be dead code eliminated in the browser\n isBrowser === false ) && cache.registered[className] === undefined) {\n cache.registered[className] = serialized.styles;\n }\n};\nvar insertStyles = function insertStyles(cache, serialized, isStringTag) {\n registerStyles(cache, serialized, isStringTag);\n var className = cache.key + \"-\" + serialized.name;\n\n if (cache.inserted[serialized.name] === undefined) {\n var current = serialized;\n\n do {\n cache.insert(serialized === current ? \".\" + className : '', current, cache.sheet, true);\n\n current = current.next;\n } while (current !== undefined);\n }\n};\n\nexport { getRegisteredStyles, insertStyles, registerStyles };\n","var unitlessKeys = {\n animationIterationCount: 1,\n aspectRatio: 1,\n borderImageOutset: 1,\n borderImageSlice: 1,\n borderImageWidth: 1,\n boxFlex: 1,\n boxFlexGroup: 1,\n boxOrdinalGroup: 1,\n columnCount: 1,\n columns: 1,\n flex: 1,\n flexGrow: 1,\n flexPositive: 1,\n flexShrink: 1,\n flexNegative: 1,\n flexOrder: 1,\n gridRow: 1,\n gridRowEnd: 1,\n gridRowSpan: 1,\n gridRowStart: 1,\n gridColumn: 1,\n gridColumnEnd: 1,\n gridColumnSpan: 1,\n gridColumnStart: 1,\n msGridRow: 1,\n msGridRowSpan: 1,\n msGridColumn: 1,\n msGridColumnSpan: 1,\n fontWeight: 1,\n lineHeight: 1,\n opacity: 1,\n order: 1,\n orphans: 1,\n tabSize: 1,\n widows: 1,\n zIndex: 1,\n zoom: 1,\n WebkitLineClamp: 1,\n // SVG-related properties\n fillOpacity: 1,\n floodOpacity: 1,\n stopOpacity: 1,\n strokeDasharray: 1,\n strokeDashoffset: 1,\n strokeMiterlimit: 1,\n strokeOpacity: 1,\n strokeWidth: 1\n};\n\nexport { unitlessKeys as default };\n","function memoize(fn) {\n var cache = Object.create(null);\n return function (arg) {\n if (cache[arg] === undefined) cache[arg] = fn(arg);\n return cache[arg];\n };\n}\n\nexport { memoize as default };\n","import hashString from '@emotion/hash';\nimport unitless from '@emotion/unitless';\nimport memoize from '@emotion/memoize';\n\nvar ILLEGAL_ESCAPE_SEQUENCE_ERROR = \"You have illegal escape sequence in your template literal, most likely inside content's property value.\\nBecause you write your CSS inside a JavaScript string you actually have to do double escaping, so for example \\\"content: '\\\\00d7';\\\" should become \\\"content: '\\\\\\\\00d7';\\\".\\nYou can read more about this here:\\nhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#ES2018_revision_of_illegal_escape_sequences\";\nvar UNDEFINED_AS_OBJECT_KEY_ERROR = \"You have passed in falsy value as style object's key (can happen when in example you pass unexported component as computed key).\";\nvar hyphenateRegex = /[A-Z]|^ms/g;\nvar animationRegex = /_EMO_([^_]+?)_([^]*?)_EMO_/g;\n\nvar isCustomProperty = function isCustomProperty(property) {\n return property.charCodeAt(1) === 45;\n};\n\nvar isProcessableValue = function isProcessableValue(value) {\n return value != null && typeof value !== 'boolean';\n};\n\nvar processStyleName = /* #__PURE__ */memoize(function (styleName) {\n return isCustomProperty(styleName) ? styleName : styleName.replace(hyphenateRegex, '-$&').toLowerCase();\n});\n\nvar processStyleValue = function processStyleValue(key, value) {\n switch (key) {\n case 'animation':\n case 'animationName':\n {\n if (typeof value === 'string') {\n return value.replace(animationRegex, function (match, p1, p2) {\n cursor = {\n name: p1,\n styles: p2,\n next: cursor\n };\n return p1;\n });\n }\n }\n }\n\n if (unitless[key] !== 1 && !isCustomProperty(key) && typeof value === 'number' && value !== 0) {\n return value + 'px';\n }\n\n return value;\n};\n\nif (process.env.NODE_ENV !== 'production') {\n var contentValuePattern = /(var|attr|counters?|url|element|(((repeating-)?(linear|radial))|conic)-gradient)\\(|(no-)?(open|close)-quote/;\n var contentValues = ['normal', 'none', 'initial', 'inherit', 'unset'];\n var oldProcessStyleValue = processStyleValue;\n var msPattern = /^-ms-/;\n var hyphenPattern = /-(.)/g;\n var hyphenatedCache = {};\n\n processStyleValue = function processStyleValue(key, value) {\n if (key === 'content') {\n if (typeof value !== 'string' || contentValues.indexOf(value) === -1 && !contentValuePattern.test(value) && (value.charAt(0) !== value.charAt(value.length - 1) || value.charAt(0) !== '\"' && value.charAt(0) !== \"'\")) {\n throw new Error(\"You seem to be using a value for 'content' without quotes, try replacing it with `content: '\\\"\" + value + \"\\\"'`\");\n }\n }\n\n var processed = oldProcessStyleValue(key, value);\n\n if (processed !== '' && !isCustomProperty(key) && key.indexOf('-') !== -1 && hyphenatedCache[key] === undefined) {\n hyphenatedCache[key] = true;\n console.error(\"Using kebab-case for css properties in objects is not supported. Did you mean \" + key.replace(msPattern, 'ms-').replace(hyphenPattern, function (str, _char) {\n return _char.toUpperCase();\n }) + \"?\");\n }\n\n return processed;\n };\n}\n\nvar noComponentSelectorMessage = 'Component selectors can only be used in conjunction with ' + '@emotion/babel-plugin, the swc Emotion plugin, or another Emotion-aware ' + 'compiler transform.';\n\nfunction handleInterpolation(mergedProps, registered, interpolation) {\n if (interpolation == null) {\n return '';\n }\n\n if (interpolation.__emotion_styles !== undefined) {\n if (process.env.NODE_ENV !== 'production' && interpolation.toString() === 'NO_COMPONENT_SELECTOR') {\n throw new Error(noComponentSelectorMessage);\n }\n\n return interpolation;\n }\n\n switch (typeof interpolation) {\n case 'boolean':\n {\n return '';\n }\n\n case 'object':\n {\n if (interpolation.anim === 1) {\n cursor = {\n name: interpolation.name,\n styles: interpolation.styles,\n next: cursor\n };\n return interpolation.name;\n }\n\n if (interpolation.styles !== undefined) {\n var next = interpolation.next;\n\n if (next !== undefined) {\n // not the most efficient thing ever but this is a pretty rare case\n // and there will be very few iterations of this generally\n while (next !== undefined) {\n cursor = {\n name: next.name,\n styles: next.styles,\n next: cursor\n };\n next = next.next;\n }\n }\n\n var styles = interpolation.styles + \";\";\n\n if (process.env.NODE_ENV !== 'production' && interpolation.map !== undefined) {\n styles += interpolation.map;\n }\n\n return styles;\n }\n\n return createStringFromObject(mergedProps, registered, interpolation);\n }\n\n case 'function':\n {\n if (mergedProps !== undefined) {\n var previousCursor = cursor;\n var result = interpolation(mergedProps);\n cursor = previousCursor;\n return handleInterpolation(mergedProps, registered, result);\n } else if (process.env.NODE_ENV !== 'production') {\n console.error('Functions that are interpolated in css calls will be stringified.\\n' + 'If you want to have a css call based on props, create a function that returns a css call like this\\n' + 'let dynamicStyle = (props) => css`color: ${props.color}`\\n' + 'It can be called directly with props or interpolated in a styled call like this\\n' + \"let SomeComponent = styled('div')`${dynamicStyle}`\");\n }\n\n break;\n }\n\n case 'string':\n if (process.env.NODE_ENV !== 'production') {\n var matched = [];\n var replaced = interpolation.replace(animationRegex, function (match, p1, p2) {\n var fakeVarName = \"animation\" + matched.length;\n matched.push(\"const \" + fakeVarName + \" = keyframes`\" + p2.replace(/^@keyframes animation-\\w+/, '') + \"`\");\n return \"${\" + fakeVarName + \"}\";\n });\n\n if (matched.length) {\n console.error('`keyframes` output got interpolated into plain string, please wrap it with `css`.\\n\\n' + 'Instead of doing this:\\n\\n' + [].concat(matched, [\"`\" + replaced + \"`\"]).join('\\n') + '\\n\\nYou should wrap it with `css` like this:\\n\\n' + (\"css`\" + replaced + \"`\"));\n }\n }\n\n break;\n } // finalize string values (regular strings and functions interpolated into css calls)\n\n\n if (registered == null) {\n return interpolation;\n }\n\n var cached = registered[interpolation];\n return cached !== undefined ? cached : interpolation;\n}\n\nfunction createStringFromObject(mergedProps, registered, obj) {\n var string = '';\n\n if (Array.isArray(obj)) {\n for (var i = 0; i < obj.length; i++) {\n string += handleInterpolation(mergedProps, registered, obj[i]) + \";\";\n }\n } else {\n for (var _key in obj) {\n var value = obj[_key];\n\n if (typeof value !== 'object') {\n if (registered != null && registered[value] !== undefined) {\n string += _key + \"{\" + registered[value] + \"}\";\n } else if (isProcessableValue(value)) {\n string += processStyleName(_key) + \":\" + processStyleValue(_key, value) + \";\";\n }\n } else {\n if (_key === 'NO_COMPONENT_SELECTOR' && process.env.NODE_ENV !== 'production') {\n throw new Error(noComponentSelectorMessage);\n }\n\n if (Array.isArray(value) && typeof value[0] === 'string' && (registered == null || registered[value[0]] === undefined)) {\n for (var _i = 0; _i < value.length; _i++) {\n if (isProcessableValue(value[_i])) {\n string += processStyleName(_key) + \":\" + processStyleValue(_key, value[_i]) + \";\";\n }\n }\n } else {\n var interpolated = handleInterpolation(mergedProps, registered, value);\n\n switch (_key) {\n case 'animation':\n case 'animationName':\n {\n string += processStyleName(_key) + \":\" + interpolated + \";\";\n break;\n }\n\n default:\n {\n if (process.env.NODE_ENV !== 'production' && _key === 'undefined') {\n console.error(UNDEFINED_AS_OBJECT_KEY_ERROR);\n }\n\n string += _key + \"{\" + interpolated + \"}\";\n }\n }\n }\n }\n }\n }\n\n return string;\n}\n\nvar labelPattern = /label:\\s*([^\\s;\\n{]+)\\s*(;|$)/g;\nvar sourceMapPattern;\n\nif (process.env.NODE_ENV !== 'production') {\n sourceMapPattern = /\\/\\*#\\ssourceMappingURL=data:application\\/json;\\S+\\s+\\*\\//g;\n} // this is the cursor for keyframes\n// keyframes are stored on the SerializedStyles object as a linked list\n\n\nvar cursor;\nvar serializeStyles = function serializeStyles(args, registered, mergedProps) {\n if (args.length === 1 && typeof args[0] === 'object' && args[0] !== null && args[0].styles !== undefined) {\n return args[0];\n }\n\n var stringMode = true;\n var styles = '';\n cursor = undefined;\n var strings = args[0];\n\n if (strings == null || strings.raw === undefined) {\n stringMode = false;\n styles += handleInterpolation(mergedProps, registered, strings);\n } else {\n if (process.env.NODE_ENV !== 'production' && strings[0] === undefined) {\n console.error(ILLEGAL_ESCAPE_SEQUENCE_ERROR);\n }\n\n styles += strings[0];\n } // we start at 1 since we've already handled the first arg\n\n\n for (var i = 1; i < args.length; i++) {\n styles += handleInterpolation(mergedProps, registered, args[i]);\n\n if (stringMode) {\n if (process.env.NODE_ENV !== 'production' && strings[i] === undefined) {\n console.error(ILLEGAL_ESCAPE_SEQUENCE_ERROR);\n }\n\n styles += strings[i];\n }\n }\n\n var sourceMap;\n\n if (process.env.NODE_ENV !== 'production') {\n styles = styles.replace(sourceMapPattern, function (match) {\n sourceMap = match;\n return '';\n });\n } // using a global regex with .exec is stateful so lastIndex has to be reset each time\n\n\n labelPattern.lastIndex = 0;\n var identifierName = '';\n var match; // https://esbench.com/bench/5b809c2cf2949800a0f61fb5\n\n while ((match = labelPattern.exec(styles)) !== null) {\n identifierName += '-' + // $FlowFixMe we know it's not null\n match[1];\n }\n\n var name = hashString(styles) + identifierName;\n\n if (process.env.NODE_ENV !== 'production') {\n // $FlowFixMe SerializedStyles type doesn't have toString property (and we don't want to add it)\n return {\n name: name,\n styles: styles,\n map: sourceMap,\n next: cursor,\n toString: function toString() {\n return \"You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop).\";\n }\n };\n }\n\n return {\n name: name,\n styles: styles,\n next: cursor\n };\n};\n\nexport { serializeStyles };\n","/* eslint-disable */\n// Inspired by https://github.com/garycourt/murmurhash-js\n// Ported from https://github.com/aappleby/smhasher/blob/61a0530f28277f2e850bfc39600ce61d02b518de/src/MurmurHash2.cpp#L37-L86\nfunction murmur2(str) {\n // 'm' and 'r' are mixing constants generated offline.\n // They're not really 'magic', they just happen to work well.\n // const m = 0x5bd1e995;\n // const r = 24;\n // Initialize the hash\n var h = 0; // Mix 4 bytes at a time into the hash\n\n var k,\n i = 0,\n len = str.length;\n\n for (; len >= 4; ++i, len -= 4) {\n k = str.charCodeAt(i) & 0xff | (str.charCodeAt(++i) & 0xff) << 8 | (str.charCodeAt(++i) & 0xff) << 16 | (str.charCodeAt(++i) & 0xff) << 24;\n k =\n /* Math.imul(k, m): */\n (k & 0xffff) * 0x5bd1e995 + ((k >>> 16) * 0xe995 << 16);\n k ^=\n /* k >>> r: */\n k >>> 24;\n h =\n /* Math.imul(k, m): */\n (k & 0xffff) * 0x5bd1e995 + ((k >>> 16) * 0xe995 << 16) ^\n /* Math.imul(h, m): */\n (h & 0xffff) * 0x5bd1e995 + ((h >>> 16) * 0xe995 << 16);\n } // Handle the last few bytes of the input array\n\n\n switch (len) {\n case 3:\n h ^= (str.charCodeAt(i + 2) & 0xff) << 16;\n\n case 2:\n h ^= (str.charCodeAt(i + 1) & 0xff) << 8;\n\n case 1:\n h ^= str.charCodeAt(i) & 0xff;\n h =\n /* Math.imul(h, m): */\n (h & 0xffff) * 0x5bd1e995 + ((h >>> 16) * 0xe995 << 16);\n } // Do a few final mixes of the hash to ensure the last few\n // bytes are well-incorporated.\n\n\n h ^= h >>> 13;\n h =\n /* Math.imul(h, m): */\n (h & 0xffff) * 0x5bd1e995 + ((h >>> 16) * 0xe995 << 16);\n return ((h ^ h >>> 15) >>> 0).toString(36);\n}\n\nexport { murmur2 as default };\n","import * as React from 'react';\n\nvar syncFallback = function syncFallback(create) {\n return create();\n};\n\nvar useInsertionEffect = React['useInsertion' + 'Effect'] ? React['useInsertion' + 'Effect'] : false;\nvar useInsertionEffectAlwaysWithSyncFallback = useInsertionEffect || syncFallback;\nvar useInsertionEffectWithLayoutFallback = useInsertionEffect || React.useLayoutEffect;\n\nexport { useInsertionEffectAlwaysWithSyncFallback, useInsertionEffectWithLayoutFallback };\n","import * as React from 'react';\nimport { useContext, forwardRef } from 'react';\nimport createCache from '@emotion/cache';\nimport _extends from '@babel/runtime/helpers/esm/extends';\nimport weakMemoize from '@emotion/weak-memoize';\nimport hoistNonReactStatics from '../_isolated-hnrs/dist/emotion-react-_isolated-hnrs.browser.esm.js';\nimport { getRegisteredStyles, registerStyles, insertStyles } from '@emotion/utils';\nimport { serializeStyles } from '@emotion/serialize';\nimport { useInsertionEffectAlwaysWithSyncFallback } from '@emotion/use-insertion-effect-with-fallbacks';\n\nvar isBrowser = \"object\" !== 'undefined';\nvar hasOwnProperty = {}.hasOwnProperty;\n\nvar EmotionCacheContext = /* #__PURE__ */React.createContext( // we're doing this to avoid preconstruct's dead code elimination in this one case\n// because this module is primarily intended for the browser and node\n// but it's also required in react native and similar environments sometimes\n// and we could have a special build just for that\n// but this is much easier and the native packages\n// might use a different theme context in the future anyway\ntypeof HTMLElement !== 'undefined' ? /* #__PURE__ */createCache({\n key: 'css'\n}) : null);\n\nif (process.env.NODE_ENV !== 'production') {\n EmotionCacheContext.displayName = 'EmotionCacheContext';\n}\n\nvar CacheProvider = EmotionCacheContext.Provider;\nvar __unsafe_useEmotionCache = function useEmotionCache() {\n return useContext(EmotionCacheContext);\n};\n\nvar withEmotionCache = function withEmotionCache(func) {\n // $FlowFixMe\n return /*#__PURE__*/forwardRef(function (props, ref) {\n // the cache will never be null in the browser\n var cache = useContext(EmotionCacheContext);\n return func(props, cache, ref);\n });\n};\n\nif (!isBrowser) {\n withEmotionCache = function withEmotionCache(func) {\n return function (props) {\n var cache = useContext(EmotionCacheContext);\n\n if (cache === null) {\n // yes, we're potentially creating this on every render\n // it doesn't actually matter though since it's only on the server\n // so there will only every be a single render\n // that could change in the future because of suspense and etc. but for now,\n // this works and i don't want to optimise for a future thing that we aren't sure about\n cache = createCache({\n key: 'css'\n });\n return /*#__PURE__*/React.createElement(EmotionCacheContext.Provider, {\n value: cache\n }, func(props, cache));\n } else {\n return func(props, cache);\n }\n };\n };\n}\n\nvar ThemeContext = /* #__PURE__ */React.createContext({});\n\nif (process.env.NODE_ENV !== 'production') {\n ThemeContext.displayName = 'EmotionThemeContext';\n}\n\nvar useTheme = function useTheme() {\n return React.useContext(ThemeContext);\n};\n\nvar getTheme = function getTheme(outerTheme, theme) {\n if (typeof theme === 'function') {\n var mergedTheme = theme(outerTheme);\n\n if (process.env.NODE_ENV !== 'production' && (mergedTheme == null || typeof mergedTheme !== 'object' || Array.isArray(mergedTheme))) {\n throw new Error('[ThemeProvider] Please return an object from your theme function, i.e. theme={() => ({})}!');\n }\n\n return mergedTheme;\n }\n\n if (process.env.NODE_ENV !== 'production' && (theme == null || typeof theme !== 'object' || Array.isArray(theme))) {\n throw new Error('[ThemeProvider] Please make your theme prop a plain object');\n }\n\n return _extends({}, outerTheme, theme);\n};\n\nvar createCacheWithTheme = /* #__PURE__ */weakMemoize(function (outerTheme) {\n return weakMemoize(function (theme) {\n return getTheme(outerTheme, theme);\n });\n});\nvar ThemeProvider = function ThemeProvider(props) {\n var theme = React.useContext(ThemeContext);\n\n if (props.theme !== theme) {\n theme = createCacheWithTheme(theme)(props.theme);\n }\n\n return /*#__PURE__*/React.createElement(ThemeContext.Provider, {\n value: theme\n }, props.children);\n};\nfunction withTheme(Component) {\n var componentName = Component.displayName || Component.name || 'Component';\n\n var render = function render(props, ref) {\n var theme = React.useContext(ThemeContext);\n return /*#__PURE__*/React.createElement(Component, _extends({\n theme: theme,\n ref: ref\n }, props));\n }; // $FlowFixMe\n\n\n var WithTheme = /*#__PURE__*/React.forwardRef(render);\n WithTheme.displayName = \"WithTheme(\" + componentName + \")\";\n return hoistNonReactStatics(WithTheme, Component);\n}\n\nvar getLastPart = function getLastPart(functionName) {\n // The match may be something like 'Object.createEmotionProps' or\n // 'Loader.prototype.render'\n var parts = functionName.split('.');\n return parts[parts.length - 1];\n};\n\nvar getFunctionNameFromStackTraceLine = function getFunctionNameFromStackTraceLine(line) {\n // V8\n var match = /^\\s+at\\s+([A-Za-z0-9$.]+)\\s/.exec(line);\n if (match) return getLastPart(match[1]); // Safari / Firefox\n\n match = /^([A-Za-z0-9$.]+)@/.exec(line);\n if (match) return getLastPart(match[1]);\n return undefined;\n};\n\nvar internalReactFunctionNames = /* #__PURE__ */new Set(['renderWithHooks', 'processChild', 'finishClassComponent', 'renderToString']); // These identifiers come from error stacks, so they have to be valid JS\n// identifiers, thus we only need to replace what is a valid character for JS,\n// but not for CSS.\n\nvar sanitizeIdentifier = function sanitizeIdentifier(identifier) {\n return identifier.replace(/\\$/g, '-');\n};\n\nvar getLabelFromStackTrace = function getLabelFromStackTrace(stackTrace) {\n if (!stackTrace) return undefined;\n var lines = stackTrace.split('\\n');\n\n for (var i = 0; i < lines.length; i++) {\n var functionName = getFunctionNameFromStackTraceLine(lines[i]); // The first line of V8 stack traces is just \"Error\"\n\n if (!functionName) continue; // If we reach one of these, we have gone too far and should quit\n\n if (internalReactFunctionNames.has(functionName)) break; // The component name is the first function in the stack that starts with an\n // uppercase letter\n\n if (/^[A-Z]/.test(functionName)) return sanitizeIdentifier(functionName);\n }\n\n return undefined;\n};\n\nvar typePropName = '__EMOTION_TYPE_PLEASE_DO_NOT_USE__';\nvar labelPropName = '__EMOTION_LABEL_PLEASE_DO_NOT_USE__';\nvar createEmotionProps = function createEmotionProps(type, props) {\n if (process.env.NODE_ENV !== 'production' && typeof props.css === 'string' && // check if there is a css declaration\n props.css.indexOf(':') !== -1) {\n throw new Error(\"Strings are not allowed as css prop values, please wrap it in a css template literal from '@emotion/react' like this: css`\" + props.css + \"`\");\n }\n\n var newProps = {};\n\n for (var key in props) {\n if (hasOwnProperty.call(props, key)) {\n newProps[key] = props[key];\n }\n }\n\n newProps[typePropName] = type; // For performance, only call getLabelFromStackTrace in development and when\n // the label hasn't already been computed\n\n if (process.env.NODE_ENV !== 'production' && !!props.css && (typeof props.css !== 'object' || typeof props.css.name !== 'string' || props.css.name.indexOf('-') === -1)) {\n var label = getLabelFromStackTrace(new Error().stack);\n if (label) newProps[labelPropName] = label;\n }\n\n return newProps;\n};\n\nvar Insertion = function Insertion(_ref) {\n var cache = _ref.cache,\n serialized = _ref.serialized,\n isStringTag = _ref.isStringTag;\n registerStyles(cache, serialized, isStringTag);\n useInsertionEffectAlwaysWithSyncFallback(function () {\n return insertStyles(cache, serialized, isStringTag);\n });\n\n return null;\n};\n\nvar Emotion = /* #__PURE__ */withEmotionCache(function (props, cache, ref) {\n var cssProp = props.css; // so that using `css` from `emotion` and passing the result to the css prop works\n // not passing the registered cache to serializeStyles because it would\n // make certain babel optimisations not possible\n\n if (typeof cssProp === 'string' && cache.registered[cssProp] !== undefined) {\n cssProp = cache.registered[cssProp];\n }\n\n var WrappedComponent = props[typePropName];\n var registeredStyles = [cssProp];\n var className = '';\n\n if (typeof props.className === 'string') {\n className = getRegisteredStyles(cache.registered, registeredStyles, props.className);\n } else if (props.className != null) {\n className = props.className + \" \";\n }\n\n var serialized = serializeStyles(registeredStyles, undefined, React.useContext(ThemeContext));\n\n if (process.env.NODE_ENV !== 'production' && serialized.name.indexOf('-') === -1) {\n var labelFromStack = props[labelPropName];\n\n if (labelFromStack) {\n serialized = serializeStyles([serialized, 'label:' + labelFromStack + ';']);\n }\n }\n\n className += cache.key + \"-\" + serialized.name;\n var newProps = {};\n\n for (var key in props) {\n if (hasOwnProperty.call(props, key) && key !== 'css' && key !== typePropName && (process.env.NODE_ENV === 'production' || key !== labelPropName)) {\n newProps[key] = props[key];\n }\n }\n\n newProps.ref = ref;\n newProps.className = className;\n return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Insertion, {\n cache: cache,\n serialized: serialized,\n isStringTag: typeof WrappedComponent === 'string'\n }), /*#__PURE__*/React.createElement(WrappedComponent, newProps));\n});\n\nif (process.env.NODE_ENV !== 'production') {\n Emotion.displayName = 'EmotionCssPropInternal';\n}\n\nvar Emotion$1 = Emotion;\n\nexport { CacheProvider as C, Emotion$1 as E, ThemeContext as T, __unsafe_useEmotionCache as _, ThemeProvider as a, withTheme as b, createEmotionProps as c, hasOwnProperty as h, isBrowser as i, useTheme as u, withEmotionCache as w };\n","import { h as hasOwnProperty, E as Emotion, c as createEmotionProps, w as withEmotionCache, T as ThemeContext, i as isBrowser$1 } from './emotion-element-c39617d8.browser.esm.js';\nexport { C as CacheProvider, T as ThemeContext, a as ThemeProvider, _ as __unsafe_useEmotionCache, u as useTheme, w as withEmotionCache, b as withTheme } from './emotion-element-c39617d8.browser.esm.js';\nimport * as React from 'react';\nimport { insertStyles, registerStyles, getRegisteredStyles } from '@emotion/utils';\nimport { useInsertionEffectWithLayoutFallback, useInsertionEffectAlwaysWithSyncFallback } from '@emotion/use-insertion-effect-with-fallbacks';\nimport { serializeStyles } from '@emotion/serialize';\nimport '@emotion/cache';\nimport '@babel/runtime/helpers/extends';\nimport '@emotion/weak-memoize';\nimport '../_isolated-hnrs/dist/emotion-react-_isolated-hnrs.browser.esm.js';\nimport 'hoist-non-react-statics';\n\nvar pkg = {\n\tname: \"@emotion/react\",\n\tversion: \"11.11.0\",\n\tmain: \"dist/emotion-react.cjs.js\",\n\tmodule: \"dist/emotion-react.esm.js\",\n\tbrowser: {\n\t\t\"./dist/emotion-react.esm.js\": \"./dist/emotion-react.browser.esm.js\"\n\t},\n\texports: {\n\t\t\".\": {\n\t\t\tmodule: {\n\t\t\t\tworker: \"./dist/emotion-react.worker.esm.js\",\n\t\t\t\tbrowser: \"./dist/emotion-react.browser.esm.js\",\n\t\t\t\t\"default\": \"./dist/emotion-react.esm.js\"\n\t\t\t},\n\t\t\t\"import\": \"./dist/emotion-react.cjs.mjs\",\n\t\t\t\"default\": \"./dist/emotion-react.cjs.js\"\n\t\t},\n\t\t\"./jsx-runtime\": {\n\t\t\tmodule: {\n\t\t\t\tworker: \"./jsx-runtime/dist/emotion-react-jsx-runtime.worker.esm.js\",\n\t\t\t\tbrowser: \"./jsx-runtime/dist/emotion-react-jsx-runtime.browser.esm.js\",\n\t\t\t\t\"default\": \"./jsx-runtime/dist/emotion-react-jsx-runtime.esm.js\"\n\t\t\t},\n\t\t\t\"import\": \"./jsx-runtime/dist/emotion-react-jsx-runtime.cjs.mjs\",\n\t\t\t\"default\": \"./jsx-runtime/dist/emotion-react-jsx-runtime.cjs.js\"\n\t\t},\n\t\t\"./_isolated-hnrs\": {\n\t\t\tmodule: {\n\t\t\t\tworker: \"./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.worker.esm.js\",\n\t\t\t\tbrowser: \"./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.browser.esm.js\",\n\t\t\t\t\"default\": \"./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.esm.js\"\n\t\t\t},\n\t\t\t\"import\": \"./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.cjs.mjs\",\n\t\t\t\"default\": \"./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.cjs.js\"\n\t\t},\n\t\t\"./jsx-dev-runtime\": {\n\t\t\tmodule: {\n\t\t\t\tworker: \"./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.worker.esm.js\",\n\t\t\t\tbrowser: \"./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.browser.esm.js\",\n\t\t\t\t\"default\": \"./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.esm.js\"\n\t\t\t},\n\t\t\t\"import\": \"./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.cjs.mjs\",\n\t\t\t\"default\": \"./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.cjs.js\"\n\t\t},\n\t\t\"./package.json\": \"./package.json\",\n\t\t\"./types/css-prop\": \"./types/css-prop.d.ts\",\n\t\t\"./macro\": {\n\t\t\ttypes: {\n\t\t\t\t\"import\": \"./macro.d.mts\",\n\t\t\t\t\"default\": \"./macro.d.ts\"\n\t\t\t},\n\t\t\t\"default\": \"./macro.js\"\n\t\t}\n\t},\n\ttypes: \"types/index.d.ts\",\n\tfiles: [\n\t\t\"src\",\n\t\t\"dist\",\n\t\t\"jsx-runtime\",\n\t\t\"jsx-dev-runtime\",\n\t\t\"_isolated-hnrs\",\n\t\t\"types/*.d.ts\",\n\t\t\"macro.*\"\n\t],\n\tsideEffects: false,\n\tauthor: \"Emotion Contributors\",\n\tlicense: \"MIT\",\n\tscripts: {\n\t\t\"test:typescript\": \"dtslint types\"\n\t},\n\tdependencies: {\n\t\t\"@babel/runtime\": \"^7.18.3\",\n\t\t\"@emotion/babel-plugin\": \"^11.11.0\",\n\t\t\"@emotion/cache\": \"^11.11.0\",\n\t\t\"@emotion/serialize\": \"^1.1.2\",\n\t\t\"@emotion/use-insertion-effect-with-fallbacks\": \"^1.0.1\",\n\t\t\"@emotion/utils\": \"^1.2.1\",\n\t\t\"@emotion/weak-memoize\": \"^0.3.1\",\n\t\t\"hoist-non-react-statics\": \"^3.3.1\"\n\t},\n\tpeerDependencies: {\n\t\treact: \">=16.8.0\"\n\t},\n\tpeerDependenciesMeta: {\n\t\t\"@types/react\": {\n\t\t\toptional: true\n\t\t}\n\t},\n\tdevDependencies: {\n\t\t\"@definitelytyped/dtslint\": \"0.0.112\",\n\t\t\"@emotion/css\": \"11.11.0\",\n\t\t\"@emotion/css-prettifier\": \"1.1.3\",\n\t\t\"@emotion/server\": \"11.11.0\",\n\t\t\"@emotion/styled\": \"11.11.0\",\n\t\t\"html-tag-names\": \"^1.1.2\",\n\t\treact: \"16.14.0\",\n\t\t\"svg-tag-names\": \"^1.1.1\",\n\t\ttypescript: \"^4.5.5\"\n\t},\n\trepository: \"https://github.com/emotion-js/emotion/tree/main/packages/react\",\n\tpublishConfig: {\n\t\taccess: \"public\"\n\t},\n\t\"umd:main\": \"dist/emotion-react.umd.min.js\",\n\tpreconstruct: {\n\t\tentrypoints: [\n\t\t\t\"./index.js\",\n\t\t\t\"./jsx-runtime.js\",\n\t\t\t\"./jsx-dev-runtime.js\",\n\t\t\t\"./_isolated-hnrs.js\"\n\t\t],\n\t\tumdName: \"emotionReact\",\n\t\texports: {\n\t\t\tenvConditions: [\n\t\t\t\t\"browser\",\n\t\t\t\t\"worker\"\n\t\t\t],\n\t\t\textra: {\n\t\t\t\t\"./types/css-prop\": \"./types/css-prop.d.ts\",\n\t\t\t\t\"./macro\": {\n\t\t\t\t\ttypes: {\n\t\t\t\t\t\t\"import\": \"./macro.d.mts\",\n\t\t\t\t\t\t\"default\": \"./macro.d.ts\"\n\t\t\t\t\t},\n\t\t\t\t\t\"default\": \"./macro.js\"\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n};\n\nvar jsx = function jsx(type, props) {\n var args = arguments;\n\n if (props == null || !hasOwnProperty.call(props, 'css')) {\n // $FlowFixMe\n return React.createElement.apply(undefined, args);\n }\n\n var argsLength = args.length;\n var createElementArgArray = new Array(argsLength);\n createElementArgArray[0] = Emotion;\n createElementArgArray[1] = createEmotionProps(type, props);\n\n for (var i = 2; i < argsLength; i++) {\n createElementArgArray[i] = args[i];\n } // $FlowFixMe\n\n\n return React.createElement.apply(null, createElementArgArray);\n};\n\nvar warnedAboutCssPropForGlobal = false; // maintain place over rerenders.\n// initial render from browser, insertBefore context.sheet.tags[0] or if a style hasn't been inserted there yet, appendChild\n// initial client-side render from SSR, use place of hydrating tag\n\nvar Global = /* #__PURE__ */withEmotionCache(function (props, cache) {\n if (process.env.NODE_ENV !== 'production' && !warnedAboutCssPropForGlobal && ( // check for className as well since the user is\n // probably using the custom createElement which\n // means it will be turned into a className prop\n // $FlowFixMe I don't really want to add it to the type since it shouldn't be used\n props.className || props.css)) {\n console.error(\"It looks like you're using the css prop on Global, did you mean to use the styles prop instead?\");\n warnedAboutCssPropForGlobal = true;\n }\n\n var styles = props.styles;\n var serialized = serializeStyles([styles], undefined, React.useContext(ThemeContext));\n\n if (!isBrowser$1) {\n var _ref;\n\n var serializedNames = serialized.name;\n var serializedStyles = serialized.styles;\n var next = serialized.next;\n\n while (next !== undefined) {\n serializedNames += ' ' + next.name;\n serializedStyles += next.styles;\n next = next.next;\n }\n\n var shouldCache = cache.compat === true;\n var rules = cache.insert(\"\", {\n name: serializedNames,\n styles: serializedStyles\n }, cache.sheet, shouldCache);\n\n if (shouldCache) {\n return null;\n }\n\n return /*#__PURE__*/React.createElement(\"style\", (_ref = {}, _ref[\"data-emotion\"] = cache.key + \"-global \" + serializedNames, _ref.dangerouslySetInnerHTML = {\n __html: rules\n }, _ref.nonce = cache.sheet.nonce, _ref));\n } // yes, i know these hooks are used conditionally\n // but it is based on a constant that will never change at runtime\n // it's effectively like having two implementations and switching them out\n // so it's not actually breaking anything\n\n\n var sheetRef = React.useRef();\n useInsertionEffectWithLayoutFallback(function () {\n var key = cache.key + \"-global\"; // use case of https://github.com/emotion-js/emotion/issues/2675\n\n var sheet = new cache.sheet.constructor({\n key: key,\n nonce: cache.sheet.nonce,\n container: cache.sheet.container,\n speedy: cache.sheet.isSpeedy\n });\n var rehydrating = false; // $FlowFixMe\n\n var node = document.querySelector(\"style[data-emotion=\\\"\" + key + \" \" + serialized.name + \"\\\"]\");\n\n if (cache.sheet.tags.length) {\n sheet.before = cache.sheet.tags[0];\n }\n\n if (node !== null) {\n rehydrating = true; // clear the hash so this node won't be recognizable as rehydratable by other s\n\n node.setAttribute('data-emotion', key);\n sheet.hydrate([node]);\n }\n\n sheetRef.current = [sheet, rehydrating];\n return function () {\n sheet.flush();\n };\n }, [cache]);\n useInsertionEffectWithLayoutFallback(function () {\n var sheetRefCurrent = sheetRef.current;\n var sheet = sheetRefCurrent[0],\n rehydrating = sheetRefCurrent[1];\n\n if (rehydrating) {\n sheetRefCurrent[1] = false;\n return;\n }\n\n if (serialized.next !== undefined) {\n // insert keyframes\n insertStyles(cache, serialized.next, true);\n }\n\n if (sheet.tags.length) {\n // if this doesn't exist then it will be null so the style element will be appended\n var element = sheet.tags[sheet.tags.length - 1].nextElementSibling;\n sheet.before = element;\n sheet.flush();\n }\n\n cache.insert(\"\", serialized, sheet, false);\n }, [cache, serialized.name]);\n return null;\n});\n\nif (process.env.NODE_ENV !== 'production') {\n Global.displayName = 'EmotionGlobal';\n}\n\nfunction css() {\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n return serializeStyles(args);\n}\n\nvar keyframes = function keyframes() {\n var insertable = css.apply(void 0, arguments);\n var name = \"animation-\" + insertable.name; // $FlowFixMe\n\n return {\n name: name,\n styles: \"@keyframes \" + name + \"{\" + insertable.styles + \"}\",\n anim: 1,\n toString: function toString() {\n return \"_EMO_\" + this.name + \"_\" + this.styles + \"_EMO_\";\n }\n };\n};\n\nvar classnames = function classnames(args) {\n var len = args.length;\n var i = 0;\n var cls = '';\n\n for (; i < len; i++) {\n var arg = args[i];\n if (arg == null) continue;\n var toAdd = void 0;\n\n switch (typeof arg) {\n case 'boolean':\n break;\n\n case 'object':\n {\n if (Array.isArray(arg)) {\n toAdd = classnames(arg);\n } else {\n if (process.env.NODE_ENV !== 'production' && arg.styles !== undefined && arg.name !== undefined) {\n console.error('You have passed styles created with `css` from `@emotion/react` package to the `cx`.\\n' + '`cx` is meant to compose class names (strings) so you should convert those styles to a class name by passing them to the `css` received from component.');\n }\n\n toAdd = '';\n\n for (var k in arg) {\n if (arg[k] && k) {\n toAdd && (toAdd += ' ');\n toAdd += k;\n }\n }\n }\n\n break;\n }\n\n default:\n {\n toAdd = arg;\n }\n }\n\n if (toAdd) {\n cls && (cls += ' ');\n cls += toAdd;\n }\n }\n\n return cls;\n};\n\nfunction merge(registered, css, className) {\n var registeredStyles = [];\n var rawClassName = getRegisteredStyles(registered, registeredStyles, className);\n\n if (registeredStyles.length < 2) {\n return className;\n }\n\n return rawClassName + css(registeredStyles);\n}\n\nvar Insertion = function Insertion(_ref) {\n var cache = _ref.cache,\n serializedArr = _ref.serializedArr;\n useInsertionEffectAlwaysWithSyncFallback(function () {\n\n for (var i = 0; i < serializedArr.length; i++) {\n insertStyles(cache, serializedArr[i], false);\n }\n });\n\n return null;\n};\n\nvar ClassNames = /* #__PURE__ */withEmotionCache(function (props, cache) {\n var hasRendered = false;\n var serializedArr = [];\n\n var css = function css() {\n if (hasRendered && process.env.NODE_ENV !== 'production') {\n throw new Error('css can only be used during render');\n }\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n var serialized = serializeStyles(args, cache.registered);\n serializedArr.push(serialized); // registration has to happen here as the result of this might get consumed by `cx`\n\n registerStyles(cache, serialized, false);\n return cache.key + \"-\" + serialized.name;\n };\n\n var cx = function cx() {\n if (hasRendered && process.env.NODE_ENV !== 'production') {\n throw new Error('cx can only be used during render');\n }\n\n for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n args[_key2] = arguments[_key2];\n }\n\n return merge(cache.registered, css, classnames(args));\n };\n\n var content = {\n css: css,\n cx: cx,\n theme: React.useContext(ThemeContext)\n };\n var ele = props.children(content);\n hasRendered = true;\n return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Insertion, {\n cache: cache,\n serializedArr: serializedArr\n }), ele);\n});\n\nif (process.env.NODE_ENV !== 'production') {\n ClassNames.displayName = 'EmotionClassNames';\n}\n\nif (process.env.NODE_ENV !== 'production') {\n var isBrowser = \"object\" !== 'undefined'; // #1727, #2905 for some reason Jest and Vitest evaluate modules twice if some consuming module gets mocked\n\n var isTestEnv = typeof jest !== 'undefined' || typeof vi !== 'undefined';\n\n if (isBrowser && !isTestEnv) {\n // globalThis has wide browser support - https://caniuse.com/?search=globalThis, Node.js 12 and later\n var globalContext = // $FlowIgnore\n typeof globalThis !== 'undefined' ? globalThis // eslint-disable-line no-undef\n : isBrowser ? window : global;\n var globalKey = \"__EMOTION_REACT_\" + pkg.version.split('.')[0] + \"__\";\n\n if (globalContext[globalKey]) {\n console.warn('You are loading @emotion/react when it is already loaded. Running ' + 'multiple instances may cause problems. This can happen if multiple ' + 'versions are used, or if multiple builds of the same version are ' + 'used.');\n }\n\n globalContext[globalKey] = true;\n }\n}\n\nexport { ClassNames, Global, jsx as createElement, css, jsx, keyframes };\n","\"use strict\";\n\nexports.__esModule = true;\nexports.applyTrailingSlashOption = void 0;\nconst applyTrailingSlashOption = (input, option = `always`) => {\n const hasHtmlSuffix = input.endsWith(`.html`);\n const hasXmlSuffix = input.endsWith(`.xml`);\n const hasPdfSuffix = input.endsWith(`.pdf`);\n if (input === `/`) return input;\n if (hasHtmlSuffix || hasXmlSuffix || hasPdfSuffix) {\n option = `never`;\n }\n if (option === `always`) {\n return input.endsWith(`/`) ? input : `${input}/`;\n }\n if (option === `never`) {\n return input.endsWith(`/`) ? input.slice(0, -1) : input;\n }\n return input;\n};\nexports.applyTrailingSlashOption = applyTrailingSlashOption;","\"use strict\";\n\nexports.__esModule = true;\nexports.useScrollRestoration = exports.ScrollContext = void 0;\nvar _scrollHandler = require(\"./scroll-handler\");\nexports.ScrollContext = _scrollHandler.ScrollHandler;\nvar _useScrollRestoration = require(\"./use-scroll-restoration\");\nexports.useScrollRestoration = _useScrollRestoration.useScrollRestoration;","\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\nexports.__esModule = true;\nexports.ScrollHandler = exports.ScrollContext = void 0;\nvar _assertThisInitialized2 = _interopRequireDefault(require(\"@babel/runtime/helpers/assertThisInitialized\"));\nvar _inheritsLoose2 = _interopRequireDefault(require(\"@babel/runtime/helpers/inheritsLoose\"));\nvar React = _interopRequireWildcard(require(\"react\"));\nvar _propTypes = _interopRequireDefault(require(\"prop-types\"));\nvar _sessionStorage = require(\"./session-storage\");\nfunction _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \"function\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }\nfunction _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== \"object\" && typeof obj !== \"function\") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \"default\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }\nvar ScrollContext = /*#__PURE__*/React.createContext(new _sessionStorage.SessionStorage());\nexports.ScrollContext = ScrollContext;\nScrollContext.displayName = \"GatsbyScrollContext\";\nvar ScrollHandler = /*#__PURE__*/function (_React$Component) {\n (0, _inheritsLoose2.default)(ScrollHandler, _React$Component);\n function ScrollHandler() {\n var _this;\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n _this = _React$Component.call.apply(_React$Component, [this].concat(args)) || this;\n _this._stateStorage = new _sessionStorage.SessionStorage();\n _this._isTicking = false;\n _this._latestKnownScrollY = 0;\n _this.scrollListener = function () {\n _this._latestKnownScrollY = window.scrollY;\n if (!_this._isTicking) {\n _this._isTicking = true;\n requestAnimationFrame(_this._saveScroll.bind((0, _assertThisInitialized2.default)(_this)));\n }\n };\n _this.windowScroll = function (position, prevProps) {\n if (_this.shouldUpdateScroll(prevProps, _this.props)) {\n window.scrollTo(0, position);\n }\n };\n _this.scrollToHash = function (hash, prevProps) {\n var node = document.getElementById(hash.substring(1));\n if (node && _this.shouldUpdateScroll(prevProps, _this.props)) {\n node.scrollIntoView();\n }\n };\n _this.shouldUpdateScroll = function (prevRouterProps, routerProps) {\n var shouldUpdateScroll = _this.props.shouldUpdateScroll;\n if (!shouldUpdateScroll) {\n return true;\n }\n\n // Hack to allow accessing this._stateStorage.\n return shouldUpdateScroll.call((0, _assertThisInitialized2.default)(_this), prevRouterProps, routerProps);\n };\n return _this;\n }\n var _proto = ScrollHandler.prototype;\n _proto._saveScroll = function _saveScroll() {\n var key = this.props.location.key || null;\n if (key) {\n this._stateStorage.save(this.props.location, key, this._latestKnownScrollY);\n }\n this._isTicking = false;\n };\n _proto.componentDidMount = function componentDidMount() {\n window.addEventListener(\"scroll\", this.scrollListener);\n var scrollPosition;\n var _this$props$location = this.props.location,\n key = _this$props$location.key,\n hash = _this$props$location.hash;\n if (key) {\n scrollPosition = this._stateStorage.read(this.props.location, key);\n }\n\n /** If a hash is present in the browser url as the component mounts (i.e. the user is navigating\n * from an external website) then scroll to the hash instead of any previously stored scroll\n * position. */\n if (hash) {\n this.scrollToHash(decodeURI(hash), undefined);\n } else if (scrollPosition) {\n this.windowScroll(scrollPosition, undefined);\n }\n };\n _proto.componentWillUnmount = function componentWillUnmount() {\n window.removeEventListener(\"scroll\", this.scrollListener);\n };\n _proto.componentDidUpdate = function componentDidUpdate(prevProps) {\n var _this$props$location2 = this.props.location,\n hash = _this$props$location2.hash,\n key = _this$props$location2.key;\n var scrollPosition;\n if (key) {\n scrollPosition = this._stateStorage.read(this.props.location, key);\n }\n\n /** There are two pieces of state: the browser url and\n * history state which keeps track of scroll position\n * Native behaviour prescribes that we ought to restore scroll position\n * when a user navigates back in their browser (this is the `POP` action)\n * Currently, reach router has a bug that prevents this at https://github.com/reach/router/issues/228\n * So we _always_ stick to the url as a source of truth — if the url\n * contains a hash, we scroll to it\n */\n\n if (hash) {\n this.scrollToHash(decodeURI(hash), prevProps);\n } else {\n this.windowScroll(scrollPosition, prevProps);\n }\n };\n _proto.render = function render() {\n return /*#__PURE__*/React.createElement(ScrollContext.Provider, {\n value: this._stateStorage\n }, this.props.children);\n };\n return ScrollHandler;\n}(React.Component);\nexports.ScrollHandler = ScrollHandler;\nScrollHandler.propTypes = {\n shouldUpdateScroll: _propTypes.default.func,\n children: _propTypes.default.element.isRequired,\n location: _propTypes.default.object.isRequired\n};","\"use strict\";\n\nexports.__esModule = true;\nexports.SessionStorage = void 0;\nvar STATE_KEY_PREFIX = \"@@scroll|\";\nvar GATSBY_ROUTER_SCROLL_STATE = \"___GATSBY_REACT_ROUTER_SCROLL\";\nvar SessionStorage = /*#__PURE__*/function () {\n function SessionStorage() {}\n var _proto = SessionStorage.prototype;\n _proto.read = function read(location, key) {\n var stateKey = this.getStateKey(location, key);\n try {\n var value = window.sessionStorage.getItem(stateKey);\n return value ? JSON.parse(value) : 0;\n } catch (e) {\n if (process.env.NODE_ENV !== \"production\") {\n console.warn(\"[gatsby-react-router-scroll] Unable to access sessionStorage; sessionStorage is not available.\");\n }\n if (window && window[GATSBY_ROUTER_SCROLL_STATE] && window[GATSBY_ROUTER_SCROLL_STATE][stateKey]) {\n return window[GATSBY_ROUTER_SCROLL_STATE][stateKey];\n }\n return 0;\n }\n };\n _proto.save = function save(location, key, value) {\n var stateKey = this.getStateKey(location, key);\n var storedValue = JSON.stringify(value);\n try {\n window.sessionStorage.setItem(stateKey, storedValue);\n } catch (e) {\n if (window && window[GATSBY_ROUTER_SCROLL_STATE]) {\n window[GATSBY_ROUTER_SCROLL_STATE][stateKey] = JSON.parse(storedValue);\n } else {\n window[GATSBY_ROUTER_SCROLL_STATE] = {};\n window[GATSBY_ROUTER_SCROLL_STATE][stateKey] = JSON.parse(storedValue);\n }\n if (process.env.NODE_ENV !== \"production\") {\n console.warn(\"[gatsby-react-router-scroll] Unable to save state in sessionStorage; sessionStorage is not available.\");\n }\n }\n };\n _proto.getStateKey = function getStateKey(location, key) {\n var stateKeyBase = \"\" + STATE_KEY_PREFIX + location.pathname;\n return key === null || typeof key === \"undefined\" ? stateKeyBase : stateKeyBase + \"|\" + key;\n };\n return SessionStorage;\n}();\nexports.SessionStorage = SessionStorage;","\"use strict\";\n\nexports.__esModule = true;\nexports.useScrollRestoration = useScrollRestoration;\nvar _scrollHandler = require(\"./scroll-handler\");\nvar _react = require(\"react\");\nvar _reachRouter = require(\"@gatsbyjs/reach-router\");\nfunction useScrollRestoration(identifier) {\n var location = (0, _reachRouter.useLocation)();\n var state = (0, _react.useContext)(_scrollHandler.ScrollContext);\n var ref = (0, _react.useRef)(null);\n (0, _react.useLayoutEffect)(function () {\n if (ref.current) {\n var position = state.read(location, identifier);\n ref.current.scrollTo(0, position || 0);\n }\n }, [location.key]);\n return {\n ref: ref,\n onScroll: function onScroll() {\n if (ref.current) {\n state.save(location, identifier, ref.current.scrollTop);\n }\n }\n };\n}","\"use strict\";\n\nexports.__esModule = true;\nexports.onInitialClientRender = void 0;\nvar _gatsbyScript = require(\"gatsby-script\");\nvar _injectPartytownSnippet = require(\"./utils/inject-partytown-snippet\");\n// Makes sure off-main-thread scripts are loaded in `gatsby develop`\nconst onInitialClientRender = () => {\n if (process.env.NODE_ENV !== `development`) {\n return;\n }\n (0, _injectPartytownSnippet.injectPartytownSnippet)(_gatsbyScript.collectedScriptsByPage.get(window.location.pathname));\n\n // Clear scripts after we've used them to avoid leaky behavior\n _gatsbyScript.collectedScriptsByPage.delete(window.location.pathname);\n};\n\n// Client-side navigation (CSR, e.g. Gatsby Link navigations) are broken upstream in Partytown.\n// We need an official API from Partytown for handling re-configuration and on-demand script loading.\n// Until then, `off-main-thread` scripts load only on server-side navigation (SSR).\n// See https://github.com/BuilderIO/partytown/issues/74 for more details.\nexports.onInitialClientRender = onInitialClientRender;\n//# sourceMappingURL=gatsby-browser.js.map","\"use strict\";\n\nexports.__esModule = true;\nexports.getForwards = getForwards;\nfunction getForwards(collectedScripts) {\n return collectedScripts === null || collectedScripts === void 0 ? void 0 : collectedScripts.flatMap(script => (script === null || script === void 0 ? void 0 : script.forward) || []);\n}\n//# sourceMappingURL=get-forwards.js.map","\"use strict\";\n\nexports.__esModule = true;\nexports.injectPartytownSnippet = injectPartytownSnippet;\nvar _integration = require(\"@builder.io/partytown/integration\");\nvar _getForwards = require(\"./get-forwards\");\n// Adapted from https://github.com/BuilderIO/partytown/blob/main/src/react/snippet.tsx to only include CSR logic\nfunction injectPartytownSnippet(collectedScripts) {\n if (!collectedScripts.length) {\n return;\n }\n const existingSnippet = document.querySelector(`script[data-partytown]`);\n const existingSandbox = document.querySelector(`iframe[src*=\"~partytown/partytown-sandbox-sw\"]`);\n if (existingSnippet) {\n existingSnippet.remove();\n }\n if (existingSandbox) {\n existingSandbox.remove();\n }\n const forwards = (0, _getForwards.getForwards)(collectedScripts);\n const snippet = document.createElement(`script`);\n snippet.dataset.partytown = ``;\n snippet.innerHTML = (0, _integration.partytownSnippet)({\n forward: forwards\n });\n document.head.appendChild(snippet);\n}\n//# sourceMappingURL=inject-partytown-snippet.js.map","exports.components = {\n \"component---src-pages-404-jsx\": () => import(\"./../../../src/pages/404.jsx\" /* webpackChunkName: \"component---src-pages-404-jsx\" */),\n \"component---src-pages-search-jsx\": () => import(\"./../../../src/pages/search.jsx\" /* webpackChunkName: \"component---src-pages-search-jsx\" */),\n \"component---src-templates-default-jsx\": () => import(\"./../../../src/templates/default.jsx\" /* webpackChunkName: \"component---src-templates-default-jsx\" */)\n}\n\n","module.exports = [{\n plugin: require('../node_modules/gatsby-plugin-layout/gatsby-browser.js'),\n options: {\"plugins\":[],\"component\":\"/home/runner/work/icatproject.github.io/icatproject.github.io/src/components/layout.jsx\"},\n },{\n plugin: require('../node_modules/gatsby-plugin-catch-links/gatsby-browser.js'),\n options: {\"plugins\":[]},\n },{\n plugin: require('../node_modules/gatsby-remark-images/gatsby-browser.js'),\n options: {\"plugins\":[],\"maxWidth\":700,\"showCaptions\":true,\"wrapperStyle\":\"margin-left: 0 !important; margin-right: 0 !important;\",\"linkImagesToOriginal\":true,\"markdownCaptions\":false,\"backgroundColor\":\"white\",\"quality\":50,\"withWebp\":false,\"withAvif\":false,\"loading\":\"lazy\",\"decoding\":\"async\",\"disableBgImageOnAlpha\":false,\"disableBgImage\":false},\n },{\n plugin: require('../node_modules/gatsby-plugin-manifest/gatsby-browser.js'),\n options: {\"plugins\":[],\"name\":\"ICAT project website\",\"short_name\":\"ICAT project\",\"start_url\":\"/\",\"background_color\":\"#ffffff\",\"theme_color\":\"#000000\",\"display\":\"browser\",\"icon\":\"src/images/favicon.ico\",\"legacy\":true,\"theme_color_in_head\":true,\"cache_busting_mode\":\"query\",\"crossOrigin\":\"anonymous\",\"include_favicon\":true,\"cacheDigest\":\"ff9257ddcf8e692608ae9f7a0c4c4455\"},\n },{\n plugin: require('../node_modules/gatsby/dist/internal-plugins/partytown/gatsby-browser.js'),\n options: {\"plugins\":[]},\n }]\n","const plugins = require(`./api-runner-browser-plugins`)\nconst { getResourceURLsForPathname, loadPage, loadPageSync } =\n require(`./loader`).publicLoader\n\nexports.apiRunner = (api, args = {}, defaultReturn, argTransform) => {\n // Hooks for gatsby-cypress's API handler\n if (process.env.CYPRESS_SUPPORT) {\n if (window.___apiHandler) {\n window.___apiHandler(api)\n } else if (window.___resolvedAPIs) {\n window.___resolvedAPIs.push(api)\n } else {\n window.___resolvedAPIs = [api]\n }\n }\n\n let results = plugins.map(plugin => {\n if (!plugin.plugin[api]) {\n return undefined\n }\n\n args.getResourceURLsForPathname = getResourceURLsForPathname\n args.loadPage = loadPage\n args.loadPageSync = loadPageSync\n\n const result = plugin.plugin[api](args, plugin.options)\n if (result && argTransform) {\n args = argTransform({ args, result, plugin })\n }\n return result\n })\n\n // Filter out undefined results.\n results = results.filter(result => typeof result !== `undefined`)\n\n if (results.length > 0) {\n return results\n } else if (defaultReturn) {\n return [defaultReturn]\n } else {\n return []\n }\n}\n\nexports.apiRunnerAsync = (api, args, defaultReturn) =>\n plugins.reduce(\n (previous, next) =>\n next.plugin[api]\n ? previous.then(() => next.plugin[api](args, next.options))\n : previous,\n Promise.resolve()\n )\n","exports.createContentDigest = () => ``\n","import mitt from \"mitt\"\n\nconst emitter = mitt()\nexport default emitter\n","// \n// An event handler can take an optional event argument\n// and should not return a value\n \n \n\n// An array of all currently registered event handlers for a type\n \n \n// A map of event types and their corresponding event handlers.\n \n \n \n \n\n/** Mitt: Tiny (~200b) functional event emitter / pubsub.\n * @name mitt\n * @returns {Mitt}\n */\nfunction mitt(all ) {\n\tall = all || Object.create(null);\n\n\treturn {\n\t\t/**\n\t\t * Register an event handler for the given type.\n\t\t *\n\t\t * @param {String} type\tType of event to listen for, or `\"*\"` for all events\n\t\t * @param {Function} handler Function to call in response to given event\n\t\t * @memberOf mitt\n\t\t */\n\t\ton: function on(type , handler ) {\n\t\t\t(all[type] || (all[type] = [])).push(handler);\n\t\t},\n\n\t\t/**\n\t\t * Remove an event handler for the given type.\n\t\t *\n\t\t * @param {String} type\tType of event to unregister `handler` from, or `\"*\"`\n\t\t * @param {Function} handler Handler function to remove\n\t\t * @memberOf mitt\n\t\t */\n\t\toff: function off(type , handler ) {\n\t\t\tif (all[type]) {\n\t\t\t\tall[type].splice(all[type].indexOf(handler) >>> 0, 1);\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Invoke all handlers for the given type.\n\t\t * If present, `\"*\"` handlers are invoked after type-matched handlers.\n\t\t *\n\t\t * @param {String} type The event type to invoke\n\t\t * @param {Any} [evt] Any value (object is recommended and powerful), passed to each handler\n\t\t * @memberOf mitt\n\t\t */\n\t\temit: function emit(type , evt ) {\n\t\t\t(all[type] || []).slice().map(function (handler) { handler(evt); });\n\t\t\t(all['*'] || []).slice().map(function (handler) { handler(type, evt); });\n\t\t}\n\t};\n}\n\nexport default mitt;\n//# sourceMappingURL=mitt.es.js.map\n","export default pathAndSearch => {\n if (pathAndSearch === undefined) {\n return pathAndSearch\n }\n let [path, search = ``] = pathAndSearch.split(`?`)\n if (search) {\n search = `?` + search\n }\n\n if (path === `/`) {\n return `/` + search\n }\n if (path.charAt(path.length - 1) === `/`) {\n return path.slice(0, -1) + search\n }\n return path + search\n}\n","import { pick } from \"@gatsbyjs/reach-router\"\nimport stripPrefix from \"./strip-prefix\"\nimport normalizePagePath from \"./normalize-page-path\"\nimport { maybeGetBrowserRedirect } from \"./redirect-utils.js\"\n\nconst pathCache = new Map()\nlet matchPaths = []\n\nconst trimPathname = rawPathname => {\n let newRawPathname = rawPathname\n const queryIndex = rawPathname.indexOf(`?`)\n\n if (queryIndex !== -1) {\n const [path, qs] = rawPathname.split(`?`)\n newRawPathname = `${path}?${encodeURIComponent(qs)}`\n }\n\n const pathname = decodeURIComponent(newRawPathname)\n\n // Remove the pathPrefix from the pathname.\n const trimmedPathname = stripPrefix(\n pathname,\n decodeURIComponent(__BASE_PATH__)\n )\n // Remove any hashfragment\n .split(`#`)[0]\n\n return trimmedPathname\n}\n\nfunction absolutify(path) {\n // If it's already absolute, return as-is\n if (\n path.startsWith(`/`) ||\n path.startsWith(`https://`) ||\n path.startsWith(`http://`)\n ) {\n return path\n }\n // Calculate path relative to current location, adding a trailing slash to\n // match behavior of @reach/router\n return new URL(\n path,\n window.location.href + (window.location.href.endsWith(`/`) ? `` : `/`)\n ).pathname\n}\n\n/**\n * Set list of matchPaths\n *\n * @param {Array<{path: string, matchPath: string}>} value collection of matchPaths\n */\nexport const setMatchPaths = value => {\n matchPaths = value\n}\n\n/**\n * Return a matchpath url\n * if `match-paths.json` contains `{ \"/foo*\": \"/page1\", ...}`, then\n * `/foo?bar=far` => `/page1`\n *\n * @param {string} rawPathname A raw pathname\n * @return {string|null}\n */\nexport const findMatchPath = rawPathname => {\n const trimmedPathname = cleanPath(rawPathname)\n\n const pickPaths = matchPaths.map(({ path, matchPath }) => {\n return {\n path: matchPath,\n originalPath: path,\n }\n })\n\n const path = pick(pickPaths, trimmedPathname)\n\n if (path) {\n return normalizePagePath(path.route.originalPath)\n }\n\n return null\n}\n\n/**\n * Return a matchpath params from reach/router rules\n * if `match-paths.json` contains `{ \":bar/*foo\" }`, and the path is /baz/zaz/zoo\n * then it returns\n * { bar: baz, foo: zaz/zoo }\n *\n * @param {string} rawPathname A raw pathname\n * @return {object}\n */\nexport const grabMatchParams = rawPathname => {\n const trimmedPathname = cleanPath(rawPathname)\n\n const pickPaths = matchPaths.map(({ path, matchPath }) => {\n return {\n path: matchPath,\n originalPath: path,\n }\n })\n\n const path = pick(pickPaths, trimmedPathname)\n\n if (path) {\n return path.params\n }\n\n return {}\n}\n\n// Given a raw URL path, returns the cleaned version of it (trim off\n// `#` and query params), or if it matches an entry in\n// `match-paths.json`, its matched path is returned\n//\n// E.g. `/foo?bar=far` => `/foo`\n//\n// Or if `match-paths.json` contains `{ \"/foo*\": \"/page1\", ...}`, then\n// `/foo?bar=far` => `/page1`\nexport const findPath = rawPathname => {\n const trimmedPathname = trimPathname(absolutify(rawPathname))\n if (pathCache.has(trimmedPathname)) {\n return pathCache.get(trimmedPathname)\n }\n\n const redirect = maybeGetBrowserRedirect(rawPathname)\n if (redirect) {\n return findPath(redirect.toPath)\n }\n\n let foundPath = findMatchPath(trimmedPathname)\n\n if (!foundPath) {\n foundPath = cleanPath(rawPathname)\n }\n\n pathCache.set(trimmedPathname, foundPath)\n\n return foundPath\n}\n\n/**\n * Clean a url and converts /index.html => /\n * E.g. `/foo?bar=far` => `/foo`\n *\n * @param {string} rawPathname A raw pathname\n * @return {string}\n */\nexport const cleanPath = rawPathname => {\n const trimmedPathname = trimPathname(absolutify(rawPathname))\n\n let foundPath = trimmedPathname\n if (foundPath === `/index.html`) {\n foundPath = `/`\n }\n\n foundPath = normalizePagePath(foundPath)\n\n return foundPath\n}\n","export default function _getPrototypeOf(o) {\n _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) {\n return o.__proto__ || Object.getPrototypeOf(o);\n };\n return _getPrototypeOf(o);\n}","import setPrototypeOf from \"./setPrototypeOf.js\";\nimport isNativeReflectConstruct from \"./isNativeReflectConstruct.js\";\nexport default function _construct(Parent, args, Class) {\n if (isNativeReflectConstruct()) {\n _construct = Reflect.construct.bind();\n } else {\n _construct = function _construct(Parent, args, Class) {\n var a = [null];\n a.push.apply(a, args);\n var Constructor = Function.bind.apply(Parent, a);\n var instance = new Constructor();\n if (Class) setPrototypeOf(instance, Class.prototype);\n return instance;\n };\n }\n return _construct.apply(null, arguments);\n}","export default function _isNativeReflectConstruct() {\n if (typeof Reflect === \"undefined\" || !Reflect.construct) return false;\n if (Reflect.construct.sham) return false;\n if (typeof Proxy === \"function\") return true;\n try {\n Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));\n return true;\n } catch (e) {\n return false;\n }\n}","import getPrototypeOf from \"./getPrototypeOf.js\";\nimport setPrototypeOf from \"./setPrototypeOf.js\";\nimport isNativeFunction from \"./isNativeFunction.js\";\nimport construct from \"./construct.js\";\nexport default function _wrapNativeSuper(Class) {\n var _cache = typeof Map === \"function\" ? new Map() : undefined;\n _wrapNativeSuper = function _wrapNativeSuper(Class) {\n if (Class === null || !isNativeFunction(Class)) return Class;\n if (typeof Class !== \"function\") {\n throw new TypeError(\"Super expression must either be null or a function\");\n }\n if (typeof _cache !== \"undefined\") {\n if (_cache.has(Class)) return _cache.get(Class);\n _cache.set(Class, Wrapper);\n }\n function Wrapper() {\n return construct(Class, arguments, getPrototypeOf(this).constructor);\n }\n Wrapper.prototype = Object.create(Class.prototype, {\n constructor: {\n value: Wrapper,\n enumerable: false,\n writable: true,\n configurable: true\n }\n });\n return setPrototypeOf(Wrapper, Class);\n };\n return _wrapNativeSuper(Class);\n}","export default function _isNativeFunction(fn) {\n return Function.toString.call(fn).indexOf(\"[native code]\") !== -1;\n}","import React from \"react\"\n\nexport const ServerSliceRenderer = ({ sliceId, children }) => {\n const contents = [\n React.createElement(`slice-start`, {\n id: `${sliceId}-1`,\n }),\n React.createElement(`slice-end`, {\n id: `${sliceId}-1`,\n }),\n ]\n\n if (children) {\n // if children exist, we split the slice into a before and after piece\n // see renderSlices in render-html\n contents.push(children)\n contents.push(\n React.createElement(`slice-start`, {\n id: `${sliceId}-2`,\n }),\n React.createElement(`slice-end`, {\n id: `${sliceId}-2`,\n })\n )\n }\n\n return contents\n}\n","import React, { useContext } from \"react\"\nimport { createContentDigest } from \"gatsby-core-utils/create-content-digest\"\nimport { SlicesMapContext, SlicesPropsContext } from \"./context\"\nimport { ServerSliceRenderer } from \"./server-slice-renderer\"\n\nconst getSliceId = (sliceName, sliceProps) => {\n if (!Object.keys(sliceProps).length) {\n return sliceName\n }\n\n const propsString = createContentDigest(sliceProps)\n return `${sliceName}-${propsString}`\n}\n\nexport const ServerSlice = ({\n sliceName,\n allowEmpty,\n children,\n ...sliceProps\n}) => {\n const slicesMap = useContext(SlicesMapContext)\n const slicesProps = useContext(SlicesPropsContext)\n const concreteSliceName = slicesMap[sliceName]\n\n if (!concreteSliceName) {\n if (allowEmpty) {\n return null\n } else {\n throw new Error(\n `Slice \"${concreteSliceName}\" for \"${sliceName}\" slot not found`\n )\n }\n }\n\n const sliceId = getSliceId(concreteSliceName, sliceProps)\n\n // set props on context object for static-entry to return\n let sliceUsage = slicesProps[sliceId]\n if (!sliceUsage) {\n slicesProps[sliceId] = sliceUsage = {\n props: sliceProps,\n sliceName: concreteSliceName,\n hasChildren: !!children,\n }\n } else {\n if (children) {\n sliceUsage.hasChildren = true\n }\n }\n\n return {children}\n}\n","import React, { useContext } from \"react\"\nimport { SlicesMapContext, SlicesResultsContext } from \"./context\"\n\nexport const InlineSlice = ({\n sliceName,\n allowEmpty,\n children,\n ...sliceProps\n}) => {\n const slicesMap = useContext(SlicesMapContext)\n const slicesResultsMap = useContext(SlicesResultsContext)\n const concreteSliceName = slicesMap[sliceName]\n const slice = slicesResultsMap.get(concreteSliceName)\n\n if (!slice) {\n if (allowEmpty) {\n return null\n } else {\n throw new Error(\n `Slice \"${concreteSliceName}\" for \"${sliceName}\" slot not found`\n )\n }\n }\n\n return (\n \n {children}\n \n )\n}\n","\"use client\"\n\nimport React, { useContext } from \"react\"\nimport { ServerSlice } from \"./slice/server-slice\"\nimport { InlineSlice } from \"./slice/inline-slice\"\nimport { SlicesContext } from \"./slice/context\"\n\nexport function Slice(props) {\n if (process.env.GATSBY_SLICES) {\n // we use sliceName internally, so remap alias to sliceName\n const internalProps = {\n ...props,\n sliceName: props.alias,\n }\n delete internalProps.alias\n delete internalProps.__renderedByLocation\n\n const slicesContext = useContext(SlicesContext)\n\n // validate props\n const propErrors = validateSliceProps(props)\n if (Object.keys(propErrors).length) {\n throw new SlicePropsError(\n slicesContext.renderEnvironment === `browser`,\n internalProps.sliceName,\n propErrors,\n props.__renderedByLocation\n )\n }\n\n if (slicesContext.renderEnvironment === `server`) {\n return \n } else if (slicesContext.renderEnvironment === `browser`) {\n // in the browser, we'll just render the component as is\n return \n } else if (\n slicesContext.renderEnvironment === `engines` ||\n slicesContext.renderEnvironment === `dev-ssr`\n ) {\n // if we're in SSR, we'll just render the component as is\n return \n } else if (slicesContext.renderEnvironment === `slices`) {\n // we are not yet supporting nested slices\n\n let additionalContextMessage = ``\n\n // just in case generating additional contextual information fails, we still want the base message to show\n // and not show another cryptic error message\n try {\n additionalContextMessage = `\\n\\nSlice component \"${slicesContext.sliceRoot.name}\" (${slicesContext.sliceRoot.componentPath}) tried to render `\n } catch {\n // don't need to handle it, we will just skip the additional context message if we fail to generate it\n }\n\n throw new Error(\n `Nested slices are not supported.${additionalContextMessage}\\n\\nSee https://gatsbyjs.com/docs/reference/built-in-components/gatsby-slice#nested-slices`\n )\n } else {\n throw new Error(\n `Slice context \"${slicesContext.renderEnvironment}\" is not supported.`\n )\n }\n } else {\n throw new Error(`Slices are disabled.`)\n }\n}\n\nclass SlicePropsError extends Error {\n constructor(inBrowser, sliceName, propErrors, renderedByLocation) {\n const errors = Object.entries(propErrors)\n .map(\n ([key, value]) =>\n `not serializable \"${value}\" type passed to \"${key}\" prop`\n )\n .join(`, `)\n\n const name = `SlicePropsError`\n let stack = ``\n let message = ``\n\n if (inBrowser) {\n // They're just (kinda) kidding, I promise... You can still work here <3\n // https://www.gatsbyjs.com/careers/\n const fullStack =\n React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactDebugCurrentFrame.getCurrentStack()\n\n // remove the first line of the stack trace\n const stackLines = fullStack.trim().split(`\\n`).slice(1)\n stackLines[0] = stackLines[0].trim()\n stack = `\\n` + stackLines.join(`\\n`)\n\n message = `Slice \"${sliceName}\" was passed props that are not serializable (${errors}).`\n } else {\n // we can't really grab any extra info outside of the browser, so just print what we can\n message = `${name}: Slice \"${sliceName}\" was passed props that are not serializable (${errors}).`\n const stackLines = new Error().stack.trim().split(`\\n`).slice(2)\n stack = `${message}\\n${stackLines.join(`\\n`)}`\n }\n\n super(message)\n this.name = name\n if (stack) {\n this.stack = stack\n } else {\n Error.captureStackTrace(this, SlicePropsError)\n }\n\n if (renderedByLocation) {\n this.forcedLocation = { ...renderedByLocation, functionName: `Slice` }\n }\n }\n}\n\nconst validateSliceProps = (\n props,\n errors = {},\n seenObjects = [],\n path = null\n) => {\n // recursively validate all props\n for (const [name, value] of Object.entries(props)) {\n if (\n value === undefined ||\n value === null ||\n (!path && name === `children`)\n ) {\n continue\n }\n\n const propPath = path ? `${path}.${name}` : name\n\n if (typeof value === `function`) {\n errors[propPath] = typeof value\n } else if (typeof value === `object` && seenObjects.indexOf(value) <= 0) {\n seenObjects.push(value)\n validateSliceProps(value, errors, seenObjects, propPath)\n }\n }\n\n return errors\n}\n","import loader from \"./loader\"\n\nconst prefetchPathname = loader.enqueue\n\nfunction graphql() {\n throw new Error(\n `It appears like Gatsby is misconfigured. Gatsby related \\`graphql\\` calls ` +\n `are supposed to only be evaluated at compile time, and then compiled away. ` +\n `Unfortunately, something went wrong and the query was left in the compiled code.\\n\\n` +\n `Unless your site has a complex or custom babel/Gatsby configuration this is likely a bug in Gatsby.`\n )\n}\n\nexport { default as PageRenderer } from \"./public-page-renderer\"\nexport { useScrollRestoration } from \"gatsby-react-router-scroll\"\nexport {\n Link,\n withPrefix,\n withAssetPrefix,\n navigate,\n parsePath,\n} from \"gatsby-link\"\n\nexport { graphql, prefetchPathname }\nexport { StaticQuery, StaticQueryContext, useStaticQuery } from \"./static-query\"\nexport { Slice } from \"./slice\"\nexport * from \"gatsby-script\"\n","const support = function (feature) {\n if (typeof document === `undefined`) {\n return false\n }\n const fakeLink = document.createElement(`link`)\n try {\n if (fakeLink.relList && typeof fakeLink.relList.supports === `function`) {\n return fakeLink.relList.supports(feature)\n }\n } catch (err) {\n return false\n }\n return false\n}\n\nconst linkPrefetchStrategy = function (url, options) {\n return new Promise((resolve, reject) => {\n if (typeof document === `undefined`) {\n reject()\n return\n }\n\n const link = document.createElement(`link`)\n link.setAttribute(`rel`, `prefetch`)\n link.setAttribute(`href`, url)\n\n Object.keys(options).forEach(key => {\n link.setAttribute(key, options[key])\n })\n\n link.onload = resolve\n link.onerror = reject\n\n const parentElement =\n document.getElementsByTagName(`head`)[0] ||\n document.getElementsByName(`script`)[0].parentNode\n parentElement.appendChild(link)\n })\n}\n\nconst xhrPrefetchStrategy = function (url) {\n return new Promise((resolve, reject) => {\n const req = new XMLHttpRequest()\n req.open(`GET`, url, true)\n\n req.onload = () => {\n if (req.status === 200) {\n resolve()\n } else {\n reject()\n }\n }\n\n req.send(null)\n })\n}\n\nconst supportedPrefetchStrategy = support(`prefetch`)\n ? linkPrefetchStrategy\n : xhrPrefetchStrategy\n\nconst preFetched = {}\n\nconst prefetch = function (url, options) {\n return new Promise(resolve => {\n if (preFetched[url]) {\n resolve()\n return\n }\n\n supportedPrefetchStrategy(url, options)\n .then(() => {\n resolve()\n preFetched[url] = true\n })\n .catch(() => {}) // 404s are logged to the console anyway\n })\n}\n\nexport default prefetch\n","import { createFromReadableStream } from \"react-server-dom-webpack\"\nimport prefetchHelper from \"./prefetch\"\nimport emitter from \"./emitter\"\nimport { setMatchPaths, findPath, findMatchPath } from \"./find-path\"\n\n/**\n * Available resource loading statuses\n */\nexport const PageResourceStatus = {\n /**\n * At least one of critical resources failed to load\n */\n Error: `error`,\n /**\n * Resources loaded successfully\n */\n Success: `success`,\n}\n\nconst preferDefault = m => (m && m.default) || m\n\nconst stripSurroundingSlashes = s => {\n s = s[0] === `/` ? s.slice(1) : s\n s = s.endsWith(`/`) ? s.slice(0, -1) : s\n return s\n}\n\nconst createPageDataUrl = rawPath => {\n const [path, maybeSearch] = rawPath.split(`?`)\n const fixedPath = path === `/` ? `index` : stripSurroundingSlashes(path)\n return `${__PATH_PREFIX__}/page-data/${fixedPath}/page-data.json${\n maybeSearch ? `?${maybeSearch}` : ``\n }`\n}\n\n/**\n * Utility to check the path that goes into doFetch for e.g. potential malicious intentions.\n * It checks for \"//\" because with this you could do a fetch request to a different domain.\n */\nconst shouldAbortFetch = rawPath => rawPath.startsWith(`//`)\n\nfunction doFetch(url, method = `GET`) {\n return new Promise(resolve => {\n const req = new XMLHttpRequest()\n req.open(method, url, true)\n req.onreadystatechange = () => {\n if (req.readyState == 4) {\n resolve(req)\n }\n }\n req.send(null)\n })\n}\n\nconst doesConnectionSupportPrefetch = () => {\n if (\n `connection` in navigator &&\n typeof navigator.connection !== `undefined`\n ) {\n if ((navigator.connection.effectiveType || ``).includes(`2g`)) {\n return false\n }\n if (navigator.connection.saveData) {\n return false\n }\n }\n return true\n}\n\n// Regex that matches common search crawlers\nconst BOT_REGEX = /bot|crawler|spider|crawling/i\n\nconst toPageResources = (pageData, component = null, head) => {\n const page = {\n componentChunkName: pageData.componentChunkName,\n path: pageData.path,\n webpackCompilationHash: pageData.webpackCompilationHash,\n matchPath: pageData.matchPath,\n staticQueryHashes: pageData.staticQueryHashes,\n getServerDataError: pageData.getServerDataError,\n slicesMap: pageData.slicesMap ?? {},\n }\n\n return {\n component,\n head,\n json: pageData.result,\n page,\n }\n}\n\nfunction waitForResponse(response) {\n return new Promise(resolve => {\n try {\n const result = response.readRoot()\n resolve(result)\n } catch (err) {\n if (\n Object.hasOwnProperty.call(err, `_response`) &&\n Object.hasOwnProperty.call(err, `_status`)\n ) {\n setTimeout(() => {\n waitForResponse(response).then(resolve)\n }, 200)\n } else {\n throw err\n }\n }\n })\n}\n\nexport class BaseLoader {\n constructor(loadComponent, matchPaths) {\n // Map of pagePath -> Page. Where Page is an object with: {\n // status: PageResourceStatus.Success || PageResourceStatus.Error,\n // payload: PageResources, // undefined if PageResourceStatus.Error\n // }\n // PageResources is {\n // component,\n // json: pageData.result,\n // page: {\n // componentChunkName,\n // path,\n // webpackCompilationHash,\n // staticQueryHashes\n // },\n // staticQueryResults\n // }\n this.pageDb = new Map()\n this.inFlightDb = new Map()\n this.staticQueryDb = {}\n this.pageDataDb = new Map()\n this.partialHydrationDb = new Map()\n this.slicesDataDb = new Map()\n this.sliceInflightDb = new Map()\n this.slicesDb = new Map()\n this.isPrefetchQueueRunning = false\n this.prefetchQueued = []\n this.prefetchTriggered = new Set()\n this.prefetchCompleted = new Set()\n this.loadComponent = loadComponent\n setMatchPaths(matchPaths)\n }\n\n inFlightNetworkRequests = new Map()\n\n memoizedGet(url) {\n let inFlightPromise = this.inFlightNetworkRequests.get(url)\n\n if (!inFlightPromise) {\n inFlightPromise = doFetch(url, `GET`)\n this.inFlightNetworkRequests.set(url, inFlightPromise)\n }\n\n // Prefer duplication with then + catch over .finally to prevent problems in ie11 + firefox\n return inFlightPromise\n .then(response => {\n this.inFlightNetworkRequests.delete(url)\n return response\n })\n .catch(err => {\n this.inFlightNetworkRequests.delete(url)\n throw err\n })\n }\n\n setApiRunner(apiRunner) {\n this.apiRunner = apiRunner\n this.prefetchDisabled = apiRunner(`disableCorePrefetching`).some(a => a)\n }\n\n fetchPageDataJson(loadObj) {\n const { pagePath, retries = 0 } = loadObj\n const url = createPageDataUrl(pagePath)\n return this.memoizedGet(url).then(req => {\n const { status, responseText } = req\n\n // Handle 200\n if (status === 200) {\n try {\n const jsonPayload = JSON.parse(responseText)\n if (jsonPayload.path === undefined) {\n throw new Error(`not a valid pageData response`)\n }\n\n const maybeSearch = pagePath.split(`?`)[1]\n if (maybeSearch && !jsonPayload.path.includes(maybeSearch)) {\n jsonPayload.path += `?${maybeSearch}`\n }\n\n return Object.assign(loadObj, {\n status: PageResourceStatus.Success,\n payload: jsonPayload,\n })\n } catch (err) {\n // continue regardless of error\n }\n }\n\n // Handle 404\n if (status === 404 || status === 200) {\n // If the request was for a 404/500 page and it doesn't exist, we're done\n if (pagePath === `/404.html` || pagePath === `/500.html`) {\n return Object.assign(loadObj, {\n status: PageResourceStatus.Error,\n })\n }\n\n // Need some code here to cache the 404 request. In case\n // multiple loadPageDataJsons result in 404s\n return this.fetchPageDataJson(\n Object.assign(loadObj, { pagePath: `/404.html`, notFound: true })\n )\n }\n\n // handle 500 response (Unrecoverable)\n if (status === 500) {\n return this.fetchPageDataJson(\n Object.assign(loadObj, {\n pagePath: `/500.html`,\n internalServerError: true,\n })\n )\n }\n\n // Handle everything else, including status === 0, and 503s. Should retry\n if (retries < 3) {\n return this.fetchPageDataJson(\n Object.assign(loadObj, { retries: retries + 1 })\n )\n }\n\n // Retried 3 times already, result is an error.\n return Object.assign(loadObj, {\n status: PageResourceStatus.Error,\n })\n })\n }\n\n fetchPartialHydrationJson(loadObj) {\n const { pagePath, retries = 0 } = loadObj\n const url = createPageDataUrl(pagePath).replace(`.json`, `-rsc.json`)\n return this.memoizedGet(url).then(req => {\n const { status, responseText } = req\n\n // Handle 200\n if (status === 200) {\n try {\n return Object.assign(loadObj, {\n status: PageResourceStatus.Success,\n payload: responseText,\n })\n } catch (err) {\n // continue regardless of error\n }\n }\n\n // Handle 404\n if (status === 404 || status === 200) {\n // If the request was for a 404/500 page and it doesn't exist, we're done\n if (pagePath === `/404.html` || pagePath === `/500.html`) {\n return Object.assign(loadObj, {\n status: PageResourceStatus.Error,\n })\n }\n\n // Need some code here to cache the 404 request. In case\n // multiple loadPageDataJsons result in 404s\n return this.fetchPartialHydrationJson(\n Object.assign(loadObj, { pagePath: `/404.html`, notFound: true })\n )\n }\n\n // handle 500 response (Unrecoverable)\n if (status === 500) {\n return this.fetchPartialHydrationJson(\n Object.assign(loadObj, {\n pagePath: `/500.html`,\n internalServerError: true,\n })\n )\n }\n\n // Handle everything else, including status === 0, and 503s. Should retry\n if (retries < 3) {\n return this.fetchPartialHydrationJson(\n Object.assign(loadObj, { retries: retries + 1 })\n )\n }\n\n // Retried 3 times already, result is an error.\n return Object.assign(loadObj, {\n status: PageResourceStatus.Error,\n })\n })\n }\n\n loadPageDataJson(rawPath) {\n const pagePath = findPath(rawPath)\n if (this.pageDataDb.has(pagePath)) {\n const pageData = this.pageDataDb.get(pagePath)\n if (process.env.BUILD_STAGE !== `develop` || !pageData.stale) {\n return Promise.resolve(pageData)\n }\n }\n\n return this.fetchPageDataJson({ pagePath }).then(pageData => {\n this.pageDataDb.set(pagePath, pageData)\n\n return pageData\n })\n }\n\n loadPartialHydrationJson(rawPath) {\n const pagePath = findPath(rawPath)\n if (this.partialHydrationDb.has(pagePath)) {\n const pageData = this.partialHydrationDb.get(pagePath)\n if (process.env.BUILD_STAGE !== `develop` || !pageData.stale) {\n return Promise.resolve(pageData)\n }\n }\n\n return this.fetchPartialHydrationJson({ pagePath }).then(pageData => {\n this.partialHydrationDb.set(pagePath, pageData)\n\n return pageData\n })\n }\n\n loadSliceDataJson(sliceName) {\n if (this.slicesDataDb.has(sliceName)) {\n const jsonPayload = this.slicesDataDb.get(sliceName)\n return Promise.resolve({ sliceName, jsonPayload })\n }\n\n const url = `${__PATH_PREFIX__}/slice-data/${sliceName}.json`\n return doFetch(url, `GET`).then(res => {\n const jsonPayload = JSON.parse(res.responseText)\n\n this.slicesDataDb.set(sliceName, jsonPayload)\n return { sliceName, jsonPayload }\n })\n }\n\n findMatchPath(rawPath) {\n return findMatchPath(rawPath)\n }\n\n // TODO check all uses of this and whether they use undefined for page resources not exist\n loadPage(rawPath) {\n const pagePath = findPath(rawPath)\n if (this.pageDb.has(pagePath)) {\n const page = this.pageDb.get(pagePath)\n if (process.env.BUILD_STAGE !== `develop` || !page.payload.stale) {\n if (page.error) {\n return Promise.resolve({\n error: page.error,\n status: page.status,\n })\n }\n\n return Promise.resolve(page.payload)\n }\n }\n\n if (this.inFlightDb.has(pagePath)) {\n return this.inFlightDb.get(pagePath)\n }\n\n const loadDataPromises = [\n this.loadAppData(),\n this.loadPageDataJson(pagePath),\n ]\n\n if (global.hasPartialHydration) {\n loadDataPromises.push(this.loadPartialHydrationJson(pagePath))\n }\n\n const inFlightPromise = Promise.all(loadDataPromises).then(allData => {\n const [appDataResponse, pageDataResponse, rscDataResponse] = allData\n\n if (\n pageDataResponse.status === PageResourceStatus.Error ||\n rscDataResponse?.status === PageResourceStatus.Error\n ) {\n return {\n status: PageResourceStatus.Error,\n }\n }\n\n let pageData = pageDataResponse.payload\n\n const {\n componentChunkName,\n staticQueryHashes: pageStaticQueryHashes = [],\n slicesMap = {},\n } = pageData\n\n const finalResult = {}\n\n const dedupedSliceNames = Array.from(new Set(Object.values(slicesMap)))\n\n const loadSlice = slice => {\n if (this.slicesDb.has(slice.name)) {\n return this.slicesDb.get(slice.name)\n } else if (this.sliceInflightDb.has(slice.name)) {\n return this.sliceInflightDb.get(slice.name)\n }\n\n const inFlight = this.loadComponent(slice.componentChunkName).then(\n component => {\n return {\n component: preferDefault(component),\n sliceContext: slice.result.sliceContext,\n data: slice.result.data,\n }\n }\n )\n\n this.sliceInflightDb.set(slice.name, inFlight)\n inFlight.then(results => {\n this.slicesDb.set(slice.name, results)\n this.sliceInflightDb.delete(slice.name)\n })\n\n return inFlight\n }\n\n return Promise.all(\n dedupedSliceNames.map(sliceName => this.loadSliceDataJson(sliceName))\n ).then(slicesData => {\n const slices = []\n const dedupedStaticQueryHashes = [...pageStaticQueryHashes]\n\n for (const { jsonPayload, sliceName } of Object.values(slicesData)) {\n slices.push({ name: sliceName, ...jsonPayload })\n for (const staticQueryHash of jsonPayload.staticQueryHashes) {\n if (!dedupedStaticQueryHashes.includes(staticQueryHash)) {\n dedupedStaticQueryHashes.push(staticQueryHash)\n }\n }\n }\n\n const loadChunkPromises = [\n Promise.all(slices.map(loadSlice)),\n this.loadComponent(componentChunkName, `head`),\n ]\n\n if (!global.hasPartialHydration) {\n loadChunkPromises.push(this.loadComponent(componentChunkName))\n }\n\n // In develop we have separate chunks for template and Head components\n // to enable HMR (fast refresh requires single exports).\n // In production we have shared chunk with both exports. Double loadComponent here\n // will be deduped by webpack runtime resulting in single request and single module\n // being loaded for both `component` and `head`.\n // get list of components to get\n const componentChunkPromises = Promise.all(loadChunkPromises).then(\n components => {\n const [sliceComponents, headComponent, pageComponent] = components\n\n finalResult.createdAt = new Date()\n\n for (const sliceComponent of sliceComponents) {\n if (!sliceComponent || sliceComponent instanceof Error) {\n finalResult.status = PageResourceStatus.Error\n finalResult.error = sliceComponent\n }\n }\n\n if (\n !global.hasPartialHydration &&\n (!pageComponent || pageComponent instanceof Error)\n ) {\n finalResult.status = PageResourceStatus.Error\n finalResult.error = pageComponent\n }\n\n let pageResources\n\n if (finalResult.status !== PageResourceStatus.Error) {\n finalResult.status = PageResourceStatus.Success\n if (\n pageDataResponse.notFound === true ||\n rscDataResponse?.notFound === true\n ) {\n finalResult.notFound = true\n }\n pageData = Object.assign(pageData, {\n webpackCompilationHash: appDataResponse\n ? appDataResponse.webpackCompilationHash\n : ``,\n })\n\n if (typeof rscDataResponse?.payload === `string`) {\n pageResources = toPageResources(pageData, null, headComponent)\n\n pageResources.partialHydration = rscDataResponse.payload\n\n const readableStream = new ReadableStream({\n start(controller) {\n const te = new TextEncoder()\n controller.enqueue(te.encode(rscDataResponse.payload))\n },\n pull(controller) {\n // close on next read when queue is empty\n controller.close()\n },\n cancel() {},\n })\n\n return waitForResponse(\n createFromReadableStream(readableStream)\n ).then(result => {\n pageResources.partialHydration = result\n\n return pageResources\n })\n } else {\n pageResources = toPageResources(\n pageData,\n pageComponent,\n headComponent\n )\n }\n }\n\n // undefined if final result is an error\n return pageResources\n }\n )\n\n // get list of static queries to get\n const staticQueryBatchPromise = Promise.all(\n dedupedStaticQueryHashes.map(staticQueryHash => {\n // Check for cache in case this static query result has already been loaded\n if (this.staticQueryDb[staticQueryHash]) {\n const jsonPayload = this.staticQueryDb[staticQueryHash]\n return { staticQueryHash, jsonPayload }\n }\n\n return this.memoizedGet(\n `${__PATH_PREFIX__}/page-data/sq/d/${staticQueryHash}.json`\n )\n .then(req => {\n const jsonPayload = JSON.parse(req.responseText)\n return { staticQueryHash, jsonPayload }\n })\n .catch(() => {\n throw new Error(\n `We couldn't load \"${__PATH_PREFIX__}/page-data/sq/d/${staticQueryHash}.json\"`\n )\n })\n })\n ).then(staticQueryResults => {\n const staticQueryResultsMap = {}\n\n staticQueryResults.forEach(({ staticQueryHash, jsonPayload }) => {\n staticQueryResultsMap[staticQueryHash] = jsonPayload\n this.staticQueryDb[staticQueryHash] = jsonPayload\n })\n\n return staticQueryResultsMap\n })\n\n return (\n Promise.all([componentChunkPromises, staticQueryBatchPromise])\n .then(([pageResources, staticQueryResults]) => {\n let payload\n if (pageResources) {\n payload = { ...pageResources, staticQueryResults }\n finalResult.payload = payload\n emitter.emit(`onPostLoadPageResources`, {\n page: payload,\n pageResources: payload,\n })\n }\n\n this.pageDb.set(pagePath, finalResult)\n\n if (finalResult.error) {\n return {\n error: finalResult.error,\n status: finalResult.status,\n }\n }\n\n return payload\n })\n // when static-query fail to load we throw a better error\n .catch(err => {\n return {\n error: err,\n status: PageResourceStatus.Error,\n }\n })\n )\n })\n })\n\n inFlightPromise\n .then(() => {\n this.inFlightDb.delete(pagePath)\n })\n .catch(error => {\n this.inFlightDb.delete(pagePath)\n throw error\n })\n\n this.inFlightDb.set(pagePath, inFlightPromise)\n\n return inFlightPromise\n }\n\n // returns undefined if the page does not exists in cache\n loadPageSync(rawPath, options = {}) {\n const pagePath = findPath(rawPath)\n if (this.pageDb.has(pagePath)) {\n const pageData = this.pageDb.get(pagePath)\n\n if (pageData.payload) {\n return pageData.payload\n }\n\n if (options?.withErrorDetails) {\n return {\n error: pageData.error,\n status: pageData.status,\n }\n }\n }\n return undefined\n }\n\n shouldPrefetch(pagePath) {\n // Skip prefetching if we know user is on slow or constrained connection\n if (!doesConnectionSupportPrefetch()) {\n return false\n }\n\n // Don't prefetch if this is a crawler bot\n if (navigator.userAgent && BOT_REGEX.test(navigator.userAgent)) {\n return false\n }\n\n // Check if the page exists.\n if (this.pageDb.has(pagePath)) {\n return false\n }\n\n return true\n }\n\n prefetch(pagePath) {\n if (!this.shouldPrefetch(pagePath)) {\n return {\n then: resolve => resolve(false),\n abort: () => {},\n }\n }\n if (this.prefetchTriggered.has(pagePath)) {\n return {\n then: resolve => resolve(true),\n abort: () => {},\n }\n }\n\n const defer = {\n resolve: null,\n reject: null,\n promise: null,\n }\n defer.promise = new Promise((resolve, reject) => {\n defer.resolve = resolve\n defer.reject = reject\n })\n this.prefetchQueued.push([pagePath, defer])\n const abortC = new AbortController()\n abortC.signal.addEventListener(`abort`, () => {\n const index = this.prefetchQueued.findIndex(([p]) => p === pagePath)\n // remove from the queue\n if (index !== -1) {\n this.prefetchQueued.splice(index, 1)\n }\n })\n\n if (!this.isPrefetchQueueRunning) {\n this.isPrefetchQueueRunning = true\n setTimeout(() => {\n this._processNextPrefetchBatch()\n }, 3000)\n }\n\n return {\n then: (resolve, reject) => defer.promise.then(resolve, reject),\n abort: abortC.abort.bind(abortC),\n }\n }\n\n _processNextPrefetchBatch() {\n const idleCallback = window.requestIdleCallback || (cb => setTimeout(cb, 0))\n\n idleCallback(() => {\n const toPrefetch = this.prefetchQueued.splice(0, 4)\n const prefetches = Promise.all(\n toPrefetch.map(([pagePath, dPromise]) => {\n // Tell plugins with custom prefetching logic that they should start\n // prefetching this path.\n if (!this.prefetchTriggered.has(pagePath)) {\n this.apiRunner(`onPrefetchPathname`, { pathname: pagePath })\n this.prefetchTriggered.add(pagePath)\n }\n\n // If a plugin has disabled core prefetching, stop now.\n if (this.prefetchDisabled) {\n return dPromise.resolve(false)\n }\n\n return this.doPrefetch(findPath(pagePath)).then(() => {\n if (!this.prefetchCompleted.has(pagePath)) {\n this.apiRunner(`onPostPrefetchPathname`, { pathname: pagePath })\n this.prefetchCompleted.add(pagePath)\n }\n\n dPromise.resolve(true)\n })\n })\n )\n\n if (this.prefetchQueued.length) {\n prefetches.then(() => {\n setTimeout(() => {\n this._processNextPrefetchBatch()\n }, 3000)\n })\n } else {\n this.isPrefetchQueueRunning = false\n }\n })\n }\n\n doPrefetch(pagePath) {\n const pageDataUrl = createPageDataUrl(pagePath)\n\n if (global.hasPartialHydration) {\n return Promise.all([\n prefetchHelper(pageDataUrl, {\n crossOrigin: `anonymous`,\n as: `fetch`,\n }).then(() =>\n // This was just prefetched, so will return a response from\n // the cache instead of making another request to the server\n this.loadPageDataJson(pagePath)\n ),\n prefetchHelper(pageDataUrl.replace(`.json`, `-rsc.json`), {\n crossOrigin: `anonymous`,\n as: `fetch`,\n }).then(() =>\n // This was just prefetched, so will return a response from\n // the cache instead of making another request to the server\n this.loadPartialHydrationJson(pagePath)\n ),\n ])\n } else {\n return prefetchHelper(pageDataUrl, {\n crossOrigin: `anonymous`,\n as: `fetch`,\n }).then(() =>\n // This was just prefetched, so will return a response from\n // the cache instead of making another request to the server\n this.loadPageDataJson(pagePath)\n )\n }\n }\n\n hovering(rawPath) {\n this.loadPage(rawPath)\n }\n\n getResourceURLsForPathname(rawPath) {\n const pagePath = findPath(rawPath)\n const page = this.pageDataDb.get(pagePath)\n if (page) {\n const pageResources = toPageResources(page.payload)\n\n return [\n ...createComponentUrls(pageResources.page.componentChunkName),\n createPageDataUrl(pagePath),\n ]\n } else {\n return null\n }\n }\n\n isPageNotFound(rawPath) {\n const pagePath = findPath(rawPath)\n const page = this.pageDb.get(pagePath)\n return !page || page.notFound\n }\n\n loadAppData(retries = 0) {\n return this.memoizedGet(`${__PATH_PREFIX__}/page-data/app-data.json`).then(\n req => {\n const { status, responseText } = req\n\n let appData\n\n if (status !== 200 && retries < 3) {\n // Retry 3 times incase of non-200 responses\n return this.loadAppData(retries + 1)\n }\n\n // Handle 200\n if (status === 200) {\n try {\n const jsonPayload = JSON.parse(responseText)\n if (jsonPayload.webpackCompilationHash === undefined) {\n throw new Error(`not a valid app-data response`)\n }\n\n appData = jsonPayload\n } catch (err) {\n // continue regardless of error\n }\n }\n\n return appData\n }\n )\n }\n}\n\nconst createComponentUrls = componentChunkName =>\n (window.___chunkMapping[componentChunkName] || []).map(\n chunk => __PATH_PREFIX__ + chunk\n )\n\nexport class ProdLoader extends BaseLoader {\n constructor(asyncRequires, matchPaths, pageData) {\n const loadComponent = (chunkName, exportType = `components`) => {\n if (!global.hasPartialHydration) {\n exportType = `components`\n }\n\n if (!asyncRequires[exportType][chunkName]) {\n throw new Error(\n `We couldn't find the correct component chunk with the name \"${chunkName}\"`\n )\n }\n\n return (\n asyncRequires[exportType][chunkName]()\n // loader will handle the case when component is error\n .catch(err => err)\n )\n }\n\n super(loadComponent, matchPaths)\n\n if (pageData) {\n this.pageDataDb.set(findPath(pageData.path), {\n pagePath: pageData.path,\n payload: pageData,\n status: `success`,\n })\n }\n }\n\n doPrefetch(pagePath) {\n return super.doPrefetch(pagePath).then(result => {\n if (result.status !== PageResourceStatus.Success) {\n return Promise.resolve()\n }\n const pageData = result.payload\n const chunkName = pageData.componentChunkName\n const componentUrls = createComponentUrls(chunkName)\n return Promise.all(componentUrls.map(prefetchHelper)).then(() => pageData)\n })\n }\n\n loadPageDataJson(rawPath) {\n return super.loadPageDataJson(rawPath).then(data => {\n if (data.notFound) {\n if (shouldAbortFetch(rawPath)) {\n return data\n }\n // check if html file exist using HEAD request:\n // if it does we should navigate to it instead of showing 404\n return doFetch(rawPath, `HEAD`).then(req => {\n if (req.status === 200) {\n // page (.html file) actually exist (or we asked for 404 )\n // returning page resources status as errored to trigger\n // regular browser navigation to given page\n return {\n status: PageResourceStatus.Error,\n }\n }\n\n // if HEAD request wasn't 200, return notFound result\n // and show 404 page\n return data\n })\n }\n return data\n })\n }\n\n loadPartialHydrationJson(rawPath) {\n return super.loadPartialHydrationJson(rawPath).then(data => {\n if (data.notFound) {\n if (shouldAbortFetch(rawPath)) {\n return data\n }\n // check if html file exist using HEAD request:\n // if it does we should navigate to it instead of showing 404\n return doFetch(rawPath, `HEAD`).then(req => {\n if (req.status === 200) {\n // page (.html file) actually exist (or we asked for 404 )\n // returning page resources status as errored to trigger\n // regular browser navigation to given page\n return {\n status: PageResourceStatus.Error,\n }\n }\n\n // if HEAD request wasn't 200, return notFound result\n // and show 404 page\n return data\n })\n }\n return data\n })\n }\n}\n\nlet instance\n\nexport const setLoader = _loader => {\n instance = _loader\n}\n\nexport const publicLoader = {\n enqueue: rawPath => instance.prefetch(rawPath),\n\n // Real methods\n getResourceURLsForPathname: rawPath =>\n instance.getResourceURLsForPathname(rawPath),\n loadPage: rawPath => instance.loadPage(rawPath),\n // TODO add deprecation to v4 so people use withErrorDetails and then we can remove in v5 and change default behaviour\n loadPageSync: (rawPath, options = {}) =>\n instance.loadPageSync(rawPath, options),\n prefetch: rawPath => instance.prefetch(rawPath),\n isPageNotFound: rawPath => instance.isPageNotFound(rawPath),\n hovering: rawPath => instance.hovering(rawPath),\n loadAppData: () => instance.loadAppData(),\n}\n\nexport default publicLoader\n\nexport function getStaticQueryResults() {\n if (instance) {\n return instance.staticQueryDb\n } else {\n return {}\n }\n}\n\nexport function getSliceResults() {\n if (instance) {\n return instance.slicesDb\n } else {\n return {}\n }\n}\n","import { useEffect } from \"react\"\n\n/*\n * Calls callback in an effect and renders children\n */\nexport function FireCallbackInEffect({ children, callback }) {\n useEffect(() => {\n callback()\n })\n\n return children\n}\n","export const VALID_NODE_NAMES = [\n `link`,\n `meta`,\n `style`,\n `title`,\n `base`,\n `noscript`,\n `script`,\n `html`,\n `body`,\n]\n","import { VALID_NODE_NAMES } from \"./constants\"\n\n/**\n * Filter the props coming from a page down to just the ones that are relevant for head.\n * This e.g. filters out properties that are undefined during SSR.\n */\nexport function filterHeadProps(input) {\n return {\n location: {\n pathname: input.location.pathname,\n },\n params: input.params,\n data: input.data || {},\n serverData: input.serverData,\n pageContext: input.pageContext,\n }\n}\n\n/**\n * Throw error if Head export is not a valid function\n */\nexport function headExportValidator(head) {\n if (typeof head !== `function`)\n throw new Error(\n `Expected \"Head\" export to be a function got \"${typeof head}\".`\n )\n}\n\n/**\n * Warn once for same messsage\n */\nlet warnOnce = _ => {}\nif (process.env.NODE_ENV !== `production`) {\n const warnings = new Set()\n warnOnce = msg => {\n if (!warnings.has(msg)) {\n console.warn(msg)\n }\n warnings.add(msg)\n }\n}\n\n/**\n * Warn for invalid tags in Head which may have been directly added or introduced by `wrapRootElement`\n * @param {string} tagName\n */\nexport function warnForInvalidTag(tagName) {\n if (process.env.NODE_ENV !== `production`) {\n const warning = createWarningForInvalidTag(tagName)\n warnOnce(warning)\n }\n}\n\nfunction createWarningForInvalidTag(tagName) {\n return `<${tagName}> is not a valid head element. Please use one of the following: ${VALID_NODE_NAMES.join(\n `, `\n )}.\\n\\nAlso make sure that wrapRootElement in gatsby-ssr/gatsby-browser doesn't contain UI elements: https://gatsby.dev/invalid-head-elements`\n}\n\n/**\n * When a `nonce` is present on an element, browsers such as Chrome and Firefox strip it out of the\n * actual HTML attributes for security reasons *when the element is added to the document*. Thus,\n * given two equivalent elements that have nonces, `Element,isEqualNode()` will return false if one\n * of those elements gets added to the document. Although the `element.nonce` property will be the\n * same for both elements, the one that was added to the document will return an empty string for\n * its nonce HTML attribute value.\n *\n * This custom `isEqualNode()` function therefore removes the nonce value from the `newTag` before\n * comparing it to `oldTag`, restoring it afterwards.\n *\n * For more information, see:\n * https://bugs.chromium.org/p/chromium/issues/detail?id=1211471#c12\n */\nexport function isEqualNode(oldTag, newTag) {\n if (oldTag instanceof HTMLElement && newTag instanceof HTMLElement) {\n const nonce = newTag.getAttribute(`nonce`)\n // Only strip the nonce if `oldTag` has had it stripped. An element's nonce attribute will not\n // be stripped if there is no content security policy response header that includes a nonce.\n if (nonce && !oldTag.getAttribute(`nonce`)) {\n const cloneTag = newTag.cloneNode(true)\n cloneTag.setAttribute(`nonce`, ``)\n cloneTag.nonce = nonce\n return nonce === oldTag.nonce && oldTag.isEqualNode(cloneTag)\n }\n }\n\n return oldTag.isEqualNode(newTag)\n}\n\nexport function diffNodes({ oldNodes, newNodes, onStale, onNew }) {\n for (const existingHeadElement of oldNodes) {\n const indexInNewNodes = newNodes.findIndex(e =>\n isEqualNode(e, existingHeadElement)\n )\n\n if (indexInNewNodes === -1) {\n onStale(existingHeadElement)\n } else {\n // this node is re-created as-is, so we keep old node, and remove it from list of new nodes (as we handled it already here)\n newNodes.splice(indexInNewNodes, 1)\n }\n }\n\n // remaing new nodes didn't have matching old node, so need to be added\n for (const newNode of newNodes) {\n onNew(newNode)\n }\n}\n\nexport function getValidHeadNodesAndAttributes(\n rootNode,\n htmlAndBodyAttributes = {\n html: {},\n body: {},\n }\n) {\n const seenIds = new Map()\n const validHeadNodes = []\n\n // Filter out non-element nodes before looping since we don't care about them\n for (const node of rootNode.childNodes) {\n const nodeName = node.nodeName.toLowerCase()\n const id = node.attributes?.id?.value\n\n if (!isElementType(node)) continue\n\n if (isValidNodeName(nodeName)) {\n // and tags are treated differently, in that we don't render them, we only extract the attributes and apply them separetely\n if (nodeName === `html` || nodeName === `body`) {\n for (const attribute of node.attributes) {\n htmlAndBodyAttributes[nodeName] = {\n ...htmlAndBodyAttributes[nodeName],\n [attribute.name]: attribute.value,\n }\n }\n } else {\n let clonedNode = node.cloneNode(true)\n clonedNode.setAttribute(`data-gatsby-head`, true)\n\n // // This is hack to make script tags work\n if (clonedNode.nodeName.toLowerCase() === `script`) {\n clonedNode = massageScript(clonedNode)\n }\n // Duplicate ids are not allowed in the head, so we need to dedupe them\n if (id) {\n if (!seenIds.has(id)) {\n validHeadNodes.push(clonedNode)\n seenIds.set(id, validHeadNodes.length - 1)\n } else {\n const indexOfPreviouslyInsertedNode = seenIds.get(id)\n validHeadNodes[\n indexOfPreviouslyInsertedNode\n ].parentNode?.removeChild(\n validHeadNodes[indexOfPreviouslyInsertedNode]\n )\n validHeadNodes[indexOfPreviouslyInsertedNode] = clonedNode\n }\n } else {\n validHeadNodes.push(clonedNode)\n }\n }\n } else {\n warnForInvalidTag(nodeName)\n }\n\n if (node.childNodes.length) {\n validHeadNodes.push(\n ...getValidHeadNodesAndAttributes(node, htmlAndBodyAttributes)\n .validHeadNodes\n )\n }\n }\n\n return { validHeadNodes, htmlAndBodyAttributes }\n}\n\nfunction massageScript(node) {\n const script = document.createElement(`script`)\n for (const attr of node.attributes) {\n script.setAttribute(attr.name, attr.value)\n }\n script.innerHTML = node.innerHTML\n\n return script\n}\n\nexport function isValidNodeName(nodeName) {\n return VALID_NODE_NAMES.includes(nodeName)\n}\n/*\n * For Head, we only care about element nodes(type = 1), so this util is used to skip over non-element nodes\n * For Node type, see https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType\n */\nexport function isElementType(node) {\n return node.nodeType === 1\n}\n\n/**\n * Removes all the head elements that were added by `Head`\n */\nexport function removePrevHeadElements() {\n const prevHeadNodes = document.querySelectorAll(`[data-gatsby-head]`)\n for (const node of prevHeadNodes) {\n node.parentNode.removeChild(node)\n }\n}\n\nexport function applyHtmlAndBodyAttributes(htmlAndBodyAttributes) {\n if (!htmlAndBodyAttributes) return\n\n const { html, body } = htmlAndBodyAttributes\n\n const htmlElement = document.querySelector(`html`)\n if (htmlElement) {\n Object.entries(html).forEach(([attributeName, attributeValue]) => {\n htmlElement.setAttribute(attributeName, attributeValue)\n })\n }\n\n const bodyElement = document.querySelector(`body`)\n if (bodyElement) {\n Object.entries(body).forEach(([attributeName, attributeValue]) => {\n bodyElement.setAttribute(attributeName, attributeValue)\n })\n }\n}\n\nexport function removeHtmlAndBodyAttributes(htmlAndBodyattributeList) {\n if (!htmlAndBodyattributeList) return\n\n const { html, body } = htmlAndBodyattributeList\n\n if (html) {\n const htmlElement = document.querySelector(`html`)\n html.forEach(attributeName => {\n if (htmlElement) {\n htmlElement.removeAttribute(attributeName)\n }\n })\n }\n\n if (body) {\n const bodyElement = document.querySelector(`body`)\n body.forEach(attributeName => {\n if (bodyElement) {\n bodyElement.removeAttribute(attributeName)\n }\n })\n }\n}\n","import React from \"react\"\nimport { useEffect } from \"react\"\nimport { StaticQueryContext } from \"gatsby\"\nimport { LocationProvider } from \"@gatsbyjs/reach-router\"\nimport { reactDOMUtils } from \"../react-dom-utils\"\nimport { FireCallbackInEffect } from \"./components/fire-callback-in-effect\"\nimport {\n headExportValidator,\n filterHeadProps,\n diffNodes,\n getValidHeadNodesAndAttributes,\n removePrevHeadElements,\n applyHtmlAndBodyAttributes,\n removeHtmlAndBodyAttributes,\n} from \"./utils\"\nimport { apiRunner } from \"../api-runner-browser\"\n\nconst hiddenRoot = document.createElement(`div`)\nconst keysOfHtmlAndBodyAttributes = {\n html: [],\n body: [],\n}\n\nconst onHeadRendered = () => {\n const { validHeadNodes, htmlAndBodyAttributes } =\n getValidHeadNodesAndAttributes(hiddenRoot)\n\n keysOfHtmlAndBodyAttributes.html = Object.keys(htmlAndBodyAttributes.html)\n keysOfHtmlAndBodyAttributes.body = Object.keys(htmlAndBodyAttributes.body)\n\n applyHtmlAndBodyAttributes(htmlAndBodyAttributes)\n\n /**\n * The rest of the code block below is a diffing mechanism to ensure that\n * the head elements aren't duplicted on every re-render.\n */\n const existingHeadElements = document.querySelectorAll(`[data-gatsby-head]`)\n\n if (existingHeadElements.length === 0) {\n document.head.append(...validHeadNodes)\n return\n }\n\n const newHeadNodes = []\n diffNodes({\n oldNodes: existingHeadElements,\n newNodes: validHeadNodes,\n onStale: node => node.parentNode.removeChild(node),\n onNew: node => newHeadNodes.push(node),\n })\n\n document.head.append(...newHeadNodes)\n}\n\nif (process.env.BUILD_STAGE === `develop`) {\n // sigh ... and elements are not valid descedents of
(our hidden element)\n // react-dom in dev mode will warn about this. There doesn't seem to be a way to render arbitrary\n // user Head without hitting this issue (our hidden element could be just \"new Document()\", but\n // this can only have 1 child, and we don't control what is being rendered so that's not an option)\n // instead we continue to render to
, and just silence warnings for and elements\n // https://github.com/facebook/react/blob/e2424f33b3ad727321fc12e75c5e94838e84c2b5/packages/react-dom-bindings/src/client/validateDOMNesting.js#L498-L520\n const originalConsoleError = console.error.bind(console)\n console.error = (...args) => {\n if (\n Array.isArray(args) &&\n args.length >= 2 &&\n args[0]?.includes?.(`validateDOMNesting(...): %s cannot appear as`) &&\n (args[1] === `` || args[1] === ``)\n ) {\n return undefined\n }\n return originalConsoleError(...args)\n }\n\n /* We set up observer to be able to regenerate after react-refresh\n updates our hidden element.\n */\n const observer = new MutationObserver(onHeadRendered)\n observer.observe(hiddenRoot, {\n attributes: true,\n childList: true,\n characterData: true,\n subtree: true,\n })\n}\n\nexport function headHandlerForBrowser({\n pageComponent,\n staticQueryResults,\n pageComponentProps,\n}) {\n useEffect(() => {\n if (pageComponent?.Head) {\n headExportValidator(pageComponent.Head)\n\n const { render } = reactDOMUtils()\n\n const HeadElement = (\n \n )\n\n const WrapHeadElement = apiRunner(\n `wrapRootElement`,\n { element: HeadElement },\n HeadElement,\n ({ result }) => {\n return { element: result }\n }\n ).pop()\n\n render(\n // just a hack to call the callback after react has done first render\n // Note: In dev, we call onHeadRendered twice( in FireCallbackInEffect and after mutualution observer dectects initail render into hiddenRoot) this is for hot reloading\n // In Prod we only call onHeadRendered in FireCallbackInEffect to render to head\n \n \n {WrapHeadElement}\n \n ,\n hiddenRoot\n )\n }\n\n return () => {\n removePrevHeadElements()\n removeHtmlAndBodyAttributes(keysOfHtmlAndBodyAttributes)\n }\n })\n}\n","import React, { Suspense, createElement } from \"react\"\nimport PropTypes from \"prop-types\"\nimport { apiRunner } from \"./api-runner-browser\"\nimport { grabMatchParams } from \"./find-path\"\nimport { headHandlerForBrowser } from \"./head/head-export-handler-for-browser\"\n\n// Renders page\nfunction PageRenderer(props) {\n const pageComponentProps = {\n ...props,\n params: {\n ...grabMatchParams(props.location.pathname),\n ...props.pageResources.json.pageContext.__params,\n },\n }\n\n const preferDefault = m => (m && m.default) || m\n\n let pageElement\n if (props.pageResources.partialHydration) {\n pageElement = props.pageResources.partialHydration\n } else {\n pageElement = createElement(preferDefault(props.pageResources.component), {\n ...pageComponentProps,\n key: props.path || props.pageResources.page.path,\n })\n }\n\n const pageComponent = props.pageResources.head\n\n headHandlerForBrowser({\n pageComponent,\n staticQueryResults: props.pageResources.staticQueryResults,\n pageComponentProps,\n })\n\n const wrappedPage = apiRunner(\n `wrapPageElement`,\n {\n element: pageElement,\n props: pageComponentProps,\n },\n pageElement,\n ({ result }) => {\n return { element: result, props: pageComponentProps }\n }\n ).pop()\n\n return wrappedPage\n}\n\nPageRenderer.propTypes = {\n location: PropTypes.object.isRequired,\n pageResources: PropTypes.object.isRequired,\n data: PropTypes.object,\n pageContext: PropTypes.object.isRequired,\n}\n\nexport default PageRenderer\n","// This is extracted to separate module because it's shared\n// between browser and SSR code\nexport const RouteAnnouncerProps = {\n id: `gatsby-announcer`,\n style: {\n position: `absolute`,\n top: 0,\n width: 1,\n height: 1,\n padding: 0,\n overflow: `hidden`,\n clip: `rect(0, 0, 0, 0)`,\n whiteSpace: `nowrap`,\n border: 0,\n },\n \"aria-live\": `assertive`,\n \"aria-atomic\": `true`,\n}\n","import React from \"react\"\nimport PropTypes from \"prop-types\"\nimport loader, { PageResourceStatus } from \"./loader\"\nimport { maybeGetBrowserRedirect } from \"./redirect-utils.js\"\nimport { apiRunner } from \"./api-runner-browser\"\nimport emitter from \"./emitter\"\nimport { RouteAnnouncerProps } from \"./route-announcer-props\"\nimport {\n navigate as reachNavigate,\n globalHistory,\n} from \"@gatsbyjs/reach-router\"\nimport { parsePath } from \"gatsby-link\"\n\nfunction maybeRedirect(pathname) {\n const redirect = maybeGetBrowserRedirect(pathname)\n const { hash, search } = window.location\n\n if (redirect != null) {\n window.___replace(redirect.toPath + search + hash)\n return true\n } else {\n return false\n }\n}\n\n// Catch unhandled chunk loading errors and force a restart of the app.\nlet nextRoute = ``\n\nwindow.addEventListener(`unhandledrejection`, event => {\n if (/loading chunk \\d* failed./i.test(event.reason)) {\n if (nextRoute) {\n window.location.pathname = nextRoute\n }\n }\n})\n\nconst onPreRouteUpdate = (location, prevLocation) => {\n if (!maybeRedirect(location.pathname)) {\n nextRoute = location.pathname\n apiRunner(`onPreRouteUpdate`, { location, prevLocation })\n }\n}\n\nconst onRouteUpdate = (location, prevLocation) => {\n if (!maybeRedirect(location.pathname)) {\n apiRunner(`onRouteUpdate`, { location, prevLocation })\n if (\n process.env.GATSBY_QUERY_ON_DEMAND &&\n process.env.GATSBY_QUERY_ON_DEMAND_LOADING_INDICATOR === `true`\n ) {\n emitter.emit(`onRouteUpdate`, { location, prevLocation })\n }\n }\n}\n\nconst navigate = (to, options = {}) => {\n // Support forward/backward navigation with numbers\n // navigate(-2) (jumps back 2 history steps)\n // navigate(2) (jumps forward 2 history steps)\n if (typeof to === `number`) {\n globalHistory.navigate(to)\n return\n }\n\n const { pathname, search, hash } = parsePath(to)\n const redirect = maybeGetBrowserRedirect(pathname)\n\n // If we're redirecting, just replace the passed in pathname\n // to the one we want to redirect to.\n if (redirect) {\n to = redirect.toPath + search + hash\n }\n\n // If we had a service worker update, no matter the path, reload window and\n // reset the pathname whitelist\n if (window.___swUpdated) {\n window.location = pathname + search + hash\n return\n }\n\n // Start a timer to wait for a second before transitioning and showing a\n // loader in case resources aren't around yet.\n const timeoutId = setTimeout(() => {\n emitter.emit(`onDelayedLoadPageResources`, { pathname })\n apiRunner(`onRouteUpdateDelayed`, {\n location: window.location,\n })\n }, 1000)\n\n loader.loadPage(pathname + search).then(pageResources => {\n // If no page resources, then refresh the page\n // Do this, rather than simply `window.location.reload()`, so that\n // pressing the back/forward buttons work - otherwise when pressing\n // back, the browser will just change the URL and expect JS to handle\n // the change, which won't always work since it might not be a Gatsby\n // page.\n if (!pageResources || pageResources.status === PageResourceStatus.Error) {\n window.history.replaceState({}, ``, location.href)\n window.location = pathname\n clearTimeout(timeoutId)\n return\n }\n\n // If the loaded page has a different compilation hash to the\n // window, then a rebuild has occurred on the server. Reload.\n if (process.env.NODE_ENV === `production` && pageResources) {\n if (\n pageResources.page.webpackCompilationHash !==\n window.___webpackCompilationHash\n ) {\n // Purge plugin-offline cache\n if (\n `serviceWorker` in navigator &&\n navigator.serviceWorker.controller !== null &&\n navigator.serviceWorker.controller.state === `activated`\n ) {\n navigator.serviceWorker.controller.postMessage({\n gatsbyApi: `clearPathResources`,\n })\n }\n\n window.location = pathname + search + hash\n }\n }\n reachNavigate(to, options)\n clearTimeout(timeoutId)\n })\n}\n\nfunction shouldUpdateScroll(prevRouterProps, { location }) {\n const { pathname, hash } = location\n const results = apiRunner(`shouldUpdateScroll`, {\n prevRouterProps,\n // `pathname` for backwards compatibility\n pathname,\n routerProps: { location },\n getSavedScrollPosition: args => [\n 0,\n // FIXME this is actually a big code smell, we should fix this\n // eslint-disable-next-line @babel/no-invalid-this\n this._stateStorage.read(args, args.key),\n ],\n })\n if (results.length > 0) {\n // Use the latest registered shouldUpdateScroll result, this allows users to override plugin's configuration\n // @see https://github.com/gatsbyjs/gatsby/issues/12038\n return results[results.length - 1]\n }\n\n if (prevRouterProps) {\n const {\n location: { pathname: oldPathname },\n } = prevRouterProps\n if (oldPathname === pathname) {\n // Scroll to element if it exists, if it doesn't, or no hash is provided,\n // scroll to top.\n return hash ? decodeURI(hash.slice(1)) : [0, 0]\n }\n }\n return true\n}\n\nfunction init() {\n // The \"scroll-behavior\" package expects the \"action\" to be on the location\n // object so let's copy it over.\n globalHistory.listen(args => {\n args.location.action = args.action\n })\n\n window.___push = to => navigate(to, { replace: false })\n window.___replace = to => navigate(to, { replace: true })\n window.___navigate = (to, options) => navigate(to, options)\n}\n\nclass RouteAnnouncer extends React.Component {\n constructor(props) {\n super(props)\n this.announcementRef = React.createRef()\n }\n\n componentDidUpdate(prevProps, nextProps) {\n requestAnimationFrame(() => {\n let pageName = `new page at ${this.props.location.pathname}`\n if (document.title) {\n pageName = document.title\n }\n const pageHeadings = document.querySelectorAll(`#gatsby-focus-wrapper h1`)\n if (pageHeadings && pageHeadings.length) {\n pageName = pageHeadings[0].textContent\n }\n const newAnnouncement = `Navigated to ${pageName}`\n if (this.announcementRef.current) {\n const oldAnnouncement = this.announcementRef.current.innerText\n if (oldAnnouncement !== newAnnouncement) {\n this.announcementRef.current.innerText = newAnnouncement\n }\n }\n })\n }\n\n render() {\n return
\n }\n}\n\nconst compareLocationProps = (prevLocation, nextLocation) => {\n if (prevLocation.href !== nextLocation.href) {\n return true\n }\n\n if (prevLocation?.state?.key !== nextLocation?.state?.key) {\n return true\n }\n\n return false\n}\n\n// Fire on(Pre)RouteUpdate APIs\nclass RouteUpdates extends React.Component {\n constructor(props) {\n super(props)\n onPreRouteUpdate(props.location, null)\n }\n\n componentDidMount() {\n onRouteUpdate(this.props.location, null)\n }\n\n shouldComponentUpdate(nextProps) {\n if (compareLocationProps(this.props.location, nextProps.location)) {\n onPreRouteUpdate(nextProps.location, this.props.location)\n return true\n }\n return false\n }\n\n componentDidUpdate(prevProps) {\n if (compareLocationProps(prevProps.location, this.props.location)) {\n onRouteUpdate(this.props.location, prevProps.location)\n }\n }\n\n render() {\n return (\n \n {this.props.children}\n \n \n )\n }\n}\n\nRouteUpdates.propTypes = {\n location: PropTypes.object.isRequired,\n}\n\nexport { init, shouldUpdateScroll, RouteUpdates, maybeGetBrowserRedirect }\n","// Pulled from react-compat\n// https://github.com/developit/preact-compat/blob/7c5de00e7c85e2ffd011bf3af02899b63f699d3a/src/index.js#L349\nfunction shallowDiffers(a, b) {\n for (var i in a) {\n if (!(i in b)) return true;\n }for (var _i in b) {\n if (a[_i] !== b[_i]) return true;\n }return false;\n}\n\nexport default (function (instance, nextProps, nextState) {\n return shallowDiffers(instance.props, nextProps) || shallowDiffers(instance.state, nextState);\n});","import React from \"react\"\nimport loader, { PageResourceStatus } from \"./loader\"\nimport shallowCompare from \"shallow-compare\"\n\nclass EnsureResources extends React.Component {\n constructor(props) {\n super()\n const { location, pageResources } = props\n this.state = {\n location: { ...location },\n pageResources:\n pageResources ||\n loader.loadPageSync(location.pathname + location.search, {\n withErrorDetails: true,\n }),\n }\n }\n\n static getDerivedStateFromProps({ location }, prevState) {\n if (prevState.location.href !== location.href) {\n const pageResources = loader.loadPageSync(\n location.pathname + location.search,\n {\n withErrorDetails: true,\n }\n )\n\n return {\n pageResources,\n location: { ...location },\n }\n }\n\n return {\n location: { ...location },\n }\n }\n\n loadResources(rawPath) {\n loader.loadPage(rawPath).then(pageResources => {\n if (pageResources && pageResources.status !== PageResourceStatus.Error) {\n this.setState({\n location: { ...window.location },\n pageResources,\n })\n } else {\n window.history.replaceState({}, ``, location.href)\n window.location = rawPath\n }\n })\n }\n\n shouldComponentUpdate(nextProps, nextState) {\n // Always return false if we're missing resources.\n if (!nextState.pageResources) {\n this.loadResources(\n nextProps.location.pathname + nextProps.location.search\n )\n return false\n }\n\n if (\n process.env.BUILD_STAGE === `develop` &&\n nextState.pageResources.stale\n ) {\n this.loadResources(\n nextProps.location.pathname + nextProps.location.search\n )\n return false\n }\n\n // Check if the component or json have changed.\n if (this.state.pageResources !== nextState.pageResources) {\n return true\n }\n if (\n this.state.pageResources.component !== nextState.pageResources.component\n ) {\n return true\n }\n\n if (this.state.pageResources.json !== nextState.pageResources.json) {\n return true\n }\n // Check if location has changed on a page using internal routing\n // via matchPath configuration.\n if (\n this.state.location.key !== nextState.location.key &&\n nextState.pageResources.page &&\n (nextState.pageResources.page.matchPath ||\n nextState.pageResources.page.path)\n ) {\n return true\n }\n return shallowCompare(this, nextProps, nextState)\n }\n\n render() {\n if (\n process.env.NODE_ENV !== `production` &&\n (!this.state.pageResources ||\n this.state.pageResources.status === PageResourceStatus.Error)\n ) {\n const message = `EnsureResources was not able to find resources for path: \"${this.props.location.pathname}\"\nThis typically means that an issue occurred building components for that path.\nRun \\`gatsby clean\\` to remove any cached elements.`\n if (this.state.pageResources?.error) {\n console.error(message)\n throw this.state.pageResources.error\n }\n\n throw new Error(message)\n }\n\n return this.props.children(this.state)\n }\n}\n\nexport default EnsureResources\n","import { apiRunner, apiRunnerAsync } from \"./api-runner-browser\"\nimport React from \"react\"\nimport { Router, navigate, Location, BaseContext } from \"@gatsbyjs/reach-router\"\nimport { ScrollContext } from \"gatsby-react-router-scroll\"\nimport { StaticQueryContext } from \"./static-query\"\nimport {\n SlicesMapContext,\n SlicesContext,\n SlicesResultsContext,\n} from \"./slice/context\"\nimport {\n shouldUpdateScroll,\n init as navigationInit,\n RouteUpdates,\n} from \"./navigation\"\nimport emitter from \"./emitter\"\nimport PageRenderer from \"./page-renderer\"\nimport asyncRequires from \"$virtual/async-requires\"\nimport {\n setLoader,\n ProdLoader,\n publicLoader,\n PageResourceStatus,\n getStaticQueryResults,\n getSliceResults,\n} from \"./loader\"\nimport EnsureResources from \"./ensure-resources\"\nimport stripPrefix from \"./strip-prefix\"\n\n// Generated during bootstrap\nimport matchPaths from \"$virtual/match-paths.json\"\nimport { reactDOMUtils } from \"./react-dom-utils\"\n\nconst loader = new ProdLoader(asyncRequires, matchPaths, window.pageData)\nsetLoader(loader)\nloader.setApiRunner(apiRunner)\n\nconst { render, hydrate } = reactDOMUtils()\n\nwindow.asyncRequires = asyncRequires\nwindow.___emitter = emitter\nwindow.___loader = publicLoader\n\nnavigationInit()\n\nconst reloadStorageKey = `gatsby-reload-compilation-hash-match`\n\napiRunnerAsync(`onClientEntry`).then(() => {\n // Let plugins register a service worker. The plugin just needs\n // to return true.\n if (apiRunner(`registerServiceWorker`).filter(Boolean).length > 0) {\n require(`./register-service-worker`)\n }\n\n // In gatsby v2 if Router is used in page using matchPaths\n // paths need to contain full path.\n // For example:\n // - page have `/app/*` matchPath\n // - inside template user needs to use `/app/xyz` as path\n // Resetting `basepath`/`baseuri` keeps current behaviour\n // to not introduce breaking change.\n // Remove this in v3\n const RouteHandler = props => (\n \n \n \n )\n\n const DataContext = React.createContext({})\n\n const slicesContext = {\n renderEnvironment: `browser`,\n }\n\n class GatsbyRoot extends React.Component {\n render() {\n const { children } = this.props\n return (\n \n {({ location }) => (\n \n {({ pageResources, location }) => {\n const staticQueryResults = getStaticQueryResults()\n const sliceResults = getSliceResults()\n\n return (\n \n \n \n \n \n {children}\n \n \n \n \n \n )\n }}\n \n )}\n \n )\n }\n }\n\n class LocationHandler extends React.Component {\n render() {\n return (\n \n {({ pageResources, location }) => (\n \n \n \n \n \n \n \n )}\n \n )\n }\n }\n\n const { pagePath, location: browserLoc } = window\n\n // Explicitly call navigate if the canonical path (window.pagePath)\n // is different to the browser path (window.location.pathname). SSR\n // page paths might include search params, while SSG and DSG won't.\n // If page path include search params we also compare query params.\n // But only if NONE of the following conditions hold:\n //\n // - The url matches a client side route (page.matchPath)\n // - it's a 404 page\n // - it's the offline plugin shell (/offline-plugin-app-shell-fallback/)\n if (\n pagePath &&\n __BASE_PATH__ + pagePath !==\n browserLoc.pathname + (pagePath.includes(`?`) ? browserLoc.search : ``) &&\n !(\n loader.findMatchPath(stripPrefix(browserLoc.pathname, __BASE_PATH__)) ||\n pagePath.match(/^\\/(404|500)(\\/?|.html)$/) ||\n pagePath.match(/^\\/offline-plugin-app-shell-fallback\\/?$/)\n )\n ) {\n navigate(\n __BASE_PATH__ +\n pagePath +\n (!pagePath.includes(`?`) ? browserLoc.search : ``) +\n browserLoc.hash,\n {\n replace: true,\n }\n )\n }\n\n // It's possible that sessionStorage can throw an exception if access is not granted, see https://github.com/gatsbyjs/gatsby/issues/34512\n const getSessionStorage = () => {\n try {\n return sessionStorage\n } catch {\n return null\n }\n }\n\n publicLoader.loadPage(browserLoc.pathname + browserLoc.search).then(page => {\n const sessionStorage = getSessionStorage()\n\n if (\n page?.page?.webpackCompilationHash &&\n page.page.webpackCompilationHash !== window.___webpackCompilationHash\n ) {\n // Purge plugin-offline cache\n if (\n `serviceWorker` in navigator &&\n navigator.serviceWorker.controller !== null &&\n navigator.serviceWorker.controller.state === `activated`\n ) {\n navigator.serviceWorker.controller.postMessage({\n gatsbyApi: `clearPathResources`,\n })\n }\n\n // We have not matching html + js (inlined `window.___webpackCompilationHash`)\n // with our data (coming from `app-data.json` file). This can cause issues such as\n // errors trying to load static queries (as list of static queries is inside `page-data`\n // which might not match to currently loaded `.js` scripts).\n // We are making attempt to reload if hashes don't match, but we also have to handle case\n // when reload doesn't fix it (possibly broken deploy) so we don't end up in infinite reload loop\n if (sessionStorage) {\n const isReloaded = sessionStorage.getItem(reloadStorageKey) === `1`\n\n if (!isReloaded) {\n sessionStorage.setItem(reloadStorageKey, `1`)\n window.location.reload(true)\n return\n }\n }\n }\n\n if (sessionStorage) {\n sessionStorage.removeItem(reloadStorageKey)\n }\n\n if (!page || page.status === PageResourceStatus.Error) {\n const message = `page resources for ${browserLoc.pathname} not found. Not rendering React`\n\n // if the chunk throws an error we want to capture the real error\n // This should help with https://github.com/gatsbyjs/gatsby/issues/19618\n if (page && page.error) {\n console.error(message)\n throw page.error\n }\n\n throw new Error(message)\n }\n\n const SiteRoot = apiRunner(\n `wrapRootElement`,\n { element: },\n ,\n ({ result }) => {\n return { element: result }\n }\n ).pop()\n\n const App = function App() {\n const onClientEntryRanRef = React.useRef(false)\n\n React.useEffect(() => {\n if (!onClientEntryRanRef.current) {\n onClientEntryRanRef.current = true\n if (performance.mark) {\n performance.mark(`onInitialClientRender`)\n }\n\n apiRunner(`onInitialClientRender`)\n }\n }, [])\n\n return {SiteRoot}\n }\n\n const focusEl = document.getElementById(`gatsby-focus-wrapper`)\n\n // Client only pages have any empty body so we just do a normal\n // render to avoid React complaining about hydration mis-matches.\n let defaultRenderer = render\n if (focusEl && focusEl.children.length) {\n defaultRenderer = hydrate\n }\n\n const renderer = apiRunner(\n `replaceHydrateFunction`,\n undefined,\n defaultRenderer\n )[0]\n\n function runRender() {\n const rootElement =\n typeof window !== `undefined`\n ? document.getElementById(`___gatsby`)\n : null\n\n renderer(, rootElement)\n }\n\n // https://github.com/madrobby/zepto/blob/b5ed8d607f67724788ec9ff492be297f64d47dfc/src/zepto.js#L439-L450\n // TODO remove IE 10 support\n const doc = document\n if (\n doc.readyState === `complete` ||\n (doc.readyState !== `loading` && !doc.documentElement.doScroll)\n ) {\n setTimeout(function () {\n runRender()\n }, 0)\n } else {\n const handler = function () {\n doc.removeEventListener(`DOMContentLoaded`, handler, false)\n window.removeEventListener(`load`, handler, false)\n\n runRender()\n }\n\n doc.addEventListener(`DOMContentLoaded`, handler, false)\n window.addEventListener(`load`, handler, false)\n }\n\n return\n })\n})\n","import React from \"react\"\nimport PropTypes from \"prop-types\"\n\nimport loader from \"./loader\"\nimport InternalPageRenderer from \"./page-renderer\"\n\nconst ProdPageRenderer = ({ location }) => {\n const pageResources = loader.loadPageSync(location.pathname)\n if (!pageResources) {\n return null\n }\n return React.createElement(InternalPageRenderer, {\n location,\n pageResources,\n ...pageResources.json,\n })\n}\n\nProdPageRenderer.propTypes = {\n location: PropTypes.shape({\n pathname: PropTypes.string.isRequired,\n }).isRequired,\n}\n\nexport default ProdPageRenderer\n","const preferDefault = m => (m && m.default) || m\n\nif (process.env.BUILD_STAGE === `develop`) {\n module.exports = preferDefault(require(`./public-page-renderer-dev`))\n} else if (process.env.BUILD_STAGE === `build-javascript`) {\n module.exports = preferDefault(require(`./public-page-renderer-prod`))\n} else {\n module.exports = () => null\n}\n","const map = new WeakMap()\n\nexport function reactDOMUtils() {\n const reactDomClient = require(`react-dom/client`)\n\n const render = (Component, el) => {\n let root = map.get(el)\n if (!root) {\n map.set(el, (root = reactDomClient.createRoot(el)))\n }\n root.render(Component)\n }\n\n const hydrate = (Component, el) => reactDomClient.hydrateRoot(el, Component)\n\n return { render, hydrate }\n}\n","import redirects from \"./redirects.json\"\n\n// Convert to a map for faster lookup in maybeRedirect()\n\nconst redirectMap = new Map()\nconst redirectIgnoreCaseMap = new Map()\n\nredirects.forEach(redirect => {\n if (redirect.ignoreCase) {\n redirectIgnoreCaseMap.set(redirect.fromPath, redirect)\n } else {\n redirectMap.set(redirect.fromPath, redirect)\n }\n})\n\nexport function maybeGetBrowserRedirect(pathname) {\n let redirect = redirectMap.get(pathname)\n if (!redirect) {\n redirect = redirectIgnoreCaseMap.get(pathname.toLowerCase())\n }\n return redirect\n}\n","import { apiRunner } from \"./api-runner-browser\"\n\nif (\n window.location.protocol !== `https:` &&\n window.location.hostname !== `localhost`\n) {\n console.error(\n `Service workers can only be used over HTTPS, or on localhost for development`\n )\n} else if (`serviceWorker` in navigator) {\n navigator.serviceWorker\n .register(`${__BASE_PATH__}/sw.js`)\n .then(function (reg) {\n reg.addEventListener(`updatefound`, () => {\n apiRunner(`onServiceWorkerUpdateFound`, { serviceWorker: reg })\n // The updatefound event implies that reg.installing is set; see\n // https://w3c.github.io/ServiceWorker/#service-worker-registration-updatefound-event\n const installingWorker = reg.installing\n console.log(`installingWorker`, installingWorker)\n installingWorker.addEventListener(`statechange`, () => {\n switch (installingWorker.state) {\n case `installed`:\n if (navigator.serviceWorker.controller) {\n // At this point, the old content will have been purged and the fresh content will\n // have been added to the cache.\n\n // We set a flag so Gatsby Link knows to refresh the page on next navigation attempt\n window.___swUpdated = true\n // We call the onServiceWorkerUpdateReady API so users can show update prompts.\n apiRunner(`onServiceWorkerUpdateReady`, { serviceWorker: reg })\n\n // If resources failed for the current page, reload.\n if (window.___failedResources) {\n console.log(`resources failed, SW updated - reloading`)\n window.location.reload()\n }\n } else {\n // At this point, everything has been precached.\n // It's the perfect time to display a \"Content is cached for offline use.\" message.\n console.log(`Content is now available offline!`)\n\n // Post to service worker that install is complete.\n // Delay to allow time for the event listener to be added --\n // otherwise fetch is called too soon and resources aren't cached.\n apiRunner(`onServiceWorkerInstalled`, { serviceWorker: reg })\n }\n break\n\n case `redundant`:\n console.error(`The installing service worker became redundant.`)\n apiRunner(`onServiceWorkerRedundant`, { serviceWorker: reg })\n break\n\n case `activated`:\n apiRunner(`onServiceWorkerActive`, { serviceWorker: reg })\n break\n }\n })\n })\n })\n .catch(function (e) {\n console.error(`Error during service worker registration:`, e)\n })\n}\n","import React from \"react\"\n\nconst SlicesResultsContext = React.createContext({})\nconst SlicesContext = React.createContext({})\nconst SlicesMapContext = React.createContext({})\nconst SlicesPropsContext = React.createContext({})\n\nexport {\n SlicesResultsContext,\n SlicesContext,\n SlicesMapContext,\n SlicesPropsContext,\n}\n","import React from \"react\"\nimport PropTypes from \"prop-types\"\nimport { createServerOrClientContext } from \"./context-utils\"\n\nconst StaticQueryContext = createServerOrClientContext(`StaticQuery`, {})\n\nfunction StaticQueryDataRenderer({ staticQueryData, data, query, render }) {\n const finalData = data\n ? data.data\n : staticQueryData[query] && staticQueryData[query].data\n\n return (\n \n {finalData && render(finalData)}\n {!finalData &&
Loading (StaticQuery)
}\n
\n )\n}\n\nlet warnedAboutStaticQuery = false\n\n// TODO(v6): Remove completely\nconst StaticQuery = props => {\n const { data, query, render, children } = props\n\n if (process.env.NODE_ENV === `development` && !warnedAboutStaticQuery) {\n console.warn(\n `The component is deprecated and will be removed in Gatsby v6. Use useStaticQuery instead. Refer to the migration guide for more information: https://gatsby.dev/migrating-4-to-5/#staticquery--is-deprecated`\n )\n warnedAboutStaticQuery = true\n }\n\n return (\n \n {staticQueryData => (\n \n )}\n \n )\n}\n\nStaticQuery.propTypes = {\n data: PropTypes.object,\n query: PropTypes.string.isRequired,\n render: PropTypes.func,\n children: PropTypes.func,\n}\n\nconst useStaticQuery = query => {\n if (\n typeof React.useContext !== `function` &&\n process.env.NODE_ENV === `development`\n ) {\n // TODO(v5): Remove since we require React >= 18\n throw new Error(\n `You're likely using a version of React that doesn't support Hooks\\n` +\n `Please update React and ReactDOM to 16.8.0 or later to use the useStaticQuery hook.`\n )\n }\n\n const context = React.useContext(StaticQueryContext)\n\n // query is a stringified number like `3303882` when wrapped with graphql, If a user forgets\n // to wrap the query in a grqphql, then casting it to a Number results in `NaN` allowing us to\n // catch the misuse of the API and give proper direction\n if (isNaN(Number(query))) {\n throw new Error(`useStaticQuery was called with a string but expects to be called using \\`graphql\\`. Try this:\n\nimport { useStaticQuery, graphql } from 'gatsby';\n\nuseStaticQuery(graphql\\`${query}\\`);\n`)\n }\n\n if (context[query]?.data) {\n return context[query].data\n } else {\n throw new Error(\n `The result of this StaticQuery could not be fetched.\\n\\n` +\n `This is likely a bug in Gatsby and if refreshing the page does not fix it, ` +\n `please open an issue in https://github.com/gatsbyjs/gatsby/issues`\n )\n }\n}\n\nexport { StaticQuery, StaticQueryContext, useStaticQuery }\n","import React from \"react\"\n\n// Ensure serverContext is not created more than once as React will throw when creating it more than once\n// https://github.com/facebook/react/blob/dd2d6522754f52c70d02c51db25eb7cbd5d1c8eb/packages/react/src/ReactServerContext.js#L101\nconst createServerContext = (name, defaultValue = null) => {\n /* eslint-disable no-undef */\n if (!globalThis.__SERVER_CONTEXT) {\n globalThis.__SERVER_CONTEXT = {}\n }\n\n if (!globalThis.__SERVER_CONTEXT[name]) {\n globalThis.__SERVER_CONTEXT[name] = React.createServerContext(\n name,\n defaultValue\n )\n }\n\n return globalThis.__SERVER_CONTEXT[name]\n}\n\nfunction createServerOrClientContext(name, defaultValue) {\n if (React.createServerContext) {\n return createServerContext(name, defaultValue)\n }\n\n return React.createContext(defaultValue)\n}\n\nexport { createServerOrClientContext }\n","/**\n * Remove a prefix from a string. Return the input string if the given prefix\n * isn't found.\n */\n\nexport default function stripPrefix(str, prefix = ``) {\n if (!prefix) {\n return str\n }\n\n if (str === prefix) {\n return `/`\n }\n\n if (str.startsWith(`${prefix}/`)) {\n return str.slice(prefix.length)\n }\n\n return str\n}\n","import escapeStringRegexp from \"escape-string-regexp\";\nimport { withPrefix } from \"gatsby\";\nexport const userIsForcingNavigation = event => event.button !== 0 || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;\n\n// IE does not include leading slash in anchor.pathname\nexport const slashedPathname = pathname => pathname[0] === `/` ? pathname : `/${pathname}`;\nexport const navigationWasHandledElsewhere = event => event.defaultPrevented;\nexport const findClosestAnchor = node => {\n for (; node.parentNode; node = node.parentNode) {\n if (node.nodeName.toLowerCase() === `a`) {\n return node;\n }\n }\n return null;\n};\nexport const anchorsTargetIsEquivalentToSelf = anchor => /* If target attribute is not present it's treated as _self */\nanchor.hasAttribute(`target`) === false ||\n/**\n * The browser defaults to _self, but, not all browsers set\n * a.target to the string value `_self` by default\n */\n\n/**\n * Assumption: some browsers use null/undefined for default\n * attribute values\n */\nanchor.target == null ||\n/**\n * Some browsers use the empty string to mean _self, check\n * for actual `_self`\n */\n[`_self`, ``].includes(anchor.target) ||\n/**\n * As per https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attr-target\n */\nanchor.target === `_parent` && (!anchor.ownerDocument.defaultView.parent ||\n// Assumption: This can be falsey\nanchor.ownerDocument.defaultView.parent === anchor.ownerDocument.defaultView) || anchor.target === `_top` && (!anchor.ownerDocument.defaultView.top ||\n// Assumption: This can be falsey\nanchor.ownerDocument.defaultView.top === anchor.ownerDocument.defaultView);\nexport const authorIsForcingNavigation = anchor =>\n/**\n * HTML5 attribute that informs the browser to handle the\n * href as a downloadable file; let the browser handle it\n */\nanchor.hasAttribute(`download`) === true ||\n/**\n * Let the browser handle anything that doesn't look like a\n * target=\"_self\" anchor\n */\nanchorsTargetIsEquivalentToSelf(anchor) === false;\n\n// https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy\nexport const urlsAreOnSameOrigin = (origin, destination) => origin.protocol === destination.protocol && /* a.host includes both hostname and port in the expected format host:port */\norigin.host === destination.host;\nexport const pathIsNotHandledByApp = (destination, pathStartRegEx) => {\n const pathFileExtensionRegEx = /^.*\\.((?!htm)[a-z0-9]{1,5})$/i;\n return (\n /**\n * For when pathPrefix is used in an app and there happens to be a link\n * pointing to the same domain but outside of the app's pathPrefix. For\n * example, a Gatsby app lives at https://example.com/myapp/, with the\n * pathPrefix set to `/myapp`. When adding an absolute link to the same\n * domain but outside of the /myapp path, for example, `` the plugin won't catch it and\n * will navigate to an external link instead of doing a pushState resulting\n * in `https://example.com/myapp/https://example.com/not-my-app`\n */\n pathStartRegEx.test(slashedPathname(destination.pathname)) === false ||\n /**\n * Don't catch links pointed at what look like file extensions (other than\n * .htm/html extensions).\n */\n destination.pathname.search(pathFileExtensionRegEx) !== -1\n );\n};\nexport const hashShouldBeFollowed = (origin, destination) => destination.hash !== `` && (\n/**\n * Dynamically created anchor links (href=\"#my-anchor\") do not always\n * have pathname on IE\n */\ndestination.pathname === `` || /* Don't catch links pointed to the same page but with a hash. */\ndestination.pathname === origin.pathname);\nexport const routeThroughBrowserOrApp = (hrefHandler, pluginOptions) => event => {\n if (window.___failedResources) return true;\n if (userIsForcingNavigation(event)) return true;\n if (navigationWasHandledElsewhere(event)) return true;\n const clickedAnchor = findClosestAnchor(event.target);\n if (clickedAnchor == null) return true;\n if (authorIsForcingNavigation(clickedAnchor)) return true;\n\n // IE clears the host value if the anchor href changed after creation, e.g.\n // in React. Creating a new anchor element to ensure host value is present\n const destination = document.createElement(`a`);\n\n // https://html.spec.whatwg.org/multipage/links.html#concept-hyperlink-url-set\n // If clickedAnchor has no href attribute like `example`, the href getter returns empty string.\n if (clickedAnchor.href !== ``) {\n destination.href = clickedAnchor.href;\n }\n if (`SVGAnimatedString` in window && clickedAnchor.href instanceof SVGAnimatedString) {\n destination.href = clickedAnchor.href.animVal;\n }\n\n // In IE, the default port is included in the anchor host but excluded from\n // the location host. This affects the ability to directly compare\n // location host to anchor host. For example: http://example.com would\n // have a location.host of 'example.com' and an destination.host of\n // 'example.com:80' Creating anchor from the location.href to normalize the\n // host value.\n const origin = document.createElement(`a`);\n origin.href = window.location.href;\n if (urlsAreOnSameOrigin(origin, destination) === false) return true;\n\n // Regex to test pathname against pathPrefix\n const pathStartRegEx = new RegExp(`^${escapeStringRegexp(withPrefix(`/`))}`);\n if (pathIsNotHandledByApp(destination, pathStartRegEx)) return true;\n if (hashShouldBeFollowed(origin, destination)) return true;\n if (pluginOptions.excludePattern) {\n const excludeRegex = new RegExp(pluginOptions.excludePattern);\n if (excludeRegex.test(destination.pathname)) {\n return true;\n }\n }\n event.preventDefault();\n\n // See issue #8907: destination.pathname already includes pathPrefix added\n // by gatsby-transformer-remark but gatsby-link.navigate needs href without\n const destinationPathname = slashedPathname(destination.pathname).replace(pathStartRegEx, `/`);\n hrefHandler(`${destinationPathname}${destination.search}${destination.hash}`);\n return false;\n};\nexport default function (root, pluginOptions, cb) {\n const clickHandler = routeThroughBrowserOrApp(cb, pluginOptions);\n root.addEventListener(`click`, clickHandler);\n return () => root.removeEventListener(`click`, clickHandler);\n}","import { navigate } from \"gatsby\";\nimport catchLinks from \"./catch-links\";\nexport const onClientEntry = (_, pluginOptions = {}) => {\n catchLinks(window, pluginOptions, href => {\n navigate(href);\n });\n};","'use strict';\n\nvar matchOperatorsRe = /[|\\\\{}()[\\]^$+*?.]/g;\n\nmodule.exports = function (str) {\n\tif (typeof str !== 'string') {\n\t\tthrow new TypeError('Expected a string');\n\t}\n\n\treturn str.replace(matchOperatorsRe, '\\\\$&');\n};\n","\"use strict\";\n\nexports.wrapPageElement = require(\"./wrap-page\");","\"use strict\";\n\nvar React = require(\"react\");\nvar preferDefault = function preferDefault(m) {\n return m && m.default || m;\n};\nvar Layout;\ntry {\n Layout = preferDefault(require(GATSBY_LAYOUT_COMPONENT_PATH));\n} catch (e) {\n if (e.toString().indexOf(\"Error: Cannot find module\") !== -1) {\n throw new Error(\"Couldn't find layout component at \\\"\" + GATSBY_LAYOUT_COMPONENT_PATH + \".\\n\\n\" + \"Please create layout component in that location or specify path to layout component in gatsby-config.js\");\n } else {\n // Logging the error for debugging older browsers as there is no way\n // to wrap the thrown error in a try/catch.\n console.error(e);\n throw e;\n }\n}\n\n// eslint-disable-next-line react/prop-types,react/display-name\nmodule.exports = function (_ref) {\n var element = _ref.element,\n props = _ref.props;\n return /*#__PURE__*/React.createElement(Layout, props, element);\n};","/* global __MANIFEST_PLUGIN_HAS_LOCALISATION__ */\nimport { withPrefix } from \"gatsby\";\nimport getManifestForPathname from \"./get-manifest-pathname\";\n\n// when we don't have localisation in our manifest, we tree shake everything away\nexport const onRouteUpdate = function onRouteUpdate({\n location\n}, pluginOptions) {\n if (__MANIFEST_PLUGIN_HAS_LOCALISATION__) {\n const {\n localize\n } = pluginOptions;\n const manifestFilename = getManifestForPathname(location.pathname, localize, true);\n const manifestEl = document.head.querySelector(`link[rel=\"manifest\"]`);\n if (manifestEl) {\n manifestEl.setAttribute(`href`, withPrefix(manifestFilename));\n }\n }\n};","\"use strict\";\n\nexports.__esModule = true;\nexports.default = void 0;\nvar _gatsby = require(\"gatsby\");\n/**\n * Get a manifest filename depending on localized pathname\n *\n * @param {string} pathname\n * @param {Array<{start_url: string, lang: string}>} localizedManifests\n * @param {boolean} shouldPrependPathPrefix\n * @return string\n */\nvar _default = (pathname, localizedManifests, shouldPrependPathPrefix = false) => {\n const defaultFilename = `manifest.webmanifest`;\n if (!Array.isArray(localizedManifests)) {\n return defaultFilename;\n }\n const localizedManifest = localizedManifests.find(app => {\n let startUrl = app.start_url;\n if (shouldPrependPathPrefix) {\n startUrl = (0, _gatsby.withPrefix)(startUrl);\n }\n return pathname.startsWith(startUrl);\n });\n if (!localizedManifest) {\n return defaultFilename;\n }\n return `manifest_${localizedManifest.lang}.webmanifest`;\n};\nexports.default = _default;","\"use strict\";\n\nexports.DEFAULT_OPTIONS = {\n maxWidth: 650,\n wrapperStyle: \"\",\n backgroundColor: \"white\",\n linkImagesToOriginal: true,\n showCaptions: false,\n markdownCaptions: false,\n withWebp: false,\n withAvif: false,\n tracedSVG: false,\n loading: \"lazy\",\n decoding: \"async\",\n disableBgImageOnAlpha: false,\n disableBgImage: false\n};\nexports.EMPTY_ALT = \"GATSBY_EMPTY_ALT\";\nexports.imageClass = \"gatsby-resp-image-image\";\nexports.imageWrapperClass = \"gatsby-resp-image-wrapper\";\nexports.imageBackgroundClass = \"gatsby-resp-image-background-image\";","\"use strict\";\n\nvar _require = require(\"./constants\"),\n DEFAULT_OPTIONS = _require.DEFAULT_OPTIONS,\n imageClass = _require.imageClass,\n imageBackgroundClass = _require.imageBackgroundClass,\n imageWrapperClass = _require.imageWrapperClass;\nexports.onRouteUpdate = function (apiCallbackContext, pluginOptions) {\n var options = Object.assign({}, DEFAULT_OPTIONS, pluginOptions);\n var imageWrappers = document.querySelectorAll(\".\" + imageWrapperClass);\n\n // https://css-tricks.com/snippets/javascript/loop-queryselectorall-matches/\n // for cross-browser looping through NodeList without polyfills\n var _loop = function _loop() {\n var imageWrapper = imageWrappers[i];\n var backgroundElement = imageWrapper.querySelector(\".\" + imageBackgroundClass);\n var imageElement = imageWrapper.querySelector(\".\" + imageClass);\n var onImageLoad = function onImageLoad() {\n backgroundElement.style.transition = \"opacity 0.5s 0.5s\";\n imageElement.style.transition = \"opacity 0.5s\";\n onImageComplete();\n };\n var onImageComplete = function onImageComplete() {\n backgroundElement.style.opacity = 0;\n imageElement.style.opacity = 1;\n imageElement.style.color = \"inherit\";\n imageElement.style.boxShadow = \"inset 0px 0px 0px 400px \" + options.backgroundColor;\n imageElement.removeEventListener(\"load\", onImageLoad);\n imageElement.removeEventListener(\"error\", onImageComplete);\n };\n imageElement.style.opacity = 0;\n imageElement.addEventListener(\"load\", onImageLoad);\n imageElement.addEventListener(\"error\", onImageComplete);\n if (imageElement.complete) {\n onImageComplete();\n }\n };\n for (var i = 0; i < imageWrappers.length; i++) {\n _loop();\n }\n};","function ownKeys(object, enumerableOnly) {\n var keys = Object.keys(object);\n\n if (Object.getOwnPropertySymbols) {\n var symbols = Object.getOwnPropertySymbols(object);\n enumerableOnly && (symbols = symbols.filter(function (sym) {\n return Object.getOwnPropertyDescriptor(object, sym).enumerable;\n })), keys.push.apply(keys, symbols);\n }\n\n return keys;\n}\n\nfunction _objectSpread2(target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = null != arguments[i] ? arguments[i] : {};\n i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {\n _defineProperty(target, key, source[key]);\n }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {\n Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));\n });\n }\n\n return target;\n}\n\nfunction _typeof(obj) {\n \"@babel/helpers - typeof\";\n\n return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (obj) {\n return typeof obj;\n } : function (obj) {\n return obj && \"function\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n }, _typeof(obj);\n}\n\nfunction _wrapRegExp() {\n _wrapRegExp = function (re, groups) {\n return new BabelRegExp(re, void 0, groups);\n };\n\n var _super = RegExp.prototype,\n _groups = new WeakMap();\n\n function BabelRegExp(re, flags, groups) {\n var _this = new RegExp(re, flags);\n\n return _groups.set(_this, groups || _groups.get(re)), _setPrototypeOf(_this, BabelRegExp.prototype);\n }\n\n function buildGroups(result, re) {\n var g = _groups.get(re);\n\n return Object.keys(g).reduce(function (groups, name) {\n return groups[name] = result[g[name]], groups;\n }, Object.create(null));\n }\n\n return _inherits(BabelRegExp, RegExp), BabelRegExp.prototype.exec = function (str) {\n var result = _super.exec.call(this, str);\n\n return result && (result.groups = buildGroups(result, this)), result;\n }, BabelRegExp.prototype[Symbol.replace] = function (str, substitution) {\n if (\"string\" == typeof substitution) {\n var groups = _groups.get(this);\n\n return _super[Symbol.replace].call(this, str, substitution.replace(/\\$<([^>]+)>/g, function (_, name) {\n return \"$\" + groups[name];\n }));\n }\n\n if (\"function\" == typeof substitution) {\n var _this = this;\n\n return _super[Symbol.replace].call(this, str, function () {\n var args = arguments;\n return \"object\" != typeof args[args.length - 1] && (args = [].slice.call(args)).push(buildGroups(args, _this)), substitution.apply(this, args);\n });\n }\n\n return _super[Symbol.replace].call(this, str, substitution);\n }, _wrapRegExp.apply(this, arguments);\n}\n\nfunction _classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n}\n\nfunction _defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n}\n\nfunction _createClass(Constructor, protoProps, staticProps) {\n if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n if (staticProps) _defineProperties(Constructor, staticProps);\n Object.defineProperty(Constructor, \"prototype\", {\n writable: false\n });\n return Constructor;\n}\n\nfunction _defineProperty(obj, key, value) {\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n\n return obj;\n}\n\nfunction _inherits(subClass, superClass) {\n if (typeof superClass !== \"function\" && superClass !== null) {\n throw new TypeError(\"Super expression must either be null or a function\");\n }\n\n subClass.prototype = Object.create(superClass && superClass.prototype, {\n constructor: {\n value: subClass,\n writable: true,\n configurable: true\n }\n });\n Object.defineProperty(subClass, \"prototype\", {\n writable: false\n });\n if (superClass) _setPrototypeOf(subClass, superClass);\n}\n\nfunction _setPrototypeOf(o, p) {\n _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {\n o.__proto__ = p;\n return o;\n };\n\n return _setPrototypeOf(o, p);\n}\n\nfunction _slicedToArray(arr, i) {\n return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();\n}\n\nfunction _toConsumableArray(arr) {\n return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();\n}\n\nfunction _arrayWithoutHoles(arr) {\n if (Array.isArray(arr)) return _arrayLikeToArray(arr);\n}\n\nfunction _arrayWithHoles(arr) {\n if (Array.isArray(arr)) return arr;\n}\n\nfunction _iterableToArray(iter) {\n if (typeof Symbol !== \"undefined\" && iter[Symbol.iterator] != null || iter[\"@@iterator\"] != null) return Array.from(iter);\n}\n\nfunction _iterableToArrayLimit(arr, i) {\n var _i = arr == null ? null : typeof Symbol !== \"undefined\" && arr[Symbol.iterator] || arr[\"@@iterator\"];\n\n if (_i == null) return;\n var _arr = [];\n var _n = true;\n var _d = false;\n\n var _s, _e;\n\n try {\n for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {\n _arr.push(_s.value);\n\n if (i && _arr.length === i) break;\n }\n } catch (err) {\n _d = true;\n _e = err;\n } finally {\n try {\n if (!_n && _i[\"return\"] != null) _i[\"return\"]();\n } finally {\n if (_d) throw _e;\n }\n }\n\n return _arr;\n}\n\nfunction _unsupportedIterableToArray(o, minLen) {\n if (!o) return;\n if (typeof o === \"string\") return _arrayLikeToArray(o, minLen);\n var n = Object.prototype.toString.call(o).slice(8, -1);\n if (n === \"Object\" && o.constructor) n = o.constructor.name;\n if (n === \"Map\" || n === \"Set\") return Array.from(o);\n if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);\n}\n\nfunction _arrayLikeToArray(arr, len) {\n if (len == null || len > arr.length) len = arr.length;\n\n for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];\n\n return arr2;\n}\n\nfunction _nonIterableSpread() {\n throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n}\n\nfunction _nonIterableRest() {\n throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n}\n\nvar noop = function noop() {};\n\nvar _WINDOW = {};\nvar _DOCUMENT = {};\nvar _MUTATION_OBSERVER = null;\nvar _PERFORMANCE = {\n mark: noop,\n measure: noop\n};\n\ntry {\n if (typeof window !== 'undefined') _WINDOW = window;\n if (typeof document !== 'undefined') _DOCUMENT = document;\n if (typeof MutationObserver !== 'undefined') _MUTATION_OBSERVER = MutationObserver;\n if (typeof performance !== 'undefined') _PERFORMANCE = performance;\n} catch (e) {}\n\nvar _ref = _WINDOW.navigator || {},\n _ref$userAgent = _ref.userAgent,\n userAgent = _ref$userAgent === void 0 ? '' : _ref$userAgent;\nvar WINDOW = _WINDOW;\nvar DOCUMENT = _DOCUMENT;\nvar MUTATION_OBSERVER = _MUTATION_OBSERVER;\nvar PERFORMANCE = _PERFORMANCE;\nvar IS_BROWSER = !!WINDOW.document;\nvar IS_DOM = !!DOCUMENT.documentElement && !!DOCUMENT.head && typeof DOCUMENT.addEventListener === 'function' && typeof DOCUMENT.createElement === 'function';\nvar IS_IE = ~userAgent.indexOf('MSIE') || ~userAgent.indexOf('Trident/');\n\nvar _familyProxy, _familyProxy2, _familyProxy3, _familyProxy4, _familyProxy5;\n\nvar NAMESPACE_IDENTIFIER = '___FONT_AWESOME___';\nvar UNITS_IN_GRID = 16;\nvar DEFAULT_CSS_PREFIX = 'fa';\nvar DEFAULT_REPLACEMENT_CLASS = 'svg-inline--fa';\nvar DATA_FA_I2SVG = 'data-fa-i2svg';\nvar DATA_FA_PSEUDO_ELEMENT = 'data-fa-pseudo-element';\nvar DATA_FA_PSEUDO_ELEMENT_PENDING = 'data-fa-pseudo-element-pending';\nvar DATA_PREFIX = 'data-prefix';\nvar DATA_ICON = 'data-icon';\nvar HTML_CLASS_I2SVG_BASE_CLASS = 'fontawesome-i2svg';\nvar MUTATION_APPROACH_ASYNC = 'async';\nvar TAGNAMES_TO_SKIP_FOR_PSEUDOELEMENTS = ['HTML', 'HEAD', 'STYLE', 'SCRIPT'];\nvar PRODUCTION = function () {\n try {\n return process.env.NODE_ENV === 'production';\n } catch (e) {\n return false;\n }\n}();\nvar FAMILY_CLASSIC = 'classic';\nvar FAMILY_SHARP = 'sharp';\nvar FAMILIES = [FAMILY_CLASSIC, FAMILY_SHARP];\n\nfunction familyProxy(obj) {\n // Defaults to the classic family if family is not available\n return new Proxy(obj, {\n get: function get(target, prop) {\n return prop in target ? target[prop] : target[FAMILY_CLASSIC];\n }\n });\n}\nvar PREFIX_TO_STYLE = familyProxy((_familyProxy = {}, _defineProperty(_familyProxy, FAMILY_CLASSIC, {\n 'fa': 'solid',\n 'fas': 'solid',\n 'fa-solid': 'solid',\n 'far': 'regular',\n 'fa-regular': 'regular',\n 'fal': 'light',\n 'fa-light': 'light',\n 'fat': 'thin',\n 'fa-thin': 'thin',\n 'fad': 'duotone',\n 'fa-duotone': 'duotone',\n 'fab': 'brands',\n 'fa-brands': 'brands',\n 'fak': 'kit',\n 'fa-kit': 'kit'\n}), _defineProperty(_familyProxy, FAMILY_SHARP, {\n 'fa': 'solid',\n 'fass': 'solid',\n 'fa-solid': 'solid',\n 'fasr': 'regular',\n 'fa-regular': 'regular',\n 'fasl': 'light',\n 'fa-light': 'light'\n}), _familyProxy));\nvar STYLE_TO_PREFIX = familyProxy((_familyProxy2 = {}, _defineProperty(_familyProxy2, FAMILY_CLASSIC, {\n 'solid': 'fas',\n 'regular': 'far',\n 'light': 'fal',\n 'thin': 'fat',\n 'duotone': 'fad',\n 'brands': 'fab',\n 'kit': 'fak'\n}), _defineProperty(_familyProxy2, FAMILY_SHARP, {\n 'solid': 'fass',\n 'regular': 'fasr',\n 'light': 'fasl'\n}), _familyProxy2));\nvar PREFIX_TO_LONG_STYLE = familyProxy((_familyProxy3 = {}, _defineProperty(_familyProxy3, FAMILY_CLASSIC, {\n 'fab': 'fa-brands',\n 'fad': 'fa-duotone',\n 'fak': 'fa-kit',\n 'fal': 'fa-light',\n 'far': 'fa-regular',\n 'fas': 'fa-solid',\n 'fat': 'fa-thin'\n}), _defineProperty(_familyProxy3, FAMILY_SHARP, {\n 'fass': 'fa-solid',\n 'fasr': 'fa-regular',\n 'fasl': 'fa-light'\n}), _familyProxy3));\nvar LONG_STYLE_TO_PREFIX = familyProxy((_familyProxy4 = {}, _defineProperty(_familyProxy4, FAMILY_CLASSIC, {\n 'fa-brands': 'fab',\n 'fa-duotone': 'fad',\n 'fa-kit': 'fak',\n 'fa-light': 'fal',\n 'fa-regular': 'far',\n 'fa-solid': 'fas',\n 'fa-thin': 'fat'\n}), _defineProperty(_familyProxy4, FAMILY_SHARP, {\n 'fa-solid': 'fass',\n 'fa-regular': 'fasr',\n 'fa-light': 'fasl'\n}), _familyProxy4));\nvar ICON_SELECTION_SYNTAX_PATTERN = /fa(s|r|l|t|d|b|k|ss|sr|sl)?[\\-\\ ]/; // eslint-disable-line no-useless-escape\n\nvar LAYERS_TEXT_CLASSNAME = 'fa-layers-text';\nvar FONT_FAMILY_PATTERN = /Font ?Awesome ?([56 ]*)(Solid|Regular|Light|Thin|Duotone|Brands|Free|Pro|Sharp|Kit)?.*/i;\nvar FONT_WEIGHT_TO_PREFIX = familyProxy((_familyProxy5 = {}, _defineProperty(_familyProxy5, FAMILY_CLASSIC, {\n '900': 'fas',\n '400': 'far',\n 'normal': 'far',\n '300': 'fal',\n '100': 'fat'\n}), _defineProperty(_familyProxy5, FAMILY_SHARP, {\n '900': 'fass',\n '400': 'fasr',\n '300': 'fasl'\n}), _familyProxy5));\nvar oneToTen = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\nvar oneToTwenty = oneToTen.concat([11, 12, 13, 14, 15, 16, 17, 18, 19, 20]);\nvar ATTRIBUTES_WATCHED_FOR_MUTATION = ['class', 'data-prefix', 'data-icon', 'data-fa-transform', 'data-fa-mask'];\nvar DUOTONE_CLASSES = {\n GROUP: 'duotone-group',\n SWAP_OPACITY: 'swap-opacity',\n PRIMARY: 'primary',\n SECONDARY: 'secondary'\n};\nvar prefixes = new Set();\nObject.keys(STYLE_TO_PREFIX[FAMILY_CLASSIC]).map(prefixes.add.bind(prefixes));\nObject.keys(STYLE_TO_PREFIX[FAMILY_SHARP]).map(prefixes.add.bind(prefixes));\nvar RESERVED_CLASSES = [].concat(FAMILIES, _toConsumableArray(prefixes), ['2xs', 'xs', 'sm', 'lg', 'xl', '2xl', 'beat', 'border', 'fade', 'beat-fade', 'bounce', 'flip-both', 'flip-horizontal', 'flip-vertical', 'flip', 'fw', 'inverse', 'layers-counter', 'layers-text', 'layers', 'li', 'pull-left', 'pull-right', 'pulse', 'rotate-180', 'rotate-270', 'rotate-90', 'rotate-by', 'shake', 'spin-pulse', 'spin-reverse', 'spin', 'stack-1x', 'stack-2x', 'stack', 'ul', DUOTONE_CLASSES.GROUP, DUOTONE_CLASSES.SWAP_OPACITY, DUOTONE_CLASSES.PRIMARY, DUOTONE_CLASSES.SECONDARY]).concat(oneToTen.map(function (n) {\n return \"\".concat(n, \"x\");\n})).concat(oneToTwenty.map(function (n) {\n return \"w-\".concat(n);\n}));\n\nvar initial = WINDOW.FontAwesomeConfig || {};\n\nfunction getAttrConfig(attr) {\n var element = DOCUMENT.querySelector('script[' + attr + ']');\n\n if (element) {\n return element.getAttribute(attr);\n }\n}\n\nfunction coerce(val) {\n // Getting an empty string will occur if the attribute is set on the HTML tag but without a value\n // We'll assume that this is an indication that it should be toggled to true\n if (val === '') return true;\n if (val === 'false') return false;\n if (val === 'true') return true;\n return val;\n}\n\nif (DOCUMENT && typeof DOCUMENT.querySelector === 'function') {\n var attrs = [['data-family-prefix', 'familyPrefix'], ['data-css-prefix', 'cssPrefix'], ['data-family-default', 'familyDefault'], ['data-style-default', 'styleDefault'], ['data-replacement-class', 'replacementClass'], ['data-auto-replace-svg', 'autoReplaceSvg'], ['data-auto-add-css', 'autoAddCss'], ['data-auto-a11y', 'autoA11y'], ['data-search-pseudo-elements', 'searchPseudoElements'], ['data-observe-mutations', 'observeMutations'], ['data-mutate-approach', 'mutateApproach'], ['data-keep-original-source', 'keepOriginalSource'], ['data-measure-performance', 'measurePerformance'], ['data-show-missing-icons', 'showMissingIcons']];\n attrs.forEach(function (_ref) {\n var _ref2 = _slicedToArray(_ref, 2),\n attr = _ref2[0],\n key = _ref2[1];\n\n var val = coerce(getAttrConfig(attr));\n\n if (val !== undefined && val !== null) {\n initial[key] = val;\n }\n });\n}\n\nvar _default = {\n styleDefault: 'solid',\n familyDefault: 'classic',\n cssPrefix: DEFAULT_CSS_PREFIX,\n replacementClass: DEFAULT_REPLACEMENT_CLASS,\n autoReplaceSvg: true,\n autoAddCss: true,\n autoA11y: true,\n searchPseudoElements: false,\n observeMutations: true,\n mutateApproach: 'async',\n keepOriginalSource: true,\n measurePerformance: false,\n showMissingIcons: true\n}; // familyPrefix is deprecated but we must still support it if present\n\nif (initial.familyPrefix) {\n initial.cssPrefix = initial.familyPrefix;\n}\n\nvar _config = _objectSpread2(_objectSpread2({}, _default), initial);\n\nif (!_config.autoReplaceSvg) _config.observeMutations = false;\nvar config = {};\nObject.keys(_default).forEach(function (key) {\n Object.defineProperty(config, key, {\n enumerable: true,\n set: function set(val) {\n _config[key] = val;\n\n _onChangeCb.forEach(function (cb) {\n return cb(config);\n });\n },\n get: function get() {\n return _config[key];\n }\n });\n}); // familyPrefix is deprecated as of 6.2.0 and should be removed in 7.0.0\n\nObject.defineProperty(config, 'familyPrefix', {\n enumerable: true,\n set: function set(val) {\n _config.cssPrefix = val;\n\n _onChangeCb.forEach(function (cb) {\n return cb(config);\n });\n },\n get: function get() {\n return _config.cssPrefix;\n }\n});\nWINDOW.FontAwesomeConfig = config;\nvar _onChangeCb = [];\nfunction onChange(cb) {\n _onChangeCb.push(cb);\n\n return function () {\n _onChangeCb.splice(_onChangeCb.indexOf(cb), 1);\n };\n}\n\nvar d = UNITS_IN_GRID;\nvar meaninglessTransform = {\n size: 16,\n x: 0,\n y: 0,\n rotate: 0,\n flipX: false,\n flipY: false\n};\nfunction insertCss(css) {\n if (!css || !IS_DOM) {\n return;\n }\n\n var style = DOCUMENT.createElement('style');\n style.setAttribute('type', 'text/css');\n style.innerHTML = css;\n var headChildren = DOCUMENT.head.childNodes;\n var beforeChild = null;\n\n for (var i = headChildren.length - 1; i > -1; i--) {\n var child = headChildren[i];\n var tagName = (child.tagName || '').toUpperCase();\n\n if (['STYLE', 'LINK'].indexOf(tagName) > -1) {\n beforeChild = child;\n }\n }\n\n DOCUMENT.head.insertBefore(style, beforeChild);\n return css;\n}\nvar idPool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';\nfunction nextUniqueId() {\n var size = 12;\n var id = '';\n\n while (size-- > 0) {\n id += idPool[Math.random() * 62 | 0];\n }\n\n return id;\n}\nfunction toArray(obj) {\n var array = [];\n\n for (var i = (obj || []).length >>> 0; i--;) {\n array[i] = obj[i];\n }\n\n return array;\n}\nfunction classArray(node) {\n if (node.classList) {\n return toArray(node.classList);\n } else {\n return (node.getAttribute('class') || '').split(' ').filter(function (i) {\n return i;\n });\n }\n}\nfunction htmlEscape(str) {\n return \"\".concat(str).replace(/&/g, '&').replace(/\"/g, '"').replace(/'/g, ''').replace(//g, '>');\n}\nfunction joinAttributes(attributes) {\n return Object.keys(attributes || {}).reduce(function (acc, attributeName) {\n return acc + \"\".concat(attributeName, \"=\\\"\").concat(htmlEscape(attributes[attributeName]), \"\\\" \");\n }, '').trim();\n}\nfunction joinStyles(styles) {\n return Object.keys(styles || {}).reduce(function (acc, styleName) {\n return acc + \"\".concat(styleName, \": \").concat(styles[styleName].trim(), \";\");\n }, '');\n}\nfunction transformIsMeaningful(transform) {\n return transform.size !== meaninglessTransform.size || transform.x !== meaninglessTransform.x || transform.y !== meaninglessTransform.y || transform.rotate !== meaninglessTransform.rotate || transform.flipX || transform.flipY;\n}\nfunction transformForSvg(_ref) {\n var transform = _ref.transform,\n containerWidth = _ref.containerWidth,\n iconWidth = _ref.iconWidth;\n var outer = {\n transform: \"translate(\".concat(containerWidth / 2, \" 256)\")\n };\n var innerTranslate = \"translate(\".concat(transform.x * 32, \", \").concat(transform.y * 32, \") \");\n var innerScale = \"scale(\".concat(transform.size / 16 * (transform.flipX ? -1 : 1), \", \").concat(transform.size / 16 * (transform.flipY ? -1 : 1), \") \");\n var innerRotate = \"rotate(\".concat(transform.rotate, \" 0 0)\");\n var inner = {\n transform: \"\".concat(innerTranslate, \" \").concat(innerScale, \" \").concat(innerRotate)\n };\n var path = {\n transform: \"translate(\".concat(iconWidth / 2 * -1, \" -256)\")\n };\n return {\n outer: outer,\n inner: inner,\n path: path\n };\n}\nfunction transformForCss(_ref2) {\n var transform = _ref2.transform,\n _ref2$width = _ref2.width,\n width = _ref2$width === void 0 ? UNITS_IN_GRID : _ref2$width,\n _ref2$height = _ref2.height,\n height = _ref2$height === void 0 ? UNITS_IN_GRID : _ref2$height,\n _ref2$startCentered = _ref2.startCentered,\n startCentered = _ref2$startCentered === void 0 ? false : _ref2$startCentered;\n var val = '';\n\n if (startCentered && IS_IE) {\n val += \"translate(\".concat(transform.x / d - width / 2, \"em, \").concat(transform.y / d - height / 2, \"em) \");\n } else if (startCentered) {\n val += \"translate(calc(-50% + \".concat(transform.x / d, \"em), calc(-50% + \").concat(transform.y / d, \"em)) \");\n } else {\n val += \"translate(\".concat(transform.x / d, \"em, \").concat(transform.y / d, \"em) \");\n }\n\n val += \"scale(\".concat(transform.size / d * (transform.flipX ? -1 : 1), \", \").concat(transform.size / d * (transform.flipY ? -1 : 1), \") \");\n val += \"rotate(\".concat(transform.rotate, \"deg) \");\n return val;\n}\n\nvar baseStyles = \":root, :host {\\n --fa-font-solid: normal 900 1em/1 \\\"Font Awesome 6 Solid\\\";\\n --fa-font-regular: normal 400 1em/1 \\\"Font Awesome 6 Regular\\\";\\n --fa-font-light: normal 300 1em/1 \\\"Font Awesome 6 Light\\\";\\n --fa-font-thin: normal 100 1em/1 \\\"Font Awesome 6 Thin\\\";\\n --fa-font-duotone: normal 900 1em/1 \\\"Font Awesome 6 Duotone\\\";\\n --fa-font-sharp-solid: normal 900 1em/1 \\\"Font Awesome 6 Sharp\\\";\\n --fa-font-sharp-regular: normal 400 1em/1 \\\"Font Awesome 6 Sharp\\\";\\n --fa-font-sharp-light: normal 300 1em/1 \\\"Font Awesome 6 Sharp\\\";\\n --fa-font-brands: normal 400 1em/1 \\\"Font Awesome 6 Brands\\\";\\n}\\n\\nsvg:not(:root).svg-inline--fa, svg:not(:host).svg-inline--fa {\\n overflow: visible;\\n box-sizing: content-box;\\n}\\n\\n.svg-inline--fa {\\n display: var(--fa-display, inline-block);\\n height: 1em;\\n overflow: visible;\\n vertical-align: -0.125em;\\n}\\n.svg-inline--fa.fa-2xs {\\n vertical-align: 0.1em;\\n}\\n.svg-inline--fa.fa-xs {\\n vertical-align: 0em;\\n}\\n.svg-inline--fa.fa-sm {\\n vertical-align: -0.0714285705em;\\n}\\n.svg-inline--fa.fa-lg {\\n vertical-align: -0.2em;\\n}\\n.svg-inline--fa.fa-xl {\\n vertical-align: -0.25em;\\n}\\n.svg-inline--fa.fa-2xl {\\n vertical-align: -0.3125em;\\n}\\n.svg-inline--fa.fa-pull-left {\\n margin-right: var(--fa-pull-margin, 0.3em);\\n width: auto;\\n}\\n.svg-inline--fa.fa-pull-right {\\n margin-left: var(--fa-pull-margin, 0.3em);\\n width: auto;\\n}\\n.svg-inline--fa.fa-li {\\n width: var(--fa-li-width, 2em);\\n top: 0.25em;\\n}\\n.svg-inline--fa.fa-fw {\\n width: var(--fa-fw-width, 1.25em);\\n}\\n\\n.fa-layers svg.svg-inline--fa {\\n bottom: 0;\\n left: 0;\\n margin: auto;\\n position: absolute;\\n right: 0;\\n top: 0;\\n}\\n\\n.fa-layers-counter, .fa-layers-text {\\n display: inline-block;\\n position: absolute;\\n text-align: center;\\n}\\n\\n.fa-layers {\\n display: inline-block;\\n height: 1em;\\n position: relative;\\n text-align: center;\\n vertical-align: -0.125em;\\n width: 1em;\\n}\\n.fa-layers svg.svg-inline--fa {\\n -webkit-transform-origin: center center;\\n transform-origin: center center;\\n}\\n\\n.fa-layers-text {\\n left: 50%;\\n top: 50%;\\n -webkit-transform: translate(-50%, -50%);\\n transform: translate(-50%, -50%);\\n -webkit-transform-origin: center center;\\n transform-origin: center center;\\n}\\n\\n.fa-layers-counter {\\n background-color: var(--fa-counter-background-color, #ff253a);\\n border-radius: var(--fa-counter-border-radius, 1em);\\n box-sizing: border-box;\\n color: var(--fa-inverse, #fff);\\n line-height: var(--fa-counter-line-height, 1);\\n max-width: var(--fa-counter-max-width, 5em);\\n min-width: var(--fa-counter-min-width, 1.5em);\\n overflow: hidden;\\n padding: var(--fa-counter-padding, 0.25em 0.5em);\\n right: var(--fa-right, 0);\\n text-overflow: ellipsis;\\n top: var(--fa-top, 0);\\n -webkit-transform: scale(var(--fa-counter-scale, 0.25));\\n transform: scale(var(--fa-counter-scale, 0.25));\\n -webkit-transform-origin: top right;\\n transform-origin: top right;\\n}\\n\\n.fa-layers-bottom-right {\\n bottom: var(--fa-bottom, 0);\\n right: var(--fa-right, 0);\\n top: auto;\\n -webkit-transform: scale(var(--fa-layers-scale, 0.25));\\n transform: scale(var(--fa-layers-scale, 0.25));\\n -webkit-transform-origin: bottom right;\\n transform-origin: bottom right;\\n}\\n\\n.fa-layers-bottom-left {\\n bottom: var(--fa-bottom, 0);\\n left: var(--fa-left, 0);\\n right: auto;\\n top: auto;\\n -webkit-transform: scale(var(--fa-layers-scale, 0.25));\\n transform: scale(var(--fa-layers-scale, 0.25));\\n -webkit-transform-origin: bottom left;\\n transform-origin: bottom left;\\n}\\n\\n.fa-layers-top-right {\\n top: var(--fa-top, 0);\\n right: var(--fa-right, 0);\\n -webkit-transform: scale(var(--fa-layers-scale, 0.25));\\n transform: scale(var(--fa-layers-scale, 0.25));\\n -webkit-transform-origin: top right;\\n transform-origin: top right;\\n}\\n\\n.fa-layers-top-left {\\n left: var(--fa-left, 0);\\n right: auto;\\n top: var(--fa-top, 0);\\n -webkit-transform: scale(var(--fa-layers-scale, 0.25));\\n transform: scale(var(--fa-layers-scale, 0.25));\\n -webkit-transform-origin: top left;\\n transform-origin: top left;\\n}\\n\\n.fa-1x {\\n font-size: 1em;\\n}\\n\\n.fa-2x {\\n font-size: 2em;\\n}\\n\\n.fa-3x {\\n font-size: 3em;\\n}\\n\\n.fa-4x {\\n font-size: 4em;\\n}\\n\\n.fa-5x {\\n font-size: 5em;\\n}\\n\\n.fa-6x {\\n font-size: 6em;\\n}\\n\\n.fa-7x {\\n font-size: 7em;\\n}\\n\\n.fa-8x {\\n font-size: 8em;\\n}\\n\\n.fa-9x {\\n font-size: 9em;\\n}\\n\\n.fa-10x {\\n font-size: 10em;\\n}\\n\\n.fa-2xs {\\n font-size: 0.625em;\\n line-height: 0.1em;\\n vertical-align: 0.225em;\\n}\\n\\n.fa-xs {\\n font-size: 0.75em;\\n line-height: 0.0833333337em;\\n vertical-align: 0.125em;\\n}\\n\\n.fa-sm {\\n font-size: 0.875em;\\n line-height: 0.0714285718em;\\n vertical-align: 0.0535714295em;\\n}\\n\\n.fa-lg {\\n font-size: 1.25em;\\n line-height: 0.05em;\\n vertical-align: -0.075em;\\n}\\n\\n.fa-xl {\\n font-size: 1.5em;\\n line-height: 0.0416666682em;\\n vertical-align: -0.125em;\\n}\\n\\n.fa-2xl {\\n font-size: 2em;\\n line-height: 0.03125em;\\n vertical-align: -0.1875em;\\n}\\n\\n.fa-fw {\\n text-align: center;\\n width: 1.25em;\\n}\\n\\n.fa-ul {\\n list-style-type: none;\\n margin-left: var(--fa-li-margin, 2.5em);\\n padding-left: 0;\\n}\\n.fa-ul > li {\\n position: relative;\\n}\\n\\n.fa-li {\\n left: calc(var(--fa-li-width, 2em) * -1);\\n position: absolute;\\n text-align: center;\\n width: var(--fa-li-width, 2em);\\n line-height: inherit;\\n}\\n\\n.fa-border {\\n border-color: var(--fa-border-color, #eee);\\n border-radius: var(--fa-border-radius, 0.1em);\\n border-style: var(--fa-border-style, solid);\\n border-width: var(--fa-border-width, 0.08em);\\n padding: var(--fa-border-padding, 0.2em 0.25em 0.15em);\\n}\\n\\n.fa-pull-left {\\n float: left;\\n margin-right: var(--fa-pull-margin, 0.3em);\\n}\\n\\n.fa-pull-right {\\n float: right;\\n margin-left: var(--fa-pull-margin, 0.3em);\\n}\\n\\n.fa-beat {\\n -webkit-animation-name: fa-beat;\\n animation-name: fa-beat;\\n -webkit-animation-delay: var(--fa-animation-delay, 0s);\\n animation-delay: var(--fa-animation-delay, 0s);\\n -webkit-animation-direction: var(--fa-animation-direction, normal);\\n animation-direction: var(--fa-animation-direction, normal);\\n -webkit-animation-duration: var(--fa-animation-duration, 1s);\\n animation-duration: var(--fa-animation-duration, 1s);\\n -webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);\\n animation-iteration-count: var(--fa-animation-iteration-count, infinite);\\n -webkit-animation-timing-function: var(--fa-animation-timing, ease-in-out);\\n animation-timing-function: var(--fa-animation-timing, ease-in-out);\\n}\\n\\n.fa-bounce {\\n -webkit-animation-name: fa-bounce;\\n animation-name: fa-bounce;\\n -webkit-animation-delay: var(--fa-animation-delay, 0s);\\n animation-delay: var(--fa-animation-delay, 0s);\\n -webkit-animation-direction: var(--fa-animation-direction, normal);\\n animation-direction: var(--fa-animation-direction, normal);\\n -webkit-animation-duration: var(--fa-animation-duration, 1s);\\n animation-duration: var(--fa-animation-duration, 1s);\\n -webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);\\n animation-iteration-count: var(--fa-animation-iteration-count, infinite);\\n -webkit-animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.28, 0.84, 0.42, 1));\\n animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.28, 0.84, 0.42, 1));\\n}\\n\\n.fa-fade {\\n -webkit-animation-name: fa-fade;\\n animation-name: fa-fade;\\n -webkit-animation-delay: var(--fa-animation-delay, 0s);\\n animation-delay: var(--fa-animation-delay, 0s);\\n -webkit-animation-direction: var(--fa-animation-direction, normal);\\n animation-direction: var(--fa-animation-direction, normal);\\n -webkit-animation-duration: var(--fa-animation-duration, 1s);\\n animation-duration: var(--fa-animation-duration, 1s);\\n -webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);\\n animation-iteration-count: var(--fa-animation-iteration-count, infinite);\\n -webkit-animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1));\\n animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1));\\n}\\n\\n.fa-beat-fade {\\n -webkit-animation-name: fa-beat-fade;\\n animation-name: fa-beat-fade;\\n -webkit-animation-delay: var(--fa-animation-delay, 0s);\\n animation-delay: var(--fa-animation-delay, 0s);\\n -webkit-animation-direction: var(--fa-animation-direction, normal);\\n animation-direction: var(--fa-animation-direction, normal);\\n -webkit-animation-duration: var(--fa-animation-duration, 1s);\\n animation-duration: var(--fa-animation-duration, 1s);\\n -webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);\\n animation-iteration-count: var(--fa-animation-iteration-count, infinite);\\n -webkit-animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1));\\n animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1));\\n}\\n\\n.fa-flip {\\n -webkit-animation-name: fa-flip;\\n animation-name: fa-flip;\\n -webkit-animation-delay: var(--fa-animation-delay, 0s);\\n animation-delay: var(--fa-animation-delay, 0s);\\n -webkit-animation-direction: var(--fa-animation-direction, normal);\\n animation-direction: var(--fa-animation-direction, normal);\\n -webkit-animation-duration: var(--fa-animation-duration, 1s);\\n animation-duration: var(--fa-animation-duration, 1s);\\n -webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);\\n animation-iteration-count: var(--fa-animation-iteration-count, infinite);\\n -webkit-animation-timing-function: var(--fa-animation-timing, ease-in-out);\\n animation-timing-function: var(--fa-animation-timing, ease-in-out);\\n}\\n\\n.fa-shake {\\n -webkit-animation-name: fa-shake;\\n animation-name: fa-shake;\\n -webkit-animation-delay: var(--fa-animation-delay, 0s);\\n animation-delay: var(--fa-animation-delay, 0s);\\n -webkit-animation-direction: var(--fa-animation-direction, normal);\\n animation-direction: var(--fa-animation-direction, normal);\\n -webkit-animation-duration: var(--fa-animation-duration, 1s);\\n animation-duration: var(--fa-animation-duration, 1s);\\n -webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);\\n animation-iteration-count: var(--fa-animation-iteration-count, infinite);\\n -webkit-animation-timing-function: var(--fa-animation-timing, linear);\\n animation-timing-function: var(--fa-animation-timing, linear);\\n}\\n\\n.fa-spin {\\n -webkit-animation-name: fa-spin;\\n animation-name: fa-spin;\\n -webkit-animation-delay: var(--fa-animation-delay, 0s);\\n animation-delay: var(--fa-animation-delay, 0s);\\n -webkit-animation-direction: var(--fa-animation-direction, normal);\\n animation-direction: var(--fa-animation-direction, normal);\\n -webkit-animation-duration: var(--fa-animation-duration, 2s);\\n animation-duration: var(--fa-animation-duration, 2s);\\n -webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);\\n animation-iteration-count: var(--fa-animation-iteration-count, infinite);\\n -webkit-animation-timing-function: var(--fa-animation-timing, linear);\\n animation-timing-function: var(--fa-animation-timing, linear);\\n}\\n\\n.fa-spin-reverse {\\n --fa-animation-direction: reverse;\\n}\\n\\n.fa-pulse,\\n.fa-spin-pulse {\\n -webkit-animation-name: fa-spin;\\n animation-name: fa-spin;\\n -webkit-animation-direction: var(--fa-animation-direction, normal);\\n animation-direction: var(--fa-animation-direction, normal);\\n -webkit-animation-duration: var(--fa-animation-duration, 1s);\\n animation-duration: var(--fa-animation-duration, 1s);\\n -webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);\\n animation-iteration-count: var(--fa-animation-iteration-count, infinite);\\n -webkit-animation-timing-function: var(--fa-animation-timing, steps(8));\\n animation-timing-function: var(--fa-animation-timing, steps(8));\\n}\\n\\n@media (prefers-reduced-motion: reduce) {\\n .fa-beat,\\n.fa-bounce,\\n.fa-fade,\\n.fa-beat-fade,\\n.fa-flip,\\n.fa-pulse,\\n.fa-shake,\\n.fa-spin,\\n.fa-spin-pulse {\\n -webkit-animation-delay: -1ms;\\n animation-delay: -1ms;\\n -webkit-animation-duration: 1ms;\\n animation-duration: 1ms;\\n -webkit-animation-iteration-count: 1;\\n animation-iteration-count: 1;\\n -webkit-transition-delay: 0s;\\n transition-delay: 0s;\\n -webkit-transition-duration: 0s;\\n transition-duration: 0s;\\n }\\n}\\n@-webkit-keyframes fa-beat {\\n 0%, 90% {\\n -webkit-transform: scale(1);\\n transform: scale(1);\\n }\\n 45% {\\n -webkit-transform: scale(var(--fa-beat-scale, 1.25));\\n transform: scale(var(--fa-beat-scale, 1.25));\\n }\\n}\\n@keyframes fa-beat {\\n 0%, 90% {\\n -webkit-transform: scale(1);\\n transform: scale(1);\\n }\\n 45% {\\n -webkit-transform: scale(var(--fa-beat-scale, 1.25));\\n transform: scale(var(--fa-beat-scale, 1.25));\\n }\\n}\\n@-webkit-keyframes fa-bounce {\\n 0% {\\n -webkit-transform: scale(1, 1) translateY(0);\\n transform: scale(1, 1) translateY(0);\\n }\\n 10% {\\n -webkit-transform: scale(var(--fa-bounce-start-scale-x, 1.1), var(--fa-bounce-start-scale-y, 0.9)) translateY(0);\\n transform: scale(var(--fa-bounce-start-scale-x, 1.1), var(--fa-bounce-start-scale-y, 0.9)) translateY(0);\\n }\\n 30% {\\n -webkit-transform: scale(var(--fa-bounce-jump-scale-x, 0.9), var(--fa-bounce-jump-scale-y, 1.1)) translateY(var(--fa-bounce-height, -0.5em));\\n transform: scale(var(--fa-bounce-jump-scale-x, 0.9), var(--fa-bounce-jump-scale-y, 1.1)) translateY(var(--fa-bounce-height, -0.5em));\\n }\\n 50% {\\n -webkit-transform: scale(var(--fa-bounce-land-scale-x, 1.05), var(--fa-bounce-land-scale-y, 0.95)) translateY(0);\\n transform: scale(var(--fa-bounce-land-scale-x, 1.05), var(--fa-bounce-land-scale-y, 0.95)) translateY(0);\\n }\\n 57% {\\n -webkit-transform: scale(1, 1) translateY(var(--fa-bounce-rebound, -0.125em));\\n transform: scale(1, 1) translateY(var(--fa-bounce-rebound, -0.125em));\\n }\\n 64% {\\n -webkit-transform: scale(1, 1) translateY(0);\\n transform: scale(1, 1) translateY(0);\\n }\\n 100% {\\n -webkit-transform: scale(1, 1) translateY(0);\\n transform: scale(1, 1) translateY(0);\\n }\\n}\\n@keyframes fa-bounce {\\n 0% {\\n -webkit-transform: scale(1, 1) translateY(0);\\n transform: scale(1, 1) translateY(0);\\n }\\n 10% {\\n -webkit-transform: scale(var(--fa-bounce-start-scale-x, 1.1), var(--fa-bounce-start-scale-y, 0.9)) translateY(0);\\n transform: scale(var(--fa-bounce-start-scale-x, 1.1), var(--fa-bounce-start-scale-y, 0.9)) translateY(0);\\n }\\n 30% {\\n -webkit-transform: scale(var(--fa-bounce-jump-scale-x, 0.9), var(--fa-bounce-jump-scale-y, 1.1)) translateY(var(--fa-bounce-height, -0.5em));\\n transform: scale(var(--fa-bounce-jump-scale-x, 0.9), var(--fa-bounce-jump-scale-y, 1.1)) translateY(var(--fa-bounce-height, -0.5em));\\n }\\n 50% {\\n -webkit-transform: scale(var(--fa-bounce-land-scale-x, 1.05), var(--fa-bounce-land-scale-y, 0.95)) translateY(0);\\n transform: scale(var(--fa-bounce-land-scale-x, 1.05), var(--fa-bounce-land-scale-y, 0.95)) translateY(0);\\n }\\n 57% {\\n -webkit-transform: scale(1, 1) translateY(var(--fa-bounce-rebound, -0.125em));\\n transform: scale(1, 1) translateY(var(--fa-bounce-rebound, -0.125em));\\n }\\n 64% {\\n -webkit-transform: scale(1, 1) translateY(0);\\n transform: scale(1, 1) translateY(0);\\n }\\n 100% {\\n -webkit-transform: scale(1, 1) translateY(0);\\n transform: scale(1, 1) translateY(0);\\n }\\n}\\n@-webkit-keyframes fa-fade {\\n 50% {\\n opacity: var(--fa-fade-opacity, 0.4);\\n }\\n}\\n@keyframes fa-fade {\\n 50% {\\n opacity: var(--fa-fade-opacity, 0.4);\\n }\\n}\\n@-webkit-keyframes fa-beat-fade {\\n 0%, 100% {\\n opacity: var(--fa-beat-fade-opacity, 0.4);\\n -webkit-transform: scale(1);\\n transform: scale(1);\\n }\\n 50% {\\n opacity: 1;\\n -webkit-transform: scale(var(--fa-beat-fade-scale, 1.125));\\n transform: scale(var(--fa-beat-fade-scale, 1.125));\\n }\\n}\\n@keyframes fa-beat-fade {\\n 0%, 100% {\\n opacity: var(--fa-beat-fade-opacity, 0.4);\\n -webkit-transform: scale(1);\\n transform: scale(1);\\n }\\n 50% {\\n opacity: 1;\\n -webkit-transform: scale(var(--fa-beat-fade-scale, 1.125));\\n transform: scale(var(--fa-beat-fade-scale, 1.125));\\n }\\n}\\n@-webkit-keyframes fa-flip {\\n 50% {\\n -webkit-transform: rotate3d(var(--fa-flip-x, 0), var(--fa-flip-y, 1), var(--fa-flip-z, 0), var(--fa-flip-angle, -180deg));\\n transform: rotate3d(var(--fa-flip-x, 0), var(--fa-flip-y, 1), var(--fa-flip-z, 0), var(--fa-flip-angle, -180deg));\\n }\\n}\\n@keyframes fa-flip {\\n 50% {\\n -webkit-transform: rotate3d(var(--fa-flip-x, 0), var(--fa-flip-y, 1), var(--fa-flip-z, 0), var(--fa-flip-angle, -180deg));\\n transform: rotate3d(var(--fa-flip-x, 0), var(--fa-flip-y, 1), var(--fa-flip-z, 0), var(--fa-flip-angle, -180deg));\\n }\\n}\\n@-webkit-keyframes fa-shake {\\n 0% {\\n -webkit-transform: rotate(-15deg);\\n transform: rotate(-15deg);\\n }\\n 4% {\\n -webkit-transform: rotate(15deg);\\n transform: rotate(15deg);\\n }\\n 8%, 24% {\\n -webkit-transform: rotate(-18deg);\\n transform: rotate(-18deg);\\n }\\n 12%, 28% {\\n -webkit-transform: rotate(18deg);\\n transform: rotate(18deg);\\n }\\n 16% {\\n -webkit-transform: rotate(-22deg);\\n transform: rotate(-22deg);\\n }\\n 20% {\\n -webkit-transform: rotate(22deg);\\n transform: rotate(22deg);\\n }\\n 32% {\\n -webkit-transform: rotate(-12deg);\\n transform: rotate(-12deg);\\n }\\n 36% {\\n -webkit-transform: rotate(12deg);\\n transform: rotate(12deg);\\n }\\n 40%, 100% {\\n -webkit-transform: rotate(0deg);\\n transform: rotate(0deg);\\n }\\n}\\n@keyframes fa-shake {\\n 0% {\\n -webkit-transform: rotate(-15deg);\\n transform: rotate(-15deg);\\n }\\n 4% {\\n -webkit-transform: rotate(15deg);\\n transform: rotate(15deg);\\n }\\n 8%, 24% {\\n -webkit-transform: rotate(-18deg);\\n transform: rotate(-18deg);\\n }\\n 12%, 28% {\\n -webkit-transform: rotate(18deg);\\n transform: rotate(18deg);\\n }\\n 16% {\\n -webkit-transform: rotate(-22deg);\\n transform: rotate(-22deg);\\n }\\n 20% {\\n -webkit-transform: rotate(22deg);\\n transform: rotate(22deg);\\n }\\n 32% {\\n -webkit-transform: rotate(-12deg);\\n transform: rotate(-12deg);\\n }\\n 36% {\\n -webkit-transform: rotate(12deg);\\n transform: rotate(12deg);\\n }\\n 40%, 100% {\\n -webkit-transform: rotate(0deg);\\n transform: rotate(0deg);\\n }\\n}\\n@-webkit-keyframes fa-spin {\\n 0% {\\n -webkit-transform: rotate(0deg);\\n transform: rotate(0deg);\\n }\\n 100% {\\n -webkit-transform: rotate(360deg);\\n transform: rotate(360deg);\\n }\\n}\\n@keyframes fa-spin {\\n 0% {\\n -webkit-transform: rotate(0deg);\\n transform: rotate(0deg);\\n }\\n 100% {\\n -webkit-transform: rotate(360deg);\\n transform: rotate(360deg);\\n }\\n}\\n.fa-rotate-90 {\\n -webkit-transform: rotate(90deg);\\n transform: rotate(90deg);\\n}\\n\\n.fa-rotate-180 {\\n -webkit-transform: rotate(180deg);\\n transform: rotate(180deg);\\n}\\n\\n.fa-rotate-270 {\\n -webkit-transform: rotate(270deg);\\n transform: rotate(270deg);\\n}\\n\\n.fa-flip-horizontal {\\n -webkit-transform: scale(-1, 1);\\n transform: scale(-1, 1);\\n}\\n\\n.fa-flip-vertical {\\n -webkit-transform: scale(1, -1);\\n transform: scale(1, -1);\\n}\\n\\n.fa-flip-both,\\n.fa-flip-horizontal.fa-flip-vertical {\\n -webkit-transform: scale(-1, -1);\\n transform: scale(-1, -1);\\n}\\n\\n.fa-rotate-by {\\n -webkit-transform: rotate(var(--fa-rotate-angle, none));\\n transform: rotate(var(--fa-rotate-angle, none));\\n}\\n\\n.fa-stack {\\n display: inline-block;\\n vertical-align: middle;\\n height: 2em;\\n position: relative;\\n width: 2.5em;\\n}\\n\\n.fa-stack-1x,\\n.fa-stack-2x {\\n bottom: 0;\\n left: 0;\\n margin: auto;\\n position: absolute;\\n right: 0;\\n top: 0;\\n z-index: var(--fa-stack-z-index, auto);\\n}\\n\\n.svg-inline--fa.fa-stack-1x {\\n height: 1em;\\n width: 1.25em;\\n}\\n.svg-inline--fa.fa-stack-2x {\\n height: 2em;\\n width: 2.5em;\\n}\\n\\n.fa-inverse {\\n color: var(--fa-inverse, #fff);\\n}\\n\\n.sr-only,\\n.fa-sr-only {\\n position: absolute;\\n width: 1px;\\n height: 1px;\\n padding: 0;\\n margin: -1px;\\n overflow: hidden;\\n clip: rect(0, 0, 0, 0);\\n white-space: nowrap;\\n border-width: 0;\\n}\\n\\n.sr-only-focusable:not(:focus),\\n.fa-sr-only-focusable:not(:focus) {\\n position: absolute;\\n width: 1px;\\n height: 1px;\\n padding: 0;\\n margin: -1px;\\n overflow: hidden;\\n clip: rect(0, 0, 0, 0);\\n white-space: nowrap;\\n border-width: 0;\\n}\\n\\n.svg-inline--fa .fa-primary {\\n fill: var(--fa-primary-color, currentColor);\\n opacity: var(--fa-primary-opacity, 1);\\n}\\n\\n.svg-inline--fa .fa-secondary {\\n fill: var(--fa-secondary-color, currentColor);\\n opacity: var(--fa-secondary-opacity, 0.4);\\n}\\n\\n.svg-inline--fa.fa-swap-opacity .fa-primary {\\n opacity: var(--fa-secondary-opacity, 0.4);\\n}\\n\\n.svg-inline--fa.fa-swap-opacity .fa-secondary {\\n opacity: var(--fa-primary-opacity, 1);\\n}\\n\\n.svg-inline--fa mask .fa-primary,\\n.svg-inline--fa mask .fa-secondary {\\n fill: black;\\n}\\n\\n.fad.fa-inverse,\\n.fa-duotone.fa-inverse {\\n color: var(--fa-inverse, #fff);\\n}\";\n\nfunction css() {\n var dcp = DEFAULT_CSS_PREFIX;\n var drc = DEFAULT_REPLACEMENT_CLASS;\n var fp = config.cssPrefix;\n var rc = config.replacementClass;\n var s = baseStyles;\n\n if (fp !== dcp || rc !== drc) {\n var dPatt = new RegExp(\"\\\\.\".concat(dcp, \"\\\\-\"), 'g');\n var customPropPatt = new RegExp(\"\\\\--\".concat(dcp, \"\\\\-\"), 'g');\n var rPatt = new RegExp(\"\\\\.\".concat(drc), 'g');\n s = s.replace(dPatt, \".\".concat(fp, \"-\")).replace(customPropPatt, \"--\".concat(fp, \"-\")).replace(rPatt, \".\".concat(rc));\n }\n\n return s;\n}\n\nvar _cssInserted = false;\n\nfunction ensureCss() {\n if (config.autoAddCss && !_cssInserted) {\n insertCss(css());\n _cssInserted = true;\n }\n}\n\nvar InjectCSS = {\n mixout: function mixout() {\n return {\n dom: {\n css: css,\n insertCss: ensureCss\n }\n };\n },\n hooks: function hooks() {\n return {\n beforeDOMElementCreation: function beforeDOMElementCreation() {\n ensureCss();\n },\n beforeI2svg: function beforeI2svg() {\n ensureCss();\n }\n };\n }\n};\n\nvar w = WINDOW || {};\nif (!w[NAMESPACE_IDENTIFIER]) w[NAMESPACE_IDENTIFIER] = {};\nif (!w[NAMESPACE_IDENTIFIER].styles) w[NAMESPACE_IDENTIFIER].styles = {};\nif (!w[NAMESPACE_IDENTIFIER].hooks) w[NAMESPACE_IDENTIFIER].hooks = {};\nif (!w[NAMESPACE_IDENTIFIER].shims) w[NAMESPACE_IDENTIFIER].shims = [];\nvar namespace = w[NAMESPACE_IDENTIFIER];\n\nvar functions = [];\n\nvar listener = function listener() {\n DOCUMENT.removeEventListener('DOMContentLoaded', listener);\n loaded = 1;\n functions.map(function (fn) {\n return fn();\n });\n};\n\nvar loaded = false;\n\nif (IS_DOM) {\n loaded = (DOCUMENT.documentElement.doScroll ? /^loaded|^c/ : /^loaded|^i|^c/).test(DOCUMENT.readyState);\n if (!loaded) DOCUMENT.addEventListener('DOMContentLoaded', listener);\n}\n\nfunction domready (fn) {\n if (!IS_DOM) return;\n loaded ? setTimeout(fn, 0) : functions.push(fn);\n}\n\nfunction toHtml(abstractNodes) {\n var tag = abstractNodes.tag,\n _abstractNodes$attrib = abstractNodes.attributes,\n attributes = _abstractNodes$attrib === void 0 ? {} : _abstractNodes$attrib,\n _abstractNodes$childr = abstractNodes.children,\n children = _abstractNodes$childr === void 0 ? [] : _abstractNodes$childr;\n\n if (typeof abstractNodes === 'string') {\n return htmlEscape(abstractNodes);\n } else {\n return \"<\".concat(tag, \" \").concat(joinAttributes(attributes), \">\").concat(children.map(toHtml).join(''), \"\");\n }\n}\n\nfunction iconFromMapping(mapping, prefix, iconName) {\n if (mapping && mapping[prefix] && mapping[prefix][iconName]) {\n return {\n prefix: prefix,\n iconName: iconName,\n icon: mapping[prefix][iconName]\n };\n }\n}\n\n/**\n * Internal helper to bind a function known to have 4 arguments\n * to a given context.\n */\n\nvar bindInternal4 = function bindInternal4(func, thisContext) {\n return function (a, b, c, d) {\n return func.call(thisContext, a, b, c, d);\n };\n};\n\n/**\n * # Reduce\n *\n * A fast object `.reduce()` implementation.\n *\n * @param {Object} subject The object to reduce over.\n * @param {Function} fn The reducer function.\n * @param {mixed} initialValue The initial value for the reducer, defaults to subject[0].\n * @param {Object} thisContext The context for the reducer.\n * @return {mixed} The final result.\n */\n\n\nvar reduce = function fastReduceObject(subject, fn, initialValue, thisContext) {\n var keys = Object.keys(subject),\n length = keys.length,\n iterator = thisContext !== undefined ? bindInternal4(fn, thisContext) : fn,\n i,\n key,\n result;\n\n if (initialValue === undefined) {\n i = 1;\n result = subject[keys[0]];\n } else {\n i = 0;\n result = initialValue;\n }\n\n for (; i < length; i++) {\n key = keys[i];\n result = iterator(result, subject[key], key, subject);\n }\n\n return result;\n};\n\n/**\n * ucs2decode() and codePointAt() are both works of Mathias Bynens and licensed under MIT\n *\n * Copyright Mathias Bynens \n\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\n * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\n * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\nfunction ucs2decode(string) {\n var output = [];\n var counter = 0;\n var length = string.length;\n\n while (counter < length) {\n var value = string.charCodeAt(counter++);\n\n if (value >= 0xD800 && value <= 0xDBFF && counter < length) {\n var extra = string.charCodeAt(counter++);\n\n if ((extra & 0xFC00) == 0xDC00) {\n // eslint-disable-line eqeqeq\n output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);\n } else {\n output.push(value);\n counter--;\n }\n } else {\n output.push(value);\n }\n }\n\n return output;\n}\n\nfunction toHex(unicode) {\n var decoded = ucs2decode(unicode);\n return decoded.length === 1 ? decoded[0].toString(16) : null;\n}\nfunction codePointAt(string, index) {\n var size = string.length;\n var first = string.charCodeAt(index);\n var second;\n\n if (first >= 0xD800 && first <= 0xDBFF && size > index + 1) {\n second = string.charCodeAt(index + 1);\n\n if (second >= 0xDC00 && second <= 0xDFFF) {\n return (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;\n }\n }\n\n return first;\n}\n\nfunction normalizeIcons(icons) {\n return Object.keys(icons).reduce(function (acc, iconName) {\n var icon = icons[iconName];\n var expanded = !!icon.icon;\n\n if (expanded) {\n acc[icon.iconName] = icon.icon;\n } else {\n acc[iconName] = icon;\n }\n\n return acc;\n }, {});\n}\n\nfunction defineIcons(prefix, icons) {\n var params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n var _params$skipHooks = params.skipHooks,\n skipHooks = _params$skipHooks === void 0 ? false : _params$skipHooks;\n var normalized = normalizeIcons(icons);\n\n if (typeof namespace.hooks.addPack === 'function' && !skipHooks) {\n namespace.hooks.addPack(prefix, normalizeIcons(icons));\n } else {\n namespace.styles[prefix] = _objectSpread2(_objectSpread2({}, namespace.styles[prefix] || {}), normalized);\n }\n /**\n * Font Awesome 4 used the prefix of `fa` for all icons. With the introduction\n * of new styles we needed to differentiate between them. Prefix `fa` is now an alias\n * for `fas` so we'll ease the upgrade process for our users by automatically defining\n * this as well.\n */\n\n\n if (prefix === 'fas') {\n defineIcons('fa', icons);\n }\n}\n\nvar duotonePathRe = [/*#__PURE__*/_wrapRegExp(/path d=\"((?:(?!\")[\\s\\S])+)\".*path d=\"((?:(?!\")[\\s\\S])+)\"/, {\n d1: 1,\n d2: 2\n}), /*#__PURE__*/_wrapRegExp(/path class=\"((?:(?!\")[\\s\\S])+)\".*d=\"((?:(?!\")[\\s\\S])+)\".*path class=\"((?:(?!\")[\\s\\S])+)\".*d=\"((?:(?!\")[\\s\\S])+)\"/, {\n cls1: 1,\n d1: 2,\n cls2: 3,\n d2: 4\n}), /*#__PURE__*/_wrapRegExp(/path class=\"((?:(?!\")[\\s\\S])+)\".*d=\"((?:(?!\")[\\s\\S])+)\"/, {\n cls1: 1,\n d1: 2\n})];\n\nvar _LONG_STYLE, _PREFIXES, _PREFIXES_FOR_FAMILY;\nvar styles = namespace.styles,\n shims = namespace.shims;\nvar LONG_STYLE = (_LONG_STYLE = {}, _defineProperty(_LONG_STYLE, FAMILY_CLASSIC, Object.values(PREFIX_TO_LONG_STYLE[FAMILY_CLASSIC])), _defineProperty(_LONG_STYLE, FAMILY_SHARP, Object.values(PREFIX_TO_LONG_STYLE[FAMILY_SHARP])), _LONG_STYLE);\nvar _defaultUsablePrefix = null;\nvar _byUnicode = {};\nvar _byLigature = {};\nvar _byOldName = {};\nvar _byOldUnicode = {};\nvar _byAlias = {};\nvar PREFIXES = (_PREFIXES = {}, _defineProperty(_PREFIXES, FAMILY_CLASSIC, Object.keys(PREFIX_TO_STYLE[FAMILY_CLASSIC])), _defineProperty(_PREFIXES, FAMILY_SHARP, Object.keys(PREFIX_TO_STYLE[FAMILY_SHARP])), _PREFIXES);\n\nfunction isReserved(name) {\n return ~RESERVED_CLASSES.indexOf(name);\n}\n\nfunction getIconName(cssPrefix, cls) {\n var parts = cls.split('-');\n var prefix = parts[0];\n var iconName = parts.slice(1).join('-');\n\n if (prefix === cssPrefix && iconName !== '' && !isReserved(iconName)) {\n return iconName;\n } else {\n return null;\n }\n}\nvar build = function build() {\n var lookup = function lookup(reducer) {\n return reduce(styles, function (o, style, prefix) {\n o[prefix] = reduce(style, reducer, {});\n return o;\n }, {});\n };\n\n _byUnicode = lookup(function (acc, icon, iconName) {\n if (icon[3]) {\n acc[icon[3]] = iconName;\n }\n\n if (icon[2]) {\n var aliases = icon[2].filter(function (a) {\n return typeof a === 'number';\n });\n aliases.forEach(function (alias) {\n acc[alias.toString(16)] = iconName;\n });\n }\n\n return acc;\n });\n _byLigature = lookup(function (acc, icon, iconName) {\n acc[iconName] = iconName;\n\n if (icon[2]) {\n var aliases = icon[2].filter(function (a) {\n return typeof a === 'string';\n });\n aliases.forEach(function (alias) {\n acc[alias] = iconName;\n });\n }\n\n return acc;\n });\n _byAlias = lookup(function (acc, icon, iconName) {\n var aliases = icon[2];\n acc[iconName] = iconName;\n aliases.forEach(function (alias) {\n acc[alias] = iconName;\n });\n return acc;\n }); // If we have a Kit, we can't determine if regular is available since we\n // could be auto-fetching it. We'll have to assume that it is available.\n\n var hasRegular = 'far' in styles || config.autoFetchSvg;\n var shimLookups = reduce(shims, function (acc, shim) {\n var maybeNameMaybeUnicode = shim[0];\n var prefix = shim[1];\n var iconName = shim[2];\n\n if (prefix === 'far' && !hasRegular) {\n prefix = 'fas';\n }\n\n if (typeof maybeNameMaybeUnicode === 'string') {\n acc.names[maybeNameMaybeUnicode] = {\n prefix: prefix,\n iconName: iconName\n };\n }\n\n if (typeof maybeNameMaybeUnicode === 'number') {\n acc.unicodes[maybeNameMaybeUnicode.toString(16)] = {\n prefix: prefix,\n iconName: iconName\n };\n }\n\n return acc;\n }, {\n names: {},\n unicodes: {}\n });\n _byOldName = shimLookups.names;\n _byOldUnicode = shimLookups.unicodes;\n _defaultUsablePrefix = getCanonicalPrefix(config.styleDefault, {\n family: config.familyDefault\n });\n};\nonChange(function (c) {\n _defaultUsablePrefix = getCanonicalPrefix(c.styleDefault, {\n family: config.familyDefault\n });\n});\nbuild();\nfunction byUnicode(prefix, unicode) {\n return (_byUnicode[prefix] || {})[unicode];\n}\nfunction byLigature(prefix, ligature) {\n return (_byLigature[prefix] || {})[ligature];\n}\nfunction byAlias(prefix, alias) {\n return (_byAlias[prefix] || {})[alias];\n}\nfunction byOldName(name) {\n return _byOldName[name] || {\n prefix: null,\n iconName: null\n };\n}\nfunction byOldUnicode(unicode) {\n var oldUnicode = _byOldUnicode[unicode];\n var newUnicode = byUnicode('fas', unicode);\n return oldUnicode || (newUnicode ? {\n prefix: 'fas',\n iconName: newUnicode\n } : null) || {\n prefix: null,\n iconName: null\n };\n}\nfunction getDefaultUsablePrefix() {\n return _defaultUsablePrefix;\n}\nvar emptyCanonicalIcon = function emptyCanonicalIcon() {\n return {\n prefix: null,\n iconName: null,\n rest: []\n };\n};\nfunction getCanonicalPrefix(styleOrPrefix) {\n var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n var _params$family = params.family,\n family = _params$family === void 0 ? FAMILY_CLASSIC : _params$family;\n var style = PREFIX_TO_STYLE[family][styleOrPrefix];\n var prefix = STYLE_TO_PREFIX[family][styleOrPrefix] || STYLE_TO_PREFIX[family][style];\n var defined = styleOrPrefix in namespace.styles ? styleOrPrefix : null;\n return prefix || defined || null;\n}\nvar PREFIXES_FOR_FAMILY = (_PREFIXES_FOR_FAMILY = {}, _defineProperty(_PREFIXES_FOR_FAMILY, FAMILY_CLASSIC, Object.keys(PREFIX_TO_LONG_STYLE[FAMILY_CLASSIC])), _defineProperty(_PREFIXES_FOR_FAMILY, FAMILY_SHARP, Object.keys(PREFIX_TO_LONG_STYLE[FAMILY_SHARP])), _PREFIXES_FOR_FAMILY);\nfunction getCanonicalIcon(values) {\n var _famProps;\n\n var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n var _params$skipLookups = params.skipLookups,\n skipLookups = _params$skipLookups === void 0 ? false : _params$skipLookups;\n var famProps = (_famProps = {}, _defineProperty(_famProps, FAMILY_CLASSIC, \"\".concat(config.cssPrefix, \"-\").concat(FAMILY_CLASSIC)), _defineProperty(_famProps, FAMILY_SHARP, \"\".concat(config.cssPrefix, \"-\").concat(FAMILY_SHARP)), _famProps);\n var givenPrefix = null;\n var family = FAMILY_CLASSIC;\n\n if (values.includes(famProps[FAMILY_CLASSIC]) || values.some(function (v) {\n return PREFIXES_FOR_FAMILY[FAMILY_CLASSIC].includes(v);\n })) {\n family = FAMILY_CLASSIC;\n }\n\n if (values.includes(famProps[FAMILY_SHARP]) || values.some(function (v) {\n return PREFIXES_FOR_FAMILY[FAMILY_SHARP].includes(v);\n })) {\n family = FAMILY_SHARP;\n }\n\n var canonical = values.reduce(function (acc, cls) {\n var iconName = getIconName(config.cssPrefix, cls);\n\n if (styles[cls]) {\n cls = LONG_STYLE[family].includes(cls) ? LONG_STYLE_TO_PREFIX[family][cls] : cls;\n givenPrefix = cls;\n acc.prefix = cls;\n } else if (PREFIXES[family].indexOf(cls) > -1) {\n givenPrefix = cls;\n acc.prefix = getCanonicalPrefix(cls, {\n family: family\n });\n } else if (iconName) {\n acc.iconName = iconName;\n } else if (cls !== config.replacementClass && cls !== famProps[FAMILY_CLASSIC] && cls !== famProps[FAMILY_SHARP]) {\n acc.rest.push(cls);\n }\n\n if (!skipLookups && acc.prefix && acc.iconName) {\n var shim = givenPrefix === 'fa' ? byOldName(acc.iconName) : {};\n var aliasIconName = byAlias(acc.prefix, acc.iconName);\n\n if (shim.prefix) {\n givenPrefix = null;\n }\n\n acc.iconName = shim.iconName || aliasIconName || acc.iconName;\n acc.prefix = shim.prefix || acc.prefix;\n\n if (acc.prefix === 'far' && !styles['far'] && styles['fas'] && !config.autoFetchSvg) {\n // Allow a fallback from the regular style to solid if regular is not available\n // but only if we aren't auto-fetching SVGs\n acc.prefix = 'fas';\n }\n }\n\n return acc;\n }, emptyCanonicalIcon());\n\n if (values.includes('fa-brands') || values.includes('fab')) {\n canonical.prefix = 'fab';\n }\n\n if (values.includes('fa-duotone') || values.includes('fad')) {\n canonical.prefix = 'fad';\n }\n\n if (!canonical.prefix && family === FAMILY_SHARP && (styles['fass'] || config.autoFetchSvg)) {\n canonical.prefix = 'fass';\n canonical.iconName = byAlias(canonical.prefix, canonical.iconName) || canonical.iconName;\n }\n\n if (canonical.prefix === 'fa' || givenPrefix === 'fa') {\n // The fa prefix is not canonical. So if it has made it through until this point\n // we will shift it to the correct prefix.\n canonical.prefix = getDefaultUsablePrefix() || 'fas';\n }\n\n return canonical;\n}\n\nvar Library = /*#__PURE__*/function () {\n function Library() {\n _classCallCheck(this, Library);\n\n this.definitions = {};\n }\n\n _createClass(Library, [{\n key: \"add\",\n value: function add() {\n var _this = this;\n\n for (var _len = arguments.length, definitions = new Array(_len), _key = 0; _key < _len; _key++) {\n definitions[_key] = arguments[_key];\n }\n\n var additions = definitions.reduce(this._pullDefinitions, {});\n Object.keys(additions).forEach(function (key) {\n _this.definitions[key] = _objectSpread2(_objectSpread2({}, _this.definitions[key] || {}), additions[key]);\n defineIcons(key, additions[key]); // TODO can we stop doing this? We can't get the icons by 'fa-solid' any longer so this probably needs to change\n\n var longPrefix = PREFIX_TO_LONG_STYLE[FAMILY_CLASSIC][key];\n if (longPrefix) defineIcons(longPrefix, additions[key]);\n build();\n });\n }\n }, {\n key: \"reset\",\n value: function reset() {\n this.definitions = {};\n }\n }, {\n key: \"_pullDefinitions\",\n value: function _pullDefinitions(additions, definition) {\n var normalized = definition.prefix && definition.iconName && definition.icon ? {\n 0: definition\n } : definition;\n Object.keys(normalized).map(function (key) {\n var _normalized$key = normalized[key],\n prefix = _normalized$key.prefix,\n iconName = _normalized$key.iconName,\n icon = _normalized$key.icon;\n var aliases = icon[2];\n if (!additions[prefix]) additions[prefix] = {};\n\n if (aliases.length > 0) {\n aliases.forEach(function (alias) {\n if (typeof alias === 'string') {\n additions[prefix][alias] = icon;\n }\n });\n }\n\n additions[prefix][iconName] = icon;\n });\n return additions;\n }\n }]);\n\n return Library;\n}();\n\nvar _plugins = [];\nvar _hooks = {};\nvar providers = {};\nvar defaultProviderKeys = Object.keys(providers);\nfunction registerPlugins(nextPlugins, _ref) {\n var obj = _ref.mixoutsTo;\n _plugins = nextPlugins;\n _hooks = {};\n Object.keys(providers).forEach(function (k) {\n if (defaultProviderKeys.indexOf(k) === -1) {\n delete providers[k];\n }\n });\n\n _plugins.forEach(function (plugin) {\n var mixout = plugin.mixout ? plugin.mixout() : {};\n Object.keys(mixout).forEach(function (tk) {\n if (typeof mixout[tk] === 'function') {\n obj[tk] = mixout[tk];\n }\n\n if (_typeof(mixout[tk]) === 'object') {\n Object.keys(mixout[tk]).forEach(function (sk) {\n if (!obj[tk]) {\n obj[tk] = {};\n }\n\n obj[tk][sk] = mixout[tk][sk];\n });\n }\n });\n\n if (plugin.hooks) {\n var hooks = plugin.hooks();\n Object.keys(hooks).forEach(function (hook) {\n if (!_hooks[hook]) {\n _hooks[hook] = [];\n }\n\n _hooks[hook].push(hooks[hook]);\n });\n }\n\n if (plugin.provides) {\n plugin.provides(providers);\n }\n });\n\n return obj;\n}\nfunction chainHooks(hook, accumulator) {\n for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {\n args[_key - 2] = arguments[_key];\n }\n\n var hookFns = _hooks[hook] || [];\n hookFns.forEach(function (hookFn) {\n accumulator = hookFn.apply(null, [accumulator].concat(args)); // eslint-disable-line no-useless-call\n });\n return accumulator;\n}\nfunction callHooks(hook) {\n for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {\n args[_key2 - 1] = arguments[_key2];\n }\n\n var hookFns = _hooks[hook] || [];\n hookFns.forEach(function (hookFn) {\n hookFn.apply(null, args);\n });\n return undefined;\n}\nfunction callProvided() {\n var hook = arguments[0];\n var args = Array.prototype.slice.call(arguments, 1);\n return providers[hook] ? providers[hook].apply(null, args) : undefined;\n}\n\nfunction findIconDefinition(iconLookup) {\n if (iconLookup.prefix === 'fa') {\n iconLookup.prefix = 'fas';\n }\n\n var iconName = iconLookup.iconName;\n var prefix = iconLookup.prefix || getDefaultUsablePrefix();\n if (!iconName) return;\n iconName = byAlias(prefix, iconName) || iconName;\n return iconFromMapping(library.definitions, prefix, iconName) || iconFromMapping(namespace.styles, prefix, iconName);\n}\nvar library = new Library();\nvar noAuto = function noAuto() {\n config.autoReplaceSvg = false;\n config.observeMutations = false;\n callHooks('noAuto');\n};\nvar dom = {\n i2svg: function i2svg() {\n var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n if (IS_DOM) {\n callHooks('beforeI2svg', params);\n callProvided('pseudoElements2svg', params);\n return callProvided('i2svg', params);\n } else {\n return Promise.reject('Operation requires a DOM of some kind.');\n }\n },\n watch: function watch() {\n var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n var autoReplaceSvgRoot = params.autoReplaceSvgRoot;\n\n if (config.autoReplaceSvg === false) {\n config.autoReplaceSvg = true;\n }\n\n config.observeMutations = true;\n domready(function () {\n autoReplace({\n autoReplaceSvgRoot: autoReplaceSvgRoot\n });\n callHooks('watch', params);\n });\n }\n};\nvar parse = {\n icon: function icon(_icon) {\n if (_icon === null) {\n return null;\n }\n\n if (_typeof(_icon) === 'object' && _icon.prefix && _icon.iconName) {\n return {\n prefix: _icon.prefix,\n iconName: byAlias(_icon.prefix, _icon.iconName) || _icon.iconName\n };\n }\n\n if (Array.isArray(_icon) && _icon.length === 2) {\n var iconName = _icon[1].indexOf('fa-') === 0 ? _icon[1].slice(3) : _icon[1];\n var prefix = getCanonicalPrefix(_icon[0]);\n return {\n prefix: prefix,\n iconName: byAlias(prefix, iconName) || iconName\n };\n }\n\n if (typeof _icon === 'string' && (_icon.indexOf(\"\".concat(config.cssPrefix, \"-\")) > -1 || _icon.match(ICON_SELECTION_SYNTAX_PATTERN))) {\n var canonicalIcon = getCanonicalIcon(_icon.split(' '), {\n skipLookups: true\n });\n return {\n prefix: canonicalIcon.prefix || getDefaultUsablePrefix(),\n iconName: byAlias(canonicalIcon.prefix, canonicalIcon.iconName) || canonicalIcon.iconName\n };\n }\n\n if (typeof _icon === 'string') {\n var _prefix = getDefaultUsablePrefix();\n\n return {\n prefix: _prefix,\n iconName: byAlias(_prefix, _icon) || _icon\n };\n }\n }\n};\nvar api = {\n noAuto: noAuto,\n config: config,\n dom: dom,\n parse: parse,\n library: library,\n findIconDefinition: findIconDefinition,\n toHtml: toHtml\n};\n\nvar autoReplace = function autoReplace() {\n var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n var _params$autoReplaceSv = params.autoReplaceSvgRoot,\n autoReplaceSvgRoot = _params$autoReplaceSv === void 0 ? DOCUMENT : _params$autoReplaceSv;\n if ((Object.keys(namespace.styles).length > 0 || config.autoFetchSvg) && IS_DOM && config.autoReplaceSvg) api.dom.i2svg({\n node: autoReplaceSvgRoot\n });\n};\n\nfunction domVariants(val, abstractCreator) {\n Object.defineProperty(val, 'abstract', {\n get: abstractCreator\n });\n Object.defineProperty(val, 'html', {\n get: function get() {\n return val.abstract.map(function (a) {\n return toHtml(a);\n });\n }\n });\n Object.defineProperty(val, 'node', {\n get: function get() {\n if (!IS_DOM) return;\n var container = DOCUMENT.createElement('div');\n container.innerHTML = val.html;\n return container.children;\n }\n });\n return val;\n}\n\nfunction asIcon (_ref) {\n var children = _ref.children,\n main = _ref.main,\n mask = _ref.mask,\n attributes = _ref.attributes,\n styles = _ref.styles,\n transform = _ref.transform;\n\n if (transformIsMeaningful(transform) && main.found && !mask.found) {\n var width = main.width,\n height = main.height;\n var offset = {\n x: width / height / 2,\n y: 0.5\n };\n attributes['style'] = joinStyles(_objectSpread2(_objectSpread2({}, styles), {}, {\n 'transform-origin': \"\".concat(offset.x + transform.x / 16, \"em \").concat(offset.y + transform.y / 16, \"em\")\n }));\n }\n\n return [{\n tag: 'svg',\n attributes: attributes,\n children: children\n }];\n}\n\nfunction asSymbol (_ref) {\n var prefix = _ref.prefix,\n iconName = _ref.iconName,\n children = _ref.children,\n attributes = _ref.attributes,\n symbol = _ref.symbol;\n var id = symbol === true ? \"\".concat(prefix, \"-\").concat(config.cssPrefix, \"-\").concat(iconName) : symbol;\n return [{\n tag: 'svg',\n attributes: {\n style: 'display: none;'\n },\n children: [{\n tag: 'symbol',\n attributes: _objectSpread2(_objectSpread2({}, attributes), {}, {\n id: id\n }),\n children: children\n }]\n }];\n}\n\nfunction makeInlineSvgAbstract(params) {\n var _params$icons = params.icons,\n main = _params$icons.main,\n mask = _params$icons.mask,\n prefix = params.prefix,\n iconName = params.iconName,\n transform = params.transform,\n symbol = params.symbol,\n title = params.title,\n maskId = params.maskId,\n titleId = params.titleId,\n extra = params.extra,\n _params$watchable = params.watchable,\n watchable = _params$watchable === void 0 ? false : _params$watchable;\n\n var _ref = mask.found ? mask : main,\n width = _ref.width,\n height = _ref.height;\n\n var isUploadedIcon = prefix === 'fak';\n var attrClass = [config.replacementClass, iconName ? \"\".concat(config.cssPrefix, \"-\").concat(iconName) : ''].filter(function (c) {\n return extra.classes.indexOf(c) === -1;\n }).filter(function (c) {\n return c !== '' || !!c;\n }).concat(extra.classes).join(' ');\n var content = {\n children: [],\n attributes: _objectSpread2(_objectSpread2({}, extra.attributes), {}, {\n 'data-prefix': prefix,\n 'data-icon': iconName,\n 'class': attrClass,\n 'role': extra.attributes.role || 'img',\n 'xmlns': 'http://www.w3.org/2000/svg',\n 'viewBox': \"0 0 \".concat(width, \" \").concat(height)\n })\n };\n var uploadedIconWidthStyle = isUploadedIcon && !~extra.classes.indexOf('fa-fw') ? {\n width: \"\".concat(width / height * 16 * 0.0625, \"em\")\n } : {};\n\n if (watchable) {\n content.attributes[DATA_FA_I2SVG] = '';\n }\n\n if (title) {\n content.children.push({\n tag: 'title',\n attributes: {\n id: content.attributes['aria-labelledby'] || \"title-\".concat(titleId || nextUniqueId())\n },\n children: [title]\n });\n delete content.attributes.title;\n }\n\n var args = _objectSpread2(_objectSpread2({}, content), {}, {\n prefix: prefix,\n iconName: iconName,\n main: main,\n mask: mask,\n maskId: maskId,\n transform: transform,\n symbol: symbol,\n styles: _objectSpread2(_objectSpread2({}, uploadedIconWidthStyle), extra.styles)\n });\n\n var _ref2 = mask.found && main.found ? callProvided('generateAbstractMask', args) || {\n children: [],\n attributes: {}\n } : callProvided('generateAbstractIcon', args) || {\n children: [],\n attributes: {}\n },\n children = _ref2.children,\n attributes = _ref2.attributes;\n\n args.children = children;\n args.attributes = attributes;\n\n if (symbol) {\n return asSymbol(args);\n } else {\n return asIcon(args);\n }\n}\nfunction makeLayersTextAbstract(params) {\n var content = params.content,\n width = params.width,\n height = params.height,\n transform = params.transform,\n title = params.title,\n extra = params.extra,\n _params$watchable2 = params.watchable,\n watchable = _params$watchable2 === void 0 ? false : _params$watchable2;\n\n var attributes = _objectSpread2(_objectSpread2(_objectSpread2({}, extra.attributes), title ? {\n 'title': title\n } : {}), {}, {\n 'class': extra.classes.join(' ')\n });\n\n if (watchable) {\n attributes[DATA_FA_I2SVG] = '';\n }\n\n var styles = _objectSpread2({}, extra.styles);\n\n if (transformIsMeaningful(transform)) {\n styles['transform'] = transformForCss({\n transform: transform,\n startCentered: true,\n width: width,\n height: height\n });\n styles['-webkit-transform'] = styles['transform'];\n }\n\n var styleString = joinStyles(styles);\n\n if (styleString.length > 0) {\n attributes['style'] = styleString;\n }\n\n var val = [];\n val.push({\n tag: 'span',\n attributes: attributes,\n children: [content]\n });\n\n if (title) {\n val.push({\n tag: 'span',\n attributes: {\n class: 'sr-only'\n },\n children: [title]\n });\n }\n\n return val;\n}\nfunction makeLayersCounterAbstract(params) {\n var content = params.content,\n title = params.title,\n extra = params.extra;\n\n var attributes = _objectSpread2(_objectSpread2(_objectSpread2({}, extra.attributes), title ? {\n 'title': title\n } : {}), {}, {\n 'class': extra.classes.join(' ')\n });\n\n var styleString = joinStyles(extra.styles);\n\n if (styleString.length > 0) {\n attributes['style'] = styleString;\n }\n\n var val = [];\n val.push({\n tag: 'span',\n attributes: attributes,\n children: [content]\n });\n\n if (title) {\n val.push({\n tag: 'span',\n attributes: {\n class: 'sr-only'\n },\n children: [title]\n });\n }\n\n return val;\n}\n\nvar styles$1 = namespace.styles;\nfunction asFoundIcon(icon) {\n var width = icon[0];\n var height = icon[1];\n\n var _icon$slice = icon.slice(4),\n _icon$slice2 = _slicedToArray(_icon$slice, 1),\n vectorData = _icon$slice2[0];\n\n var element = null;\n\n if (Array.isArray(vectorData)) {\n element = {\n tag: 'g',\n attributes: {\n class: \"\".concat(config.cssPrefix, \"-\").concat(DUOTONE_CLASSES.GROUP)\n },\n children: [{\n tag: 'path',\n attributes: {\n class: \"\".concat(config.cssPrefix, \"-\").concat(DUOTONE_CLASSES.SECONDARY),\n fill: 'currentColor',\n d: vectorData[0]\n }\n }, {\n tag: 'path',\n attributes: {\n class: \"\".concat(config.cssPrefix, \"-\").concat(DUOTONE_CLASSES.PRIMARY),\n fill: 'currentColor',\n d: vectorData[1]\n }\n }]\n };\n } else {\n element = {\n tag: 'path',\n attributes: {\n fill: 'currentColor',\n d: vectorData\n }\n };\n }\n\n return {\n found: true,\n width: width,\n height: height,\n icon: element\n };\n}\nvar missingIconResolutionMixin = {\n found: false,\n width: 512,\n height: 512\n};\n\nfunction maybeNotifyMissing(iconName, prefix) {\n if (!PRODUCTION && !config.showMissingIcons && iconName) {\n console.error(\"Icon with name \\\"\".concat(iconName, \"\\\" and prefix \\\"\").concat(prefix, \"\\\" is missing.\"));\n }\n}\n\nfunction findIcon(iconName, prefix) {\n var givenPrefix = prefix;\n\n if (prefix === 'fa' && config.styleDefault !== null) {\n prefix = getDefaultUsablePrefix();\n }\n\n return new Promise(function (resolve, reject) {\n var val = {\n found: false,\n width: 512,\n height: 512,\n icon: callProvided('missingIconAbstract') || {}\n };\n\n if (givenPrefix === 'fa') {\n var shim = byOldName(iconName) || {};\n iconName = shim.iconName || iconName;\n prefix = shim.prefix || prefix;\n }\n\n if (iconName && prefix && styles$1[prefix] && styles$1[prefix][iconName]) {\n var icon = styles$1[prefix][iconName];\n return resolve(asFoundIcon(icon));\n }\n\n maybeNotifyMissing(iconName, prefix);\n resolve(_objectSpread2(_objectSpread2({}, missingIconResolutionMixin), {}, {\n icon: config.showMissingIcons && iconName ? callProvided('missingIconAbstract') || {} : {}\n }));\n });\n}\n\nvar noop$1 = function noop() {};\n\nvar p = config.measurePerformance && PERFORMANCE && PERFORMANCE.mark && PERFORMANCE.measure ? PERFORMANCE : {\n mark: noop$1,\n measure: noop$1\n};\nvar preamble = \"FA \\\"6.4.0\\\"\";\n\nvar begin = function begin(name) {\n p.mark(\"\".concat(preamble, \" \").concat(name, \" begins\"));\n return function () {\n return end(name);\n };\n};\n\nvar end = function end(name) {\n p.mark(\"\".concat(preamble, \" \").concat(name, \" ends\"));\n p.measure(\"\".concat(preamble, \" \").concat(name), \"\".concat(preamble, \" \").concat(name, \" begins\"), \"\".concat(preamble, \" \").concat(name, \" ends\"));\n};\n\nvar perf = {\n begin: begin,\n end: end\n};\n\nvar noop$2 = function noop() {};\n\nfunction isWatched(node) {\n var i2svg = node.getAttribute ? node.getAttribute(DATA_FA_I2SVG) : null;\n return typeof i2svg === 'string';\n}\n\nfunction hasPrefixAndIcon(node) {\n var prefix = node.getAttribute ? node.getAttribute(DATA_PREFIX) : null;\n var icon = node.getAttribute ? node.getAttribute(DATA_ICON) : null;\n return prefix && icon;\n}\n\nfunction hasBeenReplaced(node) {\n return node && node.classList && node.classList.contains && node.classList.contains(config.replacementClass);\n}\n\nfunction getMutator() {\n if (config.autoReplaceSvg === true) {\n return mutators.replace;\n }\n\n var mutator = mutators[config.autoReplaceSvg];\n return mutator || mutators.replace;\n}\n\nfunction createElementNS(tag) {\n return DOCUMENT.createElementNS('http://www.w3.org/2000/svg', tag);\n}\n\nfunction createElement(tag) {\n return DOCUMENT.createElement(tag);\n}\n\nfunction convertSVG(abstractObj) {\n var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n var _params$ceFn = params.ceFn,\n ceFn = _params$ceFn === void 0 ? abstractObj.tag === 'svg' ? createElementNS : createElement : _params$ceFn;\n\n if (typeof abstractObj === 'string') {\n return DOCUMENT.createTextNode(abstractObj);\n }\n\n var tag = ceFn(abstractObj.tag);\n Object.keys(abstractObj.attributes || []).forEach(function (key) {\n tag.setAttribute(key, abstractObj.attributes[key]);\n });\n var children = abstractObj.children || [];\n children.forEach(function (child) {\n tag.appendChild(convertSVG(child, {\n ceFn: ceFn\n }));\n });\n return tag;\n}\n\nfunction nodeAsComment(node) {\n var comment = \" \".concat(node.outerHTML, \" \");\n /* BEGIN.ATTRIBUTION */\n\n comment = \"\".concat(comment, \"Font Awesome fontawesome.com \");\n /* END.ATTRIBUTION */\n\n return comment;\n}\n\nvar mutators = {\n replace: function replace(mutation) {\n var node = mutation[0];\n\n if (node.parentNode) {\n mutation[1].forEach(function (_abstract) {\n node.parentNode.insertBefore(convertSVG(_abstract), node);\n });\n\n if (node.getAttribute(DATA_FA_I2SVG) === null && config.keepOriginalSource) {\n var comment = DOCUMENT.createComment(nodeAsComment(node));\n node.parentNode.replaceChild(comment, node);\n } else {\n node.remove();\n }\n }\n },\n nest: function nest(mutation) {\n var node = mutation[0];\n var _abstract2 = mutation[1]; // If we already have a replaced node we do not want to continue nesting within it.\n // Short-circuit to the standard replacement\n\n if (~classArray(node).indexOf(config.replacementClass)) {\n return mutators.replace(mutation);\n }\n\n var forSvg = new RegExp(\"\".concat(config.cssPrefix, \"-.*\"));\n delete _abstract2[0].attributes.id;\n\n if (_abstract2[0].attributes.class) {\n var splitClasses = _abstract2[0].attributes.class.split(' ').reduce(function (acc, cls) {\n if (cls === config.replacementClass || cls.match(forSvg)) {\n acc.toSvg.push(cls);\n } else {\n acc.toNode.push(cls);\n }\n\n return acc;\n }, {\n toNode: [],\n toSvg: []\n });\n\n _abstract2[0].attributes.class = splitClasses.toSvg.join(' ');\n\n if (splitClasses.toNode.length === 0) {\n node.removeAttribute('class');\n } else {\n node.setAttribute('class', splitClasses.toNode.join(' '));\n }\n }\n\n var newInnerHTML = _abstract2.map(function (a) {\n return toHtml(a);\n }).join('\\n');\n\n node.setAttribute(DATA_FA_I2SVG, '');\n node.innerHTML = newInnerHTML;\n }\n};\n\nfunction performOperationSync(op) {\n op();\n}\n\nfunction perform(mutations, callback) {\n var callbackFunction = typeof callback === 'function' ? callback : noop$2;\n\n if (mutations.length === 0) {\n callbackFunction();\n } else {\n var frame = performOperationSync;\n\n if (config.mutateApproach === MUTATION_APPROACH_ASYNC) {\n frame = WINDOW.requestAnimationFrame || performOperationSync;\n }\n\n frame(function () {\n var mutator = getMutator();\n var mark = perf.begin('mutate');\n mutations.map(mutator);\n mark();\n callbackFunction();\n });\n }\n}\nvar disabled = false;\nfunction disableObservation() {\n disabled = true;\n}\nfunction enableObservation() {\n disabled = false;\n}\nvar mo = null;\nfunction observe(options) {\n if (!MUTATION_OBSERVER) {\n return;\n }\n\n if (!config.observeMutations) {\n return;\n }\n\n var _options$treeCallback = options.treeCallback,\n treeCallback = _options$treeCallback === void 0 ? noop$2 : _options$treeCallback,\n _options$nodeCallback = options.nodeCallback,\n nodeCallback = _options$nodeCallback === void 0 ? noop$2 : _options$nodeCallback,\n _options$pseudoElemen = options.pseudoElementsCallback,\n pseudoElementsCallback = _options$pseudoElemen === void 0 ? noop$2 : _options$pseudoElemen,\n _options$observeMutat = options.observeMutationsRoot,\n observeMutationsRoot = _options$observeMutat === void 0 ? DOCUMENT : _options$observeMutat;\n mo = new MUTATION_OBSERVER(function (objects) {\n if (disabled) return;\n var defaultPrefix = getDefaultUsablePrefix();\n toArray(objects).forEach(function (mutationRecord) {\n if (mutationRecord.type === 'childList' && mutationRecord.addedNodes.length > 0 && !isWatched(mutationRecord.addedNodes[0])) {\n if (config.searchPseudoElements) {\n pseudoElementsCallback(mutationRecord.target);\n }\n\n treeCallback(mutationRecord.target);\n }\n\n if (mutationRecord.type === 'attributes' && mutationRecord.target.parentNode && config.searchPseudoElements) {\n pseudoElementsCallback(mutationRecord.target.parentNode);\n }\n\n if (mutationRecord.type === 'attributes' && isWatched(mutationRecord.target) && ~ATTRIBUTES_WATCHED_FOR_MUTATION.indexOf(mutationRecord.attributeName)) {\n if (mutationRecord.attributeName === 'class' && hasPrefixAndIcon(mutationRecord.target)) {\n var _getCanonicalIcon = getCanonicalIcon(classArray(mutationRecord.target)),\n prefix = _getCanonicalIcon.prefix,\n iconName = _getCanonicalIcon.iconName;\n\n mutationRecord.target.setAttribute(DATA_PREFIX, prefix || defaultPrefix);\n if (iconName) mutationRecord.target.setAttribute(DATA_ICON, iconName);\n } else if (hasBeenReplaced(mutationRecord.target)) {\n nodeCallback(mutationRecord.target);\n }\n }\n });\n });\n if (!IS_DOM) return;\n mo.observe(observeMutationsRoot, {\n childList: true,\n attributes: true,\n characterData: true,\n subtree: true\n });\n}\nfunction disconnect() {\n if (!mo) return;\n mo.disconnect();\n}\n\nfunction styleParser (node) {\n var style = node.getAttribute('style');\n var val = [];\n\n if (style) {\n val = style.split(';').reduce(function (acc, style) {\n var styles = style.split(':');\n var prop = styles[0];\n var value = styles.slice(1);\n\n if (prop && value.length > 0) {\n acc[prop] = value.join(':').trim();\n }\n\n return acc;\n }, {});\n }\n\n return val;\n}\n\nfunction classParser (node) {\n var existingPrefix = node.getAttribute('data-prefix');\n var existingIconName = node.getAttribute('data-icon');\n var innerText = node.innerText !== undefined ? node.innerText.trim() : '';\n var val = getCanonicalIcon(classArray(node));\n\n if (!val.prefix) {\n val.prefix = getDefaultUsablePrefix();\n }\n\n if (existingPrefix && existingIconName) {\n val.prefix = existingPrefix;\n val.iconName = existingIconName;\n }\n\n if (val.iconName && val.prefix) {\n return val;\n }\n\n if (val.prefix && innerText.length > 0) {\n val.iconName = byLigature(val.prefix, node.innerText) || byUnicode(val.prefix, toHex(node.innerText));\n }\n\n if (!val.iconName && config.autoFetchSvg && node.firstChild && node.firstChild.nodeType === Node.TEXT_NODE) {\n val.iconName = node.firstChild.data;\n }\n\n return val;\n}\n\nfunction attributesParser (node) {\n var extraAttributes = toArray(node.attributes).reduce(function (acc, attr) {\n if (acc.name !== 'class' && acc.name !== 'style') {\n acc[attr.name] = attr.value;\n }\n\n return acc;\n }, {});\n var title = node.getAttribute('title');\n var titleId = node.getAttribute('data-fa-title-id');\n\n if (config.autoA11y) {\n if (title) {\n extraAttributes['aria-labelledby'] = \"\".concat(config.replacementClass, \"-title-\").concat(titleId || nextUniqueId());\n } else {\n extraAttributes['aria-hidden'] = 'true';\n extraAttributes['focusable'] = 'false';\n }\n }\n\n return extraAttributes;\n}\n\nfunction blankMeta() {\n return {\n iconName: null,\n title: null,\n titleId: null,\n prefix: null,\n transform: meaninglessTransform,\n symbol: false,\n mask: {\n iconName: null,\n prefix: null,\n rest: []\n },\n maskId: null,\n extra: {\n classes: [],\n styles: {},\n attributes: {}\n }\n };\n}\nfunction parseMeta(node) {\n var parser = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {\n styleParser: true\n };\n\n var _classParser = classParser(node),\n iconName = _classParser.iconName,\n prefix = _classParser.prefix,\n extraClasses = _classParser.rest;\n\n var extraAttributes = attributesParser(node);\n var pluginMeta = chainHooks('parseNodeAttributes', {}, node);\n var extraStyles = parser.styleParser ? styleParser(node) : [];\n return _objectSpread2({\n iconName: iconName,\n title: node.getAttribute('title'),\n titleId: node.getAttribute('data-fa-title-id'),\n prefix: prefix,\n transform: meaninglessTransform,\n mask: {\n iconName: null,\n prefix: null,\n rest: []\n },\n maskId: null,\n symbol: false,\n extra: {\n classes: extraClasses,\n styles: extraStyles,\n attributes: extraAttributes\n }\n }, pluginMeta);\n}\n\nvar styles$2 = namespace.styles;\n\nfunction generateMutation(node) {\n var nodeMeta = config.autoReplaceSvg === 'nest' ? parseMeta(node, {\n styleParser: false\n }) : parseMeta(node);\n\n if (~nodeMeta.extra.classes.indexOf(LAYERS_TEXT_CLASSNAME)) {\n return callProvided('generateLayersText', node, nodeMeta);\n } else {\n return callProvided('generateSvgReplacementMutation', node, nodeMeta);\n }\n}\n\nvar knownPrefixes = new Set();\nFAMILIES.map(function (family) {\n knownPrefixes.add(\"fa-\".concat(family));\n});\nObject.keys(PREFIX_TO_STYLE[FAMILY_CLASSIC]).map(knownPrefixes.add.bind(knownPrefixes));\nObject.keys(PREFIX_TO_STYLE[FAMILY_SHARP]).map(knownPrefixes.add.bind(knownPrefixes));\nknownPrefixes = _toConsumableArray(knownPrefixes);\n\nfunction onTree(root) {\n var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;\n if (!IS_DOM) return Promise.resolve();\n var htmlClassList = DOCUMENT.documentElement.classList;\n\n var hclAdd = function hclAdd(suffix) {\n return htmlClassList.add(\"\".concat(HTML_CLASS_I2SVG_BASE_CLASS, \"-\").concat(suffix));\n };\n\n var hclRemove = function hclRemove(suffix) {\n return htmlClassList.remove(\"\".concat(HTML_CLASS_I2SVG_BASE_CLASS, \"-\").concat(suffix));\n };\n\n var prefixes = config.autoFetchSvg ? knownPrefixes : FAMILIES.map(function (f) {\n return \"fa-\".concat(f);\n }).concat(Object.keys(styles$2));\n\n if (!prefixes.includes('fa')) {\n prefixes.push('fa');\n }\n\n var prefixesDomQuery = [\".\".concat(LAYERS_TEXT_CLASSNAME, \":not([\").concat(DATA_FA_I2SVG, \"])\")].concat(prefixes.map(function (p) {\n return \".\".concat(p, \":not([\").concat(DATA_FA_I2SVG, \"])\");\n })).join(', ');\n\n if (prefixesDomQuery.length === 0) {\n return Promise.resolve();\n }\n\n var candidates = [];\n\n try {\n candidates = toArray(root.querySelectorAll(prefixesDomQuery));\n } catch (e) {// noop\n }\n\n if (candidates.length > 0) {\n hclAdd('pending');\n hclRemove('complete');\n } else {\n return Promise.resolve();\n }\n\n var mark = perf.begin('onTree');\n var mutations = candidates.reduce(function (acc, node) {\n try {\n var mutation = generateMutation(node);\n\n if (mutation) {\n acc.push(mutation);\n }\n } catch (e) {\n if (!PRODUCTION) {\n if (e.name === 'MissingIcon') {\n console.error(e);\n }\n }\n }\n\n return acc;\n }, []);\n return new Promise(function (resolve, reject) {\n Promise.all(mutations).then(function (resolvedMutations) {\n perform(resolvedMutations, function () {\n hclAdd('active');\n hclAdd('complete');\n hclRemove('pending');\n if (typeof callback === 'function') callback();\n mark();\n resolve();\n });\n }).catch(function (e) {\n mark();\n reject(e);\n });\n });\n}\n\nfunction onNode(node) {\n var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;\n generateMutation(node).then(function (mutation) {\n if (mutation) {\n perform([mutation], callback);\n }\n });\n}\n\nfunction resolveIcons(next) {\n return function (maybeIconDefinition) {\n var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n var iconDefinition = (maybeIconDefinition || {}).icon ? maybeIconDefinition : findIconDefinition(maybeIconDefinition || {});\n var mask = params.mask;\n\n if (mask) {\n mask = (mask || {}).icon ? mask : findIconDefinition(mask || {});\n }\n\n return next(iconDefinition, _objectSpread2(_objectSpread2({}, params), {}, {\n mask: mask\n }));\n };\n}\n\nvar render = function render(iconDefinition) {\n var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n var _params$transform = params.transform,\n transform = _params$transform === void 0 ? meaninglessTransform : _params$transform,\n _params$symbol = params.symbol,\n symbol = _params$symbol === void 0 ? false : _params$symbol,\n _params$mask = params.mask,\n mask = _params$mask === void 0 ? null : _params$mask,\n _params$maskId = params.maskId,\n maskId = _params$maskId === void 0 ? null : _params$maskId,\n _params$title = params.title,\n title = _params$title === void 0 ? null : _params$title,\n _params$titleId = params.titleId,\n titleId = _params$titleId === void 0 ? null : _params$titleId,\n _params$classes = params.classes,\n classes = _params$classes === void 0 ? [] : _params$classes,\n _params$attributes = params.attributes,\n attributes = _params$attributes === void 0 ? {} : _params$attributes,\n _params$styles = params.styles,\n styles = _params$styles === void 0 ? {} : _params$styles;\n if (!iconDefinition) return;\n var prefix = iconDefinition.prefix,\n iconName = iconDefinition.iconName,\n icon = iconDefinition.icon;\n return domVariants(_objectSpread2({\n type: 'icon'\n }, iconDefinition), function () {\n callHooks('beforeDOMElementCreation', {\n iconDefinition: iconDefinition,\n params: params\n });\n\n if (config.autoA11y) {\n if (title) {\n attributes['aria-labelledby'] = \"\".concat(config.replacementClass, \"-title-\").concat(titleId || nextUniqueId());\n } else {\n attributes['aria-hidden'] = 'true';\n attributes['focusable'] = 'false';\n }\n }\n\n return makeInlineSvgAbstract({\n icons: {\n main: asFoundIcon(icon),\n mask: mask ? asFoundIcon(mask.icon) : {\n found: false,\n width: null,\n height: null,\n icon: {}\n }\n },\n prefix: prefix,\n iconName: iconName,\n transform: _objectSpread2(_objectSpread2({}, meaninglessTransform), transform),\n symbol: symbol,\n title: title,\n maskId: maskId,\n titleId: titleId,\n extra: {\n attributes: attributes,\n styles: styles,\n classes: classes\n }\n });\n });\n};\nvar ReplaceElements = {\n mixout: function mixout() {\n return {\n icon: resolveIcons(render)\n };\n },\n hooks: function hooks() {\n return {\n mutationObserverCallbacks: function mutationObserverCallbacks(accumulator) {\n accumulator.treeCallback = onTree;\n accumulator.nodeCallback = onNode;\n return accumulator;\n }\n };\n },\n provides: function provides(providers$$1) {\n providers$$1.i2svg = function (params) {\n var _params$node = params.node,\n node = _params$node === void 0 ? DOCUMENT : _params$node,\n _params$callback = params.callback,\n callback = _params$callback === void 0 ? function () {} : _params$callback;\n return onTree(node, callback);\n };\n\n providers$$1.generateSvgReplacementMutation = function (node, nodeMeta) {\n var iconName = nodeMeta.iconName,\n title = nodeMeta.title,\n titleId = nodeMeta.titleId,\n prefix = nodeMeta.prefix,\n transform = nodeMeta.transform,\n symbol = nodeMeta.symbol,\n mask = nodeMeta.mask,\n maskId = nodeMeta.maskId,\n extra = nodeMeta.extra;\n return new Promise(function (resolve, reject) {\n Promise.all([findIcon(iconName, prefix), mask.iconName ? findIcon(mask.iconName, mask.prefix) : Promise.resolve({\n found: false,\n width: 512,\n height: 512,\n icon: {}\n })]).then(function (_ref) {\n var _ref2 = _slicedToArray(_ref, 2),\n main = _ref2[0],\n mask = _ref2[1];\n\n resolve([node, makeInlineSvgAbstract({\n icons: {\n main: main,\n mask: mask\n },\n prefix: prefix,\n iconName: iconName,\n transform: transform,\n symbol: symbol,\n maskId: maskId,\n title: title,\n titleId: titleId,\n extra: extra,\n watchable: true\n })]);\n }).catch(reject);\n });\n };\n\n providers$$1.generateAbstractIcon = function (_ref3) {\n var children = _ref3.children,\n attributes = _ref3.attributes,\n main = _ref3.main,\n transform = _ref3.transform,\n styles = _ref3.styles;\n var styleString = joinStyles(styles);\n\n if (styleString.length > 0) {\n attributes['style'] = styleString;\n }\n\n var nextChild;\n\n if (transformIsMeaningful(transform)) {\n nextChild = callProvided('generateAbstractTransformGrouping', {\n main: main,\n transform: transform,\n containerWidth: main.width,\n iconWidth: main.width\n });\n }\n\n children.push(nextChild || main.icon);\n return {\n children: children,\n attributes: attributes\n };\n };\n }\n};\n\nvar Layers = {\n mixout: function mixout() {\n return {\n layer: function layer(assembler) {\n var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n var _params$classes = params.classes,\n classes = _params$classes === void 0 ? [] : _params$classes;\n return domVariants({\n type: 'layer'\n }, function () {\n callHooks('beforeDOMElementCreation', {\n assembler: assembler,\n params: params\n });\n var children = [];\n assembler(function (args) {\n Array.isArray(args) ? args.map(function (a) {\n children = children.concat(a.abstract);\n }) : children = children.concat(args.abstract);\n });\n return [{\n tag: 'span',\n attributes: {\n class: [\"\".concat(config.cssPrefix, \"-layers\")].concat(_toConsumableArray(classes)).join(' ')\n },\n children: children\n }];\n });\n }\n };\n }\n};\n\nvar LayersCounter = {\n mixout: function mixout() {\n return {\n counter: function counter(content) {\n var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n var _params$title = params.title,\n title = _params$title === void 0 ? null : _params$title,\n _params$classes = params.classes,\n classes = _params$classes === void 0 ? [] : _params$classes,\n _params$attributes = params.attributes,\n attributes = _params$attributes === void 0 ? {} : _params$attributes,\n _params$styles = params.styles,\n styles = _params$styles === void 0 ? {} : _params$styles;\n return domVariants({\n type: 'counter',\n content: content\n }, function () {\n callHooks('beforeDOMElementCreation', {\n content: content,\n params: params\n });\n return makeLayersCounterAbstract({\n content: content.toString(),\n title: title,\n extra: {\n attributes: attributes,\n styles: styles,\n classes: [\"\".concat(config.cssPrefix, \"-layers-counter\")].concat(_toConsumableArray(classes))\n }\n });\n });\n }\n };\n }\n};\n\nvar LayersText = {\n mixout: function mixout() {\n return {\n text: function text(content) {\n var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n var _params$transform = params.transform,\n transform = _params$transform === void 0 ? meaninglessTransform : _params$transform,\n _params$title = params.title,\n title = _params$title === void 0 ? null : _params$title,\n _params$classes = params.classes,\n classes = _params$classes === void 0 ? [] : _params$classes,\n _params$attributes = params.attributes,\n attributes = _params$attributes === void 0 ? {} : _params$attributes,\n _params$styles = params.styles,\n styles = _params$styles === void 0 ? {} : _params$styles;\n return domVariants({\n type: 'text',\n content: content\n }, function () {\n callHooks('beforeDOMElementCreation', {\n content: content,\n params: params\n });\n return makeLayersTextAbstract({\n content: content,\n transform: _objectSpread2(_objectSpread2({}, meaninglessTransform), transform),\n title: title,\n extra: {\n attributes: attributes,\n styles: styles,\n classes: [\"\".concat(config.cssPrefix, \"-layers-text\")].concat(_toConsumableArray(classes))\n }\n });\n });\n }\n };\n },\n provides: function provides(providers$$1) {\n providers$$1.generateLayersText = function (node, nodeMeta) {\n var title = nodeMeta.title,\n transform = nodeMeta.transform,\n extra = nodeMeta.extra;\n var width = null;\n var height = null;\n\n if (IS_IE) {\n var computedFontSize = parseInt(getComputedStyle(node).fontSize, 10);\n var boundingClientRect = node.getBoundingClientRect();\n width = boundingClientRect.width / computedFontSize;\n height = boundingClientRect.height / computedFontSize;\n }\n\n if (config.autoA11y && !title) {\n extra.attributes['aria-hidden'] = 'true';\n }\n\n return Promise.resolve([node, makeLayersTextAbstract({\n content: node.innerHTML,\n width: width,\n height: height,\n transform: transform,\n title: title,\n extra: extra,\n watchable: true\n })]);\n };\n }\n};\n\nvar CLEAN_CONTENT_PATTERN = new RegExp(\"\\\"\", 'ug');\nvar SECONDARY_UNICODE_RANGE = [1105920, 1112319];\nfunction hexValueFromContent(content) {\n var cleaned = content.replace(CLEAN_CONTENT_PATTERN, '');\n var codePoint = codePointAt(cleaned, 0);\n var isPrependTen = codePoint >= SECONDARY_UNICODE_RANGE[0] && codePoint <= SECONDARY_UNICODE_RANGE[1];\n var isDoubled = cleaned.length === 2 ? cleaned[0] === cleaned[1] : false;\n return {\n value: isDoubled ? toHex(cleaned[0]) : toHex(cleaned),\n isSecondary: isPrependTen || isDoubled\n };\n}\n\nfunction replaceForPosition(node, position) {\n var pendingAttribute = \"\".concat(DATA_FA_PSEUDO_ELEMENT_PENDING).concat(position.replace(':', '-'));\n return new Promise(function (resolve, reject) {\n if (node.getAttribute(pendingAttribute) !== null) {\n // This node is already being processed\n return resolve();\n }\n\n var children = toArray(node.children);\n var alreadyProcessedPseudoElement = children.filter(function (c) {\n return c.getAttribute(DATA_FA_PSEUDO_ELEMENT) === position;\n })[0];\n var styles = WINDOW.getComputedStyle(node, position);\n var fontFamily = styles.getPropertyValue('font-family').match(FONT_FAMILY_PATTERN);\n var fontWeight = styles.getPropertyValue('font-weight');\n var content = styles.getPropertyValue('content');\n\n if (alreadyProcessedPseudoElement && !fontFamily) {\n // If we've already processed it but the current computed style does not result in a font-family,\n // that probably means that a class name that was previously present to make the icon has been\n // removed. So we now should delete the icon.\n node.removeChild(alreadyProcessedPseudoElement);\n return resolve();\n } else if (fontFamily && content !== 'none' && content !== '') {\n var _content = styles.getPropertyValue('content');\n\n var family = ~['Sharp'].indexOf(fontFamily[2]) ? FAMILY_SHARP : FAMILY_CLASSIC;\n var prefix = ~['Solid', 'Regular', 'Light', 'Thin', 'Duotone', 'Brands', 'Kit'].indexOf(fontFamily[2]) ? STYLE_TO_PREFIX[family][fontFamily[2].toLowerCase()] : FONT_WEIGHT_TO_PREFIX[family][fontWeight];\n\n var _hexValueFromContent = hexValueFromContent(_content),\n hexValue = _hexValueFromContent.value,\n isSecondary = _hexValueFromContent.isSecondary;\n\n var isV4 = fontFamily[0].startsWith('FontAwesome');\n var iconName = byUnicode(prefix, hexValue);\n var iconIdentifier = iconName;\n\n if (isV4) {\n var iconName4 = byOldUnicode(hexValue);\n\n if (iconName4.iconName && iconName4.prefix) {\n iconName = iconName4.iconName;\n prefix = iconName4.prefix;\n }\n } // Only convert the pseudo element in this ::before/::after position into an icon if we haven't\n // already done so with the same prefix and iconName\n\n\n if (iconName && !isSecondary && (!alreadyProcessedPseudoElement || alreadyProcessedPseudoElement.getAttribute(DATA_PREFIX) !== prefix || alreadyProcessedPseudoElement.getAttribute(DATA_ICON) !== iconIdentifier)) {\n node.setAttribute(pendingAttribute, iconIdentifier);\n\n if (alreadyProcessedPseudoElement) {\n // Delete the old one, since we're replacing it with a new one\n node.removeChild(alreadyProcessedPseudoElement);\n }\n\n var meta = blankMeta();\n var extra = meta.extra;\n extra.attributes[DATA_FA_PSEUDO_ELEMENT] = position;\n findIcon(iconName, prefix).then(function (main) {\n var _abstract = makeInlineSvgAbstract(_objectSpread2(_objectSpread2({}, meta), {}, {\n icons: {\n main: main,\n mask: emptyCanonicalIcon()\n },\n prefix: prefix,\n iconName: iconIdentifier,\n extra: extra,\n watchable: true\n }));\n\n var element = DOCUMENT.createElement('svg');\n\n if (position === '::before') {\n node.insertBefore(element, node.firstChild);\n } else {\n node.appendChild(element);\n }\n\n element.outerHTML = _abstract.map(function (a) {\n return toHtml(a);\n }).join('\\n');\n node.removeAttribute(pendingAttribute);\n resolve();\n }).catch(reject);\n } else {\n resolve();\n }\n } else {\n resolve();\n }\n });\n}\n\nfunction replace(node) {\n return Promise.all([replaceForPosition(node, '::before'), replaceForPosition(node, '::after')]);\n}\n\nfunction processable(node) {\n return node.parentNode !== document.head && !~TAGNAMES_TO_SKIP_FOR_PSEUDOELEMENTS.indexOf(node.tagName.toUpperCase()) && !node.getAttribute(DATA_FA_PSEUDO_ELEMENT) && (!node.parentNode || node.parentNode.tagName !== 'svg');\n}\n\nfunction searchPseudoElements(root) {\n if (!IS_DOM) return;\n return new Promise(function (resolve, reject) {\n var operations = toArray(root.querySelectorAll('*')).filter(processable).map(replace);\n var end = perf.begin('searchPseudoElements');\n disableObservation();\n Promise.all(operations).then(function () {\n end();\n enableObservation();\n resolve();\n }).catch(function () {\n end();\n enableObservation();\n reject();\n });\n });\n}\n\nvar PseudoElements = {\n hooks: function hooks() {\n return {\n mutationObserverCallbacks: function mutationObserverCallbacks(accumulator) {\n accumulator.pseudoElementsCallback = searchPseudoElements;\n return accumulator;\n }\n };\n },\n provides: function provides(providers$$1) {\n providers$$1.pseudoElements2svg = function (params) {\n var _params$node = params.node,\n node = _params$node === void 0 ? DOCUMENT : _params$node;\n\n if (config.searchPseudoElements) {\n searchPseudoElements(node);\n }\n };\n }\n};\n\nvar _unwatched = false;\nvar MutationObserver$1 = {\n mixout: function mixout() {\n return {\n dom: {\n unwatch: function unwatch() {\n disableObservation();\n _unwatched = true;\n }\n }\n };\n },\n hooks: function hooks() {\n return {\n bootstrap: function bootstrap() {\n observe(chainHooks('mutationObserverCallbacks', {}));\n },\n noAuto: function noAuto() {\n disconnect();\n },\n watch: function watch(params) {\n var observeMutationsRoot = params.observeMutationsRoot;\n\n if (_unwatched) {\n enableObservation();\n } else {\n observe(chainHooks('mutationObserverCallbacks', {\n observeMutationsRoot: observeMutationsRoot\n }));\n }\n }\n };\n }\n};\n\nvar parseTransformString = function parseTransformString(transformString) {\n var transform = {\n size: 16,\n x: 0,\n y: 0,\n flipX: false,\n flipY: false,\n rotate: 0\n };\n return transformString.toLowerCase().split(' ').reduce(function (acc, n) {\n var parts = n.toLowerCase().split('-');\n var first = parts[0];\n var rest = parts.slice(1).join('-');\n\n if (first && rest === 'h') {\n acc.flipX = true;\n return acc;\n }\n\n if (first && rest === 'v') {\n acc.flipY = true;\n return acc;\n }\n\n rest = parseFloat(rest);\n\n if (isNaN(rest)) {\n return acc;\n }\n\n switch (first) {\n case 'grow':\n acc.size = acc.size + rest;\n break;\n\n case 'shrink':\n acc.size = acc.size - rest;\n break;\n\n case 'left':\n acc.x = acc.x - rest;\n break;\n\n case 'right':\n acc.x = acc.x + rest;\n break;\n\n case 'up':\n acc.y = acc.y - rest;\n break;\n\n case 'down':\n acc.y = acc.y + rest;\n break;\n\n case 'rotate':\n acc.rotate = acc.rotate + rest;\n break;\n }\n\n return acc;\n }, transform);\n};\nvar PowerTransforms = {\n mixout: function mixout() {\n return {\n parse: {\n transform: function transform(transformString) {\n return parseTransformString(transformString);\n }\n }\n };\n },\n hooks: function hooks() {\n return {\n parseNodeAttributes: function parseNodeAttributes(accumulator, node) {\n var transformString = node.getAttribute('data-fa-transform');\n\n if (transformString) {\n accumulator.transform = parseTransformString(transformString);\n }\n\n return accumulator;\n }\n };\n },\n provides: function provides(providers) {\n providers.generateAbstractTransformGrouping = function (_ref) {\n var main = _ref.main,\n transform = _ref.transform,\n containerWidth = _ref.containerWidth,\n iconWidth = _ref.iconWidth;\n var outer = {\n transform: \"translate(\".concat(containerWidth / 2, \" 256)\")\n };\n var innerTranslate = \"translate(\".concat(transform.x * 32, \", \").concat(transform.y * 32, \") \");\n var innerScale = \"scale(\".concat(transform.size / 16 * (transform.flipX ? -1 : 1), \", \").concat(transform.size / 16 * (transform.flipY ? -1 : 1), \") \");\n var innerRotate = \"rotate(\".concat(transform.rotate, \" 0 0)\");\n var inner = {\n transform: \"\".concat(innerTranslate, \" \").concat(innerScale, \" \").concat(innerRotate)\n };\n var path = {\n transform: \"translate(\".concat(iconWidth / 2 * -1, \" -256)\")\n };\n var operations = {\n outer: outer,\n inner: inner,\n path: path\n };\n return {\n tag: 'g',\n attributes: _objectSpread2({}, operations.outer),\n children: [{\n tag: 'g',\n attributes: _objectSpread2({}, operations.inner),\n children: [{\n tag: main.icon.tag,\n children: main.icon.children,\n attributes: _objectSpread2(_objectSpread2({}, main.icon.attributes), operations.path)\n }]\n }]\n };\n };\n }\n};\n\nvar ALL_SPACE = {\n x: 0,\n y: 0,\n width: '100%',\n height: '100%'\n};\n\nfunction fillBlack(_abstract) {\n var force = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;\n\n if (_abstract.attributes && (_abstract.attributes.fill || force)) {\n _abstract.attributes.fill = 'black';\n }\n\n return _abstract;\n}\n\nfunction deGroup(_abstract2) {\n if (_abstract2.tag === 'g') {\n return _abstract2.children;\n } else {\n return [_abstract2];\n }\n}\n\nvar Masks = {\n hooks: function hooks() {\n return {\n parseNodeAttributes: function parseNodeAttributes(accumulator, node) {\n var maskData = node.getAttribute('data-fa-mask');\n var mask = !maskData ? emptyCanonicalIcon() : getCanonicalIcon(maskData.split(' ').map(function (i) {\n return i.trim();\n }));\n\n if (!mask.prefix) {\n mask.prefix = getDefaultUsablePrefix();\n }\n\n accumulator.mask = mask;\n accumulator.maskId = node.getAttribute('data-fa-mask-id');\n return accumulator;\n }\n };\n },\n provides: function provides(providers) {\n providers.generateAbstractMask = function (_ref) {\n var children = _ref.children,\n attributes = _ref.attributes,\n main = _ref.main,\n mask = _ref.mask,\n explicitMaskId = _ref.maskId,\n transform = _ref.transform;\n var mainWidth = main.width,\n mainPath = main.icon;\n var maskWidth = mask.width,\n maskPath = mask.icon;\n var trans = transformForSvg({\n transform: transform,\n containerWidth: maskWidth,\n iconWidth: mainWidth\n });\n var maskRect = {\n tag: 'rect',\n attributes: _objectSpread2(_objectSpread2({}, ALL_SPACE), {}, {\n fill: 'white'\n })\n };\n var maskInnerGroupChildrenMixin = mainPath.children ? {\n children: mainPath.children.map(fillBlack)\n } : {};\n var maskInnerGroup = {\n tag: 'g',\n attributes: _objectSpread2({}, trans.inner),\n children: [fillBlack(_objectSpread2({\n tag: mainPath.tag,\n attributes: _objectSpread2(_objectSpread2({}, mainPath.attributes), trans.path)\n }, maskInnerGroupChildrenMixin))]\n };\n var maskOuterGroup = {\n tag: 'g',\n attributes: _objectSpread2({}, trans.outer),\n children: [maskInnerGroup]\n };\n var maskId = \"mask-\".concat(explicitMaskId || nextUniqueId());\n var clipId = \"clip-\".concat(explicitMaskId || nextUniqueId());\n var maskTag = {\n tag: 'mask',\n attributes: _objectSpread2(_objectSpread2({}, ALL_SPACE), {}, {\n id: maskId,\n maskUnits: 'userSpaceOnUse',\n maskContentUnits: 'userSpaceOnUse'\n }),\n children: [maskRect, maskOuterGroup]\n };\n var defs = {\n tag: 'defs',\n children: [{\n tag: 'clipPath',\n attributes: {\n id: clipId\n },\n children: deGroup(maskPath)\n }, maskTag]\n };\n children.push(defs, {\n tag: 'rect',\n attributes: _objectSpread2({\n fill: 'currentColor',\n 'clip-path': \"url(#\".concat(clipId, \")\"),\n mask: \"url(#\".concat(maskId, \")\")\n }, ALL_SPACE)\n });\n return {\n children: children,\n attributes: attributes\n };\n };\n }\n};\n\nvar MissingIconIndicator = {\n provides: function provides(providers) {\n var reduceMotion = false;\n\n if (WINDOW.matchMedia) {\n reduceMotion = WINDOW.matchMedia('(prefers-reduced-motion: reduce)').matches;\n }\n\n providers.missingIconAbstract = function () {\n var gChildren = [];\n var FILL = {\n fill: 'currentColor'\n };\n var ANIMATION_BASE = {\n attributeType: 'XML',\n repeatCount: 'indefinite',\n dur: '2s'\n }; // Ring\n\n gChildren.push({\n tag: 'path',\n attributes: _objectSpread2(_objectSpread2({}, FILL), {}, {\n d: 'M156.5,447.7l-12.6,29.5c-18.7-9.5-35.9-21.2-51.5-34.9l22.7-22.7C127.6,430.5,141.5,440,156.5,447.7z M40.6,272H8.5 c1.4,21.2,5.4,41.7,11.7,61.1L50,321.2C45.1,305.5,41.8,289,40.6,272z M40.6,240c1.4-18.8,5.2-37,11.1-54.1l-29.5-12.6 C14.7,194.3,10,216.7,8.5,240H40.6z M64.3,156.5c7.8-14.9,17.2-28.8,28.1-41.5L69.7,92.3c-13.7,15.6-25.5,32.8-34.9,51.5 L64.3,156.5z M397,419.6c-13.9,12-29.4,22.3-46.1,30.4l11.9,29.8c20.7-9.9,39.8-22.6,56.9-37.6L397,419.6z M115,92.4 c13.9-12,29.4-22.3,46.1-30.4l-11.9-29.8c-20.7,9.9-39.8,22.6-56.8,37.6L115,92.4z M447.7,355.5c-7.8,14.9-17.2,28.8-28.1,41.5 l22.7,22.7c13.7-15.6,25.5-32.9,34.9-51.5L447.7,355.5z M471.4,272c-1.4,18.8-5.2,37-11.1,54.1l29.5,12.6 c7.5-21.1,12.2-43.5,13.6-66.8H471.4z M321.2,462c-15.7,5-32.2,8.2-49.2,9.4v32.1c21.2-1.4,41.7-5.4,61.1-11.7L321.2,462z M240,471.4c-18.8-1.4-37-5.2-54.1-11.1l-12.6,29.5c21.1,7.5,43.5,12.2,66.8,13.6V471.4z M462,190.8c5,15.7,8.2,32.2,9.4,49.2h32.1 c-1.4-21.2-5.4-41.7-11.7-61.1L462,190.8z M92.4,397c-12-13.9-22.3-29.4-30.4-46.1l-29.8,11.9c9.9,20.7,22.6,39.8,37.6,56.9 L92.4,397z M272,40.6c18.8,1.4,36.9,5.2,54.1,11.1l12.6-29.5C317.7,14.7,295.3,10,272,8.5V40.6z M190.8,50 c15.7-5,32.2-8.2,49.2-9.4V8.5c-21.2,1.4-41.7,5.4-61.1,11.7L190.8,50z M442.3,92.3L419.6,115c12,13.9,22.3,29.4,30.5,46.1 l29.8-11.9C470,128.5,457.3,109.4,442.3,92.3z M397,92.4l22.7-22.7c-15.6-13.7-32.8-25.5-51.5-34.9l-12.6,29.5 C370.4,72.1,384.4,81.5,397,92.4z'\n })\n });\n\n var OPACITY_ANIMATE = _objectSpread2(_objectSpread2({}, ANIMATION_BASE), {}, {\n attributeName: 'opacity'\n });\n\n var dot = {\n tag: 'circle',\n attributes: _objectSpread2(_objectSpread2({}, FILL), {}, {\n cx: '256',\n cy: '364',\n r: '28'\n }),\n children: []\n };\n\n if (!reduceMotion) {\n dot.children.push({\n tag: 'animate',\n attributes: _objectSpread2(_objectSpread2({}, ANIMATION_BASE), {}, {\n attributeName: 'r',\n values: '28;14;28;28;14;28;'\n })\n }, {\n tag: 'animate',\n attributes: _objectSpread2(_objectSpread2({}, OPACITY_ANIMATE), {}, {\n values: '1;0;1;1;0;1;'\n })\n });\n }\n\n gChildren.push(dot);\n gChildren.push({\n tag: 'path',\n attributes: _objectSpread2(_objectSpread2({}, FILL), {}, {\n opacity: '1',\n d: 'M263.7,312h-16c-6.6,0-12-5.4-12-12c0-71,77.4-63.9,77.4-107.8c0-20-17.8-40.2-57.4-40.2c-29.1,0-44.3,9.6-59.2,28.7 c-3.9,5-11.1,6-16.2,2.4l-13.1-9.2c-5.6-3.9-6.9-11.8-2.6-17.2c21.2-27.2,46.4-44.7,91.2-44.7c52.3,0,97.4,29.8,97.4,80.2 c0,67.6-77.4,63.5-77.4,107.8C275.7,306.6,270.3,312,263.7,312z'\n }),\n children: reduceMotion ? [] : [{\n tag: 'animate',\n attributes: _objectSpread2(_objectSpread2({}, OPACITY_ANIMATE), {}, {\n values: '1;0;0;0;0;1;'\n })\n }]\n });\n\n if (!reduceMotion) {\n // Exclamation\n gChildren.push({\n tag: 'path',\n attributes: _objectSpread2(_objectSpread2({}, FILL), {}, {\n opacity: '0',\n d: 'M232.5,134.5l7,168c0.3,6.4,5.6,11.5,12,11.5h9c6.4,0,11.7-5.1,12-11.5l7-168c0.3-6.8-5.2-12.5-12-12.5h-23 C237.7,122,232.2,127.7,232.5,134.5z'\n }),\n children: [{\n tag: 'animate',\n attributes: _objectSpread2(_objectSpread2({}, OPACITY_ANIMATE), {}, {\n values: '0;0;1;1;0;0;'\n })\n }]\n });\n }\n\n return {\n tag: 'g',\n attributes: {\n 'class': 'missing'\n },\n children: gChildren\n };\n };\n }\n};\n\nvar SvgSymbols = {\n hooks: function hooks() {\n return {\n parseNodeAttributes: function parseNodeAttributes(accumulator, node) {\n var symbolData = node.getAttribute('data-fa-symbol');\n var symbol = symbolData === null ? false : symbolData === '' ? true : symbolData;\n accumulator['symbol'] = symbol;\n return accumulator;\n }\n };\n }\n};\n\nvar plugins = [InjectCSS, ReplaceElements, Layers, LayersCounter, LayersText, PseudoElements, MutationObserver$1, PowerTransforms, Masks, MissingIconIndicator, SvgSymbols];\n\nregisterPlugins(plugins, {\n mixoutsTo: api\n});\nvar noAuto$1 = api.noAuto;\nvar config$1 = api.config;\nvar library$1 = api.library;\nvar dom$1 = api.dom;\nvar parse$1 = api.parse;\nvar findIconDefinition$1 = api.findIconDefinition;\nvar toHtml$1 = api.toHtml;\nvar icon = api.icon;\nvar layer = api.layer;\nvar text = api.text;\nvar counter = api.counter;\n\nexport { noAuto$1 as noAuto, config$1 as config, library$1 as library, dom$1 as dom, parse$1 as parse, findIconDefinition$1 as findIconDefinition, toHtml$1 as toHtml, icon, layer, text, counter, api };\n","import { parse, icon } from '@fortawesome/fontawesome-svg-core';\nimport PropTypes from 'prop-types';\nimport React from 'react';\n\nfunction ownKeys(object, enumerableOnly) {\n var keys = Object.keys(object);\n\n if (Object.getOwnPropertySymbols) {\n var symbols = Object.getOwnPropertySymbols(object);\n enumerableOnly && (symbols = symbols.filter(function (sym) {\n return Object.getOwnPropertyDescriptor(object, sym).enumerable;\n })), keys.push.apply(keys, symbols);\n }\n\n return keys;\n}\n\nfunction _objectSpread2(target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = null != arguments[i] ? arguments[i] : {};\n i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {\n _defineProperty(target, key, source[key]);\n }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {\n Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));\n });\n }\n\n return target;\n}\n\nfunction _typeof(obj) {\n \"@babel/helpers - typeof\";\n\n return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (obj) {\n return typeof obj;\n } : function (obj) {\n return obj && \"function\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n }, _typeof(obj);\n}\n\nfunction _defineProperty(obj, key, value) {\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n\n return obj;\n}\n\nfunction _objectWithoutPropertiesLoose(source, excluded) {\n if (source == null) return {};\n var target = {};\n var sourceKeys = Object.keys(source);\n var key, i;\n\n for (i = 0; i < sourceKeys.length; i++) {\n key = sourceKeys[i];\n if (excluded.indexOf(key) >= 0) continue;\n target[key] = source[key];\n }\n\n return target;\n}\n\nfunction _objectWithoutProperties(source, excluded) {\n if (source == null) return {};\n\n var target = _objectWithoutPropertiesLoose(source, excluded);\n\n var key, i;\n\n if (Object.getOwnPropertySymbols) {\n var sourceSymbolKeys = Object.getOwnPropertySymbols(source);\n\n for (i = 0; i < sourceSymbolKeys.length; i++) {\n key = sourceSymbolKeys[i];\n if (excluded.indexOf(key) >= 0) continue;\n if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;\n target[key] = source[key];\n }\n }\n\n return target;\n}\n\nfunction _toConsumableArray(arr) {\n return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();\n}\n\nfunction _arrayWithoutHoles(arr) {\n if (Array.isArray(arr)) return _arrayLikeToArray(arr);\n}\n\nfunction _iterableToArray(iter) {\n if (typeof Symbol !== \"undefined\" && iter[Symbol.iterator] != null || iter[\"@@iterator\"] != null) return Array.from(iter);\n}\n\nfunction _unsupportedIterableToArray(o, minLen) {\n if (!o) return;\n if (typeof o === \"string\") return _arrayLikeToArray(o, minLen);\n var n = Object.prototype.toString.call(o).slice(8, -1);\n if (n === \"Object\" && o.constructor) n = o.constructor.name;\n if (n === \"Map\" || n === \"Set\") return Array.from(o);\n if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);\n}\n\nfunction _arrayLikeToArray(arr, len) {\n if (len == null || len > arr.length) len = arr.length;\n\n for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];\n\n return arr2;\n}\n\nfunction _nonIterableSpread() {\n throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n}\n\n// Get CSS class list from a props object\nfunction classList(props) {\n var _classes;\n\n var beat = props.beat,\n fade = props.fade,\n beatFade = props.beatFade,\n bounce = props.bounce,\n shake = props.shake,\n flash = props.flash,\n spin = props.spin,\n spinPulse = props.spinPulse,\n spinReverse = props.spinReverse,\n pulse = props.pulse,\n fixedWidth = props.fixedWidth,\n inverse = props.inverse,\n border = props.border,\n listItem = props.listItem,\n flip = props.flip,\n size = props.size,\n rotation = props.rotation,\n pull = props.pull; // map of CSS class names to properties\n\n var classes = (_classes = {\n 'fa-beat': beat,\n 'fa-fade': fade,\n 'fa-beat-fade': beatFade,\n 'fa-bounce': bounce,\n 'fa-shake': shake,\n 'fa-flash': flash,\n 'fa-spin': spin,\n 'fa-spin-reverse': spinReverse,\n 'fa-spin-pulse': spinPulse,\n 'fa-pulse': pulse,\n 'fa-fw': fixedWidth,\n 'fa-inverse': inverse,\n 'fa-border': border,\n 'fa-li': listItem,\n 'fa-flip': flip === true,\n 'fa-flip-horizontal': flip === 'horizontal' || flip === 'both',\n 'fa-flip-vertical': flip === 'vertical' || flip === 'both'\n }, _defineProperty(_classes, \"fa-\".concat(size), typeof size !== 'undefined' && size !== null), _defineProperty(_classes, \"fa-rotate-\".concat(rotation), typeof rotation !== 'undefined' && rotation !== null && rotation !== 0), _defineProperty(_classes, \"fa-pull-\".concat(pull), typeof pull !== 'undefined' && pull !== null), _defineProperty(_classes, 'fa-swap-opacity', props.swapOpacity), _classes); // map over all the keys in the classes object\n // return an array of the keys where the value for the key is not null\n\n return Object.keys(classes).map(function (key) {\n return classes[key] ? key : null;\n }).filter(function (key) {\n return key;\n });\n}\n\n// Camelize taken from humps\n// humps is copyright © 2012+ Dom Christie\n// Released under the MIT license.\n// Performant way to determine if object coerces to a number\nfunction _isNumerical(obj) {\n obj = obj - 0; // eslint-disable-next-line no-self-compare\n\n return obj === obj;\n}\n\nfunction camelize(string) {\n if (_isNumerical(string)) {\n return string;\n } // eslint-disable-next-line no-useless-escape\n\n\n string = string.replace(/[\\-_\\s]+(.)?/g, function (match, chr) {\n return chr ? chr.toUpperCase() : '';\n }); // Ensure 1st char is always lowercase\n\n return string.substr(0, 1).toLowerCase() + string.substr(1);\n}\n\nvar _excluded = [\"style\"];\n\nfunction capitalize(val) {\n return val.charAt(0).toUpperCase() + val.slice(1);\n}\n\nfunction styleToObject(style) {\n return style.split(';').map(function (s) {\n return s.trim();\n }).filter(function (s) {\n return s;\n }).reduce(function (acc, pair) {\n var i = pair.indexOf(':');\n var prop = camelize(pair.slice(0, i));\n var value = pair.slice(i + 1).trim();\n prop.startsWith('webkit') ? acc[capitalize(prop)] = value : acc[prop] = value;\n return acc;\n }, {});\n}\n\nfunction convert(createElement, element) {\n var extraProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n if (typeof element === 'string') {\n return element;\n }\n\n var children = (element.children || []).map(function (child) {\n return convert(createElement, child);\n });\n /* eslint-disable dot-notation */\n\n var mixins = Object.keys(element.attributes || {}).reduce(function (acc, key) {\n var val = element.attributes[key];\n\n switch (key) {\n case 'class':\n acc.attrs['className'] = val;\n delete element.attributes['class'];\n break;\n\n case 'style':\n acc.attrs['style'] = styleToObject(val);\n break;\n\n default:\n if (key.indexOf('aria-') === 0 || key.indexOf('data-') === 0) {\n acc.attrs[key.toLowerCase()] = val;\n } else {\n acc.attrs[camelize(key)] = val;\n }\n\n }\n\n return acc;\n }, {\n attrs: {}\n });\n\n var _extraProps$style = extraProps.style,\n existingStyle = _extraProps$style === void 0 ? {} : _extraProps$style,\n remaining = _objectWithoutProperties(extraProps, _excluded);\n\n mixins.attrs['style'] = _objectSpread2(_objectSpread2({}, mixins.attrs['style']), existingStyle);\n /* eslint-enable */\n\n return createElement.apply(void 0, [element.tag, _objectSpread2(_objectSpread2({}, mixins.attrs), remaining)].concat(_toConsumableArray(children)));\n}\n\nvar PRODUCTION = false;\n\ntry {\n PRODUCTION = process.env.NODE_ENV === 'production';\n} catch (e) {}\n\nfunction log () {\n if (!PRODUCTION && console && typeof console.error === 'function') {\n var _console;\n\n (_console = console).error.apply(_console, arguments);\n }\n}\n\nfunction normalizeIconArgs(icon) {\n // this has everything that it needs to be rendered which means it was probably imported\n // directly from an icon svg package\n if (icon && _typeof(icon) === 'object' && icon.prefix && icon.iconName && icon.icon) {\n return icon;\n }\n\n if (parse.icon) {\n return parse.icon(icon);\n } // if the icon is null, there's nothing to do\n\n\n if (icon === null) {\n return null;\n } // if the icon is an object and has a prefix and an icon name, return it\n\n\n if (icon && _typeof(icon) === 'object' && icon.prefix && icon.iconName) {\n return icon;\n } // if it's an array with length of two\n\n\n if (Array.isArray(icon) && icon.length === 2) {\n // use the first item as prefix, second as icon name\n return {\n prefix: icon[0],\n iconName: icon[1]\n };\n } // if it's a string, use it as the icon name\n\n\n if (typeof icon === 'string') {\n return {\n prefix: 'fas',\n iconName: icon\n };\n }\n}\n\n// creates an object with a key of key\n// and a value of value\n// if certain conditions are met\nfunction objectWithKey(key, value) {\n // if the value is a non-empty array\n // or it's not an array but it is truthy\n // then create the object with the key and the value\n // if not, return an empty array\n return Array.isArray(value) && value.length > 0 || !Array.isArray(value) && value ? _defineProperty({}, key, value) : {};\n}\n\nvar FontAwesomeIcon = /*#__PURE__*/React.forwardRef(function (props, ref) {\n var iconArgs = props.icon,\n maskArgs = props.mask,\n symbol = props.symbol,\n className = props.className,\n title = props.title,\n titleId = props.titleId,\n maskId = props.maskId;\n var iconLookup = normalizeIconArgs(iconArgs);\n var classes = objectWithKey('classes', [].concat(_toConsumableArray(classList(props)), _toConsumableArray(className.split(' '))));\n var transform = objectWithKey('transform', typeof props.transform === 'string' ? parse.transform(props.transform) : props.transform);\n var mask = objectWithKey('mask', normalizeIconArgs(maskArgs));\n var renderedIcon = icon(iconLookup, _objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2({}, classes), transform), mask), {}, {\n symbol: symbol,\n title: title,\n titleId: titleId,\n maskId: maskId\n }));\n\n if (!renderedIcon) {\n log('Could not find icon', iconLookup);\n return null;\n }\n\n var abstract = renderedIcon.abstract;\n var extraProps = {\n ref: ref\n };\n Object.keys(props).forEach(function (key) {\n // eslint-disable-next-line no-prototype-builtins\n if (!FontAwesomeIcon.defaultProps.hasOwnProperty(key)) {\n extraProps[key] = props[key];\n }\n });\n return convertCurry(abstract[0], extraProps);\n});\nFontAwesomeIcon.displayName = 'FontAwesomeIcon';\nFontAwesomeIcon.propTypes = {\n beat: PropTypes.bool,\n border: PropTypes.bool,\n beatFade: PropTypes.bool,\n bounce: PropTypes.bool,\n className: PropTypes.string,\n fade: PropTypes.bool,\n flash: PropTypes.bool,\n mask: PropTypes.oneOfType([PropTypes.object, PropTypes.array, PropTypes.string]),\n maskId: PropTypes.string,\n fixedWidth: PropTypes.bool,\n inverse: PropTypes.bool,\n flip: PropTypes.oneOf([true, false, 'horizontal', 'vertical', 'both']),\n icon: PropTypes.oneOfType([PropTypes.object, PropTypes.array, PropTypes.string]),\n listItem: PropTypes.bool,\n pull: PropTypes.oneOf(['right', 'left']),\n pulse: PropTypes.bool,\n rotation: PropTypes.oneOf([0, 90, 180, 270]),\n shake: PropTypes.bool,\n size: PropTypes.oneOf(['2xs', 'xs', 'sm', 'lg', 'xl', '2xl', '1x', '2x', '3x', '4x', '5x', '6x', '7x', '8x', '9x', '10x']),\n spin: PropTypes.bool,\n spinPulse: PropTypes.bool,\n spinReverse: PropTypes.bool,\n symbol: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]),\n title: PropTypes.string,\n titleId: PropTypes.string,\n transform: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),\n swapOpacity: PropTypes.bool\n};\nFontAwesomeIcon.defaultProps = {\n border: false,\n className: '',\n mask: null,\n maskId: null,\n fixedWidth: false,\n inverse: false,\n flip: false,\n icon: null,\n listItem: false,\n pull: null,\n pulse: false,\n rotation: null,\n size: null,\n spin: false,\n spinPulse: false,\n spinReverse: false,\n beat: false,\n fade: false,\n beatFade: false,\n bounce: false,\n shake: false,\n symbol: false,\n title: '',\n titleId: null,\n transform: null,\n swapOpacity: false\n};\nvar convertCurry = convert.bind(null, React.createElement);\n\nexport { FontAwesomeIcon };\n","import { useStaticQuery, graphql, Link } from 'gatsby';\nimport React from 'react';\nimport { css } from '@emotion/react';\nimport PropTypes from 'prop-types';\n\nfunction Dropdown(props) {\n const { directoryName, data, menuExpanded } = props;\n const [expanded, setExpanded] = React.useState(false);\n const [mediaQueryMatches, setMediaQueryMatches] = React.useState(false);\n\n const updateMediaQuery = React.useCallback((mediaQuery) => {\n setMediaQueryMatches(mediaQuery.matches);\n }, []);\n\n const handleBlur = React.useCallback(() => {\n setExpanded(false);\n }, []);\n\n const handleFocus = React.useCallback(() => {\n setExpanded(true);\n }, []);\n\n React.useEffect(() => {\n const mediaQuery = window.matchMedia('(max-width: 768px)');\n updateMediaQuery(mediaQuery);\n mediaQuery.addEventListener('change', updateMediaQuery);\n return () => {\n mediaQuery.removeEventListener('change', updateMediaQuery);\n };\n }, []);\n\n const renderListItem = React.useCallback(\n (node, shouldRender) => {\n if (shouldRender) {\n return (\n \n \n {node.frontmatter.title}\n \n \n );\n }\n return null;\n },\n [mediaQueryMatches, menuExpanded, handleBlur, handleFocus]\n );\n\n const menuVisibiltyCSS = expanded\n ? css`\n left: inherit;\n top: inherit;\n `\n : css`\n top: -9999px;\n left: -9999px;\n `;\n\n return (\n \n \n {directoryName.replace(/-/g, ' ')}\n \n \n {data.allMarkdownRemark.edges.map(({ node }) =>\n renderListItem(\n node,\n // we don't want index.md files as dropdown list items\n // we also only want files that are direct children of the directory\n // or are index.md files of sub directories\n !node.fileAbsolutePath.includes(`${directoryName}/index.md`) &&\n (node.fileAbsolutePath.includes(\n `${directoryName}/${node.fileAbsolutePath.split('/').pop()}`\n ) ||\n node.fileAbsolutePath.search(new RegExp(`/${directoryName}/[^/]+/index.md`)) !== -1)\n )\n )}\n \n \n );\n}\n\nfunction DropdownQueryContainer({ directoryName, menuExpanded }) {\n const data = useStaticQuery(graphql`\n query {\n allMarkdownRemark(sort: { frontmatter: { title: ASC } }) {\n edges {\n node {\n id\n frontmatter {\n title\n }\n fields {\n slug\n }\n fileAbsolutePath\n }\n }\n }\n }\n `);\n return ;\n}\n\nexport default DropdownQueryContainer;\n\nDropdownQueryContainer.propTypes = {\n directoryName: PropTypes.string.isRequired,\n menuExpanded: PropTypes.bool.isRequired,\n};\n\nDropdown.propTypes = {\n directoryName: PropTypes.string.isRequired,\n data: PropTypes.shape({\n allMarkdownRemark: PropTypes.shape({\n edges: PropTypes.arrayOf(\n PropTypes.shape({\n node: PropTypes.shape({\n id: PropTypes.string.isRequired,\n frontmatter: PropTypes.shape({ title: PropTypes.string.isRequired }).isRequired,\n fields: PropTypes.shape({ slug: PropTypes.string.isRequired }).isRequired,\n fileAbsolutePath: PropTypes.string.isRequired,\n }),\n }).isRequired\n ).isRequired,\n }).isRequired,\n }).isRequired,\n menuExpanded: PropTypes.bool.isRequired,\n};\n","import { useStaticQuery, graphql } from 'gatsby';\nimport React from 'react';\nimport PropTypes from 'prop-types';\nimport { css } from '@emotion/react';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport Dropdown from './dropdown';\n\nclass Navbar extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n expanded: false,\n };\n this.handleClick = this.handleClick.bind(this);\n this.handleBlur = this.handleBlur.bind(this);\n this.handleFocus = this.handleFocus.bind(this);\n }\n\n handleBlur() {\n this.setState({ expanded: false });\n }\n\n handleFocus() {\n this.setState({ expanded: true });\n }\n\n handleClick() {\n this.setState((currentState) => ({ expanded: !currentState.expanded }));\n }\n\n render() {\n const { data } = this.props;\n const { expanded } = this.state;\n const menuVisibiltyCSS = expanded\n ? css`\n left: inherit;\n top: 1.5rem;\n `\n : css`\n top: -9999px;\n left: -9999px;\n `;\n return (\n \n \n Skip to content\n \n \n \n \n \n {data.allDirectory.edges.map(({ node }) => (\n \n ))}\n \n \n );\n }\n}\n\nexport default function NavbarQueryContainer() {\n const data = useStaticQuery(graphql`\n query {\n allDirectory(\n filter: {\n sourceInstanceName: { eq: \"content\" }\n relativePath: { regex: \"/^[^/]+$/\" }\n name: { regex: \"/^[^/_]/\" }\n }\n sort: { name: ASC }\n ) {\n edges {\n node {\n id\n name\n }\n }\n }\n }\n `);\n return ;\n}\n\nNavbar.propTypes = {\n data: PropTypes.shape({\n allDirectory: PropTypes.shape({\n edges: PropTypes.arrayOf(\n PropTypes.shape({\n node: PropTypes.shape({\n id: PropTypes.string.isRequired,\n name: PropTypes.string.isRequired,\n }),\n }).isRequired\n ).isRequired,\n }).isRequired,\n }).isRequired,\n};\n","import { Link } from 'gatsby';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { css } from '@emotion/react';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport Navbar from './navbar';\nimport Searchbar from './searchbar';\n\nclass Header extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n searchVisible: false,\n };\n this.toggleSearch = this.toggleSearch.bind(this);\n }\n\n toggleSearch(e) {\n e.preventDefault();\n this.setState((prevState) => ({\n searchVisible: !prevState.searchVisible,\n }));\n }\n\n render() {\n const { siteTitle } = this.props;\n const { searchVisible } = this.state;\n return (\n \n

\n \n {siteTitle}\n \n

\n \n \n \n \n\n {searchVisible ? (\n \n {\n e.preventDefault();\n }}\n css={css`\n @media only screen and (min-width: 768px) {\n float: right;\n }\n padding: 0.5rem 1rem;\n `}\n >\n \n \n
\n ) : null}\n \n );\n }\n}\n\nHeader.propTypes = {\n siteTitle: PropTypes.string,\n};\n\nHeader.defaultProps = {\n siteTitle: '',\n};\n\nexport default Header;\n","import { useStaticQuery, graphql, Link } from 'gatsby';\nimport React from 'react';\nimport PropTypes from 'prop-types';\nimport { css } from '@emotion/react';\n\nfunction RecentMeetings({ styles: { ulStyle, liStyle, linkStyle, headerStyle } }) {\n const data = useStaticQuery(graphql`\n query {\n allMarkdownRemark(\n sort: { frontmatter: { date: DESC } }\n filter: {\n fileAbsolutePath: {\n regex: \"/(collaboration)/(communication)/(monthly-meetings)/((?!index).)*[.]md$/\"\n }\n }\n limit: 5\n ) {\n edges {\n node {\n id\n frontmatter {\n title\n date(formatString: \"Do MMMM YYYY\")\n }\n fields {\n slug\n }\n }\n }\n }\n }\n `);\n return (\n \n );\n}\n\nexport default RecentMeetings;\n\nRecentMeetings.propTypes = {\n styles: PropTypes.shape({\n liStyle: PropTypes.shape({ styles: PropTypes.string }).isRequired,\n ulStyle: PropTypes.shape({ styles: PropTypes.string }).isRequired,\n linkStyle: PropTypes.shape({ styles: PropTypes.string }).isRequired,\n headerStyle: PropTypes.shape({ styles: PropTypes.string }).isRequired,\n }),\n};\n\nRecentMeetings.defaultProps = {\n styles: {\n liStyle: {},\n ulStyle: {},\n linkStyle: {},\n headerStyle: {},\n },\n};\n","import React from 'react';\nimport { css } from '@emotion/react';\nimport PropTypes from 'prop-types';\n\n/**\n * Gets the most recent commit to the given repo if it exists, otherwise null\n *\n * @param repo a repository object from the github API\n * @returns {Promise} an object representing the most recent commit\n * in the repo if it exists, with the fields 'name', 'url', and 'date', otherwise\n * null\n */\nasync function fetchRepoMostRecentCommit(repo) {\n const commitUrl = repo.commits_url;\n // Cut off '{/sha}' at the end of the commits url\n const parts = commitUrl.split('{');\n return fetch(parts[0])\n .then(async (commitsResponse) => {\n const commitsData = await commitsResponse.json();\n\n if (commitsData.length === 0) return null;\n\n const mostRecent = commitsData[0];\n return {\n name: repo.name,\n url: mostRecent.html_url,\n date: mostRecent.commit.author.date,\n };\n })\n .catch((error) => {\n // eslint-disable-next-line no-console\n console.warn(`Error ${error}`);\n return null;\n });\n}\n\n/**\n * Fetches the most recent commits for all the repos in the icatproject\n * github organisation\n *\n * Note that this uses unauthenticated requests to the github API, which are\n * strictly rate limited, and therefore should not be called often.\n * @returns {Promise<*[]>}\n */\nasync function fetchRecentCommits() {\n const commits = [];\n await fetch('https://api.github.com/orgs/icatproject/repos?sort=updated')\n .then(async (reposResponse) => {\n const reposData = await reposResponse.json();\n const promises = reposData.map((repo) =>\n fetchRepoMostRecentCommit(repo)\n .then((commit) => {\n if (commit !== null) commits.push(commit);\n })\n .catch(() =>\n // eslint-disable-next-line no-console\n console.warn(`Failed to retrieve commit for ${repo}`)\n )\n );\n await Promise.all(promises);\n })\n .catch((error) => {\n // eslint-disable-next-line no-console\n console.warn(`Error ${error}`);\n return [];\n });\n return commits;\n}\n\nconst hourInMillis = 60 * 60 * 1000;\nfunction isStillRecent(date) {\n return new Date().valueOf() - date.valueOf() < hourInMillis;\n}\n/**\n * Loads and displays links to the most recent commits in icatproject repos\n */\nfunction RecentCommits({ styles: { ulStyle, liStyle, linkStyle, headerStyle } }) {\n const [githubData, setGithubData] = React.useState(null);\n\n /*\n Unauthenticated requests to the github API are rate limited to 60 per hour.\n To avoid this, we cache results in local storage and only refetch from github\n at most once per hour.\n */\n React.useEffect(() => {\n async function loadRecentCommits() {\n const serializedLastFetchTime = localStorage.getItem('recentCommitsFetchTime');\n const serializedRecents = localStorage.getItem('recentCommits');\n\n const cacheIsValid =\n serializedLastFetchTime !== null &&\n serializedRecents !== null &&\n isStillRecent(new Date(serializedLastFetchTime));\n\n if (cacheIsValid) {\n setGithubData(JSON.parse(serializedRecents));\n } else {\n const recents = await fetchRecentCommits();\n recents.sort((a, b) => new Date(b.date) - new Date(a.date));\n localStorage.setItem('recentCommits', JSON.stringify(recents));\n localStorage.setItem('recentCommitsFetchTime', new Date());\n setGithubData(recents);\n }\n }\n\n loadRecentCommits();\n }, []);\n\n return (\n
\n \n
\n );\n}\n\nexport default RecentCommits;\n\nRecentCommits.propTypes = {\n styles: PropTypes.shape({\n liStyle: PropTypes.shape({ styles: PropTypes.string }).isRequired,\n ulStyle: PropTypes.shape({ styles: PropTypes.string }).isRequired,\n linkStyle: PropTypes.shape({ styles: PropTypes.string }).isRequired,\n headerStyle: PropTypes.shape({ styles: PropTypes.string }).isRequired,\n }),\n};\n\nRecentCommits.defaultProps = {\n styles: {\n liStyle: {},\n ulStyle: {},\n linkStyle: {},\n headerStyle: {},\n },\n};\n","import React from 'react';\nimport { Link } from 'gatsby';\nimport { css } from '@emotion/react';\nimport RecentMeetings from './recentMeetings';\nimport Searchbar from './searchbar';\nimport RecentCommits from './recentCommits';\n\nexport const linkStyle = css`\n text-decoration: none;\n color: white;\n &:hover {\n color: green;\n }\n`;\n\nexport const liStyle = css`\n margin-bottom: 5px;\n`;\n\nexport const ulStyle = css`\n list-style: none;\n padding: 0;\n margin: 0;\n font-size: 11px;\n`;\n\nexport const headerStyle = css`\n margin: 12px 0;\n`;\n\nexport function Sidebar() {\n return (\n \n {\n e.preventDefault();\n }}\n >\n \n Search\n \n \n \n \n \n \n
\n );\n}\n","import React from 'react';\nimport 'normalize.css';\nimport PropTypes from 'prop-types';\nimport { useStaticQuery, graphql } from 'gatsby';\nimport { css } from '@emotion/react';\nimport { library } from '@fortawesome/fontawesome-svg-core';\nimport { faSearch, faBars } from '@fortawesome/free-solid-svg-icons';\nimport Header from './header';\nimport { Sidebar } from './sidebar';\nimport './layout.css';\n\nlibrary.add(faSearch);\nlibrary.add(faBars);\n\nfunction Layout({ children }) {\n const data = useStaticQuery(graphql`\n query SiteTitleQuery {\n site {\n siteMetadata {\n title\n }\n }\n }\n `);\n return (\n <>\n
\n \n \n \n {children}\n \n \n \n );\n}\n\nLayout.propTypes = {\n children: PropTypes.node.isRequired,\n};\n\nexport default Layout;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { navigate } from 'gatsby';\n\nexport default class Searchbar extends React.Component {\n static handleKeyPress(e) {\n if (e.key === 'Enter') {\n const query = e.target.value;\n navigate(`/search?query=${query}`);\n }\n }\n\n constructor(props) {\n super(props);\n this.state = {\n query: '',\n };\n this.handleChange = this.handleChange.bind(this);\n }\n\n handleChange(e) {\n this.setState({ query: e.target.value });\n }\n\n render() {\n const { id, inputCSS } = this.props;\n const { query } = this.state;\n return (\n \n );\n }\n}\n\nSearchbar.propTypes = {\n id: PropTypes.string.isRequired,\n inputCSS: PropTypes.shape({ styles: PropTypes.string }),\n};\n\nSearchbar.defaultProps = {\n inputCSS: { name: 'searchbar', styles: '' },\n};\n","'use strict';\n\nvar reactIs = require('react-is');\n\n/**\n * Copyright 2015, Yahoo! Inc.\n * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.\n */\nvar REACT_STATICS = {\n childContextTypes: true,\n contextType: true,\n contextTypes: true,\n defaultProps: true,\n displayName: true,\n getDefaultProps: true,\n getDerivedStateFromError: true,\n getDerivedStateFromProps: true,\n mixins: true,\n propTypes: true,\n type: true\n};\nvar KNOWN_STATICS = {\n name: true,\n length: true,\n prototype: true,\n caller: true,\n callee: true,\n arguments: true,\n arity: true\n};\nvar FORWARD_REF_STATICS = {\n '$$typeof': true,\n render: true,\n defaultProps: true,\n displayName: true,\n propTypes: true\n};\nvar MEMO_STATICS = {\n '$$typeof': true,\n compare: true,\n defaultProps: true,\n displayName: true,\n propTypes: true,\n type: true\n};\nvar TYPE_STATICS = {};\nTYPE_STATICS[reactIs.ForwardRef] = FORWARD_REF_STATICS;\nTYPE_STATICS[reactIs.Memo] = MEMO_STATICS;\n\nfunction getStatics(component) {\n // React v16.11 and below\n if (reactIs.isMemo(component)) {\n return MEMO_STATICS;\n } // React v16.12 and above\n\n\n return TYPE_STATICS[component['$$typeof']] || REACT_STATICS;\n}\n\nvar defineProperty = Object.defineProperty;\nvar getOwnPropertyNames = Object.getOwnPropertyNames;\nvar getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\nvar getPrototypeOf = Object.getPrototypeOf;\nvar objectPrototype = Object.prototype;\nfunction hoistNonReactStatics(targetComponent, sourceComponent, blacklist) {\n if (typeof sourceComponent !== 'string') {\n // don't hoist over string (html) components\n if (objectPrototype) {\n var inheritedComponent = getPrototypeOf(sourceComponent);\n\n if (inheritedComponent && inheritedComponent !== objectPrototype) {\n hoistNonReactStatics(targetComponent, inheritedComponent, blacklist);\n }\n }\n\n var keys = getOwnPropertyNames(sourceComponent);\n\n if (getOwnPropertySymbols) {\n keys = keys.concat(getOwnPropertySymbols(sourceComponent));\n }\n\n var targetStatics = getStatics(targetComponent);\n var sourceStatics = getStatics(sourceComponent);\n\n for (var i = 0; i < keys.length; ++i) {\n var key = keys[i];\n\n if (!KNOWN_STATICS[key] && !(blacklist && blacklist[key]) && !(sourceStatics && sourceStatics[key]) && !(targetStatics && targetStatics[key])) {\n var descriptor = getOwnPropertyDescriptor(sourceComponent, key);\n\n try {\n // Avoid failures from read-only properties\n defineProperty(targetComponent, key, descriptor);\n } catch (e) {}\n }\n }\n }\n\n return targetComponent;\n}\n\nmodule.exports = hoistNonReactStatics;\n","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';\n\n/**\n * Use invariant() to assert state which your program assumes to be true.\n *\n * Provide sprintf-style format (only %s is supported) and arguments\n * to provide information about what broke and what you were\n * expecting.\n *\n * The invariant message will be stripped in production, but the invariant\n * will remain to ensure logic does not differ in production.\n */\n\nvar invariant = function(condition, format, a, b, c, d, e, f) {\n if (process.env.NODE_ENV !== 'production') {\n if (format === undefined) {\n throw new Error('invariant requires an error message argument');\n }\n }\n\n if (!condition) {\n var error;\n if (format === undefined) {\n error = new Error(\n 'Minified exception occurred; use the non-minified dev environment ' +\n 'for the full error message and additional helpful warnings.'\n );\n } else {\n var args = [a, b, c, d, e, f];\n var argIndex = 0;\n error = new Error(\n format.replace(/%s/g, function() { return args[argIndex++]; })\n );\n error.name = 'Invariant Violation';\n }\n\n error.framesToPop = 1; // we don't care about invariant's own frame\n throw error;\n }\n};\n\nmodule.exports = invariant;\n","/** @license React v16.13.1\n * react-is.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';var b=\"function\"===typeof Symbol&&Symbol.for,c=b?Symbol.for(\"react.element\"):60103,d=b?Symbol.for(\"react.portal\"):60106,e=b?Symbol.for(\"react.fragment\"):60107,f=b?Symbol.for(\"react.strict_mode\"):60108,g=b?Symbol.for(\"react.profiler\"):60114,h=b?Symbol.for(\"react.provider\"):60109,k=b?Symbol.for(\"react.context\"):60110,l=b?Symbol.for(\"react.async_mode\"):60111,m=b?Symbol.for(\"react.concurrent_mode\"):60111,n=b?Symbol.for(\"react.forward_ref\"):60112,p=b?Symbol.for(\"react.suspense\"):60113,q=b?\nSymbol.for(\"react.suspense_list\"):60120,r=b?Symbol.for(\"react.memo\"):60115,t=b?Symbol.for(\"react.lazy\"):60116,v=b?Symbol.for(\"react.block\"):60121,w=b?Symbol.for(\"react.fundamental\"):60117,x=b?Symbol.for(\"react.responder\"):60118,y=b?Symbol.for(\"react.scope\"):60119;\nfunction z(a){if(\"object\"===typeof a&&null!==a){var u=a.$$typeof;switch(u){case c:switch(a=a.type,a){case l:case m:case e:case g:case f:case p:return a;default:switch(a=a&&a.$$typeof,a){case k:case n:case t:case r:case h:return a;default:return u}}case d:return u}}}function A(a){return z(a)===m}exports.AsyncMode=l;exports.ConcurrentMode=m;exports.ContextConsumer=k;exports.ContextProvider=h;exports.Element=c;exports.ForwardRef=n;exports.Fragment=e;exports.Lazy=t;exports.Memo=r;exports.Portal=d;\nexports.Profiler=g;exports.StrictMode=f;exports.Suspense=p;exports.isAsyncMode=function(a){return A(a)||z(a)===l};exports.isConcurrentMode=A;exports.isContextConsumer=function(a){return z(a)===k};exports.isContextProvider=function(a){return z(a)===h};exports.isElement=function(a){return\"object\"===typeof a&&null!==a&&a.$$typeof===c};exports.isForwardRef=function(a){return z(a)===n};exports.isFragment=function(a){return z(a)===e};exports.isLazy=function(a){return z(a)===t};\nexports.isMemo=function(a){return z(a)===r};exports.isPortal=function(a){return z(a)===d};exports.isProfiler=function(a){return z(a)===g};exports.isStrictMode=function(a){return z(a)===f};exports.isSuspense=function(a){return z(a)===p};\nexports.isValidElementType=function(a){return\"string\"===typeof a||\"function\"===typeof a||a===e||a===m||a===g||a===f||a===p||a===q||\"object\"===typeof a&&null!==a&&(a.$$typeof===t||a.$$typeof===r||a.$$typeof===h||a.$$typeof===k||a.$$typeof===n||a.$$typeof===w||a.$$typeof===x||a.$$typeof===y||a.$$typeof===v)};exports.typeOf=z;\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/react-is.production.min.js');\n} else {\n module.exports = require('./cjs/react-is.development.js');\n}\n","/**\n * @license React\n * react-server-dom-webpack.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n'use strict';var k=require(\"react\"),l={stream:!0},n=new Map,p=Symbol.for(\"react.element\"),q=Symbol.for(\"react.lazy\"),r=Symbol.for(\"react.default_value\"),t=k.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ContextRegistry;function u(a){t[a]||(t[a]=k.createServerContext(a,r));return t[a]}function v(a,b,c){this._status=a;this._value=b;this._response=c}v.prototype.then=function(a){0===this._status?(null===this._value&&(this._value=[]),this._value.push(a)):a()};\nfunction w(a){switch(a._status){case 3:return a._value;case 1:var b=JSON.parse(a._value,a._response._fromJSON);a._status=3;return a._value=b;case 2:b=a._value;for(var c=b.chunks,d=0;d {\n const { forward = [], ...filteredConfig } = config || {};\n const configStr = JSON.stringify(filteredConfig, (k, v) => {\n if (typeof v === 'function') {\n v = String(v);\n if (v.startsWith(k + '(')) {\n v = 'function ' + v;\n }\n }\n return v;\n });\n return [\n `!(function(w,p,f,c){`,\n Object.keys(filteredConfig).length > 0\n ? `c=w[p]=Object.assign(w[p]||{},${configStr});`\n : `c=w[p]=w[p]||{};`,\n `c[f]=(c[f]||[])`,\n forward.length > 0 ? `.concat(${JSON.stringify(forward)})` : ``,\n `})(window,'partytown','forward');`,\n snippetCode,\n ].join('');\n};\n\n/**\n * The `type` attribute for Partytown scripts, which does two things:\n *\n * 1. Prevents the ` + + \ No newline at end of file diff --git a/collaboration/communication/face-to-face-meetings/2023-berlin/2023-berlin-collaborative-notes-2/index.html b/collaboration/communication/face-to-face-meetings/2023-berlin/2023-berlin-collaborative-notes-2/index.html new file mode 100644 index 000000000..d657686f2 --- /dev/null +++ b/collaboration/communication/face-to-face-meetings/2023-berlin/2023-berlin-collaborative-notes-2/index.html @@ -0,0 +1,734 @@ +ICAT F2F meeting collaborative notes - day two | ICAT Project

ICAT Project

Search

ICAT F2F meeting collaborative notes - day two

Day 1 notes

+

Roadmap

+

Notes on the roadmap in this document.

+

Container and Orchestration, Packaging

+

Alan: Some Preliminary Work on Containerising Front-End Components

+
    +
  • Hardware instance periodically scans the containers for (OS) vulnerabilities, python libs, node +
      +
    • Cannot look into Java files, that has to happen on the repo itself
    • +
    +
  • +
  • Next step is to containerise the components themselves
  • +
  • Ambitious plan: replace Payara with Quarkus +
      +
    • Heard about this at KubeCon
    • +
    • Does not support EJB, will have to replace all with another thing (?)
    • +
    • Should be doable but might end up being complex
    • +
    • Old authn components are not REST so would need updating +
        +
      • Kevin: don't think anyone uses these, phase out?
      • +
      +
    • +
    • Rolf: Keycloak has recently moved to Quarkus
    • +
    +
  • +
  • This should aid development work +
      +
    • Making simple changes still takes time (now) because of the effort needed to spin up the stack
    • +
    +
  • +
  • Want to start with DataGateway, enable ~minutes to spin up
  • +
  • Want it to be faster than current process of setup scripts (wildfly?) +
      +
    • This goes into dockerfile
    • +
    +
  • +
  • DB setup might need to live in a new setup file
  • +
  • Alejandra: Currently an exploratory effort into containerising components (separately) - Can we do this? +
      +
    • Rolf: HZB's approach is flexible to how many components are spun by the one container, but these will need to share the image (presentation to come)
    • +
    +
  • +
  • Andy Q: Any reason other than ease of development? Outside pressure? +
      +
    • A: No not really, we just want it to be easy
    • +
    +
  • +
  • Andy Q: Who controls the containers? +
      +
    • A: It would be someone else, we (DSEG group) will not control ourselves +
        +
      • Alex dM: Can be easier to have direct control
      • +
      +
    • +
    +
  • +
+

Rolf: A Docker Image for ICAT and Deployment at HZB

+
    +
  • +

    Design decisions, considerations:

    +
      +
    • Don't want to have runtime config in the image
    • +
    • Image should be generic
    • +
    • ICAT runtime contains secrets, so cannot push it
    • +
    • Much easier to use the same image (for all components) in all scenarios (test, dev, prod ...) +
        +
      • These will require different config
      • +
      +
    • +
    • ICAT image based on Glassfish/Payara image
    • +
    • Image versioned in line with icat.server +
        +
      • Helps when testing python-icat against older ICAT component versions
      • +
      • Take the other component versions "at a point in time" that is consistent with the server release
      • +
      +
    • +
    +
  • +
  • +

    Viktor Q: Where do you keep the images?

    +
      +
    • A: Dockerhub, currently free. COnsidering moving away from them due to past tendancy towards commercialistion. Use GitHub (this has limits on size).
    • +
    +
  • +
  • +

    Currently image is not documented

    +
  • +
  • +

    Build:

    +
      +
    • Glassfish/Payara image unzipped
    • +
    • Delete domain1
    • +
    • Unzip distibution for each ICAT component
    • +
    +
  • +
  • +

    Runtime

    +
      +
    • Use volume bind in the "usual" way
    • +
    • APPS text file lists components we wish to deploy
    • +
    • Each component has a diretory with its config files +
        +
      • setup.properties
      • +
      • run.properties
      • +
      +
    • +
    • setup script run as usual when the container is started +
        +
      • This is a bit time consuming
      • +
      +
    • +
    • Can add a filter shell script for variable substitution in the config files
    • +
    +
  • +
  • +

    HZB deploy env: 2 RHEL7 servers

    +
  • +
  • +

    Active/passive mode

    +
      +
    • 1 server is active running ICAT
    • +
    • Other is idle
    • +
    +
  • +
  • +

    Switch between active and passive is manual

    +
      +
    • Enables maintenance on one server with little downtime
    • +
    • No high availability (yet!)
    • +
    +
  • +
  • +

    extra IP for ICAT moved between active & passive

    +
      +
    • for clients switching is transparent
    • +
    +
  • +
  • +

    systemd unit files to control starting/stopping services

    +
  • +
  • +

    Orchestration: basic, 1 docker-compose

    +
  • +
  • +

    Heavy use of volumes to add runtime config to containers, keep DB in host file system & thus included in backups and to provide access to storage

    +
  • +
  • +

    All ICAT components in 1 container

    +
  • +
  • +

    Containers making up services:

    +
      +
    • icat (see above) in addition to the following
    • +
    • mysql
    • +
    • datahub
    • +
    • icatplus
    • +
    • mongodb
    • +
    • apache +
        +
      • used as a reverse proxy
      • +
      • simplifies web config as it's all in one place
      • +
      • only this container is world-reachable
      • +
      +
    • +
    • smtp +
        +
      • Only need to configure mail in one place for all containers
      • +
      +
    • +
    • keycloak
    • +
    +
  • +
  • +

    client image for mainenance tasks, e.g. cron jobs, or run interactively for admin tasks

    +
  • +
  • +

    Outlook for the future:

    +
      +
    • Kubernetes (a lot to learn)
    • +
    • High availability
    • +
    • Database would need to be extracted as a cluster +
        +
      • Alan: most DB operators will have a Kubernetes Operator with will run it for you. Rolf: want to try out other databases e.g. PostgreSQL +
          +
        • icat utils has scripts, which generate connectors, these are DB specific
        • +
        • Upgrade scripts are native, so would be needed
        • +
        +
      • +
      +
    • +
    • Could split ICAT components into separate containers, e.g. parallelise +
        +
      • IDS can only be run at once
      • +
      • icat.server can be run in parallel? +
          +
        • Patrick: Yes, either as two separate instances (e.g. ingest and recall - think DLS do this?) or as a "cluster" that talk to each other for things like caching rule updates - don't know if anyone actually does this though?
        • +
        +
      • +
      +
    • +
    +
  • +
+

Rodrigo - Kubernetes deployment @ ALBA

+
    +
  • k8s cluster: 256 cores, 625GB RAM
  • +
  • 9 nodes: 3 master nodes and 6 worker nodes
  • +
  • Docker & containerd runtimes
  • +
  • Managed by Rancher (k8s UI)
  • +
  • CI/CD +
      +
    • push to gitlab
    • +
    • Jenkins builds
    • +
    • Push to dockerhub registry - sonartype?
    • +
    • k8s configure applications
    • +
    • k8s applications (re)deployed
    • +
    +
  • +
  • Using Rolf's ICAT base image
  • +
  • Slightly modified +
      +
    • Forward logs to logstash using filebeat
    • +
    • need this as no volumes for containers, so logs could otherwise be lost
    • +
    +
  • +
  • DataHub & associated stuff (ICAT+, mongoDB) also in k8s
  • +
  • Keycloak will also be in k8s
  • +
  • YAML config stored in a repo
  • +
+

Rolf Q: is this k8s cluster just for ICAT? A: no

+

Andy Q: Why k8s and not just Docker?

+
    +
  • Instant spawning of replacements is the main advantage
  • +
  • Not all components can be run in parallel (IDS cannot share storage or it will overwrite the others)
  • +
+

Can we share this around as a "template"?

+
    +
  • This should go into icatcontrib
  • +
+

Viktor Q: How many DB can you have?

+
    +
  • Only one
  • +
  • This makes it a single point of failure
  • +
  • Have separate server (outisde K8s) for DB
  • +
  • Not within scope (at least for now)
  • +
+

Rolf: Manually switching between HZB's active and passive servers has ~4 minutes of down time. This impacts users of logbooks. k8s would avoid this

+

Viktor: we need to plan new releses ~month in advance which is a pain to co-ordinate. k8s would make this easier, if new version fails it will automatically roll back.

+

Alex K Q: How many environments do you have?

+
    +
  • 3, test demo and prod
  • +
+

Q Version?

+
    +
  • Not using the most recent version (21' version). Looking to upgrade to latest version.
  • +
+

Alex K Q: Use of helm?

+
    +
  • not yet, want to look into it
  • +
+

Alejandra Q: ESRF use of docker?

+
    +
  • Using for integration testing but not production
  • +
+

Rolf: Metadata Ingest using python-icat

+
    +
  • python-icat provides commandline scripts: +
      +
    • icatdump
    • +
    • icatingest
    • +
    +
  • +
  • originally intended for debugging, and still used a lot in python-icat tests
  • +
  • YAML & XML support +
      +
    • ICAT data file format is 1-1 mapping of ICAT schema
    • +
    +
  • +
  • scripts based on icat.dumpfile module - easy to create scripts for custom file formats
  • +
  • reference existing entities, e.g. reference an instrument by it's PID in a datafile definition
  • +
  • many-to-many +
      +
    • either embed
    • +
    • or list as separate entities +
        +
      • using property ref="id_of_other_entity" this is the id defined within the xml, rather than the ICAT id?
      • +
      +
    • +
    +
  • +
  • Problem: ICAT data file format is TOO powerful, can create any kind of ICAT object
  • +
  • Solution: restricted version of the format for ingestion
  • +
  • root element is changed to ingest format
  • +
  • can exclude various properties, eg. completion format, as that's not the remit of the ingestor
  • +
  • e.g. for ingesting a dataset, exclude the investigation as investigation is hardcoded +
      +
    • Q: where is this harcoded? takes the investigation as a parameter to the script
    • +
    +
  • +
  • Script only allows Dataset(Parameter/Instrument/Technique) to be created
  • +
  • Validates the xml using XSD +
      +
    • Does this validate type of an attribute (e.g. date)? +
        +
      • No, if you try to do this then the underlying backend would fail
      • +
      • Can add validators to chosen objects, but do not do that here
      • +
      +
    • +
    +
  • +
  • Restricted format is a recent development
  • +
  • Documentation exists
  • +
+

Andy Q: Would this be useful for e.g. SESAME?

+
    +
  • Yes, for e.g. the Rules. Using it as an example fill the DB with needed parameters first
  • +
  • Current SESAME approach: +
      +
    • Inserting facility, instrument, parameterType using SQL directly
    • +
    • Using icatingest to import an icatdump file
    • +
    +
  • +
+

Currently, the restricted formats are in a private repository. They are HZB specific. Notices that the core functionality could be moved to python-icat?

+

How difficult is it to deploy ICAT?

+

Rolf: install process is simple, provide config files and run setup. It is as easy as it can get. Difficulty is providing the configuration files. For some this is easier than others.

+

Kevin: there are a few gotchas: placing the jar for the DB in the right directory for example.

+

Andy: the install guide is out of date? Probably?

+
    +
  • Yes it refers directly to glassfish 4. icat.manual is better as it refers to payara5, but even still referes to icat4 rather than icat5. We should be able to fairly painlessly migrate the icat.manual markdown onto the GH pages for the website.
  • +
+

Docker image might be easier but is currently undocumented. Do we want something similar for the dockerfile (to prevent it from becoming a black box)?

+
    +
  • Two things: +
      +
    • Elementary documentation, what the config options are etc.
    • +
    • Aside from that, want a tutorial like the ICAT manual but for the docker approach
    • +
    +
  • +
+

CI for icat components run using Ansible scripts (developed by STFC)

+

Dockerfile is in a way self documenting...

+

There are different target groups for our documentation here: beginers or more advanced

+

How can the optional bits of the ICAT stack be indentified and made clear to a new user/developer?

+

Misc Tech bits

+

Patrick - search

+
    +
  • Free text search goes via icat.server REST API
  • +
  • icat.server calls icat.lucene +
      +
    • icat.lucene doesn't know re: rules
    • +
    • so icat.server needs to evaluate rules on search results
    • +
    • calls icat.lucene again if more results needed (if user can't see enough)
    • +
    +
  • +
  • the search call to icat.server only returns IDs, so frontends need to call icat.server entityManager to get entity info from IDs
  • +
  • User wants to search on parameters and samples and other related entities
  • +
  • Need to return e.g. instrument data along with results
  • +
  • Facets: +
      +
    • e.g. temp 80degC, date between, sample name = CeO2
    • +
    • have user select from predefined options to shrink results set e.g. like when shopping
    • +
    +
  • +
  • Synonyms, e.g. Fe = Iron +
      +
    • synonym injection (e.g. ionising = ionizing)
    • +
    • can make common stop words searchable e.g. as, be (which double as elements)
    • +
    • needs configuration
    • +
    +
  • +
  • Diamond file limit, more than 2^32 integer limit +
      +
    • Manually route ingested files based on date/IDs (multiple indexes)
    • +
    • you get this for free in elasticsearch via sharding
    • +
    +
  • +
  • performance: improve the performance by batching authorisation
  • +
  • Aside: need good metadata +
      +
    • chicken and egg, if we don't develop features bc there's no good metadata, then people won't bother to curate good metadata
    • +
    +
  • +
  • All popular search engines use Lucene (ES, opensearch, solr)
  • +
  • Any option is viable with new ICAT search solution, using lucene just misses some nice to have features
  • +
  • ElasticSearch/OpenSearch +
      +
    • nodes, only need 1 but ideally 3 for resilience
    • +
    • more nodes = more performance or specialisation, e.g. master, ingest etc.
    • +
    +
  • +
  • Sharding, each index needs >=1 primary shard
  • +
  • each primary shard can have replica shards
  • +
  • balanced between nodes
  • +
+

implementation:

+
    +
  • +

    lucenemanager was linked to lucene API

    +
  • +
  • +

    new SearchManager which is engine independent

    +
  • +
  • +

    SearchAPI class contains common functionality, and created LuceneAPI which talks to icat.lucene and OpensearchAPI can conenct to ElasticSearch/Opensearch

    +
  • +
  • +

    Performance improvements

    +
      +
    • get all metadata from search, removes need for second API call
    • +
    • IDs authorised in batched
    • +
    • Set request timeout
    • +
    • optionally return early if we have enough data
    • +
    +
  • +
  • +

    UI changes

    +
      +
    • couldn't order results by most relevant in old method
    • +
    • simplified UI
    • +
    +
  • +
  • +

    can do unit converation if you configure it

    +
  • +
  • +

    explained that there is no equivalent icat.elasticsearch - you just point icat.server at the elasticsearch server

    +
  • +
+

Rolf: Can we add an equivalent "Open" search option that adds a criteria like the "MyData" search? With the criteria being configurable?

+
    +
  • In principle yes, however this requires anything the "Open" query relies on being indexed - e.g. releaseDate, doi... +
      +
    • Don't know if this is currently the case - it would be best to indexed everything that would be useful so we don't have to re-index everything later when we realise we don't have everything we need
    • +
    +
  • +
  • Config location? Could add it in DG but might be better for DG to just pass a boolean and icat.server to handle the specifics
  • +
+

Alex dM: Can the entities indexed be controlled? If only interested in Datasets, and specific DatasetParameters (~6 valuable ones, the rest are not interesting)?

+
    +
  • entitiesToIndex is a config option in ICAT server. Only these will be indexed by Lucene/the search engine backend. This config option will still be present in the "new" version of free text search.
  • +
  • Currently, all Parameters are stored in their own index (one for Investigation, Dataset, Datafile and Sample). When searching/faceting, under the hood we "join" the main entity index to the Parameter index.
  • +
  • Joining has a negative performance impact, but is the only way to retain nested lists of objects (i.e. the only way to keep the type.name, type.units associated with the same numericValue)
  • +
  • In your use case, where there are certain valuable Parameters, it would be better to (as you have already done) "flatten" these parameters into fields on the Dataset document, as you do not need to worry about needing to be able to update these Parameters or an explosion in the number of Parameter fields. +
      +
    • This is not currently possible in either the icat.lucene or the OS/ES backend support, however in principle it should be possible to do by writing additional logic (and would be more performant) providing you don't mind the following drawbacks: +
        +
      • Parameters need to be reduced to key:value pairs, so units would need to be embedded into either the key or the value, rangeTop/rangeBottom would need to be mapped to a single value etc.
      • +
      • You would not be able to easily modify the "ParameterType" information - e.g. to change the ParameterType.name would mean changing the mapping of the entire index, or adding an alias for the field which would need very specific logic compared to the rest of the functionality
      • +
      +
    • +
    +
  • +
+

Viktor - Search API (& DataGateway API)

+
    +
  • flask based REST API (python)
  • +
  • fetched data in ICAT either via python-icat or via a database (latter only for testing)
  • +
  • Designed for use with DataGateway
  • +
  • Requires authentication (ICAT session ID)
  • +
  • Search API +
      +
    • allows access public data from ICAT catalogues
    • +
    • designed to be integrated in the EOSC (european open science cloud)
    • +
    +
  • +
  • because we could reuse dg-api logic to make search api, they live in the same codebase
  • +
  • allows searching documents, datasets and instruments but can include some other entities
  • +
  • uses loopback REST query filters +
      +
    • easy for those using loopback and node
    • +
    • no python equivalent
    • +
    +
  • +
  • search-api entities don't map exactly to ICAT entities +
      +
    • so have configurable JSON mapping file
    • +
    +
  • +
  • codebase has two APIs +
      +
    • each one can be configured to be on or off, so can choose to just run one or both
    • +
    +
  • +
  • endpoints are separate
  • +
  • separate swagger documents
  • +
+

recent work

+
    +
  • JSON config -> YAML config
  • +
  • ICAT 5 work
  • +
  • updated test data generator script
  • +
  • increased test coverage for DB
  • +
  • Support for scoring Search API results +
      +
    • waiting on PaNOSC search component to update to work with larger datasets (10000 investigaitons)
    • +
    • uses RAM to process data
    • +
    • this is the only thing blocking ISIS results going into PaN portal
    • +
    +
  • +
  • app has now been dockerised +
      +
    • in a branch still right now
    • +
    +
  • +
+

future work

+
    +
  • general technical debt maintenance work (package updates, updating documentation, dropping old python versions)
  • +
+

Rolf: python 3.6, some effort required as in his docker image it's the default python version +Alex: do you think we should add authentication to the PaNOSC search API? yeah but it's not up to us! currently users need to either only use open data with panosc search API or use facility specific APIs

+

Rolf: Link ICAT with a Keycloak SSO

+
    +
  • OpenID Connect authz code flow +
      +
    • 4 actors: +
        +
      • user
      • +
      • frontend / service provider
      • +
      • SSO / identity provider
      • +
      • backend / resource
      • +
      +
    • +
    +
      +
    1. user makes request to service
    2. +
    3. service redirects to sso
    4. +
    5. user authenticates with sso
    6. +
    7. sso redirects back to service
    8. +
    9. services gets access token from SSO
    10. +
    11. service access resource on behalf on user
    12. +
    13. service yields some result (success or unsuccess login)
    14. +
    +
  • +
+

all the time, the redirects have some sort of URL parameter (path param or query param e.g.)

+
    +
  • +

    for implentation, you need:

    +
      +
    • keycloak
    • +
    • OpenID connect client +
        +
      • ideally use a 3rd party solution +
          +
        • e.g. mod_auth_openidc (apache)
        • +
        +
      • +
      +
    • +
    • login to ICAT: +
        +
      • authn.oidc
      • +
      • takes a single credential key: token (openID connect access token)
      • +
      +
    • +
    • tiny webservice script to do the ICAT login for TopCAT (or other frontend?)
    • +
    +
  • +
  • +

    Keycloak config

    +
      +
    • Create client, access type Confidential
    • +
    • Configure redirect urls (will only redirect to known urls)
    • +
    • Copy keycloak's random secret to apache config
    • +
    • Optionally create mapping between token and (ICAT) user
    • +
    +
  • +
  • +

    Apache config

    +
      +
    • load mod_auth_openidc
    • +
    • standard apache config stuff - see docs
    • +
    • then need a path that has authtype oidc
    • +
    • apache then does all steps 1-5 and leaves the token in the request environment
    • +
    • so webserver script just needs to take that token
    • +
    +
  • +
  • +

    ICAT config - install authn.oidc

    +
  • +
  • +

    TopCAT login script

    +
      +
    • takes the token from the apache environment
    • +
    • logs into ICAT for you
    • +
    • place the session token into browser localstorage
    • +
    • go back to frontend page you wanted
    • +
    +
  • +
+

Keycloack demo:

+
    +
  • Define ICAT client in Keycloak
  • +
  • Maintains user attributes, which can be asociated with the access token
  • +
  • Use with Topcat - demonstrates that this is possible for a frontend that was never intended for OIDC +
      +
    • Add arbitrary button to login page, that redirects to above login script
    • +
    +
  • +
  • ORCID support +
      +
    • Opens up sign in with institution (HZB)
    • +
    • Back to SSO, do not have an account so need to register
    • +
    +
  • +
  • Topcat does not show a user name in the UI +
      +
    • This is as intended, since just because I have ORCID doesn't mean I have an ICAT presence
    • +
    +
  • +
  • User appears in Keycloak
  • +
  • Manually associate the user with an ICAT user name
  • +
  • Login again and now have a username display in the UI
  • +
  • Ideally, you would use the single sign on for everything, so would submit the proposal etc. with the SSO +
      +
    • For the demo, have to manually assocaite
    • +
    • Can associate via the email address - this assumes the same person
    • +
    +
  • +
+

Open Discussions

+

Samples

+
    +
  • sample description = historical record
  • +
  • most samples are created @ facility for the experiment
  • +
  • sample prep & characterisation create data or logbook entries
  • +
  • if everything is FAIR and linked, that's the best sample description
  • +
  • concentrate right now on collecting & combining what info we already have
  • +
  • sample PID for linking the info together
  • +
  • ontology or controlled vocab for sample types might still be usefull
  • +
  • IGSN (intl generic sample number) - sample PID?
  • +
  • IGSNs are regular DOIs
  • +
  • dedicated prefix for IGSNs
  • +
  • facility sample DB
  • +
  • many parts of facility workflow need sample info +
      +
    • this could also provide IGSN lanidng pages
    • +
    +
  • +
  • API for registering samples
  • +
  • prototype as separate DB first? maybe integrate into ICAT later
  • +
  • link from sample DB to sample table in ICAT +
      +
    • ICAT could handle authorisation?
    • +
    +
  • +
  • can use local DB ids for DOI suffix, means we know what the DOI will be before minting
  • +
+

Steve: was thinking more about sample types, when users give safety info, sample name given is not expected to mean anything outside the proposal. need better, globally meaningful names. Don't expect ICAT to solve this, ICAT will just follow the relevant schema.

+

Rolf: ontology might only apply to subset of samples. e.g. chemical formulae - not relevant for a battery or a tooth! need a coarse ontology for types.

+
    +
  • For reference, currently in the ICAT schema molecular formula is required for SampleType, but a Sample doesn't need to have a SampleType defined
  • +
+

Bioinformatics have well defined ontology for their samples: https://www.ebi.ac.uk/biosamples/

+
    +
  • relationships between samples is also a factor here: this sample comes from this other sample
  • +
+

Does it make sense for each science area to have its own ontology?

+

Agreement that we should not be "inventing" this ourselves.

+

Rolf: coarse definitions are desirable and good place to start, e.g.:

+
    +
  • inorganic crystal
  • +
  • artifact
  • +
  • protein
  • +
  • ...
  • +
+

This also needs relationships (child/parents?) between SampleTypes

+

RDA: https://www.rd-alliance.org/groups/physical-samples-and-collections-research-data-ecosystem-ig

+
    +
  • Rolf to get in contact next week
  • +
+

Stars project? Not too much activity

+

DAPHNE - DAta from PHoton and Neutron Experiments for NFDI (German National Research Data Infrastructure)

+

Steve: we have Sample information, but not SampleType information - these are separate

+

Rolf: need to link the Sample

+

Using the Sample information?

+
    +
  • WHo is is the user? +
      +
    • The person making the measurement - assume they are happy with their own book-keeping but presumably would benefit from having some of their work handled by ICAT
    • +
    • The data we have now is only useful for these people
    • +
    +
  • +
  • User of the data +
      +
    • Close to no information to this user
    • +
    +
  • +
  • Safety assessment has been well documented (from proposal), but this doesn't currently consider individual samples +
      +
    • E.G. quantity of the Sample is important as well
    • +
    • Sample PID could facilitate this - each sample is of this type but has it's own history with position, temperature etc.
    • +
    • DLS have separate assesment for the experiment (from the Sample) itself (this would cover beamline safety)
    • +
    • We already have this information, just needs to be formalised
    • +
    • Do we need to add a field to Sample table
    • +
    • This kind of question can be answered by a "prototype" DB outside of ICAT (as proposed early)
    • +
    +
  • +
+

Digital leaps survey - for the facilities to fill out but results could be of interest

+

Actions:

+
    +
  • SampleType classifications +
      +
    • Study of what already exists
    • +
    • Collect lists that we already have in proposal Systems (especially for safety as this is most likely formalised)
    • +
    • Ideally this ontology is used by the User Office, and the ontology can represent everything at the Facility
    • +
    +
  • +
  • Individual Sample DBs +
      +
    • Not every facility may be interested in this - deal with case by case?
    • +
    +
  • +
+

Conclusions

+

Notes will be uploaded to the website. +Will discuss further at next collaboration meetings on the 25th of May, as a follow up. Chair and scribe will be assigned in advance or at the meeting. +Roadmap is not complete but important components were covered. +E-Logbook - was evaluated as part of ICAT+ for DDS project.

+
    +
  • One issue with Datahub/logbook is it was hardcoded for ESRF needs - work needed to make it configurable.
  • +
  • HZB had someone working on it two years ago but person left (some adaptations made), want to bring it up to date
  • +
+ + \ No newline at end of file diff --git a/collaboration/communication/face-to-face-meetings/2023-berlin/2023-berlin-roadmap-notes/index.html b/collaboration/communication/face-to-face-meetings/2023-berlin/2023-berlin-roadmap-notes/index.html new file mode 100644 index 000000000..5f778e4d4 --- /dev/null +++ b/collaboration/communication/face-to-face-meetings/2023-berlin/2023-berlin-roadmap-notes/index.html @@ -0,0 +1,540 @@ +ICAT roadmap | ICAT Project

ICAT Project

Search

ICAT roadmap

:::info +:bulb:This template is a product roadmap template that helps you finish the product roadmap. +:::

+

:ballot_box_with_check: ICAT project

+

:::success +Describe the product you want to create a roadmap. +:::

+

:calendar: STFC ICAT roadmap

+
    +
  • DataGateway +
      +
    • release progress bar for retrievals
    • +
    • release search improvements
    • +
    • complete UI for data upload
    • +
    +
  • +
  • Diamond Data Store +
      +
    • data publications work
    • +
    • data upload work
    • +
    +
  • +
  • ISIS +
      +
    • metadata already available via B2FIND
    • +
    • follow-up to make metadata available in the PaN portal
    • +
    +
  • +
  • EPAC data pipeline
  • +
  • Improvements to deployment - work on containerisation and orchestration
  • +
  • Requirements gathering for a Dashboard +
      +
    • download statistics - issues around keeping track if the download was successful
    • +
    • IRUS/COUNTER (solution from eData and ePubs)
    • +
    +
  • +
+

:calendar: ESRF ICAT roadmap

+
    +
  • UX review of data hub to make it more user friendly +
      +
    • automatic anonymous login
    • +
    +
  • +
  • Modularisation of the UI/DataHub using monorepo approach
  • +
  • Trigger data analysis from DataHub (using VISA)
  • +
  • new techniques cryo-ET, paleontology - building specific front-ends +
      +
    • micro-front ends for new techniques
    • +
    +
  • +
  • improve search using possibly what STFC developed
  • +
  • sample tracking - second version
  • +
  • dashboard - based on elasticsearch/ICAT+
  • +
  • help other users coming in the collaboration +
      +
    • help update website etc.
    • +
    +
  • +
  • sort out etherpad complaints +
      +
    • Pads being corrupted, possibly due to an EP plugin
    • +
    +
  • +
  • improve PDF export in e-logbooks
  • +
+

:calendar: HZB ICAT roadmap

+
    +
  • integration with B2FIND: OAI-PMH endpoint is already available and they have it ingested in the demo site
  • +
  • search-api - work on the data model mapping +
      +
    • integrate onto PaN portal
    • +
    • need to rework PaNOSC data model
    • +
    +
  • +
  • Handles, rework prototype
  • +
  • Experimental storage standardisation?
  • +
  • SSO
  • +
  • Using Datahub just for e-logbook functionality +
      +
    • Time stamped event based
    • +
    • Not many users, but some really rely on it
    • +
    • Both user events and machine events
    • +
    • Can this be made into a standard (core?) ICAT component?
    • +
    • interested in export in machine-readable form - exchange format for logbooks
    • +
    • persistent storage for e-logbooks
    • +
    +
  • +
  • Decide new web frontend to replace TopCAT
  • +
  • Create a web formular for data publications
  • +
  • Sample database and PIDs
  • +
+

:calendar: ALBA ICAT roadmap

+
    +
  • ICAT modules ready for publication - 2 beamlines at the moment, want to extend to more beamlines (e.g. Lorea - new beamline)
  • +
  • Working on deploying all ICAT components in Kubernetes
  • +
  • Ingester - Upgrading our current ingester to use the new data model from our new User Office application
  • +
  • Two-level storage - New tape archiving system and working on the storage plugin
  • +
  • Search API and scoring service deployed
  • +
  • Replace authentication plugin with keycloak
  • +
+

:calendar: SESAME ICAT roadmap

+
    +
  • Use the latest ICAT version
  • +
  • Integrate short term storage
  • +
  • Enhance in-house scripts for ingestion
  • +
+

:calendar: Sirius ICAT roadmap

+
    +
  • Use of ICAT in development mode;
  • +
  • Integration of ICAT with the Assonant, an in-house solution for collecting and standardizing data from beamlines;
  • +
  • Integration of ICAT with the User Office system;
  • +
  • Contribute with feedback regarding the project documentation and instruction for building environments for development and production.
  • +
+

:calendar: ICAT components roadmap

+

Planned discussions

+
    +
  • ESRF UX expert - presentation on micro-front-ends, mono-repos, etc
  • +
  • Logbooks etherpad
  • +
  • DataGateway vs DataHub presentation to HZB
  • +
  • E-logbooks for a core component?
  • +
+

:::success +Roadmap discussed in 2020 available here +:::

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Component or productStatusRoadmapESRFSTFCDLSISISHZBALBASESAMESirius
icat.serverstableICAT 5 was released, we need to consider changes for payara 6, plan ICAT 7 to include new schema changes
icat.authstable - dependabot PR open will be reviewd by Rolf, payara6 branch ready, refactor to create a base class and avoid code duplication
ids.serverstable, will need refactoring, currently v1.12
python scriptsstablenow in python3
topcatfrozenrecommendation is to use DataHub or DataGateway
python-icatstable1.0 was released, two minor issues open, HZB will look into a 1.1 release
oai-pmhstable but refactoring suggestednot high priority, would be nice to provide mapping to DCAT, schema extensions (e.g. technique) not yet available, possible to include as part of OSCARS project (ESRF), considering moving to third-party library
search-api
java-ee container / payara
icat+
dataportal
elogbook
icat.lucene
datagateway
scigateway
datagateway
datagateway-api
icat-manager
website
documentation
starter guide
website microservices/micro-front-end
+

:heavy_check_mark: Q1

+
    +
  • Product ideation
  • +
  • Related product research
  • +
  • Marketing
  • +
+

:heavy_check_mark: Q2

+
    +
  • Product ideation
  • +
  • Product Concept
  • +
+

:heavy_check_mark: Q3

+
    +
  • Product Testing
  • +
  • Marketing analysis
  • +
+

:heavy_check_mark: Q4

+
    +
  • Product Release
  • +
  • Marketing analysis
  • +
+

:calendar: Team Schedule

+

:::success +Assign work to different teams. You can refer to the example table to complete yours. +:::

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
QuarterTargetContentTeam
Q1Product ideationA
Q1Related product researchB
Q1MarketingC
Q2Product ideationA
Q2Product conceptB
Q3Product testingC
Q3Marketing analysisA
Q4Product releaseB
Q4Marketing analysisC
+

Roadmap Overview

+

:::success +To overview the achievement in the previous quarters. Share the link here. +:::

+
+ + \ No newline at end of file diff --git a/collaboration/communication/face-to-face-meetings/2023-berlin/index.html b/collaboration/communication/face-to-face-meetings/2023-berlin/index.html new file mode 100644 index 000000000..528c9cfd3 --- /dev/null +++ b/collaboration/communication/face-to-face-meetings/2023-berlin/index.html @@ -0,0 +1,63 @@ +Berlin 2023 | ICAT Project

ICAT Project

Search

Berlin 2023

ICAT F2F Meeting – Berlin – 3rd and 4th May 2023

+

See also:

+ +Attendees of the 2023 ICAT F2F in Berlin +

Agenda

+

Processed Data (Wednesday, 3rd May, 09:30)

+ +

Metadata in ICAT (Experiment Parameters, Samples) (Wednesday, 3rd May, 11:00)

+ +

Performance Issues (Wednesday, 3rd May, 13:00)

+ +

Front-End (Wednesday, 3rd May, 14:30)

+ +

Community Engagement (Wednesday, 3rd May, 16:30)

+ +

ICAT Roadmap (Thursday, 4th May, 09:00)

+

Container and Orchestration, Packaging (Thursday, 4th May, 10:30)

+ +

Misc techbits (Thursday, 4th May, 13:00)

+ +

Open Discussion, Conclusion (Thursday, 4th May, 15:00)

+
+ + \ No newline at end of file diff --git a/collaboration/communication/face-to-face-meetings/copenhagen-2016/index.html b/collaboration/communication/face-to-face-meetings/copenhagen-2016/index.html new file mode 100644 index 000000000..d157bd4b5 --- /dev/null +++ b/collaboration/communication/face-to-face-meetings/copenhagen-2016/index.html @@ -0,0 +1,86 @@ +ICAT F2F at NOBUGS 2016, Copenhagen | ICAT Project

ICAT Project

Search

ICAT F2F at NOBUGS 2016, Copenhagen

+ + + + Attendees of the 2016 ICAT F2F in Copenhagen + + +
Attendees of the 2016 ICAT F2F in Copenhagen
+

+

The talks given are listed below...

+ +

Site reports

+
    +
  • ORNL -- Peter Parker
  • +
  • ISIS -- Tom Gowland
  • +
  • DLS -- Sylvie da Graca
  • +
  • CLF -- Kevin Phipps
  • +
  • Octopus -- Brian Ritchie
  • +
  • ESRF -- Alex de Maria
  • +
  • HZB -- Rolf Krahl
  • +
+

The Roadmap

+
+ + \ No newline at end of file diff --git a/collaboration/communication/face-to-face-meetings/dls-2015/index.html b/collaboration/communication/face-to-face-meetings/dls-2015/index.html new file mode 100644 index 000000000..ae50a3650 --- /dev/null +++ b/collaboration/communication/face-to-face-meetings/dls-2015/index.html @@ -0,0 +1,89 @@ +DLS 2015 | ICAT Project

ICAT Project

Search

DLS 2015

The 2015 Collaboration and Steering Group meetings were held at Diamond +House, HSIC, Didcot, Oxfordshire, OX11 0DE, UK  on the 31st March and +the 1st April 2015.

+

Talks

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
WhatWho
Status of components – ICATSteve Fisher
Status of components – ICAT ManagerChristophe Cleva
Status of components – IDS Steve Fisher
Status of components – TopCAT Wayne Chung
Status of components – python-icat Rolf Krahl
What is ISPyB Solange Delageniere
Ideas for interworking with ISPyB Alun Ashton
Response to PanData report Steve Fisher
Status of components – IJP Brian Ritchie
Defining, managing and extracting icat metadata to hdf5 files Christophe Cleva
Autoreduction at ISIS Marcus Noble
IDS – ideas for data delivery Steve Fisher
IDS – ideas Rolf Krahl
Roadmap Steve Fisher
+

Discussion on the Roadmap:

+
    +
  • Documentation should include best practices
  • +
  • Concerning the suggested move to Github it was pointed out that +links to external repositories would always be needed
  • +
  • It was suggested that a reporting tool summarising statistics on the +data held in ICAT and its use (derived from the logs) would be +useful.
  • +
  • The icatproject.org website should include list of facilties using +ICAT and a catalogue of all known "serious" ICATs partly to attract +new users to ICAT.
  • +
+ + \ No newline at end of file diff --git a/collaboration/communication/face-to-face-meetings/dublin-2014/index.html b/collaboration/communication/face-to-face-meetings/dublin-2014/index.html new file mode 100644 index 000000000..a612103dc --- /dev/null +++ b/collaboration/communication/face-to-face-meetings/dublin-2014/index.html @@ -0,0 +1,81 @@ +Dublin 2014 | ICAT Project

ICAT Project

Search

Dublin 2014

Dublin Meeting, Trinity College Dublin, March 2014

+

Presentations

+

ICAT collaboration and its governance – Brian Matthews

+

Site reports

+

DESY – Frank Shluenzen

+

DLS – Alun Ashton (presented by Tom Griffin)

+

Elettra – Milan Prica

+

ESRF – Alistair Mills

+

HZB – Rolf Krahl

+

ISIS – Tom Griffin

+

SNS – Shelly Ren

+

ALBA – Daniel Salvat

+

Presentations

+

python-icat – a library for writing ICAT clients in Python – Rolf Krahl

+

A domain specific ICAT GUI – Tom Griffin

+

ISIS authz Rules -Tom Griffin

+

Authz rules – Rolf Krahl

+

Mantid and ICAT – Jay Rainey

+

IRO Viewer – Brian Matthews

+

IJP for LSF –  Steve Fisher

+

Experience of the ICAT API and Documentation – Jay Rainey

+

J2EE containers – Steve Fisher

+

Status and Roadmap

+

ICAT Core, IDS and IJP – Steve Fisher

+

TopCAT – Wayne Chung

+

Observations

+
    +
  • +

    A good and constructive meeting

    +
  • +
  • +

    Tom's domain specific GUI looks very promising

    +
  • +
  • +

    Jay liked the speed and simplicity of ICAT4.3 compared to ICAT 3 but +requested some  clarifications to the documentation

    +
  • +
  • +

    Very few people have actually used the ICAT API.

    +
  • +
  • +

    Rolf's suggestion to add an InvestigationGroup was interesting and +will de discussed further on the icatgroup list before deciding +whether or not to accept it.

    +
  • +
  • +

    There was not much enthusiasm for trying other J2EE containers at +the moment.

    +
  • +
  • +

    The Status and Roadmap presentations were accepted but:

    +
      +
    1. There was no interest in changing the getAPIVersion() to have a +more sensible name.
    2. +
    3. The config operation of the setup scripts should be preserved +though should not be required.
    4. +
    5. There was concern that the Lucene index was a single point of +failure in a multi-ICAT setup – it was also pointed out that it +could require a lot of memory.
    6. +
    7. The federation part of TopCAT was considered to be essential by +a significant number of people – so multi-ICAT searches will be +kept.
    8. +
    +
  • +
  • +

    It was suggested that an existing abstraction of a job system +should be used when generalising the IJP. In factthe only one +I found was BLAH +of which I was aware but had forgotten.

    +
  • +
  • +

    Many thanks to John Walsh and TCD for the organisation.

    +
  • +
+ + \ No newline at end of file diff --git a/collaboration/communication/face-to-face-meetings/esrf-2020/index.html b/collaboration/communication/face-to-face-meetings/esrf-2020/index.html new file mode 100644 index 000000000..14985e157 --- /dev/null +++ b/collaboration/communication/face-to-face-meetings/esrf-2020/index.html @@ -0,0 +1,20 @@ +ESRF 2020 | ICAT Project

ICAT Project

Search

ESRF 2020

The 2020 face-2-face meeting for developers and users of the ICAT metadata catalogue took place at the European Synchrotron Radiation Facility (ESRF) on 10th and 11th March 2020. The latests developments around ICAT and ICAT+ from sites using ICAT were discussed at the meeting. Topics to be covered included:

+
- data portal(s) to replace topcat
+- the electronic logbook,
+- the OAI-PMH interface
+- elasticsearch for searching
+- the common API for PaNOSC and ExPaNDS
+
+

Timetable

+

The timetable of the meeting is on the ESRF indico website.

+

Collaborative Notes

+

Collaborative notes were taken using Google Docs at: http://bit.ly/icatf2f2020.

+

News Article

+

Stuart Pullinger wrote a news article about the F2F meeting highlighting the topics covered as well as how to collaborate across borders and minimising environmental impact.

+ + \ No newline at end of file diff --git a/collaboration/communication/face-to-face-meetings/grenoble-2012/index.html b/collaboration/communication/face-to-face-meetings/grenoble-2012/index.html new file mode 100644 index 000000000..34151d7e6 --- /dev/null +++ b/collaboration/communication/face-to-face-meetings/grenoble-2012/index.html @@ -0,0 +1,166 @@ +Grenoble 2012 | ICAT Project

ICAT Project

Search

Grenoble 2012

4th ICAT Workshop – Grenoble – 20th March 2012

+

The purpose  was to  discuss plans for the development and use of ICAT +at facilities and by projects such as PaN-Data and CRISP.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Start TimeSubjectTime (mins)Speaker
09:00Welcome and introductions15Jean-François
09:15TopCAT30Alistair/Kevin/Antony
09:45Organisation and structure of the ICAT project team10Alistair
10:00ILL Status05Jean-François
10:05CLF Status05Alistair
10:10DLS Status05Ghita
10:15LSF Status05Kevin
10:20Elettra Status05Milan
10:25ISIS Status05Tom
10:30SNS Status05Shelley
10:35ESRF Status05Dominique
10:40PSI Status05Heinz-Joseph
10:45Soleil Status05Chado
10:50ALBA Status05Daniel
10:55DESY Status05Thorsten
11:00Technical presentation of the functionalities and the roadmap; ICAT 4.160Steve/ Alistair
  13:30CRISP Status10Jean-François
13:40PANDATA WP3 -- User Catalogue and AA Service10Heinz-Joseph
13:50PANDATA WP4 -- Data Catalogue Service10Milan
14:00PANDATA WP5 -- Virtual Laboratories10Thorsten
14:10PANDATA WP6 -- Provenance10Steve
14:20PANDATA WP7 -- Preservation10Jean-François
14:45Collaboration between the ICAT team  PanData75All
16:30Technical clinic60Harjinder/ Kevin
+ + \ No newline at end of file diff --git a/collaboration/communication/face-to-face-meetings/icat-workshop-at-nobugs2012/index.html b/collaboration/communication/face-to-face-meetings/icat-workshop-at-nobugs2012/index.html new file mode 100644 index 000000000..69ce51f8e --- /dev/null +++ b/collaboration/communication/face-to-face-meetings/icat-workshop-at-nobugs2012/index.html @@ -0,0 +1,54 @@ +ICAT Workshop at NOBUGS2012 | ICAT Project

ICAT Project

Search

ICAT Workshop at NOBUGS2012

+ + \ No newline at end of file diff --git a/collaboration/communication/face-to-face-meetings/index.html b/collaboration/communication/face-to-face-meetings/index.html new file mode 100644 index 000000000..fb234f978 --- /dev/null +++ b/collaboration/communication/face-to-face-meetings/index.html @@ -0,0 +1,17 @@ +Face to face meetings | ICAT Project

ICAT Project

Search

Face to face meetings

+ + \ No newline at end of file diff --git a/collaboration/communication/face-to-face-meetings/lund-2013/index.html b/collaboration/communication/face-to-face-meetings/lund-2013/index.html new file mode 100644 index 000000000..365b412d1 --- /dev/null +++ b/collaboration/communication/face-to-face-meetings/lund-2013/index.html @@ -0,0 +1,99 @@ +Lund 2013 | ICAT Project

ICAT Project

Search

Lund 2013

Meeting in Lund in 2013 at MAX V Laboratory

+

Agenda

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Status of the ICAT collaboration project Alistair Mills
RestfulShelly
xml-ingestTom
Nexus ingestShelly
ICAT setupSteve Fisher
icat-xml-clientAlistair
api-examplesAlistair
training materialsAlistair
Alba StatusDaniel
Elettra StatusMilan
ESRF StatusNicola
ILL StatusJamie
ISIS StatusTom
SNS StatusShelly
Technical presentation on TopcatAntony Wilson
Technical presentation on IDSAntony Wilson/ Frazer Barnsley
Technical presentation on ICAT 4.3 plansSteve Fisher
ICAT Job PortalSteve Fisher
AuthenticationHeinz-Josef
WP3 StatusHeinz-Josef
+ + \ No newline at end of file diff --git a/collaboration/communication/face-to-face-meetings/paris-2011/index.html b/collaboration/communication/face-to-face-meetings/paris-2011/index.html new file mode 100644 index 000000000..f718bc641 --- /dev/null +++ b/collaboration/communication/face-to-face-meetings/paris-2011/index.html @@ -0,0 +1,219 @@ +Paris 2011 | ICAT Project

ICAT Project

Search

Paris 2011

Collaboration meeting in Paris 2011

+

Agenda

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
09:45ILLHolger Gebhard
10:00ISIS and TopCATTom Griffin
10:15CLFSteve Fisher
10:40ELETTRAFabio Bonaccorso
11:15Discussion on parameters
13:30Discussion- Reporting in ICAT (usage reporting, scientific stats)
15:30DOIs at STFCTom Griffin
MySQL SupportTom Griffin
15:45I2S2? – Personal ICATBrian Matthews
16:15Discussion- DOIs
+

Headline Discussion Points

+
    +
  • ISIS and ILL to joint release their ICATs ~27th Feb 2007
  • +
  • TopCAT and Mantid as the interface for ISIS. ILL own interface
  • +
  • Central Laser Facility using ICAT to store laser diagnostic data +(not metadata + data)
  • +
  • Parameters – agreement to extend types (string, number, +DateTime? + +int + boolean)
  • +
  • Agreed change to parameter search API (simplification without loss +of power)
  • +
  • 'Reporting': ISIS to add system for 'usage tracking'; ILL interested +in more powerful querying (OLAP cubes?)
  • +
  • Authorisation model: agreement in principle to add groups and +limited rules for instrument scientists
  • +
  • Agreement to remove XMLIngest from main API to (optional) plugin API
  • +
  • Plans for improvement on documentation and error handling
  • +
  • STFC/ISIS will be issuing DOIs to all experiment datasets from 1st +March (ILL interesting in doing the same but longer timescale)
  • +
  • A basic MySQL version of ICAT is being tested
  • +
  • Discussion on whether ICAT is an appropriate solution for storing +some palaeontology datasets at ESRF
  • +
+

Actions Record

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NewDescriptionRespStatusComment
16.00Document the meetingTG/AMDone
16.01Distribute a discussion paper on authorisation modelTG03/2011
16.02Move xmlingest to a separate packageTGicat4
16.03Prepare a road map for icat4TG/SN03/2011
16.04Provide a design for 'management' reporting'JRi/p03/2011
16.05Provide information on BIRT – Business IntelligenceHG03/2011
16.06Review the API documentation and lead/co-ordinate efforts to improveAM/SF03/2011
16.07Provide exemplar documentation of one class in the APISF03/2011
16.08Provide an exemplar of enhancements to the API (parameter searching)SF/AM03/2011
16.09Provide additional exceptions in the APISF/AM03/2011
16.10Provide a discussion paper on the use of DOI with ICATBM/SN03/2011
16.11Extend parameter types to match programming language/NeXus?SF03/2011
+

Attendees

+
    +
  • SP Stephane Poirier – Soleil
  • +
  • TG Tom Griffin – STFC
  • +
  • HG Holger Gebhard – ILL
  • +
  • SF Steve Fisher – STFC
  • +
  • AM Alistair Mills – STFC
  • +
  • HJ Heinz-Joesph Weyer – PSI
  • +
  • FA Freddy Akeroyd – STFC
  • +
  • JR Jessica Robinson – STFC
  • +
  • BM Brian Matthews – STFC
  • +
  • DH Dietmar Herrendorer – HZB
  • +
  • CJ Christian Jung – HZB
  • +
  • JF Jean-François Perin – ILL
  • +
  • JX Jamie ? – ILL
  • +
  • AG Andy Gotz – ESRF
  • +
  • JK Jorg Klora – ALBA
  • +
  • MX Magid ? – Solei
  • +
+

Apologies

+
    +
  • SN Sri Nagella – STFC
  • +
  • RS Richard Sinclair – STFC
  • +
  • FB Fabio Bonnacorso – ELETTRA
  • +
  • RD Roger Downing- STFC
  • +
  • RF Ron Fowler- STFC
  • +
  • GKM Ghita Kouadri Mostefaoui – Diamond
  • +
+ + \ No newline at end of file diff --git a/collaboration/communication/face-to-face-meetings/stfc-2017/index.html b/collaboration/communication/face-to-face-meetings/stfc-2017/index.html new file mode 100644 index 000000000..156280d1b --- /dev/null +++ b/collaboration/communication/face-to-face-meetings/stfc-2017/index.html @@ -0,0 +1,49 @@ +STFC 2017 | ICAT Project

ICAT Project

Search

STFC 2017

ICAT F2F at STFC Rutherford Appleton Laboratory, November 2017

+

Component Updates

+ +

Guest Speakers

+ +

Site Updates

+ +

ICAT Developments at HZB (Rolf Krahl)

+

Schema Changes

+ +

Data Volumes

+ +

Development processes and experiences

+
+ + \ No newline at end of file diff --git a/collaboration/communication/index.html b/collaboration/communication/index.html new file mode 100644 index 000000000..5dc02c6fd --- /dev/null +++ b/collaboration/communication/index.html @@ -0,0 +1,28 @@ +Communication | ICAT Project

ICAT Project

Search

Communication

Communication within the collaboration is by means of three googlegroup +mailing lists, monthly telephone meetings and a face-to-face meeting +about once a year.

+

Mailing lists

+

None of these groups include other groups. They are:

+

icatgroup to which those +interested in ICAT should subscribe. It is used to announce new +releases, for meeting information and for general discussion on ICAT +components.

+

icatproject-support is +for people to post to when seeking support. Anybody can post from within +the project or outside. By subscribing to the list it is expected that +you will attempt to answer support questions. Don't subscribe to ask +questions but to answer them!

+

Monthly Meetings

+

These are normally held on the fourth Thursday of the month at 15:00 UK +time.  See joining instructions and past meetings +and the meetings for +2016.

+

Face-to-face meetings

+

See the face-to-face meetings page for a list of all the face-to-face meetings.

+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2010-meetings/index.html b/collaboration/communication/monthly-meetings/2010-meetings/index.html new file mode 100644 index 000000000..67e73171a --- /dev/null +++ b/collaboration/communication/monthly-meetings/2010-meetings/index.html @@ -0,0 +1,11 @@ +2010 Meetings | ICAT Project

ICAT Project

Search

2010 Meetings

+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2010-meetings/meeting-11-19-november-2010/index.html b/collaboration/communication/monthly-meetings/2010-meetings/meeting-11-19-november-2010/index.html new file mode 100644 index 000000000..0b80e2798 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2010-meetings/meeting-11-19-november-2010/index.html @@ -0,0 +1,59 @@ +Meeting 11 – 19 November 2010 | ICAT Project

ICAT Project

Search

Meeting 11 – 19 November 2010

Actions from ICAT collaboration meeting on 18 November 2010
+11.1 – Alistair Mills – 19 November +2010

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NewDescriptionRespStatusComment
11.01Improve way of capturing documentation/service requests; copy existing requests into Google groupsTGIn progressSoon
11.02Provide requirements for logging/reporting in ICATALLSee 12.05Subsumed by 12.05
11.03Provide ideas for test suiteALLSee 12.06Subsumed by 12.06
11.04Meet again 2nd DecALL
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2010-meetings/meeting-12-1-december-2010/index.html b/collaboration/communication/monthly-meetings/2010-meetings/meeting-12-1-december-2010/index.html new file mode 100644 index 000000000..fe1cba64b --- /dev/null +++ b/collaboration/communication/monthly-meetings/2010-meetings/meeting-12-1-december-2010/index.html @@ -0,0 +1,263 @@ +Meeting 12 – 1 December 2010 | ICAT Project

ICAT Project

Search

Meeting 12 – 1 December 2010

Actions from ICAT collaboration meeting on 01 December 2010
+12.1 – Alistair Mills – 01 December +2010

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NewDescriptionRes*(1)StatusComment*(2)
12.00Document this meetingAMOk.
12.01Take responsibility for Code documentationAMEnd Jan 2011
12.02Take responsibility for Installation documentationSNEnd Jan 2011
12.03Take responsibility for My SQL version of icatRS/AMEnd Jan 2011
12.04Take responsibility for User AuthenticationTGEnd Jan 2011
12.05Take responsibility for ReportingTGEnd Mar 2011
12.06Take responsibility for Test suiteAMEnd Jan 2011
12.07Take responsibility for Application server independence..
12.08Take responsibility for Authorisation/ PermissionsSN/AMEnd Mar 2011
12.09Take responsibility for XML IngestAM/SNEnd Jan 2011
12.10Take responsibility for Data loaderRD/AMEnd Jan 2011
12.11Take responsibility for LoggingSFEnd Jan 2011Note: Transferred to SF
12.12Take responsibility for Admin documentationTGEnd Jan 2011
12.13Take responsibility for direct build and testSNEnd Jan 2011
12.14Take responsibility for surrogate idsTGEnd Jan 2011
12.15Take responsibility for document the parameter searchNCEnd Jan 2011
12.16Take responsibility for API change managementSNEnd Jan 2011
12.17Provide spec of new method for searchNC/HGSoon
12.18Meet again on 16 December 2010 at 1300 GMTAll
+

 

+

*(1) Responsibilities of participants:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PrimarySecondary
TGTom Griffin4
SNSri Nagella41
AMAlistair Mills32
RSRichard Sinclair1
HGHolger Gebhard1
NCNajor Cruz-cruz2
RDRoger Downing1
SFSteve Fisher1
RFRon Fowler
+

 

+

*(2) Comments The dates shown here are the earliest dates when we can +expect to see real progress with the work. The persons responsible will +be expected to provide status on their work at each meeting.

+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2010-meetings/meeting-13-17-december-2010/index.html b/collaboration/communication/monthly-meetings/2010-meetings/meeting-13-17-december-2010/index.html new file mode 100644 index 000000000..0aa5ee9c6 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2010-meetings/meeting-13-17-december-2010/index.html @@ -0,0 +1,258 @@ +Meeting 13 – 17 December 2010 | ICAT Project

ICAT Project

Search

Meeting 13 – 17 December 2010

Actions from ICAT collaboration meeting on 16 December 2010
+13.1 – Alistair Mills – 17 December +2010

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NewDescriptionRes*(1)StatusComment*(2)
13.00Document this meetingAMOk.
13.01Meet again on 6 January 2011 at 1300 GMTAll
+

 

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
UpdatesDescriptionRes*(1)StatusComment*(2)
12.01Take responsibility for Code documentationAMWrite a test for the API which documents the APIEnd Jan 2011
12.02Take responsibility for Installation documentationSNWork has been done on this by Ron – distribute itEnd Jan 2011
12.03Take responsibility for My SQL version of icatRS/AMWork has been done on this by RichardEnd Jan 2011
12.04Take responsibility for User AuthenticationTGNo progressEnd Jan 2011
12.05Take responsibility for ReportingTGLooking at JASPER, BIRT and scientific reports. HG to add to wiki pageEnd Mar 2011
12.06Take responsibility for Test suiteAMThere is a test for xmlingest in progressEnd Jan 2011
12.07Take responsibility for Application server independence.No progress.
12.08Take responsibility for Authorisation/ PermissionsSN/AMNo progressEnd Mar 2011
12.09Take responsibility for XML IngestAM/SNMultiple threading causes 4% failure. Try single threadingEnd Jan 2011
12.10Take responsibility for documenting Data loader (DLS database load)RD/AMChase Roger about thisEnd Jan 2011
12.11Take responsibility for LoggingSFSteve has done some work to consolidate in log4jEnd Jan 2011
12.12Take responsibility for Admin documentationTGAM to provide information about the CLF stored proceduresEnd Jan 2011
12.13Take responsibility for direct build and testSNThis is being tested in the CLF projectEnd Jan 2011
12.14Take responsibility for surrogate idsTGOn goingEnd Jan 2011
12.15Take responsibility for document the parameter searchNCAdd the documentation to the Google SVN and WikiEnd Jan 2011
12.16Take responsibility for API change managementSNNo progressEnd Jan 2011
12.17Provide spec of new method for searchNC/HGComplete. Sri to verifySoon
+

 

+

*(1) Collaborators:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PresentApologies
TG Tom Griffin+
SN Sri Nagella+
AM Alistair Mills+
RS Richard Sinclair+
RD Roger Downing
HG Holger Gebhard+
NC Najor Cruzcruz+
SF Steve Fisher+
RF Ron Fowler+
GKM Ghita Kouadri Mostefaoui+
+

 

+

*(2) Comments The dates shown here are the earliest dates when we can +expect to see real progress with the work. The persons responsible will +be expected to provide status on their work at each meeting.

+
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2011-meetings/index.html b/collaboration/communication/monthly-meetings/2011-meetings/index.html new file mode 100644 index 000000000..6b36f4ebf --- /dev/null +++ b/collaboration/communication/monthly-meetings/2011-meetings/index.html @@ -0,0 +1,20 @@ +2011 Meetings | ICAT Project

ICAT Project

Search

2011 Meetings

+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2011-meetings/meeting-14-7-january-2011/index.html b/collaboration/communication/monthly-meetings/2011-meetings/meeting-14-7-january-2011/index.html new file mode 100644 index 000000000..8df96ac78 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2011-meetings/meeting-14-7-january-2011/index.html @@ -0,0 +1,250 @@ +Meeting 14 – 7 January 2011 | ICAT Project

ICAT Project

Search

Meeting 14 – 7 January 2011

Actions from ICAT collaboration meeting on 6 January 2011
+14.1 – Tom Griffin – 7 January 2011

+

Brief summary of discussions
+– SF suggestion for refactoring of +ParameterSearching?
+– SN fixed test cases for +ParameterSearching?
+– SF asked what was special about CLF XML ingest. TG and SN gave history +of ISIS XML +ingest

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NewDescriptionRes*(1)StatusComment*(2)
14.00Document this meetingTGDone.
14.01Meetings now to be on alternate Thursdays at 1300GMT, starting 20th Jan 2011All
14.02Refactoring of Parameter Methods – SF to circulate changes and reasoningSF
14.03All to feedback on SF’s suggestionsALL
14.04Document difference between CLF and ISIS XML IngestSNNext meeting
+

 

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
UpdatesDescriptionRes*(1)StatusComment*(2)
12.01Take responsibility for Code documentationAMWrite a test for the API which documents the APIEnd Jan 2011
12.02Take responsibility for Installation documentationSNRon still working on thisEnd Jan 2011
12.03Take responsibility for My SQL version of icatRS/AMTG has completed code/app server work. Waiting for RS to resolve SEQUENCE issueEnd Jan 2011
12.04Take responsibility for User AuthenticationTGNo progressEnd Jan 2011
12.05Take responsibility for ReportingTGLooking at JASPER, BIRT and scientific reports. HG to add to wiki pageEnd Mar 2011
12.06Take responsibility for Test suiteAMThere is a test for xmlingest in progressEnd Jan 2011
12.07Take responsibility for Application server independence.No progress.
12.08Take responsibility for Authorisation/ PermissionsSN/AMNo progressEnd Mar 2011
12.09Take responsibility for XML IngestAM/SNMultiple threading causes 4% failure. Try single threading. Failure rate possibly worse than thoughEnd Jan 2011
12.10Take responsibility for documenting Data loader (DLS database load)RD/AMChase Roger about thisEnd Jan 2011
12.11Take responsibility for LoggingSFSteve has documented and made minor code change. SF to investigate SN reported unit test issueEnd Jan 2011
12.12Take responsibility for Admin documentationTGAM to provide information about the CLF stored proceduresEnd Jan 2011
12.13Take responsibility for direct build and testSNThis is being tested in the CLF projectEnd Jan 2011
12.14Take responsibility for surrogate idsTGOn goingEnd Jan 2011
12.15Take responsibility for document the parameter searchNCDocument emailed. All to review (esp. SF)End Jan 2011
12.16Take responsibility for API change managementSNNo progressEnd Jan 2011
+

 

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CompletedDescriptionRes*(1)StatusComment*(2)
12.17Provide spec of new method for searchNC/HGComplete
13.00Document this meetingAMComplete.
13.01Meet again on 6 January 2011 at 1300 GMTComplete
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2011-meetings/meeting-17-17-february-2011/index.html b/collaboration/communication/monthly-meetings/2011-meetings/meeting-17-17-february-2011/index.html new file mode 100644 index 000000000..ca46383d0 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2011-meetings/meeting-17-17-february-2011/index.html @@ -0,0 +1,156 @@ +Meeting 17 – 17 February 2011 | ICAT Project

ICAT Project

Search

Meeting 17 – 17 February 2011

Actions from ICAT collaboration meeting on 17 February 2011
+17.0 – AM, TG – 17 February +2011

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IdDescriptionRes**(1)**Tgt(2)Comment
17.00Document the actionsAMDone
17.01Document the road map for icat4 and distribute for comm.AMDone
17.02Document the collaboration structure and distributeAMDone
17.03Consolidate open actions into ticketsTG03/03
17.04Invite Fabio to give a talk on 24/2 and invite collab.TGDone
+

(1) Collaborators:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameInstitutePresentApologies
TGTom GriffinISIS+
AMAlistair MillsSTFC+
GKMGhita Kouadri MostefaouiDiamond+
FBFabio BonaccorsoELETTRA+
HGHolger GebhardILL+
SFSteve FisherSTFC+
SNSri NagellaSTFC+
RSRichard SinclairSTFC+
RDRoger DowningSTFC+
RFRon FowlerSTFC+
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2011-meetings/meeting-18-3-march-2011/index.html b/collaboration/communication/monthly-meetings/2011-meetings/meeting-18-3-march-2011/index.html new file mode 100644 index 000000000..3387d3a99 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2011-meetings/meeting-18-3-march-2011/index.html @@ -0,0 +1,96 @@ +Meeting 18 – 3 March 2011 | ICAT Project

ICAT Project

Search

Meeting 18 – 3 March 2011

Actions from ICAT collaboration telephone conference on 03 March 2011
+18.1 – Alistair Mills – 3 March +2011

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NewDescriptionRes**(1)**StatusComment(2)
18.00Document the meetingTG/AMDone
18.01Be aware that from 01/2012 ILL may have another ICAT devAllOk
18.02Inform Roger Downing about the CIC ingest performanceAM.
18.03Create a road map for TopCat? 1.1 or TopCat? 2SN.
18.04Provide a paper on rule based authenticationTG.
18.05Update the road map for icat4 and put on GoogleCode? WikiAM.
18.06Update the workpackage description and put on GoogleCode?AM.
+

 

+

(1) Collaborators

+

|| Apologies || + || +

+

| | | | | | +| ---- | ------------------------ | --------- | ------- | | +| init | Name | Institute | Present | | +| TG | Tom Griffin | STFC ISIS | + | | +| HG | Holger Gebhard | ILL | | | +| SF | Steve Fisher | STFC | | | +| AM | Alistair Mills | STFC | + | | +| GKM | Ghita Kouadri Mostefaoui | Diamond | | | +| SN | Sri Nagella | STFC | + | | +| RS | Richard Sinclair | STFC | | | +| RF | Ron Fowler | STFC | | | +| HC | Harjinder Chahal | STFC | + | | +| KP | Kevin Phipps | STFC | | |

+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2011-meetings/meeting-19-31-march-2011/index.html b/collaboration/communication/monthly-meetings/2011-meetings/meeting-19-31-march-2011/index.html new file mode 100644 index 000000000..670788f22 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2011-meetings/meeting-19-31-march-2011/index.html @@ -0,0 +1,73 @@ +Meeting 19 – 31 March 2011 | ICAT Project

ICAT Project

Search

Meeting 19 – 31 March 2011

Actions from ICAT collaboration telephone conference on 03 March 2011
+19.1 – Alistair Mills – 31 March +2011

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NewDescriptionRes**(1)**StatusComment(2)
19.00Document the meetingTG/AMDone
19.01Add REST web service interface to roadmapAMOk
19.02Provide the ISIS TopCat? reqs to Sri for TopCat? roadmapTG.
19.03Update the ICAT roadmap and distributeAMOk
19.04Ticket review at next meetingTG.
19.05Schedule next meeting for WEDNESDAY 13 April 2011TGOk
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2011-meetings/meeting-20-12-may-2011/index.html b/collaboration/communication/monthly-meetings/2011-meetings/meeting-20-12-may-2011/index.html new file mode 100644 index 000000000..207fbb0db --- /dev/null +++ b/collaboration/communication/monthly-meetings/2011-meetings/meeting-20-12-may-2011/index.html @@ -0,0 +1,59 @@ +Meeting 20 – 12 May 2011 | ICAT Project

ICAT Project

Search

Meeting 20 – 12 May 2011

Actions from ICAT collaboration telephone conference on 12 May 2011
+20.1 – Alistair Mills – 12 May +2011

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionRes**(1)**StatusComment
20.00Document the meetingAMDone
20.01Provide feedback to Steve on his authorisation ideasAllDone
20.02Provide feedback to Jessica on her download stats componentAllDone
20.03Arrange the next meeting for 7 July 2011AM/TGDone
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2011-meetings/meeting-21-7-july-2011/index.html b/collaboration/communication/monthly-meetings/2011-meetings/meeting-21-7-july-2011/index.html new file mode 100644 index 000000000..fbbad7a7f --- /dev/null +++ b/collaboration/communication/monthly-meetings/2011-meetings/meeting-21-7-july-2011/index.html @@ -0,0 +1,94 @@ +Meeting 21 – 7 July 2011 | ICAT Project

ICAT Project

Search

Meeting 21 – 7 July 2011

Actions from ICAT collaboration telephone conference on 7 July 2011
+21.1 – Alistair Mills – 7 July +2011

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionRes**(1)**StatusComment
21.00Document the meetingAMDone
21.01Add a note about rule based authentication to googlecodeSF
21.02Review the status of the MySQL version of ICATAW
21.03Review the status of the continuous build of ICATSN
21.04Provide a copy of the documentation on the API to googlecodeKP
21.05Provide an update/demo of BERTHG
21.06Try using the ICAT from the head of the SVN on GooglecodeSO
21.07Arrange the next meeting for 8 September 2011AM/TG
21.08Arrange a meeting of ICAT users at RAL on 22/7 about ICAT4AM/TGDone
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2011-meetings/meeting-22-22-july-2011/index.html b/collaboration/communication/monthly-meetings/2011-meetings/meeting-22-22-july-2011/index.html new file mode 100644 index 000000000..c4979fdc1 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2011-meetings/meeting-22-22-july-2011/index.html @@ -0,0 +1,80 @@ +Meeting 22 – 22 July 2011 | ICAT Project

ICAT Project

Search

Meeting 22 – 22 July 2011

Actions from ICAT collaboration telephone conference on 22 July 2011
+22.1 – Alistair Mills – 22 July +2011

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionRes**(1)**StatusComment
22.00Document the meetingAMDone
22.01Add information about Mariusz work on the examples to wikiAMStarted
22.02Inform AM about the status of the documentation on the APIKPDone
22.03Publish information on the continuous build web siteAM
22.04Provide material for icat3 performance testsTG
22.05Update the roadmap for ICAT4AM
22.06Update the plan for the improvements for XML Ingest for DLSAM
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2011-meetings/meeting-23-8-september-2011/index.html b/collaboration/communication/monthly-meetings/2011-meetings/meeting-23-8-september-2011/index.html new file mode 100644 index 000000000..fc5e75d5e --- /dev/null +++ b/collaboration/communication/monthly-meetings/2011-meetings/meeting-23-8-september-2011/index.html @@ -0,0 +1,123 @@ +Meeting 23 – 8 September 2011 | ICAT Project

ICAT Project

Search

Meeting 23 – 8 September 2011

Actions 23

+

Actions from ICAT collaboration telephone conference on 8 September +2011
+23.1 – Alistair Mills – 8 September +2011

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemSee alsoDescriptionRes**(1)**StatusComment
23.00Document the meetingAMDone
23.0122.02Documentation on API for ICAT3 and ICAT4KPICAT3 – Done
23.0222.03Create location for Jenkins, Sonar and Nexus on icatproject.orgAMDeferred
23.0322.04Performance tests for icat – Discuss with TomAMDone
23.0422.05Discuss the content of ICAT4 – Do this at mtg 24AMDone
23.0521.06Improvements to xmlingest – Discuss with SriAMDone
23.0621.01Rule based authentication – Discuss with SteveAMDone
23.0721.02Deploy a vanilla ICAT4 in a VM, eg projectscott-ppeAMDone
23.0821.03Continuous build – Hudson – projectscott-tst and esctestAMDone
23.0921.04Copy of the documentation of the API of ICAT3 (icatproject.org)AMDone
23.1021.05Update/demo of BIRT – Remind HGAMDone
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2011-meetings/meeting-24-22-september-2011/index.html b/collaboration/communication/monthly-meetings/2011-meetings/meeting-24-22-september-2011/index.html new file mode 100644 index 000000000..b43b927d9 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2011-meetings/meeting-24-22-september-2011/index.html @@ -0,0 +1,217 @@ +Meeting 24 – 22 September 2011 | ICAT Project

ICAT Project

Search

Meeting 24 – 22 September 2011

Actions 24

+

Actions from ICAT collaboration telephone conference on 22 September +2011
+24.1 – Alistair Mills – 22 September +2011

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionRes**(1)**StatusComment
24.00Document the meetingAMDone
24.01Add Ghita, Holger, Shelly and Harjinder to the meeting listAMDone
24.02Write a note for the wiki about the Release criteria for ICAT4AMDone
24.03Write a note for the wiki about the use of Maven with ICAT4AMDone
24.04Test Glassfish 3.11 with ICAT4 and document any alertsAMDone
24.05Update the road map for ICAT 4 and link it to the Release criteriaAMDone
24.06Write a note with estimates of the effort required to release ICAT4AMCancelled
24.07Remind people of the next meeting on 6 OctoberAMDone
24.08Update the ICAT4 roadmapAMDone
+

 

+

(1) Collaborators

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
InitNameInstitutePresentApologies
TGTom GriffinSTFC ISIS+
HGHolger GebhardILL
SFSteve FisherSTFC+
AMAlistair MillsSTFC+
GKMGhita Kouadri MostefaouiDiamond
SNSri NagellaSTFC+
RSRichard SinclairSTFC
RFRon FowlerSTFC
HCHarjinder ChahalSTFC+
KPKevin PhippsSTFC+
SRShelly RenORNL+
GKGeorge KourousiasELLETRA
MPMilan PricaELLETRA
BMBrian MatthewsSTFC
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2011-meetings/meeting-25-3-november-2011/index.html b/collaboration/communication/monthly-meetings/2011-meetings/meeting-25-3-november-2011/index.html new file mode 100644 index 000000000..5c1cf5281 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2011-meetings/meeting-25-3-november-2011/index.html @@ -0,0 +1,239 @@ +Meeting 25 – 3 November 2011 | ICAT Project

ICAT Project

Search

Meeting 25 – 3 November 2011

Agenda for ICAT collaboration telephone conference on 3 November 2011

+
    +
  • Actions since the meeting on 22 September
  • +
  • Status of ICAT 4 (Alistair)
  • +
  • Representation of time (Steve)
  • +
  • Status of port to MySQL (Alistair)
  • +
  • Resources available in 2012 (All)
  • +
  • Progress on evaluation of ICAT4 (Steve)
  • +
  • Possibility of adding a .props file for configuration
  • +
  • Brief thoughts on adding notification
  • +
  • BMT rather than CMT (Steve)
  • +
  • Status of ICAT work at ILL (J-F)
  • +
  • Status of ICAT work at ORNL (SR)
  • +
+

 

+

Actions 25

+

Actions from ICAT collaboration telephone conference on 3 November +2011
+25.1 – Alistair Mills – 3 November +2011

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionRes**(1)**StatusComment
25.00Document the meetingAMDone
25.01Follow up on actions 24.04 and 24.06AMDone
25.02Follow up on action 24.03 (Use of Maven for building ICAT4)SFDone
25.03Attempt to do ICAT 3 to ICAT 4 upgrade using an ISIS testbedTG.
25.04Attempt to do ICAT 3 to ICAT 4 upgrade using an ILL testbedJ-F.
25.05Discuss the GF 3.1.1 problemAM/SRDone
25.06Investigate ways to represent time to suit the dataSF/RS.
25.07Add a properties file to ICAT4SFDone
25.08Experiment with Bean Managed Transactions for ICAT 4.1SFDone
25.09Send comments on the changes to the ICAT API to SteveAllDone
25.10Provide a document about notificationSFDone
25.11Add fields for STARTTIME and ENDTIME to DATASET for ICAT 4.0SFDone
25.12Defer further implementation of MySQL with ICAT until ICAT 4.1AMDone
25.13Follow up with Shelly on ORNL requirementsSRDone
25.14Investigate hosting a collaboration meeting at ILL in 1Q2012J-FDone
25.15Schedule next collaboration meeting for 17 November 2011AMDone
+

 

+

(1) Collaborators

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
initNameInstitutePresentApologies
TGTom GriffinSTFC ISIS+
SFSteve FisherSTFC+
AMAlistair MillsSTFC+
HCHarjinder ChahalSTFC+
KPKevin PhippsSTFC+
SRShelly RenORNL+
J-FJean-FrancoisILL+
RSRichard SinclairSTFC
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2011-meetings/meeting-26-17-november-2011/index.html b/collaboration/communication/monthly-meetings/2011-meetings/meeting-26-17-november-2011/index.html new file mode 100644 index 000000000..61277435d --- /dev/null +++ b/collaboration/communication/monthly-meetings/2011-meetings/meeting-26-17-november-2011/index.html @@ -0,0 +1,122 @@ +Meeting 26 – 17 November 2011 | ICAT Project

ICAT Project

Search

Meeting 26 – 17 November 2011

Actions 26

+

26.1 – Alistair Mills – 28 November +2011

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionRes**(1)**StatusComment
26.00Document the meetingAMDone
26.01Provide more information on the usage of ICAT4SF/AMDone
26.02Write a note describing controlling metadata based on IP of clientTGDone
26.03Send pom files for building ICAT4 to SFSRDone
26.04Try maven build with SF’s maven scripts – see 26.03HCDone
26.05Investigate the Facility Unit tests in ICAT4SF/HC.
26.06Add upgrade of logging to icat4 roadmapAMDone
26.07Add IP address to session id in the roadmapAMDone
26.08Provide date for collaboration meeting in Grenoble to SR and othersAMWaiting
26.09Add Milan to the invitation list for the meetingsAMDone
26.10Chase Holger about attending the collaboration meetingsAMDone
+

 

+

Agenda 26

+
    +
  • Actions since the meeting on 3 November
  • +
  • Status of ICAT work at ORNL (SR) +
      +
    • Removal of local maven repository
    • +
    • Facility based unit test: looks like test input data are hard +coded
    • +
    • Reporting and event logging in icat4
    • +
    • IP address gets logged with sessionId? (requested by SNS IT)
    • +
    +
  • +
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2011-meetings/meeting-27-1-december-2011/index.html b/collaboration/communication/monthly-meetings/2011-meetings/meeting-27-1-december-2011/index.html new file mode 100644 index 000000000..f2cceaec1 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2011-meetings/meeting-27-1-december-2011/index.html @@ -0,0 +1,210 @@ +Meeting 27 – 1 December 2011 | ICAT Project

ICAT Project

Search

Meeting 27 – 1 December 2011

Actions 27

+

Actions from ICAT collaboration telephone conference on 1 December +2011
+27.1 – Alistair Mills – 1 December +2011

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionRes**(1)**StatusComment
27.00Document the meetingAMDone
27.01Comment on Tom’s note on adding IP to session id wiki:AnonAccessToMetadata?AllDone
27.02Investigate the packaging of the authentication plugin and a properties fileSFDone
27.03Co-operate with the visitor from Software Sustainability Institute (Steve Crouch)All/AMDone
27.04Prepare the materials for the release of ICAT 4.0All/AMIn progress
27.05Send a note to GKM about the ICAT4 API changes and meet with Ghita and DWGKM/AM/DWDone
27.06Provide release note for ICAT 4.0AMDone
27.07Remove the My Proxy option from ICAT 4.0SFDone
27.08Change get user details method to work in ICAT 4.0SFDone
27.09Alistair and DW to visit Nick Draper re ICAT 4.0 APIAMDone
+

 

+

Attendance 27

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
InitNameInstitutePresentApologies
TGTom GriffinSTFC ISIS+
SFSteve FisherSTFC+
AMAlistair MillsSTFC+
GKMGhita Kouadri MostefaouiDiamond+
HCHarjinder ChahalSTFC+
SRShelly RenORNL+
MPMilan PricaELLETRA+
SCSteve CrouchUniv of Southampton /SSI
DWDavid WebsterUniv of Leeds
KPKevin PhippsSTFC+
+

 

+

Agenda 27

+
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2012-meetings/index.html b/collaboration/communication/monthly-meetings/2012-meetings/index.html new file mode 100644 index 000000000..8f6a4ceba --- /dev/null +++ b/collaboration/communication/monthly-meetings/2012-meetings/index.html @@ -0,0 +1,30 @@ +2012 Meetings | ICAT Project

ICAT Project

Search

2012 Meetings

+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2012-meetings/meeting-28-12-january-2012/index.html b/collaboration/communication/monthly-meetings/2012-meetings/meeting-28-12-january-2012/index.html new file mode 100644 index 000000000..5c67034bf --- /dev/null +++ b/collaboration/communication/monthly-meetings/2012-meetings/meeting-28-12-january-2012/index.html @@ -0,0 +1,215 @@ +Meeting 28 – 12 January 2012 | ICAT Project

ICAT Project

Search

Meeting 28 – 12 January 2012

Actions 28

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionRes**(1)**StatusComment
28.00Document the meetingAMDone
28.01Agree a description of the PanData?/ ICAT collaborationAM/GKDone
28.02Provide a list of requirement for ICAT from PanData?GK.
28.03Prepare a list of PanData? contacts for the ICAT collaboration (1 per partner)GK.
28.04Put discussion of related projects such as Eudat on the agenda for future meetingsAMDone
28.05Comment on Steve’s paper on notificationAllDone
28.06Prepare ICAT 4.0.RC.0 as soon as possible and inform collaborationAMDone
28.07Test ICAT RCs and provide feedbackAllDone
28.08Prepare a road map for ICAT 4.1 for discussion at the next meetingAM.
28.09Send email to Shelly about the meeting in HamburgAMDone
+

 

+

Agenda 28

+ +

Attendance 28

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
InitNameInstitutePresentApologies
TGTom GriffinSTFC ISIS+
SFSteve FisherSTFC+
AMAlistair MillsSTFC+
GKMGhita Kouadri MostefaouiDiamond+
HCHarjinder ChahalSTFC+
SRShelly RenORNL+
MPMilan PricaELLETRA+
GKGeorge KourousiasELLETRA+
KPKevin PhippsSTFC+
SWShaun de WittSTFC+
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2012-meetings/meeting-29-26-january-2012/index.html b/collaboration/communication/monthly-meetings/2012-meetings/meeting-29-26-january-2012/index.html new file mode 100644 index 000000000..cd56c80af --- /dev/null +++ b/collaboration/communication/monthly-meetings/2012-meetings/meeting-29-26-january-2012/index.html @@ -0,0 +1,242 @@ +Meeting 29 – 26 January 2012 | ICAT Project

ICAT Project

Search

Meeting 29 – 26 January 2012

Actions 29

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionRes**(1)**StatusComment
29.00Document the meetingAMDone
29.01Make the release of ICAT 4.0AMDoneIcat40Announcement?
29.02Email Shelly about possible visit to SNSAMDone
29.03Email all about the proposed arrangements for Grenoble on 20/Mar/12TGDoneWorkshopGrenoble2012
29.04Provide a note on the wiki about OIIMPH and ICATSN.
29.05Comment on Steve’s paper on ideas for ICATAllDone
29.06Provide a copy of the report of Steve Crouch when availableAM.SsiExecutiveSummary
29.07Test ICAT 4.0 and provide feedbackAllDone
29.08Create a wiki page for the ICAT 4.1 requirementsAMDoneRequirementsIcat41?
29.09Add requirements for ICAT 4.1 for discussion at the next meetingSW/TG/SR.RequirementsIcat41?
29.10Put a note on the wiki about the use of the ICAT on the InternetHC/AM.Icat40Demonstrator?
29.11Send note to Ghita about the use of ICAT admin for ICAT for DLSSN.
29.12Follow up with George about this meetingAMDone
+

 

+

We could not contact George for the meeting, but he send this report:

+

1. The installation and testing will happen the following weeks as some +key persons were not available these days.

+

2. The date for WP4 +PaNdata? telco +will be announced next week.

+

3. During the WP4 telco we will identify the ICAT responsible for most +facilities. (but I expect to be slow procedure as the WP has just +started).

+

Attendance 29

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
InitNameInstitutePresentApologies
TGTom GriffinSTFC ISIS+
SFSteve FisherSTFC eSc+
AMAlistair MillsSTFC eSc+
GKMGhita Kouadri MostefaouiDiamond+
HCHarjinder ChahalSTFC eSc+
SRShelly RenORNL SNS+
KPKevin PhippsSTFC eSc+
SNSri NagellaSTFC eSc+
SWShaun de WittSTFC eSc (EUDAT)+
MPMilan PricaELLETRA+
GKGeorge KourousiasELLETRA+
+

 

+

Agenda 29

+
    +
  • Actions from the meetings of 12 January
  • +
  • Status of ICAT 4.0
  • +
  • Road map for ICAT 4.1
  • +
  • Collaboration agreement of +PanData? and +ICAT
  • +
  • Meeting in Hamburg
  • +
  • Review of ICAT Collaboration by Software Sustainability Institute
  • +
  • AOB
  • +
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2012-meetings/meeting-30-9-february-2012/index.html b/collaboration/communication/monthly-meetings/2012-meetings/meeting-30-9-february-2012/index.html new file mode 100644 index 000000000..fe8a19d6b --- /dev/null +++ b/collaboration/communication/monthly-meetings/2012-meetings/meeting-30-9-february-2012/index.html @@ -0,0 +1,242 @@ +Meeting 30 – 9 February 2012 | ICAT Project

ICAT Project

Search

Meeting 30 – 9 February 2012

Actions 30

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionRes**(1)**StatusComment
30.00Document the meetingAMDone
30.01Make an announcement about the meeting in GrenobleAMDoneWorkshopGrenoble2012
30.02Contact CRISP project about GrenobleAMDoneSpoke to Jean-Francois
30.03Remind SN about OIIMPHAMDoneSN has nothing to add!
30.04Remind SdeW about Eudat requirements for ICAT 4.1AMDoneRequirementsIcat41#Eudat?
30.05Remind SN about DLS login informationAMDoneCompleted
30.06Distribute Topcat40 for installation with ICAT40AMIn progressAsk Harjinder
30.07Ask for requirements for ICAT 4.1 from CLF, SNS, DLSAMIn progressRequirementsIcat41?
30.08Add requirements for ICAT 4.1 for PANDATAAMDoneRequirementsIcat41#Pandata?
30.09Email collaboration about sample dataAll.
30.10Email TG about requirements for the meeting in GrenobleAllDone
30.11Coordinate arrangements with the contact person at ILL for the workshopTGIn progress
+

 

+

Agenda 30

+
    +
  • Actions from the meetings of 26 January
  • +
  • Status of ICAT 4.0 +(Icat40Announcement?)
  • +
  • Publicly available ICAT 4.0 demonstration system +(Icat40Demonstrator?)
  • +
  • Road map for ICAT 4.1 +(Icat41Roadmap?)
  • +
  • Collaboration agreement of +PanData? and +ICAT +(IcatPandataAgreement?)
  • +
  • Proposal to reduce the number of fields for an Investigation and to +regularise the field and entity names. (Steve)
  • +
  • The Sample, Dataset, Investigation triangle (Steve)
  • +
  • Face to Face Meeting in Grenoble in 2012 +(WorkshopGrenoble2012)
  • +
  • Review of ICAT Collaboration by Software Sustainability Institute +(SsiExecutiveSummary)
  • +
  • AOB
  • +
+

Attendance 30

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
InitNameInstitutePresentApologies
TGTom GriffinSTFC ISIS+
SFSteve FisherSTFC eSc+
AMAlistair MillsSTFC eSc+
BMBrian MatthewsSTFC eSc+
GKMGhita Kouadri MostefaouiDiamond+
HCHarjinder ChahalSTFC eSc+
SRShelly RenORNL SNS+
KPKevin PhippsSTFC eSc+
SWShaun de WittSTFC EUDAT+
MPMilan PricaELLETRA+
GKGeorge KourousiasELLETRA+
AWAntony WilsonSTFC eSc+
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2012-meetings/meeting-31-23-february-2012/index.html b/collaboration/communication/monthly-meetings/2012-meetings/meeting-31-23-february-2012/index.html new file mode 100644 index 000000000..06555bb65 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2012-meetings/meeting-31-23-february-2012/index.html @@ -0,0 +1,175 @@ +Meeting 31 – 23 February 2012 | ICAT Project

ICAT Project

Search

Meeting 31 – 23 February 2012

Actions 31

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionRes**(1)**StatusComment
31.00Document the meetingTGDone
31.01Remind PaN-data meeting about meeting in GrenobleMP/GK/BMDone
31.02Respond to Valerie Duchasténier with your details for Grenoble meetingAllIn progress
31.03Contact Frank about his problems installing ICATHCDone Issue 72 
+

 

+

Agenda 31

+
    +
  • Actions from the meetings of 9 February
  • +
  • Road map for ICAT 4.1 +(Icat41Roadmap?)
  • +
  • Face to Face Meeting in Grenoble in 2012 +(WorkshopGrenoble2012)
  • +
  • Review of ICAT Collaboration by Software Sustainability Institute +(SsiExecutiveSummary)
  • +
  • AOB
  • +
+

Attendance 31

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
InitNameInstitutePresentApologies
TGTom GriffinSTFC ISIS+
SFSteve FisherSTFC eSc+
AMAlistair MillsSTFC eSc+
BMBrian MatthewsSTFC eSc+
GKMGhita Kouadri MostefaouiDiamond+
HCHarjinder ChahalSTFC eSc+
SRShelly RenORNL SNS+
KPKevin PhippsSTFC eSc+
SWShaun de WittSTFC EUDAT+
MPMilan PricaELLETRA+
GKGeorge KourousiasELLETRA+
AWAntony WilsonSTFC eSc+
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2012-meetings/meeting-32-8-march-2012/index.html b/collaboration/communication/monthly-meetings/2012-meetings/meeting-32-8-march-2012/index.html new file mode 100644 index 000000000..8f0924ed6 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2012-meetings/meeting-32-8-march-2012/index.html @@ -0,0 +1,167 @@ +Meeting 32 – 8 March 2012 | ICAT Project

ICAT Project

Search

Meeting 32 – 8 March 2012

Actions 32

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionRes**(1)**StatusComment
32.00Document the meetingTGDone
32.01Review and update the install documentation using feedback from Frank and MilanHJ/AMDone
32.02Consult main ICAT mailing list on proposed schema changesSFDone
32.03Send Ghita link to documents about ICAT changesTGDonehttp://www.icatproject.org/icat.html
+

 

+

Agenda 32

+
    +
  • Actions from the meetings of 23 February
  • +
  • Update from PaN-data meeting (Milan/George)
  • +
  • Face to Face Meeting in Grenoble in 2012 +(WorkshopGrenoble2012)
  • +
  • Revised ICAT schema proposal for 4.1 (Steve’s emails)
  • +
  • Constraints on parameter values (Steve’s email)
  • +
  • AOB
  • +
+

Attendance 32

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
InitNameInstitutePresentApologies
TGTom GriffinSTFC ISIS+
SFSteve FisherSTFC eSc+
AMAlistair MillsSTFC eSc+
BMBrian MatthewsSTFC eSc+
GKMGhita Kouadri MostefaouiDiamond+
HCHarjinder ChahalSTFC eSc+
SRShelly RenORNL SNS+
KPKevin PhippsSTFC eSc+
MPMilan PricaELLETRA+
GKGeorge KourousiasELLETRA+
AWAntony WilsonSTFC eSc+
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2012-meetings/meeting-33-20-march-2012/index.html b/collaboration/communication/monthly-meetings/2012-meetings/meeting-33-20-march-2012/index.html new file mode 100644 index 000000000..9281d517c --- /dev/null +++ b/collaboration/communication/monthly-meetings/2012-meetings/meeting-33-20-march-2012/index.html @@ -0,0 +1,109 @@ +Meeting 33 – 20 March 2012 | ICAT Project

ICAT Project

Search

Meeting 33 – 20 March 2012

This was the face to face meeting in Grenoble. For details, other than +the actions, +see WorkshopGrenoble2012.

+

Actions 33

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionRes**(1)**StatusComment
33.00Document the meetingAMDone
33.01Remove all of the uses of “3” in the APISFDone
33.02Consider the possibility of creating a list of objects in one callSFTicket #73
33.03Consider how to provide a free text search in ICAT 4SFTicket #74
33.04Put Topcat on the client user list for JMS notificationsAWTicket #75
33.05Test that ICAT 4 provides support for ISIS reporting using JMS notificationAMTicket #75
33.06Remove shift user from ICAT 4SFNo action
33.07Provide an early view of innovative features in early releases such as 4.0.1AMOn-going
33.08Data mining tools are required to support CRISPAMAdded to reqsReqsIcat41
33.09Make presentations from this meeting available from the Google Code siteAMDone
33.10Write an email to the participants with the call to actionAMDone
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2012-meetings/meeting-34-5-april-2012/index.html b/collaboration/communication/monthly-meetings/2012-meetings/meeting-34-5-april-2012/index.html new file mode 100644 index 000000000..fbe40bf68 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2012-meetings/meeting-34-5-april-2012/index.html @@ -0,0 +1,202 @@ +Meeting 34 – 5 April 2012 | ICAT Project

ICAT Project

Search

Meeting 34 – 5 April 2012

Agenda 34

+
    +
  • Actions from the meetings of 20 March (Alistair)
  • +
  • Availability of Topcat40 (Alistair)
  • +
  • Update from PaN-data meeting (Milan/George)
  • +
  • Schema changes – the end is in sight? (Steve)
  • +
  • Mailing lists (Alistair)
  • +
  • Open ticket review (Alistair)
  • +
  • Work packages (Alistair)
  • +
  • Digital certificate on www.icatproject.org and other common ICAT +deployments
  • +
+

(Alistair)

+
    +
  • Priorities
  • +
  • AOB
  • +
+

Actions 34

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionRes**(1)**StatusComment
34.00Document the meetingAMDone
34.01Try Topcat40 and provide feedback to HarjinderMP.
34.02Contact Christian Felder about his work on web services python interfaceAMDone
34.04Try Ghita’s plugin for EclipseHC.
34.05Chase people for feedback on sample type and sampleSF.
34.06Try to get a RC for ICAT 4.1 available by 19/4/2012AM/HC.
34.07Add discussion of Ghita’s plugin to next meetingAM/GDADone
34.08....
+

 

+

Attendance 34

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
InitNameInstitutePresentApologies
TGTom GriffinSTFC ISIS+
SFSteve FisherSTFC eSc+
AMAlistair MillsSTFC eSc+
BMBrian MatthewsSTFC eSc+
GKMGhita Kouadri MostefaouiDiamond+
HCHarjinder ChahalSTFC eSc++
SRShelly RenORNL SNS+
KPKevin PhippsSTFC eSc+
MPMilan PricaELETTRA+
GKGeorge KourousiasELETTRA+
AWAntony WilsonSTFC eSc+
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2012-meetings/meeting-35-19-april-2012/index.html b/collaboration/communication/monthly-meetings/2012-meetings/meeting-35-19-april-2012/index.html new file mode 100644 index 000000000..404d8a0e8 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2012-meetings/meeting-35-19-april-2012/index.html @@ -0,0 +1,178 @@ +Meeting 35 – 19 April 2012 | ICAT Project

ICAT Project

Search

Meeting 35 – 19 April 2012

Agenda 35

+
    +
  • Actions from the meetings of 5 April (Alistair)
  • +
  • Demonstration of Eclipse Plugin (Ghita)
  • +
  • Presentation about Python work on ICAT 4 at Julich (Christian)
  • +
  • Availability of Topcat40 (Alistair)
  • +
  • Availability of Jenkins service +on http://www.icatproject.org:6080/jenkins (Alistair)
  • +
  • Update from PaN-data meeting (Milan/George)
  • +
  • ICAT 4.1 – Schema (Steve)
  • +
  • Availability of ICAT41 (Alistair)
  • +
  • AOB
  • +
+

(All)

+

Actions 35

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionRes**(1)**StatusComment
35.00Document the meetingAMDone
35.01Ask Juan to add Alistair to Pandata mailing listsAMDone
35.02Send comments to Milan/George re Deliverable 5.1 of PandataAMSee 36.1
35.03Release Topcat 4.1AMDonewiki:InstallTopcat40?
35.04Consider proposed change to ICAT API to support PythonSFDone
35.05Test deployment of ICAT 4.1 with MySql?AMSee 36.2
35.06Ask ALBA for help with testing ICAT 4.1 using MySql?AMSee 36.3
+

 

+

Attendance 35

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
InitNameInstitutePresentApologies
SFSteve FisherSTFC eSc+
AMAlistair MillsSTFC eSc+
GKMGhita Kouadri MostefaouiDiamond+
HCHarjinder ChahalSTFC eSc+
SRShelly RenORNL SNS+
KPKevin PhippsSTFC eSc+
MPMilan PricaELETTRA+
GKGeorge KourousiasELETTRA+
AWAntony WilsonSTFC eSc+
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2012-meetings/meeting-36-3-may-2012/index.html b/collaboration/communication/monthly-meetings/2012-meetings/meeting-36-3-may-2012/index.html new file mode 100644 index 000000000..cf155e8d2 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2012-meetings/meeting-36-3-may-2012/index.html @@ -0,0 +1,228 @@ +Meeting 36 – 3 May 2012 | ICAT Project

ICAT Project

Search

Meeting 36 – 3 May 2012

Agenda 36

+
    +
  • Actions from the meetings of 19 April (Alistair)
  • +
  • Update from PaN-data (Milan/George)
  • +
  • New participants joining in Grenoble (Tom)
  • +
  • Availability of Mysql support for Topcat40 (Alistair)
  • +
  • ICAT 4.1 – Status (Steve)
  • +
  • Python Client API (Steve)
  • +
  • Availability of release candidate for ICAT41 (Alistair)
  • +
  • Structure of the ‘work packages’ (Tom)
  • +
  • AOB
  • +
+

(Any)

+
+

Actions 36

+
+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionRes**(1)**StatusComment
36.00Document the meetingAMDone
36.01Send comments to Milan/George re Deliverable 5.1 of PandataAMDone
36.02Test deployment of ICAT 4.1 with MySql?AMsee 37.01
36.03Ask ALBA for help with testing ICAT 4.1 using MySql?AMDone
36.04Plan for Pandata meeting in Trieste 27-28/6Allhttps://sites.google.com/site/pandatatrieste
36.05Include Nicolas at ESRF on invitation to collaboration meetingsAMDone
36.06Include email list members in invitation to collaboration meetingsAMDone
36.07Verify that Topcat40 deploys on icat40 as documentedAWDone
36.08Set up a working group to deal with migration of ISIS ICAT to ICAT 4.1AM/TGDone
36.09Email Christian at Julich re Python i/f to icat 4.1AM/SFDone
36.10Add documentation on addMany method to ICAT 4.1 API documentationSFsee 37.02
36.11Add Python interface to the roadmap for ICAT 4.1AMDone
36.12Add new technology eg EVO to the agenda for next meetingAMDeferred
36.13Prepare a topcat41 which is compatible with ICAT 4.1AWsee 37.03
36.14Fix what went wrong with the phone in CR02 at RAL for this meetingAMDone
+

 

+

Attendance 36

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
InitNameInstitutePresentApologies
SFSteve FisherSTFC eSc+
AMAlistair MillsSTFC eSc+
GKMGhita Kouadri MostefaouiDiamond+
HCHarjinder ChahalSTFC eSc+
KPKevin PhippsSTFC eSc+
MPMilan PricaELETTRA+
AWAntony WilsonSTFC eSc+
TGTom GriffinSTFC ISIS Facility+
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2012-meetings/meeting-37-17-may-2012/index.html b/collaboration/communication/monthly-meetings/2012-meetings/meeting-37-17-may-2012/index.html new file mode 100644 index 000000000..87fcc253a --- /dev/null +++ b/collaboration/communication/monthly-meetings/2012-meetings/meeting-37-17-may-2012/index.html @@ -0,0 +1,192 @@ +Meeting 37 – 17 May 2012 | ICAT Project

ICAT Project

Search

Meeting 37 – 17 May 2012

Agenda 37

+
    +
  • Actions from the meetings of 3 May (Alistair)
  • +
  • ICAT Executive Board (IEB) Proposed Terms for the +Board?
  • +
  • Changes to the SVN on +GoogleCode? (Steve)
  • +
  • Update from PaN-data (Milan/George)
  • +
  • ICAT 4.1 – Status (Steve)
  • +
  • Availability of release candidate for ICAT41 (Alistair)efficientyly
  • +
  • Availability of Mysql version of ICAT
  • +
  • AOB
  • +
+

(Any)

+

Actions 37

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionRes**(1)**StatusComment
37.00Document the meetingAMDone
37.01Test deployment of ICAT 4.1 with MySql?AMDone
37.02Add documentation on addMany method to ICAT 4.1 API documentationSFDone
37.03Prepare a topcat41 which is compatible with ICAT 4.1AWAwaiting 4.1
37.04Add pages to the wiki for planning ICAT 4.2AMDoneIcat42Roadmap?, RequirementsIcat42?, Icat42ReleaseCriteria?
37.05Comment on Terms for the Executive BoardAllDoneIcatExecutiveBoard?
37.06Communicate with Shelly about the downloaderAW/SRIn progress
37.07Do initial definition of ICAT 4.2TG/AMIn progressIcat42Roadmap?, RequirementsIcat42?, Icat42ReleaseCriteria?
+

 

+

Attendance 37

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
InitNameInstitutePresentApologies
SFSteve FisherSTFC eSc+
AMAlistair MillsSTFC eSc+
GKMGhita Kouadri MostefaouiDiamond+
HCHarjinder ChahalSTFC eSc+
KPKevin PhippsSTFC eSc+
AWAntony WilsonSTFC eSc+
TGTom GriffinSTFC ISIS Facility+
MPMilan PricaELETTRA+
GKGeorge KourousiasELETTRA+
SRShelly RenORNL SNS+
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2012-meetings/meeting-38-31-may-2012/index.html b/collaboration/communication/monthly-meetings/2012-meetings/meeting-38-31-may-2012/index.html new file mode 100644 index 000000000..1bef8b0f7 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2012-meetings/meeting-38-31-may-2012/index.html @@ -0,0 +1,167 @@ +Meeting 38 – 31 May 2012 | ICAT Project

ICAT Project

Search

Meeting 38 – 31 May 2012

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
InitNameInstitutePresentApologies
SFSteve FisherSTFC eSc+
AMAlistair MillsSTFC eSc+
GKMGhita Kouadri MostefaouiDiamond+
HCHarjinder ChahalSTFC eSc+
KPKevin PhippsSTFC eSc+
AWAntony WilsonSTFC eSc+
TGTom GriffinSTFC ISIS Facility+
MPMilan PricaELETTRA+
GKGeorge KourousiasELETTRA+
SRShelly RenORNL SNS+
+

Agenda 38

+
    +
  • Actions from the meetings of 19 May (Alistair)
  • +
  • ICAT 4.1 – Status (Steve)
  • +
  • Availability of release candidate for ICAT41 including Mysql +(Alistair)
  • +
  • Plans for ICAT 4.2 (Tom)
  • +
  • Deployment of ICAT 4 for DLS (Ghita)
  • +
  • Deployment of ICAT 4 for ISIS (Tom)
  • +
  • Update from PaN-data (Milan/George)
  • +
  • AOB
  • +
+

(Any)

+

Actions 38

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionRes**(1)**StatusComment
38.00Document the meetingAMDone
38.01Send a message to Barcelona asking for help testing ICAT 4.1 RCAMDone
38.02Include Topcat in the responsibilities of the IEBAMDone
38.03ICAT Collaboration is to include discussion of requirements and changes to TopcatAllDone
38.04Send changes to ICAT 4.0 to support SNS to SFSRDone
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2012-meetings/meeting-39-14-june-2012/index.html b/collaboration/communication/monthly-meetings/2012-meetings/meeting-39-14-june-2012/index.html new file mode 100644 index 000000000..618b82795 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2012-meetings/meeting-39-14-june-2012/index.html @@ -0,0 +1,63 @@ +Meeting 39 – 14 June 2012 | ICAT Project

ICAT Project

Search

Meeting 39 – 14 June 2012

Agenda 39

+
    +
  • Actions from the meetings of 31 May (Alistair)
  • +
  • ICAT 4.1 – Status (Steve)
  • +
  • Plans for ICAT 4.2 (Tom)
  • +
  • Update from PaN-data (Milan/George)
  • +
  • Deployment of ICAT 4 for DLS (Ghita)
  • +
  • Deployment of ICAT 4 for ISIS (Tom)
  • +
  • AOB
  • +
+

(Any)

+

Actions 39

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionRes**(1)**StatusComment
39.00Document the meetingAMDone
39.01Distribute TOC/Plan for the Pandata Deliverable WP4.1MPDone
39.02Make an announcement about the availability of ICAT 4.1AMDone
+

 

+

Attendance 39

+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2012-meetings/meeting-40-26-july-2012/index.html b/collaboration/communication/monthly-meetings/2012-meetings/meeting-40-26-july-2012/index.html new file mode 100644 index 000000000..2e1ec23a2 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2012-meetings/meeting-40-26-july-2012/index.html @@ -0,0 +1,171 @@ +Meeting 40 – 26 July 2012 | ICAT Project

ICAT Project

Search

Meeting 40 – 26 July 2012

Agenda 40

+
    +
  • Actions from the meetings of 14 June (Steve)
  • +
  • ICAT 4.1 – Status (Steve)
  • +
  • Plans for ICAT 4.2 (Tom)
  • +
  • Update from PaN-data (Milan/George)
  • +
  • Deployment of ICAT 4.2 for DLS (Ghita)
  • +
  • Deployment of ICAT 4.2 for ISIS (Tom)
  • +
  • Deployment of ICAT 4.1 for CLF (Steve)
  • +
  • AOB
  • +
+

(Any)

+

Actions 40

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionRes**(1)**StatusComment
40.00Document the meetingSMFDone
40.01Investigate XMLIngest with new API – can it be generic?TGOn-going
40.02Organise ICAT presence at NOBUGS and its ICAT workshopTGOn-going
40.03Provide data to Ghita in ICAT 4.1/4.2 formatGKMAssigned to Ghita for the moment to make sure it is not forgotten.
+

 

+

Attendance 40

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
InitNameInstitutePresentApologies
SMFSteve FisherSTFC eSc+
AMAlistair MillsSTFC eSc+
GKMGhita Kouadri MostefaouiDiamond+
HCHarjinder ChahalSTFC eSc+
KPKevin PhippsSTFC eSc+
AWAntony WilsonSTFC eSc+
TGTom GriffinSTFC ISIS Facility+
MPMilan PricaELETTRA
GKGeorge KourousiasELETTRA
SRShelly RenORNL SNS
+

 

+

Notes 40

+

Steve mentioned the timing issue in 4.1

+

Tom indicated that ISIS would like XMLIngest back – but they will modify +it to use the new API efficiently and attempt to make it generic.

+

The purpose and format of the ICAT workshop at NOBUGS was discussed. It +was thought that a tutorial might be useful. Neither Alistair nor Steve +will be present.

+

Ghita would like some data in an ICAT 4.1 to test her eclipse plugin.

+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2012-meetings/meeting-41-9-august-2012/index.html b/collaboration/communication/monthly-meetings/2012-meetings/meeting-41-9-august-2012/index.html new file mode 100644 index 000000000..01627a8f1 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2012-meetings/meeting-41-9-august-2012/index.html @@ -0,0 +1,155 @@ +Meeting 41 – 9 August 2012 | ICAT Project

ICAT Project

Search

Meeting 41 – 9 August 2012

Agenda 41

+
    +
  • Actions from the meeting 40 (Alistair)
  • +
  • ICAT 4.1 – Status (Alistair)
  • +
  • Plans for ICAT 4.3 (Tom)
  • +
  • Update from PaN-data (Milan/George)
  • +
  • Deployment of ICAT 4.3 for DLS (Ghita)
  • +
  • Deployment of ICAT 4.3 for ISIS (Tom)
  • +
  • Deployment of ICAT 4.2 for CLF (Alistair)
  • +
  • AOB
  • +
+

(Any)

+

Actions 41

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionRes**(1)**StatusComment
41.00Document the meetingAMDone
41.01Publish the Nexus ingest to Google/contribSRDone
41.02Call the next meeting on 23 August 2012AMDone
+

 

+

Attendance 41

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
InitNameInstitutePresentApologies
SMFSteve FisherSTFC eSc+
AMAlistair MillsSTFC eSc+
GKMGhita Kouadri MostefaouiDiamond+
HCHarjinder ChahalSTFC eSc+
KPKevin PhippsSTFC eSc+
AWAntony WilsonSTFC eSc+
TGTom GriffinSTFC ISIS Facility+
MPMilan PricaELETTRA+
GKGeorge KourousiasELETTRA
SRShelly RenORNL SNS+
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2012-meetings/meeting-42-23-august-2012/index.html b/collaboration/communication/monthly-meetings/2012-meetings/meeting-42-23-august-2012/index.html new file mode 100644 index 000000000..f2b4a4ae1 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2012-meetings/meeting-42-23-august-2012/index.html @@ -0,0 +1,177 @@ +Meeting 42 – 23 August 2012 | ICAT Project

ICAT Project

Search

Meeting 42 – 23 August 2012

Agenda 42

+
    +
  • Actions from the meeting 41 (Alistair)
  • +
  • Ingest client for ICAT (Tom/ Shelly)
  • +
  • ICAT 4.2 – Status (Steve)
  • +
  • Plans for ICAT 4.3 (Tom)
  • +
  • Update from PaN-data (Milan/George)
  • +
  • Deployment of ICAT 4.3 for DLS (Ghita)
  • +
  • Deployment of ICAT 4.3 for ISIS (Tom)
  • +
  • Deployment of ICAT 4.2 for CLF (Alistair)
  • +
  • AOB
  • +
+

(Any)

+

Actions 42

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionRes**(1)**StatusComment
42.00Document the meetingAMDone
42.01Make an announcement of the availability of ICAT 4.2.0SFDone
42.02Discuss anonymous login and NeXus? ingest clientTG/SRSee action 44.02
42.03Steve to chair the meeting on 6 September, Kevin the meeting on 20/09SF/KPDone
42.04Call the next meeting on 6 September 2012 – to be chaired by SteveAMDone
+

 

+

Attendance 42

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
InitNameInstitutePresentApologies
SMFSteve FisherSTFC eSc+
AMAlistair MillsSTFC eSc+
GKMGhita Kouadri MostefaouiDiamond+
HCHarjinder ChahalSTFC eSc+
KPKevin PhippsSTFC eSc+
AWAntony WilsonSTFC eSc+
TGTom GriffinSTFC ISIS Facility+
MPMilan PricaELETTRA+
GKGeorge KourousiasELETTRA
SRShelly RenORNL SNS+
MGMark GreenTech-X+
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2012-meetings/meeting-43-6-september-2012/index.html b/collaboration/communication/monthly-meetings/2012-meetings/meeting-43-6-september-2012/index.html new file mode 100644 index 000000000..8a503b11e --- /dev/null +++ b/collaboration/communication/monthly-meetings/2012-meetings/meeting-43-6-september-2012/index.html @@ -0,0 +1,89 @@ +Meeting 43 – 6 September 2012 | ICAT Project

ICAT Project

Search

Meeting 43 – 6 September 2012

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionRes**(1)**StatusComment
44.00Document the meetingAMDone
44.01Add notes to the this page about action 42.2SR/AMDone
44.02Ask Christian to put his python work into the contrib directoryAMSee action 45.03
44.03Distribute note about trouble shooting ICAT 4.2.1SFDone
44.04Put a link into this page about the Nobugs materials NOBUGS2012WorkshopAMDone
44.05Provide a copy of the entity diagram for commentNB/SFSee action 45.02
44.06Send an email to SF about the difficulties of building ICAT with EclipseNBDone
+

Agenda 43

+
    +
  • Actions from the meeting 42 (Steve)
  • +
  • Ingest client for ICAT (Tom/ Shelly)
  • +
  • ICAT 4.2 – Status (Steve)
  • +
  • Plans for ICAT 4.3 (Tom)
  • +
  • Update on plans for the ICAT meeting at Nobugs2012 (Kevin)
  • +
  • Update from PaN-data (Milan/George)
  • +
  • Deployment of ICAT 4.3 for DLS (Ghita)
  • +
  • Deployment of ICAT 4.3 for ISIS (Tom)
  • +
  • Deployment of ICAT 4.2 for CLF (Alistair)
  • +
  • AOB (Any)
  • +
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2012-meetings/meeting-44-4-october-2012/index.html b/collaboration/communication/monthly-meetings/2012-meetings/meeting-44-4-october-2012/index.html new file mode 100644 index 000000000..a146c7003 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2012-meetings/meeting-44-4-october-2012/index.html @@ -0,0 +1,178 @@ +Meeting 44 – 4 October 2012 | ICAT Project

ICAT Project

Search

Meeting 44 – 4 October 2012

Agenda 44

+
    +
  • Actions from the meetings 42 and 43 (Alistair/Steve)
  • +
  • Report on the ICAT meeting at Nobugs2012 (Kevin)
  • +
  • ICAT 4.2.1 – Status (Steve)
  • +
  • Plans for ICAT 4.3 (Tom)
  • +
  • Update from PaN-data (Milan/George)
  • +
  • Deployment of ICAT 4.3 for DLS (Ghita)
  • +
  • Deployment of ICAT 4.3 for ISIS (Tom)
  • +
  • Deployment of ICAT 4.2 for CLF (Alistair)
  • +
  • Report on visit to Australia Synchrotron (Alistair)
  • +
  • AOB – Nicola and Shelly
  • +
+

Attendance 44

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
InitNameInstitutePresentApologies
AMAlistair MillsSTFC eSc+
AWAntony WilsonSTFC eSc+
GKMGhita Kouadri MostefaouiDiamond+
KPKevin PhippsSTFC eSc+
MPMilan PricaELETTRA+
NBNicola BessoneESRF+
SFSteve FisherSTFC eSc+
SRShelly RenORNL SNS+
+

 

+

 

+

 

+

Notes 44

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
InitNameInstitutePresentApologies
MGMark GreenTech-X+
TGTom GriffinSTFC ISIS Facility+
+

Kevin reported that the meeting at NOBUGS2012 had gone well and that the +materials from the presentations are on the wiki for download.

+

Steve reported that ICAT 4.2.1 has been available for two weeks, and +that it has been installed on pre-production service for CLF at RAL.

+

As Tom was not present, discussion of ICAT 4.3 is deferred to the next +meeting.

+

Milan reported that the +PanData? review +is in Brussels on 26-27/11. He would like to report that the Service +Verifications have started and that there are six organisations +participating. He also reported that there is a deliverable due in +December on the progress of the deployments. Alistair reported that we +would visit ILL/ESRF on 18-19/10 and that the first Service Verification +should take place around 3 November 2012.

+

Ghita reported that there is a meeting scheduled for 11/10/12 about the +migration to ICAT 4.3. There is now a test server in DLS running 4.2, +but there is no data available. DLS is planning to migrate to ICAT 4.3 +during the next shutdown period at the beginning of December 2012.

+

As Tom was not present, there was no discussion about the deployment for +ISIS.

+

Alistair reported that a pre-production server is running ICAT 4.2 for +CLF and that migration to ICAT 4.3 will happen in December 2012.

+

Alistair reported that he had visited the Australian Synchrotron in +Melbourne. the data catalog uses Tardis and the development work is done +by a group in Monash University. They are interested in integrating +Tardis with Pandata using Topcat. During 2013, the lead software +engineer for this work will visit RAL to work on a prototype +implementation.

+

Nicola reported that work on installing ICAT 4.2.1 was in progress at +ILL and ESRF.

+

Shelly reported that she added the following two modules to the icat +project contrib repository:

+

1. icat-rest-ws is a java based restful web service that retrieves +certain metadata with open access such as runs proposals for a given +instruments, runs for a given proposal, and file locations of a given +run etc.. Tom documented a use case note +at:http://code.google.com/p/icatproject/wiki/AnonAccessToMetadata

+

2. ingestNexus python script would read a Nexus file, parse metadata, +create ICAT client objects, and calling ICAT server for cataloging. I +plan to add more comments to the readme file of this module to explain +what it does and how it works.

+

Actions 44

+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2012-meetings/meeting-45-18-october-2012/index.html b/collaboration/communication/monthly-meetings/2012-meetings/meeting-45-18-october-2012/index.html new file mode 100644 index 000000000..fa33a2cde --- /dev/null +++ b/collaboration/communication/monthly-meetings/2012-meetings/meeting-45-18-october-2012/index.html @@ -0,0 +1,261 @@ +Meeting 45 – 18 October 2012 | ICAT Project

ICAT Project

Search

Meeting 45 – 18 October 2012

Agenda 45

+
    +
  • Actions from the meetings 44 (Alistair/Steve)
  • +
  • Plans for ICAT 4.3 (Tom)
  • +
  • Update from PaN-data (Milan/George)
  • +
  • Deployment of ICAT 4.3 for DLS (Ghita)
  • +
  • Deployment of ICAT 4.3 for ISIS (Tom)
  • +
  • Deployment of ICAT 4.2 for CLF (Alistair)
  • +
  • AOB (Any)
  • +
+

Attendance 45

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
InitNameInstitutePresentApologies
AMAlistair MillsSTFC eSc+
SFSteve FisherSTFC eSc+
KPKevin PhippsSTFC eSc+
MPMilan PricaELETTRA+
GKGeorge KourousiasELETTRA+
NBNicola BessoneESRF+
JSJulian SavoyetESRF+
JHJamie HallILL+
JDJuergen StarkDESY+
+

 

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
InitNameInstitutePresentApologies
TGTom GriffinSTFC ISIS Facility+
AWAntony WilsonSTFC eSc+
GKMGhita Kouadri MostefaouiDiamond+
SRShelly RenORNL SNS+
+

 

+

Notes 45

+

There was was an excellent attendance at the meeting with Juergen, Jamie +and Julian attending for the first time.

+

The CRISP project has written a deliverable comparing meta data catalogs +and selected ICAT as the preferred catalog.

+

Tom was absent, so discussion of icat 4.3 was deferred.

+

Pandata is planning a series of monthly service verifications, with sv-0 +planned for 9 November 2012.

+

ESRF proposes the following changes for icat 4.3:

+
    +
  • Add a property to icat.properties to deploy to http rather than +http;
  • +
+ +
    +
  • Add additional properties to auth_ldap.properties to support +deployment at ESRF;
  • +
+ +
    +
  • Change the installation scripts such as create.sh and +glassfish.props to enhance support for domains other than domain1;
  • +
+ +
    +
  • Eliminate the need for the user to supply the authentication +mechanism (ie db or ldap).
  • +
+

The DLS deployment of 4.2 is making good progress and full deployment is +planned for the close-down period in January 2013.

+

The ISIS deployment of 4.2 is making good progress and full deployment +is planned for the close-down period in December 2012.

+

The CLF deployment of 4.2 is making good progress and full deployment is +planned for November 2012.

+

It was noted that the 1st of November is a public holiday in both France +and Italy so attendance will be reduced for the meeting on that +day.

+

Actions 45

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionRes**(1)**StatusComment
45.00Document the meetingAMDone
45.01Add a page to the wiki with an index to contribAMDone
45.02Publish the ER diagrams for icat 4.1 and 4.2 to contribNBDone
45.03Send an email to Christian about his web service web siteAM.
45.04Put a link into the wiki to the site of ChristianAMDone
45.05Discuss the changes proposed by ESRFSF/AMDone
45.06Arrange next meeting on 1 November, but it is a holiday in France and ItalyAMDone
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2012-meetings/meeting-46-1-november-2012/index.html b/collaboration/communication/monthly-meetings/2012-meetings/meeting-46-1-november-2012/index.html new file mode 100644 index 000000000..da704420e --- /dev/null +++ b/collaboration/communication/monthly-meetings/2012-meetings/meeting-46-1-november-2012/index.html @@ -0,0 +1,82 @@ +Meeting 46 – 1 November 2012 | ICAT Project

ICAT Project

Search

Meeting 46 – 1 November 2012

    +
  • Actions from the meetings 45 (Alistair/Steve)
  • +
  • Plan for the face to face meeting in March 2013
  • +
  • Plans for ICAT 4.3 (Tom)
  • +
  • Update from PaN-data (Milan/George)
  • +
  • Deployment of ICAT 4.2 for DLS (Ghita)
  • +
  • Deployment of ICAT 4.2 for ISIS (Tom)
  • +
  • Deployment of ICAT 4.2 for CLF (Alistair)
  • +
  • AOB
  • +
+

(Any)

+

Actions 46

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionRes**(1)**StatusComment
46.00Document the meetingAMDone
46.01Find the data for the ICAT/Pandata meeting in Sweden in 2013AM11-14/March/2013TBC
46.02Review the ICAT requirements pageTGDoneIcatRequirements?
46.03Update the SNS requirements for ICATSR.
46.04Schedule RAL meeting about the ISIS migrationAMDone15/11/12
46.05Arrange next meeting for 15 November 2012AMDone
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2012-meetings/meeting-47-15-november-2012/index.html b/collaboration/communication/monthly-meetings/2012-meetings/meeting-47-15-november-2012/index.html new file mode 100644 index 000000000..d57994ccb --- /dev/null +++ b/collaboration/communication/monthly-meetings/2012-meetings/meeting-47-15-november-2012/index.html @@ -0,0 +1,308 @@ +Meeting 47 – 15 November 2012 | ICAT Project

ICAT Project

Search

Meeting 47 – 15 November 2012

    +
  • Actions from the meetings 46 (Alistair/Steve)
  • +
  • Plans for ICAT 4.3 and beyond (Tom)
  • +
  • Update from PaN-data (Milan/George)
  • +
  • Deployment of ICAT 4.2 for DLS (Ghita)
  • +
  • Deployment of ICAT 4.2 for ISIS (Tom)
  • +
  • Deployment of ICAT 4.2 for CLF (Alistair)
  • +
  • AOB (Any)
  • +
+

Attendance 47

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
InitNameInstitutePresentApologies
AMAlistair MillsSTFC SCD+
SFSteve FisherSTFC SCD+
KPKevin PhippsSTFC SCD+
MPMilan PricaELETTRA+
GKGeorge KourousiasELETTRA+
JHJamie HallILL+
TGTom GriffinSTFC ISIS Facility+
AWAntony WilsonSTFC SCD+
BMBrian MatthewsSTFC SCD+
FBFrazer BarnselySTFC SCD+
+

 

+

Actions 47

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionRes**(1)**StatusComment
47.00Document the meetingAMDone
47.01Send Shelly an email about the meeting in MarchAMDone
47.02Clarify ICAT licenceAMDonehttp://opensource.org/licenses/BSD-3-Clause
47.03Notify people of IcatLegacyPolicy?AMDone
47.04Clarify the data mining requirementsJH.
47.05Add more bootstrap information for developers to wikis and documentationSFTicketed #86
47.06Ask Juergen to investigate deploying ICAT using JbossAMDone
47.07Remove ICATCompat from icat 4.3SFTicketed #87
47.08Update IcatRequirements? based on the discussions in this meetingTGDone
47.09Do a prototype of machine generated documentation of the WS End PointAWTicketed #88
47.10Investigate the ICAT class in NexusGKDone
47.01Call next meeting on Thursday 29th November (NOT a public holiday in USA)AMDone
+

 

+

Attendance 47

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
InitNameInstitutePresentApologies
AMAlistair MillsSTFC SCD+
SFSteve FisherSTFC SCD+
KPKevin PhippsSTFC SCD+
MPMilan PricaELETTRA+
GKGeorge KourousiasELETTRA+
JHJamie HallILL+
TGTom GriffinSTFC ISIS Facility+
AWAntony WilsonSTFC SCD+
BMBrian MatthewsSTFC SCD+
FBFrazer BarnselySTFC SCD+
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2012-meetings/meeting-48-29-november-2012/index.html b/collaboration/communication/monthly-meetings/2012-meetings/meeting-48-29-november-2012/index.html new file mode 100644 index 000000000..9354b695c --- /dev/null +++ b/collaboration/communication/monthly-meetings/2012-meetings/meeting-48-29-november-2012/index.html @@ -0,0 +1,223 @@ +Meeting 48 – 29 November 2012 | ICAT Project

ICAT Project

Search

Meeting 48 – 29 November 2012

    +
  • Actions from the meetings 47 (Alistair)
  • +
  • Icat legacy policy +(IcatLegacyPolicy?) +(Alistair)
  • +
  • Requirements for ICAT 4.3 and beyond +(IcatRequirements?)(Tom)
  • +
  • Update from PaN-data (Milan/George)
  • +
  • Deployment of ICAT 4.2 for DLS (Ghita)
  • +
  • Deployment of ICAT 4.2 for ISIS (Tom)
  • +
  • Deployment of ICAT 4.2 for CLF (Alistair)
  • +
  • Status of contribs +(ContribIndex) +– icat_setup, artefects from pandata/crisp (Alistair)
  • +
  • AOB
  • +
+

(Any)

+

Actions 48

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionRes**(1)**StatusComment
48.00Document the meetingAMDone
48.01Ask Juan to clarify the dates for the conference in Lund in March (ICAT 2013)AMEmail to Juan
48.02Email Shelly about the conference in LundAMEmail to Juan
48.03Add licence information to all source code parts in ICAT 4.3 (ticket)AMDoneTicket #85
48.04Remind Jamie Hall about clarifications of requirements for data miningAMDone
48.05Create tickets for action 47.05, 47.07, 47.09AMDoneTickets #86, #87 #88
48.06Add a note to the wiki about Nexus Archive and ICATGK.
48.07Contact Mark Koenig about Nexus standards and ICATGKCancelled
48.08Talk to Bill Pulford about Nexus, DLS and ICATAMDone
48.09Create wiki page for the agenda for ICAT 2013 and add item on NexusAMDoneSweden2013
48.10Enhance the ICAT Legacy Policy with a clause for support of ICAT after 6 monthsAMDone by Tom
48.11Start a discussion on the mailing lists about changes to uniqueness constraintsSFDone
48.12Call next meetings on 13 December 2012, 10 January 2013; cancel 27 December 2012AMDone
+

 

+

Attendance 48

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
InitNameInstitutePresentApologies
AMAlistair MillsSTFC SCD+
SFSteve FisherSTFC SCD+
KPKevin PhippsSTFC SCD+
MPMilan PricaELETTRA+
GKGeorge KourousiasELETTRA+
TGTom GriffinSTFC ISIS Facility+
AWAntony WilsonSTFC SCD+
GKMGhita Kouadri MostefaouiDiamond+
SRShelly RenORNL SNS+
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2012-meetings/meeting-49-13-december-2012/index.html b/collaboration/communication/monthly-meetings/2012-meetings/meeting-49-13-december-2012/index.html new file mode 100644 index 000000000..7973bda40 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2012-meetings/meeting-49-13-december-2012/index.html @@ -0,0 +1,184 @@ +Meeting 49 – 13 December 2012 | ICAT Project

ICAT Project

Search

Meeting 49 – 13 December 2012

    +
  • Actions from the meetings 48 (Alistair)
  • +
  • Plans for ICAT 2013 (Tom)
  • +
  • Open ticket review (Steve)
  • +
  • Update from PaN-data (Milan/George)
  • +
  • Deployment of ICAT 4.2 for RAL – DLS, ISIS and CLF (Ghita, Tom, +Kevin)
  • +
  • Status of contribs +(ContribIndex) +(Alistair)
  • +
  • AOB
  • +
+

(Any)

+

Actions 49

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionRes**(1)**StatusComment
49.00Document the meetingAMDone
49.01Forward the email from Juan about Sweden to ShellyAMDone
49.02Update the page on the wiki with information about SwedenAMon-going
49.03Update the status of the tickets on google codeSFDone
49.04Call next meeting for 10 January 2013AMDone
+

 

+

Attendance 48

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
InitNameInstitutePresentApologies
AMAlistair MillsSTFC SCD+
SFSteve FisherSTFC SCD+
KPKevin PhippsSTFC SCD+
MPMilan PricaELETTRA+
GKGeorge KourousiasELETTRA+
TGTom GriffinSTFC ISIS Facility+
AWAntony WilsonSTFC SCD+
GKMGhita Kouadri MostefaouiDiamond+
SRShelly RenORNL SNS+
PxPablo GarciaAlba+
DLDavid LopezAlba+
JSJulian SavoyetESRF+
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2013-meetings/index.html b/collaboration/communication/monthly-meetings/2013-meetings/index.html new file mode 100644 index 000000000..b83c9a7f2 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2013-meetings/index.html @@ -0,0 +1,29 @@ +2013 Meetings | ICAT Project

ICAT Project

Search

2013 Meetings

+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2013-meetings/meeting-50-10-january-2013/index.html b/collaboration/communication/monthly-meetings/2013-meetings/meeting-50-10-january-2013/index.html new file mode 100644 index 000000000..adcff78e7 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2013-meetings/meeting-50-10-january-2013/index.html @@ -0,0 +1,161 @@ +Meeting 50 – 10 January 2013 | ICAT Project

ICAT Project

Search

Meeting 50 – 10 January 2013

    +
  • Actions from the meetings 49 (Alistair)
  • +
  • Plans for Sweden2013 (Tom)
  • +
  • Update from PaN-data (Milan/George)
  • +
  • Deployment of ICAT 4.2 for RAL – DLS, ISIS and CLF (Ghita, Tom, +Kevin)
  • +
  • Status of contribs +(ContribIndex) +(Alistair)
  • +
  • AOB (Any)
  • +
+

Notes 50

+

Shelly asked that additional information such as venue, contact names +and hotel details be added to the wiki for the conference in Sweden. See +actions 50.01 and 50.02.

+

Milan reported that he was working on a deliverable for WP4 of Pandata, +but requires data from Thorsten in DESY. Thorsten is still on vacation +and so the deliverable will be delayed until the data is available. He +is expecting to use the data for the next service verification on 1 +February. When this has occurred, the deliverable can be completed.

+

Steve reported that he was considering including some speculative +features in ICAT 4.3. These speculative features are being introduced to +support data mining and they may change or be removed from future ICATs. +There was discussion about how to achieve this. The meeting did not +agree any particular mechanism. It was proposed that odd numbered minor +revisions such as 4.3 may contain such features, but even numbered +revisions such as 4.2 and 4.4 do not. A facility using ICAT would +normally go from even to even. However where a Facility requires a +speculative feature, then it may deploy an odd version on the +understanding that the interface to the speculative feature may change. +See action 50.03.

+

The meeting finished at 15:30.

+

Attendance 50

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
InitNameInstitutePresentApologies
AMAlistair MillsSTFC SCD+
SFSteve FisherSTFC SCD+
KPKevin PhippsSTFC SCD+
MPMilan PricaELETTRA+
GKGeorge KourousiasELETTRA+
SRShelly RenORNL SNS+
+

 

+

Actions 50

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionRes**(1)**StatusComment
50.00Document the meetingAMDone
50.01Provide additional information about venue, hotel, contacts for SwedenAM.
50.02Update the page on the wiki with information about SwedenAMon-going
50.03Consider a mechanism for introducing speculative features to ICATSFDone
50.04Call next meeting for 24 January 2013AMDone
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2013-meetings/meeting-51-24-january-2013/index.html b/collaboration/communication/monthly-meetings/2013-meetings/meeting-51-24-january-2013/index.html new file mode 100644 index 000000000..d42d02e68 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2013-meetings/meeting-51-24-january-2013/index.html @@ -0,0 +1,180 @@ +Meeting 51 – 24 January 2013 | ICAT Project

ICAT Project

Search

Meeting 51 – 24 January 2013

    +
  • Actions from the meetings 50 (Alistair)
  • +
  • Contents of ICAT 4.3
  • +
  • Plans for Sweden2013 (Tom)
  • +
  • Update from PaN-data (Milan/George)
  • +
  • Proposals for ICAT 4.3 release
  • +
  • AOB
  • +
+

(Any)

+

Actions 51

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionRes**(1)**StatusComment
51.00Document the meetingAMDone
51.01Find out about visa requirements and notify GKMKLDone
51.02Review the wiki page about the meeting in Sweden regularlyAMOn-going
51.03Update the description of ICAT 4.3 based on the discussion in the meetingSFDone
51.04Have one to one discussion of ICAT 4.3 on the telephoneSF/SRDone
51.05Call the next meeting on 7 February; Antony to lead the discussion of IDSAM/AW.
+

 

+

Attendance 51

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
InitNameInstitutePresentApologies
AMAlistair MillsSTFC SCD+
SFSteve FisherSTFC SCD+
KPKevin PhippsSTFC SCD+
JSJuergen StarekDESY+
KLKristen LarssonMAX+
SRShelly RenORNL SNS+
TGTom GriffinSTFC ISIS Facility+
AWAntony WilsonSTFC SCD+
GKMGhita Kouadri MostefaouiDiamond+
MPMilan PricaELETTRA+
GKGeorge KourousiasELETTRA+
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2013-meetings/meeting-52-7-february-2013/index.html b/collaboration/communication/monthly-meetings/2013-meetings/meeting-52-7-february-2013/index.html new file mode 100644 index 000000000..9e30f6f74 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2013-meetings/meeting-52-7-february-2013/index.html @@ -0,0 +1,225 @@ +Meeting 52 – 7 February 2013 | ICAT Project

ICAT Project

Search

Meeting 52 – 7 February 2013

    +
  • Actions from the meetings 51 (Alistair)
  • +
  • Plans for Sweden2013 (Krister)
  • +
  • Status of IDS reference implementation (Antony)
  • +
  • Update from PaN-data (Milan/George)
  • +
  • AOB (Any)
  • +
+

Attendance 52

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
InitNameInstitutePresentApologies
AMAlistair MillsSTFC SCD+
SFSteve FisherSTFC SCD+
KPKevin PhippsSTFC SCD+
MPMilan PricaELETTRA+
GKGeorge KourousiasELETTRA+
SRShelly RenORNL SNS+
KLKrister LarssonMAX+
JHJamie HallILL+
GKMGhita Kouadri MostefaouiDiamond+
+

 

+

Notes 52

+

Steve reported that he had only a small amount of feedback about the +content of ICAT 4.3 and so he would post to the mailing list again.

+

Shelly asked if people with experience of calling the ICAT API in C++ +could provide advice on which package to use. Gsoap is a candidate.

+

Krister asked that we add a note to the web site about lunch being +available before the ICAT meeting in Lund. He also said that he intends +to send out another announcement about the meeting in Lund. Krister said +that a representative of ESS would attend the ICAT workshop in Lund; he +said that ESS is a potential big user of ICAT.

+

Jamie asked that changes be included in ICAT 4.3 to support ILL. He will +send a note to the mailing list about this.

+

Antony and Frazer lead a discussion of the plans for IDS.

+

Milan reported that he was working on a deliverable for WP4 of Pandata. +He reported that +SV2? was held on 1st +February, but it had not been possible to include meta-data ingestion in +the +verification.

+

Actions 52

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionRes**(1)**StatusComment
52.00Document the meetingAMDone
52.01Ask again for feedback on ICAT 4.3SFDone
52.02Send comments to Shelly about the use of C++ for ICAT APIAllDone
52.03Add a note to the wiki about Antony’s talkAMDonehttp://code.google.com/p/icat-data-service/wiki/07_02_13
52.04Send an announcement about the meeting in Lund with clarification of venueKLDone
52.05Provide a copy of the draft of the pandata deliverable WP4.D.2 to AMMPDone
52.06Send a copy of the mail about the changes to ICAT proposed by ILLJHDone
52.07Send a note to AM about installing a certificate in GFJH.
52.08Investigate the effect on GF of the loss of the database connectionAM.
52.09Provide a “dry-run” option on API calls to support greyed-out buttons in GUIsSFDoneThis will be in ICAT 4.3
52.10Fix for bug in createMany to be released in icat 4.2.3SFDone
52.11Chair the next meeting on 21 February 2013 as Alistair will be on leaveSFDone
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2013-meetings/meeting-53-21-february-2013/index.html b/collaboration/communication/monthly-meetings/2013-meetings/meeting-53-21-february-2013/index.html new file mode 100644 index 000000000..f0b7171b3 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2013-meetings/meeting-53-21-february-2013/index.html @@ -0,0 +1,94 @@ +Meeting 53 – 21 February 2013 | ICAT Project

ICAT Project

Search

Meeting 53 – 21 February 2013

    +
  • Actions from the meetings 52 (Alistair)
  • +
  • Plans for Sweden2013 (Krister)
  • +
  • Update from PaN-data (Milan/George)
  • +
  • AOB (Any)
  • +
+

Notes 53

+

Actions 52.02, 52.06 and 52.10 have been completed

+

Nothing else to report and no AOB.

+

Attendance 53

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
InitNameInstitutePresentApologies
SFSteve FisherSTFC SCD+
KPKevin PhippsSTFC SCD+
MPMilan PricaELETTRA+
SRShelly RenORNL SNS+
KLKrister LarssonMAX+
TGTom GriffinSTFC ISIS Facility+
AWAntony WilsonSTFC SCD+
DLDavid LopezAlba+
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2013-meetings/meeting-54-7-march-2013/index.html b/collaboration/communication/monthly-meetings/2013-meetings/meeting-54-7-march-2013/index.html new file mode 100644 index 000000000..15b9c3e44 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2013-meetings/meeting-54-7-march-2013/index.html @@ -0,0 +1,171 @@ +Meeting 54 – 7 March 2013 | ICAT Project

ICAT Project

Search

Meeting 54 – 7 March 2013

    +
  • Actions from the meetings 52-53 (Alistair)
  • +
  • Plans for Sweden2013 (Krister)
  • +
  • Update from PaN-data (Milan/George)
  • +
  • AOB
  • +
+

(Any)

+

Actions 54

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionRes**(1)**StatusComment
54.00Document the meetingAMDone
54.01Update the timetable for Sweden2013AMDone
54.02Send information about the conference venue to SRAMDone
54.03Send Elettra status summary for presentation in Lund to AMMPDone
54.04Send one page template for status of a contrib to SR, TG, SRAMDone
54.05Distribute the latest notes on the contents of icat 4.3SFDone
+

 

+

Attendance 54

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
InitNameInstitutePresentApologies
SFSteve FisherSTFC SCD+
KPKevin PhippsSTFC SCD+
MPMilan PricaELETTRA+
SRShelly RenORNL SNS+
TGTom GriffinSTFC ISIS Facility+
AWAntony WilsonSTFC SCD+
DSDaniel SalvatAlba+
DLDavid LopezAlba+
AMAlistair MillsSTFC SCD+
GKMGhita Kouadri MostefaouiDiamond+
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2013-meetings/meeting-55-21-march-2013/index.html b/collaboration/communication/monthly-meetings/2013-meetings/meeting-55-21-march-2013/index.html new file mode 100644 index 000000000..819c094f3 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2013-meetings/meeting-55-21-march-2013/index.html @@ -0,0 +1,201 @@ +Meeting 55 – 21 March 2013 | ICAT Project

ICAT Project

Search

Meeting 55 – 21 March 2013

    +
  • Actions from the meetings 52-54 (Alistair)
  • +
  • Discussion of the outcomes from Lund
  • +
  • Discussion of the content of ICAT 4.3
  • +
  • Discussion of the agenda for the collaboration meetings Spring 2013
  • +
  • Update from PaN-data (Milan/George)
  • +
  • AOB (Any)
  • +
+

Notes 55

+

The meeting discussed actions from earlier meetings and updated the +status.

+

The meeting discussed the conference in Lund. It was generally agreed +that it was successful. A number of items are worthy of note:

+
    +
  • Sites such as Alba may have to enhance the reference implementation +of IDS when it is available, to meet their requirements for data +management;
  • +
  • There were presentations at the Pandata meeeting (such as Tom’s on +ICAT and Umbrella integration) which should be made available to the +ICAT collaboration;
  • +
  • There should be a half day ICAT workshop added to the Pandata +meeting in Barcelona in September;
  • +
  • There will be a Pandata WP4 telco next week to discuss matters +arising from the Pandata meeting in Lund.
  • +
+

 

+

The meeting discussed topics to be addressed in the next three months of +collaboration meetings – see the list above.

+

The meeting finished at +15h35.

+

Actions 55

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionRes**(1)**StatusComment
55.00Document the meeting and update the actionsAMDone
55.01Arrange for copies of Pandata presentations to be availableAMDone
55.02Arrange an ICAT workshop with the Pandata meeting at Alba in SeptemberAM/DSOn-going
+

 

+

Attendance 55

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
InitNameInstitutePresentApologies
AMAlistair MillsSTFC SCD+
SFSteve FisherSTFC SCD+
ICIdrissou ChadoSoleil+
MPMilan PricaELETTRA+
GKGeorge KourousiasELETTRA+
NVNicola BessoneESRF+
DSDaniel SalvatAlba+
DLDavid LopezAlba+
PGPablo GarciaAlba+
SRShelly RenORNL SNS+
KPKevin PhippsSTFC SCD+
AWAntony WilsonSTFC SCD+
GKMGhita Kouadri MostefaouiDiamond+
TGTom GriffinSTFC ISIS Facility+
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2013-meetings/meeting-56-4-april-2013/index.html b/collaboration/communication/monthly-meetings/2013-meetings/meeting-56-4-april-2013/index.html new file mode 100644 index 000000000..7b8c447fc --- /dev/null +++ b/collaboration/communication/monthly-meetings/2013-meetings/meeting-56-4-april-2013/index.html @@ -0,0 +1,207 @@ +Meeting 56 – 4 April 2013 | ICAT Project

ICAT Project

Search

Meeting 56 – 4 April 2013

    +
  • Actions from the meetings 55 (Alistair)
  • +
  • Review of requirements for ICAT (Steve)
  • +
  • Review of requirements for ICAT related parts such as Topcat, IDS, +IJP (Steve)
  • +
  • AOB
  • +
+

(Any)

+

Actions 56

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionRes**(1)**StatusComment
56.00Document the meeting and update the actionsAMDone
56.01Arrange for copies of Pandata presentations to be availableAMDonehttps://code.google.com/p/icatproject/source/browse/#svn%2Fmeetings%2FPandataLund,https://code.google.com/p/icatproject/source/browse/#svn%2Fmeetings%2FLund2013Talks
56.02Add a paragraph to the requirements page about general requirementsAMDoneDeployment, Ingestion, Publishing, User office, Setup, Operations, Common standards
.– PMH interfaceSMFDone
.– Revision of XML schemaSMFDone
.– Additional indices in some tablesSMFDone
56.03Make the priority of the requirement for filesystem interface to ICAT, highSMFDone
56.04Create tickets for each of the ICAT requirements and link to index pageSMFDone
56.05Provide information about the memory leak in the logging to SN et aliaTGDone
+

 

+

Attendance 56

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
InitNameInstitutePresentApologies
AMAlistair MillsSTFC SCD+
SMFSteve FisherSTFC SCD+
MPMilan PricaELETTRA+
NVNicola BessoneESRF+
PGPablo GarciaAlba+
SRShelly RenORNL SNS+
KPKevin PhippsSTFC SCD+
BMBrian MatthewsSTFC SCD+
AWAntony WilsonSTFC SCD+
GKMGhita Kouadri MostefaouiDiamond+
TGTom GriffinSTFC ISIS Facility+
ICIdrissou ChadoSoleil+
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2013-meetings/meeting-57-18-april-2013/index.html b/collaboration/communication/monthly-meetings/2013-meetings/meeting-57-18-april-2013/index.html new file mode 100644 index 000000000..5cdbb417d --- /dev/null +++ b/collaboration/communication/monthly-meetings/2013-meetings/meeting-57-18-april-2013/index.html @@ -0,0 +1,165 @@ +Meeting 57 – 18 April 2013 | ICAT Project

ICAT Project

Search

Meeting 57 – 18 April 2013

    +
  • Actions from the meetings 56 (Alistair)
  • +
  • Icat Data Server (IDS) development (Antony)
  • +
  • AOB (Any)
  • +
+

Notes 57

+

The meeting discussed actions from earlier meetings and updated the +status of actions.

+

The meeting discussed the arrival of CCFE as a collaborator. Alistair +agreed to send a note to the collaboration about this. There is now a +note called +InductionProcess? on +the wiki. The intention is to follow this process and to enhance the +note. The purpose of this is to ensure that new partners get off to a +good start. We look forward to having a representative of CCFE attend +one of these meetings.

+

The meeting discussed the status of the reference implementation of the +IDS. One part of this is called the Download Manager. This is now in +pre-production with both the ISIS and DLS facilities. It will also be +used as part of the service verification which will be conducted by +Pandata. It was agreed to make a distribution of the download manager. +This is a technology preview, and should only be used for testing.

+

As Steve Fisher is on vacation, the meeting did not discuss the status +of ICAT 4.3.

+

Tom has created a google group called icat-issues@googlegroups.com. +Alistair agreed to add a link to this group +onhttp://www.icatproject.org.

+

The meeting concluded after 20 minutes. A new record for +brevity!

+

Actions 57

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionRes**(1)**StatusComment
57.00Document the meeting and update the actionsAMDone
57.01Inform the collaboration of the arrival of CCFEAMDonehttp://www.ccfe.ac.uk
57.02Prepare a distribution of a technology preview of the Download ManagerAW.
57.03Add a link to icat-issues on http://www.icatproject.orgAMDone
+

 

+

Attendance 57

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
InitNameInstitutePresentApologies
AMAlistair MillsSTFC SCD+
SMFSteve FisherSTFC SCD+
DGDavid GarciaAlba+
KPKevin PhippsSTFC SCD+
AWAntony WilsonSTFC SCD+
GKMGhita Kouadri MostefaouiDiamond+
TGTom GriffinSTFC ISIS Facility+
FBFrazer BarnsleySTFC SCD+
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2013-meetings/meeting-58-2-may-2013/index.html b/collaboration/communication/monthly-meetings/2013-meetings/meeting-58-2-may-2013/index.html new file mode 100644 index 000000000..59f6b2662 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2013-meetings/meeting-58-2-may-2013/index.html @@ -0,0 +1,188 @@ +Meeting 58 – 2 May 2013 | ICAT Project

ICAT Project

Search

Meeting 58 – 2 May 2013

    +
  • Actions from the meetings 57 (SMF)
  • +
  • Status of ICAT 4.3 (SMF)
  • +
  • Status of SV4 of Pandata (AM)
  • +
  • Status of CCFE (AM)
  • +
  • AOB (Any)
  • +
+

Notes 58

+

The meeting discussed actions and updated the status of actions.

+

SMF stated that a 4.2.5 version of ICAT would be released to fix a +thread/memory leak related to the initialisation of log4j. He was +reminded that there may be a problem with the frequency of access to the +sequence table and that this might also go into 4.2.5.

+

SMF stated that ICAT 4.3.0 would include the changes required by ISIS +for a more powerful query language supporting more complex authz rules.

+

In AM’s absence GK reported on +PaNdata? SV4 +which will start next week and be based on “Big V”.

+

AOB:

+

SR reported that she was working with APS on a new pilot project

+

SMF asked if there was any interest in a “File Authenticator”. There +wasn’t so it will not happen. The question then arose can we find out +what authenticators are present and what credentials they require. +TopCAT can manage without but at the expense of having to configure a +plugin correctly. A new requirement will be added.

+

AW reported that there was good progress on Noris’s admin interface to +TopCAT.

+

It was reported that the Chinese Neutron Source have successfully +deployed an ICAT and TopCAT.

+

Finally GKM reported that “Actors” had been added to +DAWN.

+

Actions 58

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionResStatusComment
57.02Prepare a distribution of a technology preview of the Download ManagerAWDone
58.00Document the meeting and update the actionsSMFDone
58.01Produce 4.2.5 release of ICATSMFDone
58.02Add a requirement to be able to discover what authenticators are present and what credentials they require.SMFDoneIssue 122
+

 

+

Attendance 58

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
InitNameInstitutePresentApologies
AMAlistair MillsSTFC SCD+
SMFSteve FisherSTFC SCD+
DGDavid GarciaAlba+
KPKevin PhippsSTFC SCD+
AWAntony WilsonSTFC SCD+
GKMGhita Kouadri MostefaouiDiamond+
TGTom GriffinSTFC ISIS Facility+
NBNicola BessoneESRF+
ICIdrissou ChadoSoleil+
SRShelly RenORNL SNS+
GKGeorge KourousiasELETTRA+
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2013-meetings/meeting-59-16-may-2013/index.html b/collaboration/communication/monthly-meetings/2013-meetings/meeting-59-16-may-2013/index.html new file mode 100644 index 000000000..1b19e6e6f --- /dev/null +++ b/collaboration/communication/monthly-meetings/2013-meetings/meeting-59-16-may-2013/index.html @@ -0,0 +1,179 @@ +Meeting 59 – 16 May 2013 | ICAT Project

ICAT Project

Search

Meeting 59 – 16 May 2013

    +
  • Actions from the meetings 58 (Alistair)
  • +
  • Status of ICAT 4.3 (Steve)
  • +
  • Status of anonymous authenticator (Steve)
  • +
  • Status of IDS (Antony)
  • +
  • AOB (Any)
  • +
+

Notes 59

+

Steve reported that Antony has now left the collaboration as he has a +new job within STFC SCD. Alistair was asked to make an announcement +about the availability of the technology preview of the IDS. Alistair +reported that the downloader part of the IDS had performed well during +the service verification on 10 May 2013.

+

(Steve and Alistair reviewed the status of the materials for the IDS on +22 May 2013 and decided that the IDS is not ready for a technology +preview. There will be a student working on this from July, and we +expect to have it ready for preview by September).

+

Steve reported that the anonymous authenticator is now available. +Alistair reported that he has successfully deployed it on one of the +test icats for Pandata.

+

Kevin reported that he has deployed ICAT 4.2.5 in production for CLF at +RAL. This appears to have cured the problem of memory leak and improved +the reliability of ICAT.

+

Kevin and Tom both reported that adding additional indexes to some of +the tables in the database has made a large difference to the time +required for queries. The response time is much lower, and it is much +more consistent.

+

There was discussion of how to implement index generation in ICAT 4.3. +There is not a standard way in SQL to tell a database to create indexes. +Furthermore, the tables which requires the indexes can vary from one +installation to another. There is a way to tell +EclipseLink? to +generate indexes in tables, but this does not work if a different +persistence provider is used. It was agreed to provide documentation on +index generation.

+

Steve reported that adding the extensions to the query language for ICAT +to support the changes to the schema to be introduced in icat 4.3 is +rather complicated and would delay the availability of ICAT 4.3. It was +agreed that Steve should take the time to get it correct, and if it +delays ICAT 4.3 until after the summer recess, this would be +satisfactory. (There is a requirement of Pandata that the changes to the +schema of ICAT are required by October 2013 – +Ed).

+

Actions 59

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionResStatusComment
59.00Document the meeting and update the actionsAMDone
58.01Make an announcement about the technology preview of the IDSAMWill not be doneThe IDS is not ready
+

 

+

Attendance 59

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
InitNameInstitutePresentApologies
AMAlistair MillsSTFC SCD+
SMFSteve FisherSTFC SCD+
DGDavid GarciaAlba+
DGPabloAlba+
KPKevin PhippsSTFC SCD+
GKMGhita Kouadri MostefaouiDiamond+
TGTom GriffinSTFC ISIS Facility+
NBNicola BessoneESRF+
ICIdrissou ChadoSoleil+
JHJamie HallIIL+
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2013-meetings/meeting-60-30-may-2013/index.html b/collaboration/communication/monthly-meetings/2013-meetings/meeting-60-30-may-2013/index.html new file mode 100644 index 000000000..d236bd992 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2013-meetings/meeting-60-30-may-2013/index.html @@ -0,0 +1,208 @@ +Meeting 60 – 30 May 2013 | ICAT Project

ICAT Project

Search

Meeting 60 – 30 May 2013

    +
  • Actions from the meeting 59 (Alistair)
  • +
  • Roadmap for ICAT 4.3 (Alistair)
  • +
  • Release conditions for ICAT 4.3 (Alistair)
  • +
  • Status of IJP (Steve)
  • +
  • Status of IDS (Alistair)
  • +
  • Status of Topcat (Alistair)
  • +
  • AOB (Any)
  • +
+

Notes 60

+

We were pleased to have Milan join us again. He has been away from work +for a month following an operation on his wrist.

+

Ghita informed us that she is going to leave Diamond in June to take up +an academic position teaching Computer Science in a University. The +chairman thanked Ghita for her work with ICAT and wished her well in her +new position.

+

Steve said that work on ICAT 4.3 was progressing well, with the +development of Notifications and Logging completed. He will deal with +Free text next. He said that when he completes the development of a +feature, he changes the status of the corresponding ticket to started. +The ticket will be closed when the feature is included in a release. If +further work is required following release, a new ticket will be +created.

+

Alistair reported that he had written notes about the release conditions +for ICAT and IDS. He will send an email to the mailing list inviting +comments.

+

Steve reported that the IJP is now ready for deployment in LSF at STFC. +A paper has been written and will be presented at a conference in Zurich +new week. He agreed to finalise a release of this product and to make an +announcement.

+

Steve reported that as Antony has left the project, we are short of +resources for the development and support of Topcat. We would very much +appreciate it, if one of our partners were to volunteer to support or +develop Topcat.

+

Alistair reported that as Frazer has left the project, we have recruited +a student who will join for three months from the beginning of +September. His main task will be to prepare the IDS for release. We are +expecting to have Frazer working with the project team from September +again. This will provide continuity in the work with IDS.

+

Alistair and Steve reported that STFC is going to recruit at least one +contractor for several months to support the ICAT related work until a +permanent replacement can be found for Antony.

+

The meeting finished at 15:25 +BST.

+

Actions 60

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionResStatusComment
60.00Document the meeting and update the actionsAMDone
60.01Add a page to the wiki about ICAT 4.3 and IDS 1.0 release conditionsAMDone
60.02Send a note to the mailing list about the notes on release conditionsAMDone
60.03Finalise a release of IJP and send a note to the mailing listSF.
60.04Consider offering help to support or develop TopcatAll.
60.05Make changes to the room booking at RAL for the ICAT meetingsAMDone
+

 

+

Attendance 60

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
InitNameInstitutePresentApologies
AMAlistair MillsSTFC SCD+
SMFSteve FisherSTFC SCD+
PGPablo GarciaAlba+
GKMGhita Kouadri MostefaouiDiamond+
NBNicola BessoneESRF+
MPMilan PricaELETTRA+
GKGeorge KELETTRA+
KPKevin PhippsSTFC SCD+
TGTom GriffinSTFC ISIS Facility+
ICIdrissou ChadoSoleil+
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2013-meetings/meeting-61-13-june-2013/index.html b/collaboration/communication/monthly-meetings/2013-meetings/meeting-61-13-june-2013/index.html new file mode 100644 index 000000000..ffb953915 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2013-meetings/meeting-61-13-june-2013/index.html @@ -0,0 +1,173 @@ +Meeting 61 – 13 June 2013 | ICAT Project

ICAT Project

Search

Meeting 61 – 13 June 2013

    +
  • Actions from the meeting 60 (Alistair)
  • +
  • Release conditions for products (Alistair)
  • +
  • Status of contribs (Alistair)
  • +
  • AOB (Any)
  • +
+

Notes 61

+

We were pleased to have Milan join us again. He has been away from work +for a month following an operation on his wrist.

+

Nicola informed us that he is going to leave ESRF in June to work in a +commercial organisation in Zurich. The chairman thanked Nicola for his +work with ICAT and wished him well in his new position.

+

There was discussion about the appropriateness of the release conditions +which AM had added to the wiki. It was agreed that this would be +discussed again, for example when ICAT 4.3 is close to release.

+

SF reported that progress with ICAT 4.3 is good; that free text search +is working and is very efficient; that consolidation of code is reducing +the volume of code, and making things simpler in the longer term.

+

TG reported that he is working on a simple browser for ICAT. He will put +it into contrib when it is ready.

+

SF reported that he has done some timing tests on the download component +of the IDS. This has led to changes in the implementation which ensures +that the cypher in SSL mode is set dynamically and this generally ensure +less time for the cypher.

+

AM reported that GF 4 has been released and that he has deployed ICAT, +Authdb and Topcat on a GF 4 and that they appear to work correctly. +There was a problem trying to deploy the download component of IDS; as +this is not yet a supported product, this is a matter for development.

+

AM reported that he had deployed ICAT with GF4 with an Apache front-end. +This work has been done at ESRF and will be used for the ESRF production +ICAT. The GF4 and the Apache communicate with one another using AJP. +There was a bug in GF 3 which meant that this did not work when using +https, due to an error in the GF which continued to use http, when it +should have used https. The bug has been fixed in GF 4. To verify that +the bug was due to GF3, having got ICAT to work with GF4, AM then tried +changing back to GF3, and the ICAT did not +work.

+

Actions 61

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionResStatusComment
61.00Document the meeting and update the actionsAMDone
61.01Put the simple ICAT browser into contrib when it is readyTG.
61.02Write a note about the performance on the download component of IDSSF.
61.03Write a note about GF 4 and AJPAMDone
+

 

+

Attendance 61

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
InitNameInstitutePresentApologies
AMAlistair MillsSTFC SCD+
SMFSteve FisherSTFC SCD+
NBNicola BessoneESRF+
MPMilan PricaELETTRA+
TGTom GriffinSTFC ISIS Facility+
JHJamie HallILL+
KPKevin PhippsSTFC SCD+
ICIdrissou ChadoSoleil+
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2013-meetings/meeting-62-11-july-2013/index.html b/collaboration/communication/monthly-meetings/2013-meetings/meeting-62-11-july-2013/index.html new file mode 100644 index 000000000..5ea9fbd95 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2013-meetings/meeting-62-11-july-2013/index.html @@ -0,0 +1,84 @@ +Meeting 62 – 11 July 2013 | ICAT Project

ICAT Project

Search

Meeting 62 – 11 July 2013

    +
  • Actions from the meeting 61 (Chair)
  • +
  • Status of ICAT 4.3 (Steve)
  • +
  • New components (Steve)
  • +
  • Feedback on Topcat 1.9 Snapshot (All)
  • +
  • Issues from ICAT production deployments (All)
  • +
  • AOB (All)
  • +
+

Notes 62

+

Present: Daniel Salvat, Pablo Garcia, David Lopez, George Kourousias, +Tom Griffin and Steve Fisher (Chair)

+

SMF: ICAT4.3 now needs two more things: schema changes with associated +scripts and enhanced query language. End of August still looks possible.

+

Rolf Krahl’s simple authenticator has been released and at some point a +class he has written to handle hashed passwords will also be used by the +db authenticator.

+

A SNAPSHOT of TopCAT 1.9 has been made available – no feedback has been +received so far.

+

Releases of ice (an ICAT Editor and icat-setup for editing authz related +tables) are imminent. Kevin will test them both before release.

+

TG: ISIS is still using ICAT3.3 and is waiting for ICAT4.3 with the +enhanced query language to support more specific rules.

+

GK: Umbrella will be part of the next PaNData verifications so will +probably need an umbrella authenticator.

+

DS: Reminder about the Barcelona workshop which is expected to have two +satellite meetings: one on icat and and one on +umbrella.

+

Actions 62

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionResStatus
62.00Document the meeting and update the actionsSteveDone
61.01Put the simple ICAT browser into contrib when it is readyTom.
61.02Write a note about glassfish configuration to reduce https overheadSteve.
61.03Write a note about GF 4 and AJPAlistairDone
60.03Finalise a release of IJP and send a note to the mailing listSteve.
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2013-meetings/meeting-63-25-july-2013/index.html b/collaboration/communication/monthly-meetings/2013-meetings/meeting-63-25-july-2013/index.html new file mode 100644 index 000000000..ee99751a9 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2013-meetings/meeting-63-25-july-2013/index.html @@ -0,0 +1,113 @@ +Meeting 63 – 25 July 2013 | ICAT Project

ICAT Project

Search

Meeting 63 – 25 July 2013

    +
  • Actions from the meeting 62 (Chair)
  • +
  • Status of ICAT 4.3 (Steve)
  • +
  • Feedback on new components (authn_simple, topcat 1.9, ice and +icat-setup (All)
  • +
  • Feedback on changes to query language, authz rules etc (All)
  • +
  • Feedback on guidelines for developers (All)
  • +
  • Issues from ICAT production deployments (All)
  • +
  • AOB (All)
  • +
+

Notes 63

+

Present: Juergen, Milan, George, Shelley, Tom, Brian, Kevin and Steve +(Chair)

+

There was no progress on any of the actions.

+

Steve: ICAT 4.3 is still progressing well. There is a problem in the +MySQL migration script. It is hoped that when this is converted to +Oracle the error may become apparent. It currently looks like a MySQL +bug. Besides this the only work left to do is the new query language and +related authz changes. Old style queries are being parsed and converted +into the new JPQL style. They will then be subject to the new +authorization code. This means that because the authz code is changing +the data that comes back from INCLUDE may change in 4.3. Some +modifications to authz rules may be needed to restore the old behaviour +if so desired.

+

Tom: A couple of feature requests for TopCAT have been submitted, ice +and icat-setup seem to work as advertised.

+

Steve: Feedback on the query language changes had been received saying +that we should keep the old language for an extended period. This is to +avoid forcing people to change and because its simplicity is +appreciated. There seems to be no problem with this. Following a +question from Tom, it was explained that authz rules would be applied to +included entities but that a mechanism would be provided to say that it +was always allowed to go from one specific entity type to another: for +example from Dataset to Datafile.

+

The developer guidelines were discussed briefly. Antony had requested by +e-mail the inclusion of something about logging. Tom questioned the need +to provide a python install script for the trivial installations, but +agreed that, if it were provided, then it should be in python and follow +the guidelines. Tom would also like to see some documentation on what +the scripts were doing. He was happy to have a verbose option to provide +this.

+

AOB: Earlier in the meeting Shelley had asked about the IDS – Steve +emphasised that though it had been made available to parts of PanData it +was not yet a supported ICAT component. Juergen expressed an interest in +using OpenId with ICAT however he has no spare effort at the moment to +do anything about it. Brian asked what was being done about organising +the ICAT part of the Barcelona meeting. Steve suggested that it should +have two parts: one relating to PanData and a more general part. An +action has been added for Steve and +Alistair.

+

Actions 63

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionResStatus
63.00Document the meeting and update the actionsSteveDone
61.01Put the simple ICAT browser into contrib when it is readyTom.
61.02Write a note about glassfish configuration to reduce https overheadSteveDone
61.03Write a note about GF 4 and AJPAlistairApacheAndGlassfish?
60.03Finalise a release of IJP and send a note to the mailing listSteve.
63.01Plan the ICAT meeting in BarcelonaSteve/AlistairDone
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2013-meetings/meeting-64-8-august-2013/index.html b/collaboration/communication/monthly-meetings/2013-meetings/meeting-64-8-august-2013/index.html new file mode 100644 index 000000000..602e35eb6 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2013-meetings/meeting-64-8-august-2013/index.html @@ -0,0 +1,97 @@ +Meeting 64 – 8 August 2013 | ICAT Project

ICAT Project

Search

Meeting 64 – 8 August 2013

    +
  • Actions from the meeting 63 (Alistair)
  • +
  • Status of ICAT 4.3 (Steve)
  • +
  • ICAT F2F Meeting (Steve and Alistair)
  • +
  • Issues from ICAT production deployments (All)
  • +
  • AOB (All)
  • +
+

Notes 64

+

Present: Alistair (STFC/chair), Kevin (STFC), Tom (ISIS), Ivan (CCFE) +and Steve (STFC)

+

As it is August, the meeting was quiet.

+

Ivan from CCFE joined the conference for the first time. CCFE is the +Centre for Fusion Energy. We welcome CCFE to the collaboration.

+

The Pandata meeting in Barcelona in September was discussed. It was +noted that there would NOT be a meeting about ICAT. However Steve +offered to host a web cast session in September where he would discuss +the contents of ICAT 4.3.

+

It was agreed to invite members of the collaboration to offer to host a +face to face meeting of ICAT in March 2014.

+

Steve discussed the status of ICAT 4.3 and reported that progress was +good. He will make a snapshot of the software and the documentation +available to interested parties later in August. Following that, he will +release ICAT 4.3. During September, he will host a webcast session to +discuss ICAT 4.3.

+

There are no known problems with the production deployments.

+

Ivan reported that he was making progress with ICAT. At the moment he is +investigating how to integrate ICAT with other meta data systems at +CCFE.

+

Steve reported that he intends to move www.icatproject.org to a new host +during August. The new host will be located within STFC and have a new +IP address. This change should not affect anyone using the resources +such as the maven repository on www.icatproject.org.

+

The meeting concluded at +15h30.

+

Actions 64

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionResStatus
64.00Document the meeting and update the actionsAlistairDone
64.01Invite invitations to host the ICAT collaboration meeting in March ’14AlistairDone
64.02Schedule a web cast on the contents of ICAT 4.3 for SeptemberSteve.
64.03Make snapshots of ICAT 4.3.rc available for comment in AugustSteve.
61.01Put the simple ICAT browser into contrib when it is readyTom.
60.03Finalise a release of IJP and send a note to the mailing listSteve.
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2013-meetings/meeting-65-5-september-2013/index.html b/collaboration/communication/monthly-meetings/2013-meetings/meeting-65-5-september-2013/index.html new file mode 100644 index 000000000..375c12d97 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2013-meetings/meeting-65-5-september-2013/index.html @@ -0,0 +1,104 @@ +Meeting 65 – 5 September 2013 | ICAT Project

ICAT Project

Search

Meeting 65 – 5 September 2013

    +
  • Actions from the meeting 64 (Alistair)
  • +
  • Status of ICAT 4.3 (Steve)
  • +
  • Issues from ICAT production deployments (All)
  • +
  • AOB (All)
  • +
+

Notes 65

+

Present: Alistair (STFC/chair), Kevin (STFC), Tom (ISIS), Idrissou +(Soleil) and Steve (STFC)

+

There has been an offer from ISIS to host the face to face meeting in +March 2014. It was agreed to accept this offer and the chairman thanked +Tom for the offer. The meeting is likely to be held in collaboration +with the final meeting of Pandata.

+

Steve reported that progress on the collection of parts associated with +release of ICAT 4.3 was going well. There are a small number of +interdependencies. For example ICAT 4.3 requires a new version of +Icat-setup. The authn_db has also changed. There was a discussion of +detection of compatibilities. It was agreed to review these, following +experience of using the new versions of the parts.

+

There were no issues with any production deployment. However Tom +reported that he was very keen to move to ICAT 4.3 as it solves some of +his difficulties.

+

There was a question about the status of IDS. Steve reported the +technical work was going well, and that a version for comment would be +available in October. Tom asked that this version be available soon, +even if some advanced features for remote file systems are not +supported.

+

The meeting concluded at +15h30.

+

Actions 65

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionResStatus
65.00Document the meeting and update the actionsAMDone
65.01Discuss the arrangements for ICAT 2014 with PandataTG/AMDone
65.02Provide feedback on ICAT 4.3 and its related partsAllOn-going
65.03Meet again on 19 SeptemberAllDone
64.02Schedule a web cast on the contents of ICAT 4.3 for SeptemberSteve.
64.03Make snapshots of ICAT 4.3.rc available for comment in AugustSteveDone
61.01Put the simple ICAT browser into contrib when it is readyTom.
60.03Finalise a release of IJP and send a note to the mailing listSteve.
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2013-meetings/meeting-66-19-september-2013/index.html b/collaboration/communication/monthly-meetings/2013-meetings/meeting-66-19-september-2013/index.html new file mode 100644 index 000000000..6125a9efe --- /dev/null +++ b/collaboration/communication/monthly-meetings/2013-meetings/meeting-66-19-september-2013/index.html @@ -0,0 +1,118 @@ +Meeting 66 – 19 September 2013 | ICAT Project

ICAT Project

Search

Meeting 66 – 19 September 2013

    +
  • Actions from the meeting 65 (Alistair)
  • +
  • Status of ICAT 4.3 (Steve)
  • +
  • Update from Pandata (Alistair)
  • +
  • Status of IDS (Steve)
  • +
  • AOB (All)
  • +
+

Notes 66

+

Present: Alistair (STFC/chair), Frazer (ISIS), Tom (ISIS), George +(Elettra), Milan (Elettra), Julien (ESRF), Shelly (SNS) and Steve (STFC)

+

Apologies: Jamie (ILL)

+

The date of the ICAT face to face meeting in 2014 was discussed. The +final Pandata meeting is scheduled for 29 March 2014 in Dublin to meet +in the same week as the RDA meeting in Dublin. The last three face to +face meetings in 2011 (Paris), 2012 (Grenoble) and 2013 (Lund) were +schedule to meet in the same week as a Pandata meeting. It was agreed +that we would defer a decision on the date until more information is +available about a successor project to Pandata. It is likely that +ICAT-2014 will be in May 2014. We will try to settle the data by +December 2013.

+

Tom reported that a bug in +NxIngest? had +been detected and corrected.

+

Steve reported that the snapshots for ICAT 4.3 and related components +are available and he would like more feedback.

+

Steve reported that progress on IDS 1.0 was good, and that it should be +available in October/November.

+

Tom reported that Mantid now supports ICAT 4.2.

+

Shelly reported that SNS is now investigating the use of ICAT with +autoreduction.

+

Alistair reported that he is arranging a two day training course for +technical people in Pandata. The training will include the installation, +deployment and operations of the latest ICAT materials including their +integration with Apache. The training will also cover Topcat, IDS, +Umbrella.

+

The meeting concluded at +15h30.

+

Actions 66

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionResStatus
66.00Document the meeting and update the actionsAMDone
66.01Fix the dates of the ICAT and Pandata meetings in Spring 2014TG/AM.
66.02Send a note to TG about NxingestAM.
66.03Send a note to the icat collaboration about the training for PandataAMhttps://code.google.com/p/pandata/wiki/TrainingSwInstallation
66.04Discuss autoreduction with Erica Yang and Shelly RenAM.
65.02Provide feedback on ICAT 4.3 and its related partsAllOn-going
64.02Schedule a web cast on the contents of ICAT 4.3 for SeptemberSteve.
61.01Put the simple ICAT browser into contrib when it is readyTom.
60.03Finalise a release of IJP and send a note to the mailing listSteve.
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2013-meetings/meeting-67-3-october-2013/index.html b/collaboration/communication/monthly-meetings/2013-meetings/meeting-67-3-october-2013/index.html new file mode 100644 index 000000000..857a56729 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2013-meetings/meeting-67-3-october-2013/index.html @@ -0,0 +1,94 @@ +Meeting 67 – 3 October 2013 | ICAT Project

ICAT Project

Search

Meeting 67 – 3 October 2013

    +
  • Actions from meeting 66 (Steve)
  • +
  • Status of ICAT 4.3 (Steve)
  • +
  • Status of IDS (Steve)
  • +
  • Issues from ICAT production deployments (All)
  • +
  • AOB (All)
  • +
+

Notes 67

+

Present: Milan, George, Shelly, Steve, Tom, Wayne and Frazer

+

It was noted that the date of the ICAT meeting in Spring next year is +not yet fixed. It should be done soon.

+

It was suggested that actions 61.01 and 60.03 should be removed as they +will be done when they are ready and are not urgent.

+

Tom reported on his work testing the ICAT4.3.0-SNAPSHOTs. There were +still some problems to be addressed with multiple rules. He suggested +that the installation script might check for the EJBTimer. This is +present when Glassfish is installed but might have been deleted. He had +been unable to use the installation scripts on +Windows.

+

Actions 67

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionResStatus
67.00Document the meeting and update the actionsSMFDone
66.01Fix the dates of the ICAT and Pandata meetings in Spring 2014TG/AM.
66.02Send a note to TG about NxingestAM.
66.04Discuss with Erica Yang issues of mutual concernShelly.
65.02Provide feedback on ICAT 4.3 and its related partsAllDone
64.02Schedule a web cast on the contents of ICAT 4.3Steve.
61.01Put the simple ICAT browser into contrib when it is readyTomDrop
60.03Finalise a release of IJP and send a note to the mailing listSteveDrop
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2013-meetings/meeting-68-17-october-2013/index.html b/collaboration/communication/monthly-meetings/2013-meetings/meeting-68-17-october-2013/index.html new file mode 100644 index 000000000..f66fbeeb0 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2013-meetings/meeting-68-17-october-2013/index.html @@ -0,0 +1,107 @@ +Meeting 68 – 17 October 2013 | ICAT Project

ICAT Project

Search

Meeting 68 – 17 October 2013

    +
  • Actions from meeting 67 (Alistair)
  • +
  • Status of ICAT 4.3 (Steve)
  • +
  • Status of IDS (Steve)
  • +
  • Status of TopCAT (Wayne)
  • +
  • Issues from ICAT production deployments (All)
  • +
  • AOB (All)
  • +
+

Notes 68

+

Present: Steve, Tom, Wayne, Frazer, Alistair, Kunal

+

Tom reported that the date of the Spring meeting was still being +discussed.

+

As discussed at the previous meeting actions 61.01 and 60.03 have been +dropped – they will be done at some stage.

+

There had been a lot of useful feedback on the ICAT 4.3.0 snapshots +resulting in a number of improvements. The only remaining issue was the +inability to install it on Glassfish 4.

+

There has been some progress with the IDS but not much as Steve has been +working mostly on ICAT. He plans to make some changes to the API to make +it more convenient to use.

+

Wayne reported that there had been a review of TopCAT issues out of +which the items that should be fixed for the next release were +identified. He is working on interfacing to ICAT 4.3.0 but does not have +one installed. Tom suggested he should use the ISIS one. Tom will also +check to see if he has anything else to add to the issue +list.

+

Actions 68

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionResStatus
68.00Document the meeting and update the actionsAMDone
68.01Check that the list of requirements for TopcatTGDone
68.02Check that the topcat43 plugins works with ICAT 4.3.0WCDone
68.03Get a credential from ISIS to access the ISIS TopcatWCDone
68.04Talk to Bill and Stefan about Umbrella authentication plugin for ICATSMFDone
66.01Fix the dates of the ICAT and Pandata meetings in Spring 2014TG/AM.
66.02Send a note to TG about NxingestAMDone
66.04Discuss with Erica Yang issues of mutual concernShelly.
64.02Schedule a web cast on the contents of ICAT 4.3Steve.
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2013-meetings/meeting-69-31-october-2013/index.html b/collaboration/communication/monthly-meetings/2013-meetings/meeting-69-31-october-2013/index.html new file mode 100644 index 000000000..74f5bdd01 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2013-meetings/meeting-69-31-october-2013/index.html @@ -0,0 +1,123 @@ +Meeting 69 – 31 October 2013 | ICAT Project

ICAT Project

Search

Meeting 69 – 31 October 2013

    +
  • Actions from meeting 68 (Alistair)
  • +
  • Status of ICAT 4.3 (Steve)
  • +
  • Status of IDS (Steve)
  • +
  • Status of TopCAT (Steve)
  • +
  • Issues from ICAT production deployments (All)
  • +
  • AOB (All)
  • +
+

Notes 69

+

Present: Steve, Frazer, Alistair, Kunal, Milan

+

Apologies: Shelly, Jamie, Christophe, Tom

+

Steve reported that he had talked to Bill and Stefan in ISIS about +Umbrella authentication. He also reported that he had exchanged emails +with Bjorn at PSI. He said that he was making progress, but it was not +possible to say when it would work, as completion is dependent on the +collaboration of the group.

+

Steve reported that ICAT 4.3.0 was now available and he had only on +reported fault.

+

Steve reported that he was now working on IDS, and that he was confident +that the IDS release will be ready in November 2013.

+

Steve reported that Wayne is making good progress with Topcat. It is +expected that Topcat 2.0 will be available in November 2013 and include +support for IDS.

+

Frazer reported that ISIS now has ICAT 4.3 available with Topcat 1.9.

+

Steve reported that ISIS now has ICAT 4.3 available with Topcat 1.9.

+

Milan reported that SV6 is due on 1 November and that the tests are +running correctly at Elettra.

+

Alistair reported that the materials for the training course on in the +installation of the Pandata software stack are almost ready and that the +course will take place next week.

+

Alistair reported that good progress was being made with the ingester +for ESRF and that ingestion into the production ICAT at ESRF will start +during November.

+

(Ed’s note – Jamie sent a report that ILL has recruited an additional +engineer to work on the ILL catalogue. The engineer will start work in +November).

+

Actions 69

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionResStatus
69.00Document the meeting and update the actionsAMDone
69.01Make use of the new ISIS ICAT in SV6 on 1 NovemberAMDone
69.02Make use of the new DLS ICAT in SV6 on 1 NovemberAMDone
69.03Discuss that training course for Pandata and make changes to the materialsAM/SFDone
66.01Fix the dates of the ICAT and Pandata meetings in Spring 2014TG/AMDone
66.02Send a note to TG about NxingestAMDone
66.04Discuss with Erica Yang issues of mutual concernShellyDone
64.02Schedule a web cast on the contents of ICAT 4.3SteveCancelled
61.01Put the simple ICAT browser into contrib when it is readyTom.
60.03Finalise a release of IJP and send a note to the mailing listSteve.
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2013-meetings/meeting-70-12-december-2013/index.html b/collaboration/communication/monthly-meetings/2013-meetings/meeting-70-12-december-2013/index.html new file mode 100644 index 000000000..d631699b9 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2013-meetings/meeting-70-12-december-2013/index.html @@ -0,0 +1,125 @@ +Meeting 70 – 12 December 2013 | ICAT Project

ICAT Project

Search

Meeting 70 – 12 December 2013

    +
  • Actions from meeting 69 (Alistair)
  • +
  • Status of ICAT 4.3 and related parts such as authn (Steve)
  • +
  • Status of IDS (Steve)
  • +
  • Status of TopCAT (Wayne)
  • +
  • Training and SV for Panadata (Alistair)
  • +
  • Issues from ICAT production deployments (All)
  • +
  • AOB (All)
  • +
+

Notes 70

+

Present: Steve, Wayne, Alistair, Shelly, Tom

+

The actions were reviewed and their stati updated/

+

The face to face meeting for 2014 has been set for 24-25 March. The +venue is the Department of Computer Science at Trinity College, Dublin.

+

There will be releases of ICAT, Topcat, Authn_shib and IDS around the +end of 2013, or the beginning of 2014.

+

A collection of ICAT parts will be tested as a group and adopted by +Pandata as part of the Pandata software stack release in January 2014.

+

There is a need to investigate the use of ICATs sharing a single lucene +index.

+

There was discussion about the ICAT collaboration meetings. It was +agreed to reduce the frequency of meetings from fortnightly to monthly. +It was agreed to investigate the use of alternative technology for the +meetings. The present arrangements with voice only connections in a +telephone conference does not support visual means of +communication.

+

Actions 70

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionResStatus
70.0Document the meeting and update the actionsAMDone
70.1See Juan about the ICAT meeting in DublinTGDone
70.2Close actions 66.04 and 64.02AMDone
70.3Release ICAT 4.3.1SFDone
70.4Release update to the SNAPSHOT IDS and the python apiSFDone
70.5Release Topcat 1.11SFDone
70.6Test a collection of ICAT parts as Pandata release 003AMIn progress
70.7Investigate 2 icats sharing a lucene indexSFTo be considered as part of the Road Map
70.8Release the shibboleth authenticator for use by UmbrellaSFDone
70.9Schedule a set of meetings for ICAT in 2014 and investigate alternative technologyKunalIn progress – transferred to Kunal
61.01Put the simple ICAT browser into contrib when it is readyTom.
60.03Finalise a release of IJP and send a note to the mailing listSteve.
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2014-meetings/index.html b/collaboration/communication/monthly-meetings/2014-meetings/index.html new file mode 100644 index 000000000..adf73fcdf --- /dev/null +++ b/collaboration/communication/monthly-meetings/2014-meetings/index.html @@ -0,0 +1,19 @@ +2014 Meetings | ICAT Project

ICAT Project

Search

2014 Meetings

+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2014-meetings/meeting-71-31-january-2014/index.html b/collaboration/communication/monthly-meetings/2014-meetings/meeting-71-31-january-2014/index.html new file mode 100644 index 000000000..ebe0fc62b --- /dev/null +++ b/collaboration/communication/monthly-meetings/2014-meetings/meeting-71-31-january-2014/index.html @@ -0,0 +1,116 @@ +Meeting 71 – 31 January 2014 | ICAT Project

ICAT Project

Search

Meeting 71 – 31 January 2014

    +
  • Actions from meeting 70 (Steve)
  • +
  • Meeting technology (Alistair)
  • +
  • Meeting in Dublin in March (Alistair)
  • +
  • ICAT roadmap (Steve)
  • +
  • Status of recent releases (Steve)
  • +
  • Coordination of IDS plugins (Andy/Christophe)
  • +
  • Release and SV for Pandata (Alistair)
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • AOB (Any)
  • +
+

Notes 71

+

Present: Rolf, Shelley, Milan, Alistair, Kunal and Steve

+

Apologies: Tom

+

Kunal had looked at a number of choices including +GoToMeeting? and +Teamviewer. Evo was also suggested as another possibility. He will try +out one or more products with Milan and Shelley and report back.

+

Alastair explained that the current Dublin meeting agenda was currently +a clone of that for the the last meeting. Steve requested that any site +reports should highlight any problems.

+

Steve went through the draft Road Map. A lot of useful ideas were put +forward which will be reflected in the map:

+
    +
  • Documentation improvements are needed for search and authorization +(doing it efficiently)
  • +
  • Rolf has data export/import for his python code but it is quite +slow. He uses yaml syntax with ids replaced by the uniqueness +constraint fields which is similar to what Steve had in mind.
  • +
  • It was suggested again that it would be good to isolate the +federation part of Topcat. This might be a service in its own right.
  • +
  • There was a suggestion that ICE should be incorporated into TopCAT.
  • +
+

 

+

PaNData service verification will start tomorrow.

+

Alistair said that he planned to produce a report on ICAT from PaNData. +Steve asked him to make sure that problems were promptly reported in the +usual way (the appropriate googlecode issue list) so that any issues +could be addressed as soon as possible.

+

Milan had found a problem with TopCAT for which he will submit a bug +report

+

Actions 71

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionAssignedStatus
71.0Organise the Dublin meetingAlistairIn progress
71.1Update road map with ideas from meetingSteveNew
71.2Submit TopCAT bug reportMilanNew
71.3Invite WP4 of Pandata to provide feedback on their experience of ICAT productsAlistairNew
70.6Test a collection of ICAT parts as Pandata release 003AlistairIn progress
70.9Investigate alternative meeting technologyKunalIn progress
61.1Put the simple ICAT browser into contrib when it is readyTomPending
60.3Finalise a release of IJP and send a note to the mailing listStevePending
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2014-meetings/meeting-72-27-february-2014/index.html b/collaboration/communication/monthly-meetings/2014-meetings/meeting-72-27-february-2014/index.html new file mode 100644 index 000000000..7bf694282 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2014-meetings/meeting-72-27-february-2014/index.html @@ -0,0 +1,146 @@ +Meeting 72 – 27 February 2014 | ICAT Project

ICAT Project

Search

Meeting 72 – 27 February 2014

Agenda

+
    +
  • Actions from meeting 71 (Steve)
  • +
  • Meeting technology (Kunal)
  • +
  • Meeting in Dublin in March (Alistair)
  • +
  • ICAT roadmap (Steve)
  • +
  • ICAT development (Steve)
  • +
  • TopCAT development (Wayne)
  • +
  • Coordination of IDS plugins (Andy/Christophe)
  • +
  • Release and SV for Pandata (Alistair)
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • AOB (Any)
  • +
+

Notes 72

+

Present: Milan, Shelly, Ivan, Alistair, Christophe, Anton, Kunal, Tom, +Wayne and Steve

+

Apologies: Rolf

+

Action 71.0 – there has not been much progress yet with the preparation +of the Dublin meeting besides essentials such as a room to meet in. This +will be rectified over the next few weeks. It will not appear on the +actions list as there will be no further meeting before Dublin. Tom +volunteered Jay to talk about integration of ICAT and Mantid and also to +talk about his experience (as someone new to ICAT) with the ICAT API.

+

Action 71.1 – this has now been completed and the first version +finalised. Steve will circulate a note with probable time scales for the +items on the road map. The time scales may become part of the map when +it is next revised.

+

Action 71.2 – a request has been sent in to the icat-support list Wayne +is in discussion with Milan about it. This will be closed.

+

Action 70.6 – +PanData? release +003 has exhibited no problems. This action will be closed.

+

Action 70.9 – Kunal has been investigation alternative meeting +technologies. He has tried a meeting using Google Hangouts with Shelley +and Milan and all were favourably impressed. It was noted that it did +take a little while to get used to but the functionality was excellent. +Kunal will register people as required and will set up a test meeting +for anyone who wants to familiarise themselves with the technology so +that the next ICAT collaboration meeting progresses smoothly. This will +be in a around two weeks time.

+

Agenda items except where covered by actions:

+

Steve reported on ICAT progress and the problems he has been having +trying to add a servlet to the icat ear file. He will work around the +problem for now with a SOAP interface for the lucene communication.

+

Wayne reported that he had been discussing the behaviour of TopCAT with +Milan. The next release of TopCAT will include data upload.

+

Christophe explained that the IDS plugin mechanism did not give him the +flexibility he needed. He will send a note to Steve explaining what he +needs.

+

The PanData? SV +has shown up a problem accessing the ISIS ICAT. This may be a firewall +problem somewhere as it used to work. Alistair will follow up on any +possible firewall issues. In about 3 week’s time the SV will concentrate +on Umbrella.

+

Tom asked if anybody had seen any odd behaviour with case sensitivity of +searches.

+

Tom will submit his authz rules to the contrib directory.

+

Alistair has discovered proxyvole to search for and use existing proxy +configurations. This will be used in the next SV.

+

Christophe asked how to record which instrument a dataset is related to +now that we have a many to many relation between investigation and +instrument. Besides using a +DatasetParameter? no +other suggestion was +offered.

+

Actions 72

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionAssignedStatus
72.0Circulate likely time-scales for the items on the current road mapSteveNew
72.1Organise a Hangout familiarisation meetingKunalNew
72.2Send note to Steve about the shortcomings of the IDS plugin interfaceChristopheNew
72.3Understand why SV’s fail when ISIS ICAT is contactedAlistairNew
72.4Raise an issue on case sensitivity of searchesTomNew
72.5Add authz rules to contrib directoryTomNew
71.3Invite WP4 of Pandata to provide feedback on their experience of ICAT productsAlistairPending
61.1Put the simple ICAT browser into contrib when it is readyTomPending
60.3Finalise a release of IJP and send a note to the mailing listStevePending
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2014-meetings/meeting-73-24-april-2014/index.html b/collaboration/communication/monthly-meetings/2014-meetings/meeting-73-24-april-2014/index.html new file mode 100644 index 000000000..1f3ec8bf1 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2014-meetings/meeting-73-24-april-2014/index.html @@ -0,0 +1,111 @@ +Meeting 73 – 24 April 2014 | ICAT Project

ICAT Project

Search

Meeting 73 – 24 April 2014

Agenda

+
    +
  • Actions from meeting 72 (Steve)
  • +
  • ICAT development (Steve)
  • +
  • TopCAT development (Wayne)
  • +
  • Alternatives to Glassfish (Any)
  • +
  • Issuing DOIs for ICAT (Tom)
  • +
  • ICAT roadmap update (Steve)
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • AOB (Any)
  • +
+

Notes 73

+

Present: Steve, Wayne, Kunal, Tom, Shelly

+

Apologies: Milan, Anton, Rolf

+

The meeting startup was delayed by about 10 minutes because of mistakes +in setting up a laptop at RAL. Action 72.0 – Circulate likely +time-scales for the items on the current road map is no longer relevant +as a new roadmap – with dates – will be discussed in this meeting – +Closed

+

Action 72.1 – Kunal had organised a Hangout familiarisation meeting last +week – Closed

+

Action 72.2 – The IDS plugin interface was discussed in Dub with SSIlin +and the views of Christophe accepted – Closed Action 72.3 – Tom +explained that Alistair had had some misconfiguration – Closed

+

Action 72.4 – Fixed in 4.3.3 – Closed

+

Steve reported on the 4.3.3 SNAPSHOTs of the server and client. Shelly +asked about the need to use Glassfish 4. Steve explained that Glassfish +4 was used for testing and that it allowed the deployment order of +components to be defined but that version 3 of Glassfish should still +work.

+

Wayne reported that the next TopCAT release was delayed by about a +month. Various bug fixes had been made but the upload facility was not +yet complete.

+

Kunal has started looking at WildFly as an alternative container. He +will report next month.

+

Tom explained his ideas about issuing DOIs for the ICAT software. He +will put this into a posting in order to get feedback on the desired +granularity – Action

+

Steve explained the updated roadmap. A couple of small changes were +suggested and having reassured Tom that nothing had been removed besides +giving consideration to integration of ICE into TopCAT and the +construction of a federation service there was agreement that the +updated roadmap – with the two extra changes from the meeting should +replace the existing roadmap, but that the existing one be preserved on +the web site to show progress. Changes to multi-ICAT searching were +discussed, including providing mockups of the proposed designs.

+

Tom reported that Kevin had been updating their ICAT 4.3.2 to use +Glassfish 4. He had had some problems with certificates.

+

Shelly asked about the date of the next meeting. It is normally held on +the last Thursday of the month – so in this case the 29th +May.

+

Actions 73

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionAssigned
73.0Send round a proposal for ICAT DOIsTom
73.1Report on issues porting to WildFlyKunal
73.2Send around details of Balsamiq mockupsTom
72.5Add authz rules to contrib directoryTom
71.3Invite WP4 of Pandata to provide feedback on their experience of ICAT productsAlistair
61.1Put the simple ICAT browser into contrib when it is readyTom
60.3Finalise a release of IJP and send a note to the mailing listSteve
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2014-meetings/meeting-74-29-may-2014/index.html b/collaboration/communication/monthly-meetings/2014-meetings/meeting-74-29-may-2014/index.html new file mode 100644 index 000000000..9f32ef8b5 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2014-meetings/meeting-74-29-may-2014/index.html @@ -0,0 +1,126 @@ +Meeting 74 – 29 May 2014 | ICAT Project

ICAT Project

Search

Meeting 74 – 29 May 2014

Agenda

+
    +
  • Actions from meeting 73 (Steve)
  • +
  • Steering Group (Tom or any other member)
  • +
  • ICAT development (Steve)
  • +
  • IDS development (Steve)
  • +
  • TopCAT development (Wayne)
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • AOB (Any)
  • +
+

Notes

+

Present: Kunal, Alistair, Wayne, Kevin, Tom, Milan, Steve

+

Apologies: Anton, Rolf, Shelly

+

Action 73.0 – Tom has sent a note around about DOIs and has already +received one reply.

+

Action 73.1 – Kunal reported his Wildfly findings – primarily the need +for a java:/ in front of a field in the persistence.xml. Steve then +reported that he had managed to install an ICAT with one authenticator +but that testicat would not run properly because the published wsdl was +a little different and meant that it was not possible to use SUDS to +create a credential object – so logging in was not possible. Steve +commented that in may respects Wildfly is more regular than Glassfish +and that the support on the forum is excellent. Having demonstrated that +there appear to be no major problems he will take this work further at +some later date with the intention of updating the setup script to +modify the glassfish version of the .war file and to deploy it on +wildfly. Kunal has done some work preparing scripts but does not have +the time currently. Steve has also tried TomEE+ but found that this was +harder to get started with. Probably work on TomEE+ will be delayed for +much longer as Wildfly appears to be a viable alternative to Glassfish. +Tom asked for JDBC connector resilience with Wildfly to be checked.

+

Action 73.2 – Tom has sent around details of Balsamiq.

+

Action 72.5 – Tom is tidying up the rules and will then share them

+

Action 71.3 – Alistair said that he did not intend to carry out this +action. Milan suggested that a round table at the forthcoming +PanData?workshop +could address this. The workshop is before the next meeting so the +action will be removed.

+

Tom reported on the ICAT Steering Group which had its first meeting last +week.The main items of discussion were the ToR and the choice of +chairman. The meeting has not yet chosen a chairman. TopCAT was also +discussed. The consensus was that TopCAT would be needed but that two +labs still needed to have their own bespoke interface as well.The work +of the group will be public and the ToR (once finalised) and the minutes +of the meetings will appear on icatproject.org.

+

Steve reported on ICAT development. The 4.3.3-SNAPSHOT was made +available around the end of April for both server and client. Note that +the updated documentation for the client is with the client as the +server and client are now released separately. No feedback has been +received yet. Work on producing a RESTful interface covering at least +import and export has started. As a consequence of a chnage made to +facilitiate deployment on Wildlfy icat will now be packaged as a .war +file instead of a .ear file. This has fixed the problem reported earlier +on deploying a RESTful interface side by side with a SOAP interface.

+

Steve also reported on the IDS development for which a snapshot is also +available. Rolf has deployed in but found that had disabled the +background data checking. Steve hopes that this can be restored but at a +level where it does not have too big an impact. A change is being made +to support file uploads from TopCAT using POST.

+

Wayne then reported on TopCAT. The remaining work preventing the next +release is the file upload. The file can be uploaded but he is not able +to see whether or not the operation was successful because of the +same-origin policy enforced by the browser. He is lookign for a +work-around. Next week he plans to use Balsamiq to mock up a new TopCAT +interface with the hope that it can be shown at the forthcoming +PanData? workshop +to attract feedback.

+

Tom reported that he had been working with Kevin to fix a problem when +the Oracle RAC nodes go down and no failover takes place. The solution +should appear in the installation scripts or at least be documented. Tom +also reported that as a test he had tried deleting all the +investigations for an instrument and that it took about a second for +each investigation (which is the top of a tree of course) so he resorted +to a direct operation on the database.

+

There were no AOB +items.

+

Actions

+

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionAssigned
74.0Look into JDBC connector resilience with WildflySteve
74.1Document or implement in setup script the JDBC connector fix for Glassfish/OracleKevin or Steve
72.5Add authz rules to contrib directoryTom
61.1Put the simple ICAT browser into contrib when it is readyTom
60.3Finalise a release of IJP and send a note to the mailing listSteve
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2014-meetings/meeting-75-26-june-2014/index.html b/collaboration/communication/monthly-meetings/2014-meetings/meeting-75-26-june-2014/index.html new file mode 100644 index 000000000..75c6cf62b --- /dev/null +++ b/collaboration/communication/monthly-meetings/2014-meetings/meeting-75-26-june-2014/index.html @@ -0,0 +1,134 @@ +Meeting 75 – 26 June 2014 | ICAT Project

ICAT Project

Search

Meeting 75 – 26 June 2014

Agenda

+
    +
  • Actions from meeting 74 (Steve)
  • +
  • DOIs – next steps (Tom)
  • +
  • Report from recent PanData meeting (Alistair and others)
  • +
  • Actions from the PanData meeting (Steve and others)
  • +
  • ICAT development (Steve)
  • +
  • InvestigationGroup (Rolf)
  • +
  • IDS development (Steve)
  • +
  • TopCAT development (Wayne)
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • AOB (Any)
  • +
+

Notes

+

Present: Kunal, Alistair, Wayne, Brian M, Rolf, Milan, Steve

+

Apologies: Tom, Shelly, Kevin

+

Action 72.5 – Add authz rules to contrib directory has been done by Tom +who has provided some code

+

Action 74.1 – Document or implement in setup script the JDBC connector +fix for Glassfish/Oracle. Kevin and Steve have discussed this but it has +not yet gone into the setup script. It has not gone into the list of +issues for ICAT for milestone release 4.4 so will be removed from here.

+

Actions from the PanData meeting. A number of items were raised – these +are recorded below as actions 75.0 to 75.6. In addition, the following +have already been done:

+
    +
  1. a diagram overview of the system has been added at +http://icatproject.org/about/components-of-the-icat-project/
  2. +
  3. a bug has been submitted against ICE as it does not work in Safari
  4. +
  5. a bug has been submitted against authn_db to allow ldap to bind as +a user defined in auth_db.properties
  6. +
+

Alistair suggested that the TopCAT mockup should make use of icons to +help identify facilities and make more sensible use of colour (add to +the TopCAT issues list) and that we should use local expertise in +graphic design.

+

ICAT development – Steve reported that 4.3.3 client had been released +and that a new 4.3.3 snapshot for the server had been made available. +This snapshot addresses bugs found by Tom in his testing with multiple +ICAT servers.

+

InvestigationGroup – Rolf asked us to go ahead with the addition of the +InvestigationGroup. The only disadvantage raised was that it would make +the system slightly more complex. Steve said he thought that the only +person with reservations about the proposal was Tom. Steve suggested +that unless Tom had a convincing argument for not doing so, then the new +entity type would be added to ICAT 4.4.

+

TopCAT development – Wayne requested a revised IDS snapshot to allow him +to complete testing of 1.12. The upload is now almost ready.

+

AOB – Alistair told us that the final PanData service verification was +about to start and that it would use the latest 4.3.3-SNAPSHOT. He also +said that he had been contacted by SSI who had reviewed the ICAT project +a few years ago. He observed that of the 34 recommendations they had +made 26 had been implemented. The meeting agreed that if SSI wish to +repeat the exercise we would agree to +it.

+

Actions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionAssigned
75.0Produce a diagram and description of the schemaSteve
75.1Consider using a config file rather than topcatadminWayne
75.2Convert balsamiq desktop licences to web and consider suitable license for open source software developmentTom
75.3Publish improved TopCAT mockupWayne
75.4Submit TopCAT requirementsAndy
75.5Contact Christian Felder concerning future of py-icatSteve
75.6Check that existing release of IDS includes facility name in the ZIP pathAlistair
75.7Produce new IDS snapshotSteve
74.0Look into JDBC connector resilience with WildflySteve
61.1Put the simple ICAT browser into contrib when it is readyTom
60.3Finalise a release of IJP and send a note to the mailing listSteve
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2014-meetings/meeting-76-24-july-2014/index.html b/collaboration/communication/monthly-meetings/2014-meetings/meeting-76-24-july-2014/index.html new file mode 100644 index 000000000..fe95f1f48 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2014-meetings/meeting-76-24-july-2014/index.html @@ -0,0 +1,121 @@ +Meeting 76 – 24 July 2014 | ICAT Project

ICAT Project

Search

Meeting 76 – 24 July 2014

Agenda

+
    +
  • Actions from meeting 75 (Steve)
  • +
  • DOIs – next steps (Tom)
  • +
  • ICAT development (Steve)
  • +
  • InvestigationGroup (Rolf/Tom)
  • +
  • IDS development – and linking proposal (Steve)
  • +
  • TopCAT development (Wayne)
  • +
  • Roadmap (Steve)
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • AOB (Any)
  • +
+

Notes

+

Present : Alastair, Steve, Kevin, Wayne, Brian R, Milan, Kunal, Tom, +Condie and Shelly
+Apologies : Rolf

+

This was the first meeting for Brian Ritchie who has started work on the +IJP and for Condie Mckenzie-Smith who is working  with Tom for a year.

+
    +
  • Action 75.0 to produce a diagram and description of the schema has +been done.
  • +
  • Tom is awaiting a reply on the balsamiq license for open source +development (75.2). Meanwhile he has provided a license that can be +used to get started with the web (rather than desktop) version.
  • +
  • Wayne (75.3) has moved the TopCAT mockup to the web version of +balsamiq but wants to make more changes before sharing it. Tom +expressed an interest in making available what had been done so far.
  • +
  • Steve has contacted Christian Felder concerning the future of +py-icat (75.5). Christian is still interested but acknowledges that +the current version needs updating to make it work with ICAT 4.3.
  • +
  • IDS 1.1.0 has been released (75.7)
  • +
  • The action to put the simple ICAT browser into contrib (60.1) has +been transferred to Condie.
  • +
+

Tom spoke on next steps for DOIs. As we have agreement on what to do, +Steve will look at the scripts which are used by mantid to see if they +can easily be integrated into the release process – new Action 76.0

+

Steve spoke on the ICAT development and mentioned that ICAT 4.3.3 had +been released and that the restful interface for 4.4.0 was well +underway. The import/export and session management were complete and +search and create are now being worked on. The client calls are as far +as possible like the SOAP ones however the interfaces are quite +independent and a generator of entity objects for a Java and Python +client will be needed.

+

The discussion on InvestigationGroup was postponed to the next meeting +when we hope Rolf and Tom will coincide.

+

Steve spoke briefly about the IDS linking proposal. Tom thought it might +be useful to ISIS  in the future.

+

Wayne spoke about TopCAT development. 1.12.0-SNAPSHOT has been made +available. Christophe had tried it and only had a few minor criticisms.

+

Steve suggested that the interval between roadmap updates should be +increased from three to four months. It was suggested that he send out +an email to request suggestions which will then be discussed at the next +monthly meeting.

+

Tom reported a couple of issues from ISIS with TopCAT’s use of the IDS. +One problem is that TopCAT can generate URLs that are too +long.

+

Actions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionAssigned
76.0Look into using variant of mantid scripts to publish DOIs for ICAT software.Steve
75.1Consider using a config file rather than topcatadminWayne
75.2Convert balsamiq desktop licences to web and consider suitable license for open source software developmentTom
75.3Publish improved TopCAT mockupWayne
75.4Submit TopCAT requirementsAndy
75.6Check that existing release of IDS includes facility name in the ZIP pathAlistair
74.0Look into JDBC connector resilience with WildflySteve
61.1Put the simple ICAT browser into contrib when it is readyCondie
60.3Finalise a release of IJP and send a note to the mailing listSteve
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2014-meetings/meeting-77-28-august-2014/index.html b/collaboration/communication/monthly-meetings/2014-meetings/meeting-77-28-august-2014/index.html new file mode 100644 index 000000000..8b3551203 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2014-meetings/meeting-77-28-august-2014/index.html @@ -0,0 +1,121 @@ +Meeting 77 – 28 August 2014 | ICAT Project

ICAT Project

Search

Meeting 77 – 28 August 2014

Agenda

+
    +
  • Actions from meeting 76 (Steve)
  • +
  • ICAT development (Steve)
  • +
  • InvestigationGroup (Rolf/Tom)
  • +
  • IDS development (Steve)
  • +
  • TopCAT development (Wayne)
  • +
  • IJP development (Brian R)
  • +
  • Roadmap (Steve)
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • AOB (Any)
  • +
+

Notes

+

Present : Kunal, Condie, Tom, Kevin, Brian R, Steve, Milan, Rolf, +Shelly and Brian M.

+
    +
  • There were no comments on the minutes
  • +
  • Action 76.0 – Steve has modified Mantid scripts to generate DOIs and +store metadata for the ICAT components.
  • +
  • Action 75.2 – Tom has obtained balsamiq licences for web use for +open source software development.
  • +
  • Action 75.3 – Wayne has made balsamiq mockups of the proposed new +TopCAT available.
  • +
  • Action 75.6 – This can be taken as done.
  • +
  • Action 61.1 – One of Alistair’s students has been working on the +“Simple ICAT Browser”
  • +
  • Action 60.3 – The current IJP development makes a release much more +practical.
  • +
  • Steve reported that there had been no progress with the ICAT server +this month.
  • +
  • There was a good discussion on introducing the InvestigationGroup to +the schema. Tom was concerned that it could cause confusion by +offering two ways to do the same thing and that it might have a +negative impact upon performance. The agreement was to try the +InvestigationGroup in the 4.4.0-SNAPSHOT to ensure that there were +no practical problems. and to document that InvestigationGroup +should be used for authz and that  InvestigationUser entries should +be used only to indicate specific roles such as PI. The role +attribute might be made non-optional.
  • +
  • Steve described what was in the latest IDS SNAPSHOT.  Plugin +developers may need to update their plugins to suit. A new getLink +call has been added. Rolf confirmed that he had no objection to the +implementation of getLink.
  • +
  • Wayne had released the balsamiq mockups of the new TopCAT. These we +only made available very recently and it would seem that nobody had +examined them yet.
  • +
  • Steve explained that the batch side of the IJP had been factored out +into a different service. Different implementaions could be written +and the IJP would be able to make use of multiple batch services. He +has written one for the simple unix batch/atq/atrm system. Brian R +is working on a more serious one for IBM Platform LSF.
  • +
  • Steve having received no input on the roadmap, froze the existing +one as the April version and produced a new draft with those things +which had been released (even if only as SNAPSHOTs) being removed, a +few new bits added and dates made more realistic. Tom said his +priority was for rules controlling access to projections of the +tables (i.e. only some attributes being available), Shelly expressed +an interest in the import/export and Tom also said that FUSE access +would be very useful. Some work on this has already been carried out +by a student working for Alistair. The roadmap will be adjusted to +address these requests, discussed by e-mail and, if agreed, the word +“draft” removed next meeting.
  • +
  • Shelly said that she was going to NOBUGS and asked if anyone else +was going. Steve said that he had submitted an IDS abstract and +would be going. Brian M pointed out that it clashed with an RDA +meeting.
  • +
+

Actions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ITEMDESCRIPTIONASSIGNED
77.0Check the icatgroup list to ensure that people who should be present are addedSteve
77.1Update the roadmapSteve
75.1Consider using a config file rather than topcatadminWayne
75.4Submit TopCAT requirementsAndy
74.0Look into JDBC connector resilience with WildflySteve
61.1Put the simple ICAT browser into contrib when it is readyCondie
60.3Finalise a release of IJP and send a note to the mailing listSteve
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2014-meetings/meeting-78-18-september-2014/index.html b/collaboration/communication/monthly-meetings/2014-meetings/meeting-78-18-september-2014/index.html new file mode 100644 index 000000000..84e9c6113 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2014-meetings/meeting-78-18-september-2014/index.html @@ -0,0 +1,130 @@ +Meeting 78 – 18 September 2014 | ICAT Project

ICAT Project

Search

Meeting 78 – 18 September 2014

Agenda

+
    +
  • Actions from meeting 77 (Steve)
  • +
  • ICAT development (Steve)
  • +
  • An eclipse based ICAT editor  (Christophe)
  • +
  • IDS development (Steve)
  • +
  • TopCAT development (Wayne)
  • +
  • IJP development (Brian R)
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • AOB (Any)
  • +
+

Notes

+

Apologies: Milan and Alistair

+

Present: Wayne, Steve, David, Rolf, Andy, Kevin, Christophe, Brian M and +Brian R

+

Unfortunately Anton Telechev and Matt Viljoen were both unable to attend +because of problems with hangouts. I hope to understand what went wrong +so that we get it right next time.

+
    +
  • Action 77.0 – Steve has added a couple of people to the icatgroup +list – including Andy.
  • +
  • Action 77.1 – Steve updated the road map as agreed at the last +meeting. The main change was to include less in icat.server 4.4.0. +so that it could be released sooner. This had been advertised. One +person said he was happy and nobody opposed it so the word “Draft” +has been removed.
  • +
  • Action 75.1 – This action relating to topcatadmin is no longer +relevant as we are now thinking about TopCAT 2
  • +
  • Action 75.4 – Andy has prepared a set of Use Cases relevant to +TopCAT these should be publicised very soon.
  • +
  • Steve reported that progress with icat.server 4.4.0 is good. He has +two major things to solve – “the DISTINCT problem” which was a hack +introduced  to avoid multiple copies of the same entity being +returned when someone was authorized by more than one route and +authz to include projections. As the former is a bug rather than an +enhancement it will be tackled first. A release is expected in about +a month.
  • +
  • Christophe presented an Eclipse based ICAT editor. This has +functionality conceptually similar to that of ICE but is much more +pleasant to use and requires no installation. He had a problem with +an earlier version with huge combo box menus but has been able to +introduce a filtering mechanism to avoid this problem. It will be +made generally available very shortly.
  • +
  • Steve reported that updates to the various IDS components had been +made he referred to the release notes such as those for the +server +and for the +client +. There was a brief discussion on the limit imposed by the IDS +client on the size of URLs that it will send as GET calls. This may +result in a bug report.
  • +
  • Wayne stated that TopCAT 1.12.0 had been released. The alternative +layout proposals from Anton were discussed however as mentioned +above he was unfortunately not connected in. Anton’s diagrams seem +to show support of only one ICAT rather than multiple ICATs. Wayne +liked the generally simpler views that Anton presented and will +incorporate what he considers to be improvements from Anton. Ideas +which are not accepted will be discussed. Wayne will also make sure +that the use cases from Andy are accommodated by the design. There +was a brief discussion about the “shopping cart”. Wayne explained +that for single data files, datasets or investigations they could be +downloaded immediately without using the cart. Andy was interested +in having some visualization features if practical and also being +able to see more of the information that is available in ICAT.
  • +
  • Brian R described the work he had been doing on the IJP writing a +batch interface to talk to Platform LSF. The IJP has been modified +to talk to a standardised batch interface of which we now have +three. Andy said that they had potential users but they would need +to have support for OAR
  • +
  • Under AOB, Andy asked how to produce a robust ICAT deployment. Steve +said that since icat.server 4.3.3 multiple servers could communicate +with one database but they must be correctly configured. There is +also the issue of configuring glassfish to make good use of an +Oracle RAC
  • +
+

system.

+

Actions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ITEMDESCRIPTIONASSIGNED
78.0Release Eclipse based ICAT editorChristophe
78.1Merge Anton’s material and try to satisfy TopCAT uses cases from Andy.Wayne
78.2Make sure that install scripts and/or documentation includes configuration of glassfish for Oracle RAC systemKevin
75.4Submit TopCAT Use Cases/requirementsAndy
74.0Look into JDBC connector resilience with WildflySteve
61.1Put the simple ICAT browser into contrib when it is readyCondie
60.3Finalise a release of IJP and send a note to the mailing listSteve
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2014-meetings/meeting-79-30-october-2014/index.html b/collaboration/communication/monthly-meetings/2014-meetings/meeting-79-30-october-2014/index.html new file mode 100644 index 000000000..61f0f848e --- /dev/null +++ b/collaboration/communication/monthly-meetings/2014-meetings/meeting-79-30-october-2014/index.html @@ -0,0 +1,104 @@ +Meeting 79 – 30 October 2014 | ICAT Project

ICAT Project

Search

Meeting 79 – 30 October 2014

Agenda

+
    +
  • Actions from meeting 78 (Steve)
  • +
  • ICAT development (Steve)
  • +
  • ICAT Manager (Christophe)
  • +
  • IDS development (Steve)
  • +
  • TopCAT development (Wayne)
  • +
  • IJP development (Brian R)
  • +
  • Installation Script (Leonardo)
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • AOB (Any)
  • +
+

Notes

+

Apologies:  Christophe (who tried to join but was unable), Daniel and +Alistair.

+

Present: Shelly, Rolf, Milan, Brian M, Brian R, Kevin, Wayne, Steve, +Matt and Tom.

+
    +
  • Action 78:0 – Christophe has now made a number of releases of the +ICAT Manager.
  • +
  • Action 78.1 – Wayne has produced some new Balsamiq mockups
  • +
  • Action 78.2 – The glassfish configuration for Oracle RAC servers is +now part of the setup scripts.
  • +
  • Action 75.4 – Andy has submitted Use Cases for TopCAT
  • +
  • Action 60.3 – As this concerns the IJP it is being transferred to +Brian R.
  • +
  • Steve reported that the Rolf had tried ICAT 4.4.0 and that it seems +to work – but he had not tested the new parts (import/export and +other restful things) .  The code is also being tested for DLS but +other testers would be appreciated. The main issue to be resolved is +the presence of a “role” attribute in the InvestigationGroup table. +Rolf stated that the InvestigationGroup without a role attribute was +useless so we must add the attribute or abandon the +InvestigationGroup. The new agreement was to add the role and to +change the documentation to say that if you want separate the +authorization rules from who is actually on the proposal then you +can use both InvestigationUser and InvestigationGroup where +the InvestigationUser reflects the proposal and +the InvestigationGroup is used in authorization rules. +Otherwise InvestigationUser can be used for both purposes.
  • +
  • Steve then reported on the IDS. He has added support for archives +organised by datafile (prompted by DLS needs and which appears to +work well) in addition to organisation by dataset. He has also added +a new mechanism for handling prepareData (which just keeps the +expansion into datafile objects and triggers any restoration from +archive) and has simplified the interface for communicating which +datasets or datafiles to archive when main storage is running low. + There is currently a security problem which has been explained on +the icatgroup list. The problem is that the location field cannot be +trusted. There are two suggested ways to address this – passing more +information to the plugin to permit sanity checks to be made by the +plugin or adding a cryptographic hash to the location field – or +both. It has also been proposed to not pass the dataset.location via +the plugin interface. Tom thought that it was probably best to +include both solutions and nobody objected to the elimination of +dataset.location from the plugin interface.
  • +
  • Wayne reported that TopCAT 1.12 had been released and that yesterday +a big update to the balsamiq mock-ups had been announced. Not +surprisingly people had not yet studied them. Steve emphasised the +importance of making sure that these mock-ups appear to reflect what +people really want to see.
  • +
  • Brian R reported that he had – refactored lsfbatch to use shared +classes which ensure that all the IJP batch systems have a common +interface. He is now considering how to select and pass datafiles +(as well as datasets) to jobs. Wayne had suggested that it might be +worth using balsamiq to produce a mock-up of the revised GUI.
  • +
  • Tom said that they were trialling an “auto-reduction” system with + users next
  • +
+

week.

+

Actions

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ITEMDESCRIPTIONASSIGNED
74.0Look into JDBC connector resilience with WildflySteve
61.1Put the simple ICAT browser into contrib when it is readyCondie
60.3Finalise a release of IJP and send a note to the mailing listBrian R
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2014-meetings/meeting-80-27-november-2014/index.html b/collaboration/communication/monthly-meetings/2014-meetings/meeting-80-27-november-2014/index.html new file mode 100644 index 000000000..141d22664 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2014-meetings/meeting-80-27-november-2014/index.html @@ -0,0 +1,139 @@ +Meeting 80 – 27 November 2014 | ICAT Project

ICAT Project

Search

Meeting 80 – 27 November 2014

Agenda

+
    +
  • Actions from meeting 79 (Steve)
  • +
  • ICAT development (Steve)
  • +
  • ICAT Manager (Christophe)
  • +
  • IDS development (Steve)
  • +
  • TopCAT development (Wayne)
  • +
  • IJP development (Brian R)
  • +
  • Installation Script (Leonardo)
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • 2015 F2F Meeting and Steering Group Meeting (Steve and Andy)
  • +
  • AOB (Any)
  • +
+

Notes

+

Apologies: None
+Present: Matt, Tom, Kevin, Wayne, Steve, Brian R,Christophe, Milan, +Andy, Rolf

+
    +
  • Actions – No progress
  • +
  • ICAT development: Steve reported that “role” had been added to +InvestigationGroup as agreed last meeting. The icat.server 4.4.0 +would have been ready to go out except for the new idea about +allowing multiple roles which could be added very quickly if people +agree. It has been discussed today by e-mail. One more snapshot will +be produced with this change and in a few days time 4.4.0 will be +released.
    +The next release (4.5.0) will include extra RESTFul calls for the +benefit of TopCAT 2 making heavy use of the lucene indexing. Steve +would like to drop the existing searchText call if nobody is using +it. Tom will check with the Mantid people.  These three new calls +are currently very specialised. Maybe a more generic way can be +found in the future but this is not obvious.  The queries use the +notion of “my data” which is defined as the existence of an entry in +the InvestigationUser table (irrespective of role) to define the +relationship between an Investigation and a User. The meeting was +happy with this choice. The investigation call is complete and the +dataset call is almost complete. The datafile code has not yet been +started. It will be tested on a large scale with a clone of the DLS +ICAT. Tom asked if DLS were ingesting via the API which will keep +the indices up to date – they are for the bulk of the data but not +for the “Investigation”.As the update rules do not work as might be +expected Steve plans to check against the UPDATE permissions before +the change and against the CREATE permissions after the change. + This is to make sure that update cannot get the system into a +state that could not be achieved by a create call.
  • +
  • Christophe said that the ICAT manager’s update feature now worked +proper;y behind a web proxy. He plans a new feature to allow +multiple entities to be updated together.
  • +
  • IDS 1.3 is about ready to release as well. This will be done after +ICAT 4.4.0 has been released though there is no dependency. A couple +of bugs have been fixed since the last meeting and the mechanism to +use a cryptographic hash to protect the datafile location has been +added. Rolf told the meeting that he had submitted a bug relating to +a possible race condition.
  • +
  • Wayne reported on his  latest mock-ups of TopCAT 2. He has received +a number of questions from Rolf which he will address shortly. Wayne +answered a question from Tom about the technology to be used and was +told that the plan was to to use AngularJS with (probably) jQWidgets +as it is preferable to use widgets that are free and support +angular.
  • +
  • Brian reported that development of the IJP was going smoothly. He +explained that when introducing datafile selection it was actually +easiest to start be selecting available jobs and then you will be +offered datafiles or datasets according to the type of job.
  • +
  • Steve was the only person present who had tried Leonardo’s latest +installation scripts. He was a little concerned by the proliferation +of bash scripts.
  • +
  • Kevin reported that the Vulcan laser ICAT and ingestion was now in +pre-production and that plans were in hand for another ICAT +installation for Artemis.
  • +
  • Rolf told us that a new version of python icat was about to be +released once it had been tested with the final release of +icat.server 4.4.0
  • +
  • Milan reminded us that a report by PaNData on ICAT experience would +soon be made available.
  • +
  • Andy gave us the good news that the ESS steering committee had +decided to use ICAT. They are also going to use ISPyB so we should +consider how best to use them together.
  • +
  • A F2F and Steering Group Meeting for early 2015 was discussed. A +host is needed. ESRF are prepared to do this unless someone else +comes forward. It was felt that we should not attempt to co-locate +with PaNDAas as this would delay things unnecessarily. Steve will +send round an e-mail to see if anybody would like to act as host As +Andy was not sure who was actually on the steering group, Steve will +set up a mailing list
  • +
  • Finally Tom told us that this would be his last meeting representing +ISIS as he is starting his new job as group leader in SCD replacing +Brian Matthews on the 1st
  • +
+

December.

+

Actions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ITEMDESCRIPTIONASSIGNED
80.0Find out if Mantid is using the searchText callTom
80.1Seek a host for the 2015 F2F and Steering Group MeetingSteve
80.2Set up mailing list for steering groupSteve
74.0Look into JDBC connector resilience with WildflySteve
61.1Put the simple ICAT browser into contrib when it is readyCondie
60.3Finalise a release of IJP and send a note to the mailing listBrian R
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2014-meetings/meeting-81-18-december-2014/index.html b/collaboration/communication/monthly-meetings/2014-meetings/meeting-81-18-december-2014/index.html new file mode 100644 index 000000000..55e76dd81 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2014-meetings/meeting-81-18-december-2014/index.html @@ -0,0 +1,149 @@ +Meeting 81 – 18 December 2014 | ICAT Project

ICAT Project

Search

Meeting 81 – 18 December 2014

Agenda

+
    +
  • Actions from meeting 80 (Steve)
  • +
  • ICAT development (Steve)
  • +
  • ICAT Manager (Christophe)
  • +
  • IDS development (Steve)
  • +
  • TopCAT development – new requirements from DLS (Steve, Matt and +Alun?)
  • +
  • IJP development (Brian R)
  • +
  • Installation Script (Leonardo)
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • Monthly meetings for 2015 (Steve)
  • +
  • 2015 F2F Meeting and Steering Group Meeting (Steve, Andy and Alun)
  • +
  • AOB (Any)
  • +
+

Notes

+

Present: Rolf, Matt, Brian M, Brian R, Kevin, Tom, Andy, Shelley and +Milan Apologies: Christophe

+
    +
  • The start of the meeting was slightly delayed as the laptop was +connected to the wrong microphone.
  • +
  • Under matters arising from the previous minutes Tom reminded the +meeting that ESS had not formally decided to adopt ICAT.
  • +
  • Action 80.0: Tom confimed that Mantid does not use the searchText +call
  • +
  • Action 80.1 Alun Ashton plans to host the meeting at DLS.
  • +
  • Action 80.2 Steve has set up a steering group mailing list.
  • +
  • Action 60.3 Brian said that a first release of the IJP was imminent.
  • +
  • ICAT 4.4.0 has been released. One interesting problem has been +reported by Rolf with a search using limits in conjunction with a +search by id. It would appear that this is not a new problem but is +a bug in eclipselink. If you replace “id=42” with “id IN (42)” it +works fine. To fix this would require that the code recognises this +case to provide a work-around. Steve proposed that it be marked as a +“wont fix” but the meeting thought that as ICAT was not working as +advertised it should be fixed. No action will be recorded as it is +already in the list of issues. Steve will in addition report the +problem to eclipse. ICAT 4.5.0 is progressing steadily with +customised lucene searches to match TopCAT2.
  • +
  • PaNdata have produced a report on ICAT as one of their deliverables. +This has been circulated to the steering group. Milan has agreed +that it can be made available to all those in the ICAT collaboration +so Steve will send it round after this meeting. It brings up a +number of interesting issues and exposes some misunderstandings. +Steve plans to produce a response which will also be sent to the +icatgroup list.
  • +
  • Christophe had informed Steve that he has not yet made the planned +improvement to his ICAT Manager Steve said that version 1.3 is about +to be released. Rolf has submitted a bug report – along with a fix +which has not yet been applied. When this has been applied and +tested another snapshot will be made available before a release is +made.
  • +
  • Following a presentation to DLS on TopCAT2 a number of +new requirements were drafted. This document has not yet been +approved by DLS so will not be circulated yet. Steve went through +the points and the following issues were brought up: +
      +
    1. Don’t need filters on column values as well as global filters.
    2. +
    3. There was a discussion on scroll bars which get the data when it +comes into view as opposed to regular scroll bars where the HTML +is fully rendered.
    4. +
    5. The need for an API to TopCAT was not understood and DLS should +be asked to provided Use Cases.
    6. +
    7. Nobody other than DLS wanted a Datafile.location view. Steve +said that he thought it would require an extra database table in +ICAT which would be slightly larger than the Datafile table. He +suggested making it an ICAT configuration option.
    8. +
    9. Matt also said that DLS would like more information on the +progress of restores/downloads.
    10. +
    +
  • +
  • Jan has recently checked some new documentation in.
  • +
  • Tom reported that the IDS did not seem to recover well from network +breaks. Steve will submit a “bug”. Matt asked for the IDS to be able +to provide usage statistics.
  • +
  • Brian R reported good progress on the IJP and that he hopes to have +a release around Christmas time making use of the “unixbatch” batch +server. T he IJP will now pass datafile Ids to jobs. He has written +small “jobs” to do things such as copying  a datafile to another +dataset. Interactive jobs are not currently supported as the +previous mechanism was too tied to one implementation. This will be +addressed ASAP.
  • +
  • Steve asked if there were any changes needed to the schedule of +meetings for 2015 – there were none.
  • +
  • It is expected that the 2015 F2F Meeting and Steering Group Meeting + will be hosted by DLS. A doodle poll will be carried out once we +get possible dates from Alun. This should be done before Christmas +to give people time to obtain travel
  • +
+

approval.

+

Actions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ITEMDESCRIPTIONASSIGNED
81.0Report bug in eclipselinkSteve
81.1Circulate response to PaNdata document.Steve
81.2Circulate DLS TopCAT 2 requirementsSteve
81.3Request use case for TopCAT APISteve
81.4Demo the IJP to the meeting when it has been released.Brian R
74.0Look into JDBC connector resilience with WildflySteve
61.1Put the simple ICAT browser into contrib when it is readyCondie
60.3Finalise a release of IJP and send a note to the mailing listBrian R
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2015-meetings/index.html b/collaboration/communication/monthly-meetings/2015-meetings/index.html new file mode 100644 index 000000000..a6ed34477 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2015-meetings/index.html @@ -0,0 +1,19 @@ +2015 Meetings | ICAT Project

ICAT Project

Search

2015 Meetings

+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2015-meetings/meeting-82-22-january-2015/index.html b/collaboration/communication/monthly-meetings/2015-meetings/meeting-82-22-january-2015/index.html new file mode 100644 index 000000000..1263452c4 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2015-meetings/meeting-82-22-january-2015/index.html @@ -0,0 +1,145 @@ +Meeting 82 – 22 January 2015 | ICAT Project

ICAT Project

Search

Meeting 82 – 22 January 2015

Agenda

+
    +
  • Actions from meeting 81 (Steve)
  • +
  • ICAT development (Steve)
  • +
  • ICAT Manager (Christophe)
  • +
  • IDS development (Steve)
  • +
  • TopCAT development (Wayne)
  • +
  • IJP development (Brian R)
  • +
  • Installation (Leonardo, Steve)
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • 2015 F2F Meeting and Steering Group Meeting at DLS (Steve, Andy and +Alun)
  • +
  • AOB (Any)
  • +
+

Notes

+

Present : Condie, Steve, Shelley, Wayne, Kevin P, Brian R, Tom, +Christophe, Matt, Rolf, Milan
+Apologies: Kevin Knowles, Andy

+
    +
  • Action 81.1: Steve has confirmed that some work has been done in +response to the PaNdata document. Circulation of response possibly +deferred to the F2F meeting.
  • +
  • Action 81.2: Steve confirmed that the DLS TopCAT 2 requirements have +been circulated.
  • +
  • Action 81.3: DLS have now been asked for a use case for the TopCAT +API. They did not seem to appreciate that the IDS is an interface.
  • +
  • Action 81.4: Deferred to the F2F meeting.
  • +
  • Action 60.3: IJP released and the mailing list has been informed.
  • +
  • Two ICAT authenticators have been repackaged and released by Steve. +Replaced the old authenticators and made them easier to use with the +ICAT installer. Snapshot was not released as the new authenticators +did not add any new functionality.
  • +
  • Steve mentioned that he is looking into making the LDAP +authenticator work with a functional ID. This feature has been +requested by multiple sites in the PaNdata report. Steve is waiting +to receive input from Milan’s colleague. Steve will release a new +LDAP snapshot when the enhancements are made.
  • +
  • Rolf had informed Steve of an authorisation issue when deleting +items as any cascading items are also deleted regardless of the +users permissions.
  • +
  • Christophe is in the process of developing the next release of the +ICATManager which is to be released shortly. The new features +mentioned include editing multiple entities at once, the navigation +from any entity to any related entities order persistence when +closing entity tabs.
  • +
  • IDS 1.3.0 has been released. It is able to work well with data +stored on tape by datafile rather than dataset and the prepareData +mechanism has been rewritten to avoid making a copy of the data to +download later. Fix for glassfish bug that caused downloads to be +truncated after 15 minutes has been sent out by Steve and added to +the ICAT installer. DLS requested alternates to HTTP for downloads +via the IDS. Steve mentioned that the alternate solutions must be +robust for large quantities of data.
  • +
  • Wayne reported that he is still in this very early stages of +development for TopCAT2. He is also in the process of answering +Rolfs comments in regards to the layout design.
  • +
  • A snapshot release of the IJP is now available. The IJP components +have been have been successfully installed on linux VM’s by two +people so far.
  • +
  • The ICAT installer has been developed by Steve in response to a +complaint by PaNdata. A licence has been obtained to use an +installer generator from BitRock. The installer currently runs +successfully on linux but has an issue regarding subprocesses on +windows. BitRock have been informed and Steve is waiting on a +resolution.
  • +
  • The 2015 F2F meeting and Steering Group Meeting dates have been +narrowed down to 31st March – 2nd April at DLS. This may be reduced +to a two day meeting with the exact dates to be confirmed. The +meetings agenda is to be released
  • +
+

soon.

+

Actions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ITEMDESCRIPTIONASSIGNED
82.0LDAP enhancement to work with a functional IDSteve
82.1Cascading deletion authorisation bugSteve
82.2Alternate download protocols for IDSSteve
82.3Respond to comments on TopCAT 2 layout designWayne
82.4ICAT installer windows subprocess issueSteve
82.5Release F2F Meeting agendaSteve
81.0Report bug in eclipselinkSteve
81.1Circulate response to PaNdata documentSteve
74.0Look into JDBC connector resilience with WildflySteve
61.1Put the simple ICAT browser into contrib when readyCondie
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2015-meetings/meeting-83-26-february-2015/index.html b/collaboration/communication/monthly-meetings/2015-meetings/meeting-83-26-february-2015/index.html new file mode 100644 index 000000000..7ee50ce09 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2015-meetings/meeting-83-26-february-2015/index.html @@ -0,0 +1,162 @@ +Meeting 83 – 26 February 2015 | ICAT Project

ICAT Project

Search

Meeting 83 – 26 February 2015

Agenda

+
    +
  • Actions from meeting 82 (Steve)
  • +
  • ICAT development (Steve)
  • +
  • ICAT Manager (Christophe)
  • +
  • Python-ICAT (Rolf)
  • +
  • IDS development (Steve)
  • +
  • TopCAT development (Wayne)
  • +
  • IJP development (Brian R)
  • +
  • Installation (Steve)
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • 2015 F2F Meeting and Steering Group Meeting at DLS (Steve, Andy and +Alun)
  • +
  • AOB (Any)
  • +
+

Notes

+

Present: Condie, Steve, Christophe, Brian R, Rolf, Tom, Shelley, Nick

+

Apologies: Kevin Knowles, Matt, Kevin P, Wayne, Andy, Milan

+
    +
  • Action 82.0: Steve is planning to proceed with development of the +enhancement focusing on what suits the needs of ELETTRA then add +further functionality for other sites at a later date if required.
  • +
  • Action 82.1: This issue has been marked as bug 150 and will no +longer be tracked here.
  • +
  • Action 82.2: See under IDS development
  • +
  • Action 82.3: Layout mockups currently being updated by Wayne to +match latest inputs from Diamond. Once the updates have been +completed the layout mockups will be circulated to all interested +parties for approval.
  • +
  • Action 82.4: After a lot of communication with BitRock Steve has +established the issue to be caused by the way that Python handles +subprocesses within Windows. Steve will add calls to the installer +the are normally handled by the python setup script to overcome this +issue. Currently the only component affected is the +ids.storage_file.
  • +
  • Action 82.5: The F2F meeting agenda has been released and the +mailing list has been informed.
  • +
  • Action 81.1: Currently in preparation and will be circulated prior +to the F2F meeting.
  • +
  • Steve has begun development on ICAT 4.5.0 with lucene based +searching for use by TopCAT.
  • +
  • ICAT 4.4.0 has been found to not support selects of the form “SELECT +a.b FROM…” where b is not a simple attribute. This was never +documented as a feature and therefore has never been tested, however +it used to work in versions of ICAT prior to 4.4.0. This has been +fixed and tested in 4.5.0 and so far appears to be successful.
  • +
  • Steve may possibly release ICAT 4.5.0 without the lucene calls to +address bug fixes in 4.4.0. The TopCAT matching lucene calls would +then be delayed to version 4.6.0. Everyone was happy with this +approach.
  • +
  • A new version of ICAT Manager is to be released in the upcoming +month. There will be some small additional features and bug fixes +but no major changes to functionality.
  • +
  • A new version (0.7.0) of Python-ICAT has been released. There is +mostly only one change: a new module icat.query with a class Query +have been added.  This class can be used to build ICAT search +expressions.  Instances of the class may be used in place of search +expression strings where appropriate.Using the Query class can +improve readability of your Python code. Currently no plans to add +new features to Python-ICAT or bug fixes required.
  • +
  • Version 1.3.1 of the IDS has been released. This includes a fix to a +bug causing file handled remaining open for individually downloaded +files.
  • +
  • Version 1.3.1 of the ids.storage_file has been released. This +includes a fix to to a bug in the algorithm that chooses which files +to archive.
  • +
  • Steve is to provide a new IDS bug fix soon for an issue related the +file checking. Currently the file that holds the last ID checked can +be corrupted.
  • +
  • Steve, in conjunction with DLS, are currently investigating various +methods for alternate download method for the IDS. One option being +a new component that makes calls to the IDS via the use of the +getLink call and then pushing the data via a choice of mechanisms. +This may be one component or several that make use a shared library. +Another option is a client that can be run by the user that is user +installable and can run in the background. Steve to circulate +diagrams outline each of the possibilities.
  • +
  • Steve found an issue when attempting to provide logging through the +IDS plugin as it interferes with the main IDS logging. Steve +suggested changing logging framework  as Log4J interacts badly with +Glassfish. Tom stated that the new logging framework would be +required to provide daily rolling log files as well as the ability +to set the maximum size of a log file. Steve is going to test the +use of the Java Util logging framework on the ids.storage_file and +this will be discussed further at the F2F meeting.
  • +
  • Agile development to be begin soon for TopCAT v2. Tom mentioned +inviting the interested parties to the sprint reviews to get +feedback on development.
  • +
  • A new release of the ICAT installer that is compatible with Windows +will soon be released by Steve. Sample data will also be offered by +the
  • +
+

installer.

+

Actions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ITEMDESCRIPTIONASSIGNED
83.0Circulate diagrams to showcase solutions to alternate download protocols for IDSSteve
83.1Invite customer representatives from interested facilities to TopCAT v2 sprint reviewsTom
83.2Finalize TopCAT v2 layout mockups and circulateWayne
82.0LDAP enhancement to work with a functional IDSteve
82.2Alternate download protocols for IDSSteve
81.0Report bug in eclipselinkSteve
81.1Circulate response to PaNdata documentSteve
74.0Look into JDBC connector resilience with WildflySteve
61.1Put the simple ICAT browser into contrib when readyCondie
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2015-meetings/meeting-84-30-april-2015/index.html b/collaboration/communication/monthly-meetings/2015-meetings/meeting-84-30-april-2015/index.html new file mode 100644 index 000000000..ee2fc29b4 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2015-meetings/meeting-84-30-april-2015/index.html @@ -0,0 +1,140 @@ +Meeting 84 – 30 April 2015 | ICAT Project

ICAT Project

Search

Meeting 84 – 30 April 2015

Agenda

+
    +
  • Actions from meeting 83 (Steve)
  • +
  • Component development +
      +
    • ICAT (Steve)
    • +
    • ICAT Manager
    • +
    • Python-icat (Rolf)
    • +
    • IDS (Steve) +
        +
      • FUSE (Condie)
      • +
      • Globus transfer (Frazer)
      • +
      • SmartClient (Steve)
      • +
      • WebDAV (Kevin)
      • +
      +
    • +
    • TopCAT (Wayne)
    • +
    • IJP (Brian R)
    • +
    • Installation (Steve)
    • +
    +
  • +
  • Migration to git/github (Steve)
  • +
  • RoadMap (Steve)
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • AOB (Any)
  • +
+

Notes

+

Present: Condie, Steve, Tom, Wayne, Kevin P, Brian R, Fazer, Rolf, Milan

+

Apologies: Andy

+
    +
  • Action 83.0: The IDS alternate download protocol diagram was +replaced by a presentation shown at the F2F meeting.
  • +
  • Action 83.1: Customer representatives from facilities invited to +TopCAT v2 sprint review meetings with overall positive feedback.
  • +
  • Action 83.2: TopCAT v2 layout mockups finalised and circulated.
  • +
  • Action 82.2: Not being kept as a specific action and is being +replacement by on going discussions for each related component in +the agenda.
  • +
  • Action 81.1: Response to PaNdata document has been circulated.
  • +
  • Since the previous meeting Steve informed the group that a few bugs +have been brought to light in the latest release of ICAT. The first +being that the export call of the ICAT RESTful interface does not +always produce properly formatted output. Issues surrounding the +installation of ICAT with recent versions of Java were also reported +by Rolf and Tom.
  • +
  • Rolf informed the group that a new release of Python-ICAT is +imminent, given that no new bugs or feature requests emerge. The +release will include example scipts for using the ICAT import and +export with REST.
  • +
  • ICAT-FUSE is still being developed with work still required to find +a fix to how Fuse handles ‘move to recycle bin’ in nautilus.
  • +
  • Kevin mentioned that a functioning version of WebDAV will be put +into production by Artemis over the next month or so. A full version +that can be used by different ICAT implementations will be looked at +after the Artimus implementation is deployed.
  • +
  • Wayne mentioned that TopCAT v2 development is underway with the +login/authentication, meta data panel engine being complete.
  • +
  • An AngularJs version of IJP is currently being developed by Brian.
  • +
  • Shelley has requested the Mac Os compatibility be included in the +ICAT Installer. Steve to look into the complexity of this before +deciding whether or not to proceed with adding this functionality.
  • +
  • Steve spoke about some of the current work he is undergoing to +migrate the ICAT codebase away from google code to Git. The existing +SVN repositories need to be split into multiple repositories in +order to match the definition of a repository in Git. This will also +require some manual cleanup of branches and tags. The wikis and +issues to also be manually moved to Git/Github, however issues will +not retain its history to simplify this process. Total migration is +still a few months away from +completion.
  • +
+

Actions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ITEMDESCRIPTIONASSIGNED
84.0Invite Jianguo to the monthly ICAT meetingsSteve
84.1Circulate Git book detailsSteve
84.2Schedule TopCAT v2 sprint review meetingsTom
84.3Create backup of SVNSteve
84.4Update RoadMapSteve
82.0LDAP enhancement to work with a functional IDSteve
81.0Report bug in eclipselinkSteve
74.0Look into JDBC connector resilience with WildflySteve
61.1Put the simple ICAT browser into contrib when readyCondie
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2015-meetings/meeting-85-28-may-2015/index.html b/collaboration/communication/monthly-meetings/2015-meetings/meeting-85-28-may-2015/index.html new file mode 100644 index 000000000..71cbb8382 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2015-meetings/meeting-85-28-may-2015/index.html @@ -0,0 +1,162 @@ +Meeting 85 – 28 May 2015 | ICAT Project

ICAT Project

Search

Meeting 85 – 28 May 2015

Agenda

+
    +
  • Actions from meeting 84 (Steve)
  • +
  • Component development +
      +
    • ICAT (Steve)
    • +
    • ICAT Manager
    • +
    • Python-icat (Rolf)
    • +
    • IDS (Steve) +
        +
      • FUSE (Condie)
      • +
      • Globus transfer (Frazer)
      • +
      • SmartClient (Steve)
      • +
      • WebDAV (Kevin)
      • +
      +
    • +
    • TopCAT (Wayne)
    • +
    • IJP (Brian R)
    • +
    • Installation (Steve)
    • +
    +
  • +
  • Migration to git/github (Steve)
  • +
  • RoadMap (Steve)
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • AOB (Any)
  • +
+

Notes

+

Present : Condie, Steve, Tom G, Wayne, Milan, Kevin P, Brian R, Jianguo, +Andy, Frazer

+

Apologies: Rolf

+
    +
  • Action 84.0: Jianguo has been invited to and is currently attending +the monthly meetings.
  • +
  • Action 84.1: Steve has circulated the details of the book to the +group.
  • +
  • Action 84.2: The TopCAT V2 sprint reviews have been scheduled with +one having taken place.
  • +
  • Action 84.3: Steve has created a backup of the SVN repository.
  • +
  • Action 84.4: Steve has updated the roadmap (Discussed in agenda).
  • +
  • Steve is beginning to finalising ICAT 4.5 with only minor +outstanding bugs to be fixed before release. Lucene has been removed +from the 4.5 release.
  • +
  • A new version of python-icat has been released. The source +repository of python-icat has been moved to GitHub.
  • +
  • Frazer informed the group that the work on Globus Transfer has +resumed with PAM authenticators being built to work with ICAT.
  • +
  • Kevin reported that the Artemis version of WebDAV is progressing +well with a pre-production system being launched within the upcoming +weeks. The current version has been speed tested and is to undergo +resilience testing before being pushed to pre-production. Kevin also +mentions that once stable in production on Artemis is should only be +a further few weeks until a general version is released.
  • +
  • TopCAT V2 has just entered Sprint 1 after a Sprint review with the +product owners and users. Wayne mentioned there was a lot of +positive feedback and that new requests have emerged from the Sprint +review. Wayne also mentioned that there is a live working test +version for people to use. TopCAT V2 is expected to be rolled out +for all sites by the end of the summer.
  • +
  • Brian informed the group that a login dialog created for IJP +AngularJS GUI. He also mentioned that there has been interface +changes between the IJP server and the batch connectors. Work is +ongoing to prepare the installation of the IJP on CLF systems, with +it currently running on two test VM’s. Brian is also investigating +the current configurations on the CLF machines and how they interact +with the IJP changes. Brian mentioned he has also been working on +converting CLF job scripts to work with the new options passing +mechanism; this still requires testing.
  • +
  • Steve is looking into porting the ICAT installer to work with Mac +OS. Steve mentioned he now has a machine to begin this development +but is yet to start.
  • +
  • Steve informed the group that the migration of the ICAT source code +from googlecode to GitHub has begun with most components migrated +successfully. Steve mentioned that the issues and wiki pages do not +migrate in the same way and proposed several solutions on how this +can be achieved. Whether or not the wiki and issue pages should live +on the repos of each component or in a stand alone repo needs to be +investigated further before a decision is made.
  • +
  • The roadmap has been circulated to the Steering group and group +members for feedback. A website review is to be added to the roadmap +at the suggestion of Andy.
  • +
  • The ESRF are to continue using ICAT alongside ISPyB and are planning +to roll out ICAT for use on all beamlines.
  • +
  • The ESS are committed to using ICAT and wish to hold talks regarding +the work they would like to see surrounding ICAT.
  • +
+

This was Condie’s last ICAT meeting. He was thanked for all his +contributions to the +project.

+

Actions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ITEMDESCRIPTIONASSIGNED
85.0Circulate notes and recording link from TopCAT V2 sprint reviewTom
85.1Circulate link and instructions for using the live test version of TopCAT V2Wayne
85.2Add a list of current sponsors to ICAT websiteTom
85.3Migrate ICAT Manager to the ICAT project GitHubChristophe
85.4Add ESS to the steering groupAndy
85.5Ask Mantid for information on how they migrated wikis and issue to GitHubTom
82.0LDAP enhancement to work with a functional IDSteve
81.0Report bug in eclipselinkSteve
74.0Look into JDBC connector resilience with WildflySteve
61.1Put the simple ICAT browser into contrib when readyCondie
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2015-meetings/meeting-86-2-july-2015/index.html b/collaboration/communication/monthly-meetings/2015-meetings/meeting-86-2-july-2015/index.html new file mode 100644 index 000000000..fb536804b --- /dev/null +++ b/collaboration/communication/monthly-meetings/2015-meetings/meeting-86-2-july-2015/index.html @@ -0,0 +1,150 @@ +Meeting 86 – 2 July 2015 | ICAT Project

ICAT Project

Search

Meeting 86 – 2 July 2015

Agenda

+
    +
  • Actions from meeting 85 (Steve)
  • +
  • Component development +
      +
    • Waffle.io (Steve)
    • +
    • ICAT (Steve)
    • +
    • ICAT Manager
    • +
    • Python-icat (Rolf)
    • +
    • IDS (Steve) +
        +
      • FUSE (Condie)
      • +
      • Globus transfer (Frazer)
      • +
      • SmartClient (Steve)
      • +
      • WebDAV (Kevin)
      • +
      +
    • +
    • TopCAT (Wayne)
    • +
    • IJP (Brian R)
    • +
    • Installation (Steve)
    • +
    +
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • AOB (Any)
  • +
+

Notes

+

Present : Steve, Wayne, Kevin P, Brian R, Alex PD, Frazer, Chris, Jens + and Paulina Karp.

+

Apologies: Rolf and Tom G

+
    +
  • Action 85.0: Notes have been circulated and recording. and links + from the TopCAT V2 sprint review.
  • +
  • Action 85.1:  Links and instructions for using the live test version +of TopCAT V2 has been circulated.
  • +
  • Action 85.5: Asking the Mantid group on how they migrated their +wikis is no longer relevant.
  • +
  • Action 61.1: Steve will speak to Tom about transferring Fuse to +Alex.
  • +
+

General Comments:

+
    +
  • Steve discussed about Waffle IO. Mentioned about its benefits of +being used along multiple repositories and suggested that it should +be exploited. Steve has also posted the details of Waffle IO and +added a link for the web site.
  • +
  • Steve has put up a new 4.5.0 ICAT SNAPSHOT. There are two new +features to be found. Firstly old lucene calls have been removed and +secondly the way ID’s have been allocated have also been changed.
  • +
  • Steve mentioned that there have been several small updates to the +IDS to allow it to work with the new ICAT 4.5.0 snapshot.
  • +
  • Frazer discussed how Globus Transfer is going very well and is +moving along at a sufficient pace. Jens asked if Frazer would be +able to have part of Globus Transfer working so that it can either +be discussed in length or presented to the meeting with Diamond on +July the 13th.
  • +
  • Steve’s smart client project is going very well. Steve has tested +the smart client over the past few days. From these tests it appears +to behave as planned.
  • +
  • Kevin informed the group that webdav has edged forward in its +development. Test servers are currently being set up for this and he +hasn’t encountered any particular problems.
  • +
  • Wayne discussed how TopCAT V2 is moving along. There have been 2 +sprint review meetings since the last ICAT collaboration meeting. +Sprint review 3 was poorly attended.
  • +
  • Brian told the team that the ICAT job portal has been deployed on +the CLF system. It is currently working without too many issues. +There are currently a few interactive jobs working on the system +however there was an issue if a customer doesn’t close the session +correctly. This causes the interactive jobs to not be correctly +cleared up.
  • +
  • Steve mentioned that there has been an issue with ICAT at Diamond. +ICAT cannot cope with a dataset that had over 1.3 million datafiles. +The limit has been pushed up to 250,000 but Steve has said he will +need to discuss with Diamond about allocation of datafiles to +datasets.
  • +
+

Actions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ITEMDESCRIPTIONASSIGNED
86.0Discuss with Tom about what should happen with Fuse. If it should be handed over to Alex or not.Steve
86.1Meet with Jens to discuss the meeting with Diamond about Globus Transfer.Kevin/Frazer
86.2Send out sprint review 3 recordings and notes to the participants that were unable to attend.Wayne
86.3Steve to meet with Greg from Diamond about optimizing their datasets.Steve
86.4Tom to decide who needs to put the simple ICAT browser into contrib.Tom
86.6Use waffle.ioEveryone
85.2Add a list of current sponsors to the ICAT websiteTom
85.3Migrate ICAT Manager to the ICAT project GitHubChristophe
81.0Report bug in eclipselinkSteve
74.0Look into JDBC connector resilience with WildflySteve
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2015-meetings/meeting-87-23-july-2015/index.html b/collaboration/communication/monthly-meetings/2015-meetings/meeting-87-23-july-2015/index.html new file mode 100644 index 000000000..70de063b9 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2015-meetings/meeting-87-23-july-2015/index.html @@ -0,0 +1,170 @@ +Meeting 87 – 23 July 2015 | ICAT Project

ICAT Project

Search

Meeting 87 – 23 July 2015

Agenda

+
    +
  • Actions from meeting 86 (Steve)
  • +
  • Component development +
      +
    • Waffle.io (Steve)
    • +
    • ICAT (Steve) – Should the import/export format also be +available in other formats such as XML, YAML and JSON.
    • +
    • ICAT Manager
    • +
    • Python-icat (Rolf)
    • +
    • IDS (Steve) +
        +
      • FUSE (Condie)
      • +
      • Globus transfer (Frazer)
      • +
      • SmartClient (Steve)
      • +
      • WebDAV (Kevin)
      • +
      +
    • +
    • TopCAT (Wayne)
    • +
    • IJP (Brian R)
    • +
    • Installation (Steve) and revised configured SSL cifers for +Glassfish (Kevin)
    • +
    +
  • +
  • Googlecode migration (Steve) +
      +
    • What to do with contrib
    • +
    • Wiki – CSMD and old meeting reports
    • +
    +
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • AOB (Any)
  • +
+

Notes

+

Present: Steve, Tom , Wayne, Milan, Kevin P, Kevin M, Brian R, Alex, +Rolf and Jianguo Rao.

+

Action 86.0: It has been decided that Alex is to continue development of +Fuse.

+

Action 86.1: Tom met with the Diamond team to discuss the Globus +project. Future plans involve bringing the system on line for initial +usage.

+

Action 86.2: Notes and recording links from TopCAT V2 sprint review 4 +and 5 have been circulated.

+

Action 86.3: Steve has spoken to Greg about the optimisation of their +Datasets. Greg wishes for a list of the worst offending datasets so they +can be reviewed.

+

Action 86.4: It has been decided that Alex will put the simple ICAT +browser into contrib.

+

Action 86.6: The team has explored Waffle.io. Continued usage was +recommended.

+

General comments:

+
    +
  • Steve discussed more about the general benefits of waffle.io and how +it can be applied to the projects that currently use GitHub.
  • +
  • On the 23rd of July Steve released ICAT and IDS 4.5.
  • +
  • Steve mentioned about the future version of ICAT 4.6. The main focus +of this update will be extra Lucene searches for TopCat V2. Much of +the work has been done.
  • +
  • Rolf plans to release a new version of python ICAT within the next +week. He currently needs to test the new ICAT 4.5 before release.
  • +
  • Frazer discussed how he is currently building Globus against the +TopCat V2 API that Wayne has provided.
  • +
  • Steve has solved several bugs to do with the Windows version of +Smart client. Within the upcoming week Steve will have a Beta +release for the Smart Client.
  • +
  • Kevin P talked about how WebDav is moving a long. Currently having +issues with special characters in files names. It is currently a +very time consuming issue.
  • +
  • Wayne discussed how there have been two sprint reviews, 4 and 5, +since the last ICAT meeting. The 4th meeting was mainly on how items +are selected and stored from the browsing area into a local area. +The 5th meeting focused on the back end logic. How items are saved +to a database and how in the future Globus  will have access to the +tables pulled up by the IDS.
  • +
  • Brian mentioned that IJP has had a new version release with 3 new +components: IJP.Server, IJP.Unix Batch and IJP.demo. The development +of IJP for CLF is still in the pipeline and going well. The issue +with dangling clients has been solved. The solution also terminates +inactive sessions.
  • +
  • Kevin discussed the issues we are currently having with the SSL +ciphers we use. RC4 is no longer secure and has been removed from +the open JDK. There has also been a new release of FireFox 39 which +has caused compatability issues with the diffie hellman cipher. This +has stopped certain users from accessing the ICAT installations +website.
  • +
  • Possible replacements to RC4 were discussed including one of the AES +ciphers however issues with speed were brought up and the point +requires further research.
  • +
  • The google code migration is nearly complete. There are a few more +parts that need to be moved over including contrib. Different +solutions as to where put contrib were discussed. The favourite +option was to push all of remaining code onto a github repository +and then trim off any code that is not relevant any more.
  • +
  • Steve has cleared up the ICAT wiki and has removed out of date +sections.
  • +
+

Actions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ITEMDESCRIPTIONASSIGNED
87.0Run DOI script for all recent releases.Steve
87.1Test installation on OS XSteve
87.2Look into different symmetric encryption solutions.Everyone
87.3Move contrib from google code to a suitable replacement location.Steve
87.4Collect a list of datasets that caused issues with ICAT from DiamondSteve
87.5Give permission to Rolf to allow write access to ICAT repositrySteve
85.2Add a list of current sponsors to the ICAT websiteTom
85.3Migrate ICAT Manager to the ICAT project GitHubChristophe
81.0Report bug in eclipselinkSteve
74.0Look into JDBC connector resilience with WildflySteve
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2015-meetings/meeting-88-27-august-2015/index.html b/collaboration/communication/monthly-meetings/2015-meetings/meeting-88-27-august-2015/index.html new file mode 100644 index 000000000..15622f877 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2015-meetings/meeting-88-27-august-2015/index.html @@ -0,0 +1,129 @@ +Meeting 88 – 27 August 2015 | ICAT Project

ICAT Project

Search

Meeting 88 – 27 August 2015

Agenda

+
    +
  • Actions from meeting 87 (Steve)
  • +
  • Component development +
      +
    • ICAT (Steve)
    • +
    • ICAT Manager
    • +
    • Python-icat (Rolf)
    • +
    • IDS (Steve) +
        +
      • FUSE (Condie)
      • +
      • Globus transfer (Frazer)
      • +
      • SmartClient (Steve)
      • +
      • WebDAV (Kevin)
      • +
      +
    • +
    • TopCAT (Wayne)
    • +
    • IJP (Brian R)
    • +
    • ICAT Dashboard (Alex)
    • +
    • Installation (Steve)
    • +
    +
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • AOB (Any)
  • +
+

Notes

+

Present: Milan, Steve, Tom, Jianguo, Brian R, Wayne
+Apologies: Rolf, Shelley, Andy, Peter Parker, Frazer

+

Action 87.2 glassfish-setup.py and the instructions on the web have been +updated to make use of different symmetric encryption algorithms.

+

Action 87.3 a new organisation icatproject-contrib has been created to +hold the old googlecode contrib

+

Action 87.4 is being tracked in another meeting

+

Action 87.5 will be changed to “Provide an example ICAT facility page +for ISIS in icatproject.org”

+
    +
  • Release 4.6 of icat.server is being prepared. A new restful call to +obtain properties has been added to return everything useful +that doesn’t need authentication, including info about +authenticators which can be used by tools such as topcat. The ESCAPE +keyword now works in JPQL queries. The lucene searching targetting +topcat is under way.
  • +
  • Brian has started to use python-icat for some IJP job scripts. He +needs to be able to use an existing ICAT sessionId and ensure that +the client does not close the session on termination. He will +discuss this with Rolf.
  • +
  • The ids.smartclient has needed a few changes to make it work well +with topcat. This could now be released but will first be tested on +OS X.
  • +
  • webdav for ids. Kevin is on leave but Tom reported that testing with +very large file transfers gave session timeout problems .
  • +
  • The backend (for the “Angular topcat” is mostly done. There is still +an issue that getStatus requires a sessionId and Wayne would like +the option to not require it.
  • +
  • IJP needs uodating to work with latest ICAT and IDS.
  • +
  • For the icat dashboard, in the absence of Alex, Tom reported that +feedback on the plans would be appreciated. Steve has already +circulated a suggestion that the presentation layer should bve a +separate component. The ids will need to produce some kind of record +of what it has been doing.
  • +
  • Steve reported that he was obtaining a license for MireDot (free for +open source projects) to generate documentation for the ids.server +and for the restful interface  to the
  • +
+

icat.server.

+

Actions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ITEMDESCRIPTIONASSIGNED
88.0Discuss use of existing icat sessions in python-icat with Rolf.Brian
87.0Run DOI script for all recent releases.Steve
87.1Test installation on OS XSteve
87.5Give permission to Rolf to allow write access to ICAT repositrySteve
85.2Provide an example ICAT facility page for ISIS in icatproject.orgTom
85.3Migrate ICAT Manager to the ICAT project GitHubChristophe/Andy
81.0Report bug in eclipselinkSteve
74.0Look into JDBC connector resilience with WildflySteve
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2015-meetings/meeting-89-17-september-2015/index.html b/collaboration/communication/monthly-meetings/2015-meetings/meeting-89-17-september-2015/index.html new file mode 100644 index 000000000..96488fb11 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2015-meetings/meeting-89-17-september-2015/index.html @@ -0,0 +1,125 @@ +Meeting 89 – 17 September 2015 | ICAT Project

ICAT Project

Search

Meeting 89 – 17 September 2015

Agenda

+
    +
  • Actions from meeting 88 (Steve)
  • +
  • Component development +
      +
    • ICAT (Steve)
    • +
    • ICAT Manager
    • +
    • Python-icat (Rolf)
    • +
    • IDS (Steve) +
        +
      • FUSE (Alex)
      • +
      • Globus transfer (Frazer)
      • +
      • SmartClient (Steve)
      • +
      • WebDAV (Kevin)
      • +
      +
    • +
    • TopCAT (Wayne)
    • +
    • IJP (Brian R)
    • +
    • ICAT Dashboard (Alex)
    • +
    • Installation (Steve)
    • +
    +
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • AOB (Any)
  • +
+

Present: Milan, Steve, Tom, Jianguo, Brian M, Wayne, Alex, Andy, Rolf +and Chris P

+

Action 87.0 All of the DOI scripts have been run for recent releases.

+

Action 87.1 Testing on OS X is complete. During testing Steve found that +glassfish 4.0 doesn’t work with OS X which mean glassfish 4.2 would have +to be used. ICAT however, doesn’t work with 4.2 so Steve proposes to +wait for the WildFly configuation to be ready.

+
    +
  • Steve has made available a ICAT 4.6 SNAPSHOT.  He is currently +waiting for feedback from Wayne about the Lucene calls.
  • +
  • Steve has updated the authenticators to include the new +getDescription calls. These are also available as SNAPSHOTS.
  • +
  • Steve has given Rolf a login to the repository but Rolf still +requires an area.
  • +
  • Rolf had concerns that the ICAT might be leaning away from SOAP and +as python-icat is a SOAP client this could mean having to change the +code base. Steve commented on how ICAT will continue to have the +option of using SOAP which answered Rolfs concerns.
  • +
  • Steve has released the ids.smartclient with .debian,  .rpm and .exe +for windows. Steve is not far off from making a .pkg for OS X.
  • +
  • In Kevin’s absence Tom reported on webdav, informing the team that +it will be out for testing within the next few weeks for CLF.
  • +
  • Wayne has released a V1.13 SNAPSHOT last week. This has added +support for ICAT v4.5.
  • +
  • TopCat V2 is currently working with Https, globus and smartclient. +There is currently an issue with Firefox and TopCat V2 that Wayne is +currently investigating. There will be a Beta release of TopCat V2 +soon.
  • +
  • Alex reported on the requirements meeting with ISIS for ICAT +dashboard. No new requirements were captured.
  • +
  • Steve will be producing an updated installer once Topcat 1.13.0 is +no longer a SNAPSHOT.
  • +
  • Steve is currently working on the Wildfly container and all is going +well so
  • +
+

far.

+

Actions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ITEMDESCRIPTIONASSIGNED
89.0Steve to create area on github for ICAT dashboard.Steve
89.1Provide feedback on icat.server 4.6.0 snapshotWayne
88.0Discuss use of existing icat sessions in python-icat with Rolf.Brian
87.5Give permission to Rolf to allow write access to ICAT repositrySteve
85.2Provide an example ICAT facility page for ISIS in icatproject.orgTom
85.3Migrate ICAT Manager to the ICAT project GitHubChristophe/Andy
81.0Report bug in eclipselinkSteve
74.0Look into JDBC connector resilience with WildflySteve
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2015-meetings/meeting-90--22-october-2015/index.html b/collaboration/communication/monthly-meetings/2015-meetings/meeting-90--22-october-2015/index.html new file mode 100644 index 000000000..767778971 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2015-meetings/meeting-90--22-october-2015/index.html @@ -0,0 +1,122 @@ +Meeting 90 – 22 October 2015 | ICAT Project

ICAT Project

Search

Meeting 90 – 22 October 2015

Agenda

+
    +
  • Actions from meeting 89 (Steve)
  • +
  • Component development +
      +
    • ICAT (Steve)
    • +
    • ICAT Manager
    • +
    • Python-icat (Rolf)
    • +
    • IDS (Steve) +
        +
      • FUSE (Alex)
      • +
      • Globus transfer (Frazer)
      • +
      • SmartClient (Steve)
      • +
      • WebDAV (Kevin)
      • +
      +
    • +
    • TopCAT (Wayne)
    • +
    • IJP (Brian R)
    • +
    • ICAT Dashboard (Alex)
    • +
    • Installation (Steve)
    • +
    +
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • AOB (Any)
  • +
+

Present: Steve, Wayne, Frazer, Jody, Brian R, Kevin, Rolf, Shelly, +Peter, Tom

+

Apologies: Andy

+

Action 89.0  Steve created an area on github for ICAT dashboard.

+

Action 87.5  Steve gave permission to Rolf to allow write access to ICAT +repository and Rolf has populated it.

+
    +
  • This is Wayne’s last meeting before he leaves STFC.
  • +
  • Jody Salt was introduced who is taking over Wayne’s work on TopCAT.
  • +
  • Steve mentioned that it is not possible to define a startup sequence +in Wildfly so the components will have to be able to wait until +dependencies are available before starting up fully.
  • +
  • If the IDS starts up without an ICAT available then it needs to fail +graciously and loop whilst waiting for the ICAT to be available.
  • +
  • Steve has fixed a few small IDS problems.
  • +
  • Diamond were having a problem with the IDS failing to restore a file +but continuously trying – this needs fixing.
  • +
  • Globus and SmartClient downloading will be tested more as TopCAT V2 +gets more testing.
  • +
  • Tom explained the Diamond requirement to have the ability to restore +files from an IDS to a local HPC cluster and asked if there was +wider interest in this.
  • +
  • Shelly commented that SNS would be interested in this.
  • +
  • Kevin reported that the WebDAV client for CLF has been released for +testing and he is awaiting feedback. It is on a public GitHub repo – +not the ICAT one yet as it is still a bit CLF specific to be of +wider use. It will be modified to make it work for ISIS shortly.
  • +
  • ICAT Dashboard development has started. The IDS will log using JMS +so that the dashboard gets the data it needs. Steve is proposing to +move ICAT call logging to JMS as well.
  • +
  • The ICAT installer now works first time since a fix in ICAT 4.5.1.
  • +
  • Steve has been having problems with JMS in Wildfly and has updated +to a later version which has less problems. He hopes to have an ICAT +running on Wildfly in about a week’s time.
  • +
  • Rolf has just reported and issue with TopCAT V2 following on from +the conversation on the
  • +
+

icatgroup.

+

Actions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ITEMDESCRIPTIONASSIGNED
90.0Make the software to restore files from the IDS to a local filesystem/HPC cluster available to the ICAT communityFrazer
89.1Provide feedback on icat.server 4.6.0 snapshot (relating to Lucene search API)Jody
88.0Discuss use of existing icat sessions in python-icat with Rolf.Brian
85.2Provide an example ICAT facility page for ISIS in icatproject.orgTom
85.3Migrate ICAT Manager to the ICAT project GitHubAndy
81.0Report bug in eclipselinkSteve
74.0Look into JDBC connector resilience with WildflySteve
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2015-meetings/meeting-91-19-november-2015/index.html b/collaboration/communication/monthly-meetings/2015-meetings/meeting-91-19-november-2015/index.html new file mode 100644 index 000000000..ba7434dfd --- /dev/null +++ b/collaboration/communication/monthly-meetings/2015-meetings/meeting-91-19-november-2015/index.html @@ -0,0 +1,102 @@ +Meeting 91 – 19 November 2015 | ICAT Project

ICAT Project

Search

Meeting 91 – 19 November 2015

Agenda

+
    +
  • Actions from meeting 90 (Steve)
  • +
  • Component development +
      +
    • ICAT (Steve)
    • +
    • ICAT Manager
    • +
    • Python-icat (Rolf)
    • +
    • IDS (Steve) +
        +
      • FUSE (Alex)
      • +
      • Globus transfer (Frazer)
      • +
      • SmartClient (Steve)
      • +
      • WebDAV (Kevin)
      • +
      +
    • +
    • TopCAT (Jody)
    • +
    • IJP (Brian R)
    • +
    • ICAT Dashboard (Alex)
    • +
    • Multi-container support (Steve)
    • +
    • Installation (Steve)
    • +
    +
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • AOB (Any)
  • +
+

Present: Steve, Tom, Frazer, Jody, Brian R, Kevin, Rolf, Peter, Jianguo

+

Apologies: Alex, Andy

+

Action 90.0 Make the software to restore files from the IDS to a local +filesystem/HPC cluster available to the ICAT community. Frazer reported +that emails had been exchanged.

+

Action 85.2 Provide an example ICAT facility page for ISIS in +icatproject.org. Tom has send information to Steve.

+
    +
  • CLF are starting to use  the WebDav system but it is not yet in a +state where it can be easily used by other facilities.
  • +
  • getSize calls in TopCAT 2 are now sent to ICAT for multiple files to +improve performance. Jody has addressed a number of issues and is +now working to make use of the ICAT Lucene indexing.
  • +
  • One of the IJP batch connectors was considering machines that were +DOWN rather than OFFLINE to be ONLINE.
  • +
  • ICAT 4.6 Snapshot, which has not yet been made generally available, +works with multiple containers (WildFly and Glassfish) apart from +Message Driven Beans and more importantly there are problems with +transaction handling in Hibernate which is the default JPA +implementation for WildFly.
  • +
  • When building the Lucene index with the ICAT 4.6 Snapshot – large +amounts of memory are needed.
  • +
  • ICAT 4.6 should be released soon.
  • +
  • Peter reported that he had been working on Puppet components for +ICAT management. He was encouraged to share these on
  • +
+

Contrib.

+

Actions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ITEMDESCRIPTIONASSIGNED
91.0Add Puppet modules to contribPeter
89.1Provide feedback on icat.server 4.6.0 snapshot (relating to Lucene search API)Jody
85.3Migrate ICAT Manager to the ICAT project GitHubAndy
81.0Report bug in eclipselinkSteve
74.0Look into JDBC connector resilience with WildflySteve
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2015-meetings/meeting-92-17-december-2015/index.html b/collaboration/communication/monthly-meetings/2015-meetings/meeting-92-17-december-2015/index.html new file mode 100644 index 000000000..32ec94695 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2015-meetings/meeting-92-17-december-2015/index.html @@ -0,0 +1,124 @@ +Meeting 92 – 17 December 2015 | ICAT Project

ICAT Project

Search

Meeting 92 – 17 December 2015

Agenda

+
    +
  • Actions from meeting 91 (Steve)
  • +
  • Report from steering group meeting #3 (Tom/Andy)
  • +
  • Component development +
      +
    • ICAT (Steve)
    • +
    • ICAT Manager
    • +
    • Python-icat (Rolf)
    • +
    • IDS (Steve) +
        +
      • FUSE (Alex)
      • +
      • Globus transfer (Frazer)
      • +
      • SmartClient (Steve)
      • +
      • WebDAV (Kevin)
      • +
      +
    • +
    • TopCAT (Jody)
    • +
    • IJP (Brian R)
    • +
    • ICAT Dashboard (Alex)
    • +
    • Multi-container support (Steve)
    • +
    • Installation (Steve)
    • +
    +
  • +
  • icatproject.org (Steve)
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • AOB (Any)
  • +
+

Present: Steve, Tom, Frazer, Jody, Brian R, Kevin, Rolf, Peter, Jianguo, +Alex and Chris P

+

Apologizes: Shelly.

+

Action 91.0 Add Puppet modules to contrib. Peter has added them to +github but still needs to put them into the ICAT organization area.

+

Action 89.1 Provide feedback on icat.server 4.6.0 snapshot (relating to +Lucene search API).  Jody explained how the search works well but there +are a few minor issues that require further communication with Steve.

+

Action 81.0 Steve has reported 3 bugs in eclipselink. Currently waiting +on feedback from the Eclipse team.

+
    +
  • Steve has created a paper on some possible upcoming ICAT +enhancements.
  • +
  • Steve brought forward the new request of adding a DOI attribute to +the DatafileCollection entity – there was no objection.
  • +
  • Rolf has released a new version of python ICAT 0.10. The release +includes some important improvements. Rolf would like to move to a +major release 1.0 but this would require more user feedback.
  • +
  • Rolf is going to create and post a user survey on python ICAT in +January to gather feedback.
  • +
  • Steve is putting in JMS calls for the IDS to allow the Dashboard to +gather information on what the IDS is being used for. The JMS +logging will be for all calls.
  • +
  • The TopCAT in development can now combine columns on browsing. You +can also specify custom templates for cells and a custom JPQL +expression for the combining of columns.
  • +
  • The Dashboard now has a full stack skeleton with some data being +displayed in graphs. Development is being pushed to fill out the +Skeleton for the first sprint review meeting at the end of January.
  • +
  • Tom reported on the recent ICAT steering group meeting. The main +point from the meeting was the plan to co-locate the next +face-to-face ICAT meeting with the NOBUGS conference being +organised by ESS in Copenhagen in October.
  • +
  • Shelly is preparing specification/requirements for an alternative +authorization
  • +
+

scheme.

+

Actions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ITEMDESCRIPTIONASSIGNED
92.0Provide feedback on the ICAT enhancements paper. Even if there is no feedback respond with such.All
92.1Provide feedback on the idea of adding a DOI attribute to the DatafileCollection.All
92.2Provide information on LSF’s use and potential future use of ICAT components.Jianguo
92.3Create user survey for Python ICAT.Rolf
91.0Add Puppet modules to contribPeter
85.3Migrate ICAT Manager to the ICAT project GitHubAndy
74.0Look into JDBC connector resilience with WildflySteve
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2016-meetings/index.html b/collaboration/communication/monthly-meetings/2016-meetings/index.html new file mode 100644 index 000000000..91d890ab8 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2016-meetings/index.html @@ -0,0 +1,18 @@ +2016 Meetings | ICAT Project

ICAT Project

Search

2016 Meetings

+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2016-meetings/meeting-100-25-august-2016/index.html b/collaboration/communication/monthly-meetings/2016-meetings/meeting-100-25-august-2016/index.html new file mode 100644 index 000000000..48ceaf3d2 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2016-meetings/meeting-100-25-august-2016/index.html @@ -0,0 +1,136 @@ +Meeting 100 – 25 August 2016 | ICAT Project

ICAT Project

Search

Meeting 100 – 25 August 2016

Agenda:

+
    +
  • Actions from meeting 99 (Steve)
  • +
  • Component development +
      +
    • ICAT (Steve)
    • +
    • ICAT Manager (Alex)
    • +
    • Python-icat (Rolf)
    • +
    • IDS (Steve) +
        +
      • FUSE
      • +
      • PollCat (Frazer)
      • +
      • SmartClient (Steve)
      • +
      • WebDAV (Tom Gowland)
      • +
      +
    • +
    • TopCAT (Jody)
    • +
    • IJP (Brian R & Becky)
    • +
    • ICAT Dashboard (Tom Gowland)
    • +
    • Multi-container support (Steve)
    • +
    • Installation (Steve)
    • +
    +
  • +
  • Face to Face meeting for 2016 and NOBUGS (Steve)
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • AOB (Any)
  • +
+

Present: Brian R, Tom Griffin, Becky, Steve, Jeremy, Frazer, Sylvie, +Andy, Peter, Alex and Tom Gowland

+

Apologies: Rolf and Jianguo

+

Action 98.1: Tom Griffin has now been removed from the action to +“Publish state for STFC production deployments” leaving Kevin +assigned.

+

Action 99.0: Tom Gowland has produced a draft of the screencast for +TopCAT. He has received very useful feedback and will be producing a new +draft shortly.

+
    +
  • ICAT: Steve reported on the issue surrounding duplicate datafile +locations. Rolf wrote in the ICAT group that because if the IDS has +hash function protection of the location field then datafiles can’t +be cloned. To circumvent this problem requires that ICAT and the IDS +must communicate somehow.  Andy asked which facility requires +duplicate datafiles and why. Steve replied that it is Octopus that +require the duplication and DLS already have a huge number. Steve +also reported that he is working on a Restful API client in Python. +Due to the synergy between python and JSON, this is working well. +Steve has also been working on the general documentation around +ICAT.
  • +
  • ICAT Manager: Andy reported that there was nothing planned yet +regarding the issues in GitHub and suggested that perhaps it should +be something to be talked about at the face to face meeting in +October.
  • +
  • IDS: Steve reported that he wants to allow to manage multiple files +with the same physical location for both downloaded and deletion.
  • +
  • PollCAT: Frazer reported that there has been more development on +staging to SCARF. Shirley has been writing the code for this but it +still needs testing.
  • +
  • SmartClient: Steve reported that Jody has been integrating +SmartClient into TopCAT and wasn’t happy about the user having to +accept a self-signed certificate. Steve has now set the server of +the SmartClient to run on http as the only requests will come from +localhost.
  • +
  • WebDAV: Tom Gowland reported that he has been working on the WebDAV +system to allow it to be more dynamic. WebDAV now works for the ISIS +facility (and hierarchy) and he is planning to allow it to be more +configurable such that it can work for any facility after setting +values in configuration files.
  • +
  • TopCAT: Steve reported on behalf of Jody. TopCAT is now pluggable +meaning that the backend can be implemented in any language or +framework. Jody is also working with Frazer on a TopCAT plugin that +allows for remote analysis of data with ICAT. The DOI generation has +bee separated out into another plugin. Becky also reported that she +had been working on external filters meaning that you can now have +filters other than the ones at the top of each grid. Andy thought +that TopCAT seemed to be running slowly when trying to calculate the +size of many datafiles and that when the page was refreshed it tried +to calculate these sizes again. Tom Griffin reported that the issue +had been fixed in TopCAT 2.1 and Andy confirmed he was using version +2.0.
  • +
  • IJP: Becky reported that she has re-implemented the IJP GUI as a +plugin for TopCAT. This is due to be released at the same time as +the next version of TopCAT. Brian reported that he had been making +minor changes to the backend including refreshing job types at +regular intervals (a requirement from Octopus) and also adding +miredot document generation to the server.
  • +
  • Dashboard: Tom reported that he is working on building and deploying +the Dashboard as well as being able to configure it properly in +preparation for the demonstration at the face to face meeting.
  • +
  • Face to face meeting: Steve reported that he has uploaded the agenda +for the meeting and has updated it to give Rolf a slot to present +Ingestion with Python-ICAT. He has also removed Rolf from the IDS +talk and Steve may be talking about this in his stead. The steering +group meeting time has been set to 17:30 and will take place at the +Avenue Hotel. Steve also welcomed any proposals for site reports. +Andy also reported that he had uploaded an agenda for the steering +group meeting and welcomes any feedback people
  • +
+

have.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionAssigned
98.1Publish state for STFC production deploymentsKevin
99.0Produce a screencast for the TopCAT demoTom Gowland
100.0Submit a bug for adding the upgrade path for TopCAT JSONSteve
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2016-meetings/meeting-101-22-september-2016/index.html b/collaboration/communication/monthly-meetings/2016-meetings/meeting-101-22-september-2016/index.html new file mode 100644 index 000000000..3717901d3 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2016-meetings/meeting-101-22-september-2016/index.html @@ -0,0 +1,106 @@ +Meeting 101 – 22 September 2016 | ICAT Project

ICAT Project

Search

Meeting 101 – 22 September 2016

Agenda:

+
    +
  • Actions from meeting 100 (Steve)
  • +
  • Component development +
      +
    • ICAT (Steve)
    • +
    • ICAT Manager (Alex)
    • +
    • Python-icat (Rolf)
    • +
    • IDS (Steve) +
        +
      • PollCat (Frazer)
      • +
      • SmartClient (Steve)
      • +
      • WebDAV (Tom Gowland)
      • +
      +
    • +
    • TopCAT (Jody)
    • +
    • IJP (Brian R)
    • +
    • ICAT Dashboard (Tom Gowland)
    • +
    • Multi-container support (Steve)
    • +
    • Installation (Steve)
    • +
    +
  • +
  • Face to Face meeting for 2016 and NOBUGS (Steve)
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • AOB (Any)
  • +
+

Present: Steve, Kevin, Frazer, Jody, Jeremy, Tom Griffin, Tom Gowland, +Jianguo, Milan, Peter, Rolf, Andy, Gordon Brown, Brian M

+

Apologies: Cathy

+

Action 98.1: Kevin has been looking into the states for STFC production +deployments and is working on producing the report.

+

Action 99.0: Produce a screencast for the TopCAT demo: Tom Gowland +reported that he has split the screencast into two separate videos, one +aimed at facilities and another, shorter video aimed at users. He also +reported that he is looking for feeback about the screencasts.

+

Action 100.0: There turned out to be no upgrade path needed and Jody was +able to confirm this.

+
    +
  • ICAT: Steve reported that he has improved the documentation for the +ICAT client and server. He also reported that he has released the +4.8.0 snapshot. This update allows the server to update individual +attributes for DOIs and it also adds the clone entity operation. The +client now has a new python class which uses the RESTful API and +handles error conditions better.
  • +
  • IDS: Steve reported that the IDS now supports multiple datafiles +that have the same location.
  • +
  • WebDav: Tom Gowland reported that he has been working on making +WebDav more responsive as well as allowing it to be more dynamic. He +has been working on issues related to Windows file path issues where +certain characters are not allowed. Steve reported that WestLife are +interested in WebDav.
  • +
  • TopCAT: Jody reported that there has been a significance performance +increase mainly due to the optimization of the loading spinners. +TopCAT is now also more pluggable and he is currently working on a +DOI plugin which can be used at Diamond and now thinks it will be +more sensible to produce a separate DOI plugin for ISIS if the +Diamond one can’t be used there.
  • +
  • Dashboard: Tom Gowland reported that he has been working through the +various tickets surrounding Dashboard in the hope to get a more +easily deployable application that works for multiple hierarchies. +He has also been doing some front-end development to add more graphs +to the main pages of Dashboard.
  • +
  • NOBUGS: Steve reported that the deadline for submitting talks is the +4 ^(th) of October. Brian Matthews commented that he thinks that +there should be a reference paper for ICAT and the ICAT family in +general. Steve also appealed for anyone wishing to do a site report +as well as anyone happy to do a session about using Docker. Rolf and +Peter agreed to do a session on Docker.
  • +
  • AOB: Rolf reported that if IDS gets an I/O error that it currently +isn’t logged. Steve said that he would look into it. Andy reported +problems with Lucene and asked if they could be down to the +specification of his machine. Kevin reported that this should be +addressed in the report that he is producing and there was general +agreement that 500MB was probably not enough RAM for Lucene +indexing. Brian Matthews reported that the Research Data Alliance +(RDA) are interested in the interop abilities between ICAT and other +data catalogues.
  • +
+ + + + + + + + + + + + + + + + + + + + +
ItemDescriptionAssigned
98.1Publish state for STFC production deploymentsKevin
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2016-meetings/meeting-102-17-november-2016/index.html b/collaboration/communication/monthly-meetings/2016-meetings/meeting-102-17-november-2016/index.html new file mode 100644 index 000000000..1abd45a0f --- /dev/null +++ b/collaboration/communication/monthly-meetings/2016-meetings/meeting-102-17-november-2016/index.html @@ -0,0 +1,102 @@ +Meeting 102 – 17 November 2016 | ICAT Project

ICAT Project

Search

Meeting 102 – 17 November 2016

Agenda

+
    +
  • Actions from meeting 101 (Steve)
  • +
  • Copenhagen meeting – what did we do wrong and what did we get right
  • +
  • Component development +
      +
    • ICAT (Steve)
    • +
    • ICAT Manager (Alex)
    • +
    • Python-icat (Rolf)
    • +
    • IDS (Steve) +
        +
      • PollCat (Frazer)
      • +
      • SmartClient (Steve)
      • +
      • WebDAV (Tom Gowland)
      • +
      +
    • +
    • TopCAT (Jody)
    • +
    • IJP (Brian R and Thomas)
    • +
    • ICAT Dashboard (Tom Gowland)
    • +
    • Multi-container support (Steve)
    • +
    • Installation (Steve)
    • +
    +
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • AOB (Any)
  • +
+

Present: Steve, Gordon Brown, Frazer, Kevin, Sylvie, Brian R.,  Shelley, +Milan, Peter, Rolf

+

Apologies: Cathy. Tom Gowland. Jody, Alex. Jianguo Rao.

+

Action 98.1: Kevin has  publish state for STFC production deployments +via the google group.

+
    +
  • Copenhagen meeting – what did we do wrong and what did we get +right: Rolf and Milan said it was very nice. half a dozen new +people.  Maybe too fast and too much information for +newcomers?  Steve didn’t feel he got much feedback,
    +except for the person from ELI/ALPS. Not checked with Brian M. to +see if any followup with the people he was looking after.
  • +
  • ICAT development – Steve has added SOAP call to find out about +authenticators. Developed a REST authenticator; easy to add more. +REST mechanism works side by side with old mechanism.
    +It also allows failover – try successive auth servers. Working +on making lucene access as separate RESTful component,
    +which can then be shared by multiple ICATs. There will be a
    +lightweight security mechanism using known ip addresses.
  • +
  • IDS – Locking work by Rolf is waiting for comments from Steve.
  • +
  • IJP – Brian reported that Tom Attwood, an ISIS graduate, is on loan +to us for two months and is working on modifications to the IJP. +Most of these are specific to Octopus, though some will be more +generally applicable. He has modified the IJP GUI so that when +dataset versioning is used, only the most recent version of each +dataset will be shown in results. He is now working on linking job +provenance to the IJP’s job details. There are two main changes +here: a RESTful call that jobscripts can make
    +to pass the ID of any provenance record to the IJP; and modifying +the IJP GUI to allow users to see provenance details of their +jobs.
    +Brian has updated the IJP demo project (in light of Tom’s experience +in installing it). Brian notes that the official releases of IJP +components are not compatible with the current ICAT/IDS releases, +and he should produce new releases.
  • +
  • ICAT Dashboard – Tom reported that it now works for any hierarchy.
  • +
  • Multi-container support – Installation script for Payara +(supported/maintained version of glassfish 4.1). Steve recommends +using it once installation scripts have been updated. Will need new +release of all components.
  • +
  • Issues from ICAT production deployments (Any)
    +Rolf: discussed OAI-PMH at HZB, decided nice student project. In the +next year? If so, deadline early August, prototype August. Steve +suggested an earlier interaction might be useful.  Project would be +10 weeks; but will use Github, so can
  • +
+

track.

+

Actions

+ + + + + + + + + + + + + + + + + + + + +
ItemDescriptionAssigned
102.1Send message to icatgroup explaining proposed modification to plugin interface for IDS lockingRolf
102.2Produce new releases of IJP componentsBrian R.
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2016-meetings/meeting-93-28-january-2016/index.html b/collaboration/communication/monthly-meetings/2016-meetings/meeting-93-28-january-2016/index.html new file mode 100644 index 000000000..93ddd9628 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2016-meetings/meeting-93-28-january-2016/index.html @@ -0,0 +1,163 @@ +Meeting 93 – 28 January 2016 | ICAT Project

ICAT Project

Search

Meeting 93 – 28 January 2016

Agenda

+
    +
  • Actions from meeting 92 (Steve)
  • +
  • Component development +
      +
    • ICAT (Steve)
    • +
    • ICAT Manager
    • +
    • Python-icat (Rolf)
    • +
    • IDS (Steve) +
        +
      • FUSE (Alex)
      • +
      • Globus transfer (Frazer)
      • +
      • SmartClient (Steve)
      • +
      • WebDAV (Kevin)
      • +
      +
    • +
    • TopCAT (Jody) – with demo
    • +
    • IJP (Brian R)
    • +
    • ICAT Dashboard (Alex)
    • +
    • Face to Face meeting for 2016 (Steve)
    • +
    +
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • AOB (Any)
  • +
+

Present: Frazer, Jody, Jianguo, Steve, Brian R, Kevin, Tom,  Rolf, Alex +dM and Shelley

+

Apologizes: Alex PD.

+

Action 92.0 Provide feedback on the ICAT enhancements paper.  Some have +been provided this can be marked as done.

+

Action 92.1Provide feedback on the idea of adding a DOI attribute to the +DatafileCollection. There have been no objections so it will happen in +ICAT 4.7

+

Action 92.3 Rolf has produced a python-icat survey but has only three +responses so far.

+

Action 91.0 Peter has added his Puppet modules to contrib and included a +link to Travis

+

Action 85.3 Migrate ICAT Manager to the ICAT project GitHub. The action +was transferred from Andy to Alex de Maria.

+
    +
  • Steve reported on progress with ICAT 4.6 which is almost ready to go +out with the following new features: +
      +
    • “getProperties()” restful call to find out what can be revealed +about a server without a sessionId. This includes maxEntities +and information about the available authenticators. Requires +updated authenticators
    • +
    • New calls added to the restful interface for lucene queries.
    • +
    • Documentation for the restful interface is now generated by +MireDot.
    • +
    • Changes to properties files to work with container independent +setup script.
    • +
    • Change from log4j to slf4j with logback
    • +
    +
  • +
  • Steve also reported that ICAT 4.7 is in a good state with the +following features: +
      +
    • A restful select can mention multiple quantities to be returned
    • +
    • A major re-write of the authorization code should make it more +efficient in most cases as all the work is carried out by the +database unless the INCLUDE mechanism is used.
    • +
    • COUNT queries will not fail because they are are counting more +than maxEntities values
    • +
    • A couple of bugs in eclipse link result in incorrect information +being returned. One of these bugs was trapped previously but +with the generality of the queries now supported it has become +impractical to trap.
    • +
    • A restful delete(Many) call has been added. Authz is applied to +all entities involved
    • +
    • A restful write call to do both create(Many) and update(Many) +has been written. Notifications are sent for all objects created +and/or updated. Authz is also applied to all new or updated +entries.
    • +
    +
  • +
  • This was followed by a discussion about Rolf’s pull request to add a +SOAP call to be able to find out about the authenticators (which is +currently only available in the SOAP call). Steve wants to support +the SOAP web service while it is needed – which will of course +include bug fixes – but not to enhance it. He considers that the +extra efficiency of the RESTful interface means that new application +code should avoid the SOAP API. Shelley said she was happy to have +only RESTful and Kevin emphasised the need to maintain the SOAP +interface while it is needed by existing code.
  • +
  • Alex dM is starting to familiarise himself with the ICAT manager. He +plans to visit RAL soon.
  • +
  • A small change is being made to the JMS messages that the Dashboard +can pick up from the IDS. Rolf has found a possible bug and is +investigating more possible race conditions.
  • +
  • Jody then gave a demo of TopCAT. The new interface was generally +appreciated. Alex dM suggests that Jody make a screencast of his +demo.  Shelley asked whether it would be possible for users +to annotate metadata to help with re-running auto-reduction of +their data.  This is not possible at present, but may be considered +in future (along with other features such as the ability to mint +DOIs).  Steve asked whether there are known performance issues +with large volumes of data. There is no problem with ISIS but the +Diamond data has not been indexed yet.
  • +
  • Steve reported that  from Alex PD had reported that a sprint review +would be held mid February. It was suggested to give a demo at the +next ICAT meeting.
  • +
  • Concerning the F2F meeting which we hope to co-locate with NOBUGS, +Steve has not received a reply yet from the organisers.
  • +
  • Rolf reported they have a new person, “Michael Hellmig”.
  • +
  • Tom reported that there are now 1.1 billion files in the Diamond +ICAT catalogue. They are not yet indexed – with an estimated four +months to build the lucene index. (Note that at the time of writing +these minutes the estimate is now four and a half days.)
  • +
  • Shelley said they have a second facility and are considering using +the same ICAT instance for both. Kevin pointed out that for +CLF separate ICAT instances are used for each laser, as their +non-overlapping downtimes would otherwise make it difficult to +schedule upgrades.
  • +
  • Alex dM asked whether TopCAT would be able to cope with different +versions of ICAT and IDS. The general view was that this should be +possible except for very old
  • +
+

versions.

+

Actions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionAssigned
93.0Make screencast of TopCAT demoJody
93.1Demo of dashboardAlex PD
92.2Provide information on LSF’s use and potential future use of ICAT components.Jianguo
85.3Migrate ICAT Manager to the ICAT project GitHubAlex dM
74.0Look into JDBC connector resilience with WildflySteve
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2016-meetings/meeting-94-25-february-2016/index.html b/collaboration/communication/monthly-meetings/2016-meetings/meeting-94-25-february-2016/index.html new file mode 100644 index 000000000..0e9a9d1a3 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2016-meetings/meeting-94-25-february-2016/index.html @@ -0,0 +1,103 @@ +Meeting 94 – 25 February 2016 | ICAT Project

ICAT Project

Search

Meeting 94 – 25 February 2016

AGENDA

+
    +
  • Actions from meeting 93 (Steve)
  • +
  • Component development +
      +
    • ICAT (Steve)
    • +
    • ICAT Manager
    • +
    • Python-icat (Rolf)
    • +
    • IDS (Steve) +
        +
      • FUSE (Alex)
      • +
      • Globus transfer (Frazer)
      • +
      • SmartClient (Steve)
      • +
      • WebDAV (Kevin)
      • +
      +
    • +
    • TopCAT (Jody)
    • +
    • IJP (Brian R)
    • +
    • ICAT Dashboard (Alex)
    • +
    • Multi-container support (Steve)
    • +
    • Installation (Steve)
    • +
    • Face to Face meeting for 2016 (Steve)
    • +
    +
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • AOB (Any)
  • +
+

Present: Frazer, Jody, Steve, Brian R, Kevin, Tom, Milan, Andy, Kevin, +Peter, Alex dM and Shelley

+

Apologies: Rolf

+

Action 93.1 Demo of the dashboard was carried out.

+
    +
  • Steve reported that a bug was found in the ICAT 4.6 release. The bug +only affects the call to update. Advice was to move to 4.6.1.
  • +
  • Logging in ICAT 4.7 has been transferred from the Log table to JMS +messaging. The logging data will now be captured and processed by +the Dashboard. The format of the ICAT JMS messages will be the same +as the IDS ones.
  • +
  • Tom reported that the Globus server is moving from development to +production in the coming month.
  • +
  • Jody reported that TopCat has had many small improvements. Mainly +aimed towards ISIS requirements. It was also reported that TopCat in +the coming month will be pushed into production for both Diamond and +ISIS.
  • +
  • Alex commented on how the TopCat installation is straightforward and +very similar to how other ICAT family components are installed.
  • +
  • Alex demonstrated the Dashboard with it’s current features. Feedback +was generally
  • +
+

positive.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionAssigned
94.0Create a formal release of TopCat 2.0Jody
94.1Provide any requirements for the DashboardAll
93.0Make screencast of TopCAT demoJody
92.2Provide information on LSF’s use and potential future use of ICAT components.Jianguo
85.3Migrate ICAT Manager to the ICAT project GitHubAlex dM
74.0Look into JDBC connector resilience with WildflySteve
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2016-meetings/meeting-95-17-march-2016/index.html b/collaboration/communication/monthly-meetings/2016-meetings/meeting-95-17-march-2016/index.html new file mode 100644 index 000000000..93be942cc --- /dev/null +++ b/collaboration/communication/monthly-meetings/2016-meetings/meeting-95-17-march-2016/index.html @@ -0,0 +1,129 @@ +Meeting 95 – 17 March 2016 | ICAT Project

ICAT Project

Search

Meeting 95 – 17 March 2016

Agenda

+
    +
  • Actions from meeting 94 (Steve)
  • +
  • Component development +
      +
    • ICAT (Steve)
    • +
    • ICAT Manager
    • +
    • Python-icat (Rolf)
    • +
    • IDS (Steve) +
        +
      • FUSE (Alex)
      • +
      • Globus transfer (Frazer)
      • +
      • SmartClient (Steve)
      • +
      • WebDAV (Kevin)
      • +
      +
    • +
    • TopCAT (Jody)
    • +
    • IJP (Brian R)
    • +
    • ICAT Dashboard (Alex)
    • +
    • Multi-container support (Steve)
    • +
    • Installation (Steve)
    • +
    • Face to Face meeting for 2016 (Steve)
    • +
    +
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • AOB (Any)
  • +
+

Present: Kevin, Steve, Jody, Brian R, Becky, Frazer, Rolf, Milan

+

Apologizes: Tom, Andy, Jianguo

+

Action 85.3 Steve reported that Alex has migrated the whole of ICAT +Manager to github and that the version on github is more up to date the +the package hosted on the ESRF website.

+
    +
  • Becky introduced herself to the team. She is a graduate on a 6 month +placement within the Research Data Group who will be working on a +new GUI for the ICAT Job Portal.
  • +
  • Steve talked about Alex and Andy’s visit to RAL being very +informative and useful for both teams.
  • +
  • ICAT 4.7 is moving along with many of the new features complete. +Steve is currently working on getting multiple ICATs to work with an +Apache front end.  Currently there are a few issues with the Apache +front end.
  • +
  • There was a discussion about the Update Semantics. There were +worries about the complexity of the problem and further research is +required.
  • +
  • There was a discussion about the request to add an Orchid Id field +to the user table. There was also a discussion about adding more +fields which brought up concerns about security and possibly +accessing data directly from the User office. This was another point +that would require more thought.
  • +
  • Steve talked about adding a Boolean flag to the IDS properties file +to ask the user if they would like the IDS to write as fast as it +can or as slowly as you can to tape systems.
  • +
  • Steve talked about the changes to the IDS-plugin where the plugin +used to depend on the ICAT-utils which would then depend on the +ICAT. This would cause the plugin to be unnecessarily large. This +has now been changed.
  • +
  • Frazer talked about a new node being set-up for SCARF that will +allow users to download data from TopCat which would then be staged +in a home directory in SCARF.
  • +
  • TopCats major tickets are now complete apart from one which is now +being worked on for the upcoming release.
  • +
  • Brian discussed about how there new work is starting on the IJP. LSF +have presented Brian R with some new requirements that have been +collected over the past year. Becky will now start working on the +new user interface. There have been meetings with LSF to discuss +what they would like to see in the UI and mocks up are now starting +to be created.
  • +
  • Alex talked about how the Dashboard now collects and presents data +on current downloads and failed downloads. There will be a snapshot +produced soon which will then require further user testing.
  • +
  • There was further discussion on the upcoming ICAT meet up and how we +should try to invite more people from outside the teams to spread +the word of
  • +
+

ICAT.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionAssigned
95.0Tom to circulate current Dashboard RequirementsTom
94.0Create a formal release of TopCat 2.0Jody
94.1Provide any requirements for the DashboardAll
93.0Make screencast of TopCAT demoJody
92.2Provide information on LSF’s use and potential future use of ICAT components.Jianguo
74.0Look into JDBC connector resilience with WildflySteve
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2016-meetings/meeting-96-28-april-2016/index.html b/collaboration/communication/monthly-meetings/2016-meetings/meeting-96-28-april-2016/index.html new file mode 100644 index 000000000..ed92202ab --- /dev/null +++ b/collaboration/communication/monthly-meetings/2016-meetings/meeting-96-28-april-2016/index.html @@ -0,0 +1,108 @@ +Meeting 96 – 28 April 2016 | ICAT Project

ICAT Project

Search

Meeting 96 – 28 April 2016

Agenda

+
    +
  • Actions from meeting 95 (Steve)
  • +
  • Component development +
      +
    • ICAT (Steve)
    • +
    • ICAT Manager (Alex)
    • +
    • Python-icat (Rolf)
    • +
    • IDS (Steve) +
        +
      • FUSE (Alex)
      • +
      • Globus transfer (Frazer)
      • +
      • SmartClient (Steve)
      • +
      • WebDAV (Kevin)
      • +
      +
    • +
    • TopCAT (Jody)
    • +
    • IJP (Brian R)
    • +
    • ICAT Dashboard (Alex)
    • +
    • Multi-container support (Steve)
    • +
    • Installation (Steve)
    • +
    +
  • +
  • Face to Face meeting for 2016 (Steve)
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • AOB (Any)
  • +
+

Present: Peter , Steve, Jody, Brian R, Brian M, Rolf, Tom, Shelly and +Andrew

+

Apologies: Andy and Milan

+

Action 95.0 The requirements were successfully circulated to the ICAT +group.

+

Action 94.0 Jody created a formal release of TopCat V2.0.0. This was +successfully released onto Diamond and out to the community.

+

Action 94.1 All the requirements for the Dashboard have been now been +gathered and uploaded onto GitHub.

+
    +
  • Steve reported that there are currently two things that are +preventing the release of ICAT 4.7. Firstly, the possible addition +of an extra call to see if a user is still currently logged in. +Secondly, the load balancing with multiple ICATs which is +potentially being caused by Apache timeouts.
  • +
  • The release of IDS 4.6 is very close to release however there is one +small issue that is holding it up. This issue is to do with the +current getSize call now taking minutes. Steve has been given access +to the machines that are presenting this behaviour so the problem +can be explored further.
  • +
  • Brian reported that he and Becky are working on changes towards the +IJP. Becky has presented some new mock ups to Octopus which have +been accepted. Brian has also been thinking about how to support the +Octopus requirement for versions on dataset collections.
  • +
  • Alex reported that the Dashboard is nearly completion from its +initial requirements. The next stage is releasing a snapshot  so +that people can have a go with it.
  • +
  • Steve spoke about the upcoming ICAT face to face. There was a +discussion on the schedule and how it could possibly play out over +the two days.
  • +
  • Rolf reported that he has been playing around with Docker and +explained what he might do with it going forward.
  • +
  • Peter and Shelly explored an idea about having a more abstract layer +onto of the ICAT API to shield the consumers of their ICAT from any +schema/API changes. There was a following short discussion on +possible alternatives and the use case for an extra
  • +
+

layer.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionAssigned
96.0Assign screencast role for the TopCAT demoTom
96.1Release a snapshot of the DashboardAlex/Steve
92.2Provide information on Octopus’s use and potential future use of ICAT components.Jianguo
74.0Look into JDBC connector resilience with WildflySteve
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2016-meetings/meeting-97-26-may-2016/index.html b/collaboration/communication/monthly-meetings/2016-meetings/meeting-97-26-may-2016/index.html new file mode 100644 index 000000000..7881220fd --- /dev/null +++ b/collaboration/communication/monthly-meetings/2016-meetings/meeting-97-26-may-2016/index.html @@ -0,0 +1,95 @@ +Meeting 97 – 26 May 2016 | ICAT Project

ICAT Project

Search

Meeting 97 – 26 May 2016

AGENDA

+
    +
  • Actions from meeting 96 (Steve)
  • +
  • Component development +
      +
    • ICAT (Steve)
    • +
    • ICAT Manager (Alex)
    • +
    • Python-icat (Rolf)
    • +
    • IDS (Steve) +
        +
      • FUSE (Alex)
      • +
      • Globus transfer (Frazer)
      • +
      • SmartClient (Steve)
      • +
      • WebDAV (Kevin)
      • +
      +
    • +
    • TopCAT (Jody)
    • +
    • IJP (Brian R)
    • +
    • ICAT Dashboard (Alex P-D)
    • +
    • Multi-container support (Steve)
    • +
    • Installation (Steve)
    • +
    +
  • +
  • Face to Face meeting for 2016 (Steve)
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • AOB (Any)
  • +
+

Apologies: Brian R, Alex dM, Alex P-D

+

Present: Rolf, Shelly, Milan, Frazer, Rebecca, Sylvia, Jody, Jianguo, +Tom, Steve, Brian M, Peter

+

Action 96.0: Tom has now identified someone who would be able to produce +the TopCAT screencast however the action will remain with Tom for the +present.

+

Action 96.1: The dashboard snapshot has been delayed because of concerns +expressed by an STFC DBA about some potentially expensive queries.

+

Action 92.2: Jianguo has provided information on Octopus’s use and +potential future use of ICAT components.

+

Action 74.0: Steve has finally looked into JDBC connector resilience +with Wildfly. He reported that the mechanism is rather different from +the Glassfish one but it would appear to be OK and has been coded into +the setup_utils.py library.

+
    +
  • Steve reported that a number of components – in particular +icat.server and and icat.client 4.7.0 and ids.server 1.6.0 has been +released.
  • +
  • Rolf told the meeting that python-icat 0.11 was almost ready.
  • +
  • Frazer explained that the IDS Globus transfer was better called +PollCat and that it had a number of plugins – one of which was for +Globus file transfer.  PollCat is currently in a private repository +but will shortly be moved.
  • +
  • Kevin said that the WebDav interface was still not general and so +will remain in a private repository until it has been made more +general.
  • +
  • Jody reported that a second TopCAT 2.0.1 snapshot has been produced. +This may be one that can be released. It is currently planned to add +DOI generation to the next TopCAT – presumably 2.1.0. Rolf said he +would like to see file upload (which was in TopCAT 1.13.0) to be +added as well.
  • +
  • Rebecca said that Brian was restructuring the Rest API of the IJP +server to be JSON only and that there were plans to allow TopCAT to +be able to make calls to this IJP server.
  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionAssigned
96.0Assign screencast role for the TopCAT demoTom
96.1Release a snapshot of the DashboardAlex/Steve
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2016-meetings/meeting-98-23-june-2016/index.html b/collaboration/communication/monthly-meetings/2016-meetings/meeting-98-23-june-2016/index.html new file mode 100644 index 000000000..5d82fc008 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2016-meetings/meeting-98-23-june-2016/index.html @@ -0,0 +1,123 @@ +Meeting 98 – 23 June 2016 | ICAT Project

ICAT Project

Search

Meeting 98 – 23 June 2016

AGENDA

+
    +
  • Actions from meeting 97 (Steve)
  • +
  • Component development +
      +
    • ICAT (Steve)
    • +
    • ICAT Manager (Alex)
    • +
    • Python-icat (Rolf)
    • +
    • IDS (Steve) +
        +
      • FUSE (Alex)
      • +
      • PollCat (Frazer)
      • +
      • SmartClient (Steve)
      • +
      • WebDAV (Kevin)
      • +
      +
    • +
    • TopCAT (Jody)
    • +
    • IJP (Brian R)
    • +
    • ICAT Dashboard (Alex P-D)
    • +
    • Multi-container support (Steve)
    • +
    • Installation (Steve)
    • +
    +
  • +
  • Face to Face meeting for 2016 and NOBUGS (Steve)
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • AOB (Any)
  • +
+

Present:Present: Steve, Kevin, Tom, Becky, Jianguo, Brian R, +Sylvie, Peter, Milan, Rolf, Alex dM, Shelley

+

Action 96.1 Release a snapshot of the Dashboard. This has gone into +production for ISIS but has not been formally released. This will be +addressed when Alex P-D is back.

+
    +
  • Python-icat: Rolf reported that he had released version 0.11.0 with +support for icat 4.7
  • +
  • IDS: Steve has been thinking about multiple servers and multiple +caches. This will be discussed at RAL and then the ideas circulated +unless the ideas turn out not to be useful.
  • +
  • PollCat:  Frazer has moved the code to the icatproject github.
  • +
  • SmartClient: Steve reported that there had been no changes and that +he was still waiting for integration into TopCAT by Jody.
  • +
  • WebDAV: Kevin reported that Alex was due to make it more generic so +that it could aslo be used by ISIS.  Octopus/CLF are considering +using it. He also reported that there is a known vulnerability with +WebDAV and that he working on a fix.
  • +
  • TopCAT: Kevin reported that Jody had deployed a new version for ISIS +but that this is an ad-hoc snapshot.
  • +
  • IJP: Brian R reported that the new AngularJS GUI being developed by +Becky is taking shape and that he is still
    +working on getting the RESTful API to the point where the GUI can +use it. Generally this means changing the responses to return JSON +objects with all the info that the GUI needs.
  • +
  • ICAT Dashboard: Kevin reported that  Alex P-D had installed it for +ISIS. The results are interesting . It will be released properly +once Alex is back.
  • +
  • repo.icatproject.org : Steve reported that this was now ready to  be +published to by maven. To get to use it you just need +a username/password to be stored on the server.
  • +
  • The NOBUGS abstract deadline is 1st July. Steve suggests paper on +recent developments in ICAT and Tom suggests a separate publication +on IJP as talks are limited to 15 minutes plus 5 minutes for +discussion.
  • +
  • Rolf asks does anybody know anything about memory usage of glassfish +in deployments? HZB are planning to buy hardware, so need estimates. +Tom replied that STFC  use VMs and could circulate specs for them. +The IDS is run on a physical box to get the best network +performance.
  • +
  • Rolf told the meeting that HZB were adopting a data policy which was + due to be published. There was an interst from the meeting in +seeing this policy.
  • +
  • Tom announced that he is leaving Scientific Computing Department to +become the ISIS computing group leader. He will be less directly +involved in ICAT, but will appear from time to
  • +
+

time.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionAssigned
96.0Assign screencast role for the TopCAT demoTom
96.1Release a snapshot of the DashboardAlex/Steve
98.0Get Brian R a miredot licence for the IJP.Steve
98.1Publish stats for STFC production deployments.Tom and Kevin
98.2Distribute pointer to  HZB data policy when it is publishedRolf
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2016-meetings/meeting-99-28-july-2016/index.html b/collaboration/communication/monthly-meetings/2016-meetings/meeting-99-28-july-2016/index.html new file mode 100644 index 000000000..47472aafe --- /dev/null +++ b/collaboration/communication/monthly-meetings/2016-meetings/meeting-99-28-july-2016/index.html @@ -0,0 +1,102 @@ +Meeting 99 – 28 July 2016 | ICAT Project

ICAT Project

Search

Meeting 99 – 28 July 2016

Agenda:

+
    +
  • Actions from meeting 98 (Steve)
  • +
  • Component development +
      +
    • ICAT (Steve)
    • +
    • ICAT Manager (Alex)
    • +
    • Python-icat (Rolf)
    • +
    • IDS (Steve) +
        +
      • FUSE (Alex P-D)
      • +
      • PollCat (Frazer)
      • +
      • SmartClient (Steve)
      • +
      • WebDAV (Kevin)
      • +
      +
    • +
    • TopCAT (Jody)
    • +
    • IJP (Brian R & Becky)
    • +
    • ICAT Dashboard (Tom Gowland)
    • +
    • Multi-container support (Steve)
    • +
    • Installation (Steve)
    • +
    +
  • +
  • Face to Face meeting for 2016 and NOBUGS (Steve)
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • AOB (Any)
  • +
+

Present: Steve, Jody, Becky, Tom Gowland, Brian R, Rolf, Jianguo, +Shelley, Peter and Milan

+

Apologies: Cathy and Frazer

+

Action 96.0: Tom Griffin has asked Tom Gowland to 96.0 produce a +screencast to demo TopCAT.

+

Action 96.1: A final snapshot of the Dashboard was made by Alex PD.

+

Action 98.0: A Miredot licence for the IJP has been obtained.

+

Action 98.2: Rolf has distributed a pointer to the HZB data policy.

+
    +
  • ICAT: Steve reported that he is working on adding roles for single +attributes. The purpose of this is to allow investigators to control +their DOI but not to be able to fiddle with other parts. There has +also been discussion of removal of the old query language. Steve +suggests that the main part of the documentation should only discuss +JPQL and that there should be an appendix added to discuss the old +query language as some still like it (Rolf included).
  • +
  • SmartClient: Steve reported that the SmartClient will be integrated +into the next TopCAT release.
  • +
  • WebDAV: Tom reported that he will be continuing Alex PD’s work on +WebDAV following a meeting with Kevin to be arranged next week.
  • +
  • TopCAT: Jody reported that he has released TopCAT 2.1.0 which added +a feature which shows a user’s full name next to their login and +which also fixes some bugs. He also reported that there is now a +2.2.0 milestone in GitHub with tickets that need completing. The +largest issue is DOI publishing. Steve mentioned that this is +dependent on the next ICAT release which will include the ability to +control update access to individual attributes.
  • +
  • IJP: Brian R reported that the main changes to IJP have been to the +restful interface so that the GUI can access it. Becky reported that +the IJP GUI is now in development and has reached the point where it +has all of the features of the old GUI. Becky also reported that +there has been a test deployment of the IJP GUI in Octopus. The hope +is that the GUI can be extended to be available to other groups +outside of Octopus in the future.
  • +
  • NOBUGS: Steve reported that all of the NOBUGS abstracts have now +been sent off and most are still awaiting a response.
  • +
  • Rolf asked when there will be an agenda set up for the face to face +meeting for 2016. Steve replied that he was going to base the agenda +on who is coming to the meeting as the content should vary dependent +on how many newcomers there
  • +
+

are.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionAssigned
98.1Publish state for STFC production deploymentsKevin and Tom Griffin
99.0Produce a screencast for the TopCAT demoTom Gowland
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2017-meetings/index.html b/collaboration/communication/monthly-meetings/2017-meetings/index.html new file mode 100644 index 000000000..ecd490c1f --- /dev/null +++ b/collaboration/communication/monthly-meetings/2017-meetings/index.html @@ -0,0 +1,18 @@ +2017 Meetings | ICAT Project

ICAT Project

Search

2017 Meetings

+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2017-meetings/meeting-103-26-january-2017/index.html b/collaboration/communication/monthly-meetings/2017-meetings/meeting-103-26-january-2017/index.html new file mode 100644 index 000000000..96651ea25 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2017-meetings/meeting-103-26-january-2017/index.html @@ -0,0 +1,53 @@ +Meeting 103 – 26 January 2017 | ICAT Project

ICAT Project

Search

Meeting 103 – 26 January 2017

Present : Jody, Brian, Tom, Tom, Frazer, Steve, Jeremy, +Sylvie,  Andy,  Rolf and Milan

+
    +
  • Topcat – 2.3 developments presented by Jody includes file upload, +plugin api extended, doi plugin almost working now will appear as +component soon, daas plugin almost working based on openstack not +ready yet, novnc interface,
  • +
  • IDS – pull request from Rolf, still waiting for Steve to answer – +high on Steve’s list
  • +
  • icat server – 4.9 will come out in 4 weeks, next release of python +icat will be 0.13 depends on on icat server 4.9, Payara needs new +releases of all components, will drop some components from python +icat (cgi module and icat 4.2)
  • +
  • HZB – currently evaluating a storage system
  • +
  • ESRF – new beamlines (BioSAX + MX) + IDS design for ESRF storage +still on going. Rolf offered to help and visit the ESRF next month.
  • +
  • Thematic services – Andy briefly presented the proposal to integrate +icat as a service in the EINFRA12a e-infrastructures proposal. Rolf, +Tom + Steve are on board. Andy + Tom (Griffin) would be the +proposers.
  • +
  • e-logbook – brief discussion about e-logbooks and if they should be +linked to
  • +
+

icat

+

Actions

+ + + + + + + + + + + + + + + + + + + + +
ItemDescriptionAssigned
102.1Send message to icatgroup explaining proposed modification to plugin interface for IDS lockingRolf
102.2Produce new releases of IJP componentsBrian R.
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2017-meetings/meeting-104-23-february-2017/index.html b/collaboration/communication/monthly-meetings/2017-meetings/meeting-104-23-february-2017/index.html new file mode 100644 index 000000000..9f60cc405 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2017-meetings/meeting-104-23-february-2017/index.html @@ -0,0 +1,154 @@ +Meeting 104 – 23 February 2017 | ICAT Project

ICAT Project

Search

Meeting 104 – 23 February 2017

Agenda:

+
    +
  • Actions from meeting 103 (Steve)
  • +
  • Component development +
      +
    • ICAT (Steve)
    • +
    • ICAT Manager (Alex)
    • +
    • Python-icat (Rolf)
    • +
    • IDS (Steve) +
        +
      • FUSE
      • +
      • PollCat (Frazer)
      • +
      • SmartClient (Steve)
      • +
      • WebDAV (Tom Gowland)
      • +
      +
    • +
    • TopCAT (Jody)
    • +
    • IJP (Brian R)
    • +
    • ICAT Dashboard (Tom Gowland)
    • +
    • Multi-container support (Steve)
    • +
    • Installation (Steve)
    • +
    +
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • AOB (Any)
  • +
+

Present: Steve, Jody, Sylvie, Tom Gowland, Frazer, Kevin, Gordon, Brian +Ritchie, Jianguo, Andy, Milan, Alex, Shelley, Tom Griffin, Rolf, Peter

+

Action 102.1: Rolf has not yet completed this action because the +suggestion is first dependent on another change to the IDS regarding +internal logging.

+

Action 102.2: Brian R. has not done this yet due to there being too many +changes before the new releases

+
    +
  • ICAT Development – Steve reported ICAT 4.9 is near to release. He +reported that there is one more change that he’d like to make to +separate the Lucene indexing such that two ICATs can rely on one +Lucene index. There is still testing that needs to be done to +overcome a bug that has been preventing this until now. Steve also +reported that there has been a request from Diamon to allow the +browsing of data in TopCAT by the data structure. Tom Griffin raised +a concern about how to handle permissions on the nodes in this +separate structure. Steve agreed to look into how rules would be +enforced at this level. Steve made a final point about making ICAT +more portable. A recent foray into ICAT by ELI-ALPS has shown up the +problems with deploying on WildFly. Steve thinks this is due to +WildFly not being able to find the properties files relatively. A +possible solution will be to use a similar principal as with the +logback XML files where the properties files are packaged up into +the War file. Further to this point, Tom Griffin asked about +Glassfish 4.1 support and Steve responded by saying new releases +will gear towards supporting Payara instead.
  • +
  • Python-ICAT – Rolf reported that he is waiting for ICAT 4.9 to be +released before making any further changes to Python-ICAT.
  • +
  • IDS – Steve reported that he has looked into Rolf’s pull-request +which contains his work on locking. Steve sent a couple of +suggestions back to Rolf and Rolf asked for some clarification on +one of the points.
  • +
  • PollCat – Frazer reported that Sylvie has started to look into using +PollCat for Diamond. Once there is a more formal plan in place, +Frazer said he will look into providing a better installation path +for PollCat.
  • +
  • WebDav – Tom Gowland reported that there is an upcoming deployment +for ISIS. He also reported that there have been issues with datasets +which contain many datafiles which is mainly due to the way in which +Windows handles the files. When you mouse over a directory in +Windows, it will attempt to load all of the information beyond that +directory even though you might never have wanted that data in the +first place. The best way to see if this will affect users of WebDav +will be to see what comments come out of the deployment.
  • +
  • TopCAT – Jody reported that TopCAT 2.2.1 is now out. He is still +doing some tinkering for Diamond and hopes that this will resolve +any issues they are still having. He also reported that 2.3.0 is now +nearly ready but before release it will need some more documentation +of the plugin API. There was also some general discussion about +Jody’s idea of simplifying the TopCAT configuration from the +user’s perspective. This would involve extending the admin section +of TopCAT to include a section where users can edit their TopCAT +settings with explanations alongside. There was also an idea from +Frazer which was to split the JSON file up into multiple smaller +files to make TopCAT more easily configurable.
  • +
  • IJP – The graduate student (Thomas Attwood) did some work on +supporting the versioning of datasets. He also worked on provenance +linking betweek jobs. IJP now also checks that there is a +corresponding application for each job type rather than making up +its own. Brian has also been working on some changes to the +appearance of the TopCAT plugin, introducing interactive sessions +into the IJP and expanding the configure job dialogue.
  • +
  • Dashboard – Tom Gowland reported that he had been helping Alex at +the ESRF to complete his Dashboard installation. The ESRF reported +that they were using the Dashboard daily and they would love to see +some more configurability. Tom Gowland suggested that if they had +any specific wishes that they should add them to the GitHub issues +for Dashboard. Tom also said that he had been working on the bugs +that had been reported by the ESRF team and also adding a contacts +page so that users with queries or issues could raise them by +contacting the right people.
  • +
  • Multi-Container Support – As previously reported, this should be +made more practical with the addition of properties files to the War +file.
  • +
  • Installation – There was some general discussion about the +documentation of ICAT as a whole. Steve mentioned that one outcome +of the ICAT steering group was for Andy and Shelley to provide some +feedback about how to improve the ICAT website. Tom Griffin +mentioned that he had recently installed a piece of software which +only required a Vagrant install in order to get a test copy up and +running to see if it was fit for purpose. Tom said that this could +be useful for those trying to get started with ICAT.
  • +
  • Issues from ICAT production deployments – Andy and Alex reported +their performance issues which seem to have been fixed by the newest +TopCAT release. They intend to closely monitor the situation to see +if anything changes.
  • +
  • AOB – Andy submitted a proposal to E-Infra 12 which was declined. +Rolf will be travelling to the ESRF to have discussions about the +IDS. Andy reported that Alex and Damien will visit STFC to learn +about TopCAT plugins. Kevin reported that he has just started work +alongside the European Space Agency who want to use ICAT for their +new Mars Rover
  • +
+

project.

+

Actions

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionAssigned
102.1Send message to icatgroup explaining proposed modification to plugin interface for IDS lockingRolf
102.2Produce new releases of IJP componentsBrian Ritchie
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2017-meetings/meeting-105-23-march-2017/index.html b/collaboration/communication/monthly-meetings/2017-meetings/meeting-105-23-march-2017/index.html new file mode 100644 index 000000000..9d2893f8d --- /dev/null +++ b/collaboration/communication/monthly-meetings/2017-meetings/meeting-105-23-march-2017/index.html @@ -0,0 +1,168 @@ +Meeting 105 – 23 March 2017 | ICAT Project

ICAT Project

Search

Meeting 105 – 23 March 2017

Agenda:

+
    +
  • Actions from meeting 104 (Steve)
  • +
  • Component development +
      +
    • ICAT (Steve)
    • +
    • ICAT Manager (Alex)
    • +
    • Python-icat (Rolf)
    • +
    • IDS (Steve) +
        +
      • FUSE
      • +
      • PollCat (Frazer)
      • +
      • SmartClient (Steve)
      • +
      • IDAV (Tom Gowland)
      • +
      +
    • +
    • TopCAT (Jody)
    • +
    • IJP (Brian R/Alastair)
    • +
    • ICAT Dashboard (Tom Gowland)
    • +
    • Multi-container support (Steve)
    • +
    • Installation (Steve)
    • +
    • Review of website (Andy)
    • +
    +
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • AOB (Any)
  • +
+

Present: Steve, Jianguo, Tom Gowland, Rolf, Jody, Peter, Frazer, Milan

+

Apologies: Alex, Andy, Kevin, Tom Griffin, Alastair

+

Actions from +104

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionAssigned
102.1Send message to icatgroup explaining proposed modification to plugin interface for IDS lockingRolf
102.2Produce new releases of IJP componentsBrian Ritchie
+

Action 102.1: Rolf reported that this is ongoing and is dependent on the +work being done on the internal logging in the IDS.

+

Action 102.2: Brian was not present to discuss this action.

+

Component Development

+

ICAT – Steve reported that 8 snapshots have been released as part of +4.9. The Lucene release requires Payara and all of the other releases +support Payara as well as GlassFish 4.0. Steve also reported that the +same installation scripts from Glassfish installations can still be used +and that Payara is externally almost identical to Glassfish. Steve has +also made changes to the RESTful authenticators and notes  that if you +specify a JNDI  it will be preferred to a RESTful url. Therefore, any +configuration of the authenticators should be done with care at this +point. Rolf has messaged the group to further explore the issues that +he’s been having with installing the new releases on GlassFish 4.0. +Steve said he would look further into Rolf’s issues and try to reproduce +the errors by installing the new releases on GlassFish 4.0.

+

IDS – Steve is still awaiting a reply from Rolf regarding IDS +locking issues. Steve also suggested that Java’s own reentrantlock class +might be useful in the development of IDS. Rolf said he would look into +this. Steve reported that he has recently been looking into issues that +Diamond have been having with the IDS. The isPrepared call might take a +long time at the moment. A fix has been coded and will be available in +the next release along with  a more efficient getSize. This next release +will also use the new style property configuration files.

+

PollCat – Frazer reported that there has recently been more movement +in the staging of data onto the Scarf cluster at STFC. There will also +be further developments so that PollCat can make use of the isPrepared +call which is being introduced into the IDS.

+

IDAV – Tom Gowland reported that recent developments have been +focussed on adding a MyData view to the top level structure of IDAV. +When IDAV was given to users at ISIS to test, they reported that they +would like an easier way to get to the data that belongs to them. +Although a MyData view had been attempted before, the code needed a +general refactor to make progress possible. Tom also reported that he +has been working on trying to speed up the listing of datafiles which +takes a long time for any more than 100 files.

+

TopCAT – Jody reported that version 2.3 of TopCAt is very close to +being released. 2.3 will include a file uploader and also improvements +to pluggability and documentation. Jody has also been developing a +plugin in order to facilitate a single sign on option for ISIS. He has +also spent two days with Damien and Alex from the ESRF to introduce them +to developing their own TopCAT plugins.

+

ICAT Dashboard – Tom Gowland reported that he has recently been +helping the ESRF team to redeploy Dashboard for their facility. The +issues were initially solved by getting around the proxy at ESRF so that +Dashboard could communicate with the APIs that it needs. Tom also +reported he had been working on adding more configurability to the +Dashboard such that users can change their default home page and default +time periods that data is shown for as well amongst other options. He is +also working on making the frequency with which Dashboard talks to ICAT +configurable as well which is something the team at ESRF have suggested.

+

IJP – Alastair had sent in a report saying that what he has done +with the IJP has been on things that will enable the Octopus use of IJP +rather than central IJP functionality. Enhancements include: emptying of +cart when job is completed and improvements to the configure job +dialog. Bug fixes include enabling the detection of jobs with status +unknown, handling of orphaned jobs correctly , better failure messages +for submission failures and optional options for job provenance.

+

Review of ICAT Project website – Although unable to attend the +meeting, Andy had reported that he has started work on the review of the +website and hopes to distribute it at the start of next week.

+

AOB & Issues from ICAT Production Deployments

+

Package Nomenclature – Rolf has sent a mail which outlines his +proposal for defining a specific nomenclature for code packages. He +suggests that they should all be of the following initial structure: +org.icatproject.site.<FacilityName>. There was general agreement for +this proposal.

+

Config files on GitHub – Rolf reported that he had set up a GitHub +repository containing configuration files from different ICAT +components. He suggested that other facilities might find more examples +useful and Steve asked him to move the repository to the ICAT/contrib +repository for people to have a look and see if they find it useful.

+

File uploading query – Jianguo asked Jody whether the new file +uploader would allow a user to upload a whole folder or just individual +files. Jody replied that multiple files could be selected and added at +once but adding a folder itself would not +work.

+

Actions

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionAssigned
102.1Send message to icatgroup explaining proposed modification to plugin interface for IDS lockingRolf
102.2Produce new releases of IJP componentsBrian Ritchie
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2017-meetings/meeting-106-27-april-2017/index.html b/collaboration/communication/monthly-meetings/2017-meetings/meeting-106-27-april-2017/index.html new file mode 100644 index 000000000..8bc26d2c0 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2017-meetings/meeting-106-27-april-2017/index.html @@ -0,0 +1,180 @@ +Meeting 106 – 27 April 2017 | ICAT Project

ICAT Project

Search

Meeting 106 – 27 April 2017

Agenda:

+
    +
  • Actions from meeting 105 (Steve)
  • +
  • Component development +
      +
    • ICAT (Steve)
    • +
    • ICAT Manager (Alex)
    • +
    • Python-icat (Rolf)
    • +
    • IDS (Steve) +
        +
      • FUSE
      • +
      • PollCat (Frazer)
      • +
      • SmartClient (Steve)
      • +
      • IDAV (Tom Gowland)
      • +
      +
    • +
    • TopCAT (Jody)
    • +
    • IJP (Brian R/Alastair)
    • +
    • ICAT Dashboard (Tom Gowland)
    • +
    • Multi-container support (Steve)
    • +
    • Installation (Steve)
    • +
    • Review of website (Andy)
    • +
    +
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • AOB (Any)
  • +
+

Present: Steve, Jody, Sylvie, Frazer, Kevin, Brian, Tom Gowland, Alex, +Rolf, Milan

+

Apologies: Andy

+

Actions from +105

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionAssigned
102.1Send message to icatgroup explaining proposed modification to plugin interface for IDS lockingRolf
102.2Produce new releases of IJP componentsBrian Ritchie
+

Action 102.1: Rolf reported that he was awaiting advice from Steve on +running Steve’s test suite. The proposed modification is pending on +that.

+

Component Development

+

ICAT – Steve reported that Rolf has now successfully installed the +new ICAT components for Payara and that he will now be happy to release +4.9.0.  Steve went on to report that he has developed a solution to +‘location views’ whereby it is possible to ask any node what is +beneath it. This should make WebDav a lot more efficient. Steve is +investigating an issue that Diamond have discovered whereby ICAT 4.8.0 +appears to be slower than 4.6.1 and that he is also writing some tests +to avoid this in the future. With regards to the possible schema change +that Steve has mentioned on the ICAT Group, there is going to be a +document which will outline all of the changes. This will ensure that +any elements that are unused in the schema (be it relationships, +entities etc…) are removed. There is also a new idea that would be +useful to Kevin whereby datafiles could be put directly into the +investigation level through the use of nested datasets.

+

Python-ICAT – Rolf reported that he was still awaiting ICAT 4.9.0 +and that he may soon release 0.13. Steve asked if Rolf was planning a +1.0 release and Rolf replied that the only thing that he wanted to add +before that stage would be more thorough documentation.

+

IDS – Steve reported that he wants to implement the new locking and +this is awaiting communication between Rolf and Steve about the +test-suite. Steve also mentioned that 1.7.1 should be releasing shortly. +Brian reported that part of the work he is doing for Octopus might make +use of CEPH storage. This will mean developing an IDS storage plugin for +use with Amazon.

+

IDAV – Tom Gowland reported that he has completed the work that he +mentioned in the last meeting. This involved adding a MyData view at the +top level to allow for easier browsing to datafiles that you are +associated with. Tom also reported that he has managed to implement +changes that will warrant a slight speed increase in folders with large +amounts of datafiles. However, he believes that Steve’s implementation +of the location views will make this redundant in time. Tom also said +that there is now more work to be done on making a more universal system +that can be used at any facility with an ICAT.

+

TopCAT – Jody reported that he has been working on a prototype for +Data Analysis as a Service which makes use of TopCAT. The prototype +allows users who are logged into TopCAT to see a ‘My Machines’ page +where they can create and share their virtual machines with other users. +As well as this, Jody reported that he will soon be releasing TopCAT 2.3 +where he has still to implement DOI features and remove ISIS and Diamond +specific elements.

+

IJP – Brian reported that he has made a change to the IJP servers +such that they keep sessions alive when jobs are queued. This is mainly +to help users of the command line client (as the GUI will keep your +session alive anyway). Brian is also going to be revisiting the problem +of having a platform LSF connector for STFC’s SCARF cluster.

+

Dashboard – Tom Gowland reported that he has been working on adding +more configurability to Dashboard. He also mentioned that he had talked +to Steve about a potential release although they have not discussed it +since.

+

Multi-Container Support – Steve had an email from Andy who was +wondering if ICAT was moving away from supporting GlassFish. Steve +reported that he wants ICAT to be able to run on both WildFly and +GlassFish (soon to be Payara). Steve went on to say that now setup +scripts aren’t reliant on being in a certain folder, WildFly support +should be made easier. Kevin asked whether we should be supporting both +containers if no one wanted to user WildFly. Steve replied that he +thought Alex would prefer to use WildFly and that the overhead of +testing both containers was not large. Steve also thought that testing +for two containers would add more robustness to the code.

+

Review of Website – Andy has produced a detailed report. Steve +reported that there will soon be a new employee starting work at RAL +(Stuart). The plan is for Stuart to install ICAT from scratch only using +the documentation available to see which parts of the process can be +most difficult to deal with. This should give a good idea of the +consistencies between Andy’s report and a real world scenario.

+

AOB & Issues from ICAT Production Deployments

+

Diamond ICAT failure – Steve reported that on the previous day, the +Diamond ICAT had stopped working with some EJB exceptions. The solution +in the end was to redeploy ICAT. The cause is still unknown.

+

High Swap Space Usage – Kevin reported that many of his machines +which hosted parts of the ICAT family were running a lot of swap space. +He has had the memory increased on these machines and yet they still run +a high amount of swap. Steve hopes that a move to Payara will fix these +kinds of +problems.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionAssigned
102.1Send message to icatgroup explaining proposed modification to plugin interface for IDS lockingRolf
102.2Produce new releases of IJP componentsBrian Ritchie
106.1Produce a report detailing the suggested schema changesSteve
106.2Produce response to Andy’s review and an action plan to address the problems.Steve
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2017-meetings/meeting-107-25-may-2017/index.html b/collaboration/communication/monthly-meetings/2017-meetings/meeting-107-25-may-2017/index.html new file mode 100644 index 000000000..31d220b2f --- /dev/null +++ b/collaboration/communication/monthly-meetings/2017-meetings/meeting-107-25-may-2017/index.html @@ -0,0 +1,119 @@ +Meeting 107 – 25 May 2017 | ICAT Project

ICAT Project

Search

Meeting 107 – 25 May 2017

Agenda:

+
    +
  • Actions from meeting 106 (Steve)
  • +
  • Component development +
      +
    • ICAT (Steve)
    • +
    • ICAT Manager (Alex)
    • +
    • Python-icat (Rolf)
    • +
    • IDS (Steve) +
        +
      • FUSE
      • +
      • PollCat (Frazer)
      • +
      • SmartClient (Steve)
      • +
      • IDAV (Tom Gowland)
      • +
      +
    • +
    • TopCAT (Jody)
    • +
    • IJP (Brian R/Alastair)
    • +
    • ICAT Dashboard (Tom Gowland)
    • +
    • Multi-container support (Steve)
    • +
    • Installation (Steve)
    • +
    +
  • +
  • Review of website (Andy)
  • +
  • Next F2F Meeting
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • AOB (Any)
  • +
+

Present: Steve, Brian, Frazer, Kevin, Stuart Pullinger, Milan and Peter

+

Apologies: Rolf, Alex, Andy, Sylvie, Tom Gowland and Jody

+

Actions from 106

+

None have been addressed

+

Component Development

+

ICAT – Steve reported that he has started work on releasing those +components that have been tested on Payara; but he will not announce +until all are complete. Some problems were encountered as some +components had not been updated since the move to repo.icatproject.org.

+

Having tested the ICAT performance (using the DLS ingest code) on ICAT +4.6, 4.8 and 4.8, Steve found that they are all roughly the same; +however 4.9.0 is significantly slower with icat.lucene enabled and +deployed on the same machine. He will continue the investigation but +will not delay releases, though 4.9.0 will carry a warning.

+

ICAT Manager – Stuart reported that the link on icatproject.org +is broken. It will be reported.

+

IDS – Steve has not yet had time to sort out whatever is stopping +Rolf carrying out IDS development, and suggests that an independent +attempt at deployment may be informative. A number of bug fixes have +been prepared, mostly to improve performance. The behaviour of the +Oracle query planner seems to suggest that LIMIT clauses should be +avoided when dealing with large tables. The new properties regime for +the IDS requires revised versions of the plugins.

+

IJP – Brian reported that he has been trying a different IJP +configuration with the server and batch connector on different systems. +This works, but has led to small changes to ijp.demo. He has also +revised the documentation for ijp.server (though this has still to be +released).

+

Review of Website

+

Stuart reported that he has been following the instructions on +icatproject.org to install the ICAT components, and estimates he is +about half-way through. He has made copious notes on his experiences, +and will share them in due course.

+

Next F2F Meeting

+

Steve mentioned that we should start thinking about the next F2F +meeting; where it should be (co-located with xxx???) and what form it +should take . Steve said that he would ask Andy to take this to the +steering group.

+

AOB and Issues from production deployments

+

None reported. Milan and Peter may be absent for the next meeting, due +to an adjacent meeting in +Grenoble.

+

Actions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionAssigned
102.1Send message to icatgroup explaining proposed modification to plugin interface for IDS lockingRolf
102.2Produce new releases of IJP componentsBrian Ritchie
106.1Produce a report detailing the suggested schema changesSteve
106.2Produce response to Andy’s review and an action plan to address the problems.Steve
107.1Ask Andy to consider next F2F meetingSteve
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2017-meetings/meeting-108-22-june-2017/index.html b/collaboration/communication/monthly-meetings/2017-meetings/meeting-108-22-june-2017/index.html new file mode 100644 index 000000000..9d77b3ff6 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2017-meetings/meeting-108-22-june-2017/index.html @@ -0,0 +1,217 @@ +Meeting 108 – 22 June 2017 | ICAT Project

ICAT Project

Search

Meeting 108 – 22 June 2017

Agenda:

+
    +
  • Actions from meeting 107 (Kevin)
  • +
  • Component development +
      +
    • ICAT (Steve)
    • +
    • ICAT Manager (Alex)
    • +
    • Python-icat (Rolf)
    • +
    • IDS (Steve) +
        +
      • FUSE
      • +
      • PollCat (Frazer)
      • +
      • SmartClient (Steve)
      • +
      • IDAV (Tom Gowland)
      • +
      +
    • +
    • TopCAT (Jody)
    • +
    • IJP (Brian R/Alastair)
    • +
    • ICAT Dashboard (Tom Gowland)
    • +
    • Multi-container support (Steve)
    • +
    • Installation (Steve)
    • +
    +
  • +
  • Review of website (Stuart)
  • +
  • Next F2F Meeting
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • AOB (Any)
  • +
+

Present: Kevin, Brian Ritchie, Tom Gowland, Jody, Stuart, Rolf, Peter, +Andy

+

Apologies: Milan, Steve (who had produced written reports for the +meeting)

+

Actions from +107

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionAssigned
102.1Send message to icatgroup explaining proposed modification to plugin interface for IDS lockingRolf
102.2Produce new releases of IJP componentsBrian Ritchie
106.1Produce a report detailing the suggested schema changesSteve
106.2Produce response to Andy’s review and an action plan to address the problems.Steve
107.1Ask Andy to consider next F2F meetingSteve
+

Action 102.1: Rolf reported that he is waiting for the locking +mechanism to go into the IDS. He was previously unable to run the IDS +test suite and therefore couldn’t work through Steve’s suggestions about +his original pull request. Steve has now made the relevant changes to +the test suite to ensure that Rolf can run the tests and can now debug +the problems.

+

Action 102.2: Brian reported that there are further changes which +need to be made before any release.

+

Action 106.1: Steve reported that he has started a report about +schema changes but wants to have another think about it before +releasing.

+

Action 106.2: Steve reported that this will probably be done by the +next meeting with help from Stuart’s input who has been installing the +ICAT stack with no prior knowledge.

+

Action 107.1: Andy reported that the next face to face meeting will +most likely be hosted at STFC in September or October. Rolf reported +that there will be RDA (Research Data Alliance) meeting in September (19 +^(th) – 21 ^(st) September https://www.rd-alliance.org/ ) and Andy +reported that there is an ICALEPCS meeting in October (8 ^(th) – 13 +^(th) October http://www.icalepcs2017.org/ ).

+

Component Development

+

ICAT – Steve reported the ICAT server 4.9.0, ICAT Lucene and 4 +authorization plugins have been released to work on Payara. There are +also now separate pages for GlassFish 4.0 and Payara releases which +should avoid any confusion about what components work with what.

+

Steve also reported that the GlassFish 4.0 issues have now been +understood. The incompatibility with GlassFish in the ICAT Lucene has +been traced to the use of lambda functions. There is also one of these +Lambda functions in the IDS.server 1.8.0 snapshot. In the case of the +IDS, this lambda function can simply be removed. This makes the code +less clean but will provide a solution for an upgrade for DLS. However, +after 1.8.0, Glassfish 4.0 will no longer be  supported. Steve said that +he would probably try again to see if all components now made available +with Payara also work with WildFly.

+

Python-ICAT – Rolf reported that there was a 0.13 release which was +waiting for ICAT server 4.9.0 to be released. There are some +incompatibilities with previous versions in 0.13 and Rolf advised that +old code may need to be updated to work with the new release.

+

IDS – Steve reported that the IDS 1.8.0 snapshot has been made +available along with the storage_file plugin. The plugin now has a +different interface as it now has a properties file passed to it rather +than trying to find its own properties. This means that all of the +run.properties for the IDS and its plugin are in the same file. +Unfortunately, Steve failed to check in the updated storage_test which +caused a problem for Rolf. There are a number of other small changes +that Steve wants to make before 1.8.0 is released. These are generally +related to downloading very large numbers of files.

+

IDAV – Tom reported that the MyData view in IDAV was now in place +and was just awaiting some user testing to get further feedback.

+

IJP – Brian reported that he has been working on a batch connector +for HTCondor. He is developing it in Python as the Condor Python library +is very good. He reported that he is still some way from connecting this +up to work with the IJP.

+

Review of website – Stuart reported that he has been following +installation documents on the ICAT website without any further help. +Along the way, he has been making notes about his experience and using +the SSI (Software Sustainability Institute) guidelines to help shape his +report. Stuart then went on to share his main findings. His main +concerns were regarding the organisation of information and +documentation and at times he struggled with finding where to look for +information.

+

At times during the installation process, he would have to be +referencing information on three or more separate pages (for example: +installation instructions, schema and project summary pages). Stuart +also said that much of the documentation assumed prior knowledge and +therefore wasn’t very friendly for beginners.  Andy agreed on this point +in particular and felt that the installation process should be +consolidated into one page in an easy-to-follow way.

+

Stuart said that the SSI categorises uses in different classes. He +thinks it would be useful to consider these classes when thinking about +the organisation of information. Stuart would consider the classes to be +as follows:

+
    +
  • End User – The person who actually ends up using the software once +it is in production
  • +
  • Installer – The person who only wants to install an instance of the +software
  • +
  • API User – The person who writes software which will user the REST +or SOAP API
  • +
  • Developer – The person who actually wants to contribute code to the +software project
  • +
+

Stuart also said that the final category “Developer” could be split into +those that actually have write access to the repositories and those who +don’t.

+

For a beginner, Stuart said that it would currently be very difficult to +understand what ICAT actually does, what it is, what it looks like, who +will use it, how it will be used and where the data comes from in the +first place. He also said that there should be more help available for +developers which explains how to contribute code and patches to the +project.

+

His main recommendations were to re-organise the website according to +groups of people. He reported that he was going to be researching +websites that already to this well. Andy referenced the Django website ( +https://www.djangoproject.com/ ) which he thinks does this well.

+

Overall, Stuart said that he agrees with all of the document that Andy +had previously produced on this subject.

+

108 +Actions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionAssigned
102.1Send message to icatgroup explaining proposed modification to plugin interface for IDS lockingRolf
102.2Produce new releases of IJP componentsBrian Ritchie
106.1Produce a report detailing the suggested schema changesSteve
106.2Produce response to Andy’s review and an action plan to address the problems.Steve + Stuart
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2017-meetings/meeting-109-24-august-2017/index.html b/collaboration/communication/monthly-meetings/2017-meetings/meeting-109-24-august-2017/index.html new file mode 100644 index 000000000..0ae367ba9 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2017-meetings/meeting-109-24-august-2017/index.html @@ -0,0 +1,151 @@ +Meeting 109 – 24 August 2017 | ICAT Project

ICAT Project

Search

Meeting 109 – 24 August 2017

Agenda

+
    +
  • Actions from meeting 108 (Steve)
  • +
  • Component development +
      +
    • ICAT (Steve)
    • +
    • ICAT Manager (Alex)
    • +
    • Python-icat (Rolf)
    • +
    • IDS (Steve) +
        +
      • FUSE
      • +
      • PollCat (Frazer)
      • +
      • SmartClient (Steve)
      • +
      • IDAV (Jamie)
      • +
      +
    • +
    • TopCAT (Jody)
    • +
    • IJP (Brian R/Alastair)
    • +
    • ICAT Dashboard (Jamie)
    • +
    • Multi-container support (Steve)
    • +
    • Installation (Steve)
    • +
    +
  • +
  • Website (Stuart)
  • +
  • Next F2F Meeting – Steve/Andy
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • AOB (Any)
  • +
+

Present: Brian, Jody, Jamie, Steve, Kevin, Rolf, Tom Griffin, Alex, +Peter
+Apologies: Stuart, Frazer

+

Actions from +108

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionAssigned
102.1Send message to icatgroup explaining proposed modification to plugin interface for IDS lockingRolf
102.2Produce new releases of IJP componentsBrian Ritchie
106.1Produce a report detailing the suggested schema changesSteve
106.2Produce response to Andy’s review and an action plan to address the problems.Steve + Stuart
+

Action 102.2 – Brian reported he hasn’t finished producing new +releases of the IJP components yet but is still working on it.

+

Action 106.1 – Steve reported he hasn’t produced report detailing +the suggested schema changes. It’s too large to discuss on a telecom and +would be better suited for the face to face.

+

Steve reported that he will be reducing his input into the ICAT project +and will be slowly handing over to Stuart.

+

Component development

+

ICAT – Steve reported ICAT 4.9.1 is not formally released yet but is +ready. It avoids the performance degradation introduced with the +separate lucene component in ICAT 4.9.0. Now update messages are grouped +together. It requires an updated version of the lucense server to accept +the aggregated messages.

+

IDS – Steve reported IDS 1.8 is released but not updated on webpage +yet. This includes the new installation property files, setup.properties +and run.properties.

+

Work on the next release has now started. Two pull requests from Rolf +have been accepted. Support for Glassfish 4.0 has been removed so will +require Glassfish 4.1+ or Payara; Steve recommends the latter.

+

Python ICAT – Rolf reports minor release in June to fix difficulty +having multiple client instances.

+

Topcat – Jody reported 2.3.0 released in early August. Jody also +reported that all current 2.4.0 tickets are complete and any more +features people want adding to 2.4.0 urgently should be discussed on the +icatgroup.

+

IJP –Brian reports batch connector for HTCondor now working and that +he’s still working on the new IJP component releases.

+

Installation – Steve reports BitRock installer has been updated +using the final set of components for Glassfish before the switch to +Payara. Steve welcomes people to test on Unix and Windows and report any +issues.

+

F2F

+

Steve asks if everyone if there are any problems with the proposed date +of 20 ^(th) – 21 ^(st) November, at RAL. There were no objections so +that date is now fixed.  Tom suggests meeting to be held across two half +days rather than a full day to allow people to travel to and from RAL. +Steve will work on the agenda.

+

109 +Actions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionAssigned
102.1Send message to icatgroup explaining proposed modification to plugin interface for IDS lockingRolf
102.2Produce new releases of IJP componentsBrian Ritchie
106.2Produce response to Andy’s review and an action plan to address the problems.Steve + Stuart
109.1Produce agenda for F2FSteve
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2017-meetings/meeting-110-28-september-2017/index.html b/collaboration/communication/monthly-meetings/2017-meetings/meeting-110-28-september-2017/index.html new file mode 100644 index 000000000..4ad695c91 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2017-meetings/meeting-110-28-september-2017/index.html @@ -0,0 +1,75 @@ +Meeting 110 – 28 September 2017 | ICAT Project

ICAT Project

Search

Meeting 110 – 28 September 2017

Agenda

+
    +
  • Actions from meeting 109 (Steve)
  • +
  • Component development +
      +
    • ICAT (Steve/Stuart)
    • +
    • ICAT Manager (Alex)
    • +
    • Python-icat (Rolf)
    • +
    • IDS (Steve/Stuart) +
        +
      • FUSE
      • +
      • PollCat (Frazer)
      • +
      • SmartClient (Steve)
      • +
      • IDAV (Jamie)
      • +
      +
    • +
    • TopCAT (Jody/Brian)
    • +
    • IJP (Brian R/Alastair)
    • +
    • ICAT Dashboard (Jamie)
    • +
    • Multi-container support (Steve)
    • +
    • Installation (Steve/Stuart)
    • +
    +
  • +
  • Website (Stuart)
  • +
  • Next F2F Meeting – Stuart/Andy
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • AOB (Any)
  • +
+

Present:
+Apologies: Rolf, Tom

+

Actions from +109

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionAssigned
102.1Send message to icatgroup explaining proposed modification to plugin interface for IDS lockingRolf
102.2Produce new releases of IJP componentsBrian Ritchie
106.2Produce response to Andy’s review and an action plan to address the problems.Steve + Stuart
109.1Produce agenda for F2FSteve
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2017-meetings/meeting-111-26th-october-2017/index.html b/collaboration/communication/monthly-meetings/2017-meetings/meeting-111-26th-october-2017/index.html new file mode 100644 index 000000000..a60f069d7 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2017-meetings/meeting-111-26th-october-2017/index.html @@ -0,0 +1,94 @@ +Meeting 111 – 26th October 2017 | ICAT Project

ICAT Project

Search

Meeting 111 – 26th October 2017

Agenda

+
    +
  • Actions from meeting 110 (Stuart)
  • +
  • Component development +
      +
    • ICAT (Steve/Stuart)
    • +
    • ICAT Manager (Alex)
    • +
    • Python-icat (Rolf)
    • +
    • IDS (Steve/Stuart) +
        +
      • FUSE
      • +
      • PollCat (Frazer)
      • +
      • SmartClient (Steve)
      • +
      • IDAV (Jamie)
      • +
      +
    • +
    • TopCAT (Brian)
    • +
    • IJP (Brian R/Alastair)
    • +
    • ICAT Dashboard (Jamie)
    • +
    • Multi-container support (Steve)
    • +
    +
  • +
  • Website/Documentation (Stuart)
  • +
  • Next F2F Meeting – Stuart
  • +
  • Issues from ICAT production deployments (Any)
  • +
  • AOB (Any)
  • +
+

Present: Brian, Tom Griffin, Frazer, Kevin, Stuart, Andy, Alex, Maxime, +Rolf, Milan, Peter
+Apologies: Silvia, Steve

+

Actions from previous:

+

102.2 – Brian is still working on this!

+

110.1 – The ICAT Manger download link has been fixed

+

ICAT Components:

+

Steve is continuing to handover the ICAT components to Stuart.

+

IDS – Rolf reports that he still has pull requests open on the IDS. +Stuart says he will look at them with Steve.

+

Topcat- Brian reminds everyone to skip Topcat 2.3.4 as the file is +corrupt. Brian reports a few of the new features/issues he’s currently +working on: an info button on rows to toggle the meta tabs, a loading +page on start-up and fixing the download count when using multiple +facilities. Rolf asks Brian to look at the issue he posted to the group +regarding passing ids and ICAT URLs to the RESTful API.

+

Installation and website – Tutorial to be tested by Maxime, +Stuart welcomes any feedback.

+

F2F

+

Stuart reminds everyone that registration is still open. Stuart is asked +to send round an outline of the agenda so people know what time to book +flights for. It’s suggested to prepare as much as possible for the +document sprint to make the most efficient use of the time available. +It’s also suggested to discuss the use of DOI’s at the F2F.

+

AOB

+

Stuart reports he has an apprentice who’s working on converting the ICAT +install instructions to Ansible. This can be used in continuous +integration to test the ICAT components. In the future could be +potentially used for Selenium testing.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionAssigned
102.2Produce new releases of IJP componentsBrian Ritchie
111.1Look at Rolf’s IDS pull requestStuart and Steve
111.2Send outline of agenda for F2FStuart
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2017-meetings/meeting-112-21st-december-2017/index.html b/collaboration/communication/monthly-meetings/2017-meetings/meeting-112-21st-december-2017/index.html new file mode 100644 index 000000000..683badd9c --- /dev/null +++ b/collaboration/communication/monthly-meetings/2017-meetings/meeting-112-21st-december-2017/index.html @@ -0,0 +1,105 @@ +Meeting 112 – 21st December 2017 | ICAT Project

ICAT Project

Search

Meeting 112 – 21st December 2017

Agenda

+
    +
  • Components
  • +
  • Sites
  • +
  • Previous Actions
  • +
  • AOB
  • +
  • Next Meeting
  • +
+

Attendees: Stuart Pullinger (SP); Brian Ritchie (BR); Rolf Krahl (RK); +Milan (Milan); Andy Gotz (AG)

+

Components

+
icat.server (SP)
+

Nothing to report

+
TopCat (BR)
+
    +
  • Better error logging
  • +
  • Instructions sent to ESRF on setting poll.delay setting to reduce +wait on 2 ^(nd) downloads
  • +
  • Treat HTTP the same as HTTPS for downloads in TopCat
  • +
  • Improvements to testing and Travis-CI
  • +
+
IJP (BR)
+
    +
  • Nothing new to report
  • +
  • No release yet
  • +
  • Possible new requirement for web interface
  • +
+
Python-Icat (RK)
+
    +
  • Nothing to report
  • +
+
IDS (RK)
+
    +
  • Aim for new release in January
  • +
  • Filesystem locking: RK to open pull request in January
  • +
+

Sites

+
Diamond (SP)
+
    +
  • Problems with Diamond’s infrastructure around ICAT. Not necessarily +bugs/issues with ICAT.
  • +
  • Problems with user account migration. Highlighted need for better +documentation of this procedure and/or recommended best practices.
  • +
  • Problems with failed or long data recalls.
  • +
+
ESRF (AG)
+
    +
  • Assessing new requests from beamlines: for example, re-using a scan +name from an aborted scan
  • +
  • Working on a DOI landing page
  • +
+

AOB

+
    +
  • RK reminded us of the RDA meeting in March with the 2-day meeting +before 19 ^(th) /20 ^(th)
  • +
  • AG: Infradev 4 – European Open Science Cloud involvement. Elettra +are involved in the consortium. We should discuss in +January/February for possible ICAT effort.
  • +
  • Milan: Elettra 2.0 confirmed: 6 years funding.
  • +
  • RK: we need a plan for taking forward Steve’s suggestions from the +Face to Face meeting
  • +
  • SP: A meeting will be arranged in January to allocate tasks and set +priorities for development of ICAT components
  • +
  • AG: We need to quantify the limitations experienced by Diamond in +accessing large tables of metadata.
  • +
+

Actions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionAssigned
102.2Produce new releases of IJP componentsBrian Ritchie
112.1Grant RK access to github repositoryStuart
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2018-meetings/index.html b/collaboration/communication/monthly-meetings/2018-meetings/index.html new file mode 100644 index 000000000..90a47426a --- /dev/null +++ b/collaboration/communication/monthly-meetings/2018-meetings/index.html @@ -0,0 +1,18 @@ +2018 Meetings | ICAT Project

ICAT Project

Search

2018 Meetings

+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2018-meetings/meeting-113-8th-february-2018-(january-meeting-delayed)/index.html b/collaboration/communication/monthly-meetings/2018-meetings/meeting-113-8th-february-2018-(january-meeting-delayed)/index.html new file mode 100644 index 000000000..154bc025f --- /dev/null +++ b/collaboration/communication/monthly-meetings/2018-meetings/meeting-113-8th-february-2018-(january-meeting-delayed)/index.html @@ -0,0 +1,89 @@ +Meeting 113 – 8th February 2018 (January Meeting delayed) | ICAT Project

ICAT Project

Search

Meeting 113 – 8th February 2018 (January Meeting delayed)

Attendees: Catherine Jones (CJ), Brian Ritchie (BR) , Rolf Krahl (RK), +Brian Matthew (BM), Milan (M), Andy Gotz (AG), Alex de Maria (AM)

+

Apologies: Stuart Pullinger

+

Actions from previous:

+

102.2 – BR is still working on this!

+

112.1 – SP has granted RK access to the GitHub repository.

+

ICAT Components:

+

IDS – RK reports he’s added the new locking mechanism ready for the +1.9 release. Most open issues for 1.9 are complete. RK is also waiting +for SP to review the Pull Requests open in GitHub as it decided at the +F2F to review code before merging.

+

Topcat – BR reports no changes recently except getting the Travis +build working. Screen flicker issue reported again and BR has found a +fix but it is going to require more testing to make sure it doesn’t +break anything else.

+

Nothing to report on all other components.

+

Site Updates

+

Diamond – CJ reports on behalf of SP that diamond have moved their +preprod to Payara, no problems apart from changing the setup scripts for +the old components as already known.

+

ESRF – AM reports they have a basic version implemented of automatic +DOI minting for new investigations with a dynamically created landing +page. Currently using test DOIs to check everything is working correctly +before putting into production.

+

Milan – Announces it now official that the EST will be using the +ICAT stack.

+

RDA Berlin Meeting

+

RK reminds us of the RDA meeting in March with the 2-day meeting before +19 ^(th) /20 ^(th) . RK asks if ESRF would like to present at the +workshop. AM says he could talk about something like ‘how to map nexus +files to ICAT’ or the ‘overview of data management at ESRF’. Anyone who +wants to should send ideas for contributions to RK. ICAT steering +committee meeting set to go ahead even though AG cannot attend in +person.

+

PaNOSC

+

AG explains they’re looking at create a federated API that can be used +to access ICAT and other data cataloguing systems. The project also +involves looking at data policies and data stewardship and checking +their compliance with the FAIR data principles.

+

AOB

+

AM suggests thinking about the replacement for Topcat and how can the +ESRF make their requirements known. CJ suggests a separate meeting +should be scheduled to find out what’s essential from each of the +facilities using Topcat, and then a technology can be decided on. It is +decided to hold this before the Berlin meeting so discussion can +continue there.

+

CJ announces STFC has successfully recruited a Topcat developer due to +start in the summer and that a graduate will be joining us in the autumn +to work on the ICAT stack.

+

Actions **

+

**

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionAssigned
102.2Produce new releases of IJP componentsBrian Ritchie
113.1Look at Rolfs IDS pull requestStuart Pullinger
113.2Organise a meeting for the
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2018-meetings/meeting-114-22nd-february-2018/index.html b/collaboration/communication/monthly-meetings/2018-meetings/meeting-114-22nd-february-2018/index.html new file mode 100644 index 000000000..366685d5e --- /dev/null +++ b/collaboration/communication/monthly-meetings/2018-meetings/meeting-114-22nd-february-2018/index.html @@ -0,0 +1,75 @@ +Meeting 114 – 22nd February 2018 | ICAT Project

ICAT Project

Search

Meeting 114 – 22nd February 2018

Attendees

+

Stuart Pullinger (SP), Silvia Da Graca Ramos, (SR), Brian Ritchie, (BR), +Rolf Krhl (RK), Alex de Maria (AM), Maxime Chaillet (MC).

+

Apologies: Andy Gotz, Catherine Jones.

+

Actions from previous

+

102.2 – BR still working on this.

+

113.1 – SP has looked and commented on one of the pull requests for +IDS server. Still another for SP to look at as well as new pull request +from RK on IDS plugin regarding abstract class changes.

+

113.2 – CJ will organise the Topcat development meeting for before +steering committee meeting.

+

ICAT Components

+

Website and Manual – SP reports he is working on the website as well +as updating the manual and hopes to have something to show by March for +steering committee meeting.

+

IDS Server – RK reports IDS server 1.9.0 snapshot created, includes +new locking mechanism that’s been in master since August and the pull +requests that are still pending.

+

IDS Plugin – RK reports 1.4.0 snapshot created. This release +simplifies the abstract classes, along with new documentation.

+

Site Updates

+

Diamond – SR reports diamond IDS updated to 1.8 on preprod with no +problems, along with more Glassfish to Payara updates

+

ESRF – AM reports updating from ICAT server 4.8 to 4.9.1 to fix +performance issue with updating investigation with thousands of +datasets. Also updating from Glassfish to Payara, SP mentions install +script version problem but AM already aware.

+

AOB

+

AM asks about the Lucene index, RK confirms it is only required for text +searching ICAT and not anything else. SR mentions if using Lucene and +database manually edited the Lucene Index will need force updating.

+

RK mentions he still needs title of talks for RDA meeting in March. Also +RK mentions that the next scheduled monthly meeting will be in the same +week as the steering committee meeting so it’s decided to rearrange the +monthly meeting to the 29^(th) of +March.

+

Actions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionAssigned
102.2Produce new releases of IJP componentsBrian Ritchie
113.1Look at Rolfs IDS Server and IDS Plugin pull requestStuart Pullinger
113.2Organise a meeting for the discussion of a Topcat replacementCatherine Jones
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2018-meetings/meeting-115-29th-march-2018/index.html b/collaboration/communication/monthly-meetings/2018-meetings/meeting-115-29th-march-2018/index.html new file mode 100644 index 000000000..3492d1592 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2018-meetings/meeting-115-29th-march-2018/index.html @@ -0,0 +1,174 @@ +Meeting 115 – 29th March 2018 | ICAT Project

ICAT Project

Search

Meeting 115 – 29th March 2018

Attendees

+

Stuart Pullinger (SP), Chris Prosser (CP), Brian Ritchie (BR), Rolf +Krahl (RK), Heike  , Alex di Maria (AM), Maxime Chaillet (MC).

+

Apologies: Silvia Da Graca Ramos.

+

Actions from previous

+

102.2 – BR still working on this.

+

113.1 – SP to look at IDS pull requests. SP can’t remember where +he’d got to. Rolf sent responses today; back to Stuart to run Rolf’s +test script. Rolf ran test, no problems.

+

113.2 – Catherine (CJ) to organise the Topcat development meeting. +Probably not going to happen this month, maybe some time late in May. +Lots of us away.

+

ICAT Components

+

Topcat (BR) –  DLS has problem with cart which revealed that +add-to-cart client code was casting longs (in json) to signed ints, +resulting in overflow. Fixed and released as 2.3.2.1 (as DLS are using +2.3.2); fix applied to master, but not to current release (2.3.6). Hope +to release 2.4.0 rather than patch 2.3.6.

+

IJP (BR) –  progress in prototype deployment for Octopus – finally +succeeded in submitting IJP job to Scarf (Platform LSF cluster).  +Continuing to develop HTCondor batch connector.

+

**IDS (RK) **–  snapshot one month ago, no comments. Considering +releasing ids plugin 1.4, ids storage, ids server 1.9.0, sometime in +April. Stuart will test these at same time as trying out Rolf’s script. +(RK: script could be tried on production as it’s read-only. SP will try +on DLS pre-prod.)

+

Site Updates

+

**DLS (CP) – ** experiencing a number of problems. Service usage is +increasing: 1000 recalls in last 6 months. There are issues with recalls +moving from prep to expired. The ‘prepareData’ call is not timely in +responding (exceeding the 30 minute timeout in topcat?) DLS have a +mechanism to replay recalls, but tedious & manual. CP thinks root cause +is the query generated by Java/JPA for large filesets: Oracle not able +to execute it quickly enough. Also experiencing probs with Topcat +download test script, during high (IDS) load, tests can time out.

+

RK: open issue on ids.server from DLS, “archive can be too slow” +(last Sep); perhaps filling up ids cache?

+

CP: if several users request large files, the cache can get full.

+

RK: needs more info than described in the issue to determine +circumstances.

+

HZB (RK): not too much. 2nd data publication. no workflow yet so +improvising.

+

ESRF (AM): DOI / landing page probs – datacite. Not sure about +features. More beamlines. No icat issues.

+

SP: After upgrading to Payara, increased memory usage on DLS +preprod, related to lucene (icat.server 4.8.0 – so Lucene component is +still integrated). Possibly some differences in default configuration +between Payara and Glassfish? No-one else sees similar problems.   Nor +ISIS.

+

Review Outstanding Schema Changes (SP)

+

The proposals are drawn from presentations at the Face to Face meeting. +This review is only intended to decide whether a proposal has enough +support to be considered. The proposals will be looked at in more detail +at future meetings. Comments are by SP unless indicated.

+

Rolf’s presentation

+

The first and last proposals are uncontroversial, the middle proposal is +larger and may need more discussion.

+

Persistent ID Proposal: we have persistent IDs for investigation, +dataset, datafile, but not for instrument, parameter type, sample. +Propose to add doi field to these entities.
+Conclusion: Consider adopting this.

+

Data Publication Workflow: Workflow to include fields from DataCite. +Would require adding new classes/relations. SP sees no problem, but +thinks it needs more discussion, so suggests pushing it back (behind +other changes).

+

SP: wonders if it has any crossover with collaboration/integrations +with other data-sharing standards eg. OAIPMH?
+RK: suggests DataCite metadata. Depends on which objects we want to +describe. For current schema, Investigation doesn’t perfectly match +Datacite (would need to be lax on semantics). Dataset would need creator +and maybe contributors. InvestigationUsers may not be Creators, etc.
+AM: Using InvestigationUser as Creators.
+RK: proposal matches DataCite
+Conclusion: Consider adopting. Discuss after other, easier, schema +changes.

+

Add Relation from Shift to Instrument:

+

SP: small, easy.
+Conclusion: Consider adopting this.

+

Steve’s presentation

+

Eliminate unused entities: for example: study, publication, +keyword.
+SP: worth keeping and reviewing.

+

Rename Investigation to Visit, introduce Proposal/Investigation: +SP: not sure it’s worth the effort. Alex: makes sense to us (and +DLS).
+Conclusion: Consider adopting this.

+

Add count of datafiles and total size to dataset and up:
+Worth considering. No objections raised.
+Conclusion: Consider adopting this.

+

Removing dataset replacing with Directory (possibly hierarchical)
+Remote Datafile and Dataset/Directory from RDBMS.
+These are more radical changes; but see whether DLS or others would like +it.
+AM: would like Datasets to be able to contain Datasets.
+RK: need to discuss v. thoroughly – big impact.
+Conclusion: Consider adopting. Discuss after other, easier, schema +changes and after getting more feedback from DLS.

+

Final proposal

+

Add json type to parameter fields.
+RK: how search for individual items? Other than that, happy.
+AM: considering creating another component, json-based, to add +searchable data linked to ICAT.
+RK: would need a prototype to experiment.
+Conclusion: Consider adopting this.

+

Ticket Review (SP)

+
    +
  • Looking at the Waffle.io 'Kanban'-style issue tracker which displays +the open issues in the Icatproject Github repositories. There are 4 +columns: Backlog (containing most of the issues), Ready (currently +empty), In Progress and Done.
  • +
  • Running out of time so only reviewing issues in ‘In Progress’
  • +
  • ‘In Progress’ should mean the owner expects to report on it at next +meeting.
  • +
  • IJP-related tickets to be reviewed by BR
  • +
  • #368 Topcat shaking screen: BR has a fix in test
  • +
  • IDS items: RK happy to keep them in ‘In Progress’
  • +
  • SP: asks all to look at Backlog and move to Ready any that are +higher-priority.
  • +
+

Actions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionAssigned
102.2Produce new releases of IJP componentsBrian Ritchie
113.1Look at and test Rolfs IDS Server and IDS Plugin pull requestsStuart Pullinger
113.2Organise a meeting for the discussion of a Topcat replacementCatherine Jones
115.1Look at issues in the Backlog on waffle.io and move to Ready any that are higher-priorityAll
115.2Review IJP-related tickets in ‘In Progress’ column on waffle.ioBrian Ritchie
115.3Create a timetable for discussions of schema changesStuart Pullinger
+

Next meeting will be Thursday 26th April, 3pm UK time

+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2018-meetings/meeting-116-26th-april-2018/index.html b/collaboration/communication/monthly-meetings/2018-meetings/meeting-116-26th-april-2018/index.html new file mode 100644 index 000000000..28cf6ef03 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2018-meetings/meeting-116-26th-april-2018/index.html @@ -0,0 +1,127 @@ +Meeting 116 – 26th April 2018 | ICAT Project

ICAT Project

Search

Meeting 116 – 26th April 2018

Attendees

+

Brian (BR), Chris (CP), Silvie (SR), Stuart (SP), Rolf (RK), Milan (M), +Andy (AG), Maxime (MC)

+

Actions from previous

+

102.2 – BR still working on this.

+

113.1 – Stuart hasn’t managed to do this. Is having issues with python +script used to test performance of IDS queries.

+

113.2 – Catherine to organise the topcat development meeting, Stuart +will follow up on this.

+

115.1 – Stuart didn’t see any pressing issues, i.e. issues that are +causing significant problems and need fixing immediately.

+

115.2 – Brian has closed many tickets, most of them no were longer +required.

+

115.3 – Schema changes timetable not done but discussion in this meeting +about two smaller changes.

+

ICAT Components

+

Server (SP) – Alex reported timer issue in glassfish which required +redeployment. Brian found configuration setting in Payara that means the +timers would be restarted rather than expunged if they fail. Stuart will +test this configuration change to Payara actually fixes the issue and +will add it to the setup-glassfish.py script. Stuart also notes that the +setup-glassfish script isn’t in version control so he will be adding +this.

+

Topcat (BR) – Brian created 2.4.0 snapshot that he would like +testing. The only change since then is missing lang.json.example items. +Stuart will test on Diamond pre-production and Jamie will test on ISIS +pre-production. Brian notes to be aware of the changes to +topcat.properties  when upgrading.

+

IJP (BR) – Brian reviewed in-progress issues in waffle.io and closed +most of them. Reports that ** **IJP job to SCARF no longer works due to +problem with platform LSF.

+

IDS (RK) – Snapshot released and no feedback received yet. Waiting +for Stuart to test the database performance.

+

Site Updates

+

Diamond (CP) – Double the volume of diamond user recalls over the +last two weeks has caused problems. Issue with recalls taking too long +to complete, timing out and falling into an expired state. Also because +the IDS’s are under heavy load with CPU and disk usage being very high +the test they run every 20 minutes is failing. Andy Gotz expressed +interest in Diamonds test script so Stuart says he will share it as it +may be useful for others.

+

ESRF (AG and MC) – Only issue has been topcat download/timer issue +already discussed. ESRF have DOI landing pages now but asked about +anonymous downloads. Rolf explains anonymous auth plugin, rules and +topcat config of anonymous plugin is all that’s required. MC has written +up requirements for logbook that will work closely with ICAT and will +share when complete. AG also reports that their cyroEM is fully +integrated into ICAT.

+

Waffle.IO tickets

+

‘Ready’ tickets should be for issues that are ready to be worked on. If +an issue is ‘In progress’ the ticket assignee should be prepared to talk +about it at the next monthly meeting.

+

Stuart has added two new issues to Ready. Adding setup-glassfish script +into version control and testing the Payara configuration option to stop +timers being expunged.

+

Silvia reported she made some changes to the IDS specific to Diamond. +Rolf says she can create a PR to be reviewed.

+

Stuart asked about python 2.7 end of life, Rolf confirms that +python-icat works with python 3. Stuart says he will look at getting the +setup scripts python 3 compatible.

+

Schema Changes

+

Stuart reported he’s going to start with non-controversial additive +changes, their presence shouldn’t affect anyone who doesn’t want to use +them.

+

No one objected to adding persistent identifiers to Instruments. Stuart +asked if 255 characters are enough, Rolf has never seen a persistent +identifier that is longer than 255. Stuart asked what the update should +be called and it’s agreed to at least be a minor number change since +it’s a schema change.

+

There’s some discussion regarding the creation of an optional shift to +instrument relation but the meeting is cut short so no firm decision is +made.

+

Actions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionAssigned
102.2Produce new releases of IJP componentsBrian Ritchie
113.1Look at Rolfs IDS Server and IDS Plugin pull requestStuart Pullinger
113.2Organise a meeting for thediscussion of a Topcat replacementCatherine Jones
115.3Create a timetable for discussions of schema changesStuart Pullinger
116.1Test Topcat 2.4.0 snapshot on ISIS and diamondJamie and Stuart
116.2Share diamond download test script.Stuart
116.3Look at converting setup scripts to python 3Stuart
+

Next meeting scheduled for Thursday 24th May, 3pm UK time.

+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2018-meetings/meeting-117-24th-may-2018/index.html b/collaboration/communication/monthly-meetings/2018-meetings/meeting-117-24th-may-2018/index.html new file mode 100644 index 000000000..7ea7178ec --- /dev/null +++ b/collaboration/communication/monthly-meetings/2018-meetings/meeting-117-24th-may-2018/index.html @@ -0,0 +1,84 @@ +Meeting 117 – 24th May 2018 | ICAT Project

ICAT Project

Search

Meeting 117 – 24th May 2018

Attendees:  Brian (BR), Silvie (SR), Stuart (SP), Rolf (RK), Jamie (JS)

+

Apologies: Chris (CP), Catherine

+

Actions from previous:

+

102.2 – Decided to drop this action but BR will still work on it.

+

113.1 – Stuart tried out testing script but it froze, hasn’t +investigated further. It’s decided to release IDS anyway.

+

113.2 – New starter who was going to work on Topcat no longer starting +in July. STFC are applying internally for graduate effort to work on +Topcat and ICAT. If the application is successful, they will start +between September and December this year. [Update: STFC have been +successful in their application for 1 graduate to work across TopCat and +Icat. They will start in November.]

+

STFC would like to get all the stakeholders together who currently use +the different interfaces to TopCat – possibly in person – to discuss the +future and the requirements

+

115.3 – Schema changes are in ticketing system, timetable not required.

+

116.1 – ISIS tested Topcat 2.4.0 snapshot with no issues. Not tested for +diamond yet due to some other system related issues.

+

116.2 – Diamond download test script was shared.

+

116.3 – Issue created for conversion of setup scripts to Python 3.

+

ICAT Components:

+

Topcat (BR) – Brian released a few new snapshots since last meeting. +Latest snapshot should be final release; it just needs testing by +diamond.

+

IJP (BR) – Brian reports that scarf are dropping Platform LSF in +favour of Slurm. Brian’s hoping this will be a simple change for the IJP +but is unsure yet.

+

IDS (RK) – Fixed JMS session bug in notification transmitter. The +snapshot is considered ready for release.

+

Site Updates

+

Diamond (SR) – Diamond production has been updated to use Payara.

+

ISIS (JS)  – ICAT server updated to from 4.7 to 4.9.1 to fix slow +lucene on update calls, which has worked.

+

HZB (RK) – Rolf reports he’s working on using Docker to deploy the +whole ICAT stack. As a first step it seemed too complicated to get each +component deployed on multiple machines, so going to start by deploying +on one machine with multiple containers.

+

Waffle.IO tickets

+

All ‘in progress’ tickets are IDS issues that are in the Snapshot which +it has been agreed to be released soon.

+

Stuart’s going to work on the schema change tickets that were agreed +last meeting (#198 and #199), he will make pull request for review +once done.

+

The JMS issue (#202) will be fixed in ICAT server too, Stuart’s going +to implement a similar fix as Rolf did for the IDS.

+

Stuart has had problems testing icat.utils expunged timer issue (#8).

+

There’s discussion about icat.server issue #201, adding familyName, +givenName and affiliation to User. Jamie raises issue of keeping the +redundant fullName attribute but it’s agreed this is fine. Schema change +is agreed on and ticket is placed into the ‘Ready’ list.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionAssigned
113.1Look at Rolfs IDS Server and IDS Plugin pull requestStuart Pullinger
113.2Organise a meeting for the discussion of a Topcat replacementCatherine Jones
116.1Test Topcat 2.4.0 snapshot for diamondBrain
+

Next meeting scheduled for Thursday 28th June, 3pm UK time.

+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2018-meetings/meeting-118-28th-june-2018/index.html b/collaboration/communication/monthly-meetings/2018-meetings/meeting-118-28th-june-2018/index.html new file mode 100644 index 000000000..29152e262 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2018-meetings/meeting-118-28th-june-2018/index.html @@ -0,0 +1,96 @@ +Meeting 118 – 28th June 2018 | ICAT Project

ICAT Project

Search

Meeting 118 – 28th June 2018

Attendees: Rolf (RK), Stuart (SP), Sylvie (SR), Brian (BR), Alex (AD), +Maxime (MC), Jamie (JS), George (GC)

+

Apologies: Chris (CP)

+

Actions from previous:

+

113.1 – IDS has been released so action can be removed.

+

113.2 – Stuart to speak to Catherine about the status of this.

+

116.1 – Topcat 2.4.0 GUI tested by Sylvie along with a non-recall +download. Couldn’t test larger download due to storage D issue but since +Topcat 2.4.0 has been released this action can be removed.

+

Stuart apologies for the lateness of last meetings minutes, this was +because he was waiting to hear status of a graduate working on the ICAT +project, one graduate has been successfully recruited and will be +starting in November.

+

ICAT Components:

+

ICAT Ansible (SP) – Stuart has been tweaking the Ansible Jack wrote +to get it into a state where it works on Travis, Ubuntu and Redhat 6/7 +as a prerequisite to the expunge timer problem in icat.server.

+

Topcat (BR) – 2.4.0 released. One small change since last meeting, +action buttons in plugins can now use the entity parameter in their +‘show’, so buttons can be chosen to be displayed based on the entity +as request by Jamie at ISIS. Any old plugins should not be broken by +this change, the parameter is ignored. However Brian advises testing +this and letting him know if you find that it does break your plugin.

+

IJP (BR) – Brian has experienced setbacks because the Slurm +installation seems to have overwritten condor along with its settings.

+

IDS (RK) – Released IDS server 1.9.0 along with storage file plugin +and the generic ids plugin. Fixes include the JMS session bug in the +notification transmitter that was discussed last time.

+

Python ICAT (RK) – Released 0.14.1 which allows use of the new write +ids API call.

+

Site Updates

+

Diamond (SR) – Sylvie reports in 9 months between October 2017 and +now there’s been 0.5 PB of downloads, compared to 0.3PB between in the +year between October 2016 and October 2017.

+

ESRF (AD) – Alex and Maxime have been working on something called +“ICAT +” a NodeJS, React and MongoDB application that allows +electronic log book functionality and the managing of complex metadata +to be integrated with ICAT. They hope to release the first version +before the end of the year. It allows people to comment on +investigations, non-key pair value parameters and rich metadata, such as +displaying graphs alongside investigations. Short term will be used +alongside Topcat but in the long run it will replace Topcat at the ESRF. +Stuart asks if Alex would give a demo at the next meeting.

+

HZB (RK) – Rolf reports he is installing the ICAT components to new +machines and hopes to be done by August.

+

Stuart reports that Diamond is investigating whether ICAT is the correct +tool for them with their ever increasing volume of data, which is +currently over 2B datafiles (compared to ISIS’ 17 million!). This is +only in the planning stage at the moment.

+

Waffle.IO tickets

+

#377 (pass row entity to action button show) is done and released in +the latest version of Topcat.

+

The ICAT schema changes are still in the Ready

+

The timers being expunged issue (#8 in icat.utils) is still in Ready, +Stuart is still trying to reproduce it by installing the test +application which is why he was working on the Ansible scripts.

+

JMS session issue #202 in icat.server is ready to be reviewed, Stuart +will assign Rolf the PR. Stuart says his change is similar to the one in +the IDS but not identical.

+

ids.server #87 that is causing locks to not be released when an +exception is thrown in a thread was discovered at Diamond. Rolf says he +has a student starting in October that could fix it; Stuart is going to +ask Diamond if that’s okay or if it’s required to be fixed more +urgently.

+

The other schema changes will be discussed another time as there are +still schema changes waiting to be +implemented.

+ + + + + + + + + + + + + + + + + + + + +
ItemDescriptionAssigned
113.2Organise a meeting for the discussion of a Topcat replacementCatherine Jones
+

Next meeting scheduled for Thursday 26th July 3pm UK time.

+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2018-meetings/meeting-119-26th-july-2018/index.html b/collaboration/communication/monthly-meetings/2018-meetings/meeting-119-26th-july-2018/index.html new file mode 100644 index 000000000..4db3dce27 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2018-meetings/meeting-119-26th-july-2018/index.html @@ -0,0 +1,64 @@ +Meeting 119 – 26th July 2018 | ICAT Project

ICAT Project

Search

Meeting 119 – 26th July 2018

Attendees:

+

Rolf (RK), Stuart (SP), Brian (BR), Chris Prosser (CP), Maxime (MC), +George (GC), Milan (M)

+

Apologies:

+

Alex, Catherine

+

Actions from previous:

+

113.2 – Stuart to speak to Catherine about this. Probably delayed till +after August. Stuart asked if it could be attached to the NoBugs meeting +but RK and MC are not attending.

+

ICAT Components:

+
ICAT Server (SP):
+
    +
  • Updated ICAT installation tutorial to use Payara and latest versions
  • +
  • Rolf brings up point on proxy configuration for ICAT. Not present in +tutorial.
  • +
  • Non-ascii characters are not correctly returned from the REST API. +RK and SP investigating the cause.
  • +
+
Topcat (BR)
+
    +
  • Rewritten Topcat getsize to use IDS API.
  • +
  • Reference to Topcat.css issue resolved.
  • +
+

IJP (BR), IDS (RK) and Python ICAT (RK) – Nothing to report.

+

Site Updates

+

Diamond (CP), ESRF (MC) – Nothing to report

+

HZB (RK) – Rolf reports he is installing the ICAT components to new +machines in August.

+

Waffle.IO tickets

+

#87 locking and threading problem in file explorer resolved, could be +included in next release. SP says this could be released in September.

+

RK says he may be able to look at other schema changes in August.
+Item Description +Assigned

+

Actions

+ + + + + + + + + + + + + + + + + + + + +
113.2Organise a meeting for the discussion of a Topcat replacementCatherine Jones
119.1Review and update instructions for Apache proxy configuration.SP and RK
+

Next meeting scheduled for Thursday 23rd August 3pm UK time.

+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2018-meetings/meeting-120-27th-september-2018/index.html b/collaboration/communication/monthly-meetings/2018-meetings/meeting-120-27th-september-2018/index.html new file mode 100644 index 000000000..9b7bdc9ca --- /dev/null +++ b/collaboration/communication/monthly-meetings/2018-meetings/meeting-120-27th-september-2018/index.html @@ -0,0 +1,135 @@ +Meeting 120 – 27th September 2018 | ICAT Project

ICAT Project

Search

Meeting 120 – 27th September 2018

Attendees:

+

Sylvie (SR), Stuart (SP), Alex (AdM), Maxime (Max), Rolf (RK)

+

Apologies:

+

George Christian, Catherine Jones, Brian Ritchie, Chris Prosser

+

ICAT Components:

+
ICAT Server (SP & RK):
+
    +
  • SP working on search replacement component +
      +
    • first job to document API nearly done
    • +
    • next job: write tests
    • +
    +
  • +
+

AdM: Why index on Datafiles at all?

+

SR: Users need to be able to find files by name.

+
    +
  • RK: ICAT Schema changes nearly done. Only need to add tests.
  • +
  • RK: ICAT test suite does not run -- hard-coded to Steve Fisher's +computer. See +#205 and +#206.
  • +
+
Topcat (BR)
+

Released 2.3.2.2 in August: bugfix release for DLS. Adds configuration +to show/hide the Search tab.  As indexing is disabled in DLS, Search +doesn't work, so DLS asked for the Search tab to be removed. In this +release, Search is removed by default; this meant that it could be +installed (and Search removed) without having to change topcat.json.

+

Whether a similar change is required to the topcat master (2.4.x) +depends on whether or not a solution is found to the DLS indexing +problem before DLS is ready to upgrade topcat to 2.4.x.

+
IJP (BR)
+

Nothing (interesting) to report. Octopus work is being re-planned; may +be more interested in DAaaS than in the IJP.  Current Octopus +development VMs are due to be retired in October, I am working on +creating replacements in the new Cloud service -- assuming they will +still be wanted!

+

The Scarf team plan to take over the HTCondor-Slurm work; I'm more than +happy, provided that the IJP can use whatever they do!

+

IDS (RK) and Python ICAT (RK) -- Nothing to report.

+

Site Updates

+

STFC (SP)

+
    +
  • New staff starting +
      +
    • October: Service managers
    • +
    • November: Developer
    • +
    +
  • +
  • No one from STFC is attending NoBugs 2018
  • +
  • Consultants will start to look at the DLS infrastructure (including +their use of ICAT) from October.
  • +
+

Diamond (SR)

+
    +
  • Archive has now reached 15 Petabytes!
  • +
  • A new directory structure -- by village -- has been implemented. +
      +
    • (SP: this had no real impact on ICAT)
    • +
    +
  • +
  • Now using ActiveMQ in the ingest workflow.
  • +
+

ESRF (AdM)

+
    +
  • The replacement for TopCat (eDataPortal -- built using React) is +waiting to be put into production.
  • +
  • It includes an eLogBook tab which receives notifications from +beamlines. Built using MongoDB.
  • +
  • Action: AdM to demo it at the next meeting.
  • +
+

HZB (RK) -- Nothing to report

+

AOB

+

INFRAEOSC-5 ExPanDS (RK)

+

Interesting proposal. Work package 3 is on metadata catalogues.

+

Action: SP to discuss STFC's involvement with Brian Matthews.

+

AdM: What do other sites do when an investigation wants to have 2 +datasets with the same name, eg. 'Test'?

+

SR: DLS users cannot choose a dataset name -- but they can create a +folder which becomes the dataset name.

+

RK: HZB has 2 instruments connected to ICAT. For each scan/run, a new +scan/run number is created which becomes the dataset name.

+

(Note from SP: the conclusion was that other sites did not have this +problem as either a) users could not choose a dataset name (HZB) or b) +users were forced to create a unique dataset name (DLS)).

+

AdM: Could we store the file count and size in the Dataset and +Investigation?

+

AdM: At ESRF, all files in a Dataset are ingested at the same time and +not updated so the calculation is easy.

+

SR: suggested this to Steve Fisher but he was against the idea.

+

RK: we may have to think about who/what has write access to +investigation parameters. At HZB, the ingester does not have this +permission. Retrieving the file count and size of a Dataset are +implemented in the IDS.

+

Actions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
113.2Organise a meeting for the discussion of a Topcat replacementCatherine Jones
119.1Review and update instructions for Apache proxy configuration.SP and RK
120.1Alex to demonstrate ESRF's replacement for TopCat.Alex de Maria
120.2Stuart to speak to Brian Matthews about ExPanDSStuart Pullinger
+

Next meeting scheduled for Thursday 25th October 3pm UK time.

+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2018-meetings/meeting-121-25th-october-2018/index.html b/collaboration/communication/monthly-meetings/2018-meetings/meeting-121-25th-october-2018/index.html new file mode 100644 index 000000000..1546d7f72 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2018-meetings/meeting-121-25th-october-2018/index.html @@ -0,0 +1,165 @@ +Meeting 121 - 25th October 2018 | ICAT Project

ICAT Project

Search

Meeting 121 - 25th October 2018

Attendees:

+

Maxime, Brian Ritchie (BR), Stuart Pullinger (SP), Rolf Krahl (RK), +George Christian (GC), Chris Prosser (CP), Bruno Canning (BC), Julimar +Romero (JC), Milan

+

Apologies:

+

Silvie Da Graca Ramos, Catherine Jones, Alex de Maria

+

ICAT Components:

+
ICAT Server (SP & RK):
+
    +
  • SP working on making Datafile search configurable
  • +
  • RK: ICAT Schema changes done. Pull request is in. Expected to +release in icat.server 4.10.
  • +
+
IDS(RK)
+
    +
  • Bug fix for DfRestorer bug ready for next release.
  • +
  • Filesystem locking change pull request is ready. Enables concurrent +access to the filesystem. +
      +
    • requires plugins to be recompiled (if they inherit from +mainstorage.
    • +
    • or make a new call if they just implement the interface.
    • +
    • ACTION (All): plugin authors to read and comment on RK’s email +to icatgroup.
    • +
    +
  • +
+
Python-ICAT (RK)
+
    +
  • Made new release with small change for own needs.
  • +
+
Topcat (BR)
+
    +
  • New snapshot release for Topcat 2.4.1 +
      +
    • getSize() call rewritten to improve performance.
    • +
    • slight change to address issue where new user in same browser +can see previous user’s cart and browse path.
    • +
    +
  • +
+
IJP (BR)
+
    +
  • Nothing to report.
  • +
+

Site Updates

+

STFC (SP)

+
    +
  • New starter in November: Louise Davies joins as a developer.
  • +
  • SP increasing hours from 70% to 90% of full time in November.
  • +
+

ISIS (GC)

+
    +
  • On installing new certificates, found that the root certificate was +not in the trusted key store in Payara. Had to manually install the +root CA certificate in Payara on all the ICAT stack machines. The +missing root certificate was issued by Quo Vardis Root CA 2 G3.
  • +
+

HZB (RK)

+
    +
  • Had a student working; done good work; pull requests on the way.
  • +
+

ESRF (Max)

+
    +
  • Continuing development of the new data portal.
  • +
  • Have one early adopter who is providing helpful feedback.
  • +
+

AOB

+

Vulnerability in Apache HttpClient used in ICAT Server

+
    +
  • +

    Github are now scanning our code for security vulnerabilities in our +dependencies. This is only visible to project administrators.

    +
  • +
  • +

    An alert was posted for the Apache HttpClient version 4.3.4 which is +used by all versions of ICAT Server since +4.4.0.

    +
  • +
  • +

    Details:

    +
    CVE-2015-5262 More information
    +

    moderate severity

    +

    Vulnerable versions: < 4.3.6

    +

    Patched version: 4.3.6

    +

    http/conn/ssl/SSLConnectionSocketFactory.java in Apache +HttpComponents HttpClient before 4.3.6 ignores the +http.socket.timeout configuration setting during an SSL handshake, +which allows remote attackers to cause a denial of service (HTTPS +call hang) via unspecified vectors.

    +
  • +
  • +

    RK and SP think that it is unlikely to present a danger to ICAT +systems provided they have the ‘ip’ property configured to restrict +access to ICAT to whitelisted ip address ranges.

    +
  • +
  • +

    SP will include a fix (by upgrading the dependency to 4.3.6) in the +next bug fix release of ICAT server (4.9.2)

    +
  • +
+

INFRAEOSC-5 ExPaNDS H2020 proposal (SP)

+
    +
  • SP attending meeting at Heathrow next week.
  • +
  • Work will establish a standard ontology for metadata in the +catalogues used at facilities such as ISIS and DLS.
  • +
  • Implements and adapts some of the output of PaNOSC (including ESRF) +for other facilities.
  • +
  • SP interested in possible changes to ICAT API.
  • +
  • PSI (who are creating the SciCat metadata catalogue for ESS and +presented at the last face to face meeting) are involved.
  • +
+

Google Dataset search (GC)

+
    +
  • GC has made ISIS data available through Google’s Dataset search +facility.
  • +
  • Many expressed interest in how this was achieved.
  • +
  • ACTION: GC to post to the email group an explanation of how it was +done.
  • +
+

Actions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
113.2Organise a meeting for the discussion of a Topcat replacementCatherine Jones
119.1Review and update instructions for Apache proxy configuration.SP and RK
120.1Alex to demonstrate ESRF’s replacement for TopCat.Alex de Maria
121.1Plugin authors to read and comment on RK’s email to icatgroup.All
121.2Post to the email group an explanation of how Google Dataset search was enabled.GC
+

Next meeting scheduled for Thursday 22nd November at 3pm UK time.

+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2018-meetings/meeting-122-22nd-november-2018/index.html b/collaboration/communication/monthly-meetings/2018-meetings/meeting-122-22nd-november-2018/index.html new file mode 100644 index 000000000..43c77261f --- /dev/null +++ b/collaboration/communication/monthly-meetings/2018-meetings/meeting-122-22nd-november-2018/index.html @@ -0,0 +1,91 @@ +Meeting 122 - 22nd November 2018 | ICAT Project

ICAT Project

Search

Meeting 122 - 22nd November 2018

Attendees:

+

Alex de Maria (AM), Maxime, Brian Ritchie (BR), Stuart Pullinger (SP), Rolf Krahl (RK), Chris Prosser (CP), Silvie Da Graca Ramos (SR), Louise Davies (LD), Lukas Masaitis, Nick Cook

+

Apologies:

+

Bruno Canning, Catherine Jones, Milan

+

ICAT Components:

+

ICAT Server (SP):

+
    +
  • New release now available: 4.9.2
  • +
  • Includes a minor upgrade to a dependency to fix a security issue
  • +
  • New configuration option to choose which entities are included in the lucene index. Allows Diamond to remove Datafiles from the lucene index.
  • +
  • In preparing the release, I found a problem with the fix for issue 202 (JMS Session not closed if an exception is thrown) so it was not included in this release. A future release will address this.
  • +
  • Basic Travis CI configurations are being included for ICAT components to automate running unit tests. They will be extended to run integration tests eventually.
  • +
+

IDS(RK)

+
    +
  • Bug fix for issue 202 above will be released as 1.9.1 soon
  • +
+

Python-ICAT (RK):

+

Nothing to report

+

Topcat (BR)

+
    +
  • 2.4.1 released on 2nd November.
  • +
  • getSize calculations now use the IdsClient API (issue #386), which should improve performance.
  • +
  • fix issue #379 : restore copying topcat.css into styles/ in setup [this clears an error message that was appearing in the FF console]
  • +
  • fix issue #381 : IcatClient.getFullName returns UserName if no FullName is found [was causing problems for the DAaaS plugin]
  • +
  • fix issue #384 : Cart no longer inherited by different user on same browser; also, if a different user logs in, the browse path is reset.
  • +
  • added optional “disabled” flag to site.search configuration in topcat.json.
  • +
  • If present and true, the Search tab will not be added. [required for Diamond]
  • +
+

Since then, some small changes that will become part of 2.4.2:

+
    +
  • improve DOI redirection failure message (issue #388)
  • +
  • mail configuration properties can be removed if not required (issue #389)
  • +
+

but these are not show-stoppers so no urgency to release them yet.

+

IJP (BR)

+

Nothing to report.

+

Site Updates

+

DLS (SP)

+
    +
  • Upgraded icat.server from 4.8.0 to 4.9.2 +
      +
    • now using separate Lucene component
    • +
    • and rest authenticators
    • +
    • configured to prevent lucene from indexing Datafiles on ingest.
    • +
    +
  • +
  • IDS is still on 1.8.0. Awaiting fix for bug
  • +
+

HZB (RK)

+
    +
  • Upgraded to icat.server 4.9.2 and TopCat 2.4.1
  • +
+

AOB

+
    +
  • INFRAEOSC-5 ExPaNDS H2020 proposal has now been submitted. (SP)
  • +
  • ALBA will be installing the ICAT Stack. (AM)
  • +
+

Demo

+

Alex demonstrated the new web interface to ICAT being developed at ESRF. Slides of the presentation are available here: +Datahub Demo.

+

Actions

+ + + + + + + + + + + + + + + + + + + + +
113.2Organise a meeting for the discussion of a Topcat replacementCatherine Jones
119.1Review and update instructions for Apache proxy configuration.SP and RK
+

Next meeting proposed for Thursday 20th December at 3pm UK time. SP to email icatgroup earlier that week to see if there is interest in having a meeting.

+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2019-meetings/index.html b/collaboration/communication/monthly-meetings/2019-meetings/index.html new file mode 100644 index 000000000..65f4d01bd --- /dev/null +++ b/collaboration/communication/monthly-meetings/2019-meetings/index.html @@ -0,0 +1,12 @@ +2019 Meetings | ICAT Project

ICAT Project

Search

2019 Meetings

+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2019-meetings/meeting-123-24th-january-2019/index.html b/collaboration/communication/monthly-meetings/2019-meetings/meeting-123-24th-january-2019/index.html new file mode 100644 index 000000000..66dc9a734 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2019-meetings/meeting-123-24th-january-2019/index.html @@ -0,0 +1,252 @@ +Meeting 123 – 24th January 2019 | ICAT Project

ICAT Project

Search

Meeting 123 – 24th January 2019

Attendees:

+

Alex de Maria (AM), Maxime, Brian Ritchie (BR), Stuart Pullinger (SP), +Rolf Krahl (RK), Chris Prosser (CP), Silvie Da Graca Ramos (SR), Louise +Davies (LD), George Christian (GC)

+

Apologies:

+

Andy Gotz

+

ICAT Components:

+

ICAT Server (SP):

+
    +
  • 4.9.2 released allowing entities to be excluded from Lucene search +for the purpose of limiting index size. Resolves a Diamond issue +where the maximum index size was reached.
  • +
  • 4.9.3 snapshot release: bugfix for Diamond
  • +
  • 4.10 release in progress to provide schema changes: DOI for study, +fields for given name, surname and a few other additive changes.
  • +
+

Rolf – Add uniqueness constraints to parameters to be included in future +release.

+

Rolf – Question around status of Travis build for icat.server. SP: +Travis builds are a work in progress. LD still working on making them +reliable.

+

Topcat (BR)

+
    +
  • Version 2.4.2 snapshot release available.
  • +
  • Bugfix for 2.4.0 -> change in API had resulted in internal tools +breaking.
  • +
  • Diamond bugfix where adding too many entities to cart caused +download failure.
  • +
  • Bugfix for investigation size cache -> new API call that clears +individual cache entries -> Time limit on cache -> Option to not +cache zero sizes.
  • +
  • Browser console cache monitoring
  • +
  • Update of Topcat web framework from AngularJS to Angular being +considered. Substantial rewrite of the Topcat code required.
  • +
+

Since then, some small changes that will become part of 2.4.2:

+
    +
  • improve DOI redirection failure message (issue #388)
  • +
  • mail configuration properties can be removed if not required (issue +#389)
  • +
+

but these are not show-stoppers so no urgency to release them yet.

+

IDS(RK)

+
    +
  • 1.9.1 released
  • +
  • New ids.plugin snapshot release – 1.5.0
  • +
  • New ids.server snapshot release – 1.9.2
  • +
  • IDS plugin API slightly changed so that developers must recompile to +retain compatibility. Exceptions added to MainStorageInterface.put() +and MainStorageInterface.exists().
  • +
+

Site Updates

+

ISIS – George

+
    +
  • Adding DOIs to the study table so that a single DOI can cover an +entire experiment.
  • +
  • Taking measures to resolve Topcat cache inconsistencies.
  • +
+

ESRF – Alex and Maxime

+
    +
  • Would like a way to signal to the user that a dataset is empty and +therefore not available to download. Particular issue with the +download button being available next to an empty dataset.
  • +
+

Decision taken to postpone further discussion due to poor network +connection at +RAL.

+

Meeting 123: continued – 31st January 2019

+

ICAT Roadmap Update (SP)

+

Slides +(copied below)

+

Outline of the Roadmap

+
    +
  • Securing Longevity +
      +
    • address long-term and near-term technical ideas to ensure ICAT +has longevity
    • +
    +
  • +
  • Supporting Open Science +
      +
    • adopt standards and interfaces to support open science
    • +
    +
  • +
  • Sustaining the ICAT Project +
      +
    • improve development processes and documentation
    • +
    • accept input and effort from more people
    • +
    +
  • +
  • Extending ICAT functionality
  • +
+

Securing longevity

+
    +
  • Review of user requirements +
      +
    • Ongoing work looking at requirements for DLS
    • +
    • Will start reviewing user interface needs with STFC facilities +soon
    • +
    +
  • +
  • Investigation of technologies: see below
  • +
  • Topcat/eCat/ICAT Manager rewrite +
      +
    • More activity recently
    • +
    • Hope to be able to report progress next month
    • +
    +
  • +
  • REST API +
      +
    • Louise has/will be looking at this (including ICAT+ and SciCat)
    • +
    +
  • +
  • GraphQL +
      +
    • Louise looking at this: GatsbyJS for the website?
    • +
    +
  • +
+

Supporting Open Science

+
    +
  • Data publication/DOIs +
      +
    • Expecting schema changes for icat.server 4.10.0
    • +
    +
  • +
  • Interoperability +
      +
    • Expecting to follow lead from PANOSC (ESRF)
    • +
    • We have a small amount of effort in EXPANDS too (if it is +funded)
    • +
    +
  • +
  • DAAS +
      +
    • Very active though no activity planned through this project
    • +
    +
  • +
  • Provenance tracking +
      +
    • Expecting schema changes for icat.server 4.10.0
    • +
    +
  • +
+

Sustaining the ICAT Project

+
    +
  • Formalisation of development process +
      +
    • Some additions to the developer instructions
    • +
    • Louise has created automated build and test configurations for +Travis CI
    • +
    +
  • +
  • Improved documentation/manual +
      +
    • Was not able to secure extra effort for this last year
    • +
    • Louise and Stuart need to make a plan for this
    • +
    +
  • +
  • New Website +
      +
    • Louise looking at options including GatsbyJS – as a way to also +learn React and assess GraphQL.
    • +
    +
  • +
+

Extending ICAT Functionality

+
    +
  • Tickets +
      +
    • Ongoing
    • +
    +
  • +
  • Schema review +
      +
    • After these slides!
    • +
    • Will return to monthly meetings after 4.10.0 is released.
    • +
    +
  • +
  • Richer metadata +
      +
    • Stuart to look into this. No recent progress to report.
    • +
    +
  • +
+

Schema Discussion (AM)

+

(Based on Alex’s questions to the list)

+

Development of a common metadata catalogues API

+
    +
  • **** Related to WP3 in the PANOSC proposal.
  • +
  • Work on WP3 has not started yet but will start soon.
  • +
  • ICAT is probably one if not the most widespread metadata catalogue +in Europe for large facilities
  • +
  • It might be worth to discuss internally in the ICAT’s collaboration +and agree what we might expect of a common API for metadata +catalogues.
  • +
  • I imagine that it is also directly connected to EXPANDS (btw any new +about the funding?)
  • +
+
PANOSC work package description
+

“Define an API to be used in the Photon and Neutron community that will +allow for FAIR exposure of the data at the individual institutions +through a catalogue service. The API will allow federation, and exposure +of metadata relevant for the area, in a way that will enable search and +facilitate access of researchers across scientific disciplines. Existing +APIs (e.g OAI-PMH) and communities (e.g. +openarchives.org , Dublin Core Metadata +Initiative (DCMI), OpenAIRE) will be taken into account. The API will +enable domain specific search extensions aware of the metadata +definitions and usage at photon and neutron facilities. In order to test +any implementation at facilities for compliance, a set of API tests will +be developed. The test harness will be executable against a given site +catalogue service and result in a report stating the status towards +compliance”

+

SP: definitely interested in pursuing this and being involved. Suggested +ICAT-Plus and SciCat APIs as a starting point. Concerned that +developments in PANOSC may not be ready in time to influence the new +ICAT Rest API.

+

ACTION: SP to send a link to the SciCat schema to the list.

+

RK: Need more information from PANOSC on what is the scope and +technology in use.

+

Schema Discussion

+
    +
  • Status for the modification of the schema to include the +equivalent to visit so there is (1 investigation -> N visits ) or +(1 proposal -> N investigations).
  • +
  • I don’t remember well the status of this or even if this agreed or +done.
  • +
+

ESRF: Investigation entity does not fit their data model. Would like to +have a separate set of users at the proposal level so a DOI can be +minted with those users in the metadata.

+

SP: Covered in Steve’s slide +(no. 5) +from the Face to face – but not yet implemented

+

George: Study entity in the current schema is mostly interchangeable with +proposed concept of proposal.

+

Rolf: HZB only mints DOIs for publications, not data itself. Believes +that it is not possible to properly attribute credit for a dataset. +Associates a PID with the data rather than a DOI, no metadata needs to +be provided.

+

ACTION: AM to investigate whether Study Entity (with, or without +additional properties) is sufficient to model the relationship he needs.

+

Discussion ended as we ran out of time.

+

Next meeting: Thursday 28th February 3pm (UTC)

+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2019-meetings/meeting-124-28th-february-2019/index.html b/collaboration/communication/monthly-meetings/2019-meetings/meeting-124-28th-february-2019/index.html new file mode 100644 index 000000000..3f37639ec --- /dev/null +++ b/collaboration/communication/monthly-meetings/2019-meetings/meeting-124-28th-february-2019/index.html @@ -0,0 +1,83 @@ +Meeting 124 – 28th February 2019 | ICAT Project

ICAT Project

Search

Meeting 124 – 28th February 2019

Attendees:

+

Alex de Maria (AM), Maxime, Brian Ritchie (BR), Stuart Pullinger (SP), +Rolf Krahl (RK), Chris Prosser (CP), Silvie Da Graca Ramos (SR), Louise +Davies (LD), George Christian (GC)

+

Component Updates

+

ICAT server (SP):

+
    +
  • 4.9.3 released
  • +
  • Snapshot released for 4.10.0
  • +
  • Bug with JSONising Study to be fixed before final release
  • +
  • End date also to be added to study table
  • +
+

Topcat (BR):

+
    +
  • 2.4.3 snapshot released
  • +
  • Accounts for schema changes in ICAT server 4.10
  • +
  • Made study accessible through topcat.json
  • +
  • Fixed bug with metatabs display
  • +
+

ICAT project website (LD):

+
    +
  • Migration of WordPress site to Github Pages
  • +
  • Website being rewritten in the same style using GatsbyJS
  • +
  • Allows pages to be written in Markdown
  • +
  • Github workflow allows easier modification
  • +
  • (RK) Would like to see the inclusion of structured text. ACTION: +(LD) to look into feasibility.
  • +
+

IDS (RK):

+
    +
  • Snapshots for IDS plugin 1.10 coming in March
  • +
  • Users will need to recompile plugins for next IDS release
  • +
+

Python-ICAT (RK):

+
    +
  • 15 being released adding support for ICAT server 4.10.0
  • +
  • Next release will drop support for Python 2.6 and ICAT server 4.2
  • +
+

Site Updates

+

ISIS (GC):

+
    +
  • Continuing to add support for study DOIs
  • +
  • Working on a Topcat plugin that can set permissions on investigation +data for use by data analysis systems.
  • +
+

DLS (CP) (SR):

+
    +
  • Globus increasingly being used
  • +
  • Working on making data ingestion more reliable
  • +
  • Feedback from Globus workshop: More universities establishing +endpoints that are properly configured for best performance.
  • +
+

ESRF

+
    +
  • ICAT+ ready to be pushed to a GitHub repository on icat-contrib
  • +
  • Looking into combining ElasticSearch with ICAT. Principal issue is +transferring permissions from ICAT rules to ElasticSearch.
  • +
+

HZB (RK):

+
    +
  • Student working on an OAI-PMH plugin for ICAT server
  • +
+

Discussion

+

Schema structure (AM)(Maxime):

+
    +
  • Study is inadequate because it can only have a single user.
  • +
  • Can’t associate samples with a study
  • +
  • Can’t associate parameters with a study
  • +
+

Addition of data volume column to investigation and dataset:

+
    +
  • (AM) ESRF currently using investigation parameters for this purpose
  • +
  • (GC) Raised issue #211 on icat.server mentioning this
  • +
  • (SR) DLS thinking of running a batch SQL query to update volumes
  • +
+

Next meeting: Thursday 28th March 2019

+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2019-meetings/meeting-125-28th-march-2019/index.html b/collaboration/communication/monthly-meetings/2019-meetings/meeting-125-28th-march-2019/index.html new file mode 100644 index 000000000..e413011d9 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2019-meetings/meeting-125-28th-march-2019/index.html @@ -0,0 +1,228 @@ +Meeting 125 – 28th March 2019 | ICAT Project

ICAT Project

Search

Meeting 125 – 28th March 2019

Attendees:

+

Alex de Maria (AM), Brian Ritchie (BR), Stuart Pullinger (SP), Rolf +Krahl (RK), Chris Prosser (CP), Silvie Da Graca Ramos (SR), Louise +Davies (LD), George Christian (GC), Andy, Maxime

+

Component Updates

+

ICAT server (SP):

+
    +
  • Released 4.10.0 `icat-server` and `icat-client`
  • +
  • Schema changes: +
      +
    • Added pid and enddate to Study
    • +
    • Rofl’s schema changes
    • +
    • Need to run schema upgrade scripts to upgrade
    • +
    • Only additions to schema, minor changes needed
    • +
    +
  • +
  • Issues: +
      +
    • Steve used MireDot to generate REST API docs
    • +
    • Licence has experied – awaiting a new licence
    • +
    • Proprietry software but free for open source
    • +
    • Will generate docs for previous releases once this has happened
    • +
    • Waffle.io (used for kanban board) is closing
    • +
    • Move issues across to Github Projects
    • +
    +
  • +
+

IDS (RK):

+
    +
  • Snapshot releases for `ids-server`, `ids-plugin`, +`ids-plugin-file` +
      +
    • main change: support for file system locking +
        +
      • if plugin decides to implement, allows for concurrent access +to storage
      • +
      +
    • +
    +
  • +
+

Python-ICAT (RK):

+
    +
  • Released `python-icat` 0.15.0 +
      +
    • Supports icat-server schema changes
    • +
    • Fixes some compatibility issues
    • +
    • Last version to support Python 2.6
    • +
    +
  • +
+

Q: Andy: python 2.6 support dropped – will 2.7 still be supported?

+

RK: When python-icat v1 is released, likely will drop support for Python +2 then, following on discussions on the mailing list

+

SP: scripts in icat-server are Python 2 only, so work needed to convert +to python 3
+Should we convert to support both or just support python 3?
+RH6 only has python 2 as default, so sensible to make them support both

+

RK: shouldn’t be too hard to support both for small scripts

+

SP: aim to support both

+

Topcat (BR):

+
    +
  • Released topcat 2.4.3 +
      +
    • contains schema changes from icat-server 4.10.0
    • +
    • Minor change from last snapshots: remove spinners for cells that +are blank
    • +
    • component updates in vagrant/travis build
    • +
    • Travis still sporiadically fails, some attempts have been made +but no definitive fix
    • +
    +
  • +
+

Site Updates

+

DLS (CP):

+
    +
  • 2 mechanisms for user recall: standard HTTPS and Globus/PollCAT – +lots of user recalls on both +
      +
    • +

      HTTPS: 2 user recalls had issues to do with tape, IDS timed out, +script normally restarts recall but the scripts didn’t have +enough storage to retrieve the files – resolved by restarting +IDS

      +
    • +
    • +
    • +

      GLOBUS: millions of files requested/several TB of data, swamped +IDS, made us reconsider PollCAT design

      +
    • +
    +
  • +
  • Everything else seems fine
  • +
+

SR:

+
    +
  • changing ingest – putting into pre-prod soon
  • +
+

Q: Andy – how many times do you copy data when moved in the Globus +system?

+

SR – Diamond uses datafile and not dataset level storage

+

SP – Scans table in TopCAT directly for downloads marked as Globus, and +ignores HTTPS. Files are copied from tape to StorageD, then copied to +IDS main storage, then copied into separate Globus download area

+

SR – google group mailing issue about copying data might seem similar, +but believe Diamond issue is separate

+

Andy – tape storage managers want to reduce copies to only 1 copy rather +than 3

+

RK – IDS has intermediate step if you have dataset where archive is +copied to cache, and then it is extracted to main, datafile does not +have this step. This extra step has been an issue from 2016, but it is +difficult. Would like to refactor some code in IDS before tackling this +issue, so no promises of when a fix will happen. You will still have 2 +copies – 1 in archive and 1 in main, this is hard to avoid.

+

Q: AM – can we restore data automatically into main area?

+

RK – no

+

Andy – “restore to original place” – aka main storage

+

RK – IDS doesn’t know about tape storage, so it must request from tape +first, it is built with archive and main. Client request comes in, IDS +triggers restore, reads ZIP from archive and restores to main.

+

SP – can storage system unzip to main behind IDS’s back? IDS checks if +it is on disk first, before it goes to archive and if it’s available it +can use it. If ids-plugin isn’t responsible for restoring, and a +separate system unzips?

+

RK – would need to talk directly to tape storage, but then would need to +code all backends. No direct communication between IDS-server and +storage backend. IDS talks to main storage plugin and then archive +storage plugin. No direct way to avoid this.

+

HZB (RK):

+
    +
  • Nothing to report
  • +
+

AOB

+

Diamond recall bug

+

SP – Diamond problems with restarting recall where IDS needs to be +restarted – seems similar to bug (issue #87) where IDS locked files +when recalling, but if thread crashed then the files would remain locked +until IDS restarted. Check Diamond has a version of IDS which includes +this bugfix and if it doesn’t then upgrade.

+

RK – fixed in IDS 1.9.1

+

Plugin Logging

+

SP – Diamond StorageD plugin, most ids-plugins don’t have much logging. +RK’s student has solution to get logging in plugins?

+

RK – You can use logging in the plugins, using log4j, one caveat: you +need to provide a logfile config that shadows logfile from IDS-server. +Inconvenient because logging for IDS-server is in plugin, but it works.

+

SP – where is this fix recorded?

+

RK – issue #76, some documentation in this issue

+

SP – next version of IDS may require recompilation for plugins, so might +be a good idea to look at logging now to save multiple recompilations

+

RK – away for next 2 weeks, but after may provide information on how to +modify plugins delete should not throw exception then file to delete +does not exist additional call lock. Suggest adding these things to +archive storage, otherwise need to add dummy method

+

Moving instead of copying in Diamond

+

CP – Manually deleting data from IDS, response from RK that this isn’t a +good idea. Want to move data from IDS cache

+

SP – on globus IDS files are restored from archive to main like normal +IDS, these files are then copied to separate Globus area. Can we just +move them instead of copying? Problem: 2 requests for same file, IDS +thinks it’s there for second file but file has been moved by request for +first file

+

RK – clarify: you want to move files from main storage to transfer area? +This is a problem as IDS doesn’t know file is not there. IDS might +restore things twice. Can you not make a hard link?

+

Silvia – Is it possible to change permissions in main storage area so +users can access?

+

SP – Globus has its own user, don’t know how this will work with +permissions, but hard link might work

+

RK – hard link will only work if both areas are on same file system

+

Silvia – IDS has functionality to remove files when we want, different +process to perform

+

CP – user1/user2 causing double recall from archive is fine, this is +rare case and offset by increase in move efficiency

+

RK – should be fine, deleting files from datafile level storage is fine

+

CP – so move works, but less efficient in multiple users requesting same +file

+

Silvia – hard link might be useful for multiple users case

+

RK – you can make hardlinks for file to users area, when IDS removes +file from main storage this will also remove hard links. Still have to +check that permissions are separate between hardlinks and not shared.

+

Dataset level issue

+

SP: RK is proposing change when zip requested from archive, when files +don’t exist in zip or there are unexpected files, throw exceptions. +Concern this is not suitable for ESRF where it ma be better to continue +working and log errors instead. Is there a comprimise – e.g. config +option?

+

AM: Understand RK’s POV, but this is the best we can do. Sometimes +people rename files and it’s impossible to find files. So we’d like to +make best effort to restore what we can.

+

RK: you should make it consistent

+

AM: you are imposing this constraint

+

RK: IDS fundamentally relies that the data in ICAT is correct. If data +is not correct you don’t get reliable. If the files in the ZIP don’t +match then the data is not correct. IDS ignores files with null +location.

+

AM: we like that the location has a record of where it was

+

RK: location is controlled by IDS, if it’s not then IDS is unstable

+

SP: is it true that to accommodate RK’s change, you need to scan all +files to check that they match what IDS expects – this is a big job

+

AM: this isn’t too much of a worry, the worry is removing location that +is useful to the user

+

RK: location isn’t supposed to e useful for user, meant to be +administrative field for IDs to use

+

AM: would prefer not to delete location – our IDS is working well

+

RK: you will run into strange errors: restore will get stuck with an +error. IDS relies on location, if it’s not correct then IDS is not +correct

+

SP: could IDS be written that if file is missing you throw the error, in +the catch you check config option and skip this file, otherwise rethrow +exception

+

RK: you could do this, but doesn’t remove problem that IDS assumes +location is correct and exists

+

SP: ICAT/Diamond doesn’t have this problem because datafile level +storage

+

RK: IDS will still file if it doesn’t exist

+

SP: But if it fails for 1 file it will continue to next file, unlike +dataset storage.

+

AM: might be possible to use own field/parameter to record the previous +location, then location can be nulled

+

SP: look at how ingest works and look for inconsistency, look for skips

+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2019-meetings/meeting-126-25th-april-2019/index.html b/collaboration/communication/monthly-meetings/2019-meetings/meeting-126-25th-april-2019/index.html new file mode 100644 index 000000000..a2eda76d3 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2019-meetings/meeting-126-25th-april-2019/index.html @@ -0,0 +1,92 @@ +Meeting 126 – 25th April 2019 | ICAT Project

ICAT Project

Search

Meeting 126 – 25th April 2019

Attendees:

+

Stuart, Chris P,  Brian R. Sylvie, Rolf, Alex

+

Apologies:

+

Andy G.  Louise, George on leave.

+

Stuart: could we replace Hangouts with BlueJeans / Zoom stuff, and our +VC stuff?

+

Rolf: will switch to HZB’s videoconf rooms – pressure not to use +Hangouts (too)!

+

Alex: would need to book VC room, but could do.  Stuart says BlueJeans / +Zoom can be used on a laptop.

+

Component releases:

+

ICAT Server (Stuart):

+
    +
  • Nothing to report
  • +
+

Topcat (Brian):

+

Topcat new snapshot (yesterday):

+
    +
  • console warning if wait for plugins starts to get long
  • +
  • Add optional preamble HTML to login page, defined in lang.json +(issue #415)
  • +
  • Add showAsButton to authenticator configuration (in topcat.json) to +give an authenticator its own login button (issue #418)
  • +
  • Add extraLoginButtons to facility configuration (in topcat.json) +(issue #419)
  • +
  • Remove DOI and some login redirections from browser history (issue +#424)
  • +
  • Replace hard-wired entity inclusions in metatabs with calculated +inclusions (issue #405)
  • +
+

The login/authenticator configuration changes were motivated by ISIS +requirements, largely concerning users coming to Topcat from DOI landing +pages, who were finding the login page confusing; so more text needed, +and separate buttons for anonymous login and for registration with the +ISIS User Office); also, redirections within Topcat were making it +impossible for them to get back to the DOI landing page by using their +browser’s Back button.

+

IDS Server (Rolf):

+
    +
  • Last week released plugin and storage-file; have discussed changes +additional log call main storage; have sent instructions for plugin +authors.
  • +
  • New call only from upcoming version of ids server; so only update +plugin then.
  • +
  • Mostly ready to release ids server; debate today, release tomorrow.
  • +
+

Stuart summarised the issue: behaviour of current IDS – when restoring +dataset level, if a file is missing, can cause an exception in the +plugin. Rolf would like IDS to throw an exception; but Alex relies on +current behaviour where it continues to restore data from the zipfile. +Stuart suggests a compromise of making the strict behaviour the default +but configurable.  Rolf: this may not work. If ICAT is not consistent +with storage, IDS will not work. Many other places where this can +happen. Risk of downloading a corrupt zipfile.

+

Stuart: how does it work for Alex at present?

+

Rolf: it will restore with ids 1.9.0 but zipfile will be corrupt. Alex: +impression was it was working fine; but it doesn’t. Test yesterday +produced an error. So it may never have worked [after all].

+

Rolf: new behaviour would throw an error, so DSRestorer would stop.

+

Stuart: is this reported back to the user?

+

Rolf: nothing happens: the file does not restore, and so [sits at +Restoring…?]

+

Alex would like to test again.  Consider adding [expected] location as +new datafile parameter, but will have to be added to every datafile.

+

Stuart: suggest Alex tests again tomorrow, if still fails, let Rolf +continue with his pull request, as it won’t make any difference to what +Alex sees.

+

Rolf: consider visit Grenoble to discuss further.

+

Site reports

+

ISIS

+

Stuart: nothing from ISIS (via George)

+

Diamond

+

Chris: no real changes in last few weeks. Interested in progressing +discussions on IDS improvements, including new hardware.

+

Stuart: Rolf suggested using hard links, and that looks like a good +solution – one-line change to code, so trying it.  Considering a larger +change to the tidier process, perhaps use it to point to the area where +we create these links, and use it to clean them up. More thought needed.

+

Rolf: can’t use current tidier to do this.

+

Stuart: ? separate tidier to manage links? Delete old files, or delete +files until some threshold is reached.

+

HZB

+

Rolf: upgraded production to 4.10, and it works.  Also tried using +schema changes, successfully.

+

Chris: DLS still to decide 4.9.3 vs. 4.10 – may not need schema changes.

+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2023-meetings/20230525-meeting/index.html b/collaboration/communication/monthly-meetings/2023-meetings/20230525-meeting/index.html new file mode 100644 index 000000000..67677a906 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2023-meetings/20230525-meeting/index.html @@ -0,0 +1,165 @@ +ICAT Collaboration Meeting 25/05/2023 | ICAT Project

ICAT Project

Search

ICAT Collaboration Meeting 25/05/2023

ICAT Collaboration Meeting 25/05/2023

+

Attendees

+

Alejandra Gonzalez-Beltran, Marjolaine Bodin, Will Taylor, Alex Kemp, Louise Davies, Malik Almohammad, Grabiel Preuẞ, Nicolas Soler, Allan Pinto, Patrick Austin, Alan Kyffin, Kevin Phupps, Matt Richards, Viktor Bozhinov, Rodrigo Cabezas Quirós

+

Apologies

+

Andy Gotz, Rolf Krahl, Alex de Maria

+

Face to face

+

Please upload slides to the Indico site (if not already) +Will try to upload photo to the website +AGB to try to summarise the notes from the meeting (if anyone has ideas, get in touch)

+

Site Updates

+

SESAME (Malik):

+
    +
  • Went to ESRF after F2F, went great, can now see all the metadata
  • +
  • Have ICAT server running with all metadata
  • +
  • Not enough time to finish ingestion for all data
  • +
  • After returning, wrote python code for collecting all data and putting in the portal
  • +
  • Now have it running, but have issue: still using Topcat, need support for newer UI +
      +
    • Either DataGateway or Datahub would be valid choices
    • +
    • Rolf also facing this decision
    • +
    • Discussed with HZB
    • +
    • Compatability issues with Red Hat 8
    • +
    +
  • +
  • Still using 4.8, need to update to version 5
  • +
+

ESRF (Marjolaine):

+
    +
  • ISpyB collaboration meeting, ingesting MX and CryoET data into ICAT + dedicated UI
  • +
  • Will start to work on ingesting paleontology data, existing portal is old +
      +
    • Similar to approach to the human organ atlas
    • +
    +
  • +
  • Certification (CTS) Core Trust Seal approved
  • +
+

HZB (Gabriel)

+
    +
  • Rolf on leave, and have had leave recently so not much to report +
      +
    • IDS work to come
    • +
    • More detailed schedule to come
    • +
    +
  • +
+

ISIS (Will)

+
    +
  • No updates
  • +
+

DLS (Kirsty)

+
    +
  • No updates
  • +
  • STFC: still working on open data/DOI minting work
  • +
+

ALBA (Rodrigo)

+
    +
  • Started working on ingestor
  • +
  • Had maintenance on K8s cluster
  • +
  • Preparing another beamline to ingest ARPES data in ICAT
  • +
  • Trying to use metadata standards, also talking to bealine scientists
  • +
  • SO far 2 beamlines ingesting ("incompletely") to ICAT
  • +
  • Want to use ARPES as the case study for further beamlines
  • +
+

Sirius (Allan)

+
    +
  • Running the tutorial for the ICAT
  • +
  • Try to follow it but found some problems +
      +
    • Alejandra: please report issues with current documentation via mailing list or Slack +
        +
      • If documentation is on GH, feel free to contribute directly
      • +
      +
    • +
    • Malik: working on issues encountered for RH7/8 distros, from installation to authentication
    • +
    +
  • +
  • Found ESRF repo icat compose, was able to use that start a demo which is working fine, version 4.9?? +
      +
    • Should this be moved to GitHub, with the other "core" components (at least a link in the icat web site)
    • +
    +
  • +
  • Next step is to ... currently migrating VMs to Docker containers, saw that many repos are using ... are we using docker composers or is the aim to have it running in production? +
      +
    • Rodrigo: running everything in their K8s cluster
    • +
    • Documentation recommends setting up a VM - can there be a containerised version - think this would be easier for people
    • +
    • ALBA has a TODO list item to share their docker/k8s config with the ICAT collab - just want to make some changes first
    • +
    • Rolf has started to work on an ICAT mini docker - don't think it's finished yet, expect a mailing list announcement
    • +
    +
  • +
+

Component Updates

+

ICAT Manager (Will Taylor)

+ +

icat.server

+
    +
  • Patch version released for both ICAT 4 (4.11.2) & 5 (5.0.1)
  • +
  • Resolves an issue re: authorizing one-to-many/many-to-many relationships +
      +
    • This is considered a vulnerability
    • +
    +
  • +
  • Also switches scripts to use Python 3 in 5.0.1 only
  • +
+

Payara 6

+
    +
  • ICAT 5 only runs in Payara 5, which is out of support
  • +
  • A lot of breaking changes due to supported libraries, but no functional change
  • +
  • No change in schema between 5 and 6
  • +
  • Haven't completed testing in anger
  • +
  • Affects multiple components as well
  • +
+

Standalone logbook

+
    +
  • Marcus at HZB working on it
  • +
  • Have a running prototype
  • +
  • Based on ESRF's work that's currently integrated into Datahub
  • +
+

AOB

+

South Africa Conference

+
    +
  • Andy submitted abstract for Cape Town conference
  • +
  • If accepted, will become a paper to describe the status of ICAT
  • +
  • Every facility can contribute with how they are using it
  • +
+

NFDI meeting (DAPHNE?)

+
    +
  • Discussed some of their work (including at HZB) for better management
  • +
  • Some facilities using SciCat
  • +
  • Focus on standardizing between facilities
  • +
  • Discussions on logbooks also relevant
  • +
+

Tutorials

+
    +
  • Q: there are many out there, what would be considered "official"? +
      +
    • A: the icat manual repo, markdown based tutorials
    • +
    • Might not be up to date, but is closest we have
    • +
    • Stuarts gitbook: definitely out of date, will still be on Payara4
    • +
    • SHould it br easier to find this manual? Link/copy directly to the website
    • +
    • Malik: we already use every service from https://repo.icatproject.org/, a lot of documentation - find this very useful (should this also be more prominent)
    • +
    +
  • +
+

Website?

+
    +
  • Out of date - reference job portal, topcat and other outdated components
  • +
  • In the icatproject.github.io repo is the source
  • +
  • Open pull requests for improvements, contributions welcome
  • +
  • Issues asking for new content
  • +
  • In parallel to content changes, should we update the look
  • +
  • Kenneth, Louise currently assigned to review
  • +
  • Include notes from collab meetings in future
  • +
+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2023-meetings/20230629/index.html b/collaboration/communication/monthly-meetings/2023-meetings/20230629/index.html new file mode 100644 index 000000000..748ea36e6 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2023-meetings/20230629/index.html @@ -0,0 +1,129 @@ +ICAT Collaboration Meeting - 29th June 2023 | ICAT Project

ICAT Project

Search

ICAT Collaboration Meeting - 29th June 2023

Attendees:

+
    +
  • Patrick
  • +
  • Nicolas Soler
  • +
  • Rolf Krahl
  • +
  • Louise
  • +
  • Allan Pinto
  • +
  • Alexander
  • +
  • Alejandra
  • +
  • Marjolaine
  • +
+

Apologies:

+
    +
  • Alex de Maria (ESRF)
  • +
  • Andy Goetz (ESRF)
  • +
  • Kevin
  • +
  • Malik
  • +
  • Gabriel Preuß
  • +
+

Site Updates

+

ESRF (Marjolaine):

+

Busy with 3-days visit from DLS people on Thursday

+
    +
  • Spoke a lot about data management
  • +
+

Alex spoke at ispyb collab meeting about putting their data into ICAT DB +Working on generic sample tracking for all beamlines (merging ISPyB and ICAT sample tracking) +Had corrupted Etherpad files, have removed from frontend and placed it on standby (deployed, but hidden from users)

+

HZB (Rolf):

+

Cyber attack two weeks ago, "everything is down" (including email)

+
    +
  • Lots of Windows PCs have been infected, encrypting files
  • +
  • No known instances of Linux machines being affected - confident about the data infrastructure +
      +
    • But no way to check
    • +
    +
  • +
  • Forensic experts are currently investigation, rumoured to be a matter of weeks before bringing things back
  • +
+

Would be interested in meeting re: logbooks

+

ALBA (Nicolas)

+

In process of implementing ICAT on beamline +Desigining the metadata that should be uploaded to ICAT +Also exploring the logbook (will need ICAT+ API)

+

Sirius (Allan)

+

Not too much to report +Deciding on data format for tomographic beamlines (already have it for other domain) +Then will begin ingest, play around with project and try to understand the components +Want to test:

+
    +
  • Kubernetes (hope to have feedback by next meeting) - looking at ALBA's solution
  • +
+

ISIS

+

Don't think Will Taylor has been able to work on this recently

+

DLS

+

Effort migrating tape archive from castor to CTA +Pre-prod installation for Payara6

+
    +
  • Alan has been making releases for this
  • +
+

ICAT 6 / Payara 6

+
    +
  • Want to encourage adoption of Payara6 (for security concerns and to avoid having to support multiple versions) +
      +
    • HZB: soonish
    • +
    • ESRF: no plan yet, TBD
    • +
    • Sirius: using 5
    • +
    • ALBA: don't know
    • +
    +
  • +
  • Deadline for moving? TBD via mailing list or in future meeting
  • +
+

Component Updates

+

python-icat

+

More or less ready for 1.1 release:

+
    +
  • Provides an IngestReader, which was implemented in HZB specific code before and is now moved into main python-icat codebase
  • +
  • Few minor fixes
  • +
+

Q: Do we want a snapshot, or release outright (do not expect compatibility issues)?

+
    +
  • DG-API pins the version, so we can test afterwards
  • +
  • Direct release is fine
  • +
+

Expect tomorrow or next week

+

Logbooks (timestamped version)

+

Interest from multiple facilities +HZB working on making it suitable for multiple facilities

+
    +
  • Ideally want to push changes upstream to ESRF +
      +
    • Need to tweak things which are "hardcoded" to ESRF logic, this is the main effort currently, making them configurable
    • +
    +
  • +
  • Using the DataHub verson, not the standalone version
  • +
+

ESRF working on the DataPortal version too, one item of the plan is to make it standalone version (not clear when)

+

Notebooks (Etherpad version)

+

STFC student has been adapting the permissions and work on endpoint, use DG-API or speak with ICAT server. +Concerns of the corruptions of pads, under investigation. +Other concern is suitability of Etherpad due to the lack of updates. There has been some activitiy in the repository. +There are some alternatives:

+ +

Permissions would be configurable. +ESRF - they haven't had time to investigate a lot but scientists complain because when they entered images or tables, it wasn't working.

+

Upload

+

Sample tracking

+

Question from Allan - information per sample might be different for each group wanting to implement sample tracking, is it better to implement a standalone solution?

+
    +
  • ESRF have ICAT(+) (for all beamlines) and ispyb (for MX) and are trying to merge these
  • +
  • Have a configuration (processing plan) for each beamline
  • +
  • Interface retrieves config and displays the relevant column
  • +
  • Generic (configurable) solution
  • +
+

Currently collating the information from the three interested groups, will reach out in the future.

+

AOB

+

Availability for July/August meetings?

+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2023-meetings/20230727-meeting/index.html b/collaboration/communication/monthly-meetings/2023-meetings/20230727-meeting/index.html new file mode 100644 index 000000000..f2f30b938 --- /dev/null +++ b/collaboration/communication/monthly-meetings/2023-meetings/20230727-meeting/index.html @@ -0,0 +1,220 @@ +ICAT Collaboration Meeting - 27th July 2023 | ICAT Project

ICAT Project

Search

ICAT Collaboration Meeting - 27th July 2023

Attendees:

+
    +
  • Patrick
  • +
  • Louise
  • +
  • Gabriel
  • +
  • Rolf
  • +
  • Allan
  • +
  • Alexander
  • +
  • Alex dM
  • +
  • Marjolaine
  • +
  • Rodrigo
  • +
+

Apologies:

+
    +
  • Chris Prosser
  • +
  • Alejandra
  • +
  • Kevin
  • +
+

Site Updates

+

ESRF (Alex):

+

Working quite a lot on MX

+
    +
  • especially UI
  • +
  • Some beamlines/techniques want to view by sample - how can differnt views be achieved generically
  • +
+

Changing how the folders work

+
    +
  • More special folders for Datasets +
      +
    • like the /gallery folder for thumbnails
    • +
    +
  • +
  • /online: not archived, always available
  • +
  • /novacap (? - might have misheard): files aren't achived - like temp files +
      +
    • ingestor doesn't create Datasets
    • +
    +
  • +
  • Rolf: callback in the IDS can control what is archived (or not) +
      +
    • Can define criteria in plugin
    • +
    • Alex: 90 days after experiment, everything is lost
    • +
    • Achieving always online by moving files to different location - issue is how to tell ICAT the files have moved +
        +
      • Rolf: I can help with this - will catch-up offline
      • +
      +
    • +
    +
  • +
+

HZB (Rolf):

+

ICAT server still down following incident +Cannot develop on ICAT servers +More time for developing ICAT components

+

ALBA (Rodrigo)

+

Deployed infrastructure using K8s in production +Finsished testing the ingestor with a new beamline - still a work in progress

+

Sirius (Allan)

+

No updates +ICAT still in dev mode +Working on k8s infrastructure +Hope to have it ready end of August +Starting to deploy ICAT and other systems +Studying source code, trying to understand the project +In about a week, will be ready to discuss sample tracking

+
    +
  • Rolf: we can discuss in AOB
  • +
+

ISIS (Louise)

+

No changes (Will Taylor hasn't had enough time due to other commitments)

+

DLS (Louise)

+

Recently updated two major versions (4.11.2 -> 6)

+
    +
  • Skipped ICAT 5
  • +
  • Went fine (on the day)
  • +
+

Noticed performance issues with the DB (Oracle)

+
    +
  • Possibly due to changes in the EcpliseLink driver, using different indices
  • +
  • More difficult to diagnose as Kevin is currently on leave
  • +
+

Component Updates

+

icat.server

+

miredot documentation is missing

+
    +
  • Rolf has created an issue
  • +
  • probably an issue with the plugin
  • +
+

With ICAT 5 had schema upgrade - only cared about easy changes

+
    +
  • Still have pending proposals +
      +
    • Might want to create new proposal for a hidden field on Datafiles/Datasets for Diamond's DOI use case
    • +
    +
  • +
  • In particular, relationship between sample and investigation
  • +
+

ids.server

+

Had a look at long time pending issues/pull requests this week +Ready for a 1.12.1 release

+
    +
  • changes are relatively minor
  • +
  • Only thing of interest to others is some dependencies updated
  • +
  • Rolf needs his mvn credentials reset - Louise will mention this to Matt Richards who manages the relevant machine
  • +
+

Rolf asked Alan to review a PR with a fix to the tests +Rolf: Payara 6 release is pretty much ready (in his opinion), Alan to create a PR and this can be ids.server v2 +Rolf: is anybody using fileChecker or getLink call? Want to deprecate in 2.0.0 release

+
    +
  • Louise: we'd have to check with ISIS
  • +
  • Rolf: important to know if ids.r2dfoo is using it
  • +
  • Functionality is important, but don't think it belongs in IDS +
      +
    • Should just be a CRON job
    • +
    +
  • +
+

Still plan to refactor major parts of the code aiming for a 3.0.0 release

+
    +
  • Allows deprecation of old features in 2.0.0
  • +
+

authn.oidc & icat.oaipmh

+

Small changes pending to release for Payara5 +Also a branch for Payara6

+
    +
  • Release as version 2.0.0
  • +
+

Create PRs for both of these

+

DataGateway / icat-doi-api

+

Demo-ed DOI minting for user defined DataPublications

+
    +
  • Generally positive
  • +
  • Raised additional requirements
  • +
+

DataHub

+

No news

+

AOB

+

ICAT schema changes

+

ICAT 5 had schema upgrades

+
    +
  • only added "easy" schema changes
  • +
+

Still have "harder" schema change proposals

+
    +
  • e.g. sample-investigation link
  • +
  • Rolf: need to organise more meetings to discuss these
  • +
  • Maybe in fall/autumn
  • +
+

Other meetings

+

Sample tracking

+

Allan wants to have discussions with users/beamlines before this meeting

+
    +
  • Information from beamlines might be too different from each other for general solution? +
      +
    • 4 different beamlines
    • +
    • Doubts over whether different info could be accomodated
    • +
    +
  • +
  • Current ICAT sample tracking is very generic +
      +
    • Presumably this is DataHub
    • +
    • Users want more specialised ones
    • +
    • Is it possible to have a interface that could accomodate this? Or should Sirius implement their own, or if others are interested then it could be a community effort +
        +
      • Rolf plans to setup a facility sample DB next year - alongside rather than integrated into ICAT (at least initially)
      • +
      • Open to dedicated meeting on this
      • +
      +
    • +
    +
  • +
+

ESRF have system close to ICAT but not in ICAT

+
    +
  • Sample tracking is a wide term: +
      +
    • What is the sample
    • +
    • Experiment plan +
        +
      • Temperature
      • +
      • Vibration %
      • +
      • Unit cell
      • +
      • PBD
      • +
      +
    • +
    • Also want plan for processing - downloaded and run automatically
    • +
    • Don't care where it is on site, but on the synchrotron
    • +
    +
  • +
+

Have dedicated meeting

+
    +
  • Allan to organise/set up a doodle poll
  • +
+

Logbooks

+
    +
  • Rolf is going to organise +
      +
    • hasn't been done yet as Markus, who in HZB is responsible for this, is on leave
    • +
    +
  • +
  • In the next couple of weeks, Rolf will send doodle poll
  • +
  • What kind of format do we want? e.g. how long? +
      +
    • Alex: if people are presenting things: half a day, if just discussion, 1-1.5hr?
    • +
    • Rolf: interested in the extraction of logbook from DataHub to it's own microservice/microfrontend
    • +
    +
  • +
  • Rolf: will plan for 3 hours
  • +
  • Target a meeting in September
  • +
+

Next Collaboration Meeting

+

Potential for availability issues in late August (e.g. Rolf, STFC has bank holidays that week) +Organise changes by email if needed

+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/2023-meetings/20230831-meeting/index.html b/collaboration/communication/monthly-meetings/2023-meetings/20230831-meeting/index.html new file mode 100644 index 000000000..fa87f227f --- /dev/null +++ b/collaboration/communication/monthly-meetings/2023-meetings/20230831-meeting/index.html @@ -0,0 +1,192 @@ + | ICAT Project

ICAT Project

Search

ICAT Collaboration Meeting 31st August 2023

+

Attendees

+
    +
  • Gabriel
  • +
  • Allan
  • +
  • Kirsty
  • +
  • Alejandra
  • +
  • Alex
  • +
  • Patrick
  • +
  • Andy
  • +
  • Marjolaine
  • +
  • Viktor
  • +
  • Christopher
  • +
+

Agenda

+
    +
  1. Introductions (if needed)
  2. +
  3. ICALEPCS paper
  4. +
  5. Extra meetings being arranged + +
  6. +
  7. Java version discussion
  8. +
  9. Usual components and site updates
  10. +
  11. AOB
  12. +
+

Introductions

+

Chris for Allan/Gabriel

+

ICALEPS paper

+
    +
  • Deadline early October
  • +
  • Andy plans to create paper on Overleaf
  • +
  • Suggestions for draft sections/topics +
      +
    • Summary of sites (facilities) and their status
    • +
    +
  • +
  • ICALEPS link:
  • +
  • Intention is to send update on the lastest ICAT developments
  • +
  • Andy will be chairing conference, only author planned to attend the conference
  • +
  • Meeting in a week to confirm sections +
      +
    • Organise now? Next Thursday same time? +
        +
      • Alejandra can't make it but not everyone needs to be there - meet anyway
      • +
      +
    • +
    +
  • +
+

Extra meetings

+

E-logbooks

+

https://terminplaner6.dfn.de/de/p/50ab9986e7d3334ee89bc3c088352098-352747

+
    +
  • Looking like 14th of September is most popular date?
  • +
  • Wait until Rolf is back to organise the meeting
  • +
  • Wait for feedback from HZB e-logbook contributor (Marcus?) - final decision on date next week +
      +
    • Probably back from the 12th
    • +
    +
  • +
  • Andy: Interest from other communities - is this an internal meeeting? Yes
  • +
+

Sample tracking

+

https://doodle.com/meeting/participate/id/bqZ4v8Gd +Allan to orgnaise. Deadline for filling form for next Monday - send reminder then.

+
    +
  • Sirius has a problem with some beamline which want sample tracking (SAXS, powder diffraction and tomography beamlines)
  • +
  • ESRF have a WIP tracking solution which joins the ispyb and ICAT Samples
  • +
  • Good time for discussion for if (Sirius) can collaborate on this
  • +
  • Andy: see no problem with supporting multiple techniques +
      +
    • Allan: is this feasible? does it make sense to have information for the different domains in the same interface
    • +
    • Alex: when the samples are sent to the synchotron, we want to know where the sample is and also describe it. Parameters are determined by the acquisition panel - (temperate etc.) also processing parameters (what has been done). This is more than just "sample tracking" in terms of location. +
        +
      • Allan: Sirius has two beamlines that do want to know T and other physical parameters. Special case at Sirius for safety of the sample - user needs to fill in a form to assure the safety of the sample at Sirius. Want a way of extracting this information. What is the pipeline from user sending the sample to then sending the form - how are other synchotrons doing this?
      • +
      • Alex: Have safety concerns as well. Have a diagram showing the process.
      • +
      +
    • +
    +
  • +
  • Alejandra: we are also interested in how people are doing this and want to know if the description of samples can be standardised and shared. +
      +
    • Kirsty: there is interest/progress along these lines at DLS as well (but Kirsty is not the person to ask about it)
    • +
    +
  • +
+

Java versions

+

https://www.oracle.com/java/technologies/java-se-support-roadmap.html

+
    +
  • Might be worth waiting for Rolf as he raised this.
  • +
  • Discussion ongoing via the mailing list
  • +
  • Pros/cons of running 11/17 in production? + +
  • +
+

Site updates

+

ESRF: Alex

+
    +
  • Still working on supporting crystallography with ICAT
  • +
  • Goal is to have one beamline simultaneously on ICAT and ispyb
  • +
  • Support for running workflows and the results ending up in ICAT + +
  • +
  • Marjolaine is working on a new access method to the data (have IDS and MongoDB for small files) but want larger file support - "/online" +
      +
    • Will be archived but also accessible 10 -> 100 MB in size
    • +
    • "online" directory treated differently than "gallery" for example
    • +
    +
  • +
+

HZB: Gabriel

+
    +
  • No real updates, still down from the cyber attack, no realistic timeline for when things will be running again - open time frame
  • +
  • Rolf has announced snapshot releases for several minor components.
  • +
  • ANdy: security of ICAT being considered? +
      +
    • ICAT has nothing to do with the cyber attack. To prevent fututre attacks the network infrastructure of the institute external facing tools are being discussed. ICAT will not be online until this is resolved.
    • +
    +
  • +
+

ALBA: No-one present

+

Sirius: Allan

+
    +
  • Almost finished K8s infrastructure but no update to give
  • +
  • In November want to have ICAT running in production - good time as a nation attempting data standardisation - two techniques
  • +
  • Andy: installing ICAT+? Docker compose is the thing working for them, working through the icatproject documentation +
      +
    • Sesame have ICAT running
    • +
    +
  • +
+

ISIS: No-one present

+

DLS: Kirsty and Chris

+
    +
  • Yesterday moved ingest to K8s - "baby steps"
  • +
  • Hopeful improve stability and make more improvements in the future
  • +
  • Have been running ICAT6 (Payara6 etc.) for a month +
      +
    • Had minor performance issues with DB, created new indices to improve READs
    • +
    +
  • +
  • Also upgrading servers for ingesting to tape to improve throughput 60TB a day currently +
      +
    • Want to duplicate ingest path to double the throughput
    • +
    +
  • +
+

Component updates

+

Snapshot releases mentioned in email from Rolf

+

icat.server

+

ids.server

+

authn.oidc & icat.oaipmh

+

DataGateway

+

icat-doi-api

+

DataHub

+

AOB

+

Gabriel wants to join mailing list - but this requires linking the business and personal accounts

+ +

Some emails to the mailing list get flagged as spam/moderation

+
    +
  • Requires AGB to manually approve emails which get caught (unclear what triggers this)
  • +
+

Next meeting on the 28th of September. Alejandra unable to chair.

+ + \ No newline at end of file diff --git a/collaboration/communication/monthly-meetings/index.html b/collaboration/communication/monthly-meetings/index.html new file mode 100644 index 000000000..acae8cdab --- /dev/null +++ b/collaboration/communication/monthly-meetings/index.html @@ -0,0 +1,37 @@ +Monthly Meetings | ICAT Project

ICAT Project

Search

Monthly Meetings

These are normally held on the fourth Thursday of the month at 15:00 UK +time.

+

We  hold meetings using Google Hangout technology. This is supported +well on Chrome on Windows and on some releases of Linux.  It is also +well supported on Android and on Apple devices. To set it up you should:

+
    +
  • Create a Google account if you don't already have one -- this does +not require that you have a gmail account. +(https://accounts.google.com/signupwithoutgmail)
  • +
  • Tell dr.s.m.fisher@gmail.com one of the email addresses associated +with your Google account and ask to be added to the ICAT hangout.
  • +
  • If you are logged in to your Google account then you should receive +a message when the meeting starts, if you are late you should be +able to find the meeting and connect to it.
  • +
+

You might be asked to install a plugin when you join a  hangout for the +first time. More information can be found +at http://www.google.com/hangouts/ If in doubt please +contact dr.s.m.fisher@gmail.com

+

Records of the meetings are grouped by year:

+
+ + \ No newline at end of file diff --git a/collaboration/communication/schema/index.html b/collaboration/communication/schema/index.html new file mode 100644 index 000000000..bb795a191 --- /dev/null +++ b/collaboration/communication/schema/index.html @@ -0,0 +1,26 @@ +Schema Discussion | ICAT Project

ICAT Project

Search

Schema Discussion

+ + \ No newline at end of file diff --git a/collaboration/communication/steering-group/index.html b/collaboration/communication/steering-group/index.html new file mode 100644 index 000000000..800e24d5f --- /dev/null +++ b/collaboration/communication/steering-group/index.html @@ -0,0 +1,37 @@ +Steering Group | ICAT Project

ICAT Project

Search

Steering Group

The ICAT Steering Group provides a forum for representatives of the +stakeholders in ICAT to steer and advise on the priorities and the +direction of the ICAT suite of data management components. ICAT +developers already meet regularly to discuss progress, under the +coordination of the manager of the ICAT project. However, as +an open-source collaboration, it requires oversight and guidance from +stakeholders.

+

A mailing list for +the group is available; anyone can post to this list and anyone can read +it however membership is only the steering group.

+

The Terms of Reference are available as is a proposed update

+

List of past meetings:

+ +

Current membership is:

+

Alun Ashton (DLS)
+Rob Clarke (CLF)
+Steve Fisher (ICAT Project Manager -- but no vote)
+Andy Gotz (ESRF and chair)
+Tom Griffin (ISIS)
+Catherine Jones(Secretary)
+Rolf Krahl (HZB)
+Brian Matthews (STFC)
+Jean-Francois Perrin (ILL)
+Milan Prica (ELETTRA)
+Shelly Ren (ORNL)

+ + \ No newline at end of file diff --git a/collaboration/communication/steering-group/meeting-02/index.html b/collaboration/communication/steering-group/meeting-02/index.html new file mode 100644 index 000000000..c50e904be --- /dev/null +++ b/collaboration/communication/steering-group/meeting-02/index.html @@ -0,0 +1,217 @@ +Meeting 02 | ICAT Project

ICAT Project

Search

Meeting 02

ICAT Steering Committee Meeting

+

Minutes – 1st April 2015 – 14:00 – DLS – UK

+

0. Attendance

+
    +
  • Brian Matthews (BM), STFC, Scientific Computing
  • +
  • Tom Griffin (TG), STFC, Scientific Computing
  • +
  • Andy Goetz (AG), ESRF
  • +
  • Shelly Ren (SR), SNS
  • +
  • Alun Ashton (AA), DLS
  • +
  • Kevin Knowles (KK), STFC, ISIS
  • +
  • Alistair Mills (AM), STFC, Scientific Computing
  • +
  • Steve Fisher (SF), STFC, Scientific Computing
  • +
+

1. Review of actions from meeting in May 2014

+
    +
  • Write minutes – Alistair.
  • +
  • September meeting – did not happen.
  • +
  • Mailing list – a list has been created.
  • +
  • Discuss chairmanship with Andy – Done (By JFP).
  • +
  • Survey of requirements for TopCAT – Wayne – Done.
  • +
  • Roadmap feedback – Received.
  • +
+

It was agreed that the minutes of the Steering Committee meeting should +be open to all. They will be posted on the icatproject.org website and a +note sent to the ICAT mailing list.

+

2. Election of new SC secretary

+
    +
  • Alistair Mills is retiring from STFC and hence the secretary role.
  • +
  • Tom was proposed as the new secretary (Andy, seconded by Brian) and +carried nem con.
  • +
+

3. Review of SC terms of reference

+
    +
  • The terms of reference document will be added to the icatproject.org +website (Action 2.1)
  • +
  • Andy raised that the voting criteria are not stated. It was agreed +this should be simple majority, with the chair having the casting +vote in the event of a tie. (Action 2.2)
  • +
  • Alun asked when/if should members be removed for the Steering +committee e.g. ELETTRA. It was agreed that active involvement is +key, but this was not clearly defined. Any partner not active for 1 +year will be reviewed by the steering committee.
  • +
  • Andy to talk to Milan/ELETTRA to see if they wish to continue. +(Action 2.3)
  • +
+

4. Review of membership

+
    +
  • The status of CLF vs LSF (a division in an STFC department) was +discussed. Brian is to check with CLF/LSF that they are represented +by Rob Clarke. (Action 2.4)
  • +
  • HZB – data collection will continue at the neutron source until 2019. +Rolf is now permanent. Andy to invite HZB to join the steering committee (Action 2.5)
  • +
  • PSI – The committee received a request from Leonardo Sala PSI +requesting to join the SC with Jan Solca as representative. PSI have +not attended monthly meetings
  • +
  • Andy to email Jan/PSI welcoming them in principle – when they +become active, including monthly meetings. This should be extended +to all interested parties (Action 2.6)
  • +
  • A general note to be written on membership of this committee (Action +2.7)
  • +
+

5. Googlecode is shutting down – where should ICAT move to?

+
    +
  • It was unanimously agreed to move to GitHub.
  • +
  • There was a short discussion of push vs pull requests.
  • +
  • The licence's ICAT is released under was queried. It is currently +Apache v2 and BSD. There was as short discussion on whether or not +all files have the licence in them.
  • +
  • Action on Steve – move all projects to Apache v2 licence. (2.8)
  • +
+

6. Roadmap update and endorsement

+
    +
  • as presented by Steve at the developer meeting.
  • +
  • Steve to update the roadmap and dates, and circulate (Action 2.9)
  • +
  • GlobusOnline was discussed and confirmed as a key requirement for +large data transfer by Diamond and ORNL.
  • +
  • Shelly queried using external authorisation mechanisms (LDAP). +Shelly to write a specification (Action 2.10)
  • +
+

7. Website future contributions

+
    +
  • Andy reported that things are missing or difficult to find on the +website. He described TANGO's positive experience of getting a +communications person involved
  • +
  • Tom to ask for help from STFC comms staff (Action 2.11)
  • +
+

8. Review of ICAT resources

+
    +
  • STFC/SCD provides the core development effort and supports STFC +facilities : total of ~3FTEs working on ICAT related projects, +though this includes projects to meet internal requirements for the +facilities such as most CLF work.
  • +
  • ISIS: Condie is split 50% on the ISIS pipeline , 50% on TopCATv2.
  • +
  • ESRF: Christophe has provided the ICATManager and Nexus explorer. A +permanent post would have some time to contribute to 'core' ICAT. +ICATManager is to be moved to GitHub (under icatproject).
  • +
  • HZB: Rolf has contributed PythonICAT.
  • +
  • The status of Mantid was queried. It was confirmed to be continuing +using ICAT.
  • +
  • Dawn – ICAT component unsupported and not continuing.
  • +
+

9. Boundaries of ICAT

+
    +
  • The definition of the official ICAT was discussed – where does +contrib begin, when does a component become 'official'. (e.g. +PythonICAT, ICATManager)
  • +
  • Shelly queried if anyone used PythonICAT in production.
  • +
+

10. AOB

+
    +
  • Brian queried the status of Wildfly support. Answer: ICAT will +support WildFly and GlassFish later this year. Development and +testing will focus on WildFly as the default platform.
  • +
  • Brian thanked to Alistair Mill for setting up the steering committee +and all his efforts on ICAT.
  • +
  • Alistair reiterated the issues people have with the website and +documentation, and getting started when it is installed – in his +view this is the main issue ICAT needs to solve. Andy said this not +the only problem. The gap between what they have and what ICAT does +is too big – no metadata and no usecase.
  • +
  • Shelly said it would help people getting started to provide a +generic Nexus ingestor.
  • +
+

Actions:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
No.Sec.DetailResp.
2.13Add the steering committee terms of reference to the icatproject websiteTG
2.23Update the ToR to include a section on votingTG
2.34Ask ELETTRA if they wish to continue on the Steering committeeAG
2.44Check with CLF/LSF that they are correctly representedBM
2.54Invite HZB to join the steering committeeAG
2.64Contact PSI, DESY, ALBA, MAXLab and ESS about their involvement in the project and committeeAG
2.74Write a general note on criteria for membership of the steering committeeTG
2.85Move all ICAT projects to Apache v2 licence and GitHubSF
2.96Update the roadmap and dates, and circulateSF
2.106Write a specification of external authorization serviceSR
2.117Ask communications for help to review web siteTG
2.127.Arrange the next meeting for 6 months time (tele/video-conference)TG
+

Next meeting: 6 months – TC/VC

+

AG: ICAT at the next NOBUGS: Autumn 2016 at ESS

+ + \ No newline at end of file diff --git a/collaboration/communication/steering-group/meeting-03/index.html b/collaboration/communication/steering-group/meeting-03/index.html new file mode 100644 index 000000000..2f76ad792 --- /dev/null +++ b/collaboration/communication/steering-group/meeting-03/index.html @@ -0,0 +1,186 @@ +Meeting 03 | ICAT Project

ICAT Project

Search

Meeting 03

ICAT Steering Group Meeting #3

+

9th December 2015 15:00GMT
+Video/Phone meeting (Bluejeans)

+

Attendance

+
    +
  • Steve Fisher (SF), STFC, Scientific Computing
  • +
  • Tom Griffin (TG), STFC, Scientific Computing
  • +
  • Andy Goetz (AG), ESRF
  • +
  • Milan Prica (MP), ELETTRA
  • +
  • Shelly Ren (SR), SNS
  • +
  • Alun Ashton (AA), Diamond
  • +
+

Apologies

+
    +
  • Rolf Krahl, HZB
  • +
  • Brian Matthews, STFC, Scientific Computing
  • +
+

1. Welcome +AG welcomed those present. Apologies were received from Rolf Krahl and +Brian Matthews.

+

2. Actions of the previous meeting

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
No.DetailResp.Status
2.1  Add the steering committee terms of reference to the icatproject website TG Done
2.2Update the ToR to include a section on votingTGNot Done
2.3Ask ELETTRA if they wish to continue on the Steering committeeAGDone- Milan is ELETTRA's representive
2.4Check with CLF/LSF that they are correctly representedBMTG to discuss with BM and CLF
2.5Invite HZB to join the steering committeeAGComplete – Rolf is HZB's representative
2.6Contact PSI, DESY, ALBA, MAXLab and ESS about their involvement in the project and committeeAGDone.
2.7Write a general note on criteria for membership of the steering committeeTGNot done
2.8Move all ICAT projects to Apache v2 licence and GitHubSFDone
2.9Update the roadmap and dates, and circulateSFDone
2.10Write a specification of external authorization serviceSRNot done
2.11Ask communications for help to review web siteTGSCD has recruited an impact manager. TG to discuss with them
2.12Arrange the next meeting for 6 months time (tele/video-conference)TGDone
+

3. Review of membership
+No business

+

4. Status of Components
+See Steve's slides
+Shelly asked about Dashboard – management information
+Shelly asked about Glassfish and Wildfly – answer – both will be +supported.

+

5. Roadmap
+See slides
+Move to Wildfly/hibernate testing revealed issues in the existing code.

+

Facility requests/comments

+

Shelly: SNS is working on automatic roll-out via Puppet to help ease +rollout. Will be shared via GitHub.
+Tom – We should consider the role of Docker in releasing and running +ICAT.
+Andy – data policy will be rolled out at ESRF; Request to embed DOI +issuing in ICAT/TopCAT.
+Shelly – documentation is a major issue;
+Andy – suggested a  workshop could spend 1/2 day fixing documentation;

+

Globus: Tom explained Globus; Andy reported that CERN move all data with +FTS3 and it could be integrated in ICAT, it is percieved to be even +easier to use than Globus.

+

Cloud/Docker – it is possible to build whole VM, but fairly +uninteresting. It is better to package individual components – could +lead to a more scalable system.
+Shelly – install has been too fragile and unclear errors in the past.

+

7. Website
+ICATProject.org had been 'hacked' The root cause was probably simply a +weak password. Steve has since hardened  security significantly.

+

8. Review of ICAT resources

+

No business

+

9. AOB.

+

No business

+

10. Next meeting/Developer meeting
+It was agreed that the next SC meeting should be face-to-face and + Colocated with NoBUGS2016 in Copenhagen.

+

A developer meeting will be held at the same time.

+

New Actions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
No.DetailResp.
2.2Update the ToR to include a section on votingTG
2.4Check with CLF/LSF that they are correctly representedTG & BM
2.7Write a general note on criteria for membership of the steering committeeTG
2.10Write a specification of external authorization serviceSR
2.11Ask communications for help to review web siteTG
+ + \ No newline at end of file diff --git a/collaboration/communication/steering-group/meeting-04/index.html b/collaboration/communication/steering-group/meeting-04/index.html new file mode 100644 index 000000000..f39c67504 --- /dev/null +++ b/collaboration/communication/steering-group/meeting-04/index.html @@ -0,0 +1,215 @@ +Meeting 04 | ICAT Project

ICAT Project

Search

Meeting 04

ICAT Steering Group Meeting #4

+

20th October 2016 17:30CET
+The Avenue Hotel, Copenhagen

+

Attendance

+
    +
  • Steve Fisher (SF), STFC, Scientific Computing
  • +
  • Tom Griffin (TG), STFC, ISIS
  • +
  • Andy Gotz (AG), ESRF (Chair)
  • +
  • Milan Prica (MP), ELETTRA
  • +
  • Shelly Ren (SR), SNS
  • +
  • Silvia Da Graca Ramos (SDGR), Diamond
  • +
  • Rolf Krahl (RK), HZB
  • +
  • Brian Matthews (BM), STFC, Scientific Computing
  • +
  • Ming Tang (MT), CSNS
  • +
  • Kevin Phipps (KP), STFC, Scientific Computing (Secretary)
  • +
+

Apologies

+
    +
  • Catherine Jones, STFC, Scientific Computing
  • +
+

1. Welcome

+

AG welcomed those present, including a new member Ming Tang from CSNS, +the China Spallation Neutron Source.

+

2. Election of new SC secretary

+

Catherine Jones will be the new secretary. Kevin Phipps is standing in +for this meeting in Catherine's absence. No election was necessary as +STFC provides the secretary.

+

3. Actions of the previous meeting

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
No.DetailResp.StatusNotes
2.2Update the ToR to include a section on votingTGDoneTG has added something corresponding to what was discussed
2.4Check with CLF/LSF that they are correctly representedBMNot doneBM will resolve this
2.7Write a general note on criteria for membership of the steering committeeTGDone
2.10Write a specification of external authorization serviceSRDoneSR believes she now has a way to do this using the new rules system
2.11Ask communications for help to review web siteTGDoneTG got feedback along the lines of the site needs a major redesign. The photo of ICAT people on the front page should be a screenshot of an application with the photo moved to under Communication.
+

4. Review of membership and potential new members to invite

+

AG has contacted Jean-Francois at ILL and believes that he still wants +to remain on the steering group for now.
+BM has changed roles and will let the steering group know if he is going +to remain a member. (ACTION)
+It was clarified that the secretary should not have a vote and thought +that this should be explicit in the TOR. (ACTION)
+AG raised the issue that it may be necessary to limit the membership of +the steering group if more facilities start using ICAT.

+

5. Review of move of ICAT code to GitHub and workflow

+

Steve has completed the move to Github. This has been a success.
+TG asked how components move from Contrib to Core. AG suggested that the +steering group makes this decision. It was also suggested that it should +be a standard agenda item for the steering group to review Contrib and +Core.
+SR asked why the TopCAT DOI component is not in Core and SF said that it +is too STFC specific at the moment.
+It was suggested that the criteria for moving a component into Core +should be that it is written to be usable by multiple sites and is +actively being maintained.
+BM suggested moving some of the Contribs to a documentation area.

+

6. Review website + documentation

+

There was a lot of discussion about this. The following is a summary of +the main discussion points:
+All of the facilities should provide a summary page of how they are +using ICAT. A link to their TopCAT page would be good as well. (ACTION)
+AG would like documentation to be more obvious from a higher level +rather than having to drill down into components.
+The TopCAT videos produced by Tom Gowland should be linked from the +website. (ACTION)
+The current release link should go straight to the current release +rather than displaying a long list of releases with the most recent at +the bottom.
+There was a suggestion to group related components together eg. IJP, +authenticators.
+MP suggested that a short description should be displayed next to each +component.
+It was felt that the list of current releases is too long and +potentially off-putting/daunting to new users. Maybe a smaller subset of +essential components should be presented by default.
+AG and SR offered to give feedback to SF on the website (ACTION).
+AG and RK suggested using something like Sphinx for generating +documentation and AG showed the Django website as an example of a good +website.
+It was recognised that there is potentially a lot of work involved to +redo the icatproject website. SF will wait for comments before doing +anything.

+

7. Review of ICAT resources

+

RK said he might look into writing an OAI-PMH interface for ICAT.
+RK will put in a pull request to solve the IDS locking problem which he +discussed separately with SF.
+CSNS would like to add some data analysis capabilities to TopCAT. This +should be able to be done via plugins and MT said that they should be +able to share this.
+ELETTRA are hoping to move their code to open source but cannot commit +to anything yet. Their IT department wants to move everything (Tango +devices, GUIs, acquisition frameworks etc.) to GitHub with an open +source license but it is not official yet and will require management +approval.
+ISIS have a sandwich student (Tom Gowland) working roughly half time on +core ISIS work and half time on general ICAT components.
+SR hopes that Peter Parker is able to contribute to general ICAT +components once he completes what he is currently working on.
+AG offered to provide some examples of metadata that can be stored in +ICAT to make available on the website (ACTION).

+

8. Roadmap

+

SF presented the roadmap which will be published on the website.

+

Steve has ideas for possible changes that could be made ICAT 5 such as +replacing the concept of Dataset with something else. This would all +need to be discussed and agreed because of the potential implications +for facilities already using ICAT.

+

RK pointed out that dropping the SOAP interface to ICAT would mean +dropping python-icat. SF said that maintaining the SOAP interface is not +much of an overhead and where possible ICAT 4 will provide both SOAP and +REST interfaces.

+

RK asked to have the ability to translate/map parameter names added to +TopCAT in a way that is more convenient. TG wants to see more general +improvements to parameter searching in TopCAT.

+

There was discussion as to whether UTF-8 is sufficient to support +Chinese and Japanese characters. The outcome was unclear.

+

9. AOB.

+

No business

+

10. Next meeting/Developer meeting

+

The next steering group meeting will be a virtual meeting in 6 months +time.

+

New Actions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
No.DetailResp.
2.4Check with CLF/LSF that they are correctly representedBM
4.1Let the steering group know if he is going to remain a member.BM
4.2Update the TOR to make it explicit that the steering group secretary does not have a vote??
4.3Provide a summary page for the icatproject website preferably containing a link to TopCATAG, SDGR, SR, MT
4.4Provide a link to the TopCAT videos from icatprojectSF
4.5Provide feedback to SF on how to improve the websiteAG, SR
4.6Provide some examples of metadata that can be stored in ICAT to make available on the websiteAG
+ + \ No newline at end of file diff --git a/collaboration/communication/steering-group/meeting-05/index.html b/collaboration/communication/steering-group/meeting-05/index.html new file mode 100644 index 000000000..6c6ec6b1e --- /dev/null +++ b/collaboration/communication/steering-group/meeting-05/index.html @@ -0,0 +1,332 @@ +Meeting 05 | ICAT Project

ICAT Project

Search

Meeting 05

ICAT Steering Group Meeting #5

+

21st November 2017, 3pm  Rutherford Appleton Lab, STFC

+

Attendance

+
    +
  • Andy Gotz (AG), ESRF (Chair)
  • +
  • Suart Pullinger (SP), STFC, Scientific Computing
  • +
  • Tom Griffin (TG), STFC, ISIS
  • +
  • Shelly Ren (SR), SNS
  • +
  • Rolf Krahl (RK), HZB
  • +
  • Brian Matthews (BM), STFC, Scientific Computing
  • +
  • Alun Ashton  (AA), Diamond
  • +
  • Gordon Brown (GB), STFC, Scientific Computing
  • +
  • Catherine Jones (CJ), STFC, Scientific Computing (Secretary)
  • +
+

Apologies

+
    +
  • Milan Prica (MP), ELETTRA
  • +
+

1. Welcome & Agree agenda

+

AG welcomed those present. The proposed agenda was agreed.

+

2. Minutes of the previous meeting

+

These were agreed. They are available from +/collaboration/communication/steering-group/meeting-04

+

2.1 Review of actions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
No.DetailResp.StatusNotes
2.4Check with CLF/LSF that they are correctly representedBMCompleted They were happy for representation through STFC Facilities Programme Manager (GB)
4.1Let the steering group know if he is going to remain a member.BMCompleted BM stays as a non-voting member to represent corporate memory
4.2Update the TOR to make it explicit that the steering group secretary does not have a voteCMJOngoing CMJ taken this action and will amend ToRs
4.3Provide a summary page for the icatproject website preferably containing a link to TopCATAG, SDGR, SR, MTSuperseded and thus closedWork on new website/documentation means this is no longer relevant
4.4Provide a link to the TopCAT videos from icatprojectSPOngoing Actiontransferred to SP and will be done as part of new website
4.5Provide feedback to SF on how to improve the websiteAG, SRCompletedFeedback being incorporated in new website work
4.6Provide some examples of metadata that can be stored in ICAT to make available on the websiteAGOngoingWill be done as part of new website
+
    +
  1. SC Membership review
  2. +
+

No new members planned.

+
    +
  1. GitHub Repositories review
  2. +
+

The move to GitHub was considered a success and was working well.  There +was a discussion about how to distinguish projects in contrib and core. +It was agreed that projects in core should be used by more than one +site and are actively maintained. Moves from contrib to core shall be +recommended by the developer(s) and approved by the Steering Committee.

+

Active maintenance includes working on high priority bugs and formal +developer workflows.

+

ACTION 5.1: Produce contrib rules/guidelines (SP)

+

ACTION 5.2 Review the settings for projects currently in +Contrib/Official and propose changes (SP & CJ)

+
    +
  1. Component Review
  2. +
+

It was agreed that it is in the interests of the community to have an +active developers collaboration.  For components which are only used & +developed at one site, then they make decisions based on listening to +the community (collaboration meetings). For components that have more +than one contributor, then there needs to be a more formal process with +the SC responsible for any resolution of disagreements.

+

ACTION 5.3 Document the process for collaboration (SP & CJ)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ComponentCommentSteward
AuthenticationAll sites need to implement this for their own needs.
There are example/reference ones in the ICAT project. These are considered to be part of the core ICAT project
STFC – SP
ICAT Server
Including
  • ICAT-Client
  • Lucene
STFC is currently the sole site developing thisSTFC – SP
IDS client, plug-in & serverNoted concerns from Rolf’s boss regarding liability but agreed covered by Apache licenceHZB – RK
Secondary STFC – SP
IJPNoted that this should probably move to contrib following reviewn/a
TopCatESRF keen to collaborate hereSTFC – BR
Secondary ESRF – Alex
+

There was then a discussion about eLog notebooks and the links to ICAT.

+

ACTION 5.4 Report back to SC on investigations into possible tools & +approaches (AG)

+
    +
  1. Website review
  2. +
+

The SC noted the plans SP had put forward for refreshing the website. +Noted that using Markdown means it would be possible to port the revised +website to another provider.

+

Agreed that other sites would have the opportunity to comment once the +site is ready & content moved

+

ACTION 5.5 STFC to ask for feedback once website is ready for launch +(SP)

+
    +
  1. Documentation review
  2. +
+

The SC noted the good start with the Documentathon running +simultaneously with the SC meeting. It was suggested that the monthly +collaboration meeting would be a good place to review progress.

+

It was acknowledged that this is a significant piece of work.

+

It was suggested that there should be more time in the next face to face +meeting for a documentation sprint

+

ACTION 5.6 Consider further documentation sprints on the agenda of +the next meeting (RK & SP)

+
    +
  1. Review of ICAT resources
  2. +
+

AG started the discussion on this topic with a reminder that to survive +we need to grow.

+

ACTION 5.7 Contact the CSNS to re-engage with them (GB)

+

ESRF are able to contribute 1.5 FTE to the development.

+

DLS 1.2 (more operational than development)

+

ISIS 1 FTE (split 50-50 operation/development

+

HRZ 1 FTE

+

STFC 3-4 FTE (although currently there are vacancies following staff +movements)

+

SR noted that there is a steep learning curve for using ICAT and +suggested using Docker for deployment. The issue with the metadata being +collected changing causes issues with using ICAT.

+

There was a discussion about EC requirements to hold data for at least +10 years and to comply with the FAIR principles. AG noted that EOSC is +mainly about data.

+
    +
  1. Roadmap
  2. +
+

Points discussed in the meeting included:

+
    +
  • the observation that the ICAT approach to parameters is not flexible +enough
  • +
  • The schema might benefit from a review, especially around datafiles +in the RDBMS and consideration of scaling issues and new technology
  • +
  • Further investigation of ONCat (see section x) and SCICat
  • +
  • Need to signal high priority of blocking issues that need to be +addressed
  • +
+

It was agreed that SP would consolidate the suggestions made by Steve +Fisher and the general tickets into a new roadmap.

+

ACTION 5.8 Share access to ONCat with the collaboration (SR)

+

ACTION 5.9 Share high priority or blocking issues (via tickets) (All +sites)

+

ACTION 5.10 Establish a new roadmap (SP)

+
    +
  1. New projects
  2. +
+

SR updated the SC on a new project ORNL are working on called ONCat. +They have been working on data management/reduction with the HFIR +(https://neutrons.ornl.gov/hfir ). This has 12 instruments and 30 +years of data. There is a challenge to use ICAT for the metadata as the +approach to parameters is too flat a structure and there is not enough +consistency in parameters between instruments.  The metadata parameters +change between run cycles as well as instruments. It is difficult to get +metadata out of ICAT. They are looking at MongoDB & elasticsearch  and +gained flexibility and performance using this approach & technology and +they have developed ONCAT (Oakridge Neutron Catalogue).  This has an API +and there are several different clients. They have ingested all +experimental data. This enables google-like searches and thumbnail +displays.

+

AG asked if it was going to replace ICAT. SR responded that they are +both running and ONCat is not in production.

+

SR reported that there was also US based work on materials data facility +(U Chicago) and Argonne National Lab ran a hackathon on commonality in +data management.

+

PSI are using similar technology in SCICat for the ESS and Max IV +(scicatproject.org)

+

DLS have additional resource through the INSTRUCT project for +prototyping, for similar requirements as the ICR discussion in the main +meeting.  They have also submitted to SRI and Mark Basham will be +attending the conference/meeting in Japan.

+
    +
  1. AOB.
  2. +
+

RK noted that the next RDA meeting is in Berlin in March.

+
    +
  1. Next meeting
  2. +
+

The next steering group meeting will be in Berlin, colocated with the +RDA meeting and the workshop on Scientific Data Management for Photon +and Neutron Facilities. The workshop will be on 19 and 20 March at HZB, +see [1] for details. RK has scheduled the SC meeting for Tuesday +afternoon after the workshop. (The workshop is planned to end on 20 +March 15:00, a room for the SC from 14:00 -- 17:00.)

+

[1]: +https://www.helmholtz-berlin.de/events/scientific-data-management/

+

Noted that the next NoBugs meeting is in the autumn in the US

+

There is an expectation that sites will send deputies if main +representative not able to attend. AA apologised in advance for not +being able to attend the next meeting

+

ACTION 5.11 Ensure there is remote participation available for the +Berlin SC meeting (RK)

+

New Actions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NoDescriptionResp
5.1Produce contrib rules/guidelinesSP
5.2Review the settings for projects currently in Contrib/Official and propose changesSP & CJ
5.3Document the process for collaborationSP & CJ
5.4Report back to SC on investigations into possible tools & approaches for eLog booksAG
5.5STFC to ask for feedback once website is ready for launchSP
5.6Consider further documentation sprints on the agenda of the next meetingRK & SP
5.7Contact the CSNS to re-engage with themGB
5.8Share access to ONCat with the collaborationSR
5.9Share high priority or blocking issues (via tickets)All sites
5.10Establish a new roadmapSP
5.11Ensure there is remote participation available for the Berlin SC meetingRK
+ + \ No newline at end of file diff --git a/collaboration/communication/steering-group/steering-group-terms-of-reference-proposed-update/index.html b/collaboration/communication/steering-group/steering-group-terms-of-reference-proposed-update/index.html new file mode 100644 index 000000000..453a6267e --- /dev/null +++ b/collaboration/communication/steering-group/steering-group-terms-of-reference-proposed-update/index.html @@ -0,0 +1,103 @@ +STEERING GROUP TERMS OF REFERENCE – PROPOSED UPDATE | ICAT Project

ICAT Project

Search

STEERING GROUP TERMS OF REFERENCE – PROPOSED UPDATE

THIS IS A PROPOSAL FOR AN UPDATE TO THE TERMS OF REFERENCE TO COMPLETE +SC ACTIONS 2.2 AND 2.7

+

The ICAT Steering Committee provides a forum for representatives of the +stakeholders in ICAT to steer and advise on the priorities and the +direction of the ICAT suite of data management components (referred to +as ICAT).    ICAT developers already meet regularly to discuss current +progress, under the coordination of the Project manager of the ICAT +project.  However, as an open-source collaboration, it requires +oversight and guidance from all senior members of stakeholder +organisations involved to ensure that it continues to develop as a +valuable component for data management within facilities +infrastructure.  The Steering Committee will meet more infrequently to +undertake this role.

+

Purpose

+

The Committee exists for the following reasons:

+
    +
  • to advise on the likely usage and requirements for ICAT;
  • +
  • to provide senior management oversight for the work of the ICAT +collaboration partners;
  • +
  • to provide strategic guidance on the development and deployment of +ICAT.
  • +
+

Responsibilities of the ICAT Steering Committee

+

The members of the Committee have the following responsibilities:

+
    +
  • to provide strategic advice to the collaboration;
  • +
  • to protect the interests of the institution which they represent;
  • +
  • to advise on new initiatives and plans which may affect the +development of ICAT;
  • +
  • to advise on major requirements which may affect the development of +ICAT;
  • +
  • to oversee the ICAT development roadmap, including the incorporation +of additional components into ICAT which have been proposed by +developers or users;
  • +
  • to ensure that ICAT components continue to remain aligned to the +aims of the stakeholders, within a common functionality and code +base;
  • +
  • to advise on ownership, licencing of components and +commercialisation opportunities;
  • +
  • to ensure that the institution which they represent provides +appropriate resources to the collaboration.
  • +
+

Membership

+

The Committee has one representative from each the major stakeholders +who are actively involved in developing, deploying and exploiting +ICAT. The Committee will regularly review membership to ensure that +it remains representative of the active users of ICAT, and invite new +members as appropriate.

+

The Project Manager of the ICAT Project should attend meetings in a +non-voting capacity.

+

The Committee has the following resources:

+
    +
  • a Chairperson elected from its members;
  • +
  • a Secretary provided by STFC Scientific Computing.
  • +
+

In the event of a decision requiring a vote, each member has a single +vote, except the ICAT project manager who does not have a vote. +A simple majority system will be used, with the chair having the +casting vote in the event of a tie. The secretary is not a member of the +committee and does not have a vote.

+

Chairperson

+

The Chairperson has the following responsibilities:

+
    +
  • to call the meetings of the Committee;
  • +
  • to set the agenda for the meetings;
  • +
  • to chair the meetings;
  • +
  • to direct the Secretary between Committee meetings;
  • +
  • to resolve conflicts of interest which may arise among the parties +in the collaboration;
  • +
  • to review the membership of the Committee annually, and invite new +members.
  • +
+

Secretary

+

The Secretary has the following responsibilities:

+
    +
  • to deal with the administrative needs of the Committee;
  • +
  • to arrange the meetings of the Committee;
  • +
  • to maintain and publish the minutes of the meetings.
  • +
+

Meetings

+

The Committee will meet as required, but at least once per annum, via +teleconference or in person. Proposals of agenda items can be sent to +the Secretary.

+

Current Membership

+

Proposed Membership as of 24/2/14 constitutes:

+
    +
  • a representative of ISIS;
  • +
  • a representative of DLS;
  • +
  • a representative of CLF;
  • +
  • a representative of SNS;
  • +
  • a representative of Scientific Computing at STFC;
  • +
  • a representative of ILL;
  • +
  • a representative of ESRF;
  • +
  • a representative of ELETTRA;
  • +
  • a representative of the PanData consortium;
  • +
+ + \ No newline at end of file diff --git a/collaboration/communication/steering-group/steering-group-terms-of-reference/index.html b/collaboration/communication/steering-group/steering-group-terms-of-reference/index.html new file mode 100644 index 000000000..db19962ad --- /dev/null +++ b/collaboration/communication/steering-group/steering-group-terms-of-reference/index.html @@ -0,0 +1,97 @@ +Steering Group Terms of Reference | ICAT Project

ICAT Project

Search

Steering Group Terms of Reference

24 February 2014

+

The ICAT Steering Committee provides a forum for representatives of the +stakeholders in ICAT to steer and advise on the priorities and the +direction of the ICAT suite of data management components (referred to +as ICAT).    ICAT developers already meet regularly to discuss current +progress, under the coordination of the Project manager of the ICAT +project.  However, as an open-source collaboration, it requires +oversight and guidance from all senior members of stakeholder +organisations involved to ensure that it continues to develop as a +valuable component for data management within facilities +infrastructure.  The Steering Committee will meet more infrequently to +undertake this role.

+

Purpose

+

The Committee exists for the following reasons:

+
    +
  • to advise on the likely usage and requirements for ICAT;
  • +
  • to provide senior management oversight for the work of the ICAT +collaboration partners;
  • +
  • to provide strategic guidance on the development and deployment of +ICAT.
  • +
+

Responsibilities of the ICAT Steering Committee

+

The members of the Committee have the following responsibilities:

+
    +
  • to provide strategic advice to the collaboration;
  • +
  • to protect the interests of the institution which they represent;
  • +
  • to advise on new initiatives and plans which may affect the +development of ICAT;
  • +
  • to advise on major requirements which may affect the development of +ICAT;
  • +
  • to oversee the ICAT development roadmap, including the incorporation +of additional components into ICAT which have been proposed by +developers or users;
  • +
  • to ensure that ICAT components continue to remain aligned to the +aims of the stakeholders, within a common functionality and code +base;
  • +
  • to advise on ownership, licencing of components and +commercialisation opportunities;
  • +
  • to ensure that the institution which they represent provides +appropriate resources to the collaboration.
  • +
+

Membership

+

The Committee has one representative from each the major stakeholders +who are actively involved in developing, deploying and exploiting +ICAT. The Committee will regularly review membership to ensure that +it remains representative of the active users of ICAT, and invite new +members as appropriate.

+

The Project Manager of the ICAT Project should attend meetings in a +non-voting capacity.

+

The Committee has the following resources:

+
    +
  • a Chairperson elected from its members;
  • +
  • a Secretary provided by STFC Scientific Computing.
  • +
+

Chairperson

+

The Chairperson has the following responsibilities:

+
    +
  • to call the meetings of the Committee;
  • +
  • to set the agenda for the meetings;
  • +
  • to chair the meetings;
  • +
  • to direct the Secretary between Committee meetings;
  • +
  • to resolve conflicts of interest which may arise among the parties +in the collaboration;
  • +
  • to review the membership of the Committee annually, and invite new +members.
  • +
+

Secretary

+

The Secretary has the following responsibilities:

+
    +
  • to deal with the administrative needs of the Committee;
  • +
  • to arrange the meetings of the Committee;
  • +
  • to maintain and publish the minutes of the meetings.
  • +
+

Meetings

+

The Committee will meet as required, but at least once per annum, via +teleconference or in person. Proposals of agenda items can be sent to +the Secretary.

+

Current Membership

+

Proposed Membership as of 24/2/14 constitutes:

+
    +
  • a representative of ISIS;
  • +
  • a representative of DLS;
  • +
  • a representative of CLF;
  • +
  • a representative of SNS;
  • +
  • a representative of Scientific Computing at STFC;
  • +
  • a representative of ILL;
  • +
  • a representative of ESRF;
  • +
  • a representative of ELETTRA;
  • +
  • a representative of the PanData consortium;
  • +
+ + \ No newline at end of file diff --git a/collaboration/component-guidelines/index.html b/collaboration/component-guidelines/index.html new file mode 100644 index 000000000..244f4cbe1 --- /dev/null +++ b/collaboration/component-guidelines/index.html @@ -0,0 +1,63 @@ +Component Guidelines | ICAT Project

ICAT Project

Search

Component Guidelines

Introduction

+

These guidelines are for developers of components to encourage +uniformity -- especially as seen by the installer and the user.

+

Java

+
    +
  • All java packages should be below org.icatproject
  • +
  • All java components must be pure maven builds
  • +
  • All java components should make use of the maven site plugin for +documentation
  • +
  • All java components must make use of the maven release mechanism to +generate artifacts to be stored on repo.icatproject.org. This +requires that the pom.xml is configured correctly.
  • +
+

Installation

+
    +
  • Installation scripts should be in python compatible with versions +2.4 to 2.7
  • +
  • The normal installation mechanism is to download a file +xxxxx-n.n.n-distro.zip, unpack it and run setup.py install and +uninstalled by setup.py uninstall. Any properties should have a +suffix .example appended or be within a directory having a .example +appended.
  • +
  • the distribution should contain a file README.txt pointing to the +top level of the documentation for that component on +repo.icatproject.org
  • +
  • setup.py may have options -- especially if the component does not +really need an xxxxxx-setup.properties file
  • +
  • setup.py may be interactive but this should be avoided where +possible
  • +
  • It should be possible to run setup.py install or setup.py uninstall +multiple times without errors.
  • +
  • in the case .war and .ear files containing a version number, install +should remove the previous one first
  • +
  • uninstall should reverse the install except that if two or more +components make the same state change upon installation they should +not reverse it when uninstalled.
  • +
+

Documentation

+
    +
  • All components must make use of the maven site mechanism to deploy a +user guide and installation manual as one or more html pages on +repo.icatproject.org
  • +
+

Testing

+
    +
  • Unit tests should be written by the developer to test as much as +possible of the internals
  • +
  • All components should be tested before release by someone other than +the person making the last set of changes
  • +
  • Testing should ensure that these guidelines have been followed, that +the component can be installed and uninstalled as described in the +installation manual and that it performs as described in the user +guide.
  • +
  • If the release notes describe bugs, reported by a user, which have +been fixed there should normally be a corresponding system test.
  • +
+ + \ No newline at end of file diff --git a/collaboration/configuring-the-pom-xml/index.html b/collaboration/configuring-the-pom-xml/index.html new file mode 100644 index 000000000..cb6c7458d --- /dev/null +++ b/collaboration/configuring-the-pom-xml/index.html @@ -0,0 +1,231 @@ +Configuring the pom.xml | ICAT Project

ICAT Project

Search

Configuring the pom.xml

Introduction

+

The examples below are derived from the pom file for the icat.server but +the icat.server text has been replaced by xxx.yyy to reduce the risk of +writing accidentally to the icat.server area.

+

The maven repository is at https://repo.icatproject.org/repo. Anybody +may read it but writing is only available to authorized individuals. The +site area (where maven writes documentation for components) is +at https://repo.icatproject.org/site.

+

README.txt

+

This file contains URLs and giving the xxx.yyy as an example should look +like:

+
xxx.yyy
+
+-------
+
+
+
+General installation instructions are at https://www.icatproject.org/installation/component
+
+
+
+Specific installation instructions are at https://repo.icatproject.org/site/xxx/yyy/${project.version}/installation.html
+
+
+
+All documentation on the xxx.yyy may be found at https://repo.icatproject.org/site/xxx/yyy/${project.version}
+
+

pom.xml

+

The groupId should be org.icatproject

+

The artifactId should be one word (such as topcat) or two separated by a +dot such as icat.server (or in this case xxx.yyy)

+

The version should initially be 1.0.0-SNAPSHOT

+

<properties> section

+

should contain

+
 <properties>
+
+     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+
+     <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+
+     <project.scm.id>github</project.scm.id>
+
+     <gitUrl>https://github.com/icatproject/xxx.yyy</gitUrl>
+
+ </properties>
+
+

where the project.scm.id identifies a section in your .m2/settings.xml +-- this will be discussed later.

+

Specifying the gitUrl simplifies the pom file.

+

<repositories> section

+

this should contain

+
 <repositories>
+
+    <repository>
+
+        <id>ICAT Repo</id>
+
+        <url>https://repo.icatproject.org/repo</url>
+
+    </repository>
+
+ </repositories>
+
+

to permit your pom file to find other icat components

+

<scm>, <issueManagement>, <licenses> and <organization> sections

+

If you have specified gitUrl in the properties then the following will +require no changes:

+
<scm>
+
+   <connection>scm:git:${gitUrl}.git</connection>
+
+   <developerConnection>scm:git:${gitUrl}.git</developerConnection>
+
+   <url>${gitUrl}</url>
+
+ </scm>
+
+
+
+<issueManagement>
+
+    <url>${gitUrl}/issues</url>
+
+    <system>GitHub</system>
+
+</issueManagement>
+
+
+
+<licenses>
+
+    <license>
+
+        <name>Apache License, Version 2.0</name>
+
+        <url>http://www.apache.org/licenses/LICENSE-2.0</url>
+
+    </license>
+
+</licenses>
+
+
+
+<organization>
+
+    <name>The ICAT Collaboration</name>
+
+    <url>https://www.icatproject.org</url>
+
+</organization>
+
+

<distributionManagement> section

+

This section is used by maven to identify the site and repository areas +and how to write to them. This example should only need the xxx and yyy +substituting:

+
<distributionManagement>
+
+    <downloadUrl>https://repo.icatproject.org/repo</downloadUrl>
+
+    <site>
+
+        <id>repo.icatproject.org</id>
+
+        <url>dav:https://repo.icatproject.org/site/xxx/yyy/${project.version}</url>
+
+    </site>
+
+    <repository>
+
+        <id>repo.icatproject.org</id>
+
+        <url>dav:https://repo.icatproject.org/repo</url>
+
+    </repository>
+
+</distributionManagement>
+
+

The <id> value, in this case repo.icatproject.org again specifies a +section of the ~/.m2/settings.xml file where authentication information +is stored.

+

<build> section

+

this must start off by defining extensions with a subsection of the +form:

+
<extensions>
+
+    <extension>
+
+        <groupId>org.apache.maven.wagon</groupId>
+
+        <artifactId>wagon-webdav-jackrabbit</artifactId>
+
+        <version>2.10</version>
+
+    </extension>
+
+</extensions>
+
+

the version (2.10) is currently the most up to date but should be +changed when something better comes along.

+

This is followed by a plugins section with a specification of each maven +plugin used by the pom. It is good practice to list them all to ensure +that you get a know version. If you don't then you will get warnings and +error messages and the project may not build.  You will certainly need +the plugins for: compiler, site, deploy and release. For the release +plugin you might like to specify:

+
<plugin>
+
+    <groupId>org.apache.maven.plugins</groupId>
+
+    <artifactId>maven-release-plugin</artifactId>
+
+    <version>2.5.2</version>
+
+    <configuration>
+
+        <tagNameFormat>v@{project.version}</tagNameFormat>
+
+    </configuration>
+
+</plugin>
+
+

so that the tag does not contain redundant information.

+

~/.m2/settings.xml

+

This file must contain at least the following:

+
<settings>
+
+    <servers>
+
+        <server>
+
+            <id>repo.icatproject.org</id>
+
+            <username>uuu1</username>
+
+            <password>ppp1</password>
+
+        </server>
+
+        <server>
+
+            <id>github</id>
+
+            <username>uuu2</username>
+
+            <password>ppp2</password>
+
+        </server>
+
+    </servers>
+
+</settings>
+
+

where uuu1/ppp1 is the username and password for webdav access to +repo.icatproject.org and uuu2/ppp2 is the username and password for your +github account. This information will not be transmitted in plaintext.

+

Testing the pom

+

The following command:

+
mvn clean deploy site site:deploy
+
+

will produce a snapshot. To perform a release use:

+
mvn release:prepare
+
+mvn release:perform
+
+ + \ No newline at end of file diff --git a/collaboration/facilities/alba/index.html b/collaboration/facilities/alba/index.html new file mode 100644 index 000000000..a381b8741 --- /dev/null +++ b/collaboration/facilities/alba/index.html @@ -0,0 +1,48 @@ +ALBA Synchrotron Light Source | ICAT Project

ICAT Project

Search

ALBA Synchrotron Light Source

ALBA is a 3rd generation Synchrotron Light facility located in Cerdanyola del Vallès, (Barcelona), being the newest source in the Mediterranean area.

+

It is a complex of electron accelerators to produce synchrotron light, which allows the visualization of the atomic structure of matter as well as the study of its properties.

+

ALBA began cataloging raw data using ICAT in 2020 when the integration with the first instrument, BL11 NCD-SWEET (SAXS/WAXS beamline), reached production status. Efforts are ongoing to gradually integrate the remaining instruments in the facility into the catalogue.

+

Various data formats are used at the moment due to the heterogeneous landscape of techniques currently in operation. However, efforts are being made to gradually converge towards NeXus/HDF5.

+

The ingestion process uses ActiveMQ brokers as the entry point and to decouple it from the normal operation of the instruments, while the logic is implemented using Apache Camel in order to integrate and enrich the ingested data with metadata from the various information systems at the Synchrotron, including, but not limited to, our User Office Portal. The components used to parse and send data to the ingestion process are written using Python.

+

ALBA uses the DataPortal frontend and the ICAT Plus REST API layer developed by the ESRF on top of the core ICAT stack. Authentication is done through ALBA User Office accounts, while Umbrella support is being considered for the future.

+

ALBA recently signed an agreement with DataCite to mint DOIs for raw data issued from public experiments.

+

The ALBA Data Catalogue is currently not yet accessible from outside the facility but it is expected to be opened in 2022.

+

+ + + + Exterior view of ALBA + + +
Exterior view of ALBA
+

+ + \ No newline at end of file diff --git a/collaboration/facilities/clf/index.html b/collaboration/facilities/clf/index.html new file mode 100644 index 000000000..2608630a1 --- /dev/null +++ b/collaboration/facilities/clf/index.html @@ -0,0 +1,58 @@ +CLF | ICAT Project

ICAT Project

Search

CLF

The Central Laser Facility (CLF) is a partnership between its staff and +the large number of members of UK and European universities who use the +specialised laser equipment provided to carry out a broad range of +experiments in physics, chemistry and biology.  CLF provide a broad +spectrum of laser facilities from high intensity laser systems to +ultra-fast sources and laser microscopy techniques.

+

Astra Gemini is a high power, ultra-short pulse laser system delivering +dual beams of 15 J, 30 fs laser pulses focused to intensities in excess +of 10^21^ W/cm^2^.  The facility was upgraded in 2009 and now uses ICAT +to catalogue shot and metrology data.  This raw data is made available +via a web-based tool to scientists associated with each experiment.  The +data is also combined with other sources to give the operations team an +overview of the performance of the laser.

+

Two other CLF lasers -- Vulcan and Artemis -- will be incorporated into +ICAT over the next couple of years.

+

+ + + + Astra Gemini + + +
Astra Gemini
+

+ + \ No newline at end of file diff --git a/collaboration/facilities/dls/index.html b/collaboration/facilities/dls/index.html new file mode 100644 index 000000000..f198bf2cc --- /dev/null +++ b/collaboration/facilities/dls/index.html @@ -0,0 +1,8 @@ +Diamond Light Source | ICAT Project

ICAT Project

Search

Diamond Light Source

Details coming soon.

+ + \ No newline at end of file diff --git a/collaboration/facilities/esrf/index.html b/collaboration/facilities/esrf/index.html new file mode 100644 index 000000000..e544d11ae --- /dev/null +++ b/collaboration/facilities/esrf/index.html @@ -0,0 +1,102 @@ +ESRF | ICAT Project

ICAT Project

Search

ESRF

The ESRF - The European Synchrotron Radiation Facility - is the most intense source of synchrotron-generated light, producing X-rays 100 billion times brighter than the X-rays used in hospitals. These X-rays, endowed with exceptional properties, are produced at the ESRF by the high energy electrons that race around the storage ring, a circular tunnel measuring 844 metres in circumference. +Each year, the demand to use these X-ray beams increases and near to 9000 scientists from around the world come to Grenoble, to “beamlines”, each equipped with state-of-the-art instrumentation, operating 24 hours a day, seven days a week.

+

Thanks to the brilliance and quality of its X-rays, the ESRF functions like a "super-microscope" which "films" the position and motion of atoms in condensed and living matter, and reveals the structure of matter in all its beauty and complexity. It provides unrivalled opportunities for scientists in the exploration of materials and living matter in many fields: chemistry, material physics, archaeology and cultural heritage, structural biology and medical applications, environmental sciences, information science and nanotechnologies.

+

Thirty years ago the ESRF made history as the world’s first third-generation synchrotron light source. Today, the ESRF continues to lead the way with the Extremely Brilliant Source (EBS), a brand-new generation of high-energy synchrotron, improving X-ray performances of brilliance and coherence once again by a factor of 100. This new concept, based on innovative technology, paves the way for a new standard of synchrotrons around the world. ESRF-EBS will contribute to tackling global challenges in key areas such as health, environment, energy and new industrial materials, and to unveiling hidden secrets of our natural and cultural heritage through the non-destructive investigation of precious artifacts and palaeontological treasures.

+
+ + + + The European Synchrotron + + +
The European Synchrotron
+
+

Since 2014, ICAT has been deployed and most of the ESRF beamlines are today storing their data and metadata in ICAT. It has been proven to be a reliable and mature software that allows it to be used for all the experiments.

+

In addition to the use of ICAT as a metadata catalogue, new features like the electronic logbook or the sample tracking system have been developed as well as a dedicated front-end called E-Dataportal (https://data.esrf.fr).

+

The E-Dataportal is a modern front-end used at the ESRF and it is written in React. It uses a newly developed API called ICAT+ to retrieve data. In order to make it easier for users, the approach has been to put together in the same application all tools that the users will need when performing experiments at ESRF: sample tracking, metadata catalogue and electronic logbook.

+
+ + + + The E-Data Portal shows an experiment performed at the ESRF + + +
The E-Data Portal shows an experiment performed at the ESRF
+
+

ICAT+ is a set of RESTful webservices implemented in nodeJS. ICAT+ access to the metadata catalog data via ICAT API and has also access to a Mongo database where data of the logbook and the sample tracking are stored.

+

The sample tracking system allows users to create, send and keep track of the samples that are sent to the facility including the safety aspects. Users can create addresses, shipments, parcels and describe the content of the parcel which will be validated by our safety team.

+
+ + + + The E-Data Portal shows a shipment + + +
The E-Data Portal shows a shipment
+
+

The electronic logbook allows to create both manual and automatic annotations on any experiment performed at the ESRF. Each investigation has its own logbook as well as any beamline. It is a powerful tool that allows users to capture the decision-making of an experiment. By default, the logbook is filled automatically with the command typed by the users during the experiment, then depending on the kind of experiment new inputs are accordingly sent to the logbook that will be stored and made public after the embargo period.

+
+ + + + Example of the electronic logbook in a real experiment + + +
Example of the electronic logbook in a real experiment
+
+

Besides these tools used by the scientific community ICAT+ makes use of Elastic Search to improve the searchs as well as gather statistics that have been proven extremely useful for administrators.

+
+ + + + Real time statistics on the data + + +
Real time statistics on the data
+
+
+ + + + Real time statistics on the data + + +
Real time statistics on the data
+
+ + \ No newline at end of file diff --git a/collaboration/facilities/hzb/index.html b/collaboration/facilities/hzb/index.html new file mode 100644 index 000000000..c65a516be --- /dev/null +++ b/collaboration/facilities/hzb/index.html @@ -0,0 +1,65 @@ +HZB | ICAT Project

ICAT Project

Search

HZB

At the Helmholtz-Zentrum Berlin für Materialien und Energie (HZB) we +explore materials and complex material systems that help to face current +and future challenges, such as the energy transition -- "Energiewende". +One of the HZB's research emphases is on materials for thin-film +photovoltaics and for the conversion of solar energy into chemical +energy carriers (e.g. molecular hydrogen).

+

To be able to study material structures and processes in detail, the HZB +operates two separate large-scale research facilities -- the neutron +source BER II and the synchrotron radiation source BESSY II -- used by +some 3,000 guest scientists from all around the World every year. At +both facilities, HZB teams have developed in some cases unparalleled +instruments and are continuing to work on increasing their measurement +precision to allow for new insights to be gleaned.

+

The HZB is a member of the Helmholtz Association and co-founder of the +Competence Centre for Thin-Film and Nanotechnology for Photovoltaics +Berlin (PVcomB), whose mission it is to promote the technology transfer +to industry.

+

The deployment of ICAT at HZB is at an early stage. As of 2015, we +started trial operations with a few beamlines registering their data in +ICAT. We plan to get fully operational, using ICAT as the catalogue to +access the data produced from all instruments at BER II and BESSY II in +the near future.

+

+ + + + BESSY II control centre, photo: HZB/Kevin Fuchs + + +
BESSY II control centre, photo: HZB/Kevin Fuchs
+

+ + \ No newline at end of file diff --git a/collaboration/facilities/index.html b/collaboration/facilities/index.html new file mode 100644 index 000000000..fb7046b84 --- /dev/null +++ b/collaboration/facilities/index.html @@ -0,0 +1,18 @@ +Facilities using ICAT | ICAT Project

ICAT Project

Search

Facilities using ICAT

There are multiple large-scale research facilities that rely on the ICAT ecosystem of tools for their data management provision.

+

Some of these facilities are:

+ +

You can explore how each of the facilities uses ICAT by accessing their description page above.

+ + \ No newline at end of file diff --git a/collaboration/facilities/isis/index.html b/collaboration/facilities/isis/index.html new file mode 100644 index 000000000..749078043 --- /dev/null +++ b/collaboration/facilities/isis/index.html @@ -0,0 +1,66 @@ +ISIS Neutron and Muon Source | ICAT Project

ICAT Project

Search

ISIS Neutron and Muon Source

STFC's +ISIS Neutron and Muon Source facility is a +world-leading centre for research in the physical and life sciences at the STFC +Rutherford Appleton Laboratory near Oxford in the United Kingdom. Our suite of +neutron and muon instruments gives unique insights into the properties of +materials on the atomic scale.

+

ISIS has been using ICAT since 2007 to catalogue raw data produced from all +instruments. The data catalogue can be accessed at https://data.isis.stfc.ac.uk/.

+

ISIS instruments produce NeXus files, although +much of the historical data is in a facility specific 'ISIS raw' format. Metadata +is extracted from these files and added to the catalogue to improve findability in +the data discovery process. All data produced at ISIS since 1984 has been +catalogued and is available, in line with +the ISIS data policy.

+

The ingestion pipeline is made up of a few .NET applications which communicate +over an ActiveMQ instance. +The repository +containing the pipeline code is currently private, but we're working on making it +public.

+

ISIS uses DataGateway as the web +interface to data, and the catalogue is also available in Mantid, via the ICAT +API. A disk only IDS is used to provide the data to users over https. +Authentication is handled by the +ISIS facilities system.

+

ISIS also issues DOIs for investigations using DataCite.

+

+ + + + Exterior view of STFC's ISIS Facility + + +
Exterior view of STFC's ISIS Facility
+

+

Please contact isisdata@stfc.ac.uk if you have any questions about our ICAT setup.

+ + \ No newline at end of file diff --git a/collaboration/facilities/octopus/index.html b/collaboration/facilities/octopus/index.html new file mode 100644 index 000000000..966208d56 --- /dev/null +++ b/collaboration/facilities/octopus/index.html @@ -0,0 +1,27 @@ +OCTOPUS | ICAT Project

ICAT Project

Search

OCTOPUS

The OCTOPUS (Optics Clustered to Output Unique Solutions) facility, part +of STFC's Central Laser Facility based in the Research Complex at +Harwell in Oxfordshire, is a new concept in laser imaging, in which +multiple light sources are linked to multiple imaging stations allowing +a combination of fluorescence microscopy techniques to be brought to +bear on the samples under investigation. OCTOPUS rallies expertise, +techniques and infrastructure to generate and exploit data for +understanding biological processes at the molecular level from cells to +single molecules. Critical to fully realising the potential of the +imaging data from this variety of complementary imaging methods is +scalable and robust management, processing, visualisation and +interpretation of this information.

+

OCTOPUS will use ICAT to store and manage its wide variety of both raw +data and processed data, using a customised web interface building on +TopCAT, linking this with management of data processing and +visualisation on STFC computing facilities through a new service, the +ICAT Job Portal (IJP). Metadata is extracted from files and added to the +catalogue for searchability. This will be integrated with other systems, +such as OMERO, so that additional services can be provided to OCTOPUS +users.

+ + \ No newline at end of file diff --git a/collaboration/index.html b/collaboration/index.html new file mode 100644 index 000000000..74c2bdc29 --- /dev/null +++ b/collaboration/index.html @@ -0,0 +1,20 @@ +The ICAT Collaboration | ICAT Project

ICAT Project

Search

The ICAT Collaboration

ICAT is an open-source project that is developed as part of a collaboration. Do get in touch if you would like to use the ICAT software components and we will help navigate how to use the different components. We welcome new collaborators!

+

In the pages linked below, you can find more information about the way to contact the ICAT collaboration and how to join our meetings, guidelines about the different componetns and which large-scale facilities are using ICAT:

+
+ + \ No newline at end of file diff --git a/component---src-pages-404-jsx-c5da1ea63695158586c0.js b/component---src-pages-404-jsx-c5da1ea63695158586c0.js new file mode 100644 index 000000000..afcebf24e --- /dev/null +++ b/component---src-pages-404-jsx-c5da1ea63695158586c0.js @@ -0,0 +1,2 @@ +"use strict";(self.webpackChunkicatproject_github_io=self.webpackChunkicatproject_github_io||[]).push([[256],{2059:function(t,e,n){var i=n(7294),o=n(4854),a=n(6298);function r(t){let{title:e,description:n,location:r,keywords:c}=t;const{title:l,description:s,siteUrl:u}=(0,o.useStaticQuery)("3248290905").site.siteMetadata,d={title:e+" | "+l||l,description:n||s,url:""+u+(r.pathname||"")};return(0,a.tZ)(i.Fragment,null,(0,a.tZ)("title",null,d.title),(0,a.tZ)("meta",{name:"description",content:d.description}),(0,a.tZ)("meta",{name:"og:title",content:e}),(0,a.tZ)("meta",{name:"og:description",content:d.description}),(0,a.tZ)("meta",{name:"og:type",content:"website"}),(0,a.tZ)("meta",{name:"google-site-verification",content:"9X6CrnxO5Y0COmvYo15fcva3BeU-Qd8XSu5xWV44EDM"}),c&&(0,a.tZ)("meta",{name:"keywords",content:c.join(", ")}))}r.defaultProps={keywords:[],description:void 0},e.Z=r},7291:function(t,e,n){n.r(e),n.d(e,{Head:function(){return s}});var i=n(7462),o=n(7294),a=n(2059),r=n(9463),c=n(6298);var l={name:"18ji2p4",styles:"width:300px"};function s(t){return(0,c.tZ)(a.Z,(0,i.Z)({title:"404: Not found"},t))}e.default=function(){return(0,c.tZ)(o.Fragment,null,(0,c.tZ)("h1",null,"NOT FOUND"),(0,c.tZ)("p",null,"It looks like nothing was found at this location. Maybe try a search?"),(0,c.tZ)(r.Z,{inputCSS:l}))}}}]); +//# sourceMappingURL=component---src-pages-404-jsx-c5da1ea63695158586c0.js.map \ No newline at end of file diff --git a/component---src-pages-404-jsx-c5da1ea63695158586c0.js.map b/component---src-pages-404-jsx-c5da1ea63695158586c0.js.map new file mode 100644 index 000000000..45afdae06 --- /dev/null +++ b/component---src-pages-404-jsx-c5da1ea63695158586c0.js.map @@ -0,0 +1 @@ +{"version":3,"file":"component---src-pages-404-jsx-c5da1ea63695158586c0.js","mappings":"qKAqBA,SAASA,EAAGC,GAA8C,IAA7C,MAAEC,EAAK,YAAEC,EAAW,SAAEC,EAAQ,SAAEC,GAAUJ,EACrD,MAAQC,MAAOI,EAAcH,YAAaI,EAAkB,QAAEC,IANjDC,EAAAA,EAAAA,gBAZG,cAcJC,KAAKC,aAMXC,EAAM,CACVV,MAAUA,EAAK,MAAMI,GAAkBA,EACvCH,YAAaA,GAAeI,EAC5BM,IAAI,GAAIL,GAAUJ,EAASU,UAAY,KAGzC,OACEC,EAAAA,EAAAA,IAAAC,EAAAA,SAAA,MACED,EAAAA,EAAAA,IAAA,aAAQH,EAAIV,QACZa,EAAAA,EAAAA,IAAA,QAAME,KAAK,cAAcC,QAASN,EAAIT,eACtCY,EAAAA,EAAAA,IAAA,QAAME,KAAK,WAAWC,QAAShB,KAC/Ba,EAAAA,EAAAA,IAAA,QAAME,KAAK,iBAAiBC,QAASN,EAAIT,eACzCY,EAAAA,EAAAA,IAAA,QAAME,KAAK,UAAUC,QAAQ,aAC7BH,EAAAA,EAAAA,IAAA,QAAME,KAAK,2BAA2BC,QAAQ,gDAC7Cb,IAAYU,EAAAA,EAAAA,IAAA,QAAME,KAAK,WAAWC,QAASb,EAASc,KAAK,QAGhE,CAEAnB,EAAIoB,aAAe,CACjBf,SAAU,GACVF,iBAAakB,GAYf,K,uHCtDgD,IAAApB,EAAA,CAAAgB,KAAA,UAAAK,OAAA,eAkBzC,SAASC,EAAKC,GAEnB,OAAOT,EAAAA,EAAAA,IAACf,EAAAA,GAAGyB,EAAAA,EAAAA,GAAA,CAACvB,MAAM,kBAAqBsB,GACzC,CALA,UAdA,WACE,OACET,EAAAA,EAAAA,IAAAC,EAAAA,SAAA,MACED,EAAAA,EAAAA,IAAA,UAAI,cACJA,EAAAA,EAAAA,IAAA,SAAG,0EACHA,EAAAA,EAAAA,IAACW,EAAAA,EAAS,CACRC,SAAQ1B,IAMhB,C","sources":["webpack://icatproject.github.io/./src/components/seo.jsx","webpack://icatproject.github.io/./src/pages/404.jsx"],"sourcesContent":["import React from 'react';\nimport PropTypes from 'prop-types';\nimport { useStaticQuery, graphql } from 'gatsby';\n\nconst detailsQuery = graphql`\n query DefaultSEOQuery {\n site {\n siteMetadata {\n title\n description\n }\n }\n }\n`;\n\nexport const useSiteMetadata = () => {\n const data = useStaticQuery(detailsQuery);\n\n return data.site.siteMetadata;\n};\n\nfunction SEO({ title, description, location, keywords }) {\n const { title: defaultTitle, description: defaultDescription, siteUrl } = useSiteMetadata();\n\n const seo = {\n title: `${title} | ${defaultTitle}` || defaultTitle,\n description: description || defaultDescription,\n url: `${siteUrl}${location.pathname || ''}`,\n };\n\n return (\n <>\n {seo.title}\n \n \n \n \n \n {keywords && }\n \n );\n}\n\nSEO.defaultProps = {\n keywords: [],\n description: undefined,\n};\n\nSEO.propTypes = {\n keywords: PropTypes.arrayOf(PropTypes.string),\n title: PropTypes.string.isRequired,\n description: PropTypes.string,\n location: PropTypes.shape({\n pathname: PropTypes.string.isRequired,\n }).isRequired,\n};\n\nexport default SEO;\n","import React from 'react';\nimport { css } from '@emotion/react';\nimport SEO from '../components/seo';\nimport Searchbar from '../components/searchbar';\n\nfunction NotFoundPage() {\n return (\n <>\n

NOT FOUND

\n

It looks like nothing was found at this location. Maybe try a search?

\n \n \n );\n}\n\nexport default NotFoundPage;\n\nexport function Head(props) {\n // eslint-disable-next-line react/jsx-props-no-spreading\n return ;\n}\n"],"names":["SEO","_ref","title","description","location","keywords","defaultTitle","defaultDescription","siteUrl","useStaticQuery","site","siteMetadata","seo","url","pathname","___EmotionJSX","React","name","content","join","defaultProps","undefined","styles","Head","props","_extends","Searchbar","inputCSS"],"sourceRoot":""} \ No newline at end of file diff --git a/component---src-pages-search-jsx-e5e4b91120820fbe6ad1.js b/component---src-pages-search-jsx-e5e4b91120820fbe6ad1.js new file mode 100644 index 000000000..d18253adc --- /dev/null +++ b/component---src-pages-search-jsx-e5e4b91120820fbe6ad1.js @@ -0,0 +1,3 @@ +/*! For license information please see component---src-pages-search-jsx-e5e4b91120820fbe6ad1.js.LICENSE.txt */ +(self.webpackChunkicatproject_github_io=self.webpackChunkicatproject_github_io||[]).push([[995],{8453:function(e,t,n){var i,o;!function(){var r,s,u,l,a,c,d,h,f,p,v,g,m,y,S,x,w,I,b,E,D,F,_,k,P,C,z,N,O,W=function(e){var t=new W.Index;return t.pipeline.add(W.trimmer,W.stopWordFilter,W.stemmer),e&&e.call(t,t),t};W.version="0.9.5",lunr=W,W.utils={},W.utils.warn=(r=this,function(e){r.console&&console.warn&&console.warn(e)}),W.utils.toString=function(e){return null==e?"":e.toString()},W.EventEmitter=function(){this.events={}},W.EventEmitter.prototype.addListener=function(){var e=Array.prototype.slice.call(arguments),t=e.pop(),n=e;if("function"!=typeof t)throw new TypeError("last argument must be a function");n.forEach((function(e){this.hasHandler(e)||(this.events[e]=[]),this.events[e].push(t)}),this)},W.EventEmitter.prototype.removeListener=function(e,t){if(this.hasHandler(e)){var n=this.events[e].indexOf(t);-1!==n&&(this.events[e].splice(n,1),0==this.events[e].length&&delete this.events[e])}},W.EventEmitter.prototype.emit=function(e){if(this.hasHandler(e)){var t=Array.prototype.slice.call(arguments,1);this.events[e].forEach((function(e){e.apply(void 0,t)}),this)}},W.EventEmitter.prototype.hasHandler=function(e){return e in this.events},W.tokenizer=function(e){if(!arguments.length||null==e)return[];if(Array.isArray(e)){var t=e.filter((function(e){return null!=e}));t=t.map((function(e){return W.utils.toString(e).toLowerCase()}));var n=[];return t.forEach((function(e){var t=e.split(W.tokenizer.seperator);n=n.concat(t)}),this),n}return e.toString().trim().toLowerCase().split(W.tokenizer.seperator)},W.tokenizer.defaultSeperator=/[\s\-]+/,W.tokenizer.seperator=W.tokenizer.defaultSeperator,W.tokenizer.setSeperator=function(e){null!=e&&"object"==typeof e&&(W.tokenizer.seperator=e)},W.tokenizer.resetSeperator=function(){W.tokenizer.seperator=W.tokenizer.defaultSeperator},W.tokenizer.getSeperator=function(){return W.tokenizer.seperator},W.Pipeline=function(){this._queue=[]},W.Pipeline.registeredFunctions={},W.Pipeline.registerFunction=function(e,t){t in W.Pipeline.registeredFunctions&&W.utils.warn("Overwriting existing registered function: "+t),e.label=t,W.Pipeline.registeredFunctions[t]=e},W.Pipeline.getRegisteredFunction=function(e){return e in W.Pipeline.registeredFunctions!=!0?null:W.Pipeline.registeredFunctions[e]},W.Pipeline.warnIfFunctionNotRegistered=function(e){e.label&&e.label in this.registeredFunctions||W.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},W.Pipeline.load=function(e){var t=new W.Pipeline;return e.forEach((function(e){var n=W.Pipeline.getRegisteredFunction(e);if(!n)throw new Error("Cannot load un-registered function: "+e);t.add(n)})),t},W.Pipeline.prototype.add=function(){Array.prototype.slice.call(arguments).forEach((function(e){W.Pipeline.warnIfFunctionNotRegistered(e),this._queue.push(e)}),this)},W.Pipeline.prototype.after=function(e,t){W.Pipeline.warnIfFunctionNotRegistered(t);var n=this._queue.indexOf(e);if(-1===n)throw new Error("Cannot find existingFn");this._queue.splice(n+1,0,t)},W.Pipeline.prototype.before=function(e,t){W.Pipeline.warnIfFunctionNotRegistered(t);var n=this._queue.indexOf(e);if(-1===n)throw new Error("Cannot find existingFn");this._queue.splice(n,0,t)},W.Pipeline.prototype.remove=function(e){var t=this._queue.indexOf(e);-1!==t&&this._queue.splice(t,1)},W.Pipeline.prototype.run=function(e){for(var t=[],n=e.length,i=this._queue.length,o=0;o0&&t.push(e),n)"docs"!==i&&"df"!==i&&this.expandToken(e+i,t,n[i]);return t},W.InvertedIndex.prototype.toJSON=function(){return{root:this.root}},W.Configuration=function(e,t){var n;e=e||"";if(null==t||null==t)throw new Error("fields should not be null");this.config={};try{n=JSON.parse(e),this.buildUserConfig(n,t)}catch(i){W.utils.warn("user configuration parse failed, will use default configuration"),this.buildDefaultConfig(t)}},W.Configuration.prototype.buildDefaultConfig=function(e){this.reset(),e.forEach((function(e){this.config[e]={boost:1,bool:"OR",expand:!1}}),this)},W.Configuration.prototype.buildUserConfig=function(e,t){var n="OR",i=!1;if(this.reset(),"bool"in e&&(n=e.bool||n),"expand"in e&&(i=e.expand||i),"fields"in e)for(var o in e.fields)if(t.indexOf(o)>-1){var r=e.fields[o],s=i;null!=r.expand&&(s=r.expand),this.config[o]={boost:r.boost||0===r.boost?r.boost:1,bool:r.bool||n,expand:s}}else W.utils.warn("field name in user configuration not found in index instance fields");else this.addAllFields2UserConfig(n,i,t)},W.Configuration.prototype.addAllFields2UserConfig=function(e,t,n){n.forEach((function(n){this.config[n]={boost:1,bool:e,expand:t}}),this)},W.Configuration.prototype.get=function(){return this.config},W.Configuration.prototype.reset=function(){this.config={}},lunr.SortedSet=function(){this.length=0,this.elements=[]},lunr.SortedSet.load=function(e){var t=new this;return t.elements=e,t.length=e.length,t},lunr.SortedSet.prototype.add=function(){var e,t;for(e=0;e1;){if(r===e)return o;re&&(n=o),i=n-t,o=t+Math.floor(i/2),r=this.elements[o]}return r===e?o:-1},lunr.SortedSet.prototype.locationFor=function(e){for(var t=0,n=this.elements.length,i=n-t,o=t+Math.floor(i/2),r=this.elements[o];i>1;)re&&(n=o),i=n-t,o=t+Math.floor(i/2),r=this.elements[o];return r>e?o:ro-1||i>r-1);)s[n]!==u[i]?s[n]u[i]&&i++:(t.add(s[n]),n++,i++);return t},lunr.SortedSet.prototype.clone=function(){var e=new lunr.SortedSet;return e.elements=this.toArray(),e.length=e.elements.length,e},lunr.SortedSet.prototype.union=function(e){var t,n,i;this.length>=e.length?(t=this,n=e):(t=e,n=this),i=t.clone();for(var o=0,r=n.toArray();os.Index.load(n.siteSearchIndex.index)),[n.siteSearchIndex.index]),[d,h]=o.useState([]);return o.useEffect((()=>{h(function(e,t){return e.search(t,{expand:!0}).map((t=>{let{ref:n}=t;return e.documentStore.getDoc(n)}))}(u,i))}),[u,i]),(0,l.tZ)(o.Fragment,null,(0,l.tZ)("h1",null,"Search Results for: "+i),d.map((e=>(0,l.tZ)("article",{key:e.slug},(0,l.tZ)("h2",null,(0,l.tZ)(r.Link,{css:c,to:e.slug},e.title)),(0,l.tZ)("p",null,e.excerpt," ",(0,l.tZ)(r.Link,{css:a,to:e.slug},"Continue reading →"))))))};function d(e){return(0,l.tZ)(u.Z,(0,i.Z)({title:"Search",keywords:["search","ICAT"]},e))}}}]); +//# sourceMappingURL=component---src-pages-search-jsx-e5e4b91120820fbe6ad1.js.map \ No newline at end of file diff --git a/component---src-pages-search-jsx-e5e4b91120820fbe6ad1.js.LICENSE.txt b/component---src-pages-search-jsx-e5e4b91120820fbe6ad1.js.LICENSE.txt new file mode 100644 index 000000000..595813944 --- /dev/null +++ b/component---src-pages-search-jsx-e5e4b91120820fbe6ad1.js.LICENSE.txt @@ -0,0 +1,85 @@ +/*! + * elasticlunr.Configuration + * Copyright (C) 2016 Wei Song + */ + +/*! + * elasticlunr.DocumentStore + * Copyright (C) 2016 Wei Song + */ + +/*! + * elasticlunr.EventEmitter + * Copyright (C) 2016 Oliver Nightingale + * Copyright (C) 2016 Wei Song + */ + +/*! + * elasticlunr.Index + * Copyright (C) 2016 Oliver Nightingale + * Copyright (C) 2016 Wei Song + */ + +/*! + * elasticlunr.InvertedIndex + * Copyright (C) 2016 Wei Song + * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt + */ + +/*! + * elasticlunr.Pipeline + * Copyright (C) 2016 Oliver Nightingale + * Copyright (C) 2016 Wei Song + */ + +/*! + * elasticlunr.js + * Copyright (C) 2016 Oliver Nightingale + * Copyright (C) 2016 Wei Song + */ + +/*! + * elasticlunr.stemmer + * Copyright (C) 2016 Oliver Nightingale + * Copyright (C) 2016 Wei Song + * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt + */ + +/*! + * elasticlunr.stopWordFilter + * Copyright (C) 2016 Oliver Nightingale + * Copyright (C) 2016 Wei Song + */ + +/*! + * elasticlunr.tokenizer + * Copyright (C) 2016 Oliver Nightingale + * Copyright (C) 2016 Wei Song + */ + +/*! + * elasticlunr.trimmer + * Copyright (C) 2016 Oliver Nightingale + * Copyright (C) 2016 Wei Song + */ + +/*! + * elasticlunr.utils + * Copyright (C) 2016 Oliver Nightingale + * Copyright (C) 2016 Wei Song + */ + +/*! + * lunr.SortedSet + * Copyright (C) 2016 Oliver Nightingale + */ + +/** + * elasticlunr - http://weixsong.github.io + * Lightweight full-text search engine in Javascript for browser search and offline search. - 0.9.5 + * + * Copyright (C) 2016 Oliver Nightingale + * Copyright (C) 2016 Wei Song + * MIT Licensed + * @license + */ diff --git a/component---src-pages-search-jsx-e5e4b91120820fbe6ad1.js.map b/component---src-pages-search-jsx-e5e4b91120820fbe6ad1.js.map new file mode 100644 index 000000000..ff57c387e --- /dev/null +++ b/component---src-pages-search-jsx-e5e4b91120820fbe6ad1.js.map @@ -0,0 +1 @@ +{"version":3,"file":"component---src-pages-search-jsx-e5e4b91120820fbe6ad1.js","mappings":"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","sources":["webpack://icatproject.github.io/./node_modules/elasticlunr/elasticlunr.js","webpack://icatproject.github.io/./src/components/seo.jsx","webpack://icatproject.github.io/./src/pages/search.jsx"],"sourcesContent":["/**\n * elasticlunr - http://weixsong.github.io\n * Lightweight full-text search engine in Javascript for browser search and offline search. - 0.9.5\n *\n * Copyright (C) 2016 Oliver Nightingale\n * Copyright (C) 2016 Wei Song\n * MIT Licensed\n * @license\n */\n\n(function(){\n\n/*!\n * elasticlunr.js\n * Copyright (C) 2016 Oliver Nightingale\n * Copyright (C) 2016 Wei Song\n */\n\n/**\n * Convenience function for instantiating a new elasticlunr index and configuring it\n * with the default pipeline functions and the passed config function.\n *\n * When using this convenience function a new index will be created with the\n * following functions already in the pipeline:\n * \n * 1. elasticlunr.trimmer - trim non-word character\n * 2. elasticlunr.StopWordFilter - filters out any stop words before they enter the\n * index\n * 3. elasticlunr.stemmer - stems the tokens before entering the index.\n *\n *\n * Example:\n *\n * var idx = elasticlunr(function () {\n * this.addField('id');\n * this.addField('title');\n * this.addField('body');\n * \n * //this.setRef('id'); // default ref is 'id'\n *\n * this.pipeline.add(function () {\n * // some custom pipeline function\n * });\n * });\n * \n * idx.addDoc({\n * id: 1, \n * title: 'Oracle released database 12g',\n * body: 'Yestaday, Oracle has released their latest database, named 12g, more robust. this product will increase Oracle profit.'\n * });\n * \n * idx.addDoc({\n * id: 2, \n * title: 'Oracle released annual profit report',\n * body: 'Yestaday, Oracle has released their annual profit report of 2015, total profit is 12.5 Billion.'\n * });\n * \n * # simple search\n * idx.search('oracle database');\n * \n * # search with query-time boosting\n * idx.search('oracle database', {fields: {title: {boost: 2}, body: {boost: 1}}});\n *\n * @param {Function} config A function that will be called with the new instance\n * of the elasticlunr.Index as both its context and first parameter. It can be used to\n * customize the instance of new elasticlunr.Index.\n * @namespace\n * @module\n * @return {elasticlunr.Index}\n *\n */\nvar elasticlunr = function (config) {\n var idx = new elasticlunr.Index;\n\n idx.pipeline.add(\n elasticlunr.trimmer,\n elasticlunr.stopWordFilter,\n elasticlunr.stemmer\n );\n\n if (config) config.call(idx, idx);\n\n return idx;\n};\n\nelasticlunr.version = \"0.9.5\";\n\n// only used this to make elasticlunr.js compatible with lunr-languages\n// this is a trick to define a global alias of elasticlunr\nlunr = elasticlunr;\n\n/*!\n * elasticlunr.utils\n * Copyright (C) 2016 Oliver Nightingale\n * Copyright (C) 2016 Wei Song\n */\n\n/**\n * A namespace containing utils for the rest of the elasticlunr library\n */\nelasticlunr.utils = {};\n\n/**\n * Print a warning message to the console.\n *\n * @param {String} message The message to be printed.\n * @memberOf Utils\n */\nelasticlunr.utils.warn = (function (global) {\n return function (message) {\n if (global.console && console.warn) {\n console.warn(message);\n }\n };\n})(this);\n\n/**\n * Convert an object to string.\n *\n * In the case of `null` and `undefined` the function returns\n * an empty string, in all other cases the result of calling\n * `toString` on the passed object is returned.\n *\n * @param {object} obj The object to convert to a string.\n * @return {String} string representation of the passed object.\n * @memberOf Utils\n */\nelasticlunr.utils.toString = function (obj) {\n if (obj === void 0 || obj === null) {\n return \"\";\n }\n\n return obj.toString();\n};\n/*!\n * elasticlunr.EventEmitter\n * Copyright (C) 2016 Oliver Nightingale\n * Copyright (C) 2016 Wei Song\n */\n\n/**\n * elasticlunr.EventEmitter is an event emitter for elasticlunr.\n * It manages adding and removing event handlers and triggering events and their handlers.\n *\n * Each event could has multiple corresponding functions,\n * these functions will be called as the sequence that they are added into the event.\n * \n * @constructor\n */\nelasticlunr.EventEmitter = function () {\n this.events = {};\n};\n\n/**\n * Binds a handler function to a specific event(s).\n *\n * Can bind a single function to many different events in one call.\n *\n * @param {String} [eventName] The name(s) of events to bind this function to.\n * @param {Function} fn The function to call when an event is fired.\n * @memberOf EventEmitter\n */\nelasticlunr.EventEmitter.prototype.addListener = function () {\n var args = Array.prototype.slice.call(arguments),\n fn = args.pop(),\n names = args;\n\n if (typeof fn !== \"function\") throw new TypeError (\"last argument must be a function\");\n\n names.forEach(function (name) {\n if (!this.hasHandler(name)) this.events[name] = [];\n this.events[name].push(fn);\n }, this);\n};\n\n/**\n * Removes a handler function from a specific event.\n *\n * @param {String} eventName The name of the event to remove this function from.\n * @param {Function} fn The function to remove from an event.\n * @memberOf EventEmitter\n */\nelasticlunr.EventEmitter.prototype.removeListener = function (name, fn) {\n if (!this.hasHandler(name)) return;\n\n var fnIndex = this.events[name].indexOf(fn);\n if (fnIndex === -1) return;\n\n this.events[name].splice(fnIndex, 1);\n\n if (this.events[name].length == 0) delete this.events[name];\n};\n\n/**\n * Call all functions that bounded to the given event.\n *\n * Additional data can be passed to the event handler as arguments to `emit`\n * after the event name.\n *\n * @param {String} eventName The name of the event to emit.\n * @memberOf EventEmitter\n */\nelasticlunr.EventEmitter.prototype.emit = function (name) {\n if (!this.hasHandler(name)) return;\n\n var args = Array.prototype.slice.call(arguments, 1);\n\n this.events[name].forEach(function (fn) {\n fn.apply(undefined, args);\n }, this);\n};\n\n/**\n * Checks whether a handler has ever been stored against an event.\n *\n * @param {String} eventName The name of the event to check.\n * @private\n * @memberOf EventEmitter\n */\nelasticlunr.EventEmitter.prototype.hasHandler = function (name) {\n return name in this.events;\n};\n/*!\n * elasticlunr.tokenizer\n * Copyright (C) 2016 Oliver Nightingale\n * Copyright (C) 2016 Wei Song\n */\n\n/**\n * A function for splitting a string into tokens.\n * Currently English is supported as default.\n * Uses `elasticlunr.tokenizer.seperator` to split strings, you could change\n * the value of this property to set how you want strings are split into tokens.\n * IMPORTANT: use elasticlunr.tokenizer.seperator carefully, if you are not familiar with\n * text process, then you'd better not change it.\n *\n * @module\n * @param {String} str The string that you want to tokenize.\n * @see elasticlunr.tokenizer.seperator\n * @return {Array}\n */\nelasticlunr.tokenizer = function (str) {\n if (!arguments.length || str === null || str === undefined) return [];\n if (Array.isArray(str)) {\n var arr = str.filter(function(token) {\n if (token === null || token === undefined) {\n return false;\n }\n\n return true;\n });\n\n arr = arr.map(function (t) {\n return elasticlunr.utils.toString(t).toLowerCase();\n });\n\n var out = [];\n arr.forEach(function(item) {\n var tokens = item.split(elasticlunr.tokenizer.seperator);\n out = out.concat(tokens);\n }, this);\n\n return out;\n }\n\n return str.toString().trim().toLowerCase().split(elasticlunr.tokenizer.seperator);\n};\n\n/**\n * Default string seperator.\n */\nelasticlunr.tokenizer.defaultSeperator = /[\\s\\-]+/;\n\n/**\n * The sperator used to split a string into tokens. Override this property to change the behaviour of\n * `elasticlunr.tokenizer` behaviour when tokenizing strings. By default this splits on whitespace and hyphens.\n *\n * @static\n * @see elasticlunr.tokenizer\n */\nelasticlunr.tokenizer.seperator = elasticlunr.tokenizer.defaultSeperator;\n\n/**\n * Set up customized string seperator\n *\n * @param {Object} sep The customized seperator that you want to use to tokenize a string.\n */\nelasticlunr.tokenizer.setSeperator = function(sep) {\n if (sep !== null && sep !== undefined && typeof(sep) === 'object') {\n elasticlunr.tokenizer.seperator = sep;\n }\n}\n\n/**\n * Reset string seperator\n *\n */\nelasticlunr.tokenizer.resetSeperator = function() {\n elasticlunr.tokenizer.seperator = elasticlunr.tokenizer.defaultSeperator;\n}\n\n/**\n * Get string seperator\n *\n */\nelasticlunr.tokenizer.getSeperator = function() {\n return elasticlunr.tokenizer.seperator;\n}\n/*!\n * elasticlunr.Pipeline\n * Copyright (C) 2016 Oliver Nightingale\n * Copyright (C) 2016 Wei Song\n */\n\n/**\n * elasticlunr.Pipelines maintain an ordered list of functions to be applied to \n * both documents tokens and query tokens.\n *\n * An instance of elasticlunr.Index will contain a pipeline\n * with a trimmer, a stop word filter, an English stemmer. Extra\n * functions can be added before or after either of these functions or these\n * default functions can be removed.\n *\n * When run the pipeline, it will call each function in turn.\n *\n * The output of the functions in the pipeline will be passed to the next function\n * in the pipeline. To exclude a token from entering the index the function\n * should return undefined, the rest of the pipeline will not be called with\n * this token.\n *\n * For serialisation of pipelines to work, all functions used in an instance of\n * a pipeline should be registered with elasticlunr.Pipeline. Registered functions can\n * then be loaded. If trying to load a serialised pipeline that uses functions\n * that are not registered an error will be thrown.\n *\n * If not planning on serialising the pipeline then registering pipeline functions\n * is not necessary.\n *\n * @constructor\n */\nelasticlunr.Pipeline = function () {\n this._queue = [];\n};\n\nelasticlunr.Pipeline.registeredFunctions = {};\n\n/**\n * Register a function in the pipeline.\n *\n * Functions that are used in the pipeline should be registered if the pipeline\n * needs to be serialised, or a serialised pipeline needs to be loaded.\n *\n * Registering a function does not add it to a pipeline, functions must still be\n * added to instances of the pipeline for them to be used when running a pipeline.\n *\n * @param {Function} fn The function to register.\n * @param {String} label The label to register this function with\n * @memberOf Pipeline\n */\nelasticlunr.Pipeline.registerFunction = function (fn, label) {\n if (label in elasticlunr.Pipeline.registeredFunctions) {\n elasticlunr.utils.warn('Overwriting existing registered function: ' + label);\n }\n\n fn.label = label;\n elasticlunr.Pipeline.registeredFunctions[label] = fn;\n};\n\n/**\n * Get a registered function in the pipeline.\n *\n * @param {String} label The label of registered function.\n * @return {Function}\n * @memberOf Pipeline\n */\nelasticlunr.Pipeline.getRegisteredFunction = function (label) {\n if ((label in elasticlunr.Pipeline.registeredFunctions) !== true) {\n return null;\n }\n\n return elasticlunr.Pipeline.registeredFunctions[label];\n};\n\n/**\n * Warns if the function is not registered as a Pipeline function.\n *\n * @param {Function} fn The function to check for.\n * @private\n * @memberOf Pipeline\n */\nelasticlunr.Pipeline.warnIfFunctionNotRegistered = function (fn) {\n var isRegistered = fn.label && (fn.label in this.registeredFunctions);\n\n if (!isRegistered) {\n elasticlunr.utils.warn('Function is not registered with pipeline. This may cause problems when serialising the index.\\n', fn);\n }\n};\n\n/**\n * Loads a previously serialised pipeline.\n *\n * All functions to be loaded must already be registered with elasticlunr.Pipeline.\n * If any function from the serialised data has not been registered then an\n * error will be thrown.\n *\n * @param {Object} serialised The serialised pipeline to load.\n * @return {elasticlunr.Pipeline}\n * @memberOf Pipeline\n */\nelasticlunr.Pipeline.load = function (serialised) {\n var pipeline = new elasticlunr.Pipeline;\n\n serialised.forEach(function (fnName) {\n var fn = elasticlunr.Pipeline.getRegisteredFunction(fnName);\n\n if (fn) {\n pipeline.add(fn);\n } else {\n throw new Error('Cannot load un-registered function: ' + fnName);\n }\n });\n\n return pipeline;\n};\n\n/**\n * Adds new functions to the end of the pipeline.\n *\n * Logs a warning if the function has not been registered.\n *\n * @param {Function} functions Any number of functions to add to the pipeline.\n * @memberOf Pipeline\n */\nelasticlunr.Pipeline.prototype.add = function () {\n var fns = Array.prototype.slice.call(arguments);\n\n fns.forEach(function (fn) {\n elasticlunr.Pipeline.warnIfFunctionNotRegistered(fn);\n this._queue.push(fn);\n }, this);\n};\n\n/**\n * Adds a single function after a function that already exists in the\n * pipeline.\n *\n * Logs a warning if the function has not been registered.\n * If existingFn is not found, throw an Exception.\n *\n * @param {Function} existingFn A function that already exists in the pipeline.\n * @param {Function} newFn The new function to add to the pipeline.\n * @memberOf Pipeline\n */\nelasticlunr.Pipeline.prototype.after = function (existingFn, newFn) {\n elasticlunr.Pipeline.warnIfFunctionNotRegistered(newFn);\n\n var pos = this._queue.indexOf(existingFn);\n if (pos === -1) {\n throw new Error('Cannot find existingFn');\n }\n\n this._queue.splice(pos + 1, 0, newFn);\n};\n\n/**\n * Adds a single function before a function that already exists in the\n * pipeline.\n *\n * Logs a warning if the function has not been registered.\n * If existingFn is not found, throw an Exception.\n *\n * @param {Function} existingFn A function that already exists in the pipeline.\n * @param {Function} newFn The new function to add to the pipeline.\n * @memberOf Pipeline\n */\nelasticlunr.Pipeline.prototype.before = function (existingFn, newFn) {\n elasticlunr.Pipeline.warnIfFunctionNotRegistered(newFn);\n\n var pos = this._queue.indexOf(existingFn);\n if (pos === -1) {\n throw new Error('Cannot find existingFn');\n }\n\n this._queue.splice(pos, 0, newFn);\n};\n\n/**\n * Removes a function from the pipeline.\n *\n * @param {Function} fn The function to remove from the pipeline.\n * @memberOf Pipeline\n */\nelasticlunr.Pipeline.prototype.remove = function (fn) {\n var pos = this._queue.indexOf(fn);\n if (pos === -1) {\n return;\n }\n\n this._queue.splice(pos, 1);\n};\n\n/**\n * Runs the current list of functions that registered in the pipeline against the\n * input tokens.\n *\n * @param {Array} tokens The tokens to run through the pipeline.\n * @return {Array}\n * @memberOf Pipeline\n */\nelasticlunr.Pipeline.prototype.run = function (tokens) {\n var out = [],\n tokenLength = tokens.length,\n pipelineLength = this._queue.length;\n\n for (var i = 0; i < tokenLength; i++) {\n var token = tokens[i];\n\n for (var j = 0; j < pipelineLength; j++) {\n token = this._queue[j](token, i, tokens);\n if (token === void 0 || token === null) break;\n };\n\n if (token !== void 0 && token !== null) out.push(token);\n };\n\n return out;\n};\n\n/**\n * Resets the pipeline by removing any existing processors.\n *\n * @memberOf Pipeline\n */\nelasticlunr.Pipeline.prototype.reset = function () {\n this._queue = [];\n};\n\n /**\n * Get the pipeline if user want to check the pipeline.\n *\n * @memberOf Pipeline\n */\n elasticlunr.Pipeline.prototype.get = function () {\n return this._queue;\n };\n\n/**\n * Returns a representation of the pipeline ready for serialisation.\n * Only serialize pipeline function's name. Not storing function, so when\n * loading the archived JSON index file, corresponding pipeline function is \n * added by registered function of elasticlunr.Pipeline.registeredFunctions\n *\n * Logs a warning if the function has not been registered.\n *\n * @return {Array}\n * @memberOf Pipeline\n */\nelasticlunr.Pipeline.prototype.toJSON = function () {\n return this._queue.map(function (fn) {\n elasticlunr.Pipeline.warnIfFunctionNotRegistered(fn);\n return fn.label;\n });\n};\n/*!\n * elasticlunr.Index\n * Copyright (C) 2016 Oliver Nightingale\n * Copyright (C) 2016 Wei Song\n */\n\n/**\n * elasticlunr.Index is object that manages a search index. It contains the indexes\n * and stores all the tokens and document lookups. It also provides the main\n * user facing API for the library.\n *\n * @constructor\n */\nelasticlunr.Index = function () {\n this._fields = [];\n this._ref = 'id';\n this.pipeline = new elasticlunr.Pipeline;\n this.documentStore = new elasticlunr.DocumentStore;\n this.index = {};\n this.eventEmitter = new elasticlunr.EventEmitter;\n this._idfCache = {};\n\n this.on('add', 'remove', 'update', (function () {\n this._idfCache = {};\n }).bind(this));\n};\n\n/**\n * Bind a handler to events being emitted by the index.\n *\n * The handler can be bound to many events at the same time.\n *\n * @param {String} [eventName] The name(s) of events to bind the function to.\n * @param {Function} fn The serialised set to load.\n * @memberOf Index\n */\nelasticlunr.Index.prototype.on = function () {\n var args = Array.prototype.slice.call(arguments);\n return this.eventEmitter.addListener.apply(this.eventEmitter, args);\n};\n\n/**\n * Removes a handler from an event being emitted by the index.\n *\n * @param {String} eventName The name of events to remove the function from.\n * @param {Function} fn The serialised set to load.\n * @memberOf Index\n */\nelasticlunr.Index.prototype.off = function (name, fn) {\n return this.eventEmitter.removeListener(name, fn);\n};\n\n/**\n * Loads a previously serialised index.\n *\n * Issues a warning if the index being imported was serialised\n * by a different version of elasticlunr.\n *\n * @param {Object} serialisedData The serialised set to load.\n * @return {elasticlunr.Index}\n * @memberOf Index\n */\nelasticlunr.Index.load = function (serialisedData) {\n if (serialisedData.version !== elasticlunr.version) {\n elasticlunr.utils.warn('version mismatch: current '\n + elasticlunr.version + ' importing ' + serialisedData.version);\n }\n\n var idx = new this;\n\n idx._fields = serialisedData.fields;\n idx._ref = serialisedData.ref;\n idx.documentStore = elasticlunr.DocumentStore.load(serialisedData.documentStore);\n idx.pipeline = elasticlunr.Pipeline.load(serialisedData.pipeline);\n idx.index = {};\n for (var field in serialisedData.index) {\n idx.index[field] = elasticlunr.InvertedIndex.load(serialisedData.index[field]);\n }\n\n return idx;\n};\n\n/**\n * Adds a field to the list of fields that will be searchable within documents in the index.\n *\n * Remember that inner index is build based on field, which means each field has one inverted index.\n *\n * Fields should be added before any documents are added to the index, fields\n * that are added after documents are added to the index will only apply to new\n * documents added to the index.\n *\n * @param {String} fieldName The name of the field within the document that should be indexed\n * @return {elasticlunr.Index}\n * @memberOf Index\n */\nelasticlunr.Index.prototype.addField = function (fieldName) {\n this._fields.push(fieldName);\n this.index[fieldName] = new elasticlunr.InvertedIndex;\n return this;\n};\n\n/**\n * Sets the property used to uniquely identify documents added to the index,\n * by default this property is 'id'.\n *\n * This should only be changed before adding documents to the index, changing\n * the ref property without resetting the index can lead to unexpected results.\n *\n * @param {String} refName The property to use to uniquely identify the\n * documents in the index.\n * @param {Boolean} emitEvent Whether to emit add events, defaults to true\n * @return {elasticlunr.Index}\n * @memberOf Index\n */\nelasticlunr.Index.prototype.setRef = function (refName) {\n this._ref = refName;\n return this;\n};\n\n/**\n *\n * Set if the JSON format original documents are save into elasticlunr.DocumentStore\n *\n * Defaultly save all the original JSON documents.\n *\n * @param {Boolean} save Whether to save the original JSON documents.\n * @return {elasticlunr.Index}\n * @memberOf Index\n */\nelasticlunr.Index.prototype.saveDocument = function (save) {\n this.documentStore = new elasticlunr.DocumentStore(save);\n return this;\n};\n\n/**\n * Add a JSON format document to the index.\n *\n * This is the way new documents enter the index, this function will run the\n * fields from the document through the index's pipeline and then add it to\n * the index, it will then show up in search results.\n *\n * An 'add' event is emitted with the document that has been added and the index\n * the document has been added to. This event can be silenced by passing false\n * as the second argument to add.\n *\n * @param {Object} doc The JSON format document to add to the index.\n * @param {Boolean} emitEvent Whether or not to emit events, default true.\n * @memberOf Index\n */\nelasticlunr.Index.prototype.addDoc = function (doc, emitEvent) {\n if (!doc) return;\n var emitEvent = emitEvent === undefined ? true : emitEvent;\n\n var docRef = doc[this._ref];\n\n this.documentStore.addDoc(docRef, doc);\n this._fields.forEach(function (field) {\n var fieldTokens = this.pipeline.run(elasticlunr.tokenizer(doc[field]));\n this.documentStore.addFieldLength(docRef, field, fieldTokens.length);\n\n var tokenCount = {};\n fieldTokens.forEach(function (token) {\n if (token in tokenCount) tokenCount[token] += 1;\n else tokenCount[token] = 1;\n }, this);\n\n for (var token in tokenCount) {\n var termFrequency = tokenCount[token];\n termFrequency = Math.sqrt(termFrequency);\n this.index[field].addToken(token, { ref: docRef, tf: termFrequency });\n }\n }, this);\n\n if (emitEvent) this.eventEmitter.emit('add', doc, this);\n};\n\n/**\n * Removes a document from the index by doc ref.\n *\n * To make sure documents no longer show up in search results they can be\n * removed from the index using this method.\n *\n * A 'remove' event is emitted with the document that has been removed and the index\n * the document has been removed from. This event can be silenced by passing false\n * as the second argument to remove.\n *\n * If user setting DocumentStore not storing the documents, then remove doc by docRef is not allowed.\n *\n * @param {String|Integer} docRef The document ref to remove from the index.\n * @param {Boolean} emitEvent Whether to emit remove events, defaults to true\n * @memberOf Index\n */\nelasticlunr.Index.prototype.removeDocByRef = function (docRef, emitEvent) {\n if (!docRef) return;\n if (this.documentStore.isDocStored() === false) {\n return;\n }\n\n if (!this.documentStore.hasDoc(docRef)) return;\n var doc = this.documentStore.getDoc(docRef);\n this.removeDoc(doc, false);\n};\n\n/**\n * Removes a document from the index.\n * This remove operation could work even the original doc is not store in the DocumentStore.\n *\n * To make sure documents no longer show up in search results they can be\n * removed from the index using this method.\n *\n * A 'remove' event is emitted with the document that has been removed and the index\n * the document has been removed from. This event can be silenced by passing false\n * as the second argument to remove.\n *\n *\n * @param {Object} doc The document ref to remove from the index.\n * @param {Boolean} emitEvent Whether to emit remove events, defaults to true\n * @memberOf Index\n */\nelasticlunr.Index.prototype.removeDoc = function (doc, emitEvent) {\n if (!doc) return;\n\n var emitEvent = emitEvent === undefined ? true : emitEvent;\n\n var docRef = doc[this._ref];\n if (!this.documentStore.hasDoc(docRef)) return;\n\n this.documentStore.removeDoc(docRef);\n\n this._fields.forEach(function (field) {\n var fieldTokens = this.pipeline.run(elasticlunr.tokenizer(doc[field]));\n fieldTokens.forEach(function (token) {\n this.index[field].removeToken(token, docRef);\n }, this);\n }, this);\n\n if (emitEvent) this.eventEmitter.emit('remove', doc, this);\n};\n\n/**\n * Updates a document in the index.\n *\n * When a document contained within the index gets updated, fields changed,\n * added or removed, to make sure it correctly matched against search queries,\n * it should be updated in the index.\n *\n * This method is just a wrapper around `remove` and `add`\n *\n * An 'update' event is emitted with the document that has been updated and the index.\n * This event can be silenced by passing false as the second argument to update. Only\n * an update event will be fired, the 'add' and 'remove' events of the underlying calls\n * are silenced.\n *\n * @param {Object} doc The document to update in the index.\n * @param {Boolean} emitEvent Whether to emit update events, defaults to true\n * @see Index.prototype.remove\n * @see Index.prototype.add\n * @memberOf Index\n */\nelasticlunr.Index.prototype.updateDoc = function (doc, emitEvent) {\n var emitEvent = emitEvent === undefined ? true : emitEvent;\n\n this.removeDocByRef(doc[this._ref], false);\n this.addDoc(doc, false);\n\n if (emitEvent) this.eventEmitter.emit('update', doc, this);\n};\n\n/**\n * Calculates the inverse document frequency for a token within the index of a field.\n *\n * @param {String} token The token to calculate the idf of.\n * @param {String} field The field to compute idf.\n * @see Index.prototype.idf\n * @private\n * @memberOf Index\n */\nelasticlunr.Index.prototype.idf = function (term, field) {\n var cacheKey = \"@\" + field + '/' + term;\n if (Object.prototype.hasOwnProperty.call(this._idfCache, cacheKey)) return this._idfCache[cacheKey];\n\n var df = this.index[field].getDocFreq(term);\n var idf = 1 + Math.log(this.documentStore.length / (df + 1));\n this._idfCache[cacheKey] = idf;\n\n return idf;\n};\n\n/**\n * get fields of current index instance\n *\n * @return {Array}\n */\nelasticlunr.Index.prototype.getFields = function () {\n return this._fields.slice();\n};\n\n/**\n * Searches the index using the passed query.\n * Queries should be a string, multiple words are allowed.\n *\n * If config is null, will search all fields defaultly, and lead to OR based query.\n * If config is specified, will search specified with query time boosting.\n *\n * All query tokens are passed through the same pipeline that document tokens\n * are passed through, so any language processing involved will be run on every\n * query term.\n *\n * Each query term is expanded, so that the term 'he' might be expanded to\n * 'hello' and 'help' if those terms were already included in the index.\n *\n * Matching documents are returned as an array of objects, each object contains\n * the matching document ref, as set for this index, and the similarity score\n * for this document against the query.\n *\n * @param {String} query The query to search the index with.\n * @param {JSON} userConfig The user query config, JSON format.\n * @return {Object}\n * @see Index.prototype.idf\n * @see Index.prototype.documentVector\n * @memberOf Index\n */\nelasticlunr.Index.prototype.search = function (query, userConfig) {\n if (!query) return [];\n\n var configStr = null;\n if (userConfig != null) {\n configStr = JSON.stringify(userConfig);\n }\n\n var config = new elasticlunr.Configuration(configStr, this.getFields()).get();\n\n var queryTokens = this.pipeline.run(elasticlunr.tokenizer(query));\n\n var queryResults = {};\n\n for (var field in config) {\n var fieldSearchResults = this.fieldSearch(queryTokens, field, config);\n var fieldBoost = config[field].boost;\n\n for (var docRef in fieldSearchResults) {\n fieldSearchResults[docRef] = fieldSearchResults[docRef] * fieldBoost;\n }\n\n for (var docRef in fieldSearchResults) {\n if (docRef in queryResults) {\n queryResults[docRef] += fieldSearchResults[docRef];\n } else {\n queryResults[docRef] = fieldSearchResults[docRef];\n }\n }\n }\n\n var results = [];\n for (var docRef in queryResults) {\n results.push({ref: docRef, score: queryResults[docRef]});\n }\n\n results.sort(function (a, b) { return b.score - a.score; });\n return results;\n};\n\n/**\n * search queryTokens in specified field.\n *\n * @param {Array} queryTokens The query tokens to query in this field.\n * @param {String} field Field to query in.\n * @param {elasticlunr.Configuration} config The user query config, JSON format.\n * @return {Object}\n */\nelasticlunr.Index.prototype.fieldSearch = function (queryTokens, fieldName, config) {\n var booleanType = config[fieldName].bool;\n var expand = config[fieldName].expand;\n var boost = config[fieldName].boost;\n var scores = null;\n var docTokens = {};\n\n // Do nothing if the boost is 0\n if (boost === 0) {\n return;\n }\n\n queryTokens.forEach(function (token) {\n var tokens = [token];\n if (expand == true) {\n tokens = this.index[fieldName].expandToken(token);\n }\n // Consider every query token in turn. If expanded, each query token\n // corresponds to a set of tokens, which is all tokens in the \n // index matching the pattern queryToken* .\n // For the set of tokens corresponding to a query token, find and score\n // all matching documents. Store those scores in queryTokenScores, \n // keyed by docRef.\n // Then, depending on the value of booleanType, combine the scores\n // for this query token with previous scores. If booleanType is OR,\n // then merge the scores by summing into the accumulated total, adding\n // new document scores are required (effectively a union operator). \n // If booleanType is AND, accumulate scores only if the document \n // has previously been scored by another query token (an intersection\n // operation0. \n // Furthermore, since when booleanType is AND, additional \n // query tokens can't add new documents to the result set, use the\n // current document set to limit the processing of each new query \n // token for efficiency (i.e., incremental intersection).\n \n var queryTokenScores = {};\n tokens.forEach(function (key) {\n var docs = this.index[fieldName].getDocs(key);\n var idf = this.idf(key, fieldName);\n \n if (scores && booleanType == 'AND') {\n // special case, we can rule out documents that have been\n // already been filtered out because they weren't scored\n // by previous query token passes.\n var filteredDocs = {};\n for (var docRef in scores) {\n if (docRef in docs) {\n filteredDocs[docRef] = docs[docRef];\n }\n }\n docs = filteredDocs;\n }\n // only record appeared token for retrieved documents for the\n // original token, not for expaned token.\n // beause for doing coordNorm for a retrieved document, coordNorm only care how many\n // query token appear in that document.\n // so expanded token should not be added into docTokens, if added, this will pollute the\n // coordNorm\n if (key == token) {\n this.fieldSearchStats(docTokens, key, docs);\n }\n\n for (var docRef in docs) {\n var tf = this.index[fieldName].getTermFrequency(key, docRef);\n var fieldLength = this.documentStore.getFieldLength(docRef, fieldName);\n var fieldLengthNorm = 1;\n if (fieldLength != 0) {\n fieldLengthNorm = 1 / Math.sqrt(fieldLength);\n }\n\n var penality = 1;\n if (key != token) {\n // currently I'm not sure if this penality is enough,\n // need to do verification\n penality = (1 - (key.length - token.length) / key.length) * 0.15;\n }\n\n var score = tf * idf * fieldLengthNorm * penality;\n\n if (docRef in queryTokenScores) {\n queryTokenScores[docRef] += score;\n } else {\n queryTokenScores[docRef] = score;\n }\n }\n }, this);\n \n scores = this.mergeScores(scores, queryTokenScores, booleanType);\n }, this);\n\n scores = this.coordNorm(scores, docTokens, queryTokens.length);\n return scores;\n};\n\n/**\n * Merge the scores from one set of tokens into an accumulated score table.\n * Exact operation depends on the op parameter. If op is 'AND', then only the\n * intersection of the two score lists is retained. Otherwise, the union of\n * the two score lists is returned. For internal use only.\n *\n * @param {Object} bool accumulated scores. Should be null on first call.\n * @param {String} scores new scores to merge into accumScores.\n * @param {Object} op merge operation (should be 'AND' or 'OR').\n *\n */\n\nelasticlunr.Index.prototype.mergeScores = function (accumScores, scores, op) {\n if (!accumScores) {\n return scores; \n }\n if (op == 'AND') {\n var intersection = {};\n for (var docRef in scores) {\n if (docRef in accumScores) {\n intersection[docRef] = accumScores[docRef] + scores[docRef];\n }\n }\n return intersection;\n } else {\n for (var docRef in scores) {\n if (docRef in accumScores) {\n accumScores[docRef] += scores[docRef];\n } else {\n accumScores[docRef] = scores[docRef];\n }\n }\n return accumScores;\n }\n};\n\n\n/**\n * Record the occuring query token of retrieved doc specified by doc field.\n * Only for inner user.\n *\n * @param {Object} docTokens a data structure stores which token appears in the retrieved doc.\n * @param {String} token query token\n * @param {Object} docs the retrieved documents of the query token\n *\n */\nelasticlunr.Index.prototype.fieldSearchStats = function (docTokens, token, docs) {\n for (var doc in docs) {\n if (doc in docTokens) {\n docTokens[doc].push(token);\n } else {\n docTokens[doc] = [token];\n }\n }\n};\n\n/**\n * coord norm the score of a doc.\n * if a doc contain more query tokens, then the score will larger than the doc\n * contains less query tokens.\n *\n * only for inner use.\n *\n * @param {Object} results first results\n * @param {Object} docs field search results of a token\n * @param {Integer} n query token number\n * @return {Object}\n */\nelasticlunr.Index.prototype.coordNorm = function (scores, docTokens, n) {\n for (var doc in scores) {\n if (!(doc in docTokens)) continue;\n var tokens = docTokens[doc].length;\n scores[doc] = scores[doc] * tokens / n;\n }\n\n return scores;\n};\n\n/**\n * Returns a representation of the index ready for serialisation.\n *\n * @return {Object}\n * @memberOf Index\n */\nelasticlunr.Index.prototype.toJSON = function () {\n var indexJson = {};\n this._fields.forEach(function (field) {\n indexJson[field] = this.index[field].toJSON();\n }, this);\n\n return {\n version: elasticlunr.version,\n fields: this._fields,\n ref: this._ref,\n documentStore: this.documentStore.toJSON(),\n index: indexJson,\n pipeline: this.pipeline.toJSON()\n };\n};\n\n/**\n * Applies a plugin to the current index.\n *\n * A plugin is a function that is called with the index as its context.\n * Plugins can be used to customise or extend the behaviour the index\n * in some way. A plugin is just a function, that encapsulated the custom\n * behaviour that should be applied to the index.\n *\n * The plugin function will be called with the index as its argument, additional\n * arguments can also be passed when calling use. The function will be called\n * with the index as its context.\n *\n * Example:\n *\n * var myPlugin = function (idx, arg1, arg2) {\n * // `this` is the index to be extended\n * // apply any extensions etc here.\n * }\n *\n * var idx = elasticlunr(function () {\n * this.use(myPlugin, 'arg1', 'arg2')\n * })\n *\n * @param {Function} plugin The plugin to apply.\n * @memberOf Index\n */\nelasticlunr.Index.prototype.use = function (plugin) {\n var args = Array.prototype.slice.call(arguments, 1);\n args.unshift(this);\n plugin.apply(this, args);\n};\n/*!\n * elasticlunr.DocumentStore\n * Copyright (C) 2016 Wei Song\n */\n\n/**\n * elasticlunr.DocumentStore is a simple key-value document store used for storing sets of tokens for\n * documents stored in index.\n *\n * elasticlunr.DocumentStore store original JSON format documents that you could build search snippet by this original JSON document.\n *\n * user could choose whether original JSON format document should be store, if no configuration then document will be stored defaultly.\n * If user care more about the index size, user could select not store JSON documents, then this will has some defects, such as user\n * could not use JSON document to generate snippets of search results.\n *\n * @param {Boolean} save If the original JSON document should be stored.\n * @constructor\n * @module\n */\nelasticlunr.DocumentStore = function (save) {\n if (save === null || save === undefined) {\n this._save = true;\n } else {\n this._save = save;\n }\n\n this.docs = {};\n this.docInfo = {};\n this.length = 0;\n};\n\n/**\n * Loads a previously serialised document store\n *\n * @param {Object} serialisedData The serialised document store to load.\n * @return {elasticlunr.DocumentStore}\n */\nelasticlunr.DocumentStore.load = function (serialisedData) {\n var store = new this;\n\n store.length = serialisedData.length;\n store.docs = serialisedData.docs;\n store.docInfo = serialisedData.docInfo;\n store._save = serialisedData.save;\n\n return store;\n};\n\n/**\n * check if current instance store the original doc\n *\n * @return {Boolean}\n */\nelasticlunr.DocumentStore.prototype.isDocStored = function () {\n return this._save;\n};\n\n/**\n * Stores the given doc in the document store against the given id.\n * If docRef already exist, then update doc.\n *\n * Document is store by original JSON format, then you could use original document to generate search snippets.\n *\n * @param {Integer|String} docRef The key used to store the JSON format doc.\n * @param {Object} doc The JSON format doc.\n */\nelasticlunr.DocumentStore.prototype.addDoc = function (docRef, doc) {\n if (!this.hasDoc(docRef)) this.length++;\n\n if (this._save === true) {\n this.docs[docRef] = clone(doc);\n } else {\n this.docs[docRef] = null;\n }\n};\n\n/**\n * Retrieves the JSON doc from the document store for a given key.\n *\n * If docRef not found, return null.\n * If user set not storing the documents, return null.\n *\n * @param {Integer|String} docRef The key to lookup and retrieve from the document store.\n * @return {Object}\n * @memberOf DocumentStore\n */\nelasticlunr.DocumentStore.prototype.getDoc = function (docRef) {\n if (this.hasDoc(docRef) === false) return null;\n return this.docs[docRef];\n};\n\n/**\n * Checks whether the document store contains a key (docRef).\n *\n * @param {Integer|String} docRef The id to look up in the document store.\n * @return {Boolean}\n * @memberOf DocumentStore\n */\nelasticlunr.DocumentStore.prototype.hasDoc = function (docRef) {\n return docRef in this.docs;\n};\n\n/**\n * Removes the value for a key in the document store.\n *\n * @param {Integer|String} docRef The id to remove from the document store.\n * @memberOf DocumentStore\n */\nelasticlunr.DocumentStore.prototype.removeDoc = function (docRef) {\n if (!this.hasDoc(docRef)) return;\n\n delete this.docs[docRef];\n delete this.docInfo[docRef];\n this.length--;\n};\n\n/**\n * Add field length of a document's field tokens from pipeline results.\n * The field length of a document is used to do field length normalization even without the original JSON document stored.\n *\n * @param {Integer|String} docRef document's id or reference\n * @param {String} fieldName field name\n * @param {Integer} length field length\n */\nelasticlunr.DocumentStore.prototype.addFieldLength = function (docRef, fieldName, length) {\n if (docRef === null || docRef === undefined) return;\n if (this.hasDoc(docRef) == false) return;\n\n if (!this.docInfo[docRef]) this.docInfo[docRef] = {};\n this.docInfo[docRef][fieldName] = length;\n};\n\n/**\n * Update field length of a document's field tokens from pipeline results.\n * The field length of a document is used to do field length normalization even without the original JSON document stored.\n *\n * @param {Integer|String} docRef document's id or reference\n * @param {String} fieldName field name\n * @param {Integer} length field length\n */\nelasticlunr.DocumentStore.prototype.updateFieldLength = function (docRef, fieldName, length) {\n if (docRef === null || docRef === undefined) return;\n if (this.hasDoc(docRef) == false) return;\n\n this.addFieldLength(docRef, fieldName, length);\n};\n\n/**\n * get field length of a document by docRef\n *\n * @param {Integer|String} docRef document id or reference\n * @param {String} fieldName field name\n * @return {Integer} field length\n */\nelasticlunr.DocumentStore.prototype.getFieldLength = function (docRef, fieldName) {\n if (docRef === null || docRef === undefined) return 0;\n\n if (!(docRef in this.docs)) return 0;\n if (!(fieldName in this.docInfo[docRef])) return 0;\n return this.docInfo[docRef][fieldName];\n};\n\n/**\n * Returns a JSON representation of the document store used for serialisation.\n *\n * @return {Object} JSON format\n * @memberOf DocumentStore\n */\nelasticlunr.DocumentStore.prototype.toJSON = function () {\n return {\n docs: this.docs,\n docInfo: this.docInfo,\n length: this.length,\n save: this._save\n };\n};\n\n/**\n * Cloning object\n *\n * @param {Object} object in JSON format\n * @return {Object} copied object\n */\nfunction clone(obj) {\n if (null === obj || \"object\" !== typeof obj) return obj;\n\n var copy = obj.constructor();\n\n for (var attr in obj) {\n if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];\n }\n\n return copy;\n}\n/*!\n * elasticlunr.stemmer\n * Copyright (C) 2016 Oliver Nightingale\n * Copyright (C) 2016 Wei Song\n * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt\n */\n\n/**\n * elasticlunr.stemmer is an english language stemmer, this is a JavaScript\n * implementation of the PorterStemmer taken from http://tartarus.org/~martin\n *\n * @module\n * @param {String} str The string to stem\n * @return {String}\n * @see elasticlunr.Pipeline\n */\nelasticlunr.stemmer = (function(){\n var step2list = {\n \"ational\" : \"ate\",\n \"tional\" : \"tion\",\n \"enci\" : \"ence\",\n \"anci\" : \"ance\",\n \"izer\" : \"ize\",\n \"bli\" : \"ble\",\n \"alli\" : \"al\",\n \"entli\" : \"ent\",\n \"eli\" : \"e\",\n \"ousli\" : \"ous\",\n \"ization\" : \"ize\",\n \"ation\" : \"ate\",\n \"ator\" : \"ate\",\n \"alism\" : \"al\",\n \"iveness\" : \"ive\",\n \"fulness\" : \"ful\",\n \"ousness\" : \"ous\",\n \"aliti\" : \"al\",\n \"iviti\" : \"ive\",\n \"biliti\" : \"ble\",\n \"logi\" : \"log\"\n },\n\n step3list = {\n \"icate\" : \"ic\",\n \"ative\" : \"\",\n \"alize\" : \"al\",\n \"iciti\" : \"ic\",\n \"ical\" : \"ic\",\n \"ful\" : \"\",\n \"ness\" : \"\"\n },\n\n c = \"[^aeiou]\", // consonant\n v = \"[aeiouy]\", // vowel\n C = c + \"[^aeiouy]*\", // consonant sequence\n V = v + \"[aeiou]*\", // vowel sequence\n\n mgr0 = \"^(\" + C + \")?\" + V + C, // [C]VC... is m>0\n meq1 = \"^(\" + C + \")?\" + V + C + \"(\" + V + \")?$\", // [C]VC[V] is m=1\n mgr1 = \"^(\" + C + \")?\" + V + C + V + C, // [C]VCVC... is m>1\n s_v = \"^(\" + C + \")?\" + v; // vowel in stem\n\n var re_mgr0 = new RegExp(mgr0);\n var re_mgr1 = new RegExp(mgr1);\n var re_meq1 = new RegExp(meq1);\n var re_s_v = new RegExp(s_v);\n\n var re_1a = /^(.+?)(ss|i)es$/;\n var re2_1a = /^(.+?)([^s])s$/;\n var re_1b = /^(.+?)eed$/;\n var re2_1b = /^(.+?)(ed|ing)$/;\n var re_1b_2 = /.$/;\n var re2_1b_2 = /(at|bl|iz)$/;\n var re3_1b_2 = new RegExp(\"([^aeiouylsz])\\\\1$\");\n var re4_1b_2 = new RegExp(\"^\" + C + v + \"[^aeiouwxy]$\");\n\n var re_1c = /^(.+?[^aeiou])y$/;\n var re_2 = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;\n\n var re_3 = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;\n\n var re_4 = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;\n var re2_4 = /^(.+?)(s|t)(ion)$/;\n\n var re_5 = /^(.+?)e$/;\n var re_5_1 = /ll$/;\n var re3_5 = new RegExp(\"^\" + C + v + \"[^aeiouwxy]$\");\n\n var porterStemmer = function porterStemmer(w) {\n var stem,\n suffix,\n firstch,\n re,\n re2,\n re3,\n re4;\n\n if (w.length < 3) { return w; }\n\n firstch = w.substr(0,1);\n if (firstch == \"y\") {\n w = firstch.toUpperCase() + w.substr(1);\n }\n\n // Step 1a\n re = re_1a\n re2 = re2_1a;\n\n if (re.test(w)) { w = w.replace(re,\"$1$2\"); }\n else if (re2.test(w)) { w = w.replace(re2,\"$1$2\"); }\n\n // Step 1b\n re = re_1b;\n re2 = re2_1b;\n if (re.test(w)) {\n var fp = re.exec(w);\n re = re_mgr0;\n if (re.test(fp[1])) {\n re = re_1b_2;\n w = w.replace(re,\"\");\n }\n } else if (re2.test(w)) {\n var fp = re2.exec(w);\n stem = fp[1];\n re2 = re_s_v;\n if (re2.test(stem)) {\n w = stem;\n re2 = re2_1b_2;\n re3 = re3_1b_2;\n re4 = re4_1b_2;\n if (re2.test(w)) { w = w + \"e\"; }\n else if (re3.test(w)) { re = re_1b_2; w = w.replace(re,\"\"); }\n else if (re4.test(w)) { w = w + \"e\"; }\n }\n }\n\n // Step 1c - replace suffix y or Y by i if preceded by a non-vowel which is not the first letter of the word (so cry -> cri, by -> by, say -> say)\n re = re_1c;\n if (re.test(w)) {\n var fp = re.exec(w);\n stem = fp[1];\n w = stem + \"i\";\n }\n\n // Step 2\n re = re_2;\n if (re.test(w)) {\n var fp = re.exec(w);\n stem = fp[1];\n suffix = fp[2];\n re = re_mgr0;\n if (re.test(stem)) {\n w = stem + step2list[suffix];\n }\n }\n\n // Step 3\n re = re_3;\n if (re.test(w)) {\n var fp = re.exec(w);\n stem = fp[1];\n suffix = fp[2];\n re = re_mgr0;\n if (re.test(stem)) {\n w = stem + step3list[suffix];\n }\n }\n\n // Step 4\n re = re_4;\n re2 = re2_4;\n if (re.test(w)) {\n var fp = re.exec(w);\n stem = fp[1];\n re = re_mgr1;\n if (re.test(stem)) {\n w = stem;\n }\n } else if (re2.test(w)) {\n var fp = re2.exec(w);\n stem = fp[1] + fp[2];\n re2 = re_mgr1;\n if (re2.test(stem)) {\n w = stem;\n }\n }\n\n // Step 5\n re = re_5;\n if (re.test(w)) {\n var fp = re.exec(w);\n stem = fp[1];\n re = re_mgr1;\n re2 = re_meq1;\n re3 = re3_5;\n if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) {\n w = stem;\n }\n }\n\n re = re_5_1;\n re2 = re_mgr1;\n if (re.test(w) && re2.test(w)) {\n re = re_1b_2;\n w = w.replace(re,\"\");\n }\n\n // and turn initial Y back to y\n\n if (firstch == \"y\") {\n w = firstch.toLowerCase() + w.substr(1);\n }\n\n return w;\n };\n\n return porterStemmer;\n})();\n\nelasticlunr.Pipeline.registerFunction(elasticlunr.stemmer, 'stemmer');\n/*!\n * elasticlunr.stopWordFilter\n * Copyright (C) 2016 Oliver Nightingale\n * Copyright (C) 2016 Wei Song\n */\n\n/**\n * elasticlunr.stopWordFilter is an English language stop words filter, any words\n * contained in the stop word list will not be passed through the filter.\n *\n * This is intended to be used in the Pipeline. If the token does not pass the\n * filter then undefined will be returned.\n * Currently this StopwordFilter using dictionary to do O(1) time complexity stop word filtering.\n *\n * @module\n * @param {String} token The token to pass through the filter\n * @return {String}\n * @see elasticlunr.Pipeline\n */\nelasticlunr.stopWordFilter = function (token) {\n if (token && elasticlunr.stopWordFilter.stopWords[token] !== true) {\n return token;\n }\n};\n\n/**\n * Remove predefined stop words\n * if user want to use customized stop words, user could use this function to delete\n * all predefined stopwords.\n *\n * @return {null}\n */\nelasticlunr.clearStopWords = function () {\n elasticlunr.stopWordFilter.stopWords = {};\n};\n\n/**\n * Add customized stop words\n * user could use this function to add customized stop words\n * \n * @params {Array} words customized stop words\n * @return {null}\n */\nelasticlunr.addStopWords = function (words) {\n if (words == null || Array.isArray(words) === false) return;\n\n words.forEach(function (word) {\n elasticlunr.stopWordFilter.stopWords[word] = true;\n }, this);\n};\n\n/**\n * Reset to default stop words\n * user could use this function to restore default stop words\n *\n * @return {null}\n */\nelasticlunr.resetStopWords = function () {\n elasticlunr.stopWordFilter.stopWords = elasticlunr.defaultStopWords;\n};\n\nelasticlunr.defaultStopWords = {\n \"\": true,\n \"a\": true,\n \"able\": true,\n \"about\": true,\n \"across\": true,\n \"after\": true,\n \"all\": true,\n \"almost\": true,\n \"also\": true,\n \"am\": true,\n \"among\": true,\n \"an\": true,\n \"and\": true,\n \"any\": true,\n \"are\": true,\n \"as\": true,\n \"at\": true,\n \"be\": true,\n \"because\": true,\n \"been\": true,\n \"but\": true,\n \"by\": true,\n \"can\": true,\n \"cannot\": true,\n \"could\": true,\n \"dear\": true,\n \"did\": true,\n \"do\": true,\n \"does\": true,\n \"either\": true,\n \"else\": true,\n \"ever\": true,\n \"every\": true,\n \"for\": true,\n \"from\": true,\n \"get\": true,\n \"got\": true,\n \"had\": true,\n \"has\": true,\n \"have\": true,\n \"he\": true,\n \"her\": true,\n \"hers\": true,\n \"him\": true,\n \"his\": true,\n \"how\": true,\n \"however\": true,\n \"i\": true,\n \"if\": true,\n \"in\": true,\n \"into\": true,\n \"is\": true,\n \"it\": true,\n \"its\": true,\n \"just\": true,\n \"least\": true,\n \"let\": true,\n \"like\": true,\n \"likely\": true,\n \"may\": true,\n \"me\": true,\n \"might\": true,\n \"most\": true,\n \"must\": true,\n \"my\": true,\n \"neither\": true,\n \"no\": true,\n \"nor\": true,\n \"not\": true,\n \"of\": true,\n \"off\": true,\n \"often\": true,\n \"on\": true,\n \"only\": true,\n \"or\": true,\n \"other\": true,\n \"our\": true,\n \"own\": true,\n \"rather\": true,\n \"said\": true,\n \"say\": true,\n \"says\": true,\n \"she\": true,\n \"should\": true,\n \"since\": true,\n \"so\": true,\n \"some\": true,\n \"than\": true,\n \"that\": true,\n \"the\": true,\n \"their\": true,\n \"them\": true,\n \"then\": true,\n \"there\": true,\n \"these\": true,\n \"they\": true,\n \"this\": true,\n \"tis\": true,\n \"to\": true,\n \"too\": true,\n \"twas\": true,\n \"us\": true,\n \"wants\": true,\n \"was\": true,\n \"we\": true,\n \"were\": true,\n \"what\": true,\n \"when\": true,\n \"where\": true,\n \"which\": true,\n \"while\": true,\n \"who\": true,\n \"whom\": true,\n \"why\": true,\n \"will\": true,\n \"with\": true,\n \"would\": true,\n \"yet\": true,\n \"you\": true,\n \"your\": true\n};\n\nelasticlunr.stopWordFilter.stopWords = elasticlunr.defaultStopWords;\n\nelasticlunr.Pipeline.registerFunction(elasticlunr.stopWordFilter, 'stopWordFilter');\n/*!\n * elasticlunr.trimmer\n * Copyright (C) 2016 Oliver Nightingale\n * Copyright (C) 2016 Wei Song\n */\n\n/**\n * elasticlunr.trimmer is a pipeline function for trimming non word\n * characters from the begining and end of tokens before they\n * enter the index.\n *\n * This implementation may not work correctly for non latin\n * characters and should either be removed or adapted for use\n * with languages with non-latin characters.\n *\n * @module\n * @param {String} token The token to pass through the filter\n * @return {String}\n * @see elasticlunr.Pipeline\n */\nelasticlunr.trimmer = function (token) {\n if (token === null || token === undefined) {\n throw new Error('token should not be undefined');\n }\n\n return token\n .replace(/^\\W+/, '')\n .replace(/\\W+$/, '');\n};\n\nelasticlunr.Pipeline.registerFunction(elasticlunr.trimmer, 'trimmer');\n/*!\n * elasticlunr.InvertedIndex\n * Copyright (C) 2016 Wei Song\n * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt\n */\n\n/**\n * elasticlunr.InvertedIndex is used for efficiently storing and\n * lookup of documents that contain a given token.\n *\n * @constructor\n */\nelasticlunr.InvertedIndex = function () {\n this.root = { docs: {}, df: 0 };\n};\n\n/**\n * Loads a previously serialised inverted index.\n *\n * @param {Object} serialisedData The serialised inverted index to load.\n * @return {elasticlunr.InvertedIndex}\n */\nelasticlunr.InvertedIndex.load = function (serialisedData) {\n var idx = new this;\n idx.root = serialisedData.root;\n\n return idx;\n};\n\n/**\n * Adds a {token: tokenInfo} pair to the inverted index.\n * If the token already exist, then update the tokenInfo.\n *\n * tokenInfo format: { ref: 1, tf: 2}\n * tokenInfor should contains the document's ref and the tf(token frequency) of that token in\n * the document.\n *\n * By default this function starts at the root of the current inverted index, however\n * it can start at any node of the inverted index if required.\n *\n * @param {String} token \n * @param {Object} tokenInfo format: { ref: 1, tf: 2}\n * @param {Object} root An optional node at which to start looking for the\n * correct place to enter the doc, by default the root of this elasticlunr.InvertedIndex\n * is used.\n * @memberOf InvertedIndex\n */\nelasticlunr.InvertedIndex.prototype.addToken = function (token, tokenInfo, root) {\n var root = root || this.root,\n idx = 0;\n\n while (idx <= token.length - 1) {\n var key = token[idx];\n\n if (!(key in root)) root[key] = {docs: {}, df: 0};\n idx += 1;\n root = root[key];\n }\n\n var docRef = tokenInfo.ref;\n if (!root.docs[docRef]) {\n // if this doc not exist, then add this doc\n root.docs[docRef] = {tf: tokenInfo.tf};\n root.df += 1;\n } else {\n // if this doc already exist, then update tokenInfo\n root.docs[docRef] = {tf: tokenInfo.tf};\n }\n};\n\n/**\n * Checks whether a token is in this elasticlunr.InvertedIndex.\n * \n *\n * @param {String} token The token to be checked\n * @return {Boolean}\n * @memberOf InvertedIndex\n */\nelasticlunr.InvertedIndex.prototype.hasToken = function (token) {\n if (!token) return false;\n\n var node = this.root;\n\n for (var i = 0; i < token.length; i++) {\n if (!node[token[i]]) return false;\n node = node[token[i]];\n }\n\n return true;\n};\n\n/**\n * Retrieve a node from the inverted index for a given token.\n * If token not found in this InvertedIndex, return null.\n * \n *\n * @param {String} token The token to get the node for.\n * @return {Object}\n * @see InvertedIndex.prototype.get\n * @memberOf InvertedIndex\n */\nelasticlunr.InvertedIndex.prototype.getNode = function (token) {\n if (!token) return null;\n\n var node = this.root;\n\n for (var i = 0; i < token.length; i++) {\n if (!node[token[i]]) return null;\n node = node[token[i]];\n }\n\n return node;\n};\n\n/**\n * Retrieve the documents of a given token.\n * If token not found, return {}.\n *\n *\n * @param {String} token The token to get the documents for.\n * @return {Object}\n * @memberOf InvertedIndex\n */\nelasticlunr.InvertedIndex.prototype.getDocs = function (token) {\n var node = this.getNode(token);\n if (node == null) {\n return {};\n }\n\n return node.docs;\n};\n\n/**\n * Retrieve term frequency of given token in given docRef.\n * If token or docRef not found, return 0.\n *\n *\n * @param {String} token The token to get the documents for.\n * @param {String|Integer} docRef\n * @return {Integer}\n * @memberOf InvertedIndex\n */\nelasticlunr.InvertedIndex.prototype.getTermFrequency = function (token, docRef) {\n var node = this.getNode(token);\n\n if (node == null) {\n return 0;\n }\n\n if (!(docRef in node.docs)) {\n return 0;\n }\n\n return node.docs[docRef].tf;\n};\n\n/**\n * Retrieve the document frequency of given token.\n * If token not found, return 0.\n *\n *\n * @param {String} token The token to get the documents for.\n * @return {Object}\n * @memberOf InvertedIndex\n */\nelasticlunr.InvertedIndex.prototype.getDocFreq = function (token) {\n var node = this.getNode(token);\n\n if (node == null) {\n return 0;\n }\n\n return node.df;\n};\n\n/**\n * Remove the document identified by document's ref from the token in the inverted index.\n *\n *\n * @param {String} token Remove the document from which token.\n * @param {String} ref The ref of the document to remove from given token.\n * @memberOf InvertedIndex\n */\nelasticlunr.InvertedIndex.prototype.removeToken = function (token, ref) {\n if (!token) return;\n var node = this.getNode(token);\n\n if (node == null) return;\n\n if (ref in node.docs) {\n delete node.docs[ref];\n node.df -= 1;\n }\n};\n\n/**\n * Find all the possible suffixes of given token using tokens currently in the inverted index.\n * If token not found, return empty Array.\n *\n * @param {String} token The token to expand.\n * @return {Array}\n * @memberOf InvertedIndex\n */\nelasticlunr.InvertedIndex.prototype.expandToken = function (token, memo, root) {\n if (token == null || token == '') return [];\n var memo = memo || [];\n\n if (root == void 0) {\n root = this.getNode(token);\n if (root == null) return memo;\n }\n\n if (root.df > 0) memo.push(token);\n\n for (var key in root) {\n if (key === 'docs') continue;\n if (key === 'df') continue;\n this.expandToken(token + key, memo, root[key]);\n }\n\n return memo;\n};\n\n/**\n * Returns a representation of the inverted index ready for serialisation.\n *\n * @return {Object}\n * @memberOf InvertedIndex\n */\nelasticlunr.InvertedIndex.prototype.toJSON = function () {\n return {\n root: this.root\n };\n};\n\n/*!\n * elasticlunr.Configuration\n * Copyright (C) 2016 Wei Song\n */\n \n /** \n * elasticlunr.Configuration is used to analyze the user search configuration.\n * \n * By elasticlunr.Configuration user could set query-time boosting, boolean model in each field.\n * \n * Currently configuration supports:\n * 1. query-time boosting, user could set how to boost each field.\n * 2. boolean model chosing, user could choose which boolean model to use for each field.\n * 3. token expandation, user could set token expand to True to improve Recall. Default is False.\n * \n * Query time boosting must be configured by field category, \"boolean\" model could be configured \n * by both field category or globally as the following example. Field configuration for \"boolean\"\n * will overwrite global configuration.\n * Token expand could be configured both by field category or golbally. Local field configuration will\n * overwrite global configuration.\n * \n * configuration example:\n * {\n * fields:{ \n * title: {boost: 2},\n * body: {boost: 1}\n * },\n * bool: \"OR\"\n * }\n * \n * \"bool\" field configuation overwrite global configuation example:\n * {\n * fields:{ \n * title: {boost: 2, bool: \"AND\"},\n * body: {boost: 1}\n * },\n * bool: \"OR\"\n * }\n * \n * \"expand\" example:\n * {\n * fields:{ \n * title: {boost: 2, bool: \"AND\"},\n * body: {boost: 1}\n * },\n * bool: \"OR\",\n * expand: true\n * }\n * \n * \"expand\" example for field category:\n * {\n * fields:{ \n * title: {boost: 2, bool: \"AND\", expand: true},\n * body: {boost: 1}\n * },\n * bool: \"OR\"\n * }\n * \n * setting the boost to 0 ignores the field (this will only search the title):\n * {\n * fields:{\n * title: {boost: 1},\n * body: {boost: 0}\n * }\n * }\n *\n * then, user could search with configuration to do query-time boosting.\n * idx.search('oracle database', {fields: {title: {boost: 2}, body: {boost: 1}}});\n * \n * \n * @constructor\n * \n * @param {String} config user configuration\n * @param {Array} fields fields of index instance\n * @module\n */\nelasticlunr.Configuration = function (config, fields) {\n var config = config || '';\n\n if (fields == undefined || fields == null) {\n throw new Error('fields should not be null');\n }\n\n this.config = {};\n\n var userConfig;\n try {\n userConfig = JSON.parse(config);\n this.buildUserConfig(userConfig, fields);\n } catch (error) {\n elasticlunr.utils.warn('user configuration parse failed, will use default configuration');\n this.buildDefaultConfig(fields);\n }\n};\n\n/**\n * Build default search configuration.\n * \n * @param {Array} fields fields of index instance\n */\nelasticlunr.Configuration.prototype.buildDefaultConfig = function (fields) {\n this.reset();\n fields.forEach(function (field) {\n this.config[field] = {\n boost: 1,\n bool: \"OR\",\n expand: false\n };\n }, this);\n};\n\n/**\n * Build user configuration.\n * \n * @param {JSON} config User JSON configuratoin\n * @param {Array} fields fields of index instance\n */\nelasticlunr.Configuration.prototype.buildUserConfig = function (config, fields) {\n var global_bool = \"OR\";\n var global_expand = false;\n\n this.reset();\n if ('bool' in config) {\n global_bool = config['bool'] || global_bool;\n }\n\n if ('expand' in config) {\n global_expand = config['expand'] || global_expand;\n }\n\n if ('fields' in config) {\n for (var field in config['fields']) {\n if (fields.indexOf(field) > -1) {\n var field_config = config['fields'][field];\n var field_expand = global_expand;\n if (field_config.expand != undefined) {\n field_expand = field_config.expand;\n }\n\n this.config[field] = {\n boost: (field_config.boost || field_config.boost === 0) ? field_config.boost : 1,\n bool: field_config.bool || global_bool,\n expand: field_expand\n };\n } else {\n elasticlunr.utils.warn('field name in user configuration not found in index instance fields');\n }\n }\n } else {\n this.addAllFields2UserConfig(global_bool, global_expand, fields);\n }\n};\n\n/**\n * Add all fields to user search configuration.\n * \n * @param {String} bool Boolean model\n * @param {String} expand Expand model\n * @param {Array} fields fields of index instance\n */\nelasticlunr.Configuration.prototype.addAllFields2UserConfig = function (bool, expand, fields) {\n fields.forEach(function (field) {\n this.config[field] = {\n boost: 1,\n bool: bool,\n expand: expand\n };\n }, this);\n};\n\n/**\n * get current user configuration\n */\nelasticlunr.Configuration.prototype.get = function () {\n return this.config;\n};\n\n/**\n * reset user search configuration.\n */\nelasticlunr.Configuration.prototype.reset = function () {\n this.config = {};\n};\n/**\n * sorted_set.js is added only to make elasticlunr.js compatible with lunr-languages.\n * if elasticlunr.js support different languages by default, this will make elasticlunr.js\n * much bigger that not good for browser usage.\n *\n */\n\n\n/*!\n * lunr.SortedSet\n * Copyright (C) 2016 Oliver Nightingale\n */\n\n/**\n * lunr.SortedSets are used to maintain an array of uniq values in a sorted\n * order.\n *\n * @constructor\n */\nlunr.SortedSet = function () {\n this.length = 0\n this.elements = []\n}\n\n/**\n * Loads a previously serialised sorted set.\n *\n * @param {Array} serialisedData The serialised set to load.\n * @returns {lunr.SortedSet}\n * @memberOf SortedSet\n */\nlunr.SortedSet.load = function (serialisedData) {\n var set = new this\n\n set.elements = serialisedData\n set.length = serialisedData.length\n\n return set\n}\n\n/**\n * Inserts new items into the set in the correct position to maintain the\n * order.\n *\n * @param {Object} The objects to add to this set.\n * @memberOf SortedSet\n */\nlunr.SortedSet.prototype.add = function () {\n var i, element\n\n for (i = 0; i < arguments.length; i++) {\n element = arguments[i]\n if (~this.indexOf(element)) continue\n this.elements.splice(this.locationFor(element), 0, element)\n }\n\n this.length = this.elements.length\n}\n\n/**\n * Converts this sorted set into an array.\n *\n * @returns {Array}\n * @memberOf SortedSet\n */\nlunr.SortedSet.prototype.toArray = function () {\n return this.elements.slice()\n}\n\n/**\n * Creates a new array with the results of calling a provided function on every\n * element in this sorted set.\n *\n * Delegates to Array.prototype.map and has the same signature.\n *\n * @param {Function} fn The function that is called on each element of the\n * set.\n * @param {Object} ctx An optional object that can be used as the context\n * for the function fn.\n * @returns {Array}\n * @memberOf SortedSet\n */\nlunr.SortedSet.prototype.map = function (fn, ctx) {\n return this.elements.map(fn, ctx)\n}\n\n/**\n * Executes a provided function once per sorted set element.\n *\n * Delegates to Array.prototype.forEach and has the same signature.\n *\n * @param {Function} fn The function that is called on each element of the\n * set.\n * @param {Object} ctx An optional object that can be used as the context\n * @memberOf SortedSet\n * for the function fn.\n */\nlunr.SortedSet.prototype.forEach = function (fn, ctx) {\n return this.elements.forEach(fn, ctx)\n}\n\n/**\n * Returns the index at which a given element can be found in the\n * sorted set, or -1 if it is not present.\n *\n * @param {Object} elem The object to locate in the sorted set.\n * @returns {Number}\n * @memberOf SortedSet\n */\nlunr.SortedSet.prototype.indexOf = function (elem) {\n var start = 0,\n end = this.elements.length,\n sectionLength = end - start,\n pivot = start + Math.floor(sectionLength / 2),\n pivotElem = this.elements[pivot]\n\n while (sectionLength > 1) {\n if (pivotElem === elem) return pivot\n\n if (pivotElem < elem) start = pivot\n if (pivotElem > elem) end = pivot\n\n sectionLength = end - start\n pivot = start + Math.floor(sectionLength / 2)\n pivotElem = this.elements[pivot]\n }\n\n if (pivotElem === elem) return pivot\n\n return -1\n}\n\n/**\n * Returns the position within the sorted set that an element should be\n * inserted at to maintain the current order of the set.\n *\n * This function assumes that the element to search for does not already exist\n * in the sorted set.\n *\n * @param {Object} elem The elem to find the position for in the set\n * @returns {Number}\n * @memberOf SortedSet\n */\nlunr.SortedSet.prototype.locationFor = function (elem) {\n var start = 0,\n end = this.elements.length,\n sectionLength = end - start,\n pivot = start + Math.floor(sectionLength / 2),\n pivotElem = this.elements[pivot]\n\n while (sectionLength > 1) {\n if (pivotElem < elem) start = pivot\n if (pivotElem > elem) end = pivot\n\n sectionLength = end - start\n pivot = start + Math.floor(sectionLength / 2)\n pivotElem = this.elements[pivot]\n }\n\n if (pivotElem > elem) return pivot\n if (pivotElem < elem) return pivot + 1\n}\n\n/**\n * Creates a new lunr.SortedSet that contains the elements in the intersection\n * of this set and the passed set.\n *\n * @param {lunr.SortedSet} otherSet The set to intersect with this set.\n * @returns {lunr.SortedSet}\n * @memberOf SortedSet\n */\nlunr.SortedSet.prototype.intersect = function (otherSet) {\n var intersectSet = new lunr.SortedSet,\n i = 0, j = 0,\n a_len = this.length, b_len = otherSet.length,\n a = this.elements, b = otherSet.elements\n\n while (true) {\n if (i > a_len - 1 || j > b_len - 1) break\n\n if (a[i] === b[j]) {\n intersectSet.add(a[i])\n i++, j++\n continue\n }\n\n if (a[i] < b[j]) {\n i++\n continue\n }\n\n if (a[i] > b[j]) {\n j++\n continue\n }\n };\n\n return intersectSet\n}\n\n/**\n * Makes a copy of this set\n *\n * @returns {lunr.SortedSet}\n * @memberOf SortedSet\n */\nlunr.SortedSet.prototype.clone = function () {\n var clone = new lunr.SortedSet\n\n clone.elements = this.toArray()\n clone.length = clone.elements.length\n\n return clone\n}\n\n/**\n * Creates a new lunr.SortedSet that contains the elements in the union\n * of this set and the passed set.\n *\n * @param {lunr.SortedSet} otherSet The set to union with this set.\n * @returns {lunr.SortedSet}\n * @memberOf SortedSet\n */\nlunr.SortedSet.prototype.union = function (otherSet) {\n var longSet, shortSet, unionSet\n\n if (this.length >= otherSet.length) {\n longSet = this, shortSet = otherSet\n } else {\n longSet = otherSet, shortSet = this\n }\n\n unionSet = longSet.clone()\n\n for(var i = 0, shortSetElements = shortSet.toArray(); i < shortSetElements.length; i++){\n unionSet.add(shortSetElements[i])\n }\n\n return unionSet\n}\n\n/**\n * Returns a representation of the sorted set ready for serialisation.\n *\n * @returns {Array}\n * @memberOf SortedSet\n */\nlunr.SortedSet.prototype.toJSON = function () {\n return this.toArray()\n}\n /**\n * export the module via AMD, CommonJS or as a browser global\n * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js\n */\n ;(function (root, factory) {\n if (typeof define === 'function' && define.amd) {\n // AMD. Register as an anonymous module.\n define(factory)\n } else if (typeof exports === 'object') {\n /**\n * Node. Does not work with strict CommonJS, but\n * only CommonJS-like enviroments that support module.exports,\n * like Node.\n */\n module.exports = factory()\n } else {\n // Browser globals (root is window)\n root.elasticlunr = factory()\n }\n }(this, function () {\n /**\n * Just return a value to define the module export.\n * This example returns an object, but the module\n * can return a function as the exported value.\n */\n return elasticlunr\n }))\n})();\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { useStaticQuery, graphql } from 'gatsby';\n\nconst detailsQuery = graphql`\n query DefaultSEOQuery {\n site {\n siteMetadata {\n title\n description\n }\n }\n }\n`;\n\nexport const useSiteMetadata = () => {\n const data = useStaticQuery(detailsQuery);\n\n return data.site.siteMetadata;\n};\n\nfunction SEO({ title, description, location, keywords }) {\n const { title: defaultTitle, description: defaultDescription, siteUrl } = useSiteMetadata();\n\n const seo = {\n title: `${title} | ${defaultTitle}` || defaultTitle,\n description: description || defaultDescription,\n url: `${siteUrl}${location.pathname || ''}`,\n };\n\n return (\n <>\n {seo.title}\n \n \n \n \n \n {keywords && }\n \n );\n}\n\nSEO.defaultProps = {\n keywords: [],\n description: undefined,\n};\n\nSEO.propTypes = {\n keywords: PropTypes.arrayOf(PropTypes.string),\n title: PropTypes.string.isRequired,\n description: PropTypes.string,\n location: PropTypes.shape({\n pathname: PropTypes.string.isRequired,\n }).isRequired,\n};\n\nexport default SEO;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { graphql, Link } from 'gatsby';\nimport { css } from '@emotion/react';\nimport { Index } from 'elasticlunr';\nimport SEO from '../components/seo';\n\nfunction search(index, query) {\n const results = index\n // Query the index with search string to get an [] of IDs\n .search(query, { expand: true })\n // Map over each ID and return the full document\n .map(({ ref }) => index.documentStore.getDoc(ref));\n\n return results;\n}\n\nfunction SearchPage(props) {\n const { location, data } = props;\n const searchParams = new URLSearchParams(location.search);\n const query = searchParams.get('query');\n\n // Create an elastic lunr index and hydrate with graphql query results\n const index = React.useMemo(\n () => Index.load(data.siteSearchIndex.index),\n [data.siteSearchIndex.index]\n );\n const [results, setResults] = React.useState([]);\n\n React.useEffect(() => {\n setResults(search(index, query));\n }, [index, query]);\n\n return (\n <>\n

{`Search Results for: ${query}`}

\n {results.map((page) => (\n
\n

\n \n {page.title}\n \n

\n

\n {page.excerpt}{' '}\n \n Continue reading →\n \n

\n
\n ))}\n \n );\n}\n\nexport default SearchPage;\n\nexport const query = graphql`\n query SearchIndexQuery {\n siteSearchIndex {\n index\n }\n }\n`;\n\nSearchPage.propTypes = {\n data: PropTypes.shape({\n siteSearchIndex: PropTypes.shape({\n index: PropTypes.shape({ documentStore: PropTypes.shape({}).isRequired }).isRequired,\n }).isRequired,\n }).isRequired,\n location: PropTypes.shape({\n search: PropTypes.string,\n }).isRequired,\n};\n\nexport function Head(props) {\n // eslint-disable-next-line react/jsx-props-no-spreading\n return ;\n}\n"],"names":["global","step2list","step3list","v","C","V","meq1","mgr1","s_v","re_mgr0","re_mgr1","re_meq1","re_s_v","re_1a","re2_1a","re_1b","re2_1b","re_1b_2","re2_1b_2","re3_1b_2","re4_1b_2","re_1c","re_2","re_3","re_4","re2_4","re_5","re_5_1","re3_5","elasticlunr","config","idx","Index","pipeline","add","trimmer","stopWordFilter","stemmer","call","version","lunr","utils","warn","this","message","console","toString","obj","EventEmitter","events","prototype","addListener","args","Array","slice","arguments","fn","pop","names","TypeError","forEach","name","hasHandler","push","removeListener","fnIndex","indexOf","splice","length","emit","apply","undefined","tokenizer","str","isArray","arr","filter","token","map","t","toLowerCase","out","item","tokens","split","seperator","concat","trim","defaultSeperator","setSeperator","sep","resetSeperator","getSeperator","Pipeline","_queue","registeredFunctions","registerFunction","label","getRegisteredFunction","warnIfFunctionNotRegistered","load","serialised","fnName","Error","after","existingFn","newFn","pos","before","remove","run","tokenLength","pipelineLength","i","j","reset","get","toJSON","_fields","_ref","documentStore","DocumentStore","index","eventEmitter","_idfCache","on","bind","off","serialisedData","field","fields","ref","InvertedIndex","addField","fieldName","setRef","refName","saveDocument","save","addDoc","doc","emitEvent","docRef","fieldTokens","addFieldLength","tokenCount","termFrequency","Math","sqrt","addToken","tf","removeDocByRef","isDocStored","hasDoc","getDoc","removeDoc","removeToken","updateDoc","idf","term","cacheKey","Object","hasOwnProperty","df","getDocFreq","log","getFields","search","query","userConfig","configStr","JSON","stringify","Configuration","queryTokens","queryResults","fieldSearchResults","fieldSearch","fieldBoost","boost","results","score","sort","a","b","booleanType","bool","expand","scores","docTokens","expandToken","queryTokenScores","key","docs","getDocs","filteredDocs","fieldSearchStats","getTermFrequency","fieldLength","getFieldLength","fieldLengthNorm","penality","mergeScores","coordNorm","accumScores","op","intersection","n","indexJson","use","plugin","unshift","_save","docInfo","store","copy","constructor","attr","clone","updateFieldLength","c","RegExp","w","stem","suffix","firstch","re","re2","re3","re4","substr","toUpperCase","test","replace","fp","exec","stopWords","clearStopWords","addStopWords","words","word","resetStopWords","defaultStopWords","root","tokenInfo","hasToken","node","getNode","memo","parse","buildUserConfig","error","buildDefaultConfig","global_bool","global_expand","field_config","field_expand","addAllFields2UserConfig","SortedSet","elements","set","element","locationFor","toArray","ctx","elem","start","end","sectionLength","pivot","floor","pivotElem","intersect","otherSet","intersectSet","a_len","b_len","union","longSet","shortSet","unionSet","shortSetElements","SEO","title","description","location","keywords","defaultTitle","defaultDescription","siteUrl","useStaticQuery","site","siteMetadata","seo","url","pathname","___EmotionJSX","React","content","join","defaultProps","styles","_ref2","props","data","URLSearchParams","siteSearchIndex","setResults","_ref3","page","slug","Link","css","to","excerpt","Head","_extends"],"sourceRoot":""} \ No newline at end of file diff --git a/component---src-templates-default-jsx-35953ea5596af52b66d9.js b/component---src-templates-default-jsx-35953ea5596af52b66d9.js new file mode 100644 index 000000000..25619a902 --- /dev/null +++ b/component---src-templates-default-jsx-35953ea5596af52b66d9.js @@ -0,0 +1,2 @@ +"use strict";(self.webpackChunkicatproject_github_io=self.webpackChunkicatproject_github_io||[]).push([[993],{2059:function(t,e,a){var n=a(7294),o=a(4854),i=a(6298);function r(t){let{title:e,description:a,location:r,keywords:c}=t;const{title:l,description:s,siteUrl:d}=(0,o.useStaticQuery)("3248290905").site.siteMetadata,u={title:e+" | "+l||l,description:a||s,url:""+d+(r.pathname||"")};return(0,i.tZ)(n.Fragment,null,(0,i.tZ)("title",null,u.title),(0,i.tZ)("meta",{name:"description",content:u.description}),(0,i.tZ)("meta",{name:"og:title",content:e}),(0,i.tZ)("meta",{name:"og:description",content:u.description}),(0,i.tZ)("meta",{name:"og:type",content:"website"}),(0,i.tZ)("meta",{name:"google-site-verification",content:"9X6CrnxO5Y0COmvYo15fcva3BeU-Qd8XSu5xWV44EDM"}),c&&(0,i.tZ)("meta",{name:"keywords",content:c.join(", ")}))}r.defaultProps={keywords:[],description:void 0},e.Z=r},6884:function(t,e,a){a.r(e),a.d(e,{Head:function(){return l}});var n=a(7462),o=a(7294),i=a(2059),r=a(6298);var c={name:"1otnndv",styles:"font-weight:300;text-transform:uppercase;font-size:33px"};e.default=function(t){let{data:e}=t;const a=e.markdownRemark;return(0,r.tZ)(o.Fragment,null,(0,r.tZ)("h1",{css:c},a.frontmatter.title),(0,r.tZ)("div",{dangerouslySetInnerHTML:{__html:a.html}}))};function l(t){let{data:e,...a}=t;return(0,r.tZ)(i.Z,(0,n.Z)({title:e.markdownRemark.frontmatter.title,keywords:["ICAT","ICAT data","ICAT metadata","ICAT catalogue","ICAT catalog","data catalogue","data catalog","metadata catalogue","metadata catalog","ICAT project","ICAT software"]},a))}}}]); +//# sourceMappingURL=component---src-templates-default-jsx-35953ea5596af52b66d9.js.map \ No newline at end of file diff --git a/component---src-templates-default-jsx-35953ea5596af52b66d9.js.map b/component---src-templates-default-jsx-35953ea5596af52b66d9.js.map new file mode 100644 index 000000000..6cc14fe14 --- /dev/null +++ b/component---src-templates-default-jsx-35953ea5596af52b66d9.js.map @@ -0,0 +1 @@ +{"version":3,"file":"component---src-templates-default-jsx-35953ea5596af52b66d9.js","mappings":"qKAqBA,SAASA,EAAGC,GAA8C,IAA7C,MAAEC,EAAK,YAAEC,EAAW,SAAEC,EAAQ,SAAEC,GAAUJ,EACrD,MAAQC,MAAOI,EAAcH,YAAaI,EAAkB,QAAEC,IANjDC,EAAAA,EAAAA,gBAZG,cAcJC,KAAKC,aAMXC,EAAM,CACVV,MAAUA,EAAK,MAAMI,GAAkBA,EACvCH,YAAaA,GAAeI,EAC5BM,IAAI,GAAIL,GAAUJ,EAASU,UAAY,KAGzC,OACEC,EAAAA,EAAAA,IAAAC,EAAAA,SAAA,MACED,EAAAA,EAAAA,IAAA,aAAQH,EAAIV,QACZa,EAAAA,EAAAA,IAAA,QAAME,KAAK,cAAcC,QAASN,EAAIT,eACtCY,EAAAA,EAAAA,IAAA,QAAME,KAAK,WAAWC,QAAShB,KAC/Ba,EAAAA,EAAAA,IAAA,QAAME,KAAK,iBAAiBC,QAASN,EAAIT,eACzCY,EAAAA,EAAAA,IAAA,QAAME,KAAK,UAAUC,QAAQ,aAC7BH,EAAAA,EAAAA,IAAA,QAAME,KAAK,2BAA2BC,QAAQ,gDAC7Cb,IAAYU,EAAAA,EAAAA,IAAA,QAAME,KAAK,WAAWC,QAASb,EAASc,KAAK,QAGhE,CAEAnB,EAAIoB,aAAe,CACjBf,SAAU,GACVF,iBAAakB,GAYf,K,6GCrDoC,IAAApB,EAAA,CAAAgB,KAAA,UAAAK,OAAA,2DAqBpC,UAnBA,SAAwBC,GAAY,IAAX,KAAEC,GAAMD,EAC/B,MAAME,EAAOD,EAAKE,eAClB,OACEX,EAAAA,EAAAA,IAAAC,EAAAA,SAAA,MACED,EAAAA,EAAAA,IAAA,MACEY,IAAG1B,GAMFwB,EAAKG,YAAY1B,QAGpBa,EAAAA,EAAAA,IAAA,OAAKc,wBAAyB,CAAEC,OAAQL,EAAKM,QAGnD,EA8BO,SAASC,EAAIC,GAAqB,IAApB,KAAET,KAASU,GAAMD,EACpC,OACElB,EAAAA,EAAAA,IAACf,EAAAA,GACCmC,EAAAA,EAAAA,GAAA,CACAjC,MAAOsB,EAAKE,eAAeE,YAAY1B,MACvCG,SAAU,CACR,OACA,YACA,gBACA,iBACA,eACA,iBACA,eACA,qBACA,mBACA,eACA,kBAGE6B,GAGV,C","sources":["webpack://icatproject.github.io/./src/components/seo.jsx","webpack://icatproject.github.io/./src/templates/default.jsx"],"sourcesContent":["import React from 'react';\nimport PropTypes from 'prop-types';\nimport { useStaticQuery, graphql } from 'gatsby';\n\nconst detailsQuery = graphql`\n query DefaultSEOQuery {\n site {\n siteMetadata {\n title\n description\n }\n }\n }\n`;\n\nexport const useSiteMetadata = () => {\n const data = useStaticQuery(detailsQuery);\n\n return data.site.siteMetadata;\n};\n\nfunction SEO({ title, description, location, keywords }) {\n const { title: defaultTitle, description: defaultDescription, siteUrl } = useSiteMetadata();\n\n const seo = {\n title: `${title} | ${defaultTitle}` || defaultTitle,\n description: description || defaultDescription,\n url: `${siteUrl}${location.pathname || ''}`,\n };\n\n return (\n <>\n {seo.title}\n \n \n \n \n \n {keywords && }\n \n );\n}\n\nSEO.defaultProps = {\n keywords: [],\n description: undefined,\n};\n\nSEO.propTypes = {\n keywords: PropTypes.arrayOf(PropTypes.string),\n title: PropTypes.string.isRequired,\n description: PropTypes.string,\n location: PropTypes.shape({\n pathname: PropTypes.string.isRequired,\n }).isRequired,\n};\n\nexport default SEO;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { graphql } from 'gatsby';\nimport { css } from '@emotion/react';\nimport SEO from '../components/seo';\n\nfunction DefaultTemplate({ data }) {\n const post = data.markdownRemark;\n return (\n <>\n \n {post.frontmatter.title}\n \n {/* eslint-disable-next-line react/no-danger */}\n
\n \n );\n}\n\nexport default DefaultTemplate;\n\nexport const query = graphql`\n query ($slug: String!) {\n markdownRemark(fields: { slug: { eq: $slug } }) {\n html\n frontmatter {\n title\n date\n }\n }\n }\n`;\n\nDefaultTemplate.propTypes = {\n data: PropTypes.shape({\n markdownRemark: PropTypes.shape({\n html: PropTypes.string.isRequired,\n frontmatter: PropTypes.shape({\n title: PropTypes.string.isRequired,\n date: PropTypes.string,\n }).isRequired,\n }).isRequired,\n }).isRequired,\n};\n\n// can't use proptypes with special Gatsby Head component, so just ignore\n// eslint-disable-next-line react/prop-types\nexport function Head({ data, ...rest }) {\n return (\n \n );\n}\n"],"names":["SEO","_ref","title","description","location","keywords","defaultTitle","defaultDescription","siteUrl","useStaticQuery","site","siteMetadata","seo","url","pathname","___EmotionJSX","React","name","content","join","defaultProps","undefined","styles","_ref2","data","post","markdownRemark","css","frontmatter","dangerouslySetInnerHTML","__html","html","Head","_ref3","rest","_extends"],"sourceRoot":""} \ No newline at end of file diff --git a/f7587da1a9f1129664067985d0ce444e/developers.md b/f7587da1a9f1129664067985d0ce444e/developers.md new file mode 100644 index 000000000..bd53ccb3a --- /dev/null +++ b/f7587da1a9f1129664067985d0ce444e/developers.md @@ -0,0 +1,35 @@ +--- +title: developers +--- + +# Technical Architecture + +TODO: Describe the ICAT technical architecture ie. major dependencies, technologies (eg. REST), design patterns. Check and correct this, add links: +The major components of the ICAT software are written in Java with installation scripts and supporting utilities written in Python. The software is written for the Java Enterprise Edition platform and runs inside an application server such as Glassfish (or its successor, Paraya). The main Java/JavaEE APIs used are: + +- Java Persistence API (JPA) backed by MySQL or Oracle +- Apache HttpComponents +- Java Json ... +- Java REST API (JAX-RS) provided by Jersey? +- Apache Lucene for searching +- and more... + +ICAT uses Maven for the build system and jUnit for testing. + +# How To... + +TODO: with reference to [Component Guidelines](/collaboration/component-guidelines/), the icat.server [wiki](https://github.com/icatproject/icat.server/wiki) and the ids.server [wiki](https://github.com/icatproject/ids.server/wiki). + +- [How to set up a development environment](TODO) +- [How to build ICAT](TODO) +- [How to submit a patch](TODO) +- [How to write a storage plugin for the ICAT Data Service](TODO) + +# Reference Documentation + +TODO: link to JavaDoc? + +Each component has documentation automatically generated by Maven. TODO: information on what is contained in this documentation. The Maven documentation is available [here](https://repo.icatproject.org/site/). To find the Maven documentation for icat.server version 4.8.0, for example, either follow the links or append `icat/server/4.8.0/` to the URL. For convenience, the latest releases of the major components are listed below: + +- [ICAT Server 4.8.0](https://repo.icatproject.org/site/icat/server/4.8.0/) +- TODO: add more eg. IDS, auth, storage plugins diff --git a/favicon-32x32.png b/favicon-32x32.png new file mode 100644 index 000000000..cf91e7cdc Binary files /dev/null and b/favicon-32x32.png differ diff --git a/framework-90a8991a32ec86f12233.js b/framework-90a8991a32ec86f12233.js new file mode 100644 index 000000000..dba5c98af --- /dev/null +++ b/framework-90a8991a32ec86f12233.js @@ -0,0 +1,3 @@ +/*! For license information please see framework-90a8991a32ec86f12233.js.LICENSE.txt */ +(self.webpackChunkicatproject_github_io=self.webpackChunkicatproject_github_io||[]).push([[774],{2703:function(e,n,t){"use strict";var r=t(414);function l(){}function a(){}a.resetWarningCache=l,e.exports=function(){function e(e,n,t,l,a,o){if(o!==r){var u=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw u.name="Invariant Violation",u}}function n(){return e}e.isRequired=e;var t={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:n,element:e,elementType:e,instanceOf:n,node:e,objectOf:n,oneOf:n,oneOfType:n,shape:n,exact:n,checkPropTypes:a,resetWarningCache:l};return t.PropTypes=t,t}},5697:function(e,n,t){e.exports=t(2703)()},414:function(e){"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},4448:function(e,n,t){"use strict";var r=t(7294),l=t(3840);function a(e){for(var n="https://reactjs.org/docs/error-decoder.html?invariant="+e,t=1;t