{"id":25970,"date":"2025-04-21T19:19:57","date_gmt":"2025-04-21T10:19:57","guid":{"rendered":"http:\/\/www.tyosuke20xx.com\/blog\/?p=25970"},"modified":"2025-04-21T19:19:59","modified_gmt":"2025-04-21T10:19:59","slug":"vrsns","status":"publish","type":"post","link":"http:\/\/www.tyosuke20xx.com\/blog\/?p=25970","title":{"rendered":"VRSNS"},"content":{"rendered":"\n<pre class=\"wp-block-code\"><code>&lt;!DOCTYPE html>\n&lt;html lang=\"ja\">\n&lt;head>\n&lt;meta charset=\"UTF-8\" \/>\n&lt;meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" \/>\n&lt;title>VR\u2011SNS Prototype\u00a0v8 (Spatial Audio + PTT + \u30a8\u30e2\u30fc\u30c8)&lt;\/title>\n\n&lt;!-- Libraries -->\n&lt;script src=\"https:\/\/aframe.io\/releases\/1.5.0\/aframe.min.js\">&lt;\/script>\n&lt;script src=\"https:\/\/cdn.jsdelivr.net\/npm\/aframe-extras@6.1.1\/dist\/aframe-extras.min.js\">&lt;\/script>\n&lt;script src=\"https:\/\/cdn.jsdelivr.net\/npm\/gun\/gun.min.js\">&lt;\/script>\n&lt;script src=\"https:\/\/cdn.jsdelivr.net\/npm\/simple-peer@9.11.1\/simplepeer.min.js\">&lt;\/script>\n\n&lt;style>\nhtml,body{margin:0;padding:0;overflow:hidden;font-family:\"Helvetica Neue\",Arial,sans-serif;background:#111;color:#eee}\n#ui{position:fixed;top:0;left:0;width:420px;height:100vh;overflow-y:auto;background:rgba(0,0,0,.9);backdrop-filter:blur(6px);padding:1rem;box-sizing:border-box;z-index:10;transition:transform .3s ease}\n#ui.hidden{transform:translateX(-105%)}\n#ui h1{font-size:1.5rem;margin:0 0 .8rem;text-align:center}\n#ui label{display:block;font-size:.75rem;margin:.6rem 0 .15rem;color:#8fc}\n#ui input,#ui select,#ui textarea{width:100%;box-sizing:border-box;margin-bottom:.7rem;padding:.56rem;border:none;border-radius:6px;font-size:.9rem;background:#222;color:#ddd}\n#ui textarea{resize:vertical}\n#ui button{width:100%;padding:.72rem;border:none;border-radius:6px;font-weight:bold;cursor:pointer;background:#06a;color:#fff;transition:background .2s}\n#ui button:hover{background:#089}\n#timeline{margin-top:1rem}\n.post{background:#1a1a1a;border-radius:6px;padding:.75rem;margin-bottom:.75rem;word-break:break-word;font-size:.8rem;position:relative}\n.post small{color:#999;font-size:.7rem}\n.post img{max-width:100%;border-radius:4px;margin-top:.4rem}\n.reactBar{display:flex;gap:5px;margin-top:.45rem}\n.reactBtn{flex:1;background:#333;border:none;border-radius:4px;padding:3px 0;font-size:.75rem;cursor:pointer;color:#f88;display:flex;justify-content:center;align-items:center}\n.reactBtn span{margin-left:4px;font-weight:bold;color:#ccc}\n.hashTag{color:#6af;cursor:pointer}\n#handle{position:absolute;top:50%;right:-18px;width:18px;height:80px;border-radius:0 6px 6px 0;background:#06a;cursor:pointer;display:flex;align-items:center;justify-content:center;color:#fff;font-size:.7rem;transform:translateY(-50%)}\n#tagFilter{margin-bottom:.8rem;width:100%;padding:.56rem;border:none;border-radius:6px;background:#222;color:#ddd}\n#onlineCount{font-size:.75rem;margin-bottom:.8rem;color:#9f9}\n#roomInput{width:70%;display:inline-block}\n#roomBtn{width:28%;display:inline-block;margin-left:2%}\n#ttsToggleLbl,#muteToggleLbl,#pttInfo{display:flex;align-items:center;font-size:.75rem;margin-bottom:.7rem;gap:.5rem}\n.sysMsg{color:#8ff;font-style:italic}\n.speaking{animation:pulse 1s infinite}\n@keyframes pulse{0%{opacity:1}50%{opacity:.4}100%{opacity:1}}\n.emote{position:absolute;left:50%;transform:translateX(-50%);top:-0.4m;font-size:0.4m}\n&lt;\/style>\n&lt;\/head>\n&lt;body>\n&lt;div id=\"ui\">\n  &lt;div id=\"handle\">\u2b9c&lt;\/div>\n  &lt;h1>VR\u2011SNS&lt;\/h1>\n\n  &lt;label>\u30eb\u30fc\u30e0 ID&lt;\/label>\n  &lt;input id=\"roomInput\" value=\"lobby\"\/>&lt;button id=\"roomBtn\">\u5165\u5ba4&lt;\/button>\n  &lt;div id=\"onlineCount\">\u30aa\u30f3\u30e9\u30a4\u30f3: 0&lt;\/div>\n\n  &lt;label>\u30e6\u30fc\u30b6\u30fc\u540d&lt;\/label>\n  &lt;input id=\"usernameInput\" placeholder=\"\u533f\u540d\" \/>\n\n  &lt;label>\u30a2\u30d0\u30bf\u30fc\u8272&lt;\/label>\n  &lt;input id=\"avatarColor\" type=\"color\" value=\"#ff8800\" \/>\n\n  &lt;label>\u74b0\u5883\u30c6\u30fc\u30de&lt;\/label>\n  &lt;select id=\"themeSelect\">&lt;option value=\"dusk\">\u5915\u66ae\u308c\u7a7a&lt;\/option>&lt;option value=\"midnight\">\u771f\u591c\u4e2d&lt;\/option>&lt;option value=\"day\">\u6674\u308c\u663c&lt;\/option>&lt;\/select>\n\n  &lt;label>\u30cf\u30c3\u30b7\u30e5\u30bf\u30b0\u7d5e\u308a\u8fbc\u307f&lt;\/label>\n  &lt;select id=\"tagFilter\">&lt;option value=\"all\">\u3059\u3079\u3066&lt;\/option>&lt;\/select>\n\n  &lt;label id=\"ttsToggleLbl\">&lt;input type=\"checkbox\" id=\"ttsToggle\"\/> \u6295\u7a3f\u8aad\u307f\u4e0a\u3052&lt;\/label>\n  &lt;label id=\"muteToggleLbl\">&lt;input type=\"checkbox\" id=\"muteToggle\"\/> \u30de\u30a4\u30af\u5e38\u6642OFF&lt;\/label>\n  &lt;div id=\"pttInfo\">Push\u2011To\u2011Talk: &lt;strong>V\u30ad\u30fc&lt;\/strong> \u62bc\u4e0b\u4e2d\u306e\u307f\u9001\u4fe1&lt;\/div>\n\n  &lt;label>\u6295\u7a3f&lt;\/label>\n  &lt;textarea id=\"postText\" rows=\"3\">&lt;\/textarea>\n  &lt;button id=\"postButton\">\u30dd\u30b9\u30c8&lt;\/button>\n  &lt;button id=\"clearButton\" style=\"background:#a00;margin-top:.3rem\">\u30ed\u30fc\u30ab\u30eb\u5c65\u6b74\u524a\u9664&lt;\/button>\n\n  &lt;div id=\"timeline\">&lt;\/div>\n&lt;\/div>\n\n&lt;a-scene renderer=\"antialias:true\" xr-mode-ui=\"true\" background=\"color:#112\" cursor=\"rayOrigin:mouse\">\n  &lt;a-entity environment=\"preset: forest; ground:y\">&lt;\/a-entity>\n  &lt;a-entity id=\"ground\" geometry=\"primitive:plane; width:150; height:150\" rotation=\"-90 0 0\" material=\"visible:false\" static-body>&lt;\/a-entity>\n\n  &lt;a-entity id=\"rig\" position=\"0 1.6 4\" movement-controls=\"fly:false; speed:0.22\">\n    &lt;a-entity id=\"head\" camera look-controls>&lt;\/a-entity>\n    &lt;a-entity id=\"leftHand\"  laser-controls=\"hand:left\"  raycaster=\"objects:.interactive\" teleport-controls=\"button:trigger; collisionEntities:#ground; cameraRig:#rig\">&lt;\/a-entity>\n    &lt;a-entity id=\"rightHand\" laser-controls=\"hand:right\" raycaster=\"objects:.interactive\">&lt;\/a-entity>\n  &lt;\/a-entity>\n&lt;\/a-scene>\n\n&lt;script>\n(()=>{\nconst gun=Gun({peers:&#91;'https:\/\/gun-manhattan.herokuapp.com\/gun']});\nconst myId=Gun.text.random();\nlet room='lobby',roomRef;\nconst $=id=>document.getElementById(id);\nconst ui=$('ui'),handle=$('handle');\nconst roomInput=$('roomInput'),roomBtn=$('roomBtn'),onlineCount=$('onlineCount');\nconst usernameInput=$('usernameInput'),avatarColorIn=$('avatarColor');\nconst themeSelect=$('themeSelect'),tagFilter=$('tagFilter');\nconst ttsToggle=$('ttsToggle'),muteToggle=$('muteToggle');\nconst postText=$('postText'),postBtn=$('postButton'),clearBtn=$('clearButton');\nconst timelineEl=$('timeline');\nconst scene=document.querySelector('a-scene');\nconst head=$('head'),leftHand=$('leftHand'),rightHand=$('rightHand');\n\nconst store={get:(k,d)=>JSON.parse(localStorage.getItem('vrsns_'+k)||JSON.stringify(d)),set:(k,v)=>localStorage.setItem('vrsns_'+k,JSON.stringify(v))};\nusernameInput.value=store.get('user','');avatarColorIn.value=store.get('color','#ff8800');themeSelect.value=store.get('theme','dusk');ttsToggle.checked=store.get('tts',false);\n\nconst postsMap=new Map();const tags=new Set();const remoteAvatars=new Map();const remotePeers=new Map();let micStream=null,aCtx=null;let pushTalking=false;\nlet presenceRef,posRef,presenceInterval,posInterval;\napplyTheme(themeSelect.value);createOrUpdateAvatar();setupMic();enterRoom(room);\n\nhandle.onclick=()=>ui.classList.toggle('hidden');scene.addEventListener('enter-vr',()=>ui.classList.add('hidden'));scene.addEventListener('exit-vr',()=>ui.classList.remove('hidden'));\nroomBtn.onclick=()=>{const r=roomInput.value.trim();if(r){leaveRoom();enterRoom(r)}};\nthemeSelect.onchange=e=>{const v=e.target.value;store.set('theme',v);applyTheme(v)};avatarColorIn.oninput=createOrUpdateAvatar;\nttsToggle.onchange=e=>store.set('tts',e.target.checked);\nmuteToggle.onchange=e=>updateMicState();\npostBtn.onclick=submitPost;clearBtn.onclick=()=>{if(confirm('\u30ed\u30fc\u30ab\u30eb\u5c65\u6b74\u3092\u524a\u9664\u3057\u307e\u3059\u304b\uff1f')){localStorage.removeItem('vrsns_posts_'+room);timelineEl.innerHTML='';}};\ntagFilter.onchange=filterTimeline;\nwindow.addEventListener('keydown',e=>{if(e.key==='v'&amp;&amp;!pushTalking){pushTalking=true;updateMicState();}});\nwindow.addEventListener('keyup',e=>{if(e.key==='v'){pushTalking=false;updateMicState();}});\n\nasync function setupMic(){try{aCtx=new (window.AudioContext||window.webkitAudioContext)();micStream=await navigator.mediaDevices.getUserMedia({audio:true});updateMicState();}catch(err){alert('\u30de\u30a4\u30af\u5229\u7528\u4e0d\u53ef');}}\nfunction updateMicState(){if(!micStream)return;const enabled=!muteToggle.checked&amp;&amp;(pushTalking||muteToggle.checked===false&amp;&amp;ttsToggle);micStream.getAudioTracks()&#91;0].enabled=enabled;}\n\nfunction enterRoom(r){room=r;roomRef=gun.get('vrsns').get(room);roomInput.value=room;timelineEl.innerHTML='';postsMap.clear();tags.clear();rebuildTagFilter();onlineCount.textContent='\u30aa\u30f3\u30e9\u30a4\u30f3: 0';\nroomRef.get('posts').map().on(onPost);roomRef.get('posts').map().get('reactions').map().on(onReaction);\npresenceRef=roomRef.get('presence').get(myId);presenceRef.put({ts:Gun.state(),color:avatarColorIn.value});presenceInterval=setInterval(()=>presenceRef.put({ts:Gun.state(),color:avatarColorIn.value}),10000);roomRef.get('presence').map().on(updateOnline);\nposRef=roomRef.get('pos').get(myId);sendPos();posInterval=setInterval(sendPos,100);\nroomRef.get('pos').map().on(onRemotePos);roomRef.get('signal').map().on(onSignal);sysMsg(`&#91;${room}] \u5165\u5ba4\u3057\u307e\u3057\u305f`);} \nfunction leaveRoom(){clearInterval(presenceInterval);clearInterval(posInterval);presenceRef&amp;&amp;presenceRef.put(null);posRef&amp;&amp;posRef.put(null);roomRef.off();roomRef.get('signal').off();remoteAvatars.forEach(av=>av.remove());remoteAvatars.clear();remotePeers.forEach(p=>p.destroy());remotePeers.clear();}\n\nfunction submitPost(){const user=usernameInput.value.trim()||'\u533f\u540d',text=postText.value.trim();if(!text)return;store.set('user',user);store.set('color',avatarColorIn.value);const id=Gun.text.random();const post={id,user,text,time:Date.now(),color:avatarColorIn.value,reactions:{'\u2764':0,'\ud83d\ude02':0,'\ud83d\ude2e':0,'\ud83d\ude22':0},tags:extractTags(text)};roomRef.get('posts').get(id).put(post);postText.value='';if(ttsToggle.checked)speak(`${user} \u3055\u3093: ${text.replace(\/#\/g,'')}`);} \nfunction onPost(post){if(!post||postsMap.has(post.id))return;postsMap.set(post.id,post);collectTags(post);rebuildTagFilter();renderPost2D(post);renderPost3D(post);filterTimeline();}\nfunction onReaction(v,field,key){const pid=field,emoji=key;const p=postsMap.get(pid);if(!p)return;p.reactions&#91;emoji]=v;updatePostCard(pid,p);updatePost3D(pid,p);} \nfunction react(id,emo){roomRef.get('posts').get(id).get('reactions').get(emo).once(v=>roomRef.get('posts').get(id).get('reactions').get(emo).put((v||0)+1));}\n\nfunction updateOnline(){let c=0;roomRef.get('presence').map().once(()=>c++);setTimeout(()=>onlineCount.textContent=`\u30aa\u30f3\u30e9\u30a4\u30f3: ${c}`,200);} \nfunction sendPos(){const p=head.object3D.position,l=leftHand.object3D.position,r=rightHand.object3D.position;posRef.put({x:p.x,y:p.y,z:p.z,l:{x:l.x,y:l.y,z:l.z},r:{x:r.x,y:r.y,z:r.z},color:avatarColorIn.value,ts:Gun.state()});}\n\nfunction onRemotePos(data,id){if(id===myId||!data)return;let av=remoteAvatars.get(id);if(!av){av=createAvatar(id,data.color);remoteAvatars.set(id,av);connectVoice(id);}av.setAttribute('position',`${data.x} 0 ${data.z}`);av.querySelectorAll('&#91;geometry]').forEach(g=>g.setAttribute('color',data.color||'#fff'));&#91;'l','r'].forEach(h=>{let el=av.querySelector('.'+h);if(!el){el=document.createElement('a-sphere');el.classList.add(h);el.setAttribute('radius',0.05);av.appendChild(el);}const hp=data&#91;h];if(hp)el.setAttribute('position',`${hp.x} ${hp.y} ${hp.z}`);});}\n\nfunction createAvatar(id,color){const root=document.createElement('a-entity');root.id='av_'+id;root.innerHTML=`&lt;a-sphere radius='0.25' color='${color||'#fff'}' position='0 1.6 0'>&lt;\/a-sphere>&lt;a-cylinder height='0.8' radius='0.2' color='${color||'#fff'}' position='0 1 0'>&lt;\/a-cylinder>`;scene.appendChild(root);return root;}\n\nfunction connectVoice(rid){if(remotePeers.has(rid)||!micStream)return;const init=myId>rid;const peer=new SimplePeer({initiator:init,trickle:true,stream:micStream});remotePeers.set(rid,peer);peer.on('signal',d=>roomRef.get('signal').get(myId).get(rid).put(JSON.stringify(d)));roomRef.get('signal').get(rid).get(myId).on(sig=>sig&amp;&amp;peer.signal(JSON.parse(sig)));peer.on('stream',s=>{const av=remoteAvatars.get(rid);if(!av)return;const a=new Audio();a.srcObject=s;const src=aCtx.createMediaStreamSource(s);const panner=aCtx.createPanner();panner.panningModel='HRTF';panner.distanceModel='inverse';panner.maxDistance=20;src.connect(panner).connect(aCtx.destination);function upd(){if(!av.parentNode)return;const pos=av.object3D.position;panner.setPosition(pos.x,pos.y,pos.z);requestAnimationFrame(upd);}upd();a.play();});peer.on('close',()=>remotePeers.delete(rid));peer.on('error',()=>remotePeers.delete(rid));}\n\nfunction onSignal(){}\n\nfunction renderPost2D(p){const isImg=\/\\.(gif|jpe?g|png|webp)$\/i.test(p.text.trim());const card=document.createElement('div');card.className='post';card.dataset.id=p.id;card.dataset.tags=p.tags.join(',');card.innerHTML=`&lt;strong style='color:${p.color}'>${escapeHTML(p.user)}&lt;\/strong>: ${isImg?`&lt;img src='${escapeHTML(p.text)}'\/>`:linkify(escapeHTML(p.text))}${p.tags.map(t=>` &lt;span class='hashTag'>#${t}&lt;\/span>`).join('')}&lt;br>&lt;small>${new Date(p.time).toLocaleString()}&lt;\/small>`;const bar=document.createElement('div');bar.className='reactBar';&#91;'\u2764','\ud83d\ude02','\ud83d\ude2e','\ud83d\ude22'].forEach(e=>{const b=document.createElement('button');b.className='reactBtn';b.dataset.e=e;b.innerHTML=`${e} &lt;span>${p.reactions&#91;e]||0}&lt;\/span>`;b.onclick=()=>react(p.id,e);bar.appendChild(b);});card.appendChild(bar);card.querySelectorAll('.hashTag').forEach(el=>el.onclick=()=>{tagFilter.value=el.textContent.slice(1).toLowerCase();filterTimeline();});timelineEl.insertBefore(card,timelineEl.firstChild);} \nfunction updatePostCard(id,p){const card=document.querySelector(`.post&#91;data-id='${id}']`);if(card)card.querySelectorAll('.reactBtn').forEach(btn=>btn.querySelector('span').textContent=p.reactions&#91;btn.dataset.e]||0);} \nfunction format3D(p){const top=Object.entries(p.reactions||{}).sort((a,b)=>b&#91;1]-a&#91;1])&#91;0];const r=top&amp;&amp;top&#91;1]>0?` ${top&#91;0]}\u00d7${top&#91;1]}`:'';return `${p.user}${r}\\n${p.text}`;}\nfunction renderPost3D(p){const ent=document.createElement('a-entity');ent.classList.add('interactive');ent.id='p3d_'+p.id;ent.setAttribute('text',{value:format3D(p),align:'center',width:4,color:p.color});ent.onclick=()=>react(p.id,'\u2764');positionEntity(ent);scene.appendChild(ent);setTimeout(()=>ent.remove(),300000);if(\/\\.(gif|jpe?g|png|webp)$\/i.test(p.text.trim())){const plane=document.createElement('a-plane');plane.setAttribute('src',p.text);plane.setAttribute('width',1.8);plane.setAttribute('height',1.2);plane.classList.add('interactive');positionEntity(plane,0.6);scene.appendChild(plane);setTimeout(()=>plane.remove(),300000);}}\nfunction updatePost3D(id,p){const e=$('p3d_'+id);if(e)e.setAttribute('text','value',format3D(p));}\n\nfunction positionEntity(e,y=0){const ang=Math.random()*Math.PI,rad=5+Math.random()*5;e.setAttribute('position',`${Math.cos(ang)*rad} ${2+y} ${-Math.sin(ang)*rad}`);} \nfunction collectTags(p){p.tags.forEach(t=>tags.add(t.toLowerCase()));}\nfunction rebuildTagFilter(){const cur=tagFilter.value;tagFilter.innerHTML='&lt;option value=\"all\">\u3059\u3079\u3066&lt;\/option>'+&#91;...tags].sort().map(t=>`&lt;option value='${t}'>#${t}&lt;\/option>`).join('');tagFilter.value=cur||'all';}\nfunction filterTimeline(){const f=tagFilter.value;document.querySelectorAll('.post').forEach(el=>el.style.display=(f==='all'||el.dataset.tags.includes(f))?'':'none');}\nfunction escapeHTML(s){return s.replace(\/&#91;&amp;&lt;>\"']\/g,ch=>({'&amp;':'&amp;amp;','&lt;':'&amp;lt;',\">\":\"&amp;gt;\",\"\\\"\":\"&amp;quot;\",\"'\":\"&amp;#39;\"}&#91;ch]));}\nfunction extractTags(t){return(t.match(\/#(\\w+)\/g)||&#91;]).map(x=>x.slice(1).toLowerCase());}\nfunction linkify(t){return t.replace(\/https?:\\\/\\\/\\S+\/g,u=>`&lt;a href='${u}' target='_blank'>${u}&lt;\/a>`);} \nfunction applyTheme(t){let sky=scene.querySelector('a-sky');if(!sky){sky=document.createElement('a-sky');scene.appendChild(sky);}sky.setAttribute('color',t==='midnight'?'#000022':t==='day'?'#86cefa':'#112');}\nfunction createOrUpdateAvatar(){const c=avatarColorIn.value;store.set('color',c);let av=$('myAvatar');const body=`&lt;a-sphere radius='0.25' color='${c}' position='0 1.6 0'>&lt;\/a-sphere>&lt;a-cylinder height='0.8' radius='0.2' color='${c}' position='0 1 0'>&lt;\/a-cylinder>`;if(!av){av=document.createElement('a-entity');av.id='myAvatar';av.innerHTML=body;scene.appendChild(av);}else av.innerHTML=body;}\nfunction speak(msg){speechSynthesis.speak(new SpeechSynthesisUtterance(msg));}\nfunction sysMsg(t){const el=document.createElement('div');el.className='post sysMsg';el.textContent=t;timelineEl.insertBefore(el,timelineEl.firstChild);} \n})();\n&lt;\/script>\n&lt;\/body>\n&lt;\/html>\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[80,54],"tags":[],"class_list":["post-25970","post","type-post","status-publish","format-standard","hentry","category-html","category-vr"],"aioseo_notices":[],"jetpack_featured_media_url":"","_links":{"self":[{"href":"http:\/\/www.tyosuke20xx.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/25970","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.tyosuke20xx.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.tyosuke20xx.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.tyosuke20xx.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.tyosuke20xx.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=25970"}],"version-history":[{"count":1,"href":"http:\/\/www.tyosuke20xx.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/25970\/revisions"}],"predecessor-version":[{"id":25971,"href":"http:\/\/www.tyosuke20xx.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/25970\/revisions\/25971"}],"wp:attachment":[{"href":"http:\/\/www.tyosuke20xx.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=25970"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.tyosuke20xx.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=25970"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.tyosuke20xx.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=25970"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}