A family travel blog meant to track our family goals and to inspire the world that anyone with vision backed with SMART goals are meant to have their dreams come to a reality!
merhaba · hello kumusta · how are you aile · pamilya home = us
LIVE · SUNDAY CALL
👵
🧒
one home · many clocks
🍲
one table
your family word
Turknoy
Turkish + Pinoy
pamilyaaşkım
Your result
This word belongs to your family
✓ Family word found
A family word is not official. It is personal.
Your family word, editable
✎ Tap the word to edit it
Family Language Type💙—
Not quite you? Nudge it.
Word meaning
Your family’s love language
Family motto
Short story line
Social caption, ready to post
Your shareable card
Build a card people will screenshot
Card theme
Format
✉
ManyRoots · WordPlayPASSPORT
—
—
Create yours at TurknoyTravels100.world
TurknoyTravels100.world
Social caption preview
I understand this saves my entry only on this device. I will not include private addresses, children’s full names, contact details, or sensitive personal information.
Display name optional
Country or region optional
Six themes, four formats, namely Instagram square, story, Facebook post, and Pinterest vertical. The live preview updates as you choose.
🪶This is playful, not definitive. Make a word in the Word Forge above, then a full result and a share card will appear right here. Edit, regenerate, or reject any word that does not feel like your family.
Social proof
Families like yours are already inventing words.
Tap any mix to send it straight to the Word Forge and watch it run.
How it works
Some families are built in airports, video calls, recipes, and second languages.
This studio helps you name yours in four small steps. Tap a step to preview it.
Optional
Refine your word
The Word Forge is enough for most families. Open this to add more roots, set a style and a mood, and shape the meaning.
Open the full studio controls ▾
Root 1 culture, country, language, or place
Root 2 culture, country, language, or place
Additional root optional
Where your family lives now optional
Where your family is connected to optional
Your main family experienceChoose the one that feels truest.
Word styleHow should your word feel? You can change this and regenerate any time.
Family moodShapes the tone of your caption and motto.
Family words or nicknames optional
A food, place, or ritual that feels like home optional
My Local Word Wall
Home is sometimes a sentence only your family understands.
Collect your family words here. Tap any card to try that mix in the Word Forge.
Private by design. Entries are saved only on this device in your browser. They are not posted publicly. If a public Word Wall launches later, submissions would be moderated before appearing publicly.
0 family words saved on this device
Filter by family language type
Why it matters
Distance does not divide a family. It teaches it a new language.
🍲
Food is a sentence
A shared dish can say more than words. Many families speak love through the table first.
📞
A call is a homecoming
Across time zones, a voice note or a video call becomes the door everyone walks through.
🧳
Roots and routes both count
Where your family comes from matters. So does every road it has traveled since.
Origin word
Turknoy
Turkish + Pinoy
Our story
One word among many
ManyRoots WordPlay Studio was inspired by Turknoy, a family word born from Turkish and Pinoy. But Turknoy is only one example. Around the world, families are creating their own languages across race, culture, distance, food, migration, love, and home. This free tool helps you find yours.
Turknoy is the origin word, not the boundary. It began with Turkish and Pinoy. Now it opens into a global wordplay studio for families with many roots.
Deployment validation
Copied
/* =====================================================================
ManyRoots WordPlay Studio by TurknoyTravels100.world
Static. No backend. No login. No paid API.
NOTE: This script is written with ZERO ampersand characters so that
WordPress wptexturize and WPCode entity-encoding cannot corrupt it.
Logical AND is expressed with nested ifs or ternaries.
===================================================================== */
/* ===================== DEPLOYMENT CONSTANTS (single source of truth) ===================== */
var DEPLOYED_APP_URL = “https://turknoytravels100.world/manyroots/”;
var BRAND_HOME_URL = “https://TurknoyTravels100.world”;
var OG_IMAGE_URL = “https://turknoytravels100.world/wp-content/uploads/2026/05/og-image.png”;
function isPlaceholder(u){ return u.indexOf(“FINAL_WORKING_APP_URL_HERE”) > -1; }
function syncDeploymentUrls(){
try{
var can=document.querySelector(‘link[rel=”canonical”]’); if(can){ can.setAttribute(“href”, DEPLOYED_APP_URL); }
var ogu=document.querySelector(‘meta[property=”og:url”]’); if(ogu){ ogu.setAttribute(“content”, DEPLOYED_APP_URL); }
var ogi=document.querySelector(‘meta[property=”og:image”]’); if(ogi){ ogi.setAttribute(“content”, OG_IMAGE_URL); }
var twi=document.querySelector(‘meta[name=”twitter:image”]’); if(twi){ twi.setAttribute(“content”, OG_IMAGE_URL); }
}catch(e){}
if(isPlaceholder(DEPLOYED_APP_URL)){ document.getElementById(“devBanner”).classList.add(“show”); }
}
/* ===================== DATA ===================== */
var CTAS = [
“Create yours at TurknoyTravels100.world”,
“Made with ManyRoots WordPlay Studio by TurknoyTravels100.world”,
“Find your family language at TurknoyTravels100.world”
];
var CANONICAL_BLENDS = [
{ matchAnyOrder:[[“turkish”,”turkey”,”turk”],[“filipino”,”pinoy”,”philippine”,”philippines”,”tagalog”]],
word:”Turknoy”, meaning:”Turkish and Pinoy, the origin word behind TurknoyTravels100.world.” }
];
var LOVE = {
“Roots Love”: {ic:”\uD83C\uDF33″, tag:”honoring where you come from”, tip:”For families who hold their origins close and pass them forward.”},
“Routes Love”: {ic:”\uD83E\uDDED”, tag:”belonging built on the move”, tip:”For families whose identity grew across countries and journeys.”},
“Translation Love”:{ic:”\uD83D\uDDE3\uFE0F”, tag:”meeting between languages”, tip:”For families who love across more than one language, mixing words daily.”},
“Table Love”: {ic:”\uD83C\uDF72″, tag:”love served at the table”, tip:”For families who say the most through food, recipes, and shared meals.”},
“Distance Love”: {ic:”\uD83C\uDF19″, tag:”close even when far”, tip:”For families separated by miles who stay near in heart.”},
“Time Zone Love”: {ic:”\u23F0″, tag:”one home across many clocks”, tip:”For families living in different time zones who keep one emotional home.”},
“Ritual Love”: {ic:”\uD83D\uDD6F\uFE0F”, tag:”meaning made by repetition”, tip:”For families bound by holidays, traditions, and small repeated rituals.”},
“Nickname Love”: {ic:”\uD83D\uDCAC”, tag:”a private language of names”, tip:”For families with their own nicknames, inside words, and jokes.”},
“Return Love”: {ic:”\uD83C\uDFE1″, tag:”always finding the way home”, tip:”For families defined by reunions and the joy of coming back.”},
“Bridge Love”: {ic:”\uD83C\uDF09″, tag:”two worlds, one rhythm”, tip:”For families who build a bridge between cultures and races with care.”},
“ManyHomes Love”: {ic:”\uD83D\uDDFA\uFE0F”, tag:”home in more than one place”, tip:”For families who carry several homes and belong to all of them.”},
“Voice Note Love”: {ic:”\uD83C\uDF99\uFE0F”, tag:”closeness through every call”, tip:”For families who keep in touch through calls, voice notes, and messages.”},
“Airport Love”: {ic:”\u2708\uFE0F”, tag:”hellos worth the goodbyes”, tip:”For families who measure love in arrivals and departures.”},
“Story Love”: {ic:”\uD83D\uDCD6″, tag:”memory passed down”, tip:”For families who keep their history alive through stories across generations.”},
“Food Parcel Love”:{ic:”\uD83D\uDCE6″, tag:”care you can taste”, tip:”For families who send food, spices, and packages across the world as love.”}
};
var EXP_MAP = {
“Across cultures”: [“Bridge Love”,”Translation Love”,”ManyHomes Love”],
“Across races”: [“Bridge Love”,”Roots Love”,”ManyHomes Love”],
“Across countries”: [“Routes Love”,”ManyHomes Love”,”Return Love”],
“Across languages”: [“Translation Love”,”Nickname Love”,”Bridge Love”],
“Across distance”: [“Distance Love”,”Voice Note Love”,”Airport Love”],
“Across time zones”: [“Time Zone Love”,”Distance Love”,”Voice Note Love”],
“Across generations”: [“Story Love”,”Roots Love”,”Ritual Love”],
“Across food traditions”: [“Table Love”,”Food Parcel Love”,”Ritual Love”],
“Across holidays”: [“Ritual Love”,”Return Love”,”Story Love”],
“Across many homes”: [“ManyHomes Love”,”Routes Love”,”Return Love”]
};
var EXPERIENCES = Object.keys(EXP_MAP);
var STYLES = [“Best”,”Funny”,”Poetic”,”Name-like”,”Food-inspired”,”Less food-based”,”More respectful”];
var MOODS = [“Warm”,”Funny”,”Proud”,”Poetic”,”Travel-inspired”,”Nostalgic”,”Kid-friendly”,”Social-ready”];
var THEMES = [
{id:”passport”, name:”Passport Stamp”, badge:”PASSPORT”, alt:”a navy passport-stamp card”},
{id:”table”, name:”Family Table”, badge:”ONE TABLE”, alt:”a warm terracotta family-table card”},
{id:”airport”, name:”Airport Goodbye”,badge:”BOARDING”, alt:”a teal airport boarding-pass card”},
{id:”postcard”, name:”Postcard Home”, badge:”POSTCARD”, alt:”a cream postcard with a stamp box”},
{id:”notebook”, name:”Kids Notebook”, badge:”OUR WORDS”, alt:”a lined notebook card in handwriting”},
{id:”recipe”, name:”Recipe Memory”, badge:”RECIPE”, alt:”a recipe-card style memory card”}
];
var LEXICON = [
{k:[“turkish”,”turkey”,”turk”], head:”turk”, flavor:”merhaba”, food:”simit”},
{k:[“filipino”,”pinoy”,”philippine”,”philippines”,”tagalog”,”pilipino”], head:”fili”, tail:”noy”, flavor:”mahal”, food:”adobo”},
{k:[“finnish”,”finland”,”suomi”], head:”fin”, flavor:”sisu”},
{k:[“indian”,”india”,”hindi”,”desi”], head:”ind”, flavor:”pyaar”, food:”masala”},
{k:[“british”,”britain”,”england”,”english”,”uk”], head:”brit”, tail:”shire”, flavor:”shire”},
{k:[“kenyan”,”kenya”,”swahili”], head:”ken”, flavor:”jambo”},
{k:[“french”,”france”,”francais”], head:”franc”, tail:”france”, flavor:”cherie”},
{k:[“korean”,”korea”,”hangul”], head:”kor”, flavor:”jeong”, food:”kimchi”},
{k:[“mexican”,”mexico”,”mexicano”], head:”mex”, flavor:”querido”, food:”taco”},
{k:[“nigerian”,”nigeria”,”naija”,”yoruba”,”igbo”], head:”naija”, flavor:”naija”},
{k:[“japanese”,”japan”,”nippon”,”nihon”], head:”japon”, tail:”japon”, flavor:”japon”},
{k:[“arab”,”arabic”,”arabian”], head:”habib”, flavor:”habibi”},
{k:[“brazilian”,”brazil”,”brasil”], head:”bra”, tail:”alegria”, flavor:”alegria”},
{k:[“italian”,”italy”,”italiano”], head:”ital”, flavor:”amore”, food:”pasta”},
{k:[“spanish”,”spain”,”espanol”,”espana”],head:”espa”, flavor:”carino”},
{k:[“greek”,”greece”,”ellinika”], head:”greco”, flavor:”agapi”},
{k:[“chinese”,”china”,”mandarin”,”han”], head:”chin”, flavor:”jia”},
{k:[“thai”,”thailand”], head:”thai”, flavor:”sabai”, food:”padthai”},
{k:[“vietnamese”,”vietnam”,”viet”], head:”viet”, flavor:”thuong”, food:”pho”},
{k:[“german”,”germany”,”deutsch”], head:”deut”, flavor:”heimat”},
{k:[“dutch”,”netherlands”,”holland”], head:”nether”,flavor:”gezellig”},
{k:[“polish”,”poland”,”polski”], head:”pol”, flavor:”kochanie”},
{k:[“portuguese”,”portugal”], head:”porto”, flavor:”saudade”},
{k:[“russian”,”russia”], head:”rus”, flavor:”rodina”},
{k:[“ukrainian”,”ukraine”], head:”ukra”, flavor:”rodyna”},
{k:[“egyptian”,”egypt”], head:”egy”, flavor:”habibi”},
{k:[“moroccan”,”morocco”], head:”maroc”, flavor:”baraka”},
{k:[“ethiopian”,”ethiopia”], head:”ethio”, flavor:”fiqir”, food:”injera”},
{k:[“ghanaian”,”ghana”], head:”ghana”, flavor:”akwaaba”},
{k:[“south african”,”mzansi”,”zulu”], head:”mzansi”,flavor:”ubuntu”},
{k:[“american”,”america”,”usa”,”united states”], head:”ameri”, flavor:”home”},
{k:[“canadian”,”canada”], head:”cana”, flavor:”home”},
{k:[“australian”,”australia”,”aussie”], head:”aussi”, flavor:”mate”},
{k:[“irish”,”ireland”,”eire”], head:”eire”, flavor:”gra”},
{k:[“scottish”,”scotland”], head:”scot”, flavor:”hame”},
{k:[“swedish”,”sweden”,”svensk”], head:”sven”, flavor:”fika”},
{k:[“norwegian”,”norway”,”norsk”], head:”norse”, flavor:”kos”},
{k:[“danish”,”denmark”,”dansk”], head:”dane”, flavor:”hygge”},
{k:[“lebanese”,”lebanon”], head:”leba”, flavor:”habibi”},
{k:[“syrian”,”syria”], head:”sham”, flavor:”habibi”},
{k:[“palestinian”,”palestine”], head:”pales”, flavor:”sumud”},
{k:[“iranian”,”iran”,”persian”,”farsi”], head:”pars”, flavor:”azizam”},
{k:[“pakistani”,”pakistan”,”urdu”], head:”pak”, flavor:”jaan”},
{k:[“bangladeshi”,”bangladesh”,”bengali”],head:”bangla”,flavor:”shonar”},
{k:[“sri lankan”,”sri lanka”,”tamil”,”sinhala”], head:”lanka”, flavor:”ammi”},
{k:[“nepali”,”nepal”], head:”nepa”, flavor:”maya”},
{k:[“indonesian”,”indonesia”,”bahasa”], head:”indo”, flavor:”sayang”},
{k:[“malaysian”,”malaysia”,”malay”], head:”malay”, flavor:”sayang”},
{k:[“singaporean”,”singapore”], head:”singa”, flavor:”lah”},
{k:[“colombian”,”colombia”], head:”colom”, flavor:”querido”},
{k:[“argentine”,”argentinian”,”argentina”], head:”arga”, flavor:”carino”},
{k:[“peruvian”,”peru”], head:”peru”, flavor:”carino”},
{k:[“jamaican”,”jamaica”], head:”jamai”, flavor:”irie”},
{k:[“cuban”,”cuba”], head:”cuba”, flavor:”mivida”},
{k:[“turkish cypriot”,”cypriot”,”cyprus”],head:”cypr”, flavor:”merhaba”}
];
/* ===================== HELPERS (zero ampersand) ===================== */
function bAND(a,b){ return a ? (b ? true : false) : false; }
function cleanInput(s){ if(!s) return “”; return String(s).toLowerCase().trim().replace(/[^a-z\u00E0-\u00FF\s\-]/gi,””).replace(/\s+/g,” “); }
function matchGroup(c,arr){ if(!c) return false; for(var i=0;i-1||arr[i].indexOf(c)>-1) return true; } return false; }
function checkCanonical(c1,c2){
for(var i=0;i<CANONICAL_BLENDS.length;i++){
var g=CANONICAL_BLENDS[i].matchAnyOrder;
var fwd = matchGroup(c1,g[0]) ? matchGroup(c2,g[1]) : false;
var rev = matchGroup(c1,g[1]) ? matchGroup(c2,g[0]) : false;
if(fwd||rev) return CANONICAL_BLENDS[i];
}
return null;
}
function lex(c){ if(!c) return null; for(var i=0;i<LEXICON.length;i++){ var e=LEXICON[i]; for(var j=0;j-1||e.k[j].indexOf(c)>-1) return e; } } return null; }
function stem(c){ if(!c) return “”; var w=c.split(” “)[0]; var s=w.replace(/(ish|ese|ian|ino|eans|ean|aise|ais|i)$/,””); if(s.length<3) s=w; return s; }
function cap(s){ return s? s.charAt(0).toUpperCase()+s.slice(1):s; }
function tidy(w){ if(!w) return ""; w=w.toLowerCase().replace(/(.)\1{2,}/g,"$1$1").replace(/([aeiou])\1+/g,"$1").replace(/([^aeiou])\1/g,"$1"); return cap(w); }
function pronounceable(w){ var hasV=/[aeiouy\u00E0-\u00FF]/i.test(w); var manyC=/[^aeiouy\u00E0-\u00FF]{5,}/i.test(w); return hasV ? (!manyC) : false; }
function createFamilyWord(r1,r2,r3,style){
var c1=cleanInput(r1), c2=cleanInput(r2), c3=cleanInput(r3);
var l1=lex(c1), l2=lex(c2);
var s1=stem(c1), s2=stem(c2), s3=stem(c3);
var blend=[], food=[], suffix=[], poetic=[];
function add(arr,w){ if(w) arr.push(tidy(w)); }
if(c1){ if(c2){
var headA=s1.slice(0,Math.max(3,Math.ceil(s1.length/2))); if(l1){ if(l1.head){ headA=l1.head; } }
var tailB=c2.slice(Math.max(0,Math.floor(c2.length/2))); if(l2){ if(l2.tail){ tailB=l2.tail; } }
add(blend, headA+tailB);
var hb1=s1.slice(0,3); if(l1){ if(l1.head){ hb1=l1.head; } }
var tb1=cap(s2); if(l2){ if(l2.tail){ tb1=l2.tail; } }
add(blend, hb1+tb1);
var hb2=s2.slice(0,3); if(l2){ if(l2.head){ hb2=l2.head; } }
add(blend, hb2 + c1.slice(Math.max(0,Math.floor(c1.length/2))));
if(l1){ if(l2){
var lh=l1.head?l1.head:s1; var lf=l2.flavor?l2.flavor:s2; add(blend, lh+lf);
if(l1.food){ if(l2.food){ add(food, l1.food+l2.food); } }
if(l1.flavor){ if(l2.flavor){ add(poetic, l1.flavor+l2.flavor); } }
}}
}}
if(c3){ add(blend, s1.slice(0,2)+s2.slice(0,2)+s3.slice(0,3)); }
var sfx=["home","roots","route","clan","haven","nest"];
var base=s1||s2||"family"; if(l1){ if(l1.head){ base=l1.head; } }
for(var i=0;i<sfx.length;i++){ add(suffix, base+sfx[i]); }
add(poetic, base+"home"); add(poetic, base+"haven");
var order;
switch(style){
case "Funny": order=[food,suffix,blend,poetic]; break;
case "Poetic": order=[poetic,blend,suffix,food]; break;
case "Name-like": order=[blend,poetic,suffix,food]; break;
case "Food-inspired": order=[food,blend,poetic,suffix]; break;
case "Less food-based": order=[blend,suffix,poetic]; break;
case "More respectful": order=[blend,suffix]; break;
default: order=[blend,food,suffix,poetic];
}
var merged=[];
order.forEach(function(arr){ arr.forEach(function(w){ merged.push(w); }); });
var seen={}, out=[];
for(var k=0;k<merged.length;k++){
var w=merged[k];
if(!w) continue;
if(w.length14) continue;
if(!pronounceable(w)) continue;
if(w.toLowerCase()===c1||w.toLowerCase()===c2) continue;
var key=w.toLowerCase();
if(seen[key]) continue; seen[key]=1; out.push(w);
}
if(out.length===0) out=[“ManyRoots”,”OneHome”,”Routeling”];
return out;
}
function loveCandidates(exp, words, home){
var base=(EXP_MAP[exp]||[“Bridge Love”,”ManyHomes Love”,”Routes Love”]).slice();
var t=cleanInput(words)+” “+cleanInput(home);
function bump(type){ var i=base.indexOf(type); if(i>0) base.splice(i,1); if(base[0]!==type) base.unshift(type); }
if(/call|voice|video|message|text|whatsapp|facetime/.test(t)) bump(“Voice Note Love”);
if(/food|dish|recipe|cook|meal|kitchen|adobo|kimchi|simit|rice|bread|soup|taco|pasta/.test(t)) bump(“Table Love”);
if(/parcel|package|send|box|spice/.test(t)) bump(“Food Parcel Love”);
if(/airport|flight|visit|reunion|gate|arrival/.test(t)) bump(“Airport Love”);
if(/nick|name|lola|lolo|anne|baba|tito|tita|nana|dede/.test(t)) bump(“Nickname Love”);
var seen={},out=[]; for(var i=0;i1?”histories”:”roads”)+”. One table. One family.”,”Two climates. Many stories. One home.”,”Far in miles. Close in love.”,”Many homes. One heartbeat.”];
var poetic=[“We are a sentence only we can finish.”,”Home is the word we built together.”,”Distance learned our names.”];
var funny=[“Loud kitchen. Soft hearts. Many roots.”,”Built in airports and group chats.”,”Two passports. One snack rule.”];
var set= style===”Poetic”?poetic : style===”Funny”?funny : warm;
return set[seed % set.length];
}
function createCaption(word,love,motto,style,seed){
var lt=LOVE[love]?LOVE[love].tag:”shared belonging”;
var cta=CTAS[seed % CTAS.length];
var t=[
“We found our family word: “+word+”. Our family language type is “+love+”, where “+lt+”. “+motto+” “+cta,
“Meet “+word+”. Our family language type is “+love+”: “+lt+”. Many roots, many routes, one family language. “+cta,
“Our family love language is “+love+”: “+lt+”. This is “+word+”. “+cta,
word+” is the word for our family. “+love+”, “+lt+”. “+cta
];
return t[seed % t.length];
}
function createStoryLine(roots,livesNow,connectedTo,love,seed){
var rt=roots.join(” and “);
var place=livesNow?(” Now we live in “+livesNow+”.”):””;
var conn=connectedTo?(” Our hearts stay tied to “+connectedTo+”.”):””;
var lt=LOVE[love]?LOVE[love].tag:”belonging across worlds”;
var t=[
“We are a “+rt+” family who learned that “+lt+” needs its own word.”+place+conn,
“From “+rt+”, we built a home that travels with us, fluent in “+lt+”.”+place+conn,
“A “+rt+” family writing its own quiet language of “+lt+”.”+conn+place
];
return t[seed % t.length];
}
function createShareText(word,love,motto,seed){ var cta=CTAS[(seed+1)%CTAS.length]; return “Our family word is “+word+”, a “+love+” family. “+motto+” “+cta; }
function igCaption(word,love,motto,roots){
return word+” is the word for our family. “+roots+”. Family language type: “+love+”. “+motto+”\n\nMake yours free at TurknoyTravels100.world\n#ManyRoots #FamilyLanguage #TurknoyTravels100 #MixedFamily #ThirdCulture #ManyRootsManyRoutes”;
}
function storyCaption(word,love,motto,story){
return story+”\n\nSo we gave it a word: “+word+”. A “+love+” family. “+motto+”\n\nMake your family word at TurknoyTravels100.world”;
}
/* ===================== STATE + STORAGE ===================== */
var state={ exp:”Across cultures”, style:”Best”, mood:”Warm”, seed:0, result:null, format:”square”, theme:”passport”, canon:null, lastInputs:null };
var memStore={}, WALL_KEY=”manyroots_wordwall_v2″;
function storeGet(k){ try{ return window.localStorage.getItem(k); }catch(e){ return (k in memStore)?memStore[k]:null; } }
function storeSet(k,v){ try{ window.localStorage.setItem(k,v); return true; }catch(e){ memStore[k]=v; return false; } }
function lsAvailable(){ try{ var t=”__mr_test__”; window.localStorage.setItem(t,”1″); window.localStorage.removeItem(t); return true; }catch(e){ return false; } }
var SAMPLES=[
{word:”Farhome”, roots:”Philippines + Qatar + Finland”, type:”Time Zone Love”, meaning:”A family that lives across clocks but keeps one emotional home.”, region:”Worldwide”, date:”Sample”, sample:true},
{word:”Kimchitaco”, roots:”Korean + Mexican”, type:”Table Love”, meaning:”A family table where spice, laughter, and love speak louder than borders.”, region:”Worldwide”, date:”Sample”, sample:true},
{word:”Naijapon”, roots:”Nigerian + Japanese”, type:”Bridge Love”, meaning:”A family rhythm built from warmth, respect, and shared care.”, region:”Worldwide”, date:”Sample”, sample:true},
{word:”Habibalegria”, roots:”Arab + Brazilian”, type:”Routes Love”, meaning:”Where affection, music, hospitality, and joy become one family language.”, region:”Worldwide”, date:”Sample”, sample:true},
{word:”Turknoy”, roots:”Turkish + Filipino”, type:”ManyHomes Love”, meaning:”Turkish and Pinoy, the origin word behind TurknoyTravels100.world.”, region:”Worldwide”, date:”Sample”, sample:true}
];
function loadWall(){ var raw=storeGet(WALL_KEY); if(!raw){ storeSet(WALL_KEY,JSON.stringify(SAMPLES)); return SAMPLES.slice(); } try{ return JSON.parse(raw); }catch(e){ return SAMPLES.slice(); } }
function saveWall(a){ storeSet(WALL_KEY,JSON.stringify(a)); }
/* ===================== SMALL DOM UTILS ===================== */
function el(id){ return document.getElementById(id); }
function val(id){ return el(id).value.trim(); }
function ph(id){ return el(id).placeholder; }
function reducedMotion(){ try{ return window.matchMedia(“(prefers-reduced-motion: reduce)”).matches; }catch(e){ return false; } }
function motionPaused(){ return document.body.classList.contains(“motion-paused”); }
function noMotion(){ return reducedMotion() ? true : motionPaused(); }
function announce(msg){ el(“srStatus”).textContent=msg; }
function escapeHtml(s){
var A=String.fromCharCode(38);
var map={}; map[A]=A+”amp;”; map[“”]=A+”gt;”; map[‘”‘]=A+”quot;”; map[“‘”]=A+”#39;”;
var re=new RegExp(“[“+A+”\”‘]”,”g”);
return String(s).replace(re,function(c){ return map[c]; });
}
function escapeAttr(s){ return escapeHtml(s); }
function toast(msg){ var t=el(“toast”); t.textContent=msg; t.classList.add(“show”); clearTimeout(t._tm); t._tm=setTimeout(function(){t.classList.remove(“show”);},2200); }
function copiedFlash(btn){ if(!btn) return; btn.classList.add(“copied”); clearTimeout(btn._ct); btn._ct=setTimeout(function(){ btn.classList.remove(“copied”); },1500); }
/* ===================== CHIPS ===================== */
function makeChip(text,activeVal,onPick,extraClass){
var b=document.createElement(“button”);
b.type=”button”; b.className=”chip “+(extraClass||””);
b.textContent=text;
b.setAttribute(“aria-pressed”, text===activeVal?”true”:”false”);
b.onclick=function(){ onPick(text); };
return b;
}
function setPressed(containerId,v){
document.querySelectorAll(“#”+containerId+” .chip”).forEach(function(n){ n.setAttribute(“aria-pressed”, n.textContent===v?”true”:”false”); });
}
function buildChips(){
var ec=el(“expChips”);
EXPERIENCES.forEach(function(e){ ec.appendChild(makeChip(e,state.exp,function(v){state.exp=v;setPressed(“expChips”,v);})); });
var sc=el(“styleChips”);
STYLES.forEach(function(s){ sc.appendChild(makeChip(s,state.style,function(v){ state.style=v; setPressed(“styleChips”,v); if(state.result){ generate(true); } }, “style”)); });
var mc=el(“moodChips”);
MOODS.forEach(function(m){ mc.appendChild(makeChip(m,state.mood,function(v){state.mood=v;setPressed(“moodChips”,v); if(state.result){ updateCaption(); }},”mood”)); });
}
function buildThemeChips(){
var tc=el(“themeChips”);
THEMES.forEach(function(t){
var b=document.createElement(“button”); b.type=”button”; b.className=”chip”;
b.textContent=t.name; b.setAttribute(“aria-pressed”, t.id===state.theme?”true”:”false”);
b.onclick=function(){ state.theme=t.id; document.querySelectorAll(“#themeChips .chip”).forEach(function(n){n.setAttribute(“aria-pressed”,”false”);}); b.setAttribute(“aria-pressed”,”true”); applyTheme(true); };
tc.appendChild(b);
});
}
function buildFormatChips(){
var formats=[[“square”,”Instagram square”],[“story”,”Instagram story”],[“post”,”Facebook post”],[“pin”,”Pinterest vertical”]];
var fc=el(“formatChips”);
formats.forEach(function(f){
var b=document.createElement(“button”); b.type=”button”; b.className=”chip”;
b.textContent=f[1]; b.setAttribute(“aria-pressed”, f[0]===state.format?”true”:”false”);
b.onclick=function(){ state.format=f[0]; document.querySelectorAll(“#formatChips .chip”).forEach(function(n){n.setAttribute(“aria-pressed”,”false”);}); b.setAttribute(“aria-pressed”,”true”); applyFormat(); };
fc.appendChild(b);
});
}
function applyFormat(){ var c=el(“shareCard”); c.className=”fcard “+(state.format===”square”?””:state.format); c.setAttribute(“data-theme”,state.theme); updateCardAlt(); }
function applyTheme(animate){
var c=el(“shareCard”); c.setAttribute(“data-theme”,state.theme);
var th=THEMES.filter(function(x){return x.id===state.theme;})[0];
el(“cardBadge”).textContent=th.badge;
document.querySelector(“.fc-stampbox”).style.display = state.theme===”postcard”?”flex”:”none”;
if(animate){ if(!noMotion()){ c.classList.remove(“theme-swap”); void c.offsetWidth; c.classList.add(“theme-swap”); } }
updateCardAlt();
}
/* ===================== GENERATION ===================== */
function gatherInputs(){
var roots=[];
[“root1″,”root2″,”root3”].forEach(function(id){ var v=val(id); if(v) roots.push(v); });
return { roots:roots, livesNow:val(“livesNow”), connectedTo:val(“connectedTo”), words:val(“words”), home:val(“home”) };
}
function generate(regen){
var inp=gatherInputs();
if(inp.roots.length<1){ toast("Add at least one root to begin"); announce("Please add at least one root to begin."); el("miniRoot1").focus(); return; }
state.lastInputs=inp;
if(regen){ state.seed++; } else { state.seed=0; }
var seed=state.seed;
var canon=checkCanonical(cleanInput(inp.roots[0]), cleanInput(inp.roots[1]||""));
state.canon=canon;
var words=createFamilyWord(inp.roots[0], inp.roots[1]||"", inp.roots[2]||"", state.style);
if(canon){ words=[canon.word].concat(words.filter(function(w){return w.toLowerCase()!==canon.word.toLowerCase();})); }
var word=words[seed % words.length];
var loves=loveCandidates(state.exp, inp.words, inp.home);
var love=loves[seed % loves.length];
var meaning=createMeaning(inp.roots, love, inp.home, state.style, seed, canon?canon.meaning:null);
var motto=createMotto(inp.roots, love, state.style, seed);
var caption=createCaption(word, love, motto, state.style, seed);
var story=createStoryLine(inp.roots, inp.livesNow, inp.connectedTo, love, seed);
state.result={ word:word, love:love, meaning:meaning, motto:motto, caption:caption, story:story, roots:inp.roots.join(" + ") };
renderResult(regen);
}
function staged(){
var rows=document.querySelectorAll("#resultWrap .rrow");
rows.forEach(function(r){ r.classList.remove("show"); });
if(noMotion()){ rows.forEach(function(r){ r.classList.add("show"); }); return; }
rows.forEach(function(r,ix){ setTimeout(function(){ r.classList.add("show"); }, 140*(ix+1)); });
}
function fireStamp(){
var s=el("stampFound");
s.classList.remove("go"); void s.offsetWidth;
if(!noMotion()){ s.classList.add("go"); } else { s.style.opacity="1"; }
}
function pulseRoutes(){
var c=el("collage"); if(noMotion()) return;
c.classList.remove("firepulse"); void c.offsetWidth; c.classList.add("firepulse");
}
function renderResult(regen){
var r=state.result, lv=LOVE[r.love];
el("preNudge").classList.add("hidden");
el("resultWrap").classList.remove("hidden");
var input=el("rWord");
input.value=r.word;
if(!noMotion()){ shuffleWord(input, r.word); }
el("rLoveName").textContent=r.love;
el("rLoveEmoji").textContent=lv.ic;
el("rLoveTip").textContent=lv.tip;
el("rMeaning").textContent=r.meaning;
el("rLove2").textContent="Your family love language is "+r.love+", namely "+lv.tag+".";
el("rMotto").textContent="\u201C"+r.motto+"\u201D";
el("rStory").textContent=r.story;
el("rCaption").textContent=r.caption;
updateCardFromState(r.word);
staged(); fireStamp(); pulseRoutes();
announce("Generated the family word "+r.word+". Family language type "+r.love+". You can edit the word.");
if(!regen){ el("resultWrap").scrollIntoView({behavior:noMotion()?"auto":"smooth", block:"start"}); }
}
function updateCaption(){
var r=state.result; if(!r) return;
r.caption=createCaption(document.getElementById("rWord").value.trim()||r.word, r.love, r.motto, state.style, state.seed);
el("rCaption").textContent=r.caption;
updateCapPreview();
}
function updateCapPreview(){
var r=state.result; if(!r) return;
var w=val("rWord")||r.word;
el("capPreview").textContent=igCaption(w, r.love, r.motto, r.roots);
}
function updateCardFromState(wordOverride){
var r=state.result; if(!r) return;
var lv=LOVE[r.love];
var w=wordOverride || val("rWord") || r.word;
el("cardWord").textContent=w;
el("cardRootsTop").textContent=r.roots;
el("cardType").textContent=lv.ic+" "+r.love;
el("cardMotto").textContent="\u201C"+r.motto+"\u201D";
applyTheme(false); applyFormat(); updateCapPreview();
}
function updateCardAlt(){
var r=state.result; if(!r) return;
var th=THEMES.filter(function(x){return x.id===state.theme;})[0];
var w=val("rWord")||r.word;
el("cardAlt").textContent="Card preview: "+th.alt+" showing the family word "+w+", roots "+r.roots+", family language type "+r.love+", and the line Create yours at TurknoyTravels100.world.";
}
function shuffleWord(input, finalWord){
var letters="ABCDEFGHIJKLMNOPQRSTUVWXYZ", frames=10, i=0;
input.parentNode.classList.add("shuffling");
var iv=setInterval(function(){
var s="";
for(var k=0;k<finalWord.length;k++){
if(kframes){ clearInterval(iv); input.value=finalWord; input.parentNode.classList.remove(“shuffling”); updateCardFromState(); }
},45);
}
/* feedback nudges */
function applyFeedback(style){
state.style=style; setPressed(“styleChips”,style);
if(state.result){ generate(false); }
toast(“Reforged: “+style.toLowerCase());
}
/* live forge preview */
function quickPreview(){
var r1=val(“miniRoot1”)||ph(“miniRoot1”);
var r2=val(“miniRoot2”)||ph(“miniRoot2″);
var c1=cleanInput(r1), c2=cleanInput(r2);
var canon=checkCanonical(c1,c2);
var w; if(canon){ w=canon.word; } else { var list=createFamilyWord(r1,r2,””,”Best”); w=list[0]; }
var elp=el(“forgePreview”);
if(noMotion()){ elp.textContent=w; return; }
elp.classList.add(“flip”);
setTimeout(function(){ elp.textContent=w; elp.classList.remove(“flip”); }, 170);
}
function runMini(){
var r1=val(“miniRoot1”)||ph(“miniRoot1”);
var r2=val(“miniRoot2”)||ph(“miniRoot2”);
el(“root1”).value=r1; el(“root2”).value=r2; el(“root3″).value=””;
generate(false);
}
/* ===================== EXAMPLE CAROUSEL ===================== */
var FAMILIES=[
{r1:”Filipino”, r2:”Turkish”, word:”Turknoy”, type:”ManyHomes Love”, mean:”Turkish and Pinoy, the origin word for a family at home in more than one place.”},
{r1:”Korean”, r2:”Mexican”, word:”Kimchitaco”, type:”Table Love”, mean:”A family table where spice, laughter, and love speak louder than borders.”},
{r1:”Nigerian”, r2:”Japanese”, word:”Naijapon”, type:”Bridge Love”, mean:”A family rhythm built from warmth, respect, and shared care.”},
{r1:”Indian”, r2:”British”, word:”Masalashire”, type:”Translation Love”, mean:”Two languages at one table, seasoned with everyday affection.”},
{r1:”Arab”, r2:”Brazilian”, word:”Habibalegria”, type:”Routes Love”, mean:”Where affection, music, hospitality, and joy become one family language.”},
{r1:”Filipino”, r2:”Finnish”, word:”Filifin”, type:”Time Zone Love”, mean:”Sauna quiet meets island warmth, close across every clock.”}
];
var carTimer=null, carPaused=false;
function buildCarousel(){
var box=el(“carousel”); box.innerHTML=””;
FAMILIES.forEach(function(f){
var lv=LOVE[f.type]||{ic:”\uD83D\uDC9B”};
var c=document.createElement(“div”); c.className=”famcard”;
c.innerHTML=
‘
‘+escapeHtml(f.r1)+” + “+escapeHtml(f.r2)+’
‘+
‘
‘+escapeHtml(f.word)+’
‘+
‘‘+lv.ic+” “+escapeHtml(f.type)+’‘+
‘
‘+escapeHtml(f.mean)+’
‘;
var btn=document.createElement(“button”); btn.className=”btn btn-soft btn-sm”; btn.textContent=”Try this mix”;
btn.onclick=function(){ tryMix(f.r1,f.r2); };
c.appendChild(btn);
box.appendChild(c);
});
}
function carAdvance(){
var box=el(“carousel”);
var max=box.scrollWidth-box.clientWidth-4;
if(box.scrollLeft>=max){ box.scrollTo({left:0,behavior:noMotion()?”auto”:”smooth”}); }
else { box.scrollBy({left:318,behavior:noMotion()?”auto”:”smooth”}); }
}
function carStart(){ if(noMotion()){ return; } if(carPaused){ return; } clearInterval(carTimer); carTimer=setInterval(carAdvance,4500); }
function carStop(){ clearInterval(carTimer); }
function tryMix(r1,r2){
el(“miniRoot1”).value=r1; el(“miniRoot2”).value=r2;
quickPreview();
el(“forge”).scrollIntoView({behavior:noMotion()?”auto”:”smooth”, block:”center”});
setTimeout(function(){ runMini(); }, noMotion()?0:420);
}
/* ===================== STEPPER ===================== */
var STEPS=[
{n:”01″, h:”Add your roots”, p:”Two or three cultures, countries, languages, or places that made your family.”, ic:”\uD83C\uDF0D”, big:”Two roots”, cap:”Filipino + Turkish, or any mix that is yours.”},
{n:”02″, h:”Forge the word”, p:”Watch the roots blend into one word in the live preview, then make it.”, ic:”\uD83E\uDDEC”, big:”Turknoy”, cap:”Two roots go in. One family word comes out.”},
{n:”03″, h:”Get your result”, p:”A word, a family language type, a meaning, a motto, and a caption. Edit the word freely.”, ic:”\u2728″, big:”Your result”, cap:”Nudge it more poetic, funnier, or more name-like.”},
{n:”04″, h:”Theme and share”, p:”Pick a card theme, download a story card, copy your caption, and save to your local wall.”, ic:”\uD83D\uDCEE”, big:”Share it”, cap:”Six themes, four formats, one screenshot-ready card.”}
];
function buildStepper(){
var track=el(“steptrack”);
STEPS.forEach(function(s,ix){
var row=document.createElement(“button”); row.className=”steprow”; row.type=”button”; row.setAttribute(“role”,”tab”);
row.setAttribute(“aria-selected”, ix===0?”true”:”false”);
row.innerHTML=’‘+s.n+’
‘+escapeHtml(s.h)+’
‘+escapeHtml(s.p)+’
‘;
row.onclick=function(){ selectStep(ix); };
track.appendChild(row);
});
selectStep(0);
}
function selectStep(ix){
document.querySelectorAll(“#steptrack .steprow”).forEach(function(r,i){ r.setAttribute(“aria-selected”, i===ix?”true”:”false”); });
var s=STEPS[ix];
var pv=el(“stepPreview”);
pv.innerHTML=’
‘+s.ic+’
‘+escapeHtml(s.big)+’
‘+escapeHtml(s.cap)+’
‘;
}
/* ===================== WORD WALL ===================== */
function buildWallFilter(){
var sel=el(“wallFilter”); sel.innerHTML=””;
var all=document.createElement(“option”); all.value=””; all.textContent=”All family language types”; sel.appendChild(all);
Object.keys(LOVE).forEach(function(t){ var o=document.createElement(“option”); o.value=t; o.textContent=LOVE[t].ic+” “+t; sel.appendChild(o); });
sel.onchange=renderWall;
}
function updateWallCount(){
var data=loadWall(); var mine=data.filter(function(e){ return !e.sample; }).length;
el(“wallCount”).textContent = (mine===1 ? “1 family word” : mine+” family words”) + ” saved on this device”;
}
function renderWall(newWord){
var grid=el(“wallGrid”), data=loadWall();
var q=el(“wallSearch”).value.toLowerCase().trim();
var f=el(“wallFilter”).value;
var filtered=data.filter(function(e){
var hay=(e.word+” “+e.roots+” “+e.meaning+” “+(e.name||””)+” “+(e.region||””)).toLowerCase();
var okq = q ? (hay.indexOf(q)>-1) : true;
var okf = f ? (e.type===f) : true;
return bAND(okq, okf);
});
grid.innerHTML=””;
if(filtered.length===0){ grid.innerHTML=’
\uD83D\uDDFA\uFE0F
No words here yet. Make your family word above, then add the first word to your local wall.
‘; updateWallCount(); return; }
filtered.forEach(function(e){
var lv=LOVE[e.type]||{ic:”\uD83D\uDC9B”};
var card=document.createElement(“div”); card.className=”wcard”;
if(newWord){ if(e.word===newWord){ if(!e.sample){ card.className=”wcard enter”; } } }
var badge=e.sample?’Global seed‘:”;
var parts=String(e.roots).split(“+”);
var pr1=(parts[0]||””).trim(), pr2=(parts[1]||””).trim();
var del=e.sample?”:’‘;
card.innerHTML=badge+
‘
‘;
grid.appendChild(card);
});
grid.querySelectorAll(“.wc-del”).forEach(function(b){
b.onclick=function(){ var w=b.getAttribute(“data-word”),d=b.getAttribute(“data-date”);
saveWall(loadWall().filter(function(x){ var same = (x.word===w) ? ((x.date===d) ? (!x.sample) : false) : false; return !same; }));
renderWall(); toast(“Removed from your local wall”); announce(“Removed “+w+” from your local wall.”); };
});
grid.querySelectorAll(“.wc-try”).forEach(function(b){
b.onclick=function(){ tryMix(b.getAttribute(“data-r1”), b.getAttribute(“data-r2”)); };
});
updateWallCount();
}
function addToWall(){
if(!state.result){ toast(“Make a word first”); return; }
if(!el(“consentBox”).checked){ toast(“Please confirm the consent box first”); announce(“Please confirm the consent box before adding to the wall.”); return; }
var r=state.result, w=val(“rWord”)||r.word;
var entry={ word:w, roots:r.roots, type:r.love, meaning:r.meaning, name:val(“displayName”), region:val(“displayRegion”)||”Worldwide”, date:new Date().toLocaleDateString(undefined,{year:”numeric”,month:”short”,day:”numeric”}), sample:false };
var a=loadWall(); a.unshift(entry); saveWall(a);
el(“wallSearch”).value=””; el(“wallFilter”).value=””;
renderWall(w); toast(“Added to your local wall”); announce(“Added “+w+” to your local Word Wall.”);
el(“wall”).scrollIntoView({behavior:noMotion()?”auto”:”smooth”, block:”start”});
}
function clearWall(){
var ok=window.confirm(“Clear all the family words you saved on this device? The global seed examples will stay. This cannot be undone.”);
if(!ok) return;
saveWall(loadWall().filter(function(x){ return x.sample; }));
renderWall(); toast(“Your local wall was cleared”); announce(“Cleared your local Word Wall.”);
}
/* ===================== EXPORT / COPY / SHARE ===================== */
function downloadCard(){
var node=el(“shareCard”);
var ok=false; if(window.htmlToImage){ if(htmlToImage.toPng){ ok=true; } }
if(ok){
htmlToImage.toPng(node,{pixelRatio:2,cacheBust:true})
.then(function(url){ var a=document.createElement(“a”); a.download=”ManyRoots-“+(state.result?state.result.word:”card”)+”-“+state.theme+”-“+state.format+”.png”; a.href=url; a.click(); toast(“Card downloaded as PNG”); })
.catch(function(){ toast(“PNG export is blocked here. It works on the live hosted page.”); });
} else { toast(“PNG export library not loaded. See README to connect it.”); }
}
function copyText(txt,msg,btn){
var can=false; if(navigator.clipboard){ if(navigator.clipboard.writeText){ can=true; } }
if(can){ navigator.clipboard.writeText(txt).then(function(){ toast(msg||”Copied”); copiedFlash(btn); }).catch(function(){ fallbackCopy(txt,msg,btn); }); }
else { fallbackCopy(txt,msg,btn); }
}
function fallbackCopy(txt,msg,btn){ var ta=document.createElement(“textarea”); ta.value=txt; ta.style.position=”fixed”; ta.style.opacity=”0″; document.body.appendChild(ta); ta.select(); try{ document.execCommand(“copy”); toast(msg||”Copied”); copiedFlash(btn); }catch(e){ toast(“Copy not supported”); } document.body.removeChild(ta); }
function shareNow(){
if(!state.result) return; var r=state.result, w=val(“rWord”)||r.word;
var txt=createShareText(w, r.love, r.motto, state.seed);
if(navigator.share){ navigator.share({title:”Our Family Language: “+w, text:txt, url:DEPLOYED_APP_URL}).catch(function(){ copyText(txt,”Share text copied”); }); }
else { copyText(txt,”Share text copied”); }
}
function shuffleLook(){
var t=THEMES[Math.floor(Math.random()*THEMES.length)];
var fmts=[“square”,”story”,”post”,”pin”]; var fm=fmts[Math.floor(Math.random()*fmts.length)];
state.theme=t.id; state.format=fm;
document.querySelectorAll(“#themeChips .chip”).forEach(function(n){ n.setAttribute(“aria-pressed”, n.textContent===t.name?”true”:”false”); });
document.querySelectorAll(“#formatChips .chip”).forEach(function(n){ n.setAttribute(“aria-pressed”,”false”); });
var fmtLabel={square:”Instagram square”,story:”Instagram story”,post:”Facebook post”,pin:”Pinterest vertical”}[fm];
document.querySelectorAll(“#formatChips .chip”).forEach(function(n){ if(n.textContent===fmtLabel){ n.setAttribute(“aria-pressed”,”true”); } });
applyTheme(true); applyFormat(); toast(“New look: “+t.name);
}
/* ===================== HERO ANIMATIONS ===================== */
var MORPH=[“Turknoy”,”Kimchitaco”,”Naijapon”,”Filifin”,”Masalashire”,”Habibalegria”];
var morphTimer=null, mi=0;
function startMorph(){
if(noMotion()){ el(“morphWord”).textContent=MORPH[0]; el(“twCursor”).style.display=”none”; return; }
var node=el(“morphWord”); var cur=””, target=MORPH[mi], typing=true, ci=0;
clearInterval(morphTimer);
morphTimer=setInterval(function(){
if(motionPaused()) return;
if(typing){
ci++; node.textContent=target.slice(0,ci);
if(ci>=target.length){ typing=false; setTimeout(function(){},10); }
} else {
ci–; node.textContent=target.slice(0,Math.max(0,ci));
if(ci560){ bar.classList.add(“show”); } else { bar.classList.remove(“show”); } }
window.addEventListener(“scroll”, onScroll, {passive:true}); onScroll();
el(“moMake”).onclick=function(){ el(“forge”).scrollIntoView({behavior:noMotion()?”auto”:”smooth”,block:”center”}); el(“miniRoot1”).focus(); };
el(“moCard”).onclick=function(){ if(state.result){ el(“shareCard”).scrollIntoView({behavior:noMotion()?”auto”:”smooth”,block:”center”}); } else { toast(“Make your family word first”); el(“forge”).scrollIntoView({behavior:noMotion()?”auto”:”smooth”,block:”center”}); } };
el(“moWall”).onclick=function(){ el(“wall”).scrollIntoView({behavior:noMotion()?”auto”:”smooth”,block:”start”}); };
}
/* ===================== DEBUG PANEL ===================== */
function initDebug(){
if(location.search.indexOf(“debug=true”)===-1) return;
var p=el(“debugPanel”); p.classList.add(“show”);
el(“debugClose”).onclick=function(){ p.classList.remove(“show”); };
function det(sel,attr){ var n=document.querySelector(sel); return n?n.getAttribute(attr):”(none)”; }
var can=det(‘link[rel=”canonical”]’,”href”);
var ogu=det(‘meta[property=”og:url”]’,”content”);
var ogi=det(‘meta[property=”og:image”]’,”content”);
var twi=det(‘meta[name=”twitter:image”]’,”content”);
function ynRow(label,good,detail){ return ‘