diff -urN wf-/d3.c wf/d3.c
--- wf-/d3.c	2015-12-16 00:00:00.000000000 +0900
+++ wf/d3.c	2016-01-13 00:00:00.000000000 +0900
@@ -1,4 +1,3 @@
-#include <stdio.h>
 #include "d3.h"
 
 double
diff -urN wf-/d3.h wf/d3.h
--- wf-/d3.h	2015-12-16 00:00:00.000000000 +0900
+++ wf/d3.h	2016-01-13 00:00:00.000000000 +0900
@@ -2,6 +2,7 @@
 #define __D3_H__
 
 #include <math.h>
+#include "util.h"
 
 double linear(double v, double sa, double sb, double da, double db);
 
@@ -108,4 +109,17 @@
 void affin_point_symmetry(affin_t *af, const pos_t *p);
 void affin_mirror(affin_t *af, const plane_t *pl);
 
+
+#define ALLOC_N(lv, type, n)	do{ \
+	if((lv = malloc(sizeof(type)*(n))) == NULL) ERR("No Mem"); \
+	}while(0);
+
+#define ALLOC_N_INT(lv, n)	ALLOC_N(lv, int, n)
+#define ALLOC_N_DBL(lv, n)	ALLOC_N(lv, double, n)
+#define ALLOC_N_D3(lv, n)	ALLOC_N(lv, d3_t, n)
+
+#define ALLOC_CHK(lv, type, n)	do{ if(lv == NULL) ALLOC_N(lv, type, n); }while(0)
+#define ALLOC_CHK_DBL(lv, n)	ALLOC_CHK(lv, double, n)
+#define ALLOC_CHK_D3(lv, n)	ALLOC_CHK(lv, d3_t, n)
+
 #endif
diff -urN wf-/data.c wf/data.c
--- wf-/data.c	2016-01-10 00:00:00.000000000 +0900
+++ wf/data.c	2016-01-13 00:00:00.000000000 +0900
@@ -34,6 +34,7 @@
 	CASE_RET(type_mirror);
 	CASE_RET(type_timeshift);
 	CASE_RET(type_timeshift_rot);
+	CASE_RET(type_timeshift_zoom_slide);
 	CASE_RET(type_rdiv);
 	CASE_RET(type_slide_way);
 	CASE_RET(type_slide_way_liss);
@@ -50,6 +51,7 @@
 	CASE_RET(type_copy_mirror);
 	CASE_RET(type_copy_timeshift);
 	CASE_RET(type_copy_timeshift_rot);
+	CASE_RET(type_copy_timeshift_zoom_slide);
 	CASE_RET(type_recursive);
 	CASE_RET(type_test_conv);
 	default: break;
@@ -75,6 +77,7 @@
 {
 	int i, *op = wf->odr;
 
+	ALLOC_CHK_D3(wf->v, wf->n);
 
 	for(i=0; i<wf->n; i++){
 		d3_set(&wf->v[i], 0,0,0);
@@ -153,7 +156,7 @@
 {
 	int i, *op = wf->odr;
 
-	if(!wf->t) ERR("wf->t NULL");
+	ALLOC_CHK_D3(wf->t, wf->n);
 
 	if(!prm->skip_af){
 		for(i=0; i<wf->n; i++){
@@ -365,7 +368,7 @@
 static void
 op_data_set_draw(struct op_data_set *set, prm_t *prm)
 {
-	op_data_draw(set->op, set->data, prm);
+	op_data_draw(&set->op, &set->data, prm);
 }
 
 static void
@@ -456,7 +459,7 @@
 	if(op_arr[0].type == type_end) data_draw(data, prm);
 	else{
 		data_t arr = { type_arr, &op_arr[1] };
-		struct op_data_set set = { &arr, data };
+		struct op_data_set set = { arr, *data };
 		data_t d = { type_op_data_set, &set };
 		op_data_draw(&op_arr[0], &d, prm);
 	}
@@ -550,6 +553,14 @@
 }
 
 static void
+op_data_timeshift_zoom_slide(struct timeshift_zoom_slide *tszs, data_t *data, prm_t *prm)
+{
+	data_t op = { type_zoom_and_slide, tszs->zs };
+	prm->sec += tszs->sec;
+	op_data_draw(&op, data, prm);
+}
+
+static void
 op_data_rdiv(struct rdiv *rdiv, data_t *data, prm_t *prm)
 {
 	prm->rdiv = rdiv;
@@ -752,10 +763,28 @@
 }
 
 static void
+op_data_copy_timeshift_zoom_slide(struct copy_timeshift_zoom_slide *copy, data_t *data, prm_t *prm)
+{
+	int i;
+	struct timeshift_zoom_slide tszs = {
+		.sec = copy->init_sec, 
+		.zs = { copy->init_zs[0], copy->init_zs[1] }
+	};
+	data_t op = { type_timeshift_zoom_slide, &tszs };
+
+	for(i=0; i<copy->n; i++){
+		op_data_draw(&op, data,prm);
+		tszs.sec += copy->step_sec;
+		d3_add(&tszs.zs[0], &copy->step_zs[0]);
+		d3_add(&tszs.zs[1], &copy->step_zs[1]);
+	}
+}
+
+static void
 op_data_recursive(struct recursive *r, data_t *data, prm_t *prm)
 {
 	data_t op = { type_arr, (data_t[]){
-	  *r->op,
+	  r->op,
 	  { type_recursive, r },
 	  { type_end } }};
 
@@ -813,6 +842,9 @@
 	case type_timeshift_rot:
 		op_data_timeshift_rot(op->p, data, prm);
 		break;
+	case type_timeshift_zoom_slide:
+		op_data_timeshift_zoom_slide(op->p, data, prm);
+		break;
 	case type_rdiv:
 		op_data_rdiv(op->p, data, prm);
 		break;
@@ -863,6 +895,9 @@
 	case type_copy_timeshift_rot:
 		op_data_copy_timeshift_rot(op->p, data, prm);
 		break;
+	case type_copy_timeshift_zoom_slide:
+		op_data_copy_timeshift_zoom_slide(op->p, data, prm);
+		break;
 
 	case type_recursive:
 		op_data_recursive(op->p, data, prm);
@@ -878,14 +913,3 @@
 	}
 	*prm = bak;
 }
-
-void
-wf_init_work_alloc(struct wire_frame *wf, d3_t *t_and_v)
-{
-	if(t_and_v){
-		wf->t = t_and_v;
-	}else{
-		if((wf->t = malloc(sizeof(d3_t) * wf->n * 2)) == NULL) ERR("No Mem");
-	}
-	wf->v = &wf->t[ wf->n ];
-}
diff -urN wf-/data.h wf/data.h
--- wf-/data.h	2016-01-10 00:00:00.000000000 +0900
+++ wf/data.h	2016-01-13 00:00:00.000000000 +0900
@@ -39,6 +39,7 @@
 #define type_mirror			105
 #define type_timeshift			106
 #define type_timeshift_rot		107
+#define type_timeshift_zoom_slide	108
 #define type_rdiv			110
 
 #define type_slide_way			120
@@ -57,6 +58,7 @@
 #define type_copy_mirror		203
 #define type_copy_timeshift		204
 #define type_copy_timeshift_rot		205
+#define type_copy_timeshift_zoom_slide	206
 
 #define type_recursive			220
 
@@ -92,7 +94,7 @@
 };
 
 struct op_data_set{
-	data_t *op, *data;
+	data_t op, data;
 };
 
 struct slice{
@@ -132,6 +134,11 @@
 	double deg;
 };
 
+struct timeshift_zoom_slide{
+	double sec;
+	d3_t zs[2];
+};
+
 struct rdiv{
 	int n;
 	double rate;
@@ -179,8 +186,14 @@
 	double init_deg, step_deg;
 };
 
+struct copy_timeshift_zoom_slide{
+	int n;
+	double init_sec, step_sec;
+	d3_t init_zs[2], step_zs[2];
+};
+
 struct recursive{
-	data_t *op;
+	data_t op;
 	int n, cnt;
 };
 
@@ -193,9 +206,12 @@
 	int skip_af;
 } prm_t;
 
+
+#define ALLOC_WF(wf)		do{ ALLOC_N_D3((wf).t, (wf).n); ALLOC_N_D3((wf).v, (wf).n); }while(0)
+
+
 void prm_set_eye_update(prm_t *prm, eye_t *eye);
 void data_draw(data_t *data, prm_t *prm);
 void op_data_draw(data_t *op, data_t *data, prm_t *prm);
-void wf_init_work_alloc(struct wire_frame *wf, d3_t *t_and_v);
 
 #endif
diff -urN wf-/eye.c wf/eye.c
--- wf-/eye.c	2015-12-30 00:00:00.000000000 +0900
+++ wf/eye.c	2016-01-13 00:00:00.000000000 +0900
@@ -1,4 +1,3 @@
-#include "util.h"
 #include "eye.h"
 
 static void
diff -urN wf-/nt.c wf/nt.c
--- wf-/nt.c	2016-01-03 02:00:00.000000000 +0900
+++ wf/nt.c	2016-01-13 00:00:00.000000000 +0900
@@ -7,9 +7,9 @@
 	double sky_deg = 40;
 	pos_t p = {0,0,-r};
 	data_t data = { type_op_data_set, &(struct op_data_set){
-	  .op = &(data_t){ type_rot_way, &(struct rot_way){
+	  .op = { type_rot_way, &(struct rot_way){
 	    .l=LINE_Y,.deg_way=WAY_V2(-90-sky_deg,90+sky_deg, 10,10, 3) }},
-	  .data = &(data_t){ type_test_conv, &p }
+	  .data = { type_test_conv, &p }
 	}};
 
 	eye_t eye;
diff -urN wf-/way.c wf/way.c
--- wf-/way.c	2016-01-06 00:00:00.000000000 +0900
+++ wf/way.c	2016-01-13 00:00:00.000000000 +0900
@@ -1,5 +1,3 @@
-#include <stdio.h>
-#include "util.h"
 #include "way.h"
 
 static int
diff -urN wf-/way.h wf/way.h
--- wf-/way.h	2016-01-06 00:00:00.000000000 +0900
+++ wf/way.h	2016-01-13 00:00:00.000000000 +0900
@@ -1,7 +1,6 @@
 #ifndef __INTERP_H__
 #define __INTERP_H__
 
-#include <stdio.h>
 #include "d3.h"
 
 /*
@@ -29,7 +28,8 @@
 	pos_t ret_p;
 };
 
-#define WAY_V2(v1,v2,t1,t2,dg_)	{ .n=2, .vs=(double[]){v1,v2}, .ts=(double[]){t1,t2}, .ps=NULL, .dg=dg_ }
+#define WAY_V2(v1,v2,t1,t2,dg_)	{ .n=2, .vs=(double[]){v1,v2}, .ts=(double[]){t1,t2}, .dg=dg_ }
+#define WAY_P2(x1,y1,z1, x2,y2,z2, t1,t2,dg_) { .n=2, .ps=(pos_t[]){{x1,y1,z1},{x2,y2,z2}}, .ts=(double[]){t1,t2}, .dg=dg_ }
 
 
 int way_idx_rate(const double *ts, int n, double *t);
diff -urN wf-/wf_ex.c wf/wf_ex.c
--- wf-/wf_ex.c	2016-01-10 00:00:00.000000000 +0900
+++ wf/wf_ex.c	2016-01-13 00:00:00.000000000 +0900
@@ -2,7 +2,6 @@
 #include <sys/time.h>
 #include "key.h"
 #include "x.h"
-#include "eye.h"
 #include "data.h"
 
 static double
@@ -89,7 +88,7 @@
 
 	fscanf(fp, "w=%d,h=%d", &g->w, &g->h);
 	n = g->w * g->h;
-	if((g->p = malloc(sizeof(*g->p) * n)) == NULL) ERR("No Mem");
+	ALLOC_N_D3(g->p, n);
 	for(i=0; i<n; i++) d3_set(&g->p[i], 0, 0, 0);
 
 	while(y < g->h && fscanf(fp, "%lf", &d) == 1){
@@ -113,7 +112,7 @@
 	wf->p = g->p;
 
 	odr_n = (g->w + 1) * g->h + (g->h + 1) * g->w + 1;
-	if((wf->odr = malloc(sizeof(*wf->odr) * odr_n)) == NULL) ERR("No Mem");
+	ALLOC_N_INT(wf->odr, odr_n);
 
 	op = wf->odr;
 	for(y=0; y<g->h; y++){
@@ -141,7 +140,7 @@
 	int mode = 0;
 	char *fn = opt_str("-fn", ac, av, NULL);
 	struct wire_frame wf;
-	data_t data = { type_end, NULL };
+	data_t data = { type_end };
 	prm_t prm;
 
 	cui_key_init();
@@ -163,35 +162,35 @@
 		sscanf(zoom_s, "%lf,%lf,%lf", &zoom.x, &zoom.y, &zoom.z);
 		grp_read(&grp, fopen(fn, "r"), &zoom);
 		grp_to_wf(&grp, &wf);
-		wf_init_work_alloc(&wf, NULL);
+		wf.t = wf.v = NULL;
 
 		data.type = type_op_data_set;
 		data.p = &(struct op_data_set){
-		  .op = &(data_t){ type_rdiv_way, &(struct rdiv_way){
+		  .op = { type_rdiv_way, &(struct rdiv_way){
 		    .n=4, 
-		    .rate_way={.n=2,.vs=(double[]){0,0.2},.ts=(double[]){3,3},.ps=NULL,.dg=3} }},
-		  .data = &(data_t){ type_wire_frame, &wf } };
+		    .rate_way={.n=2,.vs=(double[]){0,0.2},.ts=(double[]){3,3},.dg=3} }},
+		  .data = { type_wire_frame, &wf } };
 	}
 
 	if(opt_idx("-demo", ac, av) > 0){
 
 		data_t *ax = &(data_t){ type_arr, (data_t[]){
 		  { type_op_data_set, &(struct op_data_set){
-		    .op = &(data_t){ type_copy, &(struct copy){
+		    .op = { type_copy, &(struct copy){
 		      .n = {200,1,1}, .init = {-100,0,0}, .step = {1,0,0} }},
-		    .data = &(data_t){ type_bar, (pos_t[]){{0,0,0},{0,1,0}} } }},
+		    .data = { type_bar, (pos_t[]){{0,0,0},{0,1,0}} } }},
 		  { type_bar, (pos_t[]){{-100,0,0},{100,0,0}} },
 		  { type_end } }};
 
 		data_t *axyz = &(data_t){ type_op_data_set, &(struct op_data_set){
-		  .op = &(data_t){ type_copy_rot, &(struct copy_rot){
+		  .op = { type_copy_rot, &(struct copy_rot){
 		    .n = 3, .l = {{0,0,0},{1,1,1}}, .init_deg = 0, .step_deg = 120 }},
-		  .data = ax }};
+		  .data = *ax }};
 
 		data_t *cross = &(data_t){ type_op_data_set, &(struct op_data_set){
-		  .op = &(data_t){ type_copy, &(struct copy){
+		  .op = { type_copy, &(struct copy){
 		    .n = {5*2+1,4*2+1,2*2+1}, .init = {-20*5,-30*4,-40*2}, .step = {20,30,40} }},
-		  .data = &(data_t){ type_slice, &(struct slice){
+		  .data = { type_slice, &(struct slice){
 		    .n=6, .ds = (data_t[]){
 		      { type_cross, (pos_t[]){{-4,0,0},{4,0,0}} },
 		      { type_none },
@@ -202,36 +201,36 @@
 		    .ts = (double[]){5, 0.05, 0.05, 0.05, 0.5, 5} }} }};
 
 		data_t *rcube = &(data_t){ type_op_data_set, &(struct op_data_set){
-		  .op = &(data_t){ type_rdiv_way, &(struct rdiv_way){
+		  .op = { type_rdiv_way, &(struct rdiv_way){
 		    .n=4,
 		    .rate_way=WAY_V2(-0.5,1.0, 3,3, 3) } },
-		  .data = &(data_t){ type_cube } }};
+		  .data = { type_cube } }};
 
 		data_t *cube = &(data_t){ type_op_data_set, &(struct op_data_set){
-		  .op = &(data_t){ type_arr, (data_t[]){
+		  .op = { type_arr, (data_t[]){
 		    { type_slide_way, &(struct way){
-		      .n = 4, .vs = NULL,
+		      .n = 4,
 		      .ps = (pos_t[]){{0,0,0},{0,10,0},{10,10,0},{10,0,0}},
 		      .ts = (double[]){3,2,1,2}, .dg = 1 }},
 		    { type_zoom_way_liss, &(struct zoom_way_liss){
 		      .zs=D3_ALL(0.8), .ze=D3_ALL(1.2), .sec={0.7,0.8,0.9}, .init_sec=D3_O }},
 		    { type_end } }},
-		  .data = &(data_t){ type_cube } }};
+		  .data = { type_cube } }};
 
 		data_t *cube2 = &(data_t){ type_op_data_set, &(struct op_data_set){
-		  .op = &(data_t){ type_slide_way, &(struct way){
-		    .n = 4, .vs = NULL,
+		  .op = { type_slide_way, &(struct way){
+		    .n = 4,
                     .ps = (pos_t[]){{0,0,0},{0,10,0},{10,10,0},{10,0,0}},
                     .ts = (double[]){1,1,1,1}, .dg = 3 }},
-		  .data = rcube }};
+		  .data = *rcube }};
 
 		data_t *cube3 = &(data_t){ type_op_data_set, &(struct op_data_set){
-		  .op = &(data_t){ type_copy_timeshift, &(struct copy_timeshift){
+		  .op = { type_copy_timeshift, &(struct copy_timeshift){
 		    .n = 3, .init_sec = 0, .step_sec = -0.3, .init = {0,0,0}, .step = {0,0,0} } },
-		  .data = cube2 }};
+		  .data = *cube2 }};
 
 		data_t *cup = &(data_t){ type_op_data_set, &(struct op_data_set){
-		  .op = &(data_t){ type_arr, (data_t[]){
+		  .op = { type_arr, (data_t[]){
 		    { type_slide, &(d3_t){20,20,0} },
 		    { type_copy_rot, &(struct copy_rot){ .n=4, .l=LINE_Z, .init_deg=0, .step_deg=90 } },
 		    { type_rot_way, &(struct rot_way){
@@ -244,58 +243,58 @@
 		    { type_copy, &(struct copy){ .n={2,1,1}, .init={-2,0,0}, .step={4,0,0} } },
 		    { type_end }
 		  }},
-		  .data = &(data_t){ type_cube } }};
+		  .data = { type_cube } }};
 
 		data_t *ferris_wheel = &(data_t){ type_op_data_set, &(struct op_data_set){
-		  .op = &(data_t){ type_arr, (data_t[]){
+		  .op = { type_arr, (data_t[]){
 		    { type_slide, &(d3_t){20,20,-10} },
 		    { type_copy_timeshift, &(struct copy_timeshift){
 		      .n=12, .init_sec=0, .step_sec=10.0/12, .init={0,0,0}, .step={0,0,0} } },
 		    { type_rot_way, &(struct rot_way){
 		      .l=LINE_Y, .deg_way=WAY_V2(0,-360, 10,0, 1) } },
 		    { type_end } }},
-		  .data = &(data_t){ type_arr, (data_t[]){
+		  .data = { type_arr, (data_t[]){
 		    { type_op_data_set, &(struct op_data_set){
-		      .op = &(data_t){ type_zoom_and_slide, (d3_t[]){{3,1,1},{10-3,0,0}} },
-		      .data = &(data_t){ type_square } }},
+		      .op = { type_zoom_and_slide, (d3_t[]){{3,1,1},{10-3,0,0}} },
+		      .data = { type_square } }},
 		    { type_op_data_set, &(struct op_data_set){
-		      .op = &(data_t){ type_arr, (data_t[]){
+		      .op = { type_arr, (data_t[]){
 			{ type_slide, &(d3_t){10,0,0} },
 			{ type_rot_way, &(struct rot_way){
 			  .l=LINE_Y, .deg_way=WAY_V2(0,360, 10,0, 1) }},
 			{ type_slide, &(d3_t){0,0,-1} },
 			{ type_end } }},
-		      .data = &(data_t){ type_cube } }},
+		      .data = { type_cube } }},
 		    { type_end }
 		  }}
 		}};
 
 		data_t *merry_go_round = &(data_t){ type_op_data_set, &(struct op_data_set){
-		  .op = &(data_t){ type_arr, (data_t[]){
+		  .op = { type_arr, (data_t[]){
 		    { type_slide, &(d3_t){-20,20,0} },
 		    { type_copy_rot, &(struct copy_rot){ .n=8, .l=LINE_Z, .init_deg=0, .step_deg=45 } },
 		    { type_rot_way, &(struct rot_way){
 		      .l=LINE_Z, .deg_way=WAY_V2(0,360, 10,0, 1) } },
 		    { type_copy_timeshift, &(struct copy_timeshift){
                       .n=3, .init_sec=0, .step_sec=2.0/3, .init={10+-3,-3,0}, .step={3,3,0} } },
-		    { type_slide_way, &(struct way){ .n=2, .ps=(pos_t[]){{0,0,0},{0,0,3}}, .ts=(double[]){2,2}, .vs=NULL, .dg=3 } },
+		    { type_slide_way, &(struct way)WAY_P2(0,0,0, 0,0,3, 2,2, 3) },
 		    { type_end } }},
-		  .data = &(data_t){ type_cube }
+		  .data = { type_cube }
 		}};
 
 		data_t *ship = &(data_t){ type_op_data_set, &(struct op_data_set){
-		  .op = &(data_t){ type_arr, (data_t[]){
+		  .op = { type_arr, (data_t[]){
 		    { type_slide, &(d3_t){-20,20,-10} },
 		    { type_rot_way, &(struct rot_way){
 		      .l=LINE_Y, .deg_way=WAY_V2(-90,90, 5,5, 3) } },
 		    { type_copy_rot, &(struct copy_rot){ .n=6, .l=LINE_Y, .init_deg=-45, .step_deg=(45.0-(-45))/(6-1) } },
 		    { type_copy, &(struct copy){ .n={1,4,1}, .init={0,0,-10}, .step={0,3,0} }},
 		    { type_end } }},
-		  .data = &(data_t){ type_cube }
+		  .data = { type_cube }
 		}};
 
 		data_t *exile = &(data_t){ type_op_data_set, &(struct op_data_set){
-		  .op = &(data_t){ type_arr, (data_t[]){
+		  .op = { type_arr, (data_t[]){
 		    { type_copy_timeshift, &(struct copy_timeshift){
 		      .n=10, .init_sec=0, .step_sec=-0.3, .init={-20,10,10}, .step={0,1,0} } },
 		    { type_rot_way, &(struct rot_way){
@@ -305,11 +304,11 @@
 		      .l=LINE_Y, .deg_way=WAY_V2(0,-360, 2,0, 3) } },
 		    { type_rot, &(struct rot){ .l=LINE_X, .deg=90 } },
 		    { type_end } }},
-		  .data = &(data_t){ type_square }
+		  .data = { type_square }
 		}};
 
 		data_t *lissajours = &(data_t){ type_op_data_set, &(struct op_data_set){
-		  .op = &(data_t){ type_arr, (data_t[]){
+		  .op = { type_arr, (data_t[]){
 		    { type_copy_timeshift, &(struct copy_timeshift){
 		      .n=10, .init_sec=0, .step_sec=-0.3, .init=D3_O, .step=D3_O } },
 		    { type_slide_way_liss, &(struct slide_way_liss){
@@ -318,7 +317,7 @@
 		      .l={D3_O,D3_I}, .deg_way=WAY_V2(0,360*2, 1,1, 3) } },
 		    { type_zoom_all_way, &(struct way)WAY_V2(0,2, 3,3, 3) },
 		    { type_end } }},
-		  .data = &(data_t){ type_circle, &(struct circle){ .r=1,.n=10*4 } }
+		  .data = { type_circle, &(struct circle){ .r=1,.n=10*4 } }
 		}};
 
 		double r = 30;
@@ -327,25 +326,25 @@
 
 		double *spin_vs = (double[]){0, 0, 0, 360*3, 0, 0, 0};
 		double *spin_ts = (double[]){sky_sec+pipe_sec*2, 0, sky_sec, sky_sec, 0, pipe_sec*2+sky_sec};
-		struct way spin_way = {.n=6,.vs=spin_vs,.ts=spin_ts,.ps=NULL,.dg=3};
+		struct way spin_way = {.n=6,.vs=spin_vs,.ts=spin_ts,.dg=3};
 		data_t spin1 = { type_rot_way, &(struct rot_way){.l={D3_O,D3_I},.deg_way=spin_way} };
 		data_t spin2 = { type_rot_way, &(struct rot_way){.l=LINE_Z,.deg_way=spin_way} };
 		data_t spin = { type_arr, (data_t[]){ spin1, spin2, {type_end} }};
 
 		data_t *half_pipe = &(data_t){ type_op_data_set, &(struct op_data_set){
-		  .op = &(data_t){ type_zoom_and_slide, (d3_t[]){D3_ALL(0.1),{-30,-30,-10}} },
-		  .data = &(data_t){ type_arr, (data_t[]){
+		  .op = { type_zoom_and_slide, (d3_t[]){D3_ALL(0.1),{-30,-30,-10}} },
+		  .data = { type_arr, (data_t[]){
 		    { type_circle, &(struct circle){ .r=r*3, .n=360/10 } },
 		    { type_circle, &(struct circle){ .r=r*5, .n=360/10 } },
 		    { type_op_data_set, &(struct op_data_set){
-		      .op = &(data_t){ type_arr, (data_t[]){
+		      .op = { type_arr, (data_t[]){
 			{ type_copy_rot, &(struct copy_rot){ .n=360/10, .l=LINE_Z, .init_deg=0, .step_deg=10 } },
 		        { type_slide, &(d3_t){r*4,0,0} },
 			{ type_copy_rot, &(struct copy_rot){ .n=5, .l=LINE_Y, .init_deg=-90+30, .step_deg=30 } },
 			{ type_end } }},
-		      .data = &(data_t){ type_cross, (pos_t[]){{-1,0,-r},{1,0,-r}} } }},
+		      .data = { type_cross, (pos_t[]){{-1,0,-r},{1,0,-r}} } }},
 		    { type_op_data_set, &(struct op_data_set){
-		      .op = &(data_t){ type_arr, (data_t[]){
+		      .op = { type_arr, (data_t[]){
 			{ type_copy_timeshift, &(struct copy_timeshift){
 			  .n=40, .init_sec=0, .step_sec=-1, .init=D3_O, .step=D3_O }},
 			{ type_rot_way, &(struct rot_way){
@@ -358,18 +357,18 @@
 			  .n=3, .ds=(data_t[]){ { type_none }, spin, { type_none } },
 			  .ts=(double[]){ sky_sec+pipe_sec*2, sky_sec*2, pipe_sec*2+sky_sec} }},
 			{ type_end } }},
-		      .data = &(data_t){ type_square } }},
+		      .data = { type_square } }},
 		    { type_end } }} }};
 
 		data_t *spin_ball = &(data_t){ type_op_data_set, &(struct op_data_set){
-		    .op = &(data_t){ type_arr, (data_t[]){
+		    .op = { type_arr, (data_t[]){
 			{ type_rot_way, &(struct rot_way){.l=LINE_Y,.deg_way=WAY_V2(0,360, 1.3,0, 1) }},
 			{ type_rot_way, &(struct rot_way){.l=LINE_X,.deg_way=WAY_V2(0,360, 1,0, 1) }},
 			{ type_end } }},
-		    .data = &(data_t){ type_circle, &(struct circle){.r=1, .n=3} } }};
+		    .data = { type_circle, &(struct circle){.r=1, .n=3} } }};
 
 		data_t *fireworks = &(data_t){ type_op_data_set, &(struct op_data_set){
-		    .op = &(data_t){ type_arr, (data_t[]){
+		    .op = { type_arr, (data_t[]){
 			{ type_copy_timeshift_rot, &(struct copy_timeshift_rot){
 			    .n=3, .init_sec=0, .step_sec=2, .l=LINE_Z, .init_deg=0, .step_deg=360/3 }},
 			{ type_copy_timeshift, &(struct copy_timeshift){
@@ -385,9 +384,9 @@
 			{ type_slide_way, &(struct way){
 			    .n=7,
 			    .ps=(d3_t[]){D3_O,D3_O,D3_O,{50,0,0},{50,0,0},D3_O,D3_O},
-			    .ts=(double[]){3, 0, 3, 4, 0, 3, 0}, .vs=NULL, .dg=3 }},
+			    .ts=(double[]){3, 0, 3, 4, 0, 3, 0}, .dg=3 }},
 			{ type_end } }},
-		    .data = spin_ball }};
+		    .data = *spin_ball }};
 
 		double a = 20, b = a;
 		struct way *rail = &(struct way){
@@ -398,10 +397,10 @@
 		    {a+b,a,a},{a+b+b,0,a},{a+b+b+b,0,a},{a+b+b+b+a,a,a},{a+b+b+b,a+a,a},
 		    {a+b+b,a+a,a},{a+b,a+a,0},{a,a+a,0},{0,a,0} },
 		  .ts=(double[]){ 2,3,2,3,3, 1,1.5,1,1.5,1.5, 1,1.5,1,1.5,1.5, 2,3,2,3,3 },
-		  .vs=NULL, .dg=3 };
+		  .dg=3 };
 
 		data_t *train = &(data_t){ type_op_data_set, &(struct op_data_set){
-		  .op = &(data_t){ type_arr, (data_t[]){
+		  .op = { type_arr, (data_t[]){
 		    { type_copy_timeshift, &(struct copy_timeshift){
 		      .n=3, .init_sec=0, .step_sec=1, .init=D3_O, .step={0,0,-a*0.5} }},
 		    { type_copy_timeshift, &(struct copy_timeshift){
@@ -410,21 +409,21 @@
 		    { type_train_way, &(struct train_way){.n=6, .len=4, .len2=8, .way=*rail} },
 		    { type_zoom_and_slide, (d3_t[]){ {1,6,1},{0,-2,0} } },
 		    { type_end } }},
-		  .data = &(data_t){ type_cube } }};
+		  .data = { type_cube } }};
 
 		data_t *matryoshka = &(data_t){ type_op_data_set, &(struct op_data_set){
-		  .op = &(data_t){ type_arr, (data_t[]){
+		  .op = { type_arr, (data_t[]){
 		    { type_slide, &(d3_t){20,20,20} },
 		    { type_recursive, &(struct recursive){
-		      .op = &(data_t){ type_arr, (data_t[]){
+		      .op = { type_arr, (data_t[]){
 			{ type_zoom_all, (double[]){0.8} },
 			{ type_rot_way, &(struct rot_way){.l=LINE_Z,.deg_way=WAY_V2(0,90, 3,3, 3) }},
 			{ type_end } }},
-		      .n=20, .cnt=0 }},
+		      .n=20 }},
 		    { type_rdiv, &(struct rdiv){ .n=8, .rate=0.3 } },
 		    { type_zoom_all, (double[]){10} },
 		    { type_end } }},
-		  .data = &(data_t){ type_octahedron } }};
+		  .data = { type_octahedron } }};
 
 		data_t *clock_frm1 = &(data_t){ type_wire_frame, &(struct wire_frame){
 		  .n=5, .p=(pos_t[]){{-1,0,-1},{1,0,-1},{1,0,1},{0,0,2},{-1,0,1}},
@@ -432,8 +431,8 @@
 
 		data_t *clock_house = &(data_t){ type_arr, (data_t[]){
 		  { type_op_data_set, &(struct op_data_set){
-		    .op = &(data_t){ type_copy, &(struct copy){ .n={1,2,1}, .init=D3_O, .step={0,2,0} } },
-		    .data = clock_frm1 }},
+		    .op = { type_copy, &(struct copy){ .n={1,2,1}, .init=D3_O, .step={0,2,0} } },
+		    .data = *clock_frm1 }},
 		  { type_bars, (pos_t[]){ {-1,0,-1},{-1,2,-1},{1,0,-1},{1,2,-1},{1,0,1},{1,2,1},
 		    {0,0,2},{0,2,2},{-1,0,1},{-1,2,1}, D3_O,D3_O }},
 		  { type_end } }};
@@ -441,42 +440,49 @@
 		data_t *clock_circle = &(data_t){ type_arr, (data_t[]){
 		  { type_circle_y, &(struct circle){.r=0.8,.n=36} },
 		  { type_op_data_set, &(struct op_data_set){
-		    .op = &(data_t){ type_rot_way, &(struct rot_way){ .l=LINE_Y, .deg_way=WAY_V2(0,360, 60,0, 1) }},
-		    .data = &(data_t){ type_bar, (pos_t[]){ D3_O,{0,0,0.7} }} }},
+		    .op = { type_rot_way, &(struct rot_way){ .l=LINE_Y, .deg_way=WAY_V2(0,360, 60,0, 1) }},
+		    .data = { type_bar, (pos_t[]){ D3_O,{0,0,0.7} }} }},
 		  { type_end } }};
 
 		data_t *clock_door = &(data_t){ type_op_data_set, &(struct op_data_set){
-		  .op = &(data_t){ type_rot_way, &(struct rot_way){
+		  .op = { type_rot_way, &(struct rot_way){
 		    .l={{-1,0,0},D3_Z},
-		    .deg_way={.n=4,.vs=(double[]){0,-90,-90,0},.ts=(double[]){0.5,1+1+1,0.5,56},.ps=NULL,.dg=1} }},
-		  .data = &(data_t){ type_arr, (data_t[]){
+		    .deg_way={.n=4,.vs=(double[]){0,-90,-90,0},.ts=(double[]){0.5,1+1+1,0.5,56},.dg=1} }},
+		  .data = { type_arr, (data_t[]){
 		    *clock_frm1,
 		    *clock_circle,
 		    { type_end } }} }};
 
 		data_t *clock_bird = &(data_t){ type_op_data_set, &(struct op_data_set){
-		  .op = &(data_t){ type_arr, (data_t[]){
+		  .op = { type_arr, (data_t[]){
 		    { type_copy_timeshift, &(struct copy_timeshift){.n=5,.init_sec=0,.step_sec=-0.1,.init=D3_O,.step=D3_O} },
 		    { type_slide_way, &(struct way){
 		      .n=9,
 		      .ps=(pos_t[]){ {0,1,0},{0,1,0},{0,-2,0},{0,1,0},{0,-2,0},{0,1,0},{0,-2,0},{0,1,0},{0,1,0} },
-		      .ts=(double[]){0.5, 0.5,0.5, 0.5,0.5, 0.5,0.5, 0.5, 56},.vs=NULL,.dg=3 }},
-		    { type_zoom_all_way, &(struct way){.n=6,.vs=(double[]){0.5,0.5,0,0,0,0},.ts=(double[]){4,1,0,54,0,1},.ps=NULL,.dg=3}},
+		      .ts=(double[]){0.5, 0.5,0.5, 0.5,0.5, 0.5,0.5, 0.5, 56},.dg=3 }},
+		    { type_zoom_all_way, &(struct way){.n=6,.vs=(double[]){0.5,0.5,0,0,0,0},.ts=(double[]){4,1,0,54,0,1},.dg=3}},
 		    { type_end } }},
-		  .data = &(data_t){ type_octahedron } }};
+		  .data = { type_octahedron } }};
 
 		data_t *clock = &(data_t){ type_op_data_set, &(struct op_data_set){
-		  .op = &(data_t){ type_arr, (data_t[]){
+		  .op = { type_arr, (data_t[]){
 		    { type_timeshift, &(struct timeshift){ .sec=-5, .slide=D3_O } },
 		    { type_zoom_and_slide, (d3_t[]){ D3_ALL(2),{-20,-20,20} } },
 		    { type_end } }},
-		  .data = &(data_t){ type_arr, (data_t[]){
+		  .data = { type_arr, (data_t[]){
 		    *clock_house,
 		    *clock_door,
 		    *clock_bird,
 		    { type_end } }} }};
 
-		wf_init_work_alloc(clock_frm1->p, NULL);
+		data_t *ripple = &(data_t){ type_op_data_set, &(struct op_data_set){
+		  .op = { type_arr, (data_t[]){
+		    { type_zoom_and_slide, (d3_t[]){D3_ALL(0.2),{-10,-10,0}} },
+		    { type_copy_timeshift_zoom_slide, &(struct copy_timeshift_zoom_slide){
+		      .n=20,.init_sec=0,.step_sec=-0.4,.init_zs={D3_I,D3_O},.step_zs={{2,2,0},D3_O} }},
+		    { type_slide_way, &(struct way)WAY_P2(0,0,-1, 0,0,1, 2,2, 3) },
+		    { type_end } }},
+		  .data = { type_circle, &(struct circle){.r=1, .n=100} } }};
 
 		data.type = type_arr;
 		data.p = (data_t[]){
@@ -490,6 +496,7 @@
 			*train,
 			*matryoshka,
 			*clock,
+			*ripple,
 			{ type_end }
 		};
 	}