diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/404.html b/404.html new file mode 100644 index 00000000..06564422 --- /dev/null +++ b/404.html @@ -0,0 +1,4059 @@ + + + + + + + + + + + + + + + + + + + + + + Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + +
+ +

404 - Not found

+ +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/CNAME b/CNAME new file mode 100644 index 00000000..5d2f2f45 --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +tac.openwallet.foundation diff --git a/SIGs/architecture/index.html b/SIGs/architecture/index.html new file mode 100644 index 00000000..38c6b5ef --- /dev/null +++ b/SIGs/architecture/index.html @@ -0,0 +1,4321 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Architecture - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Architecture Special Interest Group (SIG)

+

This SIG is focused on conversations related to the architecture of digital wallet engines.

+

This SIG was accepted by the TAC on April 5, 2023.

+

Participating

+

This SIG is an open group. Anyone in the OpenWallet Foundation community can join and participate. There is no formal sign up process. Just show up and participate.

+

Meetings

+

The architecture SIG meets weekly on Mondays at 11:00 AM US/Pacific time. For details, see architecture SIG meeting details. For past notes and recordings, see the architecture SIG wiki.

+

Discord

+

Please join the OpenWallet Foundation Discord and participate in the discussion in the #architecture-sig channel.

+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/SIGs/credential-format-comparison/index.html b/SIGs/credential-format-comparison/index.html new file mode 100644 index 00000000..351059b8 --- /dev/null +++ b/SIGs/credential-format-comparison/index.html @@ -0,0 +1,4269 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Credential Format Comparison - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Credential Format Comparison Special Interest Group (SIG)

+

This SIG is dedicated to maintaining information about available credential formats for the benefit of OWF projects and the wider community. The topic is more complex than one might assume on first sight, since there are more than 14 formats for representing digital credentials and most of those formats can be combined with different signature algorithms, ways to represent cryptographic keys (with alone more than a hundred DID methods), status management methods, trust management methods and so on.

+

There is pre-existing work started at Internet Identity Workshop (IIW 34, Spring 2022) and extended and augmented during Rebooting the Web of Trust (RWOT-XI, The Hague, Sept 2022).

+

It consists of a “credential format comparison matrix”, containing information about the technical options in the different dimensions (formats, signature algorithms, …) as well as known credential profiles, i.e. concrete combinations used in implementations and an article explaining the “matrix”.

+ +

This SIG was accepted by the TAC on May 31, 2023. See Credential Format Comparison SIG Proposal for more details.

+

Participating

+

This SIG is an open group. Anyone in the OpenWallet Foundation community can join and participate. There is no formal sign up process. Just show up and participate.

+

If you are interested in participating, please join the OpenWallet Foundation Discord and participate in the discussion in the #credential-format-comparison-sig channel.

+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/SIGs/digital-wallet-and-agent-overviews/index.html b/SIGs/digital-wallet-and-agent-overviews/index.html new file mode 100644 index 00000000..a8b7c35b --- /dev/null +++ b/SIGs/digital-wallet-and-agent-overviews/index.html @@ -0,0 +1,4262 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Digital Wallet and Agent Overviews - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Digital Wallet and Agent Overviews Special Interest Group (SIG)

+

The objectives of this SIG is to further develop and maintain the Digital Wallet Overview and making a similar overview for digital identity agents/SDKs. These overviews should provide transparency of the characteristics of wallets and agents in order to allow for comparison and effective decision making on which wallet is applicable for your use case. By creating awareness of these overviews, this work can lead to less fragmentation of the SSI playing field and increase adoption.

+

This SIG was accepted by the TAC on September 20, 2023. See Digital Wallet and Agent Overviews SIG Proposal for more details.

+

Participating

+

This SIG is an open group. Anyone in the OpenWallet Foundation community can join and participate. There is no formal sign up process. Just show up and participate.

+

If you are interested in participating, please join the OpenWallet Foundation Discord and participate in the discussion in the #digital-wallet-and-agent-overviews-sig channel.

+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/SIGs/index.html b/SIGs/index.html new file mode 100644 index 00000000..93188239 --- /dev/null +++ b/SIGs/index.html @@ -0,0 +1,4212 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Special Interest Groups (SIGs) - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Special Interest Groups (SIGs)

+

A special interest group (SIG) under the Technical Advisory Council (TAC) is a group with a shared interest in advancing a specific area of knowledge, learning, or technology related to the mission of the OpenWallet Foundation where members cooperate to affect or to produce solutions within their particular field. Unlike a task force, SIGs are typically long running and may or may not produce any deliverables. A SIG can be created by anyone in the OpenWallet Foundation community and must be proposed to and approved by the TAC.

+
+

Tip

+

If you would like to propose a Special Interest Group, please see the SIG proposal process.

+
+

Active SIGs

+ + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/SIGs/safe-wallet/index.html b/SIGs/safe-wallet/index.html new file mode 100644 index 00000000..6acfe1fd --- /dev/null +++ b/SIGs/safe-wallet/index.html @@ -0,0 +1,4262 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Safe Wallet - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Safe Wallet Special Interest Group (SIG)

+

This SIG will create, distribute and promote a set of material that will become the de-facto way to determine how "safe" the new breed of digital wallets is, and be able to compare them effectively. This will increase the visibility of the solutions to correlation and profiling issues that could be introduced with digital wallet deployments.

+

This SIG was accepted by the TAC on September 20, 2023. See Safe Wallet SIG Proposal for more details.

+

Participating

+

This SIG is an open group. Anyone in the OpenWallet Foundation community can join and participate. There is no formal sign up process. Just show up and participate.

+

If you are interested in participating, please join the OpenWallet Foundation Discord and participate in the discussion in the #safe-wallet-sig channel.

+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/SIGs/updates/2024/index.html b/SIGs/updates/2024/index.html new file mode 100644 index 00000000..40062a6c --- /dev/null +++ b/SIGs/updates/2024/index.html @@ -0,0 +1,4314 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 2024 Quarterly Updates - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

2024 Quarterly Updates

+

The Special Interest Groups (SIGs) must provide a quarterly update to the TAC to ensure that the SIG is still active and that there is still value in hosting the special interest group. The following calendar provides the timing for when these updates are required to be presented to the TAC:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
QuarterSpecial Interest GroupTAC Meeting
Q1Architecture SIG2024-01-10
Q1Credential Format Comparison SIG2024-02-07
Q1Digital Wallet and Agent Overviews SIG2024-02-21
Q1Safe Wallet SIG2024-03-06
Q2Architecture SIG2024-04-03
Q2Credential Format Comparison SIG2024-05-01
Q2Digital Wallet and Agent Overviews SIG72024-05-29
Q2Safe Wallet SIG2024-06-12
Q3Architecture SIG2024-07-10
Q3Credential Format Comparison SIG2024-07-24
Q3Digital Wallet and Agent Overviews SIG2024-08-07
Q3Safe Wallet SIG2024-08-21
Q4Architecture SIG2024-10-02
Q4Credential Format Comparison SIG2024-10-16
Q4Digital Wallet and Agent Overviews SIG2024-10-30
Q4Safe Wallet SIG2024-11-13
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/assets/governance/owf-content-plan.png b/assets/governance/owf-content-plan.png new file mode 100644 index 00000000..2d8668c5 Binary files /dev/null and b/assets/governance/owf-content-plan.png differ diff --git a/assets/images/favicon.png b/assets/images/favicon.png new file mode 100644 index 00000000..1cf13b9f Binary files /dev/null and b/assets/images/favicon.png differ diff --git a/assets/javascripts/bundle.6e7f53b1.min.js b/assets/javascripts/bundle.6e7f53b1.min.js new file mode 100644 index 00000000..014790f2 --- /dev/null +++ b/assets/javascripts/bundle.6e7f53b1.min.js @@ -0,0 +1,3 @@ +"use strict";(()=>{var Bi=Object.create;var _r=Object.defineProperty;var Gi=Object.getOwnPropertyDescriptor;var Ji=Object.getOwnPropertyNames,Bt=Object.getOwnPropertySymbols,Xi=Object.getPrototypeOf,Ar=Object.prototype.hasOwnProperty,uo=Object.prototype.propertyIsEnumerable;var fo=(e,t,r)=>t in e?_r(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,j=(e,t)=>{for(var r in t||(t={}))Ar.call(t,r)&&fo(e,r,t[r]);if(Bt)for(var r of Bt(t))uo.call(t,r)&&fo(e,r,t[r]);return e};var ho=(e,t)=>{var r={};for(var o in e)Ar.call(e,o)&&t.indexOf(o)<0&&(r[o]=e[o]);if(e!=null&&Bt)for(var o of Bt(e))t.indexOf(o)<0&&uo.call(e,o)&&(r[o]=e[o]);return r};var Cr=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Zi=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of Ji(t))!Ar.call(e,n)&&n!==r&&_r(e,n,{get:()=>t[n],enumerable:!(o=Gi(t,n))||o.enumerable});return e};var Gt=(e,t,r)=>(r=e!=null?Bi(Xi(e)):{},Zi(t||!e||!e.__esModule?_r(r,"default",{value:e,enumerable:!0}):r,e));var bo=(e,t,r)=>new Promise((o,n)=>{var i=c=>{try{a(r.next(c))}catch(p){n(p)}},s=c=>{try{a(r.throw(c))}catch(p){n(p)}},a=c=>c.done?o(c.value):Promise.resolve(c.value).then(i,s);a((r=r.apply(e,t)).next())});var go=Cr((Hr,vo)=>{(function(e,t){typeof Hr=="object"&&typeof vo!="undefined"?t():typeof define=="function"&&define.amd?define(t):t()})(Hr,function(){"use strict";function e(r){var o=!0,n=!1,i=null,s={text:!0,search:!0,url:!0,tel:!0,email:!0,password:!0,number:!0,date:!0,month:!0,week:!0,time:!0,datetime:!0,"datetime-local":!0};function a(H){return!!(H&&H!==document&&H.nodeName!=="HTML"&&H.nodeName!=="BODY"&&"classList"in H&&"contains"in H.classList)}function c(H){var ft=H.type,Fe=H.tagName;return!!(Fe==="INPUT"&&s[ft]&&!H.readOnly||Fe==="TEXTAREA"&&!H.readOnly||H.isContentEditable)}function p(H){H.classList.contains("focus-visible")||(H.classList.add("focus-visible"),H.setAttribute("data-focus-visible-added",""))}function l(H){H.hasAttribute("data-focus-visible-added")&&(H.classList.remove("focus-visible"),H.removeAttribute("data-focus-visible-added"))}function f(H){H.metaKey||H.altKey||H.ctrlKey||(a(r.activeElement)&&p(r.activeElement),o=!0)}function u(H){o=!1}function d(H){a(H.target)&&(o||c(H.target))&&p(H.target)}function g(H){a(H.target)&&(H.target.classList.contains("focus-visible")||H.target.hasAttribute("data-focus-visible-added"))&&(n=!0,window.clearTimeout(i),i=window.setTimeout(function(){n=!1},100),l(H.target))}function L(H){document.visibilityState==="hidden"&&(n&&(o=!0),ee())}function ee(){document.addEventListener("mousemove",Z),document.addEventListener("mousedown",Z),document.addEventListener("mouseup",Z),document.addEventListener("pointermove",Z),document.addEventListener("pointerdown",Z),document.addEventListener("pointerup",Z),document.addEventListener("touchmove",Z),document.addEventListener("touchstart",Z),document.addEventListener("touchend",Z)}function ne(){document.removeEventListener("mousemove",Z),document.removeEventListener("mousedown",Z),document.removeEventListener("mouseup",Z),document.removeEventListener("pointermove",Z),document.removeEventListener("pointerdown",Z),document.removeEventListener("pointerup",Z),document.removeEventListener("touchmove",Z),document.removeEventListener("touchstart",Z),document.removeEventListener("touchend",Z)}function Z(H){H.target.nodeName&&H.target.nodeName.toLowerCase()==="html"||(o=!1,ne())}document.addEventListener("keydown",f,!0),document.addEventListener("mousedown",u,!0),document.addEventListener("pointerdown",u,!0),document.addEventListener("touchstart",u,!0),document.addEventListener("visibilitychange",L,!0),ee(),r.addEventListener("focus",d,!0),r.addEventListener("blur",g,!0),r.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&r.host?r.host.setAttribute("data-js-focus-visible",""):r.nodeType===Node.DOCUMENT_NODE&&(document.documentElement.classList.add("js-focus-visible"),document.documentElement.setAttribute("data-js-focus-visible",""))}if(typeof window!="undefined"&&typeof document!="undefined"){window.applyFocusVisiblePolyfill=e;var t;try{t=new CustomEvent("focus-visible-polyfill-ready")}catch(r){t=document.createEvent("CustomEvent"),t.initCustomEvent("focus-visible-polyfill-ready",!1,!1,{})}window.dispatchEvent(t)}typeof document!="undefined"&&e(document)})});var io=Cr((Vt,no)=>{(function(t,r){typeof Vt=="object"&&typeof no=="object"?no.exports=r():typeof define=="function"&&define.amd?define([],r):typeof Vt=="object"?Vt.ClipboardJS=r():t.ClipboardJS=r()})(Vt,function(){return function(){var e={686:function(o,n,i){"use strict";i.d(n,{default:function(){return Yi}});var s=i(279),a=i.n(s),c=i(370),p=i.n(c),l=i(817),f=i.n(l);function u(z){try{return document.execCommand(z)}catch(C){return!1}}var d=function(C){var _=f()(C);return u("cut"),_},g=d;function L(z){var C=document.documentElement.getAttribute("dir")==="rtl",_=document.createElement("textarea");_.style.fontSize="12pt",_.style.border="0",_.style.padding="0",_.style.margin="0",_.style.position="absolute",_.style[C?"right":"left"]="-9999px";var D=window.pageYOffset||document.documentElement.scrollTop;return _.style.top="".concat(D,"px"),_.setAttribute("readonly",""),_.value=z,_}var ee=function(C,_){var D=L(C);_.container.appendChild(D);var N=f()(D);return u("copy"),D.remove(),N},ne=function(C){var _=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body},D="";return typeof C=="string"?D=ee(C,_):C instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(C==null?void 0:C.type)?D=ee(C.value,_):(D=f()(C),u("copy")),D},Z=ne;function H(z){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?H=function(_){return typeof _}:H=function(_){return _&&typeof Symbol=="function"&&_.constructor===Symbol&&_!==Symbol.prototype?"symbol":typeof _},H(z)}var ft=function(){var C=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},_=C.action,D=_===void 0?"copy":_,N=C.container,G=C.target,Ue=C.text;if(D!=="copy"&&D!=="cut")throw new Error('Invalid "action" value, use either "copy" or "cut"');if(G!==void 0)if(G&&H(G)==="object"&&G.nodeType===1){if(D==="copy"&&G.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if(D==="cut"&&(G.hasAttribute("readonly")||G.hasAttribute("disabled")))throw new Error(`Invalid "target" attribute. You can't cut text from elements with "readonly" or "disabled" attributes`)}else throw new Error('Invalid "target" value, use a valid Element');if(Ue)return Z(Ue,{container:N});if(G)return D==="cut"?g(G):Z(G,{container:N})},Fe=ft;function R(z){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?R=function(_){return typeof _}:R=function(_){return _&&typeof Symbol=="function"&&_.constructor===Symbol&&_!==Symbol.prototype?"symbol":typeof _},R(z)}function se(z,C){if(!(z instanceof C))throw new TypeError("Cannot call a class as a function")}function ce(z,C){for(var _=0;_0&&arguments[0]!==void 0?arguments[0]:{};this.action=typeof N.action=="function"?N.action:this.defaultAction,this.target=typeof N.target=="function"?N.target:this.defaultTarget,this.text=typeof N.text=="function"?N.text:this.defaultText,this.container=R(N.container)==="object"?N.container:document.body}},{key:"listenClick",value:function(N){var G=this;this.listener=p()(N,"click",function(Ue){return G.onClick(Ue)})}},{key:"onClick",value:function(N){var G=N.delegateTarget||N.currentTarget,Ue=this.action(G)||"copy",Yt=Fe({action:Ue,container:this.container,target:this.target(G),text:this.text(G)});this.emit(Yt?"success":"error",{action:Ue,text:Yt,trigger:G,clearSelection:function(){G&&G.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(N){return Mr("action",N)}},{key:"defaultTarget",value:function(N){var G=Mr("target",N);if(G)return document.querySelector(G)}},{key:"defaultText",value:function(N){return Mr("text",N)}},{key:"destroy",value:function(){this.listener.destroy()}}],[{key:"copy",value:function(N){var G=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body};return Z(N,G)}},{key:"cut",value:function(N){return g(N)}},{key:"isSupported",value:function(){var N=arguments.length>0&&arguments[0]!==void 0?arguments[0]:["copy","cut"],G=typeof N=="string"?[N]:N,Ue=!!document.queryCommandSupported;return G.forEach(function(Yt){Ue=Ue&&!!document.queryCommandSupported(Yt)}),Ue}}]),_}(a()),Yi=Qi},828:function(o){var n=9;if(typeof Element!="undefined"&&!Element.prototype.matches){var i=Element.prototype;i.matches=i.matchesSelector||i.mozMatchesSelector||i.msMatchesSelector||i.oMatchesSelector||i.webkitMatchesSelector}function s(a,c){for(;a&&a.nodeType!==n;){if(typeof a.matches=="function"&&a.matches(c))return a;a=a.parentNode}}o.exports=s},438:function(o,n,i){var s=i(828);function a(l,f,u,d,g){var L=p.apply(this,arguments);return l.addEventListener(u,L,g),{destroy:function(){l.removeEventListener(u,L,g)}}}function c(l,f,u,d,g){return typeof l.addEventListener=="function"?a.apply(null,arguments):typeof u=="function"?a.bind(null,document).apply(null,arguments):(typeof l=="string"&&(l=document.querySelectorAll(l)),Array.prototype.map.call(l,function(L){return a(L,f,u,d,g)}))}function p(l,f,u,d){return function(g){g.delegateTarget=s(g.target,f),g.delegateTarget&&d.call(l,g)}}o.exports=c},879:function(o,n){n.node=function(i){return i!==void 0&&i instanceof HTMLElement&&i.nodeType===1},n.nodeList=function(i){var s=Object.prototype.toString.call(i);return i!==void 0&&(s==="[object NodeList]"||s==="[object HTMLCollection]")&&"length"in i&&(i.length===0||n.node(i[0]))},n.string=function(i){return typeof i=="string"||i instanceof String},n.fn=function(i){var s=Object.prototype.toString.call(i);return s==="[object Function]"}},370:function(o,n,i){var s=i(879),a=i(438);function c(u,d,g){if(!u&&!d&&!g)throw new Error("Missing required arguments");if(!s.string(d))throw new TypeError("Second argument must be a String");if(!s.fn(g))throw new TypeError("Third argument must be a Function");if(s.node(u))return p(u,d,g);if(s.nodeList(u))return l(u,d,g);if(s.string(u))return f(u,d,g);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function p(u,d,g){return u.addEventListener(d,g),{destroy:function(){u.removeEventListener(d,g)}}}function l(u,d,g){return Array.prototype.forEach.call(u,function(L){L.addEventListener(d,g)}),{destroy:function(){Array.prototype.forEach.call(u,function(L){L.removeEventListener(d,g)})}}}function f(u,d,g){return a(document.body,u,d,g)}o.exports=c},817:function(o){function n(i){var s;if(i.nodeName==="SELECT")i.focus(),s=i.value;else if(i.nodeName==="INPUT"||i.nodeName==="TEXTAREA"){var a=i.hasAttribute("readonly");a||i.setAttribute("readonly",""),i.select(),i.setSelectionRange(0,i.value.length),a||i.removeAttribute("readonly"),s=i.value}else{i.hasAttribute("contenteditable")&&i.focus();var c=window.getSelection(),p=document.createRange();p.selectNodeContents(i),c.removeAllRanges(),c.addRange(p),s=c.toString()}return s}o.exports=n},279:function(o){function n(){}n.prototype={on:function(i,s,a){var c=this.e||(this.e={});return(c[i]||(c[i]=[])).push({fn:s,ctx:a}),this},once:function(i,s,a){var c=this;function p(){c.off(i,p),s.apply(a,arguments)}return p._=s,this.on(i,p,a)},emit:function(i){var s=[].slice.call(arguments,1),a=((this.e||(this.e={}))[i]||[]).slice(),c=0,p=a.length;for(c;c{"use strict";var fs=/["'&<>]/;di.exports=us;function us(e){var t=""+e,r=fs.exec(t);if(!r)return t;var o,n="",i=0,s=0;for(i=r.index;i0&&i[i.length-1])&&(p[0]===6||p[0]===2)){r=0;continue}if(p[0]===3&&(!i||p[1]>i[0]&&p[1]=e.length&&(e=void 0),{value:e&&e[o++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function q(e,t){var r=typeof Symbol=="function"&&e[Symbol.iterator];if(!r)return e;var o=r.call(e),n,i=[],s;try{for(;(t===void 0||t-- >0)&&!(n=o.next()).done;)i.push(n.value)}catch(a){s={error:a}}finally{try{n&&!n.done&&(r=o.return)&&r.call(o)}finally{if(s)throw s.error}}return i}function B(e,t,r){if(r||arguments.length===2)for(var o=0,n=t.length,i;o1||a(u,d)})})}function a(u,d){try{c(o[u](d))}catch(g){f(i[0][3],g)}}function c(u){u.value instanceof ut?Promise.resolve(u.value.v).then(p,l):f(i[0][2],u)}function p(u){a("next",u)}function l(u){a("throw",u)}function f(u,d){u(d),i.shift(),i.length&&a(i[0][0],i[0][1])}}function Eo(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t=e[Symbol.asyncIterator],r;return t?t.call(e):(e=typeof Oe=="function"?Oe(e):e[Symbol.iterator](),r={},o("next"),o("throw"),o("return"),r[Symbol.asyncIterator]=function(){return this},r);function o(i){r[i]=e[i]&&function(s){return new Promise(function(a,c){s=e[i](s),n(a,c,s.done,s.value)})}}function n(i,s,a,c){Promise.resolve(c).then(function(p){i({value:p,done:a})},s)}}function P(e){return typeof e=="function"}function xt(e){var t=function(o){Error.call(o),o.stack=new Error().stack},r=e(t);return r.prototype=Object.create(Error.prototype),r.prototype.constructor=r,r}var Xt=xt(function(e){return function(r){e(this),this.message=r?r.length+` errors occurred during unsubscription: +`+r.map(function(o,n){return n+1+") "+o.toString()}).join(` + `):"",this.name="UnsubscriptionError",this.errors=r}});function Xe(e,t){if(e){var r=e.indexOf(t);0<=r&&e.splice(r,1)}}var ze=function(){function e(t){this.initialTeardown=t,this.closed=!1,this._parentage=null,this._finalizers=null}return e.prototype.unsubscribe=function(){var t,r,o,n,i;if(!this.closed){this.closed=!0;var s=this._parentage;if(s)if(this._parentage=null,Array.isArray(s))try{for(var a=Oe(s),c=a.next();!c.done;c=a.next()){var p=c.value;p.remove(this)}}catch(L){t={error:L}}finally{try{c&&!c.done&&(r=a.return)&&r.call(a)}finally{if(t)throw t.error}}else s.remove(this);var l=this.initialTeardown;if(P(l))try{l()}catch(L){i=L instanceof Xt?L.errors:[L]}var f=this._finalizers;if(f){this._finalizers=null;try{for(var u=Oe(f),d=u.next();!d.done;d=u.next()){var g=d.value;try{wo(g)}catch(L){i=i!=null?i:[],L instanceof Xt?i=B(B([],q(i)),q(L.errors)):i.push(L)}}}catch(L){o={error:L}}finally{try{d&&!d.done&&(n=u.return)&&n.call(u)}finally{if(o)throw o.error}}}if(i)throw new Xt(i)}},e.prototype.add=function(t){var r;if(t&&t!==this)if(this.closed)wo(t);else{if(t instanceof e){if(t.closed||t._hasParent(this))return;t._addParent(this)}(this._finalizers=(r=this._finalizers)!==null&&r!==void 0?r:[]).push(t)}},e.prototype._hasParent=function(t){var r=this._parentage;return r===t||Array.isArray(r)&&r.includes(t)},e.prototype._addParent=function(t){var r=this._parentage;this._parentage=Array.isArray(r)?(r.push(t),r):r?[r,t]:t},e.prototype._removeParent=function(t){var r=this._parentage;r===t?this._parentage=null:Array.isArray(r)&&Xe(r,t)},e.prototype.remove=function(t){var r=this._finalizers;r&&Xe(r,t),t instanceof e&&t._removeParent(this)},e.EMPTY=function(){var t=new e;return t.closed=!0,t}(),e}();var $r=ze.EMPTY;function Zt(e){return e instanceof ze||e&&"closed"in e&&P(e.remove)&&P(e.add)&&P(e.unsubscribe)}function wo(e){P(e)?e():e.unsubscribe()}var We={onUnhandledError:null,onStoppedNotification:null,Promise:void 0,useDeprecatedSynchronousErrorHandling:!1,useDeprecatedNextContext:!1};var yt={setTimeout:function(e,t){for(var r=[],o=2;o0},enumerable:!1,configurable:!0}),t.prototype._trySubscribe=function(r){return this._throwIfClosed(),e.prototype._trySubscribe.call(this,r)},t.prototype._subscribe=function(r){return this._throwIfClosed(),this._checkFinalizedStatuses(r),this._innerSubscribe(r)},t.prototype._innerSubscribe=function(r){var o=this,n=this,i=n.hasError,s=n.isStopped,a=n.observers;return i||s?$r:(this.currentObservers=null,a.push(r),new ze(function(){o.currentObservers=null,Xe(a,r)}))},t.prototype._checkFinalizedStatuses=function(r){var o=this,n=o.hasError,i=o.thrownError,s=o.isStopped;n?r.error(i):s&&r.complete()},t.prototype.asObservable=function(){var r=new I;return r.source=this,r},t.create=function(r,o){return new Co(r,o)},t}(I);var Co=function(e){ie(t,e);function t(r,o){var n=e.call(this)||this;return n.destination=r,n.source=o,n}return t.prototype.next=function(r){var o,n;(n=(o=this.destination)===null||o===void 0?void 0:o.next)===null||n===void 0||n.call(o,r)},t.prototype.error=function(r){var o,n;(n=(o=this.destination)===null||o===void 0?void 0:o.error)===null||n===void 0||n.call(o,r)},t.prototype.complete=function(){var r,o;(o=(r=this.destination)===null||r===void 0?void 0:r.complete)===null||o===void 0||o.call(r)},t.prototype._subscribe=function(r){var o,n;return(n=(o=this.source)===null||o===void 0?void 0:o.subscribe(r))!==null&&n!==void 0?n:$r},t}(T);var jr=function(e){ie(t,e);function t(r){var o=e.call(this)||this;return o._value=r,o}return Object.defineProperty(t.prototype,"value",{get:function(){return this.getValue()},enumerable:!1,configurable:!0}),t.prototype._subscribe=function(r){var o=e.prototype._subscribe.call(this,r);return!o.closed&&r.next(this._value),o},t.prototype.getValue=function(){var r=this,o=r.hasError,n=r.thrownError,i=r._value;if(o)throw n;return this._throwIfClosed(),i},t.prototype.next=function(r){e.prototype.next.call(this,this._value=r)},t}(T);var Pt={now:function(){return(Pt.delegate||Date).now()},delegate:void 0};var It=function(e){ie(t,e);function t(r,o,n){r===void 0&&(r=1/0),o===void 0&&(o=1/0),n===void 0&&(n=Pt);var i=e.call(this)||this;return i._bufferSize=r,i._windowTime=o,i._timestampProvider=n,i._buffer=[],i._infiniteTimeWindow=!0,i._infiniteTimeWindow=o===1/0,i._bufferSize=Math.max(1,r),i._windowTime=Math.max(1,o),i}return t.prototype.next=function(r){var o=this,n=o.isStopped,i=o._buffer,s=o._infiniteTimeWindow,a=o._timestampProvider,c=o._windowTime;n||(i.push(r),!s&&i.push(a.now()+c)),this._trimBuffer(),e.prototype.next.call(this,r)},t.prototype._subscribe=function(r){this._throwIfClosed(),this._trimBuffer();for(var o=this._innerSubscribe(r),n=this,i=n._infiniteTimeWindow,s=n._buffer,a=s.slice(),c=0;c0?e.prototype.schedule.call(this,r,o):(this.delay=o,this.state=r,this.scheduler.flush(this),this)},t.prototype.execute=function(r,o){return o>0||this.closed?e.prototype.execute.call(this,r,o):this._execute(r,o)},t.prototype.requestAsyncId=function(r,o,n){return n===void 0&&(n=0),n!=null&&n>0||n==null&&this.delay>0?e.prototype.requestAsyncId.call(this,r,o,n):(r.flush(this),0)},t}(St);var $o=function(e){ie(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t}(Ot);var Dr=new $o(ko);var Ro=function(e){ie(t,e);function t(r,o){var n=e.call(this,r,o)||this;return n.scheduler=r,n.work=o,n}return t.prototype.requestAsyncId=function(r,o,n){return n===void 0&&(n=0),n!==null&&n>0?e.prototype.requestAsyncId.call(this,r,o,n):(r.actions.push(this),r._scheduled||(r._scheduled=Tt.requestAnimationFrame(function(){return r.flush(void 0)})))},t.prototype.recycleAsyncId=function(r,o,n){var i;if(n===void 0&&(n=0),n!=null?n>0:this.delay>0)return e.prototype.recycleAsyncId.call(this,r,o,n);var s=r.actions;o!=null&&((i=s[s.length-1])===null||i===void 0?void 0:i.id)!==o&&(Tt.cancelAnimationFrame(o),r._scheduled=void 0)},t}(St);var Po=function(e){ie(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t.prototype.flush=function(r){this._active=!0;var o=this._scheduled;this._scheduled=void 0;var n=this.actions,i;r=r||n.shift();do if(i=r.execute(r.state,r.delay))break;while((r=n[0])&&r.id===o&&n.shift());if(this._active=!1,i){for(;(r=n[0])&&r.id===o&&n.shift();)r.unsubscribe();throw i}},t}(Ot);var ge=new Po(Ro);var x=new I(function(e){return e.complete()});function rr(e){return e&&P(e.schedule)}function Nr(e){return e[e.length-1]}function ct(e){return P(Nr(e))?e.pop():void 0}function Ie(e){return rr(Nr(e))?e.pop():void 0}function or(e,t){return typeof Nr(e)=="number"?e.pop():t}var Lt=function(e){return e&&typeof e.length=="number"&&typeof e!="function"};function nr(e){return P(e==null?void 0:e.then)}function ir(e){return P(e[wt])}function ar(e){return Symbol.asyncIterator&&P(e==null?void 0:e[Symbol.asyncIterator])}function sr(e){return new TypeError("You provided "+(e!==null&&typeof e=="object"?"an invalid object":"'"+e+"'")+" where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.")}function ca(){return typeof Symbol!="function"||!Symbol.iterator?"@@iterator":Symbol.iterator}var cr=ca();function pr(e){return P(e==null?void 0:e[cr])}function lr(e){return yo(this,arguments,function(){var r,o,n,i;return Jt(this,function(s){switch(s.label){case 0:r=e.getReader(),s.label=1;case 1:s.trys.push([1,,9,10]),s.label=2;case 2:return[4,ut(r.read())];case 3:return o=s.sent(),n=o.value,i=o.done,i?[4,ut(void 0)]:[3,5];case 4:return[2,s.sent()];case 5:return[4,ut(n)];case 6:return[4,s.sent()];case 7:return s.sent(),[3,2];case 8:return[3,10];case 9:return r.releaseLock(),[7];case 10:return[2]}})})}function mr(e){return P(e==null?void 0:e.getReader)}function U(e){if(e instanceof I)return e;if(e!=null){if(ir(e))return pa(e);if(Lt(e))return la(e);if(nr(e))return ma(e);if(ar(e))return Io(e);if(pr(e))return fa(e);if(mr(e))return ua(e)}throw sr(e)}function pa(e){return new I(function(t){var r=e[wt]();if(P(r.subscribe))return r.subscribe(t);throw new TypeError("Provided object does not correctly implement Symbol.observable")})}function la(e){return new I(function(t){for(var r=0;r=2;return function(o){return o.pipe(e?v(function(n,i){return e(n,i,o)}):be,Ee(1),r?rt(t):Zo(function(){return new ur}))}}function Yr(e){return e<=0?function(){return x}:E(function(t,r){var o=[];t.subscribe(w(r,function(n){o.push(n),e=2,!0))}function le(e){e===void 0&&(e={});var t=e.connector,r=t===void 0?function(){return new T}:t,o=e.resetOnError,n=o===void 0?!0:o,i=e.resetOnComplete,s=i===void 0?!0:i,a=e.resetOnRefCountZero,c=a===void 0?!0:a;return function(p){var l,f,u,d=0,g=!1,L=!1,ee=function(){f==null||f.unsubscribe(),f=void 0},ne=function(){ee(),l=u=void 0,g=L=!1},Z=function(){var H=l;ne(),H==null||H.unsubscribe()};return E(function(H,ft){d++,!L&&!g&&ee();var Fe=u=u!=null?u:r();ft.add(function(){d--,d===0&&!L&&!g&&(f=Br(Z,c))}),Fe.subscribe(ft),!l&&d>0&&(l=new ht({next:function(R){return Fe.next(R)},error:function(R){L=!0,ee(),f=Br(ne,n,R),Fe.error(R)},complete:function(){g=!0,ee(),f=Br(ne,s),Fe.complete()}}),U(H).subscribe(l))})(p)}}function Br(e,t){for(var r=[],o=2;oe.next(document)),e}function M(e,t=document){return Array.from(t.querySelectorAll(e))}function F(e,t=document){let r=ue(e,t);if(typeof r=="undefined")throw new ReferenceError(`Missing element: expected "${e}" to be present`);return r}function ue(e,t=document){return t.querySelector(e)||void 0}function Ve(){var e,t,r,o;return(o=(r=(t=(e=document.activeElement)==null?void 0:e.shadowRoot)==null?void 0:t.activeElement)!=null?r:document.activeElement)!=null?o:void 0}var Ha=O(h(document.body,"focusin"),h(document.body,"focusout")).pipe(Ae(1),K(void 0),m(()=>Ve()||document.body),X(1));function Ke(e){return Ha.pipe(m(t=>e.contains(t)),Y())}function nt(e,t){return k(()=>O(h(e,"mouseenter").pipe(m(()=>!0)),h(e,"mouseleave").pipe(m(()=>!1))).pipe(t?jt(r=>ke(+!r*t)):be,K(e.matches(":hover"))))}function nn(e,t){if(typeof t=="string"||typeof t=="number")e.innerHTML+=t.toString();else if(t instanceof Node)e.appendChild(t);else if(Array.isArray(t))for(let r of t)nn(e,r)}function y(e,t,...r){let o=document.createElement(e);if(t)for(let n of Object.keys(t))typeof t[n]!="undefined"&&(typeof t[n]!="boolean"?o.setAttribute(n,t[n]):o.setAttribute(n,""));for(let n of r)nn(o,n);return o}function br(e){if(e>999){let t=+((e-950)%1e3>99);return`${((e+1e-6)/1e3).toFixed(t)}k`}else return e.toString()}function At(e){let t=y("script",{src:e});return k(()=>(document.head.appendChild(t),O(h(t,"load"),h(t,"error").pipe(b(()=>Vr(()=>new ReferenceError(`Invalid script: ${e}`))))).pipe(m(()=>{}),A(()=>document.head.removeChild(t)),Ee(1))))}var an=new T,ka=k(()=>typeof ResizeObserver=="undefined"?At("https://unpkg.com/resize-observer-polyfill"):$(void 0)).pipe(m(()=>new ResizeObserver(e=>e.forEach(t=>an.next(t)))),b(e=>O(et,$(e)).pipe(A(()=>e.disconnect()))),X(1));function de(e){return{width:e.offsetWidth,height:e.offsetHeight}}function Le(e){let t=e;for(;t.clientWidth===0&&t.parentElement;)t=t.parentElement;return ka.pipe(S(r=>r.observe(t)),b(r=>an.pipe(v(o=>o.target===t),A(()=>r.unobserve(t)))),m(()=>de(e)),K(de(e)))}function Ct(e){return{width:e.scrollWidth,height:e.scrollHeight}}function vr(e){let t=e.parentElement;for(;t&&(e.scrollWidth<=t.scrollWidth&&e.scrollHeight<=t.scrollHeight);)t=(e=t).parentElement;return t?e:void 0}function sn(e){let t=[],r=e.parentElement;for(;r;)(e.clientWidth>r.clientWidth||e.clientHeight>r.clientHeight)&&t.push(r),r=(e=r).parentElement;return t.length===0&&t.push(document.documentElement),t}function Qe(e){return{x:e.offsetLeft,y:e.offsetTop}}function cn(e){let t=e.getBoundingClientRect();return{x:t.x+window.scrollX,y:t.y+window.scrollY}}function pn(e){return O(h(window,"load"),h(window,"resize")).pipe($e(0,ge),m(()=>Qe(e)),K(Qe(e)))}function gr(e){return{x:e.scrollLeft,y:e.scrollTop}}function Ye(e){return O(h(e,"scroll"),h(window,"scroll"),h(window,"resize")).pipe($e(0,ge),m(()=>gr(e)),K(gr(e)))}var ln=new T,$a=k(()=>$(new IntersectionObserver(e=>{for(let t of e)ln.next(t)},{threshold:0}))).pipe(b(e=>O(et,$(e)).pipe(A(()=>e.disconnect()))),X(1));function lt(e){return $a.pipe(S(t=>t.observe(e)),b(t=>ln.pipe(v(({target:r})=>r===e),A(()=>t.unobserve(e)),m(({isIntersecting:r})=>r))))}function mn(e,t=16){return Ye(e).pipe(m(({y:r})=>{let o=de(e),n=Ct(e);return r>=n.height-o.height-t}),Y())}var xr={drawer:F("[data-md-toggle=drawer]"),search:F("[data-md-toggle=search]")};function fn(e){return xr[e].checked}function it(e,t){xr[e].checked!==t&&xr[e].click()}function Be(e){let t=xr[e];return h(t,"change").pipe(m(()=>t.checked),K(t.checked))}function Ra(e,t){switch(e.constructor){case HTMLInputElement:return e.type==="radio"?/^Arrow/.test(t):!0;case HTMLSelectElement:case HTMLTextAreaElement:return!0;default:return e.isContentEditable}}function Pa(){return O(h(window,"compositionstart").pipe(m(()=>!0)),h(window,"compositionend").pipe(m(()=>!1))).pipe(K(!1))}function un(){let e=h(window,"keydown").pipe(v(t=>!(t.metaKey||t.ctrlKey)),m(t=>({mode:fn("search")?"search":"global",type:t.key,claim(){t.preventDefault(),t.stopPropagation()}})),v(({mode:t,type:r})=>{if(t==="global"){let o=Ve();if(typeof o!="undefined")return!Ra(o,r)}return!0}),le());return Pa().pipe(b(t=>t?x:e))}function we(){return new URL(location.href)}function at(e,t=!1){if(Q("navigation.instant")&&!t){let r=y("a",{href:e.href});document.body.appendChild(r),r.click(),r.remove()}else location.href=e.href}function dn(){return new T}function hn(){return location.hash.slice(1)}function bn(e){let t=y("a",{href:e});t.addEventListener("click",r=>r.stopPropagation()),t.click()}function Zr(e){return O(h(window,"hashchange"),e).pipe(m(hn),K(hn()),v(t=>t.length>0),X(1))}function vn(e){return Zr(e).pipe(m(t=>ue(`[id="${t}"]`)),v(t=>typeof t!="undefined"))}function Wt(e){let t=matchMedia(e);return dr(r=>t.addListener(()=>r(t.matches))).pipe(K(t.matches))}function gn(){let e=matchMedia("print");return O(h(window,"beforeprint").pipe(m(()=>!0)),h(window,"afterprint").pipe(m(()=>!1))).pipe(K(e.matches))}function eo(e,t){return e.pipe(b(r=>r?t():x))}function to(e,t){return new I(r=>{let o=new XMLHttpRequest;return o.open("GET",`${e}`),o.responseType="blob",o.addEventListener("load",()=>{o.status>=200&&o.status<300?(r.next(o.response),r.complete()):r.error(new Error(o.statusText))}),o.addEventListener("error",()=>{r.error(new Error("Network error"))}),o.addEventListener("abort",()=>{r.complete()}),typeof(t==null?void 0:t.progress$)!="undefined"&&(o.addEventListener("progress",n=>{var i;if(n.lengthComputable)t.progress$.next(n.loaded/n.total*100);else{let s=(i=o.getResponseHeader("Content-Length"))!=null?i:0;t.progress$.next(n.loaded/+s*100)}}),t.progress$.next(5)),o.send(),()=>o.abort()})}function Ge(e,t){return to(e,t).pipe(b(r=>r.text()),m(r=>JSON.parse(r)),X(1))}function yr(e,t){let r=new DOMParser;return to(e,t).pipe(b(o=>o.text()),m(o=>r.parseFromString(o,"text/html")),X(1))}function xn(e,t){let r=new DOMParser;return to(e,t).pipe(b(o=>o.text()),m(o=>r.parseFromString(o,"text/xml")),X(1))}function yn(){return{x:Math.max(0,scrollX),y:Math.max(0,scrollY)}}function En(){return O(h(window,"scroll",{passive:!0}),h(window,"resize",{passive:!0})).pipe(m(yn),K(yn()))}function wn(){return{width:innerWidth,height:innerHeight}}function Tn(){return h(window,"resize",{passive:!0}).pipe(m(wn),K(wn()))}function Sn(){return V([En(),Tn()]).pipe(m(([e,t])=>({offset:e,size:t})),X(1))}function Er(e,{viewport$:t,header$:r}){let o=t.pipe(oe("size")),n=V([o,r]).pipe(m(()=>Qe(e)));return V([r,t,n]).pipe(m(([{height:i},{offset:s,size:a},{x:c,y:p}])=>({offset:{x:s.x-c,y:s.y-p+i},size:a})))}function Ia(e){return h(e,"message",t=>t.data)}function Fa(e){let t=new T;return t.subscribe(r=>e.postMessage(r)),t}function On(e,t=new Worker(e)){let r=Ia(t),o=Fa(t),n=new T;n.subscribe(o);let i=o.pipe(re(),ae(!0));return n.pipe(re(),Ne(r.pipe(W(i))),le())}var ja=F("#__config"),Ht=JSON.parse(ja.textContent);Ht.base=`${new URL(Ht.base,we())}`;function Te(){return Ht}function Q(e){return Ht.features.includes(e)}function Me(e,t){return typeof t!="undefined"?Ht.translations[e].replace("#",t.toString()):Ht.translations[e]}function Ce(e,t=document){return F(`[data-md-component=${e}]`,t)}function me(e,t=document){return M(`[data-md-component=${e}]`,t)}function Ua(e){let t=F(".md-typeset > :first-child",e);return h(t,"click",{once:!0}).pipe(m(()=>F(".md-typeset",e)),m(r=>({hash:__md_hash(r.innerHTML)})))}function Ln(e){if(!Q("announce.dismiss")||!e.childElementCount)return x;if(!e.hidden){let t=F(".md-typeset",e);__md_hash(t.innerHTML)===__md_get("__announce")&&(e.hidden=!0)}return k(()=>{let t=new T;return t.subscribe(({hash:r})=>{e.hidden=!0,__md_set("__announce",r)}),Ua(e).pipe(S(r=>t.next(r)),A(()=>t.complete()),m(r=>j({ref:e},r)))})}function Wa(e,{target$:t}){return t.pipe(m(r=>({hidden:r!==e})))}function Mn(e,t){let r=new T;return r.subscribe(({hidden:o})=>{e.hidden=o}),Wa(e,t).pipe(S(o=>r.next(o)),A(()=>r.complete()),m(o=>j({ref:e},o)))}function Dt(e,t){return t==="inline"?y("div",{class:"md-tooltip md-tooltip--inline",id:e,role:"tooltip"},y("div",{class:"md-tooltip__inner md-typeset"})):y("div",{class:"md-tooltip",id:e,role:"tooltip"},y("div",{class:"md-tooltip__inner md-typeset"}))}function wr(...e){return y("div",{class:"md-tooltip2",role:"dialog"},y("div",{class:"md-tooltip2__inner md-typeset"},e))}function _n(...e){return y("div",{class:"md-tooltip2",role:"tooltip"},y("div",{class:"md-tooltip2__inner md-typeset"},e))}function An(e,t){if(t=t?`${t}_annotation_${e}`:void 0,t){let r=t?`#${t}`:void 0;return y("aside",{class:"md-annotation",tabIndex:0},Dt(t),y("a",{href:r,class:"md-annotation__index",tabIndex:-1},y("span",{"data-md-annotation-id":e})))}else return y("aside",{class:"md-annotation",tabIndex:0},Dt(t),y("span",{class:"md-annotation__index",tabIndex:-1},y("span",{"data-md-annotation-id":e})))}function Cn(e){return y("button",{class:"md-code__button",title:Me("clipboard.copy"),"data-clipboard-target":`#${e} > code`,"data-md-type":"copy"})}function Hn(){return y("button",{class:"md-code__button",title:"Toggle line selection","data-md-type":"select"})}function kn(){return y("nav",{class:"md-code__nav"})}function ro(e,t){let r=t&2,o=t&1,n=Object.keys(e.terms).filter(c=>!e.terms[c]).reduce((c,p)=>[...c,y("del",null,p)," "],[]).slice(0,-1),i=Te(),s=new URL(e.location,i.base);Q("search.highlight")&&s.searchParams.set("h",Object.entries(e.terms).filter(([,c])=>c).reduce((c,[p])=>`${c} ${p}`.trim(),""));let{tags:a}=Te();return y("a",{href:`${s}`,class:"md-search-result__link",tabIndex:-1},y("article",{class:"md-search-result__article md-typeset","data-md-score":e.score.toFixed(2)},r>0&&y("div",{class:"md-search-result__icon md-icon"}),r>0&&y("h1",null,e.title),r<=0&&y("h2",null,e.title),o>0&&e.text.length>0&&e.text,e.tags&&e.tags.map(c=>{let p=a?c in a?`md-tag-icon md-tag--${a[c]}`:"md-tag-icon":"";return y("span",{class:`md-tag ${p}`},c)}),o>0&&n.length>0&&y("p",{class:"md-search-result__terms"},Me("search.result.term.missing"),": ",...n)))}function $n(e){let t=e[0].score,r=[...e],o=Te(),n=r.findIndex(l=>!`${new URL(l.location,o.base)}`.includes("#")),[i]=r.splice(n,1),s=r.findIndex(l=>l.scorero(l,1)),...c.length?[y("details",{class:"md-search-result__more"},y("summary",{tabIndex:-1},y("div",null,c.length>0&&c.length===1?Me("search.result.more.one"):Me("search.result.more.other",c.length))),...c.map(l=>ro(l,1)))]:[]];return y("li",{class:"md-search-result__item"},p)}function Rn(e){return y("ul",{class:"md-source__facts"},Object.entries(e).map(([t,r])=>y("li",{class:`md-source__fact md-source__fact--${t}`},typeof r=="number"?br(r):r)))}function oo(e){let t=`tabbed-control tabbed-control--${e}`;return y("div",{class:t,hidden:!0},y("button",{class:"tabbed-button",tabIndex:-1,"aria-hidden":"true"}))}function Pn(e){return y("div",{class:"md-typeset__scrollwrap"},y("div",{class:"md-typeset__table"},e))}function Da(e){var o;let t=Te(),r=new URL(`../${e.version}/`,t.base);return y("li",{class:"md-version__item"},y("a",{href:`${r}`,class:"md-version__link"},e.title,((o=t.version)==null?void 0:o.alias)&&e.aliases.length>0&&y("span",{class:"md-version__alias"},e.aliases[0])))}function In(e,t){var o;let r=Te();return e=e.filter(n=>{var i;return!((i=n.properties)!=null&&i.hidden)}),y("div",{class:"md-version"},y("button",{class:"md-version__current","aria-label":Me("select.version")},t.title,((o=r.version)==null?void 0:o.alias)&&t.aliases.length>0&&y("span",{class:"md-version__alias"},t.aliases[0])),y("ul",{class:"md-version__list"},e.map(Da)))}var Na=0;function Va(e,t=250){let r=V([Ke(e),nt(e,t)]).pipe(m(([n,i])=>n||i),Y()),o=k(()=>sn(e)).pipe(J(Ye),gt(1),m(()=>cn(e)));return r.pipe(Re(n=>n),b(()=>V([r,o])),m(([n,i])=>({active:n,offset:i})),le())}function Nt(e,t,r=250){let{content$:o,viewport$:n}=t,i=`__tooltip2_${Na++}`;return k(()=>{let s=new T,a=new jr(!1);s.pipe(re(),ae(!1)).subscribe(a);let c=a.pipe(jt(l=>ke(+!l*250,Dr)),Y(),b(l=>l?o:x),S(l=>l.id=i),le());V([s.pipe(m(({active:l})=>l)),c.pipe(b(l=>nt(l,250)),K(!1))]).pipe(m(l=>l.some(f=>f))).subscribe(a);let p=a.pipe(v(l=>l),te(c,n),m(([l,f,{size:u}])=>{let d=e.getBoundingClientRect(),g=d.width/2;if(f.role==="tooltip")return{x:g,y:8+d.height};if(d.y>=u.height/2){let{height:L}=de(f);return{x:g,y:-16-L}}else return{x:g,y:16+d.height}}));return V([c,s,p]).subscribe(([l,{offset:f},u])=>{l.style.setProperty("--md-tooltip-host-x",`${f.x}px`),l.style.setProperty("--md-tooltip-host-y",`${f.y}px`),l.style.setProperty("--md-tooltip-x",`${u.x}px`),l.style.setProperty("--md-tooltip-y",`${u.y}px`),l.classList.toggle("md-tooltip2--top",u.y<0),l.classList.toggle("md-tooltip2--bottom",u.y>=0)}),a.pipe(v(l=>l),te(c,(l,f)=>f),v(l=>l.role==="tooltip")).subscribe(l=>{let f=de(F(":scope > *",l));l.style.setProperty("--md-tooltip-width",`${f.width}px`),l.style.setProperty("--md-tooltip-tail","0px")}),a.pipe(Y(),xe(ge),te(c)).subscribe(([l,f])=>{f.classList.toggle("md-tooltip2--active",l)}),V([a.pipe(v(l=>l)),c]).subscribe(([l,f])=>{f.role==="dialog"?(e.setAttribute("aria-controls",i),e.setAttribute("aria-haspopup","dialog")):e.setAttribute("aria-describedby",i)}),a.pipe(v(l=>!l)).subscribe(()=>{e.removeAttribute("aria-controls"),e.removeAttribute("aria-describedby"),e.removeAttribute("aria-haspopup")}),Va(e,r).pipe(S(l=>s.next(l)),A(()=>s.complete()),m(l=>j({ref:e},l)))})}function Je(e,{viewport$:t},r=document.body){return Nt(e,{content$:new I(o=>{let n=e.title,i=_n(n);return o.next(i),e.removeAttribute("title"),r.append(i),()=>{i.remove(),e.setAttribute("title",n)}}),viewport$:t},0)}function za(e,t){let r=k(()=>V([pn(e),Ye(t)])).pipe(m(([{x:o,y:n},i])=>{let{width:s,height:a}=de(e);return{x:o-i.x+s/2,y:n-i.y+a/2}}));return Ke(e).pipe(b(o=>r.pipe(m(n=>({active:o,offset:n})),Ee(+!o||1/0))))}function Fn(e,t,{target$:r}){let[o,n]=Array.from(e.children);return k(()=>{let i=new T,s=i.pipe(re(),ae(!0));return i.subscribe({next({offset:a}){e.style.setProperty("--md-tooltip-x",`${a.x}px`),e.style.setProperty("--md-tooltip-y",`${a.y}px`)},complete(){e.style.removeProperty("--md-tooltip-x"),e.style.removeProperty("--md-tooltip-y")}}),lt(e).pipe(W(s)).subscribe(a=>{e.toggleAttribute("data-md-visible",a)}),O(i.pipe(v(({active:a})=>a)),i.pipe(Ae(250),v(({active:a})=>!a))).subscribe({next({active:a}){a?e.prepend(o):o.remove()},complete(){e.prepend(o)}}),i.pipe($e(16,ge)).subscribe(({active:a})=>{o.classList.toggle("md-tooltip--active",a)}),i.pipe(gt(125,ge),v(()=>!!e.offsetParent),m(()=>e.offsetParent.getBoundingClientRect()),m(({x:a})=>a)).subscribe({next(a){a?e.style.setProperty("--md-tooltip-0",`${-a}px`):e.style.removeProperty("--md-tooltip-0")},complete(){e.style.removeProperty("--md-tooltip-0")}}),h(n,"click").pipe(W(s),v(a=>!(a.metaKey||a.ctrlKey))).subscribe(a=>{a.stopPropagation(),a.preventDefault()}),h(n,"mousedown").pipe(W(s),te(i)).subscribe(([a,{active:c}])=>{var p;if(a.button!==0||a.metaKey||a.ctrlKey)a.preventDefault();else if(c){a.preventDefault();let l=e.parentElement.closest(".md-annotation");l instanceof HTMLElement?l.focus():(p=Ve())==null||p.blur()}}),r.pipe(W(s),v(a=>a===o),ot(125)).subscribe(()=>e.focus()),za(e,t).pipe(S(a=>i.next(a)),A(()=>i.complete()),m(a=>j({ref:e},a)))})}function qa(e){let t=Te();if(e.tagName!=="CODE")return[e];let r=[".c",".c1",".cm"];if(typeof t.annotate!="undefined"){let o=e.closest("[class|=language]");if(o)for(let n of Array.from(o.classList)){if(!n.startsWith("language-"))continue;let[,i]=n.split("-");i in t.annotate&&r.push(...t.annotate[i])}}return M(r.join(", "),e)}function Ka(e){let t=[];for(let r of qa(e)){let o=[],n=document.createNodeIterator(r,NodeFilter.SHOW_TEXT);for(let i=n.nextNode();i;i=n.nextNode())o.push(i);for(let i of o){let s;for(;s=/(\(\d+\))(!)?/.exec(i.textContent);){let[,a,c]=s;if(typeof c=="undefined"){let p=i.splitText(s.index);i=p.splitText(a.length),t.push(p)}else{i.textContent=a,t.push(i);break}}}}return t}function jn(e,t){t.append(...Array.from(e.childNodes))}function Tr(e,t,{target$:r,print$:o}){let n=t.closest("[id]"),i=n==null?void 0:n.id,s=new Map;for(let a of Ka(t)){let[,c]=a.textContent.match(/\((\d+)\)/);ue(`:scope > li:nth-child(${c})`,e)&&(s.set(c,An(c,i)),a.replaceWith(s.get(c)))}return s.size===0?x:k(()=>{let a=new T,c=a.pipe(re(),ae(!0)),p=[];for(let[l,f]of s)p.push([F(".md-typeset",f),F(`:scope > li:nth-child(${l})`,e)]);return o.pipe(W(c)).subscribe(l=>{e.hidden=!l,e.classList.toggle("md-annotation-list",l);for(let[f,u]of p)l?jn(f,u):jn(u,f)}),O(...[...s].map(([,l])=>Fn(l,t,{target$:r}))).pipe(A(()=>a.complete()),le())})}function Un(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return Un(t)}}function Wn(e,t){return k(()=>{let r=Un(e);return typeof r!="undefined"?Tr(r,e,t):x})}var Nn=Gt(io());var Qa=0,Dn=O(h(window,"keydown").pipe(m(()=>!0)),O(h(window,"keyup"),h(window,"contextmenu")).pipe(m(()=>!1))).pipe(K(!1),X(1));function Vn(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return Vn(t)}}function Ya(e){return Le(e).pipe(m(({width:t})=>({scrollable:Ct(e).width>t})),oe("scrollable"))}function zn(e,t){let{matches:r}=matchMedia("(hover)"),o=k(()=>{let n=new T,i=n.pipe(Yr(1));n.subscribe(({scrollable:d})=>{d&&r?e.setAttribute("tabindex","0"):e.removeAttribute("tabindex")});let s=[],a=e.closest("pre"),c=a.closest("[id]"),p=c?c.id:Qa++;a.id=`__code_${p}`;let l=[],f=e.closest(".highlight");if(f instanceof HTMLElement){let d=Vn(f);if(typeof d!="undefined"&&(f.classList.contains("annotate")||Q("content.code.annotate"))){let g=Tr(d,e,t);l.push(Le(f).pipe(W(i),m(({width:L,height:ee})=>L&&ee),Y(),b(L=>L?g:x)))}}let u=M(":scope > span[id]",e);if(u.length&&(e.classList.add("md-code__content"),e.closest(".select")||Q("content.code.select")&&!e.closest(".no-select"))){let d=+u[0].id.split("-").pop(),g=Hn();s.push(g),Q("content.tooltips")&&l.push(Je(g,{viewport$}));let L=h(g,"click").pipe(Ut(R=>!R,!1),S(()=>g.blur()),le());L.subscribe(R=>{g.classList.toggle("md-code__button--active",R)});let ee=fe(u).pipe(J(R=>nt(R).pipe(m(se=>[R,se]))));L.pipe(b(R=>R?ee:x)).subscribe(([R,se])=>{let ce=ue(".hll.select",R);if(ce&&!se)ce.replaceWith(...Array.from(ce.childNodes));else if(!ce&&se){let he=document.createElement("span");he.className="hll select",he.append(...Array.from(R.childNodes).slice(1)),R.append(he)}});let ne=fe(u).pipe(J(R=>h(R,"mousedown").pipe(S(se=>se.preventDefault()),m(()=>R)))),Z=L.pipe(b(R=>R?ne:x),te(Dn),m(([R,se])=>{var he;let ce=u.indexOf(R)+d;if(se===!1)return[ce,ce];{let Se=M(".hll",e).map(je=>u.indexOf(je.parentElement)+d);return(he=window.getSelection())==null||he.removeAllRanges(),[Math.min(ce,...Se),Math.max(ce,...Se)]}})),H=Zr(x).pipe(v(R=>R.startsWith(`__codelineno-${p}-`)));H.subscribe(R=>{let[,,se]=R.split("-"),ce=se.split(":").map(Se=>+Se-d+1);ce.length===1&&ce.push(ce[0]);for(let Se of M(".hll:not(.select)",e))Se.replaceWith(...Array.from(Se.childNodes));let he=u.slice(ce[0]-1,ce[1]);for(let Se of he){let je=document.createElement("span");je.className="hll",je.append(...Array.from(Se.childNodes).slice(1)),Se.append(je)}}),H.pipe(Ee(1),xe(pe)).subscribe(R=>{if(R.includes(":")){let se=document.getElementById(R.split(":")[0]);se&&setTimeout(()=>{let ce=se,he=-64;for(;ce!==document.body;)he+=ce.offsetTop,ce=ce.offsetParent;window.scrollTo({top:he})},1)}});let Fe=fe(M('a[href^="#__codelineno"]',f)).pipe(J(R=>h(R,"click").pipe(S(se=>se.preventDefault()),m(()=>R)))).pipe(W(i),te(Dn),m(([R,se])=>{let he=+F(`[id="${R.hash.slice(1)}"]`).parentElement.id.split("-").pop();if(se===!1)return[he,he];{let Se=M(".hll",e).map(je=>+je.parentElement.id.split("-").pop());return[Math.min(he,...Se),Math.max(he,...Se)]}}));O(Z,Fe).subscribe(R=>{let se=`#__codelineno-${p}-`;R[0]===R[1]?se+=R[0]:se+=`${R[0]}:${R[1]}`,history.replaceState({},"",se),window.dispatchEvent(new HashChangeEvent("hashchange",{newURL:window.location.origin+window.location.pathname+se,oldURL:window.location.href}))})}if(Nn.default.isSupported()&&(e.closest(".copy")||Q("content.code.copy")&&!e.closest(".no-copy"))){let d=Cn(a.id);s.push(d),Q("content.tooltips")&&l.push(Je(d,{viewport$}))}if(s.length){let d=kn();d.append(...s),a.insertBefore(d,e)}return Ya(e).pipe(S(d=>n.next(d)),A(()=>n.complete()),m(d=>j({ref:e},d)),Ne(O(...l).pipe(W(i))))});return Q("content.lazy")?lt(e).pipe(v(n=>n),Ee(1),b(()=>o)):o}function Ba(e,{target$:t,print$:r}){let o=!0;return O(t.pipe(m(n=>n.closest("details:not([open])")),v(n=>e===n),m(()=>({action:"open",reveal:!0}))),r.pipe(v(n=>n||!o),S(()=>o=e.open),m(n=>({action:n?"open":"close"}))))}function qn(e,t){return k(()=>{let r=new T;return r.subscribe(({action:o,reveal:n})=>{e.toggleAttribute("open",o==="open"),n&&e.scrollIntoView()}),Ba(e,t).pipe(S(o=>r.next(o)),A(()=>r.complete()),m(o=>j({ref:e},o)))})}function Ga(e){let t=document.createElement("h3");t.innerHTML=e.innerHTML;let r=[t],o=e.nextElementSibling;for(;o&&!(o instanceof HTMLHeadingElement);)r.push(o),o=o.nextElementSibling;return r}function Ja(e,t){for(let r of M("[href], [src]",e))for(let o of["href","src"]){let n=r.getAttribute(o);if(n&&!/^(?:[a-z]+:)?\/\//i.test(n)){r[o]=new URL(r.getAttribute(o),t).toString();break}}return $(e)}function Kn(e,t){let{sitemap$:r}=t;if(!(e instanceof HTMLAnchorElement))return x;if(!(Q("navigation.instant.preview")||e.hasAttribute("data-preview")))return x;let o=V([Ke(e),nt(e)]).pipe(m(([i,s])=>i||s),Y(),v(i=>i));return bt([r,o]).pipe(b(([i])=>{let s=new URL(e.href);return s.search=s.hash="",i.has(`${s}`)?$(s):x}),b(i=>yr(i).pipe(b(s=>Ja(s,i)))),b(i=>{let s=e.hash?`article [id="${e.hash.slice(1)}"]`:"article h1",a=ue(s,i);return typeof a=="undefined"?x:$(Ga(a))})).pipe(b(i=>{let s=new I(a=>{let c=wr(...i);return a.next(c),document.body.append(c),()=>c.remove()});return Nt(e,j({content$:s},t))}))}var Qn=".node circle,.node ellipse,.node path,.node polygon,.node rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}marker{fill:var(--md-mermaid-edge-color)!important}.edgeLabel .label rect{fill:#0000}.label{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.label foreignObject{line-height:normal;overflow:visible}.label div .edgeLabel{color:var(--md-mermaid-label-fg-color)}.edgeLabel,.edgeLabel rect,.label div .edgeLabel{background-color:var(--md-mermaid-label-bg-color)}.edgeLabel,.edgeLabel rect{fill:var(--md-mermaid-label-bg-color);color:var(--md-mermaid-edge-color)}.edgePath .path,.flowchart-link{stroke:var(--md-mermaid-edge-color);stroke-width:.05rem}.edgePath .arrowheadPath{fill:var(--md-mermaid-edge-color);stroke:none}.cluster rect{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}.cluster span{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}g #flowchart-circleEnd,g #flowchart-circleStart,g #flowchart-crossEnd,g #flowchart-crossStart,g #flowchart-pointEnd,g #flowchart-pointStart{stroke:none}g.classGroup line,g.classGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.classGroup text{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.classLabel .box{fill:var(--md-mermaid-label-bg-color);background-color:var(--md-mermaid-label-bg-color);opacity:1}.classLabel .label{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.node .divider{stroke:var(--md-mermaid-node-fg-color)}.relation{stroke:var(--md-mermaid-edge-color)}.cardinality{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.cardinality text{fill:inherit!important}defs #classDiagram-compositionEnd,defs #classDiagram-compositionStart,defs #classDiagram-dependencyEnd,defs #classDiagram-dependencyStart,defs #classDiagram-extensionEnd,defs #classDiagram-extensionStart{fill:var(--md-mermaid-edge-color)!important;stroke:var(--md-mermaid-edge-color)!important}defs #classDiagram-aggregationEnd,defs #classDiagram-aggregationStart{fill:var(--md-mermaid-label-bg-color)!important;stroke:var(--md-mermaid-edge-color)!important}g.stateGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.stateGroup .state-title{fill:var(--md-mermaid-label-fg-color)!important;font-family:var(--md-mermaid-font-family)}g.stateGroup .composit{fill:var(--md-mermaid-label-bg-color)}.nodeLabel,.nodeLabel p{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}a .nodeLabel{text-decoration:underline}.node circle.state-end,.node circle.state-start,.start-state{fill:var(--md-mermaid-edge-color);stroke:none}.end-state-inner,.end-state-outer{fill:var(--md-mermaid-edge-color)}.end-state-inner,.node circle.state-end{stroke:var(--md-mermaid-label-bg-color)}.transition{stroke:var(--md-mermaid-edge-color)}[id^=state-fork] rect,[id^=state-join] rect{fill:var(--md-mermaid-edge-color)!important;stroke:none!important}.statediagram-cluster.statediagram-cluster .inner{fill:var(--md-default-bg-color)}.statediagram-cluster rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}.statediagram-state rect.divider{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}defs #statediagram-barbEnd{stroke:var(--md-mermaid-edge-color)}.attributeBoxEven,.attributeBoxOdd{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}.entityBox{fill:var(--md-mermaid-label-bg-color);stroke:var(--md-mermaid-node-fg-color)}.entityLabel{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.relationshipLabelBox{fill:var(--md-mermaid-label-bg-color);fill-opacity:1;background-color:var(--md-mermaid-label-bg-color);opacity:1}.relationshipLabel{fill:var(--md-mermaid-label-fg-color)}.relationshipLine{stroke:var(--md-mermaid-edge-color)}defs #ONE_OR_MORE_END *,defs #ONE_OR_MORE_START *,defs #ONLY_ONE_END *,defs #ONLY_ONE_START *,defs #ZERO_OR_MORE_END *,defs #ZERO_OR_MORE_START *,defs #ZERO_OR_ONE_END *,defs #ZERO_OR_ONE_START *{stroke:var(--md-mermaid-edge-color)!important}defs #ZERO_OR_MORE_END circle,defs #ZERO_OR_MORE_START circle{fill:var(--md-mermaid-label-bg-color)}.actor{fill:var(--md-mermaid-sequence-actor-bg-color);stroke:var(--md-mermaid-sequence-actor-border-color)}text.actor>tspan{fill:var(--md-mermaid-sequence-actor-fg-color);font-family:var(--md-mermaid-font-family)}line{stroke:var(--md-mermaid-sequence-actor-line-color)}.actor-man circle,.actor-man line{fill:var(--md-mermaid-sequence-actorman-bg-color);stroke:var(--md-mermaid-sequence-actorman-line-color)}.messageLine0,.messageLine1{stroke:var(--md-mermaid-sequence-message-line-color)}.note{fill:var(--md-mermaid-sequence-note-bg-color);stroke:var(--md-mermaid-sequence-note-border-color)}.loopText,.loopText>tspan,.messageText,.noteText>tspan{stroke:none;font-family:var(--md-mermaid-font-family)!important}.messageText{fill:var(--md-mermaid-sequence-message-fg-color)}.loopText,.loopText>tspan{fill:var(--md-mermaid-sequence-loop-fg-color)}.noteText>tspan{fill:var(--md-mermaid-sequence-note-fg-color)}#arrowhead path{fill:var(--md-mermaid-sequence-message-line-color);stroke:none}.loopLine{fill:var(--md-mermaid-sequence-loop-bg-color);stroke:var(--md-mermaid-sequence-loop-border-color)}.labelBox{fill:var(--md-mermaid-sequence-label-bg-color);stroke:none}.labelText,.labelText>span{fill:var(--md-mermaid-sequence-label-fg-color);font-family:var(--md-mermaid-font-family)}.sequenceNumber{fill:var(--md-mermaid-sequence-number-fg-color)}rect.rect{fill:var(--md-mermaid-sequence-box-bg-color);stroke:none}rect.rect+text.text{fill:var(--md-mermaid-sequence-box-fg-color)}defs #sequencenumber{fill:var(--md-mermaid-sequence-number-bg-color)!important}";var ao,Za=0;function es(){return typeof mermaid=="undefined"||mermaid instanceof Element?At("https://unpkg.com/mermaid@10/dist/mermaid.min.js"):$(void 0)}function Yn(e){return e.classList.remove("mermaid"),ao||(ao=es().pipe(S(()=>mermaid.initialize({startOnLoad:!1,themeCSS:Qn,sequence:{actorFontSize:"16px",messageFontSize:"16px",noteFontSize:"16px"}})),m(()=>{}),X(1))),ao.subscribe(()=>bo(this,null,function*(){e.classList.add("mermaid");let t=`__mermaid_${Za++}`,r=y("div",{class:"mermaid"}),o=e.textContent,{svg:n,fn:i}=yield mermaid.render(t,o),s=r.attachShadow({mode:"closed"});s.innerHTML=n,e.replaceWith(r),i==null||i(s)})),ao.pipe(m(()=>({ref:e})))}var Bn=y("table");function Gn(e){return e.replaceWith(Bn),Bn.replaceWith(Pn(e)),$({ref:e})}function ts(e){let t=e.find(r=>r.checked)||e[0];return O(...e.map(r=>h(r,"change").pipe(m(()=>F(`label[for="${r.id}"]`))))).pipe(K(F(`label[for="${t.id}"]`)),m(r=>({active:r})))}function Jn(e,{viewport$:t,target$:r}){let o=F(".tabbed-labels",e),n=M(":scope > input",e),i=oo("prev");e.append(i);let s=oo("next");return e.append(s),k(()=>{let a=new T,c=a.pipe(re(),ae(!0));V([a,Le(e),lt(e)]).pipe(W(c),$e(1,ge)).subscribe({next([{active:p},l]){let f=Qe(p),{width:u}=de(p);e.style.setProperty("--md-indicator-x",`${f.x}px`),e.style.setProperty("--md-indicator-width",`${u}px`);let d=gr(o);(f.xd.x+l.width)&&o.scrollTo({left:Math.max(0,f.x-16),behavior:"smooth"})},complete(){e.style.removeProperty("--md-indicator-x"),e.style.removeProperty("--md-indicator-width")}}),V([Ye(o),Le(o)]).pipe(W(c)).subscribe(([p,l])=>{let f=Ct(o);i.hidden=p.x<16,s.hidden=p.x>f.width-l.width-16}),O(h(i,"click").pipe(m(()=>-1)),h(s,"click").pipe(m(()=>1))).pipe(W(c)).subscribe(p=>{let{width:l}=de(o);o.scrollBy({left:l*p,behavior:"smooth"})}),r.pipe(W(c),v(p=>n.includes(p))).subscribe(p=>p.click()),o.classList.add("tabbed-labels--linked");for(let p of n){let l=F(`label[for="${p.id}"]`);l.replaceChildren(y("a",{href:`#${l.htmlFor}`,tabIndex:-1},...Array.from(l.childNodes))),h(l.firstElementChild,"click").pipe(W(c),v(f=>!(f.metaKey||f.ctrlKey)),S(f=>{f.preventDefault(),f.stopPropagation()})).subscribe(()=>{history.replaceState({},"",`#${l.htmlFor}`),l.click()})}return Q("content.tabs.link")&&a.pipe(Pe(1),te(t)).subscribe(([{active:p},{offset:l}])=>{let f=p.innerText.trim();if(p.hasAttribute("data-md-switching"))p.removeAttribute("data-md-switching");else{let u=e.offsetTop-l.y;for(let g of M("[data-tabs]"))for(let L of M(":scope > input",g)){let ee=F(`label[for="${L.id}"]`);if(ee!==p&&ee.innerText.trim()===f){ee.setAttribute("data-md-switching",""),L.click();break}}window.scrollTo({top:e.offsetTop-u});let d=__md_get("__tabs")||[];__md_set("__tabs",[...new Set([f,...d])])}}),a.pipe(W(c)).subscribe(()=>{for(let p of M("audio, video",e))p.pause()}),ts(n).pipe(S(p=>a.next(p)),A(()=>a.complete()),m(p=>j({ref:e},p)))}).pipe(Ze(pe))}function Xn(e,t){let{viewport$:r,target$:o,print$:n}=t;return O(...M(".annotate:not(.highlight)",e).map(i=>Wn(i,{target$:o,print$:n})),...M("pre:not(.mermaid) > code",e).map(i=>zn(i,{target$:o,print$:n})),...M("a:not([title])",e).map(i=>Kn(i,t)),...M("pre.mermaid",e).map(i=>Yn(i)),...M("table:not([class])",e).map(i=>Gn(i)),...M("details",e).map(i=>qn(i,{target$:o,print$:n})),...M("[data-tabs]",e).map(i=>Jn(i,{viewport$:r,target$:o})),...M("[title]",e).filter(()=>Q("content.tooltips")).map(i=>Je(i,{viewport$:r})),...M(".footnote-ref",e).filter(()=>Q("content.footnote.tooltips")).map(i=>Nt(i,{content$:new I(s=>{let a=new URL(i.href).hash.slice(1),c=Array.from(document.getElementById(a).cloneNode(!0).children),p=wr(...c);return s.next(p),document.body.append(p),()=>p.remove()}),viewport$:r})))}function rs(e,{alert$:t}){return t.pipe(b(r=>O($(!0),$(!1).pipe(ot(2e3))).pipe(m(o=>({message:r,active:o})))))}function Zn(e,t){let r=F(".md-typeset",e);return k(()=>{let o=new T;return o.subscribe(({message:n,active:i})=>{e.classList.toggle("md-dialog--active",i),r.textContent=n}),rs(e,t).pipe(S(n=>o.next(n)),A(()=>o.complete()),m(n=>j({ref:e},n)))})}var os=0;function ns(e,t){document.body.append(e);let{width:r}=de(e);e.style.setProperty("--md-tooltip-width",`${r}px`),e.remove();let o=vr(t),n=typeof o!="undefined"?Ye(o):$({x:0,y:0}),i=O(Ke(t),nt(t)).pipe(Y());return V([i,n]).pipe(m(([s,a])=>{let{x:c,y:p}=Qe(t),l=de(t),f=t.closest("table");return f&&t.parentElement&&(c+=f.offsetLeft+t.parentElement.offsetLeft,p+=f.offsetTop+t.parentElement.offsetTop),{active:s,offset:{x:c-a.x+l.width/2-r/2,y:p-a.y+l.height+8}}}))}function ei(e){let t=e.title;if(!t.length)return x;let r=`__tooltip_${os++}`,o=Dt(r,"inline"),n=F(".md-typeset",o);return n.innerHTML=t,k(()=>{let i=new T;return i.subscribe({next({offset:s}){o.style.setProperty("--md-tooltip-x",`${s.x}px`),o.style.setProperty("--md-tooltip-y",`${s.y}px`)},complete(){o.style.removeProperty("--md-tooltip-x"),o.style.removeProperty("--md-tooltip-y")}}),O(i.pipe(v(({active:s})=>s)),i.pipe(Ae(250),v(({active:s})=>!s))).subscribe({next({active:s}){s?(e.insertAdjacentElement("afterend",o),e.setAttribute("aria-describedby",r),e.removeAttribute("title")):(o.remove(),e.removeAttribute("aria-describedby"),e.setAttribute("title",t))},complete(){o.remove(),e.removeAttribute("aria-describedby"),e.setAttribute("title",t)}}),i.pipe($e(16,ge)).subscribe(({active:s})=>{o.classList.toggle("md-tooltip--active",s)}),i.pipe(gt(125,ge),v(()=>!!e.offsetParent),m(()=>e.offsetParent.getBoundingClientRect()),m(({x:s})=>s)).subscribe({next(s){s?o.style.setProperty("--md-tooltip-0",`${-s}px`):o.style.removeProperty("--md-tooltip-0")},complete(){o.style.removeProperty("--md-tooltip-0")}}),ns(o,e).pipe(S(s=>i.next(s)),A(()=>i.complete()),m(s=>j({ref:e},s)))}).pipe(Ze(pe))}function is({viewport$:e}){if(!Q("header.autohide"))return $(!1);let t=e.pipe(m(({offset:{y:n}})=>n),tt(2,1),m(([n,i])=>[nMath.abs(i-n.y)>100),m(([,[n]])=>n),Y()),o=Be("search");return V([e,o]).pipe(m(([{offset:n},i])=>n.y>400&&!i),Y(),b(n=>n?r:$(!1)),K(!1))}function ti(e,t){return k(()=>V([Le(e),is(t)])).pipe(m(([{height:r},o])=>({height:r,hidden:o})),Y((r,o)=>r.height===o.height&&r.hidden===o.hidden),X(1))}function ri(e,{header$:t,main$:r}){return k(()=>{let o=new T,n=o.pipe(re(),ae(!0));o.pipe(oe("active"),De(t)).subscribe(([{active:s},{hidden:a}])=>{e.classList.toggle("md-header--shadow",s&&!a),e.hidden=a});let i=fe(M("[title]",e)).pipe(v(()=>Q("content.tooltips")),J(s=>ei(s)));return r.subscribe(o),t.pipe(W(n),m(s=>j({ref:e},s)),Ne(i.pipe(W(n))))})}function as(e,{viewport$:t,header$:r}){return Er(e,{viewport$:t,header$:r}).pipe(m(({offset:{y:o}})=>{let{height:n}=de(e);return{active:o>=n}}),oe("active"))}function oi(e,t){return k(()=>{let r=new T;r.subscribe({next({active:n}){e.classList.toggle("md-header__title--active",n)},complete(){e.classList.remove("md-header__title--active")}});let o=ue(".md-content h1");return typeof o=="undefined"?x:as(o,t).pipe(S(n=>r.next(n)),A(()=>r.complete()),m(n=>j({ref:e},n)))})}function ni(e,{viewport$:t,header$:r}){let o=r.pipe(m(({height:i})=>i),Y()),n=o.pipe(b(()=>Le(e).pipe(m(({height:i})=>({top:e.offsetTop,bottom:e.offsetTop+i})),oe("bottom"))));return V([o,n,t]).pipe(m(([i,{top:s,bottom:a},{offset:{y:c},size:{height:p}}])=>(p=Math.max(0,p-Math.max(0,s-c,i)-Math.max(0,p+c-a)),{offset:s-i,height:p,active:s-i<=c})),Y((i,s)=>i.offset===s.offset&&i.height===s.height&&i.active===s.active))}function ss(e){let t=__md_get("__palette")||{index:e.findIndex(o=>matchMedia(o.getAttribute("data-md-color-media")).matches)},r=Math.max(0,Math.min(t.index,e.length-1));return $(...e).pipe(J(o=>h(o,"change").pipe(m(()=>o))),K(e[r]),m(o=>({index:e.indexOf(o),color:{media:o.getAttribute("data-md-color-media"),scheme:o.getAttribute("data-md-color-scheme"),primary:o.getAttribute("data-md-color-primary"),accent:o.getAttribute("data-md-color-accent")}})),X(1))}function ii(e){let t=M("input",e),r=y("meta",{name:"theme-color"});document.head.appendChild(r);let o=y("meta",{name:"color-scheme"});document.head.appendChild(o);let n=Wt("(prefers-color-scheme: light)");return k(()=>{let i=new T;return i.subscribe(s=>{if(document.body.setAttribute("data-md-color-switching",""),s.color.media==="(prefers-color-scheme)"){let a=matchMedia("(prefers-color-scheme: light)"),c=document.querySelector(a.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");s.color.scheme=c.getAttribute("data-md-color-scheme"),s.color.primary=c.getAttribute("data-md-color-primary"),s.color.accent=c.getAttribute("data-md-color-accent")}for(let[a,c]of Object.entries(s.color))document.body.setAttribute(`data-md-color-${a}`,c);for(let a=0;as.key==="Enter"),te(i,(s,a)=>a)).subscribe(({index:s})=>{s=(s+1)%t.length,t[s].click(),t[s].focus()}),i.pipe(m(()=>{let s=Ce("header"),a=window.getComputedStyle(s);return o.content=a.colorScheme,a.backgroundColor.match(/\d+/g).map(c=>(+c).toString(16).padStart(2,"0")).join("")})).subscribe(s=>r.content=`#${s}`),i.pipe(xe(pe)).subscribe(()=>{document.body.removeAttribute("data-md-color-switching")}),ss(t).pipe(W(n.pipe(Pe(1))),vt(),S(s=>i.next(s)),A(()=>i.complete()),m(s=>j({ref:e},s)))})}function ai(e,{progress$:t}){return k(()=>{let r=new T;return r.subscribe(({value:o})=>{e.style.setProperty("--md-progress-value",`${o}`)}),t.pipe(S(o=>r.next({value:o})),A(()=>r.complete()),m(o=>({ref:e,value:o})))})}function si(e,t){return e.protocol=t.protocol,e.hostname=t.hostname,e}function cs(e,t){let r=new Map;for(let o of M("url",e)){let n=F("loc",o),i=[si(new URL(n.textContent),t)];r.set(`${i[0]}`,i);for(let s of M("[rel=alternate]",o)){let a=s.getAttribute("href");a!=null&&i.push(si(new URL(a),t))}}return r}function kt(e){return xn(new URL("sitemap.xml",e)).pipe(m(t=>cs(t,new URL(e))),ye(()=>$(new Map)),le())}function ci({document$:e}){let t=new Map;e.pipe(b(()=>M("link[rel=alternate]")),m(r=>new URL(r.href)),v(r=>!t.has(r.toString())),J(r=>kt(r).pipe(m(o=>[r,o]),ye(()=>x)))).subscribe(([r,o])=>{t.set(r.toString().replace(/\/$/,""),o)}),h(document.body,"click").pipe(v(r=>!r.metaKey&&!r.ctrlKey),b(r=>{if(r.target instanceof Element){let o=r.target.closest("a");if(o&&!o.target){let n=[...t].find(([f])=>o.href.startsWith(`${f}/`));if(typeof n=="undefined")return x;let[i,s]=n,a=we();if(a.href.startsWith(i))return x;let c=Te(),p=a.href.replace(c.base,"");p=`${i}/${p}`;let l=s.has(p.split("#")[0])?new URL(p,c.base):new URL(i);return r.preventDefault(),$(l)}}return x})).subscribe(r=>at(r,!0))}var so=Gt(io());function ps(e){e.setAttribute("data-md-copying","");let t=e.closest("[data-copy]"),r=t?t.getAttribute("data-copy"):e.innerText;return e.removeAttribute("data-md-copying"),r.trimEnd()}function pi({alert$:e}){so.default.isSupported()&&new I(t=>{new so.default("[data-clipboard-target], [data-clipboard-text]",{text:r=>r.getAttribute("data-clipboard-text")||ps(F(r.getAttribute("data-clipboard-target")))}).on("success",r=>t.next(r))}).pipe(S(t=>{t.trigger.focus()}),m(()=>Me("clipboard.copied"))).subscribe(e)}function li(e,t){if(!(e.target instanceof Element))return x;let r=e.target.closest("a");if(r===null)return x;if(r.target||e.metaKey||e.ctrlKey)return x;let o=new URL(r.href);return o.search=o.hash="",t.has(`${o}`)?(e.preventDefault(),$(r)):x}function mi(e){let t=new Map;for(let r of M(":scope > *",e.head))t.set(r.outerHTML,r);return t}function fi(e){for(let t of M("[href], [src]",e))for(let r of["href","src"]){let o=t.getAttribute(r);if(o&&!/^(?:[a-z]+:)?\/\//i.test(o)){t[r]=t[r];break}}return $(e)}function ls(e){for(let o of["[data-md-component=announce]","[data-md-component=container]","[data-md-component=header-topic]","[data-md-component=outdated]","[data-md-component=logo]","[data-md-component=skip]",...Q("navigation.tabs.sticky")?["[data-md-component=tabs]"]:[]]){let n=ue(o),i=ue(o,e);typeof n!="undefined"&&typeof i!="undefined"&&n.replaceWith(i)}let t=mi(document);for(let[o,n]of mi(e))t.has(o)?t.delete(o):document.head.appendChild(n);for(let o of t.values()){let n=o.getAttribute("name");n!=="theme-color"&&n!=="color-scheme"&&o.remove()}let r=Ce("container");return qe(M("script",r)).pipe(b(o=>{let n=e.createElement("script");if(o.src){for(let i of o.getAttributeNames())n.setAttribute(i,o.getAttribute(i));return o.replaceWith(n),new I(i=>{n.onload=()=>i.complete()})}else return n.textContent=o.textContent,o.replaceWith(n),x}),re(),ae(document))}function ui({sitemap$:e,location$:t,viewport$:r,progress$:o}){if(location.protocol==="file:")return x;$(document).subscribe(fi);let n=h(document.body,"click").pipe(De(e),b(([a,c])=>li(a,c)),m(({href:a})=>new URL(a)),le()),i=h(window,"popstate").pipe(m(we),le());n.pipe(te(r)).subscribe(([a,{offset:c}])=>{history.replaceState(c,""),history.pushState(null,"",a)}),O(n,i).subscribe(t);let s=t.pipe(oe("pathname"),b(a=>yr(a,{progress$:o}).pipe(ye(()=>(at(a,!0),x)))),b(fi),b(ls),le());return O(s.pipe(te(t,(a,c)=>c)),s.pipe(b(()=>t),oe("pathname"),b(()=>t),oe("hash")),t.pipe(Y((a,c)=>a.pathname===c.pathname&&a.hash===c.hash),b(()=>n),S(()=>history.back()))).subscribe(a=>{var c,p;history.state!==null||!a.hash?window.scrollTo(0,(p=(c=history.state)==null?void 0:c.y)!=null?p:0):(history.scrollRestoration="auto",bn(a.hash),history.scrollRestoration="manual")}),t.subscribe(()=>{history.scrollRestoration="manual"}),h(window,"beforeunload").subscribe(()=>{history.scrollRestoration="auto"}),r.pipe(oe("offset"),Ae(100)).subscribe(({offset:a})=>{history.replaceState(a,"")}),Q("navigation.instant.prefetch")&&O(h(document.body,"mousemove"),h(document.body,"focusin")).pipe(De(e),b(([a,c])=>li(a,c)),Ae(25),Qr(({href:a})=>a),hr(a=>{let c=document.createElement("link");return c.rel="prefetch",c.href=a.toString(),document.head.appendChild(c),h(c,"load").pipe(m(()=>c),Ee(1))})).subscribe(a=>a.remove()),s}var bi=Gt(hi());function vi(e){let t=e.separator.split("|").map(n=>n.replace(/(\(\?[!=<][^)]+\))/g,"").length===0?"\uFFFD":n).join("|"),r=new RegExp(t,"img"),o=(n,i,s)=>`${i}${s}`;return n=>{n=n.replace(/[\s*+\-:~^]+/g," ").trim();let i=new RegExp(`(^|${e.separator}|)(${n.replace(/[|\\{}()[\]^$+*?.-]/g,"\\$&").replace(r,"|")})`,"img");return s=>(0,bi.default)(s).replace(i,o).replace(/<\/mark>(\s+)]*>/img,"$1")}}function zt(e){return e.type===1}function Sr(e){return e.type===3}function gi(e,t){let r=On(e);return O($(location.protocol!=="file:"),Be("search")).pipe(Re(o=>o),b(()=>t)).subscribe(({config:o,docs:n})=>r.next({type:0,data:{config:o,docs:n,options:{suggest:Q("search.suggest")}}})),r}function xi({document$:e}){let t=Te(),r=Ge(new URL("../versions.json",t.base)).pipe(ye(()=>x)),o=r.pipe(m(n=>{let[,i]=t.base.match(/([^/]+)\/?$/);return n.find(({version:s,aliases:a})=>s===i||a.includes(i))||n[0]}));r.pipe(m(n=>new Map(n.map(i=>[`${new URL(`../${i.version}/`,t.base)}`,i]))),b(n=>h(document.body,"click").pipe(v(i=>!i.metaKey&&!i.ctrlKey),te(o),b(([i,s])=>{if(i.target instanceof Element){let a=i.target.closest("a");if(a&&!a.target&&n.has(a.href)){let c=a.href;return!i.target.closest(".md-version")&&n.get(c)===s?x:(i.preventDefault(),$(c))}}return x}),b(i=>kt(new URL(i)).pipe(m(s=>{let c=we().href.replace(t.base,i);return s.has(c.split("#")[0])?new URL(c):new URL(i)})))))).subscribe(n=>at(n,!0)),V([r,o]).subscribe(([n,i])=>{F(".md-header__topic").appendChild(In(n,i))}),e.pipe(b(()=>o)).subscribe(n=>{var s;let i=__md_get("__outdated",sessionStorage);if(i===null){i=!0;let a=((s=t.version)==null?void 0:s.default)||"latest";Array.isArray(a)||(a=[a]);e:for(let c of a)for(let p of n.aliases.concat(n.version))if(new RegExp(c,"i").test(p)){i=!1;break e}__md_set("__outdated",i,sessionStorage)}if(i)for(let a of me("outdated"))a.hidden=!1})}function hs(e,{worker$:t}){let{searchParams:r}=we();r.has("q")&&(it("search",!0),e.value=r.get("q"),e.focus(),Be("search").pipe(Re(i=>!i)).subscribe(()=>{let i=we();i.searchParams.delete("q"),history.replaceState({},"",`${i}`)}));let o=Ke(e),n=O(t.pipe(Re(zt)),h(e,"keyup"),o).pipe(m(()=>e.value),Y());return V([n,o]).pipe(m(([i,s])=>({value:i,focus:s})),X(1))}function yi(e,{worker$:t}){let r=new T,o=r.pipe(re(),ae(!0));V([t.pipe(Re(zt)),r],(i,s)=>s).pipe(oe("value")).subscribe(({value:i})=>t.next({type:2,data:i})),r.pipe(oe("focus")).subscribe(({focus:i})=>{i&&it("search",i)}),h(e.form,"reset").pipe(W(o)).subscribe(()=>e.focus());let n=F("header [for=__search]");return h(n,"click").subscribe(()=>e.focus()),hs(e,{worker$:t}).pipe(S(i=>r.next(i)),A(()=>r.complete()),m(i=>j({ref:e},i)),X(1))}function Ei(e,{worker$:t,query$:r}){let o=new T,n=mn(e.parentElement).pipe(v(Boolean)),i=e.parentElement,s=F(":scope > :first-child",e),a=F(":scope > :last-child",e);Be("search").subscribe(l=>a.setAttribute("role",l?"list":"presentation")),o.pipe(te(r),Gr(t.pipe(Re(zt)))).subscribe(([{items:l},{value:f}])=>{switch(l.length){case 0:s.textContent=f.length?Me("search.result.none"):Me("search.result.placeholder");break;case 1:s.textContent=Me("search.result.one");break;default:let u=br(l.length);s.textContent=Me("search.result.other",u)}});let c=o.pipe(S(()=>a.innerHTML=""),b(({items:l})=>O($(...l.slice(0,10)),$(...l.slice(10)).pipe(tt(4),Xr(n),b(([f])=>f)))),m($n),le());return c.subscribe(l=>a.appendChild(l)),c.pipe(J(l=>{let f=ue("details",l);return typeof f=="undefined"?x:h(f,"toggle").pipe(W(o),m(()=>f))})).subscribe(l=>{l.open===!1&&l.offsetTop<=i.scrollTop&&i.scrollTo({top:l.offsetTop})}),t.pipe(v(Sr),m(({data:l})=>l)).pipe(S(l=>o.next(l)),A(()=>o.complete()),m(l=>j({ref:e},l)))}function bs(e,{query$:t}){return t.pipe(m(({value:r})=>{let o=we();return o.hash="",r=r.replace(/\s+/g,"+").replace(/&/g,"%26").replace(/=/g,"%3D"),o.search=`q=${r}`,{url:o}}))}function wi(e,t){let r=new T,o=r.pipe(re(),ae(!0));return r.subscribe(({url:n})=>{e.setAttribute("data-clipboard-text",e.href),e.href=`${n}`}),h(e,"click").pipe(W(o)).subscribe(n=>n.preventDefault()),bs(e,t).pipe(S(n=>r.next(n)),A(()=>r.complete()),m(n=>j({ref:e},n)))}function Ti(e,{worker$:t,keyboard$:r}){let o=new T,n=Ce("search-query"),i=O(h(n,"keydown"),h(n,"focus")).pipe(xe(pe),m(()=>n.value),Y());return o.pipe(De(i),m(([{suggest:a},c])=>{let p=c.split(/([\s-]+)/);if(a!=null&&a.length&&p[p.length-1]){let l=a[a.length-1];l.startsWith(p[p.length-1])&&(p[p.length-1]=l)}else p.length=0;return p})).subscribe(a=>e.innerHTML=a.join("").replace(/\s/g," ")),r.pipe(v(({mode:a})=>a==="search")).subscribe(a=>{switch(a.type){case"ArrowRight":e.innerText.length&&n.selectionStart===n.value.length&&(n.value=e.innerText);break}}),t.pipe(v(Sr),m(({data:a})=>a)).pipe(S(a=>o.next(a)),A(()=>o.complete()),m(()=>({ref:e})))}function Si(e,{index$:t,keyboard$:r}){let o=Te();try{let n=gi(o.search,t),i=Ce("search-query",e),s=Ce("search-result",e);h(e,"click").pipe(v(({target:c})=>c instanceof Element&&!!c.closest("a"))).subscribe(()=>it("search",!1)),r.pipe(v(({mode:c})=>c==="search")).subscribe(c=>{let p=Ve();switch(c.type){case"Enter":if(p===i){let l=new Map;for(let f of M(":first-child [href]",s)){let u=f.firstElementChild;l.set(f,parseFloat(u.getAttribute("data-md-score")))}if(l.size){let[[f]]=[...l].sort(([,u],[,d])=>d-u);f.click()}c.claim()}break;case"Escape":case"Tab":it("search",!1),i.blur();break;case"ArrowUp":case"ArrowDown":if(typeof p=="undefined")i.focus();else{let l=[i,...M(":not(details) > [href], summary, details[open] [href]",s)],f=Math.max(0,(Math.max(0,l.indexOf(p))+l.length+(c.type==="ArrowUp"?-1:1))%l.length);l[f].focus()}c.claim();break;default:i!==Ve()&&i.focus()}}),r.pipe(v(({mode:c})=>c==="global")).subscribe(c=>{switch(c.type){case"f":case"s":case"/":i.focus(),i.select(),c.claim();break}});let a=yi(i,{worker$:n});return O(a,Ei(s,{worker$:n,query$:a})).pipe(Ne(...me("search-share",e).map(c=>wi(c,{query$:a})),...me("search-suggest",e).map(c=>Ti(c,{worker$:n,keyboard$:r}))))}catch(n){return e.hidden=!0,et}}function Oi(e,{index$:t,location$:r}){return V([t,r.pipe(K(we()),v(o=>!!o.searchParams.get("h")))]).pipe(m(([o,n])=>vi(o.config)(n.searchParams.get("h"))),m(o=>{var s;let n=new Map,i=document.createNodeIterator(e,NodeFilter.SHOW_TEXT);for(let a=i.nextNode();a;a=i.nextNode())if((s=a.parentElement)!=null&&s.offsetHeight){let c=a.textContent,p=o(c);p.length>c.length&&n.set(a,p)}for(let[a,c]of n){let{childNodes:p}=y("span",null,c);a.replaceWith(...Array.from(p))}return{ref:e,nodes:n}}))}function vs(e,{viewport$:t,main$:r}){let o=e.closest(".md-grid"),n=o.offsetTop-o.parentElement.offsetTop;return V([r,t]).pipe(m(([{offset:i,height:s},{offset:{y:a}}])=>(s=s+Math.min(n,Math.max(0,a-i))-n,{height:s,locked:a>=i+n})),Y((i,s)=>i.height===s.height&&i.locked===s.locked))}function co(e,o){var n=o,{header$:t}=n,r=ho(n,["header$"]);let i=F(".md-sidebar__scrollwrap",e),{y:s}=Qe(i);return k(()=>{let a=new T,c=a.pipe(re(),ae(!0)),p=a.pipe($e(0,ge));return p.pipe(te(t)).subscribe({next([{height:l},{height:f}]){i.style.height=`${l-2*s}px`,e.style.top=`${f}px`},complete(){i.style.height="",e.style.top=""}}),p.pipe(Re()).subscribe(()=>{for(let l of M(".md-nav__link--active[href]",e)){if(!l.clientHeight)continue;let f=l.closest(".md-sidebar__scrollwrap");if(typeof f!="undefined"){let u=l.offsetTop-f.offsetTop,{height:d}=de(f);f.scrollTo({top:u-d/2})}}}),fe(M("label[tabindex]",e)).pipe(J(l=>h(l,"click").pipe(xe(pe),m(()=>l),W(c)))).subscribe(l=>{let f=F(`[id="${l.htmlFor}"]`);F(`[aria-labelledby="${l.id}"]`).setAttribute("aria-expanded",`${f.checked}`)}),Q("content.tooltips")&&fe(M("abbr[title]",e)).pipe(J(l=>Je(l,{viewport$})),W(c)).subscribe(),vs(e,r).pipe(S(l=>a.next(l)),A(()=>a.complete()),m(l=>j({ref:e},l)))})}function Li(e,t){if(typeof t!="undefined"){let r=`https://api.github.com/repos/${e}/${t}`;return bt(Ge(`${r}/releases/latest`).pipe(ye(()=>x),m(o=>({version:o.tag_name})),rt({})),Ge(r).pipe(ye(()=>x),m(o=>({stars:o.stargazers_count,forks:o.forks_count})),rt({}))).pipe(m(([o,n])=>j(j({},o),n)))}else{let r=`https://api.github.com/users/${e}`;return Ge(r).pipe(m(o=>({repositories:o.public_repos})),rt({}))}}function Mi(e,t){let r=`https://${e}/api/v4/projects/${encodeURIComponent(t)}`;return Ge(r).pipe(ye(()=>x),m(({star_count:o,forks_count:n})=>({stars:o,forks:n})),rt({}))}function _i(e){let t=e.match(/^.+github\.com\/([^/]+)\/?([^/]+)?/i);if(t){let[,r,o]=t;return Li(r,o)}if(t=e.match(/^.+?([^/]*gitlab[^/]+)\/(.+?)\/?$/i),t){let[,r,o]=t;return Mi(r,o)}return x}var gs;function xs(e){return gs||(gs=k(()=>{let t=__md_get("__source",sessionStorage);if(t)return $(t);if(me("consent").length){let o=__md_get("__consent");if(!(o&&o.github))return x}return _i(e.href).pipe(S(o=>__md_set("__source",o,sessionStorage)))}).pipe(ye(()=>x),v(t=>Object.keys(t).length>0),m(t=>({facts:t})),X(1)))}function Ai(e){let t=F(":scope > :last-child",e);return k(()=>{let r=new T;return r.subscribe(({facts:o})=>{t.appendChild(Rn(o)),t.classList.add("md-source__repository--active")}),xs(e).pipe(S(o=>r.next(o)),A(()=>r.complete()),m(o=>j({ref:e},o)))})}function ys(e,{viewport$:t,header$:r}){return Le(document.body).pipe(b(()=>Er(e,{header$:r,viewport$:t})),m(({offset:{y:o}})=>({hidden:o>=10})),oe("hidden"))}function Ci(e,t){return k(()=>{let r=new T;return r.subscribe({next({hidden:o}){e.hidden=o},complete(){e.hidden=!1}}),(Q("navigation.tabs.sticky")?$({hidden:!1}):ys(e,t)).pipe(S(o=>r.next(o)),A(()=>r.complete()),m(o=>j({ref:e},o)))})}function Es(e,{viewport$:t,header$:r}){let o=new Map,n=M(".md-nav__link",e);for(let a of n){let c=decodeURIComponent(a.hash.substring(1)),p=ue(`[id="${c}"]`);typeof p!="undefined"&&o.set(a,p)}let i=r.pipe(oe("height"),m(({height:a})=>{let c=Ce("main"),p=F(":scope > :first-child",c);return a+.8*(p.offsetTop-c.offsetTop)}),le());return Le(document.body).pipe(oe("height"),b(a=>k(()=>{let c=[];return $([...o].reduce((p,[l,f])=>{for(;c.length&&o.get(c[c.length-1]).tagName>=f.tagName;)c.pop();let u=f.offsetTop;for(;!u&&f.parentElement;)f=f.parentElement,u=f.offsetTop;let d=f.offsetParent;for(;d;d=d.offsetParent)u+=d.offsetTop;return p.set([...c=[...c,l]].reverse(),u)},new Map))}).pipe(m(c=>new Map([...c].sort(([,p],[,l])=>p-l))),De(i),b(([c,p])=>t.pipe(Ut(([l,f],{offset:{y:u},size:d})=>{let g=u+d.height>=Math.floor(a.height);for(;f.length;){let[,L]=f[0];if(L-p=u&&!g)f=[l.pop(),...f];else break}return[l,f]},[[],[...c]]),Y((l,f)=>l[0]===f[0]&&l[1]===f[1])))))).pipe(m(([a,c])=>({prev:a.map(([p])=>p),next:c.map(([p])=>p)})),K({prev:[],next:[]}),tt(2,1),m(([a,c])=>a.prev.length{let i=new T,s=i.pipe(re(),ae(!0));if(i.subscribe(({prev:a,next:c})=>{for(let[p]of c)p.classList.remove("md-nav__link--passed"),p.classList.remove("md-nav__link--active");for(let[p,[l]]of a.entries())l.classList.add("md-nav__link--passed"),l.classList.toggle("md-nav__link--active",p===a.length-1)}),Q("toc.follow")){let a=O(t.pipe(Ae(1),m(()=>{})),t.pipe(Ae(250),m(()=>"smooth")));i.pipe(v(({prev:c})=>c.length>0),De(o.pipe(xe(pe))),te(a)).subscribe(([[{prev:c}],p])=>{let[l]=c[c.length-1];if(l.offsetHeight){let f=vr(l);if(typeof f!="undefined"){let u=l.offsetTop-f.offsetTop,{height:d}=de(f);f.scrollTo({top:u-d/2,behavior:p})}}})}return Q("navigation.tracking")&&t.pipe(W(s),oe("offset"),Ae(250),Pe(1),W(n.pipe(Pe(1))),vt({delay:250}),te(i)).subscribe(([,{prev:a}])=>{let c=we(),p=a[a.length-1];if(p&&p.length){let[l]=p,{hash:f}=new URL(l.href);c.hash!==f&&(c.hash=f,history.replaceState({},"",`${c}`))}else c.hash="",history.replaceState({},"",`${c}`)}),Es(e,{viewport$:t,header$:r}).pipe(S(a=>i.next(a)),A(()=>i.complete()),m(a=>j({ref:e},a)))})}function ws(e,{viewport$:t,main$:r,target$:o}){let n=t.pipe(m(({offset:{y:s}})=>s),tt(2,1),m(([s,a])=>s>a&&a>0),Y()),i=r.pipe(m(({active:s})=>s));return V([i,n]).pipe(m(([s,a])=>!(s&&a)),Y(),W(o.pipe(Pe(1))),ae(!0),vt({delay:250}),m(s=>({hidden:s})))}function ki(e,{viewport$:t,header$:r,main$:o,target$:n}){let i=new T,s=i.pipe(re(),ae(!0));return i.subscribe({next({hidden:a}){e.hidden=a,a?(e.setAttribute("tabindex","-1"),e.blur()):e.removeAttribute("tabindex")},complete(){e.style.top="",e.hidden=!0,e.removeAttribute("tabindex")}}),r.pipe(W(s),oe("height")).subscribe(({height:a})=>{e.style.top=`${a+16}px`}),h(e,"click").subscribe(a=>{a.preventDefault(),window.scrollTo({top:0})}),ws(e,{viewport$:t,main$:o,target$:n}).pipe(S(a=>i.next(a)),A(()=>i.complete()),m(a=>j({ref:e},a)))}function $i({document$:e,viewport$:t}){e.pipe(b(()=>M(".md-ellipsis")),J(r=>lt(r).pipe(W(e.pipe(Pe(1))),v(o=>o),m(()=>r),Ee(1))),v(r=>r.offsetWidth{let o=r.innerText,n=r.closest("a")||r;return n.title=o,Je(n,{viewport$:t}).pipe(W(e.pipe(Pe(1))),A(()=>n.removeAttribute("title")))})).subscribe(),e.pipe(b(()=>M(".md-status")),J(r=>Je(r,{viewport$:t}))).subscribe()}function Ri({document$:e,tablet$:t}){e.pipe(b(()=>M(".md-toggle--indeterminate")),S(r=>{r.indeterminate=!0,r.checked=!1}),J(r=>h(r,"change").pipe(Jr(()=>r.classList.contains("md-toggle--indeterminate")),m(()=>r))),te(t)).subscribe(([r,o])=>{r.classList.remove("md-toggle--indeterminate"),o&&(r.checked=!1)})}function Ts(){return/(iPad|iPhone|iPod)/.test(navigator.userAgent)}function Pi({document$:e}){e.pipe(b(()=>M("[data-md-scrollfix]")),S(t=>t.removeAttribute("data-md-scrollfix")),v(Ts),J(t=>h(t,"touchstart").pipe(m(()=>t)))).subscribe(t=>{let r=t.scrollTop;r===0?t.scrollTop=1:r+t.offsetHeight===t.scrollHeight&&(t.scrollTop=r-1)})}function Ii({viewport$:e,tablet$:t}){V([Be("search"),t]).pipe(m(([r,o])=>r&&!o),b(r=>$(r).pipe(ot(r?400:100))),te(e)).subscribe(([r,{offset:{y:o}}])=>{if(r)document.body.setAttribute("data-md-scrolllock",""),document.body.style.top=`-${o}px`;else{let n=-1*parseInt(document.body.style.top,10);document.body.removeAttribute("data-md-scrolllock"),document.body.style.top="",n&&window.scrollTo(0,n)}})}Object.entries||(Object.entries=function(e){let t=[];for(let r of Object.keys(e))t.push([r,e[r]]);return t});Object.values||(Object.values=function(e){let t=[];for(let r of Object.keys(e))t.push(e[r]);return t});typeof Element!="undefined"&&(Element.prototype.scrollTo||(Element.prototype.scrollTo=function(e,t){typeof e=="object"?(this.scrollLeft=e.left,this.scrollTop=e.top):(this.scrollLeft=e,this.scrollTop=t)}),Element.prototype.replaceWith||(Element.prototype.replaceWith=function(...e){let t=this.parentNode;if(t){e.length===0&&t.removeChild(this);for(let r=e.length-1;r>=0;r--){let o=e[r];typeof o=="string"?o=document.createTextNode(o):o.parentNode&&o.parentNode.removeChild(o),r?t.insertBefore(this.previousSibling,o):t.replaceChild(o,this)}}}));function Ss(){return location.protocol==="file:"?At(`${new URL("search/search_index.js",Or.base)}`).pipe(m(()=>__index),X(1)):Ge(new URL("search/search_index.json",Or.base))}document.documentElement.classList.remove("no-js");document.documentElement.classList.add("js");var st=on(),Kt=dn(),$t=vn(Kt),po=un(),He=Sn(),Lr=Wt("(min-width: 960px)"),ji=Wt("(min-width: 1220px)"),Ui=gn(),Or=Te(),Wi=document.forms.namedItem("search")?Ss():et,lo=new T;pi({alert$:lo});ci({document$:st});var mo=new T,Di=kt(Or.base);Q("navigation.instant")&&ui({sitemap$:Di,location$:Kt,viewport$:He,progress$:mo}).subscribe(st);var Fi;((Fi=Or.version)==null?void 0:Fi.provider)==="mike"&&xi({document$:st});O(Kt,$t).pipe(ot(125)).subscribe(()=>{it("drawer",!1),it("search",!1)});po.pipe(v(({mode:e})=>e==="global")).subscribe(e=>{switch(e.type){case"p":case",":let t=ue("link[rel=prev]");typeof t!="undefined"&&at(t);break;case"n":case".":let r=ue("link[rel=next]");typeof r!="undefined"&&at(r);break;case"Enter":let o=Ve();o instanceof HTMLLabelElement&&o.click()}});$i({viewport$:He,document$:st});Ri({document$:st,tablet$:Lr});Pi({document$:st});Ii({viewport$:He,tablet$:Lr});var mt=ti(Ce("header"),{viewport$:He}),qt=st.pipe(m(()=>Ce("main")),b(e=>ni(e,{viewport$:He,header$:mt})),X(1)),Os=O(...me("consent").map(e=>Mn(e,{target$:$t})),...me("dialog").map(e=>Zn(e,{alert$:lo})),...me("header").map(e=>ri(e,{viewport$:He,header$:mt,main$:qt})),...me("palette").map(e=>ii(e)),...me("progress").map(e=>ai(e,{progress$:mo})),...me("search").map(e=>Si(e,{index$:Wi,keyboard$:po})),...me("source").map(e=>Ai(e))),Ls=k(()=>O(...me("announce").map(e=>Ln(e)),...me("content").map(e=>Xn(e,{sitemap$:Di,viewport$:He,target$:$t,print$:Ui})),...me("content").map(e=>Q("search.highlight")?Oi(e,{index$:Wi,location$:Kt}):x),...me("header-title").map(e=>oi(e,{viewport$:He,header$:mt})),...me("sidebar").map(e=>e.getAttribute("data-md-type")==="navigation"?eo(ji,()=>co(e,{viewport$:He,header$:mt,main$:qt})):eo(Lr,()=>co(e,{viewport$:He,header$:mt,main$:qt}))),...me("tabs").map(e=>Ci(e,{viewport$:He,header$:mt})),...me("toc").map(e=>Hi(e,{viewport$:He,header$:mt,main$:qt,target$:$t})),...me("top").map(e=>ki(e,{viewport$:He,header$:mt,main$:qt,target$:$t})))),Ni=st.pipe(b(()=>Ls),Ne(Os),X(1));Ni.subscribe();window.document$=st;window.location$=Kt;window.target$=$t;window.keyboard$=po;window.viewport$=He;window.tablet$=Lr;window.screen$=ji;window.print$=Ui;window.alert$=lo;window.progress$=mo;window.component$=Ni;})(); diff --git a/assets/javascripts/lunr/min/lunr.ar.min.js b/assets/javascripts/lunr/min/lunr.ar.min.js new file mode 100644 index 00000000..9b06c26c --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.ar.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.ar=function(){this.pipeline.reset(),this.pipeline.add(e.ar.trimmer,e.ar.stopWordFilter,e.ar.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ar.stemmer))},e.ar.wordCharacters="ء-ٛٱـ",e.ar.trimmer=e.trimmerSupport.generateTrimmer(e.ar.wordCharacters),e.Pipeline.registerFunction(e.ar.trimmer,"trimmer-ar"),e.ar.stemmer=function(){var e=this;return e.result=!1,e.preRemoved=!1,e.sufRemoved=!1,e.pre={pre1:"ف ك ب و س ل ن ا ي ت",pre2:"ال لل",pre3:"بال وال فال تال كال ولل",pre4:"فبال كبال وبال وكال"},e.suf={suf1:"ه ك ت ن ا ي",suf2:"نك نه ها وك يا اه ون ين تن تم نا وا ان كم كن ني نن ما هم هن تك ته ات يه",suf3:"تين كهم نيه نهم ونه وها يهم ونا ونك وني وهم تكم تنا تها تني تهم كما كها ناه نكم هنا تان يها",suf4:"كموه ناها ونني ونهم تكما تموه تكاه كماه ناكم ناهم نيها وننا"},e.patterns=JSON.parse('{"pt43":[{"pt":[{"c":"ا","l":1}]},{"pt":[{"c":"ا,ت,ن,ي","l":0}],"mPt":[{"c":"ف","l":0,"m":1},{"c":"ع","l":1,"m":2},{"c":"ل","l":2,"m":3}]},{"pt":[{"c":"و","l":2}],"mPt":[{"c":"ف","l":0,"m":0},{"c":"ع","l":1,"m":1},{"c":"ل","l":2,"m":3}]},{"pt":[{"c":"ا","l":2}]},{"pt":[{"c":"ي","l":2}],"mPt":[{"c":"ف","l":0,"m":0},{"c":"ع","l":1,"m":1},{"c":"ا","l":2},{"c":"ل","l":3,"m":3}]},{"pt":[{"c":"م","l":0}]}],"pt53":[{"pt":[{"c":"ت","l":0},{"c":"ا","l":2}]},{"pt":[{"c":"ا,ن,ت,ي","l":0},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ت","l":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"ا","l":0},{"c":"ا","l":2}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ع","l":2,"m":3},{"c":"ل","l":3,"m":4},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"ا","l":0},{"c":"ا","l":3}],"mPt":[{"c":"ف","l":0,"m":1},{"c":"ع","l":1,"m":2},{"c":"ل","l":2,"m":4}]},{"pt":[{"c":"ا","l":3},{"c":"ن","l":4}]},{"pt":[{"c":"ت","l":0},{"c":"ي","l":3}]},{"pt":[{"c":"م","l":0},{"c":"و","l":3}]},{"pt":[{"c":"ا","l":1},{"c":"و","l":3}]},{"pt":[{"c":"و","l":1},{"c":"ا","l":2}]},{"pt":[{"c":"م","l":0},{"c":"ا","l":3}]},{"pt":[{"c":"م","l":0},{"c":"ي","l":3}]},{"pt":[{"c":"ا","l":2},{"c":"ن","l":3}]},{"pt":[{"c":"م","l":0},{"c":"ن","l":1}],"mPt":[{"c":"ا","l":0},{"c":"ن","l":1},{"c":"ف","l":2,"m":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"م","l":0},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ت","l":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"م","l":0},{"c":"ا","l":2}]},{"pt":[{"c":"م","l":1},{"c":"ا","l":3}]},{"pt":[{"c":"ي,ت,ا,ن","l":0},{"c":"ت","l":1}],"mPt":[{"c":"ف","l":0,"m":2},{"c":"ع","l":1,"m":3},{"c":"ا","l":2},{"c":"ل","l":3,"m":4}]},{"pt":[{"c":"ت,ي,ا,ن","l":0},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ت","l":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"ا","l":2},{"c":"ي","l":3}]},{"pt":[{"c":"ا,ي,ت,ن","l":0},{"c":"ن","l":1}],"mPt":[{"c":"ا","l":0},{"c":"ن","l":1},{"c":"ف","l":2,"m":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"ا","l":3},{"c":"ء","l":4}]}],"pt63":[{"pt":[{"c":"ا","l":0},{"c":"ت","l":2},{"c":"ا","l":4}]},{"pt":[{"c":"ا,ت,ن,ي","l":0},{"c":"س","l":1},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"س","l":1},{"c":"ت","l":2},{"c":"ف","l":3,"m":3},{"c":"ع","l":4,"m":4},{"c":"ا","l":5},{"c":"ل","l":6,"m":5}]},{"pt":[{"c":"ا,ن,ت,ي","l":0},{"c":"و","l":3}]},{"pt":[{"c":"م","l":0},{"c":"س","l":1},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"س","l":1},{"c":"ت","l":2},{"c":"ف","l":3,"m":3},{"c":"ع","l":4,"m":4},{"c":"ا","l":5},{"c":"ل","l":6,"m":5}]},{"pt":[{"c":"ي","l":1},{"c":"ي","l":3},{"c":"ا","l":4},{"c":"ء","l":5}]},{"pt":[{"c":"ا","l":0},{"c":"ن","l":1},{"c":"ا","l":4}]}],"pt54":[{"pt":[{"c":"ت","l":0}]},{"pt":[{"c":"ا,ي,ت,ن","l":0}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ع","l":2,"m":2},{"c":"ل","l":3,"m":3},{"c":"ر","l":4,"m":4},{"c":"ا","l":5},{"c":"ر","l":6,"m":4}]},{"pt":[{"c":"م","l":0}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ع","l":2,"m":2},{"c":"ل","l":3,"m":3},{"c":"ر","l":4,"m":4},{"c":"ا","l":5},{"c":"ر","l":6,"m":4}]},{"pt":[{"c":"ا","l":2}]},{"pt":[{"c":"ا","l":0},{"c":"ن","l":2}]}],"pt64":[{"pt":[{"c":"ا","l":0},{"c":"ا","l":4}]},{"pt":[{"c":"م","l":0},{"c":"ت","l":1}]}],"pt73":[{"pt":[{"c":"ا","l":0},{"c":"س","l":1},{"c":"ت","l":2},{"c":"ا","l":5}]}],"pt75":[{"pt":[{"c":"ا","l":0},{"c":"ا","l":5}]}]}'),e.execArray=["cleanWord","removeDiacritics","cleanAlef","removeStopWords","normalizeHamzaAndAlef","removeStartWaw","removePre432","removeEndTaa","wordCheck"],e.stem=function(){var r=0;for(e.result=!1,e.preRemoved=!1,e.sufRemoved=!1;r=0)return!0},e.normalizeHamzaAndAlef=function(){return e.word=e.word.replace("ؤ","ء"),e.word=e.word.replace("ئ","ء"),e.word=e.word.replace(/([\u0627])\1+/gi,"ا"),!1},e.removeEndTaa=function(){return!(e.word.length>2)||(e.word=e.word.replace(/[\u0627]$/,""),e.word=e.word.replace("ة",""),!1)},e.removeStartWaw=function(){return e.word.length>3&&"و"==e.word[0]&&"و"==e.word[1]&&(e.word=e.word.slice(1)),!1},e.removePre432=function(){var r=e.word;if(e.word.length>=7){var t=new RegExp("^("+e.pre.pre4.split(" ").join("|")+")");e.word=e.word.replace(t,"")}if(e.word==r&&e.word.length>=6){var c=new RegExp("^("+e.pre.pre3.split(" ").join("|")+")");e.word=e.word.replace(c,"")}if(e.word==r&&e.word.length>=5){var l=new RegExp("^("+e.pre.pre2.split(" ").join("|")+")");e.word=e.word.replace(l,"")}return r!=e.word&&(e.preRemoved=!0),!1},e.patternCheck=function(r){for(var t=0;t3){var t=new RegExp("^("+e.pre.pre1.split(" ").join("|")+")");e.word=e.word.replace(t,"")}return r!=e.word&&(e.preRemoved=!0),!1},e.removeSuf1=function(){var r=e.word;if(0==e.sufRemoved&&e.word.length>3){var t=new RegExp("("+e.suf.suf1.split(" ").join("|")+")$");e.word=e.word.replace(t,"")}return r!=e.word&&(e.sufRemoved=!0),!1},e.removeSuf432=function(){var r=e.word;if(e.word.length>=6){var t=new RegExp("("+e.suf.suf4.split(" ").join("|")+")$");e.word=e.word.replace(t,"")}if(e.word==r&&e.word.length>=5){var c=new RegExp("("+e.suf.suf3.split(" ").join("|")+")$");e.word=e.word.replace(c,"")}if(e.word==r&&e.word.length>=4){var l=new RegExp("("+e.suf.suf2.split(" ").join("|")+")$");e.word=e.word.replace(l,"")}return r!=e.word&&(e.sufRemoved=!0),!1},e.wordCheck=function(){for(var r=(e.word,[e.removeSuf432,e.removeSuf1,e.removePre1]),t=0,c=!1;e.word.length>=7&&!e.result&&t=f.limit)return;f.cursor++}for(;!f.out_grouping(w,97,248);){if(f.cursor>=f.limit)return;f.cursor++}d=f.cursor,d=d&&(r=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,e=f.find_among_b(c,32),f.limit_backward=r,e))switch(f.bra=f.cursor,e){case 1:f.slice_del();break;case 2:f.in_grouping_b(p,97,229)&&f.slice_del()}}function t(){var e,r=f.limit-f.cursor;f.cursor>=d&&(e=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,f.find_among_b(l,4)?(f.bra=f.cursor,f.limit_backward=e,f.cursor=f.limit-r,f.cursor>f.limit_backward&&(f.cursor--,f.bra=f.cursor,f.slice_del())):f.limit_backward=e)}function s(){var e,r,i,n=f.limit-f.cursor;if(f.ket=f.cursor,f.eq_s_b(2,"st")&&(f.bra=f.cursor,f.eq_s_b(2,"ig")&&f.slice_del()),f.cursor=f.limit-n,f.cursor>=d&&(r=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,e=f.find_among_b(m,5),f.limit_backward=r,e))switch(f.bra=f.cursor,e){case 1:f.slice_del(),i=f.limit-f.cursor,t(),f.cursor=f.limit-i;break;case 2:f.slice_from("løs")}}function o(){var e;f.cursor>=d&&(e=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,f.out_grouping_b(w,97,248)?(f.bra=f.cursor,u=f.slice_to(u),f.limit_backward=e,f.eq_v_b(u)&&f.slice_del()):f.limit_backward=e)}var a,d,u,c=[new r("hed",-1,1),new r("ethed",0,1),new r("ered",-1,1),new r("e",-1,1),new r("erede",3,1),new r("ende",3,1),new r("erende",5,1),new r("ene",3,1),new r("erne",3,1),new r("ere",3,1),new r("en",-1,1),new r("heden",10,1),new r("eren",10,1),new r("er",-1,1),new r("heder",13,1),new r("erer",13,1),new r("s",-1,2),new r("heds",16,1),new r("es",16,1),new r("endes",18,1),new r("erendes",19,1),new r("enes",18,1),new r("ernes",18,1),new r("eres",18,1),new r("ens",16,1),new r("hedens",24,1),new r("erens",24,1),new r("ers",16,1),new r("ets",16,1),new r("erets",28,1),new r("et",-1,1),new r("eret",30,1)],l=[new r("gd",-1,-1),new r("dt",-1,-1),new r("gt",-1,-1),new r("kt",-1,-1)],m=[new r("ig",-1,1),new r("lig",0,1),new r("elig",1,1),new r("els",-1,1),new r("løst",-1,2)],w=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],p=[239,254,42,3,0,0,0,0,0,0,0,0,0,0,0,0,16],f=new i;this.setCurrent=function(e){f.setCurrent(e)},this.getCurrent=function(){return f.getCurrent()},this.stem=function(){var r=f.cursor;return e(),f.limit_backward=r,f.cursor=f.limit,n(),f.cursor=f.limit,t(),f.cursor=f.limit,s(),f.cursor=f.limit,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.da.stemmer,"stemmer-da"),e.da.stopWordFilter=e.generateStopWordFilter("ad af alle alt anden at blev blive bliver da de dem den denne der deres det dette dig din disse dog du efter eller en end er et for fra ham han hans har havde have hende hendes her hos hun hvad hvis hvor i ikke ind jeg jer jo kunne man mange med meget men mig min mine mit mod ned noget nogle nu når og også om op os over på selv sig sin sine sit skal skulle som sådan thi til ud under var vi vil ville vor være været".split(" ")),e.Pipeline.registerFunction(e.da.stopWordFilter,"stopWordFilter-da")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.de.min.js b/assets/javascripts/lunr/min/lunr.de.min.js new file mode 100644 index 00000000..f3b5c108 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.de.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `German` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.de=function(){this.pipeline.reset(),this.pipeline.add(e.de.trimmer,e.de.stopWordFilter,e.de.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.de.stemmer))},e.de.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.de.trimmer=e.trimmerSupport.generateTrimmer(e.de.wordCharacters),e.Pipeline.registerFunction(e.de.trimmer,"trimmer-de"),e.de.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,i=new function(){function e(e,r,n){return!(!v.eq_s(1,e)||(v.ket=v.cursor,!v.in_grouping(p,97,252)))&&(v.slice_from(r),v.cursor=n,!0)}function i(){for(var r,n,i,s,t=v.cursor;;)if(r=v.cursor,v.bra=r,v.eq_s(1,"ß"))v.ket=v.cursor,v.slice_from("ss");else{if(r>=v.limit)break;v.cursor=r+1}for(v.cursor=t;;)for(n=v.cursor;;){if(i=v.cursor,v.in_grouping(p,97,252)){if(s=v.cursor,v.bra=s,e("u","U",i))break;if(v.cursor=s,e("y","Y",i))break}if(i>=v.limit)return void(v.cursor=n);v.cursor=i+1}}function s(){for(;!v.in_grouping(p,97,252);){if(v.cursor>=v.limit)return!0;v.cursor++}for(;!v.out_grouping(p,97,252);){if(v.cursor>=v.limit)return!0;v.cursor++}return!1}function t(){m=v.limit,l=m;var e=v.cursor+3;0<=e&&e<=v.limit&&(d=e,s()||(m=v.cursor,m=v.limit)return;v.cursor++}}}function c(){return m<=v.cursor}function u(){return l<=v.cursor}function a(){var e,r,n,i,s=v.limit-v.cursor;if(v.ket=v.cursor,(e=v.find_among_b(w,7))&&(v.bra=v.cursor,c()))switch(e){case 1:v.slice_del();break;case 2:v.slice_del(),v.ket=v.cursor,v.eq_s_b(1,"s")&&(v.bra=v.cursor,v.eq_s_b(3,"nis")&&v.slice_del());break;case 3:v.in_grouping_b(g,98,116)&&v.slice_del()}if(v.cursor=v.limit-s,v.ket=v.cursor,(e=v.find_among_b(f,4))&&(v.bra=v.cursor,c()))switch(e){case 1:v.slice_del();break;case 2:if(v.in_grouping_b(k,98,116)){var t=v.cursor-3;v.limit_backward<=t&&t<=v.limit&&(v.cursor=t,v.slice_del())}}if(v.cursor=v.limit-s,v.ket=v.cursor,(e=v.find_among_b(_,8))&&(v.bra=v.cursor,u()))switch(e){case 1:v.slice_del(),v.ket=v.cursor,v.eq_s_b(2,"ig")&&(v.bra=v.cursor,r=v.limit-v.cursor,v.eq_s_b(1,"e")||(v.cursor=v.limit-r,u()&&v.slice_del()));break;case 2:n=v.limit-v.cursor,v.eq_s_b(1,"e")||(v.cursor=v.limit-n,v.slice_del());break;case 3:if(v.slice_del(),v.ket=v.cursor,i=v.limit-v.cursor,!v.eq_s_b(2,"er")&&(v.cursor=v.limit-i,!v.eq_s_b(2,"en")))break;v.bra=v.cursor,c()&&v.slice_del();break;case 4:v.slice_del(),v.ket=v.cursor,e=v.find_among_b(b,2),e&&(v.bra=v.cursor,u()&&1==e&&v.slice_del())}}var d,l,m,h=[new r("",-1,6),new r("U",0,2),new r("Y",0,1),new r("ä",0,3),new r("ö",0,4),new r("ü",0,5)],w=[new r("e",-1,2),new r("em",-1,1),new r("en",-1,2),new r("ern",-1,1),new r("er",-1,1),new r("s",-1,3),new r("es",5,2)],f=[new r("en",-1,1),new r("er",-1,1),new r("st",-1,2),new r("est",2,1)],b=[new r("ig",-1,1),new r("lich",-1,1)],_=[new r("end",-1,1),new r("ig",-1,2),new r("ung",-1,1),new r("lich",-1,3),new r("isch",-1,2),new r("ik",-1,2),new r("heit",-1,3),new r("keit",-1,4)],p=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32,8],g=[117,30,5],k=[117,30,4],v=new n;this.setCurrent=function(e){v.setCurrent(e)},this.getCurrent=function(){return v.getCurrent()},this.stem=function(){var e=v.cursor;return i(),v.cursor=e,t(),v.limit_backward=e,v.cursor=v.limit,a(),v.cursor=v.limit_backward,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.de.stemmer,"stemmer-de"),e.de.stopWordFilter=e.generateStopWordFilter("aber alle allem allen aller alles als also am an ander andere anderem anderen anderer anderes anderm andern anderr anders auch auf aus bei bin bis bist da damit dann das dasselbe dazu daß dein deine deinem deinen deiner deines dem demselben den denn denselben der derer derselbe derselben des desselben dessen dich die dies diese dieselbe dieselben diesem diesen dieser dieses dir doch dort du durch ein eine einem einen einer eines einig einige einigem einigen einiger einiges einmal er es etwas euch euer eure eurem euren eurer eures für gegen gewesen hab habe haben hat hatte hatten hier hin hinter ich ihm ihn ihnen ihr ihre ihrem ihren ihrer ihres im in indem ins ist jede jedem jeden jeder jedes jene jenem jenen jener jenes jetzt kann kein keine keinem keinen keiner keines können könnte machen man manche manchem manchen mancher manches mein meine meinem meinen meiner meines mich mir mit muss musste nach nicht nichts noch nun nur ob oder ohne sehr sein seine seinem seinen seiner seines selbst sich sie sind so solche solchem solchen solcher solches soll sollte sondern sonst um und uns unse unsem unsen unser unses unter viel vom von vor war waren warst was weg weil weiter welche welchem welchen welcher welches wenn werde werden wie wieder will wir wird wirst wo wollen wollte während würde würden zu zum zur zwar zwischen über".split(" ")),e.Pipeline.registerFunction(e.de.stopWordFilter,"stopWordFilter-de")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.du.min.js b/assets/javascripts/lunr/min/lunr.du.min.js new file mode 100644 index 00000000..49a0f3f0 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.du.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Dutch` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");console.warn('[Lunr Languages] Please use the "nl" instead of the "du". The "nl" code is the standard code for Dutch language, and "du" will be removed in the next major versions.'),e.du=function(){this.pipeline.reset(),this.pipeline.add(e.du.trimmer,e.du.stopWordFilter,e.du.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.du.stemmer))},e.du.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.du.trimmer=e.trimmerSupport.generateTrimmer(e.du.wordCharacters),e.Pipeline.registerFunction(e.du.trimmer,"trimmer-du"),e.du.stemmer=function(){var r=e.stemmerSupport.Among,i=e.stemmerSupport.SnowballProgram,n=new function(){function e(){for(var e,r,i,o=C.cursor;;){if(C.bra=C.cursor,e=C.find_among(b,11))switch(C.ket=C.cursor,e){case 1:C.slice_from("a");continue;case 2:C.slice_from("e");continue;case 3:C.slice_from("i");continue;case 4:C.slice_from("o");continue;case 5:C.slice_from("u");continue;case 6:if(C.cursor>=C.limit)break;C.cursor++;continue}break}for(C.cursor=o,C.bra=o,C.eq_s(1,"y")?(C.ket=C.cursor,C.slice_from("Y")):C.cursor=o;;)if(r=C.cursor,C.in_grouping(q,97,232)){if(i=C.cursor,C.bra=i,C.eq_s(1,"i"))C.ket=C.cursor,C.in_grouping(q,97,232)&&(C.slice_from("I"),C.cursor=r);else if(C.cursor=i,C.eq_s(1,"y"))C.ket=C.cursor,C.slice_from("Y"),C.cursor=r;else if(n(r))break}else if(n(r))break}function n(e){return C.cursor=e,e>=C.limit||(C.cursor++,!1)}function o(){_=C.limit,f=_,t()||(_=C.cursor,_<3&&(_=3),t()||(f=C.cursor))}function t(){for(;!C.in_grouping(q,97,232);){if(C.cursor>=C.limit)return!0;C.cursor++}for(;!C.out_grouping(q,97,232);){if(C.cursor>=C.limit)return!0;C.cursor++}return!1}function s(){for(var e;;)if(C.bra=C.cursor,e=C.find_among(p,3))switch(C.ket=C.cursor,e){case 1:C.slice_from("y");break;case 2:C.slice_from("i");break;case 3:if(C.cursor>=C.limit)return;C.cursor++}}function u(){return _<=C.cursor}function c(){return f<=C.cursor}function a(){var e=C.limit-C.cursor;C.find_among_b(g,3)&&(C.cursor=C.limit-e,C.ket=C.cursor,C.cursor>C.limit_backward&&(C.cursor--,C.bra=C.cursor,C.slice_del()))}function l(){var e;w=!1,C.ket=C.cursor,C.eq_s_b(1,"e")&&(C.bra=C.cursor,u()&&(e=C.limit-C.cursor,C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-e,C.slice_del(),w=!0,a())))}function m(){var e;u()&&(e=C.limit-C.cursor,C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-e,C.eq_s_b(3,"gem")||(C.cursor=C.limit-e,C.slice_del(),a())))}function d(){var e,r,i,n,o,t,s=C.limit-C.cursor;if(C.ket=C.cursor,e=C.find_among_b(h,5))switch(C.bra=C.cursor,e){case 1:u()&&C.slice_from("heid");break;case 2:m();break;case 3:u()&&C.out_grouping_b(z,97,232)&&C.slice_del()}if(C.cursor=C.limit-s,l(),C.cursor=C.limit-s,C.ket=C.cursor,C.eq_s_b(4,"heid")&&(C.bra=C.cursor,c()&&(r=C.limit-C.cursor,C.eq_s_b(1,"c")||(C.cursor=C.limit-r,C.slice_del(),C.ket=C.cursor,C.eq_s_b(2,"en")&&(C.bra=C.cursor,m())))),C.cursor=C.limit-s,C.ket=C.cursor,e=C.find_among_b(k,6))switch(C.bra=C.cursor,e){case 1:if(c()){if(C.slice_del(),i=C.limit-C.cursor,C.ket=C.cursor,C.eq_s_b(2,"ig")&&(C.bra=C.cursor,c()&&(n=C.limit-C.cursor,!C.eq_s_b(1,"e")))){C.cursor=C.limit-n,C.slice_del();break}C.cursor=C.limit-i,a()}break;case 2:c()&&(o=C.limit-C.cursor,C.eq_s_b(1,"e")||(C.cursor=C.limit-o,C.slice_del()));break;case 3:c()&&(C.slice_del(),l());break;case 4:c()&&C.slice_del();break;case 5:c()&&w&&C.slice_del()}C.cursor=C.limit-s,C.out_grouping_b(j,73,232)&&(t=C.limit-C.cursor,C.find_among_b(v,4)&&C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-t,C.ket=C.cursor,C.cursor>C.limit_backward&&(C.cursor--,C.bra=C.cursor,C.slice_del())))}var f,_,w,b=[new r("",-1,6),new r("á",0,1),new r("ä",0,1),new r("é",0,2),new r("ë",0,2),new r("í",0,3),new r("ï",0,3),new r("ó",0,4),new r("ö",0,4),new r("ú",0,5),new r("ü",0,5)],p=[new r("",-1,3),new r("I",0,2),new r("Y",0,1)],g=[new r("dd",-1,-1),new r("kk",-1,-1),new r("tt",-1,-1)],h=[new r("ene",-1,2),new r("se",-1,3),new r("en",-1,2),new r("heden",2,1),new r("s",-1,3)],k=[new r("end",-1,1),new r("ig",-1,2),new r("ing",-1,1),new r("lijk",-1,3),new r("baar",-1,4),new r("bar",-1,5)],v=[new r("aa",-1,-1),new r("ee",-1,-1),new r("oo",-1,-1),new r("uu",-1,-1)],q=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],j=[1,0,0,17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],z=[17,67,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],C=new i;this.setCurrent=function(e){C.setCurrent(e)},this.getCurrent=function(){return C.getCurrent()},this.stem=function(){var r=C.cursor;return e(),C.cursor=r,o(),C.limit_backward=r,C.cursor=C.limit,d(),C.cursor=C.limit_backward,s(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.du.stemmer,"stemmer-du"),e.du.stopWordFilter=e.generateStopWordFilter(" aan al alles als altijd andere ben bij daar dan dat de der deze die dit doch doen door dus een eens en er ge geen geweest haar had heb hebben heeft hem het hier hij hoe hun iemand iets ik in is ja je kan kon kunnen maar me meer men met mij mijn moet na naar niet niets nog nu of om omdat onder ons ook op over reeds te tegen toch toen tot u uit uw van veel voor want waren was wat werd wezen wie wil worden wordt zal ze zelf zich zij zijn zo zonder zou".split(" ")),e.Pipeline.registerFunction(e.du.stopWordFilter,"stopWordFilter-du")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.el.min.js b/assets/javascripts/lunr/min/lunr.el.min.js new file mode 100644 index 00000000..ace017bd --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.el.min.js @@ -0,0 +1 @@ +!function(e,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():t()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.el=function(){this.pipeline.reset(),void 0===this.searchPipeline&&this.pipeline.add(e.el.trimmer,e.el.normilizer),this.pipeline.add(e.el.stopWordFilter,e.el.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.el.stemmer))},e.el.wordCharacters="A-Za-zΑαΒβΓγΔδΕεΖζΗηΘθΙιΚκΛλΜμΝνΞξΟοΠπΡρΣσςΤτΥυΦφΧχΨψΩωΆάΈέΉήΊίΌόΎύΏώΪΐΫΰΐΰ",e.el.trimmer=e.trimmerSupport.generateTrimmer(e.el.wordCharacters),e.Pipeline.registerFunction(e.el.trimmer,"trimmer-el"),e.el.stemmer=function(){function e(e){return s.test(e)}function t(e){return/[ΑΕΗΙΟΥΩ]$/.test(e)}function r(e){return/[ΑΕΗΙΟΩ]$/.test(e)}function n(n){var s=n;if(n.length<3)return s;if(!e(n))return s;if(i.indexOf(n)>=0)return s;var u=new RegExp("(.*)("+Object.keys(l).join("|")+")$"),o=u.exec(s);return null!==o&&(s=o[1]+l[o[2]]),null!==(o=/^(.+?)(ΑΔΕΣ|ΑΔΩΝ)$/.exec(s))&&(s=o[1],/(ΟΚ|ΜΑΜ|ΜΑΝ|ΜΠΑΜΠ|ΠΑΤΕΡ|ΓΙΑΓΙ|ΝΤΑΝΤ|ΚΥΡ|ΘΕΙ|ΠΕΘΕΡ|ΜΟΥΣΑΜ|ΚΑΠΛΑΜ|ΠΑΡ|ΨΑΡ|ΤΖΟΥΡ|ΤΑΜΠΟΥΡ|ΓΑΛΑΤ|ΦΑΦΛΑΤ)$/.test(o[1])||(s+="ΑΔ")),null!==(o=/^(.+?)(ΕΔΕΣ|ΕΔΩΝ)$/.exec(s))&&(s=o[1],/(ΟΠ|ΙΠ|ΕΜΠ|ΥΠ|ΓΗΠ|ΔΑΠ|ΚΡΑΣΠ|ΜΙΛ)$/.test(o[1])&&(s+="ΕΔ")),null!==(o=/^(.+?)(ΟΥΔΕΣ|ΟΥΔΩΝ)$/.exec(s))&&(s=o[1],/(ΑΡΚ|ΚΑΛΙΑΚ|ΠΕΤΑΛ|ΛΙΧ|ΠΛΕΞ|ΣΚ|Σ|ΦΛ|ΦΡ|ΒΕΛ|ΛΟΥΛ|ΧΝ|ΣΠ|ΤΡΑΓ|ΦΕ)$/.test(o[1])&&(s+="ΟΥΔ")),null!==(o=/^(.+?)(ΕΩΣ|ΕΩΝ|ΕΑΣ|ΕΑ)$/.exec(s))&&(s=o[1],/^(Θ|Δ|ΕΛ|ΓΑΛ|Ν|Π|ΙΔ|ΠΑΡ|ΣΤΕΡ|ΟΡΦ|ΑΝΔΡ|ΑΝΤΡ)$/.test(o[1])&&(s+="Ε")),null!==(o=/^(.+?)(ΕΙΟ|ΕΙΟΣ|ΕΙΟΙ|ΕΙΑ|ΕΙΑΣ|ΕΙΕΣ|ΕΙΟΥ|ΕΙΟΥΣ|ΕΙΩΝ)$/.exec(s))&&o[1].length>4&&(s=o[1]),null!==(o=/^(.+?)(ΙΟΥΣ|ΙΑΣ|ΙΕΣ|ΙΟΣ|ΙΟΥ|ΙΟΙ|ΙΩΝ|ΙΟΝ|ΙΑ|ΙΟ)$/.exec(s))&&(s=o[1],(t(s)||s.length<2||/^(ΑΓ|ΑΓΓΕΛ|ΑΓΡ|ΑΕΡ|ΑΘΛ|ΑΚΟΥΣ|ΑΞ|ΑΣ|Β|ΒΙΒΛ|ΒΥΤ|Γ|ΓΙΑΓ|ΓΩΝ|Δ|ΔΑΝ|ΔΗΛ|ΔΗΜ|ΔΟΚΙΜ|ΕΛ|ΖΑΧΑΡ|ΗΛ|ΗΠ|ΙΔ|ΙΣΚ|ΙΣΤ|ΙΟΝ|ΙΩΝ|ΚΙΜΩΛ|ΚΟΛΟΝ|ΚΟΡ|ΚΤΗΡ|ΚΥΡ|ΛΑΓ|ΛΟΓ|ΜΑΓ|ΜΠΑΝ|ΜΠΡ|ΝΑΥΤ|ΝΟΤ|ΟΠΑΛ|ΟΞ|ΟΡ|ΟΣ|ΠΑΝΑΓ|ΠΑΤΡ|ΠΗΛ|ΠΗΝ|ΠΛΑΙΣ|ΠΟΝΤ|ΡΑΔ|ΡΟΔ|ΣΚ|ΣΚΟΡΠ|ΣΟΥΝ|ΣΠΑΝ|ΣΤΑΔ|ΣΥΡ|ΤΗΛ|ΤΙΜ|ΤΟΚ|ΤΟΠ|ΤΡΟΧ|ΦΙΛ|ΦΩΤ|Χ|ΧΙΛ|ΧΡΩΜ|ΧΩΡ)$/.test(o[1]))&&(s+="Ι"),/^(ΠΑΛ)$/.test(o[1])&&(s+="ΑΙ")),null!==(o=/^(.+?)(ΙΚΟΣ|ΙΚΟΝ|ΙΚΕΙΣ|ΙΚΟΙ|ΙΚΕΣ|ΙΚΟΥΣ|ΙΚΗ|ΙΚΗΣ|ΙΚΟ|ΙΚΑ|ΙΚΟΥ|ΙΚΩΝ|ΙΚΩΣ)$/.exec(s))&&(s=o[1],(t(s)||/^(ΑΔ|ΑΛ|ΑΜΑΝ|ΑΜΕΡ|ΑΜΜΟΧΑΛ|ΑΝΗΘ|ΑΝΤΙΔ|ΑΠΛ|ΑΤΤ|ΑΦΡ|ΒΑΣ|ΒΡΩΜ|ΓΕΝ|ΓΕΡ|Δ|ΔΙΚΑΝ|ΔΥΤ|ΕΙΔ|ΕΝΔ|ΕΞΩΔ|ΗΘ|ΘΕΤ|ΚΑΛΛΙΝ|ΚΑΛΠ|ΚΑΤΑΔ|ΚΟΥΖΙΝ|ΚΡ|ΚΩΔ|ΛΟΓ|Μ|ΜΕΡ|ΜΟΝΑΔ|ΜΟΥΛ|ΜΟΥΣ|ΜΠΑΓΙΑΤ|ΜΠΑΝ|ΜΠΟΛ|ΜΠΟΣ|ΜΥΣΤ|Ν|ΝΙΤ|ΞΙΚ|ΟΠΤ|ΠΑΝ|ΠΕΤΣ|ΠΙΚΑΝΤ|ΠΙΤΣ|ΠΛΑΣΤ|ΠΛΙΑΤΣ|ΠΟΝΤ|ΠΟΣΤΕΛΝ|ΠΡΩΤΟΔ|ΣΕΡΤ|ΣΗΜΑΝΤ|ΣΤΑΤ|ΣΥΝΑΔ|ΣΥΝΟΜΗΛ|ΤΕΛ|ΤΕΧΝ|ΤΡΟΠ|ΤΣΑΜ|ΥΠΟΔ|Φ|ΦΙΛΟΝ|ΦΥΛΟΔ|ΦΥΣ|ΧΑΣ)$/.test(o[1])||/(ΦΟΙΝ)$/.test(o[1]))&&(s+="ΙΚ")),"ΑΓΑΜΕ"===s&&(s="ΑΓΑΜ"),null!==(o=/^(.+?)(ΑΓΑΜΕ|ΗΣΑΜΕ|ΟΥΣΑΜΕ|ΗΚΑΜΕ|ΗΘΗΚΑΜΕ)$/.exec(s))&&(s=o[1]),null!==(o=/^(.+?)(ΑΜΕ)$/.exec(s))&&(s=o[1],/^(ΑΝΑΠ|ΑΠΟΘ|ΑΠΟΚ|ΑΠΟΣΤ|ΒΟΥΒ|ΞΕΘ|ΟΥΛ|ΠΕΘ|ΠΙΚΡ|ΠΟΤ|ΣΙΧ|Χ)$/.test(o[1])&&(s+="ΑΜ")),null!==(o=/^(.+?)(ΑΓΑΝΕ|ΗΣΑΝΕ|ΟΥΣΑΝΕ|ΙΟΝΤΑΝΕ|ΙΟΤΑΝΕ|ΙΟΥΝΤΑΝΕ|ΟΝΤΑΝΕ|ΟΤΑΝΕ|ΟΥΝΤΑΝΕ|ΗΚΑΝΕ|ΗΘΗΚΑΝΕ)$/.exec(s))&&(s=o[1],/^(ΤΡ|ΤΣ)$/.test(o[1])&&(s+="ΑΓΑΝ")),null!==(o=/^(.+?)(ΑΝΕ)$/.exec(s))&&(s=o[1],(r(s)||/^(ΒΕΤΕΡ|ΒΟΥΛΚ|ΒΡΑΧΜ|Γ|ΔΡΑΔΟΥΜ|Θ|ΚΑΛΠΟΥΖ|ΚΑΣΤΕΛ|ΚΟΡΜΟΡ|ΛΑΟΠΛ|ΜΩΑΜΕΘ|Μ|ΜΟΥΣΟΥΛΜΑΝ|ΟΥΛ|Π|ΠΕΛΕΚ|ΠΛ|ΠΟΛΙΣ|ΠΟΡΤΟΛ|ΣΑΡΑΚΑΤΣ|ΣΟΥΛΤ|ΤΣΑΡΛΑΤ|ΟΡΦ|ΤΣΙΓΓ|ΤΣΟΠ|ΦΩΤΟΣΤΕΦ|Χ|ΨΥΧΟΠΛ|ΑΓ|ΟΡΦ|ΓΑΛ|ΓΕΡ|ΔΕΚ|ΔΙΠΛ|ΑΜΕΡΙΚΑΝ|ΟΥΡ|ΠΙΘ|ΠΟΥΡΙΤ|Σ|ΖΩΝΤ|ΙΚ|ΚΑΣΤ|ΚΟΠ|ΛΙΧ|ΛΟΥΘΗΡ|ΜΑΙΝΤ|ΜΕΛ|ΣΙΓ|ΣΠ|ΣΤΕΓ|ΤΡΑΓ|ΤΣΑΓ|Φ|ΕΡ|ΑΔΑΠ|ΑΘΙΓΓ|ΑΜΗΧ|ΑΝΙΚ|ΑΝΟΡΓ|ΑΠΗΓ|ΑΠΙΘ|ΑΤΣΙΓΓ|ΒΑΣ|ΒΑΣΚ|ΒΑΘΥΓΑΛ|ΒΙΟΜΗΧ|ΒΡΑΧΥΚ|ΔΙΑΤ|ΔΙΑΦ|ΕΝΟΡΓ|ΘΥΣ|ΚΑΠΝΟΒΙΟΜΗΧ|ΚΑΤΑΓΑΛ|ΚΛΙΒ|ΚΟΙΛΑΡΦ|ΛΙΒ|ΜΕΓΛΟΒΙΟΜΗΧ|ΜΙΚΡΟΒΙΟΜΗΧ|ΝΤΑΒ|ΞΗΡΟΚΛΙΒ|ΟΛΙΓΟΔΑΜ|ΟΛΟΓΑΛ|ΠΕΝΤΑΡΦ|ΠΕΡΗΦ|ΠΕΡΙΤΡ|ΠΛΑΤ|ΠΟΛΥΔΑΠ|ΠΟΛΥΜΗΧ|ΣΤΕΦ|ΤΑΒ|ΤΕΤ|ΥΠΕΡΗΦ|ΥΠΟΚΟΠ|ΧΑΜΗΛΟΔΑΠ|ΨΗΛΟΤΑΒ)$/.test(o[1]))&&(s+="ΑΝ")),null!==(o=/^(.+?)(ΗΣΕΤΕ)$/.exec(s))&&(s=o[1]),null!==(o=/^(.+?)(ΕΤΕ)$/.exec(s))&&(s=o[1],(r(s)||/(ΟΔ|ΑΙΡ|ΦΟΡ|ΤΑΘ|ΔΙΑΘ|ΣΧ|ΕΝΔ|ΕΥΡ|ΤΙΘ|ΥΠΕΡΘ|ΡΑΘ|ΕΝΘ|ΡΟΘ|ΣΘ|ΠΥΡ|ΑΙΝ|ΣΥΝΔ|ΣΥΝ|ΣΥΝΘ|ΧΩΡ|ΠΟΝ|ΒΡ|ΚΑΘ|ΕΥΘ|ΕΚΘ|ΝΕΤ|ΡΟΝ|ΑΡΚ|ΒΑΡ|ΒΟΛ|ΩΦΕΛ)$/.test(o[1])||/^(ΑΒΑΡ|ΒΕΝ|ΕΝΑΡ|ΑΒΡ|ΑΔ|ΑΘ|ΑΝ|ΑΠΛ|ΒΑΡΟΝ|ΝΤΡ|ΣΚ|ΚΟΠ|ΜΠΟΡ|ΝΙΦ|ΠΑΓ|ΠΑΡΑΚΑΛ|ΣΕΡΠ|ΣΚΕΛ|ΣΥΡΦ|ΤΟΚ|Υ|Δ|ΕΜ|ΘΑΡΡ|Θ)$/.test(o[1]))&&(s+="ΕΤ")),null!==(o=/^(.+?)(ΟΝΤΑΣ|ΩΝΤΑΣ)$/.exec(s))&&(s=o[1],/^ΑΡΧ$/.test(o[1])&&(s+="ΟΝΤ"),/ΚΡΕ$/.test(o[1])&&(s+="ΩΝΤ")),null!==(o=/^(.+?)(ΟΜΑΣΤΕ|ΙΟΜΑΣΤΕ)$/.exec(s))&&(s=o[1],/^ΟΝ$/.test(o[1])&&(s+="ΟΜΑΣΤ")),null!==(o=/^(.+?)(ΙΕΣΤΕ)$/.exec(s))&&(s=o[1],/^(Π|ΑΠ|ΣΥΜΠ|ΑΣΥΜΠ|ΑΚΑΤΑΠ|ΑΜΕΤΑΜΦ)$/.test(o[1])&&(s+="ΙΕΣΤ")),null!==(o=/^(.+?)(ΕΣΤΕ)$/.exec(s))&&(s=o[1],/^(ΑΛ|ΑΡ|ΕΚΤΕΛ|Ζ|Μ|Ξ|ΠΑΡΑΚΑΛ|ΠΡΟ|ΝΙΣ)$/.test(o[1])&&(s+="ΕΣΤ")),null!==(o=/^(.+?)(ΗΘΗΚΑ|ΗΘΗΚΕΣ|ΗΘΗΚΕ)$/.exec(s))&&(s=o[1]),null!==(o=/^(.+?)(ΗΚΑ|ΗΚΕΣ|ΗΚΕ)$/.exec(s))&&(s=o[1],(/(ΣΚΩΛ|ΣΚΟΥΛ|ΝΑΡΘ|ΣΦ|ΟΘ|ΠΙΘ)$/.test(o[1])||/^(ΔΙΑΘ|Θ|ΠΑΡΑΚΑΤΑΘ|ΠΡΟΣΘ|ΣΥΝΘ)$/.test(o[1]))&&(s+="ΗΚ")),null!==(o=/^(.+?)(ΟΥΣΑ|ΟΥΣΕΣ|ΟΥΣΕ)$/.exec(s))&&(s=o[1],(t(s)||/^(ΦΑΡΜΑΚ|ΧΑΔ|ΑΓΚ|ΑΝΑΡΡ|ΒΡΟΜ|ΕΚΛΙΠ|ΛΑΜΠΙΔ|ΛΕΧ|Μ|ΠΑΤ|Ρ|Λ|ΜΕΔ|ΜΕΣΑΖ|ΥΠΟΤΕΙΝ|ΑΜ|ΑΙΘ|ΑΝΗΚ|ΔΕΣΠΟΖ|ΕΝΔΙΑΦΕΡ)$/.test(o[1])||/(ΠΟΔΑΡ|ΒΛΕΠ|ΠΑΝΤΑΧ|ΦΡΥΔ|ΜΑΝΤΙΛ|ΜΑΛΛ|ΚΥΜΑΤ|ΛΑΧ|ΛΗΓ|ΦΑΓ|ΟΜ|ΠΡΩΤ)$/.test(o[1]))&&(s+="ΟΥΣ")),null!==(o=/^(.+?)(ΑΓΑ|ΑΓΕΣ|ΑΓΕ)$/.exec(s))&&(s=o[1],(/^(ΑΒΑΣΤ|ΠΟΛΥΦ|ΑΔΗΦ|ΠΑΜΦ|Ρ|ΑΣΠ|ΑΦ|ΑΜΑΛ|ΑΜΑΛΛΙ|ΑΝΥΣΤ|ΑΠΕΡ|ΑΣΠΑΡ|ΑΧΑΡ|ΔΕΡΒΕΝ|ΔΡΟΣΟΠ|ΞΕΦ|ΝΕΟΠ|ΝΟΜΟΤ|ΟΛΟΠ|ΟΜΟΤ|ΠΡΟΣΤ|ΠΡΟΣΩΠΟΠ|ΣΥΜΠ|ΣΥΝΤ|Τ|ΥΠΟΤ|ΧΑΡ|ΑΕΙΠ|ΑΙΜΟΣΤ|ΑΝΥΠ|ΑΠΟΤ|ΑΡΤΙΠ|ΔΙΑΤ|ΕΝ|ΕΠΙΤ|ΚΡΟΚΑΛΟΠ|ΣΙΔΗΡΟΠ|Λ|ΝΑΥ|ΟΥΛΑΜ|ΟΥΡ|Π|ΤΡ|Μ)$/.test(o[1])||/(ΟΦ|ΠΕΛ|ΧΟΡΤ|ΛΛ|ΣΦ|ΡΠ|ΦΡ|ΠΡ|ΛΟΧ|ΣΜΗΝ)$/.test(o[1])&&!/^(ΨΟΦ|ΝΑΥΛΟΧ)$/.test(o[1])||/(ΚΟΛΛ)$/.test(o[1]))&&(s+="ΑΓ")),null!==(o=/^(.+?)(ΗΣΕ|ΗΣΟΥ|ΗΣΑ)$/.exec(s))&&(s=o[1],/^(Ν|ΧΕΡΣΟΝ|ΔΩΔΕΚΑΝ|ΕΡΗΜΟΝ|ΜΕΓΑΛΟΝ|ΕΠΤΑΝ|Ι)$/.test(o[1])&&(s+="ΗΣ")),null!==(o=/^(.+?)(ΗΣΤΕ)$/.exec(s))&&(s=o[1],/^(ΑΣΒ|ΣΒ|ΑΧΡ|ΧΡ|ΑΠΛ|ΑΕΙΜΝ|ΔΥΣΧΡ|ΕΥΧΡ|ΚΟΙΝΟΧΡ|ΠΑΛΙΜΨ)$/.test(o[1])&&(s+="ΗΣΤ")),null!==(o=/^(.+?)(ΟΥΝΕ|ΗΣΟΥΝΕ|ΗΘΟΥΝΕ)$/.exec(s))&&(s=o[1],/^(Ν|Ρ|ΣΠΙ|ΣΤΡΑΒΟΜΟΥΤΣ|ΚΑΚΟΜΟΥΤΣ|ΕΞΩΝ)$/.test(o[1])&&(s+="ΟΥΝ")),null!==(o=/^(.+?)(ΟΥΜΕ|ΗΣΟΥΜΕ|ΗΘΟΥΜΕ)$/.exec(s))&&(s=o[1],/^(ΠΑΡΑΣΟΥΣ|Φ|Χ|ΩΡΙΟΠΛ|ΑΖ|ΑΛΛΟΣΟΥΣ|ΑΣΟΥΣ)$/.test(o[1])&&(s+="ΟΥΜ")),null!=(o=/^(.+?)(ΜΑΤΟΙ|ΜΑΤΟΥΣ|ΜΑΤΟ|ΜΑΤΑ|ΜΑΤΩΣ|ΜΑΤΩΝ|ΜΑΤΟΣ|ΜΑΤΕΣ|ΜΑΤΗ|ΜΑΤΗΣ|ΜΑΤΟΥ)$/.exec(s))&&(s=o[1]+"Μ",/^(ΓΡΑΜ)$/.test(o[1])?s+="Α":/^(ΓΕ|ΣΤΑ)$/.test(o[1])&&(s+="ΑΤ")),null!==(o=/^(.+?)(ΟΥΑ)$/.exec(s))&&(s=o[1]+"ΟΥ"),n.length===s.length&&null!==(o=/^(.+?)(Α|ΑΓΑΤΕ|ΑΓΑΝ|ΑΕΙ|ΑΜΑΙ|ΑΝ|ΑΣ|ΑΣΑΙ|ΑΤΑΙ|ΑΩ|Ε|ΕΙ|ΕΙΣ|ΕΙΤΕ|ΕΣΑΙ|ΕΣ|ΕΤΑΙ|Ι|ΙΕΜΑΙ|ΙΕΜΑΣΤΕ|ΙΕΤΑΙ|ΙΕΣΑΙ|ΙΕΣΑΣΤΕ|ΙΟΜΑΣΤΑΝ|ΙΟΜΟΥΝ|ΙΟΜΟΥΝΑ|ΙΟΝΤΑΝ|ΙΟΝΤΟΥΣΑΝ|ΙΟΣΑΣΤΑΝ|ΙΟΣΑΣΤΕ|ΙΟΣΟΥΝ|ΙΟΣΟΥΝΑ|ΙΟΤΑΝ|ΙΟΥΜΑ|ΙΟΥΜΑΣΤΕ|ΙΟΥΝΤΑΙ|ΙΟΥΝΤΑΝ|Η|ΗΔΕΣ|ΗΔΩΝ|ΗΘΕΙ|ΗΘΕΙΣ|ΗΘΕΙΤΕ|ΗΘΗΚΑΤΕ|ΗΘΗΚΑΝ|ΗΘΟΥΝ|ΗΘΩ|ΗΚΑΤΕ|ΗΚΑΝ|ΗΣ|ΗΣΑΝ|ΗΣΑΤΕ|ΗΣΕΙ|ΗΣΕΣ|ΗΣΟΥΝ|ΗΣΩ|Ο|ΟΙ|ΟΜΑΙ|ΟΜΑΣΤΑΝ|ΟΜΟΥΝ|ΟΜΟΥΝΑ|ΟΝΤΑΙ|ΟΝΤΑΝ|ΟΝΤΟΥΣΑΝ|ΟΣ|ΟΣΑΣΤΑΝ|ΟΣΑΣΤΕ|ΟΣΟΥΝ|ΟΣΟΥΝΑ|ΟΤΑΝ|ΟΥ|ΟΥΜΑΙ|ΟΥΜΑΣΤΕ|ΟΥΝ|ΟΥΝΤΑΙ|ΟΥΝΤΑΝ|ΟΥΣ|ΟΥΣΑΝ|ΟΥΣΑΤΕ|Υ||ΥΑ|ΥΣ|Ω|ΩΝ|ΟΙΣ)$/.exec(s))&&(s=o[1]),null!=(o=/^(.+?)(ΕΣΤΕΡ|ΕΣΤΑΤ|ΟΤΕΡ|ΟΤΑΤ|ΥΤΕΡ|ΥΤΑΤ|ΩΤΕΡ|ΩΤΑΤ)$/.exec(s))&&(/^(ΕΞ|ΕΣ|ΑΝ|ΚΑΤ|Κ|ΠΡ)$/.test(o[1])||(s=o[1]),/^(ΚΑ|Μ|ΕΛΕ|ΛΕ|ΔΕ)$/.test(o[1])&&(s+="ΥΤ")),s}var l={"ΦΑΓΙΑ":"ΦΑ","ΦΑΓΙΟΥ":"ΦΑ","ΦΑΓΙΩΝ":"ΦΑ","ΣΚΑΓΙΑ":"ΣΚΑ","ΣΚΑΓΙΟΥ":"ΣΚΑ","ΣΚΑΓΙΩΝ":"ΣΚΑ","ΣΟΓΙΟΥ":"ΣΟ","ΣΟΓΙΑ":"ΣΟ","ΣΟΓΙΩΝ":"ΣΟ","ΤΑΤΟΓΙΑ":"ΤΑΤΟ","ΤΑΤΟΓΙΟΥ":"ΤΑΤΟ","ΤΑΤΟΓΙΩΝ":"ΤΑΤΟ","ΚΡΕΑΣ":"ΚΡΕ","ΚΡΕΑΤΟΣ":"ΚΡΕ","ΚΡΕΑΤΑ":"ΚΡΕ","ΚΡΕΑΤΩΝ":"ΚΡΕ","ΠΕΡΑΣ":"ΠΕΡ","ΠΕΡΑΤΟΣ":"ΠΕΡ","ΠΕΡΑΤΑ":"ΠΕΡ","ΠΕΡΑΤΩΝ":"ΠΕΡ","ΤΕΡΑΣ":"ΤΕΡ","ΤΕΡΑΤΟΣ":"ΤΕΡ","ΤΕΡΑΤΑ":"ΤΕΡ","ΤΕΡΑΤΩΝ":"ΤΕΡ","ΦΩΣ":"ΦΩ","ΦΩΤΟΣ":"ΦΩ","ΦΩΤΑ":"ΦΩ","ΦΩΤΩΝ":"ΦΩ","ΚΑΘΕΣΤΩΣ":"ΚΑΘΕΣΤ","ΚΑΘΕΣΤΩΤΟΣ":"ΚΑΘΕΣΤ","ΚΑΘΕΣΤΩΤΑ":"ΚΑΘΕΣΤ","ΚΑΘΕΣΤΩΤΩΝ":"ΚΑΘΕΣΤ","ΓΕΓΟΝΟΣ":"ΓΕΓΟΝ","ΓΕΓΟΝΟΤΟΣ":"ΓΕΓΟΝ","ΓΕΓΟΝΟΤΑ":"ΓΕΓΟΝ","ΓΕΓΟΝΟΤΩΝ":"ΓΕΓΟΝ","ΕΥΑ":"ΕΥ"},i=["ΑΚΡΙΒΩΣ","ΑΛΑ","ΑΛΛΑ","ΑΛΛΙΩΣ","ΑΛΛΟΤΕ","ΑΜΑ","ΑΝΩ","ΑΝΑ","ΑΝΑΜΕΣΑ","ΑΝΑΜΕΤΑΞΥ","ΑΝΕΥ","ΑΝΤΙ","ΑΝΤΙΠΕΡΑ","ΑΝΤΙΟ","ΑΞΑΦΝΑ","ΑΠΟ","ΑΠΟΨΕ","ΑΡΑ","ΑΡΑΓΕ","ΑΥΡΙΟ","ΑΦΟΙ","ΑΦΟΥ","ΑΦΟΤΟΥ","ΒΡΕ","ΓΕΙΑ","ΓΙΑ","ΓΙΑΤΙ","ΓΡΑΜΜΑ","ΔΕΗ","ΔΕΝ","ΔΗΛΑΔΗ","ΔΙΧΩΣ","ΔΥΟ","ΕΑΝ","ΕΓΩ","ΕΔΩ","ΕΔΑ","ΕΙΘΕ","ΕΙΜΑΙ","ΕΙΜΑΣΤΕ","ΕΙΣΑΙ","ΕΙΣΑΣΤΕ","ΕΙΝΑΙ","ΕΙΣΤΕ","ΕΙΤΕ","ΕΚΕΙ","ΕΚΟ","ΕΛΑ","ΕΜΑΣ","ΕΜΕΙΣ","ΕΝΤΕΛΩΣ","ΕΝΤΟΣ","ΕΝΤΩΜΕΤΑΞΥ","ΕΝΩ","ΕΞΙ","ΕΞΙΣΟΥ","ΕΞΗΣ","ΕΞΩ","ΕΟΚ","ΕΠΑΝΩ","ΕΠΕΙΔΗ","ΕΠΕΙΤΑ","ΕΠΙ","ΕΠΙΣΗΣ","ΕΠΟΜΕΝΩΣ","ΕΠΤΑ","ΕΣΑΣ","ΕΣΕΙΣ","ΕΣΤΩ","ΕΣΥ","ΕΣΩ","ΕΤΣΙ","ΕΥΓΕ","ΕΦΕ","ΕΦΕΞΗΣ","ΕΧΤΕΣ","ΕΩΣ","ΗΔΗ","ΗΜΙ","ΗΠΑ","ΗΤΟΙ","ΘΕΣ","ΙΔΙΩΣ","ΙΔΗ","ΙΚΑ","ΙΣΩΣ","ΚΑΘΕ","ΚΑΘΕΤΙ","ΚΑΘΟΛΟΥ","ΚΑΘΩΣ","ΚΑΙ","ΚΑΝ","ΚΑΠΟΤΕ","ΚΑΠΟΥ","ΚΑΤΑ","ΚΑΤΙ","ΚΑΤΟΠΙΝ","ΚΑΤΩ","ΚΕΙ","ΚΙΧ","ΚΚΕ","ΚΟΛΑΝ","ΚΥΡΙΩΣ","ΚΩΣ","ΜΑΚΑΡΙ","ΜΑΛΙΣΤΑ","ΜΑΛΛΟΝ","ΜΑΙ","ΜΑΟ","ΜΑΟΥΣ","ΜΑΣ","ΜΕΘΑΥΡΙΟ","ΜΕΣ","ΜΕΣΑ","ΜΕΤΑ","ΜΕΤΑΞΥ","ΜΕΧΡΙ","ΜΗΔΕ","ΜΗΝ","ΜΗΠΩΣ","ΜΗΤΕ","ΜΙΑ","ΜΙΑΣ","ΜΙΣ","ΜΜΕ","ΜΟΛΟΝΟΤΙ","ΜΟΥ","ΜΠΑ","ΜΠΑΣ","ΜΠΟΥΦΑΝ","ΜΠΡΟΣ","ΝΑΙ","ΝΕΣ","ΝΤΑ","ΝΤΕ","ΞΑΝΑ","ΟΗΕ","ΟΚΤΩ","ΟΜΩΣ","ΟΝΕ","ΟΠΑ","ΟΠΟΥ","ΟΠΩΣ","ΟΣΟ","ΟΤΑΝ","ΟΤΕ","ΟΤΙ","ΟΥΤΕ","ΟΧΙ","ΠΑΛΙ","ΠΑΝ","ΠΑΝΟ","ΠΑΝΤΟΤΕ","ΠΑΝΤΟΥ","ΠΑΝΤΩΣ","ΠΑΝΩ","ΠΑΡΑ","ΠΕΡΑ","ΠΕΡΙ","ΠΕΡΙΠΟΥ","ΠΙΑ","ΠΙΟ","ΠΙΣΩ","ΠΛΑΙ","ΠΛΕΟΝ","ΠΛΗΝ","ΠΟΤΕ","ΠΟΥ","ΠΡΟ","ΠΡΟΣ","ΠΡΟΧΤΕΣ","ΠΡΟΧΘΕΣ","ΡΟΔΙ","ΠΩΣ","ΣΑΙ","ΣΑΣ","ΣΑΝ","ΣΕΙΣ","ΣΙΑ","ΣΚΙ","ΣΟΙ","ΣΟΥ","ΣΡΙ","ΣΥΝ","ΣΥΝΑΜΑ","ΣΧΕΔΟΝ","ΤΑΔΕ","ΤΑΞΙ","ΤΑΧΑ","ΤΕΙ","ΤΗΝ","ΤΗΣ","ΤΙΠΟΤΑ","ΤΙΠΟΤΕ","ΤΙΣ","ΤΟΝ","ΤΟΤΕ","ΤΟΥ","ΤΟΥΣ","ΤΣΑ","ΤΣΕ","ΤΣΙ","ΤΣΟΥ","ΤΩΝ","ΥΠΟ","ΥΠΟΨΗ","ΥΠΟΨΙΝ","ΥΣΤΕΡΑ","ΦΕΤΟΣ","ΦΙΣ","ΦΠΑ","ΧΑΦ","ΧΘΕΣ","ΧΤΕΣ","ΧΩΡΙΣ","ΩΣ","ΩΣΑΝ","ΩΣΟΤΟΥ","ΩΣΠΟΥ","ΩΣΤΕ","ΩΣΤΟΣΟ"],s=new RegExp("^[ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ]+$");return function(e){return"function"==typeof e.update?e.update(function(e){return n(e.toUpperCase()).toLowerCase()}):n(e.toUpperCase()).toLowerCase()}}(),e.Pipeline.registerFunction(e.el.stemmer,"stemmer-el"),e.el.stopWordFilter=e.generateStopWordFilter("αλλα αν αντι απο αυτα αυτεσ αυτη αυτο αυτοι αυτοσ αυτουσ αυτων για δε δεν εαν ειμαι ειμαστε ειναι εισαι ειστε εκεινα εκεινεσ εκεινη εκεινο εκεινοι εκεινοσ εκεινουσ εκεινων ενω επι η θα ισωσ κ και κατα κι μα με μετα μη μην να ο οι ομωσ οπωσ οσο οτι παρα ποια ποιεσ ποιο ποιοι ποιοσ ποιουσ ποιων που προσ πωσ σε στη στην στο στον τα την τησ το τον τοτε του των ωσ".split(" ")),e.Pipeline.registerFunction(e.el.stopWordFilter,"stopWordFilter-el"),e.el.normilizer=function(){var e={"Ά":"Α","ά":"α","Έ":"Ε","έ":"ε","Ή":"Η","ή":"η","Ί":"Ι","ί":"ι","Ό":"Ο","ο":"ο","Ύ":"Υ","ύ":"υ","Ώ":"Ω","ώ":"ω","Ϊ":"Ι","ϊ":"ι","Ϋ":"Υ","ϋ":"υ","ΐ":"ι","ΰ":"υ"};return function(t){if("function"==typeof t.update)return t.update(function(t){for(var r="",n=0;n=A.limit)return!0;A.cursor++}return!1}return!0}function n(){if(A.in_grouping(x,97,252)){var s=A.cursor;if(e()){if(A.cursor=s,!A.in_grouping(x,97,252))return!0;for(;!A.out_grouping(x,97,252);){if(A.cursor>=A.limit)return!0;A.cursor++}}return!1}return!0}function i(){var s,r=A.cursor;if(n()){if(A.cursor=r,!A.out_grouping(x,97,252))return;if(s=A.cursor,e()){if(A.cursor=s,!A.in_grouping(x,97,252)||A.cursor>=A.limit)return;A.cursor++}}g=A.cursor}function a(){for(;!A.in_grouping(x,97,252);){if(A.cursor>=A.limit)return!1;A.cursor++}for(;!A.out_grouping(x,97,252);){if(A.cursor>=A.limit)return!1;A.cursor++}return!0}function t(){var e=A.cursor;g=A.limit,p=g,v=g,i(),A.cursor=e,a()&&(p=A.cursor,a()&&(v=A.cursor))}function o(){for(var e;;){if(A.bra=A.cursor,e=A.find_among(k,6))switch(A.ket=A.cursor,e){case 1:A.slice_from("a");continue;case 2:A.slice_from("e");continue;case 3:A.slice_from("i");continue;case 4:A.slice_from("o");continue;case 5:A.slice_from("u");continue;case 6:if(A.cursor>=A.limit)break;A.cursor++;continue}break}}function u(){return g<=A.cursor}function w(){return p<=A.cursor}function c(){return v<=A.cursor}function m(){var e;if(A.ket=A.cursor,A.find_among_b(y,13)&&(A.bra=A.cursor,(e=A.find_among_b(q,11))&&u()))switch(e){case 1:A.bra=A.cursor,A.slice_from("iendo");break;case 2:A.bra=A.cursor,A.slice_from("ando");break;case 3:A.bra=A.cursor,A.slice_from("ar");break;case 4:A.bra=A.cursor,A.slice_from("er");break;case 5:A.bra=A.cursor,A.slice_from("ir");break;case 6:A.slice_del();break;case 7:A.eq_s_b(1,"u")&&A.slice_del()}}function l(e,s){if(!c())return!0;A.slice_del(),A.ket=A.cursor;var r=A.find_among_b(e,s);return r&&(A.bra=A.cursor,1==r&&c()&&A.slice_del()),!1}function d(e){return!c()||(A.slice_del(),A.ket=A.cursor,A.eq_s_b(2,e)&&(A.bra=A.cursor,c()&&A.slice_del()),!1)}function b(){var e;if(A.ket=A.cursor,e=A.find_among_b(S,46)){switch(A.bra=A.cursor,e){case 1:if(!c())return!1;A.slice_del();break;case 2:if(d("ic"))return!1;break;case 3:if(!c())return!1;A.slice_from("log");break;case 4:if(!c())return!1;A.slice_from("u");break;case 5:if(!c())return!1;A.slice_from("ente");break;case 6:if(!w())return!1;A.slice_del(),A.ket=A.cursor,e=A.find_among_b(C,4),e&&(A.bra=A.cursor,c()&&(A.slice_del(),1==e&&(A.ket=A.cursor,A.eq_s_b(2,"at")&&(A.bra=A.cursor,c()&&A.slice_del()))));break;case 7:if(l(P,3))return!1;break;case 8:if(l(F,3))return!1;break;case 9:if(d("at"))return!1}return!0}return!1}function f(){var e,s;if(A.cursor>=g&&(s=A.limit_backward,A.limit_backward=g,A.ket=A.cursor,e=A.find_among_b(W,12),A.limit_backward=s,e)){if(A.bra=A.cursor,1==e){if(!A.eq_s_b(1,"u"))return!1;A.slice_del()}return!0}return!1}function _(){var e,s,r,n;if(A.cursor>=g&&(s=A.limit_backward,A.limit_backward=g,A.ket=A.cursor,e=A.find_among_b(L,96),A.limit_backward=s,e))switch(A.bra=A.cursor,e){case 1:r=A.limit-A.cursor,A.eq_s_b(1,"u")?(n=A.limit-A.cursor,A.eq_s_b(1,"g")?A.cursor=A.limit-n:A.cursor=A.limit-r):A.cursor=A.limit-r,A.bra=A.cursor;case 2:A.slice_del()}}function h(){var e,s;if(A.ket=A.cursor,e=A.find_among_b(z,8))switch(A.bra=A.cursor,e){case 1:u()&&A.slice_del();break;case 2:u()&&(A.slice_del(),A.ket=A.cursor,A.eq_s_b(1,"u")&&(A.bra=A.cursor,s=A.limit-A.cursor,A.eq_s_b(1,"g")&&(A.cursor=A.limit-s,u()&&A.slice_del())))}}var v,p,g,k=[new s("",-1,6),new s("á",0,1),new s("é",0,2),new s("í",0,3),new s("ó",0,4),new s("ú",0,5)],y=[new s("la",-1,-1),new s("sela",0,-1),new s("le",-1,-1),new s("me",-1,-1),new s("se",-1,-1),new s("lo",-1,-1),new s("selo",5,-1),new s("las",-1,-1),new s("selas",7,-1),new s("les",-1,-1),new s("los",-1,-1),new s("selos",10,-1),new s("nos",-1,-1)],q=[new s("ando",-1,6),new s("iendo",-1,6),new s("yendo",-1,7),new s("ándo",-1,2),new s("iéndo",-1,1),new s("ar",-1,6),new s("er",-1,6),new s("ir",-1,6),new s("ár",-1,3),new s("ér",-1,4),new s("ír",-1,5)],C=[new s("ic",-1,-1),new s("ad",-1,-1),new s("os",-1,-1),new s("iv",-1,1)],P=[new s("able",-1,1),new s("ible",-1,1),new s("ante",-1,1)],F=[new s("ic",-1,1),new s("abil",-1,1),new s("iv",-1,1)],S=[new s("ica",-1,1),new s("ancia",-1,2),new s("encia",-1,5),new s("adora",-1,2),new s("osa",-1,1),new s("ista",-1,1),new s("iva",-1,9),new s("anza",-1,1),new s("logía",-1,3),new s("idad",-1,8),new s("able",-1,1),new s("ible",-1,1),new s("ante",-1,2),new s("mente",-1,7),new s("amente",13,6),new s("ación",-1,2),new s("ución",-1,4),new s("ico",-1,1),new s("ismo",-1,1),new s("oso",-1,1),new s("amiento",-1,1),new s("imiento",-1,1),new s("ivo",-1,9),new s("ador",-1,2),new s("icas",-1,1),new s("ancias",-1,2),new s("encias",-1,5),new s("adoras",-1,2),new s("osas",-1,1),new s("istas",-1,1),new s("ivas",-1,9),new s("anzas",-1,1),new s("logías",-1,3),new s("idades",-1,8),new s("ables",-1,1),new s("ibles",-1,1),new s("aciones",-1,2),new s("uciones",-1,4),new s("adores",-1,2),new s("antes",-1,2),new s("icos",-1,1),new s("ismos",-1,1),new s("osos",-1,1),new s("amientos",-1,1),new s("imientos",-1,1),new s("ivos",-1,9)],W=[new s("ya",-1,1),new s("ye",-1,1),new s("yan",-1,1),new s("yen",-1,1),new s("yeron",-1,1),new s("yendo",-1,1),new s("yo",-1,1),new s("yas",-1,1),new s("yes",-1,1),new s("yais",-1,1),new s("yamos",-1,1),new s("yó",-1,1)],L=[new s("aba",-1,2),new s("ada",-1,2),new s("ida",-1,2),new s("ara",-1,2),new s("iera",-1,2),new s("ía",-1,2),new s("aría",5,2),new s("ería",5,2),new s("iría",5,2),new s("ad",-1,2),new s("ed",-1,2),new s("id",-1,2),new s("ase",-1,2),new s("iese",-1,2),new s("aste",-1,2),new s("iste",-1,2),new s("an",-1,2),new s("aban",16,2),new s("aran",16,2),new s("ieran",16,2),new s("ían",16,2),new s("arían",20,2),new s("erían",20,2),new s("irían",20,2),new s("en",-1,1),new s("asen",24,2),new s("iesen",24,2),new s("aron",-1,2),new s("ieron",-1,2),new s("arán",-1,2),new s("erán",-1,2),new s("irán",-1,2),new s("ado",-1,2),new s("ido",-1,2),new s("ando",-1,2),new s("iendo",-1,2),new s("ar",-1,2),new s("er",-1,2),new s("ir",-1,2),new s("as",-1,2),new s("abas",39,2),new s("adas",39,2),new s("idas",39,2),new s("aras",39,2),new s("ieras",39,2),new s("ías",39,2),new s("arías",45,2),new s("erías",45,2),new s("irías",45,2),new s("es",-1,1),new s("ases",49,2),new s("ieses",49,2),new s("abais",-1,2),new s("arais",-1,2),new s("ierais",-1,2),new s("íais",-1,2),new s("aríais",55,2),new s("eríais",55,2),new s("iríais",55,2),new s("aseis",-1,2),new s("ieseis",-1,2),new s("asteis",-1,2),new s("isteis",-1,2),new s("áis",-1,2),new s("éis",-1,1),new s("aréis",64,2),new s("eréis",64,2),new s("iréis",64,2),new s("ados",-1,2),new s("idos",-1,2),new s("amos",-1,2),new s("ábamos",70,2),new s("áramos",70,2),new s("iéramos",70,2),new s("íamos",70,2),new s("aríamos",74,2),new s("eríamos",74,2),new s("iríamos",74,2),new s("emos",-1,1),new s("aremos",78,2),new s("eremos",78,2),new s("iremos",78,2),new s("ásemos",78,2),new s("iésemos",78,2),new s("imos",-1,2),new s("arás",-1,2),new s("erás",-1,2),new s("irás",-1,2),new s("ís",-1,2),new s("ará",-1,2),new s("erá",-1,2),new s("irá",-1,2),new s("aré",-1,2),new s("eré",-1,2),new s("iré",-1,2),new s("ió",-1,2)],z=[new s("a",-1,1),new s("e",-1,2),new s("o",-1,1),new s("os",-1,1),new s("á",-1,1),new s("é",-1,2),new s("í",-1,1),new s("ó",-1,1)],x=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,1,17,4,10],A=new r;this.setCurrent=function(e){A.setCurrent(e)},this.getCurrent=function(){return A.getCurrent()},this.stem=function(){var e=A.cursor;return t(),A.limit_backward=e,A.cursor=A.limit,m(),A.cursor=A.limit,b()||(A.cursor=A.limit,f()||(A.cursor=A.limit,_())),A.cursor=A.limit,h(),A.cursor=A.limit_backward,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.es.stemmer,"stemmer-es"),e.es.stopWordFilter=e.generateStopWordFilter("a al algo algunas algunos ante antes como con contra cual cuando de del desde donde durante e el ella ellas ellos en entre era erais eran eras eres es esa esas ese eso esos esta estaba estabais estaban estabas estad estada estadas estado estados estamos estando estar estaremos estará estarán estarás estaré estaréis estaría estaríais estaríamos estarían estarías estas este estemos esto estos estoy estuve estuviera estuvierais estuvieran estuvieras estuvieron estuviese estuvieseis estuviesen estuvieses estuvimos estuviste estuvisteis estuviéramos estuviésemos estuvo está estábamos estáis están estás esté estéis estén estés fue fuera fuerais fueran fueras fueron fuese fueseis fuesen fueses fui fuimos fuiste fuisteis fuéramos fuésemos ha habida habidas habido habidos habiendo habremos habrá habrán habrás habré habréis habría habríais habríamos habrían habrías habéis había habíais habíamos habían habías han has hasta hay haya hayamos hayan hayas hayáis he hemos hube hubiera hubierais hubieran hubieras hubieron hubiese hubieseis hubiesen hubieses hubimos hubiste hubisteis hubiéramos hubiésemos hubo la las le les lo los me mi mis mucho muchos muy más mí mía mías mío míos nada ni no nos nosotras nosotros nuestra nuestras nuestro nuestros o os otra otras otro otros para pero poco por porque que quien quienes qué se sea seamos sean seas seremos será serán serás seré seréis sería seríais seríamos serían serías seáis sido siendo sin sobre sois somos son soy su sus suya suyas suyo suyos sí también tanto te tendremos tendrá tendrán tendrás tendré tendréis tendría tendríais tendríamos tendrían tendrías tened tenemos tenga tengamos tengan tengas tengo tengáis tenida tenidas tenido tenidos teniendo tenéis tenía teníais teníamos tenían tenías ti tiene tienen tienes todo todos tu tus tuve tuviera tuvierais tuvieran tuvieras tuvieron tuviese tuvieseis tuviesen tuvieses tuvimos tuviste tuvisteis tuviéramos tuviésemos tuvo tuya tuyas tuyo tuyos tú un una uno unos vosotras vosotros vuestra vuestras vuestro vuestros y ya yo él éramos".split(" ")),e.Pipeline.registerFunction(e.es.stopWordFilter,"stopWordFilter-es")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.fi.min.js b/assets/javascripts/lunr/min/lunr.fi.min.js new file mode 100644 index 00000000..29f5dfce --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.fi.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Finnish` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(i,e){"function"==typeof define&&define.amd?define(e):"object"==typeof exports?module.exports=e():e()(i.lunr)}(this,function(){return function(i){if(void 0===i)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===i.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");i.fi=function(){this.pipeline.reset(),this.pipeline.add(i.fi.trimmer,i.fi.stopWordFilter,i.fi.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(i.fi.stemmer))},i.fi.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",i.fi.trimmer=i.trimmerSupport.generateTrimmer(i.fi.wordCharacters),i.Pipeline.registerFunction(i.fi.trimmer,"trimmer-fi"),i.fi.stemmer=function(){var e=i.stemmerSupport.Among,r=i.stemmerSupport.SnowballProgram,n=new function(){function i(){f=A.limit,d=f,n()||(f=A.cursor,n()||(d=A.cursor))}function n(){for(var i;;){if(i=A.cursor,A.in_grouping(W,97,246))break;if(A.cursor=i,i>=A.limit)return!0;A.cursor++}for(A.cursor=i;!A.out_grouping(W,97,246);){if(A.cursor>=A.limit)return!0;A.cursor++}return!1}function t(){return d<=A.cursor}function s(){var i,e;if(A.cursor>=f)if(e=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,i=A.find_among_b(h,10)){switch(A.bra=A.cursor,A.limit_backward=e,i){case 1:if(!A.in_grouping_b(x,97,246))return;break;case 2:if(!t())return}A.slice_del()}else A.limit_backward=e}function o(){var i,e,r;if(A.cursor>=f)if(e=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,i=A.find_among_b(v,9))switch(A.bra=A.cursor,A.limit_backward=e,i){case 1:r=A.limit-A.cursor,A.eq_s_b(1,"k")||(A.cursor=A.limit-r,A.slice_del());break;case 2:A.slice_del(),A.ket=A.cursor,A.eq_s_b(3,"kse")&&(A.bra=A.cursor,A.slice_from("ksi"));break;case 3:A.slice_del();break;case 4:A.find_among_b(p,6)&&A.slice_del();break;case 5:A.find_among_b(g,6)&&A.slice_del();break;case 6:A.find_among_b(j,2)&&A.slice_del()}else A.limit_backward=e}function l(){return A.find_among_b(q,7)}function a(){return A.eq_s_b(1,"i")&&A.in_grouping_b(L,97,246)}function u(){var i,e,r;if(A.cursor>=f)if(e=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,i=A.find_among_b(C,30)){switch(A.bra=A.cursor,A.limit_backward=e,i){case 1:if(!A.eq_s_b(1,"a"))return;break;case 2:case 9:if(!A.eq_s_b(1,"e"))return;break;case 3:if(!A.eq_s_b(1,"i"))return;break;case 4:if(!A.eq_s_b(1,"o"))return;break;case 5:if(!A.eq_s_b(1,"ä"))return;break;case 6:if(!A.eq_s_b(1,"ö"))return;break;case 7:if(r=A.limit-A.cursor,!l()&&(A.cursor=A.limit-r,!A.eq_s_b(2,"ie"))){A.cursor=A.limit-r;break}if(A.cursor=A.limit-r,A.cursor<=A.limit_backward){A.cursor=A.limit-r;break}A.cursor--,A.bra=A.cursor;break;case 8:if(!A.in_grouping_b(W,97,246)||!A.out_grouping_b(W,97,246))return}A.slice_del(),k=!0}else A.limit_backward=e}function c(){var i,e,r;if(A.cursor>=d)if(e=A.limit_backward,A.limit_backward=d,A.ket=A.cursor,i=A.find_among_b(P,14)){if(A.bra=A.cursor,A.limit_backward=e,1==i){if(r=A.limit-A.cursor,A.eq_s_b(2,"po"))return;A.cursor=A.limit-r}A.slice_del()}else A.limit_backward=e}function m(){var i;A.cursor>=f&&(i=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,A.find_among_b(F,2)?(A.bra=A.cursor,A.limit_backward=i,A.slice_del()):A.limit_backward=i)}function w(){var i,e,r,n,t,s;if(A.cursor>=f){if(e=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,A.eq_s_b(1,"t")&&(A.bra=A.cursor,r=A.limit-A.cursor,A.in_grouping_b(W,97,246)&&(A.cursor=A.limit-r,A.slice_del(),A.limit_backward=e,n=A.limit-A.cursor,A.cursor>=d&&(A.cursor=d,t=A.limit_backward,A.limit_backward=A.cursor,A.cursor=A.limit-n,A.ket=A.cursor,i=A.find_among_b(S,2))))){if(A.bra=A.cursor,A.limit_backward=t,1==i){if(s=A.limit-A.cursor,A.eq_s_b(2,"po"))return;A.cursor=A.limit-s}return void A.slice_del()}A.limit_backward=e}}function _(){var i,e,r,n;if(A.cursor>=f){for(i=A.limit_backward,A.limit_backward=f,e=A.limit-A.cursor,l()&&(A.cursor=A.limit-e,A.ket=A.cursor,A.cursor>A.limit_backward&&(A.cursor--,A.bra=A.cursor,A.slice_del())),A.cursor=A.limit-e,A.ket=A.cursor,A.in_grouping_b(y,97,228)&&(A.bra=A.cursor,A.out_grouping_b(W,97,246)&&A.slice_del()),A.cursor=A.limit-e,A.ket=A.cursor,A.eq_s_b(1,"j")&&(A.bra=A.cursor,r=A.limit-A.cursor,A.eq_s_b(1,"o")?A.slice_del():(A.cursor=A.limit-r,A.eq_s_b(1,"u")&&A.slice_del())),A.cursor=A.limit-e,A.ket=A.cursor,A.eq_s_b(1,"o")&&(A.bra=A.cursor,A.eq_s_b(1,"j")&&A.slice_del()),A.cursor=A.limit-e,A.limit_backward=i;;){if(n=A.limit-A.cursor,A.out_grouping_b(W,97,246)){A.cursor=A.limit-n;break}if(A.cursor=A.limit-n,A.cursor<=A.limit_backward)return;A.cursor--}A.ket=A.cursor,A.cursor>A.limit_backward&&(A.cursor--,A.bra=A.cursor,b=A.slice_to(),A.eq_v_b(b)&&A.slice_del())}}var k,b,d,f,h=[new e("pa",-1,1),new e("sti",-1,2),new e("kaan",-1,1),new e("han",-1,1),new e("kin",-1,1),new e("hän",-1,1),new e("kään",-1,1),new e("ko",-1,1),new e("pä",-1,1),new e("kö",-1,1)],p=[new e("lla",-1,-1),new e("na",-1,-1),new e("ssa",-1,-1),new e("ta",-1,-1),new e("lta",3,-1),new e("sta",3,-1)],g=[new e("llä",-1,-1),new e("nä",-1,-1),new e("ssä",-1,-1),new e("tä",-1,-1),new e("ltä",3,-1),new e("stä",3,-1)],j=[new e("lle",-1,-1),new e("ine",-1,-1)],v=[new e("nsa",-1,3),new e("mme",-1,3),new e("nne",-1,3),new e("ni",-1,2),new e("si",-1,1),new e("an",-1,4),new e("en",-1,6),new e("än",-1,5),new e("nsä",-1,3)],q=[new e("aa",-1,-1),new e("ee",-1,-1),new e("ii",-1,-1),new e("oo",-1,-1),new e("uu",-1,-1),new e("ää",-1,-1),new e("öö",-1,-1)],C=[new e("a",-1,8),new e("lla",0,-1),new e("na",0,-1),new e("ssa",0,-1),new e("ta",0,-1),new e("lta",4,-1),new e("sta",4,-1),new e("tta",4,9),new e("lle",-1,-1),new e("ine",-1,-1),new e("ksi",-1,-1),new e("n",-1,7),new e("han",11,1),new e("den",11,-1,a),new e("seen",11,-1,l),new e("hen",11,2),new e("tten",11,-1,a),new e("hin",11,3),new e("siin",11,-1,a),new e("hon",11,4),new e("hän",11,5),new e("hön",11,6),new e("ä",-1,8),new e("llä",22,-1),new e("nä",22,-1),new e("ssä",22,-1),new e("tä",22,-1),new e("ltä",26,-1),new e("stä",26,-1),new e("ttä",26,9)],P=[new e("eja",-1,-1),new e("mma",-1,1),new e("imma",1,-1),new e("mpa",-1,1),new e("impa",3,-1),new e("mmi",-1,1),new e("immi",5,-1),new e("mpi",-1,1),new e("impi",7,-1),new e("ejä",-1,-1),new e("mmä",-1,1),new e("immä",10,-1),new e("mpä",-1,1),new e("impä",12,-1)],F=[new e("i",-1,-1),new e("j",-1,-1)],S=[new e("mma",-1,1),new e("imma",0,-1)],y=[17,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8],W=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],L=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],x=[17,97,24,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],A=new r;this.setCurrent=function(i){A.setCurrent(i)},this.getCurrent=function(){return A.getCurrent()},this.stem=function(){var e=A.cursor;return i(),k=!1,A.limit_backward=e,A.cursor=A.limit,s(),A.cursor=A.limit,o(),A.cursor=A.limit,u(),A.cursor=A.limit,c(),A.cursor=A.limit,k?(m(),A.cursor=A.limit):(A.cursor=A.limit,w(),A.cursor=A.limit),_(),!0}};return function(i){return"function"==typeof i.update?i.update(function(i){return n.setCurrent(i),n.stem(),n.getCurrent()}):(n.setCurrent(i),n.stem(),n.getCurrent())}}(),i.Pipeline.registerFunction(i.fi.stemmer,"stemmer-fi"),i.fi.stopWordFilter=i.generateStopWordFilter("ei eivät emme en et ette että he heidän heidät heihin heille heillä heiltä heissä heistä heitä hän häneen hänelle hänellä häneltä hänen hänessä hänestä hänet häntä itse ja johon joiden joihin joiksi joilla joille joilta joina joissa joista joita joka joksi jolla jolle jolta jona jonka jos jossa josta jota jotka kanssa keiden keihin keiksi keille keillä keiltä keinä keissä keistä keitä keneen keneksi kenelle kenellä keneltä kenen kenenä kenessä kenestä kenet ketkä ketkä ketä koska kuin kuka kun me meidän meidät meihin meille meillä meiltä meissä meistä meitä mihin miksi mikä mille millä miltä minkä minkä minua minulla minulle minulta minun minussa minusta minut minuun minä minä missä mistä mitkä mitä mukaan mutta ne niiden niihin niiksi niille niillä niiltä niin niin niinä niissä niistä niitä noiden noihin noiksi noilla noille noilta noin noina noissa noista noita nuo nyt näiden näihin näiksi näille näillä näiltä näinä näissä näistä näitä nämä ole olemme olen olet olette oli olimme olin olisi olisimme olisin olisit olisitte olisivat olit olitte olivat olla olleet ollut on ovat poikki se sekä sen siihen siinä siitä siksi sille sillä sillä siltä sinua sinulla sinulle sinulta sinun sinussa sinusta sinut sinuun sinä sinä sitä tai te teidän teidät teihin teille teillä teiltä teissä teistä teitä tuo tuohon tuoksi tuolla tuolle tuolta tuon tuona tuossa tuosta tuota tähän täksi tälle tällä tältä tämä tämän tänä tässä tästä tätä vaan vai vaikka yli".split(" ")),i.Pipeline.registerFunction(i.fi.stopWordFilter,"stopWordFilter-fi")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.fr.min.js b/assets/javascripts/lunr/min/lunr.fr.min.js new file mode 100644 index 00000000..68cd0094 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.fr.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `French` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.fr=function(){this.pipeline.reset(),this.pipeline.add(e.fr.trimmer,e.fr.stopWordFilter,e.fr.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.fr.stemmer))},e.fr.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.fr.trimmer=e.trimmerSupport.generateTrimmer(e.fr.wordCharacters),e.Pipeline.registerFunction(e.fr.trimmer,"trimmer-fr"),e.fr.stemmer=function(){var r=e.stemmerSupport.Among,s=e.stemmerSupport.SnowballProgram,i=new function(){function e(e,r,s){return!(!W.eq_s(1,e)||(W.ket=W.cursor,!W.in_grouping(F,97,251)))&&(W.slice_from(r),W.cursor=s,!0)}function i(e,r,s){return!!W.eq_s(1,e)&&(W.ket=W.cursor,W.slice_from(r),W.cursor=s,!0)}function n(){for(var r,s;;){if(r=W.cursor,W.in_grouping(F,97,251)){if(W.bra=W.cursor,s=W.cursor,e("u","U",r))continue;if(W.cursor=s,e("i","I",r))continue;if(W.cursor=s,i("y","Y",r))continue}if(W.cursor=r,W.bra=r,!e("y","Y",r)){if(W.cursor=r,W.eq_s(1,"q")&&(W.bra=W.cursor,i("u","U",r)))continue;if(W.cursor=r,r>=W.limit)return;W.cursor++}}}function t(){for(;!W.in_grouping(F,97,251);){if(W.cursor>=W.limit)return!0;W.cursor++}for(;!W.out_grouping(F,97,251);){if(W.cursor>=W.limit)return!0;W.cursor++}return!1}function u(){var e=W.cursor;if(q=W.limit,g=q,p=q,W.in_grouping(F,97,251)&&W.in_grouping(F,97,251)&&W.cursor=W.limit){W.cursor=q;break}W.cursor++}while(!W.in_grouping(F,97,251))}q=W.cursor,W.cursor=e,t()||(g=W.cursor,t()||(p=W.cursor))}function o(){for(var e,r;;){if(r=W.cursor,W.bra=r,!(e=W.find_among(h,4)))break;switch(W.ket=W.cursor,e){case 1:W.slice_from("i");break;case 2:W.slice_from("u");break;case 3:W.slice_from("y");break;case 4:if(W.cursor>=W.limit)return;W.cursor++}}}function c(){return q<=W.cursor}function a(){return g<=W.cursor}function l(){return p<=W.cursor}function w(){var e,r;if(W.ket=W.cursor,e=W.find_among_b(C,43)){switch(W.bra=W.cursor,e){case 1:if(!l())return!1;W.slice_del();break;case 2:if(!l())return!1;W.slice_del(),W.ket=W.cursor,W.eq_s_b(2,"ic")&&(W.bra=W.cursor,l()?W.slice_del():W.slice_from("iqU"));break;case 3:if(!l())return!1;W.slice_from("log");break;case 4:if(!l())return!1;W.slice_from("u");break;case 5:if(!l())return!1;W.slice_from("ent");break;case 6:if(!c())return!1;if(W.slice_del(),W.ket=W.cursor,e=W.find_among_b(z,6))switch(W.bra=W.cursor,e){case 1:l()&&(W.slice_del(),W.ket=W.cursor,W.eq_s_b(2,"at")&&(W.bra=W.cursor,l()&&W.slice_del()));break;case 2:l()?W.slice_del():a()&&W.slice_from("eux");break;case 3:l()&&W.slice_del();break;case 4:c()&&W.slice_from("i")}break;case 7:if(!l())return!1;if(W.slice_del(),W.ket=W.cursor,e=W.find_among_b(y,3))switch(W.bra=W.cursor,e){case 1:l()?W.slice_del():W.slice_from("abl");break;case 2:l()?W.slice_del():W.slice_from("iqU");break;case 3:l()&&W.slice_del()}break;case 8:if(!l())return!1;if(W.slice_del(),W.ket=W.cursor,W.eq_s_b(2,"at")&&(W.bra=W.cursor,l()&&(W.slice_del(),W.ket=W.cursor,W.eq_s_b(2,"ic")))){W.bra=W.cursor,l()?W.slice_del():W.slice_from("iqU");break}break;case 9:W.slice_from("eau");break;case 10:if(!a())return!1;W.slice_from("al");break;case 11:if(l())W.slice_del();else{if(!a())return!1;W.slice_from("eux")}break;case 12:if(!a()||!W.out_grouping_b(F,97,251))return!1;W.slice_del();break;case 13:return c()&&W.slice_from("ant"),!1;case 14:return c()&&W.slice_from("ent"),!1;case 15:return r=W.limit-W.cursor,W.in_grouping_b(F,97,251)&&c()&&(W.cursor=W.limit-r,W.slice_del()),!1}return!0}return!1}function f(){var e,r;if(W.cursor=q){if(s=W.limit_backward,W.limit_backward=q,W.ket=W.cursor,e=W.find_among_b(P,7))switch(W.bra=W.cursor,e){case 1:if(l()){if(i=W.limit-W.cursor,!W.eq_s_b(1,"s")&&(W.cursor=W.limit-i,!W.eq_s_b(1,"t")))break;W.slice_del()}break;case 2:W.slice_from("i");break;case 3:W.slice_del();break;case 4:W.eq_s_b(2,"gu")&&W.slice_del()}W.limit_backward=s}}function b(){var e=W.limit-W.cursor;W.find_among_b(U,5)&&(W.cursor=W.limit-e,W.ket=W.cursor,W.cursor>W.limit_backward&&(W.cursor--,W.bra=W.cursor,W.slice_del()))}function d(){for(var e,r=1;W.out_grouping_b(F,97,251);)r--;if(r<=0){if(W.ket=W.cursor,e=W.limit-W.cursor,!W.eq_s_b(1,"é")&&(W.cursor=W.limit-e,!W.eq_s_b(1,"è")))return;W.bra=W.cursor,W.slice_from("e")}}function k(){if(!w()&&(W.cursor=W.limit,!f()&&(W.cursor=W.limit,!m())))return W.cursor=W.limit,void _();W.cursor=W.limit,W.ket=W.cursor,W.eq_s_b(1,"Y")?(W.bra=W.cursor,W.slice_from("i")):(W.cursor=W.limit,W.eq_s_b(1,"ç")&&(W.bra=W.cursor,W.slice_from("c")))}var p,g,q,v=[new r("col",-1,-1),new r("par",-1,-1),new r("tap",-1,-1)],h=[new r("",-1,4),new r("I",0,1),new r("U",0,2),new r("Y",0,3)],z=[new r("iqU",-1,3),new r("abl",-1,3),new r("Ièr",-1,4),new r("ièr",-1,4),new r("eus",-1,2),new r("iv",-1,1)],y=[new r("ic",-1,2),new r("abil",-1,1),new r("iv",-1,3)],C=[new r("iqUe",-1,1),new r("atrice",-1,2),new r("ance",-1,1),new r("ence",-1,5),new r("logie",-1,3),new r("able",-1,1),new r("isme",-1,1),new r("euse",-1,11),new r("iste",-1,1),new r("ive",-1,8),new r("if",-1,8),new r("usion",-1,4),new r("ation",-1,2),new r("ution",-1,4),new r("ateur",-1,2),new r("iqUes",-1,1),new r("atrices",-1,2),new r("ances",-1,1),new r("ences",-1,5),new r("logies",-1,3),new r("ables",-1,1),new r("ismes",-1,1),new r("euses",-1,11),new r("istes",-1,1),new r("ives",-1,8),new r("ifs",-1,8),new r("usions",-1,4),new r("ations",-1,2),new r("utions",-1,4),new r("ateurs",-1,2),new r("ments",-1,15),new r("ements",30,6),new r("issements",31,12),new r("ités",-1,7),new r("ment",-1,15),new r("ement",34,6),new r("issement",35,12),new r("amment",34,13),new r("emment",34,14),new r("aux",-1,10),new r("eaux",39,9),new r("eux",-1,1),new r("ité",-1,7)],x=[new r("ira",-1,1),new r("ie",-1,1),new r("isse",-1,1),new r("issante",-1,1),new r("i",-1,1),new r("irai",4,1),new r("ir",-1,1),new r("iras",-1,1),new r("ies",-1,1),new r("îmes",-1,1),new r("isses",-1,1),new r("issantes",-1,1),new r("îtes",-1,1),new r("is",-1,1),new r("irais",13,1),new r("issais",13,1),new r("irions",-1,1),new r("issions",-1,1),new r("irons",-1,1),new r("issons",-1,1),new r("issants",-1,1),new r("it",-1,1),new r("irait",21,1),new r("issait",21,1),new r("issant",-1,1),new r("iraIent",-1,1),new r("issaIent",-1,1),new r("irent",-1,1),new r("issent",-1,1),new r("iront",-1,1),new r("ît",-1,1),new r("iriez",-1,1),new r("issiez",-1,1),new r("irez",-1,1),new r("issez",-1,1)],I=[new r("a",-1,3),new r("era",0,2),new r("asse",-1,3),new r("ante",-1,3),new r("ée",-1,2),new r("ai",-1,3),new r("erai",5,2),new r("er",-1,2),new r("as",-1,3),new r("eras",8,2),new r("âmes",-1,3),new r("asses",-1,3),new r("antes",-1,3),new r("âtes",-1,3),new r("ées",-1,2),new r("ais",-1,3),new r("erais",15,2),new r("ions",-1,1),new r("erions",17,2),new r("assions",17,3),new r("erons",-1,2),new r("ants",-1,3),new r("és",-1,2),new r("ait",-1,3),new r("erait",23,2),new r("ant",-1,3),new r("aIent",-1,3),new r("eraIent",26,2),new r("èrent",-1,2),new r("assent",-1,3),new r("eront",-1,2),new r("ât",-1,3),new r("ez",-1,2),new r("iez",32,2),new r("eriez",33,2),new r("assiez",33,3),new r("erez",32,2),new r("é",-1,2)],P=[new r("e",-1,3),new r("Ière",0,2),new r("ière",0,2),new r("ion",-1,1),new r("Ier",-1,2),new r("ier",-1,2),new r("ë",-1,4)],U=[new r("ell",-1,-1),new r("eill",-1,-1),new r("enn",-1,-1),new r("onn",-1,-1),new r("ett",-1,-1)],F=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,128,130,103,8,5],S=[1,65,20,0,0,0,0,0,0,0,0,0,0,0,0,0,128],W=new s;this.setCurrent=function(e){W.setCurrent(e)},this.getCurrent=function(){return W.getCurrent()},this.stem=function(){var e=W.cursor;return n(),W.cursor=e,u(),W.limit_backward=e,W.cursor=W.limit,k(),W.cursor=W.limit,b(),W.cursor=W.limit,d(),W.cursor=W.limit_backward,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.fr.stemmer,"stemmer-fr"),e.fr.stopWordFilter=e.generateStopWordFilter("ai aie aient aies ait as au aura aurai auraient aurais aurait auras aurez auriez aurions aurons auront aux avaient avais avait avec avez aviez avions avons ayant ayez ayons c ce ceci celà ces cet cette d dans de des du elle en es est et eu eue eues eurent eus eusse eussent eusses eussiez eussions eut eux eûmes eût eûtes furent fus fusse fussent fusses fussiez fussions fut fûmes fût fûtes ici il ils j je l la le les leur leurs lui m ma mais me mes moi mon même n ne nos notre nous on ont ou par pas pour qu que quel quelle quelles quels qui s sa sans se sera serai seraient serais serait seras serez seriez serions serons seront ses soi soient sois soit sommes son sont soyez soyons suis sur t ta te tes toi ton tu un une vos votre vous y à étaient étais était étant étiez étions été étée étées étés êtes".split(" ")),e.Pipeline.registerFunction(e.fr.stopWordFilter,"stopWordFilter-fr")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.he.min.js b/assets/javascripts/lunr/min/lunr.he.min.js new file mode 100644 index 00000000..b863d3ea --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.he.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.he=function(){this.pipeline.reset(),this.pipeline.add(e.he.trimmer,e.he.stopWordFilter,e.he.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.he.stemmer))},e.he.wordCharacters="֑-״א-תa-zA-Za-zA-Z0-90-9",e.he.trimmer=e.trimmerSupport.generateTrimmer(e.he.wordCharacters),e.Pipeline.registerFunction(e.he.trimmer,"trimmer-he"),e.he.stemmer=function(){var e=this;return e.result=!1,e.preRemoved=!1,e.sufRemoved=!1,e.pre={pre1:"ה ו י ת",pre2:"ב כ ל מ ש כש",pre3:"הב הכ הל המ הש בש לכ",pre4:"וב וכ ול ומ וש",pre5:"מה שה כל",pre6:"מב מכ מל ממ מש",pre7:"בה בו בי בת כה כו כי כת לה לו לי לת",pre8:"ובה ובו ובי ובת וכה וכו וכי וכת ולה ולו ולי ולת"},e.suf={suf1:"ך כ ם ן נ",suf2:"ים ות וך וכ ום ון ונ הם הן יכ יך ינ ים",suf3:"תי תך תכ תם תן תנ",suf4:"ותי ותך ותכ ותם ותן ותנ",suf5:"נו כם כן הם הן",suf6:"ונו וכם וכן והם והן",suf7:"תכם תכן תנו תהם תהן",suf8:"הוא היא הם הן אני אתה את אנו אתם אתן",suf9:"ני נו כי כו כם כן תי תך תכ תם תן",suf10:"י ך כ ם ן נ ת"},e.patterns=JSON.parse('{"hebrewPatterns": [{"pt1": [{"c": "ה", "l": 0}]}, {"pt2": [{"c": "ו", "l": 0}]}, {"pt3": [{"c": "י", "l": 0}]}, {"pt4": [{"c": "ת", "l": 0}]}, {"pt5": [{"c": "מ", "l": 0}]}, {"pt6": [{"c": "ל", "l": 0}]}, {"pt7": [{"c": "ב", "l": 0}]}, {"pt8": [{"c": "כ", "l": 0}]}, {"pt9": [{"c": "ש", "l": 0}]}, {"pt10": [{"c": "כש", "l": 0}]}, {"pt11": [{"c": "בה", "l": 0}]}, {"pt12": [{"c": "וב", "l": 0}]}, {"pt13": [{"c": "וכ", "l": 0}]}, {"pt14": [{"c": "ול", "l": 0}]}, {"pt15": [{"c": "ומ", "l": 0}]}, {"pt16": [{"c": "וש", "l": 0}]}, {"pt17": [{"c": "הב", "l": 0}]}, {"pt18": [{"c": "הכ", "l": 0}]}, {"pt19": [{"c": "הל", "l": 0}]}, {"pt20": [{"c": "המ", "l": 0}]}, {"pt21": [{"c": "הש", "l": 0}]}, {"pt22": [{"c": "מה", "l": 0}]}, {"pt23": [{"c": "שה", "l": 0}]}, {"pt24": [{"c": "כל", "l": 0}]}]}'),e.execArray=["cleanWord","removeDiacritics","removeStopWords","normalizeHebrewCharacters"],e.stem=function(){var r=0;for(e.result=!1,e.preRemoved=!1,e.sufRemoved=!1;r=0)return!0},e.normalizeHebrewCharacters=function(){return e.word=e.word.replace("ך","כ"),e.word=e.word.replace("ם","מ"),e.word=e.word.replace("ן","נ"),e.word=e.word.replace("ף","פ"),e.word=e.word.replace("ץ","צ"),!1},function(r){return"function"==typeof r.update?r.update(function(r){return e.setCurrent(r),e.stem(),e.getCurrent()}):(e.setCurrent(r),e.stem(),e.getCurrent())}}(),e.Pipeline.registerFunction(e.he.stemmer,"stemmer-he"),e.he.stopWordFilter=e.generateStopWordFilter("אבל או אולי אותו אותי אותך אותם אותן אותנו אז אחר אחרות אחרי אחריכן אחרים אחרת אי איזה איך אין איפה אל אלה אלו אם אנחנו אני אף אפשר את אתה אתכם אתכן אתם אתן באיזה באיזו בגלל בין בלבד בעבור בעזרת בכל בכן בלי במידה במקום שבו ברוב בשביל בשעה ש בתוך גם דרך הוא היא היה היי היכן היתה היתי הם הן הנה הסיבה שבגללה הרי ואילו ואת זאת זה זות יהיה יוכל יוכלו יותר מדי יכול יכולה יכולות יכולים יכל יכלה יכלו יש כאן כאשר כולם כולן כזה כי כיצד כך כל כלל כמו כן כפי כש לא לאו לאיזותך לאן לבין לה להיות להם להן לו לזה לזות לי לך לכם לכן למה למעלה למעלה מ למטה למטה מ למעט למקום שבו למרות לנו לעבר לעיכן לפיכך לפני מאד מאחורי מאיזו סיבה מאין מאיפה מבלי מבעד מדוע מה מהיכן מול מחוץ מי מידע מכאן מכל מכן מלבד מן מנין מסוגל מעט מעטים מעל מצד מקום בו מתחת מתי נגד נגר נו עד עז על עלי עליו עליה עליהם עליך עלינו עם עצמה עצמהם עצמהן עצמו עצמי עצמם עצמן עצמנו פה רק שוב של שלה שלהם שלהן שלו שלי שלך שלכה שלכם שלכן שלנו שם תהיה תחת".split(" ")),e.Pipeline.registerFunction(e.he.stopWordFilter,"stopWordFilter-he")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.hi.min.js b/assets/javascripts/lunr/min/lunr.hi.min.js new file mode 100644 index 00000000..7dbc4140 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.hi.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.hi=function(){this.pipeline.reset(),this.pipeline.add(e.hi.trimmer,e.hi.stopWordFilter,e.hi.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.hi.stemmer))},e.hi.wordCharacters="ऀ-ःऄ-एऐ-टठ-यर-िी-ॏॐ-य़ॠ-९॰-ॿa-zA-Za-zA-Z0-90-9",e.hi.trimmer=e.trimmerSupport.generateTrimmer(e.hi.wordCharacters),e.Pipeline.registerFunction(e.hi.trimmer,"trimmer-hi"),e.hi.stopWordFilter=e.generateStopWordFilter("अत अपना अपनी अपने अभी अंदर आदि आप इत्यादि इन इनका इन्हीं इन्हें इन्हों इस इसका इसकी इसके इसमें इसी इसे उन उनका उनकी उनके उनको उन्हीं उन्हें उन्हों उस उसके उसी उसे एक एवं एस ऐसे और कई कर करता करते करना करने करें कहते कहा का काफ़ी कि कितना किन्हें किन्हों किया किर किस किसी किसे की कुछ कुल के को कोई कौन कौनसा गया घर जब जहाँ जा जितना जिन जिन्हें जिन्हों जिस जिसे जीधर जैसा जैसे जो तक तब तरह तिन तिन्हें तिन्हों तिस तिसे तो था थी थे दबारा दिया दुसरा दूसरे दो द्वारा न नके नहीं ना निहायत नीचे ने पर पहले पूरा पे फिर बनी बही बहुत बाद बाला बिलकुल भी भीतर मगर मानो मे में यदि यह यहाँ यही या यिह ये रखें रहा रहे ऱ्वासा लिए लिये लेकिन व वग़ैरह वर्ग वह वहाँ वहीं वाले वुह वे वो सकता सकते सबसे सभी साथ साबुत साभ सारा से सो संग ही हुआ हुई हुए है हैं हो होता होती होते होना होने".split(" ")),e.hi.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}();var r=e.wordcut;r.init(),e.hi.tokenizer=function(i){if(!arguments.length||null==i||void 0==i)return[];if(Array.isArray(i))return i.map(function(r){return isLunr2?new e.Token(r.toLowerCase()):r.toLowerCase()});var t=i.toString().toLowerCase().replace(/^\s+/,"");return r.cut(t).split("|")},e.Pipeline.registerFunction(e.hi.stemmer,"stemmer-hi"),e.Pipeline.registerFunction(e.hi.stopWordFilter,"stopWordFilter-hi")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.hu.min.js b/assets/javascripts/lunr/min/lunr.hu.min.js new file mode 100644 index 00000000..ed9d909f --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.hu.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Hungarian` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,n){"function"==typeof define&&define.amd?define(n):"object"==typeof exports?module.exports=n():n()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.hu=function(){this.pipeline.reset(),this.pipeline.add(e.hu.trimmer,e.hu.stopWordFilter,e.hu.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.hu.stemmer))},e.hu.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.hu.trimmer=e.trimmerSupport.generateTrimmer(e.hu.wordCharacters),e.Pipeline.registerFunction(e.hu.trimmer,"trimmer-hu"),e.hu.stemmer=function(){var n=e.stemmerSupport.Among,r=e.stemmerSupport.SnowballProgram,i=new function(){function e(){var e,n=L.cursor;if(d=L.limit,L.in_grouping(W,97,252))for(;;){if(e=L.cursor,L.out_grouping(W,97,252))return L.cursor=e,L.find_among(g,8)||(L.cursor=e,e=L.limit)return void(d=e);L.cursor++}if(L.cursor=n,L.out_grouping(W,97,252)){for(;!L.in_grouping(W,97,252);){if(L.cursor>=L.limit)return;L.cursor++}d=L.cursor}}function i(){return d<=L.cursor}function a(){var e;if(L.ket=L.cursor,(e=L.find_among_b(h,2))&&(L.bra=L.cursor,i()))switch(e){case 1:L.slice_from("a");break;case 2:L.slice_from("e")}}function t(){var e=L.limit-L.cursor;return!!L.find_among_b(p,23)&&(L.cursor=L.limit-e,!0)}function s(){if(L.cursor>L.limit_backward){L.cursor--,L.ket=L.cursor;var e=L.cursor-1;L.limit_backward<=e&&e<=L.limit&&(L.cursor=e,L.bra=e,L.slice_del())}}function c(){var e;if(L.ket=L.cursor,(e=L.find_among_b(_,2))&&(L.bra=L.cursor,i())){if((1==e||2==e)&&!t())return;L.slice_del(),s()}}function o(){L.ket=L.cursor,L.find_among_b(v,44)&&(L.bra=L.cursor,i()&&(L.slice_del(),a()))}function w(){var e;if(L.ket=L.cursor,(e=L.find_among_b(z,3))&&(L.bra=L.cursor,i()))switch(e){case 1:L.slice_from("e");break;case 2:case 3:L.slice_from("a")}}function l(){var e;if(L.ket=L.cursor,(e=L.find_among_b(y,6))&&(L.bra=L.cursor,i()))switch(e){case 1:case 2:L.slice_del();break;case 3:L.slice_from("a");break;case 4:L.slice_from("e")}}function u(){var e;if(L.ket=L.cursor,(e=L.find_among_b(j,2))&&(L.bra=L.cursor,i())){if((1==e||2==e)&&!t())return;L.slice_del(),s()}}function m(){var e;if(L.ket=L.cursor,(e=L.find_among_b(C,7))&&(L.bra=L.cursor,i()))switch(e){case 1:L.slice_from("a");break;case 2:L.slice_from("e");break;case 3:case 4:case 5:case 6:case 7:L.slice_del()}}function k(){var e;if(L.ket=L.cursor,(e=L.find_among_b(P,12))&&(L.bra=L.cursor,i()))switch(e){case 1:case 4:case 7:case 9:L.slice_del();break;case 2:case 5:case 8:L.slice_from("e");break;case 3:case 6:L.slice_from("a")}}function f(){var e;if(L.ket=L.cursor,(e=L.find_among_b(F,31))&&(L.bra=L.cursor,i()))switch(e){case 1:case 4:case 7:case 8:case 9:case 12:case 13:case 16:case 17:case 18:L.slice_del();break;case 2:case 5:case 10:case 14:case 19:L.slice_from("a");break;case 3:case 6:case 11:case 15:case 20:L.slice_from("e")}}function b(){var e;if(L.ket=L.cursor,(e=L.find_among_b(S,42))&&(L.bra=L.cursor,i()))switch(e){case 1:case 4:case 5:case 6:case 9:case 10:case 11:case 14:case 15:case 16:case 17:case 20:case 21:case 24:case 25:case 26:case 29:L.slice_del();break;case 2:case 7:case 12:case 18:case 22:case 27:L.slice_from("a");break;case 3:case 8:case 13:case 19:case 23:case 28:L.slice_from("e")}}var d,g=[new n("cs",-1,-1),new n("dzs",-1,-1),new n("gy",-1,-1),new n("ly",-1,-1),new n("ny",-1,-1),new n("sz",-1,-1),new n("ty",-1,-1),new n("zs",-1,-1)],h=[new n("á",-1,1),new n("é",-1,2)],p=[new n("bb",-1,-1),new n("cc",-1,-1),new n("dd",-1,-1),new n("ff",-1,-1),new n("gg",-1,-1),new n("jj",-1,-1),new n("kk",-1,-1),new n("ll",-1,-1),new n("mm",-1,-1),new n("nn",-1,-1),new n("pp",-1,-1),new n("rr",-1,-1),new n("ccs",-1,-1),new n("ss",-1,-1),new n("zzs",-1,-1),new n("tt",-1,-1),new n("vv",-1,-1),new n("ggy",-1,-1),new n("lly",-1,-1),new n("nny",-1,-1),new n("tty",-1,-1),new n("ssz",-1,-1),new n("zz",-1,-1)],_=[new n("al",-1,1),new n("el",-1,2)],v=[new n("ba",-1,-1),new n("ra",-1,-1),new n("be",-1,-1),new n("re",-1,-1),new n("ig",-1,-1),new n("nak",-1,-1),new n("nek",-1,-1),new n("val",-1,-1),new n("vel",-1,-1),new n("ul",-1,-1),new n("nál",-1,-1),new n("nél",-1,-1),new n("ból",-1,-1),new n("ról",-1,-1),new n("tól",-1,-1),new n("bõl",-1,-1),new n("rõl",-1,-1),new n("tõl",-1,-1),new n("ül",-1,-1),new n("n",-1,-1),new n("an",19,-1),new n("ban",20,-1),new n("en",19,-1),new n("ben",22,-1),new n("képpen",22,-1),new n("on",19,-1),new n("ön",19,-1),new n("képp",-1,-1),new n("kor",-1,-1),new n("t",-1,-1),new n("at",29,-1),new n("et",29,-1),new n("ként",29,-1),new n("anként",32,-1),new n("enként",32,-1),new n("onként",32,-1),new n("ot",29,-1),new n("ért",29,-1),new n("öt",29,-1),new n("hez",-1,-1),new n("hoz",-1,-1),new n("höz",-1,-1),new n("vá",-1,-1),new n("vé",-1,-1)],z=[new n("án",-1,2),new n("én",-1,1),new n("ánként",-1,3)],y=[new n("stul",-1,2),new n("astul",0,1),new n("ástul",0,3),new n("stül",-1,2),new n("estül",3,1),new n("éstül",3,4)],j=[new n("á",-1,1),new n("é",-1,2)],C=[new n("k",-1,7),new n("ak",0,4),new n("ek",0,6),new n("ok",0,5),new n("ák",0,1),new n("ék",0,2),new n("ök",0,3)],P=[new n("éi",-1,7),new n("áéi",0,6),new n("ééi",0,5),new n("é",-1,9),new n("ké",3,4),new n("aké",4,1),new n("eké",4,1),new n("oké",4,1),new n("áké",4,3),new n("éké",4,2),new n("öké",4,1),new n("éé",3,8)],F=[new n("a",-1,18),new n("ja",0,17),new n("d",-1,16),new n("ad",2,13),new n("ed",2,13),new n("od",2,13),new n("ád",2,14),new n("éd",2,15),new n("öd",2,13),new n("e",-1,18),new n("je",9,17),new n("nk",-1,4),new n("unk",11,1),new n("ánk",11,2),new n("énk",11,3),new n("ünk",11,1),new n("uk",-1,8),new n("juk",16,7),new n("ájuk",17,5),new n("ük",-1,8),new n("jük",19,7),new n("éjük",20,6),new n("m",-1,12),new n("am",22,9),new n("em",22,9),new n("om",22,9),new n("ám",22,10),new n("ém",22,11),new n("o",-1,18),new n("á",-1,19),new n("é",-1,20)],S=[new n("id",-1,10),new n("aid",0,9),new n("jaid",1,6),new n("eid",0,9),new n("jeid",3,6),new n("áid",0,7),new n("éid",0,8),new n("i",-1,15),new n("ai",7,14),new n("jai",8,11),new n("ei",7,14),new n("jei",10,11),new n("ái",7,12),new n("éi",7,13),new n("itek",-1,24),new n("eitek",14,21),new n("jeitek",15,20),new n("éitek",14,23),new n("ik",-1,29),new n("aik",18,26),new n("jaik",19,25),new n("eik",18,26),new n("jeik",21,25),new n("áik",18,27),new n("éik",18,28),new n("ink",-1,20),new n("aink",25,17),new n("jaink",26,16),new n("eink",25,17),new n("jeink",28,16),new n("áink",25,18),new n("éink",25,19),new n("aitok",-1,21),new n("jaitok",32,20),new n("áitok",-1,22),new n("im",-1,5),new n("aim",35,4),new n("jaim",36,1),new n("eim",35,4),new n("jeim",38,1),new n("áim",35,2),new n("éim",35,3)],W=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,1,17,52,14],L=new r;this.setCurrent=function(e){L.setCurrent(e)},this.getCurrent=function(){return L.getCurrent()},this.stem=function(){var n=L.cursor;return e(),L.limit_backward=n,L.cursor=L.limit,c(),L.cursor=L.limit,o(),L.cursor=L.limit,w(),L.cursor=L.limit,l(),L.cursor=L.limit,u(),L.cursor=L.limit,k(),L.cursor=L.limit,f(),L.cursor=L.limit,b(),L.cursor=L.limit,m(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.hu.stemmer,"stemmer-hu"),e.hu.stopWordFilter=e.generateStopWordFilter("a abban ahhoz ahogy ahol aki akik akkor alatt amely amelyek amelyekben amelyeket amelyet amelynek ami amikor amit amolyan amíg annak arra arról az azok azon azonban azt aztán azután azzal azért be belül benne bár cikk cikkek cikkeket csak de e ebben eddig egy egyes egyetlen egyik egyre egyéb egész ehhez ekkor el ellen elsõ elég elõ elõször elõtt emilyen ennek erre ez ezek ezen ezt ezzel ezért fel felé hanem hiszen hogy hogyan igen ill ill. illetve ilyen ilyenkor ismét ison itt jobban jó jól kell kellett keressünk keresztül ki kívül között közül legalább legyen lehet lehetett lenne lenni lesz lett maga magát majd majd meg mellett mely melyek mert mi mikor milyen minden mindenki mindent mindig mint mintha mit mivel miért most már más másik még míg nagy nagyobb nagyon ne nekem neki nem nincs néha néhány nélkül olyan ott pedig persze rá s saját sem semmi sok sokat sokkal szemben szerint szinte számára talán tehát teljes tovább továbbá több ugyanis utolsó után utána vagy vagyis vagyok valaki valami valamint való van vannak vele vissza viszont volna volt voltak voltam voltunk által általában át én éppen és így õ õk õket össze úgy új újabb újra".split(" ")),e.Pipeline.registerFunction(e.hu.stopWordFilter,"stopWordFilter-hu")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.hy.min.js b/assets/javascripts/lunr/min/lunr.hy.min.js new file mode 100644 index 00000000..b37f7929 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.hy.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.hy=function(){this.pipeline.reset(),this.pipeline.add(e.hy.trimmer,e.hy.stopWordFilter)},e.hy.wordCharacters="[A-Za-z԰-֏ff-ﭏ]",e.hy.trimmer=e.trimmerSupport.generateTrimmer(e.hy.wordCharacters),e.Pipeline.registerFunction(e.hy.trimmer,"trimmer-hy"),e.hy.stopWordFilter=e.generateStopWordFilter("դու և եք էիր էիք հետո նաև նրանք որը վրա է որ պիտի են այս մեջ ն իր ու ի այդ որոնք այն կամ էր մի ես համար այլ իսկ էին ենք հետ ին թ էինք մենք նրա նա դուք եմ էի ըստ որպես ում".split(" ")),e.Pipeline.registerFunction(e.hy.stopWordFilter,"stopWordFilter-hy"),e.hy.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}(),e.Pipeline.registerFunction(e.hy.stemmer,"stemmer-hy")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.it.min.js b/assets/javascripts/lunr/min/lunr.it.min.js new file mode 100644 index 00000000..344b6a3c --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.it.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Italian` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.it=function(){this.pipeline.reset(),this.pipeline.add(e.it.trimmer,e.it.stopWordFilter,e.it.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.it.stemmer))},e.it.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.it.trimmer=e.trimmerSupport.generateTrimmer(e.it.wordCharacters),e.Pipeline.registerFunction(e.it.trimmer,"trimmer-it"),e.it.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,i=new function(){function e(e,r,n){return!(!x.eq_s(1,e)||(x.ket=x.cursor,!x.in_grouping(L,97,249)))&&(x.slice_from(r),x.cursor=n,!0)}function i(){for(var r,n,i,o,t=x.cursor;;){if(x.bra=x.cursor,r=x.find_among(h,7))switch(x.ket=x.cursor,r){case 1:x.slice_from("à");continue;case 2:x.slice_from("è");continue;case 3:x.slice_from("ì");continue;case 4:x.slice_from("ò");continue;case 5:x.slice_from("ù");continue;case 6:x.slice_from("qU");continue;case 7:if(x.cursor>=x.limit)break;x.cursor++;continue}break}for(x.cursor=t;;)for(n=x.cursor;;){if(i=x.cursor,x.in_grouping(L,97,249)){if(x.bra=x.cursor,o=x.cursor,e("u","U",i))break;if(x.cursor=o,e("i","I",i))break}if(x.cursor=i,x.cursor>=x.limit)return void(x.cursor=n);x.cursor++}}function o(e){if(x.cursor=e,!x.in_grouping(L,97,249))return!1;for(;!x.out_grouping(L,97,249);){if(x.cursor>=x.limit)return!1;x.cursor++}return!0}function t(){if(x.in_grouping(L,97,249)){var e=x.cursor;if(x.out_grouping(L,97,249)){for(;!x.in_grouping(L,97,249);){if(x.cursor>=x.limit)return o(e);x.cursor++}return!0}return o(e)}return!1}function s(){var e,r=x.cursor;if(!t()){if(x.cursor=r,!x.out_grouping(L,97,249))return;if(e=x.cursor,x.out_grouping(L,97,249)){for(;!x.in_grouping(L,97,249);){if(x.cursor>=x.limit)return x.cursor=e,void(x.in_grouping(L,97,249)&&x.cursor=x.limit)return;x.cursor++}k=x.cursor}function a(){for(;!x.in_grouping(L,97,249);){if(x.cursor>=x.limit)return!1;x.cursor++}for(;!x.out_grouping(L,97,249);){if(x.cursor>=x.limit)return!1;x.cursor++}return!0}function u(){var e=x.cursor;k=x.limit,p=k,g=k,s(),x.cursor=e,a()&&(p=x.cursor,a()&&(g=x.cursor))}function c(){for(var e;;){if(x.bra=x.cursor,!(e=x.find_among(q,3)))break;switch(x.ket=x.cursor,e){case 1:x.slice_from("i");break;case 2:x.slice_from("u");break;case 3:if(x.cursor>=x.limit)return;x.cursor++}}}function w(){return k<=x.cursor}function l(){return p<=x.cursor}function m(){return g<=x.cursor}function f(){var e;if(x.ket=x.cursor,x.find_among_b(C,37)&&(x.bra=x.cursor,(e=x.find_among_b(z,5))&&w()))switch(e){case 1:x.slice_del();break;case 2:x.slice_from("e")}}function v(){var e;if(x.ket=x.cursor,!(e=x.find_among_b(S,51)))return!1;switch(x.bra=x.cursor,e){case 1:if(!m())return!1;x.slice_del();break;case 2:if(!m())return!1;x.slice_del(),x.ket=x.cursor,x.eq_s_b(2,"ic")&&(x.bra=x.cursor,m()&&x.slice_del());break;case 3:if(!m())return!1;x.slice_from("log");break;case 4:if(!m())return!1;x.slice_from("u");break;case 5:if(!m())return!1;x.slice_from("ente");break;case 6:if(!w())return!1;x.slice_del();break;case 7:if(!l())return!1;x.slice_del(),x.ket=x.cursor,e=x.find_among_b(P,4),e&&(x.bra=x.cursor,m()&&(x.slice_del(),1==e&&(x.ket=x.cursor,x.eq_s_b(2,"at")&&(x.bra=x.cursor,m()&&x.slice_del()))));break;case 8:if(!m())return!1;x.slice_del(),x.ket=x.cursor,e=x.find_among_b(F,3),e&&(x.bra=x.cursor,1==e&&m()&&x.slice_del());break;case 9:if(!m())return!1;x.slice_del(),x.ket=x.cursor,x.eq_s_b(2,"at")&&(x.bra=x.cursor,m()&&(x.slice_del(),x.ket=x.cursor,x.eq_s_b(2,"ic")&&(x.bra=x.cursor,m()&&x.slice_del())))}return!0}function b(){var e,r;x.cursor>=k&&(r=x.limit_backward,x.limit_backward=k,x.ket=x.cursor,e=x.find_among_b(W,87),e&&(x.bra=x.cursor,1==e&&x.slice_del()),x.limit_backward=r)}function d(){var e=x.limit-x.cursor;if(x.ket=x.cursor,x.in_grouping_b(y,97,242)&&(x.bra=x.cursor,w()&&(x.slice_del(),x.ket=x.cursor,x.eq_s_b(1,"i")&&(x.bra=x.cursor,w()))))return void x.slice_del();x.cursor=x.limit-e}function _(){d(),x.ket=x.cursor,x.eq_s_b(1,"h")&&(x.bra=x.cursor,x.in_grouping_b(U,99,103)&&w()&&x.slice_del())}var g,p,k,h=[new r("",-1,7),new r("qu",0,6),new r("á",0,1),new r("é",0,2),new r("í",0,3),new r("ó",0,4),new r("ú",0,5)],q=[new r("",-1,3),new r("I",0,1),new r("U",0,2)],C=[new r("la",-1,-1),new r("cela",0,-1),new r("gliela",0,-1),new r("mela",0,-1),new r("tela",0,-1),new r("vela",0,-1),new r("le",-1,-1),new r("cele",6,-1),new r("gliele",6,-1),new r("mele",6,-1),new r("tele",6,-1),new r("vele",6,-1),new r("ne",-1,-1),new r("cene",12,-1),new r("gliene",12,-1),new r("mene",12,-1),new r("sene",12,-1),new r("tene",12,-1),new r("vene",12,-1),new r("ci",-1,-1),new r("li",-1,-1),new r("celi",20,-1),new r("glieli",20,-1),new r("meli",20,-1),new r("teli",20,-1),new r("veli",20,-1),new r("gli",20,-1),new r("mi",-1,-1),new r("si",-1,-1),new r("ti",-1,-1),new r("vi",-1,-1),new r("lo",-1,-1),new r("celo",31,-1),new r("glielo",31,-1),new r("melo",31,-1),new r("telo",31,-1),new r("velo",31,-1)],z=[new r("ando",-1,1),new r("endo",-1,1),new r("ar",-1,2),new r("er",-1,2),new r("ir",-1,2)],P=[new r("ic",-1,-1),new r("abil",-1,-1),new r("os",-1,-1),new r("iv",-1,1)],F=[new r("ic",-1,1),new r("abil",-1,1),new r("iv",-1,1)],S=[new r("ica",-1,1),new r("logia",-1,3),new r("osa",-1,1),new r("ista",-1,1),new r("iva",-1,9),new r("anza",-1,1),new r("enza",-1,5),new r("ice",-1,1),new r("atrice",7,1),new r("iche",-1,1),new r("logie",-1,3),new r("abile",-1,1),new r("ibile",-1,1),new r("usione",-1,4),new r("azione",-1,2),new r("uzione",-1,4),new r("atore",-1,2),new r("ose",-1,1),new r("ante",-1,1),new r("mente",-1,1),new r("amente",19,7),new r("iste",-1,1),new r("ive",-1,9),new r("anze",-1,1),new r("enze",-1,5),new r("ici",-1,1),new r("atrici",25,1),new r("ichi",-1,1),new r("abili",-1,1),new r("ibili",-1,1),new r("ismi",-1,1),new r("usioni",-1,4),new r("azioni",-1,2),new r("uzioni",-1,4),new r("atori",-1,2),new r("osi",-1,1),new r("anti",-1,1),new r("amenti",-1,6),new r("imenti",-1,6),new r("isti",-1,1),new r("ivi",-1,9),new r("ico",-1,1),new r("ismo",-1,1),new r("oso",-1,1),new r("amento",-1,6),new r("imento",-1,6),new r("ivo",-1,9),new r("ità",-1,8),new r("istà",-1,1),new r("istè",-1,1),new r("istì",-1,1)],W=[new r("isca",-1,1),new r("enda",-1,1),new r("ata",-1,1),new r("ita",-1,1),new r("uta",-1,1),new r("ava",-1,1),new r("eva",-1,1),new r("iva",-1,1),new r("erebbe",-1,1),new r("irebbe",-1,1),new r("isce",-1,1),new r("ende",-1,1),new r("are",-1,1),new r("ere",-1,1),new r("ire",-1,1),new r("asse",-1,1),new r("ate",-1,1),new r("avate",16,1),new r("evate",16,1),new r("ivate",16,1),new r("ete",-1,1),new r("erete",20,1),new r("irete",20,1),new r("ite",-1,1),new r("ereste",-1,1),new r("ireste",-1,1),new r("ute",-1,1),new r("erai",-1,1),new r("irai",-1,1),new r("isci",-1,1),new r("endi",-1,1),new r("erei",-1,1),new r("irei",-1,1),new r("assi",-1,1),new r("ati",-1,1),new r("iti",-1,1),new r("eresti",-1,1),new r("iresti",-1,1),new r("uti",-1,1),new r("avi",-1,1),new r("evi",-1,1),new r("ivi",-1,1),new r("isco",-1,1),new r("ando",-1,1),new r("endo",-1,1),new r("Yamo",-1,1),new r("iamo",-1,1),new r("avamo",-1,1),new r("evamo",-1,1),new r("ivamo",-1,1),new r("eremo",-1,1),new r("iremo",-1,1),new r("assimo",-1,1),new r("ammo",-1,1),new r("emmo",-1,1),new r("eremmo",54,1),new r("iremmo",54,1),new r("immo",-1,1),new r("ano",-1,1),new r("iscano",58,1),new r("avano",58,1),new r("evano",58,1),new r("ivano",58,1),new r("eranno",-1,1),new r("iranno",-1,1),new r("ono",-1,1),new r("iscono",65,1),new r("arono",65,1),new r("erono",65,1),new r("irono",65,1),new r("erebbero",-1,1),new r("irebbero",-1,1),new r("assero",-1,1),new r("essero",-1,1),new r("issero",-1,1),new r("ato",-1,1),new r("ito",-1,1),new r("uto",-1,1),new r("avo",-1,1),new r("evo",-1,1),new r("ivo",-1,1),new r("ar",-1,1),new r("ir",-1,1),new r("erà",-1,1),new r("irà",-1,1),new r("erò",-1,1),new r("irò",-1,1)],L=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,128,128,8,2,1],y=[17,65,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,8,2],U=[17],x=new n;this.setCurrent=function(e){x.setCurrent(e)},this.getCurrent=function(){return x.getCurrent()},this.stem=function(){var e=x.cursor;return i(),x.cursor=e,u(),x.limit_backward=e,x.cursor=x.limit,f(),x.cursor=x.limit,v()||(x.cursor=x.limit,b()),x.cursor=x.limit,_(),x.cursor=x.limit_backward,c(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.it.stemmer,"stemmer-it"),e.it.stopWordFilter=e.generateStopWordFilter("a abbia abbiamo abbiano abbiate ad agl agli ai al all alla alle allo anche avemmo avendo avesse avessero avessi avessimo aveste avesti avete aveva avevamo avevano avevate avevi avevo avrai avranno avrebbe avrebbero avrei avremmo avremo avreste avresti avrete avrà avrò avuta avute avuti avuto c che chi ci coi col come con contro cui da dagl dagli dai dal dall dalla dalle dallo degl degli dei del dell della delle dello di dov dove e ebbe ebbero ebbi ed era erano eravamo eravate eri ero essendo faccia facciamo facciano facciate faccio facemmo facendo facesse facessero facessi facessimo faceste facesti faceva facevamo facevano facevate facevi facevo fai fanno farai faranno farebbe farebbero farei faremmo faremo fareste faresti farete farà farò fece fecero feci fosse fossero fossi fossimo foste fosti fu fui fummo furono gli ha hai hanno ho i il in io l la le lei li lo loro lui ma mi mia mie miei mio ne negl negli nei nel nell nella nelle nello noi non nostra nostre nostri nostro o per perché più quale quanta quante quanti quanto quella quelle quelli quello questa queste questi questo sarai saranno sarebbe sarebbero sarei saremmo saremo sareste saresti sarete sarà sarò se sei si sia siamo siano siate siete sono sta stai stando stanno starai staranno starebbe starebbero starei staremmo staremo stareste staresti starete starà starò stava stavamo stavano stavate stavi stavo stemmo stesse stessero stessi stessimo steste stesti stette stettero stetti stia stiamo stiano stiate sto su sua sue sugl sugli sui sul sull sulla sulle sullo suo suoi ti tra tu tua tue tuo tuoi tutti tutto un una uno vi voi vostra vostre vostri vostro è".split(" ")),e.Pipeline.registerFunction(e.it.stopWordFilter,"stopWordFilter-it")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.ja.min.js b/assets/javascripts/lunr/min/lunr.ja.min.js new file mode 100644 index 00000000..5f254ebe --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.ja.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r="2"==e.version[0];e.ja=function(){this.pipeline.reset(),this.pipeline.add(e.ja.trimmer,e.ja.stopWordFilter,e.ja.stemmer),r?this.tokenizer=e.ja.tokenizer:(e.tokenizer&&(e.tokenizer=e.ja.tokenizer),this.tokenizerFn&&(this.tokenizerFn=e.ja.tokenizer))};var t=new e.TinySegmenter;e.ja.tokenizer=function(i){var n,o,s,p,a,u,m,l,c,f;if(!arguments.length||null==i||void 0==i)return[];if(Array.isArray(i))return i.map(function(t){return r?new e.Token(t.toLowerCase()):t.toLowerCase()});for(o=i.toString().toLowerCase().replace(/^\s+/,""),n=o.length-1;n>=0;n--)if(/\S/.test(o.charAt(n))){o=o.substring(0,n+1);break}for(a=[],s=o.length,c=0,l=0;c<=s;c++)if(u=o.charAt(c),m=c-l,u.match(/\s/)||c==s){if(m>0)for(p=t.segment(o.slice(l,c)).filter(function(e){return!!e}),f=l,n=0;n=C.limit)break;C.cursor++;continue}break}for(C.cursor=o,C.bra=o,C.eq_s(1,"y")?(C.ket=C.cursor,C.slice_from("Y")):C.cursor=o;;)if(e=C.cursor,C.in_grouping(q,97,232)){if(i=C.cursor,C.bra=i,C.eq_s(1,"i"))C.ket=C.cursor,C.in_grouping(q,97,232)&&(C.slice_from("I"),C.cursor=e);else if(C.cursor=i,C.eq_s(1,"y"))C.ket=C.cursor,C.slice_from("Y"),C.cursor=e;else if(n(e))break}else if(n(e))break}function n(r){return C.cursor=r,r>=C.limit||(C.cursor++,!1)}function o(){_=C.limit,d=_,t()||(_=C.cursor,_<3&&(_=3),t()||(d=C.cursor))}function t(){for(;!C.in_grouping(q,97,232);){if(C.cursor>=C.limit)return!0;C.cursor++}for(;!C.out_grouping(q,97,232);){if(C.cursor>=C.limit)return!0;C.cursor++}return!1}function s(){for(var r;;)if(C.bra=C.cursor,r=C.find_among(p,3))switch(C.ket=C.cursor,r){case 1:C.slice_from("y");break;case 2:C.slice_from("i");break;case 3:if(C.cursor>=C.limit)return;C.cursor++}}function u(){return _<=C.cursor}function c(){return d<=C.cursor}function a(){var r=C.limit-C.cursor;C.find_among_b(g,3)&&(C.cursor=C.limit-r,C.ket=C.cursor,C.cursor>C.limit_backward&&(C.cursor--,C.bra=C.cursor,C.slice_del()))}function l(){var r;w=!1,C.ket=C.cursor,C.eq_s_b(1,"e")&&(C.bra=C.cursor,u()&&(r=C.limit-C.cursor,C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-r,C.slice_del(),w=!0,a())))}function m(){var r;u()&&(r=C.limit-C.cursor,C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-r,C.eq_s_b(3,"gem")||(C.cursor=C.limit-r,C.slice_del(),a())))}function f(){var r,e,i,n,o,t,s=C.limit-C.cursor;if(C.ket=C.cursor,r=C.find_among_b(h,5))switch(C.bra=C.cursor,r){case 1:u()&&C.slice_from("heid");break;case 2:m();break;case 3:u()&&C.out_grouping_b(j,97,232)&&C.slice_del()}if(C.cursor=C.limit-s,l(),C.cursor=C.limit-s,C.ket=C.cursor,C.eq_s_b(4,"heid")&&(C.bra=C.cursor,c()&&(e=C.limit-C.cursor,C.eq_s_b(1,"c")||(C.cursor=C.limit-e,C.slice_del(),C.ket=C.cursor,C.eq_s_b(2,"en")&&(C.bra=C.cursor,m())))),C.cursor=C.limit-s,C.ket=C.cursor,r=C.find_among_b(k,6))switch(C.bra=C.cursor,r){case 1:if(c()){if(C.slice_del(),i=C.limit-C.cursor,C.ket=C.cursor,C.eq_s_b(2,"ig")&&(C.bra=C.cursor,c()&&(n=C.limit-C.cursor,!C.eq_s_b(1,"e")))){C.cursor=C.limit-n,C.slice_del();break}C.cursor=C.limit-i,a()}break;case 2:c()&&(o=C.limit-C.cursor,C.eq_s_b(1,"e")||(C.cursor=C.limit-o,C.slice_del()));break;case 3:c()&&(C.slice_del(),l());break;case 4:c()&&C.slice_del();break;case 5:c()&&w&&C.slice_del()}C.cursor=C.limit-s,C.out_grouping_b(z,73,232)&&(t=C.limit-C.cursor,C.find_among_b(v,4)&&C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-t,C.ket=C.cursor,C.cursor>C.limit_backward&&(C.cursor--,C.bra=C.cursor,C.slice_del())))}var d,_,w,b=[new e("",-1,6),new e("á",0,1),new e("ä",0,1),new e("é",0,2),new e("ë",0,2),new e("í",0,3),new e("ï",0,3),new e("ó",0,4),new e("ö",0,4),new e("ú",0,5),new e("ü",0,5)],p=[new e("",-1,3),new e("I",0,2),new e("Y",0,1)],g=[new e("dd",-1,-1),new e("kk",-1,-1),new e("tt",-1,-1)],h=[new e("ene",-1,2),new e("se",-1,3),new e("en",-1,2),new e("heden",2,1),new e("s",-1,3)],k=[new e("end",-1,1),new e("ig",-1,2),new e("ing",-1,1),new e("lijk",-1,3),new e("baar",-1,4),new e("bar",-1,5)],v=[new e("aa",-1,-1),new e("ee",-1,-1),new e("oo",-1,-1),new e("uu",-1,-1)],q=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],z=[1,0,0,17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],j=[17,67,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],C=new i;this.setCurrent=function(r){C.setCurrent(r)},this.getCurrent=function(){return C.getCurrent()},this.stem=function(){var e=C.cursor;return r(),C.cursor=e,o(),C.limit_backward=e,C.cursor=C.limit,f(),C.cursor=C.limit_backward,s(),!0}};return function(r){return"function"==typeof r.update?r.update(function(r){return n.setCurrent(r),n.stem(),n.getCurrent()}):(n.setCurrent(r),n.stem(),n.getCurrent())}}(),r.Pipeline.registerFunction(r.nl.stemmer,"stemmer-nl"),r.nl.stopWordFilter=r.generateStopWordFilter(" aan al alles als altijd andere ben bij daar dan dat de der deze die dit doch doen door dus een eens en er ge geen geweest haar had heb hebben heeft hem het hier hij hoe hun iemand iets ik in is ja je kan kon kunnen maar me meer men met mij mijn moet na naar niet niets nog nu of om omdat onder ons ook op over reeds te tegen toch toen tot u uit uw van veel voor want waren was wat werd wezen wie wil worden wordt zal ze zelf zich zij zijn zo zonder zou".split(" ")),r.Pipeline.registerFunction(r.nl.stopWordFilter,"stopWordFilter-nl")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.no.min.js b/assets/javascripts/lunr/min/lunr.no.min.js new file mode 100644 index 00000000..92bc7e4e --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.no.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Norwegian` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.no=function(){this.pipeline.reset(),this.pipeline.add(e.no.trimmer,e.no.stopWordFilter,e.no.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.no.stemmer))},e.no.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.no.trimmer=e.trimmerSupport.generateTrimmer(e.no.wordCharacters),e.Pipeline.registerFunction(e.no.trimmer,"trimmer-no"),e.no.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,i=new function(){function e(){var e,r=w.cursor+3;if(a=w.limit,0<=r||r<=w.limit){for(s=r;;){if(e=w.cursor,w.in_grouping(d,97,248)){w.cursor=e;break}if(e>=w.limit)return;w.cursor=e+1}for(;!w.out_grouping(d,97,248);){if(w.cursor>=w.limit)return;w.cursor++}a=w.cursor,a=a&&(r=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,e=w.find_among_b(m,29),w.limit_backward=r,e))switch(w.bra=w.cursor,e){case 1:w.slice_del();break;case 2:n=w.limit-w.cursor,w.in_grouping_b(c,98,122)?w.slice_del():(w.cursor=w.limit-n,w.eq_s_b(1,"k")&&w.out_grouping_b(d,97,248)&&w.slice_del());break;case 3:w.slice_from("er")}}function t(){var e,r=w.limit-w.cursor;w.cursor>=a&&(e=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,w.find_among_b(u,2)?(w.bra=w.cursor,w.limit_backward=e,w.cursor=w.limit-r,w.cursor>w.limit_backward&&(w.cursor--,w.bra=w.cursor,w.slice_del())):w.limit_backward=e)}function o(){var e,r;w.cursor>=a&&(r=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,e=w.find_among_b(l,11),e?(w.bra=w.cursor,w.limit_backward=r,1==e&&w.slice_del()):w.limit_backward=r)}var s,a,m=[new r("a",-1,1),new r("e",-1,1),new r("ede",1,1),new r("ande",1,1),new r("ende",1,1),new r("ane",1,1),new r("ene",1,1),new r("hetene",6,1),new r("erte",1,3),new r("en",-1,1),new r("heten",9,1),new r("ar",-1,1),new r("er",-1,1),new r("heter",12,1),new r("s",-1,2),new r("as",14,1),new r("es",14,1),new r("edes",16,1),new r("endes",16,1),new r("enes",16,1),new r("hetenes",19,1),new r("ens",14,1),new r("hetens",21,1),new r("ers",14,1),new r("ets",14,1),new r("et",-1,1),new r("het",25,1),new r("ert",-1,3),new r("ast",-1,1)],u=[new r("dt",-1,-1),new r("vt",-1,-1)],l=[new r("leg",-1,1),new r("eleg",0,1),new r("ig",-1,1),new r("eig",2,1),new r("lig",2,1),new r("elig",4,1),new r("els",-1,1),new r("lov",-1,1),new r("elov",7,1),new r("slov",7,1),new r("hetslov",9,1)],d=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],c=[119,125,149,1],w=new n;this.setCurrent=function(e){w.setCurrent(e)},this.getCurrent=function(){return w.getCurrent()},this.stem=function(){var r=w.cursor;return e(),w.limit_backward=r,w.cursor=w.limit,i(),w.cursor=w.limit,t(),w.cursor=w.limit,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.no.stemmer,"stemmer-no"),e.no.stopWordFilter=e.generateStopWordFilter("alle at av bare begge ble blei bli blir blitt både båe da de deg dei deim deira deires dem den denne der dere deres det dette di din disse ditt du dykk dykkar då eg ein eit eitt eller elles en enn er et ett etter for fordi fra før ha hadde han hans har hennar henne hennes her hjå ho hoe honom hoss hossen hun hva hvem hver hvilke hvilken hvis hvor hvordan hvorfor i ikke ikkje ikkje ingen ingi inkje inn inni ja jeg kan kom korleis korso kun kunne kva kvar kvarhelst kven kvi kvifor man mange me med medan meg meget mellom men mi min mine mitt mot mykje ned no noe noen noka noko nokon nokor nokre nå når og også om opp oss over på samme seg selv si si sia sidan siden sin sine sitt sjøl skal skulle slik so som som somme somt så sånn til um upp ut uten var vart varte ved vere verte vi vil ville vore vors vort vår være være vært å".split(" ")),e.Pipeline.registerFunction(e.no.stopWordFilter,"stopWordFilter-no")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.pt.min.js b/assets/javascripts/lunr/min/lunr.pt.min.js new file mode 100644 index 00000000..6c16996d --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.pt.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Portuguese` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.pt=function(){this.pipeline.reset(),this.pipeline.add(e.pt.trimmer,e.pt.stopWordFilter,e.pt.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.pt.stemmer))},e.pt.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.pt.trimmer=e.trimmerSupport.generateTrimmer(e.pt.wordCharacters),e.Pipeline.registerFunction(e.pt.trimmer,"trimmer-pt"),e.pt.stemmer=function(){var r=e.stemmerSupport.Among,s=e.stemmerSupport.SnowballProgram,n=new function(){function e(){for(var e;;){if(z.bra=z.cursor,e=z.find_among(k,3))switch(z.ket=z.cursor,e){case 1:z.slice_from("a~");continue;case 2:z.slice_from("o~");continue;case 3:if(z.cursor>=z.limit)break;z.cursor++;continue}break}}function n(){if(z.out_grouping(y,97,250)){for(;!z.in_grouping(y,97,250);){if(z.cursor>=z.limit)return!0;z.cursor++}return!1}return!0}function i(){if(z.in_grouping(y,97,250))for(;!z.out_grouping(y,97,250);){if(z.cursor>=z.limit)return!1;z.cursor++}return g=z.cursor,!0}function o(){var e,r,s=z.cursor;if(z.in_grouping(y,97,250))if(e=z.cursor,n()){if(z.cursor=e,i())return}else g=z.cursor;if(z.cursor=s,z.out_grouping(y,97,250)){if(r=z.cursor,n()){if(z.cursor=r,!z.in_grouping(y,97,250)||z.cursor>=z.limit)return;z.cursor++}g=z.cursor}}function t(){for(;!z.in_grouping(y,97,250);){if(z.cursor>=z.limit)return!1;z.cursor++}for(;!z.out_grouping(y,97,250);){if(z.cursor>=z.limit)return!1;z.cursor++}return!0}function a(){var e=z.cursor;g=z.limit,b=g,h=g,o(),z.cursor=e,t()&&(b=z.cursor,t()&&(h=z.cursor))}function u(){for(var e;;){if(z.bra=z.cursor,e=z.find_among(q,3))switch(z.ket=z.cursor,e){case 1:z.slice_from("ã");continue;case 2:z.slice_from("õ");continue;case 3:if(z.cursor>=z.limit)break;z.cursor++;continue}break}}function w(){return g<=z.cursor}function m(){return b<=z.cursor}function c(){return h<=z.cursor}function l(){var e;if(z.ket=z.cursor,!(e=z.find_among_b(F,45)))return!1;switch(z.bra=z.cursor,e){case 1:if(!c())return!1;z.slice_del();break;case 2:if(!c())return!1;z.slice_from("log");break;case 3:if(!c())return!1;z.slice_from("u");break;case 4:if(!c())return!1;z.slice_from("ente");break;case 5:if(!m())return!1;z.slice_del(),z.ket=z.cursor,e=z.find_among_b(j,4),e&&(z.bra=z.cursor,c()&&(z.slice_del(),1==e&&(z.ket=z.cursor,z.eq_s_b(2,"at")&&(z.bra=z.cursor,c()&&z.slice_del()))));break;case 6:if(!c())return!1;z.slice_del(),z.ket=z.cursor,e=z.find_among_b(C,3),e&&(z.bra=z.cursor,1==e&&c()&&z.slice_del());break;case 7:if(!c())return!1;z.slice_del(),z.ket=z.cursor,e=z.find_among_b(P,3),e&&(z.bra=z.cursor,1==e&&c()&&z.slice_del());break;case 8:if(!c())return!1;z.slice_del(),z.ket=z.cursor,z.eq_s_b(2,"at")&&(z.bra=z.cursor,c()&&z.slice_del());break;case 9:if(!w()||!z.eq_s_b(1,"e"))return!1;z.slice_from("ir")}return!0}function f(){var e,r;if(z.cursor>=g){if(r=z.limit_backward,z.limit_backward=g,z.ket=z.cursor,e=z.find_among_b(S,120))return z.bra=z.cursor,1==e&&z.slice_del(),z.limit_backward=r,!0;z.limit_backward=r}return!1}function d(){var e;z.ket=z.cursor,(e=z.find_among_b(W,7))&&(z.bra=z.cursor,1==e&&w()&&z.slice_del())}function v(e,r){if(z.eq_s_b(1,e)){z.bra=z.cursor;var s=z.limit-z.cursor;if(z.eq_s_b(1,r))return z.cursor=z.limit-s,w()&&z.slice_del(),!1}return!0}function p(){var e;if(z.ket=z.cursor,e=z.find_among_b(L,4))switch(z.bra=z.cursor,e){case 1:w()&&(z.slice_del(),z.ket=z.cursor,z.limit-z.cursor,v("u","g")&&v("i","c"));break;case 2:z.slice_from("c")}}function _(){if(!l()&&(z.cursor=z.limit,!f()))return z.cursor=z.limit,void d();z.cursor=z.limit,z.ket=z.cursor,z.eq_s_b(1,"i")&&(z.bra=z.cursor,z.eq_s_b(1,"c")&&(z.cursor=z.limit,w()&&z.slice_del()))}var h,b,g,k=[new r("",-1,3),new r("ã",0,1),new r("õ",0,2)],q=[new r("",-1,3),new r("a~",0,1),new r("o~",0,2)],j=[new r("ic",-1,-1),new r("ad",-1,-1),new r("os",-1,-1),new r("iv",-1,1)],C=[new r("ante",-1,1),new r("avel",-1,1),new r("ível",-1,1)],P=[new r("ic",-1,1),new r("abil",-1,1),new r("iv",-1,1)],F=[new r("ica",-1,1),new r("ância",-1,1),new r("ência",-1,4),new r("ira",-1,9),new r("adora",-1,1),new r("osa",-1,1),new r("ista",-1,1),new r("iva",-1,8),new r("eza",-1,1),new r("logía",-1,2),new r("idade",-1,7),new r("ante",-1,1),new r("mente",-1,6),new r("amente",12,5),new r("ável",-1,1),new r("ível",-1,1),new r("ución",-1,3),new r("ico",-1,1),new r("ismo",-1,1),new r("oso",-1,1),new r("amento",-1,1),new r("imento",-1,1),new r("ivo",-1,8),new r("aça~o",-1,1),new r("ador",-1,1),new r("icas",-1,1),new r("ências",-1,4),new r("iras",-1,9),new r("adoras",-1,1),new r("osas",-1,1),new r("istas",-1,1),new r("ivas",-1,8),new r("ezas",-1,1),new r("logías",-1,2),new r("idades",-1,7),new r("uciones",-1,3),new r("adores",-1,1),new r("antes",-1,1),new r("aço~es",-1,1),new r("icos",-1,1),new r("ismos",-1,1),new r("osos",-1,1),new r("amentos",-1,1),new r("imentos",-1,1),new r("ivos",-1,8)],S=[new r("ada",-1,1),new r("ida",-1,1),new r("ia",-1,1),new r("aria",2,1),new r("eria",2,1),new r("iria",2,1),new r("ara",-1,1),new r("era",-1,1),new r("ira",-1,1),new r("ava",-1,1),new r("asse",-1,1),new r("esse",-1,1),new r("isse",-1,1),new r("aste",-1,1),new r("este",-1,1),new r("iste",-1,1),new r("ei",-1,1),new r("arei",16,1),new r("erei",16,1),new r("irei",16,1),new r("am",-1,1),new r("iam",20,1),new r("ariam",21,1),new r("eriam",21,1),new r("iriam",21,1),new r("aram",20,1),new r("eram",20,1),new r("iram",20,1),new r("avam",20,1),new r("em",-1,1),new r("arem",29,1),new r("erem",29,1),new r("irem",29,1),new r("assem",29,1),new r("essem",29,1),new r("issem",29,1),new r("ado",-1,1),new r("ido",-1,1),new r("ando",-1,1),new r("endo",-1,1),new r("indo",-1,1),new r("ara~o",-1,1),new r("era~o",-1,1),new r("ira~o",-1,1),new r("ar",-1,1),new r("er",-1,1),new r("ir",-1,1),new r("as",-1,1),new r("adas",47,1),new r("idas",47,1),new r("ias",47,1),new r("arias",50,1),new r("erias",50,1),new r("irias",50,1),new r("aras",47,1),new r("eras",47,1),new r("iras",47,1),new r("avas",47,1),new r("es",-1,1),new r("ardes",58,1),new r("erdes",58,1),new r("irdes",58,1),new r("ares",58,1),new r("eres",58,1),new r("ires",58,1),new r("asses",58,1),new r("esses",58,1),new r("isses",58,1),new r("astes",58,1),new r("estes",58,1),new r("istes",58,1),new r("is",-1,1),new r("ais",71,1),new r("eis",71,1),new r("areis",73,1),new r("ereis",73,1),new r("ireis",73,1),new r("áreis",73,1),new r("éreis",73,1),new r("íreis",73,1),new r("ásseis",73,1),new r("ésseis",73,1),new r("ísseis",73,1),new r("áveis",73,1),new r("íeis",73,1),new r("aríeis",84,1),new r("eríeis",84,1),new r("iríeis",84,1),new r("ados",-1,1),new r("idos",-1,1),new r("amos",-1,1),new r("áramos",90,1),new r("éramos",90,1),new r("íramos",90,1),new r("ávamos",90,1),new r("íamos",90,1),new r("aríamos",95,1),new r("eríamos",95,1),new r("iríamos",95,1),new r("emos",-1,1),new r("aremos",99,1),new r("eremos",99,1),new r("iremos",99,1),new r("ássemos",99,1),new r("êssemos",99,1),new r("íssemos",99,1),new r("imos",-1,1),new r("armos",-1,1),new r("ermos",-1,1),new r("irmos",-1,1),new r("ámos",-1,1),new r("arás",-1,1),new r("erás",-1,1),new r("irás",-1,1),new r("eu",-1,1),new r("iu",-1,1),new r("ou",-1,1),new r("ará",-1,1),new r("erá",-1,1),new r("irá",-1,1)],W=[new r("a",-1,1),new r("i",-1,1),new r("o",-1,1),new r("os",-1,1),new r("á",-1,1),new r("í",-1,1),new r("ó",-1,1)],L=[new r("e",-1,1),new r("ç",-1,2),new r("é",-1,1),new r("ê",-1,1)],y=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,3,19,12,2],z=new s;this.setCurrent=function(e){z.setCurrent(e)},this.getCurrent=function(){return z.getCurrent()},this.stem=function(){var r=z.cursor;return e(),z.cursor=r,a(),z.limit_backward=r,z.cursor=z.limit,_(),z.cursor=z.limit,p(),z.cursor=z.limit_backward,u(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.pt.stemmer,"stemmer-pt"),e.pt.stopWordFilter=e.generateStopWordFilter("a ao aos aquela aquelas aquele aqueles aquilo as até com como da das de dela delas dele deles depois do dos e ela elas ele eles em entre era eram essa essas esse esses esta estamos estas estava estavam este esteja estejam estejamos estes esteve estive estivemos estiver estivera estiveram estiverem estivermos estivesse estivessem estivéramos estivéssemos estou está estávamos estão eu foi fomos for fora foram forem formos fosse fossem fui fôramos fôssemos haja hajam hajamos havemos hei houve houvemos houver houvera houveram houverei houverem houveremos houveria houveriam houvermos houverá houverão houveríamos houvesse houvessem houvéramos houvéssemos há hão isso isto já lhe lhes mais mas me mesmo meu meus minha minhas muito na nas nem no nos nossa nossas nosso nossos num numa não nós o os ou para pela pelas pelo pelos por qual quando que quem se seja sejam sejamos sem serei seremos seria seriam será serão seríamos seu seus somos sou sua suas são só também te tem temos tenha tenham tenhamos tenho terei teremos teria teriam terá terão teríamos teu teus teve tinha tinham tive tivemos tiver tivera tiveram tiverem tivermos tivesse tivessem tivéramos tivéssemos tu tua tuas tém tínhamos um uma você vocês vos à às éramos".split(" ")),e.Pipeline.registerFunction(e.pt.stopWordFilter,"stopWordFilter-pt")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.ro.min.js b/assets/javascripts/lunr/min/lunr.ro.min.js new file mode 100644 index 00000000..72771401 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.ro.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Romanian` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,i){"function"==typeof define&&define.amd?define(i):"object"==typeof exports?module.exports=i():i()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.ro=function(){this.pipeline.reset(),this.pipeline.add(e.ro.trimmer,e.ro.stopWordFilter,e.ro.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ro.stemmer))},e.ro.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.ro.trimmer=e.trimmerSupport.generateTrimmer(e.ro.wordCharacters),e.Pipeline.registerFunction(e.ro.trimmer,"trimmer-ro"),e.ro.stemmer=function(){var i=e.stemmerSupport.Among,r=e.stemmerSupport.SnowballProgram,n=new function(){function e(e,i){L.eq_s(1,e)&&(L.ket=L.cursor,L.in_grouping(W,97,259)&&L.slice_from(i))}function n(){for(var i,r;;){if(i=L.cursor,L.in_grouping(W,97,259)&&(r=L.cursor,L.bra=r,e("u","U"),L.cursor=r,e("i","I")),L.cursor=i,L.cursor>=L.limit)break;L.cursor++}}function t(){if(L.out_grouping(W,97,259)){for(;!L.in_grouping(W,97,259);){if(L.cursor>=L.limit)return!0;L.cursor++}return!1}return!0}function a(){if(L.in_grouping(W,97,259))for(;!L.out_grouping(W,97,259);){if(L.cursor>=L.limit)return!0;L.cursor++}return!1}function o(){var e,i,r=L.cursor;if(L.in_grouping(W,97,259)){if(e=L.cursor,!t())return void(h=L.cursor);if(L.cursor=e,!a())return void(h=L.cursor)}L.cursor=r,L.out_grouping(W,97,259)&&(i=L.cursor,t()&&(L.cursor=i,L.in_grouping(W,97,259)&&L.cursor=L.limit)return!1;L.cursor++}for(;!L.out_grouping(W,97,259);){if(L.cursor>=L.limit)return!1;L.cursor++}return!0}function c(){var e=L.cursor;h=L.limit,k=h,g=h,o(),L.cursor=e,u()&&(k=L.cursor,u()&&(g=L.cursor))}function s(){for(var e;;){if(L.bra=L.cursor,e=L.find_among(z,3))switch(L.ket=L.cursor,e){case 1:L.slice_from("i");continue;case 2:L.slice_from("u");continue;case 3:if(L.cursor>=L.limit)break;L.cursor++;continue}break}}function w(){return h<=L.cursor}function m(){return k<=L.cursor}function l(){return g<=L.cursor}function f(){var e,i;if(L.ket=L.cursor,(e=L.find_among_b(C,16))&&(L.bra=L.cursor,m()))switch(e){case 1:L.slice_del();break;case 2:L.slice_from("a");break;case 3:L.slice_from("e");break;case 4:L.slice_from("i");break;case 5:i=L.limit-L.cursor,L.eq_s_b(2,"ab")||(L.cursor=L.limit-i,L.slice_from("i"));break;case 6:L.slice_from("at");break;case 7:L.slice_from("aţi")}}function p(){var e,i=L.limit-L.cursor;if(L.ket=L.cursor,(e=L.find_among_b(P,46))&&(L.bra=L.cursor,m())){switch(e){case 1:L.slice_from("abil");break;case 2:L.slice_from("ibil");break;case 3:L.slice_from("iv");break;case 4:L.slice_from("ic");break;case 5:L.slice_from("at");break;case 6:L.slice_from("it")}return _=!0,L.cursor=L.limit-i,!0}return!1}function d(){var e,i;for(_=!1;;)if(i=L.limit-L.cursor,!p()){L.cursor=L.limit-i;break}if(L.ket=L.cursor,(e=L.find_among_b(F,62))&&(L.bra=L.cursor,l())){switch(e){case 1:L.slice_del();break;case 2:L.eq_s_b(1,"ţ")&&(L.bra=L.cursor,L.slice_from("t"));break;case 3:L.slice_from("ist")}_=!0}}function b(){var e,i,r;if(L.cursor>=h){if(i=L.limit_backward,L.limit_backward=h,L.ket=L.cursor,e=L.find_among_b(q,94))switch(L.bra=L.cursor,e){case 1:if(r=L.limit-L.cursor,!L.out_grouping_b(W,97,259)&&(L.cursor=L.limit-r,!L.eq_s_b(1,"u")))break;case 2:L.slice_del()}L.limit_backward=i}}function v(){var e;L.ket=L.cursor,(e=L.find_among_b(S,5))&&(L.bra=L.cursor,w()&&1==e&&L.slice_del())}var _,g,k,h,z=[new i("",-1,3),new i("I",0,1),new i("U",0,2)],C=[new i("ea",-1,3),new i("aţia",-1,7),new i("aua",-1,2),new i("iua",-1,4),new i("aţie",-1,7),new i("ele",-1,3),new i("ile",-1,5),new i("iile",6,4),new i("iei",-1,4),new i("atei",-1,6),new i("ii",-1,4),new i("ului",-1,1),new i("ul",-1,1),new i("elor",-1,3),new i("ilor",-1,4),new i("iilor",14,4)],P=[new i("icala",-1,4),new i("iciva",-1,4),new i("ativa",-1,5),new i("itiva",-1,6),new i("icale",-1,4),new i("aţiune",-1,5),new i("iţiune",-1,6),new i("atoare",-1,5),new i("itoare",-1,6),new i("ătoare",-1,5),new i("icitate",-1,4),new i("abilitate",-1,1),new i("ibilitate",-1,2),new i("ivitate",-1,3),new i("icive",-1,4),new i("ative",-1,5),new i("itive",-1,6),new i("icali",-1,4),new i("atori",-1,5),new i("icatori",18,4),new i("itori",-1,6),new i("ători",-1,5),new i("icitati",-1,4),new i("abilitati",-1,1),new i("ivitati",-1,3),new i("icivi",-1,4),new i("ativi",-1,5),new i("itivi",-1,6),new i("icităi",-1,4),new i("abilităi",-1,1),new i("ivităi",-1,3),new i("icităţi",-1,4),new i("abilităţi",-1,1),new i("ivităţi",-1,3),new i("ical",-1,4),new i("ator",-1,5),new i("icator",35,4),new i("itor",-1,6),new i("ător",-1,5),new i("iciv",-1,4),new i("ativ",-1,5),new i("itiv",-1,6),new i("icală",-1,4),new i("icivă",-1,4),new i("ativă",-1,5),new i("itivă",-1,6)],F=[new i("ica",-1,1),new i("abila",-1,1),new i("ibila",-1,1),new i("oasa",-1,1),new i("ata",-1,1),new i("ita",-1,1),new i("anta",-1,1),new i("ista",-1,3),new i("uta",-1,1),new i("iva",-1,1),new i("ic",-1,1),new i("ice",-1,1),new i("abile",-1,1),new i("ibile",-1,1),new i("isme",-1,3),new i("iune",-1,2),new i("oase",-1,1),new i("ate",-1,1),new i("itate",17,1),new i("ite",-1,1),new i("ante",-1,1),new i("iste",-1,3),new i("ute",-1,1),new i("ive",-1,1),new i("ici",-1,1),new i("abili",-1,1),new i("ibili",-1,1),new i("iuni",-1,2),new i("atori",-1,1),new i("osi",-1,1),new i("ati",-1,1),new i("itati",30,1),new i("iti",-1,1),new i("anti",-1,1),new i("isti",-1,3),new i("uti",-1,1),new i("işti",-1,3),new i("ivi",-1,1),new i("ităi",-1,1),new i("oşi",-1,1),new i("ităţi",-1,1),new i("abil",-1,1),new i("ibil",-1,1),new i("ism",-1,3),new i("ator",-1,1),new i("os",-1,1),new i("at",-1,1),new i("it",-1,1),new i("ant",-1,1),new i("ist",-1,3),new i("ut",-1,1),new i("iv",-1,1),new i("ică",-1,1),new i("abilă",-1,1),new i("ibilă",-1,1),new i("oasă",-1,1),new i("ată",-1,1),new i("ită",-1,1),new i("antă",-1,1),new i("istă",-1,3),new i("ută",-1,1),new i("ivă",-1,1)],q=[new i("ea",-1,1),new i("ia",-1,1),new i("esc",-1,1),new i("ăsc",-1,1),new i("ind",-1,1),new i("ând",-1,1),new i("are",-1,1),new i("ere",-1,1),new i("ire",-1,1),new i("âre",-1,1),new i("se",-1,2),new i("ase",10,1),new i("sese",10,2),new i("ise",10,1),new i("use",10,1),new i("âse",10,1),new i("eşte",-1,1),new i("ăşte",-1,1),new i("eze",-1,1),new i("ai",-1,1),new i("eai",19,1),new i("iai",19,1),new i("sei",-1,2),new i("eşti",-1,1),new i("ăşti",-1,1),new i("ui",-1,1),new i("ezi",-1,1),new i("âi",-1,1),new i("aşi",-1,1),new i("seşi",-1,2),new i("aseşi",29,1),new i("seseşi",29,2),new i("iseşi",29,1),new i("useşi",29,1),new i("âseşi",29,1),new i("işi",-1,1),new i("uşi",-1,1),new i("âşi",-1,1),new i("aţi",-1,2),new i("eaţi",38,1),new i("iaţi",38,1),new i("eţi",-1,2),new i("iţi",-1,2),new i("âţi",-1,2),new i("arăţi",-1,1),new i("serăţi",-1,2),new i("aserăţi",45,1),new i("seserăţi",45,2),new i("iserăţi",45,1),new i("userăţi",45,1),new i("âserăţi",45,1),new i("irăţi",-1,1),new i("urăţi",-1,1),new i("ârăţi",-1,1),new i("am",-1,1),new i("eam",54,1),new i("iam",54,1),new i("em",-1,2),new i("asem",57,1),new i("sesem",57,2),new i("isem",57,1),new i("usem",57,1),new i("âsem",57,1),new i("im",-1,2),new i("âm",-1,2),new i("ăm",-1,2),new i("arăm",65,1),new i("serăm",65,2),new i("aserăm",67,1),new i("seserăm",67,2),new i("iserăm",67,1),new i("userăm",67,1),new i("âserăm",67,1),new i("irăm",65,1),new i("urăm",65,1),new i("ârăm",65,1),new i("au",-1,1),new i("eau",76,1),new i("iau",76,1),new i("indu",-1,1),new i("ându",-1,1),new i("ez",-1,1),new i("ească",-1,1),new i("ară",-1,1),new i("seră",-1,2),new i("aseră",84,1),new i("seseră",84,2),new i("iseră",84,1),new i("useră",84,1),new i("âseră",84,1),new i("iră",-1,1),new i("ură",-1,1),new i("âră",-1,1),new i("ează",-1,1)],S=[new i("a",-1,1),new i("e",-1,1),new i("ie",1,1),new i("i",-1,1),new i("ă",-1,1)],W=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,2,32,0,0,4],L=new r;this.setCurrent=function(e){L.setCurrent(e)},this.getCurrent=function(){return L.getCurrent()},this.stem=function(){var e=L.cursor;return n(),L.cursor=e,c(),L.limit_backward=e,L.cursor=L.limit,f(),L.cursor=L.limit,d(),L.cursor=L.limit,_||(L.cursor=L.limit,b(),L.cursor=L.limit),v(),L.cursor=L.limit_backward,s(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.ro.stemmer,"stemmer-ro"),e.ro.stopWordFilter=e.generateStopWordFilter("acea aceasta această aceea acei aceia acel acela acele acelea acest acesta aceste acestea aceşti aceştia acolo acord acum ai aia aibă aici al ale alea altceva altcineva am ar are asemenea asta astea astăzi asupra au avea avem aveţi azi aş aşadar aţi bine bucur bună ca care caut ce cel ceva chiar cinci cine cineva contra cu cum cumva curând curînd când cât câte câtva câţi cînd cît cîte cîtva cîţi că căci cărei căror cărui către da dacă dar datorită dată dau de deci deja deoarece departe deşi din dinaintea dintr- dintre doi doilea două drept după dă ea ei el ele eram este eu eşti face fata fi fie fiecare fii fim fiu fiţi frumos fără graţie halbă iar ieri la le li lor lui lângă lîngă mai mea mei mele mereu meu mi mie mine mult multă mulţi mulţumesc mâine mîine mă ne nevoie nici nicăieri nimeni nimeri nimic nişte noastre noastră noi noroc nostru nouă noştri nu opt ori oricare orice oricine oricum oricând oricât oricînd oricît oriunde patra patru patrulea pe pentru peste pic poate pot prea prima primul prin puţin puţina puţină până pînă rog sa sale sau se spate spre sub sunt suntem sunteţi sută sînt sîntem sînteţi să săi său ta tale te timp tine toate toată tot totuşi toţi trei treia treilea tu tăi tău un una unde undeva unei uneia unele uneori unii unor unora unu unui unuia unul vi voastre voastră voi vostru vouă voştri vreme vreo vreun vă zece zero zi zice îi îl îmi împotriva în înainte înaintea încotro încât încît între întrucât întrucît îţi ăla ălea ăsta ăstea ăştia şapte şase şi ştiu ţi ţie".split(" ")),e.Pipeline.registerFunction(e.ro.stopWordFilter,"stopWordFilter-ro")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.ru.min.js b/assets/javascripts/lunr/min/lunr.ru.min.js new file mode 100644 index 00000000..186cc485 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.ru.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Russian` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,n){"function"==typeof define&&define.amd?define(n):"object"==typeof exports?module.exports=n():n()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.ru=function(){this.pipeline.reset(),this.pipeline.add(e.ru.trimmer,e.ru.stopWordFilter,e.ru.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ru.stemmer))},e.ru.wordCharacters="Ѐ-҄҇-ԯᴫᵸⷠ-ⷿꙀ-ꚟ︮︯",e.ru.trimmer=e.trimmerSupport.generateTrimmer(e.ru.wordCharacters),e.Pipeline.registerFunction(e.ru.trimmer,"trimmer-ru"),e.ru.stemmer=function(){var n=e.stemmerSupport.Among,r=e.stemmerSupport.SnowballProgram,t=new function(){function e(){for(;!W.in_grouping(S,1072,1103);){if(W.cursor>=W.limit)return!1;W.cursor++}return!0}function t(){for(;!W.out_grouping(S,1072,1103);){if(W.cursor>=W.limit)return!1;W.cursor++}return!0}function w(){b=W.limit,_=b,e()&&(b=W.cursor,t()&&e()&&t()&&(_=W.cursor))}function i(){return _<=W.cursor}function u(e,n){var r,t;if(W.ket=W.cursor,r=W.find_among_b(e,n)){switch(W.bra=W.cursor,r){case 1:if(t=W.limit-W.cursor,!W.eq_s_b(1,"а")&&(W.cursor=W.limit-t,!W.eq_s_b(1,"я")))return!1;case 2:W.slice_del()}return!0}return!1}function o(){return u(h,9)}function s(e,n){var r;return W.ket=W.cursor,!!(r=W.find_among_b(e,n))&&(W.bra=W.cursor,1==r&&W.slice_del(),!0)}function c(){return s(g,26)}function m(){return!!c()&&(u(C,8),!0)}function f(){return s(k,2)}function l(){return u(P,46)}function a(){s(v,36)}function p(){var e;W.ket=W.cursor,(e=W.find_among_b(F,2))&&(W.bra=W.cursor,i()&&1==e&&W.slice_del())}function d(){var e;if(W.ket=W.cursor,e=W.find_among_b(q,4))switch(W.bra=W.cursor,e){case 1:if(W.slice_del(),W.ket=W.cursor,!W.eq_s_b(1,"н"))break;W.bra=W.cursor;case 2:if(!W.eq_s_b(1,"н"))break;case 3:W.slice_del()}}var _,b,h=[new n("в",-1,1),new n("ив",0,2),new n("ыв",0,2),new n("вши",-1,1),new n("ивши",3,2),new n("ывши",3,2),new n("вшись",-1,1),new n("ившись",6,2),new n("ывшись",6,2)],g=[new n("ее",-1,1),new n("ие",-1,1),new n("ое",-1,1),new n("ые",-1,1),new n("ими",-1,1),new n("ыми",-1,1),new n("ей",-1,1),new n("ий",-1,1),new n("ой",-1,1),new n("ый",-1,1),new n("ем",-1,1),new n("им",-1,1),new n("ом",-1,1),new n("ым",-1,1),new n("его",-1,1),new n("ого",-1,1),new n("ему",-1,1),new n("ому",-1,1),new n("их",-1,1),new n("ых",-1,1),new n("ею",-1,1),new n("ою",-1,1),new n("ую",-1,1),new n("юю",-1,1),new n("ая",-1,1),new n("яя",-1,1)],C=[new n("ем",-1,1),new n("нн",-1,1),new n("вш",-1,1),new n("ивш",2,2),new n("ывш",2,2),new n("щ",-1,1),new n("ющ",5,1),new n("ующ",6,2)],k=[new n("сь",-1,1),new n("ся",-1,1)],P=[new n("ла",-1,1),new n("ила",0,2),new n("ыла",0,2),new n("на",-1,1),new n("ена",3,2),new n("ете",-1,1),new n("ите",-1,2),new n("йте",-1,1),new n("ейте",7,2),new n("уйте",7,2),new n("ли",-1,1),new n("или",10,2),new n("ыли",10,2),new n("й",-1,1),new n("ей",13,2),new n("уй",13,2),new n("л",-1,1),new n("ил",16,2),new n("ыл",16,2),new n("ем",-1,1),new n("им",-1,2),new n("ым",-1,2),new n("н",-1,1),new n("ен",22,2),new n("ло",-1,1),new n("ило",24,2),new n("ыло",24,2),new n("но",-1,1),new n("ено",27,2),new n("нно",27,1),new n("ет",-1,1),new n("ует",30,2),new n("ит",-1,2),new n("ыт",-1,2),new n("ют",-1,1),new n("уют",34,2),new n("ят",-1,2),new n("ны",-1,1),new n("ены",37,2),new n("ть",-1,1),new n("ить",39,2),new n("ыть",39,2),new n("ешь",-1,1),new n("ишь",-1,2),new n("ю",-1,2),new n("ую",44,2)],v=[new n("а",-1,1),new n("ев",-1,1),new n("ов",-1,1),new n("е",-1,1),new n("ие",3,1),new n("ье",3,1),new n("и",-1,1),new n("еи",6,1),new n("ии",6,1),new n("ами",6,1),new n("ями",6,1),new n("иями",10,1),new n("й",-1,1),new n("ей",12,1),new n("ией",13,1),new n("ий",12,1),new n("ой",12,1),new n("ам",-1,1),new n("ем",-1,1),new n("ием",18,1),new n("ом",-1,1),new n("ям",-1,1),new n("иям",21,1),new n("о",-1,1),new n("у",-1,1),new n("ах",-1,1),new n("ях",-1,1),new n("иях",26,1),new n("ы",-1,1),new n("ь",-1,1),new n("ю",-1,1),new n("ию",30,1),new n("ью",30,1),new n("я",-1,1),new n("ия",33,1),new n("ья",33,1)],F=[new n("ост",-1,1),new n("ость",-1,1)],q=[new n("ейше",-1,1),new n("н",-1,2),new n("ейш",-1,1),new n("ь",-1,3)],S=[33,65,8,232],W=new r;this.setCurrent=function(e){W.setCurrent(e)},this.getCurrent=function(){return W.getCurrent()},this.stem=function(){return w(),W.cursor=W.limit,!(W.cursor=i&&(e-=i,t[e>>3]&1<<(7&e)))return this.cursor++,!0}return!1},in_grouping_b:function(t,i,s){if(this.cursor>this.limit_backward){var e=r.charCodeAt(this.cursor-1);if(e<=s&&e>=i&&(e-=i,t[e>>3]&1<<(7&e)))return this.cursor--,!0}return!1},out_grouping:function(t,i,s){if(this.cursors||e>3]&1<<(7&e)))return this.cursor++,!0}return!1},out_grouping_b:function(t,i,s){if(this.cursor>this.limit_backward){var e=r.charCodeAt(this.cursor-1);if(e>s||e>3]&1<<(7&e)))return this.cursor--,!0}return!1},eq_s:function(t,i){if(this.limit-this.cursor>1),f=0,l=o0||e==s||c)break;c=!0}}for(;;){var _=t[s];if(o>=_.s_size){if(this.cursor=n+_.s_size,!_.method)return _.result;var b=_.method();if(this.cursor=n+_.s_size,b)return _.result}if((s=_.substring_i)<0)return 0}},find_among_b:function(t,i){for(var s=0,e=i,n=this.cursor,u=this.limit_backward,o=0,h=0,c=!1;;){for(var a=s+(e-s>>1),f=0,l=o=0;m--){if(n-l==u){f=-1;break}if(f=r.charCodeAt(n-1-l)-_.s[m])break;l++}if(f<0?(e=a,h=l):(s=a,o=l),e-s<=1){if(s>0||e==s||c)break;c=!0}}for(;;){var _=t[s];if(o>=_.s_size){if(this.cursor=n-_.s_size,!_.method)return _.result;var b=_.method();if(this.cursor=n-_.s_size,b)return _.result}if((s=_.substring_i)<0)return 0}},replace_s:function(t,i,s){var e=s.length-(i-t),n=r.substring(0,t),u=r.substring(i);return r=n+s+u,this.limit+=e,this.cursor>=i?this.cursor+=e:this.cursor>t&&(this.cursor=t),e},slice_check:function(){if(this.bra<0||this.bra>this.ket||this.ket>this.limit||this.limit>r.length)throw"faulty slice operation"},slice_from:function(r){this.slice_check(),this.replace_s(this.bra,this.ket,r)},slice_del:function(){this.slice_from("")},insert:function(r,t,i){var s=this.replace_s(r,t,i);r<=this.bra&&(this.bra+=s),r<=this.ket&&(this.ket+=s)},slice_to:function(){return this.slice_check(),r.substring(this.bra,this.ket)},eq_v_b:function(r){return this.eq_s_b(r.length,r)}}}},r.trimmerSupport={generateTrimmer:function(r){var t=new RegExp("^[^"+r+"]+"),i=new RegExp("[^"+r+"]+$");return function(r){return"function"==typeof r.update?r.update(function(r){return r.replace(t,"").replace(i,"")}):r.replace(t,"").replace(i,"")}}}}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.sv.min.js b/assets/javascripts/lunr/min/lunr.sv.min.js new file mode 100644 index 00000000..3e5eb640 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.sv.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Swedish` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.sv=function(){this.pipeline.reset(),this.pipeline.add(e.sv.trimmer,e.sv.stopWordFilter,e.sv.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.sv.stemmer))},e.sv.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.sv.trimmer=e.trimmerSupport.generateTrimmer(e.sv.wordCharacters),e.Pipeline.registerFunction(e.sv.trimmer,"trimmer-sv"),e.sv.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,t=new function(){function e(){var e,r=w.cursor+3;if(o=w.limit,0<=r||r<=w.limit){for(a=r;;){if(e=w.cursor,w.in_grouping(l,97,246)){w.cursor=e;break}if(w.cursor=e,w.cursor>=w.limit)return;w.cursor++}for(;!w.out_grouping(l,97,246);){if(w.cursor>=w.limit)return;w.cursor++}o=w.cursor,o=o&&(w.limit_backward=o,w.cursor=w.limit,w.ket=w.cursor,e=w.find_among_b(u,37),w.limit_backward=r,e))switch(w.bra=w.cursor,e){case 1:w.slice_del();break;case 2:w.in_grouping_b(d,98,121)&&w.slice_del()}}function i(){var e=w.limit_backward;w.cursor>=o&&(w.limit_backward=o,w.cursor=w.limit,w.find_among_b(c,7)&&(w.cursor=w.limit,w.ket=w.cursor,w.cursor>w.limit_backward&&(w.bra=--w.cursor,w.slice_del())),w.limit_backward=e)}function s(){var e,r;if(w.cursor>=o){if(r=w.limit_backward,w.limit_backward=o,w.cursor=w.limit,w.ket=w.cursor,e=w.find_among_b(m,5))switch(w.bra=w.cursor,e){case 1:w.slice_del();break;case 2:w.slice_from("lös");break;case 3:w.slice_from("full")}w.limit_backward=r}}var a,o,u=[new r("a",-1,1),new r("arna",0,1),new r("erna",0,1),new r("heterna",2,1),new r("orna",0,1),new r("ad",-1,1),new r("e",-1,1),new r("ade",6,1),new r("ande",6,1),new r("arne",6,1),new r("are",6,1),new r("aste",6,1),new r("en",-1,1),new r("anden",12,1),new r("aren",12,1),new r("heten",12,1),new r("ern",-1,1),new r("ar",-1,1),new r("er",-1,1),new r("heter",18,1),new r("or",-1,1),new r("s",-1,2),new r("as",21,1),new r("arnas",22,1),new r("ernas",22,1),new r("ornas",22,1),new r("es",21,1),new r("ades",26,1),new r("andes",26,1),new r("ens",21,1),new r("arens",29,1),new r("hetens",29,1),new r("erns",21,1),new r("at",-1,1),new r("andet",-1,1),new r("het",-1,1),new r("ast",-1,1)],c=[new r("dd",-1,-1),new r("gd",-1,-1),new r("nn",-1,-1),new r("dt",-1,-1),new r("gt",-1,-1),new r("kt",-1,-1),new r("tt",-1,-1)],m=[new r("ig",-1,1),new r("lig",0,1),new r("els",-1,1),new r("fullt",-1,3),new r("löst",-1,2)],l=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,24,0,32],d=[119,127,149],w=new n;this.setCurrent=function(e){w.setCurrent(e)},this.getCurrent=function(){return w.getCurrent()},this.stem=function(){var r=w.cursor;return e(),w.limit_backward=r,w.cursor=w.limit,t(),w.cursor=w.limit,i(),w.cursor=w.limit,s(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return t.setCurrent(e),t.stem(),t.getCurrent()}):(t.setCurrent(e),t.stem(),t.getCurrent())}}(),e.Pipeline.registerFunction(e.sv.stemmer,"stemmer-sv"),e.sv.stopWordFilter=e.generateStopWordFilter("alla allt att av blev bli blir blivit de dem den denna deras dess dessa det detta dig din dina ditt du där då efter ej eller en er era ert ett från för ha hade han hans har henne hennes hon honom hur här i icke ingen inom inte jag ju kan kunde man med mellan men mig min mina mitt mot mycket ni nu när någon något några och om oss på samma sedan sig sin sina sitta själv skulle som så sådan sådana sådant till under upp ut utan vad var vara varför varit varje vars vart vem vi vid vilka vilkas vilken vilket vår våra vårt än är åt över".split(" ")),e.Pipeline.registerFunction(e.sv.stopWordFilter,"stopWordFilter-sv")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.ta.min.js b/assets/javascripts/lunr/min/lunr.ta.min.js new file mode 100644 index 00000000..a644bed2 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.ta.min.js @@ -0,0 +1 @@ +!function(e,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():t()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.ta=function(){this.pipeline.reset(),this.pipeline.add(e.ta.trimmer,e.ta.stopWordFilter,e.ta.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ta.stemmer))},e.ta.wordCharacters="஀-உஊ-ஏஐ-ஙச-ட஠-னப-யர-ஹ஺-ிீ-௉ொ-௏ௐ-௙௚-௟௠-௩௪-௯௰-௹௺-௿a-zA-Za-zA-Z0-90-9",e.ta.trimmer=e.trimmerSupport.generateTrimmer(e.ta.wordCharacters),e.Pipeline.registerFunction(e.ta.trimmer,"trimmer-ta"),e.ta.stopWordFilter=e.generateStopWordFilter("அங்கு அங்கே அது அதை அந்த அவர் அவர்கள் அவள் அவன் அவை ஆக ஆகவே ஆகையால் ஆதலால் ஆதலினால் ஆனாலும் ஆனால் இங்கு இங்கே இது இதை இந்த இப்படி இவர் இவர்கள் இவள் இவன் இவை இவ்வளவு உனக்கு உனது உன் உன்னால் எங்கு எங்கே எது எதை எந்த எப்படி எவர் எவர்கள் எவள் எவன் எவை எவ்வளவு எனக்கு எனது எனவே என் என்ன என்னால் ஏது ஏன் தனது தன்னால் தானே தான் நாங்கள் நாம் நான் நீ நீங்கள்".split(" ")),e.ta.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}();var t=e.wordcut;t.init(),e.ta.tokenizer=function(r){if(!arguments.length||null==r||void 0==r)return[];if(Array.isArray(r))return r.map(function(t){return isLunr2?new e.Token(t.toLowerCase()):t.toLowerCase()});var i=r.toString().toLowerCase().replace(/^\s+/,"");return t.cut(i).split("|")},e.Pipeline.registerFunction(e.ta.stemmer,"stemmer-ta"),e.Pipeline.registerFunction(e.ta.stopWordFilter,"stopWordFilter-ta")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.te.min.js b/assets/javascripts/lunr/min/lunr.te.min.js new file mode 100644 index 00000000..9fa7a93b --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.te.min.js @@ -0,0 +1 @@ +!function(e,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():t()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.te=function(){this.pipeline.reset(),this.pipeline.add(e.te.trimmer,e.te.stopWordFilter,e.te.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.te.stemmer))},e.te.wordCharacters="ఀ-ఄఅ-ఔక-హా-ౌౕ-ౖౘ-ౚౠ-ౡౢ-ౣ౦-౯౸-౿఼ఽ్ౝ౷౤౥",e.te.trimmer=e.trimmerSupport.generateTrimmer(e.te.wordCharacters),e.Pipeline.registerFunction(e.te.trimmer,"trimmer-te"),e.te.stopWordFilter=e.generateStopWordFilter("అందరూ అందుబాటులో అడగండి అడగడం అడ్డంగా అనుగుణంగా అనుమతించు అనుమతిస్తుంది అయితే ఇప్పటికే ఉన్నారు ఎక్కడైనా ఎప్పుడు ఎవరైనా ఎవరో ఏ ఏదైనా ఏమైనప్పటికి ఒక ఒకరు కనిపిస్తాయి కాదు కూడా గా గురించి చుట్టూ చేయగలిగింది తగిన తర్వాత దాదాపు దూరంగా నిజంగా పై ప్రకారం ప్రక్కన మధ్య మరియు మరొక మళ్ళీ మాత్రమే మెచ్చుకో వద్ద వెంట వేరుగా వ్యతిరేకంగా సంబంధం".split(" ")),e.te.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}();var t=e.wordcut;t.init(),e.te.tokenizer=function(r){if(!arguments.length||null==r||void 0==r)return[];if(Array.isArray(r))return r.map(function(t){return isLunr2?new e.Token(t.toLowerCase()):t.toLowerCase()});var i=r.toString().toLowerCase().replace(/^\s+/,"");return t.cut(i).split("|")},e.Pipeline.registerFunction(e.te.stemmer,"stemmer-te"),e.Pipeline.registerFunction(e.te.stopWordFilter,"stopWordFilter-te")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.th.min.js b/assets/javascripts/lunr/min/lunr.th.min.js new file mode 100644 index 00000000..dee3aac6 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.th.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r="2"==e.version[0];e.th=function(){this.pipeline.reset(),this.pipeline.add(e.th.trimmer),r?this.tokenizer=e.th.tokenizer:(e.tokenizer&&(e.tokenizer=e.th.tokenizer),this.tokenizerFn&&(this.tokenizerFn=e.th.tokenizer))},e.th.wordCharacters="[฀-๿]",e.th.trimmer=e.trimmerSupport.generateTrimmer(e.th.wordCharacters),e.Pipeline.registerFunction(e.th.trimmer,"trimmer-th");var t=e.wordcut;t.init(),e.th.tokenizer=function(i){if(!arguments.length||null==i||void 0==i)return[];if(Array.isArray(i))return i.map(function(t){return r?new e.Token(t):t});var n=i.toString().replace(/^\s+/,"");return t.cut(n).split("|")}}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.tr.min.js b/assets/javascripts/lunr/min/lunr.tr.min.js new file mode 100644 index 00000000..563f6ec1 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.tr.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Turkish` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(r,i){"function"==typeof define&&define.amd?define(i):"object"==typeof exports?module.exports=i():i()(r.lunr)}(this,function(){return function(r){if(void 0===r)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===r.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");r.tr=function(){this.pipeline.reset(),this.pipeline.add(r.tr.trimmer,r.tr.stopWordFilter,r.tr.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(r.tr.stemmer))},r.tr.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",r.tr.trimmer=r.trimmerSupport.generateTrimmer(r.tr.wordCharacters),r.Pipeline.registerFunction(r.tr.trimmer,"trimmer-tr"),r.tr.stemmer=function(){var i=r.stemmerSupport.Among,e=r.stemmerSupport.SnowballProgram,n=new function(){function r(r,i,e){for(;;){var n=Dr.limit-Dr.cursor;if(Dr.in_grouping_b(r,i,e)){Dr.cursor=Dr.limit-n;break}if(Dr.cursor=Dr.limit-n,Dr.cursor<=Dr.limit_backward)return!1;Dr.cursor--}return!0}function n(){var i,e;i=Dr.limit-Dr.cursor,r(Wr,97,305);for(var n=0;nDr.limit_backward&&(Dr.cursor--,e=Dr.limit-Dr.cursor,i()))?(Dr.cursor=Dr.limit-e,!0):(Dr.cursor=Dr.limit-n,r()?(Dr.cursor=Dr.limit-n,!1):(Dr.cursor=Dr.limit-n,!(Dr.cursor<=Dr.limit_backward)&&(Dr.cursor--,!!i()&&(Dr.cursor=Dr.limit-n,!0))))}function u(r){return t(r,function(){return Dr.in_grouping_b(Wr,97,305)})}function o(){return u(function(){return Dr.eq_s_b(1,"n")})}function s(){return u(function(){return Dr.eq_s_b(1,"s")})}function c(){return u(function(){return Dr.eq_s_b(1,"y")})}function l(){return t(function(){return Dr.in_grouping_b(Lr,105,305)},function(){return Dr.out_grouping_b(Wr,97,305)})}function a(){return Dr.find_among_b(ur,10)&&l()}function m(){return n()&&Dr.in_grouping_b(Lr,105,305)&&s()}function d(){return Dr.find_among_b(or,2)}function f(){return n()&&Dr.in_grouping_b(Lr,105,305)&&c()}function b(){return n()&&Dr.find_among_b(sr,4)}function w(){return n()&&Dr.find_among_b(cr,4)&&o()}function _(){return n()&&Dr.find_among_b(lr,2)&&c()}function k(){return n()&&Dr.find_among_b(ar,2)}function p(){return n()&&Dr.find_among_b(mr,4)}function g(){return n()&&Dr.find_among_b(dr,2)}function y(){return n()&&Dr.find_among_b(fr,4)}function z(){return n()&&Dr.find_among_b(br,2)}function v(){return n()&&Dr.find_among_b(wr,2)&&c()}function h(){return Dr.eq_s_b(2,"ki")}function q(){return n()&&Dr.find_among_b(_r,2)&&o()}function C(){return n()&&Dr.find_among_b(kr,4)&&c()}function P(){return n()&&Dr.find_among_b(pr,4)}function F(){return n()&&Dr.find_among_b(gr,4)&&c()}function S(){return Dr.find_among_b(yr,4)}function W(){return n()&&Dr.find_among_b(zr,2)}function L(){return n()&&Dr.find_among_b(vr,4)}function x(){return n()&&Dr.find_among_b(hr,8)}function A(){return Dr.find_among_b(qr,2)}function E(){return n()&&Dr.find_among_b(Cr,32)&&c()}function j(){return Dr.find_among_b(Pr,8)&&c()}function T(){return n()&&Dr.find_among_b(Fr,4)&&c()}function Z(){return Dr.eq_s_b(3,"ken")&&c()}function B(){var r=Dr.limit-Dr.cursor;return!(T()||(Dr.cursor=Dr.limit-r,E()||(Dr.cursor=Dr.limit-r,j()||(Dr.cursor=Dr.limit-r,Z()))))}function D(){if(A()){var r=Dr.limit-Dr.cursor;if(S()||(Dr.cursor=Dr.limit-r,W()||(Dr.cursor=Dr.limit-r,C()||(Dr.cursor=Dr.limit-r,P()||(Dr.cursor=Dr.limit-r,F()||(Dr.cursor=Dr.limit-r))))),T())return!1}return!0}function G(){if(W()){Dr.bra=Dr.cursor,Dr.slice_del();var r=Dr.limit-Dr.cursor;return Dr.ket=Dr.cursor,x()||(Dr.cursor=Dr.limit-r,E()||(Dr.cursor=Dr.limit-r,j()||(Dr.cursor=Dr.limit-r,T()||(Dr.cursor=Dr.limit-r)))),nr=!1,!1}return!0}function H(){if(!L())return!0;var r=Dr.limit-Dr.cursor;return!E()&&(Dr.cursor=Dr.limit-r,!j())}function I(){var r,i=Dr.limit-Dr.cursor;return!(S()||(Dr.cursor=Dr.limit-i,F()||(Dr.cursor=Dr.limit-i,P()||(Dr.cursor=Dr.limit-i,C()))))||(Dr.bra=Dr.cursor,Dr.slice_del(),r=Dr.limit-Dr.cursor,Dr.ket=Dr.cursor,T()||(Dr.cursor=Dr.limit-r),!1)}function J(){var r,i=Dr.limit-Dr.cursor;if(Dr.ket=Dr.cursor,nr=!0,B()&&(Dr.cursor=Dr.limit-i,D()&&(Dr.cursor=Dr.limit-i,G()&&(Dr.cursor=Dr.limit-i,H()&&(Dr.cursor=Dr.limit-i,I()))))){if(Dr.cursor=Dr.limit-i,!x())return;Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,r=Dr.limit-Dr.cursor,S()||(Dr.cursor=Dr.limit-r,W()||(Dr.cursor=Dr.limit-r,C()||(Dr.cursor=Dr.limit-r,P()||(Dr.cursor=Dr.limit-r,F()||(Dr.cursor=Dr.limit-r))))),T()||(Dr.cursor=Dr.limit-r)}Dr.bra=Dr.cursor,Dr.slice_del()}function K(){var r,i,e,n;if(Dr.ket=Dr.cursor,h()){if(r=Dr.limit-Dr.cursor,p())return Dr.bra=Dr.cursor,Dr.slice_del(),i=Dr.limit-Dr.cursor,Dr.ket=Dr.cursor,W()?(Dr.bra=Dr.cursor,Dr.slice_del(),K()):(Dr.cursor=Dr.limit-i,a()&&(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K()))),!0;if(Dr.cursor=Dr.limit-r,w()){if(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,e=Dr.limit-Dr.cursor,d())Dr.bra=Dr.cursor,Dr.slice_del();else{if(Dr.cursor=Dr.limit-e,Dr.ket=Dr.cursor,!a()&&(Dr.cursor=Dr.limit-e,!m()&&(Dr.cursor=Dr.limit-e,!K())))return!0;Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K())}return!0}if(Dr.cursor=Dr.limit-r,g()){if(n=Dr.limit-Dr.cursor,d())Dr.bra=Dr.cursor,Dr.slice_del();else if(Dr.cursor=Dr.limit-n,m())Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K());else if(Dr.cursor=Dr.limit-n,!K())return!1;return!0}}return!1}function M(r){if(Dr.ket=Dr.cursor,!g()&&(Dr.cursor=Dr.limit-r,!k()))return!1;var i=Dr.limit-Dr.cursor;if(d())Dr.bra=Dr.cursor,Dr.slice_del();else if(Dr.cursor=Dr.limit-i,m())Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K());else if(Dr.cursor=Dr.limit-i,!K())return!1;return!0}function N(r){if(Dr.ket=Dr.cursor,!z()&&(Dr.cursor=Dr.limit-r,!b()))return!1;var i=Dr.limit-Dr.cursor;return!(!m()&&(Dr.cursor=Dr.limit-i,!d()))&&(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K()),!0)}function O(){var r,i=Dr.limit-Dr.cursor;return Dr.ket=Dr.cursor,!(!w()&&(Dr.cursor=Dr.limit-i,!v()))&&(Dr.bra=Dr.cursor,Dr.slice_del(),r=Dr.limit-Dr.cursor,Dr.ket=Dr.cursor,!(!W()||(Dr.bra=Dr.cursor,Dr.slice_del(),!K()))||(Dr.cursor=Dr.limit-r,Dr.ket=Dr.cursor,!(a()||(Dr.cursor=Dr.limit-r,m()||(Dr.cursor=Dr.limit-r,K())))||(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K()),!0)))}function Q(){var r,i,e=Dr.limit-Dr.cursor;if(Dr.ket=Dr.cursor,!p()&&(Dr.cursor=Dr.limit-e,!f()&&(Dr.cursor=Dr.limit-e,!_())))return!1;if(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,r=Dr.limit-Dr.cursor,a())Dr.bra=Dr.cursor,Dr.slice_del(),i=Dr.limit-Dr.cursor,Dr.ket=Dr.cursor,W()||(Dr.cursor=Dr.limit-i);else if(Dr.cursor=Dr.limit-r,!W())return!0;return Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,K(),!0}function R(){var r,i,e=Dr.limit-Dr.cursor;if(Dr.ket=Dr.cursor,W())return Dr.bra=Dr.cursor,Dr.slice_del(),void K();if(Dr.cursor=Dr.limit-e,Dr.ket=Dr.cursor,q())if(Dr.bra=Dr.cursor,Dr.slice_del(),r=Dr.limit-Dr.cursor,Dr.ket=Dr.cursor,d())Dr.bra=Dr.cursor,Dr.slice_del();else{if(Dr.cursor=Dr.limit-r,Dr.ket=Dr.cursor,!a()&&(Dr.cursor=Dr.limit-r,!m())){if(Dr.cursor=Dr.limit-r,Dr.ket=Dr.cursor,!W())return;if(Dr.bra=Dr.cursor,Dr.slice_del(),!K())return}Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K())}else if(Dr.cursor=Dr.limit-e,!M(e)&&(Dr.cursor=Dr.limit-e,!N(e))){if(Dr.cursor=Dr.limit-e,Dr.ket=Dr.cursor,y())return Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,i=Dr.limit-Dr.cursor,void(a()?(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K())):(Dr.cursor=Dr.limit-i,W()?(Dr.bra=Dr.cursor,Dr.slice_del(),K()):(Dr.cursor=Dr.limit-i,K())));if(Dr.cursor=Dr.limit-e,!O()){if(Dr.cursor=Dr.limit-e,d())return Dr.bra=Dr.cursor,void Dr.slice_del();Dr.cursor=Dr.limit-e,K()||(Dr.cursor=Dr.limit-e,Q()||(Dr.cursor=Dr.limit-e,Dr.ket=Dr.cursor,(a()||(Dr.cursor=Dr.limit-e,m()))&&(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K()))))}}}function U(){var r;if(Dr.ket=Dr.cursor,r=Dr.find_among_b(Sr,4))switch(Dr.bra=Dr.cursor,r){case 1:Dr.slice_from("p");break;case 2:Dr.slice_from("ç");break;case 3:Dr.slice_from("t");break;case 4:Dr.slice_from("k")}}function V(){for(;;){var r=Dr.limit-Dr.cursor;if(Dr.in_grouping_b(Wr,97,305)){Dr.cursor=Dr.limit-r;break}if(Dr.cursor=Dr.limit-r,Dr.cursor<=Dr.limit_backward)return!1;Dr.cursor--}return!0}function X(r,i,e){if(Dr.cursor=Dr.limit-r,V()){var n=Dr.limit-Dr.cursor;if(!Dr.eq_s_b(1,i)&&(Dr.cursor=Dr.limit-n,!Dr.eq_s_b(1,e)))return!0;Dr.cursor=Dr.limit-r;var t=Dr.cursor;return Dr.insert(Dr.cursor,Dr.cursor,e),Dr.cursor=t,!1}return!0}function Y(){var r=Dr.limit-Dr.cursor;(Dr.eq_s_b(1,"d")||(Dr.cursor=Dr.limit-r,Dr.eq_s_b(1,"g")))&&X(r,"a","ı")&&X(r,"e","i")&&X(r,"o","u")&&X(r,"ö","ü")}function $(){for(var r,i=Dr.cursor,e=2;;){for(r=Dr.cursor;!Dr.in_grouping(Wr,97,305);){if(Dr.cursor>=Dr.limit)return Dr.cursor=r,!(e>0)&&(Dr.cursor=i,!0);Dr.cursor++}e--}}function rr(r,i,e){for(;!Dr.eq_s(i,e);){if(Dr.cursor>=Dr.limit)return!0;Dr.cursor++}return(tr=i)!=Dr.limit||(Dr.cursor=r,!1)}function ir(){var r=Dr.cursor;return!rr(r,2,"ad")||(Dr.cursor=r,!rr(r,5,"soyad"))}function er(){var r=Dr.cursor;return!ir()&&(Dr.limit_backward=r,Dr.cursor=Dr.limit,Y(),Dr.cursor=Dr.limit,U(),!0)}var nr,tr,ur=[new i("m",-1,-1),new i("n",-1,-1),new i("miz",-1,-1),new i("niz",-1,-1),new i("muz",-1,-1),new i("nuz",-1,-1),new i("müz",-1,-1),new i("nüz",-1,-1),new i("mız",-1,-1),new i("nız",-1,-1)],or=[new i("leri",-1,-1),new i("ları",-1,-1)],sr=[new i("ni",-1,-1),new i("nu",-1,-1),new i("nü",-1,-1),new i("nı",-1,-1)],cr=[new i("in",-1,-1),new i("un",-1,-1),new i("ün",-1,-1),new i("ın",-1,-1)],lr=[new i("a",-1,-1),new i("e",-1,-1)],ar=[new i("na",-1,-1),new i("ne",-1,-1)],mr=[new i("da",-1,-1),new i("ta",-1,-1),new i("de",-1,-1),new i("te",-1,-1)],dr=[new i("nda",-1,-1),new i("nde",-1,-1)],fr=[new i("dan",-1,-1),new i("tan",-1,-1),new i("den",-1,-1),new i("ten",-1,-1)],br=[new i("ndan",-1,-1),new i("nden",-1,-1)],wr=[new i("la",-1,-1),new i("le",-1,-1)],_r=[new i("ca",-1,-1),new i("ce",-1,-1)],kr=[new i("im",-1,-1),new i("um",-1,-1),new i("üm",-1,-1),new i("ım",-1,-1)],pr=[new i("sin",-1,-1),new i("sun",-1,-1),new i("sün",-1,-1),new i("sın",-1,-1)],gr=[new i("iz",-1,-1),new i("uz",-1,-1),new i("üz",-1,-1),new i("ız",-1,-1)],yr=[new i("siniz",-1,-1),new i("sunuz",-1,-1),new i("sünüz",-1,-1),new i("sınız",-1,-1)],zr=[new i("lar",-1,-1),new i("ler",-1,-1)],vr=[new i("niz",-1,-1),new i("nuz",-1,-1),new i("nüz",-1,-1),new i("nız",-1,-1)],hr=[new i("dir",-1,-1),new i("tir",-1,-1),new i("dur",-1,-1),new i("tur",-1,-1),new i("dür",-1,-1),new i("tür",-1,-1),new i("dır",-1,-1),new i("tır",-1,-1)],qr=[new i("casına",-1,-1),new i("cesine",-1,-1)],Cr=[new i("di",-1,-1),new i("ti",-1,-1),new i("dik",-1,-1),new i("tik",-1,-1),new i("duk",-1,-1),new i("tuk",-1,-1),new i("dük",-1,-1),new i("tük",-1,-1),new i("dık",-1,-1),new i("tık",-1,-1),new i("dim",-1,-1),new i("tim",-1,-1),new i("dum",-1,-1),new i("tum",-1,-1),new i("düm",-1,-1),new i("tüm",-1,-1),new i("dım",-1,-1),new i("tım",-1,-1),new i("din",-1,-1),new i("tin",-1,-1),new i("dun",-1,-1),new i("tun",-1,-1),new i("dün",-1,-1),new i("tün",-1,-1),new i("dın",-1,-1),new i("tın",-1,-1),new i("du",-1,-1),new i("tu",-1,-1),new i("dü",-1,-1),new i("tü",-1,-1),new i("dı",-1,-1),new i("tı",-1,-1)],Pr=[new i("sa",-1,-1),new i("se",-1,-1),new i("sak",-1,-1),new i("sek",-1,-1),new i("sam",-1,-1),new i("sem",-1,-1),new i("san",-1,-1),new i("sen",-1,-1)],Fr=[new i("miş",-1,-1),new i("muş",-1,-1),new i("müş",-1,-1),new i("mış",-1,-1)],Sr=[new i("b",-1,1),new i("c",-1,2),new i("d",-1,3),new i("ğ",-1,4)],Wr=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,8,0,0,0,0,0,0,1],Lr=[1,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,1],xr=[1,64,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],Ar=[17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,130],Er=[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],jr=[17],Tr=[65],Zr=[65],Br=[["a",xr,97,305],["e",Ar,101,252],["ı",Er,97,305],["i",jr,101,105],["o",Tr,111,117],["ö",Zr,246,252],["u",Tr,111,117]],Dr=new e;this.setCurrent=function(r){Dr.setCurrent(r)},this.getCurrent=function(){return Dr.getCurrent()},this.stem=function(){return!!($()&&(Dr.limit_backward=Dr.cursor,Dr.cursor=Dr.limit,J(),Dr.cursor=Dr.limit,nr&&(R(),Dr.cursor=Dr.limit_backward,er())))}};return function(r){return"function"==typeof r.update?r.update(function(r){return n.setCurrent(r),n.stem(),n.getCurrent()}):(n.setCurrent(r),n.stem(),n.getCurrent())}}(),r.Pipeline.registerFunction(r.tr.stemmer,"stemmer-tr"),r.tr.stopWordFilter=r.generateStopWordFilter("acaba altmış altı ama ancak arada aslında ayrıca bana bazı belki ben benden beni benim beri beş bile bin bir biri birkaç birkez birçok birşey birşeyi biz bizden bize bizi bizim bu buna bunda bundan bunlar bunları bunların bunu bunun burada böyle böylece da daha dahi de defa değil diye diğer doksan dokuz dolayı dolayısıyla dört edecek eden ederek edilecek ediliyor edilmesi ediyor elli en etmesi etti ettiği ettiğini eğer gibi göre halen hangi hatta hem henüz hep hepsi her herhangi herkesin hiç hiçbir iki ile ilgili ise itibaren itibariyle için işte kadar karşın katrilyon kendi kendilerine kendini kendisi kendisine kendisini kez ki kim kimden kime kimi kimse kırk milyar milyon mu mü mı nasıl ne neden nedenle nerde nerede nereye niye niçin o olan olarak oldu olduklarını olduğu olduğunu olmadı olmadığı olmak olması olmayan olmaz olsa olsun olup olur olursa oluyor on ona ondan onlar onlardan onları onların onu onun otuz oysa pek rağmen sadece sanki sekiz seksen sen senden seni senin siz sizden sizi sizin tarafından trilyon tüm var vardı ve veya ya yani yapacak yapmak yaptı yaptıkları yaptığı yaptığını yapılan yapılması yapıyor yedi yerine yetmiş yine yirmi yoksa yüz zaten çok çünkü öyle üzere üç şey şeyden şeyi şeyler şu şuna şunda şundan şunları şunu şöyle".split(" ")),r.Pipeline.registerFunction(r.tr.stopWordFilter,"stopWordFilter-tr")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.vi.min.js b/assets/javascripts/lunr/min/lunr.vi.min.js new file mode 100644 index 00000000..22aed28c --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.vi.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.vi=function(){this.pipeline.reset(),this.pipeline.add(e.vi.stopWordFilter,e.vi.trimmer)},e.vi.wordCharacters="[A-Za-ẓ̀͐́͑̉̃̓ÂâÊêÔôĂ-ăĐ-đƠ-ơƯ-ư]",e.vi.trimmer=e.trimmerSupport.generateTrimmer(e.vi.wordCharacters),e.Pipeline.registerFunction(e.vi.trimmer,"trimmer-vi"),e.vi.stopWordFilter=e.generateStopWordFilter("là cái nhưng mà".split(" "))}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.zh.min.js b/assets/javascripts/lunr/min/lunr.zh.min.js new file mode 100644 index 00000000..fda66e9c --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.zh.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r(require("@node-rs/jieba")):r()(e.lunr)}(this,function(e){return function(r,t){if(void 0===r)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===r.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var i="2"==r.version[0];r.zh=function(){this.pipeline.reset(),this.pipeline.add(r.zh.trimmer,r.zh.stopWordFilter,r.zh.stemmer),i?this.tokenizer=r.zh.tokenizer:(r.tokenizer&&(r.tokenizer=r.zh.tokenizer),this.tokenizerFn&&(this.tokenizerFn=r.zh.tokenizer))},r.zh.tokenizer=function(n){if(!arguments.length||null==n||void 0==n)return[];if(Array.isArray(n))return n.map(function(e){return i?new r.Token(e.toLowerCase()):e.toLowerCase()});t&&e.load(t);var o=n.toString().trim().toLowerCase(),s=[];e.cut(o,!0).forEach(function(e){s=s.concat(e.split(" "))}),s=s.filter(function(e){return!!e});var u=0;return s.map(function(e,t){if(i){var n=o.indexOf(e,u),s={};return s.position=[n,e.length],s.index=t,u=n,new r.Token(e,s)}return e})},r.zh.wordCharacters="\\w一-龥",r.zh.trimmer=r.trimmerSupport.generateTrimmer(r.zh.wordCharacters),r.Pipeline.registerFunction(r.zh.trimmer,"trimmer-zh"),r.zh.stemmer=function(){return function(e){return e}}(),r.Pipeline.registerFunction(r.zh.stemmer,"stemmer-zh"),r.zh.stopWordFilter=r.generateStopWordFilter("的 一 不 在 人 有 是 为 為 以 于 於 上 他 而 后 後 之 来 來 及 了 因 下 可 到 由 这 這 与 與 也 此 但 并 並 个 個 其 已 无 無 小 我 们 們 起 最 再 今 去 好 只 又 或 很 亦 某 把 那 你 乃 它 吧 被 比 别 趁 当 當 从 從 得 打 凡 儿 兒 尔 爾 该 該 各 给 給 跟 和 何 还 還 即 几 幾 既 看 据 據 距 靠 啦 另 么 麽 每 嘛 拿 哪 您 凭 憑 且 却 卻 让 讓 仍 啥 如 若 使 谁 誰 虽 雖 随 隨 同 所 她 哇 嗡 往 些 向 沿 哟 喲 用 咱 则 則 怎 曾 至 致 着 著 诸 諸 自".split(" ")),r.Pipeline.registerFunction(r.zh.stopWordFilter,"stopWordFilter-zh")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/tinyseg.js b/assets/javascripts/lunr/tinyseg.js new file mode 100644 index 00000000..167fa6dd --- /dev/null +++ b/assets/javascripts/lunr/tinyseg.js @@ -0,0 +1,206 @@ +/** + * export the module via AMD, CommonJS or as a browser global + * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js + */ +;(function (root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(factory) + } else if (typeof exports === 'object') { + /** + * Node. Does not work with strict CommonJS, but + * only CommonJS-like environments that support module.exports, + * like Node. + */ + module.exports = factory() + } else { + // Browser globals (root is window) + factory()(root.lunr); + } +}(this, function () { + /** + * Just return a value to define the module export. + * This example returns an object, but the module + * can return a function as the exported value. + */ + + return function(lunr) { + // TinySegmenter 0.1 -- Super compact Japanese tokenizer in Javascript + // (c) 2008 Taku Kudo + // TinySegmenter is freely distributable under the terms of a new BSD licence. + // For details, see http://chasen.org/~taku/software/TinySegmenter/LICENCE.txt + + function TinySegmenter() { + var patterns = { + "[一二三四五六七八九十百千万億兆]":"M", + "[一-龠々〆ヵヶ]":"H", + "[ぁ-ん]":"I", + "[ァ-ヴーア-ン゙ー]":"K", + "[a-zA-Za-zA-Z]":"A", + "[0-90-9]":"N" + } + this.chartype_ = []; + for (var i in patterns) { + var regexp = new RegExp(i); + this.chartype_.push([regexp, patterns[i]]); + } + + this.BIAS__ = -332 + this.BC1__ = {"HH":6,"II":2461,"KH":406,"OH":-1378}; + this.BC2__ = {"AA":-3267,"AI":2744,"AN":-878,"HH":-4070,"HM":-1711,"HN":4012,"HO":3761,"IA":1327,"IH":-1184,"II":-1332,"IK":1721,"IO":5492,"KI":3831,"KK":-8741,"MH":-3132,"MK":3334,"OO":-2920}; + this.BC3__ = {"HH":996,"HI":626,"HK":-721,"HN":-1307,"HO":-836,"IH":-301,"KK":2762,"MK":1079,"MM":4034,"OA":-1652,"OH":266}; + this.BP1__ = {"BB":295,"OB":304,"OO":-125,"UB":352}; + this.BP2__ = {"BO":60,"OO":-1762}; + this.BQ1__ = {"BHH":1150,"BHM":1521,"BII":-1158,"BIM":886,"BMH":1208,"BNH":449,"BOH":-91,"BOO":-2597,"OHI":451,"OIH":-296,"OKA":1851,"OKH":-1020,"OKK":904,"OOO":2965}; + this.BQ2__ = {"BHH":118,"BHI":-1159,"BHM":466,"BIH":-919,"BKK":-1720,"BKO":864,"OHH":-1139,"OHM":-181,"OIH":153,"UHI":-1146}; + this.BQ3__ = {"BHH":-792,"BHI":2664,"BII":-299,"BKI":419,"BMH":937,"BMM":8335,"BNN":998,"BOH":775,"OHH":2174,"OHM":439,"OII":280,"OKH":1798,"OKI":-793,"OKO":-2242,"OMH":-2402,"OOO":11699}; + this.BQ4__ = {"BHH":-3895,"BIH":3761,"BII":-4654,"BIK":1348,"BKK":-1806,"BMI":-3385,"BOO":-12396,"OAH":926,"OHH":266,"OHK":-2036,"ONN":-973}; + this.BW1__ = {",と":660,",同":727,"B1あ":1404,"B1同":542,"、と":660,"、同":727,"」と":1682,"あっ":1505,"いう":1743,"いっ":-2055,"いる":672,"うし":-4817,"うん":665,"から":3472,"がら":600,"こう":-790,"こと":2083,"こん":-1262,"さら":-4143,"さん":4573,"した":2641,"して":1104,"すで":-3399,"そこ":1977,"それ":-871,"たち":1122,"ため":601,"った":3463,"つい":-802,"てい":805,"てき":1249,"でき":1127,"です":3445,"では":844,"とい":-4915,"とみ":1922,"どこ":3887,"ない":5713,"なっ":3015,"など":7379,"なん":-1113,"にし":2468,"には":1498,"にも":1671,"に対":-912,"の一":-501,"の中":741,"ませ":2448,"まで":1711,"まま":2600,"まる":-2155,"やむ":-1947,"よっ":-2565,"れた":2369,"れで":-913,"をし":1860,"を見":731,"亡く":-1886,"京都":2558,"取り":-2784,"大き":-2604,"大阪":1497,"平方":-2314,"引き":-1336,"日本":-195,"本当":-2423,"毎日":-2113,"目指":-724,"B1あ":1404,"B1同":542,"」と":1682}; + this.BW2__ = {"..":-11822,"11":-669,"――":-5730,"−−":-13175,"いう":-1609,"うか":2490,"かし":-1350,"かも":-602,"から":-7194,"かれ":4612,"がい":853,"がら":-3198,"きた":1941,"くな":-1597,"こと":-8392,"この":-4193,"させ":4533,"され":13168,"さん":-3977,"しい":-1819,"しか":-545,"した":5078,"して":972,"しな":939,"その":-3744,"たい":-1253,"たた":-662,"ただ":-3857,"たち":-786,"たと":1224,"たは":-939,"った":4589,"って":1647,"っと":-2094,"てい":6144,"てき":3640,"てく":2551,"ては":-3110,"ても":-3065,"でい":2666,"でき":-1528,"でし":-3828,"です":-4761,"でも":-4203,"とい":1890,"とこ":-1746,"とと":-2279,"との":720,"とみ":5168,"とも":-3941,"ない":-2488,"なが":-1313,"など":-6509,"なの":2614,"なん":3099,"にお":-1615,"にし":2748,"にな":2454,"によ":-7236,"に対":-14943,"に従":-4688,"に関":-11388,"のか":2093,"ので":-7059,"のに":-6041,"のの":-6125,"はい":1073,"はが":-1033,"はず":-2532,"ばれ":1813,"まし":-1316,"まで":-6621,"まれ":5409,"めて":-3153,"もい":2230,"もの":-10713,"らか":-944,"らし":-1611,"らに":-1897,"りし":651,"りま":1620,"れた":4270,"れて":849,"れば":4114,"ろう":6067,"われ":7901,"を通":-11877,"んだ":728,"んな":-4115,"一人":602,"一方":-1375,"一日":970,"一部":-1051,"上が":-4479,"会社":-1116,"出て":2163,"分の":-7758,"同党":970,"同日":-913,"大阪":-2471,"委員":-1250,"少な":-1050,"年度":-8669,"年間":-1626,"府県":-2363,"手権":-1982,"新聞":-4066,"日新":-722,"日本":-7068,"日米":3372,"曜日":-601,"朝鮮":-2355,"本人":-2697,"東京":-1543,"然と":-1384,"社会":-1276,"立て":-990,"第に":-1612,"米国":-4268,"11":-669}; + this.BW3__ = {"あた":-2194,"あり":719,"ある":3846,"い.":-1185,"い。":-1185,"いい":5308,"いえ":2079,"いく":3029,"いた":2056,"いっ":1883,"いる":5600,"いわ":1527,"うち":1117,"うと":4798,"えと":1454,"か.":2857,"か。":2857,"かけ":-743,"かっ":-4098,"かに":-669,"から":6520,"かり":-2670,"が,":1816,"が、":1816,"がき":-4855,"がけ":-1127,"がっ":-913,"がら":-4977,"がり":-2064,"きた":1645,"けど":1374,"こと":7397,"この":1542,"ころ":-2757,"さい":-714,"さを":976,"し,":1557,"し、":1557,"しい":-3714,"した":3562,"して":1449,"しな":2608,"しま":1200,"す.":-1310,"す。":-1310,"する":6521,"ず,":3426,"ず、":3426,"ずに":841,"そう":428,"た.":8875,"た。":8875,"たい":-594,"たの":812,"たり":-1183,"たる":-853,"だ.":4098,"だ。":4098,"だっ":1004,"った":-4748,"って":300,"てい":6240,"てお":855,"ても":302,"です":1437,"でに":-1482,"では":2295,"とう":-1387,"とし":2266,"との":541,"とも":-3543,"どう":4664,"ない":1796,"なく":-903,"など":2135,"に,":-1021,"に、":-1021,"にし":1771,"にな":1906,"には":2644,"の,":-724,"の、":-724,"の子":-1000,"は,":1337,"は、":1337,"べき":2181,"まし":1113,"ます":6943,"まっ":-1549,"まで":6154,"まれ":-793,"らし":1479,"られ":6820,"るる":3818,"れ,":854,"れ、":854,"れた":1850,"れて":1375,"れば":-3246,"れる":1091,"われ":-605,"んだ":606,"んで":798,"カ月":990,"会議":860,"入り":1232,"大会":2217,"始め":1681,"市":965,"新聞":-5055,"日,":974,"日、":974,"社会":2024,"カ月":990}; + this.TC1__ = {"AAA":1093,"HHH":1029,"HHM":580,"HII":998,"HOH":-390,"HOM":-331,"IHI":1169,"IOH":-142,"IOI":-1015,"IOM":467,"MMH":187,"OOI":-1832}; + this.TC2__ = {"HHO":2088,"HII":-1023,"HMM":-1154,"IHI":-1965,"KKH":703,"OII":-2649}; + this.TC3__ = {"AAA":-294,"HHH":346,"HHI":-341,"HII":-1088,"HIK":731,"HOH":-1486,"IHH":128,"IHI":-3041,"IHO":-1935,"IIH":-825,"IIM":-1035,"IOI":-542,"KHH":-1216,"KKA":491,"KKH":-1217,"KOK":-1009,"MHH":-2694,"MHM":-457,"MHO":123,"MMH":-471,"NNH":-1689,"NNO":662,"OHO":-3393}; + this.TC4__ = {"HHH":-203,"HHI":1344,"HHK":365,"HHM":-122,"HHN":182,"HHO":669,"HIH":804,"HII":679,"HOH":446,"IHH":695,"IHO":-2324,"IIH":321,"III":1497,"IIO":656,"IOO":54,"KAK":4845,"KKA":3386,"KKK":3065,"MHH":-405,"MHI":201,"MMH":-241,"MMM":661,"MOM":841}; + this.TQ1__ = {"BHHH":-227,"BHHI":316,"BHIH":-132,"BIHH":60,"BIII":1595,"BNHH":-744,"BOHH":225,"BOOO":-908,"OAKK":482,"OHHH":281,"OHIH":249,"OIHI":200,"OIIH":-68}; + this.TQ2__ = {"BIHH":-1401,"BIII":-1033,"BKAK":-543,"BOOO":-5591}; + this.TQ3__ = {"BHHH":478,"BHHM":-1073,"BHIH":222,"BHII":-504,"BIIH":-116,"BIII":-105,"BMHI":-863,"BMHM":-464,"BOMH":620,"OHHH":346,"OHHI":1729,"OHII":997,"OHMH":481,"OIHH":623,"OIIH":1344,"OKAK":2792,"OKHH":587,"OKKA":679,"OOHH":110,"OOII":-685}; + this.TQ4__ = {"BHHH":-721,"BHHM":-3604,"BHII":-966,"BIIH":-607,"BIII":-2181,"OAAA":-2763,"OAKK":180,"OHHH":-294,"OHHI":2446,"OHHO":480,"OHIH":-1573,"OIHH":1935,"OIHI":-493,"OIIH":626,"OIII":-4007,"OKAK":-8156}; + this.TW1__ = {"につい":-4681,"東京都":2026}; + this.TW2__ = {"ある程":-2049,"いった":-1256,"ころが":-2434,"しょう":3873,"その後":-4430,"だって":-1049,"ていた":1833,"として":-4657,"ともに":-4517,"もので":1882,"一気に":-792,"初めて":-1512,"同時に":-8097,"大きな":-1255,"対して":-2721,"社会党":-3216}; + this.TW3__ = {"いただ":-1734,"してい":1314,"として":-4314,"につい":-5483,"にとっ":-5989,"に当た":-6247,"ので,":-727,"ので、":-727,"のもの":-600,"れから":-3752,"十二月":-2287}; + this.TW4__ = {"いう.":8576,"いう。":8576,"からな":-2348,"してい":2958,"たが,":1516,"たが、":1516,"ている":1538,"という":1349,"ました":5543,"ません":1097,"ようと":-4258,"よると":5865}; + this.UC1__ = {"A":484,"K":93,"M":645,"O":-505}; + this.UC2__ = {"A":819,"H":1059,"I":409,"M":3987,"N":5775,"O":646}; + this.UC3__ = {"A":-1370,"I":2311}; + this.UC4__ = {"A":-2643,"H":1809,"I":-1032,"K":-3450,"M":3565,"N":3876,"O":6646}; + this.UC5__ = {"H":313,"I":-1238,"K":-799,"M":539,"O":-831}; + this.UC6__ = {"H":-506,"I":-253,"K":87,"M":247,"O":-387}; + this.UP1__ = {"O":-214}; + this.UP2__ = {"B":69,"O":935}; + this.UP3__ = {"B":189}; + this.UQ1__ = {"BH":21,"BI":-12,"BK":-99,"BN":142,"BO":-56,"OH":-95,"OI":477,"OK":410,"OO":-2422}; + this.UQ2__ = {"BH":216,"BI":113,"OK":1759}; + this.UQ3__ = {"BA":-479,"BH":42,"BI":1913,"BK":-7198,"BM":3160,"BN":6427,"BO":14761,"OI":-827,"ON":-3212}; + this.UW1__ = {",":156,"、":156,"「":-463,"あ":-941,"う":-127,"が":-553,"き":121,"こ":505,"で":-201,"と":-547,"ど":-123,"に":-789,"の":-185,"は":-847,"も":-466,"や":-470,"よ":182,"ら":-292,"り":208,"れ":169,"を":-446,"ん":-137,"・":-135,"主":-402,"京":-268,"区":-912,"午":871,"国":-460,"大":561,"委":729,"市":-411,"日":-141,"理":361,"生":-408,"県":-386,"都":-718,"「":-463,"・":-135}; + this.UW2__ = {",":-829,"、":-829,"〇":892,"「":-645,"」":3145,"あ":-538,"い":505,"う":134,"お":-502,"か":1454,"が":-856,"く":-412,"こ":1141,"さ":878,"ざ":540,"し":1529,"す":-675,"せ":300,"そ":-1011,"た":188,"だ":1837,"つ":-949,"て":-291,"で":-268,"と":-981,"ど":1273,"な":1063,"に":-1764,"の":130,"は":-409,"ひ":-1273,"べ":1261,"ま":600,"も":-1263,"や":-402,"よ":1639,"り":-579,"る":-694,"れ":571,"を":-2516,"ん":2095,"ア":-587,"カ":306,"キ":568,"ッ":831,"三":-758,"不":-2150,"世":-302,"中":-968,"主":-861,"事":492,"人":-123,"会":978,"保":362,"入":548,"初":-3025,"副":-1566,"北":-3414,"区":-422,"大":-1769,"天":-865,"太":-483,"子":-1519,"学":760,"実":1023,"小":-2009,"市":-813,"年":-1060,"強":1067,"手":-1519,"揺":-1033,"政":1522,"文":-1355,"新":-1682,"日":-1815,"明":-1462,"最":-630,"朝":-1843,"本":-1650,"東":-931,"果":-665,"次":-2378,"民":-180,"気":-1740,"理":752,"発":529,"目":-1584,"相":-242,"県":-1165,"立":-763,"第":810,"米":509,"自":-1353,"行":838,"西":-744,"見":-3874,"調":1010,"議":1198,"込":3041,"開":1758,"間":-1257,"「":-645,"」":3145,"ッ":831,"ア":-587,"カ":306,"キ":568}; + this.UW3__ = {",":4889,"1":-800,"−":-1723,"、":4889,"々":-2311,"〇":5827,"」":2670,"〓":-3573,"あ":-2696,"い":1006,"う":2342,"え":1983,"お":-4864,"か":-1163,"が":3271,"く":1004,"け":388,"げ":401,"こ":-3552,"ご":-3116,"さ":-1058,"し":-395,"す":584,"せ":3685,"そ":-5228,"た":842,"ち":-521,"っ":-1444,"つ":-1081,"て":6167,"で":2318,"と":1691,"ど":-899,"な":-2788,"に":2745,"の":4056,"は":4555,"ひ":-2171,"ふ":-1798,"へ":1199,"ほ":-5516,"ま":-4384,"み":-120,"め":1205,"も":2323,"や":-788,"よ":-202,"ら":727,"り":649,"る":5905,"れ":2773,"わ":-1207,"を":6620,"ん":-518,"ア":551,"グ":1319,"ス":874,"ッ":-1350,"ト":521,"ム":1109,"ル":1591,"ロ":2201,"ン":278,"・":-3794,"一":-1619,"下":-1759,"世":-2087,"両":3815,"中":653,"主":-758,"予":-1193,"二":974,"人":2742,"今":792,"他":1889,"以":-1368,"低":811,"何":4265,"作":-361,"保":-2439,"元":4858,"党":3593,"全":1574,"公":-3030,"六":755,"共":-1880,"円":5807,"再":3095,"分":457,"初":2475,"別":1129,"前":2286,"副":4437,"力":365,"動":-949,"務":-1872,"化":1327,"北":-1038,"区":4646,"千":-2309,"午":-783,"協":-1006,"口":483,"右":1233,"各":3588,"合":-241,"同":3906,"和":-837,"員":4513,"国":642,"型":1389,"場":1219,"外":-241,"妻":2016,"学":-1356,"安":-423,"実":-1008,"家":1078,"小":-513,"少":-3102,"州":1155,"市":3197,"平":-1804,"年":2416,"広":-1030,"府":1605,"度":1452,"建":-2352,"当":-3885,"得":1905,"思":-1291,"性":1822,"戸":-488,"指":-3973,"政":-2013,"教":-1479,"数":3222,"文":-1489,"新":1764,"日":2099,"旧":5792,"昨":-661,"時":-1248,"曜":-951,"最":-937,"月":4125,"期":360,"李":3094,"村":364,"東":-805,"核":5156,"森":2438,"業":484,"氏":2613,"民":-1694,"決":-1073,"法":1868,"海":-495,"無":979,"物":461,"特":-3850,"生":-273,"用":914,"町":1215,"的":7313,"直":-1835,"省":792,"県":6293,"知":-1528,"私":4231,"税":401,"立":-960,"第":1201,"米":7767,"系":3066,"約":3663,"級":1384,"統":-4229,"総":1163,"線":1255,"者":6457,"能":725,"自":-2869,"英":785,"見":1044,"調":-562,"財":-733,"費":1777,"車":1835,"軍":1375,"込":-1504,"通":-1136,"選":-681,"郎":1026,"郡":4404,"部":1200,"金":2163,"長":421,"開":-1432,"間":1302,"関":-1282,"雨":2009,"電":-1045,"非":2066,"駅":1620,"1":-800,"」":2670,"・":-3794,"ッ":-1350,"ア":551,"グ":1319,"ス":874,"ト":521,"ム":1109,"ル":1591,"ロ":2201,"ン":278}; + this.UW4__ = {",":3930,".":3508,"―":-4841,"、":3930,"。":3508,"〇":4999,"「":1895,"」":3798,"〓":-5156,"あ":4752,"い":-3435,"う":-640,"え":-2514,"お":2405,"か":530,"が":6006,"き":-4482,"ぎ":-3821,"く":-3788,"け":-4376,"げ":-4734,"こ":2255,"ご":1979,"さ":2864,"し":-843,"じ":-2506,"す":-731,"ず":1251,"せ":181,"そ":4091,"た":5034,"だ":5408,"ち":-3654,"っ":-5882,"つ":-1659,"て":3994,"で":7410,"と":4547,"な":5433,"に":6499,"ぬ":1853,"ね":1413,"の":7396,"は":8578,"ば":1940,"ひ":4249,"び":-4134,"ふ":1345,"へ":6665,"べ":-744,"ほ":1464,"ま":1051,"み":-2082,"む":-882,"め":-5046,"も":4169,"ゃ":-2666,"や":2795,"ょ":-1544,"よ":3351,"ら":-2922,"り":-9726,"る":-14896,"れ":-2613,"ろ":-4570,"わ":-1783,"を":13150,"ん":-2352,"カ":2145,"コ":1789,"セ":1287,"ッ":-724,"ト":-403,"メ":-1635,"ラ":-881,"リ":-541,"ル":-856,"ン":-3637,"・":-4371,"ー":-11870,"一":-2069,"中":2210,"予":782,"事":-190,"井":-1768,"人":1036,"以":544,"会":950,"体":-1286,"作":530,"側":4292,"先":601,"党":-2006,"共":-1212,"内":584,"円":788,"初":1347,"前":1623,"副":3879,"力":-302,"動":-740,"務":-2715,"化":776,"区":4517,"協":1013,"参":1555,"合":-1834,"和":-681,"員":-910,"器":-851,"回":1500,"国":-619,"園":-1200,"地":866,"場":-1410,"塁":-2094,"士":-1413,"多":1067,"大":571,"子":-4802,"学":-1397,"定":-1057,"寺":-809,"小":1910,"屋":-1328,"山":-1500,"島":-2056,"川":-2667,"市":2771,"年":374,"庁":-4556,"後":456,"性":553,"感":916,"所":-1566,"支":856,"改":787,"政":2182,"教":704,"文":522,"方":-856,"日":1798,"時":1829,"最":845,"月":-9066,"木":-485,"来":-442,"校":-360,"業":-1043,"氏":5388,"民":-2716,"気":-910,"沢":-939,"済":-543,"物":-735,"率":672,"球":-1267,"生":-1286,"産":-1101,"田":-2900,"町":1826,"的":2586,"目":922,"省":-3485,"県":2997,"空":-867,"立":-2112,"第":788,"米":2937,"系":786,"約":2171,"経":1146,"統":-1169,"総":940,"線":-994,"署":749,"者":2145,"能":-730,"般":-852,"行":-792,"規":792,"警":-1184,"議":-244,"谷":-1000,"賞":730,"車":-1481,"軍":1158,"輪":-1433,"込":-3370,"近":929,"道":-1291,"選":2596,"郎":-4866,"都":1192,"野":-1100,"銀":-2213,"長":357,"間":-2344,"院":-2297,"際":-2604,"電":-878,"領":-1659,"題":-792,"館":-1984,"首":1749,"高":2120,"「":1895,"」":3798,"・":-4371,"ッ":-724,"ー":-11870,"カ":2145,"コ":1789,"セ":1287,"ト":-403,"メ":-1635,"ラ":-881,"リ":-541,"ル":-856,"ン":-3637}; + this.UW5__ = {",":465,".":-299,"1":-514,"E2":-32768,"]":-2762,"、":465,"。":-299,"「":363,"あ":1655,"い":331,"う":-503,"え":1199,"お":527,"か":647,"が":-421,"き":1624,"ぎ":1971,"く":312,"げ":-983,"さ":-1537,"し":-1371,"す":-852,"だ":-1186,"ち":1093,"っ":52,"つ":921,"て":-18,"で":-850,"と":-127,"ど":1682,"な":-787,"に":-1224,"の":-635,"は":-578,"べ":1001,"み":502,"め":865,"ゃ":3350,"ょ":854,"り":-208,"る":429,"れ":504,"わ":419,"を":-1264,"ん":327,"イ":241,"ル":451,"ン":-343,"中":-871,"京":722,"会":-1153,"党":-654,"務":3519,"区":-901,"告":848,"員":2104,"大":-1296,"学":-548,"定":1785,"嵐":-1304,"市":-2991,"席":921,"年":1763,"思":872,"所":-814,"挙":1618,"新":-1682,"日":218,"月":-4353,"査":932,"格":1356,"機":-1508,"氏":-1347,"田":240,"町":-3912,"的":-3149,"相":1319,"省":-1052,"県":-4003,"研":-997,"社":-278,"空":-813,"統":1955,"者":-2233,"表":663,"語":-1073,"議":1219,"選":-1018,"郎":-368,"長":786,"間":1191,"題":2368,"館":-689,"1":-514,"E2":-32768,"「":363,"イ":241,"ル":451,"ン":-343}; + this.UW6__ = {",":227,".":808,"1":-270,"E1":306,"、":227,"。":808,"あ":-307,"う":189,"か":241,"が":-73,"く":-121,"こ":-200,"じ":1782,"す":383,"た":-428,"っ":573,"て":-1014,"で":101,"と":-105,"な":-253,"に":-149,"の":-417,"は":-236,"も":-206,"り":187,"る":-135,"を":195,"ル":-673,"ン":-496,"一":-277,"中":201,"件":-800,"会":624,"前":302,"区":1792,"員":-1212,"委":798,"学":-960,"市":887,"広":-695,"後":535,"業":-697,"相":753,"社":-507,"福":974,"空":-822,"者":1811,"連":463,"郎":1082,"1":-270,"E1":306,"ル":-673,"ン":-496}; + + return this; + } + TinySegmenter.prototype.ctype_ = function(str) { + for (var i in this.chartype_) { + if (str.match(this.chartype_[i][0])) { + return this.chartype_[i][1]; + } + } + return "O"; + } + + TinySegmenter.prototype.ts_ = function(v) { + if (v) { return v; } + return 0; + } + + TinySegmenter.prototype.segment = function(input) { + if (input == null || input == undefined || input == "") { + return []; + } + var result = []; + var seg = ["B3","B2","B1"]; + var ctype = ["O","O","O"]; + var o = input.split(""); + for (i = 0; i < o.length; ++i) { + seg.push(o[i]); + ctype.push(this.ctype_(o[i])) + } + seg.push("E1"); + seg.push("E2"); + seg.push("E3"); + ctype.push("O"); + ctype.push("O"); + ctype.push("O"); + var word = seg[3]; + var p1 = "U"; + var p2 = "U"; + var p3 = "U"; + for (var i = 4; i < seg.length - 3; ++i) { + var score = this.BIAS__; + var w1 = seg[i-3]; + var w2 = seg[i-2]; + var w3 = seg[i-1]; + var w4 = seg[i]; + var w5 = seg[i+1]; + var w6 = seg[i+2]; + var c1 = ctype[i-3]; + var c2 = ctype[i-2]; + var c3 = ctype[i-1]; + var c4 = ctype[i]; + var c5 = ctype[i+1]; + var c6 = ctype[i+2]; + score += this.ts_(this.UP1__[p1]); + score += this.ts_(this.UP2__[p2]); + score += this.ts_(this.UP3__[p3]); + score += this.ts_(this.BP1__[p1 + p2]); + score += this.ts_(this.BP2__[p2 + p3]); + score += this.ts_(this.UW1__[w1]); + score += this.ts_(this.UW2__[w2]); + score += this.ts_(this.UW3__[w3]); + score += this.ts_(this.UW4__[w4]); + score += this.ts_(this.UW5__[w5]); + score += this.ts_(this.UW6__[w6]); + score += this.ts_(this.BW1__[w2 + w3]); + score += this.ts_(this.BW2__[w3 + w4]); + score += this.ts_(this.BW3__[w4 + w5]); + score += this.ts_(this.TW1__[w1 + w2 + w3]); + score += this.ts_(this.TW2__[w2 + w3 + w4]); + score += this.ts_(this.TW3__[w3 + w4 + w5]); + score += this.ts_(this.TW4__[w4 + w5 + w6]); + score += this.ts_(this.UC1__[c1]); + score += this.ts_(this.UC2__[c2]); + score += this.ts_(this.UC3__[c3]); + score += this.ts_(this.UC4__[c4]); + score += this.ts_(this.UC5__[c5]); + score += this.ts_(this.UC6__[c6]); + score += this.ts_(this.BC1__[c2 + c3]); + score += this.ts_(this.BC2__[c3 + c4]); + score += this.ts_(this.BC3__[c4 + c5]); + score += this.ts_(this.TC1__[c1 + c2 + c3]); + score += this.ts_(this.TC2__[c2 + c3 + c4]); + score += this.ts_(this.TC3__[c3 + c4 + c5]); + score += this.ts_(this.TC4__[c4 + c5 + c6]); + // score += this.ts_(this.TC5__[c4 + c5 + c6]); + score += this.ts_(this.UQ1__[p1 + c1]); + score += this.ts_(this.UQ2__[p2 + c2]); + score += this.ts_(this.UQ3__[p3 + c3]); + score += this.ts_(this.BQ1__[p2 + c2 + c3]); + score += this.ts_(this.BQ2__[p2 + c3 + c4]); + score += this.ts_(this.BQ3__[p3 + c2 + c3]); + score += this.ts_(this.BQ4__[p3 + c3 + c4]); + score += this.ts_(this.TQ1__[p2 + c1 + c2 + c3]); + score += this.ts_(this.TQ2__[p2 + c2 + c3 + c4]); + score += this.ts_(this.TQ3__[p3 + c1 + c2 + c3]); + score += this.ts_(this.TQ4__[p3 + c2 + c3 + c4]); + var p = "O"; + if (score > 0) { + result.push(word); + word = ""; + p = "B"; + } + p1 = p2; + p2 = p3; + p3 = p; + word += seg[i]; + } + result.push(word); + + return result; + } + + lunr.TinySegmenter = TinySegmenter; + }; + +})); \ No newline at end of file diff --git a/assets/javascripts/lunr/wordcut.js b/assets/javascripts/lunr/wordcut.js new file mode 100644 index 00000000..0d898c9e --- /dev/null +++ b/assets/javascripts/lunr/wordcut.js @@ -0,0 +1,6708 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}(g.lunr || (g.lunr = {})).wordcut = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 1; + }) + this.addWords(words, false) + } + if(finalize){ + this.finalizeDict(); + } + }, + + dictSeek: function (l, r, ch, strOffset, pos) { + var ans = null; + while (l <= r) { + var m = Math.floor((l + r) / 2), + dict_item = this.dict[m], + len = dict_item.length; + if (len <= strOffset) { + l = m + 1; + } else { + var ch_ = dict_item[strOffset]; + if (ch_ < ch) { + l = m + 1; + } else if (ch_ > ch) { + r = m - 1; + } else { + ans = m; + if (pos == LEFT) { + r = m - 1; + } else { + l = m + 1; + } + } + } + } + return ans; + }, + + isFinal: function (acceptor) { + return this.dict[acceptor.l].length == acceptor.strOffset; + }, + + createAcceptor: function () { + return { + l: 0, + r: this.dict.length - 1, + strOffset: 0, + isFinal: false, + dict: this, + transit: function (ch) { + return this.dict.transit(this, ch); + }, + isError: false, + tag: "DICT", + w: 1, + type: "DICT" + }; + }, + + transit: function (acceptor, ch) { + var l = this.dictSeek(acceptor.l, + acceptor.r, + ch, + acceptor.strOffset, + LEFT); + if (l !== null) { + var r = this.dictSeek(l, + acceptor.r, + ch, + acceptor.strOffset, + RIGHT); + acceptor.l = l; + acceptor.r = r; + acceptor.strOffset++; + acceptor.isFinal = this.isFinal(acceptor); + } else { + acceptor.isError = true; + } + return acceptor; + }, + + sortuniq: function(a){ + return a.sort().filter(function(item, pos, arr){ + return !pos || item != arr[pos - 1]; + }) + }, + + flatten: function(a){ + //[[1,2],[3]] -> [1,2,3] + return [].concat.apply([], a); + } +}; +module.exports = WordcutDict; + +}).call(this,"/dist/tmp") +},{"glob":16,"path":22}],3:[function(require,module,exports){ +var WordRule = { + createAcceptor: function(tag) { + if (tag["WORD_RULE"]) + return null; + + return {strOffset: 0, + isFinal: false, + transit: function(ch) { + var lch = ch.toLowerCase(); + if (lch >= "a" && lch <= "z") { + this.isFinal = true; + this.strOffset++; + } else { + this.isError = true; + } + return this; + }, + isError: false, + tag: "WORD_RULE", + type: "WORD_RULE", + w: 1}; + } +}; + +var NumberRule = { + createAcceptor: function(tag) { + if (tag["NUMBER_RULE"]) + return null; + + return {strOffset: 0, + isFinal: false, + transit: function(ch) { + if (ch >= "0" && ch <= "9") { + this.isFinal = true; + this.strOffset++; + } else { + this.isError = true; + } + return this; + }, + isError: false, + tag: "NUMBER_RULE", + type: "NUMBER_RULE", + w: 1}; + } +}; + +var SpaceRule = { + tag: "SPACE_RULE", + createAcceptor: function(tag) { + + if (tag["SPACE_RULE"]) + return null; + + return {strOffset: 0, + isFinal: false, + transit: function(ch) { + if (ch == " " || ch == "\t" || ch == "\r" || ch == "\n" || + ch == "\u00A0" || ch=="\u2003"//nbsp and emsp + ) { + this.isFinal = true; + this.strOffset++; + } else { + this.isError = true; + } + return this; + }, + isError: false, + tag: SpaceRule.tag, + w: 1, + type: "SPACE_RULE"}; + } +} + +var SingleSymbolRule = { + tag: "SINSYM", + createAcceptor: function(tag) { + return {strOffset: 0, + isFinal: false, + transit: function(ch) { + if (this.strOffset == 0 && ch.match(/^[\@\(\)\/\,\-\."`]$/)) { + this.isFinal = true; + this.strOffset++; + } else { + this.isError = true; + } + return this; + }, + isError: false, + tag: "SINSYM", + w: 1, + type: "SINSYM"}; + } +} + + +var LatinRules = [WordRule, SpaceRule, SingleSymbolRule, NumberRule]; + +module.exports = LatinRules; + +},{}],4:[function(require,module,exports){ +var _ = require("underscore") + , WordcutCore = require("./wordcut_core"); +var PathInfoBuilder = { + + /* + buildByPartAcceptors: function(path, acceptors, i) { + var + var genInfos = partAcceptors.reduce(function(genInfos, acceptor) { + + }, []); + + return genInfos; + } + */ + + buildByAcceptors: function(path, finalAcceptors, i) { + var self = this; + var infos = finalAcceptors.map(function(acceptor) { + var p = i - acceptor.strOffset + 1 + , _info = path[p]; + + var info = {p: p, + mw: _info.mw + (acceptor.mw === undefined ? 0 : acceptor.mw), + w: acceptor.w + _info.w, + unk: (acceptor.unk ? acceptor.unk : 0) + _info.unk, + type: acceptor.type}; + + if (acceptor.type == "PART") { + for(var j = p + 1; j <= i; j++) { + path[j].merge = p; + } + info.merge = p; + } + + return info; + }); + return infos.filter(function(info) { return info; }); + }, + + fallback: function(path, leftBoundary, text, i) { + var _info = path[leftBoundary]; + if (text[i].match(/[\u0E48-\u0E4E]/)) { + if (leftBoundary != 0) + leftBoundary = path[leftBoundary].p; + return {p: leftBoundary, + mw: 0, + w: 1 + _info.w, + unk: 1 + _info.unk, + type: "UNK"}; +/* } else if(leftBoundary > 0 && path[leftBoundary].type !== "UNK") { + leftBoundary = path[leftBoundary].p; + return {p: leftBoundary, + w: 1 + _info.w, + unk: 1 + _info.unk, + type: "UNK"}; */ + } else { + return {p: leftBoundary, + mw: _info.mw, + w: 1 + _info.w, + unk: 1 + _info.unk, + type: "UNK"}; + } + }, + + build: function(path, finalAcceptors, i, leftBoundary, text) { + var basicPathInfos = this.buildByAcceptors(path, finalAcceptors, i); + if (basicPathInfos.length > 0) { + return basicPathInfos; + } else { + return [this.fallback(path, leftBoundary, text, i)]; + } + } +}; + +module.exports = function() { + return _.clone(PathInfoBuilder); +} + +},{"./wordcut_core":8,"underscore":25}],5:[function(require,module,exports){ +var _ = require("underscore"); + + +var PathSelector = { + selectPath: function(paths) { + var path = paths.reduce(function(selectedPath, path) { + if (selectedPath == null) { + return path; + } else { + if (path.unk < selectedPath.unk) + return path; + if (path.unk == selectedPath.unk) { + if (path.mw < selectedPath.mw) + return path + if (path.mw == selectedPath.mw) { + if (path.w < selectedPath.w) + return path; + } + } + return selectedPath; + } + }, null); + return path; + }, + + createPath: function() { + return [{p:null, w:0, unk:0, type: "INIT", mw:0}]; + } +}; + +module.exports = function() { + return _.clone(PathSelector); +}; + +},{"underscore":25}],6:[function(require,module,exports){ +function isMatch(pat, offset, ch) { + if (pat.length <= offset) + return false; + var _ch = pat[offset]; + return _ch == ch || + (_ch.match(/[กข]/) && ch.match(/[ก-ฮ]/)) || + (_ch.match(/[มบ]/) && ch.match(/[ก-ฮ]/)) || + (_ch.match(/\u0E49/) && ch.match(/[\u0E48-\u0E4B]/)); +} + +var Rule0 = { + pat: "เหก็ม", + createAcceptor: function(tag) { + return {strOffset: 0, + isFinal: false, + transit: function(ch) { + if (isMatch(Rule0.pat, this.strOffset,ch)) { + this.isFinal = (this.strOffset + 1 == Rule0.pat.length); + this.strOffset++; + } else { + this.isError = true; + } + return this; + }, + isError: false, + tag: "THAI_RULE", + type: "THAI_RULE", + w: 1}; + } +}; + +var PartRule = { + createAcceptor: function(tag) { + return {strOffset: 0, + patterns: [ + "แก", "เก", "ก้", "กก์", "กา", "กี", "กิ", "กืก" + ], + isFinal: false, + transit: function(ch) { + var offset = this.strOffset; + this.patterns = this.patterns.filter(function(pat) { + return isMatch(pat, offset, ch); + }); + + if (this.patterns.length > 0) { + var len = 1 + offset; + this.isFinal = this.patterns.some(function(pat) { + return pat.length == len; + }); + this.strOffset++; + } else { + this.isError = true; + } + return this; + }, + isError: false, + tag: "PART", + type: "PART", + unk: 1, + w: 1}; + } +}; + +var ThaiRules = [Rule0, PartRule]; + +module.exports = ThaiRules; + +},{}],7:[function(require,module,exports){ +var sys = require("sys") + , WordcutDict = require("./dict") + , WordcutCore = require("./wordcut_core") + , PathInfoBuilder = require("./path_info_builder") + , PathSelector = require("./path_selector") + , Acceptors = require("./acceptors") + , latinRules = require("./latin_rules") + , thaiRules = require("./thai_rules") + , _ = require("underscore"); + + +var Wordcut = Object.create(WordcutCore); +Wordcut.defaultPathInfoBuilder = PathInfoBuilder; +Wordcut.defaultPathSelector = PathSelector; +Wordcut.defaultAcceptors = Acceptors; +Wordcut.defaultLatinRules = latinRules; +Wordcut.defaultThaiRules = thaiRules; +Wordcut.defaultDict = WordcutDict; + + +Wordcut.initNoDict = function(dict_path) { + var self = this; + self.pathInfoBuilder = new self.defaultPathInfoBuilder; + self.pathSelector = new self.defaultPathSelector; + self.acceptors = new self.defaultAcceptors; + self.defaultLatinRules.forEach(function(rule) { + self.acceptors.creators.push(rule); + }); + self.defaultThaiRules.forEach(function(rule) { + self.acceptors.creators.push(rule); + }); +}; + +Wordcut.init = function(dict_path, withDefault, additionalWords) { + withDefault = withDefault || false; + this.initNoDict(); + var dict = _.clone(this.defaultDict); + dict.init(dict_path, withDefault, additionalWords); + this.acceptors.creators.push(dict); +}; + +module.exports = Wordcut; + +},{"./acceptors":1,"./dict":2,"./latin_rules":3,"./path_info_builder":4,"./path_selector":5,"./thai_rules":6,"./wordcut_core":8,"sys":28,"underscore":25}],8:[function(require,module,exports){ +var WordcutCore = { + + buildPath: function(text) { + var self = this + , path = self.pathSelector.createPath() + , leftBoundary = 0; + self.acceptors.reset(); + for (var i = 0; i < text.length; i++) { + var ch = text[i]; + self.acceptors.transit(ch); + + var possiblePathInfos = self + .pathInfoBuilder + .build(path, + self.acceptors.getFinalAcceptors(), + i, + leftBoundary, + text); + var selectedPath = self.pathSelector.selectPath(possiblePathInfos) + + path.push(selectedPath); + if (selectedPath.type !== "UNK") { + leftBoundary = i; + } + } + return path; + }, + + pathToRanges: function(path) { + var e = path.length - 1 + , ranges = []; + + while (e > 0) { + var info = path[e] + , s = info.p; + + if (info.merge !== undefined && ranges.length > 0) { + var r = ranges[ranges.length - 1]; + r.s = info.merge; + s = r.s; + } else { + ranges.push({s:s, e:e}); + } + e = s; + } + return ranges.reverse(); + }, + + rangesToText: function(text, ranges, delimiter) { + return ranges.map(function(r) { + return text.substring(r.s, r.e); + }).join(delimiter); + }, + + cut: function(text, delimiter) { + var path = this.buildPath(text) + , ranges = this.pathToRanges(path); + return this + .rangesToText(text, ranges, + (delimiter === undefined ? "|" : delimiter)); + }, + + cutIntoRanges: function(text, noText) { + var path = this.buildPath(text) + , ranges = this.pathToRanges(path); + + if (!noText) { + ranges.forEach(function(r) { + r.text = text.substring(r.s, r.e); + }); + } + return ranges; + }, + + cutIntoArray: function(text) { + var path = this.buildPath(text) + , ranges = this.pathToRanges(path); + + return ranges.map(function(r) { + return text.substring(r.s, r.e) + }); + } +}; + +module.exports = WordcutCore; + +},{}],9:[function(require,module,exports){ +// http://wiki.commonjs.org/wiki/Unit_Testing/1.0 +// +// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8! +// +// Originally from narwhal.js (http://narwhaljs.org) +// Copyright (c) 2009 Thomas Robinson <280north.com> +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the 'Software'), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +// when used in node, this will actually load the util module we depend on +// versus loading the builtin util module as happens otherwise +// this is a bug in node module loading as far as I am concerned +var util = require('util/'); + +var pSlice = Array.prototype.slice; +var hasOwn = Object.prototype.hasOwnProperty; + +// 1. The assert module provides functions that throw +// AssertionError's when particular conditions are not met. The +// assert module must conform to the following interface. + +var assert = module.exports = ok; + +// 2. The AssertionError is defined in assert. +// new assert.AssertionError({ message: message, +// actual: actual, +// expected: expected }) + +assert.AssertionError = function AssertionError(options) { + this.name = 'AssertionError'; + this.actual = options.actual; + this.expected = options.expected; + this.operator = options.operator; + if (options.message) { + this.message = options.message; + this.generatedMessage = false; + } else { + this.message = getMessage(this); + this.generatedMessage = true; + } + var stackStartFunction = options.stackStartFunction || fail; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, stackStartFunction); + } + else { + // non v8 browsers so we can have a stacktrace + var err = new Error(); + if (err.stack) { + var out = err.stack; + + // try to strip useless frames + var fn_name = stackStartFunction.name; + var idx = out.indexOf('\n' + fn_name); + if (idx >= 0) { + // once we have located the function frame + // we need to strip out everything before it (and its line) + var next_line = out.indexOf('\n', idx + 1); + out = out.substring(next_line + 1); + } + + this.stack = out; + } + } +}; + +// assert.AssertionError instanceof Error +util.inherits(assert.AssertionError, Error); + +function replacer(key, value) { + if (util.isUndefined(value)) { + return '' + value; + } + if (util.isNumber(value) && !isFinite(value)) { + return value.toString(); + } + if (util.isFunction(value) || util.isRegExp(value)) { + return value.toString(); + } + return value; +} + +function truncate(s, n) { + if (util.isString(s)) { + return s.length < n ? s : s.slice(0, n); + } else { + return s; + } +} + +function getMessage(self) { + return truncate(JSON.stringify(self.actual, replacer), 128) + ' ' + + self.operator + ' ' + + truncate(JSON.stringify(self.expected, replacer), 128); +} + +// At present only the three keys mentioned above are used and +// understood by the spec. Implementations or sub modules can pass +// other keys to the AssertionError's constructor - they will be +// ignored. + +// 3. All of the following functions must throw an AssertionError +// when a corresponding condition is not met, with a message that +// may be undefined if not provided. All assertion methods provide +// both the actual and expected values to the assertion error for +// display purposes. + +function fail(actual, expected, message, operator, stackStartFunction) { + throw new assert.AssertionError({ + message: message, + actual: actual, + expected: expected, + operator: operator, + stackStartFunction: stackStartFunction + }); +} + +// EXTENSION! allows for well behaved errors defined elsewhere. +assert.fail = fail; + +// 4. Pure assertion tests whether a value is truthy, as determined +// by !!guard. +// assert.ok(guard, message_opt); +// This statement is equivalent to assert.equal(true, !!guard, +// message_opt);. To test strictly for the value true, use +// assert.strictEqual(true, guard, message_opt);. + +function ok(value, message) { + if (!value) fail(value, true, message, '==', assert.ok); +} +assert.ok = ok; + +// 5. The equality assertion tests shallow, coercive equality with +// ==. +// assert.equal(actual, expected, message_opt); + +assert.equal = function equal(actual, expected, message) { + if (actual != expected) fail(actual, expected, message, '==', assert.equal); +}; + +// 6. The non-equality assertion tests for whether two objects are not equal +// with != assert.notEqual(actual, expected, message_opt); + +assert.notEqual = function notEqual(actual, expected, message) { + if (actual == expected) { + fail(actual, expected, message, '!=', assert.notEqual); + } +}; + +// 7. The equivalence assertion tests a deep equality relation. +// assert.deepEqual(actual, expected, message_opt); + +assert.deepEqual = function deepEqual(actual, expected, message) { + if (!_deepEqual(actual, expected)) { + fail(actual, expected, message, 'deepEqual', assert.deepEqual); + } +}; + +function _deepEqual(actual, expected) { + // 7.1. All identical values are equivalent, as determined by ===. + if (actual === expected) { + return true; + + } else if (util.isBuffer(actual) && util.isBuffer(expected)) { + if (actual.length != expected.length) return false; + + for (var i = 0; i < actual.length; i++) { + if (actual[i] !== expected[i]) return false; + } + + return true; + + // 7.2. If the expected value is a Date object, the actual value is + // equivalent if it is also a Date object that refers to the same time. + } else if (util.isDate(actual) && util.isDate(expected)) { + return actual.getTime() === expected.getTime(); + + // 7.3 If the expected value is a RegExp object, the actual value is + // equivalent if it is also a RegExp object with the same source and + // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`). + } else if (util.isRegExp(actual) && util.isRegExp(expected)) { + return actual.source === expected.source && + actual.global === expected.global && + actual.multiline === expected.multiline && + actual.lastIndex === expected.lastIndex && + actual.ignoreCase === expected.ignoreCase; + + // 7.4. Other pairs that do not both pass typeof value == 'object', + // equivalence is determined by ==. + } else if (!util.isObject(actual) && !util.isObject(expected)) { + return actual == expected; + + // 7.5 For all other Object pairs, including Array objects, equivalence is + // determined by having the same number of owned properties (as verified + // with Object.prototype.hasOwnProperty.call), the same set of keys + // (although not necessarily the same order), equivalent values for every + // corresponding key, and an identical 'prototype' property. Note: this + // accounts for both named and indexed properties on Arrays. + } else { + return objEquiv(actual, expected); + } +} + +function isArguments(object) { + return Object.prototype.toString.call(object) == '[object Arguments]'; +} + +function objEquiv(a, b) { + if (util.isNullOrUndefined(a) || util.isNullOrUndefined(b)) + return false; + // an identical 'prototype' property. + if (a.prototype !== b.prototype) return false; + // if one is a primitive, the other must be same + if (util.isPrimitive(a) || util.isPrimitive(b)) { + return a === b; + } + var aIsArgs = isArguments(a), + bIsArgs = isArguments(b); + if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs)) + return false; + if (aIsArgs) { + a = pSlice.call(a); + b = pSlice.call(b); + return _deepEqual(a, b); + } + var ka = objectKeys(a), + kb = objectKeys(b), + key, i; + // having the same number of owned properties (keys incorporates + // hasOwnProperty) + if (ka.length != kb.length) + return false; + //the same set of keys (although not necessarily the same order), + ka.sort(); + kb.sort(); + //~~~cheap key test + for (i = ka.length - 1; i >= 0; i--) { + if (ka[i] != kb[i]) + return false; + } + //equivalent values for every corresponding key, and + //~~~possibly expensive deep test + for (i = ka.length - 1; i >= 0; i--) { + key = ka[i]; + if (!_deepEqual(a[key], b[key])) return false; + } + return true; +} + +// 8. The non-equivalence assertion tests for any deep inequality. +// assert.notDeepEqual(actual, expected, message_opt); + +assert.notDeepEqual = function notDeepEqual(actual, expected, message) { + if (_deepEqual(actual, expected)) { + fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual); + } +}; + +// 9. The strict equality assertion tests strict equality, as determined by ===. +// assert.strictEqual(actual, expected, message_opt); + +assert.strictEqual = function strictEqual(actual, expected, message) { + if (actual !== expected) { + fail(actual, expected, message, '===', assert.strictEqual); + } +}; + +// 10. The strict non-equality assertion tests for strict inequality, as +// determined by !==. assert.notStrictEqual(actual, expected, message_opt); + +assert.notStrictEqual = function notStrictEqual(actual, expected, message) { + if (actual === expected) { + fail(actual, expected, message, '!==', assert.notStrictEqual); + } +}; + +function expectedException(actual, expected) { + if (!actual || !expected) { + return false; + } + + if (Object.prototype.toString.call(expected) == '[object RegExp]') { + return expected.test(actual); + } else if (actual instanceof expected) { + return true; + } else if (expected.call({}, actual) === true) { + return true; + } + + return false; +} + +function _throws(shouldThrow, block, expected, message) { + var actual; + + if (util.isString(expected)) { + message = expected; + expected = null; + } + + try { + block(); + } catch (e) { + actual = e; + } + + message = (expected && expected.name ? ' (' + expected.name + ').' : '.') + + (message ? ' ' + message : '.'); + + if (shouldThrow && !actual) { + fail(actual, expected, 'Missing expected exception' + message); + } + + if (!shouldThrow && expectedException(actual, expected)) { + fail(actual, expected, 'Got unwanted exception' + message); + } + + if ((shouldThrow && actual && expected && + !expectedException(actual, expected)) || (!shouldThrow && actual)) { + throw actual; + } +} + +// 11. Expected to throw an error: +// assert.throws(block, Error_opt, message_opt); + +assert.throws = function(block, /*optional*/error, /*optional*/message) { + _throws.apply(this, [true].concat(pSlice.call(arguments))); +}; + +// EXTENSION! This is annoying to write outside this module. +assert.doesNotThrow = function(block, /*optional*/message) { + _throws.apply(this, [false].concat(pSlice.call(arguments))); +}; + +assert.ifError = function(err) { if (err) {throw err;}}; + +var objectKeys = Object.keys || function (obj) { + var keys = []; + for (var key in obj) { + if (hasOwn.call(obj, key)) keys.push(key); + } + return keys; +}; + +},{"util/":28}],10:[function(require,module,exports){ +'use strict'; +module.exports = balanced; +function balanced(a, b, str) { + if (a instanceof RegExp) a = maybeMatch(a, str); + if (b instanceof RegExp) b = maybeMatch(b, str); + + var r = range(a, b, str); + + return r && { + start: r[0], + end: r[1], + pre: str.slice(0, r[0]), + body: str.slice(r[0] + a.length, r[1]), + post: str.slice(r[1] + b.length) + }; +} + +function maybeMatch(reg, str) { + var m = str.match(reg); + return m ? m[0] : null; +} + +balanced.range = range; +function range(a, b, str) { + var begs, beg, left, right, result; + var ai = str.indexOf(a); + var bi = str.indexOf(b, ai + 1); + var i = ai; + + if (ai >= 0 && bi > 0) { + begs = []; + left = str.length; + + while (i >= 0 && !result) { + if (i == ai) { + begs.push(i); + ai = str.indexOf(a, i + 1); + } else if (begs.length == 1) { + result = [ begs.pop(), bi ]; + } else { + beg = begs.pop(); + if (beg < left) { + left = beg; + right = bi; + } + + bi = str.indexOf(b, i + 1); + } + + i = ai < bi && ai >= 0 ? ai : bi; + } + + if (begs.length) { + result = [ left, right ]; + } + } + + return result; +} + +},{}],11:[function(require,module,exports){ +var concatMap = require('concat-map'); +var balanced = require('balanced-match'); + +module.exports = expandTop; + +var escSlash = '\0SLASH'+Math.random()+'\0'; +var escOpen = '\0OPEN'+Math.random()+'\0'; +var escClose = '\0CLOSE'+Math.random()+'\0'; +var escComma = '\0COMMA'+Math.random()+'\0'; +var escPeriod = '\0PERIOD'+Math.random()+'\0'; + +function numeric(str) { + return parseInt(str, 10) == str + ? parseInt(str, 10) + : str.charCodeAt(0); +} + +function escapeBraces(str) { + return str.split('\\\\').join(escSlash) + .split('\\{').join(escOpen) + .split('\\}').join(escClose) + .split('\\,').join(escComma) + .split('\\.').join(escPeriod); +} + +function unescapeBraces(str) { + return str.split(escSlash).join('\\') + .split(escOpen).join('{') + .split(escClose).join('}') + .split(escComma).join(',') + .split(escPeriod).join('.'); +} + + +// Basically just str.split(","), but handling cases +// where we have nested braced sections, which should be +// treated as individual members, like {a,{b,c},d} +function parseCommaParts(str) { + if (!str) + return ['']; + + var parts = []; + var m = balanced('{', '}', str); + + if (!m) + return str.split(','); + + var pre = m.pre; + var body = m.body; + var post = m.post; + var p = pre.split(','); + + p[p.length-1] += '{' + body + '}'; + var postParts = parseCommaParts(post); + if (post.length) { + p[p.length-1] += postParts.shift(); + p.push.apply(p, postParts); + } + + parts.push.apply(parts, p); + + return parts; +} + +function expandTop(str) { + if (!str) + return []; + + // I don't know why Bash 4.3 does this, but it does. + // Anything starting with {} will have the first two bytes preserved + // but *only* at the top level, so {},a}b will not expand to anything, + // but a{},b}c will be expanded to [a}c,abc]. + // One could argue that this is a bug in Bash, but since the goal of + // this module is to match Bash's rules, we escape a leading {} + if (str.substr(0, 2) === '{}') { + str = '\\{\\}' + str.substr(2); + } + + return expand(escapeBraces(str), true).map(unescapeBraces); +} + +function identity(e) { + return e; +} + +function embrace(str) { + return '{' + str + '}'; +} +function isPadded(el) { + return /^-?0\d/.test(el); +} + +function lte(i, y) { + return i <= y; +} +function gte(i, y) { + return i >= y; +} + +function expand(str, isTop) { + var expansions = []; + + var m = balanced('{', '}', str); + if (!m || /\$$/.test(m.pre)) return [str]; + + var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); + var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); + var isSequence = isNumericSequence || isAlphaSequence; + var isOptions = m.body.indexOf(',') >= 0; + if (!isSequence && !isOptions) { + // {a},b} + if (m.post.match(/,.*\}/)) { + str = m.pre + '{' + m.body + escClose + m.post; + return expand(str); + } + return [str]; + } + + var n; + if (isSequence) { + n = m.body.split(/\.\./); + } else { + n = parseCommaParts(m.body); + if (n.length === 1) { + // x{{a,b}}y ==> x{a}y x{b}y + n = expand(n[0], false).map(embrace); + if (n.length === 1) { + var post = m.post.length + ? expand(m.post, false) + : ['']; + return post.map(function(p) { + return m.pre + n[0] + p; + }); + } + } + } + + // at this point, n is the parts, and we know it's not a comma set + // with a single entry. + + // no need to expand pre, since it is guaranteed to be free of brace-sets + var pre = m.pre; + var post = m.post.length + ? expand(m.post, false) + : ['']; + + var N; + + if (isSequence) { + var x = numeric(n[0]); + var y = numeric(n[1]); + var width = Math.max(n[0].length, n[1].length) + var incr = n.length == 3 + ? Math.abs(numeric(n[2])) + : 1; + var test = lte; + var reverse = y < x; + if (reverse) { + incr *= -1; + test = gte; + } + var pad = n.some(isPadded); + + N = []; + + for (var i = x; test(i, y); i += incr) { + var c; + if (isAlphaSequence) { + c = String.fromCharCode(i); + if (c === '\\') + c = ''; + } else { + c = String(i); + if (pad) { + var need = width - c.length; + if (need > 0) { + var z = new Array(need + 1).join('0'); + if (i < 0) + c = '-' + z + c.slice(1); + else + c = z + c; + } + } + } + N.push(c); + } + } else { + N = concatMap(n, function(el) { return expand(el, false) }); + } + + for (var j = 0; j < N.length; j++) { + for (var k = 0; k < post.length; k++) { + var expansion = pre + N[j] + post[k]; + if (!isTop || isSequence || expansion) + expansions.push(expansion); + } + } + + return expansions; +} + + +},{"balanced-match":10,"concat-map":13}],12:[function(require,module,exports){ + +},{}],13:[function(require,module,exports){ +module.exports = function (xs, fn) { + var res = []; + for (var i = 0; i < xs.length; i++) { + var x = fn(xs[i], i); + if (isArray(x)) res.push.apply(res, x); + else res.push(x); + } + return res; +}; + +var isArray = Array.isArray || function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]'; +}; + +},{}],14:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +function EventEmitter() { + this._events = this._events || {}; + this._maxListeners = this._maxListeners || undefined; +} +module.exports = EventEmitter; + +// Backwards-compat with node 0.10.x +EventEmitter.EventEmitter = EventEmitter; + +EventEmitter.prototype._events = undefined; +EventEmitter.prototype._maxListeners = undefined; + +// By default EventEmitters will print a warning if more than 10 listeners are +// added to it. This is a useful default which helps finding memory leaks. +EventEmitter.defaultMaxListeners = 10; + +// Obviously not all Emitters should be limited to 10. This function allows +// that to be increased. Set to zero for unlimited. +EventEmitter.prototype.setMaxListeners = function(n) { + if (!isNumber(n) || n < 0 || isNaN(n)) + throw TypeError('n must be a positive number'); + this._maxListeners = n; + return this; +}; + +EventEmitter.prototype.emit = function(type) { + var er, handler, len, args, i, listeners; + + if (!this._events) + this._events = {}; + + // If there is no 'error' event listener then throw. + if (type === 'error') { + if (!this._events.error || + (isObject(this._events.error) && !this._events.error.length)) { + er = arguments[1]; + if (er instanceof Error) { + throw er; // Unhandled 'error' event + } + throw TypeError('Uncaught, unspecified "error" event.'); + } + } + + handler = this._events[type]; + + if (isUndefined(handler)) + return false; + + if (isFunction(handler)) { + switch (arguments.length) { + // fast cases + case 1: + handler.call(this); + break; + case 2: + handler.call(this, arguments[1]); + break; + case 3: + handler.call(this, arguments[1], arguments[2]); + break; + // slower + default: + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + handler.apply(this, args); + } + } else if (isObject(handler)) { + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + + listeners = handler.slice(); + len = listeners.length; + for (i = 0; i < len; i++) + listeners[i].apply(this, args); + } + + return true; +}; + +EventEmitter.prototype.addListener = function(type, listener) { + var m; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events) + this._events = {}; + + // To avoid recursion in the case that type === "newListener"! Before + // adding it to the listeners, first emit "newListener". + if (this._events.newListener) + this.emit('newListener', type, + isFunction(listener.listener) ? + listener.listener : listener); + + if (!this._events[type]) + // Optimize the case of one listener. Don't need the extra array object. + this._events[type] = listener; + else if (isObject(this._events[type])) + // If we've already got an array, just append. + this._events[type].push(listener); + else + // Adding the second element, need to change to array. + this._events[type] = [this._events[type], listener]; + + // Check for listener leak + if (isObject(this._events[type]) && !this._events[type].warned) { + var m; + if (!isUndefined(this._maxListeners)) { + m = this._maxListeners; + } else { + m = EventEmitter.defaultMaxListeners; + } + + if (m && m > 0 && this._events[type].length > m) { + this._events[type].warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + this._events[type].length); + if (typeof console.trace === 'function') { + // not supported in IE 10 + console.trace(); + } + } + } + + return this; +}; + +EventEmitter.prototype.on = EventEmitter.prototype.addListener; + +EventEmitter.prototype.once = function(type, listener) { + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + var fired = false; + + function g() { + this.removeListener(type, g); + + if (!fired) { + fired = true; + listener.apply(this, arguments); + } + } + + g.listener = listener; + this.on(type, g); + + return this; +}; + +// emits a 'removeListener' event iff the listener was removed +EventEmitter.prototype.removeListener = function(type, listener) { + var list, position, length, i; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events || !this._events[type]) + return this; + + list = this._events[type]; + length = list.length; + position = -1; + + if (list === listener || + (isFunction(list.listener) && list.listener === listener)) { + delete this._events[type]; + if (this._events.removeListener) + this.emit('removeListener', type, listener); + + } else if (isObject(list)) { + for (i = length; i-- > 0;) { + if (list[i] === listener || + (list[i].listener && list[i].listener === listener)) { + position = i; + break; + } + } + + if (position < 0) + return this; + + if (list.length === 1) { + list.length = 0; + delete this._events[type]; + } else { + list.splice(position, 1); + } + + if (this._events.removeListener) + this.emit('removeListener', type, listener); + } + + return this; +}; + +EventEmitter.prototype.removeAllListeners = function(type) { + var key, listeners; + + if (!this._events) + return this; + + // not listening for removeListener, no need to emit + if (!this._events.removeListener) { + if (arguments.length === 0) + this._events = {}; + else if (this._events[type]) + delete this._events[type]; + return this; + } + + // emit removeListener for all listeners on all events + if (arguments.length === 0) { + for (key in this._events) { + if (key === 'removeListener') continue; + this.removeAllListeners(key); + } + this.removeAllListeners('removeListener'); + this._events = {}; + return this; + } + + listeners = this._events[type]; + + if (isFunction(listeners)) { + this.removeListener(type, listeners); + } else { + // LIFO order + while (listeners.length) + this.removeListener(type, listeners[listeners.length - 1]); + } + delete this._events[type]; + + return this; +}; + +EventEmitter.prototype.listeners = function(type) { + var ret; + if (!this._events || !this._events[type]) + ret = []; + else if (isFunction(this._events[type])) + ret = [this._events[type]]; + else + ret = this._events[type].slice(); + return ret; +}; + +EventEmitter.listenerCount = function(emitter, type) { + var ret; + if (!emitter._events || !emitter._events[type]) + ret = 0; + else if (isFunction(emitter._events[type])) + ret = 1; + else + ret = emitter._events[type].length; + return ret; +}; + +function isFunction(arg) { + return typeof arg === 'function'; +} + +function isNumber(arg) { + return typeof arg === 'number'; +} + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} + +function isUndefined(arg) { + return arg === void 0; +} + +},{}],15:[function(require,module,exports){ +(function (process){ +exports.alphasort = alphasort +exports.alphasorti = alphasorti +exports.setopts = setopts +exports.ownProp = ownProp +exports.makeAbs = makeAbs +exports.finish = finish +exports.mark = mark +exports.isIgnored = isIgnored +exports.childrenIgnored = childrenIgnored + +function ownProp (obj, field) { + return Object.prototype.hasOwnProperty.call(obj, field) +} + +var path = require("path") +var minimatch = require("minimatch") +var isAbsolute = require("path-is-absolute") +var Minimatch = minimatch.Minimatch + +function alphasorti (a, b) { + return a.toLowerCase().localeCompare(b.toLowerCase()) +} + +function alphasort (a, b) { + return a.localeCompare(b) +} + +function setupIgnores (self, options) { + self.ignore = options.ignore || [] + + if (!Array.isArray(self.ignore)) + self.ignore = [self.ignore] + + if (self.ignore.length) { + self.ignore = self.ignore.map(ignoreMap) + } +} + +function ignoreMap (pattern) { + var gmatcher = null + if (pattern.slice(-3) === '/**') { + var gpattern = pattern.replace(/(\/\*\*)+$/, '') + gmatcher = new Minimatch(gpattern) + } + + return { + matcher: new Minimatch(pattern), + gmatcher: gmatcher + } +} + +function setopts (self, pattern, options) { + if (!options) + options = {} + + // base-matching: just use globstar for that. + if (options.matchBase && -1 === pattern.indexOf("/")) { + if (options.noglobstar) { + throw new Error("base matching requires globstar") + } + pattern = "**/" + pattern + } + + self.silent = !!options.silent + self.pattern = pattern + self.strict = options.strict !== false + self.realpath = !!options.realpath + self.realpathCache = options.realpathCache || Object.create(null) + self.follow = !!options.follow + self.dot = !!options.dot + self.mark = !!options.mark + self.nodir = !!options.nodir + if (self.nodir) + self.mark = true + self.sync = !!options.sync + self.nounique = !!options.nounique + self.nonull = !!options.nonull + self.nosort = !!options.nosort + self.nocase = !!options.nocase + self.stat = !!options.stat + self.noprocess = !!options.noprocess + + self.maxLength = options.maxLength || Infinity + self.cache = options.cache || Object.create(null) + self.statCache = options.statCache || Object.create(null) + self.symlinks = options.symlinks || Object.create(null) + + setupIgnores(self, options) + + self.changedCwd = false + var cwd = process.cwd() + if (!ownProp(options, "cwd")) + self.cwd = cwd + else { + self.cwd = options.cwd + self.changedCwd = path.resolve(options.cwd) !== cwd + } + + self.root = options.root || path.resolve(self.cwd, "/") + self.root = path.resolve(self.root) + if (process.platform === "win32") + self.root = self.root.replace(/\\/g, "/") + + self.nomount = !!options.nomount + + // disable comments and negation unless the user explicitly + // passes in false as the option. + options.nonegate = options.nonegate === false ? false : true + options.nocomment = options.nocomment === false ? false : true + deprecationWarning(options) + + self.minimatch = new Minimatch(pattern, options) + self.options = self.minimatch.options +} + +// TODO(isaacs): remove entirely in v6 +// exported to reset in tests +exports.deprecationWarned +function deprecationWarning(options) { + if (!options.nonegate || !options.nocomment) { + if (process.noDeprecation !== true && !exports.deprecationWarned) { + var msg = 'glob WARNING: comments and negation will be disabled in v6' + if (process.throwDeprecation) + throw new Error(msg) + else if (process.traceDeprecation) + console.trace(msg) + else + console.error(msg) + + exports.deprecationWarned = true + } + } +} + +function finish (self) { + var nou = self.nounique + var all = nou ? [] : Object.create(null) + + for (var i = 0, l = self.matches.length; i < l; i ++) { + var matches = self.matches[i] + if (!matches || Object.keys(matches).length === 0) { + if (self.nonull) { + // do like the shell, and spit out the literal glob + var literal = self.minimatch.globSet[i] + if (nou) + all.push(literal) + else + all[literal] = true + } + } else { + // had matches + var m = Object.keys(matches) + if (nou) + all.push.apply(all, m) + else + m.forEach(function (m) { + all[m] = true + }) + } + } + + if (!nou) + all = Object.keys(all) + + if (!self.nosort) + all = all.sort(self.nocase ? alphasorti : alphasort) + + // at *some* point we statted all of these + if (self.mark) { + for (var i = 0; i < all.length; i++) { + all[i] = self._mark(all[i]) + } + if (self.nodir) { + all = all.filter(function (e) { + return !(/\/$/.test(e)) + }) + } + } + + if (self.ignore.length) + all = all.filter(function(m) { + return !isIgnored(self, m) + }) + + self.found = all +} + +function mark (self, p) { + var abs = makeAbs(self, p) + var c = self.cache[abs] + var m = p + if (c) { + var isDir = c === 'DIR' || Array.isArray(c) + var slash = p.slice(-1) === '/' + + if (isDir && !slash) + m += '/' + else if (!isDir && slash) + m = m.slice(0, -1) + + if (m !== p) { + var mabs = makeAbs(self, m) + self.statCache[mabs] = self.statCache[abs] + self.cache[mabs] = self.cache[abs] + } + } + + return m +} + +// lotta situps... +function makeAbs (self, f) { + var abs = f + if (f.charAt(0) === '/') { + abs = path.join(self.root, f) + } else if (isAbsolute(f) || f === '') { + abs = f + } else if (self.changedCwd) { + abs = path.resolve(self.cwd, f) + } else { + abs = path.resolve(f) + } + return abs +} + + +// Return true, if pattern ends with globstar '**', for the accompanying parent directory. +// Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents +function isIgnored (self, path) { + if (!self.ignore.length) + return false + + return self.ignore.some(function(item) { + return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path)) + }) +} + +function childrenIgnored (self, path) { + if (!self.ignore.length) + return false + + return self.ignore.some(function(item) { + return !!(item.gmatcher && item.gmatcher.match(path)) + }) +} + +}).call(this,require('_process')) +},{"_process":24,"minimatch":20,"path":22,"path-is-absolute":23}],16:[function(require,module,exports){ +(function (process){ +// Approach: +// +// 1. Get the minimatch set +// 2. For each pattern in the set, PROCESS(pattern, false) +// 3. Store matches per-set, then uniq them +// +// PROCESS(pattern, inGlobStar) +// Get the first [n] items from pattern that are all strings +// Join these together. This is PREFIX. +// If there is no more remaining, then stat(PREFIX) and +// add to matches if it succeeds. END. +// +// If inGlobStar and PREFIX is symlink and points to dir +// set ENTRIES = [] +// else readdir(PREFIX) as ENTRIES +// If fail, END +// +// with ENTRIES +// If pattern[n] is GLOBSTAR +// // handle the case where the globstar match is empty +// // by pruning it out, and testing the resulting pattern +// PROCESS(pattern[0..n] + pattern[n+1 .. $], false) +// // handle other cases. +// for ENTRY in ENTRIES (not dotfiles) +// // attach globstar + tail onto the entry +// // Mark that this entry is a globstar match +// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $], true) +// +// else // not globstar +// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot) +// Test ENTRY against pattern[n] +// If fails, continue +// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $]) +// +// Caveat: +// Cache all stats and readdirs results to minimize syscall. Since all +// we ever care about is existence and directory-ness, we can just keep +// `true` for files, and [children,...] for directories, or `false` for +// things that don't exist. + +module.exports = glob + +var fs = require('fs') +var minimatch = require('minimatch') +var Minimatch = minimatch.Minimatch +var inherits = require('inherits') +var EE = require('events').EventEmitter +var path = require('path') +var assert = require('assert') +var isAbsolute = require('path-is-absolute') +var globSync = require('./sync.js') +var common = require('./common.js') +var alphasort = common.alphasort +var alphasorti = common.alphasorti +var setopts = common.setopts +var ownProp = common.ownProp +var inflight = require('inflight') +var util = require('util') +var childrenIgnored = common.childrenIgnored +var isIgnored = common.isIgnored + +var once = require('once') + +function glob (pattern, options, cb) { + if (typeof options === 'function') cb = options, options = {} + if (!options) options = {} + + if (options.sync) { + if (cb) + throw new TypeError('callback provided to sync glob') + return globSync(pattern, options) + } + + return new Glob(pattern, options, cb) +} + +glob.sync = globSync +var GlobSync = glob.GlobSync = globSync.GlobSync + +// old api surface +glob.glob = glob + +glob.hasMagic = function (pattern, options_) { + var options = util._extend({}, options_) + options.noprocess = true + + var g = new Glob(pattern, options) + var set = g.minimatch.set + if (set.length > 1) + return true + + for (var j = 0; j < set[0].length; j++) { + if (typeof set[0][j] !== 'string') + return true + } + + return false +} + +glob.Glob = Glob +inherits(Glob, EE) +function Glob (pattern, options, cb) { + if (typeof options === 'function') { + cb = options + options = null + } + + if (options && options.sync) { + if (cb) + throw new TypeError('callback provided to sync glob') + return new GlobSync(pattern, options) + } + + if (!(this instanceof Glob)) + return new Glob(pattern, options, cb) + + setopts(this, pattern, options) + this._didRealPath = false + + // process each pattern in the minimatch set + var n = this.minimatch.set.length + + // The matches are stored as {: true,...} so that + // duplicates are automagically pruned. + // Later, we do an Object.keys() on these. + // Keep them as a list so we can fill in when nonull is set. + this.matches = new Array(n) + + if (typeof cb === 'function') { + cb = once(cb) + this.on('error', cb) + this.on('end', function (matches) { + cb(null, matches) + }) + } + + var self = this + var n = this.minimatch.set.length + this._processing = 0 + this.matches = new Array(n) + + this._emitQueue = [] + this._processQueue = [] + this.paused = false + + if (this.noprocess) + return this + + if (n === 0) + return done() + + for (var i = 0; i < n; i ++) { + this._process(this.minimatch.set[i], i, false, done) + } + + function done () { + --self._processing + if (self._processing <= 0) + self._finish() + } +} + +Glob.prototype._finish = function () { + assert(this instanceof Glob) + if (this.aborted) + return + + if (this.realpath && !this._didRealpath) + return this._realpath() + + common.finish(this) + this.emit('end', this.found) +} + +Glob.prototype._realpath = function () { + if (this._didRealpath) + return + + this._didRealpath = true + + var n = this.matches.length + if (n === 0) + return this._finish() + + var self = this + for (var i = 0; i < this.matches.length; i++) + this._realpathSet(i, next) + + function next () { + if (--n === 0) + self._finish() + } +} + +Glob.prototype._realpathSet = function (index, cb) { + var matchset = this.matches[index] + if (!matchset) + return cb() + + var found = Object.keys(matchset) + var self = this + var n = found.length + + if (n === 0) + return cb() + + var set = this.matches[index] = Object.create(null) + found.forEach(function (p, i) { + // If there's a problem with the stat, then it means that + // one or more of the links in the realpath couldn't be + // resolved. just return the abs value in that case. + p = self._makeAbs(p) + fs.realpath(p, self.realpathCache, function (er, real) { + if (!er) + set[real] = true + else if (er.syscall === 'stat') + set[p] = true + else + self.emit('error', er) // srsly wtf right here + + if (--n === 0) { + self.matches[index] = set + cb() + } + }) + }) +} + +Glob.prototype._mark = function (p) { + return common.mark(this, p) +} + +Glob.prototype._makeAbs = function (f) { + return common.makeAbs(this, f) +} + +Glob.prototype.abort = function () { + this.aborted = true + this.emit('abort') +} + +Glob.prototype.pause = function () { + if (!this.paused) { + this.paused = true + this.emit('pause') + } +} + +Glob.prototype.resume = function () { + if (this.paused) { + this.emit('resume') + this.paused = false + if (this._emitQueue.length) { + var eq = this._emitQueue.slice(0) + this._emitQueue.length = 0 + for (var i = 0; i < eq.length; i ++) { + var e = eq[i] + this._emitMatch(e[0], e[1]) + } + } + if (this._processQueue.length) { + var pq = this._processQueue.slice(0) + this._processQueue.length = 0 + for (var i = 0; i < pq.length; i ++) { + var p = pq[i] + this._processing-- + this._process(p[0], p[1], p[2], p[3]) + } + } + } +} + +Glob.prototype._process = function (pattern, index, inGlobStar, cb) { + assert(this instanceof Glob) + assert(typeof cb === 'function') + + if (this.aborted) + return + + this._processing++ + if (this.paused) { + this._processQueue.push([pattern, index, inGlobStar, cb]) + return + } + + //console.error('PROCESS %d', this._processing, pattern) + + // Get the first [n] parts of pattern that are all strings. + var n = 0 + while (typeof pattern[n] === 'string') { + n ++ + } + // now n is the index of the first one that is *not* a string. + + // see if there's anything else + var prefix + switch (n) { + // if not, then this is rather simple + case pattern.length: + this._processSimple(pattern.join('/'), index, cb) + return + + case 0: + // pattern *starts* with some non-trivial item. + // going to readdir(cwd), but not include the prefix in matches. + prefix = null + break + + default: + // pattern has some string bits in the front. + // whatever it starts with, whether that's 'absolute' like /foo/bar, + // or 'relative' like '../baz' + prefix = pattern.slice(0, n).join('/') + break + } + + var remain = pattern.slice(n) + + // get the list of entries. + var read + if (prefix === null) + read = '.' + else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { + if (!prefix || !isAbsolute(prefix)) + prefix = '/' + prefix + read = prefix + } else + read = prefix + + var abs = this._makeAbs(read) + + //if ignored, skip _processing + if (childrenIgnored(this, read)) + return cb() + + var isGlobStar = remain[0] === minimatch.GLOBSTAR + if (isGlobStar) + this._processGlobStar(prefix, read, abs, remain, index, inGlobStar, cb) + else + this._processReaddir(prefix, read, abs, remain, index, inGlobStar, cb) +} + +Glob.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar, cb) { + var self = this + this._readdir(abs, inGlobStar, function (er, entries) { + return self._processReaddir2(prefix, read, abs, remain, index, inGlobStar, entries, cb) + }) +} + +Glob.prototype._processReaddir2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { + + // if the abs isn't a dir, then nothing can match! + if (!entries) + return cb() + + // It will only match dot entries if it starts with a dot, or if + // dot is set. Stuff like @(.foo|.bar) isn't allowed. + var pn = remain[0] + var negate = !!this.minimatch.negate + var rawGlob = pn._glob + var dotOk = this.dot || rawGlob.charAt(0) === '.' + + var matchedEntries = [] + for (var i = 0; i < entries.length; i++) { + var e = entries[i] + if (e.charAt(0) !== '.' || dotOk) { + var m + if (negate && !prefix) { + m = !e.match(pn) + } else { + m = e.match(pn) + } + if (m) + matchedEntries.push(e) + } + } + + //console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries) + + var len = matchedEntries.length + // If there are no matched entries, then nothing matches. + if (len === 0) + return cb() + + // if this is the last remaining pattern bit, then no need for + // an additional stat *unless* the user has specified mark or + // stat explicitly. We know they exist, since readdir returned + // them. + + if (remain.length === 1 && !this.mark && !this.stat) { + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + if (prefix) { + if (prefix !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + + if (e.charAt(0) === '/' && !this.nomount) { + e = path.join(this.root, e) + } + this._emitMatch(index, e) + } + // This was the last one, and no stats were needed + return cb() + } + + // now test all matched entries as stand-ins for that part + // of the pattern. + remain.shift() + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + var newPattern + if (prefix) { + if (prefix !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + this._process([e].concat(remain), index, inGlobStar, cb) + } + cb() +} + +Glob.prototype._emitMatch = function (index, e) { + if (this.aborted) + return + + if (this.matches[index][e]) + return + + if (isIgnored(this, e)) + return + + if (this.paused) { + this._emitQueue.push([index, e]) + return + } + + var abs = this._makeAbs(e) + + if (this.nodir) { + var c = this.cache[abs] + if (c === 'DIR' || Array.isArray(c)) + return + } + + if (this.mark) + e = this._mark(e) + + this.matches[index][e] = true + + var st = this.statCache[abs] + if (st) + this.emit('stat', e, st) + + this.emit('match', e) +} + +Glob.prototype._readdirInGlobStar = function (abs, cb) { + if (this.aborted) + return + + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false, cb) + + var lstatkey = 'lstat\0' + abs + var self = this + var lstatcb = inflight(lstatkey, lstatcb_) + + if (lstatcb) + fs.lstat(abs, lstatcb) + + function lstatcb_ (er, lstat) { + if (er) + return cb() + + var isSym = lstat.isSymbolicLink() + self.symlinks[abs] = isSym + + // If it's not a symlink or a dir, then it's definitely a regular file. + // don't bother doing a readdir in that case. + if (!isSym && !lstat.isDirectory()) { + self.cache[abs] = 'FILE' + cb() + } else + self._readdir(abs, false, cb) + } +} + +Glob.prototype._readdir = function (abs, inGlobStar, cb) { + if (this.aborted) + return + + cb = inflight('readdir\0'+abs+'\0'+inGlobStar, cb) + if (!cb) + return + + //console.error('RD %j %j', +inGlobStar, abs) + if (inGlobStar && !ownProp(this.symlinks, abs)) + return this._readdirInGlobStar(abs, cb) + + if (ownProp(this.cache, abs)) { + var c = this.cache[abs] + if (!c || c === 'FILE') + return cb() + + if (Array.isArray(c)) + return cb(null, c) + } + + var self = this + fs.readdir(abs, readdirCb(this, abs, cb)) +} + +function readdirCb (self, abs, cb) { + return function (er, entries) { + if (er) + self._readdirError(abs, er, cb) + else + self._readdirEntries(abs, entries, cb) + } +} + +Glob.prototype._readdirEntries = function (abs, entries, cb) { + if (this.aborted) + return + + // if we haven't asked to stat everything, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. + if (!this.mark && !this.stat) { + for (var i = 0; i < entries.length; i ++) { + var e = entries[i] + if (abs === '/') + e = abs + e + else + e = abs + '/' + e + this.cache[e] = true + } + } + + this.cache[abs] = entries + return cb(null, entries) +} + +Glob.prototype._readdirError = function (f, er, cb) { + if (this.aborted) + return + + // handle errors, and cache the information + switch (er.code) { + case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 + case 'ENOTDIR': // totally normal. means it *does* exist. + this.cache[this._makeAbs(f)] = 'FILE' + break + + case 'ENOENT': // not terribly unusual + case 'ELOOP': + case 'ENAMETOOLONG': + case 'UNKNOWN': + this.cache[this._makeAbs(f)] = false + break + + default: // some unusual error. Treat as failure. + this.cache[this._makeAbs(f)] = false + if (this.strict) { + this.emit('error', er) + // If the error is handled, then we abort + // if not, we threw out of here + this.abort() + } + if (!this.silent) + console.error('glob error', er) + break + } + + return cb() +} + +Glob.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar, cb) { + var self = this + this._readdir(abs, inGlobStar, function (er, entries) { + self._processGlobStar2(prefix, read, abs, remain, index, inGlobStar, entries, cb) + }) +} + + +Glob.prototype._processGlobStar2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { + //console.error('pgs2', prefix, remain[0], entries) + + // no entries means not a dir, so it can never have matches + // foo.txt/** doesn't match foo.txt + if (!entries) + return cb() + + // test without the globstar, and with every child both below + // and replacing the globstar. + var remainWithoutGlobStar = remain.slice(1) + var gspref = prefix ? [ prefix ] : [] + var noGlobStar = gspref.concat(remainWithoutGlobStar) + + // the noGlobStar pattern exits the inGlobStar state + this._process(noGlobStar, index, false, cb) + + var isSym = this.symlinks[abs] + var len = entries.length + + // If it's a symlink, and we're in a globstar, then stop + if (isSym && inGlobStar) + return cb() + + for (var i = 0; i < len; i++) { + var e = entries[i] + if (e.charAt(0) === '.' && !this.dot) + continue + + // these two cases enter the inGlobStar state + var instead = gspref.concat(entries[i], remainWithoutGlobStar) + this._process(instead, index, true, cb) + + var below = gspref.concat(entries[i], remain) + this._process(below, index, true, cb) + } + + cb() +} + +Glob.prototype._processSimple = function (prefix, index, cb) { + // XXX review this. Shouldn't it be doing the mounting etc + // before doing stat? kinda weird? + var self = this + this._stat(prefix, function (er, exists) { + self._processSimple2(prefix, index, er, exists, cb) + }) +} +Glob.prototype._processSimple2 = function (prefix, index, er, exists, cb) { + + //console.error('ps2', prefix, exists) + + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + // If it doesn't exist, then just mark the lack of results + if (!exists) + return cb() + + if (prefix && isAbsolute(prefix) && !this.nomount) { + var trail = /[\/\\]$/.test(prefix) + if (prefix.charAt(0) === '/') { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + if (trail) + prefix += '/' + } + } + + if (process.platform === 'win32') + prefix = prefix.replace(/\\/g, '/') + + // Mark this as a match + this._emitMatch(index, prefix) + cb() +} + +// Returns either 'DIR', 'FILE', or false +Glob.prototype._stat = function (f, cb) { + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' + + if (f.length > this.maxLength) + return cb() + + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] + + if (Array.isArray(c)) + c = 'DIR' + + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return cb(null, c) + + if (needDir && c === 'FILE') + return cb() + + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. + } + + var exists + var stat = this.statCache[abs] + if (stat !== undefined) { + if (stat === false) + return cb(null, stat) + else { + var type = stat.isDirectory() ? 'DIR' : 'FILE' + if (needDir && type === 'FILE') + return cb() + else + return cb(null, type, stat) + } + } + + var self = this + var statcb = inflight('stat\0' + abs, lstatcb_) + if (statcb) + fs.lstat(abs, statcb) + + function lstatcb_ (er, lstat) { + if (lstat && lstat.isSymbolicLink()) { + // If it's a symlink, then treat it as the target, unless + // the target does not exist, then treat it as a file. + return fs.stat(abs, function (er, stat) { + if (er) + self._stat2(f, abs, null, lstat, cb) + else + self._stat2(f, abs, er, stat, cb) + }) + } else { + self._stat2(f, abs, er, lstat, cb) + } + } +} + +Glob.prototype._stat2 = function (f, abs, er, stat, cb) { + if (er) { + this.statCache[abs] = false + return cb() + } + + var needDir = f.slice(-1) === '/' + this.statCache[abs] = stat + + if (abs.slice(-1) === '/' && !stat.isDirectory()) + return cb(null, false, stat) + + var c = stat.isDirectory() ? 'DIR' : 'FILE' + this.cache[abs] = this.cache[abs] || c + + if (needDir && c !== 'DIR') + return cb() + + return cb(null, c, stat) +} + +}).call(this,require('_process')) +},{"./common.js":15,"./sync.js":17,"_process":24,"assert":9,"events":14,"fs":12,"inflight":18,"inherits":19,"minimatch":20,"once":21,"path":22,"path-is-absolute":23,"util":28}],17:[function(require,module,exports){ +(function (process){ +module.exports = globSync +globSync.GlobSync = GlobSync + +var fs = require('fs') +var minimatch = require('minimatch') +var Minimatch = minimatch.Minimatch +var Glob = require('./glob.js').Glob +var util = require('util') +var path = require('path') +var assert = require('assert') +var isAbsolute = require('path-is-absolute') +var common = require('./common.js') +var alphasort = common.alphasort +var alphasorti = common.alphasorti +var setopts = common.setopts +var ownProp = common.ownProp +var childrenIgnored = common.childrenIgnored + +function globSync (pattern, options) { + if (typeof options === 'function' || arguments.length === 3) + throw new TypeError('callback provided to sync glob\n'+ + 'See: https://github.com/isaacs/node-glob/issues/167') + + return new GlobSync(pattern, options).found +} + +function GlobSync (pattern, options) { + if (!pattern) + throw new Error('must provide pattern') + + if (typeof options === 'function' || arguments.length === 3) + throw new TypeError('callback provided to sync glob\n'+ + 'See: https://github.com/isaacs/node-glob/issues/167') + + if (!(this instanceof GlobSync)) + return new GlobSync(pattern, options) + + setopts(this, pattern, options) + + if (this.noprocess) + return this + + var n = this.minimatch.set.length + this.matches = new Array(n) + for (var i = 0; i < n; i ++) { + this._process(this.minimatch.set[i], i, false) + } + this._finish() +} + +GlobSync.prototype._finish = function () { + assert(this instanceof GlobSync) + if (this.realpath) { + var self = this + this.matches.forEach(function (matchset, index) { + var set = self.matches[index] = Object.create(null) + for (var p in matchset) { + try { + p = self._makeAbs(p) + var real = fs.realpathSync(p, self.realpathCache) + set[real] = true + } catch (er) { + if (er.syscall === 'stat') + set[self._makeAbs(p)] = true + else + throw er + } + } + }) + } + common.finish(this) +} + + +GlobSync.prototype._process = function (pattern, index, inGlobStar) { + assert(this instanceof GlobSync) + + // Get the first [n] parts of pattern that are all strings. + var n = 0 + while (typeof pattern[n] === 'string') { + n ++ + } + // now n is the index of the first one that is *not* a string. + + // See if there's anything else + var prefix + switch (n) { + // if not, then this is rather simple + case pattern.length: + this._processSimple(pattern.join('/'), index) + return + + case 0: + // pattern *starts* with some non-trivial item. + // going to readdir(cwd), but not include the prefix in matches. + prefix = null + break + + default: + // pattern has some string bits in the front. + // whatever it starts with, whether that's 'absolute' like /foo/bar, + // or 'relative' like '../baz' + prefix = pattern.slice(0, n).join('/') + break + } + + var remain = pattern.slice(n) + + // get the list of entries. + var read + if (prefix === null) + read = '.' + else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { + if (!prefix || !isAbsolute(prefix)) + prefix = '/' + prefix + read = prefix + } else + read = prefix + + var abs = this._makeAbs(read) + + //if ignored, skip processing + if (childrenIgnored(this, read)) + return + + var isGlobStar = remain[0] === minimatch.GLOBSTAR + if (isGlobStar) + this._processGlobStar(prefix, read, abs, remain, index, inGlobStar) + else + this._processReaddir(prefix, read, abs, remain, index, inGlobStar) +} + + +GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) { + var entries = this._readdir(abs, inGlobStar) + + // if the abs isn't a dir, then nothing can match! + if (!entries) + return + + // It will only match dot entries if it starts with a dot, or if + // dot is set. Stuff like @(.foo|.bar) isn't allowed. + var pn = remain[0] + var negate = !!this.minimatch.negate + var rawGlob = pn._glob + var dotOk = this.dot || rawGlob.charAt(0) === '.' + + var matchedEntries = [] + for (var i = 0; i < entries.length; i++) { + var e = entries[i] + if (e.charAt(0) !== '.' || dotOk) { + var m + if (negate && !prefix) { + m = !e.match(pn) + } else { + m = e.match(pn) + } + if (m) + matchedEntries.push(e) + } + } + + var len = matchedEntries.length + // If there are no matched entries, then nothing matches. + if (len === 0) + return + + // if this is the last remaining pattern bit, then no need for + // an additional stat *unless* the user has specified mark or + // stat explicitly. We know they exist, since readdir returned + // them. + + if (remain.length === 1 && !this.mark && !this.stat) { + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + if (prefix) { + if (prefix.slice(-1) !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + + if (e.charAt(0) === '/' && !this.nomount) { + e = path.join(this.root, e) + } + this.matches[index][e] = true + } + // This was the last one, and no stats were needed + return + } + + // now test all matched entries as stand-ins for that part + // of the pattern. + remain.shift() + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + var newPattern + if (prefix) + newPattern = [prefix, e] + else + newPattern = [e] + this._process(newPattern.concat(remain), index, inGlobStar) + } +} + + +GlobSync.prototype._emitMatch = function (index, e) { + var abs = this._makeAbs(e) + if (this.mark) + e = this._mark(e) + + if (this.matches[index][e]) + return + + if (this.nodir) { + var c = this.cache[this._makeAbs(e)] + if (c === 'DIR' || Array.isArray(c)) + return + } + + this.matches[index][e] = true + if (this.stat) + this._stat(e) +} + + +GlobSync.prototype._readdirInGlobStar = function (abs) { + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false) + + var entries + var lstat + var stat + try { + lstat = fs.lstatSync(abs) + } catch (er) { + // lstat failed, doesn't exist + return null + } + + var isSym = lstat.isSymbolicLink() + this.symlinks[abs] = isSym + + // If it's not a symlink or a dir, then it's definitely a regular file. + // don't bother doing a readdir in that case. + if (!isSym && !lstat.isDirectory()) + this.cache[abs] = 'FILE' + else + entries = this._readdir(abs, false) + + return entries +} + +GlobSync.prototype._readdir = function (abs, inGlobStar) { + var entries + + if (inGlobStar && !ownProp(this.symlinks, abs)) + return this._readdirInGlobStar(abs) + + if (ownProp(this.cache, abs)) { + var c = this.cache[abs] + if (!c || c === 'FILE') + return null + + if (Array.isArray(c)) + return c + } + + try { + return this._readdirEntries(abs, fs.readdirSync(abs)) + } catch (er) { + this._readdirError(abs, er) + return null + } +} + +GlobSync.prototype._readdirEntries = function (abs, entries) { + // if we haven't asked to stat everything, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. + if (!this.mark && !this.stat) { + for (var i = 0; i < entries.length; i ++) { + var e = entries[i] + if (abs === '/') + e = abs + e + else + e = abs + '/' + e + this.cache[e] = true + } + } + + this.cache[abs] = entries + + // mark and cache dir-ness + return entries +} + +GlobSync.prototype._readdirError = function (f, er) { + // handle errors, and cache the information + switch (er.code) { + case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 + case 'ENOTDIR': // totally normal. means it *does* exist. + this.cache[this._makeAbs(f)] = 'FILE' + break + + case 'ENOENT': // not terribly unusual + case 'ELOOP': + case 'ENAMETOOLONG': + case 'UNKNOWN': + this.cache[this._makeAbs(f)] = false + break + + default: // some unusual error. Treat as failure. + this.cache[this._makeAbs(f)] = false + if (this.strict) + throw er + if (!this.silent) + console.error('glob error', er) + break + } +} + +GlobSync.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) { + + var entries = this._readdir(abs, inGlobStar) + + // no entries means not a dir, so it can never have matches + // foo.txt/** doesn't match foo.txt + if (!entries) + return + + // test without the globstar, and with every child both below + // and replacing the globstar. + var remainWithoutGlobStar = remain.slice(1) + var gspref = prefix ? [ prefix ] : [] + var noGlobStar = gspref.concat(remainWithoutGlobStar) + + // the noGlobStar pattern exits the inGlobStar state + this._process(noGlobStar, index, false) + + var len = entries.length + var isSym = this.symlinks[abs] + + // If it's a symlink, and we're in a globstar, then stop + if (isSym && inGlobStar) + return + + for (var i = 0; i < len; i++) { + var e = entries[i] + if (e.charAt(0) === '.' && !this.dot) + continue + + // these two cases enter the inGlobStar state + var instead = gspref.concat(entries[i], remainWithoutGlobStar) + this._process(instead, index, true) + + var below = gspref.concat(entries[i], remain) + this._process(below, index, true) + } +} + +GlobSync.prototype._processSimple = function (prefix, index) { + // XXX review this. Shouldn't it be doing the mounting etc + // before doing stat? kinda weird? + var exists = this._stat(prefix) + + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + // If it doesn't exist, then just mark the lack of results + if (!exists) + return + + if (prefix && isAbsolute(prefix) && !this.nomount) { + var trail = /[\/\\]$/.test(prefix) + if (prefix.charAt(0) === '/') { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + if (trail) + prefix += '/' + } + } + + if (process.platform === 'win32') + prefix = prefix.replace(/\\/g, '/') + + // Mark this as a match + this.matches[index][prefix] = true +} + +// Returns either 'DIR', 'FILE', or false +GlobSync.prototype._stat = function (f) { + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' + + if (f.length > this.maxLength) + return false + + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] + + if (Array.isArray(c)) + c = 'DIR' + + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return c + + if (needDir && c === 'FILE') + return false + + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. + } + + var exists + var stat = this.statCache[abs] + if (!stat) { + var lstat + try { + lstat = fs.lstatSync(abs) + } catch (er) { + return false + } + + if (lstat.isSymbolicLink()) { + try { + stat = fs.statSync(abs) + } catch (er) { + stat = lstat + } + } else { + stat = lstat + } + } + + this.statCache[abs] = stat + + var c = stat.isDirectory() ? 'DIR' : 'FILE' + this.cache[abs] = this.cache[abs] || c + + if (needDir && c !== 'DIR') + return false + + return c +} + +GlobSync.prototype._mark = function (p) { + return common.mark(this, p) +} + +GlobSync.prototype._makeAbs = function (f) { + return common.makeAbs(this, f) +} + +}).call(this,require('_process')) +},{"./common.js":15,"./glob.js":16,"_process":24,"assert":9,"fs":12,"minimatch":20,"path":22,"path-is-absolute":23,"util":28}],18:[function(require,module,exports){ +(function (process){ +var wrappy = require('wrappy') +var reqs = Object.create(null) +var once = require('once') + +module.exports = wrappy(inflight) + +function inflight (key, cb) { + if (reqs[key]) { + reqs[key].push(cb) + return null + } else { + reqs[key] = [cb] + return makeres(key) + } +} + +function makeres (key) { + return once(function RES () { + var cbs = reqs[key] + var len = cbs.length + var args = slice(arguments) + + // XXX It's somewhat ambiguous whether a new callback added in this + // pass should be queued for later execution if something in the + // list of callbacks throws, or if it should just be discarded. + // However, it's such an edge case that it hardly matters, and either + // choice is likely as surprising as the other. + // As it happens, we do go ahead and schedule it for later execution. + try { + for (var i = 0; i < len; i++) { + cbs[i].apply(null, args) + } + } finally { + if (cbs.length > len) { + // added more in the interim. + // de-zalgo, just in case, but don't call again. + cbs.splice(0, len) + process.nextTick(function () { + RES.apply(null, args) + }) + } else { + delete reqs[key] + } + } + }) +} + +function slice (args) { + var length = args.length + var array = [] + + for (var i = 0; i < length; i++) array[i] = args[i] + return array +} + +}).call(this,require('_process')) +},{"_process":24,"once":21,"wrappy":29}],19:[function(require,module,exports){ +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); + }; +} else { + // old school shim for old browsers + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor + } +} + +},{}],20:[function(require,module,exports){ +module.exports = minimatch +minimatch.Minimatch = Minimatch + +var path = { sep: '/' } +try { + path = require('path') +} catch (er) {} + +var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {} +var expand = require('brace-expansion') + +var plTypes = { + '!': { open: '(?:(?!(?:', close: '))[^/]*?)'}, + '?': { open: '(?:', close: ')?' }, + '+': { open: '(?:', close: ')+' }, + '*': { open: '(?:', close: ')*' }, + '@': { open: '(?:', close: ')' } +} + +// any single thing other than / +// don't need to escape / when using new RegExp() +var qmark = '[^/]' + +// * => any number of characters +var star = qmark + '*?' + +// ** when dots are allowed. Anything goes, except .. and . +// not (^ or / followed by one or two dots followed by $ or /), +// followed by anything, any number of times. +var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?' + +// not a ^ or / followed by a dot, +// followed by anything, any number of times. +var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?' + +// characters that need to be escaped in RegExp. +var reSpecials = charSet('().*{}+?[]^$\\!') + +// "abc" -> { a:true, b:true, c:true } +function charSet (s) { + return s.split('').reduce(function (set, c) { + set[c] = true + return set + }, {}) +} + +// normalizes slashes. +var slashSplit = /\/+/ + +minimatch.filter = filter +function filter (pattern, options) { + options = options || {} + return function (p, i, list) { + return minimatch(p, pattern, options) + } +} + +function ext (a, b) { + a = a || {} + b = b || {} + var t = {} + Object.keys(b).forEach(function (k) { + t[k] = b[k] + }) + Object.keys(a).forEach(function (k) { + t[k] = a[k] + }) + return t +} + +minimatch.defaults = function (def) { + if (!def || !Object.keys(def).length) return minimatch + + var orig = minimatch + + var m = function minimatch (p, pattern, options) { + return orig.minimatch(p, pattern, ext(def, options)) + } + + m.Minimatch = function Minimatch (pattern, options) { + return new orig.Minimatch(pattern, ext(def, options)) + } + + return m +} + +Minimatch.defaults = function (def) { + if (!def || !Object.keys(def).length) return Minimatch + return minimatch.defaults(def).Minimatch +} + +function minimatch (p, pattern, options) { + if (typeof pattern !== 'string') { + throw new TypeError('glob pattern string required') + } + + if (!options) options = {} + + // shortcut: comments match nothing. + if (!options.nocomment && pattern.charAt(0) === '#') { + return false + } + + // "" only matches "" + if (pattern.trim() === '') return p === '' + + return new Minimatch(pattern, options).match(p) +} + +function Minimatch (pattern, options) { + if (!(this instanceof Minimatch)) { + return new Minimatch(pattern, options) + } + + if (typeof pattern !== 'string') { + throw new TypeError('glob pattern string required') + } + + if (!options) options = {} + pattern = pattern.trim() + + // windows support: need to use /, not \ + if (path.sep !== '/') { + pattern = pattern.split(path.sep).join('/') + } + + this.options = options + this.set = [] + this.pattern = pattern + this.regexp = null + this.negate = false + this.comment = false + this.empty = false + + // make the set of regexps etc. + this.make() +} + +Minimatch.prototype.debug = function () {} + +Minimatch.prototype.make = make +function make () { + // don't do it more than once. + if (this._made) return + + var pattern = this.pattern + var options = this.options + + // empty patterns and comments match nothing. + if (!options.nocomment && pattern.charAt(0) === '#') { + this.comment = true + return + } + if (!pattern) { + this.empty = true + return + } + + // step 1: figure out negation, etc. + this.parseNegate() + + // step 2: expand braces + var set = this.globSet = this.braceExpand() + + if (options.debug) this.debug = console.error + + this.debug(this.pattern, set) + + // step 3: now we have a set, so turn each one into a series of path-portion + // matching patterns. + // These will be regexps, except in the case of "**", which is + // set to the GLOBSTAR object for globstar behavior, + // and will not contain any / characters + set = this.globParts = set.map(function (s) { + return s.split(slashSplit) + }) + + this.debug(this.pattern, set) + + // glob --> regexps + set = set.map(function (s, si, set) { + return s.map(this.parse, this) + }, this) + + this.debug(this.pattern, set) + + // filter out everything that didn't compile properly. + set = set.filter(function (s) { + return s.indexOf(false) === -1 + }) + + this.debug(this.pattern, set) + + this.set = set +} + +Minimatch.prototype.parseNegate = parseNegate +function parseNegate () { + var pattern = this.pattern + var negate = false + var options = this.options + var negateOffset = 0 + + if (options.nonegate) return + + for (var i = 0, l = pattern.length + ; i < l && pattern.charAt(i) === '!' + ; i++) { + negate = !negate + negateOffset++ + } + + if (negateOffset) this.pattern = pattern.substr(negateOffset) + this.negate = negate +} + +// Brace expansion: +// a{b,c}d -> abd acd +// a{b,}c -> abc ac +// a{0..3}d -> a0d a1d a2d a3d +// a{b,c{d,e}f}g -> abg acdfg acefg +// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg +// +// Invalid sets are not expanded. +// a{2..}b -> a{2..}b +// a{b}c -> a{b}c +minimatch.braceExpand = function (pattern, options) { + return braceExpand(pattern, options) +} + +Minimatch.prototype.braceExpand = braceExpand + +function braceExpand (pattern, options) { + if (!options) { + if (this instanceof Minimatch) { + options = this.options + } else { + options = {} + } + } + + pattern = typeof pattern === 'undefined' + ? this.pattern : pattern + + if (typeof pattern === 'undefined') { + throw new TypeError('undefined pattern') + } + + if (options.nobrace || + !pattern.match(/\{.*\}/)) { + // shortcut. no need to expand. + return [pattern] + } + + return expand(pattern) +} + +// parse a component of the expanded set. +// At this point, no pattern may contain "/" in it +// so we're going to return a 2d array, where each entry is the full +// pattern, split on '/', and then turned into a regular expression. +// A regexp is made at the end which joins each array with an +// escaped /, and another full one which joins each regexp with |. +// +// Following the lead of Bash 4.1, note that "**" only has special meaning +// when it is the *only* thing in a path portion. Otherwise, any series +// of * is equivalent to a single *. Globstar behavior is enabled by +// default, and can be disabled by setting options.noglobstar. +Minimatch.prototype.parse = parse +var SUBPARSE = {} +function parse (pattern, isSub) { + if (pattern.length > 1024 * 64) { + throw new TypeError('pattern is too long') + } + + var options = this.options + + // shortcuts + if (!options.noglobstar && pattern === '**') return GLOBSTAR + if (pattern === '') return '' + + var re = '' + var hasMagic = !!options.nocase + var escaping = false + // ? => one single character + var patternListStack = [] + var negativeLists = [] + var stateChar + var inClass = false + var reClassStart = -1 + var classStart = -1 + // . and .. never match anything that doesn't start with ., + // even when options.dot is set. + var patternStart = pattern.charAt(0) === '.' ? '' // anything + // not (start or / followed by . or .. followed by / or end) + : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))' + : '(?!\\.)' + var self = this + + function clearStateChar () { + if (stateChar) { + // we had some state-tracking character + // that wasn't consumed by this pass. + switch (stateChar) { + case '*': + re += star + hasMagic = true + break + case '?': + re += qmark + hasMagic = true + break + default: + re += '\\' + stateChar + break + } + self.debug('clearStateChar %j %j', stateChar, re) + stateChar = false + } + } + + for (var i = 0, len = pattern.length, c + ; (i < len) && (c = pattern.charAt(i)) + ; i++) { + this.debug('%s\t%s %s %j', pattern, i, re, c) + + // skip over any that are escaped. + if (escaping && reSpecials[c]) { + re += '\\' + c + escaping = false + continue + } + + switch (c) { + case '/': + // completely not allowed, even escaped. + // Should already be path-split by now. + return false + + case '\\': + clearStateChar() + escaping = true + continue + + // the various stateChar values + // for the "extglob" stuff. + case '?': + case '*': + case '+': + case '@': + case '!': + this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c) + + // all of those are literals inside a class, except that + // the glob [!a] means [^a] in regexp + if (inClass) { + this.debug(' in class') + if (c === '!' && i === classStart + 1) c = '^' + re += c + continue + } + + // if we already have a stateChar, then it means + // that there was something like ** or +? in there. + // Handle the stateChar, then proceed with this one. + self.debug('call clearStateChar %j', stateChar) + clearStateChar() + stateChar = c + // if extglob is disabled, then +(asdf|foo) isn't a thing. + // just clear the statechar *now*, rather than even diving into + // the patternList stuff. + if (options.noext) clearStateChar() + continue + + case '(': + if (inClass) { + re += '(' + continue + } + + if (!stateChar) { + re += '\\(' + continue + } + + patternListStack.push({ + type: stateChar, + start: i - 1, + reStart: re.length, + open: plTypes[stateChar].open, + close: plTypes[stateChar].close + }) + // negation is (?:(?!js)[^/]*) + re += stateChar === '!' ? '(?:(?!(?:' : '(?:' + this.debug('plType %j %j', stateChar, re) + stateChar = false + continue + + case ')': + if (inClass || !patternListStack.length) { + re += '\\)' + continue + } + + clearStateChar() + hasMagic = true + var pl = patternListStack.pop() + // negation is (?:(?!js)[^/]*) + // The others are (?:) + re += pl.close + if (pl.type === '!') { + negativeLists.push(pl) + } + pl.reEnd = re.length + continue + + case '|': + if (inClass || !patternListStack.length || escaping) { + re += '\\|' + escaping = false + continue + } + + clearStateChar() + re += '|' + continue + + // these are mostly the same in regexp and glob + case '[': + // swallow any state-tracking char before the [ + clearStateChar() + + if (inClass) { + re += '\\' + c + continue + } + + inClass = true + classStart = i + reClassStart = re.length + re += c + continue + + case ']': + // a right bracket shall lose its special + // meaning and represent itself in + // a bracket expression if it occurs + // first in the list. -- POSIX.2 2.8.3.2 + if (i === classStart + 1 || !inClass) { + re += '\\' + c + escaping = false + continue + } + + // handle the case where we left a class open. + // "[z-a]" is valid, equivalent to "\[z-a\]" + if (inClass) { + // split where the last [ was, make sure we don't have + // an invalid re. if so, re-walk the contents of the + // would-be class to re-translate any characters that + // were passed through as-is + // TODO: It would probably be faster to determine this + // without a try/catch and a new RegExp, but it's tricky + // to do safely. For now, this is safe and works. + var cs = pattern.substring(classStart + 1, i) + try { + RegExp('[' + cs + ']') + } catch (er) { + // not a valid class! + var sp = this.parse(cs, SUBPARSE) + re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]' + hasMagic = hasMagic || sp[1] + inClass = false + continue + } + } + + // finish up the class. + hasMagic = true + inClass = false + re += c + continue + + default: + // swallow any state char that wasn't consumed + clearStateChar() + + if (escaping) { + // no need + escaping = false + } else if (reSpecials[c] + && !(c === '^' && inClass)) { + re += '\\' + } + + re += c + + } // switch + } // for + + // handle the case where we left a class open. + // "[abc" is valid, equivalent to "\[abc" + if (inClass) { + // split where the last [ was, and escape it + // this is a huge pita. We now have to re-walk + // the contents of the would-be class to re-translate + // any characters that were passed through as-is + cs = pattern.substr(classStart + 1) + sp = this.parse(cs, SUBPARSE) + re = re.substr(0, reClassStart) + '\\[' + sp[0] + hasMagic = hasMagic || sp[1] + } + + // handle the case where we had a +( thing at the *end* + // of the pattern. + // each pattern list stack adds 3 chars, and we need to go through + // and escape any | chars that were passed through as-is for the regexp. + // Go through and escape them, taking care not to double-escape any + // | chars that were already escaped. + for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) { + var tail = re.slice(pl.reStart + pl.open.length) + this.debug('setting tail', re, pl) + // maybe some even number of \, then maybe 1 \, followed by a | + tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, function (_, $1, $2) { + if (!$2) { + // the | isn't already escaped, so escape it. + $2 = '\\' + } + + // need to escape all those slashes *again*, without escaping the + // one that we need for escaping the | character. As it works out, + // escaping an even number of slashes can be done by simply repeating + // it exactly after itself. That's why this trick works. + // + // I am sorry that you have to see this. + return $1 + $1 + $2 + '|' + }) + + this.debug('tail=%j\n %s', tail, tail, pl, re) + var t = pl.type === '*' ? star + : pl.type === '?' ? qmark + : '\\' + pl.type + + hasMagic = true + re = re.slice(0, pl.reStart) + t + '\\(' + tail + } + + // handle trailing things that only matter at the very end. + clearStateChar() + if (escaping) { + // trailing \\ + re += '\\\\' + } + + // only need to apply the nodot start if the re starts with + // something that could conceivably capture a dot + var addPatternStart = false + switch (re.charAt(0)) { + case '.': + case '[': + case '(': addPatternStart = true + } + + // Hack to work around lack of negative lookbehind in JS + // A pattern like: *.!(x).!(y|z) needs to ensure that a name + // like 'a.xyz.yz' doesn't match. So, the first negative + // lookahead, has to look ALL the way ahead, to the end of + // the pattern. + for (var n = negativeLists.length - 1; n > -1; n--) { + var nl = negativeLists[n] + + var nlBefore = re.slice(0, nl.reStart) + var nlFirst = re.slice(nl.reStart, nl.reEnd - 8) + var nlLast = re.slice(nl.reEnd - 8, nl.reEnd) + var nlAfter = re.slice(nl.reEnd) + + nlLast += nlAfter + + // Handle nested stuff like *(*.js|!(*.json)), where open parens + // mean that we should *not* include the ) in the bit that is considered + // "after" the negated section. + var openParensBefore = nlBefore.split('(').length - 1 + var cleanAfter = nlAfter + for (i = 0; i < openParensBefore; i++) { + cleanAfter = cleanAfter.replace(/\)[+*?]?/, '') + } + nlAfter = cleanAfter + + var dollar = '' + if (nlAfter === '' && isSub !== SUBPARSE) { + dollar = '$' + } + var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast + re = newRe + } + + // if the re is not "" at this point, then we need to make sure + // it doesn't match against an empty path part. + // Otherwise a/* will match a/, which it should not. + if (re !== '' && hasMagic) { + re = '(?=.)' + re + } + + if (addPatternStart) { + re = patternStart + re + } + + // parsing just a piece of a larger pattern. + if (isSub === SUBPARSE) { + return [re, hasMagic] + } + + // skip the regexp for non-magical patterns + // unescape anything in it, though, so that it'll be + // an exact match against a file etc. + if (!hasMagic) { + return globUnescape(pattern) + } + + var flags = options.nocase ? 'i' : '' + try { + var regExp = new RegExp('^' + re + '$', flags) + } catch (er) { + // If it was an invalid regular expression, then it can't match + // anything. This trick looks for a character after the end of + // the string, which is of course impossible, except in multi-line + // mode, but it's not a /m regex. + return new RegExp('$.') + } + + regExp._glob = pattern + regExp._src = re + + return regExp +} + +minimatch.makeRe = function (pattern, options) { + return new Minimatch(pattern, options || {}).makeRe() +} + +Minimatch.prototype.makeRe = makeRe +function makeRe () { + if (this.regexp || this.regexp === false) return this.regexp + + // at this point, this.set is a 2d array of partial + // pattern strings, or "**". + // + // It's better to use .match(). This function shouldn't + // be used, really, but it's pretty convenient sometimes, + // when you just want to work with a regex. + var set = this.set + + if (!set.length) { + this.regexp = false + return this.regexp + } + var options = this.options + + var twoStar = options.noglobstar ? star + : options.dot ? twoStarDot + : twoStarNoDot + var flags = options.nocase ? 'i' : '' + + var re = set.map(function (pattern) { + return pattern.map(function (p) { + return (p === GLOBSTAR) ? twoStar + : (typeof p === 'string') ? regExpEscape(p) + : p._src + }).join('\\\/') + }).join('|') + + // must match entire pattern + // ending in a * or ** will make it less strict. + re = '^(?:' + re + ')$' + + // can match anything, as long as it's not this. + if (this.negate) re = '^(?!' + re + ').*$' + + try { + this.regexp = new RegExp(re, flags) + } catch (ex) { + this.regexp = false + } + return this.regexp +} + +minimatch.match = function (list, pattern, options) { + options = options || {} + var mm = new Minimatch(pattern, options) + list = list.filter(function (f) { + return mm.match(f) + }) + if (mm.options.nonull && !list.length) { + list.push(pattern) + } + return list +} + +Minimatch.prototype.match = match +function match (f, partial) { + this.debug('match', f, this.pattern) + // short-circuit in the case of busted things. + // comments, etc. + if (this.comment) return false + if (this.empty) return f === '' + + if (f === '/' && partial) return true + + var options = this.options + + // windows: need to use /, not \ + if (path.sep !== '/') { + f = f.split(path.sep).join('/') + } + + // treat the test path as a set of pathparts. + f = f.split(slashSplit) + this.debug(this.pattern, 'split', f) + + // just ONE of the pattern sets in this.set needs to match + // in order for it to be valid. If negating, then just one + // match means that we have failed. + // Either way, return on the first hit. + + var set = this.set + this.debug(this.pattern, 'set', set) + + // Find the basename of the path by looking for the last non-empty segment + var filename + var i + for (i = f.length - 1; i >= 0; i--) { + filename = f[i] + if (filename) break + } + + for (i = 0; i < set.length; i++) { + var pattern = set[i] + var file = f + if (options.matchBase && pattern.length === 1) { + file = [filename] + } + var hit = this.matchOne(file, pattern, partial) + if (hit) { + if (options.flipNegate) return true + return !this.negate + } + } + + // didn't get any hits. this is success if it's a negative + // pattern, failure otherwise. + if (options.flipNegate) return false + return this.negate +} + +// set partial to true to test if, for example, +// "/a/b" matches the start of "/*/b/*/d" +// Partial means, if you run out of file before you run +// out of pattern, then that's fine, as long as all +// the parts match. +Minimatch.prototype.matchOne = function (file, pattern, partial) { + var options = this.options + + this.debug('matchOne', + { 'this': this, file: file, pattern: pattern }) + + this.debug('matchOne', file.length, pattern.length) + + for (var fi = 0, + pi = 0, + fl = file.length, + pl = pattern.length + ; (fi < fl) && (pi < pl) + ; fi++, pi++) { + this.debug('matchOne loop') + var p = pattern[pi] + var f = file[fi] + + this.debug(pattern, p, f) + + // should be impossible. + // some invalid regexp stuff in the set. + if (p === false) return false + + if (p === GLOBSTAR) { + this.debug('GLOBSTAR', [pattern, p, f]) + + // "**" + // a/**/b/**/c would match the following: + // a/b/x/y/z/c + // a/x/y/z/b/c + // a/b/x/b/x/c + // a/b/c + // To do this, take the rest of the pattern after + // the **, and see if it would match the file remainder. + // If so, return success. + // If not, the ** "swallows" a segment, and try again. + // This is recursively awful. + // + // a/**/b/**/c matching a/b/x/y/z/c + // - a matches a + // - doublestar + // - matchOne(b/x/y/z/c, b/**/c) + // - b matches b + // - doublestar + // - matchOne(x/y/z/c, c) -> no + // - matchOne(y/z/c, c) -> no + // - matchOne(z/c, c) -> no + // - matchOne(c, c) yes, hit + var fr = fi + var pr = pi + 1 + if (pr === pl) { + this.debug('** at the end') + // a ** at the end will just swallow the rest. + // We have found a match. + // however, it will not swallow /.x, unless + // options.dot is set. + // . and .. are *never* matched by **, for explosively + // exponential reasons. + for (; fi < fl; fi++) { + if (file[fi] === '.' || file[fi] === '..' || + (!options.dot && file[fi].charAt(0) === '.')) return false + } + return true + } + + // ok, let's see if we can swallow whatever we can. + while (fr < fl) { + var swallowee = file[fr] + + this.debug('\nglobstar while', file, fr, pattern, pr, swallowee) + + // XXX remove this slice. Just pass the start index. + if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { + this.debug('globstar found match!', fr, fl, swallowee) + // found a match. + return true + } else { + // can't swallow "." or ".." ever. + // can only swallow ".foo" when explicitly asked. + if (swallowee === '.' || swallowee === '..' || + (!options.dot && swallowee.charAt(0) === '.')) { + this.debug('dot detected!', file, fr, pattern, pr) + break + } + + // ** swallows a segment, and continue. + this.debug('globstar swallow a segment, and continue') + fr++ + } + } + + // no match was found. + // However, in partial mode, we can't say this is necessarily over. + // If there's more *pattern* left, then + if (partial) { + // ran out of file + this.debug('\n>>> no match, partial?', file, fr, pattern, pr) + if (fr === fl) return true + } + return false + } + + // something other than ** + // non-magic patterns just have to match exactly + // patterns with magic have been turned into regexps. + var hit + if (typeof p === 'string') { + if (options.nocase) { + hit = f.toLowerCase() === p.toLowerCase() + } else { + hit = f === p + } + this.debug('string match', p, f, hit) + } else { + hit = f.match(p) + this.debug('pattern match', p, f, hit) + } + + if (!hit) return false + } + + // Note: ending in / means that we'll get a final "" + // at the end of the pattern. This can only match a + // corresponding "" at the end of the file. + // If the file ends in /, then it can only match a + // a pattern that ends in /, unless the pattern just + // doesn't have any more for it. But, a/b/ should *not* + // match "a/b/*", even though "" matches against the + // [^/]*? pattern, except in partial mode, where it might + // simply not be reached yet. + // However, a/b/ should still satisfy a/* + + // now either we fell off the end of the pattern, or we're done. + if (fi === fl && pi === pl) { + // ran out of pattern and filename at the same time. + // an exact hit! + return true + } else if (fi === fl) { + // ran out of file, but still had pattern left. + // this is ok if we're doing the match as part of + // a glob fs traversal. + return partial + } else if (pi === pl) { + // ran out of pattern, still have file left. + // this is only acceptable if we're on the very last + // empty segment of a file with a trailing slash. + // a/* should match a/b/ + var emptyFileEnd = (fi === fl - 1) && (file[fi] === '') + return emptyFileEnd + } + + // should be unreachable. + throw new Error('wtf?') +} + +// replace stuff like \* with * +function globUnescape (s) { + return s.replace(/\\(.)/g, '$1') +} + +function regExpEscape (s) { + return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') +} + +},{"brace-expansion":11,"path":22}],21:[function(require,module,exports){ +var wrappy = require('wrappy') +module.exports = wrappy(once) +module.exports.strict = wrappy(onceStrict) + +once.proto = once(function () { + Object.defineProperty(Function.prototype, 'once', { + value: function () { + return once(this) + }, + configurable: true + }) + + Object.defineProperty(Function.prototype, 'onceStrict', { + value: function () { + return onceStrict(this) + }, + configurable: true + }) +}) + +function once (fn) { + var f = function () { + if (f.called) return f.value + f.called = true + return f.value = fn.apply(this, arguments) + } + f.called = false + return f +} + +function onceStrict (fn) { + var f = function () { + if (f.called) + throw new Error(f.onceError) + f.called = true + return f.value = fn.apply(this, arguments) + } + var name = fn.name || 'Function wrapped with `once`' + f.onceError = name + " shouldn't be called more than once" + f.called = false + return f +} + +},{"wrappy":29}],22:[function(require,module,exports){ +(function (process){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// resolves . and .. elements in a path array with directory names there +// must be no slashes, empty elements, or device names (c:\) in the array +// (so also no leading and trailing slashes - it does not distinguish +// relative and absolute paths) +function normalizeArray(parts, allowAboveRoot) { + // if the path tries to go above the root, `up` ends up > 0 + var up = 0; + for (var i = parts.length - 1; i >= 0; i--) { + var last = parts[i]; + if (last === '.') { + parts.splice(i, 1); + } else if (last === '..') { + parts.splice(i, 1); + up++; + } else if (up) { + parts.splice(i, 1); + up--; + } + } + + // if the path is allowed to go above the root, restore leading ..s + if (allowAboveRoot) { + for (; up--; up) { + parts.unshift('..'); + } + } + + return parts; +} + +// Split a filename into [root, dir, basename, ext], unix version +// 'root' is just a slash, or nothing. +var splitPathRe = + /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; +var splitPath = function(filename) { + return splitPathRe.exec(filename).slice(1); +}; + +// path.resolve([from ...], to) +// posix version +exports.resolve = function() { + var resolvedPath = '', + resolvedAbsolute = false; + + for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { + var path = (i >= 0) ? arguments[i] : process.cwd(); + + // Skip empty and invalid entries + if (typeof path !== 'string') { + throw new TypeError('Arguments to path.resolve must be strings'); + } else if (!path) { + continue; + } + + resolvedPath = path + '/' + resolvedPath; + resolvedAbsolute = path.charAt(0) === '/'; + } + + // At this point the path should be resolved to a full absolute path, but + // handle relative paths to be safe (might happen when process.cwd() fails) + + // Normalize the path + resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) { + return !!p; + }), !resolvedAbsolute).join('/'); + + return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; +}; + +// path.normalize(path) +// posix version +exports.normalize = function(path) { + var isAbsolute = exports.isAbsolute(path), + trailingSlash = substr(path, -1) === '/'; + + // Normalize the path + path = normalizeArray(filter(path.split('/'), function(p) { + return !!p; + }), !isAbsolute).join('/'); + + if (!path && !isAbsolute) { + path = '.'; + } + if (path && trailingSlash) { + path += '/'; + } + + return (isAbsolute ? '/' : '') + path; +}; + +// posix version +exports.isAbsolute = function(path) { + return path.charAt(0) === '/'; +}; + +// posix version +exports.join = function() { + var paths = Array.prototype.slice.call(arguments, 0); + return exports.normalize(filter(paths, function(p, index) { + if (typeof p !== 'string') { + throw new TypeError('Arguments to path.join must be strings'); + } + return p; + }).join('/')); +}; + + +// path.relative(from, to) +// posix version +exports.relative = function(from, to) { + from = exports.resolve(from).substr(1); + to = exports.resolve(to).substr(1); + + function trim(arr) { + var start = 0; + for (; start < arr.length; start++) { + if (arr[start] !== '') break; + } + + var end = arr.length - 1; + for (; end >= 0; end--) { + if (arr[end] !== '') break; + } + + if (start > end) return []; + return arr.slice(start, end - start + 1); + } + + var fromParts = trim(from.split('/')); + var toParts = trim(to.split('/')); + + var length = Math.min(fromParts.length, toParts.length); + var samePartsLength = length; + for (var i = 0; i < length; i++) { + if (fromParts[i] !== toParts[i]) { + samePartsLength = i; + break; + } + } + + var outputParts = []; + for (var i = samePartsLength; i < fromParts.length; i++) { + outputParts.push('..'); + } + + outputParts = outputParts.concat(toParts.slice(samePartsLength)); + + return outputParts.join('/'); +}; + +exports.sep = '/'; +exports.delimiter = ':'; + +exports.dirname = function(path) { + var result = splitPath(path), + root = result[0], + dir = result[1]; + + if (!root && !dir) { + // No dirname whatsoever + return '.'; + } + + if (dir) { + // It has a dirname, strip trailing slash + dir = dir.substr(0, dir.length - 1); + } + + return root + dir; +}; + + +exports.basename = function(path, ext) { + var f = splitPath(path)[2]; + // TODO: make this comparison case-insensitive on windows? + if (ext && f.substr(-1 * ext.length) === ext) { + f = f.substr(0, f.length - ext.length); + } + return f; +}; + + +exports.extname = function(path) { + return splitPath(path)[3]; +}; + +function filter (xs, f) { + if (xs.filter) return xs.filter(f); + var res = []; + for (var i = 0; i < xs.length; i++) { + if (f(xs[i], i, xs)) res.push(xs[i]); + } + return res; +} + +// String.prototype.substr - negative index don't work in IE8 +var substr = 'ab'.substr(-1) === 'b' + ? function (str, start, len) { return str.substr(start, len) } + : function (str, start, len) { + if (start < 0) start = str.length + start; + return str.substr(start, len); + } +; + +}).call(this,require('_process')) +},{"_process":24}],23:[function(require,module,exports){ +(function (process){ +'use strict'; + +function posix(path) { + return path.charAt(0) === '/'; +} + +function win32(path) { + // https://github.com/nodejs/node/blob/b3fcc245fb25539909ef1d5eaa01dbf92e168633/lib/path.js#L56 + var splitDeviceRe = /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/; + var result = splitDeviceRe.exec(path); + var device = result[1] || ''; + var isUnc = Boolean(device && device.charAt(1) !== ':'); + + // UNC paths are always absolute + return Boolean(result[2] || isUnc); +} + +module.exports = process.platform === 'win32' ? win32 : posix; +module.exports.posix = posix; +module.exports.win32 = win32; + +}).call(this,require('_process')) +},{"_process":24}],24:[function(require,module,exports){ +// shim for using process in browser +var process = module.exports = {}; + +// cached from whatever global is present so that test runners that stub it +// don't break things. But we need to wrap it in a try catch in case it is +// wrapped in strict mode code which doesn't define any globals. It's inside a +// function because try/catches deoptimize in certain engines. + +var cachedSetTimeout; +var cachedClearTimeout; + +function defaultSetTimout() { + throw new Error('setTimeout has not been defined'); +} +function defaultClearTimeout () { + throw new Error('clearTimeout has not been defined'); +} +(function () { + try { + if (typeof setTimeout === 'function') { + cachedSetTimeout = setTimeout; + } else { + cachedSetTimeout = defaultSetTimout; + } + } catch (e) { + cachedSetTimeout = defaultSetTimout; + } + try { + if (typeof clearTimeout === 'function') { + cachedClearTimeout = clearTimeout; + } else { + cachedClearTimeout = defaultClearTimeout; + } + } catch (e) { + cachedClearTimeout = defaultClearTimeout; + } +} ()) +function runTimeout(fun) { + if (cachedSetTimeout === setTimeout) { + //normal enviroments in sane situations + return setTimeout(fun, 0); + } + // if setTimeout wasn't available but was latter defined + if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { + cachedSetTimeout = setTimeout; + return setTimeout(fun, 0); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedSetTimeout(fun, 0); + } catch(e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedSetTimeout.call(null, fun, 0); + } catch(e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error + return cachedSetTimeout.call(this, fun, 0); + } + } + + +} +function runClearTimeout(marker) { + if (cachedClearTimeout === clearTimeout) { + //normal enviroments in sane situations + return clearTimeout(marker); + } + // if clearTimeout wasn't available but was latter defined + if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { + cachedClearTimeout = clearTimeout; + return clearTimeout(marker); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedClearTimeout(marker); + } catch (e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedClearTimeout.call(null, marker); + } catch (e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. + // Some versions of I.E. have different rules for clearTimeout vs setTimeout + return cachedClearTimeout.call(this, marker); + } + } + + + +} +var queue = []; +var draining = false; +var currentQueue; +var queueIndex = -1; + +function cleanUpNextTick() { + if (!draining || !currentQueue) { + return; + } + draining = false; + if (currentQueue.length) { + queue = currentQueue.concat(queue); + } else { + queueIndex = -1; + } + if (queue.length) { + drainQueue(); + } +} + +function drainQueue() { + if (draining) { + return; + } + var timeout = runTimeout(cleanUpNextTick); + draining = true; + + var len = queue.length; + while(len) { + currentQueue = queue; + queue = []; + while (++queueIndex < len) { + if (currentQueue) { + currentQueue[queueIndex].run(); + } + } + queueIndex = -1; + len = queue.length; + } + currentQueue = null; + draining = false; + runClearTimeout(timeout); +} + +process.nextTick = function (fun) { + var args = new Array(arguments.length - 1); + if (arguments.length > 1) { + for (var i = 1; i < arguments.length; i++) { + args[i - 1] = arguments[i]; + } + } + queue.push(new Item(fun, args)); + if (queue.length === 1 && !draining) { + runTimeout(drainQueue); + } +}; + +// v8 likes predictible objects +function Item(fun, array) { + this.fun = fun; + this.array = array; +} +Item.prototype.run = function () { + this.fun.apply(null, this.array); +}; +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; +process.version = ''; // empty string to avoid regexp issues +process.versions = {}; + +function noop() {} + +process.on = noop; +process.addListener = noop; +process.once = noop; +process.off = noop; +process.removeListener = noop; +process.removeAllListeners = noop; +process.emit = noop; +process.prependListener = noop; +process.prependOnceListener = noop; + +process.listeners = function (name) { return [] } + +process.binding = function (name) { + throw new Error('process.binding is not supported'); +}; + +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; +process.umask = function() { return 0; }; + +},{}],25:[function(require,module,exports){ +// Underscore.js 1.8.3 +// http://underscorejs.org +// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors +// Underscore may be freely distributed under the MIT license. + +(function() { + + // Baseline setup + // -------------- + + // Establish the root object, `window` in the browser, or `exports` on the server. + var root = this; + + // Save the previous value of the `_` variable. + var previousUnderscore = root._; + + // Save bytes in the minified (but not gzipped) version: + var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; + + // Create quick reference variables for speed access to core prototypes. + var + push = ArrayProto.push, + slice = ArrayProto.slice, + toString = ObjProto.toString, + hasOwnProperty = ObjProto.hasOwnProperty; + + // All **ECMAScript 5** native function implementations that we hope to use + // are declared here. + var + nativeIsArray = Array.isArray, + nativeKeys = Object.keys, + nativeBind = FuncProto.bind, + nativeCreate = Object.create; + + // Naked function reference for surrogate-prototype-swapping. + var Ctor = function(){}; + + // Create a safe reference to the Underscore object for use below. + var _ = function(obj) { + if (obj instanceof _) return obj; + if (!(this instanceof _)) return new _(obj); + this._wrapped = obj; + }; + + // Export the Underscore object for **Node.js**, with + // backwards-compatibility for the old `require()` API. If we're in + // the browser, add `_` as a global object. + if (typeof exports !== 'undefined') { + if (typeof module !== 'undefined' && module.exports) { + exports = module.exports = _; + } + exports._ = _; + } else { + root._ = _; + } + + // Current version. + _.VERSION = '1.8.3'; + + // Internal function that returns an efficient (for current engines) version + // of the passed-in callback, to be repeatedly applied in other Underscore + // functions. + var optimizeCb = function(func, context, argCount) { + if (context === void 0) return func; + switch (argCount == null ? 3 : argCount) { + case 1: return function(value) { + return func.call(context, value); + }; + case 2: return function(value, other) { + return func.call(context, value, other); + }; + case 3: return function(value, index, collection) { + return func.call(context, value, index, collection); + }; + case 4: return function(accumulator, value, index, collection) { + return func.call(context, accumulator, value, index, collection); + }; + } + return function() { + return func.apply(context, arguments); + }; + }; + + // A mostly-internal function to generate callbacks that can be applied + // to each element in a collection, returning the desired result — either + // identity, an arbitrary callback, a property matcher, or a property accessor. + var cb = function(value, context, argCount) { + if (value == null) return _.identity; + if (_.isFunction(value)) return optimizeCb(value, context, argCount); + if (_.isObject(value)) return _.matcher(value); + return _.property(value); + }; + _.iteratee = function(value, context) { + return cb(value, context, Infinity); + }; + + // An internal function for creating assigner functions. + var createAssigner = function(keysFunc, undefinedOnly) { + return function(obj) { + var length = arguments.length; + if (length < 2 || obj == null) return obj; + for (var index = 1; index < length; index++) { + var source = arguments[index], + keys = keysFunc(source), + l = keys.length; + for (var i = 0; i < l; i++) { + var key = keys[i]; + if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key]; + } + } + return obj; + }; + }; + + // An internal function for creating a new object that inherits from another. + var baseCreate = function(prototype) { + if (!_.isObject(prototype)) return {}; + if (nativeCreate) return nativeCreate(prototype); + Ctor.prototype = prototype; + var result = new Ctor; + Ctor.prototype = null; + return result; + }; + + var property = function(key) { + return function(obj) { + return obj == null ? void 0 : obj[key]; + }; + }; + + // Helper for collection methods to determine whether a collection + // should be iterated as an array or as an object + // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength + // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094 + var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1; + var getLength = property('length'); + var isArrayLike = function(collection) { + var length = getLength(collection); + return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX; + }; + + // Collection Functions + // -------------------- + + // The cornerstone, an `each` implementation, aka `forEach`. + // Handles raw objects in addition to array-likes. Treats all + // sparse array-likes as if they were dense. + _.each = _.forEach = function(obj, iteratee, context) { + iteratee = optimizeCb(iteratee, context); + var i, length; + if (isArrayLike(obj)) { + for (i = 0, length = obj.length; i < length; i++) { + iteratee(obj[i], i, obj); + } + } else { + var keys = _.keys(obj); + for (i = 0, length = keys.length; i < length; i++) { + iteratee(obj[keys[i]], keys[i], obj); + } + } + return obj; + }; + + // Return the results of applying the iteratee to each element. + _.map = _.collect = function(obj, iteratee, context) { + iteratee = cb(iteratee, context); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length, + results = Array(length); + for (var index = 0; index < length; index++) { + var currentKey = keys ? keys[index] : index; + results[index] = iteratee(obj[currentKey], currentKey, obj); + } + return results; + }; + + // Create a reducing function iterating left or right. + function createReduce(dir) { + // Optimized iterator function as using arguments.length + // in the main function will deoptimize the, see #1991. + function iterator(obj, iteratee, memo, keys, index, length) { + for (; index >= 0 && index < length; index += dir) { + var currentKey = keys ? keys[index] : index; + memo = iteratee(memo, obj[currentKey], currentKey, obj); + } + return memo; + } + + return function(obj, iteratee, memo, context) { + iteratee = optimizeCb(iteratee, context, 4); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length, + index = dir > 0 ? 0 : length - 1; + // Determine the initial value if none is provided. + if (arguments.length < 3) { + memo = obj[keys ? keys[index] : index]; + index += dir; + } + return iterator(obj, iteratee, memo, keys, index, length); + }; + } + + // **Reduce** builds up a single result from a list of values, aka `inject`, + // or `foldl`. + _.reduce = _.foldl = _.inject = createReduce(1); + + // The right-associative version of reduce, also known as `foldr`. + _.reduceRight = _.foldr = createReduce(-1); + + // Return the first value which passes a truth test. Aliased as `detect`. + _.find = _.detect = function(obj, predicate, context) { + var key; + if (isArrayLike(obj)) { + key = _.findIndex(obj, predicate, context); + } else { + key = _.findKey(obj, predicate, context); + } + if (key !== void 0 && key !== -1) return obj[key]; + }; + + // Return all the elements that pass a truth test. + // Aliased as `select`. + _.filter = _.select = function(obj, predicate, context) { + var results = []; + predicate = cb(predicate, context); + _.each(obj, function(value, index, list) { + if (predicate(value, index, list)) results.push(value); + }); + return results; + }; + + // Return all the elements for which a truth test fails. + _.reject = function(obj, predicate, context) { + return _.filter(obj, _.negate(cb(predicate)), context); + }; + + // Determine whether all of the elements match a truth test. + // Aliased as `all`. + _.every = _.all = function(obj, predicate, context) { + predicate = cb(predicate, context); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length; + for (var index = 0; index < length; index++) { + var currentKey = keys ? keys[index] : index; + if (!predicate(obj[currentKey], currentKey, obj)) return false; + } + return true; + }; + + // Determine if at least one element in the object matches a truth test. + // Aliased as `any`. + _.some = _.any = function(obj, predicate, context) { + predicate = cb(predicate, context); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length; + for (var index = 0; index < length; index++) { + var currentKey = keys ? keys[index] : index; + if (predicate(obj[currentKey], currentKey, obj)) return true; + } + return false; + }; + + // Determine if the array or object contains a given item (using `===`). + // Aliased as `includes` and `include`. + _.contains = _.includes = _.include = function(obj, item, fromIndex, guard) { + if (!isArrayLike(obj)) obj = _.values(obj); + if (typeof fromIndex != 'number' || guard) fromIndex = 0; + return _.indexOf(obj, item, fromIndex) >= 0; + }; + + // Invoke a method (with arguments) on every item in a collection. + _.invoke = function(obj, method) { + var args = slice.call(arguments, 2); + var isFunc = _.isFunction(method); + return _.map(obj, function(value) { + var func = isFunc ? method : value[method]; + return func == null ? func : func.apply(value, args); + }); + }; + + // Convenience version of a common use case of `map`: fetching a property. + _.pluck = function(obj, key) { + return _.map(obj, _.property(key)); + }; + + // Convenience version of a common use case of `filter`: selecting only objects + // containing specific `key:value` pairs. + _.where = function(obj, attrs) { + return _.filter(obj, _.matcher(attrs)); + }; + + // Convenience version of a common use case of `find`: getting the first object + // containing specific `key:value` pairs. + _.findWhere = function(obj, attrs) { + return _.find(obj, _.matcher(attrs)); + }; + + // Return the maximum element (or element-based computation). + _.max = function(obj, iteratee, context) { + var result = -Infinity, lastComputed = -Infinity, + value, computed; + if (iteratee == null && obj != null) { + obj = isArrayLike(obj) ? obj : _.values(obj); + for (var i = 0, length = obj.length; i < length; i++) { + value = obj[i]; + if (value > result) { + result = value; + } + } + } else { + iteratee = cb(iteratee, context); + _.each(obj, function(value, index, list) { + computed = iteratee(value, index, list); + if (computed > lastComputed || computed === -Infinity && result === -Infinity) { + result = value; + lastComputed = computed; + } + }); + } + return result; + }; + + // Return the minimum element (or element-based computation). + _.min = function(obj, iteratee, context) { + var result = Infinity, lastComputed = Infinity, + value, computed; + if (iteratee == null && obj != null) { + obj = isArrayLike(obj) ? obj : _.values(obj); + for (var i = 0, length = obj.length; i < length; i++) { + value = obj[i]; + if (value < result) { + result = value; + } + } + } else { + iteratee = cb(iteratee, context); + _.each(obj, function(value, index, list) { + computed = iteratee(value, index, list); + if (computed < lastComputed || computed === Infinity && result === Infinity) { + result = value; + lastComputed = computed; + } + }); + } + return result; + }; + + // Shuffle a collection, using the modern version of the + // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle). + _.shuffle = function(obj) { + var set = isArrayLike(obj) ? obj : _.values(obj); + var length = set.length; + var shuffled = Array(length); + for (var index = 0, rand; index < length; index++) { + rand = _.random(0, index); + if (rand !== index) shuffled[index] = shuffled[rand]; + shuffled[rand] = set[index]; + } + return shuffled; + }; + + // Sample **n** random values from a collection. + // If **n** is not specified, returns a single random element. + // The internal `guard` argument allows it to work with `map`. + _.sample = function(obj, n, guard) { + if (n == null || guard) { + if (!isArrayLike(obj)) obj = _.values(obj); + return obj[_.random(obj.length - 1)]; + } + return _.shuffle(obj).slice(0, Math.max(0, n)); + }; + + // Sort the object's values by a criterion produced by an iteratee. + _.sortBy = function(obj, iteratee, context) { + iteratee = cb(iteratee, context); + return _.pluck(_.map(obj, function(value, index, list) { + return { + value: value, + index: index, + criteria: iteratee(value, index, list) + }; + }).sort(function(left, right) { + var a = left.criteria; + var b = right.criteria; + if (a !== b) { + if (a > b || a === void 0) return 1; + if (a < b || b === void 0) return -1; + } + return left.index - right.index; + }), 'value'); + }; + + // An internal function used for aggregate "group by" operations. + var group = function(behavior) { + return function(obj, iteratee, context) { + var result = {}; + iteratee = cb(iteratee, context); + _.each(obj, function(value, index) { + var key = iteratee(value, index, obj); + behavior(result, value, key); + }); + return result; + }; + }; + + // Groups the object's values by a criterion. Pass either a string attribute + // to group by, or a function that returns the criterion. + _.groupBy = group(function(result, value, key) { + if (_.has(result, key)) result[key].push(value); else result[key] = [value]; + }); + + // Indexes the object's values by a criterion, similar to `groupBy`, but for + // when you know that your index values will be unique. + _.indexBy = group(function(result, value, key) { + result[key] = value; + }); + + // Counts instances of an object that group by a certain criterion. Pass + // either a string attribute to count by, or a function that returns the + // criterion. + _.countBy = group(function(result, value, key) { + if (_.has(result, key)) result[key]++; else result[key] = 1; + }); + + // Safely create a real, live array from anything iterable. + _.toArray = function(obj) { + if (!obj) return []; + if (_.isArray(obj)) return slice.call(obj); + if (isArrayLike(obj)) return _.map(obj, _.identity); + return _.values(obj); + }; + + // Return the number of elements in an object. + _.size = function(obj) { + if (obj == null) return 0; + return isArrayLike(obj) ? obj.length : _.keys(obj).length; + }; + + // Split a collection into two arrays: one whose elements all satisfy the given + // predicate, and one whose elements all do not satisfy the predicate. + _.partition = function(obj, predicate, context) { + predicate = cb(predicate, context); + var pass = [], fail = []; + _.each(obj, function(value, key, obj) { + (predicate(value, key, obj) ? pass : fail).push(value); + }); + return [pass, fail]; + }; + + // Array Functions + // --------------- + + // Get the first element of an array. Passing **n** will return the first N + // values in the array. Aliased as `head` and `take`. The **guard** check + // allows it to work with `_.map`. + _.first = _.head = _.take = function(array, n, guard) { + if (array == null) return void 0; + if (n == null || guard) return array[0]; + return _.initial(array, array.length - n); + }; + + // Returns everything but the last entry of the array. Especially useful on + // the arguments object. Passing **n** will return all the values in + // the array, excluding the last N. + _.initial = function(array, n, guard) { + return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n))); + }; + + // Get the last element of an array. Passing **n** will return the last N + // values in the array. + _.last = function(array, n, guard) { + if (array == null) return void 0; + if (n == null || guard) return array[array.length - 1]; + return _.rest(array, Math.max(0, array.length - n)); + }; + + // Returns everything but the first entry of the array. Aliased as `tail` and `drop`. + // Especially useful on the arguments object. Passing an **n** will return + // the rest N values in the array. + _.rest = _.tail = _.drop = function(array, n, guard) { + return slice.call(array, n == null || guard ? 1 : n); + }; + + // Trim out all falsy values from an array. + _.compact = function(array) { + return _.filter(array, _.identity); + }; + + // Internal implementation of a recursive `flatten` function. + var flatten = function(input, shallow, strict, startIndex) { + var output = [], idx = 0; + for (var i = startIndex || 0, length = getLength(input); i < length; i++) { + var value = input[i]; + if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) { + //flatten current level of array or arguments object + if (!shallow) value = flatten(value, shallow, strict); + var j = 0, len = value.length; + output.length += len; + while (j < len) { + output[idx++] = value[j++]; + } + } else if (!strict) { + output[idx++] = value; + } + } + return output; + }; + + // Flatten out an array, either recursively (by default), or just one level. + _.flatten = function(array, shallow) { + return flatten(array, shallow, false); + }; + + // Return a version of the array that does not contain the specified value(s). + _.without = function(array) { + return _.difference(array, slice.call(arguments, 1)); + }; + + // Produce a duplicate-free version of the array. If the array has already + // been sorted, you have the option of using a faster algorithm. + // Aliased as `unique`. + _.uniq = _.unique = function(array, isSorted, iteratee, context) { + if (!_.isBoolean(isSorted)) { + context = iteratee; + iteratee = isSorted; + isSorted = false; + } + if (iteratee != null) iteratee = cb(iteratee, context); + var result = []; + var seen = []; + for (var i = 0, length = getLength(array); i < length; i++) { + var value = array[i], + computed = iteratee ? iteratee(value, i, array) : value; + if (isSorted) { + if (!i || seen !== computed) result.push(value); + seen = computed; + } else if (iteratee) { + if (!_.contains(seen, computed)) { + seen.push(computed); + result.push(value); + } + } else if (!_.contains(result, value)) { + result.push(value); + } + } + return result; + }; + + // Produce an array that contains the union: each distinct element from all of + // the passed-in arrays. + _.union = function() { + return _.uniq(flatten(arguments, true, true)); + }; + + // Produce an array that contains every item shared between all the + // passed-in arrays. + _.intersection = function(array) { + var result = []; + var argsLength = arguments.length; + for (var i = 0, length = getLength(array); i < length; i++) { + var item = array[i]; + if (_.contains(result, item)) continue; + for (var j = 1; j < argsLength; j++) { + if (!_.contains(arguments[j], item)) break; + } + if (j === argsLength) result.push(item); + } + return result; + }; + + // Take the difference between one array and a number of other arrays. + // Only the elements present in just the first array will remain. + _.difference = function(array) { + var rest = flatten(arguments, true, true, 1); + return _.filter(array, function(value){ + return !_.contains(rest, value); + }); + }; + + // Zip together multiple lists into a single array -- elements that share + // an index go together. + _.zip = function() { + return _.unzip(arguments); + }; + + // Complement of _.zip. Unzip accepts an array of arrays and groups + // each array's elements on shared indices + _.unzip = function(array) { + var length = array && _.max(array, getLength).length || 0; + var result = Array(length); + + for (var index = 0; index < length; index++) { + result[index] = _.pluck(array, index); + } + return result; + }; + + // Converts lists into objects. Pass either a single array of `[key, value]` + // pairs, or two parallel arrays of the same length -- one of keys, and one of + // the corresponding values. + _.object = function(list, values) { + var result = {}; + for (var i = 0, length = getLength(list); i < length; i++) { + if (values) { + result[list[i]] = values[i]; + } else { + result[list[i][0]] = list[i][1]; + } + } + return result; + }; + + // Generator function to create the findIndex and findLastIndex functions + function createPredicateIndexFinder(dir) { + return function(array, predicate, context) { + predicate = cb(predicate, context); + var length = getLength(array); + var index = dir > 0 ? 0 : length - 1; + for (; index >= 0 && index < length; index += dir) { + if (predicate(array[index], index, array)) return index; + } + return -1; + }; + } + + // Returns the first index on an array-like that passes a predicate test + _.findIndex = createPredicateIndexFinder(1); + _.findLastIndex = createPredicateIndexFinder(-1); + + // Use a comparator function to figure out the smallest index at which + // an object should be inserted so as to maintain order. Uses binary search. + _.sortedIndex = function(array, obj, iteratee, context) { + iteratee = cb(iteratee, context, 1); + var value = iteratee(obj); + var low = 0, high = getLength(array); + while (low < high) { + var mid = Math.floor((low + high) / 2); + if (iteratee(array[mid]) < value) low = mid + 1; else high = mid; + } + return low; + }; + + // Generator function to create the indexOf and lastIndexOf functions + function createIndexFinder(dir, predicateFind, sortedIndex) { + return function(array, item, idx) { + var i = 0, length = getLength(array); + if (typeof idx == 'number') { + if (dir > 0) { + i = idx >= 0 ? idx : Math.max(idx + length, i); + } else { + length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1; + } + } else if (sortedIndex && idx && length) { + idx = sortedIndex(array, item); + return array[idx] === item ? idx : -1; + } + if (item !== item) { + idx = predicateFind(slice.call(array, i, length), _.isNaN); + return idx >= 0 ? idx + i : -1; + } + for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) { + if (array[idx] === item) return idx; + } + return -1; + }; + } + + // Return the position of the first occurrence of an item in an array, + // or -1 if the item is not included in the array. + // If the array is large and already in sort order, pass `true` + // for **isSorted** to use binary search. + _.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex); + _.lastIndexOf = createIndexFinder(-1, _.findLastIndex); + + // Generate an integer Array containing an arithmetic progression. A port of + // the native Python `range()` function. See + // [the Python documentation](http://docs.python.org/library/functions.html#range). + _.range = function(start, stop, step) { + if (stop == null) { + stop = start || 0; + start = 0; + } + step = step || 1; + + var length = Math.max(Math.ceil((stop - start) / step), 0); + var range = Array(length); + + for (var idx = 0; idx < length; idx++, start += step) { + range[idx] = start; + } + + return range; + }; + + // Function (ahem) Functions + // ------------------ + + // Determines whether to execute a function as a constructor + // or a normal function with the provided arguments + var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) { + if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args); + var self = baseCreate(sourceFunc.prototype); + var result = sourceFunc.apply(self, args); + if (_.isObject(result)) return result; + return self; + }; + + // Create a function bound to a given object (assigning `this`, and arguments, + // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if + // available. + _.bind = function(func, context) { + if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); + if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function'); + var args = slice.call(arguments, 2); + var bound = function() { + return executeBound(func, bound, context, this, args.concat(slice.call(arguments))); + }; + return bound; + }; + + // Partially apply a function by creating a version that has had some of its + // arguments pre-filled, without changing its dynamic `this` context. _ acts + // as a placeholder, allowing any combination of arguments to be pre-filled. + _.partial = function(func) { + var boundArgs = slice.call(arguments, 1); + var bound = function() { + var position = 0, length = boundArgs.length; + var args = Array(length); + for (var i = 0; i < length; i++) { + args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i]; + } + while (position < arguments.length) args.push(arguments[position++]); + return executeBound(func, bound, this, this, args); + }; + return bound; + }; + + // Bind a number of an object's methods to that object. Remaining arguments + // are the method names to be bound. Useful for ensuring that all callbacks + // defined on an object belong to it. + _.bindAll = function(obj) { + var i, length = arguments.length, key; + if (length <= 1) throw new Error('bindAll must be passed function names'); + for (i = 1; i < length; i++) { + key = arguments[i]; + obj[key] = _.bind(obj[key], obj); + } + return obj; + }; + + // Memoize an expensive function by storing its results. + _.memoize = function(func, hasher) { + var memoize = function(key) { + var cache = memoize.cache; + var address = '' + (hasher ? hasher.apply(this, arguments) : key); + if (!_.has(cache, address)) cache[address] = func.apply(this, arguments); + return cache[address]; + }; + memoize.cache = {}; + return memoize; + }; + + // Delays a function for the given number of milliseconds, and then calls + // it with the arguments supplied. + _.delay = function(func, wait) { + var args = slice.call(arguments, 2); + return setTimeout(function(){ + return func.apply(null, args); + }, wait); + }; + + // Defers a function, scheduling it to run after the current call stack has + // cleared. + _.defer = _.partial(_.delay, _, 1); + + // Returns a function, that, when invoked, will only be triggered at most once + // during a given window of time. Normally, the throttled function will run + // as much as it can, without ever going more than once per `wait` duration; + // but if you'd like to disable the execution on the leading edge, pass + // `{leading: false}`. To disable execution on the trailing edge, ditto. + _.throttle = function(func, wait, options) { + var context, args, result; + var timeout = null; + var previous = 0; + if (!options) options = {}; + var later = function() { + previous = options.leading === false ? 0 : _.now(); + timeout = null; + result = func.apply(context, args); + if (!timeout) context = args = null; + }; + return function() { + var now = _.now(); + if (!previous && options.leading === false) previous = now; + var remaining = wait - (now - previous); + context = this; + args = arguments; + if (remaining <= 0 || remaining > wait) { + if (timeout) { + clearTimeout(timeout); + timeout = null; + } + previous = now; + result = func.apply(context, args); + if (!timeout) context = args = null; + } else if (!timeout && options.trailing !== false) { + timeout = setTimeout(later, remaining); + } + return result; + }; + }; + + // Returns a function, that, as long as it continues to be invoked, will not + // be triggered. The function will be called after it stops being called for + // N milliseconds. If `immediate` is passed, trigger the function on the + // leading edge, instead of the trailing. + _.debounce = function(func, wait, immediate) { + var timeout, args, context, timestamp, result; + + var later = function() { + var last = _.now() - timestamp; + + if (last < wait && last >= 0) { + timeout = setTimeout(later, wait - last); + } else { + timeout = null; + if (!immediate) { + result = func.apply(context, args); + if (!timeout) context = args = null; + } + } + }; + + return function() { + context = this; + args = arguments; + timestamp = _.now(); + var callNow = immediate && !timeout; + if (!timeout) timeout = setTimeout(later, wait); + if (callNow) { + result = func.apply(context, args); + context = args = null; + } + + return result; + }; + }; + + // Returns the first function passed as an argument to the second, + // allowing you to adjust arguments, run code before and after, and + // conditionally execute the original function. + _.wrap = function(func, wrapper) { + return _.partial(wrapper, func); + }; + + // Returns a negated version of the passed-in predicate. + _.negate = function(predicate) { + return function() { + return !predicate.apply(this, arguments); + }; + }; + + // Returns a function that is the composition of a list of functions, each + // consuming the return value of the function that follows. + _.compose = function() { + var args = arguments; + var start = args.length - 1; + return function() { + var i = start; + var result = args[start].apply(this, arguments); + while (i--) result = args[i].call(this, result); + return result; + }; + }; + + // Returns a function that will only be executed on and after the Nth call. + _.after = function(times, func) { + return function() { + if (--times < 1) { + return func.apply(this, arguments); + } + }; + }; + + // Returns a function that will only be executed up to (but not including) the Nth call. + _.before = function(times, func) { + var memo; + return function() { + if (--times > 0) { + memo = func.apply(this, arguments); + } + if (times <= 1) func = null; + return memo; + }; + }; + + // Returns a function that will be executed at most one time, no matter how + // often you call it. Useful for lazy initialization. + _.once = _.partial(_.before, 2); + + // Object Functions + // ---------------- + + // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed. + var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString'); + var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString', + 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString']; + + function collectNonEnumProps(obj, keys) { + var nonEnumIdx = nonEnumerableProps.length; + var constructor = obj.constructor; + var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto; + + // Constructor is a special case. + var prop = 'constructor'; + if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop); + + while (nonEnumIdx--) { + prop = nonEnumerableProps[nonEnumIdx]; + if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) { + keys.push(prop); + } + } + } + + // Retrieve the names of an object's own properties. + // Delegates to **ECMAScript 5**'s native `Object.keys` + _.keys = function(obj) { + if (!_.isObject(obj)) return []; + if (nativeKeys) return nativeKeys(obj); + var keys = []; + for (var key in obj) if (_.has(obj, key)) keys.push(key); + // Ahem, IE < 9. + if (hasEnumBug) collectNonEnumProps(obj, keys); + return keys; + }; + + // Retrieve all the property names of an object. + _.allKeys = function(obj) { + if (!_.isObject(obj)) return []; + var keys = []; + for (var key in obj) keys.push(key); + // Ahem, IE < 9. + if (hasEnumBug) collectNonEnumProps(obj, keys); + return keys; + }; + + // Retrieve the values of an object's properties. + _.values = function(obj) { + var keys = _.keys(obj); + var length = keys.length; + var values = Array(length); + for (var i = 0; i < length; i++) { + values[i] = obj[keys[i]]; + } + return values; + }; + + // Returns the results of applying the iteratee to each element of the object + // In contrast to _.map it returns an object + _.mapObject = function(obj, iteratee, context) { + iteratee = cb(iteratee, context); + var keys = _.keys(obj), + length = keys.length, + results = {}, + currentKey; + for (var index = 0; index < length; index++) { + currentKey = keys[index]; + results[currentKey] = iteratee(obj[currentKey], currentKey, obj); + } + return results; + }; + + // Convert an object into a list of `[key, value]` pairs. + _.pairs = function(obj) { + var keys = _.keys(obj); + var length = keys.length; + var pairs = Array(length); + for (var i = 0; i < length; i++) { + pairs[i] = [keys[i], obj[keys[i]]]; + } + return pairs; + }; + + // Invert the keys and values of an object. The values must be serializable. + _.invert = function(obj) { + var result = {}; + var keys = _.keys(obj); + for (var i = 0, length = keys.length; i < length; i++) { + result[obj[keys[i]]] = keys[i]; + } + return result; + }; + + // Return a sorted list of the function names available on the object. + // Aliased as `methods` + _.functions = _.methods = function(obj) { + var names = []; + for (var key in obj) { + if (_.isFunction(obj[key])) names.push(key); + } + return names.sort(); + }; + + // Extend a given object with all the properties in passed-in object(s). + _.extend = createAssigner(_.allKeys); + + // Assigns a given object with all the own properties in the passed-in object(s) + // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) + _.extendOwn = _.assign = createAssigner(_.keys); + + // Returns the first key on an object that passes a predicate test + _.findKey = function(obj, predicate, context) { + predicate = cb(predicate, context); + var keys = _.keys(obj), key; + for (var i = 0, length = keys.length; i < length; i++) { + key = keys[i]; + if (predicate(obj[key], key, obj)) return key; + } + }; + + // Return a copy of the object only containing the whitelisted properties. + _.pick = function(object, oiteratee, context) { + var result = {}, obj = object, iteratee, keys; + if (obj == null) return result; + if (_.isFunction(oiteratee)) { + keys = _.allKeys(obj); + iteratee = optimizeCb(oiteratee, context); + } else { + keys = flatten(arguments, false, false, 1); + iteratee = function(value, key, obj) { return key in obj; }; + obj = Object(obj); + } + for (var i = 0, length = keys.length; i < length; i++) { + var key = keys[i]; + var value = obj[key]; + if (iteratee(value, key, obj)) result[key] = value; + } + return result; + }; + + // Return a copy of the object without the blacklisted properties. + _.omit = function(obj, iteratee, context) { + if (_.isFunction(iteratee)) { + iteratee = _.negate(iteratee); + } else { + var keys = _.map(flatten(arguments, false, false, 1), String); + iteratee = function(value, key) { + return !_.contains(keys, key); + }; + } + return _.pick(obj, iteratee, context); + }; + + // Fill in a given object with default properties. + _.defaults = createAssigner(_.allKeys, true); + + // Creates an object that inherits from the given prototype object. + // If additional properties are provided then they will be added to the + // created object. + _.create = function(prototype, props) { + var result = baseCreate(prototype); + if (props) _.extendOwn(result, props); + return result; + }; + + // Create a (shallow-cloned) duplicate of an object. + _.clone = function(obj) { + if (!_.isObject(obj)) return obj; + return _.isArray(obj) ? obj.slice() : _.extend({}, obj); + }; + + // Invokes interceptor with the obj, and then returns obj. + // The primary purpose of this method is to "tap into" a method chain, in + // order to perform operations on intermediate results within the chain. + _.tap = function(obj, interceptor) { + interceptor(obj); + return obj; + }; + + // Returns whether an object has a given set of `key:value` pairs. + _.isMatch = function(object, attrs) { + var keys = _.keys(attrs), length = keys.length; + if (object == null) return !length; + var obj = Object(object); + for (var i = 0; i < length; i++) { + var key = keys[i]; + if (attrs[key] !== obj[key] || !(key in obj)) return false; + } + return true; + }; + + + // Internal recursive comparison function for `isEqual`. + var eq = function(a, b, aStack, bStack) { + // Identical objects are equal. `0 === -0`, but they aren't identical. + // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). + if (a === b) return a !== 0 || 1 / a === 1 / b; + // A strict comparison is necessary because `null == undefined`. + if (a == null || b == null) return a === b; + // Unwrap any wrapped objects. + if (a instanceof _) a = a._wrapped; + if (b instanceof _) b = b._wrapped; + // Compare `[[Class]]` names. + var className = toString.call(a); + if (className !== toString.call(b)) return false; + switch (className) { + // Strings, numbers, regular expressions, dates, and booleans are compared by value. + case '[object RegExp]': + // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i') + case '[object String]': + // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is + // equivalent to `new String("5")`. + return '' + a === '' + b; + case '[object Number]': + // `NaN`s are equivalent, but non-reflexive. + // Object(NaN) is equivalent to NaN + if (+a !== +a) return +b !== +b; + // An `egal` comparison is performed for other numeric values. + return +a === 0 ? 1 / +a === 1 / b : +a === +b; + case '[object Date]': + case '[object Boolean]': + // Coerce dates and booleans to numeric primitive values. Dates are compared by their + // millisecond representations. Note that invalid dates with millisecond representations + // of `NaN` are not equivalent. + return +a === +b; + } + + var areArrays = className === '[object Array]'; + if (!areArrays) { + if (typeof a != 'object' || typeof b != 'object') return false; + + // Objects with different constructors are not equivalent, but `Object`s or `Array`s + // from different frames are. + var aCtor = a.constructor, bCtor = b.constructor; + if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor && + _.isFunction(bCtor) && bCtor instanceof bCtor) + && ('constructor' in a && 'constructor' in b)) { + return false; + } + } + // Assume equality for cyclic structures. The algorithm for detecting cyclic + // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. + + // Initializing stack of traversed objects. + // It's done here since we only need them for objects and arrays comparison. + aStack = aStack || []; + bStack = bStack || []; + var length = aStack.length; + while (length--) { + // Linear search. Performance is inversely proportional to the number of + // unique nested structures. + if (aStack[length] === a) return bStack[length] === b; + } + + // Add the first object to the stack of traversed objects. + aStack.push(a); + bStack.push(b); + + // Recursively compare objects and arrays. + if (areArrays) { + // Compare array lengths to determine if a deep comparison is necessary. + length = a.length; + if (length !== b.length) return false; + // Deep compare the contents, ignoring non-numeric properties. + while (length--) { + if (!eq(a[length], b[length], aStack, bStack)) return false; + } + } else { + // Deep compare objects. + var keys = _.keys(a), key; + length = keys.length; + // Ensure that both objects contain the same number of properties before comparing deep equality. + if (_.keys(b).length !== length) return false; + while (length--) { + // Deep compare each member + key = keys[length]; + if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false; + } + } + // Remove the first object from the stack of traversed objects. + aStack.pop(); + bStack.pop(); + return true; + }; + + // Perform a deep comparison to check if two objects are equal. + _.isEqual = function(a, b) { + return eq(a, b); + }; + + // Is a given array, string, or object empty? + // An "empty" object has no enumerable own-properties. + _.isEmpty = function(obj) { + if (obj == null) return true; + if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0; + return _.keys(obj).length === 0; + }; + + // Is a given value a DOM element? + _.isElement = function(obj) { + return !!(obj && obj.nodeType === 1); + }; + + // Is a given value an array? + // Delegates to ECMA5's native Array.isArray + _.isArray = nativeIsArray || function(obj) { + return toString.call(obj) === '[object Array]'; + }; + + // Is a given variable an object? + _.isObject = function(obj) { + var type = typeof obj; + return type === 'function' || type === 'object' && !!obj; + }; + + // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError. + _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) { + _['is' + name] = function(obj) { + return toString.call(obj) === '[object ' + name + ']'; + }; + }); + + // Define a fallback version of the method in browsers (ahem, IE < 9), where + // there isn't any inspectable "Arguments" type. + if (!_.isArguments(arguments)) { + _.isArguments = function(obj) { + return _.has(obj, 'callee'); + }; + } + + // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8, + // IE 11 (#1621), and in Safari 8 (#1929). + if (typeof /./ != 'function' && typeof Int8Array != 'object') { + _.isFunction = function(obj) { + return typeof obj == 'function' || false; + }; + } + + // Is a given object a finite number? + _.isFinite = function(obj) { + return isFinite(obj) && !isNaN(parseFloat(obj)); + }; + + // Is the given value `NaN`? (NaN is the only number which does not equal itself). + _.isNaN = function(obj) { + return _.isNumber(obj) && obj !== +obj; + }; + + // Is a given value a boolean? + _.isBoolean = function(obj) { + return obj === true || obj === false || toString.call(obj) === '[object Boolean]'; + }; + + // Is a given value equal to null? + _.isNull = function(obj) { + return obj === null; + }; + + // Is a given variable undefined? + _.isUndefined = function(obj) { + return obj === void 0; + }; + + // Shortcut function for checking if an object has a given property directly + // on itself (in other words, not on a prototype). + _.has = function(obj, key) { + return obj != null && hasOwnProperty.call(obj, key); + }; + + // Utility Functions + // ----------------- + + // Run Underscore.js in *noConflict* mode, returning the `_` variable to its + // previous owner. Returns a reference to the Underscore object. + _.noConflict = function() { + root._ = previousUnderscore; + return this; + }; + + // Keep the identity function around for default iteratees. + _.identity = function(value) { + return value; + }; + + // Predicate-generating functions. Often useful outside of Underscore. + _.constant = function(value) { + return function() { + return value; + }; + }; + + _.noop = function(){}; + + _.property = property; + + // Generates a function for a given object that returns a given property. + _.propertyOf = function(obj) { + return obj == null ? function(){} : function(key) { + return obj[key]; + }; + }; + + // Returns a predicate for checking whether an object has a given set of + // `key:value` pairs. + _.matcher = _.matches = function(attrs) { + attrs = _.extendOwn({}, attrs); + return function(obj) { + return _.isMatch(obj, attrs); + }; + }; + + // Run a function **n** times. + _.times = function(n, iteratee, context) { + var accum = Array(Math.max(0, n)); + iteratee = optimizeCb(iteratee, context, 1); + for (var i = 0; i < n; i++) accum[i] = iteratee(i); + return accum; + }; + + // Return a random integer between min and max (inclusive). + _.random = function(min, max) { + if (max == null) { + max = min; + min = 0; + } + return min + Math.floor(Math.random() * (max - min + 1)); + }; + + // A (possibly faster) way to get the current timestamp as an integer. + _.now = Date.now || function() { + return new Date().getTime(); + }; + + // List of HTML entities for escaping. + var escapeMap = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '`': '`' + }; + var unescapeMap = _.invert(escapeMap); + + // Functions for escaping and unescaping strings to/from HTML interpolation. + var createEscaper = function(map) { + var escaper = function(match) { + return map[match]; + }; + // Regexes for identifying a key that needs to be escaped + var source = '(?:' + _.keys(map).join('|') + ')'; + var testRegexp = RegExp(source); + var replaceRegexp = RegExp(source, 'g'); + return function(string) { + string = string == null ? '' : '' + string; + return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string; + }; + }; + _.escape = createEscaper(escapeMap); + _.unescape = createEscaper(unescapeMap); + + // If the value of the named `property` is a function then invoke it with the + // `object` as context; otherwise, return it. + _.result = function(object, property, fallback) { + var value = object == null ? void 0 : object[property]; + if (value === void 0) { + value = fallback; + } + return _.isFunction(value) ? value.call(object) : value; + }; + + // Generate a unique integer id (unique within the entire client session). + // Useful for temporary DOM ids. + var idCounter = 0; + _.uniqueId = function(prefix) { + var id = ++idCounter + ''; + return prefix ? prefix + id : id; + }; + + // By default, Underscore uses ERB-style template delimiters, change the + // following template settings to use alternative delimiters. + _.templateSettings = { + evaluate : /<%([\s\S]+?)%>/g, + interpolate : /<%=([\s\S]+?)%>/g, + escape : /<%-([\s\S]+?)%>/g + }; + + // When customizing `templateSettings`, if you don't want to define an + // interpolation, evaluation or escaping regex, we need one that is + // guaranteed not to match. + var noMatch = /(.)^/; + + // Certain characters need to be escaped so that they can be put into a + // string literal. + var escapes = { + "'": "'", + '\\': '\\', + '\r': 'r', + '\n': 'n', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + var escaper = /\\|'|\r|\n|\u2028|\u2029/g; + + var escapeChar = function(match) { + return '\\' + escapes[match]; + }; + + // JavaScript micro-templating, similar to John Resig's implementation. + // Underscore templating handles arbitrary delimiters, preserves whitespace, + // and correctly escapes quotes within interpolated code. + // NB: `oldSettings` only exists for backwards compatibility. + _.template = function(text, settings, oldSettings) { + if (!settings && oldSettings) settings = oldSettings; + settings = _.defaults({}, settings, _.templateSettings); + + // Combine delimiters into one regular expression via alternation. + var matcher = RegExp([ + (settings.escape || noMatch).source, + (settings.interpolate || noMatch).source, + (settings.evaluate || noMatch).source + ].join('|') + '|$', 'g'); + + // Compile the template source, escaping string literals appropriately. + var index = 0; + var source = "__p+='"; + text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { + source += text.slice(index, offset).replace(escaper, escapeChar); + index = offset + match.length; + + if (escape) { + source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; + } else if (interpolate) { + source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; + } else if (evaluate) { + source += "';\n" + evaluate + "\n__p+='"; + } + + // Adobe VMs need the match returned to produce the correct offest. + return match; + }); + source += "';\n"; + + // If a variable is not specified, place data values in local scope. + if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; + + source = "var __t,__p='',__j=Array.prototype.join," + + "print=function(){__p+=__j.call(arguments,'');};\n" + + source + 'return __p;\n'; + + try { + var render = new Function(settings.variable || 'obj', '_', source); + } catch (e) { + e.source = source; + throw e; + } + + var template = function(data) { + return render.call(this, data, _); + }; + + // Provide the compiled source as a convenience for precompilation. + var argument = settings.variable || 'obj'; + template.source = 'function(' + argument + '){\n' + source + '}'; + + return template; + }; + + // Add a "chain" function. Start chaining a wrapped Underscore object. + _.chain = function(obj) { + var instance = _(obj); + instance._chain = true; + return instance; + }; + + // OOP + // --------------- + // If Underscore is called as a function, it returns a wrapped object that + // can be used OO-style. This wrapper holds altered versions of all the + // underscore functions. Wrapped objects may be chained. + + // Helper function to continue chaining intermediate results. + var result = function(instance, obj) { + return instance._chain ? _(obj).chain() : obj; + }; + + // Add your own custom functions to the Underscore object. + _.mixin = function(obj) { + _.each(_.functions(obj), function(name) { + var func = _[name] = obj[name]; + _.prototype[name] = function() { + var args = [this._wrapped]; + push.apply(args, arguments); + return result(this, func.apply(_, args)); + }; + }); + }; + + // Add all of the Underscore functions to the wrapper object. + _.mixin(_); + + // Add all mutator Array functions to the wrapper. + _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { + var method = ArrayProto[name]; + _.prototype[name] = function() { + var obj = this._wrapped; + method.apply(obj, arguments); + if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0]; + return result(this, obj); + }; + }); + + // Add all accessor Array functions to the wrapper. + _.each(['concat', 'join', 'slice'], function(name) { + var method = ArrayProto[name]; + _.prototype[name] = function() { + return result(this, method.apply(this._wrapped, arguments)); + }; + }); + + // Extracts the result from a wrapped and chained object. + _.prototype.value = function() { + return this._wrapped; + }; + + // Provide unwrapping proxy for some methods used in engine operations + // such as arithmetic and JSON stringification. + _.prototype.valueOf = _.prototype.toJSON = _.prototype.value; + + _.prototype.toString = function() { + return '' + this._wrapped; + }; + + // AMD registration happens at the end for compatibility with AMD loaders + // that may not enforce next-turn semantics on modules. Even though general + // practice for AMD registration is to be anonymous, underscore registers + // as a named module because, like jQuery, it is a base library that is + // popular enough to be bundled in a third party lib, but not be part of + // an AMD load request. Those cases could generate an error when an + // anonymous define() is called outside of a loader request. + if (typeof define === 'function' && define.amd) { + define('underscore', [], function() { + return _; + }); + } +}.call(this)); + +},{}],26:[function(require,module,exports){ +arguments[4][19][0].apply(exports,arguments) +},{"dup":19}],27:[function(require,module,exports){ +module.exports = function isBuffer(arg) { + return arg && typeof arg === 'object' + && typeof arg.copy === 'function' + && typeof arg.fill === 'function' + && typeof arg.readUInt8 === 'function'; +} +},{}],28:[function(require,module,exports){ +(function (process,global){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var formatRegExp = /%[sdj%]/g; +exports.format = function(f) { + if (!isString(f)) { + var objects = []; + for (var i = 0; i < arguments.length; i++) { + objects.push(inspect(arguments[i])); + } + return objects.join(' '); + } + + var i = 1; + var args = arguments; + var len = args.length; + var str = String(f).replace(formatRegExp, function(x) { + if (x === '%%') return '%'; + if (i >= len) return x; + switch (x) { + case '%s': return String(args[i++]); + case '%d': return Number(args[i++]); + case '%j': + try { + return JSON.stringify(args[i++]); + } catch (_) { + return '[Circular]'; + } + default: + return x; + } + }); + for (var x = args[i]; i < len; x = args[++i]) { + if (isNull(x) || !isObject(x)) { + str += ' ' + x; + } else { + str += ' ' + inspect(x); + } + } + return str; +}; + + +// Mark that a method should not be used. +// Returns a modified function which warns once by default. +// If --no-deprecation is set, then it is a no-op. +exports.deprecate = function(fn, msg) { + // Allow for deprecating things in the process of starting up. + if (isUndefined(global.process)) { + return function() { + return exports.deprecate(fn, msg).apply(this, arguments); + }; + } + + if (process.noDeprecation === true) { + return fn; + } + + var warned = false; + function deprecated() { + if (!warned) { + if (process.throwDeprecation) { + throw new Error(msg); + } else if (process.traceDeprecation) { + console.trace(msg); + } else { + console.error(msg); + } + warned = true; + } + return fn.apply(this, arguments); + } + + return deprecated; +}; + + +var debugs = {}; +var debugEnviron; +exports.debuglog = function(set) { + if (isUndefined(debugEnviron)) + debugEnviron = process.env.NODE_DEBUG || ''; + set = set.toUpperCase(); + if (!debugs[set]) { + if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { + var pid = process.pid; + debugs[set] = function() { + var msg = exports.format.apply(exports, arguments); + console.error('%s %d: %s', set, pid, msg); + }; + } else { + debugs[set] = function() {}; + } + } + return debugs[set]; +}; + + +/** + * Echos the value of a value. Trys to print the value out + * in the best way possible given the different types. + * + * @param {Object} obj The object to print out. + * @param {Object} opts Optional options object that alters the output. + */ +/* legacy: obj, showHidden, depth, colors*/ +function inspect(obj, opts) { + // default options + var ctx = { + seen: [], + stylize: stylizeNoColor + }; + // legacy... + if (arguments.length >= 3) ctx.depth = arguments[2]; + if (arguments.length >= 4) ctx.colors = arguments[3]; + if (isBoolean(opts)) { + // legacy... + ctx.showHidden = opts; + } else if (opts) { + // got an "options" object + exports._extend(ctx, opts); + } + // set default options + if (isUndefined(ctx.showHidden)) ctx.showHidden = false; + if (isUndefined(ctx.depth)) ctx.depth = 2; + if (isUndefined(ctx.colors)) ctx.colors = false; + if (isUndefined(ctx.customInspect)) ctx.customInspect = true; + if (ctx.colors) ctx.stylize = stylizeWithColor; + return formatValue(ctx, obj, ctx.depth); +} +exports.inspect = inspect; + + +// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics +inspect.colors = { + 'bold' : [1, 22], + 'italic' : [3, 23], + 'underline' : [4, 24], + 'inverse' : [7, 27], + 'white' : [37, 39], + 'grey' : [90, 39], + 'black' : [30, 39], + 'blue' : [34, 39], + 'cyan' : [36, 39], + 'green' : [32, 39], + 'magenta' : [35, 39], + 'red' : [31, 39], + 'yellow' : [33, 39] +}; + +// Don't use 'blue' not visible on cmd.exe +inspect.styles = { + 'special': 'cyan', + 'number': 'yellow', + 'boolean': 'yellow', + 'undefined': 'grey', + 'null': 'bold', + 'string': 'green', + 'date': 'magenta', + // "name": intentionally not styling + 'regexp': 'red' +}; + + +function stylizeWithColor(str, styleType) { + var style = inspect.styles[styleType]; + + if (style) { + return '\u001b[' + inspect.colors[style][0] + 'm' + str + + '\u001b[' + inspect.colors[style][1] + 'm'; + } else { + return str; + } +} + + +function stylizeNoColor(str, styleType) { + return str; +} + + +function arrayToHash(array) { + var hash = {}; + + array.forEach(function(val, idx) { + hash[val] = true; + }); + + return hash; +} + + +function formatValue(ctx, value, recurseTimes) { + // Provide a hook for user-specified inspect functions. + // Check that value is an object with an inspect function on it + if (ctx.customInspect && + value && + isFunction(value.inspect) && + // Filter out the util module, it's inspect function is special + value.inspect !== exports.inspect && + // Also filter out any prototype objects using the circular check. + !(value.constructor && value.constructor.prototype === value)) { + var ret = value.inspect(recurseTimes, ctx); + if (!isString(ret)) { + ret = formatValue(ctx, ret, recurseTimes); + } + return ret; + } + + // Primitive types cannot have properties + var primitive = formatPrimitive(ctx, value); + if (primitive) { + return primitive; + } + + // Look up the keys of the object. + var keys = Object.keys(value); + var visibleKeys = arrayToHash(keys); + + if (ctx.showHidden) { + keys = Object.getOwnPropertyNames(value); + } + + // IE doesn't make error fields non-enumerable + // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx + if (isError(value) + && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { + return formatError(value); + } + + // Some type of object without properties can be shortcutted. + if (keys.length === 0) { + if (isFunction(value)) { + var name = value.name ? ': ' + value.name : ''; + return ctx.stylize('[Function' + name + ']', 'special'); + } + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } + if (isDate(value)) { + return ctx.stylize(Date.prototype.toString.call(value), 'date'); + } + if (isError(value)) { + return formatError(value); + } + } + + var base = '', array = false, braces = ['{', '}']; + + // Make Array say that they are Array + if (isArray(value)) { + array = true; + braces = ['[', ']']; + } + + // Make functions say that they are functions + if (isFunction(value)) { + var n = value.name ? ': ' + value.name : ''; + base = ' [Function' + n + ']'; + } + + // Make RegExps say that they are RegExps + if (isRegExp(value)) { + base = ' ' + RegExp.prototype.toString.call(value); + } + + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + Date.prototype.toUTCString.call(value); + } + + // Make error with message first say the error + if (isError(value)) { + base = ' ' + formatError(value); + } + + if (keys.length === 0 && (!array || value.length == 0)) { + return braces[0] + base + braces[1]; + } + + if (recurseTimes < 0) { + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } else { + return ctx.stylize('[Object]', 'special'); + } + } + + ctx.seen.push(value); + + var output; + if (array) { + output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); + } else { + output = keys.map(function(key) { + return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); + }); + } + + ctx.seen.pop(); + + return reduceToSingleString(output, base, braces); +} + + +function formatPrimitive(ctx, value) { + if (isUndefined(value)) + return ctx.stylize('undefined', 'undefined'); + if (isString(value)) { + var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + '\''; + return ctx.stylize(simple, 'string'); + } + if (isNumber(value)) + return ctx.stylize('' + value, 'number'); + if (isBoolean(value)) + return ctx.stylize('' + value, 'boolean'); + // For some reason typeof null is "object", so special case here. + if (isNull(value)) + return ctx.stylize('null', 'null'); +} + + +function formatError(value) { + return '[' + Error.prototype.toString.call(value) + ']'; +} + + +function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { + var output = []; + for (var i = 0, l = value.length; i < l; ++i) { + if (hasOwnProperty(value, String(i))) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + String(i), true)); + } else { + output.push(''); + } + } + keys.forEach(function(key) { + if (!key.match(/^\d+$/)) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + key, true)); + } + }); + return output; +} + + +function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { + var name, str, desc; + desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; + if (desc.get) { + if (desc.set) { + str = ctx.stylize('[Getter/Setter]', 'special'); + } else { + str = ctx.stylize('[Getter]', 'special'); + } + } else { + if (desc.set) { + str = ctx.stylize('[Setter]', 'special'); + } + } + if (!hasOwnProperty(visibleKeys, key)) { + name = '[' + key + ']'; + } + if (!str) { + if (ctx.seen.indexOf(desc.value) < 0) { + if (isNull(recurseTimes)) { + str = formatValue(ctx, desc.value, null); + } else { + str = formatValue(ctx, desc.value, recurseTimes - 1); + } + if (str.indexOf('\n') > -1) { + if (array) { + str = str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n').substr(2); + } else { + str = '\n' + str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n'); + } + } + } else { + str = ctx.stylize('[Circular]', 'special'); + } + } + if (isUndefined(name)) { + if (array && key.match(/^\d+$/)) { + return str; + } + name = JSON.stringify('' + key); + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { + name = name.substr(1, name.length - 2); + name = ctx.stylize(name, 'name'); + } else { + name = name.replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); + name = ctx.stylize(name, 'string'); + } + } + + return name + ': ' + str; +} + + +function reduceToSingleString(output, base, braces) { + var numLinesEst = 0; + var length = output.reduce(function(prev, cur) { + numLinesEst++; + if (cur.indexOf('\n') >= 0) numLinesEst++; + return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; + }, 0); + + if (length > 60) { + return braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; + } + + return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; +} + + +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. +function isArray(ar) { + return Array.isArray(ar); +} +exports.isArray = isArray; + +function isBoolean(arg) { + return typeof arg === 'boolean'; +} +exports.isBoolean = isBoolean; + +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; + +function isNullOrUndefined(arg) { + return arg == null; +} +exports.isNullOrUndefined = isNullOrUndefined; + +function isNumber(arg) { + return typeof arg === 'number'; +} +exports.isNumber = isNumber; + +function isString(arg) { + return typeof arg === 'string'; +} +exports.isString = isString; + +function isSymbol(arg) { + return typeof arg === 'symbol'; +} +exports.isSymbol = isSymbol; + +function isUndefined(arg) { + return arg === void 0; +} +exports.isUndefined = isUndefined; + +function isRegExp(re) { + return isObject(re) && objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} +exports.isObject = isObject; + +function isDate(d) { + return isObject(d) && objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; + +function isError(e) { + return isObject(e) && + (objectToString(e) === '[object Error]' || e instanceof Error); +} +exports.isError = isError; + +function isFunction(arg) { + return typeof arg === 'function'; +} +exports.isFunction = isFunction; + +function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; +} +exports.isPrimitive = isPrimitive; + +exports.isBuffer = require('./support/isBuffer'); + +function objectToString(o) { + return Object.prototype.toString.call(o); +} + + +function pad(n) { + return n < 10 ? '0' + n.toString(10) : n.toString(10); +} + + +var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', + 'Oct', 'Nov', 'Dec']; + +// 26 Feb 16:19:34 +function timestamp() { + var d = new Date(); + var time = [pad(d.getHours()), + pad(d.getMinutes()), + pad(d.getSeconds())].join(':'); + return [d.getDate(), months[d.getMonth()], time].join(' '); +} + + +// log is just a thin wrapper to console.log that prepends a timestamp +exports.log = function() { + console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); +}; + + +/** + * Inherit the prototype methods from one constructor into another. + * + * The Function.prototype.inherits from lang.js rewritten as a standalone + * function (not on Function.prototype). NOTE: If this file is to be loaded + * during bootstrapping this function needs to be rewritten using some native + * functions as prototype setup using normal JavaScript does not work as + * expected during bootstrapping (see mirror.js in r114903). + * + * @param {function} ctor Constructor function which needs to inherit the + * prototype. + * @param {function} superCtor Constructor function to inherit prototype from. + */ +exports.inherits = require('inherits'); + +exports._extend = function(origin, add) { + // Don't do anything if add isn't an object + if (!add || !isObject(add)) return origin; + + var keys = Object.keys(add); + var i = keys.length; + while (i--) { + origin[keys[i]] = add[keys[i]]; + } + return origin; +}; + +function hasOwnProperty(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); +} + +}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"./support/isBuffer":27,"_process":24,"inherits":26}],29:[function(require,module,exports){ +// Returns a wrapper function that returns a wrapped callback +// The wrapper function should do some stuff, and return a +// presumably different callback function. +// This makes sure that own properties are retained, so that +// decorations and such are not lost along the way. +module.exports = wrappy +function wrappy (fn, cb) { + if (fn && cb) return wrappy(fn)(cb) + + if (typeof fn !== 'function') + throw new TypeError('need wrapper function') + + Object.keys(fn).forEach(function (k) { + wrapper[k] = fn[k] + }) + + return wrapper + + function wrapper() { + var args = new Array(arguments.length) + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i] + } + var ret = fn.apply(this, args) + var cb = args[args.length-1] + if (typeof ret === 'function' && ret !== cb) { + Object.keys(cb).forEach(function (k) { + ret[k] = cb[k] + }) + } + return ret + } +} + +},{}]},{},[7])(7) +}); \ No newline at end of file diff --git a/assets/javascripts/workers/search.1e90e0fb.min.js b/assets/javascripts/workers/search.1e90e0fb.min.js new file mode 100644 index 00000000..ff43aedd --- /dev/null +++ b/assets/javascripts/workers/search.1e90e0fb.min.js @@ -0,0 +1,2 @@ +"use strict";(()=>{var xe=Object.create;var G=Object.defineProperty,ve=Object.defineProperties,Se=Object.getOwnPropertyDescriptor,Te=Object.getOwnPropertyDescriptors,Qe=Object.getOwnPropertyNames,Y=Object.getOwnPropertySymbols,Ee=Object.getPrototypeOf,X=Object.prototype.hasOwnProperty,be=Object.prototype.propertyIsEnumerable;var Z=Math.pow,J=(t,e,r)=>e in t?G(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,_=(t,e)=>{for(var r in e||(e={}))X.call(e,r)&&J(t,r,e[r]);if(Y)for(var r of Y(e))be.call(e,r)&&J(t,r,e[r]);return t},B=(t,e)=>ve(t,Te(e));var Le=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var we=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Qe(e))!X.call(t,i)&&i!==r&&G(t,i,{get:()=>e[i],enumerable:!(n=Se(e,i))||n.enumerable});return t};var Pe=(t,e,r)=>(r=t!=null?xe(Ee(t)):{},we(e||!t||!t.__esModule?G(r,"default",{value:t,enumerable:!0}):r,t));var W=(t,e,r)=>new Promise((n,i)=>{var s=u=>{try{a(r.next(u))}catch(c){i(c)}},o=u=>{try{a(r.throw(u))}catch(c){i(c)}},a=u=>u.done?n(u.value):Promise.resolve(u.value).then(s,o);a((r=r.apply(t,e)).next())});var te=Le((K,ee)=>{(function(){var t=function(e){var r=new t.Builder;return r.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),r.searchPipeline.add(t.stemmer),e.call(r,r),r.build()};t.version="2.3.9";t.utils={},t.utils.warn=function(e){return function(r){e.console&&console.warn&&console.warn(r)}}(this),t.utils.asString=function(e){return e==null?"":e.toString()},t.utils.clone=function(e){if(e==null)return e;for(var r=Object.create(null),n=Object.keys(e),i=0;i0){var f=t.utils.clone(r)||{};f.position=[a,c],f.index=s.length,s.push(new t.Token(n.slice(a,o),f))}a=o+1}}return s},t.tokenizer.separator=/[\s\-]+/;t.Pipeline=function(){this._stack=[]},t.Pipeline.registeredFunctions=Object.create(null),t.Pipeline.registerFunction=function(e,r){r in this.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+r),e.label=r,t.Pipeline.registeredFunctions[e.label]=e},t.Pipeline.warnIfFunctionNotRegistered=function(e){var r=e.label&&e.label in this.registeredFunctions;r||t.utils.warn(`Function is not registered with pipeline. This may cause problems when serialising the index. +`,e)},t.Pipeline.load=function(e){var r=new t.Pipeline;return e.forEach(function(n){var i=t.Pipeline.registeredFunctions[n];if(i)r.add(i);else throw new Error("Cannot load unregistered function: "+n)}),r},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(r){t.Pipeline.warnIfFunctionNotRegistered(r),this._stack.push(r)},this)},t.Pipeline.prototype.after=function(e,r){t.Pipeline.warnIfFunctionNotRegistered(r);var n=this._stack.indexOf(e);if(n==-1)throw new Error("Cannot find existingFn");n=n+1,this._stack.splice(n,0,r)},t.Pipeline.prototype.before=function(e,r){t.Pipeline.warnIfFunctionNotRegistered(r);var n=this._stack.indexOf(e);if(n==-1)throw new Error("Cannot find existingFn");this._stack.splice(n,0,r)},t.Pipeline.prototype.remove=function(e){var r=this._stack.indexOf(e);r!=-1&&this._stack.splice(r,1)},t.Pipeline.prototype.run=function(e){for(var r=this._stack.length,n=0;n1&&(oe&&(n=s),o!=e);)i=n-r,s=r+Math.floor(i/2),o=this.elements[s*2];if(o==e||o>e)return s*2;if(ou?f+=2:a==u&&(r+=n[c+1]*i[f+1],c+=2,f+=2);return r},t.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},t.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),r=1,n=0;r0){var o=s.str.charAt(0),a;o in s.node.edges?a=s.node.edges[o]:(a=new t.TokenSet,s.node.edges[o]=a),s.str.length==1&&(a.final=!0),i.push({node:a,editsRemaining:s.editsRemaining,str:s.str.slice(1)})}if(s.editsRemaining!=0){if("*"in s.node.edges)var u=s.node.edges["*"];else{var u=new t.TokenSet;s.node.edges["*"]=u}if(s.str.length==0&&(u.final=!0),i.push({node:u,editsRemaining:s.editsRemaining-1,str:s.str}),s.str.length>1&&i.push({node:s.node,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)}),s.str.length==1&&(s.node.final=!0),s.str.length>=1){if("*"in s.node.edges)var c=s.node.edges["*"];else{var c=new t.TokenSet;s.node.edges["*"]=c}s.str.length==1&&(c.final=!0),i.push({node:c,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)})}if(s.str.length>1){var f=s.str.charAt(0),g=s.str.charAt(1),l;g in s.node.edges?l=s.node.edges[g]:(l=new t.TokenSet,s.node.edges[g]=l),s.str.length==1&&(l.final=!0),i.push({node:l,editsRemaining:s.editsRemaining-1,str:f+s.str.slice(2)})}}}return n},t.TokenSet.fromString=function(e){for(var r=new t.TokenSet,n=r,i=0,s=e.length;i=e;r--){var n=this.uncheckedNodes[r],i=n.child.toString();i in this.minimizedNodes?n.parent.edges[n.char]=this.minimizedNodes[i]:(n.child._str=i,this.minimizedNodes[i]=n.child),this.uncheckedNodes.pop()}};t.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},t.Index.prototype.search=function(e){return this.query(function(r){var n=new t.QueryParser(e,r);n.parse()})},t.Index.prototype.query=function(e){for(var r=new t.Query(this.fields),n=Object.create(null),i=Object.create(null),s=Object.create(null),o=Object.create(null),a=Object.create(null),u=0;u1?this._b=1:this._b=e},t.Builder.prototype.k1=function(e){this._k1=e},t.Builder.prototype.add=function(e,r){var n=e[this._ref],i=Object.keys(this._fields);this._documents[n]=r||{},this.documentCount+=1;for(var s=0;s=this.length)return t.QueryLexer.EOS;var e=this.str.charAt(this.pos);return this.pos+=1,e},t.QueryLexer.prototype.width=function(){return this.pos-this.start},t.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},t.QueryLexer.prototype.backup=function(){this.pos-=1},t.QueryLexer.prototype.acceptDigitRun=function(){var e,r;do e=this.next(),r=e.charCodeAt(0);while(r>47&&r<58);e!=t.QueryLexer.EOS&&this.backup()},t.QueryLexer.prototype.more=function(){return this.pos1&&(e.backup(),e.emit(t.QueryLexer.TERM)),e.ignore(),e.more())return t.QueryLexer.lexText},t.QueryLexer.lexEditDistance=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(t.QueryLexer.EDIT_DISTANCE),t.QueryLexer.lexText},t.QueryLexer.lexBoost=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(t.QueryLexer.BOOST),t.QueryLexer.lexText},t.QueryLexer.lexEOS=function(e){e.width()>0&&e.emit(t.QueryLexer.TERM)},t.QueryLexer.termSeparator=t.tokenizer.separator,t.QueryLexer.lexText=function(e){for(;;){var r=e.next();if(r==t.QueryLexer.EOS)return t.QueryLexer.lexEOS;if(r.charCodeAt(0)==92){e.escapeCharacter();continue}if(r==":")return t.QueryLexer.lexField;if(r=="~")return e.backup(),e.width()>0&&e.emit(t.QueryLexer.TERM),t.QueryLexer.lexEditDistance;if(r=="^")return e.backup(),e.width()>0&&e.emit(t.QueryLexer.TERM),t.QueryLexer.lexBoost;if(r=="+"&&e.width()===1||r=="-"&&e.width()===1)return e.emit(t.QueryLexer.PRESENCE),t.QueryLexer.lexText;if(r.match(t.QueryLexer.termSeparator))return t.QueryLexer.lexTerm}},t.QueryParser=function(e,r){this.lexer=new t.QueryLexer(e),this.query=r,this.currentClause={},this.lexemeIdx=0},t.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var e=t.QueryParser.parseClause;e;)e=e(this);return this.query},t.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},t.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},t.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},t.QueryParser.parseClause=function(e){var r=e.peekLexeme();if(r!=null)switch(r.type){case t.QueryLexer.PRESENCE:return t.QueryParser.parsePresence;case t.QueryLexer.FIELD:return t.QueryParser.parseField;case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var n="expected either a field or a term, found "+r.type;throw r.str.length>=1&&(n+=" with value '"+r.str+"'"),new t.QueryParseError(n,r.start,r.end)}},t.QueryParser.parsePresence=function(e){var r=e.consumeLexeme();if(r!=null){switch(r.str){case"-":e.currentClause.presence=t.Query.presence.PROHIBITED;break;case"+":e.currentClause.presence=t.Query.presence.REQUIRED;break;default:var n="unrecognised presence operator'"+r.str+"'";throw new t.QueryParseError(n,r.start,r.end)}var i=e.peekLexeme();if(i==null){var n="expecting term or field, found nothing";throw new t.QueryParseError(n,r.start,r.end)}switch(i.type){case t.QueryLexer.FIELD:return t.QueryParser.parseField;case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var n="expecting term or field, found '"+i.type+"'";throw new t.QueryParseError(n,i.start,i.end)}}},t.QueryParser.parseField=function(e){var r=e.consumeLexeme();if(r!=null){if(e.query.allFields.indexOf(r.str)==-1){var n=e.query.allFields.map(function(o){return"'"+o+"'"}).join(", "),i="unrecognised field '"+r.str+"', possible fields: "+n;throw new t.QueryParseError(i,r.start,r.end)}e.currentClause.fields=[r.str];var s=e.peekLexeme();if(s==null){var i="expecting term, found nothing";throw new t.QueryParseError(i,r.start,r.end)}switch(s.type){case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var i="expecting term, found '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},t.QueryParser.parseTerm=function(e){var r=e.consumeLexeme();if(r!=null){e.currentClause.term=r.str.toLowerCase(),r.str.indexOf("*")!=-1&&(e.currentClause.usePipeline=!1);var n=e.peekLexeme();if(n==null){e.nextClause();return}switch(n.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+n.type+"'";throw new t.QueryParseError(i,n.start,n.end)}}},t.QueryParser.parseEditDistance=function(e){var r=e.consumeLexeme();if(r!=null){var n=parseInt(r.str,10);if(isNaN(n)){var i="edit distance must be numeric";throw new t.QueryParseError(i,r.start,r.end)}e.currentClause.editDistance=n;var s=e.peekLexeme();if(s==null){e.nextClause();return}switch(s.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},t.QueryParser.parseBoost=function(e){var r=e.consumeLexeme();if(r!=null){var n=parseInt(r.str,10);if(isNaN(n)){var i="boost must be numeric";throw new t.QueryParseError(i,r.start,r.end)}e.currentClause.boost=n;var s=e.peekLexeme();if(s==null){e.nextClause();return}switch(s.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},function(e,r){typeof define=="function"&&define.amd?define(r):typeof K=="object"?ee.exports=r():e.lunr=r()}(this,function(){return t})})()});var de=Pe(te());function re(t,e=document){let r=ke(t,e);if(typeof r=="undefined")throw new ReferenceError(`Missing element: expected "${t}" to be present`);return r}function ke(t,e=document){return e.querySelector(t)||void 0}Object.entries||(Object.entries=function(t){let e=[];for(let r of Object.keys(t))e.push([r,t[r]]);return e});Object.values||(Object.values=function(t){let e=[];for(let r of Object.keys(t))e.push(t[r]);return e});typeof Element!="undefined"&&(Element.prototype.scrollTo||(Element.prototype.scrollTo=function(t,e){typeof t=="object"?(this.scrollLeft=t.left,this.scrollTop=t.top):(this.scrollLeft=t,this.scrollTop=e)}),Element.prototype.replaceWith||(Element.prototype.replaceWith=function(...t){let e=this.parentNode;if(e){t.length===0&&e.removeChild(this);for(let r=t.length-1;r>=0;r--){let n=t[r];typeof n=="string"?n=document.createTextNode(n):n.parentNode&&n.parentNode.removeChild(n),r?e.insertBefore(this.previousSibling,n):e.replaceChild(n,this)}}}));function ne(t){let e=new Map;for(let r of t){let[n]=r.location.split("#"),i=e.get(n);typeof i=="undefined"?e.set(n,r):(e.set(r.location,r),r.parent=i)}return e}function H(t,e,r){var s;e=new RegExp(e,"g");let n,i=0;do{n=e.exec(t);let o=(s=n==null?void 0:n.index)!=null?s:t.length;if(in?e(r,1,n,n=i):t.charAt(i)===">"&&(t.charAt(n+1)==="/"?--s===0&&e(r++,2,n,i+1):t.charAt(i-1)!=="/"&&s++===0&&e(r,0,n,i+1),n=i+1);i>n&&e(r,1,n,i)}function se(t,e,r,n=!1){return q([t],e,r,n).pop()}function q(t,e,r,n=!1){let i=[0];for(let s=1;s>>2&1023,c=a[0]>>>12;i.push(+(u>c)+i[i.length-1])}return t.map((s,o)=>{let a=0,u=new Map;for(let f of r.sort((g,l)=>g-l)){let g=f&1048575,l=f>>>20;if(i[l]!==o)continue;let m=u.get(l);typeof m=="undefined"&&u.set(l,m=[]),m.push(g)}if(u.size===0)return s;let c=[];for(let[f,g]of u){let l=e[f],m=l[0]>>>12,x=l[l.length-1]>>>12,v=l[l.length-1]>>>2&1023;n&&m>a&&c.push(s.slice(a,m));let d=s.slice(m,x+v);for(let y of g.sort((b,E)=>E-b)){let b=(l[y]>>>12)-m,E=(l[y]>>>2&1023)+b;d=[d.slice(0,b),"",d.slice(b,E),"",d.slice(E)].join("")}if(a=x+v,c.push(d)===2)break}return n&&a{var f;switch(i[f=o+=s]||(i[f]=[]),a){case 0:case 2:i[o].push(u<<12|c-u<<2|a);break;case 1:let g=r[n].slice(u,c);H(g,lunr.tokenizer.separator,(l,m)=>{if(typeof lunr.segmenter!="undefined"){let x=g.slice(l,m);if(/^[MHIK]$/.test(lunr.segmenter.ctype_(x))){let v=lunr.segmenter.segment(x);for(let d=0,y=0;dr){return t.trim().split(/"([^"]+)"/g).map((r,n)=>n&1?r.replace(/^\b|^(?![^\x00-\x7F]|$)|\s+/g," +"):r).join("").replace(/"|(?:^|\s+)[*+\-:^~]+(?=\s+|$)/g,"").split(/\s+/g).reduce((r,n)=>{let i=e(n);return[...r,...Array.isArray(i)?i:[i]]},[]).map(r=>/([~^]$)/.test(r)?`${r}1`:r).map(r=>/(^[+-]|[~^]\d+$)/.test(r)?r:`${r}*`).join(" ")}function ue(t){return ae(t,e=>{let r=[],n=new lunr.QueryLexer(e);n.run();for(let{type:i,str:s,start:o,end:a}of n.lexemes)switch(i){case"FIELD":["title","text","tags"].includes(s)||(e=[e.slice(0,a)," ",e.slice(a+1)].join(""));break;case"TERM":H(s,lunr.tokenizer.separator,(...u)=>{r.push([e.slice(0,o),s.slice(...u),e.slice(a)].join(""))})}return r})}function ce(t){let e=new lunr.Query(["title","text","tags"]);new lunr.QueryParser(t,e).parse();for(let n of e.clauses)n.usePipeline=!0,n.term.startsWith("*")&&(n.wildcard=lunr.Query.wildcard.LEADING,n.term=n.term.slice(1)),n.term.endsWith("*")&&(n.wildcard=lunr.Query.wildcard.TRAILING,n.term=n.term.slice(0,-1));return e.clauses}function le(t,e){var i;let r=new Set(t),n={};for(let s=0;s0;){let o=i[--s];for(let u=1;un[o]-u&&(r.add(t.slice(o,o+u)),i[s++]=o+u);let a=o+n[o];n[a]&&ar=>{if(typeof r[e]=="undefined")return;let n=[r.location,e].join(":");return t.set(n,lunr.tokenizer.table=[]),r[e]}}function Re(t,e){let[r,n]=[new Set(t),new Set(e)];return[...new Set([...r].filter(i=>!n.has(i)))]}var U=class{constructor({config:e,docs:r,options:n}){let i=Oe(this.table=new Map);this.map=ne(r),this.options=n,this.index=lunr(function(){this.metadataWhitelist=["position"],this.b(0),e.lang.length===1&&e.lang[0]!=="en"?this.use(lunr[e.lang[0]]):e.lang.length>1&&this.use(lunr.multiLanguage(...e.lang)),this.tokenizer=oe,lunr.tokenizer.separator=new RegExp(e.separator),lunr.segmenter="TinySegmenter"in lunr?new lunr.TinySegmenter:void 0;let s=Re(["trimmer","stopWordFilter","stemmer"],e.pipeline);for(let o of e.lang.map(a=>a==="en"?lunr:lunr[a]))for(let a of s)this.pipeline.remove(o[a]),this.searchPipeline.remove(o[a]);this.ref("location");for(let[o,a]of Object.entries(e.fields))this.field(o,B(_({},a),{extractor:i(o)}));for(let o of r)this.add(o,{boost:o.boost})})}search(e){if(e=e.replace(new RegExp("\\p{sc=Han}+","gu"),s=>[...he(s,this.index.invertedIndex)].join("* ")),e=ue(e),!e)return{items:[]};let r=ce(e).filter(s=>s.presence!==lunr.Query.presence.PROHIBITED),n=this.index.search(e).reduce((s,{ref:o,score:a,matchData:u})=>{let c=this.map.get(o);if(typeof c!="undefined"){c=_({},c),c.tags&&(c.tags=[...c.tags]);let f=le(r,Object.keys(u.metadata));for(let l of this.index.fields){if(typeof c[l]=="undefined")continue;let m=[];for(let d of Object.values(u.metadata))typeof d[l]!="undefined"&&m.push(...d[l].position);if(!m.length)continue;let x=this.table.get([c.location,l].join(":")),v=Array.isArray(c[l])?q:se;c[l]=v(c[l],x,m,l!=="text")}let g=+!c.parent+Object.values(f).filter(l=>l).length/Object.keys(f).length;s.push(B(_({},c),{score:a*(1+Z(g,2)),terms:f}))}return s},[]).sort((s,o)=>o.score-s.score).reduce((s,o)=>{let a=this.map.get(o.location);if(typeof a!="undefined"){let u=a.parent?a.parent.location:a.location;s.set(u,[...s.get(u)||[],o])}return s},new Map);for(let[s,o]of n)if(!o.find(a=>a.location===s)){let a=this.map.get(s);o.push(B(_({},a),{score:0,terms:{}}))}let i;if(this.options.suggest){let s=this.index.query(o=>{for(let a of r)o.term(a.term,{fields:["title"],presence:lunr.Query.presence.REQUIRED,wildcard:lunr.Query.wildcard.TRAILING})});i=s.length?Object.keys(s[0].matchData.metadata):[]}return _({items:[...n.values()]},typeof i!="undefined"&&{suggest:i})}};var fe;function Ie(t){return W(this,null,function*(){let e="../lunr";if(typeof parent!="undefined"&&"IFrameWorker"in parent){let n=re("script[src]"),[i]=n.src.split("/worker");e=e.replace("..",i)}let r=[];for(let n of t.lang){switch(n){case"ja":r.push(`${e}/tinyseg.js`);break;case"hi":case"th":r.push(`${e}/wordcut.js`);break}n!=="en"&&r.push(`${e}/min/lunr.${n}.min.js`)}t.lang.length>1&&r.push(`${e}/min/lunr.multi.min.js`),r.length&&(yield importScripts(`${e}/min/lunr.stemmer.support.min.js`,...r))})}function Fe(t){return W(this,null,function*(){switch(t.type){case 0:return yield Ie(t.data.config),fe=new U(t.data),{type:1};case 2:let e=t.data;try{return{type:3,data:fe.search(e)}}catch(r){return console.warn(`Invalid query: ${e} \u2013 see https://bit.ly/2s3ChXG`),console.warn(r),{type:3,data:{items:[]}}}default:throw new TypeError("Invalid message type")}})}self.lunr=de.default;addEventListener("message",t=>W(void 0,null,function*(){postMessage(yield Fe(t.data))}));})(); diff --git a/assets/project-icon.png b/assets/project-icon.png new file mode 100644 index 00000000..297cba2b Binary files /dev/null and b/assets/project-icon.png differ diff --git a/assets/project-logo.png b/assets/project-logo.png new file mode 100644 index 00000000..56bb7ed3 Binary files /dev/null and b/assets/project-logo.png differ diff --git a/assets/projects/credo/credo-high-level-arch.png b/assets/projects/credo/credo-high-level-arch.png new file mode 100644 index 00000000..3c222132 Binary files /dev/null and b/assets/projects/credo/credo-high-level-arch.png differ diff --git a/assets/projects/fwos/Emergency_Relief_Event.png b/assets/projects/fwos/Emergency_Relief_Event.png new file mode 100644 index 00000000..0a2f74a5 Binary files /dev/null and b/assets/projects/fwos/Emergency_Relief_Event.png differ diff --git a/assets/projects/fwos/Farmworker_WalletOS_OSS_Project.png b/assets/projects/fwos/Farmworker_WalletOS_OSS_Project.png new file mode 100644 index 00000000..af6db33c Binary files /dev/null and b/assets/projects/fwos/Farmworker_WalletOS_OSS_Project.png differ diff --git a/assets/stylesheets/main.c0d16a3a.min.css b/assets/stylesheets/main.c0d16a3a.min.css new file mode 100644 index 00000000..344d70aa --- /dev/null +++ b/assets/stylesheets/main.c0d16a3a.min.css @@ -0,0 +1 @@ +@charset "UTF-8";html{-webkit-text-size-adjust:none;-moz-text-size-adjust:none;text-size-adjust:none;box-sizing:border-box}*,:after,:before{box-sizing:inherit}@media (prefers-reduced-motion){*,:after,:before{transition:none!important}}body{margin:0}a,button,input,label{-webkit-tap-highlight-color:transparent}a{color:inherit;text-decoration:none}hr{border:0;box-sizing:initial;display:block;height:.05rem;overflow:visible;padding:0}small{font-size:80%}sub,sup{line-height:1em}img{border-style:none}table{border-collapse:initial;border-spacing:0}td,th{font-weight:400;vertical-align:top}button{background:#0000;border:0;font-family:inherit;font-size:inherit;margin:0;padding:0}input{border:0;outline:none}:root{--md-primary-fg-color:#4051b5;--md-primary-fg-color--light:#5d6cc0;--md-primary-fg-color--dark:#303fa1;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3;--md-accent-fg-color:#526cfe;--md-accent-fg-color--transparent:#526cfe1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-scheme=default]{color-scheme:light}[data-md-color-scheme=default] img[src$="#gh-dark-mode-only"],[data-md-color-scheme=default] img[src$="#only-dark"]{display:none}:root,[data-md-color-scheme=default]{--md-hue:225deg;--md-default-fg-color:#000000de;--md-default-fg-color--light:#0000008a;--md-default-fg-color--lighter:#00000052;--md-default-fg-color--lightest:#00000012;--md-default-bg-color:#fff;--md-default-bg-color--light:#ffffffb3;--md-default-bg-color--lighter:#ffffff4d;--md-default-bg-color--lightest:#ffffff1f;--md-code-fg-color:#36464e;--md-code-bg-color:#f5f5f5;--md-code-bg-color--light:#f5f5f5b3;--md-code-bg-color--lighter:#f5f5f54d;--md-code-hl-color:#4287ff;--md-code-hl-color--light:#4287ff1a;--md-code-hl-number-color:#d52a2a;--md-code-hl-special-color:#db1457;--md-code-hl-function-color:#a846b9;--md-code-hl-constant-color:#6e59d9;--md-code-hl-keyword-color:#3f6ec6;--md-code-hl-string-color:#1c7d4d;--md-code-hl-name-color:var(--md-code-fg-color);--md-code-hl-operator-color:var(--md-default-fg-color--light);--md-code-hl-punctuation-color:var(--md-default-fg-color--light);--md-code-hl-comment-color:var(--md-default-fg-color--light);--md-code-hl-generic-color:var(--md-default-fg-color--light);--md-code-hl-variable-color:var(--md-default-fg-color--light);--md-typeset-color:var(--md-default-fg-color);--md-typeset-a-color:var(--md-primary-fg-color);--md-typeset-del-color:#f5503d26;--md-typeset-ins-color:#0bd57026;--md-typeset-kbd-color:#fafafa;--md-typeset-kbd-accent-color:#fff;--md-typeset-kbd-border-color:#b8b8b8;--md-typeset-mark-color:#ffff0080;--md-typeset-table-color:#0000001f;--md-typeset-table-color--light:rgba(0,0,0,.035);--md-admonition-fg-color:var(--md-default-fg-color);--md-admonition-bg-color:var(--md-default-bg-color);--md-warning-fg-color:#000000de;--md-warning-bg-color:#ff9;--md-footer-fg-color:#fff;--md-footer-fg-color--light:#ffffffb3;--md-footer-fg-color--lighter:#ffffff73;--md-footer-bg-color:#000000de;--md-footer-bg-color--dark:#00000052;--md-shadow-z1:0 0.2rem 0.5rem #0000000d,0 0 0.05rem #0000001a;--md-shadow-z2:0 0.2rem 0.5rem #0000001a,0 0 0.05rem #00000040;--md-shadow-z3:0 0.2rem 0.5rem #0003,0 0 0.05rem #00000059}.md-icon svg{fill:currentcolor;display:block;height:1.2rem;width:1.2rem}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;--md-text-font-family:var(--md-text-font,_),-apple-system,BlinkMacSystemFont,Helvetica,Arial,sans-serif;--md-code-font-family:var(--md-code-font,_),SFMono-Regular,Consolas,Menlo,monospace}aside,body,input{font-feature-settings:"kern","liga";color:var(--md-typeset-color);font-family:var(--md-text-font-family)}code,kbd,pre{font-feature-settings:"kern";font-family:var(--md-code-font-family)}:root{--md-typeset-table-sort-icon:url('data:image/svg+xml;charset=utf-8,');--md-typeset-table-sort-icon--asc:url('data:image/svg+xml;charset=utf-8,');--md-typeset-table-sort-icon--desc:url('data:image/svg+xml;charset=utf-8,')}.md-typeset{-webkit-print-color-adjust:exact;color-adjust:exact;font-size:.8rem;line-height:1.6}@media print{.md-typeset{font-size:.68rem}}.md-typeset blockquote,.md-typeset dl,.md-typeset figure,.md-typeset ol,.md-typeset pre,.md-typeset ul{margin-bottom:1em;margin-top:1em}.md-typeset h1{color:var(--md-default-fg-color--light);font-size:2em;line-height:1.3;margin:0 0 1.25em}.md-typeset h1,.md-typeset h2{font-weight:300;letter-spacing:-.01em}.md-typeset h2{font-size:1.5625em;line-height:1.4;margin:1.6em 0 .64em}.md-typeset h3{font-size:1.25em;font-weight:400;letter-spacing:-.01em;line-height:1.5;margin:1.6em 0 .8em}.md-typeset h2+h3{margin-top:.8em}.md-typeset h4{font-weight:700;letter-spacing:-.01em;margin:1em 0}.md-typeset h5,.md-typeset h6{color:var(--md-default-fg-color--light);font-size:.8em;font-weight:700;letter-spacing:-.01em;margin:1.25em 0}.md-typeset h5{text-transform:uppercase}.md-typeset hr{border-bottom:.05rem solid var(--md-default-fg-color--lightest);display:flow-root;margin:1.5em 0}.md-typeset a{color:var(--md-typeset-a-color);word-break:break-word}.md-typeset a,.md-typeset a:before{transition:color 125ms}.md-typeset a:focus,.md-typeset a:hover{color:var(--md-accent-fg-color)}.md-typeset a:focus code,.md-typeset a:hover code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-typeset a code{color:var(--md-typeset-a-color)}.md-typeset a.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-typeset code,.md-typeset kbd,.md-typeset pre{color:var(--md-code-fg-color);direction:ltr;font-variant-ligatures:none;transition:background-color 125ms}@media print{.md-typeset code,.md-typeset kbd,.md-typeset pre{white-space:pre-wrap}}.md-typeset code{background-color:var(--md-code-bg-color);border-radius:.1rem;-webkit-box-decoration-break:clone;box-decoration-break:clone;font-size:.85em;padding:0 .2941176471em;transition:color 125ms,background-color 125ms;word-break:break-word}.md-typeset code:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}.md-typeset pre{display:flow-root;line-height:1.4;position:relative}.md-typeset pre>code{-webkit-box-decoration-break:slice;box-decoration-break:slice;box-shadow:none;display:block;margin:0;outline-color:var(--md-accent-fg-color);overflow:auto;padding:.7720588235em 1.1764705882em;scrollbar-color:var(--md-default-fg-color--lighter) #0000;scrollbar-width:thin;touch-action:auto;word-break:normal}.md-typeset pre>code:hover{scrollbar-color:var(--md-accent-fg-color) #0000}.md-typeset pre>code::-webkit-scrollbar{height:.2rem;width:.2rem}.md-typeset pre>code::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-typeset pre>code::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}.md-typeset kbd{background-color:var(--md-typeset-kbd-color);border-radius:.1rem;box-shadow:0 .1rem 0 .05rem var(--md-typeset-kbd-border-color),0 .1rem 0 var(--md-typeset-kbd-border-color),0 -.1rem .2rem var(--md-typeset-kbd-accent-color) inset;color:var(--md-default-fg-color);display:inline-block;font-size:.75em;padding:0 .6666666667em;vertical-align:text-top;word-break:break-word}.md-typeset mark{background-color:var(--md-typeset-mark-color);-webkit-box-decoration-break:clone;box-decoration-break:clone;color:inherit;word-break:break-word}.md-typeset abbr{cursor:help;text-decoration:none}.md-typeset [data-preview],.md-typeset abbr{border-bottom:.05rem dotted var(--md-default-fg-color--light)}.md-typeset small{opacity:.75}[dir=ltr] .md-typeset sub,[dir=ltr] .md-typeset sup{margin-left:.078125em}[dir=rtl] .md-typeset sub,[dir=rtl] .md-typeset sup{margin-right:.078125em}[dir=ltr] .md-typeset blockquote{padding-left:.6rem}[dir=rtl] .md-typeset blockquote{padding-right:.6rem}[dir=ltr] .md-typeset blockquote{border-left:.2rem solid var(--md-default-fg-color--lighter)}[dir=rtl] .md-typeset blockquote{border-right:.2rem solid var(--md-default-fg-color--lighter)}.md-typeset blockquote{color:var(--md-default-fg-color--light);margin-left:0;margin-right:0}.md-typeset ul{list-style-type:disc}[dir=ltr] .md-typeset ol,[dir=ltr] .md-typeset ul{margin-left:.625em}[dir=rtl] .md-typeset ol,[dir=rtl] .md-typeset ul{margin-right:.625em}.md-typeset ol,.md-typeset ul{padding:0}.md-typeset ol:not([hidden]),.md-typeset ul:not([hidden]){display:flow-root}.md-typeset ol ol,.md-typeset ul ol{list-style-type:lower-alpha}.md-typeset ol ol ol,.md-typeset ul ol ol{list-style-type:lower-roman}[dir=ltr] .md-typeset ol li,[dir=ltr] .md-typeset ul li{margin-left:1.25em}[dir=rtl] .md-typeset ol li,[dir=rtl] .md-typeset ul li{margin-right:1.25em}.md-typeset ol li,.md-typeset ul li{margin-bottom:.5em}.md-typeset ol li blockquote,.md-typeset ol li p,.md-typeset ul li blockquote,.md-typeset ul li p{margin:.5em 0}.md-typeset ol li:last-child,.md-typeset ul li:last-child{margin-bottom:0}[dir=ltr] .md-typeset ol li ol,[dir=ltr] .md-typeset ol li ul,[dir=ltr] .md-typeset ul li ol,[dir=ltr] .md-typeset ul li ul{margin-left:.625em}[dir=rtl] .md-typeset ol li ol,[dir=rtl] .md-typeset ol li ul,[dir=rtl] .md-typeset ul li ol,[dir=rtl] .md-typeset ul li ul{margin-right:.625em}.md-typeset ol li ol,.md-typeset ol li ul,.md-typeset ul li ol,.md-typeset ul li ul{margin-bottom:.5em;margin-top:.5em}[dir=ltr] .md-typeset dd{margin-left:1.875em}[dir=rtl] .md-typeset dd{margin-right:1.875em}.md-typeset dd{margin-bottom:1.5em;margin-top:1em}.md-typeset img,.md-typeset svg,.md-typeset video{height:auto;max-width:100%}.md-typeset img[align=left]{margin:1em 1em 1em 0}.md-typeset img[align=right]{margin:1em 0 1em 1em}.md-typeset img[align]:only-child{margin-top:0}.md-typeset figure{display:flow-root;margin:1em auto;max-width:100%;text-align:center;width:-moz-fit-content;width:fit-content}.md-typeset figure img{display:block;margin:0 auto}.md-typeset figcaption{font-style:italic;margin:1em auto;max-width:24rem}.md-typeset iframe{max-width:100%}.md-typeset table:not([class]){background-color:var(--md-default-bg-color);border:.05rem solid var(--md-typeset-table-color);border-radius:.1rem;display:inline-block;font-size:.64rem;max-width:100%;overflow:auto;touch-action:auto}@media print{.md-typeset table:not([class]){display:table}}.md-typeset table:not([class])+*{margin-top:1.5em}.md-typeset table:not([class]) td>:first-child,.md-typeset table:not([class]) th>:first-child{margin-top:0}.md-typeset table:not([class]) td>:last-child,.md-typeset table:not([class]) th>:last-child{margin-bottom:0}.md-typeset table:not([class]) td:not([align]),.md-typeset table:not([class]) th:not([align]){text-align:left}[dir=rtl] .md-typeset table:not([class]) td:not([align]),[dir=rtl] .md-typeset table:not([class]) th:not([align]){text-align:right}.md-typeset table:not([class]) th{font-weight:700;min-width:5rem;padding:.9375em 1.25em;vertical-align:top}.md-typeset table:not([class]) td{border-top:.05rem solid var(--md-typeset-table-color);padding:.9375em 1.25em;vertical-align:top}.md-typeset table:not([class]) tbody tr{transition:background-color 125ms}.md-typeset table:not([class]) tbody tr:hover{background-color:var(--md-typeset-table-color--light);box-shadow:0 .05rem 0 var(--md-default-bg-color) inset}.md-typeset table:not([class]) a{word-break:normal}.md-typeset table th[role=columnheader]{cursor:pointer}[dir=ltr] .md-typeset table th[role=columnheader]:after{margin-left:.5em}[dir=rtl] .md-typeset table th[role=columnheader]:after{margin-right:.5em}.md-typeset table th[role=columnheader]:after{content:"";display:inline-block;height:1.2em;-webkit-mask-image:var(--md-typeset-table-sort-icon);mask-image:var(--md-typeset-table-sort-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:background-color 125ms;vertical-align:text-bottom;width:1.2em}.md-typeset table th[role=columnheader]:hover:after{background-color:var(--md-default-fg-color--lighter)}.md-typeset table th[role=columnheader][aria-sort=ascending]:after{background-color:var(--md-default-fg-color--light);-webkit-mask-image:var(--md-typeset-table-sort-icon--asc);mask-image:var(--md-typeset-table-sort-icon--asc)}.md-typeset table th[role=columnheader][aria-sort=descending]:after{background-color:var(--md-default-fg-color--light);-webkit-mask-image:var(--md-typeset-table-sort-icon--desc);mask-image:var(--md-typeset-table-sort-icon--desc)}.md-typeset__scrollwrap{margin:1em -.8rem;overflow-x:auto;touch-action:auto}.md-typeset__table{display:inline-block;margin-bottom:.5em;padding:0 .8rem}@media print{.md-typeset__table{display:block}}html .md-typeset__table table{display:table;margin:0;overflow:hidden;width:100%}@media screen and (max-width:44.984375em){.md-content__inner>pre{margin:1em -.8rem}.md-content__inner>pre code{border-radius:0}}.md-typeset .md-author{border-radius:100%;display:block;flex-shrink:0;height:1.6rem;overflow:hidden;position:relative;transition:color 125ms,transform 125ms;width:1.6rem}.md-typeset .md-author img{display:block}.md-typeset .md-author--more{background:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--lighter);font-size:.6rem;font-weight:700;line-height:1.6rem;text-align:center}.md-typeset .md-author--long{height:2.4rem;width:2.4rem}.md-typeset a.md-author{transform:scale(1)}.md-typeset a.md-author img{border-radius:100%;filter:grayscale(100%) opacity(75%);transition:filter 125ms}.md-typeset a.md-author:focus,.md-typeset a.md-author:hover{transform:scale(1.1);z-index:1}.md-typeset a.md-author:focus img,.md-typeset a.md-author:hover img{filter:grayscale(0)}.md-banner{background-color:var(--md-footer-bg-color);color:var(--md-footer-fg-color);overflow:auto}@media print{.md-banner{display:none}}.md-banner--warning{background-color:var(--md-warning-bg-color);color:var(--md-warning-fg-color)}.md-banner__inner{font-size:.7rem;margin:.6rem auto;padding:0 .8rem}[dir=ltr] .md-banner__button{float:right}[dir=rtl] .md-banner__button{float:left}.md-banner__button{color:inherit;cursor:pointer;transition:opacity .25s}.no-js .md-banner__button{display:none}.md-banner__button:hover{opacity:.7}html{font-size:125%;height:100%;overflow-x:hidden}@media screen and (min-width:100em){html{font-size:137.5%}}@media screen and (min-width:125em){html{font-size:150%}}body{background-color:var(--md-default-bg-color);display:flex;flex-direction:column;font-size:.5rem;min-height:100%;position:relative;width:100%}@media print{body{display:block}}@media screen and (max-width:59.984375em){body[data-md-scrolllock]{position:fixed}}.md-grid{margin-left:auto;margin-right:auto;max-width:61rem}.md-container{display:flex;flex-direction:column;flex-grow:1}@media print{.md-container{display:block}}.md-main{flex-grow:1}.md-main__inner{display:flex;height:100%;margin-top:1.5rem}.md-ellipsis{overflow:hidden;text-overflow:ellipsis}.md-toggle{display:none}.md-option{height:0;opacity:0;position:absolute;width:0}.md-option:checked+label:not([hidden]){display:block}.md-option.focus-visible+label{outline-color:var(--md-accent-fg-color);outline-style:auto}.md-skip{background-color:var(--md-default-fg-color);border-radius:.1rem;color:var(--md-default-bg-color);font-size:.64rem;margin:.5rem;opacity:0;outline-color:var(--md-accent-fg-color);padding:.3rem .5rem;position:fixed;transform:translateY(.4rem);z-index:-1}.md-skip:focus{opacity:1;transform:translateY(0);transition:transform .25s cubic-bezier(.4,0,.2,1),opacity 175ms 75ms;z-index:10}@page{margin:25mm}:root{--md-clipboard-icon:url('data:image/svg+xml;charset=utf-8,')}.md-clipboard{border-radius:.1rem;color:var(--md-default-fg-color--lightest);cursor:pointer;height:1.5em;outline-color:var(--md-accent-fg-color);outline-offset:.1rem;transition:color .25s;width:1.5em;z-index:1}@media print{.md-clipboard{display:none}}.md-clipboard:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}:hover>.md-clipboard{color:var(--md-default-fg-color--light)}.md-clipboard:focus,.md-clipboard:hover{color:var(--md-accent-fg-color)}.md-clipboard:after{background-color:currentcolor;content:"";display:block;height:1.125em;margin:0 auto;-webkit-mask-image:var(--md-clipboard-icon);mask-image:var(--md-clipboard-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:1.125em}.md-clipboard--inline{cursor:pointer}.md-clipboard--inline code{transition:color .25s,background-color .25s}.md-clipboard--inline:focus code,.md-clipboard--inline:hover code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}:root{--md-code-select-icon:url('data:image/svg+xml;charset=utf-8,');--md-code-copy-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .md-code__content{display:grid}.md-code__nav{background-color:var(--md-code-bg-color--lighter);border-radius:.1rem;display:flex;gap:.2rem;padding:.2rem;position:absolute;right:.25em;top:.25em;transition:background-color .25s;z-index:1}:hover>.md-code__nav{background-color:var(--md-code-bg-color--light)}.md-code__button{color:var(--md-default-fg-color--lightest);cursor:pointer;display:block;height:1.5em;outline-color:var(--md-accent-fg-color);outline-offset:.1rem;transition:color .25s;width:1.5em}:hover>*>.md-code__button{color:var(--md-default-fg-color--light)}.md-code__button.focus-visible,.md-code__button:hover{color:var(--md-accent-fg-color)}.md-code__button--active{color:var(--md-default-fg-color)!important}.md-code__button:after{background-color:currentcolor;content:"";display:block;height:1.125em;margin:0 auto;-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:1.125em}.md-code__button[data-md-type=select]:after{-webkit-mask-image:var(--md-code-select-icon);mask-image:var(--md-code-select-icon)}.md-code__button[data-md-type=copy]:after{-webkit-mask-image:var(--md-code-copy-icon);mask-image:var(--md-code-copy-icon)}@keyframes consent{0%{opacity:0;transform:translateY(100%)}to{opacity:1;transform:translateY(0)}}@keyframes overlay{0%{opacity:0}to{opacity:1}}.md-consent__overlay{animation:overlay .25s both;-webkit-backdrop-filter:blur(.1rem);backdrop-filter:blur(.1rem);background-color:#0000008a;height:100%;opacity:1;position:fixed;top:0;width:100%;z-index:5}.md-consent__inner{animation:consent .5s cubic-bezier(.1,.7,.1,1) both;background-color:var(--md-default-bg-color);border:0;border-radius:.1rem;bottom:0;box-shadow:0 0 .2rem #0000001a,0 .2rem .4rem #0003;max-height:100%;overflow:auto;padding:0;position:fixed;width:100%;z-index:5}.md-consent__form{padding:.8rem}.md-consent__settings{display:none;margin:1em 0}input:checked+.md-consent__settings{display:block}.md-consent__controls{margin-bottom:.8rem}.md-typeset .md-consent__controls .md-button{display:inline}@media screen and (max-width:44.984375em){.md-typeset .md-consent__controls .md-button{display:block;margin-top:.4rem;text-align:center;width:100%}}.md-consent label{cursor:pointer}.md-content{flex-grow:1;min-width:0}.md-content__inner{margin:0 .8rem 1.2rem;padding-top:.6rem}@media screen and (min-width:76.25em){[dir=ltr] .md-sidebar--primary:not([hidden])~.md-content>.md-content__inner{margin-left:1.2rem}[dir=ltr] .md-sidebar--secondary:not([hidden])~.md-content>.md-content__inner,[dir=rtl] .md-sidebar--primary:not([hidden])~.md-content>.md-content__inner{margin-right:1.2rem}[dir=rtl] .md-sidebar--secondary:not([hidden])~.md-content>.md-content__inner{margin-left:1.2rem}}.md-content__inner:before{content:"";display:block;height:.4rem}.md-content__inner>:last-child{margin-bottom:0}[dir=ltr] .md-content__button{float:right}[dir=rtl] .md-content__button{float:left}[dir=ltr] .md-content__button{margin-left:.4rem}[dir=rtl] .md-content__button{margin-right:.4rem}.md-content__button{margin:.4rem 0;padding:0}@media print{.md-content__button{display:none}}.md-typeset .md-content__button{color:var(--md-default-fg-color--lighter)}.md-content__button svg{display:inline;vertical-align:top}[dir=rtl] .md-content__button svg{transform:scaleX(-1)}[dir=ltr] .md-dialog{right:.8rem}[dir=rtl] .md-dialog{left:.8rem}.md-dialog{background-color:var(--md-default-fg-color);border-radius:.1rem;bottom:.8rem;box-shadow:var(--md-shadow-z3);min-width:11.1rem;opacity:0;padding:.4rem .6rem;pointer-events:none;position:fixed;transform:translateY(100%);transition:transform 0ms .4s,opacity .4s;z-index:4}@media print{.md-dialog{display:none}}.md-dialog--active{opacity:1;pointer-events:auto;transform:translateY(0);transition:transform .4s cubic-bezier(.075,.85,.175,1),opacity .4s}.md-dialog__inner{color:var(--md-default-bg-color);font-size:.7rem}.md-feedback{margin:2em 0 1em;text-align:center}.md-feedback fieldset{border:none;margin:0;padding:0}.md-feedback__title{font-weight:700;margin:1em auto}.md-feedback__inner{position:relative}.md-feedback__list{display:flex;flex-wrap:wrap;place-content:baseline center;position:relative}.md-feedback__list:hover .md-icon:not(:disabled){color:var(--md-default-fg-color--lighter)}:disabled .md-feedback__list{min-height:1.8rem}.md-feedback__icon{color:var(--md-default-fg-color--light);cursor:pointer;flex-shrink:0;margin:0 .1rem;transition:color 125ms}.md-feedback__icon:not(:disabled).md-icon:hover{color:var(--md-accent-fg-color)}.md-feedback__icon:disabled{color:var(--md-default-fg-color--lightest);pointer-events:none}.md-feedback__note{opacity:0;position:relative;transform:translateY(.4rem);transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s}.md-feedback__note>*{margin:0 auto;max-width:16rem}:disabled .md-feedback__note{opacity:1;transform:translateY(0)}.md-footer{background-color:var(--md-footer-bg-color);color:var(--md-footer-fg-color)}@media print{.md-footer{display:none}}.md-footer__inner{justify-content:space-between;overflow:auto;padding:.2rem}.md-footer__inner:not([hidden]){display:flex}.md-footer__link{align-items:end;display:flex;flex-grow:0.01;margin-bottom:.4rem;margin-top:1rem;max-width:100%;outline-color:var(--md-accent-fg-color);overflow:hidden;transition:opacity .25s}.md-footer__link:focus,.md-footer__link:hover{opacity:.7}[dir=rtl] .md-footer__link svg{transform:scaleX(-1)}@media screen and (max-width:44.984375em){.md-footer__link--prev{flex-shrink:0}.md-footer__link--prev .md-footer__title{display:none}}[dir=ltr] .md-footer__link--next{margin-left:auto}[dir=rtl] .md-footer__link--next{margin-right:auto}.md-footer__link--next{text-align:right}[dir=rtl] .md-footer__link--next{text-align:left}.md-footer__title{flex-grow:1;font-size:.9rem;margin-bottom:.7rem;max-width:calc(100% - 2.4rem);padding:0 1rem;white-space:nowrap}.md-footer__button{margin:.2rem;padding:.4rem}.md-footer__direction{font-size:.64rem;opacity:.7}.md-footer-meta{background-color:var(--md-footer-bg-color--dark)}.md-footer-meta__inner{display:flex;flex-wrap:wrap;justify-content:space-between;padding:.2rem}html .md-footer-meta.md-typeset a{color:var(--md-footer-fg-color--light)}html .md-footer-meta.md-typeset a:focus,html .md-footer-meta.md-typeset a:hover{color:var(--md-footer-fg-color)}.md-copyright{color:var(--md-footer-fg-color--lighter);font-size:.64rem;margin:auto .6rem;padding:.4rem 0;width:100%}@media screen and (min-width:45em){.md-copyright{width:auto}}.md-copyright__highlight{color:var(--md-footer-fg-color--light)}.md-social{display:inline-flex;gap:.2rem;margin:0 .4rem;padding:.2rem 0 .6rem}@media screen and (min-width:45em){.md-social{padding:.6rem 0}}.md-social__link{display:inline-block;height:1.6rem;text-align:center;width:1.6rem}.md-social__link:before{line-height:1.9}.md-social__link svg{fill:currentcolor;max-height:.8rem;vertical-align:-25%}.md-typeset .md-button{border:.1rem solid;border-radius:.1rem;color:var(--md-primary-fg-color);cursor:pointer;display:inline-block;font-weight:700;padding:.625em 2em;transition:color 125ms,background-color 125ms,border-color 125ms}.md-typeset .md-button--primary{background-color:var(--md-primary-fg-color);border-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color)}.md-typeset .md-button:focus,.md-typeset .md-button:hover{background-color:var(--md-accent-fg-color);border-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}[dir=ltr] .md-typeset .md-input{border-top-left-radius:.1rem}[dir=ltr] .md-typeset .md-input,[dir=rtl] .md-typeset .md-input{border-top-right-radius:.1rem}[dir=rtl] .md-typeset .md-input{border-top-left-radius:.1rem}.md-typeset .md-input{border-bottom:.1rem solid var(--md-default-fg-color--lighter);box-shadow:var(--md-shadow-z1);font-size:.8rem;height:1.8rem;padding:0 .6rem;transition:border .25s,box-shadow .25s}.md-typeset .md-input:focus,.md-typeset .md-input:hover{border-bottom-color:var(--md-accent-fg-color);box-shadow:var(--md-shadow-z2)}.md-typeset .md-input--stretch{width:100%}.md-header{background-color:var(--md-primary-fg-color);box-shadow:0 0 .2rem #0000,0 .2rem .4rem #0000;color:var(--md-primary-bg-color);display:block;left:0;position:sticky;right:0;top:0;z-index:4}@media print{.md-header{display:none}}.md-header[hidden]{transform:translateY(-100%);transition:transform .25s cubic-bezier(.8,0,.6,1),box-shadow .25s}.md-header--shadow{box-shadow:0 0 .2rem #0000001a,0 .2rem .4rem #0003;transition:transform .25s cubic-bezier(.1,.7,.1,1),box-shadow .25s}.md-header__inner{align-items:center;display:flex;padding:0 .2rem}.md-header__button{color:currentcolor;cursor:pointer;margin:.2rem;outline-color:var(--md-accent-fg-color);padding:.4rem;position:relative;transition:opacity .25s;vertical-align:middle;z-index:1}.md-header__button:hover{opacity:.7}.md-header__button:not([hidden]){display:inline-block}.md-header__button:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}.md-header__button.md-logo{margin:.2rem;padding:.4rem}@media screen and (max-width:76.234375em){.md-header__button.md-logo{display:none}}.md-header__button.md-logo img,.md-header__button.md-logo svg{fill:currentcolor;display:block;height:1.2rem;width:auto}@media screen and (min-width:60em){.md-header__button[for=__search]{display:none}}.no-js .md-header__button[for=__search]{display:none}[dir=rtl] .md-header__button[for=__search] svg{transform:scaleX(-1)}@media screen and (min-width:76.25em){.md-header__button[for=__drawer]{display:none}}.md-header__topic{display:flex;max-width:100%;position:absolute;transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s;white-space:nowrap}.md-header__topic+.md-header__topic{opacity:0;pointer-events:none;transform:translateX(1.25rem);transition:transform .4s cubic-bezier(1,.7,.1,.1),opacity .15s;z-index:-1}[dir=rtl] .md-header__topic+.md-header__topic{transform:translateX(-1.25rem)}.md-header__topic:first-child{font-weight:700}[dir=ltr] .md-header__title{margin-left:1rem;margin-right:.4rem}[dir=rtl] .md-header__title{margin-left:.4rem;margin-right:1rem}.md-header__title{flex-grow:1;font-size:.9rem;height:2.4rem;line-height:2.4rem}.md-header__title--active .md-header__topic{opacity:0;pointer-events:none;transform:translateX(-1.25rem);transition:transform .4s cubic-bezier(1,.7,.1,.1),opacity .15s;z-index:-1}[dir=rtl] .md-header__title--active .md-header__topic{transform:translateX(1.25rem)}.md-header__title--active .md-header__topic+.md-header__topic{opacity:1;pointer-events:auto;transform:translateX(0);transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s;z-index:0}.md-header__title>.md-header__ellipsis{height:100%;position:relative;width:100%}.md-header__option{display:flex;flex-shrink:0;max-width:100%;transition:max-width 0ms .25s,opacity .25s .25s;white-space:nowrap}[data-md-toggle=search]:checked~.md-header .md-header__option{max-width:0;opacity:0;transition:max-width 0ms,opacity 0ms}.md-header__option>input{bottom:0}.md-header__source{display:none}@media screen and (min-width:60em){[dir=ltr] .md-header__source{margin-left:1rem}[dir=rtl] .md-header__source{margin-right:1rem}.md-header__source{display:block;max-width:11.7rem;width:11.7rem}}@media screen and (min-width:76.25em){[dir=ltr] .md-header__source{margin-left:1.4rem}[dir=rtl] .md-header__source{margin-right:1.4rem}}.md-meta{color:var(--md-default-fg-color--light);font-size:.7rem;line-height:1.3}.md-meta__list{display:inline-flex;flex-wrap:wrap;list-style:none;margin:0;padding:0}.md-meta__item:not(:last-child):after{content:"·";margin-left:.2rem;margin-right:.2rem}.md-meta__link{color:var(--md-typeset-a-color)}.md-meta__link:focus,.md-meta__link:hover{color:var(--md-accent-fg-color)}.md-draft{background-color:#ff1744;border-radius:.125em;color:#fff;display:inline-block;font-weight:700;padding-left:.5714285714em;padding-right:.5714285714em}:root{--md-nav-icon--prev:url('data:image/svg+xml;charset=utf-8,');--md-nav-icon--next:url('data:image/svg+xml;charset=utf-8,');--md-toc-icon:url('data:image/svg+xml;charset=utf-8,')}.md-nav{font-size:.7rem;line-height:1.3}.md-nav__title{color:var(--md-default-fg-color--light);display:block;font-weight:700;overflow:hidden;padding:0 .6rem;text-overflow:ellipsis}.md-nav__title .md-nav__button{display:none}.md-nav__title .md-nav__button img{height:100%;width:auto}.md-nav__title .md-nav__button.md-logo img,.md-nav__title .md-nav__button.md-logo svg{fill:currentcolor;display:block;height:2.4rem;max-width:100%;object-fit:contain;width:auto}.md-nav__list{list-style:none;margin:0;padding:0}.md-nav__link{align-items:flex-start;display:flex;gap:.4rem;margin-top:.625em;scroll-snap-align:start;transition:color 125ms}.md-nav__link--passed,.md-nav__link--passed code{color:var(--md-default-fg-color--light)}.md-nav__item .md-nav__link--active,.md-nav__item .md-nav__link--active code{color:var(--md-typeset-a-color)}.md-nav__link .md-ellipsis{position:relative}.md-nav__link .md-ellipsis code{word-break:normal}[dir=ltr] .md-nav__link .md-icon:last-child{margin-left:auto}[dir=rtl] .md-nav__link .md-icon:last-child{margin-right:auto}.md-nav__link .md-typeset{font-size:.7rem;line-height:1.3}.md-nav__link svg{fill:currentcolor;flex-shrink:0;height:1.3em}.md-nav__link[for]:focus,.md-nav__link[for]:hover,.md-nav__link[href]:focus,.md-nav__link[href]:hover{color:var(--md-accent-fg-color);cursor:pointer}.md-nav__link[for]:focus code,.md-nav__link[for]:hover code,.md-nav__link[href]:focus code,.md-nav__link[href]:hover code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-nav__link.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-nav--primary .md-nav__link[for=__toc]{display:none}.md-nav--primary .md-nav__link[for=__toc] .md-icon:after{background-color:currentcolor;display:block;height:100%;-webkit-mask-image:var(--md-toc-icon);mask-image:var(--md-toc-icon);width:100%}.md-nav--primary .md-nav__link[for=__toc]~.md-nav{display:none}.md-nav__container>.md-nav__link{margin-top:0}.md-nav__container>.md-nav__link:first-child{flex-grow:1;min-width:0}.md-nav__icon{flex-shrink:0}.md-nav__source{display:none}@media screen and (max-width:76.234375em){.md-nav--primary,.md-nav--primary .md-nav{background-color:var(--md-default-bg-color);display:flex;flex-direction:column;height:100%;left:0;position:absolute;right:0;top:0;z-index:1}.md-nav--primary .md-nav__item,.md-nav--primary .md-nav__title{font-size:.8rem;line-height:1.5}.md-nav--primary .md-nav__title{background-color:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--light);cursor:pointer;height:5.6rem;line-height:2.4rem;padding:3rem .8rem .2rem;position:relative;white-space:nowrap}[dir=ltr] .md-nav--primary .md-nav__title .md-nav__icon{left:.4rem}[dir=rtl] .md-nav--primary .md-nav__title .md-nav__icon{right:.4rem}.md-nav--primary .md-nav__title .md-nav__icon{display:block;height:1.2rem;margin:.2rem;position:absolute;top:.4rem;width:1.2rem}.md-nav--primary .md-nav__title .md-nav__icon:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-nav-icon--prev);mask-image:var(--md-nav-icon--prev);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:100%}.md-nav--primary .md-nav__title~.md-nav__list{background-color:var(--md-default-bg-color);box-shadow:0 .05rem 0 var(--md-default-fg-color--lightest) inset;overflow-y:auto;scroll-snap-type:y mandatory;touch-action:pan-y}.md-nav--primary .md-nav__title~.md-nav__list>:first-child{border-top:0}.md-nav--primary .md-nav__title[for=__drawer]{background-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color);font-weight:700}.md-nav--primary .md-nav__title .md-logo{display:block;left:.2rem;margin:.2rem;padding:.4rem;position:absolute;right:.2rem;top:.2rem}.md-nav--primary .md-nav__list{flex:1}.md-nav--primary .md-nav__item{border-top:.05rem solid var(--md-default-fg-color--lightest)}.md-nav--primary .md-nav__item--active>.md-nav__link{color:var(--md-typeset-a-color)}.md-nav--primary .md-nav__item--active>.md-nav__link:focus,.md-nav--primary .md-nav__item--active>.md-nav__link:hover{color:var(--md-accent-fg-color)}.md-nav--primary .md-nav__link{margin-top:0;padding:.6rem .8rem}.md-nav--primary .md-nav__link svg{margin-top:.1em}.md-nav--primary .md-nav__link>.md-nav__link{padding:0}[dir=ltr] .md-nav--primary .md-nav__link .md-nav__icon{margin-right:-.2rem}[dir=rtl] .md-nav--primary .md-nav__link .md-nav__icon{margin-left:-.2rem}.md-nav--primary .md-nav__link .md-nav__icon{font-size:1.2rem;height:1.2rem;width:1.2rem}.md-nav--primary .md-nav__link .md-nav__icon:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-nav-icon--next);mask-image:var(--md-nav-icon--next);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:100%}[dir=rtl] .md-nav--primary .md-nav__icon:after{transform:scale(-1)}.md-nav--primary .md-nav--secondary .md-nav{background-color:initial;position:static}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav__link{padding-left:1.4rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav__link{padding-right:1.4rem}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav__link{padding-left:2rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav__link{padding-right:2rem}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav__link{padding-left:2.6rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav__link{padding-right:2.6rem}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav .md-nav__link{padding-left:3.2rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav .md-nav__link{padding-right:3.2rem}.md-nav--secondary{background-color:initial}.md-nav__toggle~.md-nav{display:flex;opacity:0;transform:translateX(100%);transition:transform .25s cubic-bezier(.8,0,.6,1),opacity 125ms 50ms}[dir=rtl] .md-nav__toggle~.md-nav{transform:translateX(-100%)}.md-nav__toggle:checked~.md-nav{opacity:1;transform:translateX(0);transition:transform .25s cubic-bezier(.4,0,.2,1),opacity 125ms 125ms}.md-nav__toggle:checked~.md-nav>.md-nav__list{-webkit-backface-visibility:hidden;backface-visibility:hidden}}@media screen and (max-width:59.984375em){.md-nav--primary .md-nav__link[for=__toc]{display:flex}.md-nav--primary .md-nav__link[for=__toc] .md-icon:after{content:""}.md-nav--primary .md-nav__link[for=__toc]+.md-nav__link{display:none}.md-nav--primary .md-nav__link[for=__toc]~.md-nav{display:flex}.md-nav__source{background-color:var(--md-primary-fg-color--dark);color:var(--md-primary-bg-color);display:block;padding:0 .2rem}}@media screen and (min-width:60em) and (max-width:76.234375em){.md-nav--integrated .md-nav__link[for=__toc]{display:flex}.md-nav--integrated .md-nav__link[for=__toc] .md-icon:after{content:""}.md-nav--integrated .md-nav__link[for=__toc]+.md-nav__link{display:none}.md-nav--integrated .md-nav__link[for=__toc]~.md-nav{display:flex}}@media screen and (min-width:60em){.md-nav{margin-bottom:-.4rem}.md-nav--secondary .md-nav__title{background:var(--md-default-bg-color);box-shadow:0 0 .4rem .4rem var(--md-default-bg-color);position:sticky;top:0;z-index:1}.md-nav--secondary .md-nav__title[for=__toc]{scroll-snap-align:start}.md-nav--secondary .md-nav__title .md-nav__icon{display:none}[dir=ltr] .md-nav--secondary .md-nav__list{padding-left:.6rem}[dir=rtl] .md-nav--secondary .md-nav__list{padding-right:.6rem}.md-nav--secondary .md-nav__list{padding-bottom:.4rem}[dir=ltr] .md-nav--secondary .md-nav__item>.md-nav__link{margin-right:.4rem}[dir=rtl] .md-nav--secondary .md-nav__item>.md-nav__link{margin-left:.4rem}}@media screen and (min-width:76.25em){.md-nav{margin-bottom:-.4rem;transition:max-height .25s cubic-bezier(.86,0,.07,1)}.md-nav--primary .md-nav__title{background:var(--md-default-bg-color);box-shadow:0 0 .4rem .4rem var(--md-default-bg-color);position:sticky;top:0;z-index:1}.md-nav--primary .md-nav__title[for=__drawer]{scroll-snap-align:start}.md-nav--primary .md-nav__title .md-nav__icon{display:none}[dir=ltr] .md-nav--primary .md-nav__list{padding-left:.6rem}[dir=rtl] .md-nav--primary .md-nav__list{padding-right:.6rem}.md-nav--primary .md-nav__list{padding-bottom:.4rem}[dir=ltr] .md-nav--primary .md-nav__item>.md-nav__link{margin-right:.4rem}[dir=rtl] .md-nav--primary .md-nav__item>.md-nav__link{margin-left:.4rem}.md-nav__toggle~.md-nav{display:grid;grid-template-rows:0fr;opacity:0;transition:grid-template-rows .25s cubic-bezier(.86,0,.07,1),opacity .25s,visibility 0ms .25s;visibility:collapse}.md-nav__toggle~.md-nav>.md-nav__list{overflow:hidden}.md-nav__toggle.md-toggle--indeterminate~.md-nav,.md-nav__toggle:checked~.md-nav{grid-template-rows:1fr;opacity:1;transition:grid-template-rows .25s cubic-bezier(.86,0,.07,1),opacity .15s .1s,visibility 0ms;visibility:visible}.md-nav__toggle.md-toggle--indeterminate~.md-nav{transition:none}.md-nav__item--nested>.md-nav>.md-nav__title{display:none}.md-nav__item--section{display:block;margin:1.25em 0}.md-nav__item--section:last-child{margin-bottom:0}.md-nav__item--section>.md-nav__link{font-weight:700}.md-nav__item--section>.md-nav__link[for]{color:var(--md-default-fg-color--light)}.md-nav__item--section>.md-nav__link:not(.md-nav__container){pointer-events:none}.md-nav__item--section>.md-nav__link .md-icon,.md-nav__item--section>.md-nav__link>[for]{display:none}[dir=ltr] .md-nav__item--section>.md-nav{margin-left:-.6rem}[dir=rtl] .md-nav__item--section>.md-nav{margin-right:-.6rem}.md-nav__item--section>.md-nav{display:block;opacity:1;visibility:visible}.md-nav__item--section>.md-nav>.md-nav__list>.md-nav__item{padding:0}.md-nav__icon{border-radius:100%;height:.9rem;transition:background-color .25s;width:.9rem}.md-nav__icon:hover{background-color:var(--md-accent-fg-color--transparent)}.md-nav__icon:after{background-color:currentcolor;border-radius:100%;content:"";display:inline-block;height:100%;-webkit-mask-image:var(--md-nav-icon--next);mask-image:var(--md-nav-icon--next);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:transform .25s;vertical-align:-.1rem;width:100%}[dir=rtl] .md-nav__icon:after{transform:rotate(180deg)}.md-nav__item--nested .md-nav__toggle:checked~.md-nav__link .md-nav__icon:after,.md-nav__item--nested .md-toggle--indeterminate~.md-nav__link .md-nav__icon:after{transform:rotate(90deg)}.md-nav--lifted>.md-nav__list>.md-nav__item,.md-nav--lifted>.md-nav__title{display:none}.md-nav--lifted>.md-nav__list>.md-nav__item--active{display:block}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link{background:var(--md-default-bg-color);box-shadow:0 0 .4rem .4rem var(--md-default-bg-color);margin-top:0;position:sticky;top:0;z-index:1}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link:not(.md-nav__container){pointer-events:none}.md-nav--lifted>.md-nav__list>.md-nav__item--active.md-nav__item--section{margin:0}[dir=ltr] .md-nav--lifted>.md-nav__list>.md-nav__item>.md-nav:not(.md-nav--secondary){margin-left:-.6rem}[dir=rtl] .md-nav--lifted>.md-nav__list>.md-nav__item>.md-nav:not(.md-nav--secondary){margin-right:-.6rem}.md-nav--lifted>.md-nav__list>.md-nav__item>[for]{color:var(--md-default-fg-color--light)}.md-nav--lifted .md-nav[data-md-level="1"]{grid-template-rows:1fr;opacity:1;visibility:visible}[dir=ltr] .md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{border-left:.05rem solid var(--md-primary-fg-color)}[dir=rtl] .md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{border-right:.05rem solid var(--md-primary-fg-color)}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{display:block;margin-bottom:1.25em;opacity:1;visibility:visible}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary>.md-nav__list{overflow:visible;padding-bottom:0}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary>.md-nav__title{display:none}}.md-pagination{font-size:.8rem;font-weight:700;gap:.4rem}.md-pagination,.md-pagination>*{align-items:center;display:flex;justify-content:center}.md-pagination>*{border-radius:.2rem;height:1.8rem;min-width:1.8rem;text-align:center}.md-pagination__current{background-color:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--light)}.md-pagination__link{transition:color 125ms,background-color 125ms}.md-pagination__link:focus,.md-pagination__link:hover{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-pagination__link:focus svg,.md-pagination__link:hover svg{color:var(--md-accent-fg-color)}.md-pagination__link.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-pagination__link svg{fill:currentcolor;color:var(--md-default-fg-color--lighter);display:block;max-height:100%;width:1.2rem}:root{--md-path-icon:url('data:image/svg+xml;charset=utf-8,')}.md-path{font-size:.7rem;margin:0 .8rem;overflow:auto;padding-top:1.2rem}.md-path:not([hidden]){display:block}@media screen and (min-width:76.25em){.md-path{margin:0 1.2rem}}.md-path__list{align-items:center;display:flex;gap:.2rem;list-style:none;margin:0;padding:0}.md-path__item:not(:first-child){display:inline-flex;gap:.2rem;white-space:nowrap}.md-path__item:not(:first-child):before{background-color:var(--md-default-fg-color--lighter);content:"";display:inline;height:.8rem;-webkit-mask-image:var(--md-path-icon);mask-image:var(--md-path-icon);width:.8rem}.md-path__link{align-items:center;color:var(--md-default-fg-color--light);display:flex}.md-path__link:focus,.md-path__link:hover{color:var(--md-accent-fg-color)}:root{--md-post-pin-icon:url('data:image/svg+xml;charset=utf-8,')}.md-post__back{border-bottom:.05rem solid var(--md-default-fg-color--lightest);margin-bottom:1.2rem;padding-bottom:1.2rem}@media screen and (max-width:76.234375em){.md-post__back{display:none}}[dir=rtl] .md-post__back svg{transform:scaleX(-1)}.md-post__authors{display:flex;flex-direction:column;gap:.6rem;margin:0 .6rem 1.2rem}.md-post .md-post__meta a{transition:color 125ms}.md-post .md-post__meta a:focus,.md-post .md-post__meta a:hover{color:var(--md-accent-fg-color)}.md-post__title{color:var(--md-default-fg-color--light);font-weight:700}.md-post--excerpt{margin-bottom:3.2rem}.md-post--excerpt .md-post__header{align-items:center;display:flex;gap:.6rem;min-height:1.6rem}.md-post--excerpt .md-post__authors{align-items:center;display:inline-flex;flex-direction:row;gap:.2rem;margin:0;min-height:2.4rem}[dir=ltr] .md-post--excerpt .md-post__meta .md-meta__list{margin-right:.4rem}[dir=rtl] .md-post--excerpt .md-post__meta .md-meta__list{margin-left:.4rem}.md-post--excerpt .md-post__content>:first-child{--md-scroll-margin:6rem;margin-top:0}.md-post>.md-nav--secondary{margin:1em 0}.md-pin{background:var(--md-default-fg-color--lightest);border-radius:1rem;margin-top:-.05rem;padding:.2rem}.md-pin:after{background-color:currentcolor;content:"";display:block;height:.6rem;margin:0 auto;-webkit-mask-image:var(--md-post-pin-icon);mask-image:var(--md-post-pin-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:.6rem}.md-profile{align-items:center;display:flex;font-size:.7rem;gap:.6rem;line-height:1.4;width:100%}.md-profile__description{flex-grow:1}.md-content--post{display:flex}@media screen and (max-width:76.234375em){.md-content--post{flex-flow:column-reverse}}.md-content--post>.md-content__inner{min-width:0}@media screen and (min-width:76.25em){[dir=ltr] .md-content--post>.md-content__inner{margin-left:1.2rem}[dir=rtl] .md-content--post>.md-content__inner{margin-right:1.2rem}}@media screen and (max-width:76.234375em){.md-sidebar.md-sidebar--post{padding:0;position:static;width:100%}.md-sidebar.md-sidebar--post .md-sidebar__scrollwrap{overflow:visible}.md-sidebar.md-sidebar--post .md-sidebar__inner{padding:0}.md-sidebar.md-sidebar--post .md-post__meta{margin-left:.6rem;margin-right:.6rem}.md-sidebar.md-sidebar--post .md-nav__item{border:none;display:inline}.md-sidebar.md-sidebar--post .md-nav__list{display:inline-flex;flex-wrap:wrap;gap:.6rem;padding-bottom:.6rem;padding-top:.6rem}.md-sidebar.md-sidebar--post .md-nav__link{padding:0}.md-sidebar.md-sidebar--post .md-nav{height:auto;margin-bottom:0;position:static}}:root{--md-progress-value:0;--md-progress-delay:400ms}.md-progress{background:var(--md-primary-bg-color);height:.075rem;opacity:min(clamp(0,var(--md-progress-value),1),clamp(0,100 - var(--md-progress-value),1));position:fixed;top:0;transform:scaleX(calc(var(--md-progress-value)*1%));transform-origin:left;transition:transform .5s cubic-bezier(.19,1,.22,1),opacity .25s var(--md-progress-delay);width:100%;z-index:4}:root{--md-search-result-icon:url('data:image/svg+xml;charset=utf-8,')}.md-search{position:relative}@media screen and (min-width:60em){.md-search{padding:.2rem 0}}.no-js .md-search{display:none}.md-search__overlay{opacity:0;z-index:1}@media screen and (max-width:59.984375em){[dir=ltr] .md-search__overlay{left:-2.2rem}[dir=rtl] .md-search__overlay{right:-2.2rem}.md-search__overlay{background-color:var(--md-default-bg-color);border-radius:1rem;height:2rem;overflow:hidden;pointer-events:none;position:absolute;top:-1rem;transform-origin:center;transition:transform .3s .1s,opacity .2s .2s;width:2rem}[data-md-toggle=search]:checked~.md-header .md-search__overlay{opacity:1;transition:transform .4s,opacity .1s}}@media screen and (min-width:60em){[dir=ltr] .md-search__overlay{left:0}[dir=rtl] .md-search__overlay{right:0}.md-search__overlay{background-color:#0000008a;cursor:pointer;height:0;position:fixed;top:0;transition:width 0ms .25s,height 0ms .25s,opacity .25s;width:0}[data-md-toggle=search]:checked~.md-header .md-search__overlay{height:200vh;opacity:1;transition:width 0ms,height 0ms,opacity .25s;width:100%}}@media screen and (max-width:29.984375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(45)}}@media screen and (min-width:30em) and (max-width:44.984375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(60)}}@media screen and (min-width:45em) and (max-width:59.984375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(75)}}.md-search__inner{-webkit-backface-visibility:hidden;backface-visibility:hidden}@media screen and (max-width:59.984375em){[dir=ltr] .md-search__inner{left:0}[dir=rtl] .md-search__inner{right:0}.md-search__inner{height:0;opacity:0;overflow:hidden;position:fixed;top:0;transform:translateX(5%);transition:width 0ms .3s,height 0ms .3s,transform .15s cubic-bezier(.4,0,.2,1) .15s,opacity .15s .15s;width:0;z-index:2}[dir=rtl] .md-search__inner{transform:translateX(-5%)}[data-md-toggle=search]:checked~.md-header .md-search__inner{height:100%;opacity:1;transform:translateX(0);transition:width 0ms 0ms,height 0ms 0ms,transform .15s cubic-bezier(.1,.7,.1,1) .15s,opacity .15s .15s;width:100%}}@media screen and (min-width:60em){[dir=ltr] .md-search__inner{float:right}[dir=rtl] .md-search__inner{float:left}.md-search__inner{padding:.1rem 0;position:relative;transition:width .25s cubic-bezier(.1,.7,.1,1);width:11.7rem}}@media screen and (min-width:60em) and (max-width:76.234375em){[data-md-toggle=search]:checked~.md-header .md-search__inner{width:23.4rem}}@media screen and (min-width:76.25em){[data-md-toggle=search]:checked~.md-header .md-search__inner{width:34.4rem}}.md-search__form{background-color:var(--md-default-bg-color);box-shadow:0 0 .6rem #0000;height:2.4rem;position:relative;transition:color .25s,background-color .25s;z-index:2}@media screen and (min-width:60em){.md-search__form{background-color:#00000042;border-radius:.1rem;height:1.8rem}.md-search__form:hover{background-color:#ffffff1f}}[data-md-toggle=search]:checked~.md-header .md-search__form{background-color:var(--md-default-bg-color);border-radius:.1rem .1rem 0 0;box-shadow:0 0 .6rem #00000012;color:var(--md-default-fg-color)}[dir=ltr] .md-search__input{padding-left:3.6rem;padding-right:2.2rem}[dir=rtl] .md-search__input{padding-left:2.2rem;padding-right:3.6rem}.md-search__input{background:#0000;font-size:.9rem;height:100%;position:relative;text-overflow:ellipsis;width:100%;z-index:2}.md-search__input::placeholder{transition:color .25s}.md-search__input::placeholder,.md-search__input~.md-search__icon{color:var(--md-default-fg-color--light)}.md-search__input::-ms-clear{display:none}@media screen and (max-width:59.984375em){.md-search__input{font-size:.9rem;height:2.4rem;width:100%}}@media screen and (min-width:60em){[dir=ltr] .md-search__input{padding-left:2.2rem}[dir=rtl] .md-search__input{padding-right:2.2rem}.md-search__input{color:inherit;font-size:.8rem}.md-search__input::placeholder{color:var(--md-primary-bg-color--light)}.md-search__input+.md-search__icon{color:var(--md-primary-bg-color)}[data-md-toggle=search]:checked~.md-header .md-search__input{text-overflow:clip}[data-md-toggle=search]:checked~.md-header .md-search__input+.md-search__icon{color:var(--md-default-fg-color--light)}[data-md-toggle=search]:checked~.md-header .md-search__input::placeholder{color:#0000}}.md-search__icon{cursor:pointer;display:inline-block;height:1.2rem;transition:color .25s,opacity .25s;width:1.2rem}.md-search__icon:hover{opacity:.7}[dir=ltr] .md-search__icon[for=__search]{left:.5rem}[dir=rtl] .md-search__icon[for=__search]{right:.5rem}.md-search__icon[for=__search]{position:absolute;top:.3rem;z-index:2}[dir=rtl] .md-search__icon[for=__search] svg{transform:scaleX(-1)}@media screen and (max-width:59.984375em){[dir=ltr] .md-search__icon[for=__search]{left:.8rem}[dir=rtl] .md-search__icon[for=__search]{right:.8rem}.md-search__icon[for=__search]{top:.6rem}.md-search__icon[for=__search] svg:first-child{display:none}}@media screen and (min-width:60em){.md-search__icon[for=__search]{pointer-events:none}.md-search__icon[for=__search] svg:last-child{display:none}}[dir=ltr] .md-search__options{right:.5rem}[dir=rtl] .md-search__options{left:.5rem}.md-search__options{pointer-events:none;position:absolute;top:.3rem;z-index:2}@media screen and (max-width:59.984375em){[dir=ltr] .md-search__options{right:.8rem}[dir=rtl] .md-search__options{left:.8rem}.md-search__options{top:.6rem}}[dir=ltr] .md-search__options>.md-icon{margin-left:.2rem}[dir=rtl] .md-search__options>.md-icon{margin-right:.2rem}.md-search__options>.md-icon{color:var(--md-default-fg-color--light);opacity:0;transform:scale(.75);transition:transform .15s cubic-bezier(.1,.7,.1,1),opacity .15s}.md-search__options>.md-icon:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}[data-md-toggle=search]:checked~.md-header .md-search__input:valid~.md-search__options>.md-icon{opacity:1;pointer-events:auto;transform:scale(1)}[data-md-toggle=search]:checked~.md-header .md-search__input:valid~.md-search__options>.md-icon:hover{opacity:.7}[dir=ltr] .md-search__suggest{padding-left:3.6rem;padding-right:2.2rem}[dir=rtl] .md-search__suggest{padding-left:2.2rem;padding-right:3.6rem}.md-search__suggest{align-items:center;color:var(--md-default-fg-color--lighter);display:flex;font-size:.9rem;height:100%;opacity:0;position:absolute;top:0;transition:opacity 50ms;white-space:nowrap;width:100%}@media screen and (min-width:60em){[dir=ltr] .md-search__suggest{padding-left:2.2rem}[dir=rtl] .md-search__suggest{padding-right:2.2rem}.md-search__suggest{font-size:.8rem}}[data-md-toggle=search]:checked~.md-header .md-search__suggest{opacity:1;transition:opacity .3s .1s}[dir=ltr] .md-search__output{border-bottom-left-radius:.1rem}[dir=ltr] .md-search__output,[dir=rtl] .md-search__output{border-bottom-right-radius:.1rem}[dir=rtl] .md-search__output{border-bottom-left-radius:.1rem}.md-search__output{overflow:hidden;position:absolute;width:100%;z-index:1}@media screen and (max-width:59.984375em){.md-search__output{bottom:0;top:2.4rem}}@media screen and (min-width:60em){.md-search__output{opacity:0;top:1.9rem;transition:opacity .4s}[data-md-toggle=search]:checked~.md-header .md-search__output{box-shadow:var(--md-shadow-z3);opacity:1}}.md-search__scrollwrap{-webkit-backface-visibility:hidden;backface-visibility:hidden;background-color:var(--md-default-bg-color);height:100%;overflow-y:auto;touch-action:pan-y}@media (-webkit-max-device-pixel-ratio:1),(max-resolution:1dppx){.md-search__scrollwrap{transform:translateZ(0)}}@media screen and (min-width:60em) and (max-width:76.234375em){.md-search__scrollwrap{width:23.4rem}}@media screen and (min-width:76.25em){.md-search__scrollwrap{width:34.4rem}}@media screen and (min-width:60em){.md-search__scrollwrap{max-height:0;scrollbar-color:var(--md-default-fg-color--lighter) #0000;scrollbar-width:thin}[data-md-toggle=search]:checked~.md-header .md-search__scrollwrap{max-height:75vh}.md-search__scrollwrap:hover{scrollbar-color:var(--md-accent-fg-color) #0000}.md-search__scrollwrap::-webkit-scrollbar{height:.2rem;width:.2rem}.md-search__scrollwrap::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-search__scrollwrap::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}}.md-search-result{color:var(--md-default-fg-color);word-break:break-word}.md-search-result__meta{background-color:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--light);font-size:.64rem;line-height:1.8rem;padding:0 .8rem;scroll-snap-align:start}@media screen and (min-width:60em){[dir=ltr] .md-search-result__meta{padding-left:2.2rem}[dir=rtl] .md-search-result__meta{padding-right:2.2rem}}.md-search-result__list{list-style:none;margin:0;padding:0;-webkit-user-select:none;user-select:none}.md-search-result__item{box-shadow:0 -.05rem var(--md-default-fg-color--lightest)}.md-search-result__item:first-child{box-shadow:none}.md-search-result__link{display:block;outline:none;scroll-snap-align:start;transition:background-color .25s}.md-search-result__link:focus,.md-search-result__link:hover{background-color:var(--md-accent-fg-color--transparent)}.md-search-result__link:last-child p:last-child{margin-bottom:.6rem}.md-search-result__more>summary{cursor:pointer;display:block;outline:none;position:sticky;scroll-snap-align:start;top:0;z-index:1}.md-search-result__more>summary::marker{display:none}.md-search-result__more>summary::-webkit-details-marker{display:none}.md-search-result__more>summary>div{color:var(--md-typeset-a-color);font-size:.64rem;padding:.75em .8rem;transition:color .25s,background-color .25s}@media screen and (min-width:60em){[dir=ltr] .md-search-result__more>summary>div{padding-left:2.2rem}[dir=rtl] .md-search-result__more>summary>div{padding-right:2.2rem}}.md-search-result__more>summary:focus>div,.md-search-result__more>summary:hover>div{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-search-result__more[open]>summary{background-color:var(--md-default-bg-color)}.md-search-result__article{overflow:hidden;padding:0 .8rem;position:relative}@media screen and (min-width:60em){[dir=ltr] .md-search-result__article{padding-left:2.2rem}[dir=rtl] .md-search-result__article{padding-right:2.2rem}}[dir=ltr] .md-search-result__icon{left:0}[dir=rtl] .md-search-result__icon{right:0}.md-search-result__icon{color:var(--md-default-fg-color--light);height:1.2rem;margin:.5rem;position:absolute;width:1.2rem}@media screen and (max-width:59.984375em){.md-search-result__icon{display:none}}.md-search-result__icon:after{background-color:currentcolor;content:"";display:inline-block;height:100%;-webkit-mask-image:var(--md-search-result-icon);mask-image:var(--md-search-result-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:100%}[dir=rtl] .md-search-result__icon:after{transform:scaleX(-1)}.md-search-result .md-typeset{color:var(--md-default-fg-color--light);font-size:.64rem;line-height:1.6}.md-search-result .md-typeset h1{color:var(--md-default-fg-color);font-size:.8rem;font-weight:400;line-height:1.4;margin:.55rem 0}.md-search-result .md-typeset h1 mark{text-decoration:none}.md-search-result .md-typeset h2{color:var(--md-default-fg-color);font-size:.64rem;font-weight:700;line-height:1.6;margin:.5em 0}.md-search-result .md-typeset h2 mark{text-decoration:none}.md-search-result__terms{color:var(--md-default-fg-color);display:block;font-size:.64rem;font-style:italic;margin:.5em 0}.md-search-result mark{background-color:initial;color:var(--md-accent-fg-color);text-decoration:underline}.md-select{position:relative;z-index:1}.md-select__inner{background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);left:50%;margin-top:.2rem;max-height:0;opacity:0;position:absolute;top:calc(100% - .2rem);transform:translate3d(-50%,.3rem,0);transition:transform .25s 375ms,opacity .25s .25s,max-height 0ms .5s}.md-select:focus-within .md-select__inner,.md-select:hover .md-select__inner{max-height:10rem;opacity:1;transform:translate3d(-50%,0,0);transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms}.md-select__inner:after{border-bottom:.2rem solid #0000;border-bottom-color:var(--md-default-bg-color);border-left:.2rem solid #0000;border-right:.2rem solid #0000;border-top:0;content:"";height:0;left:50%;margin-left:-.2rem;margin-top:-.2rem;position:absolute;top:0;width:0}.md-select__list{border-radius:.1rem;font-size:.8rem;list-style-type:none;margin:0;max-height:inherit;overflow:auto;padding:0}.md-select__item{line-height:1.8rem}[dir=ltr] .md-select__link{padding-left:.6rem;padding-right:1.2rem}[dir=rtl] .md-select__link{padding-left:1.2rem;padding-right:.6rem}.md-select__link{cursor:pointer;display:block;outline:none;scroll-snap-align:start;transition:background-color .25s,color .25s;width:100%}.md-select__link:focus,.md-select__link:hover{color:var(--md-accent-fg-color)}.md-select__link:focus{background-color:var(--md-default-fg-color--lightest)}.md-sidebar{align-self:flex-start;flex-shrink:0;padding:1.2rem 0;position:sticky;top:2.4rem;width:12.1rem}@media print{.md-sidebar{display:none}}@media screen and (max-width:76.234375em){[dir=ltr] .md-sidebar--primary{left:-12.1rem}[dir=rtl] .md-sidebar--primary{right:-12.1rem}.md-sidebar--primary{background-color:var(--md-default-bg-color);display:block;height:100%;position:fixed;top:0;transform:translateX(0);transition:transform .25s cubic-bezier(.4,0,.2,1),box-shadow .25s;width:12.1rem;z-index:5}[data-md-toggle=drawer]:checked~.md-container .md-sidebar--primary{box-shadow:var(--md-shadow-z3);transform:translateX(12.1rem)}[dir=rtl] [data-md-toggle=drawer]:checked~.md-container .md-sidebar--primary{transform:translateX(-12.1rem)}.md-sidebar--primary .md-sidebar__scrollwrap{bottom:0;left:0;margin:0;overflow:hidden;position:absolute;right:0;scroll-snap-type:none;top:0}}@media screen and (min-width:76.25em){.md-sidebar{height:0}.no-js .md-sidebar{height:auto}.md-header--lifted~.md-container .md-sidebar{top:4.8rem}}.md-sidebar--secondary{display:none;order:2}@media screen and (min-width:60em){.md-sidebar--secondary{height:0}.no-js .md-sidebar--secondary{height:auto}.md-sidebar--secondary:not([hidden]){display:block}.md-sidebar--secondary .md-sidebar__scrollwrap{touch-action:pan-y}}.md-sidebar__scrollwrap{scrollbar-gutter:stable;-webkit-backface-visibility:hidden;backface-visibility:hidden;margin:0 .2rem;overflow-y:auto;scrollbar-color:var(--md-default-fg-color--lighter) #0000;scrollbar-width:thin}.md-sidebar__scrollwrap::-webkit-scrollbar{height:.2rem;width:.2rem}.md-sidebar__scrollwrap:focus-within,.md-sidebar__scrollwrap:hover{scrollbar-color:var(--md-accent-fg-color) #0000}.md-sidebar__scrollwrap:focus-within::-webkit-scrollbar-thumb,.md-sidebar__scrollwrap:hover::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-sidebar__scrollwrap:focus-within::-webkit-scrollbar-thumb:hover,.md-sidebar__scrollwrap:hover::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}@supports selector(::-webkit-scrollbar){.md-sidebar__scrollwrap{scrollbar-gutter:auto}[dir=ltr] .md-sidebar__inner{padding-right:calc(100% - 11.5rem)}[dir=rtl] .md-sidebar__inner{padding-left:calc(100% - 11.5rem)}}@media screen and (max-width:76.234375em){.md-overlay{background-color:#0000008a;height:0;opacity:0;position:fixed;top:0;transition:width 0ms .25s,height 0ms .25s,opacity .25s;width:0;z-index:5}[data-md-toggle=drawer]:checked~.md-overlay{height:100%;opacity:1;transition:width 0ms,height 0ms,opacity .25s;width:100%}}@keyframes facts{0%{height:0}to{height:.65rem}}@keyframes fact{0%{opacity:0;transform:translateY(100%)}50%{opacity:0}to{opacity:1;transform:translateY(0)}}:root{--md-source-forks-icon:url('data:image/svg+xml;charset=utf-8,');--md-source-repositories-icon:url('data:image/svg+xml;charset=utf-8,');--md-source-stars-icon:url('data:image/svg+xml;charset=utf-8,');--md-source-version-icon:url('data:image/svg+xml;charset=utf-8,')}.md-source{-webkit-backface-visibility:hidden;backface-visibility:hidden;display:block;font-size:.65rem;line-height:1.2;outline-color:var(--md-accent-fg-color);transition:opacity .25s;white-space:nowrap}.md-source:hover{opacity:.7}.md-source__icon{display:inline-block;height:2.4rem;vertical-align:middle;width:2rem}[dir=ltr] .md-source__icon svg{margin-left:.6rem}[dir=rtl] .md-source__icon svg{margin-right:.6rem}.md-source__icon svg{margin-top:.6rem}[dir=ltr] .md-source__icon+.md-source__repository{padding-left:2rem}[dir=rtl] .md-source__icon+.md-source__repository{padding-right:2rem}[dir=ltr] .md-source__icon+.md-source__repository{margin-left:-2rem}[dir=rtl] .md-source__icon+.md-source__repository{margin-right:-2rem}[dir=ltr] .md-source__repository{margin-left:.6rem}[dir=rtl] .md-source__repository{margin-right:.6rem}.md-source__repository{display:inline-block;max-width:calc(100% - 1.2rem);overflow:hidden;text-overflow:ellipsis;vertical-align:middle}.md-source__facts{display:flex;font-size:.55rem;gap:.4rem;list-style-type:none;margin:.1rem 0 0;opacity:.75;overflow:hidden;padding:0;width:100%}.md-source__repository--active .md-source__facts{animation:facts .25s ease-in}.md-source__fact{overflow:hidden;text-overflow:ellipsis}.md-source__repository--active .md-source__fact{animation:fact .4s ease-out}[dir=ltr] .md-source__fact:before{margin-right:.1rem}[dir=rtl] .md-source__fact:before{margin-left:.1rem}.md-source__fact:before{background-color:currentcolor;content:"";display:inline-block;height:.6rem;-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:text-top;width:.6rem}.md-source__fact:nth-child(1n+2){flex-shrink:0}.md-source__fact--version:before{-webkit-mask-image:var(--md-source-version-icon);mask-image:var(--md-source-version-icon)}.md-source__fact--stars:before{-webkit-mask-image:var(--md-source-stars-icon);mask-image:var(--md-source-stars-icon)}.md-source__fact--forks:before{-webkit-mask-image:var(--md-source-forks-icon);mask-image:var(--md-source-forks-icon)}.md-source__fact--repositories:before{-webkit-mask-image:var(--md-source-repositories-icon);mask-image:var(--md-source-repositories-icon)}.md-source-file{margin:1em 0}[dir=ltr] .md-source-file__fact{margin-right:.6rem}[dir=rtl] .md-source-file__fact{margin-left:.6rem}.md-source-file__fact{align-items:center;color:var(--md-default-fg-color--light);display:inline-flex;font-size:.68rem;gap:.3rem}.md-source-file__fact .md-icon{flex-shrink:0;margin-bottom:.05rem}[dir=ltr] .md-source-file__fact .md-author{float:left}[dir=rtl] .md-source-file__fact .md-author{float:right}.md-source-file__fact .md-author{margin-right:.2rem}.md-source-file__fact svg{width:.9rem}:root{--md-status:url('data:image/svg+xml;charset=utf-8,');--md-status--new:url('data:image/svg+xml;charset=utf-8,');--md-status--deprecated:url('data:image/svg+xml;charset=utf-8,');--md-status--encrypted:url('data:image/svg+xml;charset=utf-8,')}.md-status:after{background-color:var(--md-default-fg-color--light);content:"";display:inline-block;height:1.125em;-webkit-mask-image:var(--md-status);mask-image:var(--md-status);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:text-bottom;width:1.125em}.md-status:hover:after{background-color:currentcolor}.md-status--new:after{-webkit-mask-image:var(--md-status--new);mask-image:var(--md-status--new)}.md-status--deprecated:after{-webkit-mask-image:var(--md-status--deprecated);mask-image:var(--md-status--deprecated)}.md-status--encrypted:after{-webkit-mask-image:var(--md-status--encrypted);mask-image:var(--md-status--encrypted)}.md-tabs{background-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color);display:block;line-height:1.3;overflow:auto;width:100%;z-index:3}@media print{.md-tabs{display:none}}@media screen and (max-width:76.234375em){.md-tabs{display:none}}.md-tabs[hidden]{pointer-events:none}[dir=ltr] .md-tabs__list{margin-left:.2rem}[dir=rtl] .md-tabs__list{margin-right:.2rem}.md-tabs__list{contain:content;display:flex;list-style:none;margin:0;overflow:auto;padding:0;scrollbar-width:none;white-space:nowrap}.md-tabs__list::-webkit-scrollbar{display:none}.md-tabs__item{height:2.4rem;padding-left:.6rem;padding-right:.6rem}.md-tabs__item--active .md-tabs__link{color:inherit;opacity:1}.md-tabs__link{-webkit-backface-visibility:hidden;backface-visibility:hidden;display:flex;font-size:.7rem;margin-top:.8rem;opacity:.7;outline-color:var(--md-accent-fg-color);outline-offset:.2rem;transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .25s}.md-tabs__link:focus,.md-tabs__link:hover{color:inherit;opacity:1}[dir=ltr] .md-tabs__link svg{margin-right:.4rem}[dir=rtl] .md-tabs__link svg{margin-left:.4rem}.md-tabs__link svg{fill:currentcolor;height:1.3em}.md-tabs__item:nth-child(2) .md-tabs__link{transition-delay:20ms}.md-tabs__item:nth-child(3) .md-tabs__link{transition-delay:40ms}.md-tabs__item:nth-child(4) .md-tabs__link{transition-delay:60ms}.md-tabs__item:nth-child(5) .md-tabs__link{transition-delay:80ms}.md-tabs__item:nth-child(6) .md-tabs__link{transition-delay:.1s}.md-tabs__item:nth-child(7) .md-tabs__link{transition-delay:.12s}.md-tabs__item:nth-child(8) .md-tabs__link{transition-delay:.14s}.md-tabs__item:nth-child(9) .md-tabs__link{transition-delay:.16s}.md-tabs__item:nth-child(10) .md-tabs__link{transition-delay:.18s}.md-tabs__item:nth-child(11) .md-tabs__link{transition-delay:.2s}.md-tabs__item:nth-child(12) .md-tabs__link{transition-delay:.22s}.md-tabs__item:nth-child(13) .md-tabs__link{transition-delay:.24s}.md-tabs__item:nth-child(14) .md-tabs__link{transition-delay:.26s}.md-tabs__item:nth-child(15) .md-tabs__link{transition-delay:.28s}.md-tabs__item:nth-child(16) .md-tabs__link{transition-delay:.3s}.md-tabs[hidden] .md-tabs__link{opacity:0;transform:translateY(50%);transition:transform 0ms .1s,opacity .1s}:root{--md-tag-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .md-tags:not([hidden]){display:inline-flex;flex-wrap:wrap;gap:.5em;margin-bottom:.75em;margin-top:-.125em}.md-typeset .md-tag{align-items:center;background:var(--md-default-fg-color--lightest);border-radius:2.4rem;display:inline-flex;font-size:.64rem;font-size:min(.8em,.64rem);font-weight:700;gap:.5em;letter-spacing:normal;line-height:1.6;padding:.3125em .78125em}.md-typeset .md-tag[href]{-webkit-tap-highlight-color:transparent;color:inherit;outline:none;transition:color 125ms,background-color 125ms}.md-typeset .md-tag[href]:focus,.md-typeset .md-tag[href]:hover{background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}[id]>.md-typeset .md-tag{vertical-align:text-top}.md-typeset .md-tag-shadow{opacity:.5}.md-typeset .md-tag-icon:before{background-color:var(--md-default-fg-color--lighter);content:"";display:inline-block;height:1.2em;-webkit-mask-image:var(--md-tag-icon);mask-image:var(--md-tag-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:background-color 125ms;vertical-align:text-bottom;width:1.2em}.md-typeset .md-tag-icon[href]:focus:before,.md-typeset .md-tag-icon[href]:hover:before{background-color:var(--md-accent-bg-color)}@keyframes pulse{0%{transform:scale(.95)}75%{transform:scale(1)}to{transform:scale(.95)}}:root{--md-annotation-bg-icon:url('data:image/svg+xml;charset=utf-8,');--md-annotation-icon:url('data:image/svg+xml;charset=utf-8,')}.md-tooltip{-webkit-backface-visibility:hidden;backface-visibility:hidden;background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);font-family:var(--md-text-font-family);left:clamp(var(--md-tooltip-0,0rem) + .8rem,var(--md-tooltip-x),100vw + var(--md-tooltip-0,0rem) + .8rem - var(--md-tooltip-width) - 2 * .8rem);max-width:calc(100vw - 1.6rem);opacity:0;position:absolute;top:var(--md-tooltip-y);transform:translateY(-.4rem);transition:transform 0ms .25s,opacity .25s,z-index .25s;width:var(--md-tooltip-width);z-index:0}.md-tooltip--active{opacity:1;transform:translateY(0);transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,z-index 0ms;z-index:2}.md-tooltip--inline{font-weight:700;-webkit-user-select:none;user-select:none;width:auto}.md-tooltip--inline:not(.md-tooltip--active){transform:translateY(.2rem) scale(.9)}.md-tooltip--inline .md-tooltip__inner{font-size:.5rem;padding:.2rem .4rem}[hidden]+.md-tooltip--inline{display:none}.focus-visible>.md-tooltip,.md-tooltip:target{outline:var(--md-accent-fg-color) auto}.md-tooltip__inner{font-size:.64rem;padding:.8rem}.md-tooltip__inner.md-typeset>:first-child{margin-top:0}.md-tooltip__inner.md-typeset>:last-child{margin-bottom:0}.md-annotation{font-weight:400;outline:none;vertical-align:text-bottom;white-space:normal}[dir=rtl] .md-annotation{direction:rtl}code .md-annotation{font-family:var(--md-code-font-family);font-size:inherit}.md-annotation:not([hidden]){display:inline-block;line-height:1.25}.md-annotation__index{border-radius:.01px;cursor:pointer;display:inline-block;margin-left:.4ch;margin-right:.4ch;outline:none;overflow:hidden;position:relative;-webkit-user-select:none;user-select:none;vertical-align:text-top;z-index:0}.md-annotation .md-annotation__index{transition:z-index .25s}@media screen{.md-annotation__index{width:2.2ch}[data-md-visible]>.md-annotation__index{animation:pulse 2s infinite}.md-annotation__index:before{background:var(--md-default-bg-color);-webkit-mask-image:var(--md-annotation-bg-icon);mask-image:var(--md-annotation-bg-icon)}.md-annotation__index:after,.md-annotation__index:before{content:"";height:2.2ch;-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:-.1ch;width:2.2ch;z-index:-1}.md-annotation__index:after{background-color:var(--md-default-fg-color--lighter);-webkit-mask-image:var(--md-annotation-icon);mask-image:var(--md-annotation-icon);transform:scale(1.0001);transition:background-color .25s,transform .25s}.md-tooltip--active+.md-annotation__index:after{transform:rotate(45deg)}.md-tooltip--active+.md-annotation__index:after,:hover>.md-annotation__index:after{background-color:var(--md-accent-fg-color)}}.md-tooltip--active+.md-annotation__index{animation-play-state:paused;transition-duration:0ms;z-index:2}.md-annotation__index [data-md-annotation-id]{display:inline-block}@media print{.md-annotation__index [data-md-annotation-id]{background:var(--md-default-fg-color--lighter);border-radius:2ch;color:var(--md-default-bg-color);font-weight:700;padding:0 .6ch;white-space:nowrap}.md-annotation__index [data-md-annotation-id]:after{content:attr(data-md-annotation-id)}}.md-typeset .md-annotation-list{counter-reset:xxx;list-style:none}.md-typeset .md-annotation-list li{position:relative}[dir=ltr] .md-typeset .md-annotation-list li:before{left:-2.125em}[dir=rtl] .md-typeset .md-annotation-list li:before{right:-2.125em}.md-typeset .md-annotation-list li:before{background:var(--md-default-fg-color--lighter);border-radius:2ch;color:var(--md-default-bg-color);content:counter(xxx);counter-increment:xxx;font-size:.8875em;font-weight:700;height:2ch;line-height:1.25;min-width:2ch;padding:0 .6ch;position:absolute;text-align:center;top:.25em}:root{--md-tooltip-width:20rem;--md-tooltip-tail:0.3rem}.md-tooltip2{-webkit-backface-visibility:hidden;backface-visibility:hidden;color:var(--md-default-fg-color);font-family:var(--md-text-font-family);opacity:0;pointer-events:none;position:absolute;top:calc(var(--md-tooltip-host-y) + var(--md-tooltip-y));transform:translateY(-.4rem);transform-origin:calc(var(--md-tooltip-host-x) + var(--md-tooltip-x)) 0;transition:transform 0ms .25s,opacity .25s,z-index .25s;width:100%;z-index:0}.md-tooltip2:before{border-left:var(--md-tooltip-tail) solid #0000;border-right:var(--md-tooltip-tail) solid #0000;content:"";display:block;left:clamp(1.5 * .8rem,var(--md-tooltip-host-x) + var(--md-tooltip-x) - var(--md-tooltip-tail),100vw - 2 * var(--md-tooltip-tail) - 1.5 * .8rem);position:absolute;z-index:1}.md-tooltip2--top:before{border-top:var(--md-tooltip-tail) solid var(--md-default-bg-color);bottom:calc(var(--md-tooltip-tail)*-1 + .025rem);filter:drop-shadow(0 1px 0 hsla(0,0%,0%,.05))}.md-tooltip2--bottom:before{border-bottom:var(--md-tooltip-tail) solid var(--md-default-bg-color);filter:drop-shadow(0 -1px 0 hsla(0,0%,0%,.05));top:calc(var(--md-tooltip-tail)*-1 + .025rem)}.md-tooltip2--active{opacity:1;transform:translateY(0);transition:transform .4s cubic-bezier(0,1,.5,1),opacity .25s,z-index 0ms;z-index:2}.md-tooltip2__inner{scrollbar-gutter:stable;background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);left:clamp(.8rem,var(--md-tooltip-host-x) - .8rem,100vw - var(--md-tooltip-width) - .8rem);max-height:40vh;max-width:calc(100vw - 1.6rem);position:relative;scrollbar-width:thin}.md-tooltip2__inner::-webkit-scrollbar{height:.2rem;width:.2rem}.md-tooltip2__inner::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-tooltip2__inner::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}[role=dialog]>.md-tooltip2__inner{font-size:.64rem;overflow:auto;padding:0 .8rem;pointer-events:auto;width:var(--md-tooltip-width)}[role=dialog]>.md-tooltip2__inner:after,[role=dialog]>.md-tooltip2__inner:before{content:"";display:block;height:.8rem;position:sticky;width:100%;z-index:10}[role=dialog]>.md-tooltip2__inner:before{background:linear-gradient(var(--md-default-bg-color),#0000 75%);top:0}[role=dialog]>.md-tooltip2__inner:after{background:linear-gradient(#0000,var(--md-default-bg-color) 75%);bottom:0}[role=tooltip]>.md-tooltip2__inner{font-size:.5rem;font-weight:700;left:clamp(.8rem,var(--md-tooltip-host-x) + var(--md-tooltip-x) - var(--md-tooltip-width)/2,100vw - var(--md-tooltip-width) - .8rem);max-width:min(100vw - 2 * .8rem,400px);padding:.2rem .4rem;-webkit-user-select:none;user-select:none;width:-moz-fit-content;width:fit-content}.md-tooltip2__inner.md-typeset>:first-child{margin-top:0}.md-tooltip2__inner.md-typeset>:last-child{margin-bottom:0}[dir=ltr] .md-top{margin-left:50%}[dir=rtl] .md-top{margin-right:50%}.md-top{background-color:var(--md-default-bg-color);border-radius:1.6rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color--light);cursor:pointer;display:block;font-size:.7rem;outline:none;padding:.4rem .8rem;position:fixed;top:3.2rem;transform:translate(-50%);transition:color 125ms,background-color 125ms,transform 125ms cubic-bezier(.4,0,.2,1),opacity 125ms;z-index:2}@media print{.md-top{display:none}}[dir=rtl] .md-top{transform:translate(50%)}.md-top[hidden]{opacity:0;pointer-events:none;transform:translate(-50%,.2rem);transition-duration:0ms}[dir=rtl] .md-top[hidden]{transform:translate(50%,.2rem)}.md-top:focus,.md-top:hover{background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-top svg{display:inline-block;vertical-align:-.5em}@keyframes hoverfix{0%{pointer-events:none}}:root{--md-version-icon:url('data:image/svg+xml;charset=utf-8,')}.md-version{flex-shrink:0;font-size:.8rem;height:2.4rem}[dir=ltr] .md-version__current{margin-left:1.4rem;margin-right:.4rem}[dir=rtl] .md-version__current{margin-left:.4rem;margin-right:1.4rem}.md-version__current{color:inherit;cursor:pointer;outline:none;position:relative;top:.05rem}[dir=ltr] .md-version__current:after{margin-left:.4rem}[dir=rtl] .md-version__current:after{margin-right:.4rem}.md-version__current:after{background-color:currentcolor;content:"";display:inline-block;height:.6rem;-webkit-mask-image:var(--md-version-icon);mask-image:var(--md-version-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:.4rem}.md-version__alias{margin-left:.3rem;opacity:.7}.md-version__list{background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);list-style-type:none;margin:.2rem .8rem;max-height:0;opacity:0;overflow:auto;padding:0;position:absolute;scroll-snap-type:y mandatory;top:.15rem;transition:max-height 0ms .5s,opacity .25s .25s;z-index:3}.md-version:focus-within .md-version__list,.md-version:hover .md-version__list{max-height:10rem;opacity:1;transition:max-height 0ms,opacity .25s}@media (hover:none),(pointer:coarse){.md-version:hover .md-version__list{animation:hoverfix .25s forwards}.md-version:focus-within .md-version__list{animation:none}}.md-version__item{line-height:1.8rem}[dir=ltr] .md-version__link{padding-left:.6rem;padding-right:1.2rem}[dir=rtl] .md-version__link{padding-left:1.2rem;padding-right:.6rem}.md-version__link{cursor:pointer;display:block;outline:none;scroll-snap-align:start;transition:color .25s,background-color .25s;white-space:nowrap;width:100%}.md-version__link:focus,.md-version__link:hover{color:var(--md-accent-fg-color)}.md-version__link:focus{background-color:var(--md-default-fg-color--lightest)}:root{--md-admonition-icon--note:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--abstract:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--info:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--tip:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--success:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--question:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--warning:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--failure:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--danger:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--bug:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--example:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--quote:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .admonition,.md-typeset details{background-color:var(--md-admonition-bg-color);border:.075rem solid #448aff;border-radius:.2rem;box-shadow:var(--md-shadow-z1);color:var(--md-admonition-fg-color);display:flow-root;font-size:.64rem;margin:1.5625em 0;padding:0 .6rem;page-break-inside:avoid;transition:box-shadow 125ms}@media print{.md-typeset .admonition,.md-typeset details{box-shadow:none}}.md-typeset .admonition:focus-within,.md-typeset details:focus-within{box-shadow:0 0 0 .2rem #448aff1a}.md-typeset .admonition>*,.md-typeset details>*{box-sizing:border-box}.md-typeset .admonition .admonition,.md-typeset .admonition details,.md-typeset details .admonition,.md-typeset details details{margin-bottom:1em;margin-top:1em}.md-typeset .admonition .md-typeset__scrollwrap,.md-typeset details .md-typeset__scrollwrap{margin:1em -.6rem}.md-typeset .admonition .md-typeset__table,.md-typeset details .md-typeset__table{padding:0 .6rem}.md-typeset .admonition>.tabbed-set:only-child,.md-typeset details>.tabbed-set:only-child{margin-top:0}html .md-typeset .admonition>:last-child,html .md-typeset details>:last-child{margin-bottom:.6rem}[dir=ltr] .md-typeset .admonition-title,[dir=ltr] .md-typeset summary{padding-left:2rem;padding-right:.6rem}[dir=rtl] .md-typeset .admonition-title,[dir=rtl] .md-typeset summary{padding-left:.6rem;padding-right:2rem}[dir=ltr] .md-typeset .admonition-title,[dir=ltr] .md-typeset summary{border-left-width:.2rem}[dir=rtl] .md-typeset .admonition-title,[dir=rtl] .md-typeset summary{border-right-width:.2rem}[dir=ltr] .md-typeset .admonition-title,[dir=ltr] .md-typeset summary{border-top-left-radius:.1rem}[dir=ltr] .md-typeset .admonition-title,[dir=ltr] .md-typeset summary,[dir=rtl] .md-typeset .admonition-title,[dir=rtl] .md-typeset summary{border-top-right-radius:.1rem}[dir=rtl] .md-typeset .admonition-title,[dir=rtl] .md-typeset summary{border-top-left-radius:.1rem}.md-typeset .admonition-title,.md-typeset summary{background-color:#448aff1a;border:none;font-weight:700;margin:0 -.6rem;padding-bottom:.4rem;padding-top:.4rem;position:relative}html .md-typeset .admonition-title:last-child,html .md-typeset summary:last-child{margin-bottom:0}[dir=ltr] .md-typeset .admonition-title:before,[dir=ltr] .md-typeset summary:before{left:.6rem}[dir=rtl] .md-typeset .admonition-title:before,[dir=rtl] .md-typeset summary:before{right:.6rem}.md-typeset .admonition-title:before,.md-typeset summary:before{background-color:#448aff;content:"";height:1rem;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.625em;width:1rem}.md-typeset .admonition-title code,.md-typeset summary code{box-shadow:0 0 0 .05rem var(--md-default-fg-color--lightest)}.md-typeset .admonition.note,.md-typeset details.note{border-color:#448aff}.md-typeset .admonition.note:focus-within,.md-typeset details.note:focus-within{box-shadow:0 0 0 .2rem #448aff1a}.md-typeset .note>.admonition-title,.md-typeset .note>summary{background-color:#448aff1a}.md-typeset .note>.admonition-title:before,.md-typeset .note>summary:before{background-color:#448aff;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note)}.md-typeset .note>.admonition-title:after,.md-typeset .note>summary:after{color:#448aff}.md-typeset .admonition.abstract,.md-typeset details.abstract{border-color:#00b0ff}.md-typeset .admonition.abstract:focus-within,.md-typeset details.abstract:focus-within{box-shadow:0 0 0 .2rem #00b0ff1a}.md-typeset .abstract>.admonition-title,.md-typeset .abstract>summary{background-color:#00b0ff1a}.md-typeset .abstract>.admonition-title:before,.md-typeset .abstract>summary:before{background-color:#00b0ff;-webkit-mask-image:var(--md-admonition-icon--abstract);mask-image:var(--md-admonition-icon--abstract)}.md-typeset .abstract>.admonition-title:after,.md-typeset .abstract>summary:after{color:#00b0ff}.md-typeset .admonition.info,.md-typeset details.info{border-color:#00b8d4}.md-typeset .admonition.info:focus-within,.md-typeset details.info:focus-within{box-shadow:0 0 0 .2rem #00b8d41a}.md-typeset .info>.admonition-title,.md-typeset .info>summary{background-color:#00b8d41a}.md-typeset .info>.admonition-title:before,.md-typeset .info>summary:before{background-color:#00b8d4;-webkit-mask-image:var(--md-admonition-icon--info);mask-image:var(--md-admonition-icon--info)}.md-typeset .info>.admonition-title:after,.md-typeset .info>summary:after{color:#00b8d4}.md-typeset .admonition.tip,.md-typeset details.tip{border-color:#00bfa5}.md-typeset .admonition.tip:focus-within,.md-typeset details.tip:focus-within{box-shadow:0 0 0 .2rem #00bfa51a}.md-typeset .tip>.admonition-title,.md-typeset .tip>summary{background-color:#00bfa51a}.md-typeset .tip>.admonition-title:before,.md-typeset .tip>summary:before{background-color:#00bfa5;-webkit-mask-image:var(--md-admonition-icon--tip);mask-image:var(--md-admonition-icon--tip)}.md-typeset .tip>.admonition-title:after,.md-typeset .tip>summary:after{color:#00bfa5}.md-typeset .admonition.success,.md-typeset details.success{border-color:#00c853}.md-typeset .admonition.success:focus-within,.md-typeset details.success:focus-within{box-shadow:0 0 0 .2rem #00c8531a}.md-typeset .success>.admonition-title,.md-typeset .success>summary{background-color:#00c8531a}.md-typeset .success>.admonition-title:before,.md-typeset .success>summary:before{background-color:#00c853;-webkit-mask-image:var(--md-admonition-icon--success);mask-image:var(--md-admonition-icon--success)}.md-typeset .success>.admonition-title:after,.md-typeset .success>summary:after{color:#00c853}.md-typeset .admonition.question,.md-typeset details.question{border-color:#64dd17}.md-typeset .admonition.question:focus-within,.md-typeset details.question:focus-within{box-shadow:0 0 0 .2rem #64dd171a}.md-typeset .question>.admonition-title,.md-typeset .question>summary{background-color:#64dd171a}.md-typeset .question>.admonition-title:before,.md-typeset .question>summary:before{background-color:#64dd17;-webkit-mask-image:var(--md-admonition-icon--question);mask-image:var(--md-admonition-icon--question)}.md-typeset .question>.admonition-title:after,.md-typeset .question>summary:after{color:#64dd17}.md-typeset .admonition.warning,.md-typeset details.warning{border-color:#ff9100}.md-typeset .admonition.warning:focus-within,.md-typeset details.warning:focus-within{box-shadow:0 0 0 .2rem #ff91001a}.md-typeset .warning>.admonition-title,.md-typeset .warning>summary{background-color:#ff91001a}.md-typeset .warning>.admonition-title:before,.md-typeset .warning>summary:before{background-color:#ff9100;-webkit-mask-image:var(--md-admonition-icon--warning);mask-image:var(--md-admonition-icon--warning)}.md-typeset .warning>.admonition-title:after,.md-typeset .warning>summary:after{color:#ff9100}.md-typeset .admonition.failure,.md-typeset details.failure{border-color:#ff5252}.md-typeset .admonition.failure:focus-within,.md-typeset details.failure:focus-within{box-shadow:0 0 0 .2rem #ff52521a}.md-typeset .failure>.admonition-title,.md-typeset .failure>summary{background-color:#ff52521a}.md-typeset .failure>.admonition-title:before,.md-typeset .failure>summary:before{background-color:#ff5252;-webkit-mask-image:var(--md-admonition-icon--failure);mask-image:var(--md-admonition-icon--failure)}.md-typeset .failure>.admonition-title:after,.md-typeset .failure>summary:after{color:#ff5252}.md-typeset .admonition.danger,.md-typeset details.danger{border-color:#ff1744}.md-typeset .admonition.danger:focus-within,.md-typeset details.danger:focus-within{box-shadow:0 0 0 .2rem #ff17441a}.md-typeset .danger>.admonition-title,.md-typeset .danger>summary{background-color:#ff17441a}.md-typeset .danger>.admonition-title:before,.md-typeset .danger>summary:before{background-color:#ff1744;-webkit-mask-image:var(--md-admonition-icon--danger);mask-image:var(--md-admonition-icon--danger)}.md-typeset .danger>.admonition-title:after,.md-typeset .danger>summary:after{color:#ff1744}.md-typeset .admonition.bug,.md-typeset details.bug{border-color:#f50057}.md-typeset .admonition.bug:focus-within,.md-typeset details.bug:focus-within{box-shadow:0 0 0 .2rem #f500571a}.md-typeset .bug>.admonition-title,.md-typeset .bug>summary{background-color:#f500571a}.md-typeset .bug>.admonition-title:before,.md-typeset .bug>summary:before{background-color:#f50057;-webkit-mask-image:var(--md-admonition-icon--bug);mask-image:var(--md-admonition-icon--bug)}.md-typeset .bug>.admonition-title:after,.md-typeset .bug>summary:after{color:#f50057}.md-typeset .admonition.example,.md-typeset details.example{border-color:#7c4dff}.md-typeset .admonition.example:focus-within,.md-typeset details.example:focus-within{box-shadow:0 0 0 .2rem #7c4dff1a}.md-typeset .example>.admonition-title,.md-typeset .example>summary{background-color:#7c4dff1a}.md-typeset .example>.admonition-title:before,.md-typeset .example>summary:before{background-color:#7c4dff;-webkit-mask-image:var(--md-admonition-icon--example);mask-image:var(--md-admonition-icon--example)}.md-typeset .example>.admonition-title:after,.md-typeset .example>summary:after{color:#7c4dff}.md-typeset .admonition.quote,.md-typeset details.quote{border-color:#9e9e9e}.md-typeset .admonition.quote:focus-within,.md-typeset details.quote:focus-within{box-shadow:0 0 0 .2rem #9e9e9e1a}.md-typeset .quote>.admonition-title,.md-typeset .quote>summary{background-color:#9e9e9e1a}.md-typeset .quote>.admonition-title:before,.md-typeset .quote>summary:before{background-color:#9e9e9e;-webkit-mask-image:var(--md-admonition-icon--quote);mask-image:var(--md-admonition-icon--quote)}.md-typeset .quote>.admonition-title:after,.md-typeset .quote>summary:after{color:#9e9e9e}:root{--md-footnotes-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .footnote{color:var(--md-default-fg-color--light);font-size:.64rem}[dir=ltr] .md-typeset .footnote>ol{margin-left:0}[dir=rtl] .md-typeset .footnote>ol{margin-right:0}.md-typeset .footnote>ol>li{transition:color 125ms}.md-typeset .footnote>ol>li:target{color:var(--md-default-fg-color)}.md-typeset .footnote>ol>li:focus-within .footnote-backref{opacity:1;transform:translateX(0);transition:none}.md-typeset .footnote>ol>li:hover .footnote-backref,.md-typeset .footnote>ol>li:target .footnote-backref{opacity:1;transform:translateX(0)}.md-typeset .footnote>ol>li>:first-child{margin-top:0}.md-typeset .footnote-ref{font-size:.75em;font-weight:700}html .md-typeset .footnote-ref{outline-offset:.1rem}.md-typeset [id^="fnref:"]:target>.footnote-ref{outline:auto}.md-typeset .footnote-backref{color:var(--md-typeset-a-color);display:inline-block;font-size:0;opacity:0;transform:translateX(.25rem);transition:color .25s,transform .25s .25s,opacity 125ms .25s;vertical-align:text-bottom}@media print{.md-typeset .footnote-backref{color:var(--md-typeset-a-color);opacity:1;transform:translateX(0)}}[dir=rtl] .md-typeset .footnote-backref{transform:translateX(-.25rem)}.md-typeset .footnote-backref:hover{color:var(--md-accent-fg-color)}.md-typeset .footnote-backref:before{background-color:currentcolor;content:"";display:inline-block;height:.8rem;-webkit-mask-image:var(--md-footnotes-icon);mask-image:var(--md-footnotes-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:.8rem}[dir=rtl] .md-typeset .footnote-backref:before svg{transform:scaleX(-1)}[dir=ltr] .md-typeset .headerlink{margin-left:.5rem}[dir=rtl] .md-typeset .headerlink{margin-right:.5rem}.md-typeset .headerlink{color:var(--md-default-fg-color--lighter);display:inline-block;opacity:0;transition:color .25s,opacity 125ms}@media print{.md-typeset .headerlink{display:none}}.md-typeset .headerlink:focus,.md-typeset :hover>.headerlink,.md-typeset :target>.headerlink{opacity:1;transition:color .25s,opacity 125ms}.md-typeset .headerlink:focus,.md-typeset .headerlink:hover,.md-typeset :target>.headerlink{color:var(--md-accent-fg-color)}.md-typeset :target{--md-scroll-margin:3.6rem;--md-scroll-offset:0rem;scroll-margin-top:calc(var(--md-scroll-margin) - var(--md-scroll-offset))}@media screen and (min-width:76.25em){.md-header--lifted~.md-container .md-typeset :target{--md-scroll-margin:6rem}}.md-typeset h1:target,.md-typeset h2:target,.md-typeset h3:target{--md-scroll-offset:0.2rem}.md-typeset h4:target{--md-scroll-offset:0.15rem}.md-typeset div.arithmatex{overflow:auto}@media screen and (max-width:44.984375em){.md-typeset div.arithmatex{margin:0 -.8rem}.md-typeset div.arithmatex>*{width:min-content}}.md-typeset div.arithmatex>*{margin-left:auto!important;margin-right:auto!important;padding:0 .8rem;touch-action:auto}.md-typeset div.arithmatex>* mjx-container{margin:0!important}.md-typeset div.arithmatex mjx-assistive-mml{height:0}.md-typeset del.critic{background-color:var(--md-typeset-del-color)}.md-typeset del.critic,.md-typeset ins.critic{-webkit-box-decoration-break:clone;box-decoration-break:clone}.md-typeset ins.critic{background-color:var(--md-typeset-ins-color)}.md-typeset .critic.comment{-webkit-box-decoration-break:clone;box-decoration-break:clone;color:var(--md-code-hl-comment-color)}.md-typeset .critic.comment:before{content:"/* "}.md-typeset .critic.comment:after{content:" */"}.md-typeset .critic.block{box-shadow:none;display:block;margin:1em 0;overflow:auto;padding-left:.8rem;padding-right:.8rem}.md-typeset .critic.block>:first-child{margin-top:.5em}.md-typeset .critic.block>:last-child{margin-bottom:.5em}:root{--md-details-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset details{display:flow-root;overflow:visible;padding-top:0}.md-typeset details[open]>summary:after{transform:rotate(90deg)}.md-typeset details:not([open]){box-shadow:none;padding-bottom:0}.md-typeset details:not([open])>summary{border-radius:.1rem}[dir=ltr] .md-typeset summary{padding-right:1.8rem}[dir=rtl] .md-typeset summary{padding-left:1.8rem}[dir=ltr] .md-typeset summary{border-top-left-radius:.1rem}[dir=ltr] .md-typeset summary,[dir=rtl] .md-typeset summary{border-top-right-radius:.1rem}[dir=rtl] .md-typeset summary{border-top-left-radius:.1rem}.md-typeset summary{cursor:pointer;display:block;min-height:1rem;overflow:hidden}.md-typeset summary.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-typeset summary:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}[dir=ltr] .md-typeset summary:after{right:.4rem}[dir=rtl] .md-typeset summary:after{left:.4rem}.md-typeset summary:after{background-color:currentcolor;content:"";height:1rem;-webkit-mask-image:var(--md-details-icon);mask-image:var(--md-details-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.625em;transform:rotate(0deg);transition:transform .25s;width:1rem}[dir=rtl] .md-typeset summary:after{transform:rotate(180deg)}.md-typeset summary::marker{display:none}.md-typeset summary::-webkit-details-marker{display:none}.md-typeset .emojione,.md-typeset .gemoji,.md-typeset .twemoji{--md-icon-size:1.125em;display:inline-flex;height:var(--md-icon-size);vertical-align:text-top}.md-typeset .emojione svg,.md-typeset .gemoji svg,.md-typeset .twemoji svg{fill:currentcolor;max-height:100%;width:var(--md-icon-size)}.md-typeset .lg,.md-typeset .xl,.md-typeset .xxl,.md-typeset .xxxl{vertical-align:text-bottom}.md-typeset .middle{vertical-align:middle}.md-typeset .lg{--md-icon-size:1.5em}.md-typeset .xl{--md-icon-size:2.25em}.md-typeset .xxl{--md-icon-size:3em}.md-typeset .xxxl{--md-icon-size:4em}.highlight .o,.highlight .ow{color:var(--md-code-hl-operator-color)}.highlight .p{color:var(--md-code-hl-punctuation-color)}.highlight .cpf,.highlight .l,.highlight .s,.highlight .s1,.highlight .s2,.highlight .sb,.highlight .sc,.highlight .si,.highlight .ss{color:var(--md-code-hl-string-color)}.highlight .cp,.highlight .se,.highlight .sh,.highlight .sr,.highlight .sx{color:var(--md-code-hl-special-color)}.highlight .il,.highlight .m,.highlight .mb,.highlight .mf,.highlight .mh,.highlight .mi,.highlight .mo{color:var(--md-code-hl-number-color)}.highlight .k,.highlight .kd,.highlight .kn,.highlight .kp,.highlight .kr,.highlight .kt{color:var(--md-code-hl-keyword-color)}.highlight .kc,.highlight .n{color:var(--md-code-hl-name-color)}.highlight .bp,.highlight .nb,.highlight .no{color:var(--md-code-hl-constant-color)}.highlight .nc,.highlight .ne,.highlight .nf,.highlight .nn{color:var(--md-code-hl-function-color)}.highlight .nd,.highlight .ni,.highlight .nl,.highlight .nt{color:var(--md-code-hl-keyword-color)}.highlight .c,.highlight .c1,.highlight .ch,.highlight .cm,.highlight .cs,.highlight .sd{color:var(--md-code-hl-comment-color)}.highlight .na,.highlight .nv,.highlight .vc,.highlight .vg,.highlight .vi{color:var(--md-code-hl-variable-color)}.highlight .ge,.highlight .gh,.highlight .go,.highlight .gp,.highlight .gr,.highlight .gs,.highlight .gt,.highlight .gu{color:var(--md-code-hl-generic-color)}.highlight .gd,.highlight .gi{border-radius:.1rem;margin:0 -.125em;padding:0 .125em}.highlight .gd{background-color:var(--md-typeset-del-color)}.highlight .gi{background-color:var(--md-typeset-ins-color)}.highlight .hll{background-color:var(--md-code-hl-color--light);box-shadow:2px 0 0 0 var(--md-code-hl-color) inset;display:block;margin:0 -1.1764705882em;padding:0 1.1764705882em}.highlight span.filename{background-color:var(--md-code-bg-color);border-bottom:.05rem solid var(--md-default-fg-color--lightest);border-top-left-radius:.1rem;border-top-right-radius:.1rem;display:flow-root;font-size:.85em;font-weight:700;margin-top:1em;padding:.6617647059em 1.1764705882em;position:relative}.highlight span.filename+pre{margin-top:0}.highlight span.filename+pre>code{border-top-left-radius:0;border-top-right-radius:0}.highlight [data-linenos]:before{background-color:var(--md-code-bg-color);box-shadow:-.05rem 0 var(--md-default-fg-color--lightest) inset;color:var(--md-default-fg-color--light);content:attr(data-linenos);float:left;left:-1.1764705882em;margin-left:-1.1764705882em;margin-right:1.1764705882em;padding-left:1.1764705882em;position:sticky;-webkit-user-select:none;user-select:none;z-index:3}.highlight code a[id]{position:absolute;visibility:hidden}.highlight code[data-md-copying]{display:initial}.highlight code[data-md-copying] .hll{display:contents}.highlight code[data-md-copying] .md-annotation{display:none}.highlighttable{display:flow-root}.highlighttable tbody,.highlighttable td{display:block;padding:0}.highlighttable tr{display:flex}.highlighttable pre{margin:0}.highlighttable th.filename{flex-grow:1;padding:0;text-align:left}.highlighttable th.filename span.filename{margin-top:0}.highlighttable .linenos{background-color:var(--md-code-bg-color);border-bottom-left-radius:.1rem;border-top-left-radius:.1rem;font-size:.85em;padding:.7720588235em 0 .7720588235em 1.1764705882em;-webkit-user-select:none;user-select:none}.highlighttable .linenodiv{box-shadow:-.05rem 0 var(--md-default-fg-color--lightest) inset}.highlighttable .linenodiv pre{color:var(--md-default-fg-color--light);text-align:right}.highlighttable .linenodiv span[class]{padding-right:.5882352941em}.highlighttable .code{flex:1;min-width:0}.linenodiv a{color:inherit}.md-typeset .highlighttable{direction:ltr;margin:1em 0}.md-typeset .highlighttable>tbody>tr>.code>div>pre>code{border-bottom-left-radius:0;border-top-left-radius:0}.md-typeset .highlight+.result{border:.05rem solid var(--md-code-bg-color);border-bottom-left-radius:.1rem;border-bottom-right-radius:.1rem;border-top-width:.1rem;margin-top:-1.125em;overflow:visible;padding:0 1em}.md-typeset .highlight+.result:after{clear:both;content:"";display:block}@media screen and (max-width:44.984375em){.md-content__inner>.highlight{margin:1em -.8rem}.md-content__inner>.highlight>.filename,.md-content__inner>.highlight>.highlighttable>tbody>tr>.code>div>pre>code,.md-content__inner>.highlight>.highlighttable>tbody>tr>.filename span.filename,.md-content__inner>.highlight>.highlighttable>tbody>tr>.linenos,.md-content__inner>.highlight>pre>code{border-radius:0}.md-content__inner>.highlight+.result{border-left-width:0;border-radius:0;border-right-width:0;margin-left:-.8rem;margin-right:-.8rem}}.md-typeset .keys kbd:after,.md-typeset .keys kbd:before{-moz-osx-font-smoothing:initial;-webkit-font-smoothing:initial;color:inherit;margin:0;position:relative}.md-typeset .keys span{color:var(--md-default-fg-color--light);padding:0 .2em}.md-typeset .keys .key-alt:before,.md-typeset .keys .key-left-alt:before,.md-typeset .keys .key-right-alt:before{content:"⎇";padding-right:.4em}.md-typeset .keys .key-command:before,.md-typeset .keys .key-left-command:before,.md-typeset .keys .key-right-command:before{content:"⌘";padding-right:.4em}.md-typeset .keys .key-control:before,.md-typeset .keys .key-left-control:before,.md-typeset .keys .key-right-control:before{content:"⌃";padding-right:.4em}.md-typeset .keys .key-left-meta:before,.md-typeset .keys .key-meta:before,.md-typeset .keys .key-right-meta:before{content:"◆";padding-right:.4em}.md-typeset .keys .key-left-option:before,.md-typeset .keys .key-option:before,.md-typeset .keys .key-right-option:before{content:"⌥";padding-right:.4em}.md-typeset .keys .key-left-shift:before,.md-typeset .keys .key-right-shift:before,.md-typeset .keys .key-shift:before{content:"⇧";padding-right:.4em}.md-typeset .keys .key-left-super:before,.md-typeset .keys .key-right-super:before,.md-typeset .keys .key-super:before{content:"❖";padding-right:.4em}.md-typeset .keys .key-left-windows:before,.md-typeset .keys .key-right-windows:before,.md-typeset .keys .key-windows:before{content:"⊞";padding-right:.4em}.md-typeset .keys .key-arrow-down:before{content:"↓";padding-right:.4em}.md-typeset .keys .key-arrow-left:before{content:"←";padding-right:.4em}.md-typeset .keys .key-arrow-right:before{content:"→";padding-right:.4em}.md-typeset .keys .key-arrow-up:before{content:"↑";padding-right:.4em}.md-typeset .keys .key-backspace:before{content:"⌫";padding-right:.4em}.md-typeset .keys .key-backtab:before{content:"⇤";padding-right:.4em}.md-typeset .keys .key-caps-lock:before{content:"⇪";padding-right:.4em}.md-typeset .keys .key-clear:before{content:"⌧";padding-right:.4em}.md-typeset .keys .key-context-menu:before{content:"☰";padding-right:.4em}.md-typeset .keys .key-delete:before{content:"⌦";padding-right:.4em}.md-typeset .keys .key-eject:before{content:"⏏";padding-right:.4em}.md-typeset .keys .key-end:before{content:"⤓";padding-right:.4em}.md-typeset .keys .key-escape:before{content:"⎋";padding-right:.4em}.md-typeset .keys .key-home:before{content:"⤒";padding-right:.4em}.md-typeset .keys .key-insert:before{content:"⎀";padding-right:.4em}.md-typeset .keys .key-page-down:before{content:"⇟";padding-right:.4em}.md-typeset .keys .key-page-up:before{content:"⇞";padding-right:.4em}.md-typeset .keys .key-print-screen:before{content:"⎙";padding-right:.4em}.md-typeset .keys .key-tab:after{content:"⇥";padding-left:.4em}.md-typeset .keys .key-num-enter:after{content:"⌤";padding-left:.4em}.md-typeset .keys .key-enter:after{content:"⏎";padding-left:.4em}:root{--md-tabbed-icon--prev:url('data:image/svg+xml;charset=utf-8,');--md-tabbed-icon--next:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .tabbed-set{border-radius:.1rem;display:flex;flex-flow:column wrap;margin:1em 0;position:relative}.md-typeset .tabbed-set>input{height:0;opacity:0;position:absolute;width:0}.md-typeset .tabbed-set>input:target{--md-scroll-offset:0.625em}.md-typeset .tabbed-set>input.focus-visible~.tabbed-labels:before{background-color:var(--md-accent-fg-color)}.md-typeset .tabbed-labels{-ms-overflow-style:none;box-shadow:0 -.05rem var(--md-default-fg-color--lightest) inset;display:flex;max-width:100%;overflow:auto;scrollbar-width:none}@media print{.md-typeset .tabbed-labels{display:contents}}@media screen{.js .md-typeset .tabbed-labels{position:relative}.js .md-typeset .tabbed-labels:before{background:var(--md-default-fg-color);bottom:0;content:"";display:block;height:2px;left:0;position:absolute;transform:translateX(var(--md-indicator-x));transition:width 225ms,background-color .25s,transform .25s;transition-timing-function:cubic-bezier(.4,0,.2,1);width:var(--md-indicator-width)}}.md-typeset .tabbed-labels::-webkit-scrollbar{display:none}.md-typeset .tabbed-labels>label{border-bottom:.1rem solid #0000;border-radius:.1rem .1rem 0 0;color:var(--md-default-fg-color--light);cursor:pointer;flex-shrink:0;font-size:.64rem;font-weight:700;padding:.78125em 1.25em .625em;scroll-margin-inline-start:1rem;transition:background-color .25s,color .25s;white-space:nowrap;width:auto}@media print{.md-typeset .tabbed-labels>label:first-child{order:1}.md-typeset .tabbed-labels>label:nth-child(2){order:2}.md-typeset .tabbed-labels>label:nth-child(3){order:3}.md-typeset .tabbed-labels>label:nth-child(4){order:4}.md-typeset .tabbed-labels>label:nth-child(5){order:5}.md-typeset .tabbed-labels>label:nth-child(6){order:6}.md-typeset .tabbed-labels>label:nth-child(7){order:7}.md-typeset .tabbed-labels>label:nth-child(8){order:8}.md-typeset .tabbed-labels>label:nth-child(9){order:9}.md-typeset .tabbed-labels>label:nth-child(10){order:10}.md-typeset .tabbed-labels>label:nth-child(11){order:11}.md-typeset .tabbed-labels>label:nth-child(12){order:12}.md-typeset .tabbed-labels>label:nth-child(13){order:13}.md-typeset .tabbed-labels>label:nth-child(14){order:14}.md-typeset .tabbed-labels>label:nth-child(15){order:15}.md-typeset .tabbed-labels>label:nth-child(16){order:16}.md-typeset .tabbed-labels>label:nth-child(17){order:17}.md-typeset .tabbed-labels>label:nth-child(18){order:18}.md-typeset .tabbed-labels>label:nth-child(19){order:19}.md-typeset .tabbed-labels>label:nth-child(20){order:20}}.md-typeset .tabbed-labels>label:hover{color:var(--md-default-fg-color)}.md-typeset .tabbed-labels>label>[href]:first-child{color:inherit}.md-typeset .tabbed-labels--linked>label{padding:0}.md-typeset .tabbed-labels--linked>label>a{display:block;padding:.78125em 1.25em .625em}.md-typeset .tabbed-content{width:100%}@media print{.md-typeset .tabbed-content{display:contents}}.md-typeset .tabbed-block{display:none}@media print{.md-typeset .tabbed-block{display:block}.md-typeset .tabbed-block:first-child{order:1}.md-typeset .tabbed-block:nth-child(2){order:2}.md-typeset .tabbed-block:nth-child(3){order:3}.md-typeset .tabbed-block:nth-child(4){order:4}.md-typeset .tabbed-block:nth-child(5){order:5}.md-typeset .tabbed-block:nth-child(6){order:6}.md-typeset .tabbed-block:nth-child(7){order:7}.md-typeset .tabbed-block:nth-child(8){order:8}.md-typeset .tabbed-block:nth-child(9){order:9}.md-typeset .tabbed-block:nth-child(10){order:10}.md-typeset .tabbed-block:nth-child(11){order:11}.md-typeset .tabbed-block:nth-child(12){order:12}.md-typeset .tabbed-block:nth-child(13){order:13}.md-typeset .tabbed-block:nth-child(14){order:14}.md-typeset .tabbed-block:nth-child(15){order:15}.md-typeset .tabbed-block:nth-child(16){order:16}.md-typeset .tabbed-block:nth-child(17){order:17}.md-typeset .tabbed-block:nth-child(18){order:18}.md-typeset .tabbed-block:nth-child(19){order:19}.md-typeset .tabbed-block:nth-child(20){order:20}}.md-typeset .tabbed-block>.highlight:first-child>pre,.md-typeset .tabbed-block>pre:first-child{margin:0}.md-typeset .tabbed-block>.highlight:first-child>pre>code,.md-typeset .tabbed-block>pre:first-child>code{border-top-left-radius:0;border-top-right-radius:0}.md-typeset .tabbed-block>.highlight:first-child>.filename{border-top-left-radius:0;border-top-right-radius:0;margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable{margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.filename span.filename,.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.linenos{border-top-left-radius:0;border-top-right-radius:0;margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.code>div>pre>code{border-top-left-radius:0;border-top-right-radius:0}.md-typeset .tabbed-block>.highlight:first-child+.result{margin-top:-.125em}.md-typeset .tabbed-block>.tabbed-set{margin:0}.md-typeset .tabbed-button{align-self:center;border-radius:100%;color:var(--md-default-fg-color--light);cursor:pointer;display:block;height:.9rem;margin-top:.1rem;pointer-events:auto;transition:background-color .25s;width:.9rem}.md-typeset .tabbed-button:hover{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-typeset .tabbed-button:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-tabbed-icon--prev);mask-image:var(--md-tabbed-icon--prev);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:background-color .25s,transform .25s;width:100%}.md-typeset .tabbed-control{background:linear-gradient(to right,var(--md-default-bg-color) 60%,#0000);display:flex;height:1.9rem;justify-content:start;pointer-events:none;position:absolute;transition:opacity 125ms;width:1.2rem}[dir=rtl] .md-typeset .tabbed-control{transform:rotate(180deg)}.md-typeset .tabbed-control[hidden]{opacity:0}.md-typeset .tabbed-control--next{background:linear-gradient(to left,var(--md-default-bg-color) 60%,#0000);justify-content:end;right:0}.md-typeset .tabbed-control--next .tabbed-button:after{-webkit-mask-image:var(--md-tabbed-icon--next);mask-image:var(--md-tabbed-icon--next)}@media screen and (max-width:44.984375em){[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels{padding-left:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels{padding-right:.8rem}.md-content__inner>.tabbed-set .tabbed-labels{margin:0 -.8rem;max-width:100vw;scroll-padding-inline-start:.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels:after{padding-right:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels:after{padding-left:.8rem}.md-content__inner>.tabbed-set .tabbed-labels:after{content:""}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{padding-left:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{padding-right:.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{margin-left:-.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{margin-right:-.8rem}.md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{width:2rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{padding-right:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{padding-left:.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{margin-right:-.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{margin-left:-.8rem}.md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{width:2rem}}@media screen{.md-typeset .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9){color:var(--md-default-fg-color)}.md-typeset .no-js .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.md-typeset .no-js .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.md-typeset .no-js .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.md-typeset .no-js .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.md-typeset .no-js .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.md-typeset .no-js .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.md-typeset .no-js .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.md-typeset .no-js .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.md-typeset .no-js .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.md-typeset .no-js .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.md-typeset .no-js .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.md-typeset .no-js .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.md-typeset .no-js .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.md-typeset .no-js .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.md-typeset .no-js .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.md-typeset .no-js .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.md-typeset .no-js .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.md-typeset .no-js .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.md-typeset .no-js .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.md-typeset .no-js .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9),.no-js .md-typeset .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.no-js .md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.no-js .md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.no-js .md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.no-js .md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.no-js .md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.no-js .md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.no-js .md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.no-js .md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.no-js .md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.no-js .md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.no-js .md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.no-js .md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.no-js .md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.no-js .md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.no-js .md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.no-js .md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.no-js .md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.no-js .md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.no-js .md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9){border-color:var(--md-default-fg-color)}}.md-typeset .tabbed-set>input:first-child.focus-visible~.tabbed-labels>:first-child,.md-typeset .tabbed-set>input:nth-child(10).focus-visible~.tabbed-labels>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11).focus-visible~.tabbed-labels>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12).focus-visible~.tabbed-labels>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13).focus-visible~.tabbed-labels>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14).focus-visible~.tabbed-labels>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15).focus-visible~.tabbed-labels>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16).focus-visible~.tabbed-labels>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17).focus-visible~.tabbed-labels>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18).focus-visible~.tabbed-labels>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19).focus-visible~.tabbed-labels>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2).focus-visible~.tabbed-labels>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20).focus-visible~.tabbed-labels>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3).focus-visible~.tabbed-labels>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4).focus-visible~.tabbed-labels>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5).focus-visible~.tabbed-labels>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6).focus-visible~.tabbed-labels>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7).focus-visible~.tabbed-labels>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8).focus-visible~.tabbed-labels>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9).focus-visible~.tabbed-labels>:nth-child(9){color:var(--md-accent-fg-color)}.md-typeset .tabbed-set>input:first-child:checked~.tabbed-content>:first-child,.md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-content>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-content>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-content>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-content>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-content>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-content>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-content>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-content>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-content>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-content>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-content>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-content>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-content>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-content>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-content>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-content>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-content>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-content>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-content>:nth-child(9){display:block}:root{--md-tasklist-icon:url('data:image/svg+xml;charset=utf-8,');--md-tasklist-icon--checked:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .task-list-item{list-style-type:none;position:relative}[dir=ltr] .md-typeset .task-list-item [type=checkbox]{left:-2em}[dir=rtl] .md-typeset .task-list-item [type=checkbox]{right:-2em}.md-typeset .task-list-item [type=checkbox]{position:absolute;top:.45em}.md-typeset .task-list-control [type=checkbox]{opacity:0;z-index:-1}[dir=ltr] .md-typeset .task-list-indicator:before{left:-1.5em}[dir=rtl] .md-typeset .task-list-indicator:before{right:-1.5em}.md-typeset .task-list-indicator:before{background-color:var(--md-default-fg-color--lightest);content:"";height:1.25em;-webkit-mask-image:var(--md-tasklist-icon);mask-image:var(--md-tasklist-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.15em;width:1.25em}.md-typeset [type=checkbox]:checked+.task-list-indicator:before{background-color:#00e676;-webkit-mask-image:var(--md-tasklist-icon--checked);mask-image:var(--md-tasklist-icon--checked)}:root>*{--md-mermaid-font-family:var(--md-text-font-family),sans-serif;--md-mermaid-edge-color:var(--md-code-fg-color);--md-mermaid-node-bg-color:var(--md-accent-fg-color--transparent);--md-mermaid-node-fg-color:var(--md-accent-fg-color);--md-mermaid-label-bg-color:var(--md-default-bg-color);--md-mermaid-label-fg-color:var(--md-code-fg-color);--md-mermaid-sequence-actor-bg-color:var(--md-mermaid-label-bg-color);--md-mermaid-sequence-actor-fg-color:var(--md-mermaid-label-fg-color);--md-mermaid-sequence-actor-border-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-actor-line-color:var(--md-default-fg-color--lighter);--md-mermaid-sequence-actorman-bg-color:var(--md-mermaid-label-bg-color);--md-mermaid-sequence-actorman-line-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-box-bg-color:var(--md-mermaid-node-bg-color);--md-mermaid-sequence-box-fg-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-label-bg-color:var(--md-mermaid-node-bg-color);--md-mermaid-sequence-label-fg-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-loop-bg-color:var(--md-mermaid-node-bg-color);--md-mermaid-sequence-loop-fg-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-loop-border-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-message-fg-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-message-line-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-note-bg-color:var(--md-mermaid-label-bg-color);--md-mermaid-sequence-note-fg-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-note-border-color:var(--md-mermaid-label-fg-color);--md-mermaid-sequence-number-bg-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-number-fg-color:var(--md-accent-bg-color)}.mermaid{line-height:normal;margin:1em 0}.md-typeset .grid{grid-gap:.4rem;display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,16rem),1fr));margin:1em 0}.md-typeset .grid.cards>ol,.md-typeset .grid.cards>ul{display:contents}.md-typeset .grid.cards>ol>li,.md-typeset .grid.cards>ul>li,.md-typeset .grid>.card{border:.05rem solid var(--md-default-fg-color--lightest);border-radius:.1rem;display:block;margin:0;padding:.8rem;transition:border .25s,box-shadow .25s}.md-typeset .grid.cards>ol>li:focus-within,.md-typeset .grid.cards>ol>li:hover,.md-typeset .grid.cards>ul>li:focus-within,.md-typeset .grid.cards>ul>li:hover,.md-typeset .grid>.card:focus-within,.md-typeset .grid>.card:hover{border-color:#0000;box-shadow:var(--md-shadow-z2)}.md-typeset .grid.cards>ol>li>hr,.md-typeset .grid.cards>ul>li>hr,.md-typeset .grid>.card>hr{margin-bottom:1em;margin-top:1em}.md-typeset .grid.cards>ol>li>:first-child,.md-typeset .grid.cards>ul>li>:first-child,.md-typeset .grid>.card>:first-child{margin-top:0}.md-typeset .grid.cards>ol>li>:last-child,.md-typeset .grid.cards>ul>li>:last-child,.md-typeset .grid>.card>:last-child{margin-bottom:0}.md-typeset .grid>*,.md-typeset .grid>.admonition,.md-typeset .grid>.highlight>*,.md-typeset .grid>.highlighttable,.md-typeset .grid>.md-typeset details,.md-typeset .grid>details,.md-typeset .grid>pre{margin-bottom:0;margin-top:0}.md-typeset .grid>.highlight>pre:only-child,.md-typeset .grid>.highlight>pre>code,.md-typeset .grid>.highlighttable,.md-typeset .grid>.highlighttable>tbody,.md-typeset .grid>.highlighttable>tbody>tr,.md-typeset .grid>.highlighttable>tbody>tr>.code,.md-typeset .grid>.highlighttable>tbody>tr>.code>.highlight,.md-typeset .grid>.highlighttable>tbody>tr>.code>.highlight>pre,.md-typeset .grid>.highlighttable>tbody>tr>.code>.highlight>pre>code{height:100%}.md-typeset .grid>.tabbed-set{margin-bottom:0;margin-top:0}@media screen and (min-width:45em){[dir=ltr] .md-typeset .inline{float:left}[dir=rtl] .md-typeset .inline{float:right}[dir=ltr] .md-typeset .inline{margin-right:.8rem}[dir=rtl] .md-typeset .inline{margin-left:.8rem}.md-typeset .inline{margin-bottom:.8rem;margin-top:0;width:11.7rem}[dir=ltr] .md-typeset .inline.end{float:right}[dir=rtl] .md-typeset .inline.end{float:left}[dir=ltr] .md-typeset .inline.end{margin-left:.8rem;margin-right:0}[dir=rtl] .md-typeset .inline.end{margin-left:0;margin-right:.8rem}} \ No newline at end of file diff --git a/assets/stylesheets/palette.ab4e12ef.min.css b/assets/stylesheets/palette.ab4e12ef.min.css new file mode 100644 index 00000000..75aaf842 --- /dev/null +++ b/assets/stylesheets/palette.ab4e12ef.min.css @@ -0,0 +1 @@ +@media screen{[data-md-color-scheme=slate]{--md-default-fg-color:hsla(var(--md-hue),15%,90%,0.82);--md-default-fg-color--light:hsla(var(--md-hue),15%,90%,0.56);--md-default-fg-color--lighter:hsla(var(--md-hue),15%,90%,0.32);--md-default-fg-color--lightest:hsla(var(--md-hue),15%,90%,0.12);--md-default-bg-color:hsla(var(--md-hue),15%,14%,1);--md-default-bg-color--light:hsla(var(--md-hue),15%,14%,0.54);--md-default-bg-color--lighter:hsla(var(--md-hue),15%,14%,0.26);--md-default-bg-color--lightest:hsla(var(--md-hue),15%,14%,0.07);--md-code-fg-color:hsla(var(--md-hue),18%,86%,0.82);--md-code-bg-color:hsla(var(--md-hue),15%,18%,1);--md-code-bg-color--light:hsla(var(--md-hue),15%,18%,0.9);--md-code-bg-color--lighter:hsla(var(--md-hue),15%,18%,0.54);--md-code-hl-color:#2977ff;--md-code-hl-color--light:#2977ff1a;--md-code-hl-number-color:#e6695b;--md-code-hl-special-color:#f06090;--md-code-hl-function-color:#c973d9;--md-code-hl-constant-color:#9383e2;--md-code-hl-keyword-color:#6791e0;--md-code-hl-string-color:#2fb170;--md-code-hl-name-color:var(--md-code-fg-color);--md-code-hl-operator-color:var(--md-default-fg-color--light);--md-code-hl-punctuation-color:var(--md-default-fg-color--light);--md-code-hl-comment-color:var(--md-default-fg-color--light);--md-code-hl-generic-color:var(--md-default-fg-color--light);--md-code-hl-variable-color:var(--md-default-fg-color--light);--md-typeset-color:var(--md-default-fg-color);--md-typeset-a-color:var(--md-primary-fg-color);--md-typeset-kbd-color:hsla(var(--md-hue),15%,90%,0.12);--md-typeset-kbd-accent-color:hsla(var(--md-hue),15%,90%,0.2);--md-typeset-kbd-border-color:hsla(var(--md-hue),15%,14%,1);--md-typeset-mark-color:#4287ff4d;--md-typeset-table-color:hsla(var(--md-hue),15%,95%,0.12);--md-typeset-table-color--light:hsla(var(--md-hue),15%,95%,0.035);--md-admonition-fg-color:var(--md-default-fg-color);--md-admonition-bg-color:var(--md-default-bg-color);--md-footer-bg-color:hsla(var(--md-hue),15%,10%,0.87);--md-footer-bg-color--dark:hsla(var(--md-hue),15%,8%,1);--md-shadow-z1:0 0.2rem 0.5rem #0000000d,0 0 0.05rem #0000001a;--md-shadow-z2:0 0.2rem 0.5rem #00000040,0 0 0.05rem #00000040;--md-shadow-z3:0 0.2rem 0.5rem #0006,0 0 0.05rem #00000059;color-scheme:dark}[data-md-color-scheme=slate] img[src$="#gh-light-mode-only"],[data-md-color-scheme=slate] img[src$="#only-light"]{display:none}[data-md-color-scheme=slate][data-md-color-primary=pink]{--md-typeset-a-color:#ed5487}[data-md-color-scheme=slate][data-md-color-primary=purple]{--md-typeset-a-color:#c46fd3}[data-md-color-scheme=slate][data-md-color-primary=deep-purple]{--md-typeset-a-color:#a47bea}[data-md-color-scheme=slate][data-md-color-primary=indigo]{--md-typeset-a-color:#5488e8}[data-md-color-scheme=slate][data-md-color-primary=teal]{--md-typeset-a-color:#00ccb8}[data-md-color-scheme=slate][data-md-color-primary=green]{--md-typeset-a-color:#71c174}[data-md-color-scheme=slate][data-md-color-primary=deep-orange]{--md-typeset-a-color:#ff764d}[data-md-color-scheme=slate][data-md-color-primary=brown]{--md-typeset-a-color:#c1775c}[data-md-color-scheme=slate][data-md-color-primary=black],[data-md-color-scheme=slate][data-md-color-primary=blue-grey],[data-md-color-scheme=slate][data-md-color-primary=grey],[data-md-color-scheme=slate][data-md-color-primary=white]{--md-typeset-a-color:#5e8bde}[data-md-color-switching] *,[data-md-color-switching] :after,[data-md-color-switching] :before{transition-duration:0ms!important}}[data-md-color-accent=red]{--md-accent-fg-color:#ff1947;--md-accent-fg-color--transparent:#ff19471a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=pink]{--md-accent-fg-color:#f50056;--md-accent-fg-color--transparent:#f500561a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=purple]{--md-accent-fg-color:#df41fb;--md-accent-fg-color--transparent:#df41fb1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=deep-purple]{--md-accent-fg-color:#7c4dff;--md-accent-fg-color--transparent:#7c4dff1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=indigo]{--md-accent-fg-color:#526cfe;--md-accent-fg-color--transparent:#526cfe1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=blue]{--md-accent-fg-color:#4287ff;--md-accent-fg-color--transparent:#4287ff1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=light-blue]{--md-accent-fg-color:#0091eb;--md-accent-fg-color--transparent:#0091eb1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=cyan]{--md-accent-fg-color:#00bad6;--md-accent-fg-color--transparent:#00bad61a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=teal]{--md-accent-fg-color:#00bda4;--md-accent-fg-color--transparent:#00bda41a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=green]{--md-accent-fg-color:#00c753;--md-accent-fg-color--transparent:#00c7531a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=light-green]{--md-accent-fg-color:#63de17;--md-accent-fg-color--transparent:#63de171a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=lime]{--md-accent-fg-color:#b0eb00;--md-accent-fg-color--transparent:#b0eb001a;--md-accent-bg-color:#000000de;--md-accent-bg-color--light:#0000008a}[data-md-color-accent=yellow]{--md-accent-fg-color:#ffd500;--md-accent-fg-color--transparent:#ffd5001a;--md-accent-bg-color:#000000de;--md-accent-bg-color--light:#0000008a}[data-md-color-accent=amber]{--md-accent-fg-color:#fa0;--md-accent-fg-color--transparent:#ffaa001a;--md-accent-bg-color:#000000de;--md-accent-bg-color--light:#0000008a}[data-md-color-accent=orange]{--md-accent-fg-color:#ff9100;--md-accent-fg-color--transparent:#ff91001a;--md-accent-bg-color:#000000de;--md-accent-bg-color--light:#0000008a}[data-md-color-accent=deep-orange]{--md-accent-fg-color:#ff6e42;--md-accent-fg-color--transparent:#ff6e421a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-primary=red]{--md-primary-fg-color:#ef5552;--md-primary-fg-color--light:#e57171;--md-primary-fg-color--dark:#e53734;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=pink]{--md-primary-fg-color:#e92063;--md-primary-fg-color--light:#ec417a;--md-primary-fg-color--dark:#c3185d;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=purple]{--md-primary-fg-color:#ab47bd;--md-primary-fg-color--light:#bb69c9;--md-primary-fg-color--dark:#8c24a8;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=deep-purple]{--md-primary-fg-color:#7e56c2;--md-primary-fg-color--light:#9574cd;--md-primary-fg-color--dark:#673ab6;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=indigo]{--md-primary-fg-color:#4051b5;--md-primary-fg-color--light:#5d6cc0;--md-primary-fg-color--dark:#303fa1;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=blue]{--md-primary-fg-color:#2094f3;--md-primary-fg-color--light:#42a5f5;--md-primary-fg-color--dark:#1975d2;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=light-blue]{--md-primary-fg-color:#02a6f2;--md-primary-fg-color--light:#28b5f6;--md-primary-fg-color--dark:#0287cf;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=cyan]{--md-primary-fg-color:#00bdd6;--md-primary-fg-color--light:#25c5da;--md-primary-fg-color--dark:#0097a8;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=teal]{--md-primary-fg-color:#009485;--md-primary-fg-color--light:#26a699;--md-primary-fg-color--dark:#007a6c;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=green]{--md-primary-fg-color:#4cae4f;--md-primary-fg-color--light:#68bb6c;--md-primary-fg-color--dark:#398e3d;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=light-green]{--md-primary-fg-color:#8bc34b;--md-primary-fg-color--light:#9ccc66;--md-primary-fg-color--dark:#689f38;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=lime]{--md-primary-fg-color:#cbdc38;--md-primary-fg-color--light:#d3e156;--md-primary-fg-color--dark:#b0b52c;--md-primary-bg-color:#000000de;--md-primary-bg-color--light:#0000008a}[data-md-color-primary=yellow]{--md-primary-fg-color:#ffec3d;--md-primary-fg-color--light:#ffee57;--md-primary-fg-color--dark:#fbc02d;--md-primary-bg-color:#000000de;--md-primary-bg-color--light:#0000008a}[data-md-color-primary=amber]{--md-primary-fg-color:#ffc105;--md-primary-fg-color--light:#ffc929;--md-primary-fg-color--dark:#ffa200;--md-primary-bg-color:#000000de;--md-primary-bg-color--light:#0000008a}[data-md-color-primary=orange]{--md-primary-fg-color:#ffa724;--md-primary-fg-color--light:#ffa724;--md-primary-fg-color--dark:#fa8900;--md-primary-bg-color:#000000de;--md-primary-bg-color--light:#0000008a}[data-md-color-primary=deep-orange]{--md-primary-fg-color:#ff6e42;--md-primary-fg-color--light:#ff8a66;--md-primary-fg-color--dark:#f4511f;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=brown]{--md-primary-fg-color:#795649;--md-primary-fg-color--light:#8d6e62;--md-primary-fg-color--dark:#5d4037;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=grey]{--md-primary-fg-color:#757575;--md-primary-fg-color--light:#9e9e9e;--md-primary-fg-color--dark:#616161;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3;--md-typeset-a-color:#4051b5}[data-md-color-primary=blue-grey]{--md-primary-fg-color:#546d78;--md-primary-fg-color--light:#607c8a;--md-primary-fg-color--dark:#455a63;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3;--md-typeset-a-color:#4051b5}[data-md-color-primary=light-green]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#72ad2e}[data-md-color-primary=lime]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#8b990a}[data-md-color-primary=yellow]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#b8a500}[data-md-color-primary=amber]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#d19d00}[data-md-color-primary=orange]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#e68a00}[data-md-color-primary=white]{--md-primary-fg-color:hsla(var(--md-hue),0%,100%,1);--md-primary-fg-color--light:hsla(var(--md-hue),0%,100%,0.7);--md-primary-fg-color--dark:hsla(var(--md-hue),0%,0%,0.07);--md-primary-bg-color:hsla(var(--md-hue),0%,0%,0.87);--md-primary-bg-color--light:hsla(var(--md-hue),0%,0%,0.54);--md-typeset-a-color:#4051b5}[data-md-color-primary=white] .md-button{color:var(--md-typeset-a-color)}[data-md-color-primary=white] .md-button--primary{background-color:var(--md-typeset-a-color);border-color:var(--md-typeset-a-color);color:hsla(var(--md-hue),0%,100%,1)}@media screen and (min-width:60em){[data-md-color-primary=white] .md-search__form{background-color:hsla(var(--md-hue),0%,0%,.07)}[data-md-color-primary=white] .md-search__form:hover{background-color:hsla(var(--md-hue),0%,0%,.32)}[data-md-color-primary=white] .md-search__input+.md-search__icon{color:hsla(var(--md-hue),0%,0%,.87)}}@media screen and (min-width:76.25em){[data-md-color-primary=white] .md-tabs{border-bottom:.05rem solid #00000012}}[data-md-color-primary=black]{--md-primary-fg-color:hsla(var(--md-hue),15%,9%,1);--md-primary-fg-color--light:hsla(var(--md-hue),15%,9%,0.54);--md-primary-fg-color--dark:hsla(var(--md-hue),15%,9%,1);--md-primary-bg-color:hsla(var(--md-hue),15%,100%,1);--md-primary-bg-color--light:hsla(var(--md-hue),15%,100%,0.7);--md-typeset-a-color:#4051b5}[data-md-color-primary=black] .md-button{color:var(--md-typeset-a-color)}[data-md-color-primary=black] .md-button--primary{background-color:var(--md-typeset-a-color);border-color:var(--md-typeset-a-color);color:hsla(var(--md-hue),0%,100%,1)}[data-md-color-primary=black] .md-header{background-color:hsla(var(--md-hue),15%,9%,1)}@media screen and (max-width:59.984375em){[data-md-color-primary=black] .md-nav__source{background-color:hsla(var(--md-hue),15%,11%,.87)}}@media screen and (max-width:76.234375em){html [data-md-color-primary=black] .md-nav--primary .md-nav__title[for=__drawer]{background-color:hsla(var(--md-hue),15%,9%,1)}}@media screen and (min-width:76.25em){[data-md-color-primary=black] .md-tabs{background-color:hsla(var(--md-hue),15%,9%,1)}} \ No newline at end of file diff --git a/governance/alternate-policy/index.html b/governance/alternate-policy/index.html new file mode 100644 index 00000000..927fbe84 --- /dev/null +++ b/governance/alternate-policy/index.html @@ -0,0 +1,4226 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Alternate Policy - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

TAC Alternate Policy

+

A TAC voting member may designate an alternate for a specific meeting, and must notify the chair in advance of the meeting. The TAC voting member is responsible for ensuring that the named alternate has enough information to represent the TAC voting member in all matters that will be covered in the meeting. The named alternate will participate in any votes that occur during the meeting for which they were named an alternate, and their vote will count as if it were cast by the TAC voting member.

+
+

Warning

+

If a TAC voting member regularly names an alternate and

+
    +
  • is a TAC Premier Sponsor Representative, then that TAC voting member should consider whether they should replace themselves with the alternate, or
  • +
  • is a TAC "At Large" Representative, then that TAC voting member should consider whether they should resign.
  • +
+
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/governance/antitrust/index.html b/governance/antitrust/index.html new file mode 100644 index 00000000..53d57391 --- /dev/null +++ b/governance/antitrust/index.html @@ -0,0 +1,4210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Antitrust Policy - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Antitrust Policy

+ +

The LF Europe Antitrust Policy listed at http://lfeurope.be/policies will apply for all Collaborators in the Project.

+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/governance/archiving-inactive-repositories/index.html b/governance/archiving-inactive-repositories/index.html new file mode 100644 index 00000000..f004abdf --- /dev/null +++ b/governance/archiving-inactive-repositories/index.html @@ -0,0 +1,4222 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Inactive Repositories - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Archiving Inactive Repositories

+

OpenWallet Foundation very much appreciates the contributions of the community; however, it is important to archive source repositories that have become inactive in order to ensure that others in the community are not using code or reporting issues on a repository that is not being maintained.

+

Any repository that has not had a release for 12 months or that has had no commits for 6 months may be archived.

+

Projects will be notified via a PR in the appropriate repository, as well as a notice in the project appropriate Discord channel and mailing list, if they exist.

+

Generally speaking if the project's maintainers request to keep the repository active, the request will be honored. However if the repository has a lot of out of date dependencies, particulaly ones relating to security vulnerabilites, this request may not be honored.

+

A request by the project's maintainers to un-archive a repository for the purposes of active contribution will be honored, unless the project is in an emeritus stage. In those cases the project lifecycle issues will need to be resolved first.

+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/governance/charter/index.html b/governance/charter/index.html new file mode 100644 index 00000000..d9cacf5a --- /dev/null +++ b/governance/charter/index.html @@ -0,0 +1,4425 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Charter - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

OpenWallet Foundation Charter

+

Exhibit B

+

The OpenWallet Foundation Charter

+

Linux Foundation Europe

+

Effective May 22, 2023

+ +
    +
  1. +

    Mission and Scope of the OpenWallet Foundation.

    +

    The purpose of the OpenWallet Foundation (the “OWF”) is to support various open source, open data and/or other open projects relating to or supporting development of digital wallets, including infrastructure and support initiatives related thereto (each such project, a “Technical Project”) , in accordance with the provisions of this Charter. The governance of each Technical Project is as set forth in the charter for that Technical Project.

    +

    The OWF aims to enable entities to transact securely, and in a privacy enhancing fashion, in- person and on-line where attributes stored in, and managed by, the wallet. The OWF will:

    +
      +
    • develop and maintain open source code for wallets to enable and ensure wallet interoperability,
    • +
    • advocate for the adoption of the interoperable digital wallet technology, and
    • +
    • collaborate with Standards Development Organizations (SDOs) in the development and proliferation of open standards related to digital wallets
    • +
    +

    The OWF will not publish a publicly available wallet (including into any application stores).

    +

    The OWF supports the Technical Projects. The OWF operates under the guidance of the Governing Board of the OWF (the “Governing Board”) and Linux Foundation Europe (the “LFEU”) as may be consistent with Linux Foundation Europe’s tax-exempt status.

    +

    The Governing Board manages the OWF. The Governing Board may establish other committees and other working groups (collectively, and including the Technical Advisory Council, “Committees”) which will report to the Governing Board.

    +
  2. +
  3. +

    Sponsorship.

    +
      +
    1. The OWF will be composed of Premier, General and Associate Sponsors (each, a “Sponsor” and, collectively, the “Sponsors”) in Good Standing. All Sponsors must be current Sponsors of LFEU (at any level) to participate in the OWF as a Sponsor. All sponsors in the OWF, enjoy the privileges and undertake the obligations described in this Charter, as from time-to-time amended by the Governing Board, with the approval of LFEU. During the term of their sponsorship, all Participants will comply with all such policies as the LFEU Board of Directors and/or the OWF may adopt with notice to Sponsors.
    2. +
    3. Premier Sponsors will be entitled to appoint a representative to the Governing Board and any Committee.
    4. +
    5. General Sponsors, acting as a class, will be entitled to annually elect one representative to the Governing Board for every ten General Sponsors, up to a maximum of three total representatives, provided that there will always be at least one General Sponsor representative, even if there are less than ten General Sponsors. The Governing Board determines the General Sponsor representative election process.
    6. +
    7. The Associate Sponsor category of sponsorship is limited to Associate Sponsors of LFEU. The Governing Board may set additional criteria for sponsoring the OWF as an Associate Sponsor. If the Associate Sponsor is itself a membership or participation organization, Associate Sponsorship in the OWF does not confer any privileges or rights to the members or participants of the Associate Sponsor.
    8. +
    9. Sponsors will be entitled to:
        +
      1. participate in OWF general meetings, initiatives, events and any other activities; and
      2. +
      3. identify themselves as sponsors of the OWF supporting the OWF community.
      4. +
      +
    10. +
    +
  4. +
  5. +

    Governing Board

    +
      +
    1. +

      The Governing Board voting members will consist of:

      +
        +
      1. one representative appointed by each Premier Sponsor;
      2. +
      3. the TAC Representative (as defined below), or, in the absence of a chair and with the approval of the Governing Board, any active contributor to a Technical Project so designated by the TAC (such chair or designee the “TAC Representative”); and
      4. +
      5. the elected General Sponsor representative or representatives.
      6. +
      +
    2. +
    3. +

      The Governing Board will also include nonvoting members consisting of the GAC Representative (defined in Section 4) and Associate Representative.

      +
        +
      1. The Associate Representative will be chosen based on their efforts and potential to advance the OWF mission. The Associate Representative will be selected by the Governing Board voting representatives through a process determined by the Governing Board.
      2. +
      +
    4. +
    5. +

      Only one Sponsor that is part of a group of Related Companies (as defined in Section 7) may appoint, or nominate for a sponsorship class election, a representative on the Governing Board. No single Sponsor, company or set of Related Companies will be entitled to: (i) appoint or nominate for sponsorship class election more than one representative for the Governing Board, or (ii) have more than two representatives on the Governing Board.

      +
        +
      1. The only path to two representatives from the same group of Related Companies that will be acceptable will be for one Sponsor to appoint or nominate a representative to the Governing Board and have another of its employees, or an employee of one of its Related Companies, serve as the TAC Representative on the Governing Board.
      2. +
      +
    6. +
    7. +

      Conduct of Meetings

      +
        +
      1. Governing Board meetings will be limited to the Governing Board +representatives, the Outreach Committee Chair, invited guests and OWF staff.
      2. +
      3. Governing Board meetings follow the requirements for quorum and voting outlined in this Charter. The Governing Board may decide whether to allow named representatives (one per Sponsor per Governing Board and per Committee) to attend as an alternate.
      4. +
      5. The Governing Board meetings will be private unless decided otherwise by the Governing Board. The Governing Board may invite guests to participate in consideration of specific Governing Board topics (but such guests may not participate in any vote on any matter before the Governing Board).
      6. +
      +
    8. +
    9. +

      Officers

      +
        +
      1. The officers (“Officers”) of the OWF as of the first meeting of the Governing Board will be a Chairperson (“Chair”) and a Treasurer. Additional Officer positions may be created by the Governing Board.
      2. +
      3. The Chair will preside over meetings of the Governing Board, manage any day-to-day operational decisions, and will submit minutes for Governing Board approval.
      4. +
      5. The Treasurer will assist in the preparation of budgets for Governing Board approval, monitor expenses against the budget and authorize expenditures approved in the budget.
      6. +
      +
    10. +
    11. +

      The Governing Board will be responsible for overall oversight of the OWF, including:

      +
        +
      1. approve a budget directing the use of funds raised by the OWF from all sources of sponsorship or other revenue, including to pay for the hiring of OWF leadership and staff;
      2. +
      3. vet and select a qualified leadership team to run the day-to-day management activities of the organization and evaluate the performance of the team;
      4. +
      5. provide feedback and input to the OWF leadership team responsible for planning and managing the day-to-day operation of the OWF;
      6. +
      7. maintain, if desired, a guiding principles document;
      8. +
      9. nominate and elect Officers of the OWF;
      10. +
      11. supervise and support the leadership team on OWF business and community outreach matters;
      12. +
      13. work with the LFEU on any legal matters that arise;
      14. +
      15. adopt and maintain policies or rules and procedures for the OWF (subject to LFEU’s approval);
      16. +
      17. establish advisory bodies, committees, programs or councils to resolve any particular matter or in support of the mission of the OWF and/or its Technical Projects including in support of end-users and ambassadors for the project any Technical Project;
      18. +
      19. establish any OWF conformance programs for its trademarks and solicit input (including testing tools) if deemed necessary from the applicable oversight body of any Technical Project for defining and administering any programs related to conformance with such Technical Project (each, a “Conformance Program”);
      20. +
      21. publish use cases, user stories, websites and priorities to help inform the ecosystem and technical community;
      22. +
      23. approve procedures for the nomination and election of any representative of the General Sponsors to the Governing Board and any Officer or other positions created by the Governing Board; and
      24. +
      25. vote on all decisions or matters coming before the Governing Board.
      26. +
      +
    12. +
    +
  6. +
  7. +

    Government Advisory Council

    +
      +
    1. The Government Advisory Council (the “GAC”) will provide the OWF advice from government entities approved to participate by the Governing Board. Members of the GAC must be national governments, multinational governmental organizations and treaty organizations, or public authorities. Each may appoint one representative and one alternate representative to the GAC. There are no fees to participate in the GAC.
    2. +
    3. The GAC will provide advice to OWF on issues of public policy, and especially where there may be an interaction between OWF's activities and national policies, laws or international agreements.
    4. +
    5. The Governing Board may appoint a chairperson of the GAC or delegate responsibility for selecting a chairperson to the GAC. The GAC chairperson or another person chosen by the GAC chairperson will serve as the “GAC Representative” responsible for reporting progress back to the Governing Board and interfacing with the TAC. The GAC Representative may attend meetings of the Governing Board and TAC as a non-voting member.
    6. +
    +
  8. +
  9. +

    Technical Advisory Council

    +
      +
    1. +

      The role of the TAC is to facilitate communication and collaboration among the Technical Projects. The TAC will be responsible for:

      +
        +
      1. maintaining an overall strategic vision for technical collaboration and coordinating collaboration among Technical Projects, including development of an overall technical vision for the community;
      2. +
      3. making recommendations to the Budget Committee of resource priorities for Technical Projects;
      4. +
      5. electing annually a chairperson to preside over meetings, set the agenda for meetings, ensure meeting minutes are taken and who will also serve on the Governing Board as the TAC’s representative (the “TAC Representative”);
      6. +
      7. creating, maintaining and amending project lifecycle procedures and processes, deciding where Technical Projects fall within that lifecycle;
      8. +
      9. determining when a technical project should be admitted as a Technical Project or any Technical Project should be considered a TAC Project; and
      10. +
      11. such other matters related to the technical role of the TAC as may be communicated to the TAC by the Governing Board.
      12. +
      +
    2. +
    3. +

      The voting members of the TAC consist of:

      +
        +
      1. one representative appointed by each Premier Sponsor;
      2. +
      3. up to two “at large” representatives appointed by vote of the TAC; and
      4. +
      5. one representative appointed by the technical oversight body (e.g., a technical steering committee) of each TAC Project (as defined herein).
      6. +
      +
    4. +
    5. +

      TAC meetings are intended to be open to observe by Sponsors, contributors to any TAC Project and others in the general public interested in the OpenWallet Foundation. The TAC may decide whether to allow named representatives (one per voting member) to attend as an alternate.

      +
    6. +
    7. At the start of the OWF, “TAC Projects” are those Technical Projects listed as having voting representatives on the TAC on the Directed Fund’s web site. Thereafter, any Technical Project can become a TAC Project through the approval of the Technical Project’s technical oversight body and the TAC (by a two-third’s vote). The TAC may approve and modify a project lifecycle policy that will address the incubation, archival and other stages of TAC Projects.
    8. +
    9. The TAC representatives will elect a chair to preside over meetings, ensure minutes are taken and drive the TAC agenda with input from the TAC representatives.
    10. +
    +
  10. +
  11. +

    Voting

    +
      +
    1. Quorum for Governing Board and Committee meetings will require at least fifty percent of the voting representatives. If advance notice of the meeting has been given per normal means and timing, the Governing Board may continue to meet even if quorum is not met, but will be prevented from making any decisions at the meeting.
    2. +
    3. Ideally decisions will be made based on consensus. If, however, any decision requires a vote to move forward, the representatives of the Governing Board or Committee, as applicable, will vote on a one vote per voting representative basis.
    4. +
    5. Except as provided in Section 14.a. or elsewhere in this Charter, decisions by vote at a meeting will require a simple majority vote, provided quorum is met. Except as provided in Section 14.a. or elsewhere in this Charter, decisions by electronic vote without a meeting will require a majority of all voting representatives.
    6. +
    7. In the event of a tied vote with respect to an action that cannot be resolved by the Governing Board, the Chair may refer the matter to the LFEU for assistance in reaching a decision. If there is a tied vote in any Committee that cannot be resolved, the matter may be referred to the Governing Board.
    8. +
    +
  12. +
  13. +

    Subsidiaries and Related Companies

    +
      +
    1. +

      Definitions:

      +
        +
      1. “Subsidiaries” means any entity in which a Sponsor owns, directly or indirectly, more than fifty percent of the voting securities or participation interests of the entity in question;
      2. +
      3. “Related Company” means any entity which controls or is controlled by a Sponsor or which, together with a Sponsor, is under the common control of a third party, in each case where such control results from ownership, either directly or indirectly, of more than fifty percent of the voting securities or participation interests of the entity in question; and
      4. +
      5. “Related Companies” are entities that are each a Related Company of a Sponsor.
      6. +
      +
    2. +
    3. +

      Only the legal entity which has executed a Project Sponsorship Agreement and its Subsidiaries will be entitled to enjoy the rights and privileges of such sponsorship; provided, however, that such Sponsor and its Subsidiaries will be treated together as a single Sponsor.

      +
    4. +
    5. If a Sponsor is itself a foundation, association, consortium, open source project, membership organization, participation organization, user group or other entity that has members or sponsors, then the rights and privileges granted to such Sponsor will extend only to the employee-representatives of such Sponsor, and not to its members or sponsors, unless otherwise approved by the Governing Board in a specific case.
    6. +
    7. OWF sponsorship is non-transferable, non-salable and non-assignable, except a Sponsor may transfer its current sponsorship privileges and obligations to a successor of substantially all of its business or assets, whether by merger, sale or otherwise; provided that the transferee agrees to be bound by this Charter and the Bylaws and policies required by LFEU sponsorship.
    8. +
    +
  14. +
  15. +

    Good Standing

    +
      +
    1. Linux Foundation Europe’s Good Standing Policy is available at https://linuxfoundation.eu/policies and will apply to all Sponsors of this OWF.
    2. +
    +
  16. +
  17. +

    Trademarks

    +
      +
    1. Any trademarks relating to the OWF or any Technical Project, including without limitation any mark relating to any conformance program, must be transferred to and held by LFEU or an entity in LFEU’s control and available for use pursuant to LFEU’s trademark usage policy, available at https://linuxfoundation.eu/policies.
    2. +
    +
  18. +
  19. +

    Antitrust Guidelines

    +
      +
    1. All Sponsors must abide by Linux Foundation Europe’s Antitrust Policy available at https://linuxfoundation.eu/policies.
    2. +
    3. All Sponsors must encourage open participation from any organization able to meet the sponsorship requirements, regardless of competitive interests. Put another way, the Governing Board will not seek to exclude any Sponsor based on any criteria, requirements or reasons other than those that are reasonable and applied on a non- discriminatory basis to all Sponsors.
    4. +
    +
  20. +
  21. +

    Budget

    +
      +
    1. The Governing Board will approve an annual budget and never commit to spend in excess of funds raised. The budget and the purposes to which it is applied must be consistent with both (a) the non-profit and tax-exempt mission of LFEU and (b) the goals of any Technical Project.
    2. +
    3. LFEU will provide the Governing Board with regular reports of spend levels against the budget. Under no circumstances will LFEU have any expectation or obligation to undertake an action on behalf of the OWF or otherwise related to the OWF that is not covered in full by funds raised by the OWF.
    4. +
    5. In the event an unbudgeted or otherwise unfunded obligation arises related to the OWF, LFEU will coordinate with the Governing Board to address gap funding requirements.
    6. +
    +
  22. +
  23. +

    General & Administrative Expenses

    +
      +
    1. LFEU will have custody of and final authority over the usage of any fees, funds, and other cash receipts.
    2. +
    3. A General & Administrative (G&A) fee will be applied by LFEU to funds raised to cover sponsorship records, finance, accounting, and human resources operations. The G&A fee will be 9% of the OWF’s first EUR 1,000,000 of gross receipts each year and 6% of the OWF’s gross receipts each year over EUR 1,000,000.
    4. +
    +
  24. +
  25. +

    General Rules and Operations.

    +

    The OWF activities must:

    +
      +
    1. engage in the work of the project in a professional manner consistent with maintaining a cohesive community, while also maintaining the goodwill and esteem of LFEU in the open source community;
    2. +
    3. respect the rights of all trademark owners, including any branding and usage guidelines;
    4. +
    5. engage or coordinate with LFEU on all outreach, website and marketing activities regarding the OWF or on behalf of any Technical Project that invoke or associate the name of any Technical Project or LFEU; and
    6. +
    7. operate under such rules and procedures as may be approved by the Governing Board and confirmed by LFEU.
    8. +
    +
  26. +
  27. +

    Amendments

    +
      +
    1. This Charter may be amended by a two-thirds vote of the entire Governing Board, subject to approval by LFEU.
    2. +
    +
  28. +
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/governance/code-of-conduct/index.html b/governance/code-of-conduct/index.html new file mode 100644 index 00000000..d254c0bd --- /dev/null +++ b/governance/code-of-conduct/index.html @@ -0,0 +1,4210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Code of Conduct - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Code of Conduct

+ +

The TAC may adopt a code of conduct (“CoC”) for the Project, which is subject to approval by LF Europe. In the event that a Project-specific CoC has not been approved, the LF Europe Code of Conduct listed at http://lfeurope.be/policies will apply for all Collaborators in the Project.

+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/governance/common-repository-structure/index.html b/governance/common-repository-structure/index.html new file mode 100644 index 00000000..73c920d3 --- /dev/null +++ b/governance/common-repository-structure/index.html @@ -0,0 +1,4433 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Common Repository Structure - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Common Repository Structure

+

OpenWallet Foundation projects are required to maintain a standard set of files in each repository. This document describes the required and recommended files.

+

Required Files with Specified Content

+

Repositories MUST have these files with the specific content in the linked files, or a file with a link to the specified content with minimal exposition. These files MUST be at the root of the repository.

+
    +
  • +

    LICENSE

    +
    +

    Info

    +

    All code within the OpenWallet Foundation should be licensed under Apache 2.0. Exceptions can be made by the OpenWallet Foundation Governing Board.

    +
    +
  • +
  • +

    CODE_OF_CONDUCT.md

    +
  • +
  • SECURITY.md
  • +
+

Required Files with Variable Content

+

Repositories MUST have these files. Named files MUST be at the root of the repository, and may have format suffixes such as .md, .rst, or .txt.

+
    +
  • README - A description of the project that contains information or links to information such as:
      +
    • A reference to the Apache license (required).
    • +
    • The current and important past releases
    • +
    • Documentation for developers and users
    • +
    +
  • +
  • MAINTAINERS - A list of all current maintainers with contact info. A separate document covers the specifics.
  • +
  • CONTRIBUTING - Directions on how to contribute code to the project, or a link to a page with that information.
  • +
  • CHANGELOG - A human readable list of recent changes. Changes should at least include the current release. This file may be maintainer curated or mechanically produced.
  • +
  • Continuous Integration / Continuous Delivery (CICD) configurations - Configurations needed to run CICD on OpenWallet Foundation provided systems (e.g., .github/workflows).
  • +
+ +

Repositories SHOULD have these files. Named files SHOULD be at the root of the repository

+
    +
  • NOTICE - As per section 4 subsection d of the Apache License, Version 2
  • +
  • Apache License Header information in each source code file. For new files added to OpenWallet Foundation repositories they SHOULD include the snippet SPDX-License-Identifier: Apache-2.0 as part of the header.
  • +
  • Build files consistent with the implementation language, such as:
      +
    • For JavaScript/Node.js a package.json file
    • +
    • For Ruby a Gemfile file
    • +
    • For Java one of a Maven pom.xml, an Apache Ant build.xml, or a Gralde build.gradle
    • +
    • file
    • +
    • For Python setup.py and requirements.txt files
    • +
    • For Go go.mod and optionally go.sum
    • +
    • For Rust a cargo.toml file
    • +
    • For multi-lingual repositories a Makefile or executable build.sh script
    • +
    • For other languages, other standard build files a practitioner of the language would expect.
    • +
    +
  • +
  • +

    Testing code - Code to test the code in the repository (such as unit tests), in a location appropriate for the language.

    +
    +

    Why not a MUST?

    +

    Not all repositories can be tested (homebrew, docs), which is the only reason this is a SHOULD.

    +
    +
  • +
+

Prohibited

+

Repositories MUST NOT have these files

+
    +
  • Executable binaries and shared library files built by code in the repository. This includes .exe, .dll, .so, .a and .dylib files not otherwise part of a third party library.
  • +
+

Credits

+

This document is based on the Hyperledger Foundation's Common Respository Structure guideline.

+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/governance/content-plan/index.html b/governance/content-plan/index.html new file mode 100644 index 00000000..ca379ac7 --- /dev/null +++ b/governance/content-plan/index.html @@ -0,0 +1,4269 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Content Plan - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Content Plan

+

This document provides details about the different channels that we have within the OpenWallet Foundation and what we expect each to be used for.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Channel

What

Roles

Discord

  • Real-Time Communication: Chat services facilitate real-time, synchronous communication among users. Messages are sent and received instantly, enabling quick exchanges and conversations.
  • Interactive Collaboration: Chat services are well-suited for interactive collaboration, allowing users to engage in live discussions, share files, collaborate on documents, and even conduct video calls in some cases.

Staff: Administers, creates new channels, and moderates

Community: Sends messages and monitors

Mailing Lists

  • Asynchronous Communication: Mailing lists are primarily used for asynchronous communication. Users send messages to a central email address, which are then distributed to all subscribers. Subscribers can read and respond to messages at their convenience.
  • Broadcasting Information: Mailing lists are effective for broadcasting information to a group of subscribers. They are commonly used for announcements, discussions, and sharing updates within a community or organization.
  • Archiving: Mailing lists typically archive messages, allowing subscribers to access past discussions and reference previous communications. This archival feature can be valuable for maintaining a record of conversations and facilitating knowledge sharing.

Staff: Administers, creates new lists, and moderates

Community: Sends messages and monitors

GitHub

  • Project-Based Source Code and User Documentation: Any source code for projects should utilize GitHub. GitHub pages should be used for hosting user documentation.
  • TAC Governance Documentation and Other Relevant Information: Governance documentation for the TAC must be version controlled. As such, GitHub is the appropriate place to store this information in addition to other relevant TAC materials. Currently https://tac.openwallet.foundation is generated from markdown files in GitHub.
  • SIG or Task Force Deliverables: A separate repo can be set up for SIGs and Task Forces so that they can have versioned control support for their deliverables.

Staff: Administers, creates new repos and teams

Maintainers: Reviews and handles issues and pull requests

Community: Use source,create issues, fork code, and contribute

Website

  • Blogs
  • Announcements
  • Native content
  • Events and Conferences

Staff: Administers and determines contents

Community: Visit and contribute blog posts

Wiki

  • Project Meeting Minutes
  • SIG Meeting Minutes
  • Task Force Meeting Minutes
  • Collaborative Editing

Staff: Administers and creates new spaces

Community: Creates and edits pages

LFX Meetings (Zoom)

  • Project, SIG, and TAC meetings: All project, SIG, and TAC meetings must be held using LFX meetings. This ensures that a recording of the meeting is captured and available for people to catch up on what they may have missed. Send an email to operations@openwallet.foundation to get your meetings scheduled.

Staff: Administers and creates new meetings

Community: Attends meetings and listen to recordings

YouTube

  • Community meeting recordings
  • Webinar recordings
  • Event recordings

Staff: Administers and adds videos and playlists

Community: Watch videos

Social Media

  • Posts about activities and events that the community may be interested in
  • Posts to announce new projects, SIGs, Task Forces, blog posts

Staff: Administers and posts content

Community: Reads content

+ +

Content Plan Mindmap

+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/governance/elections/index.html b/governance/elections/index.html new file mode 100644 index 00000000..b67fa2fa --- /dev/null +++ b/governance/elections/index.html @@ -0,0 +1,4593 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Elections - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Elections

+

Electing a Chair

+
+

From the OWF Charter

+

The TAC is responsible for ... electing annually a chairperson to preside over meetings, set the agenda for meetings, ensure meeting minutes are taken and who will also serve on the Governing Board as the TAC’s representative (the “TAC Representative”).

+
+

The TAC voting members (as defined by the charter) will elect a chair on a yearly basis. Only TAC voting members are eligible to run for the TAC chair seat. Electing a chair will be completed through the voting process outlined below. If the TAC chair must leave their position during their term or is otherwise unable to fulfill their duties, they should submit a resignation and allow the TAC to fill the vacancy using the process outlined below.

+

Electing a Vice Chair

+

The TAC voting members (as defined by the charter) will elect a vice chair on a yearly basis. Only TAC voting members are eligible to run for the TAC vice chair seat. Electing a vice chair will be held in conjunction with the chair election using the voting process outlined below. The person with the second highest number of votes will serve as the vice chair. If the TAC vice chair must leave their position during their term or is otherwise unable to fulfill their duties, they should submit a resignation and allow the TAC to fill the vacancy using the process outlined below.

+

Electing "At Large" Representatives

+
+

Implied from the OWF Charter

+

The TAC is responsible for ... appointing up to two "at large" representatives to the TAC.

+
+

The TAC voting members (as defined by the charter) can appoint up to two "at large" representatives to the TAC. The election process for "at large" representatives will occur on a yearly basis. Members of the community can nominate themselves for the position. Alternatively, a TAC voting member can nominate a member of the community; however, the nominee must actively affirm their candidacy. Electing "at large" representatives will be completed through the voting process outlined below. If the "at large" representative must leave their position during their term or is otherwise unable to fulfill their duties, they should submit a resignation. "At large" vacancies will be handled using the process outlined below.

+

Voting Process

+

Voting Tool

+

Voting occurs by a time-limited Helios Voting ballot.

+

Voting Schedule

+

The following is the default timeline for voting. The times can be adjusted to avoid weekends and holidays, but it is essential that the final schedule be published in advance and adhered to.

+
    +
  • Call for nominations: Noon PT, E-16 days
  • +
  • End of call for nominations: Noon PT, E-9 days
  • +
  • A ballot will be distributed on: E-7 days
  • +
  • The election will be completed on: Noon PT, E-day and election results are announced
  • +
+
+

Nominations

+

Nominees should outline their qualifications and provide a statement explaining why they would be a good choice for the seat.

+
+

Vacancies

+

TAC Chair Vacancy

+

Should the TAC Chair seat become vacant, the vacancy will be filled by the vice chair who will serve the remainder of the original term.

+

TAC Vice Chair Vacancy

+

Should the TAC Vice Chair seat become vacant, the vacancy will be filled by using the voting process outlined above and the replacement will serve the remainder of the original term.

+

TAC "At Large" Representative Vacancy

+

Should a TAC "at large" representative seat become vacant, the vacancy will be filled at the next indicative election, by electing a person for a full new term, not by serving out the vacant term.

+
+

Why?

+

A TAC "at large" vacancy is not filled immediately because the charter does not specify a lower limit for TAC "at large" representatives; it only specifies an upper limit.

+
+

TAC Premier Sponsor Representative Vacancy

+

Should a TAC premier sponsor representative seat become vacant, the premier sponsor will immediately appoint a new representative.

+

TAC Project Representative Vacancy

+

Should a TAC Project representative seat become vacant, the technical oversight body (e.g., a technical steering committee) for the TAC project will immediately appoint a new representative.

+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/governance/index.html b/governance/index.html new file mode 100644 index 00000000..a81705c8 --- /dev/null +++ b/governance/index.html @@ -0,0 +1,4287 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Governing Documents - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+ +
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Governing Documents

+

The following are the governing documents used by the OpenWallet Foundation's Technical Advisory Council.

+

Foundation Governance

+

The OpenWallet Foundation is governed by the following documents, of which the Technical Advisory Council follows:

+ +

Technical Advisory Council Governance

+

The Technical Advisory Council is governed with the following documents:

+ +

Project Requirements

+

The Technical Advisory Council has created the following requirements for projects:

+ +

Project Resources

+

The Technical Advisory Council offers the following services and tooling to projects:

+ + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/governance/maintainer-inactivity/index.html b/governance/maintainer-inactivity/index.html new file mode 100644 index 00000000..c9a888b2 --- /dev/null +++ b/governance/maintainer-inactivity/index.html @@ -0,0 +1,4297 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Maintainer Inactivity - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Maintainer Inactivity Policy

+
+

Note

+

This policy applies to projects that do not have an explicit maintainer inactivity policy. Where a project has an established and functioning policy, only that project's policy will apply.

+
+

OpenWallet Foundation very much appreciates the contributions of all maintainers but removing write privileges is in the interest of an orderly and secure project.

+

Activity can be code contributions, code reviews, issue reporting, or any other such activity trackable by GitHub attributed to a OpenWallet Foundation repository.

+

When a maintainer has not had any activity in a particular project for three months they will receive a notification informing them of the inactivity policies. The means and manner of notification (email, github mentions, etc.) will be at the discretion of the TAC Chair or who the TAC Chair designates.

+

When a maintainer has not had any activity in a particular project for six months a proposal will be opened up to move the maintainer from active status to emeritus status. A member of the TAC or a OpenWallet Foundation staff member will open this proposal. Any permissions to approve pull requests or commit code and any other such privileges associated with maintainer status will be removed.

+

The proposal will be in the form of a pull request (PR) to the relevant project repositories updating their maintainer lists. The inactive maintainer will be notified of this via an "at" @ mention in the PR. The PR will be open for at least one week to allow time for the project and maintainer to comment.

+

Inactive maintainers who express an intent to continue contributing may request a three-month extension. This request shall be made in the pull request updating their active maintainer status. Typically, only one such extension will be granted.

+

Maintainers who have been moved to emeritus status may return to active status when their activity within the project resumes and the current maintainers of the project approve their reactivation.

+

An OpenWallet Foundation Foundation staff member will provide a report (or maintain an automated means to generate a report) of the most recent GitHub tracked actions for contributors at regular intervals to the TAC. It will be the TAC's responsibility to act on the data.

+

Credits

+

This document is based on the Hyperledger Foundation's Inactivity policy

+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/governance/maintainers-file-content/index.html b/governance/maintainers-file-content/index.html new file mode 100644 index 00000000..c77245ca --- /dev/null +++ b/governance/maintainers-file-content/index.html @@ -0,0 +1,4457 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + MAINTAINERS.md Contents - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

MAINTAINERS.md File Contents

+

All OpenWallet Foundation projects MUST have a MAINTAINERS file (MAINTAINERS.md or MAINTAINERS.rst) at the top-level directory of the source code. This document will provide specifics on what to include in the MAINTAINERS file.

+

List of Project Maintainers

+

The first thing that MUST be included in the MAINTAINERS file is a list of the project's maintainers, both active and emeritus.

+

It is recommended that the lists be sorted alphabetically and contain the maintainers name, GitHub ID, LFID, Chat ID, Email, Company Affiliation, and Scope.

+
+

Important

+
    +
  • The email for a maintainer MUST be specified and be a reliable mechanism to contact the maintainer.
  • +
  • Scope is dependent on the project and may not exist for a given project. Scope could be the whole project, a specific repository, specific directories in a repository, or high-level description of responsibility (e.g., Documentation).
  • +
+
+

The following shows the suggested format for the information:

+
+

Example

+

Active Maintainers

+ + + + + + + + + + + + + + + + + + + + + + + +
MaintainerGitHub IDLFIDEmailChat IDCompany AffiliationScope
+

Emeritus Maintainers

+ + + + + + + + + + + + + + + + + + + + + + + +
MaintainerGitHub IDLFIDEmailChat IDCompany AffiliationScope
+
+

What Does Being a Maintainer Entail

+

The MAINTAINERS file SHOULD contain information about the different types of maintainers that exist (whole project, repo, part of repo) and what their duties are (e.g., maintainers calls, quarterly reports, code reviews, issue cleansing).

+

How to Become a Maintainer

+

The MAINTAINERS file SHOULD contain information about how to become a maintainer for the project. This section SHOULD list specific information about what is required. Information that SHOULD be included in this section:

+
    +
  • What is required before someone can be considered to become a maintainer
  • +
  • Consider whether there should be different requirements based on the scope (whole project, repo, part of repo) of maintainership
  • +
  • Whether sponsorship by an existing maintainer is required
  • +
  • How maintainers are proposed to the community. A number of open source projects require that a PR be done against the MAINTAINERS file to make this proposal
  • +
  • How many maintainers must approve the proposed maintainer. This should include information about what happens if someone vetoes the proposal
  • +
  • How long the existing maintainers have to respond to the proposal
  • +
+

How Maintainers are Removed or Moved to Emeritus Status

+

The MAINTAINERS file SHOULD contain information about how a maintainer is removed from the list of active maintainers. Information that SHOULD be included in this section:

+
    +
  • What are the reasons a maintainer would be removed from the list of active maintainers
  • +
  • How this is proposed; similar to the way in which maintainers are added, one way to do this is via a PR against the MAINTAINERS file
  • +
  • How an emeritus maintainer becomes active again
  • +
+

Credits

+

This document is based on the Hyperledger Foundation's MAINTAINERS guideline.

+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/governance/paid-tooling-policy/index.html b/governance/paid-tooling-policy/index.html new file mode 100644 index 00000000..d5138508 --- /dev/null +++ b/governance/paid-tooling-policy/index.html @@ -0,0 +1,4246 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Paid Tooling Policy - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Paid Tooling Policy

+

OpenWallet Foundation (OWF) provides a number of paid developer tools for projects. Below, we list the ones that our projects currently have access to and are supported by the OWF staff. We emphasize that just because a tool is not on this list does not mean projects cannot use it; it just means that the project maintainers may have to support it themselves and may need to pay for the tooling. The Governing Board has final say over the budget for tooling and its support.

+

OWF recommends the following tools that should be optimal for most projects:

+
    +
  • +

    Technical Documentation: markdown, GitHub pages, and Material for MkDocs.

    +
  • +
  • +

    Informal documentation and details (e.g. meeting notes, meeting agendas, long-term planning documentation, etc.): GitHub

    +
  • +
  • +

    CI: GitHub Actions

    +
  • +
  • +

    Artifact Storage: GitHub Packages

    +
  • +
  • +

    Communication: Discord

    +
  • +
  • +

    Bug Tracking: GitHub Issues and GitHub Projects

    +
  • +
  • +

    Mailing Lists: Groups.io

    +
  • +
  • +

    Meetings: Zoom via LFX Meetings

    +
  • +
+

Finally we emphasize that this list does not cover security-related tools or services.

+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/governance/project-and-lab-services/index.html b/governance/project-and-lab-services/index.html new file mode 100644 index 00000000..83eef870 --- /dev/null +++ b/governance/project-and-lab-services/index.html @@ -0,0 +1,4374 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Project and Lab Services - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Project and Lab Services

+

This document provides details about what resources are available for OpenWallet Foundation projects and labs. If there are any questions about anything on the document or if you'd like to leverage any of these resources for your project or lab, feel free to reach out to community-architects at openwallet dot foundation.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ServiceLabGrowth ProjectImpact Project
Infrastructure
Github reposYesYesYes
Chat channelYesYesYes
Mailing listOptionalYesYes
Paid toolingYes (with some restrictions at the discretion of OpenWallet Foundation staff)YesYes
Marketing
Access to OpenWallet Foundation's channels (social, newsletters, blogs, meetups, etc)Yes (with some restrictions at the discretion of the Marketing lead)YesYes
Page on the OpenWallet Foundation siteYesYes
Creation of an official project name and logoYesYes
Coordinate promotion of major project milestones and releasesYesYes
Option to create a Twitter accountYesYes
Priority placement on siteYes
Swag (stickers and potentially other items with the project logo)Yes
Onboarding New Users and Contributors
Able to take part in OpenWallet Foundation's annual Mentorship programTBDTBDTBD
Able to have project/lab featured in a contribution campaignYes (at the discretion of OpenWallet Foundation staff)TBDTBD
WorkshopsYes
Documentation and Translation supportTBDTBDTBD
Training/Certification
LF created training courseYes (at the discretion of LF Training)Yes (at the discretion of LF Training)
LF created certificationYes (at the discretion of LF Training)
Other
License scanningYesYes
Security auditsNot usually (although this can be done at the discretion of staff)Yes (at the discretion of OpenWallet Foundation staff)
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/governance/project-annual-review-process/index.html b/governance/project-annual-review-process/index.html new file mode 100644 index 00000000..cb35643e --- /dev/null +++ b/governance/project-annual-review-process/index.html @@ -0,0 +1,4460 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Annual Review Process - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Project Annual Review Process

+

Overview

+

The TAC will undertake an annual review of all OpenWallet Foundation projects. This annual review will include an assessment as to whether:

+
    +
  • each Lab is active
  • +
  • each Growth Stage project is making adequate progress towards the Impact Stage
  • +
  • each Impact Stage project is maintaining progress to remain at the Impact Stage
  • +
+

Reviews will start on the yearly anniversary of the project being accepted or moving to a new stage. The review will include a set of recommendations for each project to improve and/or recommendation to move a project across stages.

+

Projects can be provided with an extension of time in their current stage (up to the discretion of the TAC).

+

The project lifecycle contains Acceptance Criteria for moving a project to a new stage.

+

Filing an Annual Review

+

OpenWallet Foundation staff will notify the project maintainers when the project review is due.

+

Project maintainers are responsible for agreeing between them who will complete the annual review. One of the maintainers should create the review in GitHub under openwallet-foundation/tac/docs/projects/reviews.

+
    +
  • Raise a PR titled [Project name] [year] Annual Review (e.g., Amazing Project 2024 Annual Review)
  • +
  • The PR should include a file called <year>-<project name>-annual.md (e.g., 2024-amazingproj-annual.md) with the contents described below
  • +
  • Send an email to the TAC mailing list so that the community knows the PR is there and can comment on it
  • +
+

If your annual review is not submitted within two months of notification, we will take this as a sign that the project is not under active maintenance and the TAC is likely to decide to archive the project and move it to Emeritus status.

+
+

Success

+

If a project has genuinely stalled we can save everyone’s time and effort by archiving it.

+
+

Annual Review Contents

+

Your annual review should answer the following questions:

+
    +
  • Include information about your project's contributions and activity. We will be looking for signs of consistent or increasing contribution activity. Please feel free to add commentary to add colour to the numbers and graphs we will see on Insights.
  • +
  • How many maintainers do you have, and which organisations are they from? (Feel free to link to an existing MAINTAINERS file if appropriate.)
  • +
  • What do you know about adoption, and how has this changed since your last review or since being accepted into OWF? If you can list companies that are adopters of your project, please do so. (Feel free to link to an existing ADOPTERS file if appropriate.
  • +
  • How has the project performed against its goals since the last review? (We won't penalize you if your goals changed for good reasons.)
  • +
  • What are the current goals of the project? For example, are you working on major new features? Or are you concentrating on adoption or documentation?
  • +
  • How can the OpenWallet Foundation help you achieve your upcoming goals?
  • +
  • Do you think that your project meets the criteria for another stage (see Project Lifecycle Acceptance Criteria for the different stages)?
  • +
+

A template has been provided for your use.

+

Annual Review by the TAC

+

Annual reviews are performed in order to check in with projects, ascertain their progress, and address any outstanding questions.

+
    +
  • A TAC representative volunteers to lead the review once the project files a PR.
  • +
  • The assigned TAC member reviews the content of the PR and analyzes the project for community health indicators, their findings are placed within a thread in the private TAC channel for discussion.
      +
    • findings should highlight important facts about the project that could influence the TACs decision around the future of the project, its current stage, and path to other stages, etc.
    • +
    • the thread should always include whether the project's view of themselves is accurate and the ask of the TAC is reasonable to assist the project moving forward.
    • +
    +
  • +
  • The project's maintainers are invited to the public TAC meeting to engage in TAC led discussion around the project. Project maintainers are not obligated to attend.
  • +
  • The assigned TAC member provides a summary of the project and leverages the thread's content as the basis of discussion.
      +
    • discussion typically focuses on what is going well with the project and areas to improve.
    • +
    +
  • +
  • The project's maintainers are invited to use this time to voice any concerns and requests for help they may have that are not captured in the PR (or highlight asks within the PR).
  • +
  • At the conclusion of the public meeting, the TAC votes to approve the annual review. Should a concern be registered on a project, the vote will be held separately.
  • +
  • After the meeting wraps up, the assigned TAC member may summarize the discussion on the PR in the form of a comment to document information for the project and community.
  • +
+

Review Outcomes

+

The outcome of the annual review is either:

+
    +
  • At least two-thirds of the TAC members agree to continue to sponsor the project at its current stage, or
  • +
  • +

    If enough TAC members do not agree to continue to sponsor the project at its current stage, we will discuss with you what stage might be the appropriate next stage, including Emeritus stage.

    +
    +

    Info

    +

    If the TAC members recommend moving to a new stage, additional work may be required to provide details on how the project meets the new stage's acceptance criteria.

    +
    +
  • +
+

Credits

+

Ideas were taken from CNCF's Sandbox Annual Review Process.

+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/governance/project-lifecycle/index.html b/governance/project-lifecycle/index.html new file mode 100644 index 00000000..e62afb11 --- /dev/null +++ b/governance/project-lifecycle/index.html @@ -0,0 +1,4793 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Project Lifecycle - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Project Lifecycle

+

Overview

+

This governance policy describes how an open source project can formally join the OpenWallet Foundation via the Project Proposal Process and how an existing project within the OpenWallet Foundation can move through the lifecycle via the Project Stage Change Proposal Process. It describes the Stages a project may be admitted under and what the criteria and expectations are for a given stage, as well as the acceptance criteria for a project to move from one stage to another. It also describes the Annual Review Process through which those changes will be evaluated and made.

+

Project progression - movement from one stage to another - allows projects to participate at the level that is most appropriate for them given where they are in their lifecycle. Regardless of stage, all OpenWallet Foundation projects benefit from a deepened alignment with existing projects, and access to mentorship, support, and Foundation resources.

+
+

Info

+

Capitalized terms not otherwise defined in this Project Lifecycle Policy have the meanings ascribed to them in the Charter of the OpenWallet Foundation.

+
+

Project Proposal Process

+

Introduction

+

This governance policy sets forth the proposal process for projects to be accepted into the OpenWallet Foundation. The process is the same for both existing projects which seek to move into the OpenWallet Foundation and new projects to be formed within the OpenWallet Foundation.

+

Project Proposal Requirements

+

Projects must be formally proposed via GitHub. Project proposals submitted to the OpenWallet Foundation should provide the following information to the best of their ability:

+
    +
  • name of project
  • +
  • preferred maturity level (see stages below)
  • +
  • project description (what it does, why it is valuable, origin and history)
  • +
  • statement on alignment with the OpenWallet Foundation mission
  • +
  • link to current Code of Conduct (if one is adopted already)
  • +
  • sponsor from the TAC, if identified (a sponsor helps mentor projects)
  • +
  • project license (OSI-approved permissive open source licenses, Apache 2.0 by default)
  • +
  • source control (OpenWallet Foundation GitHub by default)
  • +
  • issue tracker (OpenWallet Foundation GitHub by default)
  • +
  • external dependencies (including licenses)
  • +
  • release methodology and mechanics
  • +
  • names of initial maintainers, if different from those submitting proposal
  • +
  • link to any documented governance practices (e.g., the project charter) (A project charter can be obtained by completing this form. Here is sample project charter that you can review)
  • +
  • existing financial sponsorship (if exists)
  • +
  • infrastructure needs or requests (OpenWallet Foundation provides a set of services for projects and labs. Please note which of these you will utilize and what else is required)
  • +
+

Project Acceptance Process

+
    +
  • Impact stage and Growth stage projects are required to present their proposal at a TAC meeting. Labs will be reviewed and approved directly via the project proposal PR. Labs may present at a TAC meeting if they would like to gain visibility from other community members, and the proposer should note this in the proposal.
  • +
  • +

    The TAC may ask for changes to bring the project into better alignment with the OpenWallet Foundation (adding a governance document to a repository or adopting a Code of Conduct, for example).

    +
    +

    Warning

    +

    The project will need to make these changes in order to progress further.

    +
    +
  • +
  • +

    Impact stage and Growth stage projects are accepted via a two-thirds supermajority vote of the TAC. Labs are accepted via a simple majority of the TAC.

    +
  • +
  • Satisfaction of the requirements of the initial stage of the project. The TAC will determine the appropriate initial stage for the project. The project can apply for a different stage via the review process.
  • +
+

Project Stage Change Proposal Process

+

Introduction

+

This governance policy sets forth the proposal process for projects within the OpenWallet Foundation that are seeking to move to another stage in the project lifecycle.

+

Proposal Process

+

The project's current proposal located in Project Proposals GitHub Repository must be updated via a PR. The project proposal should be updated to reflect the latest template, as well as any updates to the sections to reflect why the project should be considered for a new stage.

+

Project Stage Change Acceptance Process

+

The same acceptance project outlined above will be used for projects wishing to change lifecycle stage.

+

Stages

+

Every OpenWallet Foundation project has an associated maturity level. Proposed projects should state their preferred maturity level.

+

All projects may attend TAC meetings and contribute work regardless of their stage.

+
flowchart
+  p[Proposal]
+  subgraph as[Active Stages]
+    l[Labs]
+    g[Growth]
+    i[Impact]
+  end
+  subgraph is[Inactive Stages]
+    e[Emeritus]
+  end
+  p --> as
+  l <--> g
+  l <--> i
+  g <--> i
+  as --> is  
+

Labs

+

Definition

+

Labs are those which the TAC believes are, or have the potential to be, important to the ecosystem of Technical Projects or the open wallet ecosystem as a whole. They may be early-stage code just getting started, or they may be long-established projects with minimal resource needs. The Labs stage provides a beneficial, neutral home for these projects in order to foster collaborative development and provide a path to deeper alignment with other OpenWallet Foundation projects via the project lifecycle process.

+

Examples

+
    +
  1. Experimental code that is designed to extend one or more OpenWallet Foundation projects with functionality or interoperability libraries.
  2. +
  3. Independent code that fits within the Foundation's mission and provides potential to meet an unfulfilled need.
  4. +
  5. Code commissioned or sanctioned by the OpenWallet Foundation.
  6. +
  7. Any code that intends to join the Growth or later stages in the future and wishes to lay the foundation for that transition.
  8. +
+

Expectations

+

End users should evaluate Labs with care, as this stage does not set requirements for community size, governance, or production readiness. Labs will receive minimal support from the Foundation. Labs will be reviewed on an annual basis; they may also request a status review by submitting a report to the TAC.

+

Acceptance Criteria

+

To be considered for the Labs Stage, the project must meet the following requirements:

+
    +
  • Complete an project intake form. This intake form will create:
      +
    • A project charter (sample) that documents an intellectual property policy that leverages the Apache 2.0 license or a permissive open source license.
    • +
    • A collaboration agreement that in the case of existing projects, provides an agreement to transfer the project name, trademarks, and electronic account assets (github repo, social media accounts, domain names, etc.) to Linux Foundation Europe for the benefit of the OpenWallet Foundation.
    • +
    +
  • +
  • Submit a project proposal.
  • +
+

Upon acceptance, Labs must list their status prominently on their website/README (e.g., PROJECT, an OpenWallet Foundation Lab).

+

Growth Stage

+

Definition

+

The Growth Stage is for projects that are interested in reaching the Impact Stage, and have identified a growth plan for doing so. Growth Stage projects will receive mentorship from the TAC and are expected to actively develop their community of contributors, governance, project documentation, roadmap, and other variables identified in the growth plan that factor into broad success and adoption.

+

In order to support their active development, projects in the Growth stage have a higher level of access to Foundation resources, which will be agreed upon and reviewed on a yearly basis. A project's progress toward its growth plan goals will be reviewed on a yearly basis, and the TAC may ask the project to move to the Labs stage if progress on the plan drops off or stalls.

+

Examples

+
    +
  1. Projects that are on their way or very likely to become Growth or Impact projects.
  2. +
  3. Projects that have developed new growth targets or other community metrics for success.
  4. +
  5. Projects that are looking to create a lifecycle plan (maintainership succession, contributor programs, version planning, etc.).
  6. +
  7. Projects that need more active support from the Foundation or TAC mentorship in order to reach their goals.
  8. +
+

Expectations

+

Projects in the Growth stage are generally expected to move out of the Growth stage within two years. Depending on their growth plans, projects may cycle through Labs, Growth, or Impact stage as needed.

+

Acceptance Criteria

+

To be considered for Growth Stage, the project must meet the Labs requirements as well as the following:

+
    +
  • A presentation at the meeting of the TAC.
  • +
  • 2 TAC sponsors to champion the project and provide mentorship as needed.
  • +
  • Development of a growth plan, to be done in conjunction with their project mentor(s) at the TAC.
  • +
  • Development of a project roadmap that provides differentiated features and capabilities and the timeframe for completion.
  • +
  • Document that it is being used successfully in either proof of concepts or pilots by at least two independent end users which, in the TAC’s judgment, are of adequate quality and scope.
  • +
  • Demonstrate a substantial ongoing flow of commits and merged contributions.
  • +
  • Demonstrate that the current level of community participation is sufficient to meet the goals outlined in the growth plan and roadmap.
  • +
  • Since these metrics can vary significantly depending on the type, scope and size of a project, the TAC has final judgment over the level of activity that is adequate to meet these criteria.
  • +
  • Demonstrates how this project differs from existing projects in the Growth and Impact stages.
  • +
  • Receive a two-thirds supermajority vote of the TAC to move to Growth Stage.
  • +
+

Upon acceptance, Growth projects must list their status prominently on their website/README (e.g., PROJECT, an OpenWallet Foundation Project).

+

Impact Stage

+

Definition

+

The Impact Stage is for projects that have reached their growth goals and are now on a sustaining cycle of development, maintenance, and long-term support. Impact Stage projects are used commonly in enterprise production environments and have large, well-established project communities.

+

Examples

+
    +
  1. Projects that have publicly documented release cycles and plans for Long Term Support ("LTS").
  2. +
  3. Projects that have themselves become platforms for other projects.
  4. +
  5. Projects that are able to attract a healthy number of committers on the basis of its production usefulness (not simply 'developer popularity').
  6. +
  7. Projects that have several, high-profile or well known end-user implementations.
  8. +
+

Expectations

+

Impact Stage projects are expected to participate actively in TAC proceedings, and as such have a binding vote on TAC matters requiring a formal vote, such as the election of a TAC representative. They receive ongoing financial and marketing support from the Foundation, and are expected to cross promote the Foundation along with their activities.

+

Acceptance Criteria

+

To move from Labs or Growth status, or for a new project to join as an Impact project, a project must meet the Growth stage criteria plus:

+
    +
  • Have a defined governing body of at least 5 or more members (owners and core maintainers), of which no more than one-third is affiliated with the same employer. In the case there are 5 governing members, 2 may be from the same employer.
  • +
  • Have a documented and publicly accessible description of the project's governance, decision-making, and release processes.
  • +
  • Have a healthy number of maintainers from at least two organizations. A maintainer is defined as someone with the commit bit; i.e., someone who can accept contributions to some or all of the project.
  • +
  • Have a Code of Conduct in a form acceptable to the OpenWallet Foundation.
  • +
  • Explicitly define a project governance and maintainer process. This is preferably laid out in a GOVERNANCE.md file and references a CONTRIBUTING.md and MAINTAINERS.md file showing the current and emeritus maintainers (see MAINTAINERS.md File Contents for more information).
  • +
  • Document that it is being used successfully in production by at least two independent end users which, in the TAC’s judgment, are of adequate quality and scope.
  • +
  • Have a public list of project adopters for at least the primary repo (e.g., ADOPTERS.md or logos on the project website).
  • +
  • Have a good standing with respect to security.
  • +
  • Other metrics as defined by the applying Project during the application process in cooperation with the TAC.
  • +
  • Receive a supermajority vote from the TAC to move to Impact stage. Projects can move directly from Labs to Impact, if they can demonstrate sufficient maturity and have met all requirements.
  • +
+

Upon acceptance, Impact projects must list their status prominently on their website/README (e.g., PROJECT, an OpenWallet Foundation Project).

+

Emeritus Stage

+

Definition

+

Emeritus projects are projects which the maintainers feel have reached or are nearing end-of-life. Emeritus projects have contributed to the ecosystem, but are not necessarily recommended for modern development as there may be more actively maintained choices. The Foundation appreciates the contributions of these projects and their communities, and the role they have played in moving the ecosystem forward.

+

Examples

+
    +
  1. Projects that are "complete" by the maintainers' standards.
  2. +
  3. Projects that do not plan to release major versions in the future.
  4. +
+

Expectations

+

Projects in this stage are not in active development. Their maintainers may infrequently monitor their repositories, and may only push updates to address security issues, if at all. Emeritus projects should clearly state their status and what any user or contributor should expect in terms of response or support. If there is an alternative project the maintainers recommend, it should be listed as well. The Foundation will continue to hold the IP and any trademarks and domains, but the project does not draw on Foundation resources.

+

Acceptance Criteria

+

Projects may be granted Emeritus status via a two-thirds vote from the TAC and with approval from project ownership. In cases where there is a lack of project ownership, only a two-thirds vote from the TAC is required.

+

Upon acceptance, Emeritus projects must list their status prominently on their website/README.

+
+

Info

+

If members of the community would like to re-active a project that has been granted Emeritus status, the community must start the lifecycle over again by submitting a new proposal to the TAC.

+
+

Annual Review Process

+

Each project will undergo an annual review process to determine whether projects are in the stage that accurately reflects their needs and goals.

+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/governance/release-taxonomy/index.html b/governance/release-taxonomy/index.html new file mode 100644 index 00000000..6b8a5ef0 --- /dev/null +++ b/governance/release-taxonomy/index.html @@ -0,0 +1,4399 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Release Taxonomy - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Release Taxonomy

+
+

Note

+

This policy is not about exiting project stages.

+
+

Releases at OpenWallet Foundation must be done according to the SemVer taxonomy. In addition to the semantic versioning scheme, where we use MAJOR.MINOR.PATCH numbering, following the established guidance given in the semver specification, it is also strongly encouraged that projects should use the following tags, as permitted by semver:

+
    +
  • preview
  • +
  • alpha
  • +
  • beta
  • +
  • rcN (release candidate N - where N is 1-n incremented for each candidate)
  • +
  • +

    snapshot-<sha> for interim, possible unstable builds

    +
    +

    Note

    +

    Further, for interim, possibly unstable builds working towards a tagged release, we will append the first seven (7) characters of the SHA-1 hash of the latest commit for the branch from which the build is produced, so that we can identify the commit level of a given test, etc. e.g. 0.6-snapshot-36e99cd

    +
    +
  • +
+

preview

+

Not feature complete, but most functionality is implemented. Any missing functionality that is committed to the production release is identified, and there are specific people working on those features. Not heavily performance tuned, but performance testing has started with the first few hotspots identified and perhaps even addressed. No highest priority issues are in an open state. First-level developer documentation provided to help new developers with the learning curve.

+

alpha

+

Feature complete, for all features committed to the production release. Ready for Proof of Concept-level deployments. Performance can be characterized in a predictable way, so that basic PoC's can be done within the bounds of published expectations. APIs are documented. First attempts at end-user documentation have been made. Developer documentation is further advanced. No highest priority issues are in an open state.

+

beta

+

Feature complete for all features committed to the production release, perhaps with optional features when safe to add. Ready for Pilot-level engagements. Performance is very well characterized and active optimizations are being done, with a target set for the Production release. No highest priority or high priority bugs are in an open state. Developer documentation is complete; end-user documentation is mostly done.

+

rcN

+

For a forthcoming production release, we will prepare multiple candidate releases intended to be heavily tested by the community. As we cycle through resolving uncovered issues, we will issue another when no remaining highest or high priority issues remain, and repeat until we feel confident in releasing a production release, with no qualifier. e.g. 1.0.

+

Credits

+

This document is based on the Hyperledger Foundation's Release Taxonomy policy.

+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/governance/roles-and-responsibilities/index.html b/governance/roles-and-responsibilities/index.html new file mode 100644 index 00000000..f00edf23 --- /dev/null +++ b/governance/roles-and-responsibilities/index.html @@ -0,0 +1,4396 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Roles and Responsibilities - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Roles and Responsibilities

+

Technical Advisory Council

+

The OpenWallet Foundation charter states that the TAC is responsible for:

+
+

Quote

+
    +
  1. maintaining an overall strategic vision for technical collaboration and coordinating collaboration among Technical Projects, including development of an overall technical vision for the community;
  2. +
  3. making recommendations to the Budget Committee of resource priorities for Technical Projects;
  4. +
  5. electing annually a chairperson to preside over meetings, set the agenda for meetings, ensure meeting minutes are taken and who will also serve on the Governing Board as the TAC’s representative (the “TAC Representative”);
  6. +
  7. creating, maintaining and amending project lifecycle procedures and processes, deciding where Technical Projects fall within that lifecycle;
  8. +
  9. determining when a technical project should be admitted as a Technical Project or any Technical Project should be considered a TAC Project; and
  10. +
  11. such other matters related to the technical role of the TAC as may be communicated to the TAC by the Governing Board.
  12. +
+
+

TAC Members

+

TAC members are expected to:

+
    +
  • Subscribe to the TAC mailing list and the OpenWallet Github organization to stay aware of the TAC related updates and issues
  • +
  • Regularly participate in the TAC meetings
  • +
  • Bring up and help resolve any issues related to the needs of the OpenWallet technical community
  • +
  • Participate in, and optionally chair, the Task Forces set up by the TAC to address specific issues
  • +
  • Act as stewards for OpenWallet Foundation promoting and helping grow the organization and its activities by engaging of their own accord in activities such as posting on social media, responding to questions raised in forums, helping new community members find their way around, and giving talks at conferences on OpenWallet Foundation related topics
  • +
  • Participate in the appointment and election of "at large" representatives
  • +
+

TAC Chair

+

The TAC chair has the following additional responsibilities:

+
    +
  • Running the TAC meetings, such as the TAC calls per the agreed upon schedule. This includes: setting up and publishing an agenda, running the meeting, and ensuring any outcome is duly recorded
  • +
  • Representing the TAC, and more broadly the OpenWallet Foundation technical community, on the Governing Board, and giving updates to the Governing Board on TAC activities
  • +
+

TAC Vice Chair

+

The TAC vice chair has the following additional responsibilities:

+
    +
  • Running the TAC meetings when the TAC Chair is unable, including setting up and publishing an agenda and ensuring any outcome is duly recorded
  • +
  • Helping to marshall people who want to talk during a meeting
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/governance/security-template/index.html b/governance/security-template/index.html new file mode 100644 index 00000000..3fe4e062 --- /dev/null +++ b/governance/security-template/index.html @@ -0,0 +1,4353 @@ + + + + + + + + + + + + + + + + + + + + + + PROJECT Security Policy - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + +

PROJECT Security Policy

+

Instructions

+

The following is the best practices template security vulnerability disclosure +policy for OpenWallet Foundation's projects. Please copy the text below, place it into the SECURITY.md file for the primary repository of your project, +and adjust it as necessary for your project. Notably:

+
    +
  • Remove this "Instructions" section.
  • +
  • Replace PROJECT in the title of this page with the name of your project.
  • +
  • Populate the Security Team section with maintainers who have agreed to be on the security team.
  • +
  • See the "Alternative" notes in the OpenWallet Foundation's security vulnerability disclosure policy document for how the "best practices" in this document can be changed to meet the needs of your project while still adhering to the OpenWallet Foundation's policies.
  • +
+

Once your project's security vulnerability disclosure policy document is +published, place a copy of it into each of your project's repositories +(or link to the main repository's SECURITY.md).

+

About this Document

+

This document document defines how security vulnerability reporting is handled +in this project. The approach aligns with the OpenWallet Foundation's security +vulnerability disclosure policy. Please review that document to understand +the basis of the security reporting for this project

+

This policy borrows heavily from the recommendations of the OpenSSF +Vulnerability Disclosure working group. For up-to-date information on the latest +recommendations related to vulnerability disclosures, please visit the GitHub +of that working group.

+

If you are already familiar with what a security vulnerability disclosure policy +is and are ready to report a vulnerability, please jump to Report +Intakes.

+

What Is a Vulnerability Disclosure Policy?

+

No piece of software is perfect. All software (at least, all software of a +certain size and complexity) has bugs. In open source development, members of +the community or the public find bugs and report them to the project. A +vulnerability disclosure policy explains how this process functions from the +perspective of the project.

+

This vulnerability disclosure policy explains the rules and guidelines for +this project. It is intended to act as both a reference for +outsiders–including both bug reporters and those looking for information on the +project’s security practices–as well as a set of rules that maintainers and +contributors have agreed to follow.

+

Report Intakes

+

This project uses the following mechanism to submit security +vulnerabilities. While the security team members will do their best to +respond to bugs disclosed in all possible ways, it is encouraged for bug +finders to report through the following approved channel:

+ +

Security Team

+

The current security team is:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameEmail IDChat IDArea/Specialty
<><><><>
<><><><>
<><><><>
+

The security team for this project must include at least three project +Maintainers that agree to carry out the following duties and responsibilities. +Members are added and removed from the team via approved Pull Requests to this +repository. For additional background into the role of the security team, see +the People Infrastructure section of the OpenWallet Foundation's security vulnerability disclosure policy.

+

Responsibilities:

+
    +
  1. +

    Acknowledge receipt of the issue (see Report Intakes) to the reporter within 2 business days.

    +
  2. +
  3. +

    Assess the issue. Engage with the reporter to ask any outstanding questions about the report and how to reproduce it. If the report is not considered a vulnerability, then the reporter should be informed and this process can be halted. If the report is still a regular bug (just not a security vulnerability), the reporter should be informed (if necessary) of the regular process for reporting bugs.

    +
  4. +
  5. +

    Some issues may require more time and resources to correct. If a +particular report is more complex, discuss an embargo period with the reporter. +The embargo period should be negotiated with the reporter and must not be +longer than 90 days.

    +
  6. +
  7. +

    Create a patch for the issue (see Private Patch Deployment +Infrastructure).

    +
  8. +
  9. +

    Request a CVE for the issue (see CNA/CVE Reporting).

    +
  10. +
  11. +

    Decide the date of public release.

    +
  12. +
  13. +

    If applicable, notify members of the embargo list of the upcoming patch +and release, as described above.

    +
  14. +
  15. +

    Cut a new (software) release in which the bug is fixed.

    +
  16. +
  17. +

    Publicly disclose the issue within 48 hours after the release (see GitHub Security Advisories).

    +
  18. +
+

Discussion Forum

+

Discussions about each reported vulnerability are carried out in the +private GitHub security advisory about the vulnerability. +If necessary, a private channel specific to the issue may be created on the +OpenWallet Foundation's Discord server with invited participants added to the +discussion.

+

CNA/CVE Reporting

+

This project maintains a list of Common Vulnerabilities and Exposures +(CVE) and uses GitHub as its CVE numbering authority (CNA) for issuing +CVEs.

+

Embargo List

+

This project maintains a private embargo list. If you wish to be added to +the embargo list for a project, please email the [OpenWallet Foundation's +security list], including the project name and reason for being added to the +embargo list. Requests will be assessed by the security team in conjunction +with the appropriate OpenWallet Foundation staff, and a decision will be made +whether to accommodate the request.

+

GitHub Security Advisories

+

This project uses GitHub security advisories and the GitHub security process for handling security vulnerabilities.

+

Private Patch Deployment Infrastructure

+

In creating patches and new releases that address security vulnerabilities, +this project uses the private development features of GitHub for security +vulnerabilities. GitHub has extensive +documentation +about these features.

+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/governance/security/index.html b/governance/security/index.html new file mode 100644 index 00000000..0126e751 --- /dev/null +++ b/governance/security/index.html @@ -0,0 +1,4752 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Security Policy - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Security Vulnerability Disclosure Policy

+

This document outlines the OpenWallet Foundation's security vulnerability +disclosure policy +that all OpenWallet Foundation projects MUST follow. The associated +security template file is a "best practices" security vulnerability +disclosure policy that project Maintainers SHOULD use for +publishing the security policy and procedures for their project by copying the +file into their project repositories and updating it according to the +instructions in the document. This document includes the "best practices" text, +and defines how project Maintainers can use alternatives to the best practices +for their project. A project's resulting +alternative policy MUST adhere to the OpenWallet Foundation's security +vulnerability disclosure policy.

+

All project repositories MUST have a published security vulnerability +disclosure policy or have link to a common policy document for the project. +In rare cases, a repository within a project MAY have a policy different +from the project, as long as the repository policy also adheres to this +OpenWallet Foundation's security vulnerability disclosure policy.

+

About This Document

+

This policy borrows heavily from the recommendations of the OpenSSF +Vulnerability Disclosure working group. For up-to-date information on the latest +recommendations related to vulnerability disclosures, please visit the GitHub +of that working group.

+

In each of the document's sections, and in the associated +security template, the current OpenWallet Foundation's "best practices" are +defined.

+
+

Alternative

+

Alternatives that a project may use exist for some sections and are contained in these "Alternative boxes". When projects vary from the current OpenWallet Foundation's best practices, the documented alternatives MUST adhere to this policy.

+
+

What Is a Vulnerability Disclosure Policy?

+

No piece of software is perfect. All software (at least, all software of a +certain size and complexity) has bugs. In open source development, members of +the community or the public find bugs and report them to the project. A +vulnerability disclosure policy explains how this process functions from the +perspective of the project.

+

This vulnerability disclosure policy explains the rules and guidelines for +OpenWallet Foundation's projects. It is intended to act as both a reference for +outsiders–including both bug reporters and those looking for information on the +project’s security practices–as well as a set of rules that maintainers and +contributors have agreed to follow.

+

Vulnerability Disclosure Process and Associated Rules

+

All OpenWallet Foundation's projects, including this project, follow the +associated process +and rules for vulnerability disclosures. We note that this outline is derived +from the OpenSSF maintainers guide.

+

Each project will have a security team. The security team +will be comprised of maintainers or contributors to the project who are +knowledgeable about security and is responsible for responding to and +helping to fix security vulnerabilities.

+

The security team for this project will do the following for each reported vulnerability:

+
    +
  1. +

    Acknowledge receipt of the issue (see Report Intakes) to the reporter within 2 business days.

    +
  2. +
  3. +

    Assess the issue. Engage with the reporter to ask any outstanding questions about the report and how to reproduce it. If the report is not considered a vulnerability, then the reporter should be informed and this process can be halted. If the report is still a regular bug (just not a security vulnerability), the reporter should be informed (if necessary) of the regular process for reporting bugs.

    +
  4. +
  5. +

    Some issues may require more time and resources to correct. If a +particular report is more complex, discuss an embargo period with the reporter. +The embargo period should be negotiated with the reporter and must not be +longer than 90 days.

    +
  6. +
  7. +

    Create a patch for the issue (see Private Patch Deployment +Infrastructure).

    +
  8. +
  9. +

    Request a CVE for the issue (see CNA/CVE Reporting).

    +
  10. +
  11. +

    Decide the date of public release.

    +
  12. +
  13. +

    If applicable, notify members of the embargo list of the upcoming patch +and release, as described above.

    +
  14. +
  15. +

    Cut a new (software) release in which the bug is fixed.

    +
  16. +
  17. +

    Publicly disclose the issue within 48 hours after the release (see GitHub Security Advisories).

    +
  18. +
+

Report Intakes

+

OpenWallet Foundation's projects use the following mechanism to submit security +vulnerabilities. While the security team members will do their best to +respond to bugs disclosed in all possible ways, it is encouraged for bug +finders to report through the following approved channel:

+ +
+Alternative +

Projects MAY publish in their security policy that they accept security vulnerability disclosures via other mechanism. The policy MUST document the necessary details in using the alternate reporting mechanism(s). Projects MUST accept reports via the recommended GitHub security vulnerability process.

+
+

“People” Infrastructure

+

This section details the required basic vulnerability disclosure infrastructure +for all OpenWallet Foundation's projects. There are quite a few necessary +pieces of infrastructure, and we go through them in detail here.

+

Security Team

+

Projects MUST have a security response team of at +least three maintainers. This response team shall be set up BEFORE incidents +happen so that people know who to contact and how to contact them when an +emergency issue arises. It can be difficult to track down someone with unique +knowledge (e.g. in a particular area of cryptography) who is capable of +fixing a problem in a short period of time.

+
    +
  1. +

    Each security team member will be a member of +any OpenWallet Foundation-wide security infrastructure.

    +
  2. +
  3. +

    If a project has specialized code related to certain aspects of security +or cryptography (e.g. consensus algorithms or cryptographic algorithms), then +a corresponding specialist should be on the response team (e.g. someone +knowledgeable in consensus or cryptography, respectively). If a specialist +is not on the team, then the individual who is responsible for contacting or +engaging the specialists should be designated in their stead. We emphasize +that projects should have access to specialists in an area for which they +maintain code while recognizing that it may not be practical for these experts +to be on the response team.

    +
  4. +
+

Each project/repository must have a table in the security document listing the +team members in the following format.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameEmail IDChat IDArea/Specialty
<><><><>
<><><><>
<><><><>
+

Discussion Forum

+

Discussions about each reported vulnerability SHOULD be carried out in the +private GitHub security advisory about the vulnerability. If necessary, a private +channel specific to the issue MAY be created on the OpenWallet Foundation's +Discord server with invited participants added to the discussion.

+
+Alternative +

Projects MAY document on their security policy that they use other forums for private discussion forums for approved maintainers and security team participants to discuss vulnerabilities. If other forum(s) are used, details about them MUST be included.

+
+

CNA/CVE Reporting

+

OpenWallet Foundation's projects maintain a list of Common Vulnerabilities and Exposures +(CVE) and use GitHub as its CVE numbering authority (CNA) for issuing +CVEs.

+
+Alternative +

A project MAY document in its security policy that it uses a different CVE numbering authority. For example, the project might add the following text to this section of their security policy document:

+
This project uses the following CNA(s) in the following situations:
+1. `CNA_1`:  `situation_1, can just state “default” if only one CNA`
+2. `CNA_2`:  `situation_2`
+
+
+

Embargo List

+

An embargo list is a list of known, trusted entities that run +large deployments of a given OpenWallet Foundation's project. These +entities are notified ahead of time when important security patches are +incoming to minimize potential security risks to large deployments of +projects. Embargo lists are maintained by the security team for a given project/repository.

+

Parties are on an embargo list for (usually) one of two reasons, +because they can either help fix the problem (perhaps through testing a fix at +scale) or they need extra time to help prepare their ecosystem to roll out +fixes quickly. Approval is not given lightly: project leadership +(maintainers) must be convinced that institutions on the list “need to know" +about issues in advance.

+

Participation in an embargo list should not be taken lightly. List members +are expected to respect the materials shared through it and not disclose any +information to unauthorized parties until the public disclosure date. +Institutions are on this list because their presence helps the project and its +users; if their actions do not help the project and its users, they can expect +to be removed from the list.

+

The list itself is private in order to make it slightly more difficult for +attackers with vulnerabilities to find systems to attack. Entities may be +added to the embargo list by a majority vote of the project security response +team and should request to join the embargo list by contacting one or more of +the members of the security response team. If there is an issue about embargo +list membership where an entity feels like they are being dealt with unfairly +by the security response team, then they are encouraged to bring up the issue +in front of the OpenWallet Foundation's TAC, who can act as moderators.

+

OpenWallet Foundation's projects maintain private embargo lists. If you wish to be added to +the embargo list for a project, please email the [OpenWallet Foundation's +security list], including the +project name and reason for being added to the embargo list. Requests will be +assessed by the respective OpenWallet Foundation's security team in conjunction with the +appropriate OpenWallet Foundation staff, and a decision will be made to accommodate or not +the request.

+
+Alternative +

Projects MAY choose to document in their security document that they do not have an embargo list. The reason for not having an embargo list SHOULD be included when a project chooses not to have an embargo list.

+
+

GitHub Security Advisories

+

OpenWallet Foundation's projects use GitHub +security advisories and the GitHub security process for +handling security vulnerabilities. In particular, this best practice is strongly recommended +for projects that do not have a large number of security experts as the +features serve as a nice set of guardrails to help make sure that things are +done correctly.

+
+Alternative +

Projects MAY document in their security policy document that they use a security advisory mechanism other than GitHub to publish their disclosures. The alternate mechanism MUST be documented sufficiently for users to understand how to monitor the security advisories published by the project.

+
+

Private Patch Deployment Infrastructure

+

Patches to fix OpenWallet Foundation's project security vulnerabilities are typically +developed without public visibility by using the private development features of +GitHub. Projects with maintainers that are not familiar with these capabilities +are encouraged to contact the OpenWallet Foundation Community Architects to learn more.

+
+Alternative +

Projects MAY document in their security policy document that they do use a service other than GitHub for private patch deployment infrastructure, or that they don't use any private patch deployment infrastructure at all. In either case, the document MUST include the details of what is used instead.

+
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/governance/special-interest-group-process/index.html b/governance/special-interest-group-process/index.html new file mode 100644 index 00000000..c7fba167 --- /dev/null +++ b/governance/special-interest-group-process/index.html @@ -0,0 +1,4366 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Special Interest Groups - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Special Interest Group

+

A special interest group (SIG) under the Technical Advisory Council (TAC) is a group with a shared interest in advancing a specific area of knowledge, learning, or technology related to the mission of the OpenWallet Foundation where members cooperate to affect or to produce solutions within their particular field. Unlike a task force, SIGs are typically long running and may or may not produce any deliverables. A SIG can be created by anyone in the OpenWallet Foundation community and must be proposed to and approved by the TAC.

+

Propose a Special Interest Group

+

To propose a special interest group, create an issue in the TAC GitHub repository using the Special Interest Group template. The issue should be named "Special Interest Group Proposal: \<name of special interest group>". The issue should include the following information:

+
    +
  • Introduction/background material
  • +
  • Objectives of the special interest group
  • +
  • List of deliverables or work products (optional)
  • +
  • Leader(s)
  • +
  • Initial participant list
  • +
+

Approval Process

+

The TAC will review the special interest group proposal first by providing comments in the issue and secondly by bringing the special interest group proposal to a discussion and vote in a TAC meeting.

+

The decision of the vote will be documented in the issue. If the special interest group is approved, a discussion channel in Discord will be created. In addition, we will work with the OpenWallet Foundation operations team to schedule a meeting on the OpenWallet Foundation calendar. If necessary, a GitHub repository and/or mailing list will also be created at the request of the special interest group leader(s).

+

Special Interest Group Procedures

+

The special interest group can decide on the mechanism for running the SIG. Meeting minutes and a log of decisions that have been made should be kept for ensuring continuity of the special interest group. The special interest group should update the issue to reflect where the meeting notes and log of decisions is kept or use the issue directly to capture this information.

+

Reporting on Special Interest Group Activities

+

Every quarter the special interest group leader should report on the activities of the SIG at a TAC meeting. This will ensure that the SIG is still active and that there is still value in hosting the special interest group. Please see the schedule for when these updates should occur.

+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/governance/tac/index.html b/governance/tac/index.html new file mode 100644 index 00000000..f5c84610 --- /dev/null +++ b/governance/tac/index.html @@ -0,0 +1,4610 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Composition - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Open Wallet Foundation TAC composition

+

Current Composition

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Member (alphabetical by first name)Representing
David ZeuthenGoogle
Jaehoon (Ace) ShimAt Large
Pete CoolingVisa
Rolson QuadrasGen
Stavros Kounis (vice chair)At Large
Tracy Kuhrt (chair)Accenture
Wenjing ChuFutureWei Technologies
+

History

+

2023-03-08

+
    +
  • Tracy Kuhrt is running unopposed for TAC Chair
  • +
  • Composition
      +
    • Accenture - Tracy Kuhrt
    • +
    • Futurewei - Wenjing Chu
    • +
    • Gen Digital - Drummond Reed
    • +
    • Visa - Marie Austenaa
    • +
    +
  • +
+

2023-04-05

+
    +
  • TAC "at large" election results
      +
    • Jeremie Miller
    • +
    • Stavros Kounis
    • +
    +
  • +
+

2023-06-28

+
    +
  • Pete Cooling was introduced as Visa's TAC voting representative.
  • +
+

2023-08-09

+
    +
  • RESOLVED: That Stavros Kounis is hereby confirmed and approved as the TAC Vice Chair
  • +
+

2023-09-06

+
    +
  • We welcomed David Zeuthen, Google premier member representative
  • +
+

2023-10-18

+
    +
  • Mike Varley will represent Gen Digital moving forward.
  • +
+

2024-04-03

+
    +
  • TAC "at large" election results
      +
    • Ace Shim
    • +
    • Stavros Kounis
    • +
    +
  • +
+

2024-04-17

+
    +
  • Chair/Vice Chair Results
      +
    • Stavros, vice chair
    • +
    • Tracy, chair
    • +
    +
  • +
+

2024-05-15

+
    +
  • Rolson Quadras will represent Gen Digital moving forward
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/governance/task-force-process/index.html b/governance/task-force-process/index.html new file mode 100644 index 00000000..2d231a1d --- /dev/null +++ b/governance/task-force-process/index.html @@ -0,0 +1,4391 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Task Forces - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Task Force

+

A task force is a group that is focused on a task with limited scope and fixed time to complete. Unlike a special interest group, a task force will have a specific set of deliverables or work products that it will create and be limited in time to completion. A task force can be created by anyone in the OpenWallet Foundation community and must be proposed to and approved by the TAC.

+

Propose a Task Force

+

To propose a task force, create an issue in the TAC GitHub repository. The issue should be named "Task Force Proposal: \<name of task force>". The issue should include the following information:

+
    +
  • Introduction/background material
  • +
  • Objectives of the task force
  • +
  • List of deliverables or work products
  • +
  • Time to complete (no more than 6 months)
  • +
  • Leader(s)
  • +
  • Initial participant list
  • +
+

Approval Process

+

The TAC will review the task force proposal first by providing comments in the issue and secondly by bringing the task force proposal to a discussion and vote in a TAC meeting.

+

The decision of the vote will be documented in the issue. If the task force is approved, a discussion channel in Discord will be created. In addition, we will work with the OpenWallet Foundation operations team to schedule a meeting on the OpenWallet Foundation calendar. If necessary, a GitHub repository and/or mailing list will also be created at the request of the task force leader(s).

+

Task Force Procedures

+

The task force can decide on the mechanism for creating the deliverables. Meeting minutes and a log of decisions that have been made should be kept for ensuring continuity of the task force. The task force should update the issue to reflect where the meeting notes and log of decisions is kept or use the issue directly to capture this information.

+

Reporting on Task Force Completion of Deliverables

+

Upon completion of the task force's deliverables, the task force should arrange a time with the TAC chair to present the deliverables at a TAC meeting. This can be accomplished by sending an email to the TAC mailing list at tac@lists.openwallet.foundation.

+

Requesting an Extension on Completion Date

+

If the task force is not able to complete the deliverables by the specified completion date, then the leader of the task force should arrange a time with the TAC chair to discuss the extension at a TAC meeting. This discussion should include information on the current status, the delays, and the expected updates to the schedule. This can be accomplished by sending an email to the TAC mailing list at tac@lists.openwallet.foundation.

+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 00000000..71588b07 --- /dev/null +++ b/index.html @@ -0,0 +1,4156 @@ + + + + + + + + + + + + + + + + + + + + + + + + Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Home

+ +

Welcome to the OpenWallet Foundation's (OWF) Technical Advisory Council (TAC) website. Here you will find:

+
+
    +
  • +

    What is the TAC

    +
    +

    Learn more about the Technical Advisory Council's role, responsibilities, and voting members

    +
  • +
  • +

    Governing Documents

    +
    +

    Review the OpenWallet Foundation TAC Governing Documents

    +
  • +
  • +

    TAC Meetings

    +
    +

    See meeting invite details and meeting notes from past meetings

    +
  • +
  • +

    Projects

    +
    +

    Explore the OpenWallet Foundation Projects

    +
  • +
  • +

    Special Interest Groups

    +
    +

    Join an OpenWallet Foundation Special Interest Groups (SIGs)

    +
  • +
  • +

    Task Forces

    +
    +

    Work on an OpenWallet Foundation Task Forces

    +
  • +
+
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/meetings/2023/2023-03-08/index.html b/meetings/2023/2023-03-08/index.html new file mode 100644 index 00000000..8f5cc0ae --- /dev/null +++ b/meetings/2023/2023-03-08/index.html @@ -0,0 +1,4401 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 2023-03-08 - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

2023-03-08

+
+

Reminder

+

These meetings are covered by the Antitrust Policy and the Code of Conduct.

+
+

Agenda

+
    +
  • Welcome and intros of TAC
  • +
  • Reminder of TAC Charter
  • +
  • TAC Chair election
  • +
  • TAC "at large" seats
  • +
  • Call for code from the Community
  • +
  • Open Discussion and Next Steps
  • +
+

Recording

+ +

Actions

+ +

Minutes

+
    +
  • TAC Charter +
  • +
  • TAC Chair Election
      +
    • Tracy Kuhrt is running unopposed – will move to email vote to formalize
    • +
    +
  • +
  • Composition
      +
    • Accenture - Tracy Kuhrt
    • +
    • Futurewei - Wenjing Chu
    • +
    • Gen Digital - Drummond Reed
    • +
    • Visa - Marie Austenaa
    • +
    • “at large” representative #1 appointed by vote of the TAC
    • +
    • “at large” representative #2 appointed by vote of the TAC
    • +
    • one representative appointed by the technical oversight body (e.g., a technical steering committee) of each TAC Project
    • +
    +
  • +
  • Call for Code +
  • +
  • Governance rules +
  • +
  • Open Discussion
      +
    • The Governing Board met yesterday and appointed Daniel Goldscheider as Interim Executive Director. Daniel introduced himself and provided his thoughts on the future of OWF.
    • +
    • A suggestion was made for a landscape review. A comment was made that that work has begun here.
    • +
    +
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/meetings/2023/2023-03-22/index.html b/meetings/2023/2023-03-22/index.html new file mode 100644 index 00000000..0ba46809 --- /dev/null +++ b/meetings/2023/2023-03-22/index.html @@ -0,0 +1,4381 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 2023-03-22 - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

2023-03-22

+
+

Reminder

+

These meetings are covered by the Antitrust Policy and the Code of Conduct.

+
+

Agenda

+ + + +

Action Items

+
    +
  • Conduct an email vote for the Governance documents approval and adoption.
  • +
  • Conduct an email vote for the TAC "at large" schedule and process.
  • +
  • Todd to confirm whether the TAC can create an alternate policy or whether the Governing Board will need to update the charter to reflect.
  • +
  • Tracy to create a pull request to update the project proposal template to include links to the mission and project lifecycle.
  • +
  • Create a GitHub organization (openwallet-foundation-labs) to host incoming labs.
  • +
+

Minutes

+
    +
  • No comments on the TAC Governance documents. Will conduct an email vote to adopt.
  • +
  • Discussed TAC "at large" election process. Will conduct an email vote to adopt.
  • +
  • Reviewed project proposal process and instructions and went through the template. Two suggested changes:
      +
    • Include a link to the mission.
    • +
    • Include a link to the project lifecycle for stage information.
    • +
    +
  • +
  • Next steps
      +
    • Create a labs organization (openwallet-foundation-labs) to host any lab proposals.
    • +
    +
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/meetings/2023/2023-04-05/index.html b/meetings/2023/2023-04-05/index.html new file mode 100644 index 00000000..cbc4e11e --- /dev/null +++ b/meetings/2023/2023-04-05/index.html @@ -0,0 +1,4401 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 2023-04-05 - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

2023-04-05

+
+

Reminder

+

These meetings are covered by the Antitrust Policy and the Code of Conduct.

+
+

Agenda

+
    +
  • Review action items from last meeting
  • +
  • TAC "at large" election results
  • +
  • Architecture SIG update
  • +
  • Call for code from the community
  • +
  • Open discussion and next steps
  • +
+ + +

Action Items

+
    +
  • Tracy to rename the architecture-task-force GitHub repo to architecture-sig - completed
  • +
  • Jenn to rename the meeting invite for the Outside Architecture Special Interest Group to reflect that the name should be the Architecture SIG
  • +
  • Jenn to add Stavros to the TAC meeting invite - completed
  • +
  • Jenn to add Jeremie to the TAC meeting invite
  • +
  • Create a GitHub organization (openwallet-foundation-labs) to host incoming labs
  • +
+

Meeting Minutes

+
    +
  • Review action items from last meeting
      +
    • Conduct an email vote for the Governance documents approval and adoption - results 3 TAC members voted in favor; 1 TAC member abstained
    • +
    • Conduct an email vote for the TAC "at large" schedule and process - results 3 TAC members voted in favor; 1 TAC member abstained
    • +
    • Todd to confirm whether the TAC can create an alternate policy or whether the Governing Board will need to update the charter to reflect - currently no policy for TAC alternates; if we want this, we would need to present this to the GB to get a charter update
        +
      • The TAC would like to recommend that the board create an alternate policy for the TAC.
      • +
      • The language will be similar to the following "A TAC member can designate an alternate for a specific meeting, and has to notify the chair in advance."
      • +
      +
    • +
    • Tracy to create a pull request to update the project proposal template to include links to the mission and project lifecycle - pull request created and merged
    • +
    • Create a GitHub organization (openwallet-foundation-labs) to host incoming labs - not yet completed
    • +
    +
  • +
  • TAC "at large" election results
      +
    • Jeremie Miller
    • +
    • Stavros Kounis
    • +
    +
  • +
  • Architecture SIG update +
  • +
  • Call for code from the community
  • +
  • Next steps
      +
    • Discussion regarding the upcoming conference season, including IIW, EIC, and others.
    • +
    • Suggestion was made to create an OpenWallet Foundation event calendar.
    • +
    • Next meeting is April 19, 2023.
    • +
    +
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/meetings/2023/2023-04-19/index.html b/meetings/2023/2023-04-19/index.html new file mode 100644 index 00000000..661501ca --- /dev/null +++ b/meetings/2023/2023-04-19/index.html @@ -0,0 +1,4410 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 2023-04-19 - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

2023-04-19

+
+

Reminder

+

These meetings are covered by the Antitrust Policy and the Code of Conduct.

+
+

Agenda

+
    +
  • Review action items from last meeting
  • +
  • Priorities
  • +
  • Internet Identity Workshop (IIW) updates
  • +
  • Call for code from the community
  • +
  • Open discussion and next steps
  • +
+ + +

Action Items

+
    +
  • Document process for creating a task force - pull request
  • +
+

Meeting Minutes

+
    +
  • Review action items from last meeting
      +
    • Tracy to rename the architecture-task-force GitHub repo to architecture-sig - completed
    • +
    • Jenn to rename the meeting invite for the Outside Architecture Special Interest Group to reflect that the name should be the Architecture SIG - completed
    • +
    • Jenn to add Stavros to the TAC meeting invite - completed
    • +
    • Jenn to add Jeremie to the TAC meeting invite - completed
    • +
    • Create a GitHub organization (openwallet-foundation-labs) to host incoming labs - completed
    • +
    +
  • +
  • Priorities
      +
    • Projects
        +
      • Pipeline of projects
      • +
      • Getting a method of tracking and accessing projects
      • +
      • Rule book / guide on the evaluation process and criteria for new projects
      • +
      • Technical Focus
          +
        • Cloud based, edge based, and hybrid wallets
        • +
        • Common components for wallets
        • +
        • Specific components for money, identity, and object wallets
        • +
        +
      • +
      +
    • +
    • Collaboration between OWF and European Commission
        +
      • Tracking changes in the next European Digital Identity Wallet Architecture and Reference Framework (ARF) and making sure it lines up with OWF thinking
      • +
      • Maintaining dialog and exploring alignment
      • +
      +
    • +
    +
  • +
  • Internet Identity Workshop (IIW) updates
      +
    • Topics on digital wallets, credentials, and interoperability
    • +
    • Sessions on EUDI and the ARF
    • +
    • A number of OpenWallet topics will be discussed on day 2 and 3
    • +
    • Discussions about the Linux Foundation Trust umbrella
    • +
    +
  • +
  • Call for code from the community
      +
    • Completing the assessment framework may allow people to better understand what type of projects should be considered for contribution
    • +
    +
  • +
  • Next steps
      +
    • Next meeting is May 3, 2023
    • +
    +
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/meetings/2023/2023-05-03/index.html b/meetings/2023/2023-05-03/index.html new file mode 100644 index 00000000..cc27d7eb --- /dev/null +++ b/meetings/2023/2023-05-03/index.html @@ -0,0 +1,4417 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 2023-05-03 - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

2023-05-03

+
+

Reminder

+

These meetings are covered by the Antitrust Policy and the Code of Conduct.

+
+

Agenda

+
    +
  • Review action items from last meeting
  • +
  • Welcome new TAC member
  • +
  • Task Force Proposal
  • +
  • Assessment Framework - How do we want to assess incoming projects?
  • +
  • Call for code from the community
  • +
  • Open discussion and next steps
  • +
+ + +

Action Items

+
    +
  • Update Task Force process to include information on optional mailing lists and capturing meeting notes -- commit -- completed
  • +
  • Create process for Special Interest Groups similar to Task Force process and cross link the two processes together
  • +
+

Meeting Minutes

+ + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/meetings/2023/2023-05-17/index.html b/meetings/2023/2023-05-17/index.html new file mode 100644 index 00000000..0d62cbf8 --- /dev/null +++ b/meetings/2023/2023-05-17/index.html @@ -0,0 +1,4451 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 2023-05-17 - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

2023-05-17

+
+

Reminder

+

These meetings are covered by the Antitrust Policy and the Code of Conduct.

+
+

Agenda

+ + + +

TAC Voting Members

+
    +
  • Jeremie Miller
  • +
  • Marie Austenaa (Trevor Crooks attended and voted in Marie's place)
  • +
  • Stavros Kounis
  • +
  • Tracy Kuhrt
  • +
  • Troy Ronda
  • +
  • Wenjing Chu
  • +
+

Action Items

+ +

Meeting Minutes

+ + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/meetings/2023/2023-05-31/index.html b/meetings/2023/2023-05-31/index.html new file mode 100644 index 00000000..843bd802 --- /dev/null +++ b/meetings/2023/2023-05-31/index.html @@ -0,0 +1,4460 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 2023-05-31 - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

2023-05-31

+
+

Reminder

+

These meetings are covered by the Antitrust Policy and the Code of Conduct.

+
+

Agenda

+ + + +

TAC Voting Members

+
    +
  • Jeremie Miller
  • +
  • Marie Austenaa
  • +
  • Stavros Kounis
  • +
  • Tracy Kuhrt
  • +
  • Troy Ronda
  • +
  • Wenjing Chu
  • +
+

Action Items

+ +

Meeting Minutes

+
    +
  • +

    Review action items from last meeting

    + +
  • +
  • +

    Update on TAC alternates

    +
      +
    • +

      The Governing Board agreed to modify the Charter to include the following language:

      +
      +

      Updated Language

      +

      5.c) TAC meetings are intended to be open to observe by Sponsors, contributors to any TAC Project and others in the general public interested in the OpenWallet Foundation. The TAC may decide whether to allow named representatives (one per voting member) to attend as an alternate.

      +
      +
    • +
    +
  • +
  • +

    OID4VC Due Diligence Task Force

    +
      +
    • Unanimously approved by the present TAC voting members.
    • +
    +
  • +
  • +

    Credential Format Comparison SIG

    +
      +
    • Unanimously approved by the present TAC voting members.
    • +
    +
  • +
  • +

    Call for code from the community

    +
  • +
  • +

    Next steps

    +
      +
    • Next meeting is June 14, 2023
    • +
    +
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/meetings/2023/2023-06-14/index.html b/meetings/2023/2023-06-14/index.html new file mode 100644 index 00000000..139d4b89 --- /dev/null +++ b/meetings/2023/2023-06-14/index.html @@ -0,0 +1,4472 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 2023-06-14 - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

2023-06-14

+
+

Reminder

+

These meetings are covered by the Antitrust Policy and the Code of Conduct.

+
+

Agenda

+ + + +

TAC Voting Members

+
    +
  • Jeremie Miller
  • +
  • Marie Austenaa
  • +
  • Stavros Kounis
  • +
  • Tracy Kuhrt
  • +
  • Troy Ronda
  • +
  • Wenjing Chu
  • +
+

Action Items

+ +

Meeting Minutes

+
    +
  • +

    Announcements

    + +
  • +
  • +

    Review action items from last meeting

    + +
  • +
  • +

    TAC Alternates Policy

    +
      +
    • RESOLVED: That the TAC Alternates Policy is hereby confirmed, approved, and adopted.
        +
      • Unanimously approved by the present TAC voting members.
      • +
      +
    • +
    +
  • +
  • +

    Call for code from the community

    +
      +
    • A question was asked whether we were tracking a wishlist for potential projects
        +
      • In general, we are looking for projects that fit with the vision of the OpenWallet Foundation. Those that are focused on wallet engine related to identity, money, and objects
      • +
      • We previously were capturing potential code projects using this Google sheet
      • +
      +
    • +
    • If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
    • +
    +
  • +
  • +

    Open discussion and next steps

    + +
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/meetings/2023/2023-06-28/index.html b/meetings/2023/2023-06-28/index.html new file mode 100644 index 00000000..59754c20 --- /dev/null +++ b/meetings/2023/2023-06-28/index.html @@ -0,0 +1,4459 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 2023-06-28 - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

2023-06-28

+
+

Reminder

+

These meetings are covered by the Antitrust Policy and the Code of Conduct.

+
+

Agenda

+ + + +

TAC Voting Members

+
    +
  • Jeremie Miller
  • +
  • Marie Austenaa
  • +
  • Stavros Kounis
  • +
  • Tracy Kuhrt
  • +
  • Troy Ronda
  • +
  • Wenjing Chu
  • +
+

Action Items

+ +

Meeting Minutes

+
    +
  • +

    Announcements

    +
      +
    • Credential Format Comparison SIG will meet on Wednesdays at 4pm CEST on alternate weeks to the TAC. Kickoff meeting planned for July 7th.
    • +
    • OID4VC Due Diligence task force will meet weekly on Wednesdays at 5pm CEST.
    • +
    • Pete Cooling was introduced as Visa's TAC voting representative.
    • +
    +
  • +
  • +

    Review action items from last meeting

    + +
  • +
  • +

    Vice chair seat and responsibilities

    +
      +
    • RESOLVED: That the Vice Chair Seat and Responsibilities is hereby confirmed, approved, and adopted.
        +
      • Unanimously approved by the present TAC voting members.
      • +
      • Voting schedule
          +
        • Call for nominations: June 28
        • +
        • End of call for nominations: July 5, Noon PT
        • +
        • A ballot will be distributed on: July 5 by end of day PT
        • +
        • The election will be completed on: July 11, Noon PT
        • +
        • Election results are announced at the July 12 meeting
        • +
        +
      • +
      • If you would like to submit your nomination for TAC Vice Chair, please create an issue at https://github.com/openwallet-foundation/tac/issues
          +
        • Title of issue: [NOMINATION]: 2023 Vice Chair - Name
        • +
        • Include a short bio, outline your qualifications, and provide a statement explaining why you would be a good choice for the seat
        • +
        +
      • +
      +
    • +
    +
  • +
  • +

    Wallets and personal data stores

    + +
  • +
  • +

    Call for code from the community

    +
      +
    • If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
    • +
    +
  • +
  • +

    Open discussion and next steps

    +
      +
    • Next meeting is July 12, 2023
    • +
    +
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/meetings/2023/2023-07-12/index.html b/meetings/2023/2023-07-12/index.html new file mode 100644 index 00000000..ed3dd389 --- /dev/null +++ b/meetings/2023/2023-07-12/index.html @@ -0,0 +1,4468 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 2023-07-12 - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

2023-07-12

+
+

Reminder

+

These meetings are covered by the Antitrust Policy and the Code of Conduct.

+
+

Agenda

+ + + +

TAC Voting Members

+
    +
  • Jeremie Miller
  • +
  • Pete Cooling
  • +
  • Stavros Kounis
  • +
  • Tracy Kuhrt
  • +
  • Troy Ronda
  • +
  • Wenjing Chu
  • +
+

Action Items

+ +

Meeting Minutes

+
    +
  • +

    Announcements

    +
      +
    • Credential Format Comparison SIG will meet on Wednesdays at 4pm CEST on alternate weeks to the TAC +
    • +
    • OID4VC Due Diligence task force will meet weekly on Wednesdays at 5pm CEST
    • +
    • Architecture SIG meets weekly on Mondays at 11am US/Pacific
    • +
    • Invitation to fully remote ISO/IEC JTC 1/SC 17 18013-7 Interoperability Event
    • +
    • For Associate non-profit members of the OpenWallet Foundation: voting is now open to select the Associate Representative for the Governing Board. Please email operations@openwallet.foundation if you have any questions about your organization's participation in this vote.
    • +
    +
  • +
  • +

    Review action items from last meeting

    + +
  • +
  • +

    Vice Chair

    +
      +
    • RESOLVED: That the voting schedule for vice chair is hereby revised, approved, and adopted as specified.
        +
      • Revised voting schedule
          +
        • Call for nominations: July 12
        • +
        • End of call for nominations: August 2, Noon PT
        • +
        • A ballot will be distributed on: August 2 by end of day PT
        • +
        • The election will be completed on: August 8, Noon PT
        • +
        • Election results are announced at the August 9 meeting
        • +
        +
      • +
      • Unanimously approved by the present TAC voting members.
      • +
      +
    • +
    +
  • +
  • +

    Farmworker Wallet OS project proposal

    +
      +
    • Video shared on Discord
    • +
    • Question asking for clarification of the scope of the contribution
    • +
    • Concerns raised about the licensing terms of the generated output from Mendix
        +
      • Mendix does not make any intellectual property claims on the output
      • +
      +
    • +
    • Question raised about the proposed license that will need to be run past LF legal and the Governing Board
    • +
    • Need to consider naming of the repos to ensure that it allows people to determine that they are part of the same project
    • +
    • Question raised about the difference between the Aries SDK proposed to be part of this project and the one in Hyperledger
        +
      • The one in this project is a wrapper around the SDK in Hyperledger that can be used by Mendix developers
      • +
      +
    • +
    • Continue conversation on the pull request
    • +
    +
  • +
  • +

    Call for code from the community

    +
      +
    • If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
    • +
    +
  • +
  • +

    Open discussion and next steps

    +
      +
    • Next meeting is July 26, 2023
    • +
    +
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/meetings/2023/2023-07-26/index.html b/meetings/2023/2023-07-26/index.html new file mode 100644 index 00000000..91235d54 --- /dev/null +++ b/meetings/2023/2023-07-26/index.html @@ -0,0 +1,4475 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 2023-07-26 - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

2023-07-26

+
+

Reminder

+

These meetings are covered by the Antitrust Policy and the Code of Conduct.

+
+

Agenda

+ + + +

TAC Voting Members

+
    +
  • Jeremie Miller
  • +
  • Pete Cooling
  • +
  • Stavros Kounis
  • +
  • Tracy Kuhrt
  • +
  • Troy Ronda
  • +
  • Wenjing Chu
  • +
+

Action Items

+
    +
  • Develop list of budget line items needed by the TAC
  • +
  • Work with Jorge on the item of whether aries-sdk-mendix makes sense within Hyperledger
  • +
+

Meeting Minutes

+
    +
  • +

    Announcements

    + +
  • +
  • +

    Review action items from last meeting

    + +
  • +
  • +

    Materials for MkDocs Insiders version

    +
      +
    • RESOLVED: That the TAC recommends to the Governing Board the sponsorship of Material for MkDocs to obtain access to the Insiders Version is hereby confirmed, approved, and adopted.
        +
      • Proposed resolution was not voted on. It was suggested that we develop a proposal that would include other tools that the technical community would need to limit the number of requests to the Governing Board.
      • +
      +
    • +
    +
  • +
  • +

    Farmworker Wallet OS project proposal

    +
      +
    • Discussion items
        +
      • Code of Conduct
          +
        • plan to change to use OWF’s CoC
        • +
        • we may need to consider changing the template since it asks for the current CoC
        • +
        +
      • +
      • License
          +
        • change to use Apache 2.0 license
        • +
        +
      • +
      • Project Governance
          +
        • no change needed at this point
        • +
        +
      • +
      • Repo names
          +
        • Discussion was had to make sure that we are prefixing repo names with the project name to ensure that it is easy for someone to find all repos associated with a single project
        • +
        +
      • +
      • Interoperable roadmap
          +
        • No limit on what will be supported
        • +
        +
      • +
      • Hosting Aries-specific stuff at OWF
          +
        • TAC considers wrappers of other projects to be better suited to be included with the parent project
        • +
        • Tracy to work with Jorge on creating a lab proposal for Hyperledger for the Aries-specific wrappers
        • +
        • Jorge to update proposal to reflect the above recommendation
        • +
        +
      • +
      +
    • +
    +
  • +
  • +

    Call for code from the community

    +
      +
    • If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
    • +
    +
  • +
  • +

    Open discussion and next steps

    +
      +
    • Next meeting is August 9, 2023
    • +
    +
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/meetings/2023/2023-08-09/index.html b/meetings/2023/2023-08-09/index.html new file mode 100644 index 00000000..33ca525d --- /dev/null +++ b/meetings/2023/2023-08-09/index.html @@ -0,0 +1,4478 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 2023-08-09 - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

2023-08-09

+
+

Reminder

+

These meetings are covered by the Antitrust Policy and the Code of Conduct.

+
+

Agenda

+ + + +

TAC Voting Members

+
    +
  • Jeremie Miller
  • +
  • Pete Cooling
  • +
  • Stavros Kounis
  • +
  • Tracy Kuhrt
  • +
  • Troy Ronda
  • +
  • Wenjing Chu
  • +
+

Action Items

+
    +
  • Continue to work on budget line items
  • +
  • Jorge to update code of conduct on Farmworker Wallet OS proposal -- completed
  • +
  • Create repositories for the Farmworker Wallet OS Lab
  • +
  • Share document with governance best practices -- completed +
  • +
  • Comment on OWF Project Guidance - all
  • +
+

Meeting Minutes

+
    +
  • +

    Announcements

    +
      +
    • Credential Format Comparison SIG will meet on Wednesdays at 4pm CEST on alternate weeks to the TAC
    • +
    • OID4VC Due Diligence task force will meet weekly on Tuesdays at 5pm CEST
    • +
    • Architecture SIG meets weekly on Mondays at 11am US/Pacific
    • +
    • sd-jwt-python source is now available
    • +
    +
  • +
  • +

    Review action items from last meeting

    + +
  • +
  • +

    Farmworker Wallet OS project proposal

    +
      +
    • RESOLVED: That the Farmworker Wallet OS lab is hereby confirmed, approved, and adopted.
        +
      • Unanimously approved by the present TAC voting members.
      • +
      +
    • +
    +
  • +
  • +

    Budget Request to Governing Board

    + +
  • +
  • +

    Vice Chair

    +
      +
    • RESOLVED: That Stavros Kounis is hereby confirmed and approved as the TAC Vice Chair
        +
      • Approved by the present TAC voting members with Stavros abstaining.
      • +
      +
    • +
    +
  • +
  • +

    Call for code from the community

    +
      +
    • If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
    • +
    • Question asked about code proposal that depends on Aries/Bifold and whether that could be submitted to OWF?
        +
      • If the project is only dependent on Aries/Bifold, then it can be submitted to OWF.
      • +
      • If, however the project is a wrapper of Aries/Bifold, then that should probably be submitted to Hyperledger.
      • +
      +
    • +
    • Question about project governance best practices and whether we could document these best practices for new projects.
        +
      • OWF Project Guidance -- this document assumes a fairly mature project that consists of a technical steering committee and maintainers for the project. Please comment and add your thoughts/suggestions.
      • +
      • In addition, we can look at Hyperledger's Project Best Practices for additional thoughts on guiding OpenWallet Foundation projects.
      • +
      +
    • +
    +
  • +
  • +

    Open discussion and next steps

    +
      +
    • Next meeting is August 23, 2023
    • +
    +
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/meetings/2023/2023-08-23/index.html b/meetings/2023/2023-08-23/index.html new file mode 100644 index 00000000..d3af4639 --- /dev/null +++ b/meetings/2023/2023-08-23/index.html @@ -0,0 +1,4503 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 2023-08-23 - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

2023-08-23

+
+

Reminder

+

These meetings are covered by the Antitrust Policy and the Code of Conduct.

+
+

Agenda

+ + + +

TAC Voting Members

+
    +
  • Jeremie Miller
  • +
  • Pete Cooling
  • +
  • Stavros Kounis
  • +
  • Tracy Kuhrt
  • +
  • Troy Ronda
  • +
  • Wenjing Chu
  • +
+

Action Items

+ +

Meeting Minutes

+
    +
  • +

    Announcements

    +
      +
    • Credential Format Comparison SIG will meet on Wednesdays at 4pm CEST on alternate weeks to the TAC
    • +
    • OID4VC Due Diligence task force will meet weekly on Tuesdays at 5pm CEST
    • +
    • Architecture SIG meets weekly on Mondays at 11am US/Pacific
    • +
    • Farmworker Wallet OS repositories created
    • +
    • Project pages created for each approved project on the TAC website
    • +
    • Slide deck available covering the OWF Project Proposal Process
    • +
    +
  • +
  • +

    Review action items from last meeting

    +
      +
    • Continue to work on budget line items -- all
    • +
    • Jorge to update code of conduct on Farmworker Wallet OS proposal -- completed
    • +
    • Create repositories for the Farmworker Wallet OS Lab -- completed
    • +
    • Share document with governance best practices -- completed
    • +
    • Comment on OWF Project Guidance - all
    • +
    +
  • +
  • +

    Budget Request to Governing Board

    +
      +
    • Sponsorship of Material for MkDocs to obtain access to the Insiders Version at $125/month to support the TAC website
    • +
    • Wiki
        +
      • Options:
          +
        • Dokuwiki is currently included in our current LFIT budget
        • +
        • Confluence would be an additional $800/month
        • +
        • Continue utilizing GitHub wiki
        • +
        • Update the TAC website as necessary
        • +
        +
      • +
      • Discussion:
          +
        • Confluence is nice to allow for the ability to search across the entire foundation
        • +
        • Consider the migration costs
        • +
        • Confluence has a lot of nice features that GitHub wiki and Dokuwiki do not have
        • +
        • It is easier to bring markdown files into Confluence than to export to markdown
        • +
        • Most documentation for projects will be captured within projects as markdown files and hosted using something like ReadTheDocs.io or GitHub Pages
        • +
        • We do not currently have anyone that is asking for Confluence
        • +
        • If we sponsor Material for Mkdocs insiders version, then all OpenWallet Foundation projects will be able to utilize
        • +
        +
      • +
      • Outcome: We will postpone asking for budget until we have a need
      • +
      +
    • +
    • License Scanning
        +
      • Another project within the Linux Foundation cost is $65,000/year
      • +
      • We should ask for this as it allows us to remain compliant with the open licenses
      • +
      +
    • +
    • Package Hosting - GitHub? ghcr.io? Is there a package hosting solution for all technologies that exists?
        +
      • ghcr.io (GitHub Packages) is free for all public GitHub repositories – recommend we start there
      • +
      • Support for Package Registries
      • +
      • The only thing that we have currently that is not supported by GitHub Packages is Python
      • +
      +
    • +
    • Playground/Sandbox Hosting
        +
      • We do not yet have a price for this, but following are some of the things that we could see needing a sandbox
          +
        • Accessing server-side APIs
        • +
        • Deployment of server-based reference wallet
        • +
        • Interop testing
        • +
        • Reference implementation of data objects that a wallet contain - example VC issuance and verification
        • +
        +
      • +
      • Harm mentioned that he has some information on the infrastructure costs for hosting the European Interoperability Test Bed, which was presented to the architecture SIG on March 27, 2023. Harm will provide information on these costs
      • +
      • Harm is also interested in bringing the Interoperability Test Bed as a project to the OWF
      • +
      +
    • +
    • DevSecOps
        +
      • The Linux Foundation is recommending that projects use GH Actions
      • +
      • Automated security/code scanning
      • +
      • SonarQube - Static code analysis
      • +
      +
    • +
    +
  • +
  • +

    OWF Project Governance Guidance

    +
      +
    • Request to review, add comments and feedback
    • +
    • David Alexander recommended that we include information about momentum and duty of care and working across the foundation
    • +
    • Stavros asked if a TSC is required for projects
        +
      • No, a TSC is not mandatory. The idea is that if a project gets big enough where all the maintainers cannot get together easily and make decisions, more governance framework is needed, and this is the way to go in that case.
      • +
      • As such, we should make sure that this document provides the right level of guidance for projects at different stages in their lifecycle
      • +
      +
    • +
    +
  • +
  • +

    Call for code from the community

    +
      +
    • If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
    • +
    • Next time we meet, we will be reviewing the VC-API prject proposal
    • +
    +
  • +
  • +

    Open discussion and next steps

    +
      +
    • Next meeting is September 6, 2023
    • +
    +
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/meetings/2023/2023-09-06/index.html b/meetings/2023/2023-09-06/index.html new file mode 100644 index 00000000..65eb7621 --- /dev/null +++ b/meetings/2023/2023-09-06/index.html @@ -0,0 +1,4490 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 2023-09-06 - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

2023-09-06

+
+

Reminder

+

These meetings are covered by the Antitrust Policy and the Code of Conduct.

+
+

Agenda

+ + + +

TAC Voting Members

+
    +
  • David Zeuthen
  • +
  • Jeremie Miller
  • +
  • Pete Cooling
  • +
  • Stavros Kounis
  • +
  • Tracy Kuhrt
  • +
  • Troy Ronda
  • +
  • Wenjing Chu
  • +
+

Action Items

+
    +
  • Create recommendation for governing board for licenses that are compatible with Apache 2.0 to be approved -- Tracy
  • +
  • Update PR to answer questions asked during the meeting -- John
  • +
  • Determine if Energy Web Foundation is willing to relicense VC-API -- John
  • +
+

Meeting Minutes

+
    +
  • +

    Announcements

    +
      +
    • Credential Format Comparison SIG will meet on Wednesdays at 4pm CEST on alternate weeks to the TAC (next call September 13)
    • +
    • OID4VC Due Diligence task force will meet bi-weekly on Tuesdays at 5pm CEST (next call September 12)
    • +
    • Architecture SIG meets weekly on Mondays at 11am US/Pacific (next call September 11)
    • +
    +
  • +
  • +

    Review action items from last meeting

    + +
  • +
  • +

    Welcome new TAC member

    +
      +
    • We welcomed David Zeuthen, Google premier member representative
    • +
    +
  • +
  • +

    VC-API Project Proposal

    +
      +
    • How does this codebase relate to the energywebfoundation/ssi?
        +
      • Does this proposal refer to the ssi repository OR only to work under the /vc-api path?
          +
        • The intention is to bring over only the /vc-api path. We could consider whether it makes sense to bring over the other application, but it would require a separate proposal.
        • +
        +
      • +
      • Are there dependencies or references to any implementation outside this folder that need attention if it is the latter?
          +
        • Refer to the "Source Control" section of the proposal for information on what the dependencies are for the VC-API
        • +
        +
      • +
      • Could we prepare a list of all the single repositories the vc-api needs and will be part of this proposal? I would also suggest supplementing this list with the purpose of these additional repos and their relationship/dependencies to vc-api.
          +
        • This is captured in the "Source Control" section of the proposal.
        • +
        +
      • +
      • For licensing purposes, will we leave related repositories in the organization they currently are? Should we expect a licensing conflict in this case?
          +
        • John will follow up on the license with Energy Web Foundation.
        • +
        +
      • +
      • What referenced tutorials and documentation will moved from energywebfoundation GitHub organization to the OWF?
          +
        • Yes, we can move the tutorials and documentation into OWF.
        • +
        +
      • +
      +
    • +
    • Is this project an implementation of a VC API server or also client/wallet libraries?
        +
      • Server only
      • +
      +
    • +
    • Is this project based on the latest version of the CCG VC API? Does it already implement the full community report?
        +
      • It implements the latest published version of the CCG VC API. It may be missing one or two endpoints. I don't think that we have implemented derived presentation.
      • +
      +
    • +
    • Which credential formats and signature formats are supported?
        +
      • Those that are supported by SpruceID's DIDKit
      • +
      +
    • +
    • How have you tested interop?
        +
      • We have not yet tested interop. The testing that we have done is with the available test suites.
      • +
      +
    • +
    • What will be the prefix for this project?
        +
      • We need to determine a way in which projects can be separated if they implement the same specification. Project prefixes are a way to do this and will allow us to trademark them in the future.
      • +
      +
    • +
    • License
        +
      • John to follow up with Energy Web Foundation about the possibility or re-licensing
      • +
      • Develop recommendation for the OWF governing board on licenses that are compatible with Apache 2.0
      • +
      +
    • +
    • Missing DCO on existing repository
    • +
    +
  • +
  • +

    Call for code from the community

    +
      +
    • If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
    • +
    +
  • +
  • +

    Open discussion and next steps

    +
      +
    • Next meeting is September 20, 2023
    • +
    +
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/meetings/2023/2023-09-20/index.html b/meetings/2023/2023-09-20/index.html new file mode 100644 index 00000000..f63c016d --- /dev/null +++ b/meetings/2023/2023-09-20/index.html @@ -0,0 +1,4493 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 2023-09-20 - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

2023-09-20

+
+

Reminder

+

These meetings are covered by the Antitrust Policy and the Code of Conduct.

+
+

Agenda

+ + + +

TAC Voting Members

+
    +
  • David Zeuthen
  • +
  • Jeremie Miller
  • +
  • Pete Cooling
  • +
  • Stavros Kounis
  • +
  • Tracy Kuhrt
  • +
  • Troy Ronda
  • +
  • Wenjing Chu
  • +
+

Action Items

+
    +
  • Review, comment, and add feedback to the Wallet Framework .NET project proposal - all
  • +
  • Review, comment, and add feedback to the Intellectual Property Proposal - all
  • +
  • Digital Wallet and Agent Overview SIG
      +
    • Create Discord channel - Tracy
    • +
    • Add information to the TAC website regarding the SIG - Tracy
    • +
    • Add link to the above to the OpenWallet Foundation GitHub Profile - Tracy
    • +
    • Work with Maaike on infrastructure requirements (repo, mailing list) - Tracy/Maaike
    • +
    +
  • +
  • Anti-Correlation and Anti-Profiling SIG
      +
    • Create Discord channel - Tracy
    • +
    • Add information to the TAC website regarding the SIG - Tracy
    • +
    • Add link to the above to the OpenWallet Foundation GitHub Profile - Tracy
    • +
    • Work with Andy on infrastructure requirements (repo, mailing list) - Tracy/Andy
    • +
    +
  • +
  • Conduct email vote for VC-API project approval - Tracy - completed
  • +
+

Meeting Minutes

+
    +
  • +

    Announcements

    +
      +
    • Credential Format Comparison SIG will meet on Wednesdays at 4pm CEST on alternate weeks to the TAC (next call September 27)
    • +
    • OID4VC Due Diligence task force will meet bi-weekly on Tuesdays at 5pm CEST (next call September 26)
    • +
    • Architecture SIG meets weekly on Mondays at 11am US/Pacific (next call September 25)
    • +
    • New Project Proposal - Wallet Framework .NET - Please review
    • +
    • Suggested Future Project - Support the Apple pass format
    • +
    +
  • +
  • +

    Review action items from last meeting

    +
      +
    • Review, comment, and add feedback to OWF Project Governance Guidance by October 4th - all
    • +
    • Review, comment, and add feedback to VC-API project proposal - all
    • +
    • Provide infrastructure costs for the European Interoperability Test Bed - Harm Jan Arendshorst
    • +
    • Create recommendation for governing board for intellectual property policy -- Tracy -- completed
    • +
    • Update VC-API PR to answer questions asked during the meeting -- John – completed
    • +
    • Determine if Energy Web Foundation is willing to relicense VC-API -- John – completed
    • +
    +
  • +
  • +

    SIG Proposal - SSI Wallet and Agent Overviews

    + +
  • +
  • +

    SIG Proposal - Anti-Correlation and Anti-Profiling

    + +
  • +
  • +

    VC-API Project Proposal

    +
      +
    • Discussion
    • +
    • RESOLVED: That the VC-API lab is hereby confirmed, approved, and adopted.
        +
      • Since we did not have enough TAC voting members to meet the ⅔ supermajority vote, we will conduct an email vote.
      • +
      +
    • +
    +
  • +
  • +

    Intellectual Property Policy

    +
      +
    • Apache 2.0 for source code
    • +
    • CC-BY-4.0 for documentation
    • +
    • Allowed Third Party License Policy
    • +
    • RESOLVED: That the proposed Intellectual Property Policy will be forwarded to the Governing Board for consideration.
        +
      • Please review and provide your feedback
      • +
      • We will vote on this next time we meet
      • +
      +
    • +
    +
  • +
  • +

    Call for code from the community

    +
      +
    • If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
    • +
    +
  • +
  • +

    Open discussion and next steps

    +
      +
    • Next meeting is October 4, 2023
    • +
    • Discussed whether to move to weekly meetings to support influx of project proposals. It was determined that we could be more efficient on these calls if we commented on the PRs when they are submitted to get questions answered that may delay the vote.
    • +
    +
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/meetings/2023/2023-10-04/index.html b/meetings/2023/2023-10-04/index.html new file mode 100644 index 00000000..847c5e28 --- /dev/null +++ b/meetings/2023/2023-10-04/index.html @@ -0,0 +1,4468 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 2023-10-04 - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

2023-10-04

+
+

Reminder

+

These meetings are covered by the Antitrust Policy and the Code of Conduct.

+
+

Agenda

+ + + +

TAC Voting Members

+
    +
  • David Zeuthen
  • +
  • Jeremie Miller
  • +
  • Pete Cooling
  • +
  • Stavros Kounis
  • +
  • Tracy Kuhrt
  • +
  • Drummond Reed (alternate for Troy Ronda)
  • +
  • Wenjing Chu
  • +
+

Action Items

+
    +
  • Conduct email vote on the Intellectual Property Policy
  • +
  • Add project page for the Wallet Framework .NET project
  • +
  • Work with Sebastian to transfer Wallet Framework .NET project code to OWF
  • +
  • Review, comment, and add feedback to Android Identity Library project proposal - all
  • +
+

Meeting Minutes

+
    +
  • +

    Announcements

    +
      +
    • Credential Format Comparison SIG meets bi-weekly on Wednesdays at 4pm CEST on alternate weeks to the TAC (next call October 11)
    • +
    • OID4VC Due Diligence task force meets bi-weekly on Tuesdays at 5pm CEST (next call October 24)
    • +
    • Architecture SIG meets weekly on Mondays at 11am US/Pacific (next call October 16)
    • +
    • Please submit any code proposals using the process defined at openwallet-foundation/project-proposals. We will review proposals in the order submitted at a TAC meeting. If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up.
    • +
    • Pre-IIW Developer Face-to-Face October 9
    • +
    +
  • +
  • +

    Review action items from last meeting

    + +
  • +
  • +

    Project Proposal - Wallet Framework .NET

    +
      +
    • RESOLVED: That the Wallet Framework .NET proposal is hereby confirmed, approved, and adopted.
        +
      • Unanimously approved by the present TAC voting members.
      • +
      +
    • +
    +
  • +
  • +

    Project Proposal - Android Identity Library

    +
      +
    • RESOLVED: That the Android Identity Library proposal is hereby confirmed, approved, and adopted.
        +
      • Move to next meeting
      • +
      +
    • +
    +
  • +
  • +

    Intellectual Property Policy

    +
      +
    • Apache 2.0 for source code
    • +
    • CC-BY-4.0 for documentation
    • +
    • Allowed Third Party License Policy
    • +
    • Open Standards and Specifications
    • +
    • RESOLVED: That the proposed Intellectual Property Policy will be forwarded to the Governing Board for consideration.
        +
      • Conduct an email vote
      • +
      +
    • +
    +
  • +
  • +

    Open discussion and next steps

    +
      +
    • Discussion regarding conflict of the Safe Wallet SIG with other meetings
    • +
    • Standing agenda items that we might want to add:
        +
      • Socialization of what others in the community are doing
      • +
      • Project, SIG, Task Force updates
      • +
      +
    • +
    • Next meeting is October 20 2023
    • +
    +
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/meetings/2023/2023-10-18/index.html b/meetings/2023/2023-10-18/index.html new file mode 100644 index 00000000..847a6fda --- /dev/null +++ b/meetings/2023/2023-10-18/index.html @@ -0,0 +1,4474 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 2023-10-18 - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

2023-10-18

+
+

Reminder

+

These meetings are covered by the Antitrust Policy and the Code of Conduct.

+
+

Agenda

+
    +
  • Announcements
  • +
  • Review action items from last meeting
  • +
  • Welcome new TAC member (hold for next meeting)
  • +
  • Legal Discussion - Project Charters
  • +
  • Project Proposal - Android Identity Library
  • +
  • Project Proposal: SD-JWT JS
  • +
  • Open discussion and next steps
  • +
+ + +

TAC Voting Members

+
    +
  • David Zeuthen
  • +
  • Jeremie Miller
  • +
  • Pete Cooling
  • +
  • Stavros Kounis
  • +
  • Tracy Kuhrt
  • +
  • Drummond Reed (alternate for Mike Varley)
  • +
  • Wenjing Chu
  • +
+

Action Items

+
    +
  • Update project proposal template to make it easier for people to understand what the TAC is expecting for answers related to each question -- Tracy
  • +
  • Update project lifecycle to reflect project charters -- Tracy
  • +
  • Document the desire for OWF to utilize permissive licenses in the project lifecycle -- Tracy
  • +
  • Review, comment, and add feedback to SD-JWT JS lab proposal -- all
  • +
+

Meeting Minutes

+
    +
  • +

    Announcements

    +
      +
    • Architecture SIG meets weekly on Mondays at 11am US/Pacific (next call October 30)
    • +
    • OID4VC Due Diligence task force meets bi-weekly on Tuesdays at 5pm CEST (next call October 24)
    • +
    • Safe Wallet SIG meets weekly on Tuesdays at 8am US/Pacific (next call October 24)
    • +
    • Credential Format Comparison SIG meets bi-weekly on Wednesdays at 4pm CEST on alternate weeks to the TAC (next call October 25)
    • +
    • Digital Wallets and Agents Overviews SIG meets biweekly on Thursdays at 5:00pm CEST on alternate weeks to the TAC (next meeting October 26)
    • +
    • Please submit any code proposals using the process defined at https://github.com/openwallet-foundation/project-proposals. We will review proposals in the order submitted at a TAC meeting. If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up.
    • +
    +
  • +
  • +

    Review action items from last meeting

    +
      +
    • Conduct email vote on the Intellectual Property Policy – completed
    • +
    • Add project page for the Wallet Framework .NET project – completed
    • +
    • Work with Sebastian to transfer Wallet Framework .NET project code to OWF – completed
    • +
    • Review, comment, and add feedback to Android Identity Library project proposal - all
    • +
    • Provide infrastructure costs for the European Interoperability Test Bed - Harm Jan Arendshorst
    • +
    +
  • +
  • +

    Welcome New TAC Member

    +
      +
    • Mike Varley will represent Gen Digital moving forward.
    • +
    • Hold for next meeting as Mike could not attend today.
    • +
    +
  • +
  • +

    Legal Discussion

    +
      +
    • Discuss project charters
        +
      • Sample charter
      • +
      • Intake form
      • +
      • Copyleft vs. Permissive licenses (LF allows any OSI license. The OWF can decide on whether they only want permissive license.)
      • +
      +
    • +
    +
  • +
  • +

    Project Proposal - Android Identity Library

    +
      +
    • RESOLVED: That the Android Identity Library proposal is hereby confirmed, approved, and adopted.
        +
      • +

        6* Approve, 1 Abstain (David) - Project accepted

        +
        +

        Info (*)

        +

        During the meeting, Pete abstained. After the meeting, Pete changed his vote via email from Abstain to Approve.

        +
        +
      • +
      +
    • +
    +
  • +
  • +

    Project Proposal - SD-JWT JS

    + +
  • +
  • +

    Open discussion and next steps

    +
      +
    • David Alexander suggested that the OpenWallet Foundation work closely with MyData.
    • +
    • Next meeting is November 1, 2023
    • +
    +
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/meetings/2023/2023-11-01/index.html b/meetings/2023/2023-11-01/index.html new file mode 100644 index 00000000..0f8df2f0 --- /dev/null +++ b/meetings/2023/2023-11-01/index.html @@ -0,0 +1,4483 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 2023-11-01 - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

2023-11-01

+
+

Reminder

+

These meetings are covered by the Antitrust Policy and the Code of Conduct.

+
+

Agenda

+ + + +

TAC Voting Members

+
    +
  • David Zeuthen
  • +
  • Jeremie Miller
  • +
  • Mike Varley
  • +
  • Pete Cooling
  • +
  • Stavros Kounis
  • +
  • Tracy Kuhrt
  • +
  • Wenjing Chu
  • +
+

Action Items

+
    +
  • Update "permissive license" to "OSI-approved permissive license" in the project lifecycle and template PRs
  • +
  • Update Paid Tooling PR to reflect other requests require the Governing Board approval
  • +
  • Onboarding SD-JWT JS lab
      +
    • Create sd-jwt-js repo in OpenWallet Foundation Labs GitHub
    • +
    • Create sd-jwt-js Discord channel
    • +
    • Complete intake form to create project charter
    • +
    +
  • +
+

Meeting Minutes

+
    +
  • +

    Announcements

    +
      +
    • Architecture SIG meets weekly on Mondays at 11am US/Pacific (next call November 6)
    • +
    • OID4VC Due Diligence task force meets bi-weekly on Tuesdays at 5pm CEST (next call November 7)
    • +
    • Safe Wallet SIG meets weekly on Tuesdays at 8am US/Pacific (next call November 7)
    • +
    • Credential Format Comparison SIG meets bi-weekly on Wednesdays at 4pm CEST on alternate weeks to the TAC (next call November 8)
    • +
    • Digital Wallets and Agents Overviews SIG meets biweekly on Thursdays at 5:00pm CEST on the same weeks as the TAC (next meeting November 2)
    • +
    • Please submit any code proposals using the process defined at https://github.com/openwallet-foundation/project-proposals. We will review proposals in the order submitted at a TAC meeting. If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up.
    • +
    +
  • +
  • +

    Review action items from last meeting

    +
      +
    • Update project proposal template to make it easier for people to understand what the TAC is expecting for answers related to each question -- Tracy -- completed
    • +
    • Update project lifecycle to reflect project charters -- Tracy -- completed
    • +
    • Document the desire for OWF to utilize permissive licenses in the project lifecycle -- Tracy -- completed
    • +
    • Review, comment, and add feedback to SD-JWT JS lab proposal -- all
    • +
    • Work with John Henderson to transfer VC-API project to OpenWallet Foundation Labs
    • +
    • Work with David Zeuthen to transfer Android Identity Library project to OpenWallet Foundation Labs
    • +
    +
  • +
  • +

    Welcome New TAC Member

    +
      +
    • Mike Varley will represent Gen Digital moving forward.
    • +
    +
  • +
  • +

    Resolution: SD-JWT JS Project Proposal

    +
      +
    • RESOLVED: That the SD-JWT JS lab proposal is hereby confirmed, approved, and adopted.
        +
      • APPROVED with six yea, one absent
      • +
      +
    • +
    +
  • +
  • +

    Resolution: SD-JWT Rust Project Proposal

    + +
  • +
  • +

    Resolution: Proposal Process Updates

    + +
  • +
  • +

    Resolution: Project Services and Paid Tooling

    + +
  • +
  • +

    Open discussion and next steps

    +
      +
    • Next meeting is November 15, 2023
    • +
    +
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/meetings/2023/2023-11-15/index.html b/meetings/2023/2023-11-15/index.html new file mode 100644 index 00000000..358e0ff7 --- /dev/null +++ b/meetings/2023/2023-11-15/index.html @@ -0,0 +1,4472 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 2023-11-15 - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

2023-11-15

+
+

Reminder

+

These meetings are covered by the Antitrust Policy and the Code of Conduct.

+
+

Agenda

+ + + +

TAC Voting Members

+
    +
  • David Zeuthen
  • +
  • Jeremie Miller
  • +
  • Mike Varley
  • +
  • Pete Cooling
  • +
  • Stavros Kounis
  • +
  • Tracy Kuhrt
  • +
  • Wenjing Chu
  • +
+

Action Items

+
    +
  • Onboarding SD-JWT Rust lab
      +
    • Create sd-jwt-rust repo in OpenWallet Foundation Labs GitHub
    • +
    • Create sd-jwt-rust Discord channel
    • +
    • Complete intake form to create project charter -- follow up with LF Legal on status
    • +
    +
  • +
+

Meeting Minutes

+
    +
  • +

    Announcements

    +
      +
    • Architecture SIG meets weekly on Mondays at 11am US/Pacific (next call November 27; skipping week of US Thanksgiving)
    • +
    • OID4VC Due Diligence task force meets bi-weekly on Tuesdays at 5pm CET (next call November 21)
    • +
    • Safe Wallet SIG meets weekly on Tuesdays at 8am US/Pacific (next call November 21)
    • +
    • Credential Format Comparison SIG meets bi-weekly on Wednesdays at 4pm CET on alternate weeks to the TAC (next call November 22)
    • +
    • Digital Wallets and Agents Overviews SIG meets biweekly on Thursdays at 5:00pm CET on the same weeks as the TAC (next meeting November 16)
    • +
    • Please submit any code proposals using the process defined at https://github.com/openwallet-foundation/project-proposals. We will review proposals in the order submitted at a TAC meeting. If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up.
    • +
    • SIG quarterly updates will begin in January 2024
    • +
    +
  • +
  • +

    Review action items from last meeting

    +
      +
    • Update "permissive license" to "OSI-approved permissive license" in the project lifecycle and template PRs – completed and merged (lifecycle PR 69 and template PR 22)
    • +
    • Update Paid Tooling PR to reflect other requests require the Governing Board approval – completed and merged
    • +
    • Onboarding SD-JWT JS lab
        +
      • Create sd-jwt-js repo in OpenWallet Foundation Labs GitHub – completed
      • +
      • Create sd-jwt-js Discord channel – completed (#sd-jwt-js)
      • +
      • Complete intake form to create project charter
      • +
      +
    • +
    • Work with John Henderson to transfer VC-API project to OpenWallet Foundation Labs
    • +
    • Work with David Zeuthen to transfer Android Identity Library project to OpenWallet Foundation Labs
        +
      • Working on name of the project
      • +
      • David has been working with the downstream dependencies to make them aware of changes that will be coming
      • +
      +
    • +
    +
  • +
  • +

    Task Force Update: OID4VC Due Diligence

    +
      +
    • Update Slide Deck
    • +
    • Discussion about whether this task force should become a SIG
        +
      • At this time, we will leave this as a task force
      • +
      • The task force members will decide on the expanded time that is needed
      • +
      • At some point in the future, this may become an OID4VC Implementers SIG
      • +
      +
    • +
    +
  • +
  • +

    Resolution: SD-JWT Rust Project Proposal

    +
      +
    • RESOLVED: That the SD-JWT Rust lab proposal is hereby confirmed, approved, and adopted.
        +
      • Unanimously approved by the present TAC voting members.
      • +
      +
    • +
    +
  • +
  • +

    Resolution: SD-JWT .NET Project Proposal

    + +
  • +
  • +

    Open discussion and next steps

    +
      +
    • Next meeting is November 29, 2023
    • +
    +
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/meetings/2023/2023-11-29/index.html b/meetings/2023/2023-11-29/index.html new file mode 100644 index 00000000..b3f39d26 --- /dev/null +++ b/meetings/2023/2023-11-29/index.html @@ -0,0 +1,4462 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 2023-11-29 - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

2023-11-29

+
+

Reminder

+

These meetings are covered by the Antitrust Policy and the Code of Conduct.

+
+

Agenda

+ + + +

TAC Voting Members

+
    +
  • David Zeuthen
  • +
  • Jeremie Miller
  • +
  • Mike Varley
  • +
  • Pete Cooling
      +
    • Marie Austenaa
    • +
    +
  • +
  • Stavros Kounis
  • +
  • Tracy Kuhrt
  • +
  • Wenjing Chu
  • +
+

Action Items

+
    +
  • Onboard SD-JWT .NET
      +
    • Transfer sd-jwt-dotnet repo to OpenWallet Foundation Labs GitHub
    • +
    • Create sd-jwt-dotnet Discord channel
    • +
    • Follow up with LF Legal on project intake form
    • +
    +
  • +
  • Onboard Agent Framework JavaScript
      +
    • Transfer repos to OpenWallet Foundation Labs GitHub
    • +
    • Create agent-framework-js Discord channel
    • +
    • Follow up with LF Legal on project intake form
    • +
    +
  • +
+

Meeting Minutes

+
    +
  • +

    Announcements

    +
      +
    • Architecture SIG meets weekly on Mondays at 11am US/Pacific (next call December 4)
    • +
    • OID4VC Due Diligence task force meets bi-weekly on Tuesdays at 5pm CET (next call December 5)
    • +
    • Safe Wallet SIG meets weekly on Tuesdays at 7am US/Pacific (next call December 5)
    • +
    • Credential Format Comparison SIG meets bi-weekly on Wednesdays at 4pm CET on alternate weeks to the TAC (next call December 6)
    • +
    • Digital Wallets and Agents Overviews SIG meets biweekly on Thursdays at 5:00pm CET on the same weeks as the TAC (next meeting November 30)
    • +
    • Please submit any code proposals using the process defined at https://github.com/openwallet-foundation/project-proposals. We will review proposals in the order submitted at a TAC meeting. If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
    • +
    • SIG quarterly updates will begin in January 2024
    • +
    +
  • +
  • +

    Review action items from last meeting

    +
      +
    • Onboarding SD-JWT Rust lab
        +
      • Create sd-jwt-rust repo in OpenWallet Foundation Labs GitHub – completed
      • +
      • Create sd-jwt-rust Discord channel – completed (#sd-jwt-rust)
      • +
      • Complete intake form to create project charter -- follow up with LF Legal on status
      • +
      +
    • +
    • Work with John Henderson to transfer VC-API project to OpenWallet Foundation Labs
    • +
    • Work with David Zeuthen to transfer Android Identity Library project to OpenWallet Foundation Labs
    • +
    +
  • +
  • +

    Resolution: SD-JWT .NET Project Proposal

    +
      +
    • RESOLVED: That the SD-JWT .NET lab proposal is hereby confirmed, approved, and adopted.
    • +
    • Approved by role call vote; 7 aye, 0 nay, 0 abstain
    • +
    +
  • +
  • +

    Resolution: Agent Framework JavaScript Project Proposal

    +
      +
    • RESOLVED: That the Agent Framework JavaScript Project proposal is hereby confirmed, approved, and adopted.
    • +
    • Stavros Kounis agreed to be the second sponsor to bring the project in at growth stage
    • +
    • Approved by role call vote; 7 aye, 0 nay, 0 abstain
    • +
    +
  • +
  • +

    Open discussion and next steps

    + +
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/meetings/2023/2023-12-13/index.html b/meetings/2023/2023-12-13/index.html new file mode 100644 index 00000000..512eb581 --- /dev/null +++ b/meetings/2023/2023-12-13/index.html @@ -0,0 +1,4517 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 2023-12-13 - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

2023-12-13

+
+

Reminder

+

These meetings are covered by the Antitrust Policy and the Code of Conduct.

+
+

Agenda

+
    +
  • Announcements
  • +
  • Review action items from last meeting
  • +
  • Moving to LFX Meetings
  • +
  • Resolution: Add Schedule for Quarterly SIG Updates
  • +
  • 2023 Retrospective
  • +
  • Open discussion and next steps
  • +
+ + +

TAC Voting Members

+
    +
  • David Zeuthen
  • +
  • Jeremie Miller
  • +
  • Mike Varley
  • +
  • Pete Cooling
  • +
  • Stavros Kounis
  • +
  • Tracy Kuhrt
  • +
  • Wenjing Chu
  • +
+

Action Items

+
    +
  • Create Vulnerability Disclosure Policy
  • +
+

Meeting Minutes

+
    +
  • +

    Announcements

    +
      +
    • Architecture SIG meets weekly on Mondays at 11am US/Pacific (next call January 8)
    • +
    • OID4VC Due Diligence task force meets bi-weekly on Tuesdays at 5pm CET (next call December 19)
    • +
    • Safe Wallet SIG meets weekly on Tuesdays at 7am US/Pacific (next call December 19)
    • +
    • Credential Format Comparison SIG meets bi-weekly on Wednesdays at 4pm CET on alternate weeks to the TAC (next call December 20)
    • +
    • Digital Wallets and Agents Overviews SIG meets biweekly on Thursdays at 5:00pm CET on the same weeks as the TAC (next meeting December 14)
    • +
    • Please submit any code proposals using the process defined at https://github.com/openwallet-foundation/project-proposals. We will review proposals in the order submitted at a TAC meeting. If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
    • +
    +
  • +
  • +

    Review action items from last meeting

    +
      +
    • Onboard SD-JWT .NET – completed
        +
      • Transfer sd-jwt-dotnet repo to OpenWallet Foundation Labs GitHub – completed
      • +
      • Create sd-jwt-dotnet Discord channel – completed
      • +
      • Follow up with LF Legal on project intake form – completed
      • +
      +
    • +
    • Onboard Agent Framework JavaScript – completed
        +
      • Transfer repos to OpenWallet Foundation GitHub – completed
      • +
      • Create agent-framework-js Discord channel – completed
      • +
      • Follow up with LF Legal on project intake form – completed
      • +
      +
    • +
    • Work with John Henderson to transfer VC-API project to OpenWallet Foundation Labs – in progress
    • +
    • Work with David Zeuthen to transfer Android Identity Library project to OpenWallet Foundation Labs – completed
    • +
    +
  • +
  • +

    Moving to LFX Meetings

    + +
  • +
  • +

    Resolution: Add Schedule for Quarterly SIG Updates

    + +
  • +
  • +

    2023 Retrospective

    +
      +
    • Reviewed accomplishments
        +
      • Also include in the accomplishments the face-to-face and the discussion with LF Legal on project charters
      • +
      +
    • +
    • Retrospective
        +
      • Shoutouts?
          +
        • Google for hosting us at our face-to-face in Mountain View
        • +
        • Tracy for leading meetings
        • +
        • SIG and Task Force leaders
        • +
        +
      • +
      • What went well?
          +
        • Good structure on the TAC
        • +
        • Opportunity to collaborate
        • +
        • Consistency of how TAC meetings are managed and the access to the information needed so that you can do prep
        • +
        • Transparency
        • +
        • Inclusiveness
        • +
        • Team spirit
        • +
        • Advocacy
        • +
        • Provided confidence to move from being a consumer of open source to actually publishing open source at OWF
        • +
        • Learning process of what's involved in open source has been incredibly useful
        • +
        • Collaboration
        • +
        • Donation
        • +
        • Strong community engagement
        • +
        • Support OpenWallet has received in terms of projects, sponsors and Governmental Advisory Council members
        • +
        +
      • +
      • What could we do differently next year?
          +
        • Include voting members on the agenda and let people know who can vote at these meetings
        • +
        +
      • +
      • Recommendations for next year
          +
        • List of events for next year -- include in the #events channel on Discord
        • +
        • Creating a resource of slides that others have presented at conferences to present OWF
        • +
        • Challenge: helping projects grow within the OWF
        • +
        • Challenge: helping projects collaborate and work with one another
        • +
        • Engaging with the EUDI and bringing projects into OWF
        • +
        • Interoperability is a topic for us to focus on next year. Not just for the same protocols, but also across protocols. SIDI is also something that we should work closely with
        • +
        • Publish a white paper documenting our overall architectural considerations for open wallets (started already in the Architecture SIG)
        • +
        • Engaging with Trust Over IP
        • +
        +
      • +
      +
    • +
    +
  • +
  • +

    Open discussion and next steps

    + +
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/meetings/2024/2024-01-10/index.html b/meetings/2024/2024-01-10/index.html new file mode 100644 index 00000000..5572aeb0 --- /dev/null +++ b/meetings/2024/2024-01-10/index.html @@ -0,0 +1,4458 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 2024-01-10 - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

2024-01-10

+
+

Reminder

+

These meetings are covered by the Antitrust Policy and the Code of Conduct.

+
+

Agenda

+
    +
  • Announcements
  • +
  • Review action items from last meeting
  • +
  • Architecture SIG Update
  • +
  • Discuss Drafted Vulnerability Disclosure Policy
  • +
  • Goals for 2024 (time permitting)
  • +
  • Open discussion and next steps
  • +
+ + +

TAC Voting Members

+
    +
  • David Zeuthen
  • +
  • Jeremie Miller
  • +
  • Rolson Quadras (alternate for Mike Varley)
  • +
  • Pete Cooling
  • +
  • Stavros Kounis
  • +
  • Tracy Kuhrt
  • +
  • Wenjing Chu
  • +
+

Action Items

+
    +
  • List of TAC goals from other LF projects - Brian
  • +
  • Update Vulnerability Disclosure Pull Request - Tracy
  • +
+

Meeting Minutes

+
    +
  • +

    Announcements

    +
      +
    • Architecture SIG meets weekly on Mondays at 11am US/Pacific (next call January 15)
    • +
    • OID4VC Due Diligence task force meets bi-weekly on Tuesdays at 5pm CET (next call January 17)
    • +
    • Safe Wallet SIG meets weekly on Tuesdays at 7am US/Pacific (next call January 16)
    • +
    • Credential Format Comparison SIG meets bi-weekly on Wednesdays at 4pm CET on alternate weeks to the TAC (next call January 17)
    • +
    • Digital Wallets and Agents Overviews SIG meets biweekly on Thursdays at 5:00pm CET on the same weeks as the TAC (next meeting January 11)
    • +
    • Please submit any code proposals using the process defined at https://github.com/openwallet-foundation/project-proposals. We will review proposals in the order submitted at a TAC meeting. If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
    • +
    +
  • +
  • +

    Review action items from last meeting

    +
      +
    • Work with John Henderson to transfer VC-API project to OpenWallet Foundation Labs – completed
    • +
    • Create Vulnerability Disclosure Policy – drafted
    • +
    +
  • +
  • +

    Architecture SIG Update

    +
      +
    • See Architecture SIG Q1 2024 Update for the answers to the following questions:
        +
      • What is the Architecture SIG?
      • +
      • What has the Architecture SIG accomplished?
      • +
      • What is next for the Architecture SIG?
      • +
      • Where can I get information on the Architecture SIG?
      • +
      • How do I participate in the Architecture SIG?
      • +
      +
    • +
    • Discussion on how the Architecture SIG should work with projects
        +
      • In general, people see the role of the architecture SIG as a group that provides information on the state of the digital wallet architectues that can be used to provide insight into projects that may be missing from the OWF and in the long term a place that will help projects work more closely together.
      • +
      +
    • +
    +
  • +
  • +

    Discuss Drafted Vulnerability Disclosure Policy

    +
      +
    • Discuss pull request
    • +
    • Rework to consider the following audiences: reporters, people using the code, and maintainers
    • +
    • Separate out standard text from project-specific text
    • +
    +
  • +
  • +

    Goals for 2024

    +
      +
    • What specific goals does the TAC have for 2024?
        +
      • Brian suggested looking at what other TAC goals have been
      • +
      • Information for new submitters
      • +
      • Updates on existing projects
      • +
      +
    • +
    +
  • +
  • +

    Open discussion and next steps

    +
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/meetings/2024/2024-01-24/index.html b/meetings/2024/2024-01-24/index.html new file mode 100644 index 00000000..e53947c7 --- /dev/null +++ b/meetings/2024/2024-01-24/index.html @@ -0,0 +1,4502 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 2024-01-24 - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

2024-01-24

+
+

Reminder

+

These meetings are covered by the Antitrust Policy and the Code of Conduct.

+
+

Agenda

+ + + +

TAC Voting Members

+
    +
  • David Zeuthen
  • +
  • Jeremie Miller
  • +
  • Mike Varley
  • +
  • Marie Austenaa (alternate for Pete Cooling)
  • +
  • Stavros Kounis
  • +
  • Tracy Kuhrt
  • +
  • Wenjing Chu
  • +
+

Action Items

+ +

Meeting Minutes

+
    +
  • +

    Announcements

    +
      +
    • Architecture SIG meets weekly on Mondays at 11am US/Pacific (next call January 29)
    • +
    • OID4VC Due Diligence task force meets bi-weekly on Tuesdays at 5pm CET (next call January 30)
    • +
    • Safe Wallet SIG meets weekly on Tuesdays at 7am US/Pacific (next call January 30)
    • +
    • Credential Format Comparison SIG meets bi-weekly on Wednesdays at 4pm CET on alternate weeks to the TAC (next call January 31)
    • +
    • Digital Wallets and Agents Overviews SIG meets biweekly on Thursdays at 5:00pm CET on the same weeks as the TAC (next meeting January 25)
    • +
    • Please submit any code proposals using the process defined at https://github.com/openwallet-foundation/project-proposals. We will review proposals in the order submitted at a TAC meeting. If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
    • +
    +
  • +
  • +

    Review action items from last meeting

    +
      +
    • List of TAC goals from other LF projects – Brian
        +
      • Other projects at the LF only have a responsiblities list with the main goal of the TAC, TOC, or TSC to successfully carry out these responsibilities
      • +
      • Hyperledger Foundation has been putting together goals for the last couple of years (2023 Goals, 2024 Goals)
      • +
      +
    • +
    • Update Vulnerability Disclosure Policy – drafted
    • +
    +
  • +
  • +

    Project Proposal: Multi-format VC for iOS

    + +
  • +
  • +

    Discuss Vulnerability Disclosure Policy

    + +
  • +
  • +

    Elections

    +
      +
    • +

      RESOLVED: That we will run the 2024 elections based on the following schedule:

      +
        +
      • +

        TAC “At Large” Representatives

        +
          +
        • 2024-03-20 Nomination Period Begins
        • +
        • 2024-03-27 Noon PT Nomination Period Ends
        • +
        • 2024-03-27 Helios Voting Ballot Distributed to Existing TAC Members
        • +
        • 2024-04-02 Noon PT Voting Ends
        • +
        • 2024-04-02 Results Announced on the TAC mailing list
        • +
        • 2024-04-03 New “at large” representatives begin their term
        • +
        +
      • +
      • +

        TAC Chair and Vice Chair

        +
          +
        • 2023-04-03 Nomination Period Begins
        • +
        • 2023-04-10 Noon PT Nomination Period Ends
        • +
        • 2024-04-10 Helios Voting Ballot Distributed to Existing TAC Members
        • +
        • 2024-04-16 Noon PT Voting Ends
        • +
        • 2024-04-16 Results Announced on the TAC mailing list
        • +
        • 2024-04-17 New Chair and Vice Chair begin their term
        • +
        +
      • +
      • +

        Unanimously approved

        +
      • +
      +
    • +
    +
  • +
  • +

    Goals for 2024

    + +
  • +
  • +

    Open discussion and next steps

    +
      +
    • Next TAC Meeting February 7, 2024
        +
      • Credential Format Comparison SIG Update
      • +
      +
    • +
    +
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/meetings/2024/2024-02-07/index.html b/meetings/2024/2024-02-07/index.html new file mode 100644 index 00000000..006a90c1 --- /dev/null +++ b/meetings/2024/2024-02-07/index.html @@ -0,0 +1,4433 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 2024-02-07 - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

2024-02-07

+
+

Reminder

+

These meetings are covered by the Antitrust Policy and the Code of Conduct.

+
+

Agenda

+
    +
  • Announcements
  • +
  • Review action items from last meeting
  • +
  • Credential Format Comparison SIG Update
  • +
  • Open discussion and next steps
  • +
+ + +

TAC Voting Members

+
    +
  • David Zeuthen
  • +
  • Jeremie Miller
  • +
  • Mike Varley
  • +
  • Pete Cooling
  • +
  • Stavros Kounis
  • +
  • Tracy Kuhrt
  • +
  • Wenjing Chu
  • +
+

Action Items

+
    +
  • Sean to work with Mirko on a blog post on the Credential Format Comparison SIG
  • +
+

Meeting Minutes

+
    +
  • +

    Announcements

    +
      +
    • Architecture SIG meets weekly on Mondays at 11am US/Pacific (next call February 12)
    • +
    • OID4VC Due Diligence task force meets bi-weekly on Tuesdays at 5pm CET (next call February 13)
    • +
    • Safe Wallet SIG meets weekly on Tuesdays at 7am US/Pacific (next call February 13)
    • +
    • Credential Format Comparison SIG meets bi-weekly on Wednesdays at 4pm CET on alternate weeks to the TAC (next call February 14)
    • +
    • Digital Wallets and Agents Overviews SIG meets biweekly on Thursdays at 5:00pm CET on the same weeks as the TAC (next meeting February 8)
    • +
    • Please submit any code proposals using the process defined at https://github.com/openwallet-foundation/project-proposals. We will review proposals in the order submitted at a TAC meeting. If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
    • +
    +
  • +
  • +

    Review action items from last meeting

    + +
  • +
  • +

    Credential Format Comparison SIG Update

    +
  • +
  • +

    Open discussion and next steps

    +
      +
    • Next TAC Meeting February 21, 2024
        +
      • Digital Wallets and Agents Overview SIG Update
      • +
      +
    • +
    +
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/meetings/2024/2024-02-21/index.html b/meetings/2024/2024-02-21/index.html new file mode 100644 index 00000000..b16d90bc --- /dev/null +++ b/meetings/2024/2024-02-21/index.html @@ -0,0 +1,4455 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 2024-02-21 - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

2024-02-21

+
+

Reminder

+

These meetings are covered by the Antitrust Policy and the Code of Conduct.

+
+

Agenda

+
    +
  • Announcements
  • +
  • Review action items from last meeting
  • +
  • Digital Wallets and Agents Overviews SIG Update
  • +
  • Bifold Project Proposal
  • +
  • Project Promotion Process
  • +
  • Open discussion and next steps
  • +
+ + +

TAC Voting Members

+
    +
  • David Zeuthen
  • +
  • Jeremie Miller
  • +
  • Mike Varley
  • +
  • Pete Cooling
  • +
  • Stavros Kounis
  • +
  • Tracy Kuhrt
  • +
  • Wenjing Chu
  • +
+

Action Items

+
    +
  • Create a PR against the project lifecycle to include information on transitioning through the lifecycle stages -- Tracy
  • +
  • Work with Bifold to onboard project into OWF
  • +
+

Meeting Minutes

+
    +
  • +

    Announcements

    +
      +
    • Architecture SIG meets weekly on Mondays at 11am US/Pacific (next call February 26)
    • +
    • OID4VC Due Diligence task force meets bi-weekly on Tuesdays at 5pm CET (next call February 27)
    • +
    • Safe Wallet SIG meets weekly on Tuesdays at 7am US/Pacific (next call February 27)
    • +
    • Credential Format Comparison SIG meets bi-weekly on Wednesdays at 4pm CET on alternate weeks to the TAC (next call February 28)
    • +
    • Digital Wallets and Agents Overviews SIG meets biweekly on Thursdays at 5:00pm CET on the same weeks as the TAC (next meeting February 22)
    • +
    • Please submit any code proposals using the process defined at https://github.com/openwallet-foundation/project-proposals. We will review proposals in the order submitted at a TAC meeting. If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
    • +
    +
  • +
  • +

    Review action items from last meeting

    +
      +
    • Sean to work with Mirko on a blog post on the Credential Format Comparison SIG – in progress
    • +
    +
  • +
  • +

    Digital Wallets and Agents Overviews SIG Update

    +
      +
    • Information included in the slides on the work that is being done.
    • +
    +
  • +
  • +

    Bifold Project Proposal

    +
      +
    • RESOLVED: That the Bifold project proposal is hereby confirmed, approved, and adopted as a growth project.
        +
      • Wenjing volunteered to be second sponsor for the project
      • +
      • Jeremie motion; Wenjing seconded; Unanimously approved
      • +
      +
    • +
    +
  • +
  • +

    Project Promotion Process

    +
      +
    • Our current project lifecycle does not clearly outline the steps necessary for projects to progress in the lifecycle.
    • +
    • Suggested changes to the lifecycle to create a PR to update the original project proposal to include the new stage and other information relevant to meet the proposed stage’s criteria.
    • +
    • Upside: This process is similar to the original project proposal process.
    • +
    • Possible Downside: This will overwrite the original proposal but might not be a concern given the history in GitHub on the file.
    • +
    • If we do a PR to the original proposal, we will need to make sure that we can have links to the previous versions that were approved.
    • +
    • We can possibly do this via the project pages by adding a new section
    • +
    • Action: Tracy to create a PR to provide details on what this will look like.
    • +
    +
  • +
  • +

    Open discussion and next steps

    +
      +
    • Next TAC Meeting March 6, 2024
        +
      • Safe Wallet SIG Update
      • +
      +
    • +
    +
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/meetings/2024/2024-03-06/index.html b/meetings/2024/2024-03-06/index.html new file mode 100644 index 00000000..7124169b --- /dev/null +++ b/meetings/2024/2024-03-06/index.html @@ -0,0 +1,4450 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 2024-03-06 - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

2024-03-06

+
+

Reminder

+

These meetings are covered by the Antitrust Policy and the Code of Conduct.

+
+

Agenda

+ + + +

TAC Voting Members

+
    +
  • David Zeuthen
  • +
  • Jeremie Miller
  • +
  • Rolson Quadras (alternate for Mike Varley)
  • +
  • Pete Cooling
  • +
  • Stavros Kounis
  • +
  • Tracy Kuhrt
  • +
  • Wenjing Chu
  • +
+

Action Items

+
    +
  • Create discussion item to continue discussion on Wallet Stacks - Tracy -- completed
  • +
+

Meeting Minutes

+
    +
  • +

    Announcements

    +
      +
    • Architecture SIG meets weekly on Mondays at 11am US/Pacific (next call March 11)
    • +
    • OID4VC Due Diligence task force meets bi-weekly on Tuesdays at 5pm CET (next call March 12)
    • +
    • Safe Wallet SIG meets weekly on Tuesdays at 7am US/Pacific (next call March 12)
    • +
    • Credential Format Comparison SIG meets bi-weekly on Wednesdays at 4pm CET on alternate weeks to the TAC (next call March 13)
    • +
    • Digital Wallets and Agents Overviews SIG meets biweekly on Thursdays at 5:00pm CET on the same weeks as the TAC (next meeting March 7)
    • +
    • Please submit any code proposals using the process defined at https://github.com/openwallet-foundation/project-proposals. We will review proposals in the order submitted at a TAC meeting. If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
    • +
    • Reminder: Elections are coming up starting March 20, 2024; we will be accepting TAC “at large” nominations
    • +
    • Join the OpenWallet Foundation for our 1 year anniversary webinar on March 14, 9am PDT / 1700 CET / 9:30pm IST https://zoom.us/webinar/register/WN_MiUSaLFgQFOhVdTBMtlLuA#/registration
    • +
    +
  • +
  • +

    Review action items from last meeting

    +
      +
    • Create a PR against the project lifecycle to include information on transitioning through the lifecycle stages – complete
    • +
    • Work with Bifold to onboard project into OWF – completed
    • +
    +
  • +
  • +

    Safe Wallet SIG Update

    +
      +
    • Information included in the slides on the updates.
    • +
    +
  • +
  • +

    OWF Wallet Stacks

    + +
  • +
  • +

    Project Promotion Process

    +
      +
    • RESOLVED: That the project promotion process is hereby confirmed, approved, and adopted.
        +
      • Moved to the next meeting
      • +
      • Request that TAC members review the PR and provide any feedback
      • +
      +
    • +
    +
  • +
  • +

    Open discussion and next steps

    +
      +
    • Next TAC Meeting March 20 2024
    • +
    +
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/meetings/2024/2024-03-20/index.html b/meetings/2024/2024-03-20/index.html new file mode 100644 index 00000000..4acdf0f1 --- /dev/null +++ b/meetings/2024/2024-03-20/index.html @@ -0,0 +1,4462 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 2024-03-20 - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

2024-03-20

+
+

Reminder

+

These meetings are covered by the Antitrust Policy and the Code of Conduct.

+
+

Agenda

+ + + +

TAC Voting Members

+
    +
  • David Zeuthen
  • +
  • Jeremie Miller
  • +
  • Rolson Quadras (alternate for Mike Varley)
  • +
  • Pete Cooling
  • +
  • Stavros Kounis
  • +
  • Tracy Kuhrt
  • +
  • Wenjing Chu
  • +
+

Action Items

+
    +
  • Determine way to get the sample project charter more visible on the website.
  • +
+

Meeting Minutes

+
    +
  • +

    Announcements

    +
      +
    • Architecture SIG meets weekly on Mondays at 11am US/Pacific (next call March 25)
    • +
    • OID4VC Due Diligence task force meets bi-weekly on Tuesdays at 5pm CET (next call March 26)
    • +
    • Safe Wallet SIG meets weekly on Tuesdays at 7am US/Pacific (next call March 26)
    • +
    • Credential Format Comparison SIG meets bi-weekly on Wednesdays at 4pm CET on alternate weeks to the TAC (next call March 27)
    • +
    • Digital Wallets and Agents Overviews SIG meets biweekly on Thursdays at 5:00pm CET on the same weeks as the TAC (next meeting March 21)
    • +
    • Please submit any code proposals using the process defined at https://github.com/openwallet-foundation/project-proposals. We will review proposals in the order submitted at a TAC meeting. If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
    • +
    +
  • +
  • +

    Review action items from last meeting

    +
      +
    • Create discussion item to continue discussion on Wallet Stacks - Tracy -- completed
    • +
    +
  • +
  • +

    Project Promotion Process

    +
      +
    • RESOLVED: That the project promotion process is hereby confirmed, approved, and adopted.
        +
      • Motion - David Z; Seconded - Jeremie M
      • +
      • Unanimously approved
      • +
      +
    • +
    +
  • +
  • +

    TAC “At Large” Nomination Process

    +
      +
    • Submit nominations via a GitHub issue at 2024 "At Large" Nomination
    • +
    • Title of issue: [NOMINATION]: 2024 “at large” Name
    • +
    • Include a short bio, outline your qualifications, and provide a statement explaining why you would be a good choice for the seat
    • +
    +
  • +
  • +

    TAC "At Large" Voting Schedule

    +
      +
    • 2024-03-20 Nomination Period Begins
    • +
    • 2024-03-27 Noon PT Nomination Period Ends
    • +
    • 2024-03-27 Helios Voting Ballot Distributed to Existing TAC Members
    • +
    • 2024-04-02 Noon PT Voting Ends
    • +
    • 2024-04-02 Results Announced on the TAC mailing list
    • +
    • 2024-04-03 New “at large” representatives begin their term
    • +
    +
  • +
  • +

    Open discussion and next steps

    +
      +
    • Next TAC Meeting April 3 2024
        +
      • Architecture SIG Q2 Update
      • +
      +
    • +
    • Question asked about the OWF Developer Day on April 15 - should have more details early next week
    • +
    • Question asked about making it easier to find the sample project charter on the TAC website
    • +
    • Question asked about how to get sponsors for the SD-JWT JavaScript project to move to Growth - reach out to the TAC members (individually, on the #tac Discord channel, or on the TAC mailing list)
    • +
    • Question asked about how to find out what was going on in the community and how to get involved: +
    • +
    +
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/meetings/2024/2024-04-03/index.html b/meetings/2024/2024-04-03/index.html new file mode 100644 index 00000000..659c501d --- /dev/null +++ b/meetings/2024/2024-04-03/index.html @@ -0,0 +1,4482 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 2024-04-03 - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

2024-04-03

+
+

Reminder

+

These meetings are covered by the Antitrust Policy and the Code of Conduct.

+
+

Agenda

+
    +
  • Announcements
  • +
  • Review action items from last meeting
  • +
  • Welcome New “At Large” Representatives
  • +
  • Architecture SIG Q2 Update
  • +
  • TAC Chair/Vice Chair Nomination Process and Voting Schedule
  • +
  • Wiki Update
  • +
  • The Wallet Stack (and next steps)
  • +
  • Open discussion and next steps
  • +
+ + +

TAC Voting Members

+
    +
  • David Zeuthen
  • +
  • Jaehoon (Ace) Shim
  • +
  • Mike Varley
  • +
  • Pete Cooling
  • +
  • Stavros Kounis
  • +
  • Tracy Kuhrt
  • +
  • Wenjing Chu
  • +
+

Action Items

+
    +
  • Create a content plan for where stuff should live and who should control the content
  • +
+

Meeting Minutes

+
    +
  • +

    Announcements

    +
      +
    • Architecture SIG meets weekly on Mondays at 11am US/Pacific (next call April 8)
    • +
    • OID4VC Due Diligence task force meets bi-weekly on Tuesdays at 5pm CET (next call April 9)
    • +
    • Safe Wallet SIG meets weekly on Tuesdays at 7am US/Pacific (next call April 9)
    • +
    • Credential Format Comparison SIG meets bi-weekly on Wednesdays at 4pm CET on alternate weeks to the TAC (next call April 10)
    • +
    • Digital Wallets and Agents Overviews SIG meets biweekly on Thursdays at 5:00pm CET on the same weeks as the TAC (next meeting April 4)
    • +
    • Please submit any code proposals using the process defined at https://github.com/openwallet-foundation/project-proposals. We will review proposals in the order submitted at a TAC meeting. If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
    • +
    • Jorge Flores (Co-Founder & CTO of Entidad) and Jesus Torres (Co-Founder & CEO of Entidad): How an Aries digital trust ecosystem helped distribute $60M USD (& counting) to essential workers - Presenting at the Hyperledger Identity Special Interest Group on Thursday, April 4 @ 3PM UTC, 8AM PDT, 9AM MDT, 11AM EDT. Join on Zoom: https://zoom.us/j/93003523877?pwd=Q3VvMnJ1N0lSUEZSc283SmFGRk9SQT09
    • +
    • IIW Planning discussion taking place on Discord in the #iiw-planning channel
    • +
    • EIC Planning discussions taking place on Discord in the #eic-planning channel
    • +
    +
  • +
  • +

    Review action items from last meeting

    +
      +
    • Determine way to get the sample project charter more visible on the website -- completed
    • +
    +
  • +
  • +

    Welcome New “At Large” Representatives

    +
      +
    • Thank you to all the nominees.
    • +
    • Welcome back, Stavros!
    • +
    • Welcome, Ace!
    • +
    • Thank you for your service, Jeremie!
    • +
    +
  • +
  • +

    Architecture SIG Q2 Update

    + +
  • +
  • +

    TAC Chair/Vice Chair Nomination Process

    +
      +
    • Only TAC voting members are eligible to run for the TAC chair and vice chair seats
    • +
    • Electing a vice chair will be held in conjunction with the chair election; the person with the second highest number of votes will serve as the vice chair
    • +
    • Submit nominations via a GitHub issue at 2024 Chair/Vice Chair Nomination
    • +
    • Title of issue: [NOMINATION]: 2024 Chair/Vice Chair Name
    • +
    • Include a short bio, outline your qualifications, and provide a statement explaining why you would be a good choice for the seat
    • +
    • See Elections for more information
    • +
    +
  • +
  • +

    TAC Chair/Vice Chair Voting Schedule

    +
      +
    • 2024-04-03 Nomination Period Begins
    • +
    • 2024-04-10 Noon PT Nomination Period Ends
    • +
    • 2024-04-10 Helios Voting Ballot Distributed to Existing TAC Members
    • +
    • 2024-04-16 Noon PT Voting Ends
    • +
    • 2024-04-16 Results Announced on the TAC mailing list
    • +
    • 2024-04-17 New Chair and Vice Chair begin their term
    • +
    +
  • +
  • +

    Wiki Update

    +
      +
    • https://wiki.openwallet.foundation
    • +
    • Discussion about content plan. Where should information live? Who is responsible for changes?
    • +
    • TAC website makes sense for things that the TAC is responsible for
    • +
    • The maintainers should be responsible for project information
    • +
    • The LF Staff is responsible for the openwallet.foundation website content
    • +
    +
  • +
  • +

    The Wallet Stack (and next steps)

    +
      +
    • Formation of a Secure Hardware SIG
    • +
    • Looking for interested parties
    • +
    +
  • +
  • +

    Open discussion and next steps

    +
      +
    • Next TAC Meeting April 17, 2024
    • +
    +
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/meetings/2024/2024-04-17/index.html b/meetings/2024/2024-04-17/index.html new file mode 100644 index 00000000..1b185d5f --- /dev/null +++ b/meetings/2024/2024-04-17/index.html @@ -0,0 +1,4464 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 2024-04-17 - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

2024-04-17

+
+

Reminder

+

These meetings are covered by the Antitrust Policy and the Code of Conduct.

+
+

Agenda

+ + + +

TAC Voting Members

+
    +
  • David Zeuthen
  • +
  • Jaehoon (Ace) Shim
  • +
  • Mike Varley
  • +
  • Pete Cooling
  • +
  • Stavros Kounis
  • +
  • Tracy Kuhrt
  • +
  • Wenjing Chu
  • +
+

Action Items

+
    +
  • Set up new lab eudi-wallet-kit-react-native
      +
    • Discord channel
    • +
    • GitHub repo
    • +
    +
  • +
+

Meeting Minutes

+
    +
  • +

    Announcements

    +
      +
    • Architecture SIG meets weekly on Mondays at 11am US/Pacific (next call April 22)
    • +
    • OID4VC Due Diligence task force meets bi-weekly on Tuesdays at 5pm CET (next call April 23)
    • +
    • Safe Wallet SIG meets weekly on Tuesdays at 7am US/Pacific (next call April 23)
    • +
    • Credential Format Comparison SIG meets bi-weekly on Wednesdays at 4pm CET on alternate weeks to the TAC (next call April 24)
    • +
    • Digital Wallets and Agents Overviews SIG meets biweekly on Thursdays at 5:00pm CET on the same weeks as the TAC (next meeting April 18)
    • +
    • Please submit any code proposals using the process defined at https://github.com/openwallet-foundation/project-proposals. We will review proposals in the order submitted at a TAC meeting. If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
    • +
    • EIC Planning discussions taking place on Discord in the #eic-planning channel
    • +
    • The Hyperledger Identity SIG (ID SIG) recently hosted Jorge and Jesus from Entidad for "How The Aries Digital Trust Ecosystem Helped Distribute $60M USD (and counting) to Essential Workers. You can check out the recording on YouTube.
    • +
    • Michel Sahli is our GAC representative
    • +
    +
  • +
  • +

    Review action items from last meeting

    +
      +
    • Create a content plan for where stuff should live and who should control the content -- in progress
    • +
    +
  • +
  • +

    Chair/Vice Chair Results

    +
      +
    • Thank you to all nominees
    • +
    • Stavros, vice chair
    • +
    • Tracy, chair
    • +
    +
  • +
  • +

    Project Proposal: React Native Kit for EUDI Wallet Reference Implementation

    + +
  • +
  • +

    OWF Naming Policy Update

    +
      +
    • Reviewed Project Naming Policy
    • +
    • Request that the community provide suggested edits and comments
    • +
    • After incoming feedback, Sean will work with the LF Staff prior to bringing back to the TAC for approval
    • +
    +
  • +
  • +

    Content Plan

    +
      +
    • Quickly reviewed Content Plan
    • +
    • Request that the community provide suggested edits and comments
    • +
    • Determine where source of truth is for certain items, like the project list
    • +
    +
  • +
  • +

    Open discussion and next steps

    +
      +
    • Next TAC Meeting May 1, 2024
    • +
    +
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/meetings/2024/2024-05-01/index.html b/meetings/2024/2024-05-01/index.html new file mode 100644 index 00000000..0d622e80 --- /dev/null +++ b/meetings/2024/2024-05-01/index.html @@ -0,0 +1,4454 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 2024-05-01 - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

2024-05-01

+
+

Reminder

+

These meetings are covered by the Antitrust Policy and the Code of Conduct.

+
+

Agenda

+
    +
  • Announcements
  • +
  • Review action items from last meeting
  • +
  • Credential Format Comparison SIG Q2 Update
  • +
  • Content Plan
  • +
  • Reference Architecture contribution
  • +
  • Open discussion and next steps
  • +
+ + +

TAC Voting Members

+
    +
  • David Zeuthen
  • +
  • Jaehoon (Ace) Shim
  • +
  • Rolson Quandras (alternate for Mike Varley)
  • +
  • Pete Cooling
  • +
  • Stavros Kounis
  • +
  • Tracy Kuhrt
  • +
  • Wenjing Chu
  • +
+

Action Items

+
    +
  • Update Content Plan PR to include links
  • +
+

Meeting Minutes

+
    +
  • +

    Announcements

    +
      +
    • Architecture SIG meets weekly on Mondays at 11am US/Pacific (next call May 6)
    • +
    • OID4VC Due Diligence task force meets bi-weekly on Tuesdays at 5pm CET (next call May 7)
    • +
    • Safe Wallet SIG meets weekly on Tuesdays at 7am US/Pacific (next call May 7)
    • +
    • Credential Format Comparison SIG meets bi-weekly on Wednesdays at 4pm CET on alternate weeks to the TAC (next call May 8)
    • +
    • Digital Wallets and Agents Overviews SIG meets biweekly on Thursdays at 5:00pm CET on the same weeks as the TAC (next meeting May 2)
    • +
    • Please submit any code proposals using the process defined at https://github.com/openwallet-foundation/project-proposals. We will review proposals in the order submitted at a TAC meeting. If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
    • +
    • EIC Planning discussions taking place on Discord in the #eic-planning channel
    • +
    +
  • +
  • +

    Review action items from last meeting

    + +
  • +
  • +

    Content Plan

    +
      +
    • RESOLVED: That the Content Plan is hereby confirmed, approved, and adopted.
        +
      • Wenjing motion; Rolson seconded
      • +
      • Unanimously approved by the present TAC voting members
      • +
      +
    • +
    +
  • +
  • +

    Reference Architecture Contribution

    +
      +
    • Pull Request (Rendered version)
    • +
    • Proposed next steps:
        +
      • Input from community - please provide comments on the PR
      • +
      • Add a heatmap that maps our current projects to the technology capabilities
      • +
      +
    • +
    • David Z is concerned that the whitepaper may conflict with existing guidance
    • +
    • Request that a list of existing guidance be provided in the PR so that we may validate that the reference architecture whitepaper does not conflict with existing guidance
    • +
    +
  • +
  • +

    Open discussion and next steps

    +
      +
    • Next TAC Meeting May 15 2024
    • +
    • Digital Wallet and Agent Overviews SIG Update
    • +
    • OID4VC Due Diligence task force update
    • +
    • Project Proposal: Library for OpenID4BLE
    • +
    +
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/meetings/2024/2024-05-15/index.html b/meetings/2024/2024-05-15/index.html new file mode 100644 index 00000000..cef9ed6c --- /dev/null +++ b/meetings/2024/2024-05-15/index.html @@ -0,0 +1,4479 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 2024-05-15 - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

2024-05-15

+
+

Reminder

+

These meetings are covered by the Antitrust Policy and the Code of Conduct.

+
+

Agenda

+ + + +

TAC Voting Members

+
    +
  • David Zeuthen
  • +
  • Jaehoon (Ace) Shim
  • +
  • Rolson Quadras
  • +
  • Stefan Kauhaus (alternate for Pete Cooling)
  • +
  • Stavros Kounis
  • +
  • Tracy Kuhrt
  • +
  • Wenjing Chu
  • +
+

Action Items

+
    +
  • Onboard OpenID4BLE Library lab
  • +
  • Onboard Trust Spanning Protocol lab
  • +
+

Meeting Minutes

+
    +
  • +

    Announcements

    +
      +
    • Architecture SIG meets weekly on Mondays at 11am US/Pacific (next call June 3)
    • +
    • Safe Wallet SIG meets weekly on Tuesdays at 7am US/Pacific (next call June 4)
    • +
    • Credential Format Comparison SIG meets bi-weekly on Wednesdays at 4pm CET on alternate weeks to the TAC (next call June 5)
    • +
    • Digital Wallets and Agents Overviews SIG meets biweekly on Thursdays at 5:00pm CET on the same weeks as the TAC (next meeting May 30)
    • +
    • Please submit any code proposals using the process defined at https://github.com/openwallet-foundation/project-proposals. We will review proposals in the order submitted at a TAC meeting. If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
    • +
    • EIC Planning discussions taking place on Discord in the #eic-planning channel
    • +
    +
  • +
  • +

    Welcome new TAC member

    +
      +
    • Rolson Quadras will represent Gen Digital moving forward
    • +
    • Thank you Mike Varley for your service
    • +
    +
  • +
  • +

    Review action items from last meeting

    +
      +
    • Update Content Plan PR to include links - completed
    • +
    +
  • +
  • +

    Project Proposal: OpenId4BLE Library

    +
      +
    • Recommended that project come in at Labs stage
    • +
    • Recommended that project move to GitHub issues (to be completed in 3-6 months)
    • +
    • Recommended that project use Discord for communication instead of Slack
    • +
    • Discussed governance and diversity of maintainers
    • +
    • RESOLVED: That the OpenId4BLE Library lab proposal is hereby confirmed, approved, and adopted.
        +
      • Stavros motioned; David seconded
      • +
      • Unanimously approved by the present TAC voting members.
      • +
      +
    • +
    +
  • +
  • +

    Project Proposal: Trust Spanning Protocol

    +
      +
    • Discussed the need for language bindings that can be used by OWF projects. Recommendation is to implement the language bindings in conjunction with the projects that will use it to ensure correctness.
    • +
    • Research needs to be done on the license of https://github.com/dalek-cryptography/curve25519-dalek and whether an alternate implementation is needed
    • +
    • RESOLVED: That the Trust Spanning Protocol lab proposal is hereby confirmed, approved, and adopted.
        +
      • Stavros motioned; Rolson seconded
      • +
      • Unanimously approved by the present TAC voting members.
      • +
      +
    • +
    +
  • +
  • +

    Project Annual Reviews

    + +
  • +
  • +

    OID4VC Due Diligence Task Force Update

    +
      +
    • Torsten provided an update on the OID4VC Due Diligence task force and recommended closing the task force as it has accomplished its goals.
    • +
    +
  • +
  • +

    Open discussion and next steps

    +
      +
    • Next TAC Meeting May 29, 2024
        +
      • Digital Wallet and Agent Overviews SIG Update
      • +
      +
    • +
    +
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/meetings/2024/2024-05-29/index.html b/meetings/2024/2024-05-29/index.html new file mode 100644 index 00000000..75791d10 --- /dev/null +++ b/meetings/2024/2024-05-29/index.html @@ -0,0 +1,4470 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 2024-05-29 - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

2024-05-29

+
+

Reminder

+

These meetings are covered by the Antitrust Policy and the Code of Conduct.

+
+

Agenda

+ + + +

TAC Voting Members

+
    +
  • David Zeuthen
  • +
  • Jaehoon (Ace) Shim
  • +
  • Rolson Quadras
  • +
  • Pete Cooling
  • +
  • Stavros Kounis
  • +
  • Tracy Kuhrt
  • +
  • Wenjing Chu
  • +
+

Action Items

+
    +
  • Onboard Credhub project
      +
    • Create Discord channel
    • +
    • Transfer repo
    • +
    • Create project page
    • +
    +
  • +
+

Meeting Minutes

+
    +
  • +

    Announcements

    +
      +
    • Please see the OpenWallet Foundation calendar for a list of upcoming meetings
    • +
    • Please submit any code proposals using the process defined at https://github.com/openwallet-foundation/project-proposals. We will review proposals in the order submitted at a TAC meeting. If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
    • +
    • EIC Planning discussions taking place on Discord in the #eic-planning channel
    • +
    • If you are interested in participating in the architecture SIG calls, we have a when2meet survey out there to find a new meeting time
    • +
    • EUDI Architecture Reference Framework v1.4 published
    • +
    • OpenWallet Foundation is hosting two workshops -- one for OpenID Connect for VCI and one for OpenID Connect for VP -- on June 10th and June 12th. Please be on the lookout for registration links coming soon
    • +
    +
  • +
  • +

    Review action items from last meeting

    +
      +
    • Onboard OpenID4BLE Library lab
        +
      • Created Discord channel (#tuvali) - completed
      • +
      • Need to transfer repo (Issue #151) - in progress
      • +
      • Working on project page (PR #149) - in progress
      • +
      +
    • +
    • Onboard Trust Spanning Protocol lab
        +
      • Created Discord channel (#tsp) - completed
      • +
      • Need to transfer repo (Issue #150) - in progress
      • +
      • Working on project page (PR #149) - in progress
      • +
      +
    • +
    +
  • +
  • +

    Project Proposal: credhub

    +
      +
    • RESOLVED: That the credhub lab proposal is hereby confirmed, approved, and adopted.
        +
      • Stavros motioned; Wenjing seconded
      • +
      • Unanimously approved
      • +
      +
    • +
    +
  • +
  • +

    Project Annual Reviews

    + +
  • +
  • +

    Digital Wallet and Agent Overviews SIG Update

    + +
  • +
  • +

    Open discussion and next steps

    +
      +
    • Next TAC Meeting June 12, 2024
        +
      • SD-JWT Python Annual Review
      • +
      • SD-JWT Kotlin Annual Review
      • +
      • Safe Wallet SIG Update
      • +
      +
    • +
    +
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/meetings/2024/2024-06-12/index.html b/meetings/2024/2024-06-12/index.html new file mode 100644 index 00000000..7b44ad04 --- /dev/null +++ b/meetings/2024/2024-06-12/index.html @@ -0,0 +1,4493 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 2024-06-12 - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

2024-06-12

+
+

Reminder

+

These meetings are covered by the Antitrust Policy and the Code of Conduct.

+
+

Agenda

+ + + +

TAC Voting Members

+
    +
  • David Zeuthen
  • +
  • Jaehoon (Ace) Shim
  • +
  • Rolson Quadras
  • +
  • Pete Cooling
  • +
  • Stavros Kounis
  • +
  • Tracy Kuhrt
  • +
  • Wenjing Chu
  • +
+

Action Items

+
    +
  • Onboard mdl.js
  • +
  • Reach out to Fabian regarding new maintainership - Sean/Torsten
  • +
  • File PR against openwallet-foundation-labs/governance to update maintainership for sd-jwt-kotlin - Ace
  • +
+

Meeting Minutes

+
    +
  • +

    Announcements

    +
      +
    • Please see the OpenWallet Foundation calendar for a list of upcoming meetings
    • +
    • Please submit any code proposals using the process defined at https://github.com/openwallet-foundation/project-proposals. We will review proposals in the order submitted at a TAC meeting. If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
    • +
    • Architecture SIG call is moving to Mondays at 8:30 AM US/Pacific starting June 17
    • +
    • Wednesday June 12 - Part 2: OpenID4VCI This webinar will give an overview of one of the technical standards that underpin EUDIW ARF: OpenID4VCI, which defines an API for the issuance of Digital Credentials. The focus will be on the technical details and timelines, and answering questions from the participants/implementers. Registration
    • +
    • Video from Monday’s OpenID4VP workshop/AMA with Kristina and Oliver
    • +
    +
  • +
  • +

    Review action items from last meeting

    + +
  • +
  • +

    Project Proposal: mdl.js

    +
      +
    • RESOLVED: That the mdl.js lab proposal is hereby confirmed, approved, and adopted.
        +
      • Ace motioned; Pete seconded
      • +
      • Unanimously approved by the present TAC voting members
      • +
      +
    • +
    +
  • +
  • +

    Project Annual Reviews

    +
      +
    • SD-JWT Python Annual Review
        +
      • RESOLVED: TAC members agree to continue to sponsor the SD-JWT Python lab at its current stage
          +
        • Wenjing motioned; Ace seconded
        • +
        • Unanimously approved by the present TAC voting members
        • +
        +
      • +
      +
    • +
    • +

      SD-JWT Kotlin Annual Review: Opened issue openwallet-foundation-labs/sd-jwt-python#22 on May 30, 2024

      +
        +
      • +

        Discussion around whether we should move this project to Emeritus given the statement in the README

        +
        +

        Quote

        +

        Important note: This project is no longer maintained. We recommend using the eudi-lib-jvm-sdjwt-kt library instead. If you are interested in maintaining this project, please contact Fabian Hauck.

        +
        +
      • +
      • +

        Ace volunteered to maintain this project going forward

        +
      • +
      +
    • +
    +
  • +
  • +

    Safe Wallet SIG Update

    + +
  • +
  • +

    Open discussion and next steps

    +
      +
    • Next TAC Meeting June 26, 2024
        +
      • Discuss approval process for SIG output
      • +
      +
    • +
    +
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/meetings/YYYY-mm-dd/index.html b/meetings/YYYY-mm-dd/index.html new file mode 100644 index 00000000..97f9ac5a --- /dev/null +++ b/meetings/YYYY-mm-dd/index.html @@ -0,0 +1,4171 @@ + + + + + + + + + + + + + + + + + + + + + + YYYY-mm-dd - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + +

YYYY-mm-dd

+
+

Reminder

+

These meetings are covered by the Antitrust Policy and the Code of Conduct.

+
+

Agenda

+
    +
  • Include agenda items here.
  • +
+

TAC Voting Members

+
    +
  • David Zeuthen
  • +
  • Jaehoon (Ace) Shim
  • +
  • Mike Varley
  • +
  • Pete Cooling
  • +
  • Stavros Kounis
  • +
  • Tracy Kuhrt
  • +
  • Wenjing Chu
  • +
+

Notes

+
    +
  • Include discussion notes here.
  • +
+

Recording

+ + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/meetings/index.html b/meetings/index.html new file mode 100644 index 00000000..74716ae3 --- /dev/null +++ b/meetings/index.html @@ -0,0 +1,4190 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + TAC Meetings - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/projects/bifold/index.html b/projects/bifold/index.html new file mode 100644 index 00000000..b7fb456b --- /dev/null +++ b/projects/bifold/index.html @@ -0,0 +1,4379 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Bifold - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Bifold

+

Project Description

+

Bifold is an open-source project designed to enhance the way we interact with digital identities, making the process both secure and user-friendly. It is based on React Native, which lets it run smoothly on different devices and platforms, such as iOS, and Android. It is a leading example of digital wallets, with a focus on making verifiable credentials (VCs) simple and convenient for everyone. Our mission is to create a collaborative community that enhances the way digital credentials are handled, making them accessible and straightforward for all.

+

Key Features and Benefits:

+
    +
  • +

    Unified Digital Identity Management: Emphasizing security and user-friendliness, Bifold excels in consolidating and managing digital identities across various standards like AnonCreds and W3C VC Data Model. This capability positions Bifold as a pivotal resource for secure and private handling of digital identities, accessible to all.

    +
  • +
  • +

    Seamless Multi-Platform Use: Thanks to its React Native architecture, Bifold delivers a smooth experience on any device, enabling users to manage their digital identities whether they are using a phone or a tablet. This cross-platform flexibility means that developers can create applications once and deploy them on both iOS and Android, ensuring a consistent and accessible user experience.

    +
  • +
  • +

    Community-Driven Development: Bifold is more than a tool; it's a community initiative aimed at fostering collaboration and sharing innovations. By bringing together diverse groups, from organizations to individuals, Bifold encourages the pooling of resources and knowledge to facilitate the broader adoption and understanding of verifiable credentials.

    +
  • +
  • +

    Widespread Adoption and Trust: With a growing list of users around the globe, including governmental bodies in Canada and teams in Brazil, Bifold has proven its reliability and relevance. Its international use showcases the platform's adaptability to various needs and its role in advancing digital identity management on a global scale.

    +
  • +
  • +

    Adaptability to Diverse Needs: Bifold's design caters to a wide range of project types and complexities, offering tailored solutions for managing digital identities. This adaptability ensures that users can streamline their processes related to verifiable credentials, improving efficiency and simplification in digital identity initiatives.

    +
  • +
+

Source Repositories

+ +

Chat Channel

+ +

History

+ + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/projects/credhub/index.html b/projects/credhub/index.html new file mode 100644 index 00000000..4e4cf9a5 --- /dev/null +++ b/projects/credhub/index.html @@ -0,0 +1,4485 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Credhub - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Credhub

+

Project Description

+

When talking about wallets for natural persons, a lot of people think that a smartphone based wallet is the only way to go. The user should feel the security and privacy by being independent from an external provider. But we are forgetting that online based services have a great user experience in daily life: +- As a user I can use multiple clients where my data is synced, we do not have to care about backups or data recovery. +- As a developer I can implement the business logic into the cloud and only need the rendering on the client side.

+

Yes, when I am offline, I do not have access to my data anymore. But beside that the user experience is great!

+

The credhub project is a typescript based monorepo, using nx to manage multiple components. Compared to other approaches, it also comes with an issuer and verifier service to issue and verify credentials.

+

Clients

+

There are two clients that can be used to interact with a cloud wallet +- a PWA based on Angular +- a Chrome Browser Extension based on Angular

+

While the PWA is using the camera to scan QR codes, the browser extension is scanning the opened taps for QR codes and is able to show a little button next to the QR code to interact with the wallet. This approach was inspired by password managers like 1Password. In the daily use, People do not want to take out their smartphone to scan a QR code, they want an easy one click solution.

+

By implementing the whole business logic in the cloud, the client is only responsible for the rendering. Therefore building new clients in other programming languages is easy by using the OpenAPI endpoints. For authentication the OpenID Connect protocol is used, the project is using the Keycloak server for that.

+

Issuer and Verifier

+

Both relying parties are implemented as separate services, each of them comes with a web client for demo purposes. Further integration like webhooks or other services can be implemented in the future. The authentication is done by using the OpenID Connect protocol.

+

Modular approach

+

The usage of NX allows reusable components with a modular approach. Each backend implementation supports low security key management by storing the keys in the filesystem or the database, or the integration with Hashicorp Vault for high security key management. Other implementations are possible.

+

Identity Stack

+

By validating existing SSI frameworks like Credo or Veramo, this project should primary focus on the architecture reference framework of the EU. Therefore other credential formats, transport protocols or key managements like multiple DIDs methods are not supported.

+

Credential Profile:

+
    +
  • Credential Format: SD-JWT-VC
  • +
  • Key Management (issuer): VC-ISSUER Meta data, DID, X509
  • +
  • Key Management (holder): CNF (json web key)
  • +
  • Transport Protocol: OID4VC
  • +
  • Signature Algorithm: P-256
  • +
  • Status Management: OAUTH Status List
  • +
+

Source Repositories

+ +

Chat Channel

+ +

History

+ + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/projects/credo-ts/index.html b/projects/credo-ts/index.html new file mode 100644 index 00000000..33a5b9f9 --- /dev/null +++ b/projects/credo-ts/index.html @@ -0,0 +1,4366 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Credo - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Credo

+

Project Description

+

Credo has evolved significantly since its inception as a Hyperledger Aries project. Initially, it heavily relied on Hyperledger standards such as DIDComm, Indy, and AnonCreds. However, with advancements in verifiable credential technology and the emergence of new standards, the framework underwent multiple refactoring and modularization processes to maintain interoperability.

+

This allowed for the inclusion of non-Hyperledger standards like W3C Verifiable Credentials with Data Integrity Proofs, DIF Presentation Exchange, OpenID4VC, and SD-JWT integration. As industry requirements shifted towards greater modularity, it became apparent that a unified framework may be better.

+

The future direction for Credo involves adopting a compartmentalized approach consisting of single-purpose libraries designed to work together seamlessly, building on what is already out there. This transition will take considerable effort and will, therefore, be gradual.

+

In order to expand the framework's support for standards beyond the Hyperledger ecosystem, a reassessment of its governance was necessary. The OpenWallet Foundation (OWF) was chosen as a steward due to its commitment to promoting interoperability without directly developing or maintaining standard protocols.

+

credo-high-level-arch.png

+

Source Repositories

+ +

Chat Channel

+ +

History

+ + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/projects/dashboards/index.html b/projects/dashboards/index.html new file mode 100644 index 00000000..0d7b1d0e --- /dev/null +++ b/projects/dashboards/index.html @@ -0,0 +1,4211 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Dashboards - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

OpenWallet Foundation Dashboards

+
+
    +
  • +

    OWF Dashboard

    +
    +

    See the dashboard for repositories in the OpenWallet Foundation GitHub Organization.

    +
  • +
  • +

    Labs Dashboard

    +
    +

    See the dashboard for repositories in the OpenWallet Foundation Labs GitHub Organization.

    +
  • +
+
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/projects/dashboards/labs/index.html b/projects/dashboards/labs/index.html new file mode 100644 index 00000000..218bfed7 --- /dev/null +++ b/projects/dashboards/labs/index.html @@ -0,0 +1,4291 @@ + + + + + + + + + + + + + + + + + + + + + + openwallet-foundation-labs Dashboard - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + +

openwallet-foundation-labs Dashboard

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
RepoLicenseLast CommitCommitsIssuesPull RequestsOpenSSF ScorecardStarsForksWatchers
.githubGitHub LicenseGitHub last commitGitHub total commit activityGitHub Issues or Pull RequestsGitHub Issues or Pull RequestsOSSF-Scorecard ScoreGitHub Repo starsGitHub forksGitHub watchers
credhubGitHub LicenseGitHub last commitGitHub total commit activityGitHub Issues or Pull RequestsGitHub Issues or Pull RequestsOSSF-Scorecard ScoreGitHub Repo starsGitHub forksGitHub watchers
eudi-wallet-kit-react-nativeGitHub LicenseGitHub last commitGitHub total commit activityGitHub Issues or Pull RequestsGitHub Issues or Pull RequestsOSSF-Scorecard ScoreGitHub Repo starsGitHub forksGitHub watchers
farmworker-wallet-osGitHub LicenseGitHub last commitGitHub total commit activityGitHub Issues or Pull RequestsGitHub Issues or Pull RequestsOSSF-Scorecard ScoreGitHub Repo starsGitHub forksGitHub watchers
governanceGitHub LicenseGitHub last commitGitHub total commit activityGitHub Issues or Pull RequestsGitHub Issues or Pull RequestsOSSF-Scorecard ScoreGitHub Repo starsGitHub forksGitHub watchers
identity-credentialGitHub LicenseGitHub last commitGitHub total commit activityGitHub Issues or Pull RequestsGitHub Issues or Pull RequestsOSSF-Scorecard ScoreGitHub Repo starsGitHub forksGitHub watchers
multiformat-vc-iosGitHub LicenseGitHub last commitGitHub total commit activityGitHub Issues or Pull RequestsGitHub Issues or Pull RequestsOSSF-Scorecard ScoreGitHub Repo starsGitHub forksGitHub watchers
sd-jwt-dotnetGitHub LicenseGitHub last commitGitHub total commit activityGitHub Issues or Pull RequestsGitHub Issues or Pull RequestsOSSF-Scorecard ScoreGitHub Repo starsGitHub forksGitHub watchers
sd-jwt-jsGitHub LicenseGitHub last commitGitHub total commit activityGitHub Issues or Pull RequestsGitHub Issues or Pull RequestsOSSF-Scorecard ScoreGitHub Repo starsGitHub forksGitHub watchers
sd-jwt-kotlinGitHub LicenseGitHub last commitGitHub total commit activityGitHub Issues or Pull RequestsGitHub Issues or Pull RequestsOSSF-Scorecard ScoreGitHub Repo starsGitHub forksGitHub watchers
sd-jwt-pythonGitHub LicenseGitHub last commitGitHub total commit activityGitHub Issues or Pull RequestsGitHub Issues or Pull RequestsOSSF-Scorecard ScoreGitHub Repo starsGitHub forksGitHub watchers
sd-jwt-rustGitHub LicenseGitHub last commitGitHub total commit activityGitHub Issues or Pull RequestsGitHub Issues or Pull RequestsOSSF-Scorecard ScoreGitHub Repo starsGitHub forksGitHub watchers
tspGitHub LicenseGitHub last commitGitHub total commit activityGitHub Issues or Pull RequestsGitHub Issues or Pull RequestsOSSF-Scorecard ScoreGitHub Repo starsGitHub forksGitHub watchers
vc-apiGitHub LicenseGitHub last commitGitHub total commit activityGitHub Issues or Pull RequestsGitHub Issues or Pull RequestsOSSF-Scorecard ScoreGitHub Repo starsGitHub forksGitHub watchers
wallet-framework-dotnetGitHub LicenseGitHub last commitGitHub total commit activityGitHub Issues or Pull RequestsGitHub Issues or Pull RequestsOSSF-Scorecard ScoreGitHub Repo starsGitHub forksGitHub watchers
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/projects/dashboards/owf/index.html b/projects/dashboards/owf/index.html new file mode 100644 index 00000000..46f45678 --- /dev/null +++ b/projects/dashboards/owf/index.html @@ -0,0 +1,4291 @@ + + + + + + + + + + + + + + + + + + + + + + openwallet-foundation Dashboard - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + +

openwallet-foundation Dashboard

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
RepoLicenseLast CommitCommitsIssuesPull RequestsOpenSSF ScorecardStarsForksWatchers
.githubGitHub LicenseGitHub last commitGitHub total commit activityGitHub Issues or Pull RequestsGitHub Issues or Pull RequestsOSSF-Scorecard ScoreGitHub Repo starsGitHub forksGitHub watchers
architecture-sigGitHub LicenseGitHub last commitGitHub total commit activityGitHub Issues or Pull RequestsGitHub Issues or Pull RequestsOSSF-Scorecard ScoreGitHub Repo starsGitHub forksGitHub watchers
bifold-walletGitHub LicenseGitHub last commitGitHub total commit activityGitHub Issues or Pull RequestsGitHub Issues or Pull RequestsOSSF-Scorecard ScoreGitHub Repo starsGitHub forksGitHub watchers
credential-format-comparison-sigGitHub LicenseGitHub last commitGitHub total commit activityGitHub Issues or Pull RequestsGitHub Issues or Pull RequestsOSSF-Scorecard ScoreGitHub Repo starsGitHub forksGitHub watchers
credo-tsGitHub LicenseGitHub last commitGitHub total commit activityGitHub Issues or Pull RequestsGitHub Issues or Pull RequestsOSSF-Scorecard ScoreGitHub Repo starsGitHub forksGitHub watchers
credo-ts-docsGitHub LicenseGitHub last commitGitHub total commit activityGitHub Issues or Pull RequestsGitHub Issues or Pull RequestsOSSF-Scorecard ScoreGitHub Repo starsGitHub forksGitHub watchers
credo-ts-extGitHub LicenseGitHub last commitGitHub total commit activityGitHub Issues or Pull RequestsGitHub Issues or Pull RequestsOSSF-Scorecard ScoreGitHub Repo starsGitHub forksGitHub watchers
digital-wallet-and-agent-overviews-sigGitHub LicenseGitHub last commitGitHub total commit activityGitHub Issues or Pull RequestsGitHub Issues or Pull RequestsOSSF-Scorecard ScoreGitHub Repo starsGitHub forksGitHub watchers
governanceGitHub LicenseGitHub last commitGitHub total commit activityGitHub Issues or Pull RequestsGitHub Issues or Pull RequestsOSSF-Scorecard ScoreGitHub Repo starsGitHub forksGitHub watchers
mobile-wallet-test-harnessGitHub LicenseGitHub last commitGitHub total commit activityGitHub Issues or Pull RequestsGitHub Issues or Pull RequestsOSSF-Scorecard ScoreGitHub Repo starsGitHub forksGitHub watchers
mobile-wallet-test-harness2GitHub LicenseGitHub last commitGitHub total commit activityGitHub Issues or Pull RequestsGitHub Issues or Pull RequestsOSSF-Scorecard ScoreGitHub Repo starsGitHub forksGitHub watchers
OID4VC-due-diligence-tfGitHub LicenseGitHub last commitGitHub total commit activityGitHub Issues or Pull RequestsGitHub Issues or Pull RequestsOSSF-Scorecard ScoreGitHub Repo starsGitHub forksGitHub watchers
project-proposalsGitHub LicenseGitHub last commitGitHub total commit activityGitHub Issues or Pull RequestsGitHub Issues or Pull RequestsOSSF-Scorecard ScoreGitHub Repo starsGitHub forksGitHub watchers
safe-wallet-sigGitHub LicenseGitHub last commitGitHub total commit activityGitHub Issues or Pull RequestsGitHub Issues or Pull RequestsOSSF-Scorecard ScoreGitHub Repo starsGitHub forksGitHub watchers
tacGitHub LicenseGitHub last commitGitHub total commit activityGitHub Issues or Pull RequestsGitHub Issues or Pull RequestsOSSF-Scorecard ScoreGitHub Repo starsGitHub forksGitHub watchers
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/projects/eudi-wallet-kit-react-native/index.html b/projects/eudi-wallet-kit-react-native/index.html new file mode 100644 index 00000000..625936c9 --- /dev/null +++ b/projects/eudi-wallet-kit-react-native/index.html @@ -0,0 +1,4361 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + EUDI Wallet Kit React Native - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

EUDI Wallet Kit React Native

+

Project Description

+

The project is a cross-platform React Native wrapper for EUDI Wallet reference implementation.

+

It allows building cross-platform Mobile Wallet applications compliant with Electronic Identification, Authentication and Trust Services (eIDAS) Regulation and EUDI Architecture and Reference Framework (ARF) and based on reference implementations from EUDI (Android and iOS correspondingly).

+

Source Repositories

+ +

Chat Channel

+ +

History

+ + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/projects/fwos/index.html b/projects/fwos/index.html new file mode 100644 index 00000000..bffdfc69 --- /dev/null +++ b/projects/fwos/index.html @@ -0,0 +1,4458 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Farmworker Wallet OS - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Farmworker Wallet OS

+

Farmworkers line up to receive care packages

+

Project Description

+

The Farmworker Wallet OS project is a community of contribution led by Entidad and the United Farm Workers Foundation (UFWF) with the goal of furthering the adoption of an open, secure, interoperable digital wallet engine that makes it easier for farmworker communities to access an ecosystem of life-altering social and human services.

+

Farmworkers are the backbone of global food supply chains, yet they remain one of the most underserved segments of our population. Governments around the world deemed them ‘Essential’ during the recent pandemic. While services and programs exist to help, it’s challenging and costly for organizations that provide them to securely collect and verify the information needed to prove applicant eligibility claims. As a result, most farmworkers forego services and resources they need, even though they’re eligible for them.

+

Over the last three years, Entidad and the UFW Foundation have been exploring digital trust technologies to solve this problem. We’ve developed PrepareseTM, a digital infrastructure solution that lets farmworker organizations securely reuse verified farmworker information, eliminating the need for repetitive collection. The solution layers didcomm, wallet, decentralized identifiers, and verifiable credential technologies with a low-code application development platform, Mendix.

+

Mendix has been a key component in making the PrepareseTM solution possible. Low-code software development has been growing in popularity and bringing new audiences to the practice. Mendix, one of the more popular platforms with over 300K active developers and 50M users, has enabled Entidad and the UFW Foundation to develop, launch, and maintain enterprise-grade digital trust enabled solutions that solve real world problems.

+

We’ve built two products, using this technology. For organizations we’ve built Preparese PlatformTM, it allows them to quickly develop and launch digital trust enabled services and programs. For farmworkers, we’ve developed Preparese MobileTM which combines a verifiable digital profile with a suite of tools that simplify interactions with organizations on the platform.

+

The Preparese PlatformTM is being used by 9 organizations and has 5 digital services in production. The most recent service launched is being used to process and distribute $80 million in one-time relief payments to over 125,000 workers, under the United States Department of Agriculture’s Farm and Food Workers Relief Program (FFWR).

+

The second product, Preparese MobileTM, is designed around the unique needs of farmworkers. We’ve developed a react native mobile app that lets farmworkers store, manage, and exchange their verified information. Engagement with organizations is made easier with DIDComm-based communication capabilities such as text and video chat.

+

One of the cornerstone technologies of the solution is an interoperable Mendix enabled digital wallet. The wallet components need to be able to engage with various non-profit, government, and philanthropic sources, each with their own technology stacks. For this reason, interoperability and working with open standard frameworks has been a priority. The project team members have participated in TrustOverIP Foundation, Hyperledger Aries JS Working Group, and various other communities, including DID Communication Working Group and OpenWallet Foundation of late, to ensure we adhere to best practices and standards.

+

While currently focused on farmworkers, the Mendix digital wallet engine can be used to help others. There are many other underserved communities that could benefit greatly from the privacy, accessibility, and security digital wallets can provide. With this social impact purpose in mind and spirit of further collaboration, Entidad and the UFW Foundation propose to open source the digital wallet engine used in their PrepareseTM solution. By making these resources available, we hope to facilitate a wide variety of social impact.

+

Additionally, the project allows us to bridge and advance the interest of both the OpenWallet Foundation and Mendix communities. By collaborating with the Mendix community, we not only have the ability to grow the number of digital trust technology practitioners, we also tap into a community with an established customer base. By making digital wallets components that can be easily integrated into their existing solutions, the project can drive further adoption and usage of interoperable, secure and privacy preserving digital wallets.

+

Origin & History

+

The origins of the Farmworker Wallet OS project align with those of Entidad. What began as a volunteering effort by three college friends, was formalized in 2018 with the founding of Entidad as a public benefit corporation. We have primarily been working with leading farm worker-serving organizations to develop technology that leverages growing digital literacy in their communities to scale their impact.

+

The first digital service launched supported the UFW Foundation’s emergency relief efforts during the height of the COVID-19 pandemic. The solution was used to plan, manage and operate over 500 in-person community events where over $15 million in resources were distributed to over 40K families. Additionally, it has allowed us to better understand the unique challenges of building for underserved communities and why interoperable, secure, and privacy preserving technologies are key to addressing these challenges. 

+

You can read more about our journey on our blog.

+

External Dependencies

+

Mendix is a low-code application platform provider so its terms of service cover usage of Mendix services and resources by Mendix developers (organizations and/or individual contributors). The Application model for a standards compliant wallet engine will be the primary focus for the contributors of this project. The Mendix terms of service do protect the IP rights to these App models in Section 3 with reference to "Customer Data" definition in section 17.

+

There are design-time and runtime aspects of app development but one of the great things about this tooling is that there is clean separation between the two.

+

The following captures the developer's "design-time" perspective. We hope that the diagram helps to clarify the software components that would fall under the scope of this OWF project and distinguishes PrepareseTM as an example of a closed (proprietary) application that embeds core Farmworker WalletOS components. We plan on documenting a similar diagram to aid in understanding the "runtime" perspective soon.

+

Designtime perspective

+
    +
  1. Mendix Studio Pro v9.24.4 (integrated developer environment)
  2. +
  3. Eclipse Temurin JDK 11 (x64)
  4. +
  5. Mendix Native Template v7.0.1
  6. +
  7. React Native v0.70.7
  8. +
  9. Hyperledger / Aries-Framework-Javascript v0.4.0
  10. +
  11. Development instance of an Aries Mediator Service
  12. +
  13. Development instance of an Aries Cloud Agent
  14. +
+

Infrastructure

+

The Farmworker Wallet OS will be organized and published as a suite of software modules that can be imported into any existing Mendix app code repository. The Mendix software modules effectively serve as a digital wallet SDK that can be embedded into any Mendix application to enhance the user experience. The code repository for this project is itself a Mendix app repository and as such can be executed locally on any supported developer workstation.

+

The initial version of the digital wallet SDK is being built on top of Aries Framework Javascript, an open-source framework maintained by the Hyperledger Aries developer community helping to foster participation with the Aries digital trust ecosystem. Over time, the digital wallet SDK will be extended to support other digital trust open standards such as OpenID for Verifiable Credentials (OID4VC).

+

Source Repositories

+ +

Chat Channel

+ +

History

+ + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/projects/identity-credential/index.html b/projects/identity-credential/index.html new file mode 100644 index 00000000..f8db25c9 --- /dev/null +++ b/projects/identity-credential/index.html @@ -0,0 +1,4525 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Identity Credential - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Identity Credential

+

Project Description

+

Libraries and reference applications for working with real-world identity.

+

The initial focus for this work was mdoc/mDL according to ISO/IEC 18013-5:2021 +and related standards (mainly ISO 23220 series and ISO 18013-7) on Android. Current focus +includes other credential formats and operating environments.

+

Libraries

+

The project includes two libraries written in Java and Kotlin. The +first is identity which provides the core building blocks and which +can also be used on server-side environments. The other is identity-android +which provides Android-specific extensions to the former. It is designed to +run on Android (API 24 or later) and will take advantage of Android-specific +features including hardware-backed Keystore, NFC, Bluetooth +Low Energy, and so on.

+

The libraries are intended to be used by Wallet Applications (mobile +applications on the credential holder's device), Reader Applications (applications +operated on device controlled by the verifier), and Issuance Systems (applications +operated by the credential issuer or their agent). They provide the following +building blocks

+
    +
  • A light-weight Secure Area abstraction for hardware-backed keystore
      +
    • Applications can create hardware-backed Elliptic Curve Cryptography + keys which can be used for creating Signatures or performing Key Agreement. + Each key will have an attestation which can be used to prove to Relying Parties + (such as a credential issuer) that the private part of the key only exists + in a Secure Area.
    • +
    • The identity-android library includes an implementation based on + Android Keystore + with support for requiring user authentication (biometric or lock-screen knowledge + factor, e.g. system PIN) for unlocking the key and also can use + StrongBox + if available on the device. This is appropriate to use in Android applications + implementing ISO/IEC 18013-5:2021 for storing DeviceKey.
    • +
    • The identity library includes an implementation backed by BouncyCastle + with support for passphrase-protected keys. This isn't suitable for use + in Mobile Applications as its not backed by Secure Hardware.
    • +
    • Applications can supply their own Secure Area implementations for e.g. + externally attached dongles, cloud based HSMs, or whatever the issuer + deems appropriate to protect key material associated with their credential.
    • +
    +
  • +
  • A Credential Store for storage of one or more Credentials
      +
    • Each Credential has a Credential Key which can be used by the issuer + to bind a credential to a specific device which is useful when + issuing updates or refreshing a credential.
    • +
    • Additionally, each Credential has one or more Authentication Keys which + can be endorsed by the issuer and used at presentation time.
    • +
    • Finally, namespaced data and arbitrary key/value pairs can be stored + in a Credential which can be used for credential data and claims. This + data is stored encrypted at rest.
    • +
    +
  • +
  • Data structures and code for provisioning of mdoc/mDLs
      +
    • This code can can be used both on the device and issuer side. No networking + protocol is defined, the application has to define its own.
    • +
    +
  • +
  • Parsers and generators for all data structures used in ISO/IEC 18013-5:2021 + presentations, including DeviceResponse, DeviceRequest, MobileSecurityObject + and many other CBOR data structures.
  • +
  • An implementation of the ISO/IEC 18013-5:2021 presentation flows including + QR engagement, NFC engagement (both static and negotiated), device retrieval + (BLE, Wifi Aware, and NFC)
  • +
+

Wallet and Reader Android applications

+

This repository also contains two Android applications using this library +in the appholder and appverifier modules. The Wallet application is a simple +self-contained application which allows creating a number of mdoc credentials +using four different mdoc Document Types:

+
    +
  • org.iso.18013.5.1.mDL: Mobile Driving License
  • +
  • org.micov.1: mdoc for eHealth (link)
  • +
  • nl.rdw.mekb.1: mdoc for Vehicle Registration (link)
  • +
  • eu.europa.ec.eudiw.pid.1: mdoc for Personal Identification
  • +
+

and their associated mdoc name spaces. The first one is defined in +ISO/IEC 18013-5:2021 and the other three have been used at mdoc/mDL +test events organized by participants of the ISO/IEC JTC1 SC17 WG10 +working group.

+

ISO 18013-7 Reader Website

+

The wwwverifier module contains the source code for a website acting as an +mdoc reader according to the latest ISO 18013-7 working draft (as of Sep 2023) +and it's implementing the so-called REST API. There is currently a test instance +of this application available at https://mdoc-reader-external.uc.r.appspot.com/. +The Wallet Android application also has support for the REST API and registers +on Android for the mdoc:// URI scheme. This can be tested end-to-end by going +to the reader website (URL above) and clicking on one of the "Request" buttons, +and then hitting the mdoc:// link presented on the site. This will cause the +browser to invoke the Wallet app which will then connect to the reader and send +the credential after user consent.

+

Source Repositories

+ +

Chat Channel

+ +

History

+ + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/projects/index.html b/projects/index.html new file mode 100644 index 00000000..2589635f --- /dev/null +++ b/projects/index.html @@ -0,0 +1,4304 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Projects - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Projects

+

Projects in the OpenWallet Foundation follow the project lifecycle. This page lists the active projects within the OpenWallet Foundation and their current lifecycle stage.

+

Active Projects

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Approval DateProject NameLifecycle Stage
2023-May-17SD-JWT KotlinLab
2023-May-17SD-JWT PythonLab
2023-Aug-09Farmworker Wallet OSLab
2023-Sep-28VC APILab
2023-Oct-04Wallet Framework .NETLab
2023-Oct-18Identity CredentialLab
2023-Nov-01SD-JWT JavaScriptLab
2023-Nov-15SD-JWT RustLab
2023-Nov-29SD-JWT .NETLab
2023-Nov-29CredoGrowth
2024-Jan-24Multiformat VC for iOSLab
2024-Feb-21BifoldGrowth
2024-Apr-17EUDI Wallet Kit React NativeLab
2024-May-15Trust Spanning ProtocolLab
2024-May-15TuvaliLab
2024-May-29CredhubLab
2024-Jun-12MDL JavaScriptLab
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/projects/mdl-js/index.html b/projects/mdl-js/index.html new file mode 100644 index 00000000..b49a3851 --- /dev/null +++ b/projects/mdl-js/index.html @@ -0,0 +1,4365 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + MDL JavaScript - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

MDL JavaScript

+

Project Description

+

This is a Typescript(Javascript) implementation of the ISO 18013-5:2021 (MDL) specification. This project aims to provide a platform agnostic implementation of the MDL specification.

+

To provide MDL features to Biggest Wallet SDKs like Credo or Veramo, the direction of the project will be:

+

Provide a platform agnostic implementation of the MDL specification +- Bring your own crypto +- Modular approach +- Provide platform specific helper implementations for developers to use easily

+

Source Repositories

+ +

Chat Channel

+ +

History

+ + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/projects/multiformat-vc-ios/index.html b/projects/multiformat-vc-ios/index.html new file mode 100644 index 00000000..7f69f1b5 --- /dev/null +++ b/projects/multiformat-vc-ios/index.html @@ -0,0 +1,4371 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Multiformat VC for iOS - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Multiformat VC for iOS

+

Project Description

+

Pure Swift package for creating Verifiable Credentials (VCs) in multiple formats

+ +

Support for multiple data types for disclosed values including

+
    +
  • String
  • +
  • Int
  • +
  • Boolean
  • +
  • Array of Strings - [String]
  • +
  • Dictionary of String keys and String values - [String:String]
  • +
+

This project is a contribution of the work done at Ping Identity to test and establish interoperability of the various formats representing the Verifiable Credentials Data Model https://www.w3.org/TR/vc-data-model/. Along with the SD-JWT VC and JWT VC formats described above, Ping Identity has also participated in the interoperability event for OpenID4VP to present a VC JWT. That code will also be released as a part of this project.

+

Source Repositories

+

openwallet-foundation-labs/multiformat-vc-ios

+

Chat Channel

+ +

History

+ + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/projects/reviews/0000-template-annual/index.html b/projects/reviews/0000-template-annual/index.html new file mode 100644 index 00000000..926e3f16 --- /dev/null +++ b/projects/reviews/0000-template-annual/index.html @@ -0,0 +1,4235 @@ + + + + + + + + + + + + + + + + + + + + + + YYYY PROJECT NAME - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + +

YYYY PROJECT NAME

+
+

Info

+

Copy this template to the subdirectory for the current year and name the file YYYY-project-name-annual.md (e.g., 2024-amazingproj-annual.md). Update the title above to replace YYYY with the year of the annual review and PROJECT NAME with the name of the project. Update the index.md file in the current year to include a link to the markdown file. These blocks are instructions. Please remove when section has been completed.

+
+

Project Health

+
+

Info

+

Include information about your project's contributions and activity. You can find information within GitHub by looking at the Insights tab. We will be looking for signs of consistent or increasing contribution activity. Please feel free to add commentary to add color to this information.

+
+

Maintainer Diversity

+
+

Info

+

How many maintainers do you have, and which organisations are they from? How has the maintainers and diversity of your maintainers changed in the past year? Has the number of active maintainers increased/decreased? Has the diversity of maintainers increased/decreased? Please include a link to your existing MAINTAINERS file and the MAINTAINERS file from last year (if appropriate). This is a good opportunity to ensure that your MAINTAINERS file is up to date and to retire any maintainers.

+
+

Project Adoption

+
+

Info

+

What do you know about adoption, and how has this changed since your last review or since being accepted into OpenWallet Foundation? If you can list companies that are adopters of your project, please do so. Feel free to link to an existing ADOPTERS file if appropriate.

+
+

Goals

+

Performance Against Prior Goals

+
+

Info

+

Include information about the goals that you previously set for the project in the last review or since the project proposal has been approved. How has the project performed against these goals? If your goals changed from your previous annual report, let us know what changed and why. If you have not achieved the goals that you set out, that is okay. We want to know what you have accomplished and what challenges the project is having in meeting the goals.

+
+

Next Year's Goals

+
+

Info

+

What are the goals for the next year of the project? The goals should list what you want to achieve, not just what you know you can achieve. Feel free to include stretch goals and things that you are looking to explore in the next year. For example, are you working on major new features? Or are you concentrating on adoption, community growth, or documentation?

+
+

Help Required

+
+

Info

+

How can the OpenWallet Foundation or the TAC help you achieve your upcoming goals?

+
+

Project Lifecycle Stage Recommendation

+
+

Info

+

What stage do you think the project should be? If you you think that your project meets the criteria for another stage, please explain why.

+
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/projects/reviews/2024/2024-sd-jwt-python-annual/index.html b/projects/reviews/2024/2024-sd-jwt-python-annual/index.html new file mode 100644 index 00000000..1e16174b --- /dev/null +++ b/projects/reviews/2024/2024-sd-jwt-python-annual/index.html @@ -0,0 +1,4227 @@ + + + + + + + + + + + + + + + + + + + + + + 2024 sd-jwt-python (SD-JWT Reference Implementation) - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + +

2024 sd-jwt-python (SD-JWT Reference Implementation)

+

Project Health

+

The main focus of this project is to provide a reference implementation for the +IETF SD-JWT draft. As such, the code has reflected the developments in the +specification over the last year and is up to date with the latest version of +the draft. Since the draft is approaching a stable state (and hopefully a final +RFC soon-ish), no drastic changes are expected in the codebase.

+

Maintainer Diversity

+

As before, the project is maintained by a single maintainer, an editor of the +SD-JWT draft. Two developers have contributed code, one editor of the draft and +one external contributor.

+

Project Adoption

+

The main task of the project is to provide a reference implementation for the +SD-JWT draft. The project is in use

+
    +
  • by the editors of the draft to test new developments and to produce examples for the specification,
  • +
  • by external contributors to understand testdrive SD-JWT, and
  • +
  • as a reference for testing and validation of other implementations.
  • +
+

Goals

+

Performance Against Prior Goals

+

The project has met its goals for the last year, which were to keep the codebase +up to date with the latest version of the draft and to provide a reference +implementation for the draft.

+

Next Year's Goals

+

As before, the main goal of the project is to provide a reference implementation +for the SD-JWT draft. The project will continue to track the development of the +draft, including a potential transition to an RFC. The project will also continue +to exist as a reference for SD-JWT implementations.

+

Help Required

+

The project is in good shape and does not require any help at the moment.

+

Project Lifecycle Stage Recommendation

+

The project is recommended to remain in the Labs stage.

+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/projects/reviews/2024/index.html b/projects/reviews/2024/index.html new file mode 100644 index 00000000..ffcdf1a8 --- /dev/null +++ b/projects/reviews/2024/index.html @@ -0,0 +1,4301 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 2024 Project Annual Reviews - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

2024 Project Annual Reviews

+

Projects must provide an annual review to the TAC to ensure that the project is still active and in the correct lifecycle stage. The following calendar provides the timing for when these reviews are required to be presented to the TAC:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ProjectStageDate Accepted2024 Review
SD-JWT PythonLabsMay 27, 2023Jun 12, 2024
SD-JWT KotlinLabsMay 27, 2023Jun 12, 2024
Farmworker Wallet OSLabsAug 9, 2023Aug 21, 2024
VC-APILabsSep 28, 2023Oct 2, 2024
Wallet Framework .NETLabsOct 4, 2023Oct 16, 2024
Android Identity LibraryLabsOct 18, 2023Oct 30, 2024
SD-JWT JavaScriptLabsNov 1, 2023Nov 13, 2024
SD-JWT RustLabsNov 15, 2023Nov 27, 2024
CredoGrowthNov 29, 2023Dec 11, 2024
SD-JWT .NETLabsNov 29, 2023Dec 11, 2024
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/projects/reviews/2025/index.html b/projects/reviews/2025/index.html new file mode 100644 index 00000000..a7b89416 --- /dev/null +++ b/projects/reviews/2025/index.html @@ -0,0 +1,4343 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 2025 Project Annual Reviews - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

2025 Project Annual Reviews

+

Projects must provide an annual review to the TAC to ensure that the project is still active and in the correct lifecycle stage. The following calendar provides the timing for when these reviews are required to be presented to the TAC:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ProjectStageDate Accepted2025 Review
Multiformat VC for iOSLabsJan 24, 2024Feb 5, 2025
BifoldGrowthFeb 21, 2024Mar 5, 2025
EUDI Wallet Kit React NativeLabsApr 17, 2024Apr 30, 2025
Trust Spanning ProtocolLabsMay 15, 2024May 14, 2025
TuvaliLabsMay 15, 2024May 14, 2025
CredhubLabsMay 29, 2024May 28, 2025
MDL JavaScriptLabsJun 12, 2024Jun 11, 2025
SD-JWT PythonLabsMay 27, 2023
SD-JWT KotlinLabsMay 27, 2023
Farmworker Wallet OSLabsAug 9, 2023
VC-APILabsSep 28, 2023
Wallet Framework .NETLabsOct 4, 2023
Android Identity LibraryLabsOct 18, 2023
SD-JWT JavaScriptLabsNov 1, 2023
SD-JWT RustLabsNov 15, 2023
CredoGrowthNov 29, 2023
SD-JWT .NETLabsNov 29, 2023
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/projects/sd-jwt-dotnet/index.html b/projects/sd-jwt-dotnet/index.html new file mode 100644 index 00000000..5559b1b2 --- /dev/null +++ b/projects/sd-jwt-dotnet/index.html @@ -0,0 +1,4360 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + SD-JWT .NET - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/projects/sd-jwt-js/index.html b/projects/sd-jwt-js/index.html new file mode 100644 index 00000000..5be19c91 --- /dev/null +++ b/projects/sd-jwt-js/index.html @@ -0,0 +1,4360 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + SD-JWT JavaScript - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/projects/sd-jwt-kotlin/index.html b/projects/sd-jwt-kotlin/index.html new file mode 100644 index 00000000..4bf8b45f --- /dev/null +++ b/projects/sd-jwt-kotlin/index.html @@ -0,0 +1,4360 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + SD-JWT Kotlin - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/projects/sd-jwt-python/index.html b/projects/sd-jwt-python/index.html new file mode 100644 index 00000000..72733fb6 --- /dev/null +++ b/projects/sd-jwt-python/index.html @@ -0,0 +1,4360 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + SD-JWT Python - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/projects/sd-jwt-rust/index.html b/projects/sd-jwt-rust/index.html new file mode 100644 index 00000000..6800cdcc --- /dev/null +++ b/projects/sd-jwt-rust/index.html @@ -0,0 +1,4360 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + SD-JWT Rust - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/projects/tsp/index.html b/projects/tsp/index.html new file mode 100644 index 00000000..9723ab24 --- /dev/null +++ b/projects/tsp/index.html @@ -0,0 +1,4364 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Trust Spanning Protocol - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Trust Spanning Protocol

+

Project Description

+

This project is an early impementation of the draft Trust Spanning Protocol (TSP).

+

According to the above referenced specification, "The Trust Spanning Protocol (TSP) facilitates secure communication between endpoints with potentially different identifier types, using message-based exchanges. As long as these endpoints use identifiers based on public key cryptography (PKC) with a verifiable trust root, TSP ensures their messages are authentic and, if optionally chosen, confidential. Moreover, it presents various privacy protection measures against metadata-based correlation exploitations. These attributes of TSP together allow endpoints to form authentic relationships rooted in their respective verifiable identifiers (VIDs), viewing TSP messages as virtual channels for trustworthy communication."

+

A shorter introduction of TSP can be found in this blog post.

+

This project's current code includes a Rust implementation of all TSP features. We also plan to incorporate/develop related features such as additional Verifiable Identifier types, additional transport layer mechanisms, different language bindings as needed and integration modules needed to be compatible with other OpenWallet projects.

+

In addition, we may add and welcome trust task or application specific extensions.

+

Source Repositories

+ +

Chat Channel

+ +

History

+ + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/projects/tuvali/index.html b/projects/tuvali/index.html new file mode 100644 index 00000000..f5090ee3 --- /dev/null +++ b/projects/tuvali/index.html @@ -0,0 +1,4360 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Tuvali - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/projects/vc-api/index.html b/projects/vc-api/index.html new file mode 100644 index 00000000..777bd99f --- /dev/null +++ b/projects/vc-api/index.html @@ -0,0 +1,4362 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + VC-API - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

VC API

+

Project Description

+

The VC API is specification for a set of APIs for VC lifecycle management (https://w3c-ccg.github.io/vc-api/). This includes operations such as credential issuance, verification, and exchange. It is a W3C CCG work item and, as of the submission of this proposal, it is in “draft community report” status.

+

The VC API’s design is informed by use cases across a range of domains. Several of these use cases are collected in a working group note (https://w3c-ccg.github.io/vc-api-use-cases/).

+

This project is an implementation of the VC API. The implementation aims to enable organizations and individuals to effortlessly conduct SSI operations over HTTP without requiring technical expertise, making it seamless to integrate into existing projects.

+

Source Repositories

+ +

Chat Channel

+ +

History

+ + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/projects/wallet-framework-dotnet/index.html b/projects/wallet-framework-dotnet/index.html new file mode 100644 index 00000000..d41d8a89 --- /dev/null +++ b/projects/wallet-framework-dotnet/index.html @@ -0,0 +1,4362 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Wallet Framework .NET - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Wallet Framework .NET

+

Project Description

+

The wallet-framework-dotnet is a framework designed for .NET, focusing on providing a multi-platform wallet framework. Initially a part of the Hyperledger Aries project (Aries Framework .NET), this initiative has now branched out to cater to a broader audience. The primary aim is to create a multiprotocol wallet framework enabling implementations of OpenID4VC and SD-JWT VC, in accordance to the European Identity Wallet initiative's objectives.

+

Currently, the framework supports DidComm v1 and AnonCreds. There is an active intention to extend support for other promising protocols, notably DidComm v2, to ensure the framework remains at the forefront of digital identity solutions.

+

Furthermore, the team is considering the development of SD-JWT credentials as a standalone library. This might transition into a separate project proposal in the future, underscoring the commitment to modular and reusable components in the digital identity space.

+

Source Repositories

+ +

Chat Channel

+ +

History

+ + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/search/search_index.json b/search/search_index.json new file mode 100644 index 00000000..f1929740 --- /dev/null +++ b/search/search_index.json @@ -0,0 +1 @@ +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"Home","text":"

Welcome to the OpenWallet Foundation's (OWF) Technical Advisory Council (TAC) website. Here you will find:

  • What is the TAC

    Learn more about the Technical Advisory Council's role, responsibilities, and voting members

  • Governing Documents

    Review the OpenWallet Foundation TAC Governing Documents

  • TAC Meetings

    See meeting invite details and meeting notes from past meetings

  • Projects

    Explore the OpenWallet Foundation Projects

  • Special Interest Groups

    Join an OpenWallet Foundation Special Interest Groups (SIGs)

  • Task Forces

    Work on an OpenWallet Foundation Task Forces

"},{"location":"SIGs/","title":"Special Interest Groups (SIGs)","text":"

A special interest group (SIG) under the Technical Advisory Council (TAC) is a group with a shared interest in advancing a specific area of knowledge, learning, or technology related to the mission of the OpenWallet Foundation where members cooperate to affect or to produce solutions within their particular field. Unlike a task force, SIGs are typically long running and may or may not produce any deliverables. A SIG can be created by anyone in the OpenWallet Foundation community and must be proposed to and approved by the TAC.

Tip

If you would like to propose a Special Interest Group, please see the SIG proposal process.

"},{"location":"SIGs/#active-sigs","title":"Active SIGs","text":"
  • Architecture
  • Credential Format Comparison
  • Digital Wallet and Agent Overviews
  • Safe Wallet
"},{"location":"SIGs/architecture/","title":"Architecture Special Interest Group (SIG)","text":"

This SIG is focused on conversations related to the architecture of digital wallet engines.

This SIG was accepted by the TAC on April 5, 2023.

"},{"location":"SIGs/architecture/#participating","title":"Participating","text":"

This SIG is an open group. Anyone in the OpenWallet Foundation community can join and participate. There is no formal sign up process. Just show up and participate.

"},{"location":"SIGs/architecture/#meetings","title":"Meetings","text":"

The architecture SIG meets weekly on Mondays at 11:00 AM US/Pacific time. For details, see architecture SIG meeting details. For past notes and recordings, see the architecture SIG wiki.

"},{"location":"SIGs/architecture/#discord","title":"Discord","text":"

Please join the OpenWallet Foundation Discord and participate in the discussion in the #architecture-sig channel.

"},{"location":"SIGs/credential-format-comparison/","title":"Credential Format Comparison Special Interest Group (SIG)","text":"

This SIG is dedicated to maintaining information about available credential formats for the benefit of OWF projects and the wider community. The topic is more complex than one might assume on first sight, since there are more than 14 formats for representing digital credentials and most of those formats can be combined with different signature algorithms, ways to represent cryptographic keys (with alone more than a hundred DID methods), status management methods, trust management methods and so on.

There is pre-existing work started at Internet Identity Workshop (IIW 34, Spring 2022) and extended and augmented during Rebooting the Web of Trust (RWOT-XI, The Hague, Sept 2022).

It consists of a \u201ccredential format comparison matrix\u201d, containing information about the technical options in the different dimensions (formats, signature algorithms, \u2026) as well as known credential profiles, i.e. concrete combinations used in implementations and an article explaining the \u201cmatrix\u201d.

  • Article: https://github.com/WebOfTrustInfo/rwot11-the-hague/blob/master/final-documents/credential-profile-comparison.pdf
  • Source Code: https://github.com/openwallet-foundation/credential-format-comparison-sig
  • Rendered Matrix: https://openwallet-foundation.github.io/credential-format-comparison-sig/#/

This SIG was accepted by the TAC on May 31, 2023. See Credential Format Comparison SIG Proposal for more details.

"},{"location":"SIGs/credential-format-comparison/#participating","title":"Participating","text":"

This SIG is an open group. Anyone in the OpenWallet Foundation community can join and participate. There is no formal sign up process. Just show up and participate.

If you are interested in participating, please join the OpenWallet Foundation Discord and participate in the discussion in the #credential-format-comparison-sig channel.

"},{"location":"SIGs/digital-wallet-and-agent-overviews/","title":"Digital Wallet and Agent Overviews Special Interest Group (SIG)","text":"

The objectives of this SIG is to further develop and maintain the Digital Wallet Overview and making a similar overview for digital identity agents/SDKs. These overviews should provide transparency of the characteristics of wallets and agents in order to allow for comparison and effective decision making on which wallet is applicable for your use case. By creating awareness of these overviews, this work can lead to less fragmentation of the SSI playing field and increase adoption.

This SIG was accepted by the TAC on September 20, 2023. See Digital Wallet and Agent Overviews SIG Proposal for more details.

"},{"location":"SIGs/digital-wallet-and-agent-overviews/#participating","title":"Participating","text":"

This SIG is an open group. Anyone in the OpenWallet Foundation community can join and participate. There is no formal sign up process. Just show up and participate.

If you are interested in participating, please join the OpenWallet Foundation Discord and participate in the discussion in the #digital-wallet-and-agent-overviews-sig channel.

"},{"location":"SIGs/safe-wallet/","title":"Safe Wallet Special Interest Group (SIG)","text":"

This SIG will create, distribute and promote a set of material that will become the de-facto way to determine how \"safe\" the new breed of digital wallets is, and be able to compare them effectively. This will increase the visibility of the solutions to correlation and profiling issues that could be introduced with digital wallet deployments.

This SIG was accepted by the TAC on September 20, 2023. See Safe Wallet SIG Proposal for more details.

"},{"location":"SIGs/safe-wallet/#participating","title":"Participating","text":"

This SIG is an open group. Anyone in the OpenWallet Foundation community can join and participate. There is no formal sign up process. Just show up and participate.

If you are interested in participating, please join the OpenWallet Foundation Discord and participate in the discussion in the #safe-wallet-sig channel.

"},{"location":"SIGs/updates/2024/","title":"2024 Quarterly Updates","text":"

The Special Interest Groups (SIGs) must provide a quarterly update to the TAC to ensure that the SIG is still active and that there is still value in hosting the special interest group. The following calendar provides the timing for when these updates are required to be presented to the TAC:

Quarter Special Interest Group TAC Meeting Q1 Architecture SIG 2024-01-10 Q1 Credential Format Comparison SIG 2024-02-07 Q1 Digital Wallet and Agent Overviews SIG 2024-02-21 Q1 Safe Wallet SIG 2024-03-06 Q2 Architecture SIG 2024-04-03 Q2 Credential Format Comparison SIG 2024-05-01 Q2 Digital Wallet and Agent Overviews SIG7 2024-05-29 Q2 Safe Wallet SIG 2024-06-12 Q3 Architecture SIG 2024-07-10 Q3 Credential Format Comparison SIG 2024-07-24 Q3 Digital Wallet and Agent Overviews SIG 2024-08-07 Q3 Safe Wallet SIG 2024-08-21 Q4 Architecture SIG 2024-10-02 Q4 Credential Format Comparison SIG 2024-10-16 Q4 Digital Wallet and Agent Overviews SIG 2024-10-30 Q4 Safe Wallet SIG 2024-11-13"},{"location":"governance/","title":"Governing Documents","text":"

The following are the governing documents used by the OpenWallet Foundation's Technical Advisory Council.

"},{"location":"governance/#foundation-governance","title":"Foundation Governance","text":"

The OpenWallet Foundation is governed by the following documents, of which the Technical Advisory Council follows:

  • Charter
  • Antitrust Policy
  • Code of Conduct
"},{"location":"governance/#technical-advisory-council-governance","title":"Technical Advisory Council Governance","text":"

The Technical Advisory Council is governed with the following documents:

  • Roles and Responsibilities
  • TAC Alternate Policy
  • Elections
  • Project Lifecycle
  • Special Interest Groups
  • Task Forces
  • Composition
"},{"location":"governance/#project-requirements","title":"Project Requirements","text":"

The Technical Advisory Council has created the following requirements for projects:

  • Project Annual Review Process
  • Common Repository Structure
  • MAINTAINERS.md File Contents
  • Maintainer Inactivity
  • Security Policy
  • Release Taxonomy
  • Archiving Inactive Repositories
"},{"location":"governance/#project-resources","title":"Project Resources","text":"

The Technical Advisory Council offers the following services and tooling to projects:

  • Paid Tooling Policy
  • Project and Lab Services
  • Content Plan
"},{"location":"governance/alternate-policy/","title":"TAC Alternate Policy","text":"

A TAC voting member may designate an alternate for a specific meeting, and must notify the chair in advance of the meeting. The TAC voting member is responsible for ensuring that the named alternate has enough information to represent the TAC voting member in all matters that will be covered in the meeting. The named alternate will participate in any votes that occur during the meeting for which they were named an alternate, and their vote will count as if it were cast by the TAC voting member.

Warning

If a TAC voting member regularly names an alternate and

  • is a TAC Premier Sponsor Representative, then that TAC voting member should consider whether they should replace themselves with the alternate, or
  • is a TAC \"At Large\" Representative, then that TAC voting member should consider whether they should resign.
"},{"location":"governance/antitrust/","title":"Antitrust Policy","text":"

The LF Europe Antitrust Policy listed at http://lfeurope.be/policies will apply for all Collaborators in the Project.

"},{"location":"governance/archiving-inactive-repositories/","title":"Archiving Inactive Repositories","text":"

OpenWallet Foundation very much appreciates the contributions of the community; however, it is important to archive source repositories that have become inactive in order to ensure that others in the community are not using code or reporting issues on a repository that is not being maintained.

Any repository that has not had a release for 12 months or that has had no commits for 6 months may be archived.

Projects will be notified via a PR in the appropriate repository, as well as a notice in the project appropriate Discord channel and mailing list, if they exist.

Generally speaking if the project's maintainers request to keep the repository active, the request will be honored. However if the repository has a lot of out of date dependencies, particulaly ones relating to security vulnerabilites, this request may not be honored.

A request by the project's maintainers to un-archive a repository for the purposes of active contribution will be honored, unless the project is in an emeritus stage. In those cases the project lifecycle issues will need to be resolved first.

"},{"location":"governance/charter/","title":"OpenWallet Foundation Charter","text":"

Exhibit B

The OpenWallet Foundation Charter

Linux Foundation Europe

Effective May 22, 2023

  1. Mission and Scope of the OpenWallet Foundation.

    The purpose of the OpenWallet Foundation (the \u201cOWF\u201d) is to support various open source, open data and/or other open projects relating to or supporting development of digital wallets, including infrastructure and support initiatives related thereto (each such project, a \u201cTechnical Project\u201d) , in accordance with the provisions of this Charter. The governance of each Technical Project is as set forth in the charter for that Technical Project.

    The OWF aims to enable entities to transact securely, and in a privacy enhancing fashion, in- person and on-line where attributes stored in, and managed by, the wallet. The OWF will:

    • develop and maintain open source code for wallets to enable and ensure wallet interoperability,
    • advocate for the adoption of the interoperable digital wallet technology, and
    • collaborate with Standards Development Organizations (SDOs) in the development and proliferation of open standards related to digital wallets

    The OWF will not publish a publicly available wallet (including into any application stores).

    The OWF supports the Technical Projects. The OWF operates under the guidance of the Governing Board of the OWF (the \u201cGoverning Board\u201d) and Linux Foundation Europe (the \u201cLFEU\u201d) as may be consistent with Linux Foundation Europe\u2019s tax-exempt status.

    The Governing Board manages the OWF. The Governing Board may establish other committees and other working groups (collectively, and including the Technical Advisory Council, \u201cCommittees\u201d) which will report to the Governing Board.

  2. Sponsorship.

    1. The OWF will be composed of Premier, General and Associate Sponsors (each, a \u201cSponsor\u201d and, collectively, the \u201cSponsors\u201d) in Good Standing. All Sponsors must be current Sponsors of LFEU (at any level) to participate in the OWF as a Sponsor. All sponsors in the OWF, enjoy the privileges and undertake the obligations described in this Charter, as from time-to-time amended by the Governing Board, with the approval of LFEU. During the term of their sponsorship, all Participants will comply with all such policies as the LFEU Board of Directors and/or the OWF may adopt with notice to Sponsors.
    2. Premier Sponsors will be entitled to appoint a representative to the Governing Board and any Committee.
    3. General Sponsors, acting as a class, will be entitled to annually elect one representative to the Governing Board for every ten General Sponsors, up to a maximum of three total representatives, provided that there will always be at least one General Sponsor representative, even if there are less than ten General Sponsors. The Governing Board determines the General Sponsor representative election process.
    4. The Associate Sponsor category of sponsorship is limited to Associate Sponsors of LFEU. The Governing Board may set additional criteria for sponsoring the OWF as an Associate Sponsor. If the Associate Sponsor is itself a membership or participation organization, Associate Sponsorship in the OWF does not confer any privileges or rights to the members or participants of the Associate Sponsor.
    5. Sponsors will be entitled to:
      1. participate in OWF general meetings, initiatives, events and any other activities; and
      2. identify themselves as sponsors of the OWF supporting the OWF community.
  3. Governing Board

    1. The Governing Board voting members will consist of:

      1. one representative appointed by each Premier Sponsor;
      2. the TAC Representative (as defined below), or, in the absence of a chair and with the approval of the Governing Board, any active contributor to a Technical Project so designated by the TAC (such chair or designee the \u201cTAC Representative\u201d); and
      3. the elected General Sponsor representative or representatives.
    2. The Governing Board will also include nonvoting members consisting of the GAC Representative (defined in Section 4) and Associate Representative.

      1. The Associate Representative will be chosen based on their efforts and potential to advance the OWF mission. The Associate Representative will be selected by the Governing Board voting representatives through a process determined by the Governing Board.
    3. Only one Sponsor that is part of a group of Related Companies (as defined in Section 7) may appoint, or nominate for a sponsorship class election, a representative on the Governing Board. No single Sponsor, company or set of Related Companies will be entitled to: (i) appoint or nominate for sponsorship class election more than one representative for the Governing Board, or (ii) have more than two representatives on the Governing Board.

      1. The only path to two representatives from the same group of Related Companies that will be acceptable will be for one Sponsor to appoint or nominate a representative to the Governing Board and have another of its employees, or an employee of one of its Related Companies, serve as the TAC Representative on the Governing Board.
    4. Conduct of Meetings

      1. Governing Board meetings will be limited to the Governing Board representatives, the Outreach Committee Chair, invited guests and OWF staff.
      2. Governing Board meetings follow the requirements for quorum and voting outlined in this Charter. The Governing Board may decide whether to allow named representatives (one per Sponsor per Governing Board and per Committee) to attend as an alternate.
      3. The Governing Board meetings will be private unless decided otherwise by the Governing Board. The Governing Board may invite guests to participate in consideration of specific Governing Board topics (but such guests may not participate in any vote on any matter before the Governing Board).
    5. Officers

      1. The officers (\u201cOfficers\u201d) of the OWF as of the first meeting of the Governing Board will be a Chairperson (\u201cChair\u201d) and a Treasurer. Additional Officer positions may be created by the Governing Board.
      2. The Chair will preside over meetings of the Governing Board, manage any day-to-day operational decisions, and will submit minutes for Governing Board approval.
      3. The Treasurer will assist in the preparation of budgets for Governing Board approval, monitor expenses against the budget and authorize expenditures approved in the budget.
    6. The Governing Board will be responsible for overall oversight of the OWF, including:

      1. approve a budget directing the use of funds raised by the OWF from all sources of sponsorship or other revenue, including to pay for the hiring of OWF leadership and staff;
      2. vet and select a qualified leadership team to run the day-to-day management activities of the organization and evaluate the performance of the team;
      3. provide feedback and input to the OWF leadership team responsible for planning and managing the day-to-day operation of the OWF;
      4. maintain, if desired, a guiding principles document;
      5. nominate and elect Officers of the OWF;
      6. supervise and support the leadership team on OWF business and community outreach matters;
      7. work with the LFEU on any legal matters that arise;
      8. adopt and maintain policies or rules and procedures for the OWF (subject to LFEU\u2019s approval);
      9. establish advisory bodies, committees, programs or councils to resolve any particular matter or in support of the mission of the OWF and/or its Technical Projects including in support of end-users and ambassadors for the project any Technical Project;
      10. establish any OWF conformance programs for its trademarks and solicit input (including testing tools) if deemed necessary from the applicable oversight body of any Technical Project for defining and administering any programs related to conformance with such Technical Project (each, a \u201cConformance Program\u201d);
      11. publish use cases, user stories, websites and priorities to help inform the ecosystem and technical community;
      12. approve procedures for the nomination and election of any representative of the General Sponsors to the Governing Board and any Officer or other positions created by the Governing Board; and
      13. vote on all decisions or matters coming before the Governing Board.
  4. Government Advisory Council

    1. The Government Advisory Council (the \u201cGAC\u201d) will provide the OWF advice from government entities approved to participate by the Governing Board. Members of the GAC must be national governments, multinational governmental organizations and treaty organizations, or public authorities. Each may appoint one representative and one alternate representative to the GAC. There are no fees to participate in the GAC.
    2. The GAC will provide advice to OWF on issues of public policy, and especially where there may be an interaction between OWF's activities and national policies, laws or international agreements.
    3. The Governing Board may appoint a chairperson of the GAC or delegate responsibility for selecting a chairperson to the GAC. The GAC chairperson or another person chosen by the GAC chairperson will serve as the \u201cGAC Representative\u201d responsible for reporting progress back to the Governing Board and interfacing with the TAC. The GAC Representative may attend meetings of the Governing Board and TAC as a non-voting member.
  5. Technical Advisory Council

    1. The role of the TAC is to facilitate communication and collaboration among the Technical Projects. The TAC will be responsible for:

      1. maintaining an overall strategic vision for technical collaboration and coordinating collaboration among Technical Projects, including development of an overall technical vision for the community;
      2. making recommendations to the Budget Committee of resource priorities for Technical Projects;
      3. electing annually a chairperson to preside over meetings, set the agenda for meetings, ensure meeting minutes are taken and who will also serve on the Governing Board as the TAC\u2019s representative (the \u201cTAC Representative\u201d);
      4. creating, maintaining and amending project lifecycle procedures and processes, deciding where Technical Projects fall within that lifecycle;
      5. determining when a technical project should be admitted as a Technical Project or any Technical Project should be considered a TAC Project; and
      6. such other matters related to the technical role of the TAC as may be communicated to the TAC by the Governing Board.
    2. The voting members of the TAC consist of:

      1. one representative appointed by each Premier Sponsor;
      2. up to two \u201cat large\u201d representatives appointed by vote of the TAC; and
      3. one representative appointed by the technical oversight body (e.g., a technical steering committee) of each TAC Project (as defined herein).
    3. TAC meetings are intended to be open to observe by Sponsors, contributors to any TAC Project and others in the general public interested in the OpenWallet Foundation. The TAC may decide whether to allow named representatives (one per voting member) to attend as an alternate.

    4. At the start of the OWF, \u201cTAC Projects\u201d are those Technical Projects listed as having voting representatives on the TAC on the Directed Fund\u2019s web site. Thereafter, any Technical Project can become a TAC Project through the approval of the Technical Project\u2019s technical oversight body and the TAC (by a two-third\u2019s vote). The TAC may approve and modify a project lifecycle policy that will address the incubation, archival and other stages of TAC Projects.
    5. The TAC representatives will elect a chair to preside over meetings, ensure minutes are taken and drive the TAC agenda with input from the TAC representatives.
  6. Voting

    1. Quorum for Governing Board and Committee meetings will require at least fifty percent of the voting representatives. If advance notice of the meeting has been given per normal means and timing, the Governing Board may continue to meet even if quorum is not met, but will be prevented from making any decisions at the meeting.
    2. Ideally decisions will be made based on consensus. If, however, any decision requires a vote to move forward, the representatives of the Governing Board or Committee, as applicable, will vote on a one vote per voting representative basis.
    3. Except as provided in Section 14.a. or elsewhere in this Charter, decisions by vote at a meeting will require a simple majority vote, provided quorum is met. Except as provided in Section 14.a. or elsewhere in this Charter, decisions by electronic vote without a meeting will require a majority of all voting representatives.
    4. In the event of a tied vote with respect to an action that cannot be resolved by the Governing Board, the Chair may refer the matter to the LFEU for assistance in reaching a decision. If there is a tied vote in any Committee that cannot be resolved, the matter may be referred to the Governing Board.
  7. Subsidiaries and Related Companies

    1. Definitions:

      1. \u201cSubsidiaries\u201d means any entity in which a Sponsor owns, directly or indirectly, more than fifty percent of the voting securities or participation interests of the entity in question;
      2. \u201cRelated Company\u201d means any entity which controls or is controlled by a Sponsor or which, together with a Sponsor, is under the common control of a third party, in each case where such control results from ownership, either directly or indirectly, of more than fifty percent of the voting securities or participation interests of the entity in question; and
      3. \u201cRelated Companies\u201d are entities that are each a Related Company of a Sponsor.
    2. Only the legal entity which has executed a Project Sponsorship Agreement and its Subsidiaries will be entitled to enjoy the rights and privileges of such sponsorship; provided, however, that such Sponsor and its Subsidiaries will be treated together as a single Sponsor.

    3. If a Sponsor is itself a foundation, association, consortium, open source project, membership organization, participation organization, user group or other entity that has members or sponsors, then the rights and privileges granted to such Sponsor will extend only to the employee-representatives of such Sponsor, and not to its members or sponsors, unless otherwise approved by the Governing Board in a specific case.
    4. OWF sponsorship is non-transferable, non-salable and non-assignable, except a Sponsor may transfer its current sponsorship privileges and obligations to a successor of substantially all of its business or assets, whether by merger, sale or otherwise; provided that the transferee agrees to be bound by this Charter and the Bylaws and policies required by LFEU sponsorship.
  8. Good Standing

    1. Linux Foundation Europe\u2019s Good Standing Policy is available at https://linuxfoundation.eu/policies and will apply to all Sponsors of this OWF.
  9. Trademarks

    1. Any trademarks relating to the OWF or any Technical Project, including without limitation any mark relating to any conformance program, must be transferred to and held by LFEU or an entity in LFEU\u2019s control and available for use pursuant to LFEU\u2019s trademark usage policy, available at https://linuxfoundation.eu/policies.
  10. Antitrust Guidelines

    1. All Sponsors must abide by Linux Foundation Europe\u2019s Antitrust Policy available at https://linuxfoundation.eu/policies.
    2. All Sponsors must encourage open participation from any organization able to meet the sponsorship requirements, regardless of competitive interests. Put another way, the Governing Board will not seek to exclude any Sponsor based on any criteria, requirements or reasons other than those that are reasonable and applied on a non- discriminatory basis to all Sponsors.
  11. Budget

    1. The Governing Board will approve an annual budget and never commit to spend in excess of funds raised. The budget and the purposes to which it is applied must be consistent with both (a) the non-profit and tax-exempt mission of LFEU and (b) the goals of any Technical Project.
    2. LFEU will provide the Governing Board with regular reports of spend levels against the budget. Under no circumstances will LFEU have any expectation or obligation to undertake an action on behalf of the OWF or otherwise related to the OWF that is not covered in full by funds raised by the OWF.
    3. In the event an unbudgeted or otherwise unfunded obligation arises related to the OWF, LFEU will coordinate with the Governing Board to address gap funding requirements.
  12. General & Administrative Expenses

    1. LFEU will have custody of and final authority over the usage of any fees, funds, and other cash receipts.
    2. A General & Administrative (G&A) fee will be applied by LFEU to funds raised to cover sponsorship records, finance, accounting, and human resources operations. The G&A fee will be 9% of the OWF\u2019s first EUR 1,000,000 of gross receipts each year and 6% of the OWF\u2019s gross receipts each year over EUR 1,000,000.
  13. General Rules and Operations.

    The OWF activities must:

    1. engage in the work of the project in a professional manner consistent with maintaining a cohesive community, while also maintaining the goodwill and esteem of LFEU in the open source community;
    2. respect the rights of all trademark owners, including any branding and usage guidelines;
    3. engage or coordinate with LFEU on all outreach, website and marketing activities regarding the OWF or on behalf of any Technical Project that invoke or associate the name of any Technical Project or LFEU; and
    4. operate under such rules and procedures as may be approved by the Governing Board and confirmed by LFEU.
  14. Amendments

    1. This Charter may be amended by a two-thirds vote of the entire Governing Board, subject to approval by LFEU.
"},{"location":"governance/code-of-conduct/","title":"Code of Conduct","text":"

The TAC may adopt a code of conduct (\u201cCoC\u201d) for the Project, which is subject to approval by LF Europe. In the event that a Project-specific CoC has not been approved, the LF Europe Code of Conduct listed at http://lfeurope.be/policies will apply for all Collaborators in the Project.

"},{"location":"governance/common-repository-structure/","title":"Common Repository Structure","text":"

OpenWallet Foundation projects are required to maintain a standard set of files in each repository. This document describes the required and recommended files.

"},{"location":"governance/common-repository-structure/#required-files-with-specified-content","title":"Required Files with Specified Content","text":"

Repositories MUST have these files with the specific content in the linked files, or a file with a link to the specified content with minimal exposition. These files MUST be at the root of the repository.

  • LICENSE

    Info

    All code within the OpenWallet Foundation should be licensed under Apache 2.0. Exceptions can be made by the OpenWallet Foundation Governing Board.

  • CODE_OF_CONDUCT.md

  • SECURITY.md
"},{"location":"governance/common-repository-structure/#required-files-with-variable-content","title":"Required Files with Variable Content","text":"

Repositories MUST have these files. Named files MUST be at the root of the repository, and may have format suffixes such as .md, .rst, or .txt.

  • README - A description of the project that contains information or links to information such as:
    • A reference to the Apache license (required).
    • The current and important past releases
    • Documentation for developers and users
  • MAINTAINERS - A list of all current maintainers with contact info. A separate document covers the specifics.
  • CONTRIBUTING - Directions on how to contribute code to the project, or a link to a page with that information.
  • CHANGELOG - A human readable list of recent changes. Changes should at least include the current release. This file may be maintainer curated or mechanically produced.
  • Continuous Integration / Continuous Delivery (CICD) configurations - Configurations needed to run CICD on OpenWallet Foundation provided systems (e.g., .github/workflows).
"},{"location":"governance/common-repository-structure/#recommended","title":"Recommended","text":"

Repositories SHOULD have these files. Named files SHOULD be at the root of the repository

  • NOTICE - As per section 4 subsection d of the Apache License, Version 2
  • Apache License Header information in each source code file. For new files added to OpenWallet Foundation repositories they SHOULD include the snippet SPDX-License-Identifier: Apache-2.0 as part of the header.
  • Build files consistent with the implementation language, such as:
    • For JavaScript/Node.js a package.json file
    • For Ruby a Gemfile file
    • For Java one of a Maven pom.xml, an Apache Ant build.xml, or a Gralde build.gradle
    • file
    • For Python setup.py and requirements.txt files
    • For Go go.mod and optionally go.sum
    • For Rust a cargo.toml file
    • For multi-lingual repositories a Makefile or executable build.sh script
    • For other languages, other standard build files a practitioner of the language would expect.
  • Testing code - Code to test the code in the repository (such as unit tests), in a location appropriate for the language.

    Why not a MUST?

    Not all repositories can be tested (homebrew, docs), which is the only reason this is a SHOULD.

"},{"location":"governance/common-repository-structure/#prohibited","title":"Prohibited","text":"

Repositories MUST NOT have these files

  • Executable binaries and shared library files built by code in the repository. This includes .exe, .dll, .so, .a and .dylib files not otherwise part of a third party library.
"},{"location":"governance/common-repository-structure/#credits","title":"Credits","text":"

This document is based on the Hyperledger Foundation's Common Respository Structure guideline.

"},{"location":"governance/content-plan/","title":"Content Plan","text":"

This document provides details about the different channels that we have within the OpenWallet Foundation and what we expect each to be used for.

Channel

What

Roles

Discord

  • Real-Time Communication: Chat services facilitate real-time, synchronous communication among users. Messages are sent and received instantly, enabling quick exchanges and conversations.
  • Interactive Collaboration: Chat services are well-suited for interactive collaboration, allowing users to engage in live discussions, share files, collaborate on documents, and even conduct video calls in some cases.

Staff: Administers, creates new channels, and moderates

Community: Sends messages and monitors

Mailing Lists

  • Asynchronous Communication: Mailing lists are primarily used for asynchronous communication. Users send messages to a central email address, which are then distributed to all subscribers. Subscribers can read and respond to messages at their convenience.
  • Broadcasting Information: Mailing lists are effective for broadcasting information to a group of subscribers. They are commonly used for announcements, discussions, and sharing updates within a community or organization.
  • Archiving: Mailing lists typically archive messages, allowing subscribers to access past discussions and reference previous communications. This archival feature can be valuable for maintaining a record of conversations and facilitating knowledge sharing.

Staff: Administers, creates new lists, and moderates

Community: Sends messages and monitors

GitHub

  • Project-Based Source Code and User Documentation: Any source code for projects should utilize GitHub. GitHub pages should be used for hosting user documentation.
  • TAC Governance Documentation and Other Relevant Information: Governance documentation for the TAC must be version controlled. As such, GitHub is the appropriate place to store this information in addition to other relevant TAC materials. Currently https://tac.openwallet.foundation is generated from markdown files in GitHub.
  • SIG or Task Force Deliverables: A separate repo can be set up for SIGs and Task Forces so that they can have versioned control support for their deliverables.

Staff: Administers, creates new repos and teams

Maintainers: Reviews and handles issues and pull requests

Community: Use source,create issues, fork code, and contribute

Website

  • Blogs
  • Announcements
  • Native content
  • Events and Conferences

Staff: Administers and determines contents

Community: Visit and contribute blog posts

Wiki

  • Project Meeting Minutes
  • SIG Meeting Minutes
  • Task Force Meeting Minutes
  • Collaborative Editing

Staff: Administers and creates new spaces

Community: Creates and edits pages

LFX Meetings (Zoom)

  • Project, SIG, and TAC meetings: All project, SIG, and TAC meetings must be held using LFX meetings. This ensures that a recording of the meeting is captured and available for people to catch up on what they may have missed. Send an email to operations@openwallet.foundation to get your meetings scheduled.

Staff: Administers and creates new meetings

Community: Attends meetings and listen to recordings

YouTube

  • Community meeting recordings
  • Webinar recordings
  • Event recordings

Staff: Administers and adds videos and playlists

Community: Watch videos

Social Media

  • Twitter
  • LinkedIn
  • Posts about activities and events that the community may be interested in
  • Posts to announce new projects, SIGs, Task Forces, blog posts

Staff: Administers and posts content

Community: Reads content

"},{"location":"governance/elections/","title":"Elections","text":""},{"location":"governance/elections/#electing-a-chair","title":"Electing a Chair","text":"

From the OWF Charter

The TAC is responsible for ... electing annually a chairperson to preside over meetings, set the agenda for meetings, ensure meeting minutes are taken and who will also serve on the Governing Board as the TAC\u2019s representative (the \u201cTAC Representative\u201d).

The TAC voting members (as defined by the charter) will elect a chair on a yearly basis. Only TAC voting members are eligible to run for the TAC chair seat. Electing a chair will be completed through the voting process outlined below. If the TAC chair must leave their position during their term or is otherwise unable to fulfill their duties, they should submit a resignation and allow the TAC to fill the vacancy using the process outlined below.

"},{"location":"governance/elections/#electing-a-vice-chair","title":"Electing a Vice Chair","text":"

The TAC voting members (as defined by the charter) will elect a vice chair on a yearly basis. Only TAC voting members are eligible to run for the TAC vice chair seat. Electing a vice chair will be held in conjunction with the chair election using the voting process outlined below. The person with the second highest number of votes will serve as the vice chair. If the TAC vice chair must leave their position during their term or is otherwise unable to fulfill their duties, they should submit a resignation and allow the TAC to fill the vacancy using the process outlined below.

"},{"location":"governance/elections/#electing-at-large-representatives","title":"Electing \"At Large\" Representatives","text":"

Implied from the OWF Charter

The TAC is responsible for ... appointing up to two \"at large\" representatives to the TAC.

The TAC voting members (as defined by the charter) can appoint up to two \"at large\" representatives to the TAC. The election process for \"at large\" representatives will occur on a yearly basis. Members of the community can nominate themselves for the position. Alternatively, a TAC voting member can nominate a member of the community; however, the nominee must actively affirm their candidacy. Electing \"at large\" representatives will be completed through the voting process outlined below. If the \"at large\" representative must leave their position during their term or is otherwise unable to fulfill their duties, they should submit a resignation. \"At large\" vacancies will be handled using the process outlined below.

"},{"location":"governance/elections/#voting-process","title":"Voting Process","text":""},{"location":"governance/elections/#voting-tool","title":"Voting Tool","text":"

Voting occurs by a time-limited Helios Voting ballot.

"},{"location":"governance/elections/#voting-schedule","title":"Voting Schedule","text":"

The following is the default timeline for voting. The times can be adjusted to avoid weekends and holidays, but it is essential that the final schedule be published in advance and adhered to.

  • Call for nominations: Noon PT, E-16 days
  • End of call for nominations: Noon PT, E-9 days
  • A ballot will be distributed on: E-7 days
  • The election will be completed on: Noon PT, E-day and election results are announced

Nominations

Nominees should outline their qualifications and provide a statement explaining why they would be a good choice for the seat.

"},{"location":"governance/elections/#vacancies","title":"Vacancies","text":""},{"location":"governance/elections/#tac-chair-vacancy","title":"TAC Chair Vacancy","text":"

Should the TAC Chair seat become vacant, the vacancy will be filled by the vice chair who will serve the remainder of the original term.

"},{"location":"governance/elections/#tac-vice-chair-vacancy","title":"TAC Vice Chair Vacancy","text":"

Should the TAC Vice Chair seat become vacant, the vacancy will be filled by using the voting process outlined above and the replacement will serve the remainder of the original term.

"},{"location":"governance/elections/#tac-at-large-representative-vacancy","title":"TAC \"At Large\" Representative Vacancy","text":"

Should a TAC \"at large\" representative seat become vacant, the vacancy will be filled at the next indicative election, by electing a person for a full new term, not by serving out the vacant term.

Why?

A TAC \"at large\" vacancy is not filled immediately because the charter does not specify a lower limit for TAC \"at large\" representatives; it only specifies an upper limit.

"},{"location":"governance/elections/#tac-premier-sponsor-representative-vacancy","title":"TAC Premier Sponsor Representative Vacancy","text":"

Should a TAC premier sponsor representative seat become vacant, the premier sponsor will immediately appoint a new representative.

"},{"location":"governance/elections/#tac-project-representative-vacancy","title":"TAC Project Representative Vacancy","text":"

Should a TAC Project representative seat become vacant, the technical oversight body (e.g., a technical steering committee) for the TAC project will immediately appoint a new representative.

"},{"location":"governance/maintainer-inactivity/","title":"Maintainer Inactivity Policy","text":"

Note

This policy applies to projects that do not have an explicit maintainer inactivity policy. Where a project has an established and functioning policy, only that project's policy will apply.

OpenWallet Foundation very much appreciates the contributions of all maintainers but removing write privileges is in the interest of an orderly and secure project.

Activity can be code contributions, code reviews, issue reporting, or any other such activity trackable by GitHub attributed to a OpenWallet Foundation repository.

When a maintainer has not had any activity in a particular project for three months they will receive a notification informing them of the inactivity policies. The means and manner of notification (email, github mentions, etc.) will be at the discretion of the TAC Chair or who the TAC Chair designates.

When a maintainer has not had any activity in a particular project for six months a proposal will be opened up to move the maintainer from active status to emeritus status. A member of the TAC or a OpenWallet Foundation staff member will open this proposal. Any permissions to approve pull requests or commit code and any other such privileges associated with maintainer status will be removed.

The proposal will be in the form of a pull request (PR) to the relevant project repositories updating their maintainer lists. The inactive maintainer will be notified of this via an \"at\" @ mention in the PR. The PR will be open for at least one week to allow time for the project and maintainer to comment.

Inactive maintainers who express an intent to continue contributing may request a three-month extension. This request shall be made in the pull request updating their active maintainer status. Typically, only one such extension will be granted.

Maintainers who have been moved to emeritus status may return to active status when their activity within the project resumes and the current maintainers of the project approve their reactivation.

An OpenWallet Foundation Foundation staff member will provide a report (or maintain an automated means to generate a report) of the most recent GitHub tracked actions for contributors at regular intervals to the TAC. It will be the TAC's responsibility to act on the data.

"},{"location":"governance/maintainer-inactivity/#credits","title":"Credits","text":"

This document is based on the Hyperledger Foundation's Inactivity policy

"},{"location":"governance/maintainers-file-content/","title":"MAINTAINERS.md File Contents","text":"

All OpenWallet Foundation projects MUST have a MAINTAINERS file (MAINTAINERS.md or MAINTAINERS.rst) at the top-level directory of the source code. This document will provide specifics on what to include in the MAINTAINERS file.

"},{"location":"governance/maintainers-file-content/#list-of-project-maintainers","title":"List of Project Maintainers","text":"

The first thing that MUST be included in the MAINTAINERS file is a list of the project's maintainers, both active and emeritus.

It is recommended that the lists be sorted alphabetically and contain the maintainers name, GitHub ID, LFID, Chat ID, Email, Company Affiliation, and Scope.

Important

  • The email for a maintainer MUST be specified and be a reliable mechanism to contact the maintainer.
  • Scope is dependent on the project and may not exist for a given project. Scope could be the whole project, a specific repository, specific directories in a repository, or high-level description of responsibility (e.g., Documentation).

The following shows the suggested format for the information:

Example

Active Maintainers

Maintainer GitHub ID LFID Email Chat ID Company Affiliation Scope

Emeritus Maintainers

Maintainer GitHub ID LFID Email Chat ID Company Affiliation Scope"},{"location":"governance/maintainers-file-content/#what-does-being-a-maintainer-entail","title":"What Does Being a Maintainer Entail","text":"

The MAINTAINERS file SHOULD contain information about the different types of maintainers that exist (whole project, repo, part of repo) and what their duties are (e.g., maintainers calls, quarterly reports, code reviews, issue cleansing).

"},{"location":"governance/maintainers-file-content/#how-to-become-a-maintainer","title":"How to Become a Maintainer","text":"

The MAINTAINERS file SHOULD contain information about how to become a maintainer for the project. This section SHOULD list specific information about what is required. Information that SHOULD be included in this section:

  • What is required before someone can be considered to become a maintainer
  • Consider whether there should be different requirements based on the scope (whole project, repo, part of repo) of maintainership
  • Whether sponsorship by an existing maintainer is required
  • How maintainers are proposed to the community. A number of open source projects require that a PR be done against the MAINTAINERS file to make this proposal
  • How many maintainers must approve the proposed maintainer. This should include information about what happens if someone vetoes the proposal
  • How long the existing maintainers have to respond to the proposal
"},{"location":"governance/maintainers-file-content/#how-maintainers-are-removed-or-moved-to-emeritus-status","title":"How Maintainers are Removed or Moved to Emeritus Status","text":"

The MAINTAINERS file SHOULD contain information about how a maintainer is removed from the list of active maintainers. Information that SHOULD be included in this section:

  • What are the reasons a maintainer would be removed from the list of active maintainers
  • How this is proposed; similar to the way in which maintainers are added, one way to do this is via a PR against the MAINTAINERS file
  • How an emeritus maintainer becomes active again
"},{"location":"governance/maintainers-file-content/#credits","title":"Credits","text":"

This document is based on the Hyperledger Foundation's MAINTAINERS guideline.

"},{"location":"governance/paid-tooling-policy/","title":"Paid Tooling Policy","text":"

OpenWallet Foundation (OWF) provides a number of paid developer tools for projects. Below, we list the ones that our projects currently have access to and are supported by the OWF staff. We emphasize that just because a tool is not on this list does not mean projects cannot use it; it just means that the project maintainers may have to support it themselves and may need to pay for the tooling. The Governing Board has final say over the budget for tooling and its support.

OWF recommends the following tools that should be optimal for most projects:

  • Technical Documentation: markdown, GitHub pages, and Material for MkDocs.

  • Informal documentation and details (e.g. meeting notes, meeting agendas, long-term planning documentation, etc.): GitHub

  • CI: GitHub Actions

  • Artifact Storage: GitHub Packages

  • Communication: Discord

  • Bug Tracking: GitHub Issues and GitHub Projects

  • Mailing Lists: Groups.io

  • Meetings: Zoom via LFX Meetings

Finally we emphasize that this list does not cover security-related tools or services.

"},{"location":"governance/project-and-lab-services/","title":"Project and Lab Services","text":"

This document provides details about what resources are available for OpenWallet Foundation projects and labs. If there are any questions about anything on the document or if you'd like to leverage any of these resources for your project or lab, feel free to reach out to community-architects at openwallet dot foundation.

Service Lab Growth Project Impact Project Infrastructure Github repos Yes Yes Yes Chat channel Yes Yes Yes Mailing list Optional Yes Yes Paid tooling Yes (with some restrictions at the discretion of OpenWallet Foundation staff) Yes Yes Marketing Access to OpenWallet Foundation's channels (social, newsletters, blogs, meetups, etc) Yes (with some restrictions at the discretion of the Marketing lead) Yes Yes Page on the OpenWallet Foundation site Yes Yes Creation of an official project name and logo Yes Yes Coordinate promotion of major project milestones and releases Yes Yes Option to create a Twitter account Yes Yes Priority placement on site Yes Swag (stickers and potentially other items with the project logo) Yes Onboarding New Users and Contributors Able to take part in OpenWallet Foundation's annual Mentorship program TBD TBD TBD Able to have project/lab featured in a contribution campaign Yes (at the discretion of OpenWallet Foundation staff) TBD TBD Workshops Yes Documentation and Translation support TBD TBD TBD Training/Certification LF created training course Yes (at the discretion of LF Training) Yes (at the discretion of LF Training) LF created certification Yes (at the discretion of LF Training) Other License scanning Yes Yes Security audits Not usually (although this can be done at the discretion of staff) Yes (at the discretion of OpenWallet Foundation staff)"},{"location":"governance/project-annual-review-process/","title":"Project Annual Review Process","text":""},{"location":"governance/project-annual-review-process/#overview","title":"Overview","text":"

The TAC will undertake an annual review of all OpenWallet Foundation projects. This annual review will include an assessment as to whether:

  • each Lab is active
  • each Growth Stage project is making adequate progress towards the Impact Stage
  • each Impact Stage project is maintaining progress to remain at the Impact Stage

Reviews will start on the yearly anniversary of the project being accepted or moving to a new stage. The review will include a set of recommendations for each project to improve and/or recommendation to move a project across stages.

Projects can be provided with an extension of time in their current stage (up to the discretion of the TAC).

The project lifecycle contains Acceptance Criteria for moving a project to a new stage.

"},{"location":"governance/project-annual-review-process/#filing-an-annual-review","title":"Filing an Annual Review","text":"

OpenWallet Foundation staff will notify the project maintainers when the project review is due.

Project maintainers are responsible for agreeing between them who will complete the annual review. One of the maintainers should create the review in GitHub under openwallet-foundation/tac/docs/projects/reviews.

  • Raise a PR titled [Project name] [year] Annual Review (e.g., Amazing Project 2024 Annual Review)
  • The PR should include a file called <year>-<project name>-annual.md (e.g., 2024-amazingproj-annual.md) with the contents described below
  • Send an email to the TAC mailing list so that the community knows the PR is there and can comment on it

If your annual review is not submitted within two months of notification, we will take this as a sign that the project is not under active maintenance and the TAC is likely to decide to archive the project and move it to Emeritus status.

Success

If a project has genuinely stalled we can save everyone\u2019s time and effort by archiving it.

"},{"location":"governance/project-annual-review-process/#annual-review-contents","title":"Annual Review Contents","text":"

Your annual review should answer the following questions:

  • Include information about your project's contributions and activity. We will be looking for signs of consistent or increasing contribution activity. Please feel free to add commentary to add colour to the numbers and graphs we will see on Insights.
  • How many maintainers do you have, and which organisations are they from? (Feel free to link to an existing MAINTAINERS file if appropriate.)
  • What do you know about adoption, and how has this changed since your last review or since being accepted into OWF? If you can list companies that are adopters of your project, please do so. (Feel free to link to an existing ADOPTERS file if appropriate.
  • How has the project performed against its goals since the last review? (We won't penalize you if your goals changed for good reasons.)
  • What are the current goals of the project? For example, are you working on major new features? Or are you concentrating on adoption or documentation?
  • How can the OpenWallet Foundation help you achieve your upcoming goals?
  • Do you think that your project meets the criteria for another stage (see Project Lifecycle Acceptance Criteria for the different stages)?

A template has been provided for your use.

"},{"location":"governance/project-annual-review-process/#annual-review-by-the-tac","title":"Annual Review by the TAC","text":"

Annual reviews are performed in order to check in with projects, ascertain their progress, and address any outstanding questions.

  • A TAC representative volunteers to lead the review once the project files a PR.
  • The assigned TAC member reviews the content of the PR and analyzes the project for community health indicators, their findings are placed within a thread in the private TAC channel for discussion.
    • findings should highlight important facts about the project that could influence the TACs decision around the future of the project, its current stage, and path to other stages, etc.
    • the thread should always include whether the project's view of themselves is accurate and the ask of the TAC is reasonable to assist the project moving forward.
  • The project's maintainers are invited to the public TAC meeting to engage in TAC led discussion around the project. Project maintainers are not obligated to attend.
  • The assigned TAC member provides a summary of the project and leverages the thread's content as the basis of discussion.
    • discussion typically focuses on what is going well with the project and areas to improve.
  • The project's maintainers are invited to use this time to voice any concerns and requests for help they may have that are not captured in the PR (or highlight asks within the PR).
  • At the conclusion of the public meeting, the TAC votes to approve the annual review. Should a concern be registered on a project, the vote will be held separately.
  • After the meeting wraps up, the assigned TAC member may summarize the discussion on the PR in the form of a comment to document information for the project and community.
"},{"location":"governance/project-annual-review-process/#review-outcomes","title":"Review Outcomes","text":"

The outcome of the annual review is either:

  • At least two-thirds of the TAC members agree to continue to sponsor the project at its current stage, or
  • If enough TAC members do not agree to continue to sponsor the project at its current stage, we will discuss with you what stage might be the appropriate next stage, including Emeritus stage.

    Info

    If the TAC members recommend moving to a new stage, additional work may be required to provide details on how the project meets the new stage's acceptance criteria.

"},{"location":"governance/project-annual-review-process/#credits","title":"Credits","text":"

Ideas were taken from CNCF's Sandbox Annual Review Process.

"},{"location":"governance/project-lifecycle/","title":"Project Lifecycle","text":""},{"location":"governance/project-lifecycle/#overview","title":"Overview","text":"

This governance policy describes how an open source project can formally join the OpenWallet Foundation via the Project Proposal Process and how an existing project within the OpenWallet Foundation can move through the lifecycle via the Project Stage Change Proposal Process. It describes the Stages a project may be admitted under and what the criteria and expectations are for a given stage, as well as the acceptance criteria for a project to move from one stage to another. It also describes the Annual Review Process through which those changes will be evaluated and made.

Project progression - movement from one stage to another - allows projects to participate at the level that is most appropriate for them given where they are in their lifecycle. Regardless of stage, all OpenWallet Foundation projects benefit from a deepened alignment with existing projects, and access to mentorship, support, and Foundation resources.

Info

Capitalized terms not otherwise defined in this Project Lifecycle Policy have the meanings ascribed to them in the Charter of the OpenWallet Foundation.

"},{"location":"governance/project-lifecycle/#project-proposal-process","title":"Project Proposal Process","text":""},{"location":"governance/project-lifecycle/#introduction","title":"Introduction","text":"

This governance policy sets forth the proposal process for projects to be accepted into the OpenWallet Foundation. The process is the same for both existing projects which seek to move into the OpenWallet Foundation and new projects to be formed within the OpenWallet Foundation.

"},{"location":"governance/project-lifecycle/#project-proposal-requirements","title":"Project Proposal Requirements","text":"

Projects must be formally proposed via GitHub. Project proposals submitted to the OpenWallet Foundation should provide the following information to the best of their ability:

  • name of project
  • preferred maturity level (see stages below)
  • project description (what it does, why it is valuable, origin and history)
  • statement on alignment with the OpenWallet Foundation mission
  • link to current Code of Conduct (if one is adopted already)
  • sponsor from the TAC, if identified (a sponsor helps mentor projects)
  • project license (OSI-approved permissive open source licenses, Apache 2.0 by default)
  • source control (OpenWallet Foundation GitHub by default)
  • issue tracker (OpenWallet Foundation GitHub by default)
  • external dependencies (including licenses)
  • release methodology and mechanics
  • names of initial maintainers, if different from those submitting proposal
  • link to any documented governance practices (e.g., the project charter) (A project charter can be obtained by completing this form. Here is sample project charter that you can review)
  • existing financial sponsorship (if exists)
  • infrastructure needs or requests (OpenWallet Foundation provides a set of services for projects and labs. Please note which of these you will utilize and what else is required)
"},{"location":"governance/project-lifecycle/#project-acceptance-process","title":"Project Acceptance Process","text":"
  • Impact stage and Growth stage projects are required to present their proposal at a TAC meeting. Labs will be reviewed and approved directly via the project proposal PR. Labs may present at a TAC meeting if they would like to gain visibility from other community members, and the proposer should note this in the proposal.
  • The TAC may ask for changes to bring the project into better alignment with the OpenWallet Foundation (adding a governance document to a repository or adopting a Code of Conduct, for example).

    Warning

    The project will need to make these changes in order to progress further.

  • Impact stage and Growth stage projects are accepted via a two-thirds supermajority vote of the TAC. Labs are accepted via a simple majority of the TAC.

  • Satisfaction of the requirements of the initial stage of the project. The TAC will determine the appropriate initial stage for the project. The project can apply for a different stage via the review process.
"},{"location":"governance/project-lifecycle/#project-stage-change-proposal-process","title":"Project Stage Change Proposal Process","text":""},{"location":"governance/project-lifecycle/#introduction_1","title":"Introduction","text":"

This governance policy sets forth the proposal process for projects within the OpenWallet Foundation that are seeking to move to another stage in the project lifecycle.

"},{"location":"governance/project-lifecycle/#proposal-process","title":"Proposal Process","text":"

The project's current proposal located in Project Proposals GitHub Repository must be updated via a PR. The project proposal should be updated to reflect the latest template, as well as any updates to the sections to reflect why the project should be considered for a new stage.

"},{"location":"governance/project-lifecycle/#project-stage-change-acceptance-process","title":"Project Stage Change Acceptance Process","text":"

The same acceptance project outlined above will be used for projects wishing to change lifecycle stage.

"},{"location":"governance/project-lifecycle/#stages","title":"Stages","text":"

Every OpenWallet Foundation project has an associated maturity level. Proposed projects should state their preferred maturity level.

All projects may attend TAC meetings and contribute work regardless of their stage.

flowchart\n  p[Proposal]\n  subgraph as[Active Stages]\n    l[Labs]\n    g[Growth]\n    i[Impact]\n  end\n  subgraph is[Inactive Stages]\n    e[Emeritus]\n  end\n  p --> as\n  l <--> g\n  l <--> i\n  g <--> i\n  as --> is  
"},{"location":"governance/project-lifecycle/#labs","title":"Labs","text":"

Definition

Labs are those which the TAC believes are, or have the potential to be, important to the ecosystem of Technical Projects or the open wallet ecosystem as a whole. They may be early-stage code just getting started, or they may be long-established projects with minimal resource needs. The Labs stage provides a beneficial, neutral home for these projects in order to foster collaborative development and provide a path to deeper alignment with other OpenWallet Foundation projects via the project lifecycle process.

Examples

  1. Experimental code that is designed to extend one or more OpenWallet Foundation projects with functionality or interoperability libraries.
  2. Independent code that fits within the Foundation's mission and provides potential to meet an unfulfilled need.
  3. Code commissioned or sanctioned by the OpenWallet Foundation.
  4. Any code that intends to join the Growth or later stages in the future and wishes to lay the foundation for that transition.

Expectations

End users should evaluate Labs with care, as this stage does not set requirements for community size, governance, or production readiness. Labs will receive minimal support from the Foundation. Labs will be reviewed on an annual basis; they may also request a status review by submitting a report to the TAC.

Acceptance Criteria

To be considered for the Labs Stage, the project must meet the following requirements:

  • Complete an project intake form. This intake form will create:
    • A project charter (sample) that documents an intellectual property policy that leverages the Apache 2.0 license or a permissive open source license.
    • A collaboration agreement that in the case of existing projects, provides an agreement to transfer the project name, trademarks, and electronic account assets (github repo, social media accounts, domain names, etc.) to Linux Foundation Europe for the benefit of the OpenWallet Foundation.
  • Submit a project proposal.

Upon acceptance, Labs must list their status prominently on their website/README (e.g., PROJECT, an OpenWallet Foundation Lab).

"},{"location":"governance/project-lifecycle/#growth-stage","title":"Growth Stage","text":"

Definition

The Growth Stage is for projects that are interested in reaching the Impact Stage, and have identified a growth plan for doing so. Growth Stage projects will receive mentorship from the TAC and are expected to actively develop their community of contributors, governance, project documentation, roadmap, and other variables identified in the growth plan that factor into broad success and adoption.

In order to support their active development, projects in the Growth stage have a higher level of access to Foundation resources, which will be agreed upon and reviewed on a yearly basis. A project's progress toward its growth plan goals will be reviewed on a yearly basis, and the TAC may ask the project to move to the Labs stage if progress on the plan drops off or stalls.

Examples

  1. Projects that are on their way or very likely to become Growth or Impact projects.
  2. Projects that have developed new growth targets or other community metrics for success.
  3. Projects that are looking to create a lifecycle plan (maintainership succession, contributor programs, version planning, etc.).
  4. Projects that need more active support from the Foundation or TAC mentorship in order to reach their goals.

Expectations

Projects in the Growth stage are generally expected to move out of the Growth stage within two years. Depending on their growth plans, projects may cycle through Labs, Growth, or Impact stage as needed.

Acceptance Criteria

To be considered for Growth Stage, the project must meet the Labs requirements as well as the following:

  • A presentation at the meeting of the TAC.
  • 2 TAC sponsors to champion the project and provide mentorship as needed.
  • Development of a growth plan, to be done in conjunction with their project mentor(s) at the TAC.
  • Development of a project roadmap that provides differentiated features and capabilities and the timeframe for completion.
  • Document that it is being used successfully in either proof of concepts or pilots by at least two independent end users which, in the TAC\u2019s judgment, are of adequate quality and scope.
  • Demonstrate a substantial ongoing flow of commits and merged contributions.
  • Demonstrate that the current level of community participation is sufficient to meet the goals outlined in the growth plan and roadmap.
  • Since these metrics can vary significantly depending on the type, scope and size of a project, the TAC has final judgment over the level of activity that is adequate to meet these criteria.
  • Demonstrates how this project differs from existing projects in the Growth and Impact stages.
  • Receive a two-thirds supermajority vote of the TAC to move to Growth Stage.

Upon acceptance, Growth projects must list their status prominently on their website/README (e.g., PROJECT, an OpenWallet Foundation Project).

"},{"location":"governance/project-lifecycle/#impact-stage","title":"Impact Stage","text":"

Definition

The Impact Stage is for projects that have reached their growth goals and are now on a sustaining cycle of development, maintenance, and long-term support. Impact Stage projects are used commonly in enterprise production environments and have large, well-established project communities.

Examples

  1. Projects that have publicly documented release cycles and plans for Long Term Support (\"LTS\").
  2. Projects that have themselves become platforms for other projects.
  3. Projects that are able to attract a healthy number of committers on the basis of its production usefulness (not simply 'developer popularity').
  4. Projects that have several, high-profile or well known end-user implementations.

Expectations

Impact Stage projects are expected to participate actively in TAC proceedings, and as such have a binding vote on TAC matters requiring a formal vote, such as the election of a TAC representative. They receive ongoing financial and marketing support from the Foundation, and are expected to cross promote the Foundation along with their activities.

Acceptance Criteria

To move from Labs or Growth status, or for a new project to join as an Impact project, a project must meet the Growth stage criteria plus:

  • Have a defined governing body of at least 5 or more members (owners and core maintainers), of which no more than one-third is affiliated with the same employer. In the case there are 5 governing members, 2 may be from the same employer.
  • Have a documented and publicly accessible description of the project's governance, decision-making, and release processes.
  • Have a healthy number of maintainers from at least two organizations. A maintainer is defined as someone with the commit bit; i.e., someone who can accept contributions to some or all of the project.
  • Have a Code of Conduct in a form acceptable to the OpenWallet Foundation.
  • Explicitly define a project governance and maintainer process. This is preferably laid out in a GOVERNANCE.md file and references a CONTRIBUTING.md and MAINTAINERS.md file showing the current and emeritus maintainers (see MAINTAINERS.md File Contents for more information).
  • Document that it is being used successfully in production by at least two independent end users which, in the TAC\u2019s judgment, are of adequate quality and scope.
  • Have a public list of project adopters for at least the primary repo (e.g., ADOPTERS.md or logos on the project website).
  • Have a good standing with respect to security.
  • Other metrics as defined by the applying Project during the application process in cooperation with the TAC.
  • Receive a supermajority vote from the TAC to move to Impact stage. Projects can move directly from Labs to Impact, if they can demonstrate sufficient maturity and have met all requirements.

Upon acceptance, Impact projects must list their status prominently on their website/README (e.g., PROJECT, an OpenWallet Foundation Project).

"},{"location":"governance/project-lifecycle/#emeritus-stage","title":"Emeritus Stage","text":"

Definition

Emeritus projects are projects which the maintainers feel have reached or are nearing end-of-life. Emeritus projects have contributed to the ecosystem, but are not necessarily recommended for modern development as there may be more actively maintained choices. The Foundation appreciates the contributions of these projects and their communities, and the role they have played in moving the ecosystem forward.

Examples

  1. Projects that are \"complete\" by the maintainers' standards.
  2. Projects that do not plan to release major versions in the future.

Expectations

Projects in this stage are not in active development. Their maintainers may infrequently monitor their repositories, and may only push updates to address security issues, if at all. Emeritus projects should clearly state their status and what any user or contributor should expect in terms of response or support. If there is an alternative project the maintainers recommend, it should be listed as well. The Foundation will continue to hold the IP and any trademarks and domains, but the project does not draw on Foundation resources.

Acceptance Criteria

Projects may be granted Emeritus status via a two-thirds vote from the TAC and with approval from project ownership. In cases where there is a lack of project ownership, only a two-thirds vote from the TAC is required.

Upon acceptance, Emeritus projects must list their status prominently on their website/README.

Info

If members of the community would like to re-active a project that has been granted Emeritus status, the community must start the lifecycle over again by submitting a new proposal to the TAC.

"},{"location":"governance/project-lifecycle/#annual-review-process","title":"Annual Review Process","text":"

Each project will undergo an annual review process to determine whether projects are in the stage that accurately reflects their needs and goals.

"},{"location":"governance/release-taxonomy/","title":"Release Taxonomy","text":"

Note

This policy is not about exiting project stages.

Releases at OpenWallet Foundation must be done according to the SemVer taxonomy. In addition to the semantic versioning scheme, where we use MAJOR.MINOR.PATCH numbering, following the established guidance given in the semver specification, it is also strongly encouraged that projects should use the following tags, as permitted by semver:

  • preview
  • alpha
  • beta
  • rcN (release candidate N - where N is 1-n incremented for each candidate)
  • snapshot-<sha> for interim, possible unstable builds

    Note

    Further, for interim, possibly unstable builds working towards a tagged release, we will append the first seven (7) characters of the SHA-1 hash of the latest commit for the branch from which the build is produced, so that we can identify the commit level of a given test, etc. e.g. 0.6-snapshot-36e99cd

"},{"location":"governance/release-taxonomy/#preview","title":"preview","text":"

Not feature complete, but most functionality is implemented. Any missing functionality that is committed to the production release is identified, and there are specific people working on those features. Not heavily performance tuned, but performance testing has started with the first few hotspots identified and perhaps even addressed. No highest priority issues are in an open state. First-level developer documentation provided to help new developers with the learning curve.

"},{"location":"governance/release-taxonomy/#alpha","title":"alpha","text":"

Feature complete, for all features committed to the production release. Ready for Proof of Concept-level deployments. Performance can be characterized in a predictable way, so that basic PoC's can be done within the bounds of published expectations. APIs are documented. First attempts at end-user documentation have been made. Developer documentation is further advanced. No highest priority issues are in an open state.

"},{"location":"governance/release-taxonomy/#beta","title":"beta","text":"

Feature complete for all features committed to the production release, perhaps with optional features when safe to add. Ready for Pilot-level engagements. Performance is very well characterized and active optimizations are being done, with a target set for the Production release. No highest priority or high priority bugs are in an open state. Developer documentation is complete; end-user documentation is mostly done.

"},{"location":"governance/release-taxonomy/#rcn","title":"rcN","text":"

For a forthcoming production release, we will prepare multiple candidate releases intended to be heavily tested by the community. As we cycle through resolving uncovered issues, we will issue another when no remaining highest or high priority issues remain, and repeat until we feel confident in releasing a production release, with no qualifier. e.g. 1.0.

"},{"location":"governance/release-taxonomy/#credits","title":"Credits","text":"

This document is based on the Hyperledger Foundation's Release Taxonomy policy.

"},{"location":"governance/roles-and-responsibilities/","title":"Roles and Responsibilities","text":""},{"location":"governance/roles-and-responsibilities/#technical-advisory-council","title":"Technical Advisory Council","text":"

The OpenWallet Foundation charter states that the TAC is responsible for:

Quote

  1. maintaining an overall strategic vision for technical collaboration and coordinating collaboration among Technical Projects, including development of an overall technical vision for the community;
  2. making recommendations to the Budget Committee of resource priorities for Technical Projects;
  3. electing annually a chairperson to preside over meetings, set the agenda for meetings, ensure meeting minutes are taken and who will also serve on the Governing Board as the TAC\u2019s representative (the \u201cTAC Representative\u201d);
  4. creating, maintaining and amending project lifecycle procedures and processes, deciding where Technical Projects fall within that lifecycle;
  5. determining when a technical project should be admitted as a Technical Project or any Technical Project should be considered a TAC Project; and
  6. such other matters related to the technical role of the TAC as may be communicated to the TAC by the Governing Board.
"},{"location":"governance/roles-and-responsibilities/#tac-members","title":"TAC Members","text":"

TAC members are expected to:

  • Subscribe to the TAC mailing list and the OpenWallet Github organization to stay aware of the TAC related updates and issues
  • Regularly participate in the TAC meetings
  • Bring up and help resolve any issues related to the needs of the OpenWallet technical community
  • Participate in, and optionally chair, the Task Forces set up by the TAC to address specific issues
  • Act as stewards for OpenWallet Foundation promoting and helping grow the organization and its activities by engaging of their own accord in activities such as posting on social media, responding to questions raised in forums, helping new community members find their way around, and giving talks at conferences on OpenWallet Foundation related topics
  • Participate in the appointment and election of \"at large\" representatives
"},{"location":"governance/roles-and-responsibilities/#tac-chair","title":"TAC Chair","text":"

The TAC chair has the following additional responsibilities:

  • Running the TAC meetings, such as the TAC calls per the agreed upon schedule. This includes: setting up and publishing an agenda, running the meeting, and ensuring any outcome is duly recorded
  • Representing the TAC, and more broadly the OpenWallet Foundation technical community, on the Governing Board, and giving updates to the Governing Board on TAC activities
"},{"location":"governance/roles-and-responsibilities/#tac-vice-chair","title":"TAC Vice Chair","text":"

The TAC vice chair has the following additional responsibilities:

  • Running the TAC meetings when the TAC Chair is unable, including setting up and publishing an agenda and ensuring any outcome is duly recorded
  • Helping to marshall people who want to talk during a meeting
"},{"location":"governance/security-template/","title":"PROJECT Security Policy","text":""},{"location":"governance/security-template/#instructions","title":"Instructions","text":"

The following is the best practices template security vulnerability disclosure policy for OpenWallet Foundation's projects. Please copy the text below, place it into the SECURITY.md file for the primary repository of your project, and adjust it as necessary for your project. Notably:

  • Remove this \"Instructions\" section.
  • Replace PROJECT in the title of this page with the name of your project.
  • Populate the Security Team section with maintainers who have agreed to be on the security team.
  • See the \"Alternative\" notes in the OpenWallet Foundation's security vulnerability disclosure policy document for how the \"best practices\" in this document can be changed to meet the needs of your project while still adhering to the OpenWallet Foundation's policies.

Once your project's security vulnerability disclosure policy document is published, place a copy of it into each of your project's repositories (or link to the main repository's SECURITY.md).

"},{"location":"governance/security-template/#about-this-document","title":"About this Document","text":"

This document document defines how security vulnerability reporting is handled in this project. The approach aligns with the OpenWallet Foundation's security vulnerability disclosure policy. Please review that document to understand the basis of the security reporting for this project

This policy borrows heavily from the recommendations of the OpenSSF Vulnerability Disclosure working group. For up-to-date information on the latest recommendations related to vulnerability disclosures, please visit the GitHub of that working group.

If you are already familiar with what a security vulnerability disclosure policy is and are ready to report a vulnerability, please jump to Report Intakes.

"},{"location":"governance/security-template/#what-is-a-vulnerability-disclosure-policy","title":"What Is a Vulnerability Disclosure Policy?","text":"

No piece of software is perfect. All software (at least, all software of a certain size and complexity) has bugs. In open source development, members of the community or the public find bugs and report them to the project. A vulnerability disclosure policy explains how this process functions from the perspective of the project.

This vulnerability disclosure policy explains the rules and guidelines for this project. It is intended to act as both a reference for outsiders\u2013including both bug reporters and those looking for information on the project\u2019s security practices\u2013as well as a set of rules that maintainers and contributors have agreed to follow.

"},{"location":"governance/security-template/#report-intakes","title":"Report Intakes","text":"

This project uses the following mechanism to submit security vulnerabilities. While the security team members will do their best to respond to bugs disclosed in all possible ways, it is encouraged for bug finders to report through the following approved channel:

  • Open a GitHub security vulnerability report: Open a draft security advisory on the \"Security\" tab of this GitHub repository. See GitHub Security Advisories to learn more about the security infrastructure in GitHub.
"},{"location":"governance/security-template/#security-team","title":"Security Team","text":"

The current security team is:

Name Email ID Chat ID Area/Specialty <> <> <> <> <> <> <> <> <> <> <> <>

The security team for this project must include at least three project Maintainers that agree to carry out the following duties and responsibilities. Members are added and removed from the team via approved Pull Requests to this repository. For additional background into the role of the security team, see the People Infrastructure section of the OpenWallet Foundation's security vulnerability disclosure policy.

Responsibilities:

  1. Acknowledge receipt of the issue (see Report Intakes) to the reporter within 2 business days.

  2. Assess the issue. Engage with the reporter to ask any outstanding questions about the report and how to reproduce it. If the report is not considered a vulnerability, then the reporter should be informed and this process can be halted. If the report is still a regular bug (just not a security vulnerability), the reporter should be informed (if necessary) of the regular process for reporting bugs.

  3. Some issues may require more time and resources to correct. If a particular report is more complex, discuss an embargo period with the reporter. The embargo period should be negotiated with the reporter and must not be longer than 90 days.

  4. Create a patch for the issue (see Private Patch Deployment Infrastructure).

  5. Request a CVE for the issue (see CNA/CVE Reporting).

  6. Decide the date of public release.

  7. If applicable, notify members of the embargo list of the upcoming patch and release, as described above.

  8. Cut a new (software) release in which the bug is fixed.

  9. Publicly disclose the issue within 48 hours after the release (see GitHub Security Advisories).

"},{"location":"governance/security-template/#discussion-forum","title":"Discussion Forum","text":"

Discussions about each reported vulnerability are carried out in the private GitHub security advisory about the vulnerability. If necessary, a private channel specific to the issue may be created on the OpenWallet Foundation's Discord server with invited participants added to the discussion.

"},{"location":"governance/security-template/#cnacve-reporting","title":"CNA/CVE Reporting","text":"

This project maintains a list of Common Vulnerabilities and Exposures (CVE) and uses GitHub as its CVE numbering authority (CNA) for issuing CVEs.

"},{"location":"governance/security-template/#embargo-list","title":"Embargo List","text":"

This project maintains a private embargo list. If you wish to be added to the embargo list for a project, please email the [OpenWallet Foundation's security list], including the project name and reason for being added to the embargo list. Requests will be assessed by the security team in conjunction with the appropriate OpenWallet Foundation staff, and a decision will be made whether to accommodate the request.

"},{"location":"governance/security-template/#github-security-advisories","title":"GitHub Security Advisories","text":"

This project uses GitHub security advisories and the GitHub security process for handling security vulnerabilities.

"},{"location":"governance/security-template/#private-patch-deployment-infrastructure","title":"Private Patch Deployment Infrastructure","text":"

In creating patches and new releases that address security vulnerabilities, this project uses the private development features of GitHub for security vulnerabilities. GitHub has extensive documentation about these features.

"},{"location":"governance/security/","title":"Security Vulnerability Disclosure Policy","text":"

This document outlines the OpenWallet Foundation's security vulnerability disclosure policy that all OpenWallet Foundation projects MUST follow. The associated security template file is a \"best practices\" security vulnerability disclosure policy that project Maintainers SHOULD use for publishing the security policy and procedures for their project by copying the file into their project repositories and updating it according to the instructions in the document. This document includes the \"best practices\" text, and defines how project Maintainers can use alternatives to the best practices for their project. A project's resulting alternative policy MUST adhere to the OpenWallet Foundation's security vulnerability disclosure policy.

All project repositories MUST have a published security vulnerability disclosure policy or have link to a common policy document for the project. In rare cases, a repository within a project MAY have a policy different from the project, as long as the repository policy also adheres to this OpenWallet Foundation's security vulnerability disclosure policy.

"},{"location":"governance/security/#about-this-document","title":"About This Document","text":"

This policy borrows heavily from the recommendations of the OpenSSF Vulnerability Disclosure working group. For up-to-date information on the latest recommendations related to vulnerability disclosures, please visit the GitHub of that working group.

In each of the document's sections, and in the associated security template, the current OpenWallet Foundation's \"best practices\" are defined.

Alternative

Alternatives that a project may use exist for some sections and are contained in these \"Alternative boxes\". When projects vary from the current OpenWallet Foundation's best practices, the documented alternatives MUST adhere to this policy.

"},{"location":"governance/security/#what-is-a-vulnerability-disclosure-policy","title":"What Is a Vulnerability Disclosure Policy?","text":"

No piece of software is perfect. All software (at least, all software of a certain size and complexity) has bugs. In open source development, members of the community or the public find bugs and report them to the project. A vulnerability disclosure policy explains how this process functions from the perspective of the project.

This vulnerability disclosure policy explains the rules and guidelines for OpenWallet Foundation's projects. It is intended to act as both a reference for outsiders\u2013including both bug reporters and those looking for information on the project\u2019s security practices\u2013as well as a set of rules that maintainers and contributors have agreed to follow.

"},{"location":"governance/security/#vulnerability-disclosure-process-and-associated-rules","title":"Vulnerability Disclosure Process and Associated Rules","text":"

All OpenWallet Foundation's projects, including this project, follow the associated process and rules for vulnerability disclosures. We note that this outline is derived from the OpenSSF maintainers guide.

Each project will have a security team. The security team will be comprised of maintainers or contributors to the project who are knowledgeable about security and is responsible for responding to and helping to fix security vulnerabilities.

The security team for this project will do the following for each reported vulnerability:

  1. Acknowledge receipt of the issue (see Report Intakes) to the reporter within 2 business days.

  2. Assess the issue. Engage with the reporter to ask any outstanding questions about the report and how to reproduce it. If the report is not considered a vulnerability, then the reporter should be informed and this process can be halted. If the report is still a regular bug (just not a security vulnerability), the reporter should be informed (if necessary) of the regular process for reporting bugs.

  3. Some issues may require more time and resources to correct. If a particular report is more complex, discuss an embargo period with the reporter. The embargo period should be negotiated with the reporter and must not be longer than 90 days.

  4. Create a patch for the issue (see Private Patch Deployment Infrastructure).

  5. Request a CVE for the issue (see CNA/CVE Reporting).

  6. Decide the date of public release.

  7. If applicable, notify members of the embargo list of the upcoming patch and release, as described above.

  8. Cut a new (software) release in which the bug is fixed.

  9. Publicly disclose the issue within 48 hours after the release (see GitHub Security Advisories).

"},{"location":"governance/security/#report-intakes","title":"Report Intakes","text":"

OpenWallet Foundation's projects use the following mechanism to submit security vulnerabilities. While the security team members will do their best to respond to bugs disclosed in all possible ways, it is encouraged for bug finders to report through the following approved channel:

  • Open a GitHub security vulnerability report: Open a draft security advisory on the \"Security\" tab of this GitHub repository. See GitHub Security Advisories to learn more about the security infrastructure in GitHub.
Alternative

Projects MAY publish in their security policy that they accept security vulnerability disclosures via other mechanism. The policy MUST document the necessary details in using the alternate reporting mechanism(s). Projects MUST accept reports via the recommended GitHub security vulnerability process.

"},{"location":"governance/security/#people-infrastructure","title":"\u201cPeople\u201d Infrastructure","text":"

This section details the required basic vulnerability disclosure infrastructure for all OpenWallet Foundation's projects. There are quite a few necessary pieces of infrastructure, and we go through them in detail here.

"},{"location":"governance/security/#security-team","title":"Security Team","text":"

Projects MUST have a security response team of at least three maintainers. This response team shall be set up BEFORE incidents happen so that people know who to contact and how to contact them when an emergency issue arises. It can be difficult to track down someone with unique knowledge (e.g. in a particular area of cryptography) who is capable of fixing a problem in a short period of time.

  1. Each security team member will be a member of any OpenWallet Foundation-wide security infrastructure.

  2. If a project has specialized code related to certain aspects of security or cryptography (e.g. consensus algorithms or cryptographic algorithms), then a corresponding specialist should be on the response team (e.g. someone knowledgeable in consensus or cryptography, respectively). If a specialist is not on the team, then the individual who is responsible for contacting or engaging the specialists should be designated in their stead. We emphasize that projects should have access to specialists in an area for which they maintain code while recognizing that it may not be practical for these experts to be on the response team.

Each project/repository must have a table in the security document listing the team members in the following format.

Name Email ID Chat ID Area/Specialty <> <> <> <> <> <> <> <> <> <> <> <>"},{"location":"governance/security/#discussion-forum","title":"Discussion Forum","text":"

Discussions about each reported vulnerability SHOULD be carried out in the private GitHub security advisory about the vulnerability. If necessary, a private channel specific to the issue MAY be created on the OpenWallet Foundation's Discord server with invited participants added to the discussion.

Alternative

Projects MAY document on their security policy that they use other forums for private discussion forums for approved maintainers and security team participants to discuss vulnerabilities. If other forum(s) are used, details about them MUST be included.

"},{"location":"governance/security/#cnacve-reporting","title":"CNA/CVE Reporting","text":"

OpenWallet Foundation's projects maintain a list of Common Vulnerabilities and Exposures (CVE) and use GitHub as its CVE numbering authority (CNA) for issuing CVEs.

Alternative

A project MAY document in its security policy that it uses a different CVE numbering authority. For example, the project might add the following text to this section of their security policy document:

This project uses the following CNA(s) in the following situations:\n1. `CNA_1`:  `situation_1, can just state \u201cdefault\u201d if only one CNA`\n2. `CNA_2`:  `situation_2`\n
"},{"location":"governance/security/#embargo-list","title":"Embargo List","text":"

An embargo list is a list of known, trusted entities that run large deployments of a given OpenWallet Foundation's project. These entities are notified ahead of time when important security patches are incoming to minimize potential security risks to large deployments of projects. Embargo lists are maintained by the security team for a given project/repository.

Parties are on an embargo list for (usually) one of two reasons, because they can either help fix the problem (perhaps through testing a fix at scale) or they need extra time to help prepare their ecosystem to roll out fixes quickly. Approval is not given lightly: project leadership (maintainers) must be convinced that institutions on the list \u201cneed to know\" about issues in advance.

Participation in an embargo list should not be taken lightly. List members are expected to respect the materials shared through it and not disclose any information to unauthorized parties until the public disclosure date. Institutions are on this list because their presence helps the project and its users; if their actions do not help the project and its users, they can expect to be removed from the list.

The list itself is private in order to make it slightly more difficult for attackers with vulnerabilities to find systems to attack. Entities may be added to the embargo list by a majority vote of the project security response team and should request to join the embargo list by contacting one or more of the members of the security response team. If there is an issue about embargo list membership where an entity feels like they are being dealt with unfairly by the security response team, then they are encouraged to bring up the issue in front of the OpenWallet Foundation's TAC, who can act as moderators.

OpenWallet Foundation's projects maintain private embargo lists. If you wish to be added to the embargo list for a project, please email the [OpenWallet Foundation's security list], including the project name and reason for being added to the embargo list. Requests will be assessed by the respective OpenWallet Foundation's security team in conjunction with the appropriate OpenWallet Foundation staff, and a decision will be made to accommodate or not the request.

Alternative

Projects MAY choose to document in their security document that they do not have an embargo list. The reason for not having an embargo list SHOULD be included when a project chooses not to have an embargo list.

"},{"location":"governance/security/#github-security-advisories","title":"GitHub Security Advisories","text":"

OpenWallet Foundation's projects use GitHub security advisories and the GitHub security process for handling security vulnerabilities. In particular, this best practice is strongly recommended for projects that do not have a large number of security experts as the features serve as a nice set of guardrails to help make sure that things are done correctly.

Alternative

Projects MAY document in their security policy document that they use a security advisory mechanism other than GitHub to publish their disclosures. The alternate mechanism MUST be documented sufficiently for users to understand how to monitor the security advisories published by the project.

"},{"location":"governance/security/#private-patch-deployment-infrastructure","title":"Private Patch Deployment Infrastructure","text":"

Patches to fix OpenWallet Foundation's project security vulnerabilities are typically developed without public visibility by using the private development features of GitHub. Projects with maintainers that are not familiar with these capabilities are encouraged to contact the OpenWallet Foundation Community Architects to learn more.

Alternative

Projects MAY document in their security policy document that they do use a service other than GitHub for private patch deployment infrastructure, or that they don't use any private patch deployment infrastructure at all. In either case, the document MUST include the details of what is used instead.

"},{"location":"governance/special-interest-group-process/","title":"Special Interest Group","text":"

A special interest group (SIG) under the Technical Advisory Council (TAC) is a group with a shared interest in advancing a specific area of knowledge, learning, or technology related to the mission of the OpenWallet Foundation where members cooperate to affect or to produce solutions within their particular field. Unlike a task force, SIGs are typically long running and may or may not produce any deliverables. A SIG can be created by anyone in the OpenWallet Foundation community and must be proposed to and approved by the TAC.

"},{"location":"governance/special-interest-group-process/#propose-a-special-interest-group","title":"Propose a Special Interest Group","text":"

To propose a special interest group, create an issue in the TAC GitHub repository using the Special Interest Group template. The issue should be named \"Special Interest Group Proposal: \\<name of special interest group>\". The issue should include the following information:

  • Introduction/background material
  • Objectives of the special interest group
  • List of deliverables or work products (optional)
  • Leader(s)
  • Initial participant list
"},{"location":"governance/special-interest-group-process/#approval-process","title":"Approval Process","text":"

The TAC will review the special interest group proposal first by providing comments in the issue and secondly by bringing the special interest group proposal to a discussion and vote in a TAC meeting.

The decision of the vote will be documented in the issue. If the special interest group is approved, a discussion channel in Discord will be created. In addition, we will work with the OpenWallet Foundation operations team to schedule a meeting on the OpenWallet Foundation calendar. If necessary, a GitHub repository and/or mailing list will also be created at the request of the special interest group leader(s).

"},{"location":"governance/special-interest-group-process/#special-interest-group-procedures","title":"Special Interest Group Procedures","text":"

The special interest group can decide on the mechanism for running the SIG. Meeting minutes and a log of decisions that have been made should be kept for ensuring continuity of the special interest group. The special interest group should update the issue to reflect where the meeting notes and log of decisions is kept or use the issue directly to capture this information.

"},{"location":"governance/special-interest-group-process/#reporting-on-special-interest-group-activities","title":"Reporting on Special Interest Group Activities","text":"

Every quarter the special interest group leader should report on the activities of the SIG at a TAC meeting. This will ensure that the SIG is still active and that there is still value in hosting the special interest group. Please see the schedule for when these updates should occur.

"},{"location":"governance/tac/","title":"Open Wallet Foundation TAC composition","text":""},{"location":"governance/tac/#current-composition","title":"Current Composition","text":"Member (alphabetical by first name) Representing David Zeuthen Google Jaehoon (Ace) Shim At Large Pete Cooling Visa Rolson Quadras Gen Stavros Kounis (vice chair) At Large Tracy Kuhrt (chair) Accenture Wenjing Chu FutureWei Technologies"},{"location":"governance/tac/#history","title":"History","text":""},{"location":"governance/tac/#2023-03-08","title":"2023-03-08","text":"
  • Tracy Kuhrt is running unopposed for TAC Chair
  • Composition
    • Accenture - Tracy Kuhrt
    • Futurewei - Wenjing Chu
    • Gen Digital - Drummond Reed
    • Visa - Marie Austenaa
"},{"location":"governance/tac/#2023-04-05","title":"2023-04-05","text":"
  • TAC \"at large\" election results
    • Jeremie Miller
    • Stavros Kounis
"},{"location":"governance/tac/#2023-06-28","title":"2023-06-28","text":"
  • Pete Cooling was introduced as Visa's TAC voting representative.
"},{"location":"governance/tac/#2023-08-09","title":"2023-08-09","text":"
  • RESOLVED: That Stavros Kounis is hereby confirmed and approved as the TAC Vice Chair
"},{"location":"governance/tac/#2023-09-06","title":"2023-09-06","text":"
  • We welcomed David Zeuthen, Google premier member representative
"},{"location":"governance/tac/#2023-10-18","title":"2023-10-18","text":"
  • Mike Varley will represent Gen Digital moving forward.
"},{"location":"governance/tac/#2024-04-03","title":"2024-04-03","text":"
  • TAC \"at large\" election results
    • Ace Shim
    • Stavros Kounis
"},{"location":"governance/tac/#2024-04-17","title":"2024-04-17","text":"
  • Chair/Vice Chair Results
    • Stavros, vice chair
    • Tracy, chair
"},{"location":"governance/tac/#2024-05-15","title":"2024-05-15","text":"
  • Rolson Quadras will represent Gen Digital moving forward
"},{"location":"governance/task-force-process/","title":"Task Force","text":"

A task force is a group that is focused on a task with limited scope and fixed time to complete. Unlike a special interest group, a task force will have a specific set of deliverables or work products that it will create and be limited in time to completion. A task force can be created by anyone in the OpenWallet Foundation community and must be proposed to and approved by the TAC.

"},{"location":"governance/task-force-process/#propose-a-task-force","title":"Propose a Task Force","text":"

To propose a task force, create an issue in the TAC GitHub repository. The issue should be named \"Task Force Proposal: \\<name of task force>\". The issue should include the following information:

  • Introduction/background material
  • Objectives of the task force
  • List of deliverables or work products
  • Time to complete (no more than 6 months)
  • Leader(s)
  • Initial participant list
"},{"location":"governance/task-force-process/#approval-process","title":"Approval Process","text":"

The TAC will review the task force proposal first by providing comments in the issue and secondly by bringing the task force proposal to a discussion and vote in a TAC meeting.

The decision of the vote will be documented in the issue. If the task force is approved, a discussion channel in Discord will be created. In addition, we will work with the OpenWallet Foundation operations team to schedule a meeting on the OpenWallet Foundation calendar. If necessary, a GitHub repository and/or mailing list will also be created at the request of the task force leader(s).

"},{"location":"governance/task-force-process/#task-force-procedures","title":"Task Force Procedures","text":"

The task force can decide on the mechanism for creating the deliverables. Meeting minutes and a log of decisions that have been made should be kept for ensuring continuity of the task force. The task force should update the issue to reflect where the meeting notes and log of decisions is kept or use the issue directly to capture this information.

"},{"location":"governance/task-force-process/#reporting-on-task-force-completion-of-deliverables","title":"Reporting on Task Force Completion of Deliverables","text":"

Upon completion of the task force's deliverables, the task force should arrange a time with the TAC chair to present the deliverables at a TAC meeting. This can be accomplished by sending an email to the TAC mailing list at tac@lists.openwallet.foundation.

"},{"location":"governance/task-force-process/#requesting-an-extension-on-completion-date","title":"Requesting an Extension on Completion Date","text":"

If the task force is not able to complete the deliverables by the specified completion date, then the leader of the task force should arrange a time with the TAC chair to discuss the extension at a TAC meeting. This discussion should include information on the current status, the delays, and the expected updates to the schedule. This can be accomplished by sending an email to the TAC mailing list at tac@lists.openwallet.foundation.

"},{"location":"meetings/","title":"TAC Meetings","text":"

TAC meetings are intended to be open to observe by Sponsors, contributors to any TAC Project, and others in the general public interested in the OpenWallet Foundation.

The meetings will be held bi-weekly starting Wednesday, March 8, 2023 at 7:00am PT.

  • Join link with meeting ID and passcode embedded: https://zoom-lfx.platform.linuxfoundation.org/meeting/94569749258?password=68170ae3-3074-45fb-9b2e-4c479ed7d8d7
"},{"location":"meetings/YYYY-mm-dd/","title":"YYYY-mm-dd","text":"

Reminder

These meetings are covered by the Antitrust Policy and the Code of Conduct.

"},{"location":"meetings/YYYY-mm-dd/#agenda","title":"Agenda","text":"
  • Include agenda items here.
"},{"location":"meetings/YYYY-mm-dd/#tac-voting-members","title":"TAC Voting Members","text":"
  • David Zeuthen
  • Jaehoon (Ace) Shim
  • Mike Varley
  • Pete Cooling
  • Stavros Kounis
  • Tracy Kuhrt
  • Wenjing Chu
"},{"location":"meetings/YYYY-mm-dd/#notes","title":"Notes","text":"
  • Include discussion notes here.
"},{"location":"meetings/YYYY-mm-dd/#recording","title":"Recording","text":"
  • link to recording
"},{"location":"meetings/2023/2023-03-08/","title":"2023-03-08","text":"

Reminder

These meetings are covered by the Antitrust Policy and the Code of Conduct.

"},{"location":"meetings/2023/2023-03-08/#agenda","title":"Agenda","text":"
  • Welcome and intros of TAC
  • Reminder of TAC Charter
  • TAC Chair election
  • TAC \"at large\" seats
  • Call for code from the Community
  • Open Discussion and Next Steps
"},{"location":"meetings/2023/2023-03-08/#recording","title":"Recording","text":"
  • recording
"},{"location":"meetings/2023/2023-03-08/#actions","title":"Actions","text":"
  • Tracy Kuhrt is running unopposed for TAC Chair. Can the 4 TAC Representatives please +1 this to formalize.
  • Review proposed TAC Website and Governance Policies as detailed at https://lists.openwallet.foundation/g/TAC/message/3
  • Review https://github.com/openwallet-foundation/project-proposals
"},{"location":"meetings/2023/2023-03-08/#minutes","title":"Minutes","text":"
  • TAC Charter
    • The TAC is responsible for maintaining an overall strategic vision for technical collaboration and coordinating collaboration among Technical Projects, including development of an overall technical vision for the community.
    • Section 5 of https://cdn.platform.linuxfoundation.org/agreements/openwalletfoundation.pdf
  • TAC Chair Election
    • Tracy Kuhrt is running unopposed \u2013 will move to email vote to formalize
  • Composition
    • Accenture - Tracy Kuhrt
    • Futurewei - Wenjing Chu
    • Gen Digital - Drummond Reed
    • Visa - Marie Austenaa
    • \u201cat large\u201d representative #1 appointed by vote of the TAC
    • \u201cat large\u201d representative #2 appointed by vote of the TAC
    • one representative appointed by the technical oversight body (e.g., a technical steering committee) of each TAC Project
  • Call for Code
    • Please review https://github.com/openwallet-foundation/project-proposals
  • Governance rules
    • Tracy gave an overview of a proposed website and policies for the TAC at https://github.com/openwallet-foundation/tac
  • Open Discussion
    • The Governing Board met yesterday and appointed Daniel Goldscheider as Interim Executive Director. Daniel introduced himself and provided his thoughts on the future of OWF.
    • A suggestion was made for a landscape review. A comment was made that that work has begun here.
"},{"location":"meetings/2023/2023-03-22/","title":"2023-03-22","text":"

Reminder

These meetings are covered by the Antitrust Policy and the Code of Conduct.

"},{"location":"meetings/2023/2023-03-22/#agenda","title":"Agenda","text":"
  • Review and approve TAC Governance documents
  • TAC \"at large\" elections
  • Call for code from the Community
  • Open Discussion and Next Steps
"},{"location":"meetings/2023/2023-03-22/#links","title":"Links","text":"
  • slides
  • recording
"},{"location":"meetings/2023/2023-03-22/#action-items","title":"Action Items","text":"
  • Conduct an email vote for the Governance documents approval and adoption.
  • Conduct an email vote for the TAC \"at large\" schedule and process.
  • Todd to confirm whether the TAC can create an alternate policy or whether the Governing Board will need to update the charter to reflect.
  • Tracy to create a pull request to update the project proposal template to include links to the mission and project lifecycle.
  • Create a GitHub organization (openwallet-foundation-labs) to host incoming labs.
"},{"location":"meetings/2023/2023-03-22/#minutes","title":"Minutes","text":"
  • No comments on the TAC Governance documents. Will conduct an email vote to adopt.
  • Discussed TAC \"at large\" election process. Will conduct an email vote to adopt.
  • Reviewed project proposal process and instructions and went through the template. Two suggested changes:
    • Include a link to the mission.
    • Include a link to the project lifecycle for stage information.
  • Next steps
    • Create a labs organization (openwallet-foundation-labs) to host any lab proposals.
"},{"location":"meetings/2023/2023-04-05/","title":"2023-04-05","text":"

Reminder

These meetings are covered by the Antitrust Policy and the Code of Conduct.

"},{"location":"meetings/2023/2023-04-05/#agenda","title":"Agenda","text":"
  • Review action items from last meeting
  • TAC \"at large\" election results
  • Architecture SIG update
  • Call for code from the community
  • Open discussion and next steps
"},{"location":"meetings/2023/2023-04-05/#links","title":"Links","text":"
  • slides
  • recording
"},{"location":"meetings/2023/2023-04-05/#action-items","title":"Action Items","text":"
  • Tracy to rename the architecture-task-force GitHub repo to architecture-sig - completed
  • Jenn to rename the meeting invite for the Outside Architecture Special Interest Group to reflect that the name should be the Architecture SIG
  • Jenn to add Stavros to the TAC meeting invite - completed
  • Jenn to add Jeremie to the TAC meeting invite
  • Create a GitHub organization (openwallet-foundation-labs) to host incoming labs
"},{"location":"meetings/2023/2023-04-05/#meeting-minutes","title":"Meeting Minutes","text":"
  • Review action items from last meeting
    • Conduct an email vote for the Governance documents approval and adoption - results 3 TAC members voted in favor; 1 TAC member abstained
    • Conduct an email vote for the TAC \"at large\" schedule and process - results 3 TAC members voted in favor; 1 TAC member abstained
    • Todd to confirm whether the TAC can create an alternate policy or whether the Governing Board will need to update the charter to reflect - currently no policy for TAC alternates; if we want this, we would need to present this to the GB to get a charter update
      • The TAC would like to recommend that the board create an alternate policy for the TAC.
      • The language will be similar to the following \"A TAC member can designate an alternate for a specific meeting, and has to notify the chair in advance.\"
    • Tracy to create a pull request to update the project proposal template to include links to the mission and project lifecycle - pull request created and merged
    • Create a GitHub organization (openwallet-foundation-labs) to host incoming labs - not yet completed
  • TAC \"at large\" election results
    • Jeremie Miller
    • Stavros Kounis
  • Architecture SIG update
    • Digital wallet engine architecture topics brainstorm - please add any topics that you think we missed
    • Discussion on MOST important architecture topic - please add to the discussion
    • A question was brought up about the status of this group and whether it is a task force or a special interest group. The TAC formalized the group as a special interest group under the TAC.
  • Call for code from the community
  • Next steps
    • Discussion regarding the upcoming conference season, including IIW, EIC, and others.
    • Suggestion was made to create an OpenWallet Foundation event calendar.
    • Next meeting is April 19, 2023.
"},{"location":"meetings/2023/2023-04-19/","title":"2023-04-19","text":"

Reminder

These meetings are covered by the Antitrust Policy and the Code of Conduct.

"},{"location":"meetings/2023/2023-04-19/#agenda","title":"Agenda","text":"
  • Review action items from last meeting
  • Priorities
  • Internet Identity Workshop (IIW) updates
  • Call for code from the community
  • Open discussion and next steps
"},{"location":"meetings/2023/2023-04-19/#links","title":"Links","text":"
  • slides
  • recording
"},{"location":"meetings/2023/2023-04-19/#action-items","title":"Action Items","text":"
  • Document process for creating a task force - pull request
"},{"location":"meetings/2023/2023-04-19/#meeting-minutes","title":"Meeting Minutes","text":"
  • Review action items from last meeting
    • Tracy to rename the architecture-task-force GitHub repo to architecture-sig - completed
    • Jenn to rename the meeting invite for the Outside Architecture Special Interest Group to reflect that the name should be the Architecture SIG - completed
    • Jenn to add Stavros to the TAC meeting invite - completed
    • Jenn to add Jeremie to the TAC meeting invite - completed
    • Create a GitHub organization (openwallet-foundation-labs) to host incoming labs - completed
  • Priorities
    • Projects
      • Pipeline of projects
      • Getting a method of tracking and accessing projects
      • Rule book / guide on the evaluation process and criteria for new projects
      • Technical Focus
        • Cloud based, edge based, and hybrid wallets
        • Common components for wallets
        • Specific components for money, identity, and object wallets
    • Collaboration between OWF and European Commission
      • Tracking changes in the next European Digital Identity Wallet Architecture and Reference Framework (ARF) and making sure it lines up with OWF thinking
      • Maintaining dialog and exploring alignment
  • Internet Identity Workshop (IIW) updates
    • Topics on digital wallets, credentials, and interoperability
    • Sessions on EUDI and the ARF
    • A number of OpenWallet topics will be discussed on day 2 and 3
    • Discussions about the Linux Foundation Trust umbrella
  • Call for code from the community
    • Completing the assessment framework may allow people to better understand what type of projects should be considered for contribution
  • Next steps
    • Next meeting is May 3, 2023
"},{"location":"meetings/2023/2023-05-03/","title":"2023-05-03","text":"

Reminder

These meetings are covered by the Antitrust Policy and the Code of Conduct.

"},{"location":"meetings/2023/2023-05-03/#agenda","title":"Agenda","text":"
  • Review action items from last meeting
  • Welcome new TAC member
  • Task Force Proposal
  • Assessment Framework - How do we want to assess incoming projects?
  • Call for code from the community
  • Open discussion and next steps
"},{"location":"meetings/2023/2023-05-03/#links","title":"Links","text":"
  • slides
  • recording
"},{"location":"meetings/2023/2023-05-03/#action-items","title":"Action Items","text":"
  • Update Task Force process to include information on optional mailing lists and capturing meeting notes -- commit -- completed
  • Create process for Special Interest Groups similar to Task Force process and cross link the two processes together
"},{"location":"meetings/2023/2023-05-03/#meeting-minutes","title":"Meeting Minutes","text":"
  • Review action items from last meeting

    • Document process for creating a task force - pull request -- completed
  • Welcome new TAC member

    • We welcomed Troy Ronda from Gen Digital who is replacing Drummond Reed
  • Task Force Proposal

    • RESOLVED: That the task force process documented in this pull request and rendered on this page and using this issue template is hereby confirmed, approved, and adopted.
    • Unanimously passed
  • Assessment Framework

    • How do we want to assess incoming projects?
      • Currently documented project acceptance process
      • Each Project Lifecycle Stage documents its acceptance criteria
    • What are the types of projects that we want to include?
      • Alignment with the OpenWallet Foundation mission
      • \u201cvarious open source, open data and/or other open projects relating to or supporting development of digital wallets, including infrastructure and support initiatives related\u201d
    • Discussion
      • Projects that would satisfy components of the conceptual architecture created by the architecture SIG
      • Projects that would fit in slide 6 of the OpenWallet Foundation Overview 2023.02.23 deck
  • Call for code from the community

  • Next steps

    • Next meeting is May 17, 2023
"},{"location":"meetings/2023/2023-05-17/","title":"2023-05-17","text":"

Reminder

These meetings are covered by the Antitrust Policy and the Code of Conduct.

"},{"location":"meetings/2023/2023-05-17/#agenda","title":"Agenda","text":"
  • Review action items from last meeting
  • New lab proposals
    • SD-JWT Kotlin
    • SD-JWT Python
  • Special Interest Group process proposal
  • OID4VCI and OID4VP Due Diligence Task Force
  • Call for code from the community
  • Open discussion and next steps
"},{"location":"meetings/2023/2023-05-17/#links","title":"Links","text":"
  • slides
  • recording
"},{"location":"meetings/2023/2023-05-17/#tac-voting-members","title":"TAC Voting Members","text":"
  • Jeremie Miller
  • Marie Austenaa (Trevor Crooks attended and voted in Marie's place)
  • Stavros Kounis
  • Tracy Kuhrt
  • Troy Ronda
  • Wenjing Chu
"},{"location":"meetings/2023/2023-05-17/#action-items","title":"Action Items","text":"
  • Work with Fabian to transfer SD-JWT Kotlin repo to openwallet-foundation-labs organization
  • Work with Daniel to transfer SD-JWT Python repo to openwallet-foundation-labs organization
  • Comment on OID4VCI and OID4VP Due Diligence Task Force proposal and update to reflect comments. We will bring this to a vote at the next TAC meeting
"},{"location":"meetings/2023/2023-05-17/#meeting-minutes","title":"Meeting Minutes","text":"
  • Review action items from last meeting

    • Update Task Force process to include information on optional mailing lists and capturing meeting notes -- commit -- completed
    • Create process for Special Interest Groups similar to Task Force process and cross link the two processes together -- PR -- completed
  • New lab proposals

    • SD-JWT Kotlin Library
      • RESOLVED: That the SD-JWT Kotlin Library lab is hereby confirmed, approved, and adopted.
      • Unanimously approved by the present TAC voting members.
    • SD-JWT Python Reference Implementation
      • RESOLVED: That the SD-JWT Python Reference Implementation lab is hereby confirmed, approved, and adopted.
      • Unanimously approved by the present TAC voting members.
  • Special Interest Group process proposal

    • RESOLVED: That the special interest group (SIG) process documented in this pull request and rendered on this page and using this issue template is hereby confirmed, approved, and adopted.
    • Unanimously approved by the present TAC voting members.
  • OID4VCI and OID4VP Due Diligence Task Force

    • Support exists for this task force, but we ran out of time to conclude the discussion.
    • Request for comments on OID4VCI and OID4VP Due Diligence Task Force proposal and +1 if you are interested in participating.
    • Hakan will update to reflect comments so that we can bring this to a vote at the next TAC meeting.
  • Call for code from the community

  • Next steps

    • Next meeting is May 31, 2023
"},{"location":"meetings/2023/2023-05-31/","title":"2023-05-31","text":"

Reminder

These meetings are covered by the Antitrust Policy and the Code of Conduct.

"},{"location":"meetings/2023/2023-05-31/#agenda","title":"Agenda","text":"
  • Review action items from last meeting
  • Update on TAC alternates
  • OID4VC Due Diligence Task Force
  • Credential Format Comparison SIG
  • Call for code from the community
  • Open discussion and next steps
"},{"location":"meetings/2023/2023-05-31/#links","title":"Links","text":"
  • slides
  • recording
"},{"location":"meetings/2023/2023-05-31/#tac-voting-members","title":"TAC Voting Members","text":"
  • Jeremie Miller
  • Marie Austenaa
  • Stavros Kounis
  • Tracy Kuhrt
  • Troy Ronda
  • Wenjing Chu
"},{"location":"meetings/2023/2023-05-31/#action-items","title":"Action Items","text":"
  • Work with Daniel to transfer SD-JWT Python repo to openwallet-foundation-labs organization -- in progress
  • Create proposed language for TAC alternates
  • Add link to community calendar to website
  • OID4VC Due Diligence Task Force

    • Create Discord channel
    • Add information about Task Forces to TAC website
    • Add link to the above to the OpenWallet Foundation GitHub Profile
  • Credential Format Comparison SIG

    • Create Discord channel
    • Work with Torsten to get GitHub repo transferred to OpenWallet Foundation
    • Determine leader of the SIG
    • Add information about Special Interest Groups to TAC website
    • Add link to the above to the OpenWallet Foundation GitHub Profile
"},{"location":"meetings/2023/2023-05-31/#meeting-minutes","title":"Meeting Minutes","text":"
  • Review action items from last meeting

    • Work with Fabian to transfer SD-JWT Kotlin repo to openwallet-foundation-labs organization -- completed SD-JWT-Kotlin
    • Work with Daniel to transfer SD-JWT Python repo to openwallet-foundation-labs organization -- in progress
    • Comment on OID4VC Due Diligence Task Force proposal and update to reflect comments -- in progress
  • Update on TAC alternates

    • The Governing Board agreed to modify the Charter to include the following language:

      Updated Language

      5.c) TAC meetings are intended to be open to observe by Sponsors, contributors to any TAC Project and others in the general public interested in the OpenWallet Foundation. The TAC may decide whether to allow named representatives (one per voting member) to attend as an alternate.

  • OID4VC Due Diligence Task Force

    • Unanimously approved by the present TAC voting members.
  • Credential Format Comparison SIG

    • Unanimously approved by the present TAC voting members.
  • Call for code from the community

  • Next steps

    • Next meeting is June 14, 2023
"},{"location":"meetings/2023/2023-06-14/","title":"2023-06-14","text":"

Reminder

These meetings are covered by the Antitrust Policy and the Code of Conduct.

"},{"location":"meetings/2023/2023-06-14/#agenda","title":"Agenda","text":"
  • Announcements
  • Review action items from last meeting
  • TAC alternates policy
  • Call for code from the community
  • Open discussion and next steps
"},{"location":"meetings/2023/2023-06-14/#links","title":"Links","text":"
  • slides
  • recording
"},{"location":"meetings/2023/2023-06-14/#tac-voting-members","title":"TAC Voting Members","text":"
  • Jeremie Miller
  • Marie Austenaa
  • Stavros Kounis
  • Tracy Kuhrt
  • Troy Ronda
  • Wenjing Chu
"},{"location":"meetings/2023/2023-06-14/#action-items","title":"Action Items","text":"
  • Determine vice chair language
  • Work with Daniel to transfer SD-JWT Python repo to openwallet-foundation-labs organization
  • Credential Format Comparison SIG

    • Work with Torsten to get GitHub repo transferred to OpenWallet Foundation
"},{"location":"meetings/2023/2023-06-14/#meeting-minutes","title":"Meeting Minutes","text":"
  • Announcements

    • OID4VC Due Diligence Task Force kickoff meeting \u2013 Wednesday, the 21st at 5pm CEST
    • Architecture SIG merged Key Management Services conceptual architecture
    • Credential Format Comparison SIG will meet on Wednesdays at 5pm CEST on alternate weeks to the OID4VC Due Diligence Task Force. Kickoff meeting planned for June 28th
  • Review action items from last meeting

    • Work with Daniel to transfer SD-JWT Python repo to openwallet-foundation-labs organization -- in progress
    • Create proposed language for TAC alternates -- completed
    • Add link to community calendar to website -- completed
    • OID4VC Due Diligence Task Force -- completed

      • Create Discord channel (#oid4vc-due-diligence-tf)
      • Add information about Task Forces to TAC website
      • Add link to the above to the OpenWallet Foundation GitHub Profile
    • Credential Format Comparison SIG -- in progress

      • Create Discord channel (#credential-format-comparison-sig)
      • Work with Torsten to get GitHub repo transferred to OpenWallet Foundation
      • Determine leader of the SIG (Mirko Molik)
      • Add information about Special Interest Groups to TAC website
      • Add link to the above to the OpenWallet Foundation GitHub Profile
  • TAC Alternates Policy

    • RESOLVED: That the TAC Alternates Policy is hereby confirmed, approved, and adopted.
      • Unanimously approved by the present TAC voting members.
  • Call for code from the community

    • A question was asked whether we were tracking a wishlist for potential projects
      • In general, we are looking for projects that fit with the vision of the OpenWallet Foundation. Those that are focused on wallet engine related to identity, money, and objects
      • We previously were capturing potential code projects using this Google sheet
    • If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
  • Open discussion and next steps

    • Relative to the Credential Format Comparison SIG, the ToIP Foundation has just started a task force on the same thing for credential exchange protocols. See this spreadsheet
    • David Alexander will present on wallets and personal data stores at the next meeting and we will discuss further
      • Background blog post
      • Thread from Architecture SIG on personal data
      • There\u2019s also the Decentralized Web Node project that Block is leading at the Decentralized Identity Foundation
    • Next meeting is June 28, 2023
"},{"location":"meetings/2023/2023-06-28/","title":"2023-06-28","text":"

Reminder

These meetings are covered by the Antitrust Policy and the Code of Conduct.

"},{"location":"meetings/2023/2023-06-28/#agenda","title":"Agenda","text":"
  • Announcements
  • Review action items from last meeting
  • Vice chair seat and responsibilities
  • Wallets and personal data stores presentation and discussion
  • Call for code from the community
  • Open discussion and next steps
"},{"location":"meetings/2023/2023-06-28/#links","title":"Links","text":"
  • slides
  • recording
"},{"location":"meetings/2023/2023-06-28/#tac-voting-members","title":"TAC Voting Members","text":"
  • Jeremie Miller
  • Marie Austenaa
  • Stavros Kounis
  • Tracy Kuhrt
  • Troy Ronda
  • Wenjing Chu
"},{"location":"meetings/2023/2023-06-28/#action-items","title":"Action Items","text":"
  • Work with Daniel to transfer SD-JWT Python repo to openwallet-foundation-labs organization -- in progress
  • Credential Format Comparison SIG: Work with Torsten to get GitHub repo transferred to OpenWallet Foundation -- in progress
  • Review Farmworker Wallet OS project proposal - all
"},{"location":"meetings/2023/2023-06-28/#meeting-minutes","title":"Meeting Minutes","text":"
  • Announcements

    • Credential Format Comparison SIG will meet on Wednesdays at 4pm CEST on alternate weeks to the TAC. Kickoff meeting planned for July 7th.
    • OID4VC Due Diligence task force will meet weekly on Wednesdays at 5pm CEST.
    • Pete Cooling was introduced as Visa's TAC voting representative.
  • Review action items from last meeting

    • Determine vice chair language -- completed
    • Work with Daniel to transfer SD-JWT Python repo to openwallet-foundation-labs organization -- in progress
    • Credential Format Comparison SIG: Work with Torsten to get GitHub repo transferred to OpenWallet Foundation -- in progress
  • Vice chair seat and responsibilities

    • RESOLVED: That the Vice Chair Seat and Responsibilities is hereby confirmed, approved, and adopted.
      • Unanimously approved by the present TAC voting members.
      • Voting schedule
        • Call for nominations: June 28
        • End of call for nominations: July 5, Noon PT
        • A ballot will be distributed on: July 5 by end of day PT
        • The election will be completed on: July 11, Noon PT
        • Election results are announced at the July 12 meeting
      • If you would like to submit your nomination for TAC Vice Chair, please create an issue at https://github.com/openwallet-foundation/tac/issues
        • Title of issue: [NOMINATION]: 2023 Vice Chair - Name
        • Include a short bio, outline your qualifications, and provide a statement explaining why you would be a good choice for the seat
  • Wallets and personal data stores

    • Background blog post
    • Thread from Architecture SIG on personal data
    • Presentation by David Alexander
  • Call for code from the community

    • If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
  • Open discussion and next steps

    • Next meeting is July 12, 2023
"},{"location":"meetings/2023/2023-07-12/","title":"2023-07-12","text":"

Reminder

These meetings are covered by the Antitrust Policy and the Code of Conduct.

"},{"location":"meetings/2023/2023-07-12/#agenda","title":"Agenda","text":"
  • Announcements
  • Review action items from last meeting
  • Vice Chair
  • Farmworker Wallet OS project proposal
  • Call for code from the community
  • Open discussion and next steps
"},{"location":"meetings/2023/2023-07-12/#links","title":"Links","text":"
  • slides
  • recording
"},{"location":"meetings/2023/2023-07-12/#tac-voting-members","title":"TAC Voting Members","text":"
  • Jeremie Miller
  • Pete Cooling
  • Stavros Kounis
  • Tracy Kuhrt
  • Troy Ronda
  • Wenjing Chu
"},{"location":"meetings/2023/2023-07-12/#action-items","title":"Action Items","text":"
  • Review Farmworker Wallet OS project proposal - all
  • Review the proposed license of Farmworker Wallet OS project with LF legal - Jenn
"},{"location":"meetings/2023/2023-07-12/#meeting-minutes","title":"Meeting Minutes","text":"
  • Announcements

    • Credential Format Comparison SIG will meet on Wednesdays at 4pm CEST on alternate weeks to the TAC
      • Data moved from spreadsheet to github.io site
    • OID4VC Due Diligence task force will meet weekly on Wednesdays at 5pm CEST
    • Architecture SIG meets weekly on Mondays at 11am US/Pacific
    • Invitation to fully remote ISO/IEC JTC 1/SC 17 18013-7 Interoperability Event
    • For Associate non-profit members of the OpenWallet Foundation: voting is now open to select the Associate Representative for the Governing Board. Please email operations@openwallet.foundation if you have any questions about your organization's participation in this vote.
  • Review action items from last meeting

    • Work with Daniel to transfer SD-JWT Python repo to openwallet-foundation-labs organization -- in progress
    • Credential Format Comparison SIG: Work with Torsten to get GitHub repo transferred to OpenWallet Foundation -- completed (new repo created)
    • Review Farmworker Wallet OS project proposal - all
  • Vice Chair

    • RESOLVED: That the voting schedule for vice chair is hereby revised, approved, and adopted as specified.
      • Revised voting schedule
        • Call for nominations: July 12
        • End of call for nominations: August 2, Noon PT
        • A ballot will be distributed on: August 2 by end of day PT
        • The election will be completed on: August 8, Noon PT
        • Election results are announced at the August 9 meeting
      • Unanimously approved by the present TAC voting members.
  • Farmworker Wallet OS project proposal

    • Video shared on Discord
    • Question asking for clarification of the scope of the contribution
    • Concerns raised about the licensing terms of the generated output from Mendix
      • Mendix does not make any intellectual property claims on the output
    • Question raised about the proposed license that will need to be run past LF legal and the Governing Board
    • Need to consider naming of the repos to ensure that it allows people to determine that they are part of the same project
    • Question raised about the difference between the Aries SDK proposed to be part of this project and the one in Hyperledger
      • The one in this project is a wrapper around the SDK in Hyperledger that can be used by Mendix developers
    • Continue conversation on the pull request
  • Call for code from the community

    • If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
  • Open discussion and next steps

    • Next meeting is July 26, 2023
"},{"location":"meetings/2023/2023-07-26/","title":"2023-07-26","text":"

Reminder

These meetings are covered by the Antitrust Policy and the Code of Conduct.

"},{"location":"meetings/2023/2023-07-26/#agenda","title":"Agenda","text":"
  • Announcements
  • Review action items from last meeting
  • Materials for MkDocs Insiders version
  • Farmworker Wallet OS project proposal
  • Call for code from the community
  • Open discussion and next steps
"},{"location":"meetings/2023/2023-07-26/#links","title":"Links","text":"
  • slides
  • recording
"},{"location":"meetings/2023/2023-07-26/#tac-voting-members","title":"TAC Voting Members","text":"
  • Jeremie Miller
  • Pete Cooling
  • Stavros Kounis
  • Tracy Kuhrt
  • Troy Ronda
  • Wenjing Chu
"},{"location":"meetings/2023/2023-07-26/#action-items","title":"Action Items","text":"
  • Develop list of budget line items needed by the TAC
  • Work with Jorge on the item of whether aries-sdk-mendix makes sense within Hyperledger
"},{"location":"meetings/2023/2023-07-26/#meeting-minutes","title":"Meeting Minutes","text":"
  • Announcements

    • Credential Format Comparison SIG will meet on Wednesdays at 4pm CEST on alternate weeks to the TAC
    • OID4VC Due Diligence task force will meet weekly on Wednesdays at 5pm CEST
    • Architecture SIG meets weekly on Mondays at 11am US/Pacific
    • Vice chair nomination period open until August 2nd. Please submit your nominations
    • TAC website now available at https://tac.openwallet.foundation
    • OpenWallet Foundation Discord has a custom invite link: https://discord.gg/openwalletfoundation
  • Review action items from last meeting

    • Work with Daniel to transfer SD-JWT Python repo to openwallet-foundation-labs organization -- in progress
    • Review Farmworker Wallet OS project proposal -- in progress
    • Review the proposed license of Farmworker Wallet OS project with LF legal -- completed
  • Materials for MkDocs Insiders version

    • RESOLVED: That the TAC recommends to the Governing Board the sponsorship of Material for MkDocs to obtain access to the Insiders Version is hereby confirmed, approved, and adopted.
      • Proposed resolution was not voted on. It was suggested that we develop a proposal that would include other tools that the technical community would need to limit the number of requests to the Governing Board.
  • Farmworker Wallet OS project proposal

    • Discussion items
      • Code of Conduct
        • plan to change to use OWF\u2019s CoC
        • we may need to consider changing the template since it asks for the current CoC
      • License
        • change to use Apache 2.0 license
      • Project Governance
        • no change needed at this point
      • Repo names
        • Discussion was had to make sure that we are prefixing repo names with the project name to ensure that it is easy for someone to find all repos associated with a single project
      • Interoperable roadmap
        • No limit on what will be supported
      • Hosting Aries-specific stuff at OWF
        • TAC considers wrappers of other projects to be better suited to be included with the parent project
        • Tracy to work with Jorge on creating a lab proposal for Hyperledger for the Aries-specific wrappers
        • Jorge to update proposal to reflect the above recommendation
  • Call for code from the community

    • If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
  • Open discussion and next steps

    • Next meeting is August 9, 2023
"},{"location":"meetings/2023/2023-08-09/","title":"2023-08-09","text":"

Reminder

These meetings are covered by the Antitrust Policy and the Code of Conduct.

"},{"location":"meetings/2023/2023-08-09/#agenda","title":"Agenda","text":"
  • Announcements
  • Review action items from last meeting
  • Farmworker Wallet OS project proposal
  • Budget Request to Governing Board
  • Vice Chair
  • Call for code from the community
  • Open discussion and next steps
"},{"location":"meetings/2023/2023-08-09/#links","title":"Links","text":"
  • slides
  • recording
"},{"location":"meetings/2023/2023-08-09/#tac-voting-members","title":"TAC Voting Members","text":"
  • Jeremie Miller
  • Pete Cooling
  • Stavros Kounis
  • Tracy Kuhrt
  • Troy Ronda
  • Wenjing Chu
"},{"location":"meetings/2023/2023-08-09/#action-items","title":"Action Items","text":"
  • Continue to work on budget line items
  • Jorge to update code of conduct on Farmworker Wallet OS proposal -- completed
  • Create repositories for the Farmworker Wallet OS Lab
  • Share document with governance best practices -- completed
    • OWF Project Guidance -- this document assumes a fairly mature project that consists of a technical steering committee and maintainers for the project. Please comment and add your thoughts/suggestions.
    • Hyperledger's Project Best Practices
  • Comment on OWF Project Guidance - all
"},{"location":"meetings/2023/2023-08-09/#meeting-minutes","title":"Meeting Minutes","text":"
  • Announcements

    • Credential Format Comparison SIG will meet on Wednesdays at 4pm CEST on alternate weeks to the TAC
    • OID4VC Due Diligence task force will meet weekly on Tuesdays at 5pm CEST
    • Architecture SIG meets weekly on Mondays at 11am US/Pacific
    • sd-jwt-python source is now available
  • Review action items from last meeting

    • Work with Daniel to transfer SD-JWT Python repo to openwallet-foundation-labs organization -- completed
    • Review Farmworker Wallet OS project proposal -- in progress
    • Tracy to work with Jorge on creating a lab proposal for Hyperledger for the Aries-specific wrappers -- completed
    • Develop list of budget line items needed by the TAC \u2013 in progress
  • Farmworker Wallet OS project proposal

    • RESOLVED: That the Farmworker Wallet OS lab is hereby confirmed, approved, and adopted.
      • Unanimously approved by the present TAC voting members.
  • Budget Request to Governing Board

    • Thread started on Discord
    • Sponsorship of Material for MkDocs to obtain access to the Insiders Version at $125/month to support the TAC website
    • Wiki (Confluence or similar)
    • License Scanning
    • Package Hosting - GitHub? ghcr.io? Is there a package hosting solution for all technologies that exists?
    • Playground/Sandbox Hosting
    • Others?
  • Vice Chair

    • RESOLVED: That Stavros Kounis is hereby confirmed and approved as the TAC Vice Chair
      • Approved by the present TAC voting members with Stavros abstaining.
  • Call for code from the community

    • If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
    • Question asked about code proposal that depends on Aries/Bifold and whether that could be submitted to OWF?
      • If the project is only dependent on Aries/Bifold, then it can be submitted to OWF.
      • If, however the project is a wrapper of Aries/Bifold, then that should probably be submitted to Hyperledger.
    • Question about project governance best practices and whether we could document these best practices for new projects.
      • OWF Project Guidance -- this document assumes a fairly mature project that consists of a technical steering committee and maintainers for the project. Please comment and add your thoughts/suggestions.
      • In addition, we can look at Hyperledger's Project Best Practices for additional thoughts on guiding OpenWallet Foundation projects.
  • Open discussion and next steps

    • Next meeting is August 23, 2023
"},{"location":"meetings/2023/2023-08-23/","title":"2023-08-23","text":"

Reminder

These meetings are covered by the Antitrust Policy and the Code of Conduct.

"},{"location":"meetings/2023/2023-08-23/#agenda","title":"Agenda","text":"
  • Announcements
  • Review action items from last meeting
  • Budget Request to Governing Board
  • OWF Project Governance Guidance
  • Call for code from the community
  • Open discussion and next steps
"},{"location":"meetings/2023/2023-08-23/#links","title":"Links","text":"
  • slides
  • recording
"},{"location":"meetings/2023/2023-08-23/#tac-voting-members","title":"TAC Voting Members","text":"
  • Jeremie Miller
  • Pete Cooling
  • Stavros Kounis
  • Tracy Kuhrt
  • Troy Ronda
  • Wenjing Chu
"},{"location":"meetings/2023/2023-08-23/#action-items","title":"Action Items","text":"
  • Review, comment, and add feedback to OWF Project Governance Guidance - all
  • Review, comment, and add feedback to VC-API prject proposal - all
  • Provide infrastructure costs for the European Interoperability Test Bed - Harm Jan Arendshorst
"},{"location":"meetings/2023/2023-08-23/#meeting-minutes","title":"Meeting Minutes","text":"
  • Announcements

    • Credential Format Comparison SIG will meet on Wednesdays at 4pm CEST on alternate weeks to the TAC
    • OID4VC Due Diligence task force will meet weekly on Tuesdays at 5pm CEST
    • Architecture SIG meets weekly on Mondays at 11am US/Pacific
    • Farmworker Wallet OS repositories created
    • Project pages created for each approved project on the TAC website
    • Slide deck available covering the OWF Project Proposal Process
  • Review action items from last meeting

    • Continue to work on budget line items -- all
    • Jorge to update code of conduct on Farmworker Wallet OS proposal -- completed
    • Create repositories for the Farmworker Wallet OS Lab -- completed
    • Share document with governance best practices -- completed
    • Comment on OWF Project Guidance - all
  • Budget Request to Governing Board

    • Sponsorship of Material for MkDocs to obtain access to the Insiders Version at $125/month to support the TAC website
    • Wiki
      • Options:
        • Dokuwiki is currently included in our current LFIT budget
        • Confluence would be an additional $800/month
        • Continue utilizing GitHub wiki
        • Update the TAC website as necessary
      • Discussion:
        • Confluence is nice to allow for the ability to search across the entire foundation
        • Consider the migration costs
        • Confluence has a lot of nice features that GitHub wiki and Dokuwiki do not have
        • It is easier to bring markdown files into Confluence than to export to markdown
        • Most documentation for projects will be captured within projects as markdown files and hosted using something like ReadTheDocs.io or GitHub Pages
        • We do not currently have anyone that is asking for Confluence
        • If we sponsor Material for Mkdocs insiders version, then all OpenWallet Foundation projects will be able to utilize
      • Outcome: We will postpone asking for budget until we have a need
    • License Scanning
      • Another project within the Linux Foundation cost is $65,000/year
      • We should ask for this as it allows us to remain compliant with the open licenses
    • Package Hosting - GitHub? ghcr.io? Is there a package hosting solution for all technologies that exists?
      • ghcr.io (GitHub Packages) is free for all public GitHub repositories \u2013 recommend we start there
      • Support for Package Registries
      • The only thing that we have currently that is not supported by GitHub Packages is Python
    • Playground/Sandbox Hosting
      • We do not yet have a price for this, but following are some of the things that we could see needing a sandbox
        • Accessing server-side APIs
        • Deployment of server-based reference wallet
        • Interop testing
        • Reference implementation of data objects that a wallet contain - example VC issuance and verification
      • Harm mentioned that he has some information on the infrastructure costs for hosting the European Interoperability Test Bed, which was presented to the architecture SIG on March 27, 2023. Harm will provide information on these costs
      • Harm is also interested in bringing the Interoperability Test Bed as a project to the OWF
    • DevSecOps
      • The Linux Foundation is recommending that projects use GH Actions
      • Automated security/code scanning
      • SonarQube - Static code analysis
  • OWF Project Governance Guidance

    • Request to review, add comments and feedback
    • David Alexander recommended that we include information about momentum and duty of care and working across the foundation
    • Stavros asked if a TSC is required for projects
      • No, a TSC is not mandatory. The idea is that if a project gets big enough where all the maintainers cannot get together easily and make decisions, more governance framework is needed, and this is the way to go in that case.
      • As such, we should make sure that this document provides the right level of guidance for projects at different stages in their lifecycle
  • Call for code from the community

    • If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
    • Next time we meet, we will be reviewing the VC-API prject proposal
  • Open discussion and next steps

    • Next meeting is September 6, 2023
"},{"location":"meetings/2023/2023-09-06/","title":"2023-09-06","text":"

Reminder

These meetings are covered by the Antitrust Policy and the Code of Conduct.

"},{"location":"meetings/2023/2023-09-06/#agenda","title":"Agenda","text":"
  • Announcements
  • Review action items from last meeting
  • Welcome new TAC member
  • VC-API Project Proposal
  • Call for code from the community
  • Open discussion and next steps
"},{"location":"meetings/2023/2023-09-06/#links","title":"Links","text":"
  • slides
  • recording
"},{"location":"meetings/2023/2023-09-06/#tac-voting-members","title":"TAC Voting Members","text":"
  • David Zeuthen
  • Jeremie Miller
  • Pete Cooling
  • Stavros Kounis
  • Tracy Kuhrt
  • Troy Ronda
  • Wenjing Chu
"},{"location":"meetings/2023/2023-09-06/#action-items","title":"Action Items","text":"
  • Create recommendation for governing board for licenses that are compatible with Apache 2.0 to be approved -- Tracy
  • Update PR to answer questions asked during the meeting -- John
  • Determine if Energy Web Foundation is willing to relicense VC-API -- John
"},{"location":"meetings/2023/2023-09-06/#meeting-minutes","title":"Meeting Minutes","text":"
  • Announcements

    • Credential Format Comparison SIG will meet on Wednesdays at 4pm CEST on alternate weeks to the TAC (next call September 13)
    • OID4VC Due Diligence task force will meet bi-weekly on Tuesdays at 5pm CEST (next call September 12)
    • Architecture SIG meets weekly on Mondays at 11am US/Pacific (next call September 11)
  • Review action items from last meeting

    • Review, comment, and add feedback to OWF Project Governance Guidance - all
    • Review, comment, and add feedback to VC-API prject proposal - all
    • Provide infrastructure costs for the European Interoperability Test Bed - Harm Jan Arendshorst
  • Welcome new TAC member

    • We welcomed David Zeuthen, Google premier member representative
  • VC-API Project Proposal

    • How does this codebase relate to the energywebfoundation/ssi?
      • Does this proposal refer to the ssi repository OR only to work under the /vc-api path?
        • The intention is to bring over only the /vc-api path. We could consider whether it makes sense to bring over the other application, but it would require a separate proposal.
      • Are there dependencies or references to any implementation outside this folder that need attention if it is the latter?
        • Refer to the \"Source Control\" section of the proposal for information on what the dependencies are for the VC-API
      • Could we prepare a list of all the single repositories the vc-api needs and will be part of this proposal? I would also suggest supplementing this list with the purpose of these additional repos and their relationship/dependencies to vc-api.
        • This is captured in the \"Source Control\" section of the proposal.
      • For licensing purposes, will we leave related repositories in the organization they currently are? Should we expect a licensing conflict in this case?
        • John will follow up on the license with Energy Web Foundation.
      • What referenced tutorials and documentation will moved from energywebfoundation GitHub organization to the OWF?
        • Yes, we can move the tutorials and documentation into OWF.
    • Is this project an implementation of a VC API server or also client/wallet libraries?
      • Server only
    • Is this project based on the latest version of the CCG VC API? Does it already implement the full community report?
      • It implements the latest published version of the CCG VC API. It may be missing one or two endpoints. I don't think that we have implemented derived presentation.
    • Which credential formats and signature formats are supported?
      • Those that are supported by SpruceID's DIDKit
    • How have you tested interop?
      • We have not yet tested interop. The testing that we have done is with the available test suites.
    • What will be the prefix for this project?
      • We need to determine a way in which projects can be separated if they implement the same specification. Project prefixes are a way to do this and will allow us to trademark them in the future.
    • License
      • John to follow up with Energy Web Foundation about the possibility or re-licensing
      • Develop recommendation for the OWF governing board on licenses that are compatible with Apache 2.0
    • Missing DCO on existing repository
  • Call for code from the community

    • If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
  • Open discussion and next steps

    • Next meeting is September 20, 2023
"},{"location":"meetings/2023/2023-09-20/","title":"2023-09-20","text":"

Reminder

These meetings are covered by the Antitrust Policy and the Code of Conduct.

"},{"location":"meetings/2023/2023-09-20/#agenda","title":"Agenda","text":"
  • Announcements
  • Review action items from last meeting
  • SIG Proposal - SSI Wallet and Agent Overviews
  • SIG Proposal - Anti-Correlation and Anti-Profiling
  • VC-API Project Proposal
  • Intellectual Property Policy
  • Call for code from the community
  • Open discussion and next steps
"},{"location":"meetings/2023/2023-09-20/#links","title":"Links","text":"
  • slides
  • recording
"},{"location":"meetings/2023/2023-09-20/#tac-voting-members","title":"TAC Voting Members","text":"
  • David Zeuthen
  • Jeremie Miller
  • Pete Cooling
  • Stavros Kounis
  • Tracy Kuhrt
  • Troy Ronda
  • Wenjing Chu
"},{"location":"meetings/2023/2023-09-20/#action-items","title":"Action Items","text":"
  • Review, comment, and add feedback to the Wallet Framework .NET project proposal - all
  • Review, comment, and add feedback to the Intellectual Property Proposal - all
  • Digital Wallet and Agent Overview SIG
    • Create Discord channel - Tracy
    • Add information to the TAC website regarding the SIG - Tracy
    • Add link to the above to the OpenWallet Foundation GitHub Profile - Tracy
    • Work with Maaike on infrastructure requirements (repo, mailing list) - Tracy/Maaike
  • Anti-Correlation and Anti-Profiling SIG
    • Create Discord channel - Tracy
    • Add information to the TAC website regarding the SIG - Tracy
    • Add link to the above to the OpenWallet Foundation GitHub Profile - Tracy
    • Work with Andy on infrastructure requirements (repo, mailing list) - Tracy/Andy
  • Conduct email vote for VC-API project approval - Tracy - completed
"},{"location":"meetings/2023/2023-09-20/#meeting-minutes","title":"Meeting Minutes","text":"
  • Announcements

    • Credential Format Comparison SIG will meet on Wednesdays at 4pm CEST on alternate weeks to the TAC (next call September 27)
    • OID4VC Due Diligence task force will meet bi-weekly on Tuesdays at 5pm CEST (next call September 26)
    • Architecture SIG meets weekly on Mondays at 11am US/Pacific (next call September 25)
    • New Project Proposal - Wallet Framework .NET - Please review
    • Suggested Future Project - Support the Apple pass format
  • Review action items from last meeting

    • Review, comment, and add feedback to OWF Project Governance Guidance by October 4th - all
    • Review, comment, and add feedback to VC-API project proposal - all
    • Provide infrastructure costs for the European Interoperability Test Bed - Harm Jan Arendshorst
    • Create recommendation for governing board for intellectual property policy -- Tracy -- completed
    • Update VC-API PR to answer questions asked during the meeting -- John \u2013 completed
    • Determine if Energy Web Foundation is willing to relicense VC-API -- John \u2013 completed
  • SIG Proposal - SSI Wallet and Agent Overviews

    • RESOLVED: That the SSI Wallet and Agent Overviews special interest group is hereby confirmed, approved, and adopted.
      • Unanimously approved by the present TAC voting members
  • SIG Proposal - Anti-Correlation and Anti-Profiling

    • RESOLVED: That the Anti-Correlation and Anti-Profiling special interest group is hereby confirmed, approved, and adopted.
      • Unanimously approved by the present TAC voting members
  • VC-API Project Proposal

    • Discussion
    • RESOLVED: That the VC-API lab is hereby confirmed, approved, and adopted.
      • Since we did not have enough TAC voting members to meet the \u2154 supermajority vote, we will conduct an email vote.
  • Intellectual Property Policy

    • Apache 2.0 for source code
    • CC-BY-4.0 for documentation
    • Allowed Third Party License Policy
    • RESOLVED: That the proposed Intellectual Property Policy will be forwarded to the Governing Board for consideration.
      • Please review and provide your feedback
      • We will vote on this next time we meet
  • Call for code from the community

    • If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
  • Open discussion and next steps

    • Next meeting is October 4, 2023
    • Discussed whether to move to weekly meetings to support influx of project proposals. It was determined that we could be more efficient on these calls if we commented on the PRs when they are submitted to get questions answered that may delay the vote.
"},{"location":"meetings/2023/2023-10-04/","title":"2023-10-04","text":"

Reminder

These meetings are covered by the Antitrust Policy and the Code of Conduct.

"},{"location":"meetings/2023/2023-10-04/#agenda","title":"Agenda","text":"
  • Announcements
  • Review action items from last meeting
  • Project Proposal - Wallet Framework .NET
  • Project Proposal - Android Identity Library
  • Intellectual Property Policy
  • Open discussion and next steps
"},{"location":"meetings/2023/2023-10-04/#links","title":"Links","text":"
  • slides
  • recording
"},{"location":"meetings/2023/2023-10-04/#tac-voting-members","title":"TAC Voting Members","text":"
  • David Zeuthen
  • Jeremie Miller
  • Pete Cooling
  • Stavros Kounis
  • Tracy Kuhrt
  • Drummond Reed (alternate for Troy Ronda)
  • Wenjing Chu
"},{"location":"meetings/2023/2023-10-04/#action-items","title":"Action Items","text":"
  • Conduct email vote on the Intellectual Property Policy
  • Add project page for the Wallet Framework .NET project
  • Work with Sebastian to transfer Wallet Framework .NET project code to OWF
  • Review, comment, and add feedback to Android Identity Library project proposal - all
"},{"location":"meetings/2023/2023-10-04/#meeting-minutes","title":"Meeting Minutes","text":"
  • Announcements

    • Credential Format Comparison SIG meets bi-weekly on Wednesdays at 4pm CEST on alternate weeks to the TAC (next call October 11)
    • OID4VC Due Diligence task force meets bi-weekly on Tuesdays at 5pm CEST (next call October 24)
    • Architecture SIG meets weekly on Mondays at 11am US/Pacific (next call October 16)
    • Please submit any code proposals using the process defined at openwallet-foundation/project-proposals. We will review proposals in the order submitted at a TAC meeting. If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up.
    • Pre-IIW Developer Face-to-Face October 9
  • Review action items from last meeting

    • Review, comment, and add feedback to OWF Project Governance Guidance - all
    • Review, comment, and add feedback to the Intellectual Property Proposal - all
    • Review, comment, and add feedback to the Wallet Framework .NET project proposal - all
    • Provide infrastructure costs for the European Interoperability Test Bed - Harm Jan Arendshorst
    • Digital Wallet and Agent Overviews SIG onboarding - completed
    • Anti-Correlation and Anti-Profiling SIG Onboarding - completed
    • Conduct email vote for VC-API project approval - Tracy - completed and approved
  • Project Proposal - Wallet Framework .NET

    • RESOLVED: That the Wallet Framework .NET proposal is hereby confirmed, approved, and adopted.
      • Unanimously approved by the present TAC voting members.
  • Project Proposal - Android Identity Library

    • RESOLVED: That the Android Identity Library proposal is hereby confirmed, approved, and adopted.
      • Move to next meeting
  • Intellectual Property Policy

    • Apache 2.0 for source code
    • CC-BY-4.0 for documentation
    • Allowed Third Party License Policy
    • Open Standards and Specifications
    • RESOLVED: That the proposed Intellectual Property Policy will be forwarded to the Governing Board for consideration.
      • Conduct an email vote
  • Open discussion and next steps

    • Discussion regarding conflict of the Safe Wallet SIG with other meetings
    • Standing agenda items that we might want to add:
      • Socialization of what others in the community are doing
      • Project, SIG, Task Force updates
    • Next meeting is October 20 2023
"},{"location":"meetings/2023/2023-10-18/","title":"2023-10-18","text":"

Reminder

These meetings are covered by the Antitrust Policy and the Code of Conduct.

"},{"location":"meetings/2023/2023-10-18/#agenda","title":"Agenda","text":"
  • Announcements
  • Review action items from last meeting
  • Welcome new TAC member (hold for next meeting)
  • Legal Discussion - Project Charters
  • Project Proposal - Android Identity Library
  • Project Proposal: SD-JWT JS
  • Open discussion and next steps
"},{"location":"meetings/2023/2023-10-18/#links","title":"Links","text":"
  • slides
  • recording
"},{"location":"meetings/2023/2023-10-18/#tac-voting-members","title":"TAC Voting Members","text":"
  • David Zeuthen
  • Jeremie Miller
  • Pete Cooling
  • Stavros Kounis
  • Tracy Kuhrt
  • Drummond Reed (alternate for Mike Varley)
  • Wenjing Chu
"},{"location":"meetings/2023/2023-10-18/#action-items","title":"Action Items","text":"
  • Update project proposal template to make it easier for people to understand what the TAC is expecting for answers related to each question -- Tracy
  • Update project lifecycle to reflect project charters -- Tracy
  • Document the desire for OWF to utilize permissive licenses in the project lifecycle -- Tracy
  • Review, comment, and add feedback to SD-JWT JS lab proposal -- all
"},{"location":"meetings/2023/2023-10-18/#meeting-minutes","title":"Meeting Minutes","text":"
  • Announcements

    • Architecture SIG meets weekly on Mondays at 11am US/Pacific (next call October 30)
    • OID4VC Due Diligence task force meets bi-weekly on Tuesdays at 5pm CEST (next call October 24)
    • Safe Wallet SIG meets weekly on Tuesdays at 8am US/Pacific (next call October 24)
    • Credential Format Comparison SIG meets bi-weekly on Wednesdays at 4pm CEST on alternate weeks to the TAC (next call October 25)
    • Digital Wallets and Agents Overviews SIG meets biweekly on Thursdays at 5:00pm CEST on alternate weeks to the TAC (next meeting October 26)
    • Please submit any code proposals using the process defined at https://github.com/openwallet-foundation/project-proposals. We will review proposals in the order submitted at a TAC meeting. If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up.
  • Review action items from last meeting

    • Conduct email vote on the Intellectual Property Policy \u2013 completed
    • Add project page for the Wallet Framework .NET project \u2013 completed
    • Work with Sebastian to transfer Wallet Framework .NET project code to OWF \u2013 completed
    • Review, comment, and add feedback to Android Identity Library project proposal - all
    • Provide infrastructure costs for the European Interoperability Test Bed - Harm Jan Arendshorst
  • Welcome New TAC Member

    • Mike Varley will represent Gen Digital moving forward.
    • Hold for next meeting as Mike could not attend today.
  • Legal Discussion

    • Discuss project charters
      • Sample charter
      • Intake form
      • Copyleft vs. Permissive licenses (LF allows any OSI license. The OWF can decide on whether they only want permissive license.)
  • Project Proposal - Android Identity Library

    • RESOLVED: That the Android Identity Library proposal is hereby confirmed, approved, and adopted.
      • 6* Approve, 1 Abstain (David) - Project accepted

        Info (*)

        During the meeting, Pete abstained. After the meeting, Pete changed his vote via email from Abstain to Approve.

  • Project Proposal - SD-JWT JS

    • RESOLVED: That the SD-JWT JS lab proposal is hereby confirmed, approved, and adopted.
      • Some discussion about why a new project is needed instead of utilizing existing typescript implementations.
  • Open discussion and next steps

    • David Alexander suggested that the OpenWallet Foundation work closely with MyData.
    • Next meeting is November 1, 2023
"},{"location":"meetings/2023/2023-11-01/","title":"2023-11-01","text":"

Reminder

These meetings are covered by the Antitrust Policy and the Code of Conduct.

"},{"location":"meetings/2023/2023-11-01/#agenda","title":"Agenda","text":"
  • Announcements
  • Review action items from last meeting
  • Welcome new TAC member
  • Resolution: SD-JWT JS Project Proposal
  • Resolution: SD-JWT Rust Project Proposal
  • Resolution: Proposal Process Updates
    • Clarify Template Instructions
    • Update Process
  • Resolution: Project Services and Paid Tooling
  • Open discussion and next steps
"},{"location":"meetings/2023/2023-11-01/#links","title":"Links","text":"
  • slides
  • recording
"},{"location":"meetings/2023/2023-11-01/#tac-voting-members","title":"TAC Voting Members","text":"
  • David Zeuthen
  • Jeremie Miller
  • Mike Varley
  • Pete Cooling
  • Stavros Kounis
  • Tracy Kuhrt
  • Wenjing Chu
"},{"location":"meetings/2023/2023-11-01/#action-items","title":"Action Items","text":"
  • Update \"permissive license\" to \"OSI-approved permissive license\" in the project lifecycle and template PRs
  • Update Paid Tooling PR to reflect other requests require the Governing Board approval
  • Onboarding SD-JWT JS lab
    • Create sd-jwt-js repo in OpenWallet Foundation Labs GitHub
    • Create sd-jwt-js Discord channel
    • Complete intake form to create project charter
"},{"location":"meetings/2023/2023-11-01/#meeting-minutes","title":"Meeting Minutes","text":"
  • Announcements

    • Architecture SIG meets weekly on Mondays at 11am US/Pacific (next call November 6)
    • OID4VC Due Diligence task force meets bi-weekly on Tuesdays at 5pm CEST (next call November 7)
    • Safe Wallet SIG meets weekly on Tuesdays at 8am US/Pacific (next call November 7)
    • Credential Format Comparison SIG meets bi-weekly on Wednesdays at 4pm CEST on alternate weeks to the TAC (next call November 8)
    • Digital Wallets and Agents Overviews SIG meets biweekly on Thursdays at 5:00pm CEST on the same weeks as the TAC (next meeting November 2)
    • Please submit any code proposals using the process defined at https://github.com/openwallet-foundation/project-proposals. We will review proposals in the order submitted at a TAC meeting. If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up.
  • Review action items from last meeting

    • Update project proposal template to make it easier for people to understand what the TAC is expecting for answers related to each question -- Tracy -- completed
    • Update project lifecycle to reflect project charters -- Tracy -- completed
    • Document the desire for OWF to utilize permissive licenses in the project lifecycle -- Tracy -- completed
    • Review, comment, and add feedback to SD-JWT JS lab proposal -- all
    • Work with John Henderson to transfer VC-API project to OpenWallet Foundation Labs
    • Work with David Zeuthen to transfer Android Identity Library project to OpenWallet Foundation Labs
  • Welcome New TAC Member

    • Mike Varley will represent Gen Digital moving forward.
  • Resolution: SD-JWT JS Project Proposal

    • RESOLVED: That the SD-JWT JS lab proposal is hereby confirmed, approved, and adopted.
      • APPROVED with six yea, one absent
  • Resolution: SD-JWT Rust Project Proposal

    • RESOLVED: That the SD-JWT Rust lab proposal is hereby confirmed, approved, and adopted.
      • Matter not voted on.
  • Resolution: Proposal Process Updates

    • RESOLVED: That the changes suggested in Clarify Template Instructions and Update Process are hereby confirmed, approved, and adopted.
      • APPROVED with six yea, one absent
  • Resolution: Project Services and Paid Tooling

    • RESOLVED: That the Project Services and Paid Tooling is hereby confirmed, approved, and adopted.
      • APPROVED with six yea, one absent
  • Open discussion and next steps

    • Next meeting is November 15, 2023
"},{"location":"meetings/2023/2023-11-15/","title":"2023-11-15","text":"

Reminder

These meetings are covered by the Antitrust Policy and the Code of Conduct.

"},{"location":"meetings/2023/2023-11-15/#agenda","title":"Agenda","text":"
  • Announcements
  • Review action items from last meeting
  • Task force update: OID4VC Due Diligence
  • Resolution: SD-JWT Rust Project Proposal
  • Resolution: SD-JWT .NET Project Proposal
  • Open discussion and next steps
"},{"location":"meetings/2023/2023-11-15/#links","title":"Links","text":"
  • slides
  • recording
"},{"location":"meetings/2023/2023-11-15/#tac-voting-members","title":"TAC Voting Members","text":"
  • David Zeuthen
  • Jeremie Miller
  • Mike Varley
  • Pete Cooling
  • Stavros Kounis
  • Tracy Kuhrt
  • Wenjing Chu
"},{"location":"meetings/2023/2023-11-15/#action-items","title":"Action Items","text":"
  • Onboarding SD-JWT Rust lab
    • Create sd-jwt-rust repo in OpenWallet Foundation Labs GitHub
    • Create sd-jwt-rust Discord channel
    • Complete intake form to create project charter -- follow up with LF Legal on status
"},{"location":"meetings/2023/2023-11-15/#meeting-minutes","title":"Meeting Minutes","text":"
  • Announcements

    • Architecture SIG meets weekly on Mondays at 11am US/Pacific (next call November 27; skipping week of US Thanksgiving)
    • OID4VC Due Diligence task force meets bi-weekly on Tuesdays at 5pm CET (next call November 21)
    • Safe Wallet SIG meets weekly on Tuesdays at 8am US/Pacific (next call November 21)
    • Credential Format Comparison SIG meets bi-weekly on Wednesdays at 4pm CET on alternate weeks to the TAC (next call November 22)
    • Digital Wallets and Agents Overviews SIG meets biweekly on Thursdays at 5:00pm CET on the same weeks as the TAC (next meeting November 16)
    • Please submit any code proposals using the process defined at https://github.com/openwallet-foundation/project-proposals. We will review proposals in the order submitted at a TAC meeting. If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up.
    • SIG quarterly updates will begin in January 2024
  • Review action items from last meeting

    • Update \"permissive license\" to \"OSI-approved permissive license\" in the project lifecycle and template PRs \u2013 completed and merged (lifecycle PR 69 and template PR 22)
    • Update Paid Tooling PR to reflect other requests require the Governing Board approval \u2013 completed and merged
    • Onboarding SD-JWT JS lab
      • Create sd-jwt-js repo in OpenWallet Foundation Labs GitHub \u2013 completed
      • Create sd-jwt-js Discord channel \u2013 completed (#sd-jwt-js)
      • Complete intake form to create project charter
    • Work with John Henderson to transfer VC-API project to OpenWallet Foundation Labs
    • Work with David Zeuthen to transfer Android Identity Library project to OpenWallet Foundation Labs
      • Working on name of the project
      • David has been working with the downstream dependencies to make them aware of changes that will be coming
  • Task Force Update: OID4VC Due Diligence

    • Update Slide Deck
    • Discussion about whether this task force should become a SIG
      • At this time, we will leave this as a task force
      • The task force members will decide on the expanded time that is needed
      • At some point in the future, this may become an OID4VC Implementers SIG
  • Resolution: SD-JWT Rust Project Proposal

    • RESOLVED: That the SD-JWT Rust lab proposal is hereby confirmed, approved, and adopted.
      • Unanimously approved by the present TAC voting members.
  • Resolution: SD-JWT .NET Project Proposal

    • RESOLVED: That the SD-JWT .NET lab proposal is hereby confirmed, approved, and adopted.
      • Matter not voted on.
  • Open discussion and next steps

    • Next meeting is November 29, 2023
"},{"location":"meetings/2023/2023-11-29/","title":"2023-11-29","text":"

Reminder

These meetings are covered by the Antitrust Policy and the Code of Conduct.

"},{"location":"meetings/2023/2023-11-29/#agenda","title":"Agenda","text":"
  • Announcements
  • Review action items from last meeting
  • Resolution: SD-JWT .NET Project Proposal
  • Resolution: Agent Framework JavaScript Proposal
  • Open discussion and next steps
"},{"location":"meetings/2023/2023-11-29/#links","title":"Links","text":"
  • slides
  • recording
"},{"location":"meetings/2023/2023-11-29/#tac-voting-members","title":"TAC Voting Members","text":"
  • David Zeuthen
  • Jeremie Miller
  • Mike Varley
  • Pete Cooling
    • Marie Austenaa
  • Stavros Kounis
  • Tracy Kuhrt
  • Wenjing Chu
"},{"location":"meetings/2023/2023-11-29/#action-items","title":"Action Items","text":"
  • Onboard SD-JWT .NET
    • Transfer sd-jwt-dotnet repo to OpenWallet Foundation Labs GitHub
    • Create sd-jwt-dotnet Discord channel
    • Follow up with LF Legal on project intake form
  • Onboard Agent Framework JavaScript
    • Transfer repos to OpenWallet Foundation Labs GitHub
    • Create agent-framework-js Discord channel
    • Follow up with LF Legal on project intake form
"},{"location":"meetings/2023/2023-11-29/#meeting-minutes","title":"Meeting Minutes","text":"
  • Announcements

    • Architecture SIG meets weekly on Mondays at 11am US/Pacific (next call December 4)
    • OID4VC Due Diligence task force meets bi-weekly on Tuesdays at 5pm CET (next call December 5)
    • Safe Wallet SIG meets weekly on Tuesdays at 7am US/Pacific (next call December 5)
    • Credential Format Comparison SIG meets bi-weekly on Wednesdays at 4pm CET on alternate weeks to the TAC (next call December 6)
    • Digital Wallets and Agents Overviews SIG meets biweekly on Thursdays at 5:00pm CET on the same weeks as the TAC (next meeting November 30)
    • Please submit any code proposals using the process defined at https://github.com/openwallet-foundation/project-proposals. We will review proposals in the order submitted at a TAC meeting. If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
    • SIG quarterly updates will begin in January 2024
  • Review action items from last meeting

    • Onboarding SD-JWT Rust lab
      • Create sd-jwt-rust repo in OpenWallet Foundation Labs GitHub \u2013 completed
      • Create sd-jwt-rust Discord channel \u2013 completed (#sd-jwt-rust)
      • Complete intake form to create project charter -- follow up with LF Legal on status
    • Work with John Henderson to transfer VC-API project to OpenWallet Foundation Labs
    • Work with David Zeuthen to transfer Android Identity Library project to OpenWallet Foundation Labs
  • Resolution: SD-JWT .NET Project Proposal

    • RESOLVED: That the SD-JWT .NET lab proposal is hereby confirmed, approved, and adopted.
    • Approved by role call vote; 7 aye, 0 nay, 0 abstain
  • Resolution: Agent Framework JavaScript Project Proposal

    • RESOLVED: That the Agent Framework JavaScript Project proposal is hereby confirmed, approved, and adopted.
    • Stavros Kounis agreed to be the second sponsor to bring the project in at growth stage
    • Approved by role call vote; 7 aye, 0 nay, 0 abstain
  • Open discussion and next steps

    • Should we cancel the December 27, 2023 call?
    • Next meeting is December 13, 2023
    • First GAC meeting held
    • Request for feedback: https://gitlab.opencode.de/bmi/eudi-wallet/eidas-2.0-architekturkonzept-v1/
"},{"location":"meetings/2023/2023-12-13/","title":"2023-12-13","text":"

Reminder

These meetings are covered by the Antitrust Policy and the Code of Conduct.

"},{"location":"meetings/2023/2023-12-13/#agenda","title":"Agenda","text":"
  • Announcements
  • Review action items from last meeting
  • Moving to LFX Meetings
  • Resolution: Add Schedule for Quarterly SIG Updates
  • 2023 Retrospective
  • Open discussion and next steps
"},{"location":"meetings/2023/2023-12-13/#links","title":"Links","text":"
  • slides
  • recording
"},{"location":"meetings/2023/2023-12-13/#tac-voting-members","title":"TAC Voting Members","text":"
  • David Zeuthen
  • Jeremie Miller
  • Mike Varley
  • Pete Cooling
  • Stavros Kounis
  • Tracy Kuhrt
  • Wenjing Chu
"},{"location":"meetings/2023/2023-12-13/#action-items","title":"Action Items","text":"
  • Create Vulnerability Disclosure Policy
"},{"location":"meetings/2023/2023-12-13/#meeting-minutes","title":"Meeting Minutes","text":"
  • Announcements

    • Architecture SIG meets weekly on Mondays at 11am US/Pacific (next call January 8)
    • OID4VC Due Diligence task force meets bi-weekly on Tuesdays at 5pm CET (next call December 19)
    • Safe Wallet SIG meets weekly on Tuesdays at 7am US/Pacific (next call December 19)
    • Credential Format Comparison SIG meets bi-weekly on Wednesdays at 4pm CET on alternate weeks to the TAC (next call December 20)
    • Digital Wallets and Agents Overviews SIG meets biweekly on Thursdays at 5:00pm CET on the same weeks as the TAC (next meeting December 14)
    • Please submit any code proposals using the process defined at https://github.com/openwallet-foundation/project-proposals. We will review proposals in the order submitted at a TAC meeting. If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
  • Review action items from last meeting

    • Onboard SD-JWT .NET \u2013 completed
      • Transfer sd-jwt-dotnet repo to OpenWallet Foundation Labs GitHub \u2013 completed
      • Create sd-jwt-dotnet Discord channel \u2013 completed
      • Follow up with LF Legal on project intake form \u2013 completed
    • Onboard Agent Framework JavaScript \u2013 completed
      • Transfer repos to OpenWallet Foundation GitHub \u2013 completed
      • Create agent-framework-js Discord channel \u2013 completed
      • Follow up with LF Legal on project intake form \u2013 completed
    • Work with John Henderson to transfer VC-API project to OpenWallet Foundation Labs \u2013 in progress
    • Work with David Zeuthen to transfer Android Identity Library project to OpenWallet Foundation Labs \u2013 completed
  • Moving to LFX Meetings

    • Reviewed LFX Meetings
    • See LFX Meetings Management Guide
  • Resolution: Add Schedule for Quarterly SIG Updates

    • RESOLVED: That the pull request \"Resolution: Add Schedule for Quarterly SIG Updates\" is hereby confirmed, approved, and adopted.
      • Motion Wenjing, second Jeremie
      • Resolution passed with no objections or abstentions
  • 2023 Retrospective

    • Reviewed accomplishments
      • Also include in the accomplishments the face-to-face and the discussion with LF Legal on project charters
    • Retrospective
      • Shoutouts?
        • Google for hosting us at our face-to-face in Mountain View
        • Tracy for leading meetings
        • SIG and Task Force leaders
      • What went well?
        • Good structure on the TAC
        • Opportunity to collaborate
        • Consistency of how TAC meetings are managed and the access to the information needed so that you can do prep
        • Transparency
        • Inclusiveness
        • Team spirit
        • Advocacy
        • Provided confidence to move from being a consumer of open source to actually publishing open source at OWF
        • Learning process of what's involved in open source has been incredibly useful
        • Collaboration
        • Donation
        • Strong community engagement
        • Support OpenWallet has received in terms of projects, sponsors and Governmental Advisory Council members
      • What could we do differently next year?
        • Include voting members on the agenda and let people know who can vote at these meetings
      • Recommendations for next year
        • List of events for next year -- include in the #events channel on Discord
        • Creating a resource of slides that others have presented at conferences to present OWF
        • Challenge: helping projects grow within the OWF
        • Challenge: helping projects collaborate and work with one another
        • Engaging with the EUDI and bringing projects into OWF
        • Interoperability is a topic for us to focus on next year. Not just for the same protocols, but also across protocols. SIDI is also something that we should work closely with
        • Publish a white paper documenting our overall architectural considerations for open wallets (started already in the Architecture SIG)
        • Engaging with Trust Over IP
  • Open discussion and next steps

    • Vulnerability Disclosure Policy
      • Look at creating this next year
      • Resources:
        • OpenSSF Guide to implementing a coordinated vulnerability disclosure process for open source projects
        • Hyperledger Foundation Security Policy
        • Hyperledger Foundation Security Template
        • EU Digital Green Certificates Security Policy
    • Next meeting is January 10, 2024
      • Architecture SIG Quarterly Update
      • Using LFX Meetings
"},{"location":"meetings/2024/2024-01-10/","title":"2024-01-10","text":"

Reminder

These meetings are covered by the Antitrust Policy and the Code of Conduct.

"},{"location":"meetings/2024/2024-01-10/#agenda","title":"Agenda","text":"
  • Announcements
  • Review action items from last meeting
  • Architecture SIG Update
  • Discuss Drafted Vulnerability Disclosure Policy
  • Goals for 2024 (time permitting)
  • Open discussion and next steps
"},{"location":"meetings/2024/2024-01-10/#links","title":"Links","text":"
  • slides
  • recording
"},{"location":"meetings/2024/2024-01-10/#tac-voting-members","title":"TAC Voting Members","text":"
  • David Zeuthen
  • Jeremie Miller
  • Rolson Quadras (alternate for Mike Varley)
  • Pete Cooling
  • Stavros Kounis
  • Tracy Kuhrt
  • Wenjing Chu
"},{"location":"meetings/2024/2024-01-10/#action-items","title":"Action Items","text":"
  • List of TAC goals from other LF projects - Brian
  • Update Vulnerability Disclosure Pull Request - Tracy
"},{"location":"meetings/2024/2024-01-10/#meeting-minutes","title":"Meeting Minutes","text":"
  • Announcements

    • Architecture SIG meets weekly on Mondays at 11am US/Pacific (next call January 15)
    • OID4VC Due Diligence task force meets bi-weekly on Tuesdays at 5pm CET (next call January 17)
    • Safe Wallet SIG meets weekly on Tuesdays at 7am US/Pacific (next call January 16)
    • Credential Format Comparison SIG meets bi-weekly on Wednesdays at 4pm CET on alternate weeks to the TAC (next call January 17)
    • Digital Wallets and Agents Overviews SIG meets biweekly on Thursdays at 5:00pm CET on the same weeks as the TAC (next meeting January 11)
    • Please submit any code proposals using the process defined at https://github.com/openwallet-foundation/project-proposals. We will review proposals in the order submitted at a TAC meeting. If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
  • Review action items from last meeting

    • Work with John Henderson to transfer VC-API project to OpenWallet Foundation Labs \u2013 completed
    • Create Vulnerability Disclosure Policy \u2013 drafted
  • Architecture SIG Update

    • See Architecture SIG Q1 2024 Update for the answers to the following questions:
      • What is the Architecture SIG?
      • What has the Architecture SIG accomplished?
      • What is next for the Architecture SIG?
      • Where can I get information on the Architecture SIG?
      • How do I participate in the Architecture SIG?
    • Discussion on how the Architecture SIG should work with projects
      • In general, people see the role of the architecture SIG as a group that provides information on the state of the digital wallet architectues that can be used to provide insight into projects that may be missing from the OWF and in the long term a place that will help projects work more closely together.
  • Discuss Drafted Vulnerability Disclosure Policy

    • Discuss pull request
    • Rework to consider the following audiences: reporters, people using the code, and maintainers
    • Separate out standard text from project-specific text
  • Goals for 2024

    • What specific goals does the TAC have for 2024?
      • Brian suggested looking at what other TAC goals have been
      • Information for new submitters
      • Updates on existing projects
  • Open discussion and next steps

"},{"location":"meetings/2024/2024-01-24/","title":"2024-01-24","text":"

Reminder

These meetings are covered by the Antitrust Policy and the Code of Conduct.

"},{"location":"meetings/2024/2024-01-24/#agenda","title":"Agenda","text":"
  • Announcements
  • Review action items from last meeting
  • Project Proposal: Multi-format Verifiable Credentials for iOS
  • Discuss Vulnerability Disclosure Policy
  • Elections
  • Goals for 2024
  • Open discussion and next steps
"},{"location":"meetings/2024/2024-01-24/#links","title":"Links","text":"
  • slides
  • recording
"},{"location":"meetings/2024/2024-01-24/#tac-voting-members","title":"TAC Voting Members","text":"
  • David Zeuthen
  • Jeremie Miller
  • Mike Varley
  • Marie Austenaa (alternate for Pete Cooling)
  • Stavros Kounis
  • Tracy Kuhrt
  • Wenjing Chu
"},{"location":"meetings/2024/2024-01-24/#action-items","title":"Action Items","text":"
  • Onboard new lab
    • Create Discord channel
    • Create GitHub repo
  • Open discussion item for 2024 Goals -- completed
  • Provide thoughts on the 2024 TAC Goals and upvote any items that you think has importance -- All
"},{"location":"meetings/2024/2024-01-24/#meeting-minutes","title":"Meeting Minutes","text":"
  • Announcements

    • Architecture SIG meets weekly on Mondays at 11am US/Pacific (next call January 29)
    • OID4VC Due Diligence task force meets bi-weekly on Tuesdays at 5pm CET (next call January 30)
    • Safe Wallet SIG meets weekly on Tuesdays at 7am US/Pacific (next call January 30)
    • Credential Format Comparison SIG meets bi-weekly on Wednesdays at 4pm CET on alternate weeks to the TAC (next call January 31)
    • Digital Wallets and Agents Overviews SIG meets biweekly on Thursdays at 5:00pm CET on the same weeks as the TAC (next meeting January 25)
    • Please submit any code proposals using the process defined at https://github.com/openwallet-foundation/project-proposals. We will review proposals in the order submitted at a TAC meeting. If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
  • Review action items from last meeting

    • List of TAC goals from other LF projects \u2013 Brian
      • Other projects at the LF only have a responsiblities list with the main goal of the TAC, TOC, or TSC to successfully carry out these responsibilities
      • Hyperledger Foundation has been putting together goals for the last couple of years (2023 Goals, 2024 Goals)
    • Update Vulnerability Disclosure Policy \u2013 drafted
  • Project Proposal: Multi-format VC for iOS

    • RESOLVED: That the Multi-format Verifiable Credentials for iOS lab is hereby confirmed, approved, and adopted.
      • Unanimously approved
  • Discuss Vulnerability Disclosure Policy

    • Discuss pull request
    • RESOLVED: That the Vulnerability Disclosure Policy is hereby confirmed, approved, and adopted.
      • Unanimously approved
  • Elections

    • RESOLVED: That we will run the 2024 elections based on the following schedule:

      • TAC \u201cAt Large\u201d Representatives

        • 2024-03-20 Nomination Period Begins
        • 2024-03-27 Noon PT Nomination Period Ends
        • 2024-03-27 Helios Voting Ballot Distributed to Existing TAC Members
        • 2024-04-02 Noon PT Voting Ends
        • 2024-04-02 Results Announced on the TAC mailing list
        • 2024-04-03 New \u201cat large\u201d representatives begin their term
      • TAC Chair and Vice Chair

        • 2023-04-03 Nomination Period Begins
        • 2023-04-10 Noon PT Nomination Period Ends
        • 2024-04-10 Helios Voting Ballot Distributed to Existing TAC Members
        • 2024-04-16 Noon PT Voting Ends
        • 2024-04-16 Results Announced on the TAC mailing list
        • 2024-04-17 New Chair and Vice Chair begin their term
      • Unanimously approved

  • Goals for 2024

    • What specific goals does the TAC have for 2024?
      • Discussed at the 2023-12-13 meeting
      • Will open a discussion item on GitHub for offline conversation
  • Open discussion and next steps

    • Next TAC Meeting February 7, 2024
      • Credential Format Comparison SIG Update
"},{"location":"meetings/2024/2024-02-07/","title":"2024-02-07","text":"

Reminder

These meetings are covered by the Antitrust Policy and the Code of Conduct.

"},{"location":"meetings/2024/2024-02-07/#agenda","title":"Agenda","text":"
  • Announcements
  • Review action items from last meeting
  • Credential Format Comparison SIG Update
  • Open discussion and next steps
"},{"location":"meetings/2024/2024-02-07/#links","title":"Links","text":"
  • slides
  • recording
"},{"location":"meetings/2024/2024-02-07/#tac-voting-members","title":"TAC Voting Members","text":"
  • David Zeuthen
  • Jeremie Miller
  • Mike Varley
  • Pete Cooling
  • Stavros Kounis
  • Tracy Kuhrt
  • Wenjing Chu
"},{"location":"meetings/2024/2024-02-07/#action-items","title":"Action Items","text":"
  • Sean to work with Mirko on a blog post on the Credential Format Comparison SIG
"},{"location":"meetings/2024/2024-02-07/#meeting-minutes","title":"Meeting Minutes","text":"
  • Announcements

    • Architecture SIG meets weekly on Mondays at 11am US/Pacific (next call February 12)
    • OID4VC Due Diligence task force meets bi-weekly on Tuesdays at 5pm CET (next call February 13)
    • Safe Wallet SIG meets weekly on Tuesdays at 7am US/Pacific (next call February 13)
    • Credential Format Comparison SIG meets bi-weekly on Wednesdays at 4pm CET on alternate weeks to the TAC (next call February 14)
    • Digital Wallets and Agents Overviews SIG meets biweekly on Thursdays at 5:00pm CET on the same weeks as the TAC (next meeting February 8)
    • Please submit any code proposals using the process defined at https://github.com/openwallet-foundation/project-proposals. We will review proposals in the order submitted at a TAC meeting. If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
  • Review action items from last meeting

    • Onboard new lab
      • Create Discord channel -- completed (#multiformat-vc-ios)
      • Create GitHub repo -- ticket created
    • Open discussion item for 2024 Goals -- completed
    • Provide thoughts on the 2024 TAC Goals and upvote any items that you think has importance -- All
  • Credential Format Comparison SIG Update

  • Open discussion and next steps

    • Next TAC Meeting February 21, 2024
      • Digital Wallets and Agents Overview SIG Update
"},{"location":"meetings/2024/2024-02-21/","title":"2024-02-21","text":"

Reminder

These meetings are covered by the Antitrust Policy and the Code of Conduct.

"},{"location":"meetings/2024/2024-02-21/#agenda","title":"Agenda","text":"
  • Announcements
  • Review action items from last meeting
  • Digital Wallets and Agents Overviews SIG Update
  • Bifold Project Proposal
  • Project Promotion Process
  • Open discussion and next steps
"},{"location":"meetings/2024/2024-02-21/#links","title":"Links","text":"
  • slides
  • recording
"},{"location":"meetings/2024/2024-02-21/#tac-voting-members","title":"TAC Voting Members","text":"
  • David Zeuthen
  • Jeremie Miller
  • Mike Varley
  • Pete Cooling
  • Stavros Kounis
  • Tracy Kuhrt
  • Wenjing Chu
"},{"location":"meetings/2024/2024-02-21/#action-items","title":"Action Items","text":"
  • Create a PR against the project lifecycle to include information on transitioning through the lifecycle stages -- Tracy
  • Work with Bifold to onboard project into OWF
"},{"location":"meetings/2024/2024-02-21/#meeting-minutes","title":"Meeting Minutes","text":"
  • Announcements

    • Architecture SIG meets weekly on Mondays at 11am US/Pacific (next call February 26)
    • OID4VC Due Diligence task force meets bi-weekly on Tuesdays at 5pm CET (next call February 27)
    • Safe Wallet SIG meets weekly on Tuesdays at 7am US/Pacific (next call February 27)
    • Credential Format Comparison SIG meets bi-weekly on Wednesdays at 4pm CET on alternate weeks to the TAC (next call February 28)
    • Digital Wallets and Agents Overviews SIG meets biweekly on Thursdays at 5:00pm CET on the same weeks as the TAC (next meeting February 22)
    • Please submit any code proposals using the process defined at https://github.com/openwallet-foundation/project-proposals. We will review proposals in the order submitted at a TAC meeting. If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
  • Review action items from last meeting

    • Sean to work with Mirko on a blog post on the Credential Format Comparison SIG \u2013 in progress
  • Digital Wallets and Agents Overviews SIG Update

    • Information included in the slides on the work that is being done.
  • Bifold Project Proposal

    • RESOLVED: That the Bifold project proposal is hereby confirmed, approved, and adopted as a growth project.
      • Wenjing volunteered to be second sponsor for the project
      • Jeremie motion; Wenjing seconded; Unanimously approved
  • Project Promotion Process

    • Our current project lifecycle does not clearly outline the steps necessary for projects to progress in the lifecycle.
    • Suggested changes to the lifecycle to create a PR to update the original project proposal to include the new stage and other information relevant to meet the proposed stage\u2019s criteria.
    • Upside: This process is similar to the original project proposal process.
    • Possible Downside: This will overwrite the original proposal but might not be a concern given the history in GitHub on the file.
    • If we do a PR to the original proposal, we will need to make sure that we can have links to the previous versions that were approved.
    • We can possibly do this via the project pages by adding a new section
    • Action: Tracy to create a PR to provide details on what this will look like.
  • Open discussion and next steps

    • Next TAC Meeting March 6, 2024
      • Safe Wallet SIG Update
"},{"location":"meetings/2024/2024-03-06/","title":"2024-03-06","text":"

Reminder

These meetings are covered by the Antitrust Policy and the Code of Conduct.

"},{"location":"meetings/2024/2024-03-06/#agenda","title":"Agenda","text":"
  • Announcements
  • Review action items from last meeting
  • Safe Wallet SIG Update
  • OWF Wallet Stacks
  • Project Promotion Process
  • Open discussion and next steps
"},{"location":"meetings/2024/2024-03-06/#links","title":"Links","text":"
  • slides
  • recording
"},{"location":"meetings/2024/2024-03-06/#tac-voting-members","title":"TAC Voting Members","text":"
  • David Zeuthen
  • Jeremie Miller
  • Rolson Quadras (alternate for Mike Varley)
  • Pete Cooling
  • Stavros Kounis
  • Tracy Kuhrt
  • Wenjing Chu
"},{"location":"meetings/2024/2024-03-06/#action-items","title":"Action Items","text":"
  • Create discussion item to continue discussion on Wallet Stacks - Tracy -- completed
"},{"location":"meetings/2024/2024-03-06/#meeting-minutes","title":"Meeting Minutes","text":"
  • Announcements

    • Architecture SIG meets weekly on Mondays at 11am US/Pacific (next call March 11)
    • OID4VC Due Diligence task force meets bi-weekly on Tuesdays at 5pm CET (next call March 12)
    • Safe Wallet SIG meets weekly on Tuesdays at 7am US/Pacific (next call March 12)
    • Credential Format Comparison SIG meets bi-weekly on Wednesdays at 4pm CET on alternate weeks to the TAC (next call March 13)
    • Digital Wallets and Agents Overviews SIG meets biweekly on Thursdays at 5:00pm CET on the same weeks as the TAC (next meeting March 7)
    • Please submit any code proposals using the process defined at https://github.com/openwallet-foundation/project-proposals. We will review proposals in the order submitted at a TAC meeting. If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
    • Reminder: Elections are coming up starting March 20, 2024; we will be accepting TAC \u201cat large\u201d nominations
    • Join the OpenWallet Foundation for our 1 year anniversary webinar on March 14, 9am PDT / 1700 CET / 9:30pm IST https://zoom.us/webinar/register/WN_MiUSaLFgQFOhVdTBMtlLuA#/registration
  • Review action items from last meeting

    • Create a PR against the project lifecycle to include information on transitioning through the lifecycle stages \u2013 complete
    • Work with Bifold to onboard project into OWF \u2013 completed
  • Safe Wallet SIG Update

    • Information included in the slides on the updates.
  • OWF Wallet Stacks

    • Brian presented the idea of Wallet Stacks as outlined in the slides
    • Discussion ensued
    • A discussion item in the TAC GitHub will be created to continue discussions and feedback on the idea
  • Project Promotion Process

    • RESOLVED: That the project promotion process is hereby confirmed, approved, and adopted.
      • Moved to the next meeting
      • Request that TAC members review the PR and provide any feedback
  • Open discussion and next steps

    • Next TAC Meeting March 20 2024
"},{"location":"meetings/2024/2024-03-20/","title":"2024-03-20","text":"

Reminder

These meetings are covered by the Antitrust Policy and the Code of Conduct.

"},{"location":"meetings/2024/2024-03-20/#agenda","title":"Agenda","text":"
  • Announcements
  • Review action items from last meeting
  • Project Promotion Process
  • TAC \u201cAt Large\u201d Nomination Process and Voting Schedule
  • Open discussion and next steps
"},{"location":"meetings/2024/2024-03-20/#links","title":"Links","text":"
  • slides
  • recording
"},{"location":"meetings/2024/2024-03-20/#tac-voting-members","title":"TAC Voting Members","text":"
  • David Zeuthen
  • Jeremie Miller
  • Rolson Quadras (alternate for Mike Varley)
  • Pete Cooling
  • Stavros Kounis
  • Tracy Kuhrt
  • Wenjing Chu
"},{"location":"meetings/2024/2024-03-20/#action-items","title":"Action Items","text":"
  • Determine way to get the sample project charter more visible on the website.
"},{"location":"meetings/2024/2024-03-20/#meeting-minutes","title":"Meeting Minutes","text":"
  • Announcements

    • Architecture SIG meets weekly on Mondays at 11am US/Pacific (next call March 25)
    • OID4VC Due Diligence task force meets bi-weekly on Tuesdays at 5pm CET (next call March 26)
    • Safe Wallet SIG meets weekly on Tuesdays at 7am US/Pacific (next call March 26)
    • Credential Format Comparison SIG meets bi-weekly on Wednesdays at 4pm CET on alternate weeks to the TAC (next call March 27)
    • Digital Wallets and Agents Overviews SIG meets biweekly on Thursdays at 5:00pm CET on the same weeks as the TAC (next meeting March 21)
    • Please submit any code proposals using the process defined at https://github.com/openwallet-foundation/project-proposals. We will review proposals in the order submitted at a TAC meeting. If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
  • Review action items from last meeting

    • Create discussion item to continue discussion on Wallet Stacks - Tracy -- completed
  • Project Promotion Process

    • RESOLVED: That the project promotion process is hereby confirmed, approved, and adopted.
      • Motion - David Z; Seconded - Jeremie M
      • Unanimously approved
  • TAC \u201cAt Large\u201d Nomination Process

    • Submit nominations via a GitHub issue at 2024 \"At Large\" Nomination
    • Title of issue: [NOMINATION]: 2024 \u201cat large\u201d Name
    • Include a short bio, outline your qualifications, and provide a statement explaining why you would be a good choice for the seat
  • TAC \"At Large\" Voting Schedule

    • 2024-03-20 Nomination Period Begins
    • 2024-03-27 Noon PT Nomination Period Ends
    • 2024-03-27 Helios Voting Ballot Distributed to Existing TAC Members
    • 2024-04-02 Noon PT Voting Ends
    • 2024-04-02 Results Announced on the TAC mailing list
    • 2024-04-03 New \u201cat large\u201d representatives begin their term
  • Open discussion and next steps

    • Next TAC Meeting April 3 2024
      • Architecture SIG Q2 Update
    • Question asked about the OWF Developer Day on April 15 - should have more details early next week
    • Question asked about making it easier to find the sample project charter on the TAC website
    • Question asked about how to get sponsors for the SD-JWT JavaScript project to move to Growth - reach out to the TAC members (individually, on the #tac Discord channel, or on the TAC mailing list)
    • Question asked about how to find out what was going on in the community and how to get involved:
      • Walked therough the TAC website
      • Walked through the OpenWallet Foundation Participate page
"},{"location":"meetings/2024/2024-04-03/","title":"2024-04-03","text":"

Reminder

These meetings are covered by the Antitrust Policy and the Code of Conduct.

"},{"location":"meetings/2024/2024-04-03/#agenda","title":"Agenda","text":"
  • Announcements
  • Review action items from last meeting
  • Welcome New \u201cAt Large\u201d Representatives
  • Architecture SIG Q2 Update
  • TAC Chair/Vice Chair Nomination Process and Voting Schedule
  • Wiki Update
  • The Wallet Stack (and next steps)
  • Open discussion and next steps
"},{"location":"meetings/2024/2024-04-03/#links","title":"Links","text":"
  • slides
  • recording
"},{"location":"meetings/2024/2024-04-03/#tac-voting-members","title":"TAC Voting Members","text":"
  • David Zeuthen
  • Jaehoon (Ace) Shim
  • Mike Varley
  • Pete Cooling
  • Stavros Kounis
  • Tracy Kuhrt
  • Wenjing Chu
"},{"location":"meetings/2024/2024-04-03/#action-items","title":"Action Items","text":"
  • Create a content plan for where stuff should live and who should control the content
"},{"location":"meetings/2024/2024-04-03/#meeting-minutes","title":"Meeting Minutes","text":"
  • Announcements

    • Architecture SIG meets weekly on Mondays at 11am US/Pacific (next call April 8)
    • OID4VC Due Diligence task force meets bi-weekly on Tuesdays at 5pm CET (next call April 9)
    • Safe Wallet SIG meets weekly on Tuesdays at 7am US/Pacific (next call April 9)
    • Credential Format Comparison SIG meets bi-weekly on Wednesdays at 4pm CET on alternate weeks to the TAC (next call April 10)
    • Digital Wallets and Agents Overviews SIG meets biweekly on Thursdays at 5:00pm CET on the same weeks as the TAC (next meeting April 4)
    • Please submit any code proposals using the process defined at https://github.com/openwallet-foundation/project-proposals. We will review proposals in the order submitted at a TAC meeting. If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
    • Jorge Flores (Co-Founder & CTO of Entidad) and Jesus Torres (Co-Founder & CEO of Entidad): How an Aries digital trust ecosystem helped distribute $60M USD (& counting) to essential workers - Presenting at the Hyperledger Identity Special Interest Group on Thursday, April 4 @ 3PM UTC, 8AM PDT, 9AM MDT, 11AM EDT. Join on Zoom: https://zoom.us/j/93003523877?pwd=Q3VvMnJ1N0lSUEZSc283SmFGRk9SQT09
    • IIW Planning discussion taking place on Discord in the #iiw-planning channel
    • EIC Planning discussions taking place on Discord in the #eic-planning channel
  • Review action items from last meeting

    • Determine way to get the sample project charter more visible on the website -- completed
  • Welcome New \u201cAt Large\u201d Representatives

    • Thank you to all the nominees.
    • Welcome back, Stavros!
    • Welcome, Ace!
    • Thank you for your service, Jeremie!
  • Architecture SIG Q2 Update

    • Reviewed these slides
  • TAC Chair/Vice Chair Nomination Process

    • Only TAC voting members are eligible to run for the TAC chair and vice chair seats
    • Electing a vice chair will be held in conjunction with the chair election; the person with the second highest number of votes will serve as the vice chair
    • Submit nominations via a GitHub issue at 2024 Chair/Vice Chair Nomination
    • Title of issue: [NOMINATION]: 2024 Chair/Vice Chair Name
    • Include a short bio, outline your qualifications, and provide a statement explaining why you would be a good choice for the seat
    • See Elections for more information
  • TAC Chair/Vice Chair Voting Schedule

    • 2024-04-03 Nomination Period Begins
    • 2024-04-10 Noon PT Nomination Period Ends
    • 2024-04-10 Helios Voting Ballot Distributed to Existing TAC Members
    • 2024-04-16 Noon PT Voting Ends
    • 2024-04-16 Results Announced on the TAC mailing list
    • 2024-04-17 New Chair and Vice Chair begin their term
  • Wiki Update

    • https://wiki.openwallet.foundation
    • Discussion about content plan. Where should information live? Who is responsible for changes?
    • TAC website makes sense for things that the TAC is responsible for
    • The maintainers should be responsible for project information
    • The LF Staff is responsible for the openwallet.foundation website content
  • The Wallet Stack (and next steps)

    • Formation of a Secure Hardware SIG
    • Looking for interested parties
  • Open discussion and next steps

    • Next TAC Meeting April 17, 2024
"},{"location":"meetings/2024/2024-04-17/","title":"2024-04-17","text":"

Reminder

These meetings are covered by the Antitrust Policy and the Code of Conduct.

"},{"location":"meetings/2024/2024-04-17/#agenda","title":"Agenda","text":"
  • Announcements
  • Review action items from last meeting
  • Chair/Vice Chair Results
  • Project Proposal: React Native Kit for EUDI Wallet Reference Implementation
  • OWF Naming Policy Update
  • Content Plan
  • Open discussion and next steps
"},{"location":"meetings/2024/2024-04-17/#links","title":"Links","text":"
  • slides
  • recording
"},{"location":"meetings/2024/2024-04-17/#tac-voting-members","title":"TAC Voting Members","text":"
  • David Zeuthen
  • Jaehoon (Ace) Shim
  • Mike Varley
  • Pete Cooling
  • Stavros Kounis
  • Tracy Kuhrt
  • Wenjing Chu
"},{"location":"meetings/2024/2024-04-17/#action-items","title":"Action Items","text":"
  • Set up new lab eudi-wallet-kit-react-native
    • Discord channel
    • GitHub repo
"},{"location":"meetings/2024/2024-04-17/#meeting-minutes","title":"Meeting Minutes","text":"
  • Announcements

    • Architecture SIG meets weekly on Mondays at 11am US/Pacific (next call April 22)
    • OID4VC Due Diligence task force meets bi-weekly on Tuesdays at 5pm CET (next call April 23)
    • Safe Wallet SIG meets weekly on Tuesdays at 7am US/Pacific (next call April 23)
    • Credential Format Comparison SIG meets bi-weekly on Wednesdays at 4pm CET on alternate weeks to the TAC (next call April 24)
    • Digital Wallets and Agents Overviews SIG meets biweekly on Thursdays at 5:00pm CET on the same weeks as the TAC (next meeting April 18)
    • Please submit any code proposals using the process defined at https://github.com/openwallet-foundation/project-proposals. We will review proposals in the order submitted at a TAC meeting. If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
    • EIC Planning discussions taking place on Discord in the #eic-planning channel
    • The Hyperledger Identity SIG (ID SIG) recently hosted Jorge and Jesus from Entidad for \"How The Aries Digital Trust Ecosystem Helped Distribute $60M USD (and counting) to Essential Workers. You can check out the recording on YouTube.
    • Michel Sahli is our GAC representative
  • Review action items from last meeting

    • Create a content plan for where stuff should live and who should control the content -- in progress
  • Chair/Vice Chair Results

    • Thank you to all nominees
    • Stavros, vice chair
    • Tracy, chair
  • Project Proposal: React Native Kit for EUDI Wallet Reference Implementation

    • RESOLVED: That the React Native Kit for EUDI Wallet Reference Implementation lab proposal is hereby confirmed, approved, and adopted.
      • Stavros motion; Ace seconded; Approved unanimously by the present TAC members
  • OWF Naming Policy Update

    • Reviewed Project Naming Policy
    • Request that the community provide suggested edits and comments
    • After incoming feedback, Sean will work with the LF Staff prior to bringing back to the TAC for approval
  • Content Plan

    • Quickly reviewed Content Plan
    • Request that the community provide suggested edits and comments
    • Determine where source of truth is for certain items, like the project list
  • Open discussion and next steps

    • Next TAC Meeting May 1, 2024
"},{"location":"meetings/2024/2024-05-01/","title":"2024-05-01","text":"

Reminder

These meetings are covered by the Antitrust Policy and the Code of Conduct.

"},{"location":"meetings/2024/2024-05-01/#agenda","title":"Agenda","text":"
  • Announcements
  • Review action items from last meeting
  • Credential Format Comparison SIG Q2 Update
  • Content Plan
  • Reference Architecture contribution
  • Open discussion and next steps
"},{"location":"meetings/2024/2024-05-01/#links","title":"Links","text":"
  • slides
  • recording
"},{"location":"meetings/2024/2024-05-01/#tac-voting-members","title":"TAC Voting Members","text":"
  • David Zeuthen
  • Jaehoon (Ace) Shim
  • Rolson Quandras (alternate for Mike Varley)
  • Pete Cooling
  • Stavros Kounis
  • Tracy Kuhrt
  • Wenjing Chu
"},{"location":"meetings/2024/2024-05-01/#action-items","title":"Action Items","text":"
  • Update Content Plan PR to include links
"},{"location":"meetings/2024/2024-05-01/#meeting-minutes","title":"Meeting Minutes","text":"
  • Announcements

    • Architecture SIG meets weekly on Mondays at 11am US/Pacific (next call May 6)
    • OID4VC Due Diligence task force meets bi-weekly on Tuesdays at 5pm CET (next call May 7)
    • Safe Wallet SIG meets weekly on Tuesdays at 7am US/Pacific (next call May 7)
    • Credential Format Comparison SIG meets bi-weekly on Wednesdays at 4pm CET on alternate weeks to the TAC (next call May 8)
    • Digital Wallets and Agents Overviews SIG meets biweekly on Thursdays at 5:00pm CET on the same weeks as the TAC (next meeting May 2)
    • Please submit any code proposals using the process defined at https://github.com/openwallet-foundation/project-proposals. We will review proposals in the order submitted at a TAC meeting. If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
    • EIC Planning discussions taking place on Discord in the #eic-planning channel
  • Review action items from last meeting

    • Set up new lab eudi-wallet-kit-react-native - complete
      • Discord channel
      • GitHub repo
  • Content Plan

    • RESOLVED: That the Content Plan is hereby confirmed, approved, and adopted.
      • Wenjing motion; Rolson seconded
      • Unanimously approved by the present TAC voting members
  • Reference Architecture Contribution

    • Pull Request (Rendered version)
    • Proposed next steps:
      • Input from community - please provide comments on the PR
      • Add a heatmap that maps our current projects to the technology capabilities
    • David Z is concerned that the whitepaper may conflict with existing guidance
    • Request that a list of existing guidance be provided in the PR so that we may validate that the reference architecture whitepaper does not conflict with existing guidance
  • Open discussion and next steps

    • Next TAC Meeting May 15 2024
    • Digital Wallet and Agent Overviews SIG Update
    • OID4VC Due Diligence task force update
    • Project Proposal: Library for OpenID4BLE
"},{"location":"meetings/2024/2024-05-15/","title":"2024-05-15","text":"

Reminder

These meetings are covered by the Antitrust Policy and the Code of Conduct.

"},{"location":"meetings/2024/2024-05-15/#agenda","title":"Agenda","text":"
  • Announcements
  • Review action items from last meeting
  • Welcome new TAC member
  • Project Proposal: OpenId4BLE Library
  • Project Proposal: Trust Spanning Protocol
  • Project Annual Reviews
  • OpenID4VC Due Diligence Task Force Update
  • Open discussion and next steps
"},{"location":"meetings/2024/2024-05-15/#links","title":"Links","text":"
  • slides
  • recording
"},{"location":"meetings/2024/2024-05-15/#tac-voting-members","title":"TAC Voting Members","text":"
  • David Zeuthen
  • Jaehoon (Ace) Shim
  • Rolson Quadras
  • Stefan Kauhaus (alternate for Pete Cooling)
  • Stavros Kounis
  • Tracy Kuhrt
  • Wenjing Chu
"},{"location":"meetings/2024/2024-05-15/#action-items","title":"Action Items","text":"
  • Onboard OpenID4BLE Library lab
  • Onboard Trust Spanning Protocol lab
"},{"location":"meetings/2024/2024-05-15/#meeting-minutes","title":"Meeting Minutes","text":"
  • Announcements

    • Architecture SIG meets weekly on Mondays at 11am US/Pacific (next call June 3)
    • Safe Wallet SIG meets weekly on Tuesdays at 7am US/Pacific (next call June 4)
    • Credential Format Comparison SIG meets bi-weekly on Wednesdays at 4pm CET on alternate weeks to the TAC (next call June 5)
    • Digital Wallets and Agents Overviews SIG meets biweekly on Thursdays at 5:00pm CET on the same weeks as the TAC (next meeting May 30)
    • Please submit any code proposals using the process defined at https://github.com/openwallet-foundation/project-proposals. We will review proposals in the order submitted at a TAC meeting. If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
    • EIC Planning discussions taking place on Discord in the #eic-planning channel
  • Welcome new TAC member

    • Rolson Quadras will represent Gen Digital moving forward
    • Thank you Mike Varley for your service
  • Review action items from last meeting

    • Update Content Plan PR to include links - completed
  • Project Proposal: OpenId4BLE Library

    • Recommended that project come in at Labs stage
    • Recommended that project move to GitHub issues (to be completed in 3-6 months)
    • Recommended that project use Discord for communication instead of Slack
    • Discussed governance and diversity of maintainers
    • RESOLVED: That the OpenId4BLE Library lab proposal is hereby confirmed, approved, and adopted.
      • Stavros motioned; David seconded
      • Unanimously approved by the present TAC voting members.
  • Project Proposal: Trust Spanning Protocol

    • Discussed the need for language bindings that can be used by OWF projects. Recommendation is to implement the language bindings in conjunction with the projects that will use it to ensure correctness.
    • Research needs to be done on the license of https://github.com/dalek-cryptography/curve25519-dalek and whether an alternate implementation is needed
    • RESOLVED: That the Trust Spanning Protocol lab proposal is hereby confirmed, approved, and adopted.
      • Stavros motioned; Rolson seconded
      • Unanimously approved by the present TAC voting members.
  • Project Annual Reviews

    • RESOLVED: That the Project Annual Reviews pull request is hereby confirmed, approved, and adopted.
      • Adds template
      • Adds schedule
      • Vote moved to PR review
  • OID4VC Due Diligence Task Force Update

    • Torsten provided an update on the OID4VC Due Diligence task force and recommended closing the task force as it has accomplished its goals.
  • Open discussion and next steps

    • Next TAC Meeting May 29, 2024
      • Digital Wallet and Agent Overviews SIG Update
"},{"location":"meetings/2024/2024-05-29/","title":"2024-05-29","text":"

Reminder

These meetings are covered by the Antitrust Policy and the Code of Conduct.

"},{"location":"meetings/2024/2024-05-29/#agenda","title":"Agenda","text":"
  • Announcements
  • Review action items from last meeting
  • Project Proposal: credhub
  • Project Annual Reviews
  • Digital Wallet and Agent Overviews SIG Update
  • Open discussion and next steps
"},{"location":"meetings/2024/2024-05-29/#links","title":"Links","text":"
  • slides
  • recording
"},{"location":"meetings/2024/2024-05-29/#tac-voting-members","title":"TAC Voting Members","text":"
  • David Zeuthen
  • Jaehoon (Ace) Shim
  • Rolson Quadras
  • Pete Cooling
  • Stavros Kounis
  • Tracy Kuhrt
  • Wenjing Chu
"},{"location":"meetings/2024/2024-05-29/#action-items","title":"Action Items","text":"
  • Onboard Credhub project
    • Create Discord channel
    • Transfer repo
    • Create project page
"},{"location":"meetings/2024/2024-05-29/#meeting-minutes","title":"Meeting Minutes","text":"
  • Announcements

    • Please see the OpenWallet Foundation calendar for a list of upcoming meetings
    • Please submit any code proposals using the process defined at https://github.com/openwallet-foundation/project-proposals. We will review proposals in the order submitted at a TAC meeting. If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
    • EIC Planning discussions taking place on Discord in the #eic-planning channel
    • If you are interested in participating in the architecture SIG calls, we have a when2meet survey out there to find a new meeting time
    • EUDI Architecture Reference Framework v1.4 published
    • OpenWallet Foundation is hosting two workshops -- one for OpenID Connect for VCI and one for OpenID Connect for VP -- on June 10th and June 12th. Please be on the lookout for registration links coming soon
  • Review action items from last meeting

    • Onboard OpenID4BLE Library lab
      • Created Discord channel (#tuvali) - completed
      • Need to transfer repo (Issue #151) - in progress
      • Working on project page (PR #149) - in progress
    • Onboard Trust Spanning Protocol lab
      • Created Discord channel (#tsp) - completed
      • Need to transfer repo (Issue #150) - in progress
      • Working on project page (PR #149) - in progress
  • Project Proposal: credhub

    • RESOLVED: That the credhub lab proposal is hereby confirmed, approved, and adopted.
      • Stavros motioned; Wenjing seconded
      • Unanimously approved
  • Project Annual Reviews

    • RESOLVED: That the Project Annual Reviews pull request is hereby confirmed, approved, and adopted.
      • David Z motioned; Rolson seconded
      • Unanimously approved
  • Digital Wallet and Agent Overviews SIG Update

    • Mirko presented an update on the SIG
  • Open discussion and next steps

    • Next TAC Meeting June 12, 2024
      • SD-JWT Python Annual Review
      • SD-JWT Kotlin Annual Review
      • Safe Wallet SIG Update
"},{"location":"meetings/2024/2024-06-12/","title":"2024-06-12","text":"

Reminder

These meetings are covered by the Antitrust Policy and the Code of Conduct.

"},{"location":"meetings/2024/2024-06-12/#agenda","title":"Agenda","text":"
  • Announcements
  • Review action items from last meeting
  • Project Proposal: mdl.js
  • Project Annual Reviews
    • SD-JWT Python Annual Review
    • SD-JWT Kotlin Annual Review
  • Safe Wallet SIG Update
  • Open discussion and next steps
"},{"location":"meetings/2024/2024-06-12/#links","title":"Links","text":"
  • slides
  • recording
"},{"location":"meetings/2024/2024-06-12/#tac-voting-members","title":"TAC Voting Members","text":"
  • David Zeuthen
  • Jaehoon (Ace) Shim
  • Rolson Quadras
  • Pete Cooling
  • Stavros Kounis
  • Tracy Kuhrt
  • Wenjing Chu
"},{"location":"meetings/2024/2024-06-12/#action-items","title":"Action Items","text":"
  • Onboard mdl.js
  • Reach out to Fabian regarding new maintainership - Sean/Torsten
  • File PR against openwallet-foundation-labs/governance to update maintainership for sd-jwt-kotlin - Ace
"},{"location":"meetings/2024/2024-06-12/#meeting-minutes","title":"Meeting Minutes","text":"
  • Announcements

    • Please see the OpenWallet Foundation calendar for a list of upcoming meetings
    • Please submit any code proposals using the process defined at https://github.com/openwallet-foundation/project-proposals. We will review proposals in the order submitted at a TAC meeting. If you know of any potential projects that might be of interest to the OpenWallet Foundation, please let a staff member know so that they can follow up
    • Architecture SIG call is moving to Mondays at 8:30 AM US/Pacific starting June 17
    • Wednesday June 12 - Part 2: OpenID4VCI This webinar will give an overview of one of the technical standards that underpin EUDIW ARF: OpenID4VCI, which defines an API for the issuance of Digital Credentials. The focus will be on the technical details and timelines, and answering questions from the participants/implementers. Registration
    • Video from Monday\u2019s OpenID4VP workshop/AMA with Kristina and Oliver
  • Review action items from last meeting

    • Onboard OpenID4BLE Library lab - in progress
      • Created Discord channel (#tuvali) - completed
      • Repo created - code needs to be transferred
      • Project page available
    • Onboard Trust Spanning Protocol lab - completed
      • Created Discord channel (#tsp)
      • Repo available
      • Project page available
    • Onboard Credhub project - completed
      • Created Discord channel (#credhub)
      • Repo created
      • Project page available
  • Project Proposal: mdl.js

    • RESOLVED: That the mdl.js lab proposal is hereby confirmed, approved, and adopted.
      • Ace motioned; Pete seconded
      • Unanimously approved by the present TAC voting members
  • Project Annual Reviews

    • SD-JWT Python Annual Review
      • RESOLVED: TAC members agree to continue to sponsor the SD-JWT Python lab at its current stage
        • Wenjing motioned; Ace seconded
        • Unanimously approved by the present TAC voting members
    • SD-JWT Kotlin Annual Review: Opened issue openwallet-foundation-labs/sd-jwt-python#22 on May 30, 2024

      • Discussion around whether we should move this project to Emeritus given the statement in the README

        Quote

        Important note: This project is no longer maintained. We recommend using the eudi-lib-jvm-sdjwt-kt library instead. If you are interested in maintaining this project, please contact Fabian Hauck.

      • Ace volunteered to maintain this project going forward

  • Safe Wallet SIG Update

    • Dan Bachenheimer shared the EIC presentation on the Safe Wallet SIG
    • Brian brought up the concern of how to we \"approve\" the work that is done by the SIGs
  • Open discussion and next steps

    • Next TAC Meeting June 26, 2024
      • Discuss approval process for SIG output
"},{"location":"projects/","title":"Projects","text":"

Projects in the OpenWallet Foundation follow the project lifecycle. This page lists the active projects within the OpenWallet Foundation and their current lifecycle stage.

"},{"location":"projects/#active-projects","title":"Active Projects","text":"Approval Date Project Name Lifecycle Stage 2023-May-17 SD-JWT Kotlin Lab 2023-May-17 SD-JWT Python Lab 2023-Aug-09 Farmworker Wallet OS Lab 2023-Sep-28 VC API Lab 2023-Oct-04 Wallet Framework .NET Lab 2023-Oct-18 Identity Credential Lab 2023-Nov-01 SD-JWT JavaScript Lab 2023-Nov-15 SD-JWT Rust Lab 2023-Nov-29 SD-JWT .NET Lab 2023-Nov-29 Credo Growth 2024-Jan-24 Multiformat VC for iOS Lab 2024-Feb-21 Bifold Growth 2024-Apr-17 EUDI Wallet Kit React Native Lab 2024-May-15 Trust Spanning Protocol Lab 2024-May-15 Tuvali Lab 2024-May-29 Credhub Lab 2024-Jun-12 MDL JavaScript Lab"},{"location":"projects/bifold/","title":"Bifold","text":""},{"location":"projects/bifold/#project-description","title":"Project Description","text":"

Bifold is an open-source project designed to enhance the way we interact with digital identities, making the process both secure and user-friendly. It is based on React Native, which lets it run smoothly on different devices and platforms, such as iOS, and Android. It is a leading example of digital wallets, with a focus on making verifiable credentials (VCs) simple and convenient for everyone. Our mission is to create a collaborative community that enhances the way digital credentials are handled, making them accessible and straightforward for all.

Key Features and Benefits:

  • Unified Digital Identity Management: Emphasizing security and user-friendliness, Bifold excels in consolidating and managing digital identities across various standards like AnonCreds and W3C VC Data Model. This capability positions Bifold as a pivotal resource for secure and private handling of digital identities, accessible to all.

  • Seamless Multi-Platform Use: Thanks to its React Native architecture, Bifold delivers a smooth experience on any device, enabling users to manage their digital identities whether they are using a phone or a tablet. This cross-platform flexibility means that developers can create applications once and deploy them on both iOS and Android, ensuring a consistent and accessible user experience.

  • Community-Driven Development: Bifold is more than a tool; it's a community initiative aimed at fostering collaboration and sharing innovations. By bringing together diverse groups, from organizations to individuals, Bifold encourages the pooling of resources and knowledge to facilitate the broader adoption and understanding of verifiable credentials.

  • Widespread Adoption and Trust: With a growing list of users around the globe, including governmental bodies in Canada and teams in Brazil, Bifold has proven its reliability and relevance. Its international use showcases the platform's adaptability to various needs and its role in advancing digital identity management on a global scale.

  • Adaptability to Diverse Needs: Bifold's design caters to a wide range of project types and complexities, offering tailored solutions for managing digital identities. This adaptability ensures that users can streamline their processes related to verifiable credentials, improving efficiency and simplification in digital identity initiatives.

"},{"location":"projects/bifold/#source-repositories","title":"Source Repositories","text":"
  • openwallet-foundation/bifold-wallet
  • openwallet-foundation/mobile-wallet-test-harness
"},{"location":"projects/bifold/#chat-channel","title":"Chat Channel","text":"
  • #bifold on the OpenWallet Foundation Discord server
"},{"location":"projects/bifold/#history","title":"History","text":"
  • Proposal to enter Growth stage -- Approved by TAC on 2024-02-21
"},{"location":"projects/credhub/","title":"Credhub","text":""},{"location":"projects/credhub/#project-description","title":"Project Description","text":"

When talking about wallets for natural persons, a lot of people think that a smartphone based wallet is the only way to go. The user should feel the security and privacy by being independent from an external provider. But we are forgetting that online based services have a great user experience in daily life: - As a user I can use multiple clients where my data is synced, we do not have to care about backups or data recovery. - As a developer I can implement the business logic into the cloud and only need the rendering on the client side.

Yes, when I am offline, I do not have access to my data anymore. But beside that the user experience is great!

The credhub project is a typescript based monorepo, using nx to manage multiple components. Compared to other approaches, it also comes with an issuer and verifier service to issue and verify credentials.

"},{"location":"projects/credhub/#clients","title":"Clients","text":"

There are two clients that can be used to interact with a cloud wallet - a PWA based on Angular - a Chrome Browser Extension based on Angular

While the PWA is using the camera to scan QR codes, the browser extension is scanning the opened taps for QR codes and is able to show a little button next to the QR code to interact with the wallet. This approach was inspired by password managers like 1Password. In the daily use, People do not want to take out their smartphone to scan a QR code, they want an easy one click solution.

By implementing the whole business logic in the cloud, the client is only responsible for the rendering. Therefore building new clients in other programming languages is easy by using the OpenAPI endpoints. For authentication the OpenID Connect protocol is used, the project is using the Keycloak server for that.

"},{"location":"projects/credhub/#issuer-and-verifier","title":"Issuer and Verifier","text":"

Both relying parties are implemented as separate services, each of them comes with a web client for demo purposes. Further integration like webhooks or other services can be implemented in the future. The authentication is done by using the OpenID Connect protocol.

"},{"location":"projects/credhub/#modular-approach","title":"Modular approach","text":"

The usage of NX allows reusable components with a modular approach. Each backend implementation supports low security key management by storing the keys in the filesystem or the database, or the integration with Hashicorp Vault for high security key management. Other implementations are possible.

"},{"location":"projects/credhub/#identity-stack","title":"Identity Stack","text":"

By validating existing SSI frameworks like Credo or Veramo, this project should primary focus on the architecture reference framework of the EU. Therefore other credential formats, transport protocols or key managements like multiple DIDs methods are not supported.

Credential Profile:

  • Credential Format: SD-JWT-VC
  • Key Management (issuer): VC-ISSUER Meta data, DID, X509
  • Key Management (holder): CNF (json web key)
  • Transport Protocol: OID4VC
  • Signature Algorithm: P-256
  • Status Management: OAUTH Status List
"},{"location":"projects/credhub/#source-repositories","title":"Source Repositories","text":"
  • openwallet-foundation-labs/credhub
"},{"location":"projects/credhub/#chat-channel","title":"Chat Channel","text":"
  • #credhub on the OpenWallet Foundation Discord server
"},{"location":"projects/credhub/#history","title":"History","text":"
  • Proposal to enter Labs -- Approved by TAC on 2024-05-29
"},{"location":"projects/credo-ts/","title":"Credo","text":""},{"location":"projects/credo-ts/#project-description","title":"Project Description","text":"

Credo has evolved significantly since its inception as a Hyperledger Aries project. Initially, it heavily relied on Hyperledger standards such as DIDComm, Indy, and AnonCreds. However, with advancements in verifiable credential technology and the emergence of new standards, the framework underwent multiple refactoring and modularization processes to maintain interoperability.

This allowed for the inclusion of non-Hyperledger standards like W3C Verifiable Credentials with Data Integrity Proofs, DIF Presentation Exchange, OpenID4VC, and SD-JWT integration. As industry requirements shifted towards greater modularity, it became apparent that a unified framework may be better.

The future direction for Credo involves adopting a compartmentalized approach consisting of single-purpose libraries designed to work together seamlessly, building on what is already out there. This transition will take considerable effort and will, therefore, be gradual.

In order to expand the framework's support for standards beyond the Hyperledger ecosystem, a reassessment of its governance was necessary. The OpenWallet Foundation (OWF) was chosen as a steward due to its commitment to promoting interoperability without directly developing or maintaining standard protocols.

"},{"location":"projects/credo-ts/#source-repositories","title":"Source Repositories","text":"
  • openwallet-foundation/credo-ts
  • openwallet-foundation/credo-ts-ext
  • openwallet-foundation/credo-ts-docs
"},{"location":"projects/credo-ts/#chat-channel","title":"Chat Channel","text":"
  • #credo on the OpenWallet Foundation Discord server
"},{"location":"projects/credo-ts/#history","title":"History","text":"
  • Proposal to enter Growth stage -- Approved by TAC on 2023-11-29
"},{"location":"projects/eudi-wallet-kit-react-native/","title":"EUDI Wallet Kit React Native","text":""},{"location":"projects/eudi-wallet-kit-react-native/#project-description","title":"Project Description","text":"

The project is a cross-platform React Native wrapper for EUDI Wallet reference implementation.

It allows building cross-platform Mobile Wallet applications compliant with Electronic Identification, Authentication and Trust Services (eIDAS) Regulation and EUDI Architecture and Reference Framework (ARF) and based on reference implementations from EUDI (Android and iOS correspondingly).

"},{"location":"projects/eudi-wallet-kit-react-native/#source-repositories","title":"Source Repositories","text":"
  • openwallet-foundation-labs/eudi-wallet-kit-react-native
"},{"location":"projects/eudi-wallet-kit-react-native/#chat-channel","title":"Chat Channel","text":"
  • #eudi-wallet-kit-react-native on the OpenWallet Foundation Discord server
"},{"location":"projects/eudi-wallet-kit-react-native/#history","title":"History","text":"
  • Proposal to enter Labs -- Approved by TAC on 2024-04-17
"},{"location":"projects/fwos/","title":"Farmworker Wallet OS","text":""},{"location":"projects/fwos/#project-description","title":"Project Description","text":"

The Farmworker Wallet OS project is a community of contribution led by Entidad and the United Farm Workers Foundation (UFWF) with the goal of furthering the adoption of an open, secure, interoperable digital wallet engine that makes it easier for farmworker communities to access an ecosystem of life-altering social and human services.

Farmworkers are the backbone of global food supply chains, yet they remain one of the most underserved segments of our population. Governments around the world deemed them \u2018Essential\u2019 during the recent pandemic. While services and programs exist to help, it\u2019s challenging and costly for organizations that provide them to securely collect and verify the information needed to prove applicant eligibility claims. As a result, most farmworkers forego services and resources they need, even though they\u2019re eligible for them.

Over the last three years, Entidad and the UFW Foundation have been exploring digital trust technologies to solve this problem. We\u2019ve developed PrepareseTM, a digital infrastructure solution that lets farmworker organizations securely reuse verified farmworker information, eliminating the need for repetitive collection. The solution layers didcomm, wallet, decentralized identifiers, and verifiable credential technologies with a low-code application development platform, Mendix.

Mendix has been a key component in making the PrepareseTM solution possible. Low-code software development has been growing in popularity and bringing new audiences to the practice.\u202fMendix, one of the more popular platforms with over 300K active developers and 50M users, has enabled Entidad and the UFW Foundation to develop, launch, and maintain enterprise-grade digital trust enabled solutions that solve real world problems.

We\u2019ve built two products, using this technology. For organizations we\u2019ve built Preparese PlatformTM, it allows them to quickly develop and launch digital trust enabled services and programs. For farmworkers, we\u2019ve developed Preparese MobileTM which combines a verifiable digital profile with a suite of tools that simplify interactions with organizations on the platform.

The Preparese PlatformTM is being used by 9 organizations and has 5 digital services in production. The most recent service launched is being used to process and distribute $80 million in one-time relief payments to over 125,000 workers, under the United States Department of Agriculture\u2019s Farm and Food Workers Relief Program (FFWR).

The second product, Preparese MobileTM, is designed around the unique needs of farmworkers. We\u2019ve developed a react native mobile app that lets farmworkers store, manage, and exchange their verified information. Engagement with organizations is made easier with DIDComm-based communication capabilities such as text and video chat.

One of the cornerstone technologies of the solution is an interoperable Mendix enabled digital wallet. The wallet components need to be able to engage with various non-profit, government, and philanthropic sources, each with their own technology stacks. For this reason, interoperability and working with open standard frameworks has been a priority. The project team members have participated in TrustOverIP Foundation, Hyperledger Aries JS Working Group, and various other communities, including DID Communication Working Group and OpenWallet Foundation of late, to ensure we adhere to best practices and standards.

While currently focused on farmworkers, the Mendix digital wallet engine can be used to help others. There are many other underserved communities that could benefit greatly from the privacy, accessibility, and security digital wallets can provide. With this social impact purpose in mind and spirit of further collaboration, Entidad and the UFW Foundation propose to open source the digital wallet engine used in their PrepareseTM solution. By making these resources available, we hope to facilitate a wide variety of social impact.

Additionally, the project allows us to bridge and advance the interest of both the OpenWallet Foundation and Mendix communities. By collaborating with the Mendix community, we not only have the ability to grow the number of digital trust technology practitioners, we also tap into a community with an established customer base. By making digital wallets components that can be easily integrated into their existing solutions, the project can drive further adoption and usage of interoperable, secure and privacy preserving digital wallets.

"},{"location":"projects/fwos/#origin-history","title":"Origin & History","text":"

The origins of the Farmworker Wallet OS project align with those of Entidad. What began as a volunteering effort by three college friends, was formalized in 2018 with the founding of Entidad as a public benefit corporation. We have primarily been working with leading farm worker-serving organizations to develop technology that leverages growing digital literacy in their communities to scale their impact.

The first digital service launched supported the UFW Foundation\u2019s emergency relief efforts during the height of the COVID-19 pandemic. The solution was used to plan, manage and operate over 500 in-person community events where over $15 million in resources were distributed to over 40K families. Additionally, it has allowed us to better understand the unique challenges of building for underserved communities and why interoperable, secure, and privacy preserving technologies are key to addressing these challenges.\u202f

You can read more about our journey on our blog.

"},{"location":"projects/fwos/#external-dependencies","title":"External Dependencies","text":"

Mendix is a low-code application platform provider so its terms of service cover usage of Mendix services and resources by Mendix developers (organizations and/or individual contributors). The Application model for a standards compliant wallet engine will be the primary focus for the contributors of this project. The Mendix terms of service do protect the IP rights to these App models in Section 3 with reference to \"Customer Data\" definition in section 17.

There are design-time and runtime aspects of app development but one of the great things about this tooling is that there is clean separation between the two.

The following captures the developer's \"design-time\" perspective. We hope that the diagram helps to clarify the software components that would fall under the scope of this OWF project and distinguishes PrepareseTM as an example of a closed (proprietary) application that embeds core Farmworker WalletOS components. We plan on documenting a similar diagram to aid in understanding the \"runtime\" perspective soon.

  1. Mendix Studio Pro v9.24.4 (integrated developer environment)
  2. Eclipse Temurin JDK 11 (x64)
  3. Mendix Native Template v7.0.1
  4. React Native v0.70.7
  5. Hyperledger / Aries-Framework-Javascript v0.4.0
  6. Development instance of an Aries Mediator Service
  7. Development instance of an Aries Cloud Agent
"},{"location":"projects/fwos/#infrastructure","title":"Infrastructure","text":"

The Farmworker Wallet OS will be organized and published as a suite of software modules that can be imported into any existing Mendix app code repository. The Mendix software modules effectively serve as a digital wallet SDK that can be embedded into any Mendix application to enhance the user experience. The code repository for this project is itself a Mendix app repository and as such can be executed locally on any supported developer workstation.

The initial version of the digital wallet SDK is being built on top of Aries Framework Javascript, an open-source framework maintained by the Hyperledger Aries developer community helping to foster participation with the Aries digital trust ecosystem. Over time, the digital wallet SDK will be extended to support other digital trust open standards such as OpenID for Verifiable Credentials (OID4VC).

"},{"location":"projects/fwos/#source-repositories","title":"Source Repositories","text":"
  • openwallet-foundation-labs/fwos-demo-app
  • openwallet-foundation-labs/fwos-native-template
"},{"location":"projects/fwos/#chat-channel","title":"Chat Channel","text":"
  • #fwos on the OpenWallet Foundation Discord server
"},{"location":"projects/fwos/#history","title":"History","text":"
  • Proposal to enter Labs -- Approved by TAC on 2023-08-09
"},{"location":"projects/identity-credential/","title":"Identity Credential","text":""},{"location":"projects/identity-credential/#project-description","title":"Project Description","text":"

Libraries and reference applications for working with real-world identity.

The initial focus for this work was mdoc/mDL according to ISO/IEC 18013-5:2021 and related standards (mainly ISO 23220 series and ISO 18013-7) on Android. Current focus includes other credential formats and operating environments.

"},{"location":"projects/identity-credential/#libraries","title":"Libraries","text":"

The project includes two libraries written in Java and Kotlin. The first is identity which provides the core building blocks and which can also be used on server-side environments. The other is identity-android which provides Android-specific extensions to the former. It is designed to run on Android (API 24 or later) and will take advantage of Android-specific features including hardware-backed Keystore, NFC, Bluetooth Low Energy, and so on.

The libraries are intended to be used by Wallet Applications (mobile applications on the credential holder's device), Reader Applications (applications operated on device controlled by the verifier), and Issuance Systems (applications operated by the credential issuer or their agent). They provide the following building blocks

  • A light-weight Secure Area abstraction for hardware-backed keystore
    • Applications can create hardware-backed Elliptic Curve Cryptography keys which can be used for creating Signatures or performing Key Agreement. Each key will have an attestation which can be used to prove to Relying Parties (such as a credential issuer) that the private part of the key only exists in a Secure Area.
    • The identity-android library includes an implementation based on Android Keystore with support for requiring user authentication (biometric or lock-screen knowledge factor, e.g. system PIN) for unlocking the key and also can use StrongBox if available on the device. This is appropriate to use in Android applications implementing ISO/IEC 18013-5:2021 for storing DeviceKey.
    • The identity library includes an implementation backed by BouncyCastle with support for passphrase-protected keys. This isn't suitable for use in Mobile Applications as its not backed by Secure Hardware.
    • Applications can supply their own Secure Area implementations for e.g. externally attached dongles, cloud based HSMs, or whatever the issuer deems appropriate to protect key material associated with their credential.
  • A Credential Store for storage of one or more Credentials
    • Each Credential has a Credential Key which can be used by the issuer to bind a credential to a specific device which is useful when issuing updates or refreshing a credential.
    • Additionally, each Credential has one or more Authentication Keys which can be endorsed by the issuer and used at presentation time.
    • Finally, namespaced data and arbitrary key/value pairs can be stored in a Credential which can be used for credential data and claims. This data is stored encrypted at rest.
  • Data structures and code for provisioning of mdoc/mDLs
    • This code can can be used both on the device and issuer side. No networking protocol is defined, the application has to define its own.
  • Parsers and generators for all data structures used in ISO/IEC 18013-5:2021 presentations, including DeviceResponse, DeviceRequest, MobileSecurityObject and many other CBOR data structures.
  • An implementation of the ISO/IEC 18013-5:2021 presentation flows including QR engagement, NFC engagement (both static and negotiated), device retrieval (BLE, Wifi Aware, and NFC)
"},{"location":"projects/identity-credential/#wallet-and-reader-android-applications","title":"Wallet and Reader Android applications","text":"

This repository also contains two Android applications using this library in the appholder and appverifier modules. The Wallet application is a simple self-contained application which allows creating a number of mdoc credentials using four different mdoc Document Types:

  • org.iso.18013.5.1.mDL: Mobile Driving License
  • org.micov.1: mdoc for eHealth (link)
  • nl.rdw.mekb.1: mdoc for Vehicle Registration (link)
  • eu.europa.ec.eudiw.pid.1: mdoc for Personal Identification

and their associated mdoc name spaces. The first one is defined in ISO/IEC 18013-5:2021 and the other three have been used at mdoc/mDL test events organized by participants of the ISO/IEC JTC1 SC17 WG10 working group.

"},{"location":"projects/identity-credential/#iso-18013-7-reader-website","title":"ISO 18013-7 Reader Website","text":"

The wwwverifier module contains the source code for a website acting as an mdoc reader according to the latest ISO 18013-7 working draft (as of Sep 2023) and it's implementing the so-called REST API. There is currently a test instance of this application available at https://mdoc-reader-external.uc.r.appspot.com/. The Wallet Android application also has support for the REST API and registers on Android for the mdoc:// URI scheme. This can be tested end-to-end by going to the reader website (URL above) and clicking on one of the \"Request\" buttons, and then hitting the mdoc:// link presented on the site. This will cause the browser to invoke the Wallet app which will then connect to the reader and send the credential after user consent.

"},{"location":"projects/identity-credential/#source-repositories","title":"Source Repositories","text":"
  • openwallet-foundation-labs/identity-credential
"},{"location":"projects/identity-credential/#chat-channel","title":"Chat Channel","text":"
  • #identity-credential on the OpenWallet Foundation Discord server
"},{"location":"projects/identity-credential/#history","title":"History","text":"
  • Proposal to enter Labs -- Approved by TAC on 2023-10-18
"},{"location":"projects/mdl-js/","title":"MDL JavaScript","text":""},{"location":"projects/mdl-js/#project-description","title":"Project Description","text":"

This is a Typescript(Javascript) implementation of the ISO 18013-5:2021 (MDL) specification. This project aims to provide a platform agnostic implementation of the MDL specification.

To provide MDL features to Biggest Wallet SDKs like Credo or Veramo, the direction of the project will be:

Provide a platform agnostic implementation of the MDL specification - Bring your own crypto - Modular approach - Provide platform specific helper implementations for developers to use easily

"},{"location":"projects/mdl-js/#source-repositories","title":"Source Repositories","text":"
  • openwallet-foundation-labs/mdl-js
"},{"location":"projects/mdl-js/#chat-channel","title":"Chat Channel","text":"
  • #mdl-js on the OpenWallet Foundation Discord server
"},{"location":"projects/mdl-js/#history","title":"History","text":"
  • Proposal to enter Labs -- Approved by TAC on 2024-06-12
"},{"location":"projects/multiformat-vc-ios/","title":"Multiformat VC for iOS","text":""},{"location":"projects/multiformat-vc-ios/#project-description","title":"Project Description","text":"

Pure Swift package for creating Verifiable Credentials (VCs) in multiple formats

  • SD-JWT VC: Selective Disclosure JWT based Verifiable Credentials - using the specification defined at https://datatracker.ietf.org/doc/draft-ietf-oauth-sd-jwt-vc/
  • VC JWT: Verifiable Credentials as JWT - using the format defined at JWT VC Presentation Profile https://identity.foundation/jwt-vc-presentation-profile/

Support for multiple data types for disclosed values including

  • String
  • Int
  • Boolean
  • Array of Strings - [String]
  • Dictionary of String keys and String values - [String:String]

This project is a contribution of the work done at Ping Identity to test and establish interoperability of the various formats representing the Verifiable Credentials Data Model https://www.w3.org/TR/vc-data-model/. Along with the SD-JWT VC and JWT VC formats described above, Ping Identity has also participated in the interoperability event for OpenID4VP to present a VC JWT. That code will also be released as a part of this project.

"},{"location":"projects/multiformat-vc-ios/#source-repositories","title":"Source Repositories","text":"

openwallet-foundation-labs/multiformat-vc-ios

"},{"location":"projects/multiformat-vc-ios/#chat-channel","title":"Chat Channel","text":"
  • #multiformat-vc-ios on the OpenWallet Foundation Discord server
"},{"location":"projects/multiformat-vc-ios/#history","title":"History","text":"
  • Proposal to enter Labs -- Approved by TAC on 2024-01-24
"},{"location":"projects/sd-jwt-dotnet/","title":"SD-JWT .NET","text":""},{"location":"projects/sd-jwt-dotnet/#project-description","title":"Project Description","text":"

A .NET implementation of the Selective Disclosure for JWTs (SD-JWT) specification.

"},{"location":"projects/sd-jwt-dotnet/#source-repositories","title":"Source Repositories","text":"
  • openwallet-foundation-labs/sd-jwt-dotnet
"},{"location":"projects/sd-jwt-dotnet/#chat-channel","title":"Chat Channel","text":"
  • #sd-jwt-dotnet on the OpenWallet Foundation Discord server
"},{"location":"projects/sd-jwt-dotnet/#history","title":"History","text":"
  • Proposal to enter Labs -- Approved by TAC on 2023-11-29
"},{"location":"projects/sd-jwt-js/","title":"SD-JWT JavaScript","text":""},{"location":"projects/sd-jwt-js/#project-description","title":"Project Description","text":"

A JavaScript implementation of the Selective Disclosure for JWTs (SD-JWT) specification.

"},{"location":"projects/sd-jwt-js/#source-repositories","title":"Source Repositories","text":"
  • openwallet-foundation-labs/sd-jwt-js
"},{"location":"projects/sd-jwt-js/#chat-channel","title":"Chat Channel","text":"
  • #sd-jwt-js on the OpenWallet Foundation Discord server
"},{"location":"projects/sd-jwt-js/#history","title":"History","text":"
  • Proposal to enter Labs -- Approved by TAC on 2023-11-01
"},{"location":"projects/sd-jwt-kotlin/","title":"SD-JWT Kotlin","text":""},{"location":"projects/sd-jwt-kotlin/#project-description","title":"Project Description","text":"

A Kotlin implementation of the Selective Disclosure for JWTs (SD-JWT) specification.

"},{"location":"projects/sd-jwt-kotlin/#source-repositories","title":"Source Repositories","text":"
  • openwallet-foundation-labs/sd-jwt-kotlin
"},{"location":"projects/sd-jwt-kotlin/#chat-channel","title":"Chat Channel","text":"
  • #sd-jwt-kotlin on the OpenWallet Foundation Discord server
"},{"location":"projects/sd-jwt-kotlin/#history","title":"History","text":"
  • Proposal to enter Labs -- Approved by TAC on 2023-05-17
"},{"location":"projects/sd-jwt-python/","title":"SD-JWT Python","text":""},{"location":"projects/sd-jwt-python/#project-description","title":"Project Description","text":"

This is the reference implementation of the IETF SD-JWT specification maintained by the editors of the specification together with other contributors. It is written in Python.

"},{"location":"projects/sd-jwt-python/#source-repositories","title":"Source Repositories","text":"
  • openwallet-foundation-labs/sd-jwt-python
"},{"location":"projects/sd-jwt-python/#chat-channel","title":"Chat Channel","text":"
  • #sd-jwt-python on the OpenWallet Foundation Discord server
"},{"location":"projects/sd-jwt-python/#history","title":"History","text":"
  • Proposal to enter Labs -- Approved by TAC on 2023-05-17
"},{"location":"projects/sd-jwt-rust/","title":"SD-JWT Rust","text":""},{"location":"projects/sd-jwt-rust/#project-description","title":"Project Description","text":"

A Rust implementation of the Selective Disclosure for JWTs (SD-JWT) specification.

"},{"location":"projects/sd-jwt-rust/#source-repositories","title":"Source Repositories","text":"
  • openwallet-foundation-labs/sd-jwt-rust
"},{"location":"projects/sd-jwt-rust/#chat-channel","title":"Chat Channel","text":"
  • #sd-jwt-rust on the OpenWallet Foundation Discord server
"},{"location":"projects/sd-jwt-rust/#history","title":"History","text":"
  • Proposal to enter Labs -- Approved by TAC on 2023-11-15
"},{"location":"projects/tsp/","title":"Trust Spanning Protocol","text":""},{"location":"projects/tsp/#project-description","title":"Project Description","text":"

This project is an early impementation of the draft Trust Spanning Protocol (TSP).

According to the above referenced specification, \"The Trust Spanning Protocol (TSP) facilitates secure communication between endpoints with potentially different identifier types, using message-based exchanges. As long as these endpoints use identifiers based on public key cryptography (PKC) with a verifiable trust root, TSP ensures their messages are authentic and, if optionally chosen, confidential. Moreover, it presents various privacy protection measures against metadata-based correlation exploitations. These attributes of TSP together allow endpoints to form authentic relationships rooted in their respective verifiable identifiers (VIDs), viewing TSP messages as virtual channels for trustworthy communication.\"

A shorter introduction of TSP can be found in this blog post.

This project's current code includes a Rust implementation of all TSP features. We also plan to incorporate/develop related features such as additional Verifiable Identifier types, additional transport layer mechanisms, different language bindings as needed and integration modules needed to be compatible with other OpenWallet projects.

In addition, we may add and welcome trust task or application specific extensions.

"},{"location":"projects/tsp/#source-repositories","title":"Source Repositories","text":"
  • openwallet-foundation-labs/tsp
"},{"location":"projects/tsp/#chat-channel","title":"Chat Channel","text":"
  • #tsp on the OpenWallet Foundation Discord server
"},{"location":"projects/tsp/#history","title":"History","text":"
  • Proposal to enter Labs -- Approved by TAC on 2024-05-15
"},{"location":"projects/tuvali/","title":"Tuvali","text":""},{"location":"projects/tuvali/#project-description","title":"Project Description","text":"

A library which implements the OpenID4BLE specification for Android and IOS. It's written in Kotlin and Swift.

"},{"location":"projects/tuvali/#source-repositories","title":"Source Repositories","text":"
  • openwallet-foundation-labs/tuvali
"},{"location":"projects/tuvali/#chat-channel","title":"Chat Channel","text":"
  • #tuvali on the OpenWallet Foundation Discord server
"},{"location":"projects/tuvali/#history","title":"History","text":"
  • Proposal to enter Labs -- Approved by TAC on 2024-05-15
"},{"location":"projects/vc-api/","title":"VC API","text":""},{"location":"projects/vc-api/#project-description","title":"Project Description","text":"

The VC API is specification for a set of APIs for VC lifecycle management (https://w3c-ccg.github.io/vc-api/). This includes operations such as credential issuance, verification, and exchange. It is a W3C CCG work item and, as of the submission of this proposal, it is in \u201cdraft community report\u201d status.

The VC API\u2019s design is informed by use cases across a range of domains. Several of these use cases are collected in a working group note (https://w3c-ccg.github.io/vc-api-use-cases/).

This project is an implementation of the VC API. The implementation aims to enable organizations and individuals to effortlessly conduct SSI operations over HTTP without requiring technical expertise, making it seamless to integrate into existing projects.

"},{"location":"projects/vc-api/#source-repositories","title":"Source Repositories","text":"
  • openwallet-foundation-labs/vc-api
"},{"location":"projects/vc-api/#chat-channel","title":"Chat Channel","text":"
  • #vc-api on the OpenWallet Foundation Discord server
"},{"location":"projects/vc-api/#history","title":"History","text":"
  • Proposal to enter Labs -- Approved by TAC on 2023-09-28
"},{"location":"projects/wallet-framework-dotnet/","title":"Wallet Framework .NET","text":""},{"location":"projects/wallet-framework-dotnet/#project-description","title":"Project Description","text":"

The wallet-framework-dotnet is a framework designed for .NET, focusing on providing a multi-platform wallet framework. Initially a part of the Hyperledger Aries project (Aries Framework .NET), this initiative has now branched out to cater to a broader audience. The primary aim is to create a multiprotocol wallet framework enabling implementations of OpenID4VC and SD-JWT VC, in accordance to the European Identity Wallet initiative's objectives.

Currently, the framework supports DidComm v1 and AnonCreds. There is an active intention to extend support for other promising protocols, notably DidComm v2, to ensure the framework remains at the forefront of digital identity solutions.

Furthermore, the team is considering the development of SD-JWT credentials as a standalone library. This might transition into a separate project proposal in the future, underscoring the commitment to modular and reusable components in the digital identity space.

"},{"location":"projects/wallet-framework-dotnet/#source-repositories","title":"Source Repositories","text":"
  • openwallet-foundation-labs/wallet-framework-dotnet
"},{"location":"projects/wallet-framework-dotnet/#chat-channel","title":"Chat Channel","text":"
  • #wallet-framework-dotnet on the OpenWallet Foundation Discord server
"},{"location":"projects/wallet-framework-dotnet/#history","title":"History","text":"
  • Proposal to enter Labs -- Approved by TAC on 2023-10-04
"},{"location":"projects/dashboards/","title":"OpenWallet Foundation Dashboards","text":"
  • OWF Dashboard

    See the dashboard for repositories in the OpenWallet Foundation GitHub Organization.

  • Labs Dashboard

    See the dashboard for repositories in the OpenWallet Foundation Labs GitHub Organization.

"},{"location":"projects/dashboards/labs/","title":"openwallet-foundation-labs Dashboard","text":"Repo License Last Commit Commits Issues Pull Requests OpenSSF Scorecard Stars Forks Watchers .github credhub eudi-wallet-kit-react-native farmworker-wallet-os governance identity-credential multiformat-vc-ios sd-jwt-dotnet sd-jwt-js sd-jwt-kotlin sd-jwt-python sd-jwt-rust tsp vc-api wallet-framework-dotnet"},{"location":"projects/dashboards/owf/","title":"openwallet-foundation Dashboard","text":"Repo License Last Commit Commits Issues Pull Requests OpenSSF Scorecard Stars Forks Watchers .github architecture-sig bifold-wallet credential-format-comparison-sig credo-ts credo-ts-docs credo-ts-ext digital-wallet-and-agent-overviews-sig governance mobile-wallet-test-harness mobile-wallet-test-harness2 OID4VC-due-diligence-tf project-proposals safe-wallet-sig tac"},{"location":"projects/reviews/0000-template-annual/","title":"YYYY PROJECT NAME","text":"

Info

Copy this template to the subdirectory for the current year and name the file YYYY-project-name-annual.md (e.g., 2024-amazingproj-annual.md). Update the title above to replace YYYY with the year of the annual review and PROJECT NAME with the name of the project. Update the index.md file in the current year to include a link to the markdown file. These blocks are instructions. Please remove when section has been completed.

"},{"location":"projects/reviews/0000-template-annual/#project-health","title":"Project Health","text":"

Info

Include information about your project's contributions and activity. You can find information within GitHub by looking at the Insights tab. We will be looking for signs of consistent or increasing contribution activity. Please feel free to add commentary to add color to this information.

"},{"location":"projects/reviews/0000-template-annual/#maintainer-diversity","title":"Maintainer Diversity","text":"

Info

How many maintainers do you have, and which organisations are they from? How has the maintainers and diversity of your maintainers changed in the past year? Has the number of active maintainers increased/decreased? Has the diversity of maintainers increased/decreased? Please include a link to your existing MAINTAINERS file and the MAINTAINERS file from last year (if appropriate). This is a good opportunity to ensure that your MAINTAINERS file is up to date and to retire any maintainers.

"},{"location":"projects/reviews/0000-template-annual/#project-adoption","title":"Project Adoption","text":"

Info

What do you know about adoption, and how has this changed since your last review or since being accepted into OpenWallet Foundation? If you can list companies that are adopters of your project, please do so. Feel free to link to an existing ADOPTERS file if appropriate.

"},{"location":"projects/reviews/0000-template-annual/#goals","title":"Goals","text":""},{"location":"projects/reviews/0000-template-annual/#performance-against-prior-goals","title":"Performance Against Prior Goals","text":"

Info

Include information about the goals that you previously set for the project in the last review or since the project proposal has been approved. How has the project performed against these goals? If your goals changed from your previous annual report, let us know what changed and why. If you have not achieved the goals that you set out, that is okay. We want to know what you have accomplished and what challenges the project is having in meeting the goals.

"},{"location":"projects/reviews/0000-template-annual/#next-years-goals","title":"Next Year's Goals","text":"

Info

What are the goals for the next year of the project? The goals should list what you want to achieve, not just what you know you can achieve. Feel free to include stretch goals and things that you are looking to explore in the next year. For example, are you working on major new features? Or are you concentrating on adoption, community growth, or documentation?

"},{"location":"projects/reviews/0000-template-annual/#help-required","title":"Help Required","text":"

Info

How can the OpenWallet Foundation or the TAC help you achieve your upcoming goals?

"},{"location":"projects/reviews/0000-template-annual/#project-lifecycle-stage-recommendation","title":"Project Lifecycle Stage Recommendation","text":"

Info

What stage do you think the project should be? If you you think that your project meets the criteria for another stage, please explain why.

"},{"location":"projects/reviews/2024/","title":"2024 Project Annual Reviews","text":"

Projects must provide an annual review to the TAC to ensure that the project is still active and in the correct lifecycle stage. The following calendar provides the timing for when these reviews are required to be presented to the TAC:

Project Stage Date Accepted 2024 Review SD-JWT Python Labs May 27, 2023 Jun 12, 2024 SD-JWT Kotlin Labs May 27, 2023 Jun 12, 2024 Farmworker Wallet OS Labs Aug 9, 2023 Aug 21, 2024 VC-API Labs Sep 28, 2023 Oct 2, 2024 Wallet Framework .NET Labs Oct 4, 2023 Oct 16, 2024 Android Identity Library Labs Oct 18, 2023 Oct 30, 2024 SD-JWT JavaScript Labs Nov 1, 2023 Nov 13, 2024 SD-JWT Rust Labs Nov 15, 2023 Nov 27, 2024 Credo Growth Nov 29, 2023 Dec 11, 2024 SD-JWT .NET Labs Nov 29, 2023 Dec 11, 2024"},{"location":"projects/reviews/2024/2024-sd-jwt-python-annual/","title":"2024 sd-jwt-python (SD-JWT Reference Implementation)","text":""},{"location":"projects/reviews/2024/2024-sd-jwt-python-annual/#project-health","title":"Project Health","text":"

The main focus of this project is to provide a reference implementation for the IETF SD-JWT draft. As such, the code has reflected the developments in the specification over the last year and is up to date with the latest version of the draft. Since the draft is approaching a stable state (and hopefully a final RFC soon-ish), no drastic changes are expected in the codebase.

"},{"location":"projects/reviews/2024/2024-sd-jwt-python-annual/#maintainer-diversity","title":"Maintainer Diversity","text":"

As before, the project is maintained by a single maintainer, an editor of the SD-JWT draft. Two developers have contributed code, one editor of the draft and one external contributor.

"},{"location":"projects/reviews/2024/2024-sd-jwt-python-annual/#project-adoption","title":"Project Adoption","text":"

The main task of the project is to provide a reference implementation for the SD-JWT draft. The project is in use

  • by the editors of the draft to test new developments and to produce examples for the specification,
  • by external contributors to understand testdrive SD-JWT, and
  • as a reference for testing and validation of other implementations.
"},{"location":"projects/reviews/2024/2024-sd-jwt-python-annual/#goals","title":"Goals","text":""},{"location":"projects/reviews/2024/2024-sd-jwt-python-annual/#performance-against-prior-goals","title":"Performance Against Prior Goals","text":"

The project has met its goals for the last year, which were to keep the codebase up to date with the latest version of the draft and to provide a reference implementation for the draft.

"},{"location":"projects/reviews/2024/2024-sd-jwt-python-annual/#next-years-goals","title":"Next Year's Goals","text":"

As before, the main goal of the project is to provide a reference implementation for the SD-JWT draft. The project will continue to track the development of the draft, including a potential transition to an RFC. The project will also continue to exist as a reference for SD-JWT implementations.

"},{"location":"projects/reviews/2024/2024-sd-jwt-python-annual/#help-required","title":"Help Required","text":"

The project is in good shape and does not require any help at the moment.

"},{"location":"projects/reviews/2024/2024-sd-jwt-python-annual/#project-lifecycle-stage-recommendation","title":"Project Lifecycle Stage Recommendation","text":"

The project is recommended to remain in the Labs stage.

"},{"location":"projects/reviews/2025/","title":"2025 Project Annual Reviews","text":"

Projects must provide an annual review to the TAC to ensure that the project is still active and in the correct lifecycle stage. The following calendar provides the timing for when these reviews are required to be presented to the TAC:

Project Stage Date Accepted 2025 Review Multiformat VC for iOS Labs Jan 24, 2024 Feb 5, 2025 Bifold Growth Feb 21, 2024 Mar 5, 2025 EUDI Wallet Kit React Native Labs Apr 17, 2024 Apr 30, 2025 Trust Spanning Protocol Labs May 15, 2024 May 14, 2025 Tuvali Labs May 15, 2024 May 14, 2025 Credhub Labs May 29, 2024 May 28, 2025 MDL JavaScript Labs Jun 12, 2024 Jun 11, 2025 SD-JWT Python Labs May 27, 2023 SD-JWT Kotlin Labs May 27, 2023 Farmworker Wallet OS Labs Aug 9, 2023 VC-API Labs Sep 28, 2023 Wallet Framework .NET Labs Oct 4, 2023 Android Identity Library Labs Oct 18, 2023 SD-JWT JavaScript Labs Nov 1, 2023 SD-JWT Rust Labs Nov 15, 2023 Credo Growth Nov 29, 2023 SD-JWT .NET Labs Nov 29, 2023"},{"location":"task-forces/","title":"Task Forces","text":"

A task force is a group that is focused on a task with limited scope and fixed time to complete. Unlike a special interest group, a task force will have a specific set of deliverables or work products that it will create and be limited in time to completion. A task force can be created by anyone in the OpenWallet Foundation community and must be proposed to and approved by the TAC.

Tip

If you would like to propose a Task Force, please see the task force proposal process.

"},{"location":"task-forces/#active-task-forces","title":"Active Task Forces","text":"
  • None currently
"},{"location":"task-forces/#archived-task-forces","title":"Archived Task Forces","text":"
  • OID4VC Due Diligence
"},{"location":"task-forces/OID4VC-due-diligence/","title":"OID4VC Due Diligence Task Force","text":"

Currently, the OID4VC components for implementing decentralized identities such as OID4VCI and OID4VP are gaining traction, especially in Europe. These specifications are required by the European digital identity Architectural Reference Framework but also getting significant attention outside of Europe.

This task force will investigate the specifications belonging to the OID4VC family thoroughly, check the existing implementations, and start the preliminary work for potentially creating/hosting a reference implementation or a framework that can be used by a wider community for application implementations.

This task force was accepted by the TAC on May 31, 2023. See OID4VC Due Diligence Task Force Proposal for more details.

"},{"location":"task-forces/OID4VC-due-diligence/#participating","title":"Participating","text":"

This task force is an open group. Anyone in the OpenWallet Foundation community can join and participate. There is no formal sign up process. Just show up and participate.

If you are interested in participating, please join the OpenWallet Foundation Discord and participate in the discussion in the #oid4vc-due-diligence-tf channel.

"}]} \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml new file mode 100644 index 00000000..0f8724ef --- /dev/null +++ b/sitemap.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/sitemap.xml.gz b/sitemap.xml.gz new file mode 100644 index 00000000..4ea1fef3 Binary files /dev/null and b/sitemap.xml.gz differ diff --git a/task-forces/OID4VC-due-diligence/index.html b/task-forces/OID4VC-due-diligence/index.html new file mode 100644 index 00000000..f3ca5a16 --- /dev/null +++ b/task-forces/OID4VC-due-diligence/index.html @@ -0,0 +1,4262 @@ + + + + + + + + + + + + + + + + + + + + + + + + OID4VC Due Diligence - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

OID4VC Due Diligence Task Force

+

Currently, the OID4VC components for implementing decentralized identities such as OID4VCI and OID4VP are gaining traction, especially in Europe. These specifications are required by the European digital identity Architectural Reference Framework but also getting significant attention outside of Europe.

+

This task force will investigate the specifications belonging to the OID4VC family thoroughly, check the existing implementations, and start the preliminary work for potentially creating/hosting a reference implementation or a framework that can be used by a wider community for application implementations.

+

This task force was accepted by the TAC on May 31, 2023. See OID4VC Due Diligence Task Force Proposal for more details.

+

Participating

+

This task force is an open group. Anyone in the OpenWallet Foundation community can join and participate. There is no formal sign up process. Just show up and participate.

+

If you are interested in participating, please join the OpenWallet Foundation Discord and participate in the discussion in the #oid4vc-due-diligence-tf channel.

+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/task-forces/index.html b/task-forces/index.html new file mode 100644 index 00000000..fc53c6a6 --- /dev/null +++ b/task-forces/index.html @@ -0,0 +1,4224 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Task Forces - Technical Advisory Council + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Task Forces

+

A task force is a group that is focused on a task with limited scope and fixed time to complete. Unlike a special interest group, a task force will have a specific set of deliverables or work products that it will create and be limited in time to completion. A task force can be created by anyone in the OpenWallet Foundation community and must be proposed to and approved by the TAC.

+
+

Tip

+

If you would like to propose a Task Force, please see the task force proposal process.

+
+

Active Task Forces

+
    +
  • None currently
  • +
+

Archived Task Forces

+ + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file