'🍨', '🍩', '🍪', '🍫', '🍬', '🍭', '🍮', '🍯', '🍰', '🍱', '🍲', '🍳', '🍴', '🍵', '🍶', '🍷', '🍸', '🍹', '🍺', '🍻', '🍼', '🍽', '🍾', '🍿', '🎀', '🎁', '🎂', '🎃', '🎄', '🎅', '🎆', '🎇', '🎈', '🎉', '🎊', '🎋', '🎌', '🎍', '🎎', '🎏', '🎐', '🎑', '🎒', '🎓', '🎖', '🎗', '🎙', '🎚', '🎛', '🎞', '🎟', '🎠', '🎡', '🎢', '🎣', '🎤', '🎥', '🎦', '🎧', '🎨', '🎩', '🎪', '🎫', '🎬', '🎭', '🎮', '🎯', '🎰', '🎱', '🎲', '🎳', '🎴', '🎵', '🎶', '🎷', '🎸', '🎹', '🎺', '🎻', '🎼', '🎽', '🎾', '🎿', '🏀', '🏁', '🏂', '🏃', '🏄', '🏅', '🏆', '🏇', '🏈', '🏉', '🏊', '🏋', '🏌', '🏍', '🏎', '🏏', '🏐', '🏑', '🏒', '🏓', '🏔', '🏕', '🏖', '🏗', '🏘', '🏙', '🏚', '🏛', '🏜', '🏝', '🏞', '🏟', '🏠', '🏡', '🏢', '🏣', '🏤', '🏥', '🏦', '🏧', '🏨', '🏩', '🏪', '🏫', '🏬', '🏭', '🏮', '🏯', '🏰', '🏳', '🏴', '🏵', '🏷', '🏸', '🏹', '🏺', '🏻', '🏼', '🏽', '🏾', '🏿', '🐀', '🐁', '🐂', '🐃', '🐄', '🐅', '🐆', '🐇', '🐈', '🐉', '🐊', '🐋', '🐌', '🐍', '🐎', '🐏', '🐐', '🐑', '🐒', '🐓', '🐔', '🐕', '🐖', '🐗', '🐘', '🐙', '🐚', '🐛', '🐜', '🐝', '🐞', '🐟', '🐠', '🐡', '🐢', '🐣', '🐤', '🐥', '🐦', '🐧', '🐨', '🐩', '🐪', '🐫', '🐬', '🐭', '🐮', '🐯', '🐰', '🐱', '🐲', '🐳', '🐴', '🐵', '🐶', '🐷', '🐸', '🐹', '🐺', '🐻', '🐼', '🐽', '🐾', '🐿', '👀', '👁', '👂', '👃', '👄', '👅', '👆', '👇', '👈', '👉', '👊', '👋', '👌', '👍', '👎', '👏', '👐', '👑', '👒', '👓', '👔', '👕', '👖', '👗', '👘', '👙', '👚', '👛', '👜', '👝', '👞', '👟', '👠', '👡', '👢', '👣', '👤', '👥', '👦', '👧', '👨', '👩', '👪', '👫', '👬', '👭', '👮', '👯', '👰', '👱', '👲', '👳', '👴', '👵', '👶', '👷', '👸', '👹', '👺', '👻', '👼', '👽', '👾', '👿', '💀', '💁', '💂', '💃', '💄', '💅', '💆', '💇', '💈', '💉', '💊', '💋', '💌', '💍', '💎', '💏', '💐', '💑', '💒', '💓', '💔', '💕', '💖', '💗', '💘', '💙', '💚', '💛', '💜', '💝', '💞', '💟', '💠', '💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩', '💪', '💫', '💬', '💭', '💮', '💯', '💰', '💱', '💲', '💳', '💴', '💵', '💶', '💷', '💸', '💹', '💺', '💻', '💼', '💽', '💾', '💿', '📀', '📁', '📂', '📃', '📄', '📅', '📆', '📇', '📈', '📉', '📊', '📋', '📌', '📍', '📎', '📏', '📐', '📑', '📒', '📓', '📔', '📕', '📖', '📗', '📘', '📙', '📚', '📛', '📜', '📝', '📞', '📟', '📠', '📡', '📢', '📣', '📤', '📥', '📦', '📧', '📨', '📩', '📪', '📫', '📬', '📭', '📮', '📯', '📰', '📱', '📲', '📳', '📴', '📵', '📶', '📷', '📸', '📹', '📺', '📻', '📼', '📽', '📿', '🔀', '🔁', '🔂', '🔃', '🔄', '🔅', '🔆', '🔇', '🔈', '🔉', '🔊', '🔋', '🔌', '🔍', '🔎', '🔏', '🔐', '🔑', '🔒', '🔓', '🔔', '🔕', '🔖', '🔗', '🔘', '🔙', '🔚', '🔛', '🔜', '🔝', '🔞', '🔟', '🔠', '🔡', '🔢', '🔣', '🔤', '🔥', '🔦', '🔧', '🔨', '🔩', '🔪', '🔫', '🔬', '🔭', '🔮', '🔯', '🔰', '🔱', '🔲', '🔳', '🔴', '🔵', '🔶', '🔷', '🔸', '🔹', '🔺', '🔻', '🔼', '🔽', '🕉', '🕊', '🕋', '🕌', '🕍', '🕎', '🕐', '🕑', '🕒', '🕓', '🕔', '🕕', '🕖', '🕗', '🕘', '🕙', '🕚', '🕛', '🕜', '🕝', '🕞', '🕟', '🕠', '🕡', '🕢', '🕣', '🕤', '🕥', '🕦', '🕧', '🕯', '🕰', '🕳', '🕴', '🕵', '🕶', '🕷', '🕸', '🕹', '🕺', '🖇', '🖊', '🖋', '🖌', '🖍', '🖐', '🖕', '🖖', '🖤', '🖥', '🖨', '🖱', '🖲', '🖼', '🗂', '🗃', '🗄', '🗑', '🗒', '🗓', '🗜', '🗝', '🗞', '🗡', '🗣', '🗨', '🗯', '🗳', '🗺', '🗻', '🗼', '🗽', '🗾', '🗿', '😀', '😁', '😂', '😃', '😄', '😅', '😆', '😇', '😈', '😉', '😊', '😋', '😌', '😍', '😎', '😏', '😐', '😑', '😒', '😓', '😔', '😕', '😖', '😗', '😘', '😙', '😚', '😛', '😜', '😝', '😞', '😟', '😠', '😡', '😢', '😣', '😤', '😥', '😦', '😧', '😨', '😩', '😪', '😫', '😬', '😭', '😮', '😯', '😰', '😱', '😲', '😳', '😴', '😵', '😶', '😷', '😸', '😹', '😺', '😻', '😼', '😽', '😾', '😿', '🙀', '🙁', '🙂', '🙃', '🙄', '🙅', '🙆', '🙇', '🙈', '🙉', '🙊', '🙋', '🙌', '🙍', '🙎', '🙏', '🚀', '🚁', '🚂', '🚃', '🚄', '🚅', '🚆', '🚇', '🚈', '🚉', '🚊', '🚋', '🚌', '🚍', '🚎', '🚏', '🚐', '🚑', '🚒', '🚓', '🚔', '🚕', '🚖', '🚗', '🚘', '🚙', '🚚', '🚛', '🚜', '🚝', '🚞', '🚟', '🚠', '🚡', '🚢', '🚣', '🚤', '🚥', '🚦', '🚧', '🚨', '🚩', '🚪', '🚫', '🚬', '🚭', '🚮', '🚯', '🚰', '🚱', '🚲', '🚳', '🚴', '🚵', '🚶', '🚷', '🚸', '🚹', '🚺', '🚻', '🚼', '🚽', '🚾', '🚿', '🛀', '🛁', '🛂', '🛃', '🛄', '🛅', '🛋', '🛌', '🛍', '🛎', '🛏', '🛐', '🛑', '🛒', '🛕', '🛖', '🛗', '🛜', '🛝', '🛞', '🛟', '🛠', '🛡', '🛢', '🛣', '🛤', '🛥', '🛩', '🛫', '🛬', '🛰', '🛳', '🛴', '🛵', '🛶', '🛷', '🛸', '🛹', '🛺', '🛻', '🛼', '🟠', '🟡', '🟢', '🟣', '🟤', '🟥', '🟦', '🟧', '🟨', '🟩', '🟪', '🟫', '🟰', '🤌', '🤍', '🤎', '🤏', '🤐', '🤑', '🤒', '🤓', '🤔', '🤕', '🤖', '🤗', '🤘', '🤙', '🤚', '🤛', '🤜', '🤝', '🤞', '🤟', '🤠', '🤡', '🤢', '🤣', '🤤', '🤥', '🤦', '🤧', '🤨', '🤩', '🤪', '🤫', '🤬', '🤭', '🤮', '🤯', '🤰', '🤱', '🤲', '🤳', '🤴', '🤵', '🤶', '🤷', '🤸', '🤹', '🤺', '🤼', '🤽', '🤾', '🤿', '🥀', '🥁', '🥂', '🥃', '🥄', '🥅', '🥇', '🥈', '🥉', '🥊', '🥋', '🥌', '🥍', '🥎', '🥏', '🥐', '🥑', '🥒', '🥓', '🥔', '🥕', '🥖', '🥗', '🥘', '🥙', '🥚', '🥛', '🥜', '🥝', '🥞', '🥟', '🥠', '🥡', '🥢', '🥣', '🥤', '🥥', '🥦', '🥧', '🥨', '🥩', '🥪', '🥫', '🥬', '🥭', '🥮', '🥯', '🥰', '🥱', '🥲', '🥳', '🥴', '🥵', '🥶', '🥷', '🥸', '🥹', '🥺', '🥻', '🥼', '🥽', '🥾', '🥿', '🦀', '🦁', '🦂', '🦃', '🦄', '🦅', '🦆', '🦇', '🦈', '🦉', '🦊', '🦋', '🦌', '🦍', '🦎', '🦏', '🦐', '🦑', '🦒', '🦓', '🦔', '🦕', '🦖', '🦗', '🦘', '🦙', '🦚', '🦛', '🦜', '🦝', '🦞', '🦟', '🦠', '🦡', '🦢', '🦣', '🦤', '🦥', '🦦', '🦧', '🦨', '🦩', '🦪', '🦫', '🦬', '🦭', '🦮', '🦯', '🦰', '🦱', '🦲', '🦳', '🦴', '🦵', '🦶', '🦷', '🦸', '🦹', '🦺', '🦻', '🦼', '🦽', '🦾', '🦿', '🧀', '🧁', '🧂', '🧃', '🧄', '🧅', '🧆', '🧇', '🧈', '🧉', '🧊', '🧋', '🧌', '🧍', '🧎', '🧏', '🧐', '🧑', '🧒', '🧓', '🧔', '🧕', '🧖', '🧗', '🧘', '🧙', '🧚', '🧛', '🧜', '🧝', '🧞', '🧟', '🧠', '🧡', '🧢', '🧣', '🧤', '🧥', '🧦', '🧧', '🧨', '🧩', '🧪', '🧫', '🧬', '🧭', '🧮', '🧯', '🧰', '🧱', '🧲', '🧳', '🧴', '🧵', '🧶', '🧷', '🧸', '🧹', '🧺', '🧻', '🧼', '🧽', '🧾', '🧿', '🩰', '🩱', '🩲', '🩳', '🩴', '🩵', '🩶', '🩷', '🩸', '🩹', '🩺', '🩻', '🩼', '🪀', '🪁', '🪂', '🪃', '🪄', '🪅', '🪆', '🪇', '🪈', '🪐', '🪑', '🪒', '🪓', '🪔', '🪕', '🪖', '🪗', '🪘', '🪙', '🪚', '🪛', '🪜', '🪝', '🪞', '🪟', '🪠', '🪡', '🪢', '🪣', '🪤', '🪥', '🪦', '🪧', '🪨', '🪩', '🪪', '🪫', '🪬', '🪭', '🪮', '🪯', '🪰', '🪱', '🪲', '🪳', '🪴', '🪵', '🪶', '🪷', '🪸', '🪹', '🪺', '🪻', '🪼', '🪽', '🪿', '🫀', '🫁', '🫂', '🫃', '🫄', '🫅', '🫎', '🫏', '🫐', '🫑', '🫒', '🫓', '🫔', '🫕', '🫖', '🫗', '🫘', '🫙', '🫚', '🫛', '🫠', '🫡', '🫢', '🫣', '🫤', '🫥', '🫦', '🫧', '🫨', '🫰', '🫱', '🫲', '🫳', '🫴', '🫵', '🫶', '🫷', '🫸', '‼', '⁉', '™', 'ℹ', '↔', '↕', '↖', '↗', '↘', '↙', '↩', '↪', '⌚', '⌛', '⌨', '⏏', '⏩', '⏪', '⏫', '⏬', '⏭', '⏮', '⏯', '⏰', '⏱', '⏲', '⏳', '⏸', '⏹', '⏺', 'Ⓜ', '▪', '▫', '▶', '◀', '◻', '◼', '◽', '◾', '☀', '☁', '☂', '☃', '☄', '☎', '☑', '☔', '☕', '☘', '☝', '☠', '☢', '☣', '☦', '☪', '☮', '☯', '☸', '☹', '☺', '♀', '♂', '♈', '♉', '♊', '♋', '♌', '♍', '♎', '♏', '♐', '♑', '♒', '♓', '♟', '♠', '♣', '♥', '♦', '♨', '♻', '♾', '♿', '⚒', '⚓', '⚔', '⚕', '⚖', '⚗', '⚙', '⚛', '⚜', '⚠', '⚡', '⚧', '⚪', '⚫', '⚰', '⚱', '⚽', '⚾', '⛄', '⛅', '⛈', '⛎', '⛏', '⛑', '⛓', '⛔', '⛩', '⛪', '⛰', '⛱', '⛲', '⛳', '⛴', '⛵', '⛷', '⛸', '⛹', '⛺', '⛽', '✂', '✅', '✈', '✉', '✊', '✋', '✌', '✍', '✏', '✒', '✔', '✖', '✝', '✡', '✨', '✳', '✴', '❄', '❇', '❌', '❎', '❓', '❔', '❕', '❗', '❣', '❤', '➕', '➖', '➗', '➡', '➰', '➿', '⤴', '⤵', '⬅', '⬆', '⬇', '⬛', '⬜', '⭐', '⭕', '〰', '〽', '㊗', '㊙', '' );
$partials = array( '🀄', '🃏', '🅰', '🅱', '🅾', '🅿', '🆎', '🆑', '🆒', '🆓', '🆔', '🆕', '🆖', '🆗', '🆘', '🆙', '🆚', '🇦', '🇨', '🇩', '🇪', '🇫', '🇬', '🇮', '🇱', '🇲', '🇴', '🇶', '🇷', '🇸', '🇹', '🇺', '🇼', '🇽', '🇿', '🇧', '🇭', '🇯', '🇳', '🇻', '🇾', '🇰', '🇵', '🈁', '🈂', '🈚', '🈯', '🈲', '🈳', '🈴', '🈵', '🈶', '🈷', '🈸', '🈹', '🈺', '🉐', '🉑', '🌀', '🌁', '🌂', '🌃', '🌄', '🌅', '🌆', '🌇', '🌈', '🌉', '🌊', '🌋', '🌌', '🌍', '🌎', '🌏', '🌐', '🌑', '🌒', '🌓', '🌔', '🌕', '🌖', '🌗', '🌘', '🌙', '🌚', '🌛', '🌜', '🌝', '🌞', '🌟', '🌠', '🌡', '🌤', '🌥', '🌦', '🌧', '🌨', '🌩', '🌪', '🌫', '🌬', '🌭', '🌮', '🌯', '🌰', '🌱', '🌲', '🌳', '🌴', '🌵', '🌶', '🌷', '🌸', '🌹', '🌺', '🌻', '🌼', '🌽', '🌾', '🌿', '🍀', '🍁', '🍂', '🍃', '🍄', '🍅', '🍆', '🍇', '🍈', '🍉', '🍊', '🍋', '🍌', '🍍', '🍎', '🍏', '🍐', '🍑', '🍒', '🍓', '🍔', '🍕', '🍖', '🍗', '🍘', '🍙', '🍚', '🍛', '🍜', '🍝', '🍞', '🍟', '🍠', '🍡', '🍢', '🍣', '🍤', '🍥', '🍦', '🍧', '🍨', '🍩', '🍪', '🍫', '🍬', '🍭', '🍮', '🍯', '🍰', '🍱', '🍲', '🍳', '🍴', '🍵', '🍶', '🍷', '🍸', '🍹', '🍺', '🍻', '🍼', '🍽', '🍾', '🍿', '🎀', '🎁', '🎂', '🎃', '🎄', '🎅', '🏻', '🏼', '🏽', '🏾', '🏿', '🎆', '🎇', '🎈', '🎉', '🎊', '🎋', '🎌', '🎍', '🎎', '🎏', '🎐', '🎑', '🎒', '🎓', '🎖', '🎗', '🎙', '🎚', '🎛', '🎞', '🎟', '🎠', '🎡', '🎢', '🎣', '🎤', '🎥', '🎦', '🎧', '🎨', '🎩', '🎪', '🎫', '🎬', '🎭', '🎮', '🎯', '🎰', '🎱', '🎲', '🎳', '🎴', '🎵', '🎶', '🎷', '🎸', '🎹', '🎺', '🎻', '🎼', '🎽', '🎾', '🎿', '🏀', '🏁', '🏂', '🏃', '', '♀', '️', '♂', '🏄', '🏅', '🏆', '🏇', '🏈', '🏉', '🏊', '🏋', '🏌', '🏍', '🏎', '🏏', '🏐', '🏑', '🏒', '🏓', '🏔', '🏕', '🏖', '🏗', '🏘', '🏙', '🏚', '🏛', '🏜', '🏝', '🏞', '🏟', '🏠', '🏡', '🏢', '🏣', '🏤', '🏥', '🏦', '🏧', '🏨', '🏩', '🏪', '🏫', '🏬', '🏭', '🏮', '🏯', '🏰', '🏳', '⚧', '🏴', '☠', '', '', '', '', '', '', '', '', '', '', '🏵', '🏷', '🏸', '🏹', '🏺', '🐀', '🐁', '🐂', '🐃', '🐄', '🐅', '🐆', '🐇', '🐈', '⬛', '🐉', '🐊', '🐋', '🐌', '🐍', '🐎', '🐏', '🐐', '🐑', '🐒', '🐓', '🐔', '🐕', '🦺', '🐖', '🐗', '🐘', '🐙', '🐚', '🐛', '🐜', '🐝', '🐞', '🐟', '🐠', '🐡', '🐢', '🐣', '🐤', '🐥', '🐦', '🐧', '🐨', '🐩', '🐪', '🐫', '🐬', '🐭', '🐮', '🐯', '🐰', '🐱', '🐲', '🐳', '🐴', '🐵', '🐶', '🐷', '🐸', '🐹', '🐺', '🐻', '❄', '🐼', '🐽', '🐾', '🐿', '👀', '👁', '🗨', '👂', '👃', '👄', '👅', '👆', '👇', '👈', '👉', '👊', '👋', '👌', '👍', '👎', '👏', '👐', '👑', '👒', '👓', '👔', '👕', '👖', '👗', '👘', '👙', '👚', '👛', '👜', '👝', '👞', '👟', '👠', '👡', '👢', '👣', '👤', '👥', '👦', '👧', '👨', '💻', '💼', '🔧', '🔬', '🚀', '🚒', '🤝', '🦯', '🦰', '🦱', '🦲', '🦳', '🦼', '🦽', '⚕', '⚖', '✈', '❤', '💋', '👩', '👪', '👫', '👬', '👭', '👮', '👯', '👰', '👱', '👲', '👳', '👴', '👵', '👶', '👷', '👸', '👹', '👺', '👻', '👼', '👽', '👾', '👿', '💀', '💁', '💂', '💃', '💄', '💅', '💆', '💇', '💈', '💉', '💊', '💌', '💍', '💎', '💏', '💐', '💑', '💒', '💓', '💔', '💕', '💖', '💗', '💘', '💙', '💚', '💛', '💜', '💝', '💞', '💟', '💠', '💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩', '💪', '💫', '💬', '💭', '💮', '💯', '💰', '💱', '💲', '💳', '💴', '💵', '💶', '💷', '💸', '💹', '💺', '💽', '💾', '💿', '📀', '📁', '📂', '📃', '📄', '📅', '📆', '📇', '📈', '📉', '📊', '📋', '📌', '📍', '📎', '📏', '📐', '📑', '📒', '📓', '📔', '📕', '📖', '📗', '📘', '📙', '📚', '📛', '📜', '📝', '📞', '📟', '📠', '📡', '📢', '📣', '📤', '📥', '📦', '📧', '📨', '📩', '📪', '📫', '📬', '📭', '📮', '📯', '📰', '📱', '📲', '📳', '📴', '📵', '📶', '📷', '📸', '📹', '📺', '📻', '📼', '📽', '📿', '🔀', '🔁', '🔂', '🔃', '🔄', '🔅', '🔆', '🔇', '🔈', '🔉', '🔊', '🔋', '🔌', '🔍', '🔎', '🔏', '🔐', '🔑', '🔒', '🔓', '🔔', '🔕', '🔖', '🔗', '🔘', '🔙', '🔚', '🔛', '🔜', '🔝', '🔞', '🔟', '🔠', '🔡', '🔢', '🔣', '🔤', '🔥', '🔦', '🔨', '🔩', '🔪', '🔫', '🔭', '🔮', '🔯', '🔰', '🔱', '🔲', '🔳', '🔴', '🔵', '🔶', '🔷', '🔸', '🔹', '🔺', '🔻', '🔼', '🔽', '🕉', '🕊', '🕋', '🕌', '🕍', '🕎', '🕐', '🕑', '🕒', '🕓', '🕔', '🕕', '🕖', '🕗', '🕘', '🕙', '🕚', '🕛', '🕜', '🕝', '🕞', '🕟', '🕠', '🕡', '🕢', '🕣', '🕤', '🕥', '🕦', '🕧', '🕯', '🕰', '🕳', '🕴', '🕵', '🕶', '🕷', '🕸', '🕹', '🕺', '🖇', '🖊', '🖋', '🖌', '🖍', '🖐', '🖕', '🖖', '🖤', '🖥', '🖨', '🖱', '🖲', '🖼', '🗂', '🗃', '🗄', '🗑', '🗒', '🗓', '🗜', '🗝', '🗞', '🗡', '🗣', '🗯', '🗳', '🗺', '🗻', '🗼', '🗽', '🗾', '🗿', '😀', '😁', '😂', '😃', '😄', '😅', '😆', '😇', '😈', '😉', '😊', '😋', '😌', '😍', '😎', '😏', '😐', '😑', '😒', '😓', '😔', '😕', '😖', '😗', '😘', '😙', '😚', '😛', '😜', '😝', '😞', '😟', '😠', '😡', '😢', '😣', '😤', '😥', '😦', '😧', '😨', '😩', '😪', '😫', '😬', '😭', '😮', '😯', '😰', '😱', '😲', '😳', '😴', '😵', '😶', '😷', '😸', '😹', '😺', '😻', '😼', '😽', '😾', '😿', '🙀', '🙁', '🙂', '🙃', '🙄', '🙅', '🙆', '🙇', '🙈', '🙉', '🙊', '🙋', '🙌', '🙍', '🙎', '🙏', '🚁', '🚂', '🚃', '🚄', '🚅', '🚆', '🚇', '🚈', '🚉', '🚊', '🚋', '🚌', '🚍', '🚎', '🚏', '🚐', '🚑', '🚓', '🚔', '🚕', '🚖', '🚗', '🚘', '🚙', '🚚', '🚛', '🚜', '🚝', '🚞', '🚟', '🚠', '🚡', '🚢', '🚣', '🚤', '🚥', '🚦', '🚧', '🚨', '🚩', '🚪', '🚫', '🚬', '🚭', '🚮', '🚯', '🚰', '🚱', '🚲', '🚳', '🚴', '🚵', '🚶', '🚷', '🚸', '🚹', '🚺', '🚻', '🚼', '🚽', '🚾', '🚿', '🛀', '🛁', '🛂', '🛃', '🛄', '🛅', '🛋', '🛌', '🛍', '🛎', '🛏', '🛐', '🛑', '🛒', '🛕', '🛖', '🛗', '🛜', '🛝', '🛞', '🛟', '🛠', '🛡', '🛢', '🛣', '🛤', '🛥', '🛩', '🛫', '🛬', '🛰', '🛳', '🛴', '🛵', '🛶', '🛷', '🛸', '🛹', '🛺', '🛻', '🛼', '🟠', '🟡', '🟢', '🟣', '🟤', '🟥', '🟦', '🟧', '🟨', '🟩', '🟪', '🟫', '🟰', '🤌', '🤍', '🤎', '🤏', '🤐', '🤑', '🤒', '🤓', '🤔', '🤕', '🤖', '🤗', '🤘', '🤙', '🤚', '🤛', '🤜', '🤞', '🤟', '🤠', '🤡', '🤢', '🤣', '🤤', '🤥', '🤦', '🤧', '🤨', '🤩', '🤪', '🤫', '🤬', '🤭', '🤮', '🤯', '🤰', '🤱', '🤲', '🤳', '🤴', '🤵', '🤶', '🤷', '🤸', '🤹', '🤺', '🤼', '🤽', '🤾', '🤿', '🥀', '🥁', '🥂', '🥃', '🥄', '🥅', '🥇', '🥈', '🥉', '🥊', '🥋', '🥌', '🥍', '🥎', '🥏', '🥐', '🥑', '🥒', '🥓', '🥔', '🥕', '🥖', '🥗', '🥘', '🥙', '🥚', '🥛', '🥜', '🥝', '🥞', '🥟', '🥠', '🥡', '🥢', '🥣', '🥤', '🥥', '🥦', '🥧', '🥨', '🥩', '🥪', '🥫', '🥬', '🥭', '🥮', '🥯', '🥰', '🥱', '🥲', '🥳', '🥴', '🥵', '🥶', '🥷', '🥸', '🥹', '🥺', '🥻', '🥼', '🥽', '🥾', '🥿', '🦀', '🦁', '🦂', '🦃', '🦄', '🦅', '🦆', '🦇', '🦈', '🦉', '🦊', '🦋', '🦌', '🦍', '🦎', '🦏', '🦐', '🦑', '🦒', '🦓', '🦔', '🦕', '🦖', '🦗', '🦘', '🦙', '🦚', '🦛', '🦜', '🦝', '🦞', '🦟', '🦠', '🦡', '🦢', '🦣', '🦤', '🦥', '🦦', '🦧', '🦨', '🦩', '🦪', '🦫', '🦬', '🦭', '🦮', '🦴', '🦵', '🦶', '🦷', '🦸', '🦹', '🦻', '🦾', '🦿', '🧀', '🧁', '🧂', '🧃', '🧄', '🧅', '🧆', '🧇', '🧈', '🧉', '🧊', '🧋', '🧌', '🧍', '🧎', '🧏', '🧐', '🧑', '🧒', '🧓', '🧔', '🧕', '🧖', '🧗', '🧘', '🧙', '🧚', '🧛', '🧜', '🧝', '🧞', '🧟', '🧠', '🧡', '🧢', '🧣', '🧤', '🧥', '🧦', '🧧', '🧨', '🧩', '🧪', '🧫', '🧬', '🧭', '🧮', '🧯', '🧰', '🧱', '🧲', '🧳', '🧴', '🧵', '🧶', '🧷', '🧸', '🧹', '🧺', '🧻', '🧼', '🧽', '🧾', '🧿', '🩰', '🩱', '🩲', '🩳', '🩴', '🩵', '🩶', '🩷', '🩸', '🩹', '🩺', '🩻', '🩼', '🪀', '🪁', '🪂', '🪃', '🪄', '🪅', '🪆', '🪇', '🪈', '🪐', '🪑', '🪒', '🪓', '🪔', '🪕', '🪖', '🪗', '🪘', '🪙', '🪚', '🪛', '🪜', '🪝', '🪞', '🪟', '🪠', '🪡', '🪢', '🪣', '🪤', '🪥', '🪦', '🪧', '🪨', '🪩', '🪪', '🪫', '🪬', '🪭', '🪮', '🪯', '🪰', '🪱', '🪲', '🪳', '🪴', '🪵', '🪶', '🪷', '🪸', '🪹', '🪺', '🪻', '🪼', '🪽', '🪿', '🫀', '🫁', '🫂', '🫃', '🫄', '🫅', '🫎', '🫏', '🫐', '🫑', '🫒', '🫓', '🫔', '🫕', '🫖', '🫗', '🫘', '🫙', '🫚', '🫛', '🫠', '🫡', '🫢', '🫣', '🫤', '🫥', '🫦', '🫧', '🫨', '🫰', '🫱', '🫲', '🫳', '🫴', '🫵', '🫶', '🫷', '🫸', '‼', '⁉', '™', 'ℹ', '↔', '↕', '↖', '↗', '↘', '↙', '↩', '↪', '⃣', '⌚', '⌛', '⌨', '⏏', '⏩', '⏪', '⏫', '⏬', '⏭', '⏮', '⏯', '⏰', '⏱', '⏲', '⏳', '⏸', '⏹', '⏺', 'Ⓜ', '▪', '▫', '▶', '◀', '◻', '◼', '◽', '◾', '☀', '☁', '☂', '☃', '☄', '☎', '☑', '☔', '☕', '☘', '☝', '☢', '☣', '☦', '☪', '☮', '☯', '☸', '☹', '☺', '♈', '♉', '♊', '♋', '♌', '♍', '♎', '♏', '♐', '♑', '♒', '♓', '♟', '♠', '♣', '♥', '♦', '♨', '♻', '♾', '♿', '⚒', '⚓', '⚔', '⚗', '⚙', '⚛', '⚜', '⚠', '⚡', '⚪', '⚫', '⚰', '⚱', '⚽', '⚾', '⛄', '⛅', '⛈', '⛎', '⛏', '⛑', '⛓', '⛔', '⛩', '⛪', '⛰', '⛱', '⛲', '⛳', '⛴', '⛵', '⛷', '⛸', '⛹', '⛺', '⛽', '✂', '✅', '✉', '✊', '✋', '✌', '✍', '✏', '✒', '✔', '✖', '✝', '✡', '✨', '✳', '✴', '❇', '❌', '❎', '❓', '❔', '❕', '❗', '❣', '➕', '➖', '➗', '➡', '➰', '➿', '⤴', '⤵', '⬅', '⬆', '⬇', '⬜', '⭐', '⭕', '〰', '〽', '㊗', '㊙', '' );
// END: emoji arrays
if ( 'entities' === $type ) {
return $entities;
}
return $partials;
}
/**
* Shortens a URL, to be used as link text.
*
* @since 1.2.0
* @since 4.4.0 Moved to wp-includes/formatting.php from wp-admin/includes/misc.php and added $length param.
*
* @param string $url URL to shorten.
* @param int $length Optional. Maximum length of the shortened URL. Default 35 characters.
* @return string Shortened URL.
*/
function url_shorten( $url, $length = 35 ) {
$stripped = str_replace( array( 'https://', 'http://', 'www.' ), '', $url );
$short_url = untrailingslashit( $stripped );
if ( strlen( $short_url ) > $length ) {
$short_url = substr( $short_url, 0, $length - 3 ) . '…';
}
return $short_url;
}
/**
* Sanitizes a hex color.
*
* Returns either '', a 3 or 6 digit hex color (with #), or nothing.
* For sanitizing values without a #, see sanitize_hex_color_no_hash().
*
* @since 3.4.0
*
* @param string $color
* @return string|void
*/
function sanitize_hex_color( $color ) {
if ( '' === $color ) {
return '';
}
// 3 or 6 hex digits, or the empty string.
if ( preg_match( '|^#([A-Fa-f0-9]{3}){1,2}$|', $color ) ) {
return $color;
}
}
/**
* Sanitizes a hex color without a hash. Use sanitize_hex_color() when possible.
*
* Saving hex colors without a hash puts the burden of adding the hash on the
* UI, which makes it difficult to use or upgrade to other color types such as
* rgba, hsl, rgb, and HTML color names.
*
* Returns either '', a 3 or 6 digit hex color (without a #), or null.
*
* @since 3.4.0
*
* @param string $color
* @return string|null
*/
function sanitize_hex_color_no_hash( $color ) {
$color = ltrim( $color, '#' );
if ( '' === $color ) {
return '';
}
return sanitize_hex_color( '#' . $color ) ? $color : null;
}
/**
* Ensures that any hex color is properly hashed.
* Otherwise, returns value untouched.
*
* This method should only be necessary if using sanitize_hex_color_no_hash().
*
* @since 3.4.0
*
* @param string $color
* @return string
*/
function maybe_hash_hex_color( $color ) {
$unhashed = sanitize_hex_color_no_hash( $color );
if ( $unhashed ) {
return '#' . $unhashed;
}
return $color;
}
IZED;
}
return $template_info;
}
/**
* Returns an array containing the references of
* the passed blocks and their inner blocks.
*
* @since 5.9.0
* @access private
*
* @param array $blocks array of blocks.
* @return array block references to the passed blocks and their inner blocks.
*/
function _flatten_blocks( &$blocks ) {
$all_blocks = array();
$queue = array();
foreach ( $blocks as &$block ) {
$queue[] = &$block;
}
while ( count( $queue ) > 0 ) {
$block = &$queue[0];
array_shift( $queue );
$all_blocks[] = &$block;
if ( ! empty( $block['innerBlocks'] ) ) {
foreach ( $block['innerBlocks'] as &$inner_block ) {
$queue[] = &$inner_block;
}
}
}
return $all_blocks;
}
/**
* Injects the active theme's stylesheet as a `theme` attribute
* into a given template part block.
*
* @since 6.4.0
* @access private
*
* @param array $block a parsed block.
*/
function _inject_theme_attribute_in_template_part_block( &$block ) {
if (
'core/template-part' === $block['blockName'] &&
! isset( $block['attrs']['theme'] )
) {
$block['attrs']['theme'] = get_stylesheet();
}
}
/**
* Removes the `theme` attribute from a given template part block.
*
* @since 6.4.0
* @access private
*
* @param array $block a parsed block.
*/
function _remove_theme_attribute_from_template_part_block( &$block ) {
if (
'core/template-part' === $block['blockName'] &&
isset( $block['attrs']['theme'] )
) {
unset( $block['attrs']['theme'] );
}
}
/**
* Builds a unified template object based on a theme file.
*
* @since 5.9.0
* @since 6.3.0 Added `modified` property to template objects.
* @access private
*
* @param array $template_file Theme file.
* @param string $template_type Template type. Either 'wp_template' or 'wp_template_part'.
* @return WP_Block_Template Template.
*/
function _build_block_template_result_from_file( $template_file, $template_type ) {
$default_template_types = get_default_block_template_types();
$theme = get_stylesheet();
$template = new WP_Block_Template();
$template->id = $theme . '//' . $template_file['slug'];
$template->theme = $theme;
$template->content = file_get_contents( $template_file['path'] );
$template->slug = $template_file['slug'];
$template->source = 'theme';
$template->type = $template_type;
$template->title = ! empty( $template_file['title'] ) ? $template_file['title'] : $template_file['slug'];
$template->status = 'publish';
$template->has_theme_file = true;
$template->is_custom = true;
$template->modified = null;
if ( 'wp_template' === $template_type && isset( $default_template_types[ $template_file['slug'] ] ) ) {
$template->description = $default_template_types[ $template_file['slug'] ]['description'];
$template->title = $default_template_types[ $template_file['slug'] ]['title'];
$template->is_custom = false;
}
if ( 'wp_template' === $template_type && isset( $template_file['postTypes'] ) ) {
$template->post_types = $template_file['postTypes'];
}
if ( 'wp_template_part' === $template_type && isset( $template_file['area'] ) ) {
$template->area = $template_file['area'];
}
$before_block_visitor = '_inject_theme_attribute_in_template_part_block';
$after_block_visitor = null;
$hooked_blocks = get_hooked_blocks();
if ( ! empty( $hooked_blocks ) || has_filter( 'hooked_block_types' ) ) {
$before_block_visitor = make_before_block_visitor( $hooked_blocks, $template );
$after_block_visitor = make_after_block_visitor( $hooked_blocks, $template );
}
$blocks = parse_blocks( $template->content );
$template->content = traverse_and_serialize_blocks( $blocks, $before_block_visitor, $after_block_visitor );
return $template;
}
/**
* Builds the title and description of a post-specific template based on the underlying referenced post.
*
* Mutates the underlying template object.
*
* @since 6.1.0
* @access private
*
* @param string $post_type Post type, e.g. page, post, product.
* @param string $slug Slug of the post, e.g. a-story-about-shoes.
* @param WP_Block_Template $template Template to mutate adding the description and title computed.
* @return bool Returns true if the referenced post was found and false otherwise.
*/
function _wp_build_title_and_description_for_single_post_type_block_template( $post_type, $slug, WP_Block_Template $template ) {
$post_type_object = get_post_type_object( $post_type );
$default_args = array(
'post_type' => $post_type,
'post_status' => 'publish',
'posts_per_page' => 1,
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
'ignore_sticky_posts' => true,
'no_found_rows' => true,
);
$args = array(
'name' => $slug,
);
$args = wp_parse_args( $args, $default_args );
$posts_query = new WP_Query( $args );
if ( empty( $posts_query->posts ) ) {
$template->title = sprintf(
/* translators: Custom template title in the Site Editor referencing a post that was not found. 1: Post type singular name, 2: Post type slug. */
__( 'Not found: %1$s (%2$s)' ),
$post_type_object->labels->singular_name,
$slug
);
return false;
}
$post_title = $posts_query->posts[0]->post_title;
$template->title = sprintf(
/* translators: Custom template title in the Site Editor. 1: Post type singular name, 2: Post title. */
__( '%1$s: %2$s' ),
$post_type_object->labels->singular_name,
$post_title
);
$template->description = sprintf(
/* translators: Custom template description in the Site Editor. %s: Post title. */
__( 'Template for %s' ),
$post_title
);
$args = array(
'title' => $post_title,
);
$args = wp_parse_args( $args, $default_args );
$posts_with_same_title_query = new WP_Query( $args );
if ( count( $posts_with_same_title_query->posts ) > 1 ) {
$template->title = sprintf(
/* translators: Custom template title in the Site Editor. 1: Template title, 2: Post type slug. */
__( '%1$s (%2$s)' ),
$template->title,
$slug
);
}
return true;
}
/**
* Builds the title and description of a taxonomy-specific template based on the underlying entity referenced.
*
* Mutates the underlying template object.
*
* @since 6.1.0
* @access private
*
* @param string $taxonomy Identifier of the taxonomy, e.g. category.
* @param string $slug Slug of the term, e.g. shoes.
* @param WP_Block_Template $template Template to mutate adding the description and title computed.
* @return bool True if the term referenced was found and false otherwise.
*/
function _wp_build_title_and_description_for_taxonomy_block_template( $taxonomy, $slug, WP_Block_Template $template ) {
$taxonomy_object = get_taxonomy( $taxonomy );
$default_args = array(
'taxonomy' => $taxonomy,
'hide_empty' => false,
'update_term_meta_cache' => false,
);
$term_query = new WP_Term_Query();
$args = array(
'number' => 1,
'slug' => $slug,
);
$args = wp_parse_args( $args, $default_args );
$terms_query = $term_query->query( $args );
if ( empty( $terms_query ) ) {
$template->title = sprintf(
/* translators: Custom template title in the Site Editor, referencing a taxonomy term that was not found. 1: Taxonomy singular name, 2: Term slug. */
__( 'Not found: %1$s (%2$s)' ),
$taxonomy_object->labels->singular_name,
$slug
);
return false;
}
$term_title = $terms_query[0]->name;
$template->title = sprintf(
/* translators: Custom template title in the Site Editor. 1: Taxonomy singular name, 2: Term title. */
__( '%1$s: %2$s' ),
$taxonomy_object->labels->singular_name,
$term_title
);
$template->description = sprintf(
/* translators: Custom template description in the Site Editor. %s: Term title. */
__( 'Template for %s' ),
$term_title
);
$term_query = new WP_Term_Query();
$args = array(
'number' => 2,
'name' => $term_title,
);
$args = wp_parse_args( $args, $default_args );
$terms_with_same_title_query = $term_query->query( $args );
if ( count( $terms_with_same_title_query ) > 1 ) {
$template->title = sprintf(
/* translators: Custom template title in the Site Editor. 1: Template title, 2: Term slug. */
__( '%1$s (%2$s)' ),
$template->title,
$slug
);
}
return true;
}
/**
* Builds a unified template object based a post Object.
*
* @since 5.9.0
* @since 6.3.0 Added `modified` property to template objects.
* @since 6.4.0 Added support for a revision post to be passed to this function.
* @access private
*
* @param WP_Post $post Template post.
* @return WP_Block_Template|WP_Error Template or error object.
*/
function _build_block_template_result_from_post( $post ) {
$default_template_types = get_default_block_template_types();
$post_id = wp_is_post_revision( $post );
if ( ! $post_id ) {
$post_id = $post;
}
$parent_post = get_post( $post_id );
$terms = get_the_terms( $parent_post, 'wp_theme' );
if ( is_wp_error( $terms ) ) {
return $terms;
}
if ( ! $terms ) {
return new WP_Error( 'template_missing_theme', __( 'No theme is defined for this template.' ) );
}
$theme = $terms[0]->name;
$template_file = _get_block_template_file( $post->post_type, $post->post_name );
$has_theme_file = get_stylesheet() === $theme && null !== $template_file;
$origin = get_post_meta( $parent_post->ID, 'origin', true );
$is_wp_suggestion = get_post_meta( $parent_post->ID, 'is_wp_suggestion', true );
$template = new WP_Block_Template();
$template->wp_id = $post->ID;
$template->id = $theme . '//' . $parent_post->post_name;
$template->theme = $theme;
$template->content = $post->post_content;
$template->slug = $post->post_name;
$template->source = 'custom';
$template->origin = ! empty( $origin ) ? $origin : null;
$template->type = $post->post_type;
$template->description = $post->post_excerpt;
$template->title = $post->post_title;
$template->status = $post->post_status;
$template->has_theme_file = $has_theme_file;
$template->is_custom = empty( $is_wp_suggestion );
$template->author = $post->post_author;
$template->modified = $post->post_modified;
if ( 'wp_template' === $parent_post->post_type && $has_theme_file && isset( $template_file['postTypes'] ) ) {
$template->post_types = $template_file['postTypes'];
}
if ( 'wp_template' === $parent_post->post_type && isset( $default_template_types[ $template->slug ] ) ) {
$template->is_custom = false;
}
if ( 'wp_template_part' === $parent_post->post_type ) {
$type_terms = get_the_terms( $parent_post, 'wp_template_part_area' );
if ( ! is_wp_error( $type_terms ) && false !== $type_terms ) {
$template->area = $type_terms[0]->name;
}
}
// Check for a block template without a description and title or with a title equal to the slug.
if ( 'wp_template' === $parent_post->post_type && empty( $template->description ) && ( empty( $template->title ) || $template->title === $template->slug ) ) {
$matches = array();
// Check for a block template for a single author, page, post, tag, category, custom post type, or custom taxonomy.
if ( preg_match( '/(author|page|single|tag|category|taxonomy)-(.+)/', $template->slug, $matches ) ) {
$type = $matches[1];
$slug_remaining = $matches[2];
switch ( $type ) {
case 'author':
$nice_name = $slug_remaining;
$users = get_users(
array(
'capability' => 'edit_posts',
'search' => $nice_name,
'search_columns' => array( 'user_nicename' ),
'fields' => 'display_name',
)
);
if ( empty( $users ) ) {
$template->title = sprintf(
/* translators: Custom template title in the Site Editor, referencing a deleted author. %s: Author nicename. */
__( 'Deleted author: %s' ),
$nice_name
);
} else {
$author_name = $users[0];
$template->title = sprintf(
/* translators: Custom template title in the Site Editor. %s: Author name. */
__( 'Author: %s' ),
$author_name
);
$template->description = sprintf(
/* translators: Custom template description in the Site Editor. %s: Author name. */
__( 'Template for %s' ),
$author_name
);
$users_with_same_name = get_users(
array(
'capability' => 'edit_posts',
'search' => $author_name,
'search_columns' => array( 'display_name' ),
'fields' => 'display_name',
)
);
if ( count( $users_with_same_name ) > 1 ) {
$template->title = sprintf(
/* translators: Custom template title in the Site Editor. 1: Template title of an author template, 2: Author nicename. */
__( '%1$s (%2$s)' ),
$template->title,
$nice_name
);
}
}
break;
case 'page':
_wp_build_title_and_description_for_single_post_type_block_template( 'page', $slug_remaining, $template );
break;
case 'single':
$post_types = get_post_types();
foreach ( $post_types as $post_type ) {
$post_type_length = strlen( $post_type ) + 1;
// If $slug_remaining starts with $post_type followed by a hyphen.
if ( 0 === strncmp( $slug_remaining, $post_type . '-', $post_type_length ) ) {
$slug = substr( $slug_remaining, $post_type_length, strlen( $slug_remaining ) );
$found = _wp_build_title_and_description_for_single_post_type_block_template( $post_type, $slug, $template );
if ( $found ) {
break;
}
}
}
break;
case 'tag':
_wp_build_title_and_description_for_taxonomy_block_template( 'post_tag', $slug_remaining, $template );
break;
case 'category':
_wp_build_title_and_description_for_taxonomy_block_template( 'category', $slug_remaining, $template );
break;
case 'taxonomy':
$taxonomies = get_taxonomies();
foreach ( $taxonomies as $taxonomy ) {
$taxonomy_length = strlen( $taxonomy ) + 1;
// If $slug_remaining starts with $taxonomy followed by a hyphen.
if ( 0 === strncmp( $slug_remaining, $taxonomy . '-', $taxonomy_length ) ) {
$slug = substr( $slug_remaining, $taxonomy_length, strlen( $slug_remaining ) );
$found = _wp_build_title_and_description_for_taxonomy_block_template( $taxonomy, $slug, $template );
if ( $found ) {
break;
}
}
}
break;
}
}
}
$hooked_blocks = get_hooked_blocks();
if ( ! empty( $hooked_blocks ) || has_filter( 'hooked_block_types' ) ) {
$before_block_visitor = make_before_block_visitor( $hooked_blocks, $template );
$after_block_visitor = make_after_block_visitor( $hooked_blocks, $template );
$blocks = parse_blocks( $template->content );
$template->content = traverse_and_serialize_blocks( $blocks, $before_block_visitor, $after_block_visitor );
}
return $template;
}
/**
* Retrieves a list of unified template objects based on a query.
*
* @since 5.8.0
*
* @param array $query {
* Optional. Arguments to retrieve templates.
*
* @type string[] $slug__in List of slugs to include.
* @type int $wp_id Post ID of customized template.
* @type string $area A 'wp_template_part_area' taxonomy value to filter by (for 'wp_template_part' template type only).
* @type string $post_type Post type to get the templates for.
* }
* @param string $template_type Template type. Either 'wp_template' or 'wp_template_part'.
* @return WP_Block_Template[] Array of block templates.
*/
function get_block_templates( $query = array(), $template_type = 'wp_template' ) {
/**
* Filters the block templates array before the query takes place.
*
* Return a non-null value to bypass the WordPress queries.
*
* @since 5.9.0
*
* @param WP_Block_Template[]|null $block_templates Return an array of block templates to short-circuit the default query,
* or null to allow WP to run its normal queries.
* @param array $query {
* Arguments to retrieve templates. All arguments are optional.
*
* @type string[] $slug__in List of slugs to include.
* @type int $wp_id Post ID of customized template.
* @type string $area A 'wp_template_part_area' taxonomy value to filter by (for 'wp_template_part' template type only).
* @type string $post_type Post type to get the templates for.
* }
* @param string $template_type Template type. Either 'wp_template' or 'wp_template_part'.
*/
$templates = apply_filters( 'pre_get_block_templates', null, $query, $template_type );
if ( ! is_null( $templates ) ) {
return $templates;
}
$post_type = isset( $query['post_type'] ) ? $query['post_type'] : '';
$wp_query_args = array(
'post_status' => array( 'auto-draft', 'draft', 'publish' ),
'post_type' => $template_type,
'posts_per_page' => -1,
'no_found_rows' => true,
'lazy_load_term_meta' => false,
'tax_query' => array(
array(
'taxonomy' => 'wp_theme',
'field' => 'name',
'terms' => get_stylesheet(),
),
),
);
if ( 'wp_template_part' === $template_type && isset( $query['area'] ) ) {
$wp_query_args['tax_query'][] = array(
'taxonomy' => 'wp_template_part_area',
'field' => 'name',
'terms' => $query['area'],
);
$wp_query_args['tax_query']['relation'] = 'AND';
}
if ( ! empty( $query['slug__in'] ) ) {
$wp_query_args['post_name__in'] = $query['slug__in'];
$wp_query_args['posts_per_page'] = count( array_unique( $query['slug__in'] ) );
}
// This is only needed for the regular templates/template parts post type listing and editor.
if ( isset( $query['wp_id'] ) ) {
$wp_query_args['p'] = $query['wp_id'];
} else {
$wp_query_args['post_status'] = 'publish';
}
$template_query = new WP_Query( $wp_query_args );
$query_result = array();
foreach ( $template_query->posts as $post ) {
$template = _build_block_template_result_from_post( $post );
if ( is_wp_error( $template ) ) {
continue;
}
if ( $post_type && ! $template->is_custom ) {
continue;
}
if (
$post_type &&
isset( $template->post_types ) &&
! in_array( $post_type, $template->post_types, true )
) {
continue;
}
$query_result[] = $template;
}
if ( ! isset( $query['wp_id'] ) ) {
/*
* If the query has found some use templates, those have priority
* over the theme-provided ones, so we skip querying and building them.
*/
$query['slug__not_in'] = wp_list_pluck( $query_result, 'slug' );
$template_files = _get_block_templates_files( $template_type, $query );
foreach ( $template_files as $template_file ) {
$query_result[] = _build_block_template_result_from_file( $template_file, $template_type );
}
}
/**
* Filters the array of queried block templates array after they've been fetched.
*
* @since 5.9.0
*
* @param WP_Block_Template[] $query_result Array of found block templates.
* @param array $query {
* Arguments to retrieve templates. All arguments are optional.
*
* @type string[] $slug__in List of slugs to include.
* @type int $wp_id Post ID of customized template.
* @type string $area A 'wp_template_part_area' taxonomy value to filter by (for 'wp_template_part' template type only).
* @type string $post_type Post type to get the templates for.
* }
* @param string $template_type wp_template or wp_template_part.
*/
return apply_filters( 'get_block_templates', $query_result, $query, $template_type );
}
/**
* Retrieves a single unified template object using its id.
*
* @since 5.8.0
*
* @param string $id Template unique identifier (example: 'theme_slug//template_slug').
* @param string $template_type Optional. Template type. Either 'wp_template' or 'wp_template_part'.
* Default 'wp_template'.
* @return WP_Block_Template|null Template.
*/
function get_block_template( $id, $template_type = 'wp_template' ) {
/**
* Filters the block template object before the query takes place.
*
* Return a non-null value to bypass the WordPress queries.
*
* @since 5.9.0
*
* @param WP_Block_Template|null $block_template Return block template object to short-circuit the default query,
* or null to allow WP to run its normal queries.
* @param string $id Template unique identifier (example: 'theme_slug//template_slug').
* @param string $template_type Template type. Either 'wp_template' or 'wp_template_part'.
*/
$block_template = apply_filters( 'pre_get_block_template', null, $id, $template_type );
if ( ! is_null( $block_template ) ) {
return $block_template;
}
$parts = explode( '//', $id, 2 );
if ( count( $parts ) < 2 ) {
return null;
}
list( $theme, $slug ) = $parts;
$wp_query_args = array(
'post_name__in' => array( $slug ),
'post_type' => $template_type,
'post_status' => array( 'auto-draft', 'draft', 'publish', 'trash' ),
'posts_per_page' => 1,
'no_found_rows' => true,
'tax_query' => array(
array(
'taxonomy' => 'wp_theme',
'field' => 'name',
'terms' => $theme,
),
),
);
$template_query = new WP_Query( $wp_query_args );
$posts = $template_query->posts;
if ( count( $posts ) > 0 ) {
$template = _build_block_template_result_from_post( $posts[0] );
if ( ! is_wp_error( $template ) ) {
return $template;
}
}
$block_template = get_block_file_template( $id, $template_type );
/**
* Filters the queried block template object after it's been fetched.
*
* @since 5.9.0
*
* @param WP_Block_Template|null $block_template The found block template, or null if there isn't one.
* @param string $id Template unique identifier (example: 'theme_slug//template_slug').
* @param string $template_type Template type. Either 'wp_template' or 'wp_template_part'.
*/
return apply_filters( 'get_block_template', $block_template, $id, $template_type );
}
/**
* Retrieves a unified template object based on a theme file.
*
* This is a fallback of get_block_template(), used when no templates are found in the database.
*
* @since 5.9.0
*
* @param string $id Template unique identifier (example: 'theme_slug//template_slug').
* @param string $template_type Optional. Template type. Either 'wp_template' or 'wp_template_part'.
* Default 'wp_template'.
* @return WP_Block_Template|null The found block template, or null if there isn't one.
*/
function get_block_file_template( $id, $template_type = 'wp_template' ) {
/**
* Filters the block template object before the theme file discovery takes place.
*
* Return a non-null value to bypass the WordPress theme file discovery.
*
* @since 5.9.0
*
* @param WP_Block_Template|null $block_template Return block template object to short-circuit the default query,
* or null to allow WP to run its normal queries.
* @param string $id Template unique identifier (example: 'theme_slug//template_slug').
* @param string $template_type Template type. Either 'wp_template' or 'wp_template_part'.
*/
$block_template = apply_filters( 'pre_get_block_file_template', null, $id, $template_type );
if ( ! is_null( $block_template ) ) {
return $block_template;
}
$parts = explode( '//', $id, 2 );
if ( count( $parts ) < 2 ) {
/** This filter is documented in wp-includes/block-template-utils.php */
return apply_filters( 'get_block_file_template', null, $id, $template_type );
}
list( $theme, $slug ) = $parts;
if ( get_stylesheet() !== $theme ) {
/** This filter is documented in wp-includes/block-template-utils.php */
return apply_filters( 'get_block_file_template', null, $id, $template_type );
}
$template_file = _get_block_template_file( $template_type, $slug );
if ( null === $template_file ) {
/** This filter is documented in wp-includes/block-template-utils.php */
return apply_filters( 'get_block_file_template', null, $id, $template_type );
}
$block_template = _build_block_template_result_from_file( $template_file, $template_type );
/**
* Filters the block template object after it has been (potentially) fetched from the theme file.
*
* @since 5.9.0
*
* @param WP_Block_Template|null $block_template The found block template, or null if there is none.
* @param string $id Template unique identifier (example: 'theme_slug//template_slug').
* @param string $template_type Template type. Either 'wp_template' or 'wp_template_part'.
*/
return apply_filters( 'get_block_file_template', $block_template, $id, $template_type );
}
/**
* Prints a block template part.
*
* @since 5.9.0
*
* @param string $part The block template part to print. Either 'header' or 'footer'.
*/
function block_template_part( $part ) {
$template_part = get_block_template( get_stylesheet() . '//' . $part, 'wp_template_part' );
if ( ! $template_part || empty( $template_part->content ) ) {
return;
}
echo do_blocks( $template_part->content );
}
/**
* Prints the header block template part.
*
* @since 5.9.0
*/
function block_header_area() {
block_template_part( 'header' );
}
/**
* Prints the footer block template part.
*
* @since 5.9.0
*/
function block_footer_area() {
block_template_part( 'footer' );
}
/**
* Determines whether a theme directory should be ignored during export.
*
* @since 6.0.0
*
* @param string $path The path of the file in the theme.
* @return bool Whether this file is in an ignored directory.
*/
function wp_is_theme_directory_ignored( $path ) {
$directories_to_ignore = array( '.DS_Store', '.svn', '.git', '.hg', '.bzr', 'node_modules', 'vendor' );
foreach ( $directories_to_ignore as $directory ) {
if ( str_starts_with( $path, $directory ) ) {
return true;
}
}
return false;
}
/**
* Creates an export of the current templates and
* template parts from the site editor at the
* specified path in a ZIP file.
*
* @since 5.9.0
* @since 6.0.0 Adds the whole theme to the export archive.
*
* @global string $wp_version The WordPress version string.
*
* @return WP_Error|string Path of the ZIP file or error on failure.
*/
function wp_generate_block_templates_export_file() {
global $wp_version;
if ( ! class_exists( 'ZipArchive' ) ) {
return new WP_Error( 'missing_zip_package', __( 'Zip Export not supported.' ) );
}
$obscura = wp_generate_password( 12, false, false );
$theme_name = basename( get_stylesheet() );
$filename = get_temp_dir() . $theme_name . $obscura . '.zip';
$zip = new ZipArchive();
if ( true !== $zip->open( $filename, ZipArchive::CREATE | ZipArchive::OVERWRITE ) ) {
return new WP_Error( 'unable_to_create_zip', __( 'Unable to open export file (archive) for writing.' ) );
}
$zip->addEmptyDir( 'templates' );
$zip->addEmptyDir( 'parts' );
// Get path of the theme.
$theme_path = wp_normalize_path( get_stylesheet_directory() );
// Create recursive directory iterator.
$theme_files = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator( $theme_path ),
RecursiveIteratorIterator::LEAVES_ONLY
);
// Make a copy of the current theme.
foreach ( $theme_files as $file ) {
// Skip directories as they are added automatically.
if ( ! $file->isDir() ) {
// Get real and relative path for current file.
$file_path = wp_normalize_path( $file );
$relative_path = substr( $file_path, strlen( $theme_path ) + 1 );
if ( ! wp_is_theme_directory_ignored( $relative_path ) ) {
$zip->addFile( $file_path, $relative_path );
}
}
}
// Load templates into the zip file.
$templates = get_block_templates();
foreach ( $templates as $template ) {
$template->content = traverse_and_serialize_blocks(
parse_blocks( $template->content ),
'_remove_theme_attribute_from_template_part_block'
);
$zip->addFromString(
'templates/' . $template->slug . '.html',
$template->content
);
}
// Load template parts into the zip file.
$template_parts = get_block_templates( array(), 'wp_template_part' );
foreach ( $template_parts as $template_part ) {
$zip->addFromString(
'parts/' . $template_part->slug . '.html',
$template_part->content
);
}
// Load theme.json into the zip file.
$tree = WP_Theme_JSON_Resolver::get_theme_data( array(), array( 'with_supports' => false ) );
// Merge with user data.
$tree->merge( WP_Theme_JSON_Resolver::get_user_data() );
$theme_json_raw = $tree->get_data();
// If a version is defined, add a schema.
if ( $theme_json_raw['version'] ) {
$theme_json_version = 'wp/' . substr( $wp_version, 0, 3 );
$schema = array( '$schema' => 'https://schemas.wp.org/' . $theme_json_version . '/theme.json' );
$theme_json_raw = array_merge( $schema, $theme_json_raw );
}
// Convert to a string.
$theme_json_encoded = wp_json_encode( $theme_json_raw, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE );
// Replace 4 spaces with a tab.
$theme_json_tabbed = preg_replace( '~(?:^|\G)\h{4}~m', "\t", $theme_json_encoded );
// Add the theme.json file to the zip.
$zip->addFromString(
'theme.json',
$theme_json_tabbed
);
// Save changes to the zip file.
$zip->close();
return $filename;
}
/**
* Gets the template hierarchy for the given template slug to be created.
*
* Note: Always add `index` as the last fallback template.
*
* @since 6.1.0
*
* @param string $slug The template slug to be created.
* @param bool $is_custom Optional. Indicates if a template is custom or
* part of the template hierarchy. Default false.
* @param string $template_prefix Optional. The template prefix for the created template.
* Used to extract the main template type, e.g.
* in `taxonomy-books` the `taxonomy` is extracted.
* Default empty string.
* @return string[] The template hierarchy.
*/
function get_template_hierarchy( $slug, $is_custom = false, $template_prefix = '' ) {
if ( 'index' === $slug ) {
return array( 'index' );
}
if ( $is_custom ) {
return array( 'page', 'singular', 'index' );
}
if ( 'front-page' === $slug ) {
return array( 'front-page', 'home', 'index' );
}
$matches = array();
$template_hierarchy = array( $slug );
// Most default templates don't have `$template_prefix` assigned.
if ( ! empty( $template_prefix ) ) {
list( $type ) = explode( '-', $template_prefix );
// We need these checks because we always add the `$slug` above.
if ( ! in_array( $template_prefix, array( $slug, $type ), true ) ) {
$template_hierarchy[] = $template_prefix;
}
if ( $slug !== $type ) {
$template_hierarchy[] = $type;
}
} elseif ( preg_match( '/^(author|category|archive|tag|page)-.+$/', $slug, $matches ) ) {
$template_hierarchy[] = $matches[1];
} elseif ( preg_match( '/^(taxonomy|single)-(.+)$/', $slug, $matches ) ) {
$type = $matches[1];
$slug_remaining = $matches[2];
$items = 'single' === $type ? get_post_types() : get_taxonomies();
foreach ( $items as $item ) {
if ( ! str_starts_with( $slug_remaining, $item ) ) {
continue;
}
// If $slug_remaining is equal to $post_type or $taxonomy we have
// the single-$post_type template or the taxonomy-$taxonomy template.
if ( $slug_remaining === $item ) {
$template_hierarchy[] = $type;
break;
}
// If $slug_remaining is single-$post_type-$slug template.
if ( strlen( $slug_remaining ) > strlen( $item ) + 1 ) {
$template_hierarchy[] = "$type-$item";
$template_hierarchy[] = $type;
break;
}
}
}
// Handle `archive` template.
if (
str_starts_with( $slug, 'author' ) ||
str_starts_with( $slug, 'taxonomy' ) ||
str_starts_with( $slug, 'category' ) ||
str_starts_with( $slug, 'tag' ) ||
'date' === $slug
) {
$template_hierarchy[] = 'archive';
}
// Handle `single` template.
if ( 'attachment' === $slug ) {
$template_hierarchy[] = 'single';
}
// Handle `singular` template.
if (
str_starts_with( $slug, 'single' ) ||
str_starts_with( $slug, 'page' ) ||
'attachment' === $slug
) {
$template_hierarchy[] = 'singular';
}
$template_hierarchy[] = 'index';
return $template_hierarchy;
}
/**
* Inject ignoredHookedBlocks metadata attributes into a template or template part.
*
* Given an object that represents a `wp_template` or `wp_template_part` post object
* prepared for inserting or updating the database, locate all blocks that have
* hooked blocks, and inject a `metadata.ignoredHookedBlocks` attribute into the anchor
* blocks to reflect the latter.
*
* @since 6.5.0
* @access private
*
* @param stdClass $post An object representing a template or template part
* prepared for inserting or updating the database.
* @param WP_REST_Request $request Request object.
* @return stdClass The updated object representing a template or template part.
*/
function inject_ignored_hooked_blocks_metadata_attributes( $post, $request ) {
$filter_name = current_filter();
if ( ! str_starts_with( $filter_name, 'rest_pre_insert_' ) ) {
return $post;
}
$post_type = str_replace( 'rest_pre_insert_', '', $filter_name );
$hooked_blocks = get_hooked_blocks();
if ( empty( $hooked_blocks ) && ! has_filter( 'hooked_block_types' ) ) {
return $post;
}
// At this point, the post has already been created.
// We need to build the corresponding `WP_Block_Template` object as context argument for the visitor.
// To that end, we need to suppress hooked blocks from getting inserted into the template.
add_filter( 'hooked_block_types', '__return_empty_array', 99999, 0 );
$template = $request['id'] ? get_block_template( $request['id'], $post_type ) : null;
remove_filter( 'hooked_block_types', '__return_empty_array', 99999 );
$before_block_visitor = make_before_block_visitor( $hooked_blocks, $template, 'set_ignored_hooked_blocks_metadata' );
$after_block_visitor = make_after_block_visitor( $hooked_blocks, $template, 'set_ignored_hooked_blocks_metadata' );
$blocks = parse_blocks( $post->post_content );
$content = traverse_and_serialize_blocks( $blocks, $before_block_visitor, $after_block_visitor );
$post->post_content = $content;
return $post;
}
Fatal error: require(): Failed opening required '/home/healths/public_html/wp-includes/user.php' (include_path='.:') in /home/healths/public_html/wp-settings.php on line 202
Fatal error: Uncaught Error: Call to a member function set() on null in /home/healths/public_html/wp-includes/l10n.php:850
Stack trace:
#0 /home/healths/public_html/wp-includes/l10n.php(953): load_textdomain()
#1 /home/healths/public_html/wp-includes/class-wp-fatal-error-handler.php(49): load_default_textdomain()
#2 [internal function]: WP_Fatal_Error_Handler->handle()
#3 {main}
thrown in /home/healths/public_html/wp-includes/l10n.php on line 850