function wrapEntity (content, entity) {
  switch (entity.type) {
    case 'bold':
      return `<b>${content}</b>`
    case 'italic':
      return `<i>${content}</i>`
    case 'code':
      return `<code>${content}</code>`
    case 'pre':
      return `<pre>${content}</pre>`
    case 'text_link':
      return `<a href="${entity.url}">${content}</a>`
    default:
      return content
  }
}

function applyEntity (text, entity) {
  const head = text.substring(0, entity.offset)
  const tail = text.substring(entity.offset + entity.length)
  const content = wrapEntity(text.substring(entity.offset, entity.offset + entity.length), entity)
  return `${head}${content}${tail}`
}

module.exports = {
  copyMethods: {
    'audio': 'sendAudio',
    'contact': 'sendContact',
    'document': 'sendDocument',
    'location': 'sendLocation',
    'photo': 'sendPhoto',
    'sticker': 'sendSticker',
    'text': 'sendMessage',
    'venue': 'sendVenue',
    'video': 'sendVideo',
    'video_note': 'sendVideoNote',
    'voice': 'sendVoice'
  },
  text: (message) => {
    const entities = message.entities || []
    return {
      parse_mode: entities.length > 0 ? 'HTML' : '',
      text: entities.reduceRight(applyEntity, message.text)
    }
  },
  contact: (message) => {
    return {
      phone_number: message.contact.phone_number,
      first_name: message.contact.first_name,
      last_name: message.contact.last_name
    }
  },
  location: (message) => {
    return {
      latitude: message.location.latitude,
      longitude: message.location.longitude
    }
  },
  venue: (message) => {
    return {
      latitude: message.venue.location.latitude,
      longitude: message.venue.location.longitude,
      title: message.venue.title,
      address: message.venue.address,
      foursquare_id: message.venue.foursquare_id
    }
  },
  voice: (message) => {
    return {
      voice: message.voice.file_id,
      duration: message.voice.duration,
      caption: message.caption
    }
  },
  audio: (message) => {
    return {
      audio: message.audio.file_id,
      duration: message.audio.duration,
      performer: message.audio.performer,
      title: message.audio.title,
      caption: message.caption
    }
  },
  video: (message) => {
    return {
      video: message.video.file_id,
      caption: message.caption,
      duration: message.video.duration,
      width: message.video.width,
      height: message.video.height,
      supports_streaming: !!message.video.supports_streaming
    }
  },
  document: (message) => {
    return {
      document: message.document.file_id,
      caption: message.caption
    }
  },
  sticker: (message) => {
    return {
      sticker: message.sticker.file_id
    }
  },
  photo: (message) => {
    const entities = message.caption_entities || []
    return {
      photo: message.photo[message.photo.length - 1].file_id,
      parse_mode: entities.length > 0 ? 'HTML' : '',
      caption: entities.reduceRight(applyEntity, message.caption)
    }
  },
  video_note: (message) => {
    return {
      video_note: message.video_note.file_id,
      length: message.video_note.length,
      duration: message.video_note.duration
    }
  }
}

@@ -1843,32 +1843,84 @@
  (message) =%3E %7B%0A
+    const entities = message.caption_entities %7C%7C %5B%5D%0A
     return %7B%0A   
@@ -2011,369 +2011,737 @@
 on: 
-message.caption%0A    %7D%0A  %7D,%0A  audio: (message) =%3E %7B%0A    return %7B%0A      audio: message.audio.file_id,%0A      duration: message.audio.duration,%0A      performer: message.audio.performer,%0A      title: message.audio.title,%0A      caption: message.caption%0A    %7D%0A  %7D,%0A  video: (message) =%3E %7B%0A    return %7B%0A      video: message.video.file_id,%0A      caption: message.caption
+entities.reduceRight(applyEntity, message.caption),%0A      parse_mode: entities.length %3E 0 ? 'HTML' : ''%0A    %7D%0A  %7D,%0A  audio: (message) =%3E %7B%0A    const entities = message.caption_entities %7C%7C %5B%5D%0A    return %7B%0A      audio: message.audio.file_id,%0A      duration: message.audio.duration,%0A      performer: message.audio.performer,%0A      title: message.audio.title,%0A      caption: entities.reduceRight(applyEntity, message.caption),%0A      parse_mode: entities.length %3E 0 ? 'HTML' : ''%0A    %7D%0A  %7D,%0A  video: (message) =%3E %7B%0A    const entities = message.caption_entities %7C%7C %5B%5D%0A    return %7B%0A      video: message.video.file_id,%0A      caption: entities.reduceRight(applyEntity, message.caption),%0A      parse_mode: entities.length %3E 0 ? 'HTML' : ''
 ,%0A  
@@ -2939,32 +2939,84 @@
  (message) =%3E %7B%0A
+    const entities = message.caption_entities %7C%7C %5B%5D%0A
     return %7B%0A   
@@ -3069,31 +3069,119 @@
 aption: 
-message.caption
+entities.reduceRight(applyEntity, message.caption),%0A      parse_mode: entities.length %3E 0 ? 'HTML' : ''
 %0A    %7D%0A 

update replicators