From 281358e910ce190c8d8ba226ffab7c00328b46e5 Mon Sep 17 00:00:00 2001 From: Leon van Kammen Date: Mon, 1 Sep 2025 17:47:16 +0200 Subject: [PATCH] milestone 7m update/refactor documentation website based on updated spec (+adoption levels) --- doc/RF6_XR_Fragments.png | Bin 30794 -> 32029 bytes doc/RFC_XR_Fragments.html | 212 ++++--- doc/RFC_XR_Fragments.md | 251 +++++---- doc/RFC_XR_Fragments.txt | 1116 ++++++++++++++++++------------------- doc/RFC_XR_Fragments.xml | 195 +++---- doc/RFC_XR_Macros.txt | 32 +- doc/shell.nix | 13 +- 7 files changed, 914 insertions(+), 905 deletions(-) diff --git a/doc/RF6_XR_Fragments.png b/doc/RF6_XR_Fragments.png index 86cc2bcdd51e8b678dce1bb3b34edd8898276f23..a0ba0ea2e44cd736ed0dd61dc43278900bc528f8 100644 GIT binary patch literal 32029 zcmaHSWl)?!(=F~2+%33kaCevBzPQ8U?(UGF!QDMLghdt)?m-p^?(T5&)+crA{x533-%#d4m?P1J27dRu0vaxZfQ?-Kp9P(FP*OMOSSZ5)q~^w z?fgrp+q3rVpu7r4?(4#uofA&!o{~CDjAq6I)|?CJ=ftj5?KkoB?}63+E)5nH%D)*b z%qzv`v}!1n>$}=IApj&57CmNYL=GDAnegms5gP=ke$#MhWUEXJ(b)d}Nl0Y-6q@Lb zK%eM=E@V^hU3U$_+kx&J{^$Q=&O*lQ`%&Hu5mJ90=MH;~ThSjn!p_60qP$OlDKrZQ zAN`^AL$g1pOF*R{FP%(@-*)ueQuLDqyJy73PVAKfXt6>YZ6K-=v4_nk6J?@%`<6q< zMe1UTbgC3y>S5P!b zV3>GZIq_va)a=(k4MnWXp)X`yeDRkv{P0Ro;$HGgnqL(+ghH=!2*a*K<&#DxrXnGn zPzu;?o$aP4mkmfuWh*SKY~^~NX_WA$6_q)y&^c#5Lc4!P%kANf(t(-4 z`b+Tot(OftTR##J;ZfiGckG-azK$&pQ=Def&sZu7&Ch&xPZ!_Rfg>@9mgVPJH$Yckg-VZUF0cKn*<$eNYW zB>U`AWVya&aJeL2#d9#mAVrW{2TxMYCu-#hnd^mV7#IBvaMIw@Z|cg_PcX#c#{iq= z5hkhLit^8nRoy|zeN`YF)XM$IA3t+7BmEkG;a@(@&#J0Uk7?4pO4Z51Yb%fjO)UoQ z)C5<@_+d1V2hi=KWp>RYV-0xoK7f=zB_)PRF}*$MYPby=fMofy^V7c%_Im%k2rtYh zqd4glG!A%wnx81=x!bO-~VO`b6Gv0B?QO}9j-$>I49y?TRmfZi(U%9 zdv8cnf(}0ECmCf-e7um*xP7SL!5;ldTHALU=P8wNIK|6=D&O&~HDTbM1Sf)Y6yp#62sLo(*ToY)t`N2D;i6%$F} zeCBFhBRC1diK~VJk*j6EAXj?WDYYW{t}wJ<$Ad0m`Vfd zr~Gzgg5bps#AMxV&+Y$PNA6gs$Ax>+-ZTy>LCAVU2je<2WGt3+ly{7D_#h^4`9a_4 zKsp<`Z^SgCJPd|&P!ykw56?X^6p4H&zswO4XB};cdEn;mi5;pi?*zUG@u8HpP|9ww zUGVPJyr@o~pIZ>w*CpKOpx*yB>~up#npxTJ|IYETTd8kzCyMKEkR_H!2V!mWM78d- z2<%5XTB~$_xTeTWIQm(OiVoV_nn42wyz?T>ix5hI6GzpFq~3B=?`3Yu`u4~d(11>jc)*L{fH6p5F^-2P(QX&AHFMakBbSU=G947G@=w3I~JpPu^tpc$xIZ+rM-gOVxL zEu&u`7|JcqX(RF2q0g7Qo42bx!_5wmy?mZrvDc$V>P?Du4Q%sUxrSSO-P|<|W|UX* zxAq4|Rl62_>RkR?Rmzl%J*Z3Ju?-jjQ2}{BH=x_W$gm4J!J*o7rF+kM*?w~(i2L^1 z^HyHKNrxMz5Ht7~Q{D{)4cLT$kCBL8eG$NyGC!fd37+GX+dtEIbDG|T6f9+}~W3ms)*frDS@3wW=kf!4~p*AkmncVd3BNfcFvUim) zj0D*USR|xxMQc+E2=k8_C)UVWUOA#3=WvE!Nv}F$`Ct z_Vxp#?wEFy=D`|sxN3NLH+NcO>2!HahxZw3L1KQb`WL&%hH^%C3pY~yO7a%yVUKv< z7i@-G76VKgf;x^n-Y3D@t?4nS{bgXh<&|&T1c~^>+m4}zE+=?K-e%RhO`BA8beSXO zmjHO|`mj6S#_D?LT5ZZMgU&z4{lA&ny#4dfH0xvcP+{3&8J2GkB!v+DvQAt*oc-_i zgn*(u|I#c@qW=$VVdM2{8xDc;ZHZ9{%4DHtt56@B+pu5W}OV zr$>T#?ZicaA$-Rv<6TAip|i-|8yun{?&~i^-n;$n;$QuDGoW{UkNZo6==Sf!A{_#k zB8|L{1PJx-1{QZC2?eV#h!Kgp`hW(F`>>2QXf~+K;K2ZTq*2F6Yp;@*u6KURPs)_{ zOSTh5>GXd1)q%U4)72S(5|vRc4t6X|lc+Nm18z??#HB^Ye>o2dHwx_XXjH_0P90Zi zk(t>oz#ui#OBK=Vou>5ADHNESp-Q@m7YV%5#JHtISdQ)ZLAwNj5c;WMcfsKX@QIg} zCOy~=yqFQ?FL6_`sm#63U#8L7wl}S}!Vmnt<49b)H3AxG6NhezyH}Y>_tS`f#eJ=g z?=G4Ej;11`=zqRa6Y}>^oiG#NugbhY@P|-n1?rIL>Q?XnW{#?*0n%kLO^sCpr3xaX z{OCr_xMc7iDq&zRZchxF3UpSrL@MU|^1tY9wIR6 zhleIRl`sWJ`w}5;2EGGTcJ{#;39&OoJE#Qrdd$4eYI>{t4I;hn2U`hsuT_G;1sEfe z@y5c=(dtOQjpsOjBzz{-==VHtmhX#+12Nxgo+z_>@z27Zy7tZMUIhp;`Q%T}R%1`} zMm0#SRaEf~qH@$7bA?7hemb(&NuP$g1}?3#Lp^aw9bk+^ImMZEV&^q7mBPc^HlYZD zL=)IMjGR$28f4rFk1m*Fqh%xxg{~RTtv{O~*1l<^suh4a<(TRvp7)8~c%yk&)q^1m0a*GcdS)!RVZal2GpCZ&9zZ_&$; zSCsWjf?T0Rh`m-&4iK(>eGN$Mlk68TKrMlAKga)Mxcq~SL8($M!|B_EB8p##b#5!> z`IKA76=Vi+u@?6T?rKpA&yIDU$=+3bB0;_ym8Y+W@17s0sk=To@SETIL$O+Y0Up%`S$st)~4kHzH%Lj)--uU>(xLGQm7&Z5;%fE6>jX9@OR{b3Uz}k>8@hxzPRE25L4IA9j0r=dT!q+zt|~i&CVanD*i)c43Ir4_+~5w^YjO_7Bm^gc_;Hb?FXSQQga+Fr^=itDB9z_LdO#ooMWJps6RhSBIA$N+eIlol3*2irK!1W1y~9!rLH| zjs1SFdZ&IyP;;}=cc;(|)MSHODmi9Iu?XDbCg1)p)H;Sl zM|RMBeCvptpBaK%Qm2ujH>D&}Z z1F{UN{H5OR|DF$C#HlOC)Qu_&ME%Y8sznmHQV3paQLyfho2^JnP-XQ>d2err*3%Tw z9L5HAl((#zMA-LQ-5O&yBb+d0_SPBstt=kxDMrw=$+gIGg3YPkck$okn;M#4!i6<2BFiD-Wi65(wvR%WO zpccNcd+&wPBoEtpEPkpjX32Q0AY;tymKc4cP_t)D3L6m`DEgg}BjgZ*%(}ZQIH2o% z)q!&1fR7fKx+g!kh7sOR&V_P=5dwN=P_Mn^DDdM z=dM3*{ZpY6ah2UhAJzbIZ8q?_bD(qEG*q%bqR!;C2K3FvttPm+a0I%3{IV=@HEnG= z?sLMT1&^Qn9OXGS1(IS9ntwtuBoAid`bzA+Hf68mE3Wa=J90XD*u4e^XrA5D-Chko zcZfY-Me;Bx{Q*%kpqjee0p5L~SUV&6xDbZRfniBigCnZKWtnkbA%tn4XHlzmBFdcC zKGo`}Fz$^xd}33D`$dcM`1sZim;sXNTRJ-1Kv9G#KF54fl(9mRHNt!?uP8K%Yi9Fn zPE0hg)E7;AlPYeRHP(2j{*8%maQFjXpgP@n{+nt3`0!WpPOX#gri4_iZd$Z25S`U7 z_~~SM9$2#Z3ERc(;K;@B-=X0NRptZumK=SmvWJL$Un>Kqnf&GsF1dEXTq?!ss6`5v9v4G3Wm2}>M!myPh_=KLthh43AC%pJ$2qtxVi_;n z``Td*s-Yns*>IfO8UPNR^;ED{liG&FgdWCiLY?9jrXXTa21v4Fp7T%UpI|}1p%*Q? zUW#A&8w^Pksvl8QS9;tzhQKXh=P*P}wz zJIbXoyBYOV3^QGgJrnA1co1Bu!s-Vs6@&NZh@{KuU^#q@)TwexwJ0T3ziL2LEr?mw z^?NQh>2uv;D!aZz7O4dG9s|arV`wxlyK@CowLLzAgkav|xWnpCCQQ{O=VJj+#PB> z-s!3rak&1-aDCdXyyX6Z?aK9$2Fj2z%NQxP;L^)lgRs;buax3-cr~K~m7K`JImMk6 zICfj-5Pnjs*S&@a{81gP69(aq&mN+u?6!PNZ%`hu3@iNeS@NbltbgderjGs~mOLoyaItWtLx}X_2OX zU69kPwnz7IkYIRAVMuZ0YHsyQsAD(*G&w1)TFea2%;$rcA&ihLa}<29+vr7C4#BBP zb8NU@6InV4-+o6Oh2j+ap&#g^=M|hN@IMzulj8%zj!(k7I?}wFA{J2&;N;fK?=phy z+zp7Hv)`hQz&bCJVa{BC=Eoi1ukAN1+bYuQEKFUeLDpdFw~$D9z`Ee&Va>(I>AqT9 z@}oH|G2_oqlgT0vxS}}g#jrUTYm%4ATbIG`$sbo%h<{U;48TOy9TY8etr<-Fh?^hT zS%*YN(zLDO2CmVQx+C`1E~F_cz~0|=Fczrm#18)hHXA}O?VpTWEx7?y)8;s{aAchl z@D0}JN~gk+l~_tiR>Knl>GagkFxU0w=+YLe&&1GjYeEo@GZwK1MEXp@ zv-qoLUTEgT{+NfP1i#|5qGcxw)Z0o*0gZD~1QCUMA{Y7mI5Z+UGR*D106AXOuqy>Z z*deak>hud{MF(v)MLW;DR9{d_)Q6AtFmUq2)QBMUmtuKvyoFbsuxRZOKGS%u|M4l3 zBxVacXLB64Nt-YB-~G;F8tt<};1@@27eaCFCIVr@jX69Ao=T&~53nQ;FZ+e6@cv>} zcHsSOImy;h)@IW0nR;S$R;P|GM8ISEBX-0!>aEQ+mMq~5)c0|KOr=MAsCv$zK>>M` z=WdN73?l5Hi5{b3gD%UUFySP$EFFJ4+KM`wNK6P`$0>SGu7aF7*4v{`5!69RH)cK( za%4{I3uqDiHH&f3nLzhA8mE}$@K;?KPj=5IPp4Tq!$O~) zXE8z{SL{c+R{P9pjW_UoMByL2ET~qx%PbfWlJ<*{OF{Sw79FqUZ#3e1I~c}i!}`3! z47K=-kIHzHFCa|E>mKomf1R~D_$`a+JqQ+Dru%%)94q~^MEJ5KfOskqXk<&NgNuWC zL_#K>H*;hb9nO3fT}tSAA|%!Of_vrOZB)Q^VO5hPq>Hcx>wspmXh3qZth+A6(LS(^ z22_$OpXR&gMWE&&cC@E&d8o}%E{DLspaHFZ*38flE=wqL=)<)&=v}OLwzH=~ZH%Nl zGw^{w28~6rj%mls2D6y`72`Zui5L0&f5pumlwdqWBcghzIf%tRJ4#FTbGP4b(;WU# z{xlrRR{A!ZZ1R~;PBUv>fjyND){s)`HMrzdp{pnfRzdCjHu+CXMA(=iyLn`o>pSJJ zu;kjZ*X?(fY0#5RERDDF0Ob>+7OtQP@T(kN%3qG48dn;){@r%bWZxM?D;Of-ajG+4 z$^P;kk_EBIHx9j5L>h3)mbx(Qi=O;KV?ytrwBDl_w1u3lLp*j2xe0dC*T>LUB@KFA z^20L`3X#(Vk+L@i*Lxr$>bEra*}nC?HGviNCOaiK9uksOga#`3hyQ>&XpTm-Mek7P zrw0zk%}-O6Q(sF zix)iPeu|FtfJurH67j~Rh0%!ihB{}!Eb!{?>7}Lp9wS{OT#2u$JeMf7{sMkbl`AkL zsx{s*EnaLA$4qNa-gl;@3K{qdwVt-ktw&OlKEz!Cz^seJa&vS`C+RR$<(hWok+l;p47A`3g*} zxAU8^0U5~=Fw-=!BP9leRp2eIphk0BIoN`1m3Gld#-?WD((vt3S5+&hRb4*rL1tU( zTz1PJleCQ?E=ni(s0OCVH@fx`IS25-^-?^1qIgz8L1a2>5A+fhz~n=`bCQgQU5nBL zR=3i5a`Fpr9sXX6sO}eX#&(p9Db;S7YR;~a9j3HwL#~RC3R{6YDcT%x+M93wE9?E7 zhGV{9M-!l3zrnZT-V$YZ^=*1Y7QRFgu#+G*ybL*eqh?Yo6W8_G2El4Xkju<}Qb7c-n=zT}ODRjl5z| zSM*aoIUxp0xV`}k)8?gA^wjUEa>|(-sdiSd-i|Ahl&caQV_}^6lbtXFcjF8#nj&03 zYr<<6(|T536rcb5m@JVdA~jQm*$le3-;IK6X*g{FE7NSWAg`Z(PRir5bMyg5U_=a7 z@BvlYmOq&cudsDV0y<7c?}Dd^b^q^m0LoVppQq3BI)K>we%4lAA4VVayQ>ePe;s>2 ztQ~EW&I(stYZJsj#faL02xxbs$01}XHfy07*McAGrHj5Kf_eX&0ju*a&hXoxAbnuV zjpiBi|4xxVbfK1Co)kGIBqyw>Rs4x6n9=8Jix6`BwGi;dsqOKU3FEc093|89Dyxb+ zFpM;6e>2nFv8#mbQuv@C6Z$TB8!_zTVexw(?U_SQ$zg1XayDXep#)UiMA(RTG74@` zFhB4@{}Q^lA%tNeYWoomH}qgj<3o_-6#O(!aRp7OfMgpS^h*0p0m-j?-KsAk(A!ij zril7)p;a!)4i%f`C20Z$lj)NI0X*|_-b;a66w>}K30HOAXn8Ter}wE0n!Gi2og0UJ zSPRhF|8e|=3H~N($A&SB$r(oYL2--Zh(}t@GpZYBc-Y}@EB@Bp=!yzonF z-*JH1$;i!)%xmPmPdeH42M%5XLF3cB)y-TdtCFgNH(4$Coegn zH!QZ6E~x&mVMhgEowVch=j6LM;^tGZPZS8GGR_#i#v8?*aKM}P_5rsx)V-0Q2|J~?GYIQRTnDA z%GxD%1x!AC%uqpN$o~%KW^cCpz+L}nE7IE|eAEy#?Dz^UsnIg>1HZKLAYF-}`|r1z zs7FZ`anpeIJa%F$%ke4L;t2X~^eRfaOL+{3_xE_Y<8(=);O@UpFc|xWt@V{SKn!ry z!01Gp7yCAG+8BRSpWB@SW&TYJ{|yc=lpVA(cg}dE%EwKmb^OTvC=KX_8l*H;N8L^6jBUuab7SMQc)4`8x`~ zRS2`epf%Sh7|@7n?J$cod(?G&7P+8u)o6(6O55S}H*MlzLz6}PGbPd<`+ak&l*Tgk z;qd*C-GSC%H7y8wv@X?*PfG6uO1btSF5PD#?os9< z3KN9MUxDhQ#zk>hUoG%1jjmL*zZKl~RSwiD_WyFU01q47j;C~R{^X39iX$k|*a+WL zqyI&eDA?1D%1ue`>At7p|B`knMM9cq+m;dpWzuP1l3?iKbol|-xVky4Llpj0_a&4$ z9Qg~se=qC`lSN3>v;Y-tyL=PE+}Hmc->>T+ANyjDuw5jRPAaX!6@;VI(Vb|v@k_U;hxY8PUX^#+JwG4em;*p*o}5N zaLo(Q0yyzJgdctp+WKEJ>h^vI*lGH=Tna}Ez1mLNBj!*(8`VVCZU={9U7bVDEioYaAy&r8 zXf*bJ=SP^7OQFLOgBD#XNRPbR9H+buxDH>#5r~YdT5q;m?9(Fe z4>7#o(q5+=dU#z3F-93Sp+h>(+p=>IMtL{?bG-j~ za|gZBE_rZ57(K8#T(HPIrLl(hovor;COb-+2|1+&fuABv#6cgI*fie%ed9!b@O4=O_9<_|yW(N)8^bG3rfBxw1F%lK|ix z|K3G!@FDP*I#@YaZL?kIL;{s7&{hIpQdj!LWr1S1F_n z`WQttKC4p3?~Qm|SgX@>ER7XP4?E)s;4IU4mQ$#$A=s2tMz(%WnV5l+$E=Yf;{POT zpnWy=85VJ1O##oEq`bCa9dBX2v5Ir{`ulq4=IzmjYu#&fezwQ0{9pZK9r+3wUz%6? zGP7ehuaZPlmcKT0&5npYqi{2svHnTyf;M=7hvo{mnS_53&g}p2bN-vA^Z%L$@=2Y1 zo3r^}>RE;!m28}ZXKHY+ub@Fw+Uq&dMn9ids~3ZgA= zjw~8IpY?)$hUzk`MJrg2?S7k(=L?^CWzK#acKZeqz<&_3LSz2LLj^;R?RT$EX)J4#ZDWL(}6uu_^c|vH2DF_CZ{pfi4rlqq5 zA98VEnJ)Yh36A6Z1~ke<2PT9?(oTdP{*5X#f6|;9Xo@aSkHRPa;loAMMfNj+J-{f} zhtQ~qwuIb+_TwAOEM7nJ545H7oHwrD;UzOOYr7Hu&3#%X;9pvZ*5@hyFG8M`b|c0! z$i(BnSz|JYq5w`bSo(&*1Z$M*n(s?i^OnxBr3Iqke#E#>IE3=t(o+xU1@gWZSB;PuOEz7auoeX_Zh zHCT9iNJ-N1vsBd_0`v7IJXV##NJO zCWjBPqH8o?($URKHu+SISE<;;qMOo;=aY?Go0V8pj|gkRZ=zHG-U`Q_4XXZd*)%Ep zarg@gGbYSM$qs@M^IRdM_E+r2U0xdGn$o>lA?+o@3R0qPG+~2x{WAMz451!)ER}^x znGxGxxCr_X6r>v@hdauz?Xifb^|^vuVkv?s7QYCjcq8rV4MIci_~-|{`+`vuCqAJL zvVO$70p<*@ijiw|jl3?BlwYn{!x1c%oo5<;>L5bPg9INq61YQdjM0(SA;|QcOJbC zHWQfM9Okll=fsORR=Z&+UowiA0;(U>!YtWK;|#nX zFilPEM%Z><+|QXz3HnF8)hE*U7thk9JK-DRHS7!}XnFcNT!*==%Qm=YvI@cb=Xf7} zBtJXEg7l-P4ES|TQZ)f7%rU}#pVv0n(UYK~Rt&M7IOvpbVR(;!D=+VHIlzCsdu$nW z;*IsQoo%tTSvbM=EI5U6O&G^n!N*_zQlyPRXEkdXy@#tbp&m4f?y$XGLPq9yOi}k{ zCIYz~r5?l?^W>%TFfPs?ps^3UJd3Yuo^G~;*PBvvZa|$>tIze7YXb`?Ugs+a?Ic=) zgK5WkT7N2Atd?us|7fl=y&Q(u)F9*jo3+j>Nn;fnRCHnGBjNpUJk1JO`*DSS6R8E- z&ykTpuMb;9;g9|SpV>>{2)krZ8{J_p@ibJwk<&%N&WOTaVlWO{jU9XL<@+f}UxB}* zD>>&(Y2J414#^&F>8`sWCk_$*uJ<oDeG1eAEX^=B_}Hg#_fQ$MJu}5S0z`=FtiaN6G!3rAQM-0 z^%l+7d!Wvo8KQJ;z>$ld#hNelbjMV6F^KH-y!Yy(~(OMz!V!BWN z)akkRjtw0-3+C___^&LDl`}e5%k}{=m-eY z8R05MtJnJlw@jaRemxaRR4VP&?VV{tUWmto_5SyIDku$WVz#13?3}suEVPxr8yH1n zDT2r(G0(4xmn@P@(`hP4d{l<_v!qaktVAYt0XBS$8_0(WKz$XiOTsc)Vj!d@8p-Q= z9=>6qeGp=JT-Aqg7X~uw0{~n;@dW}aK;s`w9jF#u1{y3maW2|;nwPdAOrj>*lY?hb zW0%ZUudO(}#crG^JmW+mKN$q?5P2EppT-6;wBCo7dV#L(ob&mbQMXtH4~S1ce=7{A zWOX8$SU34_6l(*z|CejpfY75{{LGl(CSso>GzkUkShv_xSe zXWha=psN}8pS8s|W)4Rix!YPgK4g<`he79D@XTAAU=eV--;o#{Vc_u=rAUQ|gU;2C z^n<~;`Z}JR`m0Ufl>ZMtVwp#-#D z%aif#d5l5d@m=uNOLxj*&s*DV6RJp8_fXu+dgW)^osh&JQv~yI8#T)i#IREoN9=W5 zj+tY;hRy#a;A)5MErs_%*ShKrKl28nPZwK(_9f4_qU!PMmq$T|?}%!m`C>UC?1_(( zrjE3adye`!ym%(OBH^1%*{!j_Qyj|mm(RuXLD8Rk zW2Rka&im;u>}@PaHqN4KjKd2%K)xck2J|Q1oihLTDa4uqmOc2~<{te5l7VSMYj7Tx zqCiKFVQ1(ik8m_MUIDrgoB0MHclt#&q6MDE(hdmZXVJ)O$0W<*@{_I#2JP6IA_tld z75C(n$d171{cj7qC7Z}zRC~VJpjj~oVFA3`_ddu{FO`Hs%pTS{%|oe)OgNRE35rsu8tr8J6{^6@cAC3HtE`F3MfR@is6 zTxv8@@&9=N{_H|LbG zL_PqF?(tqDT2za8J}1RtufwP{CVqQYqhvhHp~dz|Dr?OgR4@G{w^EEa{TMrWQvLuRMQIZfT)yM2B`_nzPCx3?lSkBFb8$73geW}(YX#-&tRTV+M!r={Y z^|X3bm@Xkmqte)V+*9-6LPp!GF)78}@`p(NB=r+0p!%2SYhW4x?roeZVI)bOdaORI z|5w;KYBe8wEhDx(iS9;}UDfSn)poJ@^yu@U+6 zmc3AMJ_-+hSn$cAmrn~itx#?}$89D50Fx}ymYaM0L_{~#&7Q>XB^DvmhZrg|HdJ|k z%`Q6%%N5`vBx0kxDXIJB@jK9}u7LLrIgA}h1kStO-ZRC7%Qh3a`LK*c5&hl*npc48 zcm#y&DAG3gDGl(i+5*P>u%PM=`K%p%gS8fp^wY3@%d!N-wr-p`*vF=?CUu z@~w|x>bH;$jECD0#JSk!n`QlVH|N8K?PXJm$k;b$pl<<25f7S-tmxnuot_2rnbF3* ze=kr{p60`2kV9)Sj8EjJ`PcqsOmH?_4O1I3ThXz>t*<59rIeTkztB~URfQ}5A2XJT z;yIGe9r*;$DU#5Go2RO<&K{<>2qqkf=~}3It;L_RfT}M1-eV0^lW}BJugz(Gz}YLA&lT8JFeJ z4ckySg8HZu|(~8>D@-vD z+%Fi*ddhr)$#$}wv@LEXAQDor0Dd{hQqL1oBn#ahS*iV+o#m0<$!lT8h@Jq}QfYKV zu4k0R!wk=W)#XG(y9X7`Vb0lM1=LSDQ=&-cv0Vg*g~23Yc|T3O%%#Mn@qIj;o0|pG z;Cp6@Fyv+7Znq15Jk})Qi=h#i247^%U~SQL&^w4QM`GE3Qf3Fk`49hkLsNP0A`p-?`soH zMT}`WA%DqMuT1{On=It>lqxb>z_(B=ZO1UqN;&4Zi}4Amp9-< zSrRUD@DKVpob-mM3q5)OWF6=Hn!?YPNbYW`LL~B4fL3sa#h>!S)0KdA7xCdirIsVW zbqv$8ELx?7b-pdw*DB}W3%c{t6045{^7twI@>y1m0IgTd!W5@+BTS~f!qbdo;}awC zU{>Lec=Z}UYki_GQKL>lHP#=fW#%@x3PsvuH&t&F^s|G*-5;W%6juRT@|BfhZj}v` z+Y9dM7_$Zu9b`ch2fnAEFB-wlEknP_0g1~xaS9jyP!+bU(MUduKHtB*600m4{+vj* z&^C{oNT%ijhv(1A%4r+W&bQ2~Yw7RajYHh{KTg*_4Ut`g`lR%Te?e+_wbksI#4N%V z`9IG!7JjU^hF4aZ&0Ku7DQzBhKm`jHkwb|h2s1NV zq2@y^4^7cQ)~g0cQz%5##R>MM+>9`Ege0_AI{~$;etkmo1Q5pus(_r}wn%{WE7aZWV1r5-ggK_Az!z&^>sFs2plM#k^f#=m6 z>z%)T?0C}1o{-9bom!w+>%`Fo(tgiq; z0}Bka;1%olCWIkY?VxGC77tJJLbU|>Xv7*_J_-JlUBOwd_mQ*yokw=f5~Qm4&=)`- zwC+v#Mz$#??z@-MElZj|)th(`x2N33-&THGuMux?c3WQqhtncR2l}?=QM(`M_^(J5 zoU*kPNhUCk-a#u_kqd_sg)1ul+LA;0$ARR7kFx5w=CUi!3y7u$VAhKLx>Mcuqw&+) zI$e#&uCSQ3rzs5S}|V<85#>bY`?up+{I zVtO}>@by*tg3a{d!n3c@La*70_Lq}xOuTSXgF_&;P1u4d$x)xk$gPTod4dE9?OQMa zGWJi^@t&te0FPR=KE2VxtzYa&x%O8Gm&M~ztz$8pGK%bbM%);lzAQ8$4{impb^h0@ z&`9=p|jH^J6ghOd?TnI31qN#Tr-0j zZOB6yt%*n%w#}?K>iCG2utDXAGV*oFoh3^_ylkVA5h&w2>sb5)F-Jur#%ZBqun~TV z0vWw0<%!%=l1e)5q;?xI0)_#(cOGo#?RJC|VQfksar%46YYOigt?``;m?xeHTBH4P zNh%ch#+pOt6(m$2Qh5uVt0yjMk z=wianUT0~8JEa&h;hgw4jw|9^Eh#)~1fB|CIZ7`$JKrH!O}<+iCM(xWReqE*o5`B_ zjWCX0g1ViS2xjfd74%4$G=Z4>FsSuyxnYfP;CU?braSF|lm2gzm`d+#3=Z#sox}jM zZs)gesx-Ig_3V8p-_0exI(rPoFb<;F=1}Jw6P)xX@3U3H1pe6YB0EnlebM6!DvO8B zQ}mB>wb?#aEh6IJ1cjI0``$2fX*YuAnw#+i7_|9cB%-H~??L6}PBI*X0C%Lql-}Qb zF+I$#GVKSe2leq=45oxWoiwz7m(j(469Bdr9!Zjb{4Hja61I_%y)89ZvFqFhZW_xg ze#$LsSXg+6MqcB;qd#ZLwk5EA5Ts_XFg)R*u;pr4#f68g?hwRjpsr}xOGCp(T&~!^ zsMlJJ5h|b~hK9Z2zDAN8@2x5lXWOHyr-ZuWa4c;T2n$8zPJznmXQW{pwN9<$JhPeJ zg`-B?y4LV0IfyIUpgf5H&)N*U`C5_dJeZ-b+Gj3>|0EXh=_lRq25P=y+X@v_EmXMA z8HjqsMd<&@a&$v|2n{W-ouVtGv7UZXO|b=@hh+7My%g-99KeYe6V`QZx-9-Iv$%Hp z|B+z)j~v*yak%SnnX4@j{xXmlRWuH`NjNkw*;t!x{61oU@m?+zp=kH%Ge&{7q5BOa zkspZ$YT%x{(cZzCIM)vg6POhiE<#(=w!h!st^#g46OrF_uY;8f9@&%eg~yH-GRmK7 zXvGLn`(H@veGg`Lkz*YnFl5kfWg(KkPn}`4IEmRng9p5cV+F~^lu4_~T@<{lfy3tD z(pD{DFI5DV3RLJ8*MHOXPqalYgtoZlT7Iwo;gFTpW!E@UAhK!DcwXWSmL4E`Yi0Mo z$D^C1A_cL=z_mPwLR$WkLyl!{j(7h3X=-tm66Z_L}7N%@T9mh;<^^)MF^) zsWB}V|2UDhqvS{^VTI+MowF>=onI6eAAtU&ZrxxQ?y7h`!?2?EwWEabvbm(^1oSNd z4J_T9>$Ie$amdzHCS77+Q@PwC){nr;vmL?39A0Cc&%jsa4R46VThl$e6mDqyPt&sx zKwqA8D$;|>N|E@`^xhOkl^Cm&4D6ynm0AMGj*Z*j8Cmd1IDn9`X!J#R)H@i+y}Iu( zF>$$4&%8jYs2u6C<#0an%w&@`A2Nhe{ z4E60x9_g&G^)4cw?bz$Y{{(cM&-sS%Qa=&mWkvlw-gNOEwJi$HjEXoNICzB-K8uuc zS%Y}>Y@w!Tav^Tqmn%oM6-}4bBJuTTOGH^T@MP4@$>KEoDG8CfXR8>fU}pp!xWq8i z(zsobZ~yTlX@S!GSD3iLGCIRoxt1(FU0#<+fjo>@SVl$)!cflMa#q{ghN&~9@IJ9) zyo>d=%%K(!C_UDO4Ui|Q{e9V5ul1>mwE^U&!_u9I1fdwwyu{UgE)tQ28S^E8qaYPJ zk@(G+4JL~ofeaWqT|C=QZ=VzvDM&S#OHQb_5{us+8sAAS1I)cE5W)l<`IP4x_t;~sOw4;=H0M-;-p;vd?rMdqj+@exd_NR)x6 z9t&reZa^so(kEs)8#IIc2;%o$r!ou+WZp{%RyZL2?y&Z;7|}T3<Uy{~VED}s*NvZAI%1qH=|EIOHjEb|{ zwlrF}y9al7cPF@O;a0dqf(HmLK@!~E3GVI$cc>8D-GX#|=iGaG^zG6A`d`UwqiT=6 z*IsMRXH~_{oKDuu=6)QiiY?u%Avd6I?gJP2$a*4bPD{g%!|xe44gB_svESRMK_9W& z(rS(9+x!|$X7_KqLf(G%uj?*6E*__t-r{cSndlm#4I#+?+Ym7840E5B#KYo{uV2Qa zqPG+V(A?o!qN7=d=J!`30asXjtf4)(vzy>UUglRZ^Mx1@Snu#9Vo4X-FzWd7^%wS> z5t}t97Zk?~UYY%`>N^q%QS4fVA)1+ucf5Scm5Nuw`iLW|jikA;Opo3k#ioZ2gZYmR z-u%m$8+ksc%3~KNj1>YXh1zbKmcX|6o4AS9idTJGw0UW+35qTs3ggZTg)!mYweSLJ zk~Z&)6?VvuI%Y_Q6_0xV*FH&!a?q;Y5xXPE60Oe*ZQd{$p+ow(3Nos`a9n;G;DP;< zxzls(I0yo32;&=g&oTkYMoc}@`N*&jC137^UQBeH-HdBv;;7ck_1!)bh3U%DU z7gF+{@XhCgnt0xN+9V}~&&|2+epfp#;?4D5CbvC_5l3mEMwXCy#u3Mm!*lKY!}r5+ zuo6L+giG=Fr@gbE<^f<%$4gMLIq_nk!jCClIo7O1PAGeQPj_dTXXNppW%F1yGp5C>DYe@`I;LX z%aFm;Y%q+ks(=BDi%lS#K9IpgL3ZToOD^-pyl#<$%!CM((Rqm3Q0fC;3CsSxQ?k6Q zkF{a=k4cv`b_Md7DRJgSt9Z9oJs({gLs|P$pzLMgN>4IuDFo^G2CTW4_23%M|2`C1 z$*Y|Y_`vf0ojD7!*Rax3^yPf`Eeu_-=6T5%9cr>t^(~wnHa1fWWH2liOk}NaaY&kR z%^(AEsI%a)`F9DRzZZn5OUs(^9SMDLx)+Uz6U7yivu+ZfoSS=-x(Lg|k7L8Gta0!2 zq^9xVFfJFeYDTo8{~0h3+<$jdYHWTXfr)#SGV6M%HYY2kTmfTMpBML;^fP%sCEySN4eVe#KQ*bt9-!83YqRhduHXxhK3kMu(8;uN zEE{sbB>?V!|6U@1M}J$$9lG6s_NnY09%B9j*02aRDrx0GKnA$_z2`OQSqYX1{!L0; zN8WIE3=0YYw>i*u+l5Qr{~aa{KKh)+lS}HbRHhqgu>Q+MXp^?o%~+pk_A*`1Ks9Qw zF@36=6b!ov*Wd_UStabUPM0e7pw+XFo+^h2D{_9uoBXks990gR247F&I8wlPx7?ys z{XXrvws80QYtdPl^7$51Mj7rYL|HG|B9>_^mefR6msF-RVkl9~q|42r6eC6b+M>>N zZbq9Sl+Od${LPFv2PYRevq!d)7KvhVu4zA=q7lI+VDu*(pGUQpiOmqY^MgrWMFVTq zzr^nzskk4nLl-tGvH=7wco|zGHfIVId|PGv%5si_HYhIo!5*oHADu-rlE>Bj-izRl z9I-~USV|F;b6fjx)_nZ*o9yV4=}Cf*5(+wHMZY6(5&4;;OdKVtUO&f86+5k`Ms?(MqE0Ev3PH2}zaaTidPaLb2l}MezYv z;c7RByG0hO3^%iB#1{M$6x+jktjNo#j;W(aZ9q* zA6*_|%-E{V^W<6P5QUV}EKX1Hn-Eyx<;_#w)TmuioHj$5(VR9a0FsaeOcIXeYgsSV zpNWClamj#JgEXhi(Mfiv;9|x$#=f-bdPHaqF|?}@HPksfDYgXTyTE$w(J1+|;Oc0Y z`lGy0k$JPn5G0HLJMcO?{XBUWT^JYy>*_$d<^EQd$+%?u)9C3Jsp8uAQkT^oCnkVo zX>?<9(SxI6@dA&sxp1TL1F8oNMkxfz7FJ| z5n{po-JuKFgofXeiQz6X!d*N7Ka zKxY)pZWN94S6mx1*d+ZL`~tZp=u#w#tp{d+nuq4P_i3J*Y#QRWsy-q!($3?mnobKQ zps$Txh2z!Tpfc(KnjcXblhx=q$;njr-iqba#@9daxc2Rf7V|2}^U+nI+Nj!f3oX%P z=m&q_c{*OX8#GU!3EN_4{_4JP=fI$^FY2paRvG^>mq_|qu{8<0>fr#OEO~NtyMj#W zy{t2`dsUw(9ZE{x{|r)P29Sg|qeWYE3(;{8p@JBe6gWB@>ZYA)D&vcB9^yQmcc(>5 zqx_q=Zy%eRigBV_S#kAZQ1Ep|bj|o3)ya%Lo4r0m6zAy1Z7O@m7wL_0b%8wg!&#x% zY$nyTZ}pCrZ^J;e6P=;^z6pd+F}=B0U$ zol36t(}XeD>Lvf|F_#PSGHVQBl4csrZ-mMcs0kHUtTG;!g3nr4QDY`Tm8}PfOG^jg+b_ORRxLr$t`=b6)B2{K1kU|R;4IQ1hZnXu5ZF;5D52pch~45jId zR&&ehdx@Wso0HX%$Aj{WT{ttk#uYxJf8<9nO*6U(N9FkT+QVL3AVSPga)sfC{u5W_ zpYwx6yboSI+uLqyydjZ~Y_r4AP4lx&9srCF!SS4=s@6Y`M0R~x@&`ver2y#d_LIx~ z@itn~Y*G24xU1jRgnr%kd1qmUQxLJtDMT$!008%9k>-tVqr@VsP?Jp#=^X|%G=FflR;v zV8Z9RVjQW^d;yl%hg_~pN^Hjxma5(?PFzuz*G=I@9@VWa_7=b-aS3}*!QW5u?A^li z%E09)l2dsp4U{2X?ieWEe8}Dkbw4%;YT4g)0`wZXSt+kClz+)Sj>J2EYj+e5X!ECs zE0u4h>rKH2tAj#tqVLuZ42AP0{U9%A_@J9TrNZjrRTU29tD#T2&*4=^$-K5m=oes& zmXJ14AeY<>t;VNwvC;rRm#7{2)6?+4LQVlGfwFNNkU>Y`Dy~yVf<{O+K2jeUhii>O z%tQY9{CioHm?XYHen~IBY`(`D3_T5B{0c*Xn_(a#00CI$;J0B~(hi`}Tf-Ux?) zM(-&Q8AczXg0fEeDft#6658k~rG%XSU3NCXP5lQieldpf6FE!$WOUp_|2WcYj66zH zE|XZz_h?$Kn9?!}5@1XLN2R5!)daw0Im`XC9$Y7h=+k7IjHlIJVwoVlHbGRi(_zyP zyNi=_>2h_g-GBSI{!eyTkbSR>2NsN(ouW5;V>1~ZOE0|hQU2HCQ{*Ianf5^+b}{K( z^IF|`zO?M`AyeYS8xkt@G`R*aeEW9Q0v%HSkr)vtrge#k_^q9>6~52<+`Ot+{A_Ll+^=)hgyQ=otC3PKPf56vJ>C+aQg%8-K|jwZw` z))LnZB3S62V0eIO1I+iF+^OuJ875b+SyjmgJ$3q=a@g@F4bbr#b$P5hpTd|-iCBWh z4Fv8lamIi3OXH}~$+U!}U42Q2!NCY)Zn8?{HyP_GlCYA!jHV0wd9)u}x8J8>XUB}L z`^@kh{a@LW1gQTO8!;!~L=)#@NBmoCbfWYfPyGK78f9*d-toogjaK>oM`yIIrO^8b z2^*Y$|0Xr1Y^3VG4DYzP5NTA{`|2U5UwEjR^k0*!avtQNv2ZhcNT!?92^k1DmRGS9RAsjF?pvZR z`SOf4k88XJ3W7M4?~2?0c^AuLK?2giMLCFvuKpz~;*%$8@tjU>T)jL^q+`1=NV*GX zJd7DNwo!r2h9vR^BC0p&tb!|?;0-x0xfHHo?sh zMGuS=8^_bY!juh1WLuRpw;+9|1%{^lfDW7>;^9C22Hy;qiK3#{D~wt8!(?a)$UWP2 zzS+u{3xPTDynvBB2ITygZPvma8V?Oqw!F3mX-QaNT6&i_TdnqSnD`T-3~AeK#qHD7 zMu}{k`lo2yDPjylkvbU5|CobkOM26gFuz-*sWFgG6F9?Cteze3gTe~az=ASn6UO>O zM1*m!0jC6fTjof7R8k)iE4c}&pl^?D{#tX|Ak|Dp=0}$cBZlwME%~&-Wh%dY^KvQU zhdp=sYfS#f%$^zhM-xoT#v0fRS097O#glkwhBupNU>wO_By<8!lLcEd6W&NDzX-^{ zCsk$Bm!=w3iopFBFtOBpE(HWUC|^Q=*q3QfAUPhLvf0Z6}JT z>`(YS*v6$FLt=?@lnpmz#w#C3X{qBcSr*SP1M_*KAvH7Iu1>`v?Z@&mY(=Mp8~mh$ zEnyn85#Q$ED*JPk7KVpE`hvpX5i*$!4RySGjp!405k)un{wePpTU5}VcOhM`zpR-+ zNpbm(LV}1uG@>H%m8}JnWXrUS`UZTF{GX0rIkI5uwmUGTO5b&)0rL6GSePX$X-tr* zE+1sSeaMbLrPb+zE^t*(V*jn^PWl@eKp}w z_i<0wQoTmoNAP~9=CmdE0@U>nbftz5>BxBg&h}*SPz;gSK6>*sVz@o!yzQ-W$S_(~ znWQoHkWzn))9K|N_Ear_vWqhV4ixNRs)nH`ktkL}^f+3MmTmH0TnoLTSzn`zo9 zlPB$y@)^!lIqt~e%FB_X*+IOfN~65%f(rFhnS9Dv4C;$CLgED<6AB5iiUgeQ9#(IW zP)-$bzo}m1BcqfwWqOV%X(8n9JVSkf1ka~+?KmHn806Bv9}fENjKn7`Uh*i%r{f{jta8T>I7y~CXqe}PthXFqQY<4) z2f3S1UCRSH^j4KZbi*uoEo=W8+qR0HOiP~6sb%mPKam)L&6^AOul0^;ANd>F9x1~d zrpBA$P!LCl)Z}xnzo4TtX6_~35V2kczG#ntff8A2}!cSyFmK6A)BnupwSw*Q8N*`Q{mug;D`iw)O${Gjx! z23-uk?l$9fJF15)_)A-paFV}; zpKgsVk^QYD5Fc9_4? z^*^9m`j?n9SZNXWBc4W3*|~Ib&D)687htN8LhDgIy|#4WRb1gg&FZy4Z>s!?eq(r0 zi7jt$oe&3}jB|8S8TaE-NGMEOQsrijNaEP2hr-P_icJx|88pko-5DJ9)KoM1=Lk9JHKxcQOsWd#qh8*kE@lD~3u`hmNS#QrIf7xGh3 z`QA>E!ub$_13ywVmRQ7X=!@$6xBz53A8QNHXE0E{AQ=w-KG(BNq}qBQWlHVVRqv*3 z7tUsNm16w|6a`O$y~G^T-1Z%1rF z=$HCXN}G@8tdH7)1iF8nYC>B{GoGRse36@sT+WKY{1*aAeB65BYEF|!4heU8T8r3| zMA1oU8yXs@#M7#Mme!D&riK`FADz}y+u$0u%Ug$k@ygqlICf!8LIn{p1juGQ8|5LB2)BX>) zOe4R-@SL7HJq_)ur~}(O>JJ{DSUYS}Zr?2KUbl-D1m);tD8(J|(?+CWNSy1AN|VI2 z^kyfLK#4TJRnx}bN50a4qnv^^@a{I=2SDZF4AfZajZW> z$(yP0Yb<;HydT0a@KTxO{l1vw@Bp6=?1MzJdZSH&rJ2%Sj8O0yuAiT@YU+GGARgUl zAn+e364bDdf$OsjgeduH+@E7(0mT&Xzn6S_F(|rm6x1M5I~im=1$#PVg*IABG9Z(& z3y8nif5_Y+pkLFUhU_r9-Watw;nk3$80l7zW(7=1^nDy%pPmm2sKsW&)<3v;TZMJp zI@|9*Q$&+hyGyY){xgVjF37YFvJ*EI;USCRK`*Hs)`Ir^x-B)%*|bt))=nxe)3iMN z&-TlV&5>N%4Be43oM<_dNOC>JP=uQKfU6IA6SQXGO1sNJ8!60{@J!W zbIts9DY_r3QN0WR=umz`OaqI-e!Ap(=>8TZ13}jI-iLP42DvUESIzv0PTBT9Ct`7V zIH7L^E^Q@?0|k9h-2uKFjF!mg&v!JnHfO9)g@zc2ym%Pb^^*r^LyEaSezxo;@UD*tkqx*d0&tbtmWqqPnHDod!{*iIHMC$wTM5Wg3AB4mLl8#~Uq=Eu08CDqy ziclL>K|YQJtHild7L}cZbb(U5y^XsHRAVzGiyV)q)DOYv8Bz`TK6MN}zX@GrVj)VU z1(zHFTo%*;@7#1|vJXmB*9%(Y+Cr6C34))El=$zN3r5>MZNSJ#(+@6KFADOqN^;Z; z#TKlbzfSJIC<_WOqChYUyb{-TBJ`}uE2Bu9B5zn|!J3yNZXZj)l%%My@o;+^1|gx8 zL5W!(ZFcxIQSkUZrBJghp%dYRcfuOV1#X4uf6Jj;psF0cCx`et&(;M;s73)K!05A3 z4A4Xmweree3aH5MyDn+Gl*d=g)(_Z3*DF!aynWtsv8tw##$tScc3Ww%@&p$dpvii8 z=daafki{&u?MLVpabrT=4`CYt%I6d|HDWM&;E!J6 z%fj_uh`Srz|I|B3|303ResF`%uF!I(?~qXDRn1n_LJV4$bCBnl^Z?sfixf1 zqJa-{uqwNfaP7s{|a#iGP|K`+W zWBm`|k~ow^TM~2sKeHE!jQT$}JuUAzQg_EK+vf(Qe;i`fX9@F>!xm&=h~OP#yGkk! zcK;EcH7X+U?p;x;?~a^>HP(mE>iGT**1t@-n53D;XqpU1f&v>RDvfj6I(308a=g-W z0DZZ^oLHb0nJ#0uK}4rYbI8D`TEAjwgL8>aTYWlkb|%s0@+6wL(L_V9%7(WCPFS~ zhsMY}_S#sfDC%$&Ube%mrCpD21P?h1t$*? zb*QMQKj^OdNLA#16P$jh<34 zB=jP8EZ==dS-PKa^xMZ*D*E&z znna%H`e22--|v4V|JPB8$$RyI-fNNY9^#5RVYl1!P)(xvu#i^0 zq$+2p?K{F=eN>%?PSWs}w|RiLV{11nm^P-d}8u@sZAmc?a*G~Koub%ZW%RK&q+ z6+D*7H&O?gXLt;a@*eA}L?J=T4&T7u;89XMT7u7jfh_6Kr5F0?<}wxi!a_6~S~WVz zGH>O$xBBOQ>mYm=!Mt%SCg?1UlWK#;F$g~it6=Rdl5%Z&i*KFwK7s4lckPoPg%&ic zBJPktL~<8F!qVZtUWjx?7$wmIWyR5jFy8`13*67`A}2ah9myVZ{LB)0s$QtI|a*jH2_G#utS^Z>X)a6C7aQa71Z-VmZc9P zPLeHq0SQ8c$PW_qKyFeVu?K}y#_C9R#av~W>A}Ms(O?*e5J(ujG1xKQ$*DHzX1%y5 zq$NMUFPF!6#cz=(2=nqPT2cepyed5id%oUj@E3k7b2?B z_F*vTyxe~muse1mCLxNJoca-+kEo?muL6^Z2czP~#t$J5x_m;tK8VO0F$ugQ^r8Ii zeVlD1N+cW3!1~AOsL9t%`$7a9;vr37j^ksS=OVR1Yv=MM=S;X(Kg5a9v_Za3WSdXG z;ij{sZ)&X_FtZHO?}~Lq%c!OTlq7u!5s%&6-3WknF4ES!H_SfIQ-YPr&3dm|)lu0@^|AJhX$S6m=ht zImi(wAUJ4(da4$vtW5H~9c-PfFWjh~vO+VBgF)Z9?mf@hjo;(U(=F8k9r35hh}?Wz z7z5@@m#bQB>K7fG03Hv>8(c;gK#%7L&>gh)#8rL=N!SD%w+QD50w)LmjCthb1=W75 zboSI?UckO|0bU;uc7>IX?EbMPFUMbc7WmBVZcPOZj2yNL=8dcuIb3*nb?hB`pOx2; zQdd;A)=vpR?q<+bSgzTKXUfu6=|;+XG2(hu8Yc@@iz=oLA0pk-ap22$7=Pm)_HXiU zrBGtaQJ9i+ptz^!pu90id^rdH4)^~|k(%=pS~V4xF?JxZkfG>zD^6=iP%ium7W(VG zu%*Wb1h1|pQ4VPLAOzTLf4TGE4)5M@#(Q(Xv;s_AxP?!TS|79w-o+@_P`eVk`VbG4 zkZfO2KQ2GppX=dtWq1wJw{J70l5Zyk>jwMCE~m7vG{=`O6B5MOSSy4=hm5^)EyQ(+K}bl$@M<-i83I&<_-fG(=tMg7uUADt2q{Q;GMl zBn6?q$+yYCSuNN_7dwvaqzK~Ri5_T_&tFy*v`nH?-{@z;h7E{6p~~%{Rj+JmYmgcP zP;WFgu!lV8ru*%6dSPKDzKs-88$ZPaylZ3q78biGWXV;xY9T+5cnPH4_w)+TFz?}d zF>Yz$$)g)oSU89~Kp~)KCD=!ar=+?HnF;nk+kOjRM1p>O4BFpTo>&(o#QhMN+z{mB zhdvv}<}6ZtUnx*OK%o{Nlo&*k@KoLF@*(*-GQKh|Ip|S}seIdw=A9%rb@xLk2SVEn z6XQ$24cRPO_^^iqM&Bp#67cHA`r}7XdB$D_`az=MON$u?F8w=qZgz4DH6qtg=jnrE zIMcr1Aa0{41lcDZux?o2?S#WHzM`;TveopCWR2Lp+2*#6VKYsO?(sY=X*gV3NR2*2 z#&9bBs<&a|Qj1W^E?1CE^7NvYi+Rz=^k=vkygf0z-uMmKQW=96&GbVInjLQ8q8Ig2 zNvnZT3mCqyvTI?kxwqZWO>fkAYF@t}vZ~v!7+s{NRNG6Qrpw!P)q}%KK^jPNiid3b zm5}>K{#ot0W4`Yvz5o;$qy7=WGbY7RId0FGUQH~R6i{()Ww<|}kf>cYx-^fXF*UFz zS);@^HT8!q7=dreM-a*iZpCHZaAK%#EGhubh&Ax*;TZitk zAgIjRR?T(Z^Eg7i{ovO*OPfsf0f$7SoWJ-#B-Dks6;x(~$`0QpxqBO+wxv#6K{-}g zWd=oiWxI$Pf~a@EF65;ox!C3pAyY77=MwM6Ql?CkjNPH!_1-PzTY0sKkM;8hlRI{cu98k>H40R zMh76#WLP}e%sXj+NMyG|kZ8}c$!GP1^!aGNR zulW?OJ>Y`FSRoPEzO>M%*`CNCEI4^*?un{}{(?i|iN5s#w;)|ZF~55U2-Euvmu1jn zHKiIpT~z#;*HaQ#{MAuSY-@3@z^>~*l!u;h@T8R!_i(*l;~&(_j*Z2}sz?>>bv|)Z zgOHyMmkx_omf@5rSy;fuvYSnBJq)C~?G};N4cWv_xY){hf`h&V_k9hj`Q9-q=L$HM zO*mSY=Q@f}ag( z;=H;#&%V^$-@T2SxE5hk-;KE%%@mI9b+31Wc%3U9!EwwP4^(Vy0^eHKo9L;)d$Ml&h4+rK3a%UBKc1rZ>tLff?jFP{p8 z3NM=a%_EUG{{8aJn6vH$2I$?VS28o`b)+rp#zZuMr5L3(WQ7LYMBwmv^>CIieb^I| zRUCaDj_a7o4?pyuyc-M4*fUEuTLG?@eY`QuzdHmJe9o; zKu<+d=-ib>|8@RV<26aX<7WKn&^djAq!Uzy@cFQ}w$z3EtK6rYFj}~sF9)B@Y#dWU z4x0d#TJD`e2{ls<-*KSN=7RP;=IVnnFy0st?G4aR(UFP1`LSX~xhyGQCSwtb_vt=c zoM0M+(F&?s{7AC|7L>oojg()-bD+CmG~DGWCXD~t9;tQu@FzJ!N8$W3f!+_VXSBpj zp8y{IVd96OM%CK^Crh@ZIVmYhGGj%nd~x)ZBLhcZGMd;&fW@B?KjG-#Ctp#hopq*| zj}W?X7KK~l_EJ3}1(&D8)}uk9hksErx7nk%V^Mv?_VTSoJZbiyxr{PVsm=kwKL9O7 zCjnMd-;(CrHl~5`W+-DhV5((%ov#z~G+S$Gb57qPIpyb7M+;NUd1bqw4^u zlfJs5fpYxM8>0iaMKbbv1_V)cm%MC%cz+^*<<~7j3_|ot<3*hPFs#SfOj{t+dS@1s zZ731?5Z{#pG&Fo{rQ5n0>)_W8lc1e^aiY;UUy3_`4wc+EKOo`N zhAXqcC6Dbx(;fcJ9P}{Fl7xDxfs8-wxvEY2%Y#W=nLXzhlrdq%CW#P#w+b>6FY)SO zSig?!!xO35Cm$CV80QQ3m-~xyef*1<(sr}YJ+7aZu?|tM8o#VtP`fT(7K|y>A4eD} zc0k>1jb;c(fI`hRZW#6c(obDf`chYJ{e`$o&l!E)uYMb(rEYBSyshLmiD8uJd{;UQ zSw-REbJ5o4BI%U=9N`?$73){`ZBU1!hHP4=ua2+oPsIa83m&%qNX;)v?N&cAg3sd< zsnZP#3K=&=D9cXlgBl3OC~PZNx>F4!CNr6wrp;Vtx_;KGHMJTGQZ59}R=6HbQ=ZiFlbMH;%## zc;rn~KVc^=57@$+YZm^dsICx|Lw*0YGeCwLn`DI$i>Z~xi#H>sOKc5UaPS`-xiFE> zFVYeGJdJiB*2-_R`aZKA7F3)&H-6-6d^hA#B(?3z4B4#=?WD#>j_vOEp;|YR7?(M-gzO3h$(&fn4VJ|WGOVuokPDbT=E_1H?$$4k7gdxlyqK>+RU9t7?otrzc}8XRQ&3=1i|o|J2?q1zo=l0ic+Ano&V z9p`OJuJm!C@T)2VhQv-t6onK!!CW+=^TlfriXk9DfIpzTP%q+b)*i>0)8ekz-lF?A zwreGzp~k~(*5CEJWo?Sr&uYU3MgH--o^3+gNB=henocP^C$SoigVszDYN!gQ$&gh~ zpvsSQcy;l3)Eu|y*t3xQXMCbSRgN%fKpHdh(Z0SOS!=$9VqemLo&oD5YH*-f9)k_d z0)*MAq2MK+!_HLjvP2Vmm59k6+u8|Z{ECqx?q(QVPI^SQwS~b$SPqb|3{)T{5dn%p z%{B2=+N^r|=ZPsQeHx(%RQTnI^uFQ(UGnb07=v+?MYM&TJr)|d}ndX~qO#?->oEsj6)g+BL^)!M+^rQt+KOPSFoZKY8xmr$BT5P@`aik9hQKR%I{Wg08AisBOa2q7m|Q@rZCEJ^#2VU z;^nhf#)Cjh^#BvO?)dSdlh^C)bzkXm3f3hj9{WdzzDD-pU9&M-{=*yEi3a0+1USx5 zeH;20Z%9|A;acMs?_WLATKXuUU8~A58tr7T3eQt}HK?`we@RlT#Gt!)rDqLC)E)LB zEM7&9Ia=D$))_^Y_lbI65@+{^;i^ZoiTE^XOON|Y|7MFfuQw?}yfNpK(@+}(J8*^cmi2SQ1 z_Rv3I1Y10pMPG<&qOYAOj^iUM{NCS4F=s*3jNO{VD$WIK5HyPJySi$HlBR4%>#OrW zhe)k(-K1%Sw1lIUrEW&eF`p?j>%a1(k1X0U@*)sOd8xS1g0 z1^DPM?K3<`-PJUz3E^GErV3`l8~Ks`7q~Sy16hu0e&D^y0o8Vm@dIuPo(i9H8S(T% zWetLK_B|ISU7(3gV=ZTOe75G_5EU^YK-ecv{wbfK+^}Ka8@CHE=HF)zUA(0%_@x=?|AFe3@bZxi^JGtpz;*@_vFAK6RO2P4ph;+Y~ zxX1F|;ah}+)9bY-qhVl67VB}fSi~JdOa0j1o(PdJOCE;^zZZk+DA36xje?S2>fdG6 zT{eb0X?@`&v}GPjJ4pgsLa{|Vr62y2M4ZW<^B8}SY1deT6qd-mkGGuiUM{2w_yt8GIVj3Gn9pM|($49)hVI6OPKN;(&0;N5&ACH@*EVyxK&c;EEK1+TX($h5scDTkphlP zbhs=)^Gg9879=ro9aKSZ&_*Gxq6gSRI;h$!0&v4^eh3hsdJ zTs7BSDwcRcLaPNXg=}w|M8PZ}DztlkUGEVClgMv;Bo%!FH)ux;XCh!)N~Q^Bo_$0M z<`$F|V^l{27i*nInH|15xq(HYG9fRiJp3XkBC`M3M3)GRxRCne`hdn~-46qTW0|YV zN#S^6+dSk*4@o1`|4c7NIYIQxc`V?F8d!A@$%c+_#Ze&Z_V6)wHxCaoqbq3F%i!52 z!*HdC1LA&R-`zaRIM28;In8ntl zs--v`_Cy|CPdpnfzw5Khnm*!27CLMDhM7i1rS3$t_E6cd@<}NtnCti9Ll_Osl6pRD z8Iu}*Jv*N9|CDMN^=nMB+V5tkjt*qg2FoX_p+U)xKj{EAi(HE@&~jTNtk?cGWo z_9{2o)##ByIFN)lm#imYiTh-xd zmzO9Ow6;EW>>SspH#a8Xd!r~>xL7}mV#M*euFvJ{X)V-^!`V&)jC+%LP5*cHYOA^cX2G! zyH`sDp29YIuQw(zZbsu00!*zRS$SEff~T&~@8V=0f-6};f4puRz(^42R$!0A7Tr0# z@(hdvKK^FghCP3QroAfB+KyI&S4S5=SZLXMpqp+tshJKjT_6M*PQHYlnCfwzkQ&7F zWj)a&$2rxjH2_*B|HJ?J8Ei26VWtNUIBPiwGTo1r7E;z$2SLfXny(LjR_~^$7(<-am|(C5d2BV6mtNC*mbxl80Ek}}nPuDY(9_gWN9 zj~qPG*A5!IA%fUAjOo>nroFD3{#x#3!-_}F*JJq{_VO*Z3(57Z)?yldClo>7y*c7` z6J@cZfZE?{i-oHI{E=`(^f~?$-j(}|m3kg!p_f-|XgOqjr4JwNlyZvi9@1eCysFzJrnsBoe;+`7l%#(W;H9dAFt)AqmKu%E@+QQ~HJ?N!izFS2!% zBf`Fmqtw={xo{U2*F9%uJPbKx*6Rv;k_tN}G_2Et5{_U^VEa1(X=W>*i2%_!akkpg zl=I-^A#!ZP=~bFIe)MFN*fh~NN{|BX65%+^x}b?Ti`$+y0JF7|i|k|YYVnN)LgaJy z5_5EGa^qdma{*s?UYI+Rm@#@?rFh)GS0iW5yY^~}OeG9?u%XShfRBv%bp4TvEaeT@ zxSN<EYEzajS}XM)4W-Q(`C;;%sA$Z7Q|01{L^lNx)jTBG$oUjoNNKNfRJm zuoNYuoLZYe*Edyh*IY<1h%k+LvIpue14uDatJU)(N$(=zC4;2Tc#GrXr@c0 zhqXjzb4CDLUfI^*cNmsty#5_qfr~|PQ>1^9Vea!7BGcxCZP9d-32v|rB3A7%fwWfn zYuL!}`4vM3$X;!j-9mn9!wx|?{C6Pp*>y9Sm=m4JvTn5hQyUkL?}~PBUqaZEtBuZ0 zdn&uWrp2!rVqCaXky`SAn%c%fjV$7!HQrfBZkM_h3>OMmO!5Nir8W!2ctmdfV$5c`i`CBbbbOxa#Il zru7nsCi9UG?!OYM?J|V_JD)nn$)Q7v>kJ|5D*8tVh5>es1qF{E}BM$j!^u~pPvPE>j zBdqTRNu}b`Cgbbr)^W9_-X}rVie{KVr8x@je_ib<3EDW5zL!&|g~Dh0TEuJywTQ?6 zmot*532|D)`tkf0H)X6-ELkrGbFnLJK z{kqt1di>FA>5@#zVrC6)iQIi#{l-*RjP%#KW>(u-I9f}PM<99&Aowd+Q!q}Y&oaYE z%p}p|GJ)?5jX_?n0Mu5GqO>#GLY7_Mwj=0E+xt0c38qHtr_i(#*w3*hs07KivI;E+ c;r$)@`tEibo$IUYKYh;?WmRQrq=2FS3-6XKEC2ui literal 30794 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 aD%xTFM$l{9WcYAk1bG=1=?Y13;Qt3AVNAaO diff --git a/doc/RFC_XR_Fragments.html b/doc/RFC_XR_Fragments.html index 76810e3..acb8739 100644 --- a/doc/RFC_XR_Fragments.html +++ b/doc/RFC_XR_Fragments.html @@ -80,13 +80,14 @@ value: draft-XRFRAGMENTS-leonvankammen-00

Abstract

-

This draft is a specification for interactive URI-controllable 3D files, enabling hypermediatic navigation, to enable a spatial web for hypermedia browsers with- or without a network-connection.
+

An open specification for hyperlinking & deeplinking 3D fileformats. +This draft is a specification for interactive URI-controllable 3D files, enabling hypermediatic navigation, to enable a spatial web for hypermedia browsers with- or without a network-connection.
The specification uses W3C Media Fragments and URI Templates (RFC6570) to promote spatial addressibility, sharing, navigation, filtering and databinding objects for (XR) Browsers.
-XR Fragments allows us to better use existing metadata inside 3D scene(files), by connecting it to proven technologies like URI Fragments.
-XR Fragments views spatial webs thru the lens of 3D scene URI’s, rather than thru code(frameworks) or protocol-specific browsers (webbrowser e.g.).

+XR Fragments allows us to better use implicit metadata inside 3D scene(files), by mapping it to proven technologies like URI Fragments.
+XR Fragments views XR experiences thru the lens of 3D object URI’s, rather than thru code(frameworks) or protocol-specific browsers (webbrowser e.g.).

-

XR Fragments is a Meta scene format which leverages heuristic rules derived from any 3D scene or well-established 3D file formats, to extract meaningful features from scene hierarchies.
+

XR Fragments is a heuristical 3D format which leverages heuristic rules derived from any 3D scene or well-established 3D file formats, to extract meaningful features from scene hierarchies.
These heuristics, enable features that are both meaningful and consistent across different scene representations, allowing higher interop between fileformats, 3D editors, viewers and game-engines.

Almost every idea in this document is demonstrated at https://xrfragment.org

@@ -206,19 +207,12 @@ Instead of forcing authors to combine 3D/2D objects programmatically (publishing -#pos +#...... vector3 -#pos=0.5,0,0 #pos=room #pos=cam2 +#room1 #room2 #cam2 positions/parents camera(rig) (or XR floor) to xyz-coord/object/camera - -#rot -vector3 -#rot=0,90,0 -rotates camera to xyz-coord 0.5,0,0 - - Media Fragments media fragment @@ -251,83 +245,12 @@ Instead of forcing authors to combine 3D/2D objects programmatically (publishing XR teleport custom property in 3D fileformats - - -src -string -"src": "#cube" -XR embed / teleport -custom property in 3D fileformats - - - -tag -string -"tag": "cubes geo" -tag object (for filter-use / XRWG highlighting) -custom property in 3D fileformats - - - -# -string -"#": "#mypreset -trigger default fragment on load -custom property in 3D fileformats - -
-

Supported popular compatible 3D fileformats: .gltf, .obj, .fbx, .usdz, .json (THREE.js), .dae and so on.

-
+

HFL (Hypermediatic Feedback Loop) for XR Browsers

-

Sidecar-file

- -
-

NOTE: sidecar-files break the portability of XR (Fragments) experiences, therefore side-car files are discouraged for consumer usage/sharing. However, they can accomodate developers or applications who (for whatever reason) must not modify the 3D scene-file (a .glb e.g.).

-
- -

For developers, sidecar-file can allow for defining explicit XR Fragments metadata, outside of the 3D file.
-This can be done via a JSON-pointers RFC6901 in a JSON sidecar-file:

- -
    -
  • experience.glb
  • -
  • experience.json
  • -
- -
{
-  "/":{
-    "#":                 "#-penguin",
-    "aria-description": "description of scene",
-  },
-  "/room/chair": {
-    "href": "#penguin"
-  }
-}
-
- -
-

This would mean: hide object(s) with name or tag-value ‘penguin’ upon scene-load, and show it when the user clicks the chair

-
- -

So after loading experience.glb the existence of experience.json is detected, to apply the explicit metadata.
-The sidecar will define (or override already existing) extras, which can be handy for multi-user platforms (offer 3D scene customization/personalization to users).

- -
-

In THREE.js-code this would boil down to:

-
- -
 scene.userData['#'] = "#chair&penguin"
- scene.userData['aria-description'] = "description of scene"
- scene.getObjectByName("room").getObjectByName("chair").userData.href = "#penguin"
-
- // now the XR Fragments parser can process the XR Fragments userData 'extras' in the scene 
-
- -

Hypermediatic FeedbackLoop for XR browsers

- -

href metadata traditionally implies click AND navigate, however XR Fragments adds stateless click (xrf://#....) or navigate (xrf://#pos=...) +

href metadata traditionally implies click AND navigate, however XR Fragments adds stateless click (xrf://#....) or navigate (xrf://#...) as well (which allows many extra interactions which otherwise need a scripting language). This is known as hashbus-only events (see image above).

@@ -338,7 +261,7 @@ The sidecar will define (or override already existing) extras,
  • hypermediatic loading/clicking 3D assets (gltf/fbx e.g.) natively (with or without using HTML).
  • -
  • allowing 3D assets/nodes to publish XR Fragments to themselves/eachother using the xrf:// hashbus
  • +
  • allowing 3D assets/nodes to publish XR Fragments to themselves/eachother using the xrf:// hashbus (xrf://#person=walk to trigger walk-animation for object person)
  • collapsing the 3D scene to an wordgraph (for essential navigation purposes) controllable thru a hash(tag)bus
  • completely bypassing the security-trap of loading external scripts (by loading 3D model-files, not HTML-javascriptable resources)
@@ -435,7 +358,7 @@ sub-delims = "," / "="
-

Example: ://foo.com/my3d.gltf#pos=1,0,0&prio=-5&t=0,100

+

Example: ://foo.com/my3d.gltf#room1&prio=-5&t=0,100

@@ -448,12 +371,12 @@ sub-delims = "," / "=" - + - + @@ -505,8 +428,72 @@ For example, to render a portal with a preview-version of the scene, create an 3

It also allows sourceportation, which basically means the enduser can teleport to the original XR Document of an src embedded object, and see a visible connection to the particular embedded object. Basically an embedded link becoming an outbound link by activating it.

+
+ +

non-normative

+ +

The following below is non-normative heuristics which are not part officially part of the spec.

+ +

additional explicit metadata

+ +

| #rot | vector3 | #rot=0,90,0 | rotates camera to xyz-coord 0.5,0,0 | +| src | string | "src": "#cube" | XR embed / teleport | custom property in 3D fileformats | +| tag | string | "tag": "cubes geo" | tag object (for filter-use / XRWG highlighting) | custom property in 3D fileformats | +| # | string | "#": "#mypreset | trigger default fragment on load | custom property in 3D fileformats |

+ +
+

Supported popular compatible 3D fileformats: .gltf, .obj, .fbx, .usdz, .json (THREE.js), .dae and so on.

+
+ +

Sidecar-file

+ +
+

NOTE: sidecar-files break the portability of XR (Fragments) experiences, therefore side-car files are discouraged for consumer usage/sharing. However, they can accomodate developers or applications who (for whatever reason) must not modify the 3D scene-file (a .glb e.g.).

+
+ +

For developers, sidecar-file can allow for defining explicit XR Fragments metadata, outside of the 3D file.
+This can be done via a JSON-pointers RFC6901 in a JSON sidecar-file:

+ +
    +
  • experience.glb
  • +
  • experience.json
  • +
+ +
{
+  "/":{
+    "#":                 "#-penguin",
+    "aria-description": "description of scene",
+  },
+  "/room/chair": {
+    "href": "#penguin"
+  }
+}
+
+ +
+

This would mean: hide object(s) with name or tag-value ‘penguin’ upon scene-load, and show it when the user clicks the chair

+
+ +

So after loading experience.glb the existence of experience.json is detected, to apply the explicit metadata.
+The sidecar will define (or override already existing) extras, which can be handy for multi-user platforms (offer 3D scene customization/personalization to users).

+ +
+

In THREE.js-code this would boil down to:

+
+ +
 scene.userData['#'] = "#chair&penguin"
+ scene.userData['aria-description'] = "description of scene"
+ scene.getObjectByName("room").getObjectByName("chair").userData.href = "#penguin"
+
+ // now the XR Fragments parser can process the XR Fragments userData 'extras' in the scene 
+
+

Level2: Implicit URI Fragments

+
+

Warning: non-normative

+
+

These fragments are derived from objectnames (or their extras) within a 3D scene, and trigger certain actions when evaluated by the browser:

pos=1,2,3room1 vector/coordinate argument e.g.
pos=1,2,3&rot=0,90,0&fooroom1&rot=0,90,0&cam1 combinators
@@ -531,7 +518,7 @@ For example, to render a portal with a preview-version of the scene, create an 3 - + @@ -582,7 +569,7 @@ For example, to render a portal with a preview-version of the scene, create an 3

media fragments and datatypes

-

NOTE: below the word ‘play’ applies to 3D animations embedded in the 3D scene(file) but also media defined in src-metadata like audio/video-files (mp3/mp4 e.g.)

+

Warning: non-normative (below the word ‘play’ applies to 3D animations embedded in the 3D scene(file) but also media defined in src-metadata like audio/video-files (mp3/mp4 e.g.))

FOCUS#<tag_or_objectname>xrf://#<tag_or_objectname> string #person (and show) object(s) with tag: person or name person (XRWG lookup)
@@ -787,7 +774,7 @@ For example, to render a portal with a preview-version of the scene, create an 3 │ index.gltf │ │ │ │ │ ├── ◻ buttonA │ - │ │ └ href: #pos=1,0,1&t=100,200 │ + │ │ └ href: #room1&t=100,200 │ │ │ │ │ └── ◻ buttonB │ │ └ href: other.fbx │ <── file─agnostic (can be .gltf .obj etc) @@ -797,26 +784,35 @@ For example, to render a portal with a preview-version of the scene, create an 3

An XR Fragment-compatible browser viewing this scene, allows the end-user to interact with the buttonA and buttonB.
-In case of buttonA the end-user will be teleported to another location and time in the current loaded scene, but buttonB will replace the current scene with a new one, like other.fbx, and assume pos=0,0,0.

+In case of buttonA the end-user will be teleported to another location and time in the current loaded scene, but buttonB will replace the current scene with a new one, like other.fbx, and assume camera coordinate 0,0,0

Top-level URL processing

-

Example URL: ://foo/world.gltf#cube&pos=0,0,0

+

Example URL: ://foo/world.gltf#room1&t=10

The URL-processing-flow for hypermedia browsers goes like this:

    -
  1. IF a #cube matches a custom property-key (of an object) in the 3D file/scene (#cube: #......) THEN execute that predefined_view.
  2. -
  3. IF scene operators (pos) and/or animation operator (t) are present in the URL then (re)position the camera and/or animation-range accordingly.
  4. -
  5. IF no camera-position has been set in step 1 or 2 update the top-level URL with #pos=0,0,0 (example)
  6. +
  7. IF a #room1 matches a custom property-key (of an object) in the 3D file/scene (#room1: #......) THEN execute that predefined_view.
  8. +
  9. IF scene operators and/or animation operator (t) are present in the URL then (re)position the camera (to room1) and/or animation-range (10) accordingly.
  10. +
  11. IF no camera-position has been set in step 1 or 2 assume 0,0,0 as camera coordinate (XR: add user-height) (example)
  12. +
+ +

Non-normative / Deprecated:

+ +
  1. IF a #cube matches the name (of an object) in the 3D file/scene then draw a line from the enduser(’s heart) to that object (to highlight it).
  2. IF a #cube matches anything else in the XR Word Graph (XRWG) draw wires to them (text or related objects).

Embedding XR content using src

+
+

NOTE: only adviced for local-first experiences (where resources can be cached).

+
+

src is the 3D version of the iframe.
It instances content (in objects) in the current scene/asset, and follows similar logic like the previous chapter, except that it does not modify the camera.

@@ -914,15 +910,15 @@ Resizing will be happen accordingly to its placeholder object aquariumcube - +
href string (uri or predefined view)#pos=1,1,0
#pos=1,1,0&rot=90,0,0
://somefile.gltf#pos=1,1,0
#room1
#pos=room1&rot=90,0,0
://somefile.gltf#room1
    -
  1. clicking an outbound “external”- or “file URI” fully replaces the current scene and assumes pos=0,0,0&rot=0,0,0 by default (unless specified)

  2. +
  3. clicking an outbound “external”- or “file URI” fully replaces the current scene and assumes room2&rot=0,0,0 by default (unless specified)

  4. -
  5. relocation/reorientation should happen locally for local URI’s (#pos=....)

  6. +
  7. relocation/reorientation should happen locally for local URI’s (#....)

  8. navigation should not happen “immediately” when user is more than 5 meter away from the portal/object containing the href (to prevent accidental navigation e.g.)

  9. @@ -934,9 +930,9 @@ Resizing will be happen accordingly to its placeholder object aquariumcube
  10. ignore previous rule in special cases, like clicking an href using camera-portal collision (the back-button could cause a teleport-loop if the previous position is too close)

  11. -
  12. href-events should bubble upward the node-tree (from children to ancestors, so that ancestors can also contain an href), however only 1 href can be executed at the same time.

  13. +
  14. href-events should bubble upward the node-tree (from children to ancestors, so that ancestors can also conain an href), however only 1 href can be executed at the same time.

  15. -
  16. the end-user navigator back/forward buttons should repeat a back/forward action until a pos=... primitive is found (the stateless xrf:// href-values should not be pushed to the url-history)

  17. +
  18. the end-user navigator back/forward buttons should repeat a back/forward action until a #... primitive is found (the stateless xrf:// href-values should not be pushed to the url-history)

» example implementation
@@ -1552,16 +1548,16 @@ Spec:

  • the textlog contains aria-descriptions, and its narration (Screenreader e.g.) can be skipped (via 2-button navigation)
  • The back command should navigate back to the previous URL (alias for browser-backbutton)
  • The forward command should navigate back to the next URL (alias for browser-nextbutton)
  • -
  • A destination is a 3D node containing an href with a pos= XR fragment
  • +
  • A destination is a 3D node containing an href with a #... XR fragment (which matches a 3d object name)
  • The go command should list all possible destinations
  • The go left command should move the camera around 0.3 meters to the left
  • The go right command should move the camera around 0.3 meters to the right
  • The go forward command should move the camera 0.3 meters forward (direction of current rotation).
  • The rotate left command should rotate the camera 0.3 to the left
  • The rotate left command should rotate the camera 0.3 to the right
  • -
  • The (dynamic) go abc command should navigate to #pos=scene2 in case there’s a 3D node with name abc and href value #pos=scene2
  • -
  • The look command should give an (contextual) 3D-to-text transcript, by scanning the aria-description values of the current pos= value (including its children)
  • -
  • The do command should list all possible href values which don’t contain an pos= XR Fragment
  • +
  • The (dynamic) go abc command should navigate to #scene2 in case there’s a 3D node with name abc and href value #scene2
  • +
  • The look command should give an (contextual) 3D-to-text transcript, by scanning the aria-description values of the current #... (3D object) value (including its children)
  • +
  • The do command should list all possible href values which don’t contain an #... XR Fragment
  • The (dynamic) do abc command should navigate/execute https://.../... in case a 3D node exist with name abc and href value https://.../...
  • @@ -1783,7 +1779,7 @@ Non-HTML Hypermedia browsers should make browser extensions the right place, to XR fragment -URI Fragment with spatial hints like #pos=0,0,0&t=1,100 e.g. +URI Fragment with spatial hints (which match the name of a 3D object-, camera-, animation-object) diff --git a/doc/RFC_XR_Fragments.md b/doc/RFC_XR_Fragments.md index a2fe499..38de5ab 100644 --- a/doc/RFC_XR_Fragments.md +++ b/doc/RFC_XR_Fragments.md @@ -93,12 +93,13 @@ value: draft-XRFRAGMENTS-leonvankammen-00 .# Abstract +An open specification for hyperlinking & deeplinking 3D fileformats. This draft is a specification for interactive URI-controllable 3D files, enabling [hypermediatic](https://github.com/coderofsalvation/hypermediatic) navigation, to enable a spatial web for hypermedia browsers with- or without a network-connection.
    The specification uses [W3C Media Fragments](https://www.w3.org/TR/media-frags/) and [URI Templates (RFC6570)](https://www.rfc-editor.org/rfc/rfc6570) to promote spatial addressibility, sharing, navigation, filtering and databinding objects for (XR) Browsers.
    -XR Fragments allows us to better use existing metadata inside 3D scene(files), by connecting it to proven technologies like [URI Fragments](https://en.wikipedia.org/wiki/URI_fragment).
    -XR Fragments views spatial webs thru the lens of 3D scene URI's, rather than thru code(frameworks) or protocol-specific browsers (webbrowser e.g.). +XR Fragments allows us to better use implicit metadata inside 3D scene(files), by mapping it to proven technologies like [URI Fragments](https://en.wikipedia.org/wiki/URI_fragment).
    +XR Fragments views XR experiences thru the lens of 3D object URI's, rather than thru code(frameworks) or protocol-specific browsers (webbrowser e.g.). -> XR Fragments is a Meta scene format which leverages heuristic rules derived from any 3D scene or well-established 3D file formats, to extract meaningful features from scene hierarchies.
    +> XR Fragments is a heuristical 3D format which leverages heuristic rules derived from any 3D scene or well-established 3D file formats, to extract meaningful features from scene hierarchies.
    These heuristics, enable features that are both meaningful and consistent across different scene representations, allowing higher interop between fileformats, 3D editors, viewers and game-engines. > Almost every idea in this document is demonstrated at [https://xrfragment.org](https://xrfragment.org) @@ -201,10 +202,10 @@ XR Fragments utilizes URLs: | fragment | type | example | info | |-------------------|------------|--------------------|----------------------------------------------------------------------| -| `#pos` | vector3 | `#pos=0.5,0,0` `#pos=room` `#pos=cam2` | positions/parents camera(rig) (or XR floor) to xyz-coord/object/camera | -| `#rot` | vector3 | `#rot=0,90,0` | rotates camera to xyz-coord 0.5,0,0 | +| `#......` | vector3 | `#room1` `#room2` `#cam2` | positions/parents camera(rig) (or XR floor) to xyz-coord/object/camera | | [Media Fragments](https://www.w3.org/TR/media-frags/) | [media fragment](#media%20fragments%20and%20datatypes) | `#t=0,2&loop` | play (and loop) 3D animation from 0 seconds till 2 seconds| + # List of **explicit* metadata These are the possible 'extras' for 3D nodes and sidecar-files @@ -212,6 +213,109 @@ These are the possible 'extras' for 3D nodes and sidecar-files | key | type | example (JSON) | function | existing compatibility | |--------------|----------|------------------------|---------------------|----------------------------------------| | `href` | string | `"href": "b.gltf"` | XR teleport | custom property in 3D fileformats | + +# HFL (Hypermediatic Feedback Loop) for XR Browsers + +`href` metadata traditionally implies **click** AND **navigate**, however XR Fragments adds stateless **click** (`xrf://#....`) or **navigate** (`xrf://#...`) + as well (which allows many extra interactions which otherwise need a scripting language). This is known as **hashbus**-only events (see image above). + +> Being able to use the same URI Fragment DSL for navigation (`href: #foo`) as well as interactions (`href: xrf://#bar`) greatly simplifies implementation, increases HFL, and reduces need for scripting languages. + +This opens up the following benefits for traditional & future webbrowsers: + +* [hypermediatic](https://github.com/coderofsalvation/hypermediatic) loading/clicking 3D assets (gltf/fbx e.g.) natively (with or without using HTML). +* allowing 3D assets/nodes to publish XR Fragments to themselves/eachother using the `xrf://` hashbus (`xrf://#person=walk` to trigger `walk`-animation for object `person`) +* collapsing the 3D scene to an wordgraph (for essential navigation purposes) controllable thru a hash(tag)bus +* completely bypassing the security-trap of loading external scripts (by loading 3D model-files, not HTML-javascriptable resources) + + +XR Fragments itself are [hypermediatic](https://github.com/coderofsalvation/hypermediatic) and HTML-agnostic, though pseudo-XR Fragment browsers **can** be implemented on top of HTML/Javascript. + +| principle | XR 4D URL | HTML 2D URL | +|-----------------------------|-------------------------------------------------|---------------------------------------| +| the XRWG | wordgraph (collapses 3D scene to tags) | Ctrl-F (find) | +| the hashbus | hashtags alter camera/scene/object-projections | hashtags alter document positions | +| src metadata | renders content and offers sourceportation | renders content | +| href metadata | teleports to other XR document | jumps to other HTML document | +| href metadata | triggers predefined view | Media fragments | +| href metadata | triggers camera/scene/object/projections | n/a | +| href metadata | draws visible connection(s) for XRWG 'tag' | n/a | +| href metadata | filters certain (in)visible objects | n/a | +| href metadata | href="xrf://#-foo&bar" | href="javascript:hideFooAndShowBar()` | +| | (this does not update topLevel URI) | (this is non-standard, non-hypermediatic) | + +> An important aspect of HFL is that URI Fragments can be triggered without updating the top-level URI (default href-behaviour) thru their own 'bus' (`xrf://#.....`). This decoupling between navigation and interaction prevents non-standard things like (`href`:`javascript:dosomething()`). + +# Conventions and Definitions + +See appendix below in case certain terms are not clear. + +## XR Fragment URL Grammar + +For typical HTTP-like browsers/applications: + +``` +reserved = gen-delims / sub-delims +gen-delims = "#" / "&" +sub-delims = "," / "=" +``` + +> Example: `://foo.com/my3d.gltf#room1&prio=-5&t=0,100` + +| Demo | Explanation | +|-------------------------------|---------------------------------| +| `room1` | vector/coordinate argument e.g. | +| `room1&rot=0,90,0&cam1` | combinators | + +> this is already implemented in all browsers + +Pseudo (non-native) browser-implementations (supporting XR Fragments using HTML+JS e.g.) can use the `?` search-operator to address outbound content.
    +In other words, the URL updates to: `https://me.com?https://me.com/other.glb` when navigating to `https://me.com/other.glb` from inside a `https://me.com` WebXR experience e.g.
    +That way, if the link gets shared, the XR Fragments implementation at `https://me.com` can load the latter (and still indicates which XR Fragments entrypoint-experience/client was used). + +# Spatial Referencing 3D + +XR Fragments assume the following objectname-to-URIFragment mapping: + +``` + + my.io/scene.fbx + +─────────────────────────────+ + │ sky │ src: http://my.io/scene.fbx#sky (includes building,mainobject,floor) + │ +─────────────────────────+ │ + │ │ building │ │ src: http://my.io/scene.fbx#building (includes mainobject,floor) + │ │ +─────────────────────+ │ │ + │ │ │ mainobject │ │ │ src: http://my.io/scene.fbx#mainobject (includes floor) + │ │ │ +─────────────────+ │ │ │ + │ │ │ │ floor │ │ │ │ src: http://my.io/scene.fbx#floor (just floor object) + │ │ │ │ │ │ │ │ + │ │ │ +─────────────────+ │ │ │ + │ │ +─────────────────────+ │ │ + │ +─────────────────────────+ │ + +─────────────────────────────+ + +``` + +> Every 3D fileformat supports named 3D object, and this name allows URLs (fragments) to reference them (and their children objects). + +Clever nested design of 3D scenes allow great ways for re-using content, and/or previewing scenes.
    +For example, to render a portal with a preview-version of the scene, create an 3D object with: + +* href: `https://scene.fbx` +* src: `https://otherworld.gltf#mainobject` + +> It also allows **sourceportation**, which basically means the enduser can teleport to the original XR Document of an `src` embedded object, and see a visible connection to the particular embedded object. Basically an embedded link becoming an outbound link by activating it. + + +--- + +# non-normative + +The following below is non-normative heuristics which are not part officially part of the spec. + +# additional **explicit** metadata + +| `#rot` | vector3 | `#rot=0,90,0` | rotates camera to xyz-coord 0.5,0,0 | | `src` | string | `"src": "#cube"` | XR embed / teleport | custom property in 3D fileformats | | `tag` | string | `"tag": "cubes geo"` | tag object (for filter-use / XRWG highlighting) | custom property in 3D fileformats | | `#` | string | `"#": "#mypreset` | trigger default fragment on load | custom property in 3D fileformats | @@ -259,106 +363,16 @@ The sidecar will define (or **override** already existing) extras, which can be -# Hypermediatic FeedbackLoop for XR browsers - -`href` metadata traditionally implies **click** AND **navigate**, however XR Fragments adds stateless **click** (`xrf://#....`) or **navigate** (`xrf://#pos=...`) - as well (which allows many extra interactions which otherwise need a scripting language). This is known as **hashbus**-only events (see image above). - -> Being able to use the same URI Fragment DSL for navigation (`href: #foo`) as well as interactions (`href: xrf://#bar`) greatly simplifies implementation, increases HFL, and reduces need for scripting languages. - -This opens up the following benefits for traditional & future webbrowsers: - -* [hypermediatic](https://github.com/coderofsalvation/hypermediatic) loading/clicking 3D assets (gltf/fbx e.g.) natively (with or without using HTML). -* allowing 3D assets/nodes to publish XR Fragments to themselves/eachother using the `xrf://` hashbus -* collapsing the 3D scene to an wordgraph (for essential navigation purposes) controllable thru a hash(tag)bus -* completely bypassing the security-trap of loading external scripts (by loading 3D model-files, not HTML-javascriptable resources) - - -XR Fragments itself are [hypermediatic](https://github.com/coderofsalvation/hypermediatic) and HTML-agnostic, though pseudo-XR Fragment browsers **can** be implemented on top of HTML/Javascript. - -| principle | XR 4D URL | HTML 2D URL | -|-----------------------------|-------------------------------------------------|---------------------------------------| -| the XRWG | wordgraph (collapses 3D scene to tags) | Ctrl-F (find) | -| the hashbus | hashtags alter camera/scene/object-projections | hashtags alter document positions | -| src metadata | renders content and offers sourceportation | renders content | -| href metadata | teleports to other XR document | jumps to other HTML document | -| href metadata | triggers predefined view | Media fragments | -| href metadata | triggers camera/scene/object/projections | n/a | -| href metadata | draws visible connection(s) for XRWG 'tag' | n/a | -| href metadata | filters certain (in)visible objects | n/a | -| href metadata | href="xrf://#-foo&bar" | href="javascript:hideFooAndShowBar()` | -| | (this does not update topLevel URI) | (this is non-standard, non-hypermediatic) | - -> An important aspect of HFL is that URI Fragments can be triggered without updating the top-level URI (default href-behaviour) thru their own 'bus' (`xrf://#.....`). This decoupling between navigation and interaction prevents non-standard things like (`href`:`javascript:dosomething()`). - -# Conventions and Definitions - -See appendix below in case certain terms are not clear. - -## XR Fragment URL Grammar - -For typical HTTP-like browsers/applications: - -``` -reserved = gen-delims / sub-delims -gen-delims = "#" / "&" -sub-delims = "," / "=" -``` - -> Example: `://foo.com/my3d.gltf#pos=1,0,0&prio=-5&t=0,100` - -| Demo | Explanation | -|-------------------------------|---------------------------------| -| `pos=1,2,3` | vector/coordinate argument e.g. | -| `pos=1,2,3&rot=0,90,0&foo` | combinators | - -> this is already implemented in all browsers - -Pseudo (non-native) browser-implementations (supporting XR Fragments using HTML+JS e.g.) can use the `?` search-operator to address outbound content.
    -In other words, the URL updates to: `https://me.com?https://me.com/other.glb` when navigating to `https://me.com/other.glb` from inside a `https://me.com` WebXR experience e.g.
    -That way, if the link gets shared, the XR Fragments implementation at `https://me.com` can load the latter (and still indicates which XR Fragments entrypoint-experience/client was used). - -# Spatial Referencing 3D - -XR Fragments assume the following objectname-to-URIFragment mapping: - -``` - - my.io/scene.fbx - +─────────────────────────────+ - │ sky │ src: http://my.io/scene.fbx#sky (includes building,mainobject,floor) - │ +─────────────────────────+ │ - │ │ building │ │ src: http://my.io/scene.fbx#building (includes mainobject,floor) - │ │ +─────────────────────+ │ │ - │ │ │ mainobject │ │ │ src: http://my.io/scene.fbx#mainobject (includes floor) - │ │ │ +─────────────────+ │ │ │ - │ │ │ │ floor │ │ │ │ src: http://my.io/scene.fbx#floor (just floor object) - │ │ │ │ │ │ │ │ - │ │ │ +─────────────────+ │ │ │ - │ │ +─────────────────────+ │ │ - │ +─────────────────────────+ │ - +─────────────────────────────+ - -``` - -> Every 3D fileformat supports named 3D object, and this name allows URLs (fragments) to reference them (and their children objects). - -Clever nested design of 3D scenes allow great ways for re-using content, and/or previewing scenes.
    -For example, to render a portal with a preview-version of the scene, create an 3D object with: - -* href: `https://scene.fbx` -* src: `https://otherworld.gltf#mainobject` - -> It also allows **sourceportation**, which basically means the enduser can teleport to the original XR Document of an `src` embedded object, and see a visible connection to the particular embedded object. Basically an embedded link becoming an outbound link by activating it. - ## Level2: Implicit URI Fragments +> Warning: non-normative + These fragments are derived from objectnames (or their extras) within a 3D scene, and trigger certain actions when evaluated by the browser: | |fragment | type | example | info | |------|------------------|----------|-------------------|-------------------------------------------------------------------------------| | **PRESET** | `#` | string | `#cubes` | evaluates preset (`#foo&bar`) when a scene contains extra (`#cubes: #foo&bar` e.g.) while URL-browserbar reflects `#cubes`. Only works when metadata-key starts with `#` | -| **FOCUS** | `#` | string | `#person` | (and show) object(s) with `tag: person` or name `person` (XRWG lookup) | +| **FOCUS** | `xrf://#` | string | `#person` | (and show) object(s) with `tag: person` or name `person` (XRWG lookup) | | **FILTERS** | `#[!][-][*]` | string | `#person` (`#-person`) | will reset (`!`), show/focus or hide (`-`) focus object(s) with `tag: person` or name `person` by looking up XRWG (`*`=including children) | | **MATERIALUPDATE** | `#[*]=` | string=string | `#car=metallic`| sets material of car to material with name `metallic` (`*`=including children)| | | | | `#soldout*=halfopacity`| set material of objects tagged with `product` to material with name `metallic` | @@ -367,7 +381,7 @@ These fragments are derived from objectnames (or their extras) within a 3D scene ## media fragments and datatypes -> NOTE: below the word 'play' applies to 3D animations embedded in the 3D scene(file) **but also** media defined in `src`-metadata like audio/video-files (mp3/mp4 e.g.) +> Warning: **non-normative** (below the word 'play' applies to 3D animations embedded in the 3D scene(file) **but also** media defined in `src`-metadata like audio/video-files (mp3/mp4 e.g.)) | type | syntax | example | info | |-------------------------------|-----------------------------------|-----------------|----------------------| @@ -456,7 +470,7 @@ Here's an ascii representation of a 3D scene-graph which contains 3D objects ` │ index.gltf │ │ │ │ │ ├── ◻ buttonA │ - │ │ └ href: #pos=1,0,1&t=100,200 │ + │ │ └ href: #room1&t=100,200 │ │ │ │ │ └── ◻ buttonB │ │ └ href: other.fbx │ <── file─agnostic (can be .gltf .obj etc) @@ -466,23 +480,27 @@ Here's an ascii representation of a 3D scene-graph which contains 3D objects ` ``` An XR Fragment-compatible browser viewing this scene, allows the end-user to interact with the `buttonA` and `buttonB`.
    -In case of `buttonA` the end-user will be teleported to another location and time in the **current loaded scene**, but `buttonB` will **replace the current scene** with a new one, like `other.fbx`, and assume `pos=0,0,0`. +In case of `buttonA` the end-user will be teleported to another location and time in the **current loaded scene**, but `buttonB` will **replace the current scene** with a new one, like `other.fbx`, and assume camera coordinate `0,0,0` # Top-level URL processing -> Example URL: `://foo/world.gltf#cube&pos=0,0,0` +> Example URL: `://foo/world.gltf#room1&t=10` The URL-processing-flow for hypermedia browsers goes like this: -1. IF a `#cube` matches a custom property-key (of an object) in the 3D file/scene (`#cube`: `#......`) THEN execute that predefined_view. -2. IF scene operators (`pos`) and/or animation operator (`t`) are present in the URL then (re)position the camera and/or animation-range accordingly. -3. IF no camera-position has been set in step 1 or 2 update the top-level URL with `#pos=0,0,0` ([example](https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/navigator.js#L31]])) +1. IF a `#room1` matches a custom property-key (of an object) in the 3D file/scene (`#room1`: `#......`) THEN execute that predefined_view. +2. IF scene operators and/or animation operator (`t`) are present in the URL then (re)position the camera (to `room1`) and/or animation-range (`10`) accordingly. +3. IF no camera-position has been set in step 1 or 2 assume `0,0,0` as camera coordinate (XR: add user-height) ([example](https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/navigator.js#L31]])) + +**Non-normative / Deprecated**: + 4. IF a `#cube` matches the name (of an object) in the 3D file/scene then draw a line from the enduser('s heart) to that object (to highlight it). 5. IF a `#cube` matches anything else in the XR Word Graph (XRWG) draw wires to them (text or related objects). - # Embedding XR content using src +> NOTE: only adviced for local-first experiences (where resources can be cached). + `src` is the 3D version of the iframe.
    It instances content (in objects) in the current scene/asset, and follows similar logic like the previous chapter, except that it does not modify the camera. @@ -551,11 +569,11 @@ navigation, portals & mutations | fragment | type | example value | |----------|---------------------------------|---------------------------------------------------------------------------------------------------------------------------| -|`href` | string (uri or predefined view) | `#pos=1,1,0`
    `#pos=1,1,0&rot=90,0,0`
    `://somefile.gltf#pos=1,1,0`
    | +|`href` | string (uri or predefined view) | `#room1`
    `#pos=room1&rot=90,0,0`
    `://somefile.gltf#room1`
    | -1. clicking an outbound ''external''- or ''file URI'' fully replaces the current scene and assumes `pos=0,0,0&rot=0,0,0` by default (unless specified) +1. clicking an outbound ''external''- or ''file URI'' fully replaces the current scene and assumes `room2&rot=0,0,0` by default (unless specified) -2. relocation/reorientation should happen locally for local URI's (`#pos=....`) +2. relocation/reorientation should happen locally for local URI's (`#....`) 3. navigation should not happen ''immediately'' when user is more than 5 meter away from the portal/object containing the href (to prevent accidental navigation e.g.) @@ -567,9 +585,9 @@ navigation, portals & mutations 7. ignore previous rule in special cases, like clicking an `href` using camera-portal collision (the back-button could cause a teleport-loop if the previous position is too close) -8. href-events should bubble upward the node-tree (from children to ancestors, so that ancestors can also contain an href), however only 1 href can be executed at the same time. +8. href-events should bubble upward the node-tree (from children to ancestors, so that ancestors can also conain an href), however only 1 href can be executed at the same time. -9. the end-user navigator back/forward buttons should repeat a back/forward action until a `pos=...` primitive is found (the stateless xrf:// href-values should not be pushed to the url-history) +9. the end-user navigator back/forward buttons should repeat a back/forward action until a `#...` primitive is found (the stateless xrf:// href-values should not be pushed to the url-history) [» example implementation](https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/href.js)
    [» example 3D asset](https://github.com/coderofsalvation/xrfragment/blob/main/example/assets/href.gltf#L192)
    @@ -1000,19 +1018,18 @@ Spec:

    4. the textlog contains `aria-descriptions`, and its narration (Screenreader e.g.) can be skipped (via 2-button navigation) 5. The `back` command should navigate back to the previous URL (alias for browser-backbutton) 6. The `forward` command should navigate back to the next URL (alias for browser-nextbutton) -7. A destination is a 3D node containing an `href` with a `pos=` XR fragment +7. A destination is a 3D node containing an `href` with a `#...` XR fragment (which matches a 3d object name) 8. The `go` command should list all possible destinations 9. The `go left` command should move the camera around 0.3 meters to the left 10. The `go right` command should move the camera around 0.3 meters to the right 11. The `go forward` command should move the camera 0.3 meters forward (direction of current rotation). 12. The `rotate left` command should rotate the camera 0.3 to the left 13. The `rotate left` command should rotate the camera 0.3 to the right -14. The (dynamic) `go abc` command should navigate to `#pos=scene2` in case there's a 3D node with name `abc` and `href` value `#pos=scene2` -15. The `look` command should give an (contextual) 3D-to-text transcript, by scanning the `aria-description` values of the current `pos=` value (including its children) -16. The `do` command should list all possible `href` values which don't contain an `pos=` XR Fragment +14. The (dynamic) `go abc` command should navigate to `#scene2` in case there's a 3D node with name `abc` and `href` value `#scene2` +15. The `look` command should give an (contextual) 3D-to-text transcript, by scanning the `aria-description` values of the current `#...` (3D object) value (including its children) +16. The `do` command should list all possible `href` values which don't contain an `#...` XR Fragment 17. The (dynamic) `do abc` command should navigate/execute `https://.../...` in case a 3D node exist with name `abc` and `href` value `https://.../...` - ## Two-button navigation For specific user-profiles, gyroscope/mouse/keyboard/audio/visuals will not be available.
    @@ -1154,7 +1171,7 @@ This document has no IANA actions. |URL | something somewhere via someprotocol (`http://me.com/foo.glb`) | |URN | something at some domain (`me.com/foo.glb`) | |metadata | custom properties of text, 3D Scene or Object(nodes), relevant to machines and a human minority (academics/developers) | -|XR fragment | URI Fragment with spatial hints like `#pos=0,0,0&t=1,100` e.g. | +|XR fragment | URI Fragment with spatial hints (which match the name of a 3D object-, camera-, animation-object) | |the XRWG | wordgraph (collapses 3D scene to tags) | |the hashbus | hashtags map to camera/scene-projections | |spacetime hashtags | positions camera, triggers scene-preset/time | diff --git a/doc/RFC_XR_Fragments.txt b/doc/RFC_XR_Fragments.txt index 2639bb4..8356af8 100644 --- a/doc/RFC_XR_Fragments.txt +++ b/doc/RFC_XR_Fragments.txt @@ -3,7 +3,7 @@ Jens & Leon Internet Engineering Task Force L.R. van Kammen -Internet-Draft 14 October 2024 +Internet-Draft 1 September 2025 Intended status: Informational @@ -13,6 +13,7 @@ Intended status: Informational Abstract + An open specification for hyperlinking & deeplinking 3D fileformats. This draft is a specification for interactive URI-controllable 3D files, enabling hypermediatic (https://github.com/coderofsalvation/ hypermediatic) navigation, to enable a spatial web for hypermedia @@ -21,16 +22,16 @@ Abstract media-frags/) and URI Templates (RFC6570) (https://www.rfc- editor.org/rfc/rfc6570) to promote spatial addressibility, sharing, navigation, filtering and databinding objects for (XR) Browsers. - XR Fragments allows us to better use existing metadata inside 3D - scene(files), by connecting it to proven technologies like URI - Fragments (https://en.wikipedia.org/wiki/URI_fragment). - XR Fragments views spatial webs thru the lens of 3D scene URI's, + XR Fragments allows us to better use implicit metadata inside 3D + scene(files), by mapping it to proven technologies like URI Fragments + (https://en.wikipedia.org/wiki/URI_fragment). + XR Fragments views XR experiences thru the lens of 3D object URI's, rather than thru code(frameworks) or protocol-specific browsers (webbrowser e.g.). - XR Fragments is a Meta scene format which leverages heuristic - rules derived from any 3D scene or well-established 3D file formats, - to extract meaningful features from scene hierarchies. + XR Fragments is a heuristical 3D format which leverages + heuristic rules derived from any 3D scene or well-established 3D file + formats, to extract meaningful features from scene hierarchies. These heuristics, enable features that are both meaningful and consistent across different scene representations, allowing higher interop between fileformats, 3D editors, viewers and game- @@ -52,10 +53,9 @@ Status of This Memo - -van Kammen Expires 17 April 2025 [Page 1] +van Kammen Expires 5 March 2026 [Page 1] -Internet-Draft XR Fragments October 2024 +Internet-Draft XR Fragments September 2025 Internet-Drafts are draft documents valid for a maximum of six months @@ -63,11 +63,11 @@ Internet-Draft XR Fragments October 2024 time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress." - This Internet-Draft will expire on 17 April 2025. + This Internet-Draft will expire on 5 March 2026. Copyright Notice - Copyright (c) 2024 IETF Trust and the persons identified as the + Copyright (c) 2025 IETF Trust and the persons identified as the document authors. All rights reserved. This document is subject to BCP 78 and the IETF Trust's Legal @@ -86,55 +86,57 @@ Table of Contents 3. The XR Fragments Trinity . . . . . . . . . . . . . . . . . . 5 4. List of URI Fragments . . . . . . . . . . . . . . . . . . . . 6 5. List of *_explicit_ metadata . . . . . . . . . . . . . . . . 6 - 5.1. Sidecar-file . . . . . . . . . . . . . . . . . . . . . . 7 - 6. Hypermediatic FeedbackLoop for XR browsers . . . . . . . . . 8 - 7. Conventions and Definitions . . . . . . . . . . . . . . . . . 10 - 7.1. XR Fragment URL Grammar . . . . . . . . . . . . . . . . . 10 - 8. Spatial Referencing 3D . . . . . . . . . . . . . . . . . . . 10 - 8.1. Level2: Implicit URI Fragments . . . . . . . . . . . . . 11 - 8.2. media fragments and datatypes . . . . . . . . . . . . . . 13 - 9. Navigating 3D . . . . . . . . . . . . . . . . . . . . . . . . 16 - 10. Top-level URL processing . . . . . . . . . . . . . . . . . . 17 - 11. Embedding XR content using src . . . . . . . . . . . . . . . 18 - 12. Navigating content href portals . . . . . . . . . . . . . . . 20 - 12.1. Walking surfaces . . . . . . . . . . . . . . . . . . . . 21 - 12.2. UX spec . . . . . . . . . . . . . . . . . . . . . . . . 22 - 12.3. Scaling instanced content . . . . . . . . . . . . . . . 22 - 13. XR Fragment: pos . . . . . . . . . . . . . . . . . . . . . . 22 - 14. XR Fragment: rot . . . . . . . . . . . . . . . . . . . . . . 23 - 15. XR Fragment: t . . . . . . . . . . . . . . . . . . . . . . . 23 - 16. XR audio/video integration . . . . . . . . . . . . . . . . . 23 - 17. XR Fragment filters . . . . . . . . . . . . . . . . . . . . . 23 - 17.1. including/excluding . . . . . . . . . . . . . . . . . . 24 + 6. HFL (Hypermediatic Feedback Loop) for XR Browsers . . . . . . 6 + 7. Conventions and Definitions . . . . . . . . . . . . . . . . . 9 + 7.1. XR Fragment URL Grammar . . . . . . . . . . . . . . . . . 9 + 8. Spatial Referencing 3D . . . . . . . . . . . . . . . . . . . 9 + 9. non-normative . . . . . . . . . . . . . . . . . . . . . . . . 10 + 10. additional *explicit* metadata . . . . . . . . . . . . . . . 10 + 10.1. Sidecar-file . . . . . . . . . . . . . . . . . . . . . . 11 + 10.2. Level2: Implicit URI Fragments . . . . . . . . . . . . . 11 + 10.3. media fragments and datatypes . . . . . . . . . . . . . 13 + 11. Navigating 3D . . . . . . . . . . . . . . . . . . . . . . . . 16 + 12. Top-level URL processing . . . . . . . . . . . . . . . . . . 18 + 13. Embedding XR content using src . . . . . . . . . . . . . . . 18 + 14. Navigating content href portals . . . . . . . . . . . . . . . 21 + 14.1. Walking surfaces . . . . . . . . . . . . . . . . . . . . 22 + 14.2. UX spec . . . . . . . . . . . . . . . . . . . . . . . . 22 + 14.3. Scaling instanced content . . . . . . . . . . . . . . . 23 + 15. XR Fragment: pos . . . . . . . . . . . . . . . . . . . . . . 23 + 16. XR Fragment: rot . . . . . . . . . . . . . . . . . . . . . . 23 + 17. XR Fragment: t . . . . . . . . . . . . . . . . . . . . . . . 24 + 18. XR audio/video integration . . . . . . . . . . . . . . . . . 24 -van Kammen Expires 17 April 2025 [Page 2] +van Kammen Expires 5 March 2026 [Page 2] -Internet-Draft XR Fragments October 2024 +Internet-Draft XR Fragments September 2025 - 17.2. Filter Parser . . . . . . . . . . . . . . . . . . . . . 25 - 18. Visible links . . . . . . . . . . . . . . . . . . . . . . . . 26 - 19. Text in XR (tagging,linking to spatial objects) . . . . . . . 26 - 19.1. Default Data URI mimetype . . . . . . . . . . . . . . . 29 - 19.2. URL and Data URI . . . . . . . . . . . . . . . . . . . . 30 - 20. Importing/exporting . . . . . . . . . . . . . . . . . . . . . 31 - 21. Reflection Mapping . . . . . . . . . . . . . . . . . . . . . 31 - 22. Transclusion (broken link) resolution . . . . . . . . . . . . 31 - 23. Topic-based index-less Webrings . . . . . . . . . . . . . . . 32 - 24. URI Templates (RFC6570) . . . . . . . . . . . . . . . . . . . 33 - 25. Additional scene metadata . . . . . . . . . . . . . . . . . . 33 - 26. Accessibility interface . . . . . . . . . . . . . . . . . . . 35 - 26.1. Two-button navigation . . . . . . . . . . . . . . . . . 35 - 26.2. Overlap with fileformat-specific extensions . . . . . . 36 - 26.3. Vendor Prefixes . . . . . . . . . . . . . . . . . . . . 36 - 27. Security Considerations . . . . . . . . . . . . . . . . . . . 39 - 28. FAQ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 - 29. authors . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 - 30. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 40 - 31. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 40 - 32. Appendix: Definitions . . . . . . . . . . . . . . . . . . . . 40 + 19. XR Fragment filters . . . . . . . . . . . . . . . . . . . . . 24 + 19.1. including/excluding . . . . . . . . . . . . . . . . . . 25 + 19.2. Filter Parser . . . . . . . . . . . . . . . . . . . . . 26 + 20. Visible links . . . . . . . . . . . . . . . . . . . . . . . . 26 + 21. Text in XR (tagging,linking to spatial objects) . . . . . . . 27 + 21.1. Default Data URI mimetype . . . . . . . . . . . . . . . 29 + 21.2. URL and Data URI . . . . . . . . . . . . . . . . . . . . 30 + 22. Importing/exporting . . . . . . . . . . . . . . . . . . . . . 31 + 23. Reflection Mapping . . . . . . . . . . . . . . . . . . . . . 31 + 24. Transclusion (broken link) resolution . . . . . . . . . . . . 31 + 25. Topic-based index-less Webrings . . . . . . . . . . . . . . . 32 + 26. URI Templates (RFC6570) . . . . . . . . . . . . . . . . . . . 33 + 27. Additional scene metadata . . . . . . . . . . . . . . . . . . 33 + 28. Accessibility interface . . . . . . . . . . . . . . . . . . . 35 + 28.1. Two-button navigation . . . . . . . . . . . . . . . . . 36 + 28.2. Overlap with fileformat-specific extensions . . . . . . 36 + 28.3. Vendor Prefixes . . . . . . . . . . . . . . . . . . . . 37 + 29. Security Considerations . . . . . . . . . . . . . . . . . . . 39 + 30. FAQ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 + 31. authors . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 + 32. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 40 + 33. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 40 + 34. Appendix: Definitions . . . . . . . . . . . . . . . . . . . . 40 1. Introduction @@ -160,16 +162,16 @@ Internet-Draft XR Fragments October 2024 Word Graph (XRWG) to show visible links (#visible-links) 3. unlocking spatial potential of the (originally 2D) hashtag (which jumps to a chapter) for navigating XR documents + + + +van Kammen Expires 5 March 2026 [Page 3] + +Internet-Draft XR Fragments September 2025 + + 4. refraining from introducing scripting-engines for mundane tasks (and preventing its inevitable security-headaches) - - - -van Kammen Expires 17 April 2025 [Page 3] - -Internet-Draft XR Fragments October 2024 - - 5. the gap between text an 3d objects: object-names directly map to hashtags (=fragments), which allows 3D to text transcription. @@ -216,16 +218,16 @@ Internet-Draft XR Fragments October 2024 | But approaches things from a higherlevel feedbackloop/hypermedia | browser-perspective. - Below you can see how this translates back into good-old URLs: - -van Kammen Expires 17 April 2025 [Page 4] +van Kammen Expires 5 March 2026 [Page 4] -Internet-Draft XR Fragments October 2024 +Internet-Draft XR Fragments September 2025 + Below you can see how this translates back into good-old URLs: + +───────────────────────────────────────────────────────────────────────────────────────────────+ │ │ │ the soul of any URL: ://macro /meso ?micro #nano │ @@ -275,38 +277,31 @@ Internet-Draft XR Fragments October 2024 - - -van Kammen Expires 17 April 2025 [Page 5] +van Kammen Expires 5 March 2026 [Page 5] -Internet-Draft XR Fragments October 2024 +Internet-Draft XR Fragments September 2025 4. List of URI Fragments - +=======================+======================================+============+=============+ - |fragment |type |example |info | - +=======================+======================================+============+=============+ - |#pos |vector3 |#pos=0.5,0,0|positions/ | - | | |#pos=room |parents | - | | |#pos=cam2 |camera(rig) | - | | | |(or XR floor)| - | | | |to xyz- | - | | | |coord/object/| - | | | |camera | - +-----------------------+--------------------------------------+------------+-------------+ - |#rot |vector3 |#rot=0,90,0 |rotates | - | | | |camera to | - | | | |xyz-coord | - | | | |0.5,0,0 | - +-----------------------+--------------------------------------+------------+-------------+ - |Media Fragments |media fragment |#t=0,2&loop |play (and | - |(https://www.w3.org/TR/|(#media%20fragments%20and%20datatypes)| |loop) 3D | - |media-frags/) | | |animation | - | | | |from 0 | - | | | |seconds till | - | | | |2 seconds | - +-----------------------+--------------------------------------+------------+-------------+ + +=======================+======================================+===========+=============+ + |fragment |type |example |info | + +=======================+======================================+===========+=============+ + |#...... |vector3 |#room1 |positions/ | + | | |#room2 |parents | + | | |#cam2 |camera(rig) | + | | | |(or XR floor)| + | | | |to xyz- | + | | | |coord/object/| + | | | |camera | + +-----------------------+--------------------------------------+-----------+-------------+ + |Media Fragments |media fragment |#t=0,2&loop|play (and | + |(https://www.w3.org/TR/|(#media%20fragments%20and%20datatypes)| |loop) 3D | + |media-frags/) | | |animation | + | | | |from 0 | + | | | |seconds till | + | | | |2 seconds | + +-----------------------+--------------------------------------+-----------+-------------+ Table 1 @@ -314,121 +309,35 @@ Internet-Draft XR Fragments October 2024 These are the possible 'extras' for 3D nodes and sidecar-files - - - - - - - - - - - - - - - - - - - -van Kammen Expires 17 April 2025 [Page 6] - -Internet-Draft XR Fragments October 2024 - - - +======+========+============+===================+================+ - | key | type | example | function | existing | - | | | (JSON) | | compatibility | - +======+========+============+===================+================+ - | href | string | "href": | XR teleport | custom | - | | | "b.gltf" | | property in 3D | - | | | | | fileformats | - +------+--------+------------+-------------------+----------------+ - | src | string | "src": | XR embed / | custom | - | | | "#cube" | teleport | property in 3D | - | | | | | fileformats | - +------+--------+------------+-------------------+----------------+ - | tag | string | "tag": | tag object (for | custom | - | | | "cubes | filter-use / XRWG | property in 3D | - | | | geo" | highlighting) | fileformats | - +------+--------+------------+-------------------+----------------+ - | # | string | "#": | trigger default | custom | - | | | "#mypreset | fragment on load | property in 3D | - | | | | | fileformats | - +------+--------+------------+-------------------+----------------+ + +======+========+================+==========+===================+ + | key | type | example (JSON) | function | existing | + | | | | | compatibility | + +======+========+================+==========+===================+ + | href | string | "href": | XR | custom property | + | | | "b.gltf" | teleport | in 3D fileformats | + +------+--------+----------------+----------+-------------------+ Table 2 - | Supported popular compatible 3D fileformats: .gltf, .obj, .fbx, - | .usdz, .json (THREE.js), .dae and so on. - -5.1. Sidecar-file - - | NOTE: sidecar-files break the portability of XR (Fragments) - | experiences, therefore side-car files are discouraged for consumer - | usage/sharing. However, they can accomodate developers or - | applications who (for whatever reason) must not modify the 3D - | scene-file (a .glb e.g.). - - For developers, sidecar-file can allow for defining *explicit* XR - Fragments metadata, outside of the 3D file. - This can be done via a JSON-pointers RFC6901 (https://www.rfc- - editor.org/rfc/rfc6901) in a JSON sidecar-file - (https://en.wikipedia.org/wiki/Sidecar_file): - - * experience.glb - * experience.json - - - - - - - - - -van Kammen Expires 17 April 2025 [Page 7] - -Internet-Draft XR Fragments October 2024 - - - { - "/":{ - "#": "#-penguin", - "aria-description": "description of scene", - }, - "/room/chair": { - "href": "#penguin" - } - } - - | This would mean: hide object(s) with name or tag-value 'penguin' - | upon scene-load, and show it when the user clicks the chair - - So after loading experience.glb the existence of experience.json is - detected, to apply the explicit metadata. - The sidecar will define (or *override* already existing) extras, - which can be handy for multi-user platforms (offer 3D scene - customization/personalization to users). - - | In THREE.js-code this would boil down to: - - scene.userData['#'] = "#chair&penguin" - scene.userData['aria-description'] = "description of scene" - scene.getObjectByName("room").getObjectByName("chair").userData.href = "#penguin" - - // now the XR Fragments parser can process the XR Fragments userData 'extras' in the scene - -6. Hypermediatic FeedbackLoop for XR browsers +6. HFL (Hypermediatic Feedback Loop) for XR Browsers href metadata traditionally implies *click* AND *navigate*, however XR Fragments adds stateless *click* (xrf://#....) or *navigate* - (xrf://#pos=...) as well (which allows many extra interactions which + (xrf://#...) as well (which allows many extra interactions which otherwise need a scripting language). This is known as *hashbus*- only events (see image above). + + + + + + +van Kammen Expires 5 March 2026 [Page 6] + +Internet-Draft XR Fragments September 2025 + + | Being able to use the same URI Fragment DSL for navigation (href: | #foo) as well as interactions (href: xrf://#bar) greatly | simplifies implementation, increases HFL, and reduces need for @@ -441,15 +350,8 @@ Internet-Draft XR Fragments October 2024 loading/clicking 3D assets (gltf/fbx e.g.) natively (with or without using HTML). * allowing 3D assets/nodes to publish XR Fragments to themselves/ - eachother using the xrf:// hashbus - - - -van Kammen Expires 17 April 2025 [Page 8] - -Internet-Draft XR Fragments October 2024 - - + eachother using the xrf:// hashbus (xrf://#person=walk to trigger + walk-animation for object person) * collapsing the 3D scene to an wordgraph (for essential navigation purposes) controllable thru a hash(tag)bus * completely bypassing the security-trap of loading external scripts @@ -460,6 +362,38 @@ Internet-Draft XR Fragments October 2024 agnostic, though pseudo-XR Fragment browsers *can* be implemented on top of HTML/Javascript. + + + + + + + + + + + + + + + + + + + + + + + + + + + +van Kammen Expires 5 March 2026 [Page 7] + +Internet-Draft XR Fragments September 2025 + + +=========+======================+=====================================+ |principle|XR 4D URL |HTML 2D URL | +=========+======================+=====================================+ @@ -499,19 +433,23 @@ Internet-Draft XR Fragments October 2024 Table 3 - - -van Kammen Expires 17 April 2025 [Page 9] - -Internet-Draft XR Fragments October 2024 - - | An important aspect of HFL is that URI Fragments can be triggered | without updating the top-level URI (default href-behaviour) thru | their own 'bus' (xrf://#.....). This decoupling between | navigation and interaction prevents non-standard things like | (href:javascript:dosomething()). + + + + + + +van Kammen Expires 5 March 2026 [Page 8] + +Internet-Draft XR Fragments September 2025 + + 7. Conventions and Definitions See appendix below in case certain terms are not clear. @@ -524,17 +462,17 @@ Internet-Draft XR Fragments October 2024 gen-delims = "#" / "&" sub-delims = "," / "=" - | Example: ://foo.com/my3d.gltf#pos=1,0,0&prio=-5&t=0,100 + | Example: ://foo.com/my3d.gltf#room1&prio=-5&t=0,100 - +==========================+=================================+ - | Demo | Explanation | - +==========================+=================================+ - | pos=1,2,3 | vector/coordinate argument e.g. | - +--------------------------+---------------------------------+ - | pos=1,2,3&rot=0,90,0&foo | combinators | - +--------------------------+---------------------------------+ + +=======================+=================================+ + | Demo | Explanation | + +=======================+=================================+ + | room1 | vector/coordinate argument e.g. | + +-----------------------+---------------------------------+ + | room1&rot=0,90,0&cam1 | combinators | + +-----------------------+---------------------------------+ - Table 4 + Table 4 | this is already implemented in all browsers @@ -557,9 +495,15 @@ Internet-Draft XR Fragments October 2024 -van Kammen Expires 17 April 2025 [Page 10] + + + + + + +van Kammen Expires 5 March 2026 [Page 9] -Internet-Draft XR Fragments October 2024 +Internet-Draft XR Fragments September 2025 my.io/scene.fbx @@ -594,7 +538,85 @@ Internet-Draft XR Fragments October 2024 | embedded object. Basically an embedded link becoming an outbound | link by activating it. -8.1. Level2: Implicit URI Fragments +9. non-normative + + The following below is non-normative heuristics which are not part + officially part of the spec. + +10. additional *explicit* metadata + + | #rot | vector3 | #rot=0,90,0 | rotates camera to xyz-coord + 0.5,0,0 | | src | string | "src": "#cube" | XR embed / teleport | + custom property in 3D fileformats | | tag | string | "tag": "cubes + geo" | tag object (for filter-use / XRWG highlighting) | custom + property in 3D fileformats | | # | string | "#": "#mypreset | trigger + default fragment on load | custom property in 3D fileformats | + + | Supported popular compatible 3D fileformats: .gltf, .obj, .fbx, + | .usdz, .json (THREE.js), .dae and so on. + + + +van Kammen Expires 5 March 2026 [Page 10] + +Internet-Draft XR Fragments September 2025 + + +10.1. Sidecar-file + + | NOTE: sidecar-files break the portability of XR (Fragments) + | experiences, therefore side-car files are discouraged for consumer + | usage/sharing. However, they can accomodate developers or + | applications who (for whatever reason) must not modify the 3D + | scene-file (a .glb e.g.). + + For developers, sidecar-file can allow for defining *explicit* XR + Fragments metadata, outside of the 3D file. + This can be done via a JSON-pointers RFC6901 (https://www.rfc- + editor.org/rfc/rfc6901) in a JSON sidecar-file + (https://en.wikipedia.org/wiki/Sidecar_file): + + * experience.glb + * experience.json + + { + "/":{ + "#": "#-penguin", + "aria-description": "description of scene", + }, + "/room/chair": { + "href": "#penguin" + } + } + + | This would mean: hide object(s) with name or tag-value 'penguin' + | upon scene-load, and show it when the user clicks the chair + + So after loading experience.glb the existence of experience.json is + detected, to apply the explicit metadata. + The sidecar will define (or *override* already existing) extras, + which can be handy for multi-user platforms (offer 3D scene + customization/personalization to users). + + | In THREE.js-code this would boil down to: + + scene.userData['#'] = "#chair&penguin" + scene.userData['aria-description'] = "description of scene" + scene.getObjectByName("room").getObjectByName("chair").userData.href = "#penguin" + + // now the XR Fragments parser can process the XR Fragments userData 'extras' in the scene + +10.2. Level2: Implicit URI Fragments + + | Warning: non-normative + + + + +van Kammen Expires 5 March 2026 [Page 11] + +Internet-Draft XR Fragments September 2025 + These fragments are derived from objectnames (or their extras) within a 3D scene, and trigger certain actions when evaluated by the @@ -610,17 +632,9 @@ Internet-Draft XR Fragments October 2024 | | | | |URL-browserbar reflects| | | | | |#cubes. Only works | | | | | |when metadata-key | - - - -van Kammen Expires 17 April 2025 [Page 11] - -Internet-Draft XR Fragments October 2024 - - | | | | |starts with # | +----------------+--------------------------------------+-------------+---------------------+-----------------------+ - |*FOCUS* |# |string |#person |(and show) object(s) | + |*FOCUS* |xrf://# |string |#person |(and show) object(s) | | | | | |with tag: person or | | | | | |name person (XRWG | | | | | |lookup) | @@ -652,6 +666,14 @@ Internet-Draft XR Fragments October 2024 | | | | |e.g.), This allows for | | | | | |reactive URI Template | | | | | |(https://www.rfc- | + + + +van Kammen Expires 5 March 2026 [Page 12] + +Internet-Draft XR Fragments September 2025 + + | | | | |editor.org/rfc/rfc6570)| | | | | |defined in object | | | | | |metadata elsewhere | @@ -666,24 +688,16 @@ Internet-Draft XR Fragments October 2024 | | | | |with # | +----------------+--------------------------------------+-------------+---------------------+-----------------------+ |*ANIMATION* |#= |string=string|#people=walk |assign a different | - - - -van Kammen Expires 17 April 2025 [Page 12] - -Internet-Draft XR Fragments October 2024 - - | | | |#people=noanim |animation to object(s) | +----------------+--------------------------------------+-------------+---------------------+-----------------------+ Table 5 -8.2. media fragments and datatypes +10.3. media fragments and datatypes - | NOTE: below the word 'play' applies to 3D animations embedded in - | the 3D scene(file) *but also* media defined in src-metadata like - | audio/video-files (mp3/mp4 e.g.) + | Warning: *non-normative* (below the word 'play' applies to 3D + | animations embedded in the 3D scene(file) *but also* media defined + | in src-metadata like audio/video-files (mp3/mp4 e.g.)) +===========+======================+===============+================+ | type | syntax | example | info | @@ -708,6 +722,14 @@ Internet-Draft XR Fragments October 2024 | W3C media | | | speed of | | fragment | | | audio/ | | * | | | video/3D anim | + + + +van Kammen Expires 5 March 2026 [Page 13] + +Internet-Draft XR Fragments September 2025 + + +-----------+----------------------+---------------+----------------+ | temporal | [-]loop | loop | enable looped | | W3C media | | | playback of | @@ -722,14 +744,6 @@ Internet-Draft XR Fragments October 2024 | | | | playbackstate | | | | | of media) | +-----------+----------------------+---------------+----------------+ - - - -van Kammen Expires 17 April 2025 [Page 13] - -Internet-Draft XR Fragments October 2024 - - | vector2 | uv=u,v,uspeed,vspeed | 0,0 | set uv offset | | | | | instantly | | | | | (default | @@ -764,6 +778,14 @@ Internet-Draft XR Fragments October 2024 | | | | coordinates | +-----------+----------------------+---------------+----------------+ | media | u:= NOTE: URI Template variables are immutable and respect scope: in other words, the end-user cannot modify `blue` by entering an URL like `#blue=.....` in the browser URL, and `blue` is not accessible by the plane/media-object (however `{play}` would work). - - - - - - - - - -van Kammen Expires 17 April 2025 [Page 15] - -Internet-Draft XR Fragments October 2024 - - -9. Navigating 3D +11. Navigating 3D +====================+=========+==========================+ | fragment | type | functionality | @@ -865,6 +891,13 @@ Internet-Draft XR Fragments October 2024 » discussion (https://github.com/coderofsalvation/xrfragment/ issues/5) + + +van Kammen Expires 5 March 2026 [Page 16] + +Internet-Draft XR Fragments September 2025 + + Here's the basic *level1* flow (with optional level2 features): 1. the Y-coordinate of pos identifies the floorposition. This @@ -891,13 +924,6 @@ Internet-Draft XR Fragments October 2024 10. in case a href does not mention any pos-coordinate, the current position will be assumed - - -van Kammen Expires 17 April 2025 [Page 16] - -Internet-Draft XR Fragments October 2024 - - Here's an ascii representation of a 3D scene-graph which contains 3D objects ◻ and their metadata: @@ -906,7 +932,7 @@ Internet-Draft XR Fragments October 2024 │ index.gltf │ │ │ │ │ ├── ◻ buttonA │ - │ │ └ href: #pos=1,0,1&t=100,200 │ + │ │ └ href: #room1&t=100,200 │ │ │ │ │ └── ◻ buttonB │ │ └ href: other.fbx │ <── file─agnostic (can be .gltf .obj etc) @@ -918,43 +944,45 @@ Internet-Draft XR Fragments October 2024 In case of buttonA the end-user will be teleported to another location and time in the *current loaded scene*, but buttonB will *replace the current scene* with a new one, like other.fbx, and - assume pos=0,0,0. + assume camera coordinate 0,0,0 -10. Top-level URL processing - | Example URL: ://foo/world.gltf#cube&pos=0,0,0 + + +van Kammen Expires 5 March 2026 [Page 17] + +Internet-Draft XR Fragments September 2025 + + +12. Top-level URL processing + + | Example URL: ://foo/world.gltf#room1&t=10 The URL-processing-flow for hypermedia browsers goes like this: - 1. IF a #cube matches a custom property-key (of an object) in the 3D - file/scene (#cube: #......) THEN execute that + 1. IF a #room1 matches a custom property-key (of an object) in the + 3D file/scene (#room1: #......) THEN execute that predefined_view. - 2. IF scene operators (pos) and/or animation operator (t) are - present in the URL then (re)position the camera and/or animation- - range accordingly. - 3. IF no camera-position has been set in step 1 or 2 update - the top-level URL with #pos=0,0,0 (example (https://github.com/co - derofsalvation/xrfragment/blob/main/src/3rd/js/three/ - navigator.js#L31]])) + 2. IF scene operators and/or animation operator (t) are present in + the URL then (re)position the camera (to room1) and/or animation- + range (10) accordingly. + 3. IF no camera-position has been set in step 1 or 2 assume + 0,0,0 as camera coordinate (XR: add user-height) (example (https: + //github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/ + three/navigator.js#L31]])) + + *Non-normative / Deprecated*: + 4. IF a #cube matches the name (of an object) in the 3D file/scene then draw a line from the enduser('s heart) to that object (to highlight it). 5. IF a #cube matches anything else in the XR Word Graph (XRWG) draw wires to them (text or related objects). +13. Embedding XR content using src - - - - - - -van Kammen Expires 17 April 2025 [Page 17] - -Internet-Draft XR Fragments October 2024 - - -11. Embedding XR content using src + | NOTE: only adviced for local-first experiences (where resources + | can be cached). src is the 3D version of the iframe. @@ -962,6 +990,26 @@ Internet-Draft XR Fragments October 2024 follows similar logic like the previous chapter, except that it does not modify the camera. + + + + + + + + + + + + + + + +van Kammen Expires 5 March 2026 [Page 18] + +Internet-Draft XR Fragments September 2025 + + +========+========+===================================================+ |fragment|type |example value | +========+========+===================================================+ @@ -1000,16 +1048,6 @@ Internet-Draft XR Fragments October 2024 │ │ +────────────────────────────────────────────────────────+ - - - - - -van Kammen Expires 17 April 2025 [Page 18] - -Internet-Draft XR Fragments October 2024 - - An XR Fragment-compatible browser viewing this scene, lazy-loads and projects painting.png onto the (plane) object called canvas (which is copy-instanced in the bed and livingroom). @@ -1019,6 +1057,15 @@ Internet-Draft XR Fragments October 2024 Resizing will be happen accordingly to its placeholder object aquariumcube, see chapter Scaling. + + + + +van Kammen Expires 5 March 2026 [Page 19] + +Internet-Draft XR Fragments September 2025 + + | Instead of cherrypicking a rootobject #fishbowl with src, | additional filters can be used to include/exclude certain objects. | See next chapter on filtering below. @@ -1058,14 +1105,6 @@ Internet-Draft XR Fragments October 2024 object belongs. 12. when only one object was cherrypicked (#cube e.g.), set its position to 0,0,0 - - - -van Kammen Expires 17 April 2025 [Page 19] - -Internet-Draft XR Fragments October 2024 - - 13. when the enduser clicks an href with #t=1,0,0 (play) will be applied to all src mediacontent with a timeline (mp4/mp3 e.g.) 14. a non-euclidian portal can be rendered for flat 3D objects @@ -1075,6 +1114,14 @@ Internet-Draft XR Fragments October 2024 * model/gltf-binary * model/gltf+json * image/png + + + +van Kammen Expires 5 March 2026 [Page 20] + +Internet-Draft XR Fragments September 2025 + + * image/jpg * text/plain;charset=utf-8 @@ -1087,41 +1134,31 @@ Internet-Draft XR Fragments October 2024 » discussion (https://github.com/coderofsalvation/xrfragment/ issues/4) -12. Navigating content href portals +14. Navigating content href portals navigation, portals & mutations - +==========+==================+============================+ - | fragment | type | example value | - +==========+==================+============================+ - | href | string (uri or | #pos=1,1,0 | - | | predefined view) | #pos=1,1,0&rot=90,0,0 | - | | | ://somefile.gltf#pos=1,1,0 | - +----------+------------------+----------------------------+ + +==========+==================+========================+ + | fragment | type | example value | + +==========+==================+========================+ + | href | string (uri or | #room1 | + | | predefined view) | #pos=room1&rot=90,0,0 | + | | | ://somefile.gltf#room1 | + +----------+------------------+------------------------+ Table 9 1. clicking an outbound ''external''- or ''file URI'' fully replaces - the current scene and assumes pos=0,0,0&rot=0,0,0 by default - (unless specified) + the current scene and assumes room2&rot=0,0,0 by default (unless + specified) 2. relocation/reorientation should happen locally for local URI's - (#pos=....) + (#....) 3. navigation should not happen ''immediately'' when user is more than 5 meter away from the portal/object containing the href (to prevent accidental navigation e.g.) - - - - - -van Kammen Expires 17 April 2025 [Page 20] - -Internet-Draft XR Fragments October 2024 - - 4. URL navigation should always be reflected in the client URL-bar (in case of javascript: see [here (https://github.com/coderofsalvation/xrfragment/blob/dev/src/3rd/ @@ -1133,6 +1170,14 @@ Internet-Draft XR Fragments October 2024 (https://github.com/coderofsalvation/xrfragment/blob/dev/example/ aframe/sandbox/index.html#L26-L29) for an example wearable) + + + +van Kammen Expires 5 March 2026 [Page 21] + +Internet-Draft XR Fragments September 2025 + + 6. make sure that the ''back-button'' of the ''browser-history'' always refers to the previous position (see [here (https://github .com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/ @@ -1143,11 +1188,11 @@ Internet-Draft XR Fragments October 2024 teleport-loop if the previous position is too close) 8. href-events should bubble upward the node-tree (from children to - ancestors, so that ancestors can also contain an href), however + ancestors, so that ancestors can also conain an href), however only 1 href can be executed at the same time. 9. the end-user navigator back/forward buttons should repeat a back/ - forward action until a pos=... primitive is found (the stateless + forward action until a #... primitive is found (the stateless xrf:// href-values should not be pushed to the url-history) » example implementation @@ -1159,7 +1204,7 @@ Internet-Draft XR Fragments October 2024 » discussion (https://github.com/coderofsalvation/xrfragment/ issues/1) -12.1. Walking surfaces +14.1. Walking surfaces XR Fragment-compatible viewers can infer this data based scanning the scene for: @@ -1170,15 +1215,7 @@ Internet-Draft XR Fragments October 2024 | optionally the viewer can offer thumbstick, mouse or joystick | teleport-tools for non-roomscale VR/AR setups. - - - -van Kammen Expires 17 April 2025 [Page 21] - -Internet-Draft XR Fragments October 2024 - - -12.2. UX spec +14.2. UX spec End-users should always have read/write access to: @@ -1188,7 +1225,16 @@ Internet-Draft XR Fragments October 2024 another scene/file (and coordinate e.g. in case the URL contains XR Fragments). -12.3. Scaling instanced content + + + + +van Kammen Expires 5 March 2026 [Page 22] + +Internet-Draft XR Fragments September 2025 + + +14.3. Scaling instanced content Sometimes embedded properties (like src) instance new objects. But what about their scale? @@ -1219,7 +1265,14 @@ Internet-Draft XR Fragments October 2024 | TODO: needs intermediate visuals to make things more obvious -13. XR Fragment: pos +15. XR Fragment: pos + + [[» example implementation|https://github.com/coderofsalvation/xrfrag + ment/blob/main/src/3rd/js/three/xrf/pos.js] + (https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/ + three/xrf/pos.js])] + +16. XR Fragment: rot [[» example implementation|https://github.com/coderofsalvation/xrfrag ment/blob/main/src/3rd/js/three/xrf/pos.js] @@ -1229,26 +1282,22 @@ Internet-Draft XR Fragments October 2024 -van Kammen Expires 17 April 2025 [Page 22] + + + +van Kammen Expires 5 March 2026 [Page 23] -Internet-Draft XR Fragments October 2024 +Internet-Draft XR Fragments September 2025 -14. XR Fragment: rot - - [[» example implementation|https://github.com/coderofsalvation/xrfrag - ment/blob/main/src/3rd/js/three/xrf/pos.js] - (https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/ - three/xrf/pos.js])] - -15. XR Fragment: t +17. XR Fragment: t [[» example implementation|https://github.com/coderofsalvation/xrfrag ment/blob/main/src/3rd/js/three/xrf/t.js] (https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/ three/xrf/t.js])] -16. XR audio/video integration +18. XR audio/video integration To play global audio/video items: @@ -1267,29 +1316,10 @@ Internet-Draft XR Fragments October 2024 | embedded audio/video, otherwise the global fps applies. For more | info see [[#t|t]]. -17. XR Fragment filters +19. XR Fragment filters Include, exclude, hide/shows objects using space-separated strings: - - - - - - - - - - - - - - -van Kammen Expires 17 April 2025 [Page 23] - -Internet-Draft XR Fragments October 2024 - - +====================+===========================================+ | example | outcome | +====================+===========================================+ @@ -1307,6 +1337,15 @@ Internet-Draft XR Fragments October 2024 Table 10 + + + + +van Kammen Expires 5 March 2026 [Page 24] + +Internet-Draft XR Fragments September 2025 + + It's simple but powerful syntax which allows filtering the scene using searchengine prompt-style feeling: @@ -1318,34 +1357,13 @@ Internet-Draft XR Fragments October 2024 which used a dedicated q= variable (now deprecated and usable directly) -17.1. including/excluding +19.1. including/excluding By default, selectors work like photoshop-layers: they scan for matching layer(name/properties) within the scene-graph. Each matched object (not their children) will be toggled (in)visible when selecting. - - - - - - - - - - - - - - - - -van Kammen Expires 17 April 2025 [Page 24] - -Internet-Draft XR Fragments October 2024 - - +==========+==============================================+ | operator | info | +==========+==============================================+ @@ -1376,11 +1394,19 @@ Internet-Draft XR Fragments October 2024 » example implementation (https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/ three/xrf/q.js) » example 3D asset + + + +van Kammen Expires 5 March 2026 [Page 25] + +Internet-Draft XR Fragments September 2025 + + (https://github.com/coderofsalvation/xrfragment/blob/main/example/ assets/filter.gltf#L192) » discussion (https://github.com/coderofsalvation/xrfragment/issues/3) -17.2. Filter Parser +19.2. Filter Parser Here's how to write a filter parser: @@ -1394,14 +1420,6 @@ Internet-Draft XR Fragments October 2024 5. detect number values like foo=1 (reference regex= /^[0-9\.]+$/ ) 6. detect operators so you can easily strip keys (reference regex= /(^-|\*$)/ ) - - - -van Kammen Expires 17 April 2025 [Page 25] - -Internet-Draft XR Fragments October 2024 - - 7. detect exclude keys like -foo (reference regex= /^-/ ) 8. for every filter token split string on = 9. and we set root to true or false (true=/ root selector is @@ -1413,7 +1431,7 @@ Internet-Draft XR Fragments October 2024 | (https://github.com/coderofsalvation/xrfragment/blob/main/src/ | xrfragment/Filter.hx) -18. Visible links +20. Visible links When predefined views, XRWG fragments and ID fragments (#cube or #mytag e.g.) are triggered by the enduser (via toplevel URL or @@ -1432,13 +1450,21 @@ Internet-Draft XR Fragments October 2024 src/3rd/js/XRWG.js)), which basically has all these things already collected/organized for you during scene-load. + + + +van Kammen Expires 5 March 2026 [Page 26] + +Internet-Draft XR Fragments September 2025 + + *UX* 4. do not update the wires when the enduser moves, leave them as is 5. offer a control near the back/forward button which allows the user to (turn off) control the correlation-intensity of the XRWG -19. Text in XR (tagging,linking to spatial objects) +21. Text in XR (tagging,linking to spatial objects) How does XR Fragments interlink text with objects? @@ -1447,17 +1473,6 @@ Internet-Draft XR Fragments October 2024 | (https://github.com/coderofsalvation/xrfragment/blob/feat/macros/ | src/3rd/js/XRWG.js)), augmented by Bib(s)Tex. - - - - - - -van Kammen Expires 17 April 2025 [Page 26] - -Internet-Draft XR Fragments October 2024 - - Instead of just throwing together all kinds media types into one experience (games), what about their tagged/semantical relationships? Perhaps the following question is related: why is HTML adopted less @@ -1494,24 +1509,9 @@ Internet-Draft XR Fragments October 2024 - - - - - - - - - - - - - - - -van Kammen Expires 17 April 2025 [Page 27] +van Kammen Expires 5 March 2026 [Page 27] -Internet-Draft XR Fragments October 2024 +Internet-Draft XR Fragments September 2025 http://y.io/z.fbx | Derived XRWG (expressed as JSON) @@ -1565,9 +1565,9 @@ Internet-Draft XR Fragments October 2024 -van Kammen Expires 17 April 2025 [Page 28] +van Kammen Expires 5 March 2026 [Page 28] -Internet-Draft XR Fragments October 2024 +Internet-Draft XR Fragments September 2025 * wordmatch *inside* src text @@ -1597,7 +1597,7 @@ Internet-Draft XR Fragments October 2024 14. anti-pattern: limiting human introspection, by abandoning plain text as first tag citizen. -19.1. Default Data URI mimetype +21.1. Default Data URI mimetype The src-values work as expected (respecting mime-types), however: @@ -1621,9 +1621,9 @@ Internet-Draft XR Fragments October 2024 -van Kammen Expires 17 April 2025 [Page 29] +van Kammen Expires 5 March 2026 [Page 29] -Internet-Draft XR Fragments October 2024 +Internet-Draft XR Fragments September 2025 * out-of-the-box (de)multiplex human text and metadata in one go @@ -1645,7 +1645,7 @@ Internet-Draft XR Fragments October 2024 For all other purposes, regular mimetypes can be used (but are not required by the spec). -19.2. URL and Data URI +21.2. URL and Data URI +--------------------------------------------------------------+ +------------------------+ | | | author.com/article.txt | @@ -1677,12 +1677,12 @@ Internet-Draft XR Fragments October 2024 -van Kammen Expires 17 April 2025 [Page 30] +van Kammen Expires 5 March 2026 [Page 30] -Internet-Draft XR Fragments October 2024 +Internet-Draft XR Fragments September 2025 -20. Importing/exporting +22. Importing/exporting For usecases like importing/exporting/p2p casting a scene, the issue of external files comes into play. @@ -1690,7 +1690,7 @@ Internet-Draft XR Fragments October 2024 1. export: if the 3D scene contains relative src/href values, rewrite them into absolute URL values. -21. Reflection Mapping +23. Reflection Mapping Environment mapping is crucial for creating realistic reflections and lighting effects on 3D objects. To apply environment mapping @@ -1719,7 +1719,7 @@ Internet-Draft XR Fragments October 2024 material (as materials might be shared across objects) 3.2 set the environmentmap to the last known parent texture (P) -22. Transclusion (broken link) resolution +24. Transclusion (broken link) resolution In spirit of Ted Nelson's 'transclusion resolution', there's a soft- mechanism to harden links & minimize broken links in various ways: @@ -1733,9 +1733,9 @@ Internet-Draft XR Fragments October 2024 -van Kammen Expires 17 April 2025 [Page 31] +van Kammen Expires 5 March 2026 [Page 31] -Internet-Draft XR Fragments October 2024 +Internet-Draft XR Fragments September 2025 3. in case of src: nesting a copy of the embedded object in the @@ -1767,7 +1767,7 @@ Internet-Draft XR Fragments October 2024 │ │ +────────────────────────────────────────────────────────+ -23. Topic-based index-less Webrings +25. Topic-based index-less Webrings As hashtags in URLs map to the XWRG, href-values can be used to promote topic-based index-less webrings. @@ -1789,9 +1789,9 @@ Internet-Draft XR Fragments October 2024 -van Kammen Expires 17 April 2025 [Page 32] +van Kammen Expires 5 March 2026 [Page 32] -Internet-Draft XR Fragments October 2024 +Internet-Draft XR Fragments September 2025 | This would hide all object tagged with topic, courses or theme @@ -1802,7 +1802,7 @@ Internet-Draft XR Fragments October 2024 separate content into separate files, or show/hide things using a complex logiclayer like javascript. -24. URI Templates (RFC6570) +26. URI Templates (RFC6570) XR Fragments adopts Level1 URI *Fragment* expansion to provide safe interactivity. @@ -1826,7 +1826,7 @@ Internet-Draft XR Fragments October 2024 │ │ +─────────────────────────────────────────────+ -25. Additional scene metadata +27. Additional scene metadata XR Fragments does not aim to redefine the metadata-space or accessibility-space by introducing its own cataloging-metadata @@ -1836,24 +1836,34 @@ Internet-Draft XR Fragments October 2024 * SPDX (https://spdx.dev/) license information * ARIA (https://www.w3.org/WAI/standards-guidelines/aria/) attributes (aria-*: .....) + + | SPDX and ARIA's aria-description are normative, as they promote + | accessibility and scene transcripts: please start aria-description + | with a verb to aid transcripts. + + + + + +van Kammen Expires 5 March 2026 [Page 33] + +Internet-Draft XR Fragments September 2025 + + + The following metadata are non-normative but encouraged, since they + are popular and cheap to parse: + + * RDF/JSON-LD (https://json-ld.org) like this example + (https://mvmd.org/standards/gltf/) or via glTF's KHR_xmp_json_ld + extension + (https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/ + Khronos/KHR_xmp_json_ld) * Open Graph (https://ogp.me) attributes (og:*: .....) * Dublin-Core (https://www.dublincore.org/specifications/dublin- core/application-profile-guidelines/) attributes(dc:*: .....) * BibTex (https://bibtex.eu/fields) when known bibtex-keys exist with values enclosed in { and }, - - - -van Kammen Expires 17 April 2025 [Page 33] - -Internet-Draft XR Fragments October 2024 - - - *ARIA* (aria-description) is the most important to support, as it - promotes accessibility and allows scene transcripts. Please start - aria-description with a verb to aid transcripts. - | Example: object 'tryceratops' with aria-description: is a huge | dinosaurus standing on a #mountain generates transcript | #tryceratops is a huge dinosaurus standing on a #mountain, where @@ -1888,25 +1898,23 @@ Internet-Draft XR Fragments October 2024 Table 13 + + + +van Kammen Expires 5 March 2026 [Page 34] + +Internet-Draft XR Fragments September 2025 + + | * = these are interchangable (only one needs to be defined) - There's no silver bullet when it comes to metadata, so one should - support where the metadata is/goes. + There's no silver bullet when it comes to metadata, so XR Fragment- + implementations should support where the metadata is/goes. | These attributes can be scanned and presented during an href or | src eye/mouse-over. - - - - - -van Kammen Expires 17 April 2025 [Page 34] - -Internet-Draft XR Fragments October 2024 - - -26. Accessibility interface +28. Accessibility interface The addressibility of XR Fragments allows for unique 3D-to-text transcripts, as well as an textual interface to navigate 3D content. @@ -1925,8 +1933,8 @@ Internet-Draft XR Fragments October 2024 for browser-backbutton) 6. The forward command should navigate back to the next URL (alias for browser-nextbutton) - 7. A destination is a 3D node containing an href with a pos= XR - fragment + 7. A destination is a 3D node containing an href with a #... XR + fragment (which matches a 3d object name) 8. The go command should list all possible destinations 9. The go left command should move the camera around 0.3 meters to the left @@ -1937,31 +1945,34 @@ Internet-Draft XR Fragments October 2024 12. The rotate left command should rotate the camera 0.3 to the left 13. The rotate left command should rotate the camera 0.3 to the right - 14. The (dynamic) go abc command should navigate to #pos=scene2 in - case there's a 3D node with name abc and href value #pos=scene2 + 14. The (dynamic) go abc command should navigate to #scene2 in case + there's a 3D node with name abc and href value #scene2 15. The look command should give an (contextual) 3D-to-text transcript, by scanning the aria-description values of the - current pos= value (including its children) + current #... (3D object) value (including its children) 16. The do command should list all possible href values which don't - contain an pos= XR Fragment + contain an #... XR Fragment + + + + + +van Kammen Expires 5 March 2026 [Page 35] + +Internet-Draft XR Fragments September 2025 + + 17. The (dynamic) do abc command should navigate/execute https://.../... in case a 3D node exist with name abc and href value https://.../... -26.1. Two-button navigation +28.1. Two-button navigation For specific user-profiles, gyroscope/mouse/keyboard/audio/visuals will not be available. Therefore a 2-button navigation-interface is the bare minimum interface: - - -van Kammen Expires 17 April 2025 [Page 35] - -Internet-Draft XR Fragments October 2024 - - 1. objects with href metadata can be cycled via a key (tab on a keyboard) 2. objects with href metadata can be activated via a key (enter on a @@ -1969,7 +1980,7 @@ Internet-Draft XR Fragments October 2024 3. the TTS reads the href-value (and/or aria-description if available) -26.2. Overlap with fileformat-specific extensions +28.2. Overlap with fileformat-specific extensions Some 3D scene-fileformats have support for extensions. What if the functionality of those overlap? For example, GLTF has the OMI_LINK @@ -1998,12 +2009,21 @@ Internet-Draft XR Fragments October 2024 | e.g.) a teleport should be performed only (and other [overlapping] | metadata should be ignored). | + + + + +van Kammen Expires 5 March 2026 [Page 36] + +Internet-Draft XR Fragments September 2025 + + | *Example 2* If an Extensions uses XR Fragments in URI's (href: | #pos=otherroom or href: xrf://-walls in OMI_LINK e.g.), then | perform them according to XR Fragment spec (teleport user). But | only once: ignore further overlapping metadata for that usecase. -26.3. Vendor Prefixes +28.3. Vendor Prefixes Vendor-specific metadata in a 3D scenefiles, are similar to vendor- specific CSS-prefixes (https://en.wikipedia.org/wiki/ @@ -2011,13 +2031,6 @@ Internet-Draft XR Fragments October 2024 3D engines/frameworks, to initialize specific features when loading a scene/object, in a progressive enhanced way. - - -van Kammen Expires 17 April 2025 [Page 36] - -Internet-Draft XR Fragments October 2024 - - Vendor Prefixes allows embedding 3D engines/framework-specific features a 3D file via metadata: @@ -2056,22 +2069,9 @@ Internet-Draft XR Fragments October 2024 - - - - - - - - - - - - - -van Kammen Expires 17 April 2025 [Page 37] +van Kammen Expires 5 March 2026 [Page 37] -Internet-Draft XR Fragments October 2024 +Internet-Draft XR Fragments September 2025 +────────────────────────────────────────────────────────────────────────────────────────────────────────+ @@ -2125,12 +2125,12 @@ Internet-Draft XR Fragments October 2024 -van Kammen Expires 17 April 2025 [Page 38] +van Kammen Expires 5 March 2026 [Page 38] -Internet-Draft XR Fragments October 2024 +Internet-Draft XR Fragments September 2025 -27. Security Considerations +29. Security Considerations The only dynamic parts are W3C Media Fragments (https://www.w3.org/TR/media-frags/) and URI Templates (RFC6570) @@ -2140,7 +2140,7 @@ Internet-Draft XR Fragments October 2024 n fact, it is much safer than relying on a scripting language (javascript) which can change URN too. -28. FAQ +30. FAQ *Q:* Why is everything HTTP GET-based, what about POST/PUT/DELETE HATEOS @@ -2173,7 +2173,7 @@ Internet-Draft XR Fragments October 2024 place, to 'extend' experiences, in contrast to code/javascript inside hypermedia documents (this turned out as a hypermedia antipattern). -29. authors +31. authors * Leon van Kammen (@lvk@mastodon.online) * Jens Finkhäuser (@jens@social.finkhaeuser.de) @@ -2181,16 +2181,16 @@ Internet-Draft XR Fragments October 2024 -van Kammen Expires 17 April 2025 [Page 39] +van Kammen Expires 5 March 2026 [Page 39] -Internet-Draft XR Fragments October 2024 +Internet-Draft XR Fragments September 2025 -30. IANA Considerations +32. IANA Considerations This document has no IANA actions. -31. Acknowledgments +33. Acknowledgments * NLNET (https://nlnet.nl) * Future of Text (https://futureoftext.org) @@ -2205,7 +2205,7 @@ Internet-Draft XR Fragments October 2024 * Brandel Zackernuk * Mark Anderson -32. Appendix: Definitions +34. Appendix: Definitions +=================+=============================================+ | definition | explanation | @@ -2237,13 +2237,14 @@ Internet-Draft XR Fragments October 2024 -van Kammen Expires 17 April 2025 [Page 40] +van Kammen Expires 5 March 2026 [Page 40] -Internet-Draft XR Fragments October 2024 +Internet-Draft XR Fragments September 2025 - | XR fragment | URI Fragment with spatial hints like | - | | #pos=0,0,0&t=1,100 e.g. | + | XR fragment | URI Fragment with spatial hints (which | + | | match the name of a 3D object-, camera-, | + | | animation-object) | +-----------------+---------------------------------------------+ | the XRWG | wordgraph (collapses 3D scene to tags) | +-----------------+---------------------------------------------+ @@ -2289,15 +2290,15 @@ Internet-Draft XR Fragments October 2024 +-----------------+---------------------------------------------+ | extrospective | outward sensemaking ("I'm fairly sure John | | | is a person who lives in oklahoma") | - +-----------------+---------------------------------------------+ -van Kammen Expires 17 April 2025 [Page 41] +van Kammen Expires 5 March 2026 [Page 41] -Internet-Draft XR Fragments October 2024 +Internet-Draft XR Fragments September 2025 + +-----------------+---------------------------------------------+ | ◻ | ascii representation of an 3D object/mesh | +-----------------+---------------------------------------------+ | (un)obtrusive | obtrusive: wrapping human text/thought in | @@ -2348,5 +2349,4 @@ Internet-Draft XR Fragments October 2024 - -van Kammen Expires 17 April 2025 [Page 42] +van Kammen Expires 5 March 2026 [Page 42] diff --git a/doc/RFC_XR_Fragments.xml b/doc/RFC_XR_Fragments.xml index 10e3f53..293c234 100644 --- a/doc/RFC_XR_Fragments.xml +++ b/doc/RFC_XR_Fragments.xml @@ -10,14 +10,15 @@ Jens & Leon Internet Engineering Task Force -This draft is a specification for interactive URI-controllable 3D files, enabling hypermediatic navigation, to enable a spatial web for hypermedia browsers with- or without a network-connection.
    +An open specification for hyperlinking & deeplinking 3D fileformats. +This draft is a specification for interactive URI-controllable 3D files, enabling hypermediatic navigation, to enable a spatial web for hypermedia browsers with- or without a network-connection.
    The specification uses W3C Media Fragments and URI Templates (RFC6570) to promote spatial addressibility, sharing, navigation, filtering and databinding objects for (XR) Browsers.
    -XR Fragments allows us to better use existing metadata inside 3D scene(files), by connecting it to proven technologies like URI Fragments.
    +XR Fragments allows us to better use implicit metadata inside 3D scene(files), by mapping it to proven technologies like URI Fragments.
    -XR Fragments views spatial webs thru the lens of 3D scene URI's, rather than thru code(frameworks) or protocol-specific browsers (webbrowser e.g.).
    -XR Fragments is a <b>Meta scene format</b> which leverages heuristic rules derived from any 3D scene or well-established 3D file formats, to extract meaningful features from scene hierarchies.
    +XR Fragments views XR experiences thru the lens of 3D object URI's, rather than thru code(frameworks) or protocol-specific browsers (webbrowser e.g.).
    +XR Fragments is a <b>heuristical 3D format</b> which leverages heuristic rules derived from any 3D scene or well-established 3D file formats, to extract meaningful features from scene hierarchies.
    These heuristics, enable features that are both meaningful and consistent across different scene representations, allowing <b>higher interop</b> between fileformats, 3D editors, viewers and game-engines.
    Almost every idea in this document is demonstrated at https://xrfragment.org @@ -133,19 +134,12 @@ But approaches things from a higherlevel feedbackloop/hypermedia browser-perspec -#pos +#...... vector3 -#pos=0.5,0,0 #pos=room #pos=cam2 +#room1 #room2 #cam2 positions/parents camera(rig) (or XR floor) to xyz-coord/object/camera - -#rot -vector3 -#rot=0,90,0 -rotates camera to xyz-coord 0.5,0,0 - - Media Fragments media fragment @@ -176,80 +170,18 @@ But approaches things from a higherlevel feedbackloop/hypermedia browser-perspec XR teleport custom property in 3D fileformats - - -src -string -"src": "#cube" -XR embed / teleport -custom property in 3D fileformats - - - -tag -string -"tag": "cubes geo" -tag object (for filter-use / XRWG highlighting) -custom property in 3D fileformats - - - -# -string -"#": "#mypreset -trigger default fragment on load -custom property in 3D fileformats - -
    Supported popular compatible 3D fileformats: .gltf, .obj, .fbx, .usdz, .json (THREE.js), .dae and so on. -
    -
    Sidecar-file -
    NOTE: sidecar-files break the portability of XR (Fragments) experiences, therefore side-car files are discouraged for consumer usage/sharing. However, they can accomodate developers or applications who (for whatever reason) must not modify the 3D scene-file (a .glb e.g.). -
    For developers, sidecar-file can allow for defining explicit XR Fragments metadata, outside of the 3D file.
    +
    -This can be done via a JSON-pointers RFC6901 in a JSON sidecar-file:
    - -
      -
    • experience.glb
    • -
    • experience.json
    • -
    - - - -
    This would mean: hide object(s) with name or tag-value 'penguin' upon scene-load, and show it when the user clicks the chair -
    So after loading experience.glb the existence of experience.json is detected, to apply the explicit metadata.
    - -The sidecar will define (or override already existing) extras, which can be handy for multi-user platforms (offer 3D scene customization/personalization to users).
    -
    In THREE.js-code this would boil down to: -
    - - - - - -
    Hypermediatic FeedbackLoop for XR browsers -href metadata traditionally implies click AND navigate, however XR Fragments adds stateless click (xrf://#....) or navigate (xrf://#pos=...) +
    HFL (Hypermediatic Feedback Loop) for XR Browsers +href metadata traditionally implies click AND navigate, however XR Fragments adds stateless click (xrf://#....) or navigate (xrf://#...) as well (which allows many extra interactions which otherwise need a scripting language). This is known as hashbus-only events (see image above).
    Being able to use the same URI Fragment DSL for navigation (href: #foo) as well as interactions (href: xrf://#bar) greatly simplifies implementation, increases HFL, and reduces need for scripting languages.
    This opens up the following benefits for traditional & future webbrowsers:
    • hypermediatic loading/clicking 3D assets (gltf/fbx e.g.) natively (with or without using HTML).
    • -
    • allowing 3D assets/nodes to publish XR Fragments to themselves/eachother using the xrf:// hashbus
    • +
    • allowing 3D assets/nodes to publish XR Fragments to themselves/eachother using the xrf:// hashbus (xrf://#person=walk to trigger walk-animation for object person)
    • collapsing the 3D scene to an wordgraph (for essential navigation purposes) controllable thru a hash(tag)bus
    • completely bypassing the security-trap of loading external scripts (by loading 3D model-files, not HTML-javascriptable resources)
    @@ -338,7 +270,7 @@ gen-delims = "#" / "&" sub-delims = "," / "=" ]]> -
    Example: ://foo.com/my3d.gltf#pos=1,0,0&prio=-5&t=0,100 +
    Example: ://foo.com/my3d.gltf#room1&prio=-5&t=0,100
    @@ -349,12 +281,12 @@ sub-delims = "," / "=" - + - + @@ -398,9 +330,59 @@ For example, to render a portal with a preview-version of the scene, create an 3
  • src: https://otherworld.gltf#mainobject
  • It also allows sourceportation, which basically means the enduser can teleport to the original XR Document of an src embedded object, and see a visible connection to the particular embedded object. Basically an embedded link becoming an outbound link by activating it. +
    + +
    non-normative +The following below is non-normative heuristics which are not part officially part of the spec. +
    + +
    additional explicit metadata +| #rot | vector3 | #rot=0,90,0 | rotates camera to xyz-coord 0.5,0,0 | +| src | string | "src": "#cube" | XR embed / teleport | custom property in 3D fileformats | +| tag | string | "tag": "cubes geo" | tag object (for filter-use / XRWG highlighting) | custom property in 3D fileformats | +| # | string | "#": "#mypreset | trigger default fragment on load | custom property in 3D fileformats | +
    Supported popular compatible 3D fileformats: .gltf, .obj, .fbx, .usdz, .json (THREE.js), .dae and so on.
    +
    Sidecar-file +
    NOTE: sidecar-files break the portability of XR (Fragments) experiences, therefore side-car files are discouraged for consumer usage/sharing. However, they can accomodate developers or applications who (for whatever reason) must not modify the 3D scene-file (a .glb e.g.). +
    For developers, sidecar-file can allow for defining explicit XR Fragments metadata, outside of the 3D file.
    + +This can be done via a JSON-pointers RFC6901 in a JSON sidecar-file:
    + +
      +
    • experience.glb
    • +
    • experience.json
    • +
    + + + +
    This would mean: hide object(s) with name or tag-value 'penguin' upon scene-load, and show it when the user clicks the chair +
    So after loading experience.glb the existence of experience.json is detected, to apply the explicit metadata.
    + +The sidecar will define (or override already existing) extras, which can be handy for multi-user platforms (offer 3D scene customization/personalization to users).
    +
    In THREE.js-code this would boil down to: +
    + + +
    +
    Level2: Implicit URI Fragments -These fragments are derived from objectnames (or their extras) within a 3D scene, and trigger certain actions when evaluated by the browser: +
    Warning: non-normative +
    These fragments are derived from objectnames (or their extras) within a 3D scene, and trigger certain actions when evaluated by the browser:
    pos=1,2,3room1 vector/coordinate argument e.g.
    pos=1,2,3&rot=0,90,0&fooroom1&rot=0,90,0&cam1 combinators
    @@ -423,7 +405,7 @@ For example, to render a portal with a preview-version of the scene, create an 3 - + @@ -472,7 +454,7 @@ For example, to render a portal with a preview-version of the scene, create an 3
    FOCUS#<tag_or_objectname>xrf://#<tag_or_objectname> string #person (and show) object(s) with tag: person or name person (XRWG lookup)
    media fragments and datatypes -
    NOTE: below the word 'play' applies to 3D animations embedded in the 3D scene(file) but also media defined in src-metadata like audio/video-files (mp3/mp4 e.g.) +
    Warning: non-normative (below the word 'play' applies to 3D animations embedded in the 3D scene(file) but also media defined in src-metadata like audio/video-files (mp3/mp4 e.g.))
    @@ -670,7 +652,7 @@ For example, to render a portal with a preview-version of the scene, create an 3 │ index.gltf │ │ │ │ │ ├── ◻ buttonA │ - │ │ └ href: #pos=1,0,1&t=100,200 │ + │ │ └ href: #room1&t=100,200 │ │ │ │ │ └── ◻ buttonB │ │ └ href: other.fbx │ <── file─agnostic (can be .gltf .obj etc) @@ -681,24 +663,29 @@ For example, to render a portal with a preview-version of the scene, create an 3 An XR Fragment-compatible browser viewing this scene, allows the end-user to interact with the buttonA and buttonB.
    -In case of buttonA the end-user will be teleported to another location and time in the current loaded scene, but buttonB will replace the current scene with a new one, like other.fbx, and assume pos=0,0,0.
    +In case of buttonA the end-user will be teleported to another location and time in the current loaded scene, but buttonB will replace the current scene with a new one, like other.fbx, and assume camera coordinate 0,0,0
    Top-level URL processing -
    Example URL: ://foo/world.gltf#cube&pos=0,0,0 +
    Example URL: ://foo/world.gltf#room1&t=10
    The URL-processing-flow for hypermedia browsers goes like this:
      -
    1. IF a #cube matches a custom property-key (of an object) in the 3D file/scene (#cube: #......) <b>THEN</b> execute that predefined_view.
    2. -
    3. IF scene operators (pos) and/or animation operator (t) are present in the URL then (re)position the camera and/or animation-range accordingly.
    4. -
    5. IF no camera-position has been set in <b>step 1 or 2</b> update the top-level URL with #pos=0,0,0 (example)
    6. +
    7. IF a #room1 matches a custom property-key (of an object) in the 3D file/scene (#room1: #......) <b>THEN</b> execute that predefined_view.
    8. +
    9. IF scene operators and/or animation operator (t) are present in the URL then (re)position the camera (to room1) and/or animation-range (10) accordingly.
    10. +
    11. IF no camera-position has been set in <b>step 1 or 2</b> assume 0,0,0 as camera coordinate (XR: add user-height) (example)
    12. +
    +Non-normative / Deprecated: + +
    1. IF a #cube matches the name (of an object) in the 3D file/scene then draw a line from the enduser('s heart) to that object (to highlight it).
    2. IF a #cube matches anything else in the XR Word Graph (XRWG) draw wires to them (text or related objects).
    Embedding XR content using src -src is the 3D version of the <a target="_blank" href="https://www.w3.org/html/wiki/Elements/iframe">iframe</a>.
    +
    NOTE: only adviced for local-first experiences (where resources can be cached). +
    src is the 3D version of the <a target="_blank" href="https://www.w3.org/html/wiki/Elements/iframe">iframe</a>.
    It instances content (in objects) in the current scene/asset, and follows similar logic like the previous chapter, except that it does not modify the camera.
    @@ -800,17 +787,17 @@ Resizing will be happen accordingly to its placeholder object aquariumcube -
    href string (uri or predefined view)#pos=1,1,0
    -#pos=1,1,0&rot=90,0,0
    -://somefile.gltf#pos=1,1,0
    +
    #room1
    +#pos=room1&rot=90,0,0
    +://somefile.gltf#room1
      -
    1. clicking an outbound ''external''- or ''file URI'' fully replaces the current scene and assumes pos=0,0,0&rot=0,0,0 by default (unless specified) +
    2. clicking an outbound ''external''- or ''file URI'' fully replaces the current scene and assumes room2&rot=0,0,0 by default (unless specified)
    3. -
    4. relocation/reorientation should happen locally for local URI's (#pos=....) +
    5. relocation/reorientation should happen locally for local URI's (#....)
    6. navigation should not happen ''immediately'' when user is more than 5 meter away from the portal/object containing the href (to prevent accidental navigation e.g.)
    7. @@ -822,9 +809,9 @@ Resizing will be happen accordingly to its placeholder object aquariumcube
    8. ignore previous rule in special cases, like clicking an href using camera-portal collision (the back-button could cause a teleport-loop if the previous position is too close)
    9. -
    10. href-events should bubble upward the node-tree (from children to ancestors, so that ancestors can also contain an href), however only 1 href can be executed at the same time. +
    11. href-events should bubble upward the node-tree (from children to ancestors, so that ancestors can also conain an href), however only 1 href can be executed at the same time.
    12. -
    13. the end-user navigator back/forward buttons should repeat a back/forward action until a pos=... primitive is found (the stateless xrf:// href-values should not be pushed to the url-history) +
    14. the end-user navigator back/forward buttons should repeat a back/forward action until a #... primitive is found (the stateless xrf:// href-values should not be pushed to the url-history)
    » example implementation
    @@ -1379,16 +1366,16 @@ Spec:
  • the textlog contains aria-descriptions, and its narration (Screenreader e.g.) can be skipped (via 2-button navigation)
  • The back command should navigate back to the previous URL (alias for browser-backbutton)
  • The forward command should navigate back to the next URL (alias for browser-nextbutton)
  • -
  • A destination is a 3D node containing an href with a pos= XR fragment
  • +
  • A destination is a 3D node containing an href with a #... XR fragment (which matches a 3d object name)
  • The go command should list all possible destinations
  • The go left command should move the camera around 0.3 meters to the left
  • The go right command should move the camera around 0.3 meters to the right
  • The go forward command should move the camera 0.3 meters forward (direction of current rotation).
  • The rotate left command should rotate the camera 0.3 to the left
  • The rotate left command should rotate the camera 0.3 to the right
  • -
  • The (dynamic) go abc command should navigate to #pos=scene2 in case there's a 3D node with name abc and href value #pos=scene2
  • -
  • The look command should give an (contextual) 3D-to-text transcript, by scanning the aria-description values of the current pos= value (including its children)
  • -
  • The do command should list all possible href values which don't contain an pos= XR Fragment
  • +
  • The (dynamic) go abc command should navigate to #scene2 in case there's a 3D node with name abc and href value #scene2
  • +
  • The look command should give an (contextual) 3D-to-text transcript, by scanning the aria-description values of the current #... (3D object) value (including its children)
  • +
  • The do command should list all possible href values which don't contain an #... XR Fragment
  • The (dynamic) do abc command should navigate/execute https://.../... in case a 3D node exist with name abc and href value https://.../...
  • @@ -1601,7 +1588,7 @@ Non-HTML Hypermedia browsers should make browser extensions the right place, to XR fragment -URI Fragment with spatial hints like #pos=0,0,0&t=1,100 e.g. +URI Fragment with spatial hints (which match the name of a 3D object-, camera-, animation-object) diff --git a/doc/RFC_XR_Macros.txt b/doc/RFC_XR_Macros.txt index ed839a4..6032851 100644 --- a/doc/RFC_XR_Macros.txt +++ b/doc/RFC_XR_Macros.txt @@ -3,7 +3,7 @@ Internet Engineering Task Force L.R. van Kammen -Internet-Draft 27 September 2024 +Internet-Draft 1 September 2025 Intended status: Informational @@ -38,11 +38,11 @@ Status of This Memo time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress." - This Internet-Draft will expire on 31 March 2025. + This Internet-Draft will expire on 5 March 2026. Copyright Notice - Copyright (c) 2024 IETF Trust and the persons identified as the + Copyright (c) 2025 IETF Trust and the persons identified as the document authors. All rights reserved. This document is subject to BCP 78 and the IETF Trust's Legal @@ -53,9 +53,9 @@ Copyright Notice -van Kammen Expires 31 March 2025 [Page 1] +van Kammen Expires 5 March 2026 [Page 1] -Internet-Draft XR Macros September 2024 +Internet-Draft XR Macros September 2025 extracted from this document must include Revised BSD License text as @@ -109,9 +109,9 @@ Table of Contents -van Kammen Expires 31 March 2025 [Page 2] +van Kammen Expires 5 March 2026 [Page 2] -Internet-Draft XR Macros September 2024 +Internet-Draft XR Macros September 2025 3. Metadata-values can contain the | symbol to 🎲 roundrobin variable @@ -165,9 +165,9 @@ Internet-Draft XR Macros September 2024 -van Kammen Expires 31 March 2025 [Page 3] +van Kammen Expires 5 March 2026 [Page 3] -Internet-Draft XR Macros September 2024 +Internet-Draft XR Macros September 2025 +=========+======+===================+=================+=============+ @@ -221,9 +221,9 @@ Internet-Draft XR Macros September 2024 -van Kammen Expires 31 March 2025 [Page 4] +van Kammen Expires 5 March 2026 [Page 4] -Internet-Draft XR Macros September 2024 +Internet-Draft XR Macros September 2025 Table 3 @@ -277,9 +277,9 @@ Internet-Draft XR Macros September 2024 -van Kammen Expires 31 March 2025 [Page 5] +van Kammen Expires 5 March 2026 [Page 5] -Internet-Draft XR Macros September 2024 +Internet-Draft XR Macros September 2025 4.5. Usecase: present context menu with options @@ -333,9 +333,9 @@ click object with (`!clickme`:`!foo|!bar|!flop` e.g.) -van Kammen Expires 31 March 2025 [Page 6] +van Kammen Expires 5 March 2026 [Page 6] -Internet-Draft XR Macros September 2024 +Internet-Draft XR Macros September 2025 | Note that only macro's can trigger roundrobin values or @@ -389,4 +389,4 @@ Internet-Draft XR Macros September 2024 -van Kammen Expires 31 March 2025 [Page 7] +van Kammen Expires 5 March 2026 [Page 7] diff --git a/doc/shell.nix b/doc/shell.nix index 3ff4bf4..16611f7 100644 --- a/doc/shell.nix +++ b/doc/shell.nix @@ -1,6 +1,14 @@ -{ pkgs ? import {} }: +{ pkgs ? import {} } : +{ - pkgs.mkShell { + pkgs = import (builtins.fetchGit { + name = "nixos-23.05"; + url = "https://github.com/nixos/nixpkgs/"; + ref = "refs/heads/nixos-unstable"; + rev = "ef99fa5c5ed624460217c31ac4271cfb5cb2502c"; + }); + + foo = pkgs.mkShell { # nativeBuildInputs is usually what you want -- tools you need to run nativeBuildInputs = with pkgs.buildPackages; [ @@ -11,4 +19,5 @@ imagemagick ]; + }; }