     else if(is_command(str, "blinka"))   start_effect(BLINK_ON_A);
     else if(is_command(str, "blinkb"))   start_effect(BLINK_ON_B);
     else if(is_command(str, "breathe"))  start_effect(BREATHE_ON);
+    //else if(is_command(str, "replay"))   { strcpy(arg, last); goto replay; }
     else if(is_command(str, "flush"))    flush();
     else if(is_command(str, "blend"))    do_blend();
     else if(is_command(str, "max"))      do_max();
     else if(is_command(str, "dim"))      do_dim();
     else if(is_command(str, "bright"))   do_bright();
     else if(is_command(str, "fade"))     do_fade();
+    else if(is_command(str, "efade"))    do_exhale_fade();
     else if(is_command(str, "flood"))    do_flood();
     else if(is_command(str, "random"))   do_random();
     else if(is_command(str, "mirror"))   do_mirror();
     else if(is_command(str, "eshift"))   do_elastic_shift(String(arg).toInt());
+    else if(is_command(str, "pshift"))   do_power_shift(String(arg).toInt());
+    else if(is_command(str, "demo"))     do_demo();
     else if(is_command(str, "static"))   start_static();
     else if(is_command(str, "red"))      push_color(red);
     else if(is_command(str, "green"))    push_color(green);

  float midpoint = count / 2;
  for(int i = 0; i < midpoint; i++){
    float percent = i / midpoint;
    ease[i] = 0.5 * (ease_power_in(percent, power));
    ease[i + int(midpoint)] = (0.5 * (ease_elastic_out(percent))) + 0.5;
  }
}

void shift(int count){
  for(int i = 0; i < count; i++){
    render[i] = black;
  }
  for(int i = count; i < ANIM_LED_COUNT; i++){
    render[i] = scale_color(colors[i - count], DEFAULT_BRIGHTNESS_SCALE);
  }

  ledStrip.write(render, ANIM_LED_COUNT);
}

void unshift(int count){
  for(int i = 0; i < ANIM_LED_COUNT - count; i++){
    render[i] = scale_color(colors[i + count], DEFAULT_BRIGHTNESS_SCALE);    
  }

  ledStrip.write(render, ANIM_LED_COUNT);
}

void do_elastic_shift(int count){
  count = count == 0 ? 1 : count;
  if(count >= 1){
    for(int i = 0; i < EASE_COUNT; i++){
      int pos = ease[i] * count;
      delay(EASE_DELAY);
      shift(pos);
    }
    for(int i = 0; i < count; i++){
      push_color(black);
    }

//    for(int i = 0; i < ANIM_LED_COUNT; i++){
//      colors[i] = render[i];
//    }
//    for(int i = 0; i < count; i++){
//      effects[i] = NO_EFFECT;
//    }
//    for(int i = ANIM_LED_COUNT - 1; i >= count; i--){
//      effects[i] = effects[i - count];
//    }    

    for(int i = 0; i < ANIM_LED_COUNT; i++){
      int index = ANIM_LED_COUNT - 1;
      if(i >= count){
        effects[index] = effects[index - count];      
      } else {
        effects[index] = NO_EFFECT;      
      }
    }
  } else {
//    count *= -1;
//    for(int i = 0; i < EASE_COUNT; i++){
//      int pos = ease[i] * count;
//      delay(EASE_DELAY);
//      unshift(count - pos); // broken
//    }
  }
}

void setup() { 

#define RANDOM_SEED_PIN A1

#define EASE_EXPONENT 3 // cubic
#define EASE_COUNT 32
#define POWER_EASE_COUNT 24
#define EASE_DELAY 2
#define POWER_EASE_DELAY 2
#define EASE_ANIM_MARGIN 15

#define ANIM_LED_COUNT 64
