From 0e40c1011f8247578c892c63f823c064be3fd900 Mon Sep 17 00:00:00 2001 From: Baptiste DURAND Date: Fri, 6 Sep 2013 12:31:40 +0200 Subject: [PATCH] Add Tizen Changes to pulseaudio in case of build WRT recipes --- ...1-TIZEN-changes-to-pa-simple-api-samsung.patch} | 25 +- ...port-for-samsung-power-management-samsung.patch | 298 +++ ...-Add-preload-fileter-for-resample-samsung.patch | 2562 ++++++++++++++++++++ ...004-TIZEN-Enhance-for-echo-cancel-samsung.patch | 326 +++ .../0005-TIZEN-add-support-for-dlog-samsung.patch | 214 ++ .../0006-TIZEN-add-policy-module-samsung.patch | 1308 ++++++++++ ...node-manager-addingexternalnodemanagerAPI.patch | 563 +++++ .../pulseaudio/pulseaudio_4.0.bbappend | 9 +- proto-meta-Tizen_ivi_3.0/.spec2yoctorc | 2 +- 9 files changed, 5291 insertions(+), 16 deletions(-) rename meta-wrt-tizen/recipes-multimedia/pulseaudio/files/{TIZEN-changes-topasimpleapi-samsung.patch => 0001-TIZEN-changes-to-pa-simple-api-samsung.patch} (96%) create mode 100644 meta-wrt-tizen/recipes-multimedia/pulseaudio/files/0002-TIZEN-add-support-for-samsung-power-management-samsung.patch create mode 100644 meta-wrt-tizen/recipes-multimedia/pulseaudio/files/0003-TIZEN-Add-preload-fileter-for-resample-samsung.patch create mode 100644 meta-wrt-tizen/recipes-multimedia/pulseaudio/files/0004-TIZEN-Enhance-for-echo-cancel-samsung.patch create mode 100644 meta-wrt-tizen/recipes-multimedia/pulseaudio/files/0005-TIZEN-add-support-for-dlog-samsung.patch create mode 100644 meta-wrt-tizen/recipes-multimedia/pulseaudio/files/0006-TIZEN-add-policy-module-samsung.patch create mode 100644 meta-wrt-tizen/recipes-multimedia/pulseaudio/files/0007-TIZEN-node-manager-addingexternalnodemanagerAPI.patch diff --git a/meta-wrt-tizen/recipes-multimedia/pulseaudio/files/TIZEN-changes-topasimpleapi-samsung.patch b/meta-wrt-tizen/recipes-multimedia/pulseaudio/files/0001-TIZEN-changes-to-pa-simple-api-samsung.patch similarity index 96% rename from meta-wrt-tizen/recipes-multimedia/pulseaudio/files/TIZEN-changes-topasimpleapi-samsung.patch rename to meta-wrt-tizen/recipes-multimedia/pulseaudio/files/0001-TIZEN-changes-to-pa-simple-api-samsung.patch index 310ad10..6410420 100644 --- a/meta-wrt-tizen/recipes-multimedia/pulseaudio/files/TIZEN-changes-topasimpleapi-samsung.patch +++ b/meta-wrt-tizen/recipes-multimedia/pulseaudio/files/0001-TIZEN-changes-to-pa-simple-api-samsung.patch @@ -1,21 +1,21 @@ -From f93af4616926360bfae8e46f5328e003185b01a5 Mon Sep 17 00:00:00 2001 +From 1077d79647ec9bc9aa6068343410994e497e9ac3 Mon Sep 17 00:00:00 2001 From: "vivian,zhang" Date: Tue, 18 Jun 2013 16:10:15 +0800 -Subject: [PATCH] changes to pa simple api - samsung +Subject: [PATCH 1/6] changes to pa simple api - samsung Change-Id: I997c02217a8dc14524480164aa0baeea901c7b4e --- - src/Makefile.am | 4 +- - src/map-file | 6 ++ - src/pulse/simple.c | 278 ++++++++++++++++++++++++++++++++++++++++++++++++++++ - src/pulse/simple.h | 28 ++++++ + src/Makefile.am | 4 +- + src/map-file | 6 ++ + src/pulse/simple.c | 278 +++++++++++++++++++++++++++++++++++++++++++++++++++++ + src/pulse/simple.h | 28 ++++++ 4 files changed, 314 insertions(+), 2 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am -index 6340dbc..ebbed80 100644 +index a621a30..f058be8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am -@@ -815,7 +815,7 @@ libpulse_la_SOURCES = \ +@@ -801,7 +801,7 @@ libpulse_la_SOURCES = \ pulse/volume.c pulse/volume.h \ pulse/xmalloc.c pulse/xmalloc.h @@ -24,7 +24,7 @@ index 6340dbc..ebbed80 100644 libpulse_la_LIBADD = $(AM_LIBADD) $(WINSOCK_LIBS) $(LTLIBICONV) $(LIBJSON_LIBS) libpulsecommon-@PA_MAJORMINOR@.la libpulse_la_LDFLAGS = $(AM_LDFLAGS) $(VERSIONING_LDFLAGS) -version-info $(LIBPULSE_VERSION_INFO) -@@ -825,7 +825,7 @@ libpulse_la_LIBADD += $(DBUS_LIBS) +@@ -811,7 +811,7 @@ libpulse_la_LIBADD += $(DBUS_LIBS) endif libpulse_simple_la_SOURCES = pulse/simple.c pulse/simple.h @@ -34,10 +34,10 @@ index 6340dbc..ebbed80 100644 libpulse_simple_la_LDFLAGS = $(AM_LDFLAGS) $(VERSIONING_LDFLAGS) -version-info $(LIBPULSE_SIMPLE_VERSION_INFO) diff --git a/src/map-file b/src/map-file -index 3dee7ee..a074a49 100644 +index 955b295..4c9ba57 100644 --- a/src/map-file +++ b/src/map-file -@@ -274,11 +274,17 @@ pa_signal_new; +@@ -262,11 +262,17 @@ pa_signal_new; pa_signal_set_destroy; pa_simple_drain; pa_simple_flush; @@ -427,6 +427,5 @@ index 0fab8ee..bff9dbb 100644 PA_C_DECL_END -- -1.7.10.4 - +1.8.1.4 diff --git a/meta-wrt-tizen/recipes-multimedia/pulseaudio/files/0002-TIZEN-add-support-for-samsung-power-management-samsung.patch b/meta-wrt-tizen/recipes-multimedia/pulseaudio/files/0002-TIZEN-add-support-for-samsung-power-management-samsung.patch new file mode 100644 index 0000000..a8cd2e3 --- /dev/null +++ b/meta-wrt-tizen/recipes-multimedia/pulseaudio/files/0002-TIZEN-add-support-for-samsung-power-management-samsung.patch @@ -0,0 +1,298 @@ +From 0a6396ae3b4eae05f1a835c4e35e7141a58dad4b Mon Sep 17 00:00:00 2001 +From: "vivian,zhang" +Date: Tue, 18 Jun 2013 16:11:16 +0800 +Subject: [PATCH 2/6] add support for samsung power management - samsung + +Change-Id: Id6efaab5a9888fc5eec2883c6be35090f6df375c +--- + configure.ac | 12 +++ + src/Makefile.am | 3 + + src/modules/module-suspend-on-idle.c | 176 ++++++++++++++++++++++++++++++++++- + 3 files changed, 188 insertions(+), 3 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 388fae2..32bedf2 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -667,6 +667,18 @@ AC_SUBST(LIBSAMPLERATE_LIBS) + AM_CONDITIONAL([HAVE_LIBSAMPLERATE], [test "x$HAVE_LIBSAMPLERATE" = x1]) + AS_IF([test "x$HAVE_LIBSAMPLERATE" = "x1"], AC_DEFINE([HAVE_LIBSAMPLERATE], 1, [Have libsamplerate?])) + ++#### samsung PM API support #### ++ ++AC_ARG_ENABLE(pmlock, AC_HELP_STRING([--enable-pmlock], [using Samsung power management api]), ++[ ++ case "${enableval}" in ++ yes) USE_PM_LOCK=yes ;; ++ no) USE_PM_LOCK=no ;; ++ *) AC_MSG_ERROR(bad value ${enableval} for --enable-pmlock) ;; ++ esac ++ ],[USE_PM_LOCK=no]) ++AM_CONDITIONAL(USE_PM_LOCK, test "x$USE_PM_LOCK" = "xyes") ++ + #### Database support #### + + AC_ARG_WITH([database], +diff --git a/src/Makefile.am b/src/Makefile.am +index f058be8..b90f7e5 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -1893,6 +1893,9 @@ module_suspend_on_idle_la_SOURCES = modules/module-suspend-on-idle.c + module_suspend_on_idle_la_LDFLAGS = $(MODULE_LDFLAGS) + module_suspend_on_idle_la_LIBADD = $(MODULE_LIBADD) + module_suspend_on_idle_la_CFLAGS = $(AM_CFLAGS) ++if USE_PM_LOCK ++module_suspend_on_idle_la_CFLAGS += -DUSE_PM_LOCK ++endif + + # echo-cancel module + module_echo_cancel_la_SOURCES = \ +diff --git a/src/modules/module-suspend-on-idle.c b/src/modules/module-suspend-on-idle.c +index 02a6b91..8db2742 100644 +--- a/src/modules/module-suspend-on-idle.c ++++ b/src/modules/module-suspend-on-idle.c +@@ -34,7 +34,53 @@ + #include + #include + ++#include + #include "module-suspend-on-idle-symdef.h" ++//move to configure.ac ++//#define USE_PM_LOCK /* Enable as default */ ++#ifdef USE_PM_LOCK ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define SOCK_PATH "/tmp/pm_sock" ++#define SHIFT_UNLOCK 4 ++#define SHIFT_UNLOCK_PARAMETER 12 ++#define SHIFT_CHANGE_STATE 8 ++#define SHIFT_HOLD_KEY_BLOCK 16 ++#define SHIFT_CHANGE_TIMEOUT 20 ++#define TIMEOUT_RESET_BIT 0x80 ++ ++#define LCD_NORMAL 0x1 /**< NORMAL state */ ++#define LCD_DIM 0x2 /**< LCD dimming state */ ++#define LCD_OFF 0x4 /**< LCD off state */ ++#define SUSPEND 0x8 /**< Sleep state */ ++#define POWER_OFF 0x16 /**< Sleep state */ ++#define SETALL (LCD_DIM | LCD_OFF | LCD_NORMAL) /*< select all state - not supported yet */ ++ ++/* parameters for pm_lock_state() */ ++#define STAY_CUR_STATE 0x0 ++#define GOTO_STATE_NOW 0x1 ++#define HOLD_KEY_BLOCK 0x2 ++ ++/* paramters for pm_unlcok_state() - details are described at 162 line */ ++#define PM_SLEEP_MARGIN 0x0 /**< keep guard time for unlock */ ++#define PM_RESET_TIMER 0x1 /**< reset timer for unlock */ ++#define PM_KEEP_TIMER 0x2 /**< keep timer for unlock */ ++ ++struct pwr_msg { ++ pid_t pid; ++ unsigned int cond; ++ unsigned int timeout; ++ unsigned int timeout2; ++}; ++ ++#endif /* USE_PM_LOCK */ + + PA_MODULE_AUTHOR("Lennart Poettering"); + PA_MODULE_DESCRIPTION("When a sink/source is idle for too long, suspend it"); +@@ -47,6 +93,13 @@ static const char* const valid_modargs[] = { + NULL, + }; + ++#ifdef USE_PM_LOCK ++#define PM_TYPE_SINK 0x01 ++#define PM_TYPE_SOURCE 0x02 ++ ++#define UPDATE_PM_LOCK(current,type) (current |= type) ++#define UPDATE_PM_UNLOCK(current,type) (current &= ~type) ++#endif /* USE_PM_LOCK */ + struct userdata { + pa_core *core; + pa_usec_t timeout; +@@ -70,6 +123,9 @@ struct userdata { + *source_output_move_finish_slot, + *sink_input_state_changed_slot, + *source_output_state_changed_slot; ++#ifdef USE_PM_LOCK ++ uint32_t pm_state; ++#endif /* USE_PM_LOCK */ + }; + + struct device_info { +@@ -79,9 +135,79 @@ struct device_info { + pa_usec_t last_use; + pa_time_event *time_event; + }; ++#ifdef USE_PM_LOCK ++ ++static int send_msg(unsigned int s_bits, unsigned int timeout, unsigned int timeout2) ++{ ++ int rc = 0; ++ int sock; ++ struct pwr_msg p; ++ struct sockaddr_un remote; ++ ++ p.pid = getpid(); ++ p.cond = s_bits; ++ p.timeout = timeout; ++ p.timeout2 = timeout2; ++ ++ sock = socket(AF_UNIX, SOCK_DGRAM, 0); ++ if (sock == -1) { ++ return -1; ++ } ++ ++ remote.sun_family = AF_UNIX; ++ if(strlen(SOCK_PATH) >= sizeof(remote.sun_path)) { ++ return -1; ++ } ++ strncpy(remote.sun_path, SOCK_PATH, sizeof(remote.sun_path)); ++ ++ rc = sendto(sock, (void *)&p, sizeof(p), 0, (struct sockaddr *)&remote, ++ sizeof(struct sockaddr_un)); ++ ++ close(sock); ++ return rc; ++} ++ ++static int pm_lock_state(unsigned int s_bits, unsigned int flag, ++ unsigned int timeout) ++{ ++ switch (s_bits) { ++ case LCD_NORMAL: ++ case LCD_DIM: ++ case LCD_OFF: ++ break; ++ default: ++ return -1; ++ } ++ if (flag & GOTO_STATE_NOW) ++ /* if the flag is true, go to the locking state directly */ ++ s_bits = s_bits | (s_bits << SHIFT_CHANGE_STATE); ++ if (flag & HOLD_KEY_BLOCK) ++ s_bits = s_bits | (1 << SHIFT_HOLD_KEY_BLOCK); ++ ++ return send_msg(s_bits, timeout, 0); ++} ++ ++static int pm_unlock_state(unsigned int s_bits, unsigned int flag) ++{ ++ switch (s_bits) { ++ case LCD_NORMAL: ++ case LCD_DIM: ++ case LCD_OFF: ++ break; ++ default: ++ return -1; ++ } ++ ++ s_bits = (s_bits << SHIFT_UNLOCK); ++ s_bits = (s_bits | (flag << SHIFT_UNLOCK_PARAMETER)); ++ return send_msg(s_bits, 0, 0); ++} ++ ++#endif + + static void timeout_cb(pa_mainloop_api*a, pa_time_event* e, const struct timeval *t, void *userdata) { + struct device_info *d = userdata; ++ int ret = -1; + + pa_assert(d); + +@@ -91,12 +217,32 @@ static void timeout_cb(pa_mainloop_api*a, pa_time_event* e, const struct timeval + pa_log_info("Sink %s idle for too long, suspending ...", d->sink->name); + pa_sink_suspend(d->sink, TRUE, PA_SUSPEND_IDLE); + pa_core_maybe_vacuum(d->userdata->core); ++#ifdef USE_PM_LOCK ++ UPDATE_PM_UNLOCK(d->userdata->pm_state, PM_TYPE_SINK); ++ if(!(d->userdata->pm_state)) { ++ ret = pm_unlock_state(LCD_OFF, PM_SLEEP_MARGIN); ++ if(ret != -1) ++ pa_log_info("sink pm_unlock_state success [%d]", ret); ++ else ++ pa_log_error("sink pm_unlock_state failed [%d]", ret); ++ } ++#endif /* USE_PM_LOCK */ + } + + if (d->source && pa_source_check_suspend(d->source) <= 0 && !(d->source->suspend_cause & PA_SUSPEND_IDLE)) { + pa_log_info("Source %s idle for too long, suspending ...", d->source->name); + pa_source_suspend(d->source, TRUE, PA_SUSPEND_IDLE); +- pa_core_maybe_vacuum(d->userdata->core); ++#ifdef USE_PM_LOCK ++ ++ UPDATE_PM_UNLOCK(d->userdata->pm_state, PM_TYPE_SOURCE); ++ if(!(d->userdata->pm_state)) { ++ ret = pm_unlock_state(LCD_OFF, PM_SLEEP_MARGIN); ++ if(ret != -1) ++ pa_log_info("source pm_unlock_state success [%d]", ret); ++ else ++ pa_log_error("source pm_unlock_state failed [%d]", ret); ++ } ++#endif /* USE_PM_LOCK */ + } + } + +@@ -125,16 +271,37 @@ static void restart(struct device_info *d) { + static void resume(struct device_info *d) { + pa_assert(d); + ++ int ret = -1; + d->userdata->core->mainloop->time_restart(d->time_event, NULL); + + if (d->sink) { +- pa_log_debug("Sink %s becomes busy, resuming.", d->sink->name); ++#ifdef USE_PM_LOCK ++ UPDATE_PM_LOCK(d->userdata->pm_state, PM_TYPE_SINK); ++ ret = pm_lock_state(LCD_OFF, STAY_CUR_STATE, 0); ++ if(ret != -1) { ++ pa_log_info("sink pm_lock_state success [%d]", ret); ++ } else { ++ pa_log_error("sink pm_lock_state failed [%d]", ret); ++ } ++#endif /* USE_PM_LOCK */ + pa_sink_suspend(d->sink, FALSE, PA_SUSPEND_IDLE); ++ ++ pa_log_debug("Sink %s becomes busy.", d->sink->name); + } + + if (d->source) { +- pa_log_debug("Source %s becomes busy, resuming.", d->source->name); ++#ifdef USE_PM_LOCK ++ UPDATE_PM_LOCK(d->userdata->pm_state, PM_TYPE_SOURCE); ++ ret = pm_lock_state(LCD_OFF, STAY_CUR_STATE, 0); ++ if(ret != -1) { ++ pa_log_info("source pm_lock_state success [%d]", ret); ++ } else { ++ pa_log_error("source pm_lock_state failed [%d]", ret); ++ } ++#endif /* USE_PM_LOCK */ + pa_source_suspend(d->source, FALSE, PA_SUSPEND_IDLE); ++ ++ pa_log_debug("Source %s becomes busy.", d->source->name); + } + } + +@@ -436,6 +603,9 @@ int pa__init(pa_module*m) { + u->core = m->core; + u->timeout = timeout; + u->device_infos = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); ++#ifdef USE_PM_LOCK ++ u->pm_state = 0x00; ++#endif /* USE_PM_LOCK */ + + PA_IDXSET_FOREACH(sink, m->core->sinks, idx) + device_new_hook_cb(m->core, PA_OBJECT(sink), u); +-- +1.8.1.4 + diff --git a/meta-wrt-tizen/recipes-multimedia/pulseaudio/files/0003-TIZEN-Add-preload-fileter-for-resample-samsung.patch b/meta-wrt-tizen/recipes-multimedia/pulseaudio/files/0003-TIZEN-Add-preload-fileter-for-resample-samsung.patch new file mode 100644 index 0000000..96bb2ef --- /dev/null +++ b/meta-wrt-tizen/recipes-multimedia/pulseaudio/files/0003-TIZEN-Add-preload-fileter-for-resample-samsung.patch @@ -0,0 +1,2562 @@ +From fc713c4070338beeb7360ca795f5672f132f201d Mon Sep 17 00:00:00 2001 +From: "vivian,zhang" +Date: Tue, 18 Jun 2013 16:12:20 +0800 +Subject: [PATCH 3/6] Add preload fileter for resample - samsung + +Change-Id: Ia57b4eb1848d53bbfa15c04b25f4821554aff28f +--- + Makefile.am | 5 +++ + filter/filter_44100_48000.dat | Bin 0 -> 38950 bytes + filter/filter_44100_8000.dat | Bin 0 -> 227550 bytes + filter/filter_48000_44100.dat | Bin 0 -> 45100 bytes + filter/filter_8000_44100.dat | Bin 0 -> 32800 bytes + src/pulsecore/ffmpeg/resample2.c | 66 ++++++++++++++++++++++++++++++++++++++- + 6 files changed, 70 insertions(+), 1 deletion(-) + create mode 100644 filter/filter_44100_48000.dat + create mode 100644 filter/filter_44100_8000.dat + create mode 100644 filter/filter_48000_44100.dat + create mode 100644 filter/filter_8000_44100.dat + +diff --git a/Makefile.am b/Makefile.am +index b0b2553..a230fb7 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -52,6 +52,11 @@ dist_vapi_DATA = \ + pkgconfigdir = $(libdir)/pkgconfig + pkgconfig_DATA = libpulse.pc libpulse-simple.pc + ++filterdir = /etc/pulse/filter ++filter_DATA = filter/filter_44100_48000.dat \ ++ filter/filter_44100_8000.dat \ ++ filter/filter_48000_44100.dat \ ++ filter/filter_8000_44100.dat + if HAVE_GLIB20 + pkgconfig_DATA += \ + libpulse-mainloop-glib.pc +diff --git a/filter/filter_44100_48000.dat b/filter/filter_44100_48000.dat +new file mode 100644 +index 0000000000000000000000000000000000000000..29de3e9b4fab7d77aeeba846dff3db9e6af19e55 +GIT binary patch +literal 38950 +zcmZ_WbwCx%+XwKOJ?CuLh23IzB7z_wAgP3ODcyFr*Y57Rc8lHJomahfUfn%O!|u+! +z1A6(Lv)tFeKR(Ye+q2(22&+IN5QM8!QKAcbGbgO-=*+OHH*;LrD6u*fgc|`BKp2&( +z!KJDn`#8sesIgVg=eV(U$$1qp3P7 +z^GMY_IX-Lzsb#4GaSbX)?8WMHepDHi`Jn3N96vT(tV&eFvT-#AC2EM+jV;W%PZVEu +zWlmtJ3Mr?Cik(?i?%^sUGns1hbAs70QmaI%OaDd+Gyws)CN)%S&sNS|K~#%s({jRz +zszQa9Q?X(jwodMtDkC!cRU4BN#fFxu24=PVNv$~1nr)UFMpR_Aw45RTuWH7&&vmFW +zJaa;|p*eAEh*+5l!~d(*6!_y>RJ_=T?U~!G%CO8e)k1QT{zLf@l_1t<9dk8A9k1q_ +zlgb8*m8fuBpNvZ;+mQlI!7o*t^~n8MIWzM~wf;F7|Bp%(YqEj44=QJ5>Z|q18O{ck +zt2GE)QAuJ|HYzu(a(ZUP>Roe26IGFlFzeV1{8E+Jq}-L2(=yvsZ=Exa9sHjvS!CG} +zx#KFQX1Z2ylrynZMdEs8qi+TVl8z~&hMklfQ8_s?wtCH+DQuuvfhtj&-+yC?s!gSe +zke!p;uX0l6wCY^W^ima7rXXkrd`p$gEX%d7oS3<(I?n!sD2_5$%}Z69Sj=q5Wh=*L +zo~@pjJ(mqARds)Ngy5G-7xS5&xw=YmnJ=qrvlo=AXl$;0a2+Z`%wZ1aKB+V`Gq3vR +z?8U6V$Ws5M49wZw6P02zYt(p^y{uHll&h5~3e5G~b(NwsyVQ7?y^{4487coBYRD$8d6RT7r!#Ea)(q3&rGRtE_*#uG^JE^sS)Bw=1ZNQi4Tcy(A%xg6^ +zXKyc4bm?}4z#5dOQQ`}R%FC%3komF3%Isb2KvFA~)cT+DBxF9~;QDeosOtZYL6}>ZUYmUu6%=(Hd +z%2Ig{HBP+Aw9lJW(K9o+W_tF~QWbAjt0gE= +z`BrqzTwXIQ`!wrAR06J5Hm+Z_CWz-4&%EvxoimTr9F%>ID5y{aNXLodDJC$lPDRJe +zhc(@^FaAGjl6Z`X&XX$GXKHKq&Avhupc2hGwgLlieQL6Jm`Tq2RH091g<3tbue08z +zs%F`^S^;;WrilBQk$E>O*krb@)h_!cQ5YuSnt&V@ee>se0qCu*)Zi+PiGimRO&Xm!u@nW$oz +zZc(d5%@e0H-}5$cH8Mw7T{V3ps)(p+fF)a~!zP}nLTIU6NUeq9XhxIo&C!|nt#+Aor7F{`R$EY_7Ky`|YWdwb +zDpRo9XfhI205fsbvT^-Vi^X)NetsPeWpK4un6gXNFbm~OYAq3ynU?tyTb$9l_Iy(w +z>mlaD@@lCV&vefJ%;smf)t+W5Bq|RMFIQ`sIE3kwe~Zn|h^sx;RQy|2`8_U#+kujf +z%f(2hfBr#MpE09$hDjzW7mmQ@%895IVkk2(e>wXzV_WSw6aIhHN^vj~nm>;HmT{?e +zxQXIC#2h%1)Z$9FP)Wy7EU!(`;Uux~S@+8!pR +zRE@Gw{Yb5~q6afRzb*SRqd^@<6GxN@nydDpM6DD1Gc)t6vQIN?>+~{JBFYFy<4UBX +zMD`nmOH@N@z1WXgoS(-$$Ox&^(NyLCQ5!^iW^Ml8%$X$o?)tkjSc=oIgpvyCbnT7*JmuK`_$N)^Avx=iI^+v*b$Vd-C|7! +z7QCcaX6&nb$JqA&QG3LyOr?Sg^x}*=buSy+6ZHd5DpzZ-Sb?ciu$`Wl@uTi3V@IO? +z`46>Eq?u*~^XZuxOua+KE<}BYlQC;HE_*Vr10uzAC>Tah&S+I{r?Fe9no>?36cOF4 +zAc!8D;aYE#u?JD#V2P?&I`=Z}1WIZh5{qc3g1+?djJSF$jlGEa3a6G+hs8YFtDps) +znlZE90;4VGRjL@XT6UyXmT01b3M$a?8GqKBVYDOa3!H|P>ZqurhZGn!(HU3jjW_ls +z>hpi7W8x1wwcw>DB;#YfVMa%yKEdgjR&+crex=70T-5ky;ChKhr~gNt6hG3_3U+9` +zGaA>AHumSd#gA}CSuF{727SorPl<2o1qBNx{#Fhb*) +z5mDdAIDn}4L}`AH>sPJ%)LHQvy|o}z(>r5Q{r*PJQuRkUbxwRl?=NuFbj{dM-`?oW +z`H1geiKg@Cr +z4fKX6qW*&O%~aP?bz9s{TNS#gh4kkQz8PY;LE?*2Rr&Ya|5A6wEp(H@j_NPzxeeYK +zh7$E0F2E32s(a#kx?Q1_`fYm6hR+RgL_Jd|8#1o@;%d4_p`?1A-o4>{LjvbV)WWh_ +zBJK)o$UXT(aT)Dc_(k;~-M`^=LlRL>;i7Wtk+_KVEWD?>kv^i~IYTn%FFqj({2tf8 +zwVsIc=)l6Gstf7M8XhyG67?7^HdEb7J3bZvprZ@dt4^e6HQZ-NC+ZPgQcgV=r_m{e +z(^Uu4A2uv_sK02-CfrApKIJ&cltk$f9FSDo1Qa4=9=s3)9k?6zG?6QQ|qc +z$xQVGJ;=&duGo+cC>jCvX$zYe^eeb%@ocH8M&=%XV%!sSCn{g8OGg!j!*6K^n*5_* +zS*kYULh>B&KUIS&6l>B+MK177+Jhz^^sBfS@eC}lio`1P$f6GLX_~IdOZ^&dhJ*S9&8DJ9U|(8#)6@EmL>-5J;{39Xy~s>dr=V1z*;8~H +zY)xC#^oV{l7bhNr+si4Hl%qLXv<<9IJJ@uOehU{b9xYYXf6rGh&<$6k)RJCvp=dr> +znD(IQR{d5kLCk_XNUdM02>(*F^iy-YXe5}Crf<4Vzm2FPa3{`FC|3HWd0G?!#-&wh +zwoJdBOB4^6Q&lNW`lxwV5b-}qD~+-&9~VM{Z1}f +zJP3E=T#JrXsmjtzO?FWo5So_RY=V9lQ3uMYDpVEesYWUSz&CA4vyuAUT#C3K?lG%n +zLuR51RZV)JVTym^{%MDsrRw)`sp3Ak7w439{H1D0w>342pJLmzN6q5&`?xf5PdQbY +zswrL9G%P-kJEs|&MdEdp7mq*i6hO1h+JUAz-pr&Vh{Sbu=1U2s3n +zHd9@Rsw17%bS++j>!o#R?xR1*Wr#b=sY+B`>7>TKcpR>h=GWX!e~8NzcfbRRT9v5! +zQkKT8cnDUd4R7wCKgJ7T$ic}M6yC$KyG5(zTw0Rr-QEsHT6&}XMvW~x0GikGC +zcrlA#rsgznra#7w61Tu33RQt>F0Io{EY3#vQ){-UuRqR>7B`own!jhYq*evWT3V@@ +zUHk@JPVLd6hW-Rmn_w0;kaeGu^F$H;rCLc#HA{j%U +zMp~fRP<$BeOrtv|($71#fVYAemw>?~e~Hm9y?A?r?aGfXy0`?M +z#ezjg4P_?i%?9`hC*)l@%efToi;S*B9^w%n$>%FPxRzzYhcqMRicO>Z$t +z&P$1Exn6gTBP(zgst=hj71dvI(71^H^3RkhEmsmXSDXtk;-6&Y_t&hJD2j5EY&AY& +zU-@mymX?cj*SUG(9C)dm8X)!1gothA$0?Uv&eq-F=8Lo8<#NhX>Y^Dc){w8Id}=wB +zs0HFIqJCI(gp`-mUXw1$(#aIqYP{|yw@{o3uar|hQY+0^@rSfGrFp9nL@gF)z^e)c +zsDV;5%?$CGv@yk{RjTe5w?v!{ui<|zIs(d1YN%N#UX+%k#I=eeYN-;6N`b!}g +zBvsbz7pF=|DK}gB>F#hV#7XdGITa#tnv-IR6rS==D^H?Ui4!f99qEW*n55QR76(f{ +zDQxThy1U$JaRR)Bzm;_?Q8J8>u==jpPwJP_rgdMU)`;Wa?Q$wgDptP`+e_V3JX+fj +zwN@Mp?y*LKm#a}HtN^q!TRP!Pw)lFH@x*bs)#L?xH +z2;(F{oh$0Z3MmI#w;*bxI1=7d)DmHW^j(d_SE7{spmihNeQvWj0^Y}8$h)6kvs&^u +z7Q;m8lbVyRi-u%<>pDbj5r@MEP8^mYH +zo!e9(YMYn=AL7pz9m(3W^i17Gnl0W)9@Ivyd%$fM)8Qk9DukKRLv=T4gm@}>cpIdB +z!0iyz;Nx;?xO7L|SBez(CNFPONYqX-6+XeA$~xMUzp((0l&-7YB@b~!^0781qIQeP +z|Di@pm(+ezPjON5^ELued&DI8R8cD*j+M@;Bcx{Hl;pfN-?R_8ePSYfhCf<#%!lKp +z6Y2!1vN$ZccH0j`?HA+WbE4{!>siSjT{5mbI8i#H9wrqQ4^6gd` +zX}@}c^tCu3Ii&3~q7I3%QCVUPe2L#%bj*P>rH$%!(w^eh$>-W$A?m0Y4PPl#Hk>7`QSXpe71v9C+x8q$ +z$Hhqax}2ILEmt3srWaR8mfM~n>Vz0U)Vtpu^Gj#K1m{VM)u*NOVlk<4yTe4C62sx& +z<p8Bd3TC7cSY`2%F(_$!mLsY%eS^ZVZ2p39!s2@mf#qW}0+U+3fj2Hsn;Pxne0WOs$s6R=Ki!UYp*={XS=f%PQp_WUd)q+&9 +z_(;;VcFT#nC(){+rwfDJO +zqBs0fPHmI?)!pTpMg5cZw@)SNj_3)$Dija5OFrtp^01DD_YeldBhfPaM&~ +zOM91lCOX5PL^UXzudetXcv$MJo*<*bzYcpD?BANQ2!|(D_oUWw_{iBZSIZO2kOeHGg58!0eNfTtVG+6?TLCP+Cn{k +zZqe}zJSSCGpOhCDj!F#c*h+hg`ylp)28H?zFG!Wtm*t6tafuT0 +zzAGme1|)9m*id_u`z-b(>KV!2{Mrjk{>D%6szj-u%Rz-Mi5EK7(ca*`irt|}p+3Uv +zlB{|!_b=?0_@QGBqP~mWV0JlmQz}&bkh>N(O9Y)NYp-+vh+SX~ernP21H3KesIuiI +zh1Cap}eRUiFT@E~DVr##^b +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 +zf}^vYVs6Y*A}HTqRpmkuWUV +zDu(OxnD5D*kye5MX3CMI{no)XauX^6dS~P4c6}c5-MI78a^O);t(WUlnb0BoXS8RZ +z2YeUqlC%_ff7I$bHuCRHn}1-A6jMaiayxqHs6N3CCvvu;2`Pvuj+?a!R<0l +zt$=Ly(&&eMZt^X;yV6|Xt57T9E*VlAV6kaJw4u)pz6JL{nga%c0~WPbz&)}AcR-yf +zHoB_aHNGkLNSXx(l~eoV0(cO9H2Fk#vAfDQ;+{$~fuDtP!pq@7IUAmYPfa$_es-7n +z2HXp2I`9Yk%{n^aW$>`9gO}h9Q`6`Xc9;0N+$(7+2q3CW+281dm%=Rh2fPJOo4DxZ +zb{Bao?u|4V1cH4QY6(0pe}RwTep61=F}w48P42xk5e!zS#qgy39=?W~O>d)~+nwX9 +zaUZ4eAjm>F<3;ea{2G3SOHDVT^6bv?mANm{SP%^M{_dDV?m9};Ir%x{;Y`!vC@cFj +zd1RvH1q +zz#fZ^^Wjzb22@j#rj)3$_9u9XGf2ZgxP@}T^Wb&)GOSDuG6h7fwLi{dHe1R75nwlN +zTRN*Hqj$k`;Z6A*tWCL??4!=uALAu9Pf7!k3N;7bkx#=P>oClkq!E0@j0w4C4iW6>an~V +z_NJf{Q;lK+o2PsHrli +zS&@_a9^!eHmSaGyg>uC+;7fTO^rr;ly2wpL{lju{6o>;m%sRT_>F~9@5{6M9j58uH +z^gYObWh==MAfBjpWwYvvr@^=K5*SN8HKs>4_r@&A0EI5ifYqX1O;;^6po3)aIK$1dDhF|1qa1wRMXdUTD)JwLm +z90-!ZpBA+y!Ef?JIE&h5tP~mJu#bPvHjw>6N;&mI9s?IqtBko3(};S)HkJp0RE3%d +zd3iWoP0cgDi`YigL$3(~+gvySd~0@TXsa5FX8cq8J9!(RR_+fw!h=?XO-8ssFn +ziyCe`81b2?TWlNI6J&s`Bu8FymMhs;-SIeRl4IdvD#5raf^yu;UuWCP13;!ijfJ^# +z6g)+R87D`yAnG#PNp=InEYtuz2IkA5@Dk-~jE`_}+{0gByUP8+aInR!;{ZGw7RrI} +zHsx&eiHIfYEZakN1|t+|6cpuw@G;fP*fZh}qE50laz8K;OhtC=WaW0^|xmQB91Ri0echW*uaEFj}F8Lkc;;pHwZQHvAh=2UsV$4;TYB +zm34F=Ul|R9YGe;h6l;7QuIaaj-^=!wdxNp%6oYJF5hWYWhqokZC+jZv0^^A4@O$nZ +z$k$JqkVD-dRGAFh!(EB`ll7E)fbn3Xh01^xQAb!o_1&-_JfYuSelzPMcLNg?Djilq +zZD0-68^eh3*+gw%{p2oSBG_P7%L}K$YRDSaS3Nd_h3_J24I3zT0+SRf71l&eU~|=V +zgH!lTqE@iMatAP3p;Dj~st?<#&KTN;fA6=CU&@Bb?Z6bUo^;GB-M<{jH)YAN4zhyX +zREG@J!fB^{{6aQLZUd%TC~uqu>!WJ0k7~Q2Ags01ets@HL~aG9fpuoJym2CIh$=#7 +z)mp=cFn6M6v2n6Bm`+s3vX0(30X9Jl^inM{+zd-}I>1k76Xj-LhC;=|W{83Tsu_lZ +zVRML@%%;jsz)Y~#td9popl8FC}=heE}|R;Uofs?rS;!)_5Z +zh8-?90J9WoC~SjrK&on}VQAPtPKWpr>?pY&m<`rgbQ}WPBLf(z3O0CzG0uni40fDc +z2h6chzBmSUL_C&^38AfAPVrvsYFQ1If)!;Q`;sqbL!b+~1g@wIdhbv-m(#pEyH2LSGKC6;uIMbd +zqxz=r9-82CmUm${$p9?3P<}WFx}y`|iRz8MUg&I>bG#$FRYrIPSZ>zQ4-bZ(C=0w+ +zJ<;Qkoi68jJ9dXG;gv*n{ynRG$v4D-&>I~9A62*X-$QP=T;Ofk-EuKr4VIZHe;fb@ +zqTS$!>Vp1$$Tycue0O%AT!_~wlt1)Ce*&ZGnEq&prvGKWGkZwR!)q1F4+fykpis3} +zzc$3W|5d&{n6_ +zzs=WYFUbPlWT67FH;hKJL1XneeVvf2{qOKr>^1o(-V7F-bqvH_a44D%TB=XGT{!^jcVJgZ5E@}_`%HSB+r#xU^ +z$nWuXu+XBG8_Yl{z)RgvKOuOk>vLXWUdeCq4ht28UEwek5B$}=^wGgvT>s(=n78t4 +zywgnClV2q04@aUQAWYp+?;3p3^%bAPe2`z_U0^|3#}efNN23TZL~X5aANuh2Vf^k1M3HgF?YEJ(q$jria0zM) +zj;gQf=%AkNx%_#iBD#Q&DwGXej#`2<>a#jwaG-lWe~PJ!&f()=Hu)Cg-?0ZPiV``u?_=JTD$35X1)BxO8@70|cyxd*n4>7gTNqkbFdcbw44tS*A +zs#`xe%N_B1nfmBBJ_Tl#b+iNFxI5f{YJk7gYjslxKX!-04yF-0icc$4H@F#90q@jH +zb#a3Y?rLEx(+nNKXG&FW>0O5%h`?RpR>Xm?>N&argR2Z+gbhqfbO@gXe~^y45g)^I)b~tw`Jn?nWXm +zQfKN40#gT66&5mG&~AJ|p*q5Sr~m^^qV7%L`~fwDIZO|<6JJ!Q4)6fV#*8LPcR6tH +z04rez(;IEam%t3%y=?SRxIH|C^tg&9NVhZa)_}UgWX29{#g`ST9n3-`FRAg>%?tcK +zprJ61aYUQ(6@_XGkD+h4p~hX85vcKKB8+5Q&_;X}OgHNojoZMJ=p$~San$(-T6;7X +zG8lKX9$!=q`5C)YaV%xZu%U7|evB#rU>`8iJd{>*xmd(NxzR40z+wOBlpNp@sMk +zQ9XXoeIGCcH-k6HQ5vA(bjt#YJ^Bb<%uqBR-vv`FR8x2doyTDsN;f*7uBU_G#w4J* +z_@0FtikrZD=rkUpDb|Jt*myb#PE0bIh3|vOX0?Xm#_$0-W|A~H+P(pUJzWJmCLPVh +z4;88re2fm`OpTyz7BI@wL+Hf}N7L~mg=z?&lKp(N=Bri{u-wyI=*o;nQ}JUk$*f~6 +zZUA4PU3ik_o%W~y5zj$F2WC8)gr6u>efSdniDzp5(mwEiDb^w`d(+s=2LQg{lMJlRagP +z=CXFYe><-jp*AxQjl?gA>RGmh;&5&F5iP}=G-tGt{sX+?gzC&9G#vj0CYUMm+Ys;z +z*}6M4$FxrV30_G;C1x4Q#4pX1Er`dp;5Re}@6#O6w)FqQD@~x8RVWR=0^`eSm8hEV +z2iYQ7nw?tK|4*-B0%X>q6#UvkCEyy6Cv$yDvstV4yW%xk5a~@Q3IDB7)uEQm;zi9G +z?PI?WUgL#)dK*f>Z@@USjtRILG@vo~x@MX7n4j!5SuoN&Q7nFIp%QUbXhI|KJT3Fl|e} +z<=!iW7xWnvf<2pdvs6* +zpIyR5`VJb1zbOTE{`tea;HI>DR~= +z^I)V|$5aeqHQWa`qI+wb58CW=N!UieLoQgbP-z&z8n`F6rn_l1gUz7?)-equPzQI!UFcTYdjku69tulo9@%3(Q8vG~ +zV{ed-Wl#^d#l7gJ+Cu|t`92fo(|Xhg8x%?c4X`z~r|WB%4eaLoO8A4$MmE?8hFjDU +zL1Ww$JJYqaqXrK2eJ4zz^HEQ1vQQbg7&OHV@c_E2Hh5sV?-yYlU5vWpY%r{>mJP_j +zMW8vZi+yQM+h^c>-ygyV8lx^aN1+NqOI#BVrd8TT1NZpqgmhYkJKLYg`qF +z(@4O+H+*x1M4G`Ja307s>zIl2L0eoA51|W%&%U313xy$cMKUw_3Y7;sUKJ +z?2CkOx+-o>I+)iQMn=#Ht8hB46ZZHv8mQ6^rfcGsxRCr^|IWP)8DkDflwvf3{vpiw +z?K6( +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 +zTA(W$W3c|J<`lzarq(_p4 +zT92oa6n&Jukln}APSwH>8M>*gNNOY*dX;tTK<@UYkbHcYyp*W#{o00~F|s>Cp4{xJo*1#1lxu+(+I_R6@T6;ol7vR2@lTCqtpe +zlkB*s{3pAIckQ=5++={NZY2GaX`wdZaU>P)F7G6&Wxw;`vZ08wfeac3J<2+^CmEu# +zB=6l{-b<9G-}7+RXrk;%DoLrvkR-R0e1NF0j@s~A#-EfENjMEBwH!;2?R=7J+Kfk& +zjJAV(n5gTHnusRGPn0W3ON~&dQ6zocM?OZ>4#!3j?TxP}Pm;VE2?toz8cA~1Hu6cL +z{&4IWVPkwu4J0Y9Q5I?o9zn9uJ>;`Q#X9;#I2&)1v~i(4TA_xMlyg`40#PoG@e#hp +zOH?RHmyNMdTk$ZGU+yGdCUf81adJeM@e~zBl4@h2yV@GESnVk@VtZ3$-05kvy)I +z{5Mfe9PA>`8b?vHND^|2LM4)mLd=grrb`Y$RuLyS^VHtC@OJyWwM!2{o^^3&)UrsVwD?Ye$2=1(A(R +zU8n;jX{%JxBsp3v<&*1Bv3-@OcBa-;7D?^ShAw8~+Kr<~CbUp0BGOs=A9?E|6)nJQD4Niun!nQB9l +z%i$!UX^<%H1V7e3B`VUSrf!gw^L*%BHm(vCMzWV$NzI+&gYBnBrI;jmmn5baSg5@? +zlw>b|N(^_J?`6L>YK$odJ|gMsg$flyQkCDO3fvjq%KmWFOcM{ElO*>dg(7$J;EPn5 +zJIm+U-H2Lh`b<*er+=%GH$V9#nY|AOktF0tsTy~Ve{T0SYP0Dzd`}YQi=h)4{r}Wp +zl5u=5)#T3e$Lw;V_M0BVFC?wLM4B;4bricD|KKbj800=Q3J0sEDWzBS494Ij5?IMY3^I8Y7FUkMim0EH)`GCO6{&6VYUpS-u0zDzBM?6y+|7G +zs??FY$EWsr7Tq;_9JHb~%4-$MljQ6!NnN-Hyl0=E(GJ;}us*e(q{9F0SU|okIgC9> +zg6_Q3jeE$q?SrGevq_4RT2oF904u>6sVDcC=lWR1gk?uUYigCe9y;KDrTfIMTJB&q +zI3?L|Px&9V?PHR%17RC#g}lK+9l>s34LC0K;hyuiY@K4pWP8Dm)KYn)Lb-x!8EgT2B^Qo-Ib^#w=3sVflEt5+P)D&7*amh>ZrnS* +zx$VK2^VyA|8#PPbYF4WyS$}Z?+rbWL0QZ51w%20rW?MmTYKFYcLLK|R#_l_=sq6g% +z__M&`>-F>R_v<<5hM3$W=lMLa`ew9|?~4B}dY$-q_~T+Xf59pzbpD9QJiclwxc1UpM=eB>L7el +z*@0H^N%%w2{Ne(o8K;$JV0X5_TtN8}^}@qHJM@Tdl+J8$6tY;!`kJ^kc%g +zXw(He%Ky`sKf +zP*;$WAA^J0?#(8p5JO*7DC#ZjcdK9y6Yw5+2c_~;a0I(G{_m7-#@gtns1tM){ikZecbIk1Jv5x3 +zilf+{<4q|;j8)J*QAgphhpLSppke%UT!&4I$Ei8SVDwnjPB`MBYN3Z{2tN}?v+d)n +zrcN|s^g`6urApqBEzo;?3VK=}qe1-7xFH)6-#B%y5urDt*1}P!RaQl!r)U5_8#iWA +ze8<#PMhkf_Y9So+P&Lsr)R+GSH)UTn9hAD=s3s~=bLg!~C{yb+bjZIzz4^H~fj!kU +zFZHPLEzye-yi^VJ3iaaW;cwV=O{b;)Wqe93qIls%X)P=4{tTo!yhc6v1-Lc)Q`65?&3KB) +z#4*BYH+2>gQQo0W{8HSRt<>~pDmEP?<-`p@HT!gpR=B>ikTdfhb>NrbZmgxro7Bpt +zog_dU4ZUdYDja=8?f4bAC;PC8DYc$yBMA}L5ze})bCANsqPF~RxHnta1gAAOtt4UM +zT3)I$QlZxTO5C4a)}%^W7t=ygT^uQ#bE|b8a>X>L1-}XpVn;QJO&e^QMWVzJ!uc|) +z2IMq^A{}bZufgB5Nln_N<(MXsdg5xr1($N3IkiG6#Cgc()1w4_EgsG`YSJ%lqG=?F +z5m)h07a$kWfa3XeIE^jeBr9#6DT_1_he7XNJUm{XYdMt(HR0FeELI&iDQ%5u7)caY +z5-xeD3doEa^BZs;dp&Mp+Ab4(uPP1^F1x9VkQ!=5G5kiXWOv4GOgmxfM%syky;Kmg +zqXzsYJer*wcQEaS>3^h?I8eCaR_l^8Ef+=eoAEd{JMMDYOH%^rE-o+p<)H$Qfa>yF +z@FccV+> +z?1gjXS6J +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 +zl0iRNCPAVe+P}#cc35O5W!O(*gP?xU=dE +zvjEZl8773KOn%3y*}s!MHW<`z4GzEeIb=WDt{|M&$Zg<4yg<;Aaql9YyWBGUtU +z45)5ywNi*w)Qj81{84-^sE^X$*J^x1k9MiZPb*4c#S*oF$uHg#)K3}ht2RFOQlTgr +z<~#S|)-n5v=L8K>@ijdPJ`Z(=sVF78mqK5lQzdb$nd8MdL4%aZzE6yA>5*Sh +zG^pR1i^V;HhA1cd-ZZ|aM|i2>FvGexx170E92+!Lxytu~k)@TOdcaA>&ns4fS}@LANomQ(fN<}s?`M}f&omG2g# +znU;h4&TYkE1cRExn2V1ErYae~HAXv~=b +z18O>h4O0U%lx_Xy7%9f7dcvtl5jcTJp^x%=Q2n?mOt2v(FjG0yZ?aLs<0t+!&^@pV^t;{ +zYW4oKVp)~Oq!=a!D3z`J>l-7OH25~EH=KWU?yE!%f?9*PWG2t>J*dI{5yq%5Dt}PJ +zn6ZYo0V9-S{X>m)nN+CNr%bIXXb|xi4dwoX}{YM@IEVCEWR0V9vwFZ*%q9I&gX1U>G`H{+N{x(A#lkBAifEvmrF@G3tlpm%1 +z;IB2rGsC~4dNBEhy`UuJ|1~rR6)5UgX2q(IMH?Xcp6kl&H!K4cQU0l+CG&%q>hDtD +XGA9hV&;y&b_SDdiu8*X%@k4PLJ;QHQ9ErfMm1J|w~a{Vb{;bp_Q&r{F)g +zEd1xUhX0=PI3E0W)`0)+qVUh)LeJoz=Q8|r-GP594LjhURe*nH7XI0TE%3jF{5$_e +zcQQzq-=yyx>va(yJ{e>scFWK*e6f&dSg6!@@ +za7t?VM?qyL(`)et&8K^#rGV`Gx~pNGT`H_;4$@3RH=cgMek&xm>C(tQ2^u@a($Sh< +z_XTNY%{WZKNmsic*E7Ibzhz0SyT&%9uR^hSqQ+6TfC`*@4{#C&2G}^99{+4dQd+f~U%I-3%OHKrzPA7A> +zSY4y7#A86WKu97ZQzt0t<=+IvO{X{DO;&b>P9)9rXBV@&1?G9z51+*KP^gZDt>V*- +zrk}813yDE@1Dbg+LR2!yiv^0CL3F=EGbw0ha-8SAbZLUlyN{P$RJwvF4c0ZE?r-f+ +zJc@qIekFV+V~<~#QC=d@pxX%9`E;+eWFflK*q2=^{8i9t9{su#LD?BPY}1XTAF=a= +zM3&B_WRjN(3^$YBgf~a3y9Qe&CUix}O{^F)c4i>Ecj;E(k@Q2*C6sl~b!g`O2t)U~ +z;NWJxL)S1Gbb8P|Q-nKSRJyv>+_@=xc7JKh@d)|>`z7c!Qzt2z^5 +z%x%rxH53lIHsluF51+t(-EhiH6+&sDnH+4D-&8|4oW9S_6B1ZDS;+!Aj+;Yo!COc( +zk@iwc3Od2unW4IKwp;Xvo4bF?&aS&eP6WRW>3-cZJdD1_&K2Uzs^=Os^Ff5HWR;f* +zPE+>>?95M5Hx#m4t^I+&pzpGCgn05BQ|DH)$;&}Em)?rEYN5K>RDCMEvrC7K>;k$w +z>}(-!kZy&*bMtJv7g`dWi!^gK)gUZ&b>OaIG_x>DhbdFHO8XrTrSGt_K=;~n6`J`l +z!lPuD{}cr7OM07?onJSUid+}hdU}oCxhsQxTjdh+={%;+NwPC^L+IP=Od*b?Q##G=*iQ3v_+#sy;jOPYDnn!8}#V*ELMot-K~$S=(7yh?8QZ^6wipm#!c@6wfn=Ern)Z|gEZc06h3 +zpW0$PkiKT>E<-aPN5oR{$ZG@-w~*e2cbK|o+Gmk8GbVKl&AEHG?l(MuzRFG!6#2Qw +zugeQM#irBMf7TT-U(ftFCqnSfOn@%p$aM-;1ZBXCncWKQSI}KyCkr0=nW>Adl(v}5UQ(AUW<;->`K9TXEd`mGPcT0xT`2sK=+HfLi+{x1KmVHmY)*c +zlZZH=TQ7LIZ|OatTTXOOZMufk4b&K&{SP`O +zXXp|}p=*ify-!p&I~luuZy7Ux@Fo=xHo;C9V>`7 +zU152%5SROb-j8>aW@_paqT|TU49+ebb*wpe%d{VHFZvuiMiAsjo(s^-rxEd$!txd& +z9`|D;x*_lc6#csE*w`xXn_Xti>Z0}qY?VJi*ONZWjuv?NA<;dHNT3vvw+ivOpXdX4 +zkCj~loDFf5Pj?eFv36#3WEZ)vE%rCF778@8IP&X$2Hg+12YrSe6{IUFZxa%jx)pFD +zsOn?wZQbYOG!I7|N3t_?--GTn=$!Hc&v|I(vxtOBF?qX?ko%cF2-&?`R{}?`t}5L3 +ziXq=t@nzQsAH$*9`E|d8t~-5-9Vu|8?m6g+6WuTLA-p$A-8pPz7pg0U(x4B&GXu@^ +z>n_1P)2}-Uy7T6F=cS6HEI6S14tE3H2!WOFlkA>HBm&(IArbd$kS;#Xidfs+1?%FN +zCqm5YN)Vk3w#v`y@7i~`D}9n3E;!_So^#O5=MkSNCFGsLXWVb}VZ6`G?vWPIHKL5I +z@-E$T>oX4@=Dd5K>}rv_ikC8UPTi+ls(lN(6YMZc_X2b!Moe!6c$ni`Eek +zc82a7+=)KQ4iP9*_c9_0==KW9xTWu@`x5S%!CU3S&E3D%#i9%yuS>91e7cVG5q7YE +zmk~*oGV(qlIrlq#EF?Pz*_ol)g_|y$rCY2m#2x9w>>vS4w>@W|nTD>cykAHG +zy5sl&Y36J7p%xdKY1f^%&bx5Xog>X0Ng3JMbqjC@`Vjj$=x&+1WJ)>tfRK{=!=`%x +zy3AptONcJvz*aeeYodUz6zBxAnTxdrxIKN49SHx%O`>}hkxVHs9~4q?%jgsMptcfr +z=4;ij8w}3~zGm99J7b%>v~XAXxN}z=y<3;v(*34=joT5O2D;PG%vTY~P2KV!T^y2~ +zT{p*n7R~71^JMWnp;7iv}G5pYX+bH3?E$$Xl6~g +zs~B@v3K`k?biZm}fo?zBUw9*3C%V@WDU^!xVId9ZPT@n)%+J+V>U}K^&V(4s$gVMU +z8-=SbHdPvQqNSUU+tB;ienfW)n)x~+rBX>gBBbU1{3LX}@ev%z&d}u`x?#}FU$yzT +zHNBVZE4-GjdHlM{@=+ljw~{`M4_n#A4%6&>y0d08gLS`XU*cBu9=4D0%GAAyNTpPf +zj|u6yRYbRnH1nPom97Pjo~5tOX;fTBsB9) +zL~76-7cy|G=`)aBK$kIS?k<>HCERpnP);1s&BHC}U2HGmg>=QzRh3T&89{dzAF*_? +zaJcE(kynj+zdG%hJ76?`ejPw(ZQA +z$gVI7G;eJ#Y3QoUr-aPh-}E_rlw|i(y&I&vgPOyq?0n~4 +zbT%_8U3DuvpH3ok_k;SAHU~EYU3cM`bjj4ERcgqmg)H0}`n*l&#Tl&Z!dsUMOS%WP +zieI-KbWcs47Lm@>ttGnEurrP9qSnoWn^m6W;Y0KVofN2Gs8_ciZXP$gLIAQEo>Lzk#xb# +zF1=D)J||@7*3%d9agv>(i@@m-McH+Oaro)t+H~KmKWZ~^BYHF28Fc48$Do;dLBEnP;?T@Z3|8*RGV +zR(5kpGh4uCDxynw2^+8YMZHxH;c6&Y=hpqY8Mq<6k?klvkj|OeWmM|Q7lmA)yNpkm +z&AhECW-|@lT@<;lI=qAN;dkb{b-i$?E)NdqrsD?m2DXE6UpnhK3eCh3nUs3+B_TJr +ziM|55zu-i8t{S>@WbQsC-S^sbT%TUgwioW%boJ%SLLP22=uU>EE)hH<_-eduScW~G6AMaau-p|4uHTO>OKJ2M=zds}zf+A8HyUhFY- +z-+`_ky^d`w+%SBY8|j|$dJ#dYbmY#ZT@bed#m=o-q` +zgnXd8hEJKzyrp??+Az{x32EkORGpj%cHMXCciL23hh77^+tMk|VQ41uW>p%2EA%_5!Yxxr +zfv&N9T`0h92iPP(ILk +zVXGLr$)Nj-Z6(~4PLk{>Z#Jcgd_yS6?VxW&s%uK!L*b-5h~K5FMXzRCg6@Rp5HyqW +zW(VC(p%Ax|z8R!TgD^67=KJVw!e7%zS9VeB7HN}kO?nmELbzemHI;7(g^BJAG;<&{ +z^9D52(0y*x4I#Ja=6Ejl-!lWvj7moZeO~dOKfxIF+y$Cx=uVkiB|cRV<;M|bGYwr0 +zdL`RjxGo(h+0ot{N;CPkP=wn>-@*Z%9HY7?aL)|hD&OMv@T!q9ckj|o#MS9P*=E8u +z&>e(k8oK849ib?<8+2z$c26O@PfHgIw#v8aH`)ZEYbsooj)86(=yED8oe2N6neUg~Xv)`2uO84>B?wpyO +zPp4a3r4`&`!$a2-=FZSngS$#(x+?TCwvljII^yx^ax1Om2SN#MAAJ``uDg%ILsuHM +zO0X_LNOt3J75Wdhp>Rn$Omq%!ZlyKoN^<+@d-y!b?ulw-mkRl_3oqRPTXu%7AdaQS +zCR=5JHWpW=e+S(~(Cvq2I=p$5Hu6KE6nDU;yQaC`OIIA8&5fIw@4Wjsb5{Z-LRYYH +zBKWd1bSKSb26Q7}XBxUn^isBga6vj`(>)SOa|h}Bklk9?nNL)^t{D||cEwS;7}ixb +zvm2o<0^Jx~kzT^qx9RdKZRN*88SW71E_~9uuR&LVUd+}L&PxY9`=FVuH=oi@ej=0w +z-2+Q^RTFVaq>-IzWY;>1of%!(T@7kxWm_{Vqe3_~%$U3>Yd +zP>wrHKg1VFc8}FhO&7=1jl$(YS4TJty1gX3{7MJ;nNXfP5{Ygg+@k&24Yh93fzv$t +zvir`qRRY;1q^gkYe7di+QMeraD_dJQBkd!QJO9(G{TZPI3T|ewt}4kc +zE^L)=)cM*7T$=uotuCCD_L#atN*B;o=1y3;N9q-ghi1O7?!^bVtNeFe5gb?d>Auv4 +z<5KhwY&GEo=ysFr4Bcy?3U`uzYG(IHy$rhKHeDOCRVu)Hug&q>*+r+W2i}h>SO8W_L-8O4kgU8GgEWWUCmu +z;-IT69F=yOx}r)CSr=+>XXqEE?xAYvlA$+bXZo_c3a7a-cj2Ks4kv;=yLj42*qQUR +zp|}{mh^-_XF?E91&|#q_clKZCyg?^I^f%M4D+bN<>E>!fK=%z>Q8+B^@a%+U3f^K$ +zPZ^1|xO4PNe2p~I$c}qwcG06NL_R0x-zxsO+Xp){po3SgaD1X$s2aMW^g_0Ra7fy2 +z>3YeOSliTXfSvhJy%?fv3pc$lY|V^WT}9AUAn6*`E +zpc0T>0x9H&P{)=t^=;pE|LAQzMB%s57;GI1fFGEhg-gHV~cc +zEvpQYU1C$ByKQE7E-1UlA5x4be`c8e{z+ca(I&XVi` +zy7up_Q=?(-%A?Ti53@=?rc-6>v +zBG`4cQE6zVT{o32AZ)SehRKT9in~K}n_;WmQw?1rQ`Zuj84lS+txIg`rfI!!c6th% +zU)U_I@oa)-db|~tVRD4nn!8IoAUmJ#Oq9B&a1%R$BW$m$1fK{WrUm*s}ZBx@+Xqr%y1C0{6_sF!et~s!K}M +zMrCkf{WCIm)3lyAD?N$LCv1`ex)E|Lu`PF>WHcq=QTb+Ar^&}M#IT^0D7<@eQnrB2nlqq@hq}c3YzcVMYpaS-h;~_do#%cvtc~f`i6VoNt6T?<9blq@9dMuk0bSsH2!dq1t +zBgYdva*soF3D9%cDlwfMJmCawmC)?!qOv$tmqSC!l0hT~vw?qMquFf2-28BgdoNuH^s!F_ +zdo%sIve3+m&`h7Mys4Y7`g9|LbTyTUa$>PN_kxztW0IX;_l#^6Uv@Vm%`SR$Nz8j@ +zRJ!COyZP!wtrJc|4`(wAtE6R~wb0C1UPG5e>;XFY|A8(wJ&esHtd#yRb+wd9a#FD; +z_Y!nZ%?F^3{_JkxAL02fFn5Q{t>Vkhu1iS|Wz!4GrKLm{8+23UbR_BaJSgiS|ue?xY$y>&pBLhJ)Nh3NXLx76d>8$B+1YVOQus8dLG3fxtq +zJG;nr4Nyhw&u+Zd9w(;nStj)M9^5r@iR8w%yF`HECu*cMJPv3T23|(uIonO}kho3GLG}EVR +zgOkt$*p$K&OIKf+DW??&f-aVsonQCF)IEo-5?;E4$e&$9$j+`yO!p_cUp=d#nQ^`K +zm05B+@pBF_vC#|C%zx4y`=6Q__*HQK@0KcJAqd0_f1nFM> +zi)O~Gu8Nu6Jk_V`%_b3k2Hi?%W;|~rWuBZ#916O4=oM+^4fTljQjdimTRXEex^13! +z#)%L*cQK_KPZ`-&!D;jquvH9Q3!H%N#U=*bkEX7%@}-F#Vo;Roq^Q`Z!9*~AeX54tx*cU?UUIxozfp=(3=bR)?v`t7;< +z_`0O<{1v$_6=YWxr#0tpl-3M%-Pi=e_tJMnm%!Up`C85{js#u8Pe9iN@5H67?EJcv +z+E~~sqqL?t4(Q?w-+^ugG&6y>nX*96A&%k%CXr3|9I|^9?b+SK#!W1=nSty|;(%@{ +z%v~y~391I!`E(;e7n|YNKMs{!O +z(vj@^y3TA|VUe_m=n{hN8={k##7HB$YoL1;qPv4f;!5xiR}*aLJSb*$`{6_gWS34) +z1#>r79icVGUb+(-NBBni#?-Y?7RkBAv78*G?j@WE;j62T?YaoMBO6;-2)bp^%!J;S +z%C~YJaUAH9SlJyU**!G3%1hKWNOv?^vnz#sTgBc?e|D*kjZ)MjAD|81omasrt +zXz9L_^NQm+H@&M!{n6ebzM+NY^YO}5H# +ztpRp}P7%J6zBYBOl^^5+;v_D@(p^;#d@|WJLp5*)-KQG{I+ +zl^^AT;$+YzM@ToaGjvaM56oR}xM#Md>|3QVoCx-<68&?x9oy$Fpqrx()9Qn+4eJ)Z +zv~+EhpX5T~6wb?}2+=*T>F(lDHt +zY`XmW0EomxeNQ8TB;UICYNtg;o!{=vJ&G%$2_MEG5lstNaYQX?TlYsOCYsx>%%J+H{G%?UY~SBI0x|4wK5Jd#t-r_+)nr+jS*^ +zbhT{R)x`qcf^`XVq+P~A?BHy2R8~?Ab_(k@NV4UUw +zU1z)$Mct=8(&bM?SKHDJ0UZZAr!YgBZR$EIOXQN`Y%T$l_Pun| +zBRS2ZJG;Hemt9(_1*(lRlk8@zL$q3;Yr=9tx}|a{aSoS|NrxOHyUXfc?V&BZ*Qh(X +zXPxHJuS;fbm9p?`-WhL$trC^4CT8izEGtZxW_f;#nB-0B?W8P~ON(>=h3<&$`ObF} +z`?%TpbX~AtS3F2p$I5Q7RuenuMyx}aX4CyHml5Z2iJ0_=wPh!vd#D%OGuu(2*@cs? +zB{FpBV5`hl2WvGjLpNj@VX8FK^DD`&v+{>rR{WCtjOg~kR`E46R5#kZXHJLTXmeYy +ztHgA6hAvBxt^rF6Q=}P|ZW-w2bBUP@keyGrM|+^ZkFF&8SUS#nXSo!5S2O*(@sQmh +ztvaUZ`Ya_(Hg(CoU6kc=Iq@ql36l|VpP;TT$j5W1bnB9tpLvL^nTBo(+{EmpJ0JU29YiXCrerOC6|H!5USIRrztC`-x=NU0Eep5f^bOnXHy>mv&DN +zC*5uQZe0f0Du%8yR;ilo8_-QAx)k0X%4)f)_$|>1q?s4hf7a!Pcep;p+`TKi0_2la +zMs`u@(o?NbeaOzPtHHkJ$4Zkd-CuGw@jEURlMMyy?u2ZW%J3dgBka4YgoAD(<P6OMbL8(bV+Mfa(`AIMGE?oZRUo?O +z{79mk2)f?NTDhk96PFHjF4D{ks-fepW*WK&IG{TW&j^9+6!^T#e}BIFFI%N3+KueG +z9C}7=f~k8+RbiijZaie?)2)+h5nWE3?oQb1w&19A{j~D<1yvbzBcySj?}@IDvR-Ikav@1S2wUZXx^T`I4k +zt0VrxW%y)uIrU7Wnfz>({2{fGAvBHx+s +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 +zmK7hRQn9=F#!@HGbdsG&}K%zt{rKnUw4E` +z$?oDCNgatUn|F$GSso%D<*Ehg&IM&R0Cr|f>B_+OV%xJ@kMpA~w(Q#BVtO9Ur^|wm +zP$}4*d_zk&Rkb#8EZVrz>tYvz?X+9|YZYqMHiYW%o`~uF1p2lUz-vHcFwN +zhOKg3{aXuXT|R5>{JOkk?%EPvQg$0(Pip7!>82~!5{iU7JU&Gw_bc{K7c3ocbs!=KQ +z@lS-en;ER@5Tx5rC1$tqbwD>IVk|UshH_ILC7$8xFmv2A`**p=lQ$0}!T*Az*jg|rLqdsFd^R=ZmM3;l;MvG^;x=cNkNqyNRzQwf0Pg>~eT#D!1g(;<+H*YSPU2)xEYpIs6#^ +z?{}4VXBVu?0oiqg?DAu(%qKFfUX`>-^}iqx>`G}zruFib2!bTYG(B6 +z){$oVvdcmB0$oW{*IG-D_fQGg4SY?hm6_cv<&Hd7JkQl<8lcpqnZdd)6hjR}&+){t +z(dC7?i(Hou@229j>-ic|OV1=|W=`*H(2Wx>a1Fv(cOUz=N;|v`N3BasbnE!)Hr-u$ +zym*mo$TUQ0^s}&4j;X7(Q~FDMfozp<$j;F9AkXG@-4x1bW+!N7elmBhw6u5^6^~uZ +zSCd+JCX(#tDEH(E;w7#T(|cCksi~=(r#zIWh}XELpi8Hp +zgROE@_36&rbT6zEA?C8P>xz(O=A`;ScBSrfK-T+-Ql-|tlPwfOWGqUW$PuGQH=hLMGox-lIK*v&pkbmyNBfE{ZW_H14^nyg! +zTuXsBQyz8&UruUdX7`oyRGuN;;#x8-KzAOtO60mp&$VS*gYE)smBZ?C?Nic~Gj&ZhLnnZ)q*Tu{8k(8cyHI%rx(8f4rVYw$(>=v! +zt?UNF_i)5yGap!6r7d2Ajb_@jGj!9{iE2|V30?=fC7`Qo)6Ekfa_xh3NA-Y?qkOt* +zkCB>=NTOl#~69FD}&~x_qE}BhMEfgRULuE|R%h +zriGubCppc7v&#+d3I}vew9i1tvA^=gq}rx#k)q09iBGtWpv!90J+bC4xS132J}lT? +zd5Es;-cR>8#j?NfML{i!sXL@D(~jujtILJ_b7y1+H#D=EO|(S# +zFUrCG%omYrSvpN#AU@?fGaW*7XUv^xWcLc*FZXSg;OsJ^kC|O1_^tr|RtaPms;i(E +zA#>LlbgLAiUx@@GGhtxkHyT{n4>qc?ZkhgSs%=ds| +zQa6>#4ew6%zyV!C(9!IVK{_mdBR=Q4G95v83AT!%I~>-!^{5bhduC+1RTRbkz!#Eg +znAv@=V0n@F0(6~F_7Gi1xQTV6oKa?18bw!jzhiqd{klAmT~A!mY-S@Z0bU8Z@A-mK +zb0XDNcfJ!L +zvaLeHceM)eZLRJM#m +zHx!-&e5ZLmcum^4iG3{Hb$I3B-|LEzxoe;qx;Ku6d>*MX$@R>kYbGW;2&+ +zhVGQLRl-fT&OGn(!h3JMab?}Fi-Z55UON`>xur^;q0r2N-k%lD{WIwLFx^ev0X5uo +z4{>la*P(*sG=E$7JLtaVb6L7yK=+G?xxP#flv}?7TjhYdBq%$cGP0XO?wLk2_eOIw +zQ^U6^y^pTG78@_6UOB$vb4nFGLr8YNC{EBJXTKob0sVp1%<$Irv6|`Ay>!gyb4V44 +zu8{Xvg?IldQqKNNPn5^X&Zp}@Zeqc@2{D}AUpNN}G;^7a?{!OGo*DFMK5*fPg)Tf}E33nAkx0rhFmni$1j<2E?*>}IOt)q0v2|3*D?%;mF5o4T>1)E$m&axZF!c*7-Tp +z=abXrgZJJHT?tF~EA<3)S){U-PICV)a?U}Z%SW1NWVbKIvr7zrjbq$1%OWGYKX7E( +z<%8Em0=l}If`6eNJ7)8lr81^&i6XiG5S`A!OkYd)TaZqmLgy|zn)$Y_f;D$*Q2}zA +z8@hg0c82a}(9PmAf$nqC%q5EKUMBLO>xc5|*I=vcR}I}ge8SwBeqD8VExI0j)^9Hk +zFI_dWnRPV}=pH#{g03{t74a@r-0tO~;2iSF=(3~W?5gP{$=uZe-A~j*#|%EBRLV0D +zvNLoZq8rNeM+HcB`yji$LD>x>Cqg)6*BY&s#=~o3`QY`e{(sE)t%0p#=<-{-S#X-y)@0D#b4=yaNhOG` +zsP_*g!o5`G~~)NzoVgukQiI41LHq~f0b5hJ`sy~~tX?$x5(IU+=N +z$IPw=CBodvF^Iy+mJj|3-J)F_BLVx_%_PBAp3b2+{|p~Z!^0B +za03qLYH9*rNZoLZ=Tm^LFEq25_fN&p#RA<>n{HQ#PP5Lt=*cc>-75TU-F3$}KDkub +z(#3PH6JtBag085QT~xZd@O=-#&5Q;27~>Nim*KC0jL+77n7hh<)A4u#b72H?`}n#v@U6MaaBu88 +z5kj;39M^)mn+@k(4UNZNQ&$~hKv&SxC2(&L<2c7N!%#7z+oKw~TQGM%oeQ=~c_ +zhC?$~DGA-1#CXn$%y3lP$}U(pBFgNtppVzg_tOo+wM|`hjl=V)%Z`zJVktk-mGG`s +z61g{v@j*8Nbhlvc_NYH<;jQ}%^cU|q0Tvm@(H9oo*s~0N$(mZse8Ma*g1_E4Z7Q~RYG-ANHcfiz-b=+&5TS} +zj?7(Ejlr|2v!IJF<+gOm+&jc1&gsk;R4PQ*7VauNDTx{xGXrFQ?6ctx{E^iEaoV&(f_`lDT(^N#8?P!@P-wlWs(aZWeXM +zF_@1ls)X1l=%iDepQZg?l&XW-{YIcL(Nfm-;T`!-vio?tm+(0;-)a8O*#&e%aXq~}nY$_) +z0^Lc+K+xqdb?cRs?!96P=WJ%YO}90qneV52^q-&ajAs59-AELyn@*i@4B%r)*)3fv +z_dYSDa}G1X(tW3G)vpE3T}eI1<0GVOmM)EZznI!Nmzjvl>UYUj2`61S +zlm@=xKaky@I5V866NFRw^hJzYq48tZ +z&W^KQd9dGAZo+rk{MXl2qMkdyt`B+Tp%pfCt4K4a!-+5w`E+wZS4q?KDb!I%AKoKn +zv20p)zDo9T^qQo^rGHwre9YE#jLI{%uKLuGIhk!n|Fh*Gs$j~lFofd +zOy``>Oh)BNcHye42=5~VXJ_b!;Reu5Uv{cKnL6y~1-i_j`@&nsyGcp!J}jnpe#J}y +z-94B)L$?{SJ7~)eA^Uk39ocT&7eCX +zW+1u>rf$(c>T;2HNj_#X1G=*6RCrap1cIQP9(c6N(T2)F{ATq +zW-7Alu7qSa!**BUP`KzuLo*xd{_Ni96Q~1@9=uD+Xz4P#kAZFhGYwU=WoOrohMR;> +zR|mdpe;53Mbxi6q!Orw&HyRDM>0X0wzoR=ZN*O#IA-l5Ptx6`)WpXaGbUV~V+9o}q +zb5oy&u7dVj9}l{2ybz>2E@pOq!%T-$K1Wxcm(qJWknFZ8ncXMEEY3yD3{)vdcfj14F|T_9cNPCuS%EVlyKV$-M0BH7 +zLpPS%>*xZybe1lQ`=ppPM7I&L`xJCzkWV*H9j%tvUV?6qqciWcbla7z?o(nm=eNvE +zRN2bTr)y2_D#6)}je)HaS$1RLyemQl>t5(%sNIfEJSU~~w2v6-E$20Kr^W2f@0eMj +zdqC!Hp|(-K1la|2l(jR%PuEzltogEgp^v6^IXd#Jl*ZKUP_ntth&i0!gRTnEZC4j+ +z8-jFW;MdUnCqm5VR)ox5ZpxqCNbJ{@)1K?2sGW`uyaROYNOn7v?C!H-PUjEI>=504 +zl3j1g4f#i=GyW#kcZZwczh7Y2WrVHb*NsJ?x*d-8JR_wx +zbvuzwM6W{T&d`mZwi8`SQ@0Cr=fynEpP0F* +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 +zre-6*AB +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 +zD`TmaU2=H$Msmk3~ +zDKC~9k$pmP{v(>jbUWOGJZ4>Tm?~d~ZWB#{D}rt;IVPop?Ao}T@)D^r*)OCBrQ4xT +zm0;GbM{0K6S>Gjt_ctWQ75IC?7^dqCIvI3L$N?cG??$uzvh(Q{2W@s{T~c@lKw?~; +zzYDsfQd(KlEtQ&*gF-6a1G-qycWPzMrUw*FHw-6-CpKciJw1`X&HruR)xhh~R%N`N +zovKR&x;w&Xazxj;Trt`2PTPwN!ZmG=L32K0Hl_-F;vrb?i015Jp_ +z@wbIhpi9HDbIHr4=H#%Dny2V%(5-=K>eFpt+4b;jhJBY5-T{yhm*xKuMv}u!*VYva +zbS=mcAq}sfximJb%z>U+P?_6NV0OjXaptjr^Sh|YZWuc^Z={6QO`w`C2|Q_?0GHu^ +z7eJhe9wn>(g=h7OUv%hFvu$1jZ$R4=vo1a^ +z&HpA0CkJ(1YBk{lD#!Of!cSa#dp13pt%0p3j&6*@N@i49Y#!!KOk>_Y2?xRb!s +zy76%-{#Rib=u*j@AiLP|DybDYE~MviIJy*g34Fy|otbKO!$^bR8X5-|=YJ9glYLSO$WGI>Bd3H+Ja5v?fXdv4YO`&wWw(m; +zUG*^gF7hk$sA;MM>L$@%o-NRKiQrk}*ti(z29dpnZmrawoE9>JZXu1!`mVoc2HoqY +zivxG)s#7KSbUPHEZZ(aCi}F7T1IZpKx!e)5izly>I*>C$7T%)kwzx7Dc3rSR6URZ6hx +zCL5Kxin?%N{(GT6*{x?6UtTYDBO{_iPQZ(4Jm@<$yXkb#SEAdg_;f3&6LjB!Zl|tG +zAa9g9lM6z2UJO$=90y-^%S?S2s4K|d5c+~HDa%gPbs-mp9DGc?1hN|f+4c2IGqMXl +zU0meV)xw+6PGt&I=2qAU3E}A_2QI*WEA$~dK-U2(Goidm>PjvNIRkXNl`U+l1iNk* +z==v~S0?yUWP7_yhZ9xt_Zn#V$w~e!KNF|&VbaJ8K|3TWVf7# +z;Jo}bp(oiUC5G%exV*YNpj)PA*T>_pTL#a}uQvAGQN^vFy;gv$;Zc>Hzb+-zls7xC +zE;t3nU5Ro5k!w@N+8RUr>=_tWiCHXD^0yt*xDw_?^2&|ML_lPyvrmR(|b +zo79tB6Y}yQcsWhL`cBQxr%MIT@I`NS9@ysI>{dZ#E=At#G+kddRpP@FFa+l|bnT%s +zlgQhpUgR4gA1|47Q^M5^gMU&~S7yYzY1F5);avP>p&QvOC6v9o-sHNFA9O2>?7X^p +zP~ZO9MV&6E{tH)Dc-!1DQ+9ET>}q2*J5{$0_FX)9iXtY?$zKw>l1;iUsk}q#L%tOX +z@D9)=WR=<5GllMCeHZMyt!PhxE(d>6=t4G12_UJJ4(Jj? +z-)(mH^h~7T>yE&&N_1pb18S#%vQqKs>fmi?pE46F)2rifM*gJG*3hMt_e(>_&q4{% +ztqn)F0?q_{l^J}x0lIEJje#?Ot_@i&#gW@WWvaTNx=`f8vI&uMEMxWQ^lKId3H~`wh68}3Y0P+I<|(1NUx +zVnKGQ?vONs{4SK?6Zq-28kL#G)OS&@tBkV2)0xNMer#`cv5+~t15lX*Jv(3{Xu34~ +z5zsByb!p_o(n#`$P?k@KH_)VdcH?Pyx}i~=ou)g^bj8?4Fza@p1Ilb&7YpugqbN0h +zSZEG9m)r)jOCukVMv>b>IYYO}-QA<=*6UM6%Wf?@R;dQ}Nk(mD{yUuqrQ#0>&B!uc +zmlkxR$sM6Qp9pVc*@f1vgg0hHt&XypsrFq&y1H1)ZV;=?Sa64wsyiq&B}*llWtUby +zDvcp`L6_L18%MW5cGcOwO9Rh62aj%rqE+TlI7d)*2bDQg)44$BMk)CNLKCt?*QJw> +zf$pAA0d$*aGUz)syWrL>f{hTCZWjHBQt2~^Mr|OdP`-DbhG3Z)@F1>tQ8V9;cd{PYe6|?MuUzbeJPSXwcz1w0VU)2 +z3Ju93$)W2`NaM)^p)#M$q#H{&E1#PkLSOoK^QUm1oq8k|)>K)cxX>cx(;ZUgQcWj= +z?mbHCr^_IplqQgeLKV=#{rq}%KHW&1_7hVjcyu%9KPU;mM`%D6N)pRX)lDRigsOaU +zUANKQ)#I;QclQ{rvZUsnybxi`CY@b-`B +z*VR|lsj^U?DuKFbpi9W_5bBV5l3iAHndCFl6!KK4!KX5GUG&QQ`gDJz1pIcPHkoVa +z&Pr3sGodD*8gJLL>*5(rH$vZqugh#)t&Q5LQeRmfklhhwJ{{`W1%2m)Umf3|`204Z +z7MUXvmR)A~oHUI*7iuwGO4fIpZcR|>M#A}BF?c$4xgtYlCS}{a9^Q?7ItS=pqj>z* +z0Nr%*La5EB!8>T!y45f<&3*SliR$c5!22aWt((GhTZEcqwq%3sy1BB*=cO6sCFs)X +zx()8mo>5Sl-t5xh=+-Ilmap)23-ro#z^{(4P+WeqP=m|@T}!6BAk8Fy33WiX6S5oT +z)^r>Ebcu}YhQLNpv(vutoE!FhH3dk{Oc7vdbo4l4g_FLVZ4iq3h%s +zN!Kf1hwhl7>UP6MP<1bmi{BtrA=3@rWoZt1BQyZrZkn1^W>~uQ`msvn_1&kkt7&Wm +zZ)K|4sk-61ZX)Ppe!Wl`bb{Ohrb>4CvNV_cEi~ja{%c)Dc$fN@n<}5HbD{+(3F|w5 +zT?qVg^&E8Tgi2%@({%^k6=@!MD>ULW;XOunBaF%%h10=XOcKGnpS0slb9Rxd%VC_o +zYE#9VomsaRvRkBQ7XrTzJVQ=?E$F67R>)4(U6tmOcP8C>cSp|%x=vZerb=ktA!8#% +zjV?RfBdP8?O}9+(*B$rMJw*^<4+gaH{F%eigcrMs|-8;g<_#OuBESCB!4N;Io@_!~Aq>*;Hu)R~~{PI|uU5 +zZVA2lx$Ms~yK8djNFcG0gp3155hZUj}Am~C^l +zGEXZ0x|sY@(2Y0gmJuqnYJbqEYvWop@l*6oFjV1sL2_mP!f +zER-N)CCswRD}N6i-h824Ab>=sk)UU +zhS-+R4Z8H6;m~(#WvaT$VN_=D=oYZbH0wsud&t5s6pDckL3XO{2Wb`I#CCihd|21D +z^9=FRtuysqSi0x>^XC8UR}%j-Aamb^o!tW55c=+vvW$-Q>~#->${a=SBA#C$6eXi| +zT|W6oX*J=+_I%y|-Et$l(7H_e*GjeXyQtMkdS$A*114QexT0_uar}It2pJ_Q&Zdx^ +zs#`-WOn1bT-6|!Rb%|hRYP!=#cB<|Uiowql3X_q#F2DSfw3b-K4tzd*gl2%gTkCG; +z8BG0kNsWy#7``L;UWu&i9vRof!mmsT%|&M2a=kKR!ddBUg!#ElM_G3H<)5W>L=Zdj +z`SDR**Vd#P4f}2#3U1vP&pzloO^5h7LLo9j(sTvnU!?U!6gvgzRw~O_-;Kr@nQo)L +z&4VqwGs<$R=|nj8{{ta@wos4^mpqVNFPEl^DR$-y;A1o+t4uY!uS0hbol#bpbiX5o +zn{=fCD?btot?jK82uelZl;hQbZ%YutF)2W#IAfH +zd|c12jmKZN9{MggD^t^rWql{YvHx$#1G;=g2f~H$((%nKIx#>b4GFaCYmVcMFkPxvuUqsifafj9= +z3%4>OCp!;3|LMD~g5Zc`G&_5(r)au_co1y!M)(k9=hF?Lx6lV}8q;bxyEW0)C){xzDzwA_9Q+DMca3g#foq+r+^WW*ldG^D;6X59h7tl==a+5*Q2WMkf +zZ*V-B?+C~Ib{{qbXM47Kcn~D +z6d@NGD7|O8BJyo%8*z%g_+lpA08@6E;9Y?J+4<}6f0!y?UiS|-S;$ES7`i*sb|Qu0bPHl +z%L6R*sO;aU2T^_g#Nu8PAzWe`lF;UnXLDf}(t!}Q&#ZZ}M-34V0o#656Zlc#r +z*T>L309{;h0ACuPqnfUzryup|#$a`32CMD}^67Y(7B|r=Zmf`*^p^f+*_DtVN_$B> +zaUfqNT;0ac(mjBU@ZYlg%Q%YGj#WOLU7+qe^cOcq$i#FFp)yt7J`!IX1iJI4?3U=2 +zIRBoqhpjRc?9`%9O%A9&$*F8deTFB&9W;g|0x|LiNqm%`3QBJ*+%eIW=8#LZDdwv#JYiS +z2GkfI)pZA9BXE$(b#ZsF-e7yDIa3i!%`y6=KZ +z*M#ZTL1p@M&$!`2TGCy5DLcY56JWl8VFmiujVAU2~S*Leo@<{_MuE^E+?fg{6xD|EsT|C)`lbb(Q{N*{QlC +zB$+rO0^KI``8uSZk6IBA=i3PGg3|uLU+RB+e+MJ&NX&bzV%~RgkbmEWuUoHY7sJyV +zbboR~gw%$vjQmVGN|K8s`AYaQ&B6MvIsEq)DQb3e*hbKF&5XW#r(|UB&!~t(PnF2l +zEn+j%o82*VSuyLbqQ~4|ArgTJi3|4 +zUpJZcT?|hzdIfZYgp{N+=<35%DGR#epc}sA8BD*pJburLs#oKqG +zbsOkpkEZJhx`*6AA-PHSQaVXeiDUSx_$m!gm(r-rVAEYu%(_eH0XINMMmkE*S$5^* +zzd)B-9LrbJbt|DV1G7sBUpLYEE;w}Y^nG_6sk$k8c0K4tbf4=lBqbe8x>F>LIF7H5 +zud(b_x|;^*HlyIwHN~oKqpm|9RdMyYliY=`=|zj%T`D(08h?CtaY- +zH~Q{t(RHU6&|R*tki?{WEuA6h#0h*2{0$AQ8;i5R`%{A@yE=+CRkX@fv%AW&I}9@u +zdAif{pz9+fCherBEV~NwYw0XW54xJ6bmd^*MZYd59P_9%vo>65*K{+Gziz5W({%&g +z9j>>Kh_q$8{;mr08|fU$AWj6`b(&kR%pP<;RHmlO8qL|Mx-%wSOr+`tz)^Hld;+rD +zL^Yk_?ncj{+gvXpA!#E$f$aLbD$0LL=SfC!5?{;EHG%&0*QJWandz@vsD!WUO3$J{ +zxSm1+KivhANu12r#^37MX}Wo)?1EQ!&6J(0``1c5kH%B(pe$uY+$e +z-3oW`>*5-fc}>|&r?I|M++FDz^c&Y*h(}uKx=Qjp=_1J@PG!10(08h?JDsQavfF}! +zExWLE)ZK-iX1chbd(5({B>y8_0^KyeF8+>cy2e4M8>`Put?x8lGkg+#!?HU98$s2b +zLcem|gt(-ouB!~X%Oor4>ILZL8hxi`w>69-u}W}$m&mx%u3gXk{PQ~nesc)>?A8A$ +zTAM0n-E`z|ZI +z+1Fq9RzG_U4&4?y-J@mKnVv+ya9xDhq&ev7xCXeY$RDJuB)d2xKsPsNbt3Z5&a3md +zJJA#9XRfml3v>?+-8GU!oXI!9-|N{mg6w>{Y>-`QsLbZ<%ELfqpYm48puf2@Ix5p& +zcU|$<{ls+=T%?(UjcSocf5Dk@S)-6y}T^zQ}n_;i+C~O3ey94Nc;Mxlg(A{^|hN)6b_DJ87 +zJmOrwG5(Qdx7^(@g6x7pH_fE`R@p{pcvPJmbVt$mTsuJ`jSU@@Zjij7YXZ9bP?@T( +zOE{HTSqTg`_vr~05bzOUU1l{D?g07Ktk7ZX~R;2GpK5-uCelqE1L*JEQ`_9~V +z!KG`CPlwWd$F&hcNJFL@=u&kzNq%uY-!woso9V`3O}CA0gy_${KcwoKPbu#x)G9hO~989RO;1;s_6`{k?E9fO&v>JFmoTuUJ)sb}b7IDRCB +z#KnAz0NpIT?;^@BFPtMpM|QFGzB_}yQ+Ci<9!=MV9zfr4Ed&vCxAp8e$4{iNxP)(s +zZ_$EKnakV_Je{C2gHcyoS)d4LDhf;Y!QF=LN7uOKfg%lN+@~!Z%keyjq8ur~d99@-}O~0c< +zo0(qS{4lcf>RQu%=nB^qbhUL|ZQ0_uMT&{b_|_&}N0wc%>ssJ5=%%uh`gD6i*F>;@ +z?st}5ZP^OC;^K0?4gQT5(z8=_Gf`9(V^@Wo&6HjipuF1F2ml^I$$$8#Ju +zf~wntE^&qt0N1J-$+SuCEqq2T@HBHyQ*uUAFD){t`7W;P+OU=1nPEC +zudXHCjV^Kxg&3rU^efZVl|{$zq?EXdZ-@V&g;{0R^K>v}_i5b=cK7L*JywYg?`PNU +z6Z2;0(@oJgf?Ap1EB?9*Tmu37>HZ+4#npU!UANS&>ZTi&`TyyJPu{N*(G@>8e4oRo +zch5Nx#w7>2jcMG};o#*Nch*Xzu>Dk3}+}3rsS$0d^b(wAkD#fOX +zzplR$x-!GcE^2h=Sax$+->JHt=p5)2TQ#N|?5Zc*9Ct_=aSh)A-=;;NGF4rB$S(SI +zW!Zhvxu6Qd%TCqpre0lhrmH7VTUF^7XLXmVBaXYIthko%i0_1}OJ_`#sLal%I~Pu6 +zo~^3)U3&d`rnc`Qt1`pZS&*;q{B_Of +zc65fTBY138q@P)K^<}%`9w{%b=R4uMdUkc7GN&oijlK(3T}!O$_Rx7AHM@6iRd<@J +zEx2u!bzK8F#BrZg5I69hL06RZT^&z5LpL7hfcNwVPj>SZ3!1FY%$E2(`q89oO1Gg? +zTrJ_Ft&;Q;%TCojAQi=pd>4EVbYozusJf|ocH?nQrrV)!bFJ^9uQJ2a^@r@5(yizu +zS5x@Fbk$(0G?XRBLsIE0)4ABb)3V#kDpS=pVY(W^ds{{6N2jK9I3AJ8;wHW;zE6um +zc1s|;wk*4nu9lY4_|MGe@GOb<*UA5XoBuoAPs(08-*ZyeZAQnrYQj5PdFcnp +zZiuUq>;zp^aSPuaKhU#NbyF0dZYN5Q0{bqib>sCTG5_o?AhWJ9-Gq*DRfV@Eo$UCN +zR1>#;wr&rc-=$}7p{sb#WWt +z13#q2S>M(6w22_QJ<6LX)K!HqRrB!tXGFRMtTO+0H=-NS5zzf@D{JUnj;Em8&iBNR +zbX_f`n`-o(e`Q9$ZW3hI7tRq{;tS|!$j+zR0J_S;8(SIaCd;mg9Lw>H)DU;@z5H~O +zmCw^9hU=N$BeBSsD*oBkQsyZ<^6FYK-F`#YkZwSSxk|!olPbeGW9XiNW5dN~2(sfPcIH0R7?&AC4KUsE* +z-8CV*Nl=+zgYFl|PSd?{tGWYRdEuq4q;vza8|rE*$923Ub;R9FR}w1ItD9ozcA*SN +z&8~z}N$D32*;(MJa&2bTQUbI4MLA&T>eIDoKUYq8Vd$EH?k`eT+{5?9PpDVd3bG46 +zU2%BQX|BS-RPj}&zitiM$CVYH+e%2^vh144@f@#6J#jDJkLkv;?1Ec2(WJWt*)3vy +z_r_h1s=6|uD-OEKP?^o;_>R}4zPOL?kDo$zUfskX&d#U1gl;JZb=_;wtwwvf(!w)a +zG3mOYdqWzC`V1*FsL<_?t8Y-2nWI +z2BR)F(xysX*hpI6g{P|vy4_q!;fbxN^bO0dg`5y{jl=`|KtJ6C$gVi-y9qcqd@(6H +zXJ%MBC)?(&@g?*tROVujmR()C672%rpSB_<-CNRFJjf5i&uM9+GR?Z(L9IKa>t4C* +z&=qJWS3-DfD=b}eR&otfZj=%2ine_hQFfOhyFguW +z;gLy~*zpf(A|B=k;}~u2a0ZmlIKTUHM`9lp?YUR~bMvb3g$cFqCMa6p +z%~4{Y3CM~2;Dxv~_Se;>%h3+5nDEe6NV>|hYb7UfyeCb?Bm5B1m4V9CbmNt;L-(6< +zm@Z*`_sU(HE<@Y7qQV1PL6hzSX(k@!hvJupt~rfJ_d1BO({yKGBfN6g0^K&Q2b+3Ww)cURDF$`QKMqh|M)yCz+Nws3`nd$#<3x|ZT`emH(b%d);xvm2*O +zjAmU{c0Dufsp8P5$`$l`C|yC}t}UN*iDlPDPVVrKR^kbM1k;U!sZ!0;%%sZ$U){+B +z8=;kc2DDr8&yM>-R~`bh`}evUbTQh@6%g*&@*27n4oX^!CqefbvQu?cgHCrLU?XVR +zwZZ1>Ub<`0MQ9V3U$_mri_QwJ;jXrF3Wq}4h^P3GpetwS#u}9w4B44=7>!3h-5<(P +zy3BJH`cBm?L>sw$!XLIghAyQ8+1rYz`BC@{(=CMTn$oe#1ikMx-R>x@%#ZLTY+q$s +z;muRNZEn_GMP^-f&~4!I3cuTOOBYyn?c`JrY;Px?`Al73B`W&v|J5x(>p}OMEtg3b +z!`@yz%a6u?)ACT65oZ^@x|+%yc=F3vnQC^&^vZnUu14phbzC0dSJ0i;vrFwzb?5jo +zhOP=!<`}5VqHN#!S7vnUW(VkQgKjzNJFhM`=yHOtJWQ4LavBF`?*O{7_^qB@6;BgC +z-Co!T-o6VCoy7KC8+;X+byev+w3f>y+_L46&gr_e4&L5TJReFo-pFn*${ePyGE$FK +zzWl!X6TVZeO_iER-R8cjQd7~glW=c1M`(ku1?c9YHC#^N7h85+*FjF}u-H3^7x;1b +z9j(CnPR(w#;??EF{<>YpHjggdIAqoxhsrz$8{vh!3Z08qb2)^cZP}!=EV~YJI)~NX +zS-i-PH*}Rfje}T+kXd&}IZjtF-E+{*L94jz!cR|Ml5`~>`uo}F1Y +z5eG+h6WQ6TTA4mwTc}L4t}>mCR&v>dA8lEsGfuBgw09LRgYG@82$i|Ot?9@b%nVlDUC^y$efP{= +ziOxjJxy-^%Kb_6q19X!?SLrL!g|Lm#7Jq~8DknjA9%iPdTgGJqT_)+2vn))N&T=LP +zvG)|Of$pP8Hxeq-mtB@<&hDZz5#C~69Nt8)PL;7JY+Xe<11$yJcead%F0;dK?Er((B}U0Ax-?A%ykwJkyxNkfvWOW=5=&WIYl+yQ+EYA4K3!<3)gMwL085#($z)I3c5bx4bXWET?0D8 +zs7$l2q7s;0FzL$Esb~?GPWZ-_PCCwXT|wut_Z7e6rw8c9pu%h;M4zq;!S=ArnCxF=6rWWkD8sTn+f|aAAG6I +zTbUJ=K5U!&`YtlF^Xde@zSAnxr#nqodo*1+It4A@(g;^UcZ_A%P0sF+?fpSF)6i7_ +z-Eco$R&75E +z*0TE+D$|?Y6L(prO9i^r(ott=m@3`n9FAD_f#MJRER2+@o(WKy5$krsab{Zfj81fA +zXVyIc-5OSzs%{dR$E6f5+fo_2oQ~M`LE?}6>;T$Zg!EUo1`CS&QikCU4)JB +zr@IWDfM$d4f-Qw~*jdUo%GE>8?TBk1D*nRH#W4bOh1f>O4_|kTD&6C7v-9d^`sr?< +zhss&H)}!f4)A48)mrOWsORnpB%6S~|?8C%c{Ja3&C=`6U8p@}2NriKuJH)b6b@A=P +znT})G&2yLc)TKieO*aXv*<~~ByPfdsz5mR7sXsgU9NyRa|KG8%_T8tl({!WtzH5*D +zvnxf%p_yC~;jAs0q08$?0J>lK`Iu9xL*LDFmkT=GB}J=Dua2;N=dXM0E=9+p8C+uF +zj4i2j&{-1tu9uw8kcuEhbO%^=z2*FlMD|hQAE2`+HT23hkpot+0ZF~L3I9HBk-*Oj27(Nr#haLSfg^6CmW65B_MxA{eeuB=DX +z6@-oO?{yX=!oU9gb3hSI6?0|!>mDoTp)$4XRNWLVzHri(NZQY`>mwI%B(aYX@9>MU +z6|$QMQ^j9b0KV>+4SjxgQLkIibdTI6=qS*|6HeF?O8cB8V5;blx=FjS_NU3BTPAm4GOe|Doxm8oXu)fJ~B(PS>JaNL%F=|+RDkRzFWTo}3$CSCS$ +zvdhoT@BH`Om&)#QbT`ps<$|AX5*J4}2D-hF-Dp=|&?UEz7w_>)v8ZQP#-nBz%sQJs +zRc@j`neH;o%t!8GbOf5n#TJg*;v2fcpqn7x=a+%57F6b3cNtGDIw%}nZ)FD@tEAD- +z@1iC<5x%YB-R3jk+XzdA +z&=yiVxM99CVUW7qXjUWS1Xn*&Pm;Dp6UPp|kr4 +z$M@dK^w$*x-3ZPm>;~O-rW+)ec4V~A5?}D^OuFi{KlGidn+%m1^|}v=_gE!RHy!RF +z^XfX{AJ8+%ZZoUQ`|g5t02& +z&n{x!2t7MZcLj7;VP@WU7oh#oFs74q-C((lBeQ*u_!qwcboE$emh=Sba-y$AHO8U1MEC+ +zT`wiNbsyl|%-44>lxuV=)7^FF1>FEHhOilQn^<bluqg|0gsMR&wM +z!4p2lf^i~sQ3aBP;{Y{MMI`!dk&2uD{KAA$EmnJe>!5^TC}U}mbi?x+vw*4r%7dZrs8S8?REFBd=Z +zJ8@hiyUMh;G6>~m`>rs2i8@$yKf{rPnw_T01-jmx$GXnO8@j5FeD)Qho9P;{$}Hyj +ze{}a1?RWG4_B(=h#n1m(MXSsPaJ9C&qE_ZGfvDf}KBUumpY +zW+mFoukTb{J2-pQ_MJLaf=Bl))v{A{T~H71y>*oh>$*{L4M#!yY7trX-~^zX;-2L$ +z>QQwAO;hFbbqc(B_5b;0`TwiTU(hQ>)m?{~dE1?Xc1GQ~f2=EQNLu480NJU!LiRNx +zw(N~icL=g8`5DS*NuAzIweHYjh1UV3ftF$ZXZslG|{uGNP9wdd5n#a8~JqG +zl!z+xOX^C)ebMSwBmbGHP8BQL=AE&YomZEgc0%2_x7HP)Tg|c?E!T1sv9A+jSoVjZ +zn~ta8BKR0QzZkr_8&uQ%;m%GwqORQE*5x+pr&}*_piAVJ-2lig7jp>B +zYId)c8+0eD%s<@OK-YzPV_jzRgsgJrhrSyl*LD=OZxDIQ0njyNm08470V?y;x+=!L +z^KFDLSDBfSR+;{~sqk)GpYB$Gt^?}Ky|ym3xeZ+%M=|?G(PBA>6Pt8B{B(K3tjyrh +zeFxcn3o}#Au084mx+S1n$+8q6W6kmaBo?-~cX +zQueK4Ov@3RRL?F@cO0I@@oohF>2$1<@_pB%`TXAyFE8xX8z{ROk1P2+%xNZ+dI(Zh00WQ +zW$fEUVmXGBD?VK}rJvq+MRBm|x?nZC@2OXp33P3^r`CD4w;@Y)T|-A%`wr1=Id13* +zdCF0LUEUzd?j2ku*ZMBBt`+E>Sm)aQ)^!u)Mvij!onnaP1Wuu}V3irRu01R2WGsp7AD>z7?i)SCO#ItO%1SazzeynUA_`RU5iu27k|*hWw*Q_aq-OQnCi +zz<;VlrLHR+XLiBAp|{EpbdTP58EH$@ihFFGZF>W{JkWO&<;I}fEjlbGaY`dQRo6Eh +z-By^HW}OADOKBS+Ds)qzKGez#t^3uTk+wiBxkuJnw$~wxbzKuj1^XV+X*mVDmaH-h +zdi-@K{IZLF-C)EA=)QxQ`KvnvZH`)iZl>*3$Ra~m(Y_aSr*SGnSH>^9VAj23mFd$p +z=N?*T7`jPvQ%5EHK2Zi;YLl*usWO9G_aoiw(RAr)Gt``WV4ZIJD`cTFH}u^kxtXJ~ +zeZT0koB>@csLUDef}S$eUzZOZF{Vo7SLS25A{%;UHiWCS)!_Gpckug-uQJ~$W?fU% +zjJprImrOUoH5qhO><7eHma{kw=%#_L0Mqr+r%Ew=0-j9{9^G4$?sw$V-Eya+O;Jo=S9Q=db%m`HAjhm8t5QpeEd1>r|7j +z1?UcmaX^<=X{~2hnsx?VPPXsN*@f06gLmeB>5ULpWlmGPmFd%U#lIs>cN1o&s%wlI +zb9by$Y|lgHJ99yHQ{)zoYM_g2IUla>q*0k+>;C$}`!2NZ8vHu)Xz??ho`{`I+wbsFnGPI}L4!8gjo| +zC)%EvbT#cqnJ)cj>Yka7#DY!Nfcwol0d#YnIic^S$*mo=?8n3emPBiED-JVL&8`ESy+&1b +zpR2o#e7c|Asc1b^m;1#!mg#ap-%Xd>IqKR^iAgM1aVDjmN7I!sWmg=Z^3!bzv+r)h +z&ihj5caN2bbpwsQ3)Iy`b-16cV{8vYW;t`XCc0*TuAcq0nACF3PuIby%;?tTM}d_& +z5XI1^%5Aup;FeyQKf6=Xx~MkylXbN1fuU>fsBb?bCbN8lGn=yOp!C%HE_ij_u%#|@2fFM~nKNZocMf#daTdj^D;}h}s_;C}-|(BaR+*aaS9;K6)_rds0lFEw +zuA`$N=u%j|#aT_d_E4GG*+x(+Ggz_<)ZIaD#ivV7YoQw4P3v&mU0pXz?&N4>KQE@V +z+yGq%y)ui__DYWkbSaH1e%>Ro$eWqw%2ai4OxbC=Lwa_}X-!m}`_4Mdb|+*y%TCob +zwqFoafi9b_%i}5Lr#lVV9W(Zw+IK18iQ8I8{gos-bOVgaRCT{mv#uIeTD$iZE_OtyGGRc{RW!J;e+WxJW$?`MKt#oF6m&;RxdUexq +z3GA=i9L<&a8t$a=W_J%NQ_aq+s|>nJ*1oo%LnboaJh>;+Ww!hhhHfg%6-{?s@n#n_ +zIwyQjL%UxkKk}a{st&Pz*B#$O3h0jNxPRa2_MO!g_Y9 +zt|ZGYcy+gR-S=))SC+c~x}QQOut*{PWW28H<7jXH9(2Fyx~cA*o-w0<>VRRzQZ63KBLG3$lc46xt`03)&GN>4L(%MDWO?EAk +z2ROReZ;5#DF{7tetJ&hKzP*bZNS-_Fu)k +zOxInn%mTEf(pk^06b_wT3jL~4L6jW6JfZ&f8eO^==pH@cQFY(BWoD0dum*LB@u +zd7z`4{Wme6Dil +z&AL*k2zSid$@WdiD3;w~d62HVj|=O%?BVLlDczOLN-*mRb4RTmZP!e??)Kls{FVox +z>%p=MTh|HB@4mcFeOfOjya$$pE0bYoR{-|ib$C0Wx)G|tmvjDtJJ`(G-8U*T4lRia +zaYw8jKsVBv0s3xU|f7mOuqT*WPy3&<%0)wBHsBS{~}UDeml^{IogfGP8|P3V*)t?Z3Wr_}}U#u8`hYdhPOkP$4qrScF*FZ&&_kmV6Bs`P})3`PRMqVR-Gz{$&UDas%jFS{e)fl;dx}fwx~!hOP?>6W +zQ{cKvux0lW?i@8|_mH0U{0cKu)fGW`xV_evw(}-kfBPe`IMelJ*{Qmwpvwfh=|Q3U +z7Ph&!@BDQZacP#FSJ&R?J5_hew9Wqv +z_xvuhwz;qG#=~0#{dJEGor4xY*|{Co#++*)+;(dt+bPhcfxcTMk97>SKNrhcUNPMqUDp_N8QDfC +zgSG5B8%JW^?4n!O3v0TwdSyy9Kg!B&vo^Gy3>jePhS^^*U0KLZ)n$h4!q;ttZ=9uo +zU!Q8hR}-TnyBDl7)$DrVKjFOhG4<*4p)A~1YXjQ}LpRPb%>Gg=Z+VT&D*bd_t^i#z +z=sRzAQK9=saiWa+b(I1r1eyCz)wz*R_ouG=#vMZQqRiYDrt8nLTP=@w47dL!Ry5C`DdUczv^=-#P`a4rY->JG0_E%y>%in&w +zMoL7w6Kp +z?jrJK*Huv~GkA0&dP2QAJI#$UavQC6ZAU};>bi-JQT8`tWzbd7b(uUl>DQ{uz-_SB +zVY*aMnQP>Uj?wnN#VVF}e!7NATa-cH2%pOCm2oZlzwWz#TbWPbdf^j#o>k^GH=(&u +zdTzb7w(UqrAE&BYD^GHa0bNzgKe(bYfK{fNU7+r?J~P9r%;?oUHR*CPT`k*TLpK?8 +zZ^des_quM9JCi3zfUY=-YMsNh5hQejodIc6zLZE(Jk$W?fInPSy3sPmm2gqnhrjJ0{JJQgf?8cOaxE)2)}M +zIwsgZh&3&4TtykAXP2F7*-eJ)DrIqS=$b%wm05N^-O~VFHk686Wvyo0Z|J5uCfYxW +zwE}eYp)%9Mw;v+b6=G*VkufuUQ>7qMr^+lPBHeA6Dp%biRdp+^Rc-r1dN@-+->sLY +zgU&71ws>$=J-ZB^>@*_XW8+vQ7SgY9f>beb}n`HNhbu1KggIQ%} +z@MHsB>wxUKu=6{0-+i9W0>6tQxCc-B1AnRi@%|k}!SMT(|8GFPZT`905oFe7K`FT9 +z*2aMs2ngu22mRT#=_UO8e@=V7RyCT*L +z(AD$HF1mCz;Es;KzIz5wD1Fdp<}-L!LCbD{Th(Po$+)G~iniS$-JHpx?^NAXJBnEk +z3aPp>#4``JxmuZC-3&G}!`G#ND;r@?l`m15Ve5MM>0Z!F(08iNN;83OiM4`lm!X^G +zm&ops_u@VOA5O3pzF%A+a%8h9gf++62nhd +z_bb#{XhxKTTWl?7+ZocunG7mZ)lIj@h}qD>#i*$ah02`hRXBU>P9UN!&!O!7(nK!%3Zl0z`3AqKs=7LUx{}7e>!SGYyA*ImF|uZ+w=x~*JL5>qn_c+2`PR~)>*P%8 +zn&#Rf&vVSSTVpo0SYyosxFy+O{@@#dfiia{^~vQ>HeZuJa=JcUUqXd +z9ZJB>vzD@L_0tJ4n}Mzl=;p&zN$1JTvP-LPge#~dif-L({U~}YJjoKiE-i}B&9#=a +zZ3*e9XE)z5$1Z|S0NrpyR~stxYtTu^o82XM44M|j@l?%$UtB +zVvM@FE-hqNTWRqX=w86t(JQ?&Rb3hsmz!-ZZrcR9B+z%NZl2v1vxOz5Ntel_E02S> +zGBw>*)_1BdHRxtpi-E4au3PAsZznNZg07x2f>mZ(PguIHa0V1LQ{@r7c~?CHGSAGg +z`_8Mo2UF#e8-p$m=!)7l>bh<6BF6%|J!UJ5%}-a$s7y7xQZQ9~x<`>bGyjdwfnL+A +z9$b~_9SiLtG22+|F&Zc%p)x19(|9ueue-YrklN_`06v)`1G6M#bLinN6-r&O;;w~a +z#ida9;%;@JrL?$Hp~cVHoGT1`fzv4`&a*a`h5ER&Tl5!T;elz +zMZ#3~KDuM?cUO^_-FA_krHhRCo|FMyCz0I@eY7@G$wWJa=o-3o+k%>zw%HAWCwl|B +zYazMt^X=wXsSh?IL@FbPXPv>|%XZ +zb{h>-mnq^a@*?QkdviiFXX)cWmzll=x;OYh(M&VDfUbtL4Xy}MznLXMcJqYSosI%J +z#_}RH;!E;^XQHDUuZ>f((6?nBw{&#HLDvcu7CS=1x=P}Cm6W*xvUYQ~ZZH3d2Xybj +zj$lod>&VpY6zguI!B`&9eL}KoZwed<;`i>kKq^lp+y4#8Bl!&3^InQ{t +zt*x7&O;EDYcje5u6(1y;S%?+)xpmtUXl80==SBYPYVkqv#Kn8at&4-~&cV#wXc#Ov +z$|!W>Ko2`_iHW>FoM +z5HW~6?HQxC7TL|!Cux(FD9~lYZG>*9Q4q2V)>Q%B`;UMw3UmWWDbHxo<$z|+)hBCH +zl$`WK(6x1RMTM>q>ySpqXZNMSXRlnF;Hr@@Ss&x=hHw-vu|*)V&Kc)6{(~ +zxpnJ7mjjWA{-mU5l-g40=IK+kX-aPTv77_93(~z|>uO3n;BR;X%?t-!oJ)7d&ThSN +zmt{wCL_hMRXC&ydLo?^;Q?=ifJoFPe3UotV**%EvocNpNhuO@evrAl;E}}1a!tk6%VJ%D*5T>axUC~f58H} +z7N}sFWp|q=-ptVKOkE7jOf$Qz2n*c^&}D;lH(&ol`%5W6yUMw7M@Lr}vUBUIqK(de +zm(Wys*v2FmIX->y+{eqFKTn4TL8N0NGxM{;zU1l3pn~G}yFhk6=WDjXCo#^G|1?eve0wCg +znfsh`=0Ny;Eiqjj%ZxbgL5g{P23=NY=0g21q3bT^4be4s*4<8ck88rsOeAa((;jj@{HBv#A;>P=bgkizUoCEB7mGTGv&t=$4Vt-+orkHi +z&MI3R{N(7SYcrH0w5OaObYDR;hZy-;Azv*=S4#?q?1po{E(V(E*4?*tYmHc@ +zBZj+@!k%Gj6Or8_eY!SNDN1|E1#oB3jdJMPZz`g=D=)M-&nYx<1844Gjj`nf4?rpo7U8Pu*9T~p;u1Kp>j +z0O%SE-D2I;m7sm)LinvDbert#-sY*FU2=6dL3a;-Lh^gQ2VG`p=3;$@Hb;4k_LB=I +zs@sLCp@41*Kj&QEna#`q&#R=|e%Ao5kmKuaiJ2M5?t;kfCd-8G3f*^VBhdX2xkR6- +z%~c*3y0`f^qM3PFfuLqS8oD*cO{Std_+ygK^Q}uaPkDm&my6(cT)G;(Davop%zx9} +zOvCJQAm%&3%n?S(i-tG9_}5(=a%Xp)WkhlK1CrbGwc60@)(x_C +zqhUAC%kulGJI$;u?LyTNV)6SVm**?BfvuaPEmWSO +zgXQA*J^mdtb$NuY39P#>;Ld|vR|Wp2-kh0ft9uKwYY*qlu2LL|LO$O?p<8WSXC8D5 +zzejR)fOqG=n%QYBd@#0D7uN?B~hTO@8}jQPt&3DWB7e1yL`~hKz6&K +znVZFKo>tlIcb!$D;mt2M6U@%k-N5gV9G)*6-8^lH@(le#ejI}FnNaI(N}lkA?MYCVzNa($k*RCzW5-Ru9NYY2DR +zQ+8$sriwqiP~B~m69wz8%D_2uKmSEs +zy_(sbvzs|W>L!`lA%2LNx>d#%M$lEzWd&Uwk)5equDn3MmP_J~KsN@~U2=8xQl**k +zbzQ_%3Fr>HbXRa^lEpI!bQ&~sg}zW*p}a`H0o})8r7I49pJVRkN$YY!c7EMuCZj9( +zO_JF&P^~R=EA>U%O64W`t^5?|ezdd81I=t~Pn9~-9u&Ws6~$Y|Q*x>#M|TGW>(Zgi +zxD$!=3~=dIDKFFSL!b`N_^cJc-lOUKfL>yN$GCDerGn* +z)Jc%tWwGuqv2^GX?nrb`f3=pK-D1tueJ?+qq;88dRVKrG5AwisKn+pwx=T4-q?jsg +z;Eta)Rl1;H-4RC@fiB_>#0$Eb-b}FWR_RN$)ygaM2l*NNDIX@9nTzF)mtDB&+S%FV +zhU_feO5+lXKo@X(qIvqcbZeB-^v4igW!@;LnSR|{JUp@s=&+-^$S~;IkxZVxY7INP +zrP^Ah4CtQ4pV`^vgzSQKHBrjz7`&C&`m0{+cZ9&Y3vFg+Xr^0tR5Wv?agj;rJZ?)= +zPan{!(9G5PGHsnwmJXAj!=Lk?*jU)_!drJ1-j-$Qx=VLaZiKmCcL8)UxDDuftJNLd +zdZirwNq*j?%O$eQuUtJ=C1+D4@U{Y8EeceAsL +zaMONPN<}(CehGKy!$mWrSWaI>(agkjxl>>_XYf_R +zz|2f;c6m`cC%YKN_!;~L$>8a(R)Op+-Daf{{Z)QBMAs13onKcAZRH<{DIF$S*c8a16_}x?EV*>`Cj=4{oOq2>_)iO-J8h2?kwGL +z=GPhg6mCw4r<+>YYwFhNtF +zIn$gfrmiiV#JWqSPUegY24G+Id+eqz)eVm=QFjU(5=_kYTK1+bTsIC@e!h#R(1`XX8ND +zyUUN^#sqslRV#?>Ht6fL9ZC&4RxbC*>3T@_&9_E5y0h#KKMFd@^NISZm%_R;bvu=s +zbevos_u;>aW@cwrcDcmNtS9Y5wZ(qtZ)RF%*O#Ax_a|D-^y^NF?3Njpt`R|=j~(55 +zZI@Duj+b8*y790hWM|o-ne~xdw+(jl_`0$vwbxyIU3%`6XgoHpU@2y*|~N5 +zp_yr!U9j%7tC@!R77fVmI!u*i#u*mJ58(!c(GS&fUQ4%8+pE+CT}4Ni4VoE#y0&6B +z?+fqk4Xis$cgohCX0iMru1^g5fvwx5ZvtICI!UgC`}2{|%z;KWmd#g=*AwgRC#jy~ +z&aMle1nb(r-=)sF%Zv^}Gu^tYV!!JlnYs)-SXYnSr|+v}z3HKurfwhTCMT#HBK^A# +ze(w}dbeQMN|9V!*0N)o${3Mo;t__?sgLO-dQ|uN$fa{Wb^gXqVt=p{aSL)L#a%DUq +zB)goFUsng#-N#~P#?LM_bv3xz%#P?P^6TJPCw^Kq)70JM`*9s|*U@d(H){u!26U=i +z1rOw->}F;a%}hI89Cu&62C_>?M?rT3ri!K8hiilGUA45xZnM5cJE%0I)8wi`Hv!gN +zR+iOQme)o9O_$F8Zdh`!@61zlXfxfqvhbHo2l=mJ-G%BHJf{}Won$xoUR;aZq3?i> +zz`EP4Z`BSduhHM-YIqQ27hhK&rb->OJ=x7nd);mNw)%?DZ4tUg^besMouKYO80!i_ +zc4zEno?zGc9$b^e(YMr>ZQVBQu+o_RDObmXxnGyXSH@{(eJQ>!mwngB+z~>jN=j#U +z3Z}{xd#W(__j_#J5(BOk_-f{#fqQ2xcbz4DqRA~abns|t<%fcQt-A$O8OANTb!gu0ozXPPVaG|^>^j)Z>?!$BVU&@dWq#ci&{ZWj=$q<`-gJ=N +zHhrgdTxmxCmTQ4-tY~Hymf4r~x?=WI0l_;gK4pA*eoY?!)jxDvTaJF3r%?6&K>w3DElDc8kc@^O&e +z03$Pt^u59Z*_pZ>&TbxFx+2Kb-GZsI*f`2A@vXQb=sJKd0@mGjeYbW>d4tXZ-B%&H +z9QKY7&{gJLcsS@TBY$?mx{G`Zu0XEP_Ud!CZjW|aX-Q|x^%BuFkSyINaE%ZSx|1+f +z{5p=@x+BceU8e19-45N@q0XquM}zO +z_G{5fJ33!}&874DUg9-TcFAhyA=kQlm^vihvG2ZmOauaI-JrTUbuJE)ykI?_d;``*q@ +zXI|fnLCvfWUl_M`gwA||xJGcF#Qy8LORSluP6?Trf$UDej^Ng5{Jd!9LgOGi$JgSQ +z$yxda=n$;CUHU=og3^gDmS4v|@JXVXI@3T`!?o^GPj?2c0sc+bE}kw9)}5(4%h%wS +z$Qjx~Eh%)n^+Vc4&@GXh2;F4Z5rTCMr92I*FV?lkD0^m2Vz~MkzLyAB&j&^@(WIOr}--U0y#ySsZR*q9{mXDx(MAcq3dsW +znW?Lugf6Gk%y81}XQ%l}{5&~Ho4RyYl(*<|xj7!jr$Ba(mac@z?zWgJ``IbJ0zXGi +z&?f5RULQ1buYOd!s=Q5C$Sv?sF5UC-vinqA0hv3(DV|!{)fd<1<|*2}BeX*o?fp)Y +zN+2DYY3ddj``Ag)Jxh+$*B#w4?V9oqT`9kTe|B`LFId+AzH6DZ?iAeRw0_}A{y8(D +z{VsT_B&=&IbicrEZs{(%bj$HGXzWA$YJ`LTHMa=gmzQ;fUcEW<6rnRJ3IJts-t^NIubU`tj_(}C8XQKj)ATuIYb-U +zy8Ze|?H1_P$!+k6AYD~EyMV4L+%-yUW~SU!DF^Q^I?P9k>${|M^9@tC*wz*E8nEt6 +zU99pUUGLImVv6rs{%GhPN13_ROjCE1FTzifgS3HK)YhHS;*^g-*B1ZEe;3Wn#NfNI +zLAr)wW`;|4ZO{eeZ>FicEY{t8V>dg(7vd+#0b1YI9nepM?qj+^ZWm9NMNAd5nQq;9 +z*KS@8euJ@2(W%+YfG$F^ba!E@Sh@xHak8J*Q;T@-Lo-d?ZRHcXQErcaHQ@Tm+fJeG?&+sZJJaxz5%MJc! +zMo3Q}x9$+1k4uofpero0JE))4?kb%AIUoKf}~L?P{i_`^;H);itO?Q)QlE>gM30WEZWa78KbX +z(oJ1Ax=nr)j~3aPItseVD6>5?!%ue}y&+Cw>7*x7R(_S;GkSq;2Ri_|B4j763A($` +z%tLy#W+>h1cF>LCe?c=tb&aH>@NVecJbbcijS|!C=d*EPvV+!83)s3CjVV3o4!N_? +zO#_`0lwEk~dcsr*)@5^Lx1Z0lb@_$vupXoNgsux7%cnEHu9VZvgmtfq-_28UW)_9t +z&CRP<^PG7E&Y9NCbnE&^W;6Y|xyE+3kI%$~$aY#?&F{Sf%{;81*SOM??v&qh=`#3A +z@k;i(vvhlcni&QEX7jJ<(_U8+bl1eXvvf0XL9&fjQ}fxn3!v*ocgb(#aZYxA-9Wg$ +zYa|_mbr(LmqfRr;>`J2Spt}!KWv;P}?d3CY0kV}=wRK1I3mQ^;)7_vO&;PcY3E$Ed +z*@e4K4$?~bH6wozF^Jcnrtx$~E@A^ox^b|Dny4}pJY&V~d^O8-p +zvaLI+U(zDfesrJw9_apIzr&93Uv(G7Gwl!Sj$iQ1Ok9`4*3B`tvR(WyoQG_rmDJoK +zyQBJLEuGq*?w8-k6J5HJJhAM?!Ed_>&&;&b88B7+y4+*~tq8g}Xr`qbKo5X!5}#pb +zM|^3ki-lh&lg_RMoW!hV=HNG&rQ5=G@;`AdvYu8@a|zus{fZ{51L;Be14rj!rmlj$ +z?i$06;9hsBkzKGZ8|>zx&9rnxDutqgbbsKSWF6>o+PbS6Q3rwULp<5e&eS~#I$g}n +z#?o=n?d6}_*9hbIi4ng$3Yfqk(ZabfbqsUrXUX2pES|_Vr|`}9tLE_Df@U7quWM8tN{`B)fNmD(`Wh5;Pdtz=THIGjjb@tJ +z`E`9IB8BRv;A~_S=&}pl3H^rVQNN(a<4 +z^-FqO{tR@p?d&X_*O{4#H?xSiC-(5O%Lw~jU}heL9ian!3As8C&d${3;sM5Kau)kbB)7hVL*%qkt~A +z(Der0deDsr-4gnetvdxeP5q9Zmb(Y(9^>U;-3^e!MK{`+DyHt7t;--ii`=@6d>rorv&in09;bQL@97!P{l(|n*c^+bytm>x)#pNq>`mWtheFUdB{BajHA1! +zWmSKs7vw&8MxweV@aEV+GedQ;@FcVO+v|g0BmDbr9y~Km-67DOwRePI-5R!*kHnPB +zrBADxo!vbxn>w6cl>0h5VrQ4h-VshBOIJBrN(z@)|gNzBwekMi+5%xdNuwub+T +z)05djy6ox*dMQL#EbMi|55Th>9cOOcsWe}A$Ly0>VBIx?6L3Gt1I^42&6Hqf +z&M;Q7Rs0t$gYHRHadbJ=k@TuOQ0S&Zb~59vC@&4`u0Q;5G?Co8jyx@nXTIx>Skp=PvoJ}sv@ie8fk;W>N}bL&(`*Hr8X=FE(*gRj)Mb_B*B$FsbwA?>@{iD6hGs_VT+0Qz>!6$a0J`$<%W{1Vy@c*DYKM3E9bn6Q6dv-HdvgM$Y +z$aMOcqeI?2>KJ-c9)job#db4&tO$PvrLC@rxF=?wRm^54rh5^YIt)|gAH&oQ!-)Jv +zOQ_U)37Q$BBX3@HEWITUb#&=iLb`5tc4Nd@CFQeAjxM9*)~#U6_>Y*&f70S=23se2 +z^Qq%N_XVEMm$1KKW~O5-f$YLV*Da`-rmmpKt`B5q>VCjJ`43vm(P7Yyr?H@0;L;U_ +zW-4N4HkD4JrtqG?@X|FE`<XffBWbE0ggNcXaE2J + +literal 0 +HcmV?d00001 + +diff --git a/filter/filter_48000_44100.dat b/filter/filter_48000_44100.dat +new file mode 100644 +index 0000000000000000000000000000000000000000..d814cb030ecaf5a214abe1dc84501216f6a7440f +GIT binary patch +literal 45100 +zcmZ_XWpotD8V2C1k*v6B{ +zx?d8On`DL`d+s@Vp8KA+JELD!&6-&i^pdS-J8^*Eg1^bT@@|#Nws))4mH#Gpfq%CX +zuV*j8m>Gh9s-Rc7wzW_K^YXuV47Nd~&ip5NS?mvXLq6*Pb{*sf3Qkxf@6La#Sf+h= +zrB3{Nxf^cz2OA_PutDCFzYn&3r4IaSc}3jf4>nkkVT-&se+ul7N=p8@+ygfQyOF*4 +z-8ZMhTIdieU@XY{@>{^pu9V3?mRHAqcJ_6y4HE=}xc>ZHu$wBS^Y`VoaMM57aKVaX +z+(3R9*b|k~_&ahh+!*Yp0v%qnHP9haFd@PX<~vp_-TrQ+6#jZ#9xv(#tj|V)zBeU_=#M& +zk$eTP%0g +ztsKW6lLz2>x%OGUYkR|TY@+ZURpKV_k1CXEpH(@AKOzsrb?xliT$?1kMpd~<{8_Mr +zDo67N{j-SRsHpt^gwUfO2|zXUZ5J>6n=Y!lI>?zj^y{qBXI3M*c9O@s?AN~ +z7gi|Ieq-ebeuq2;dxG7@p8n3Q{3|zAc!=t9Gx$+pk5>-kx5(phO*{LJt$+?`!adZ0 +zo6UEvP`v$}%Ax!Qd0SlL4>m)%jT&)t`Pd4@+JCMb%&(EB;Obzv7wC|en<-pJO}Y7e +z(+W=QS>+&pg*+Ws&9zVR^?k>dLkFdB6*cD;@g5b5ws-Yt!!MC5aTTyTSbqCH*R~ff +zqgLD!UQwY)dvA}{`~rDL>>=!MXgdn$Q5$X%i3@BXwHw355R7Ju-$|M +zD3RO5k8_u{KknhjkB|?+<^Ev13wuy9x0UbVj@#eyXvzK!={f +zPL#%N=i9oY_MbhP@B`$daTz=NG1vAIwxLXJ7vIvIDVaxOzPEfFE)8}McH*cYq$$a*DAhzclku@?7%LD4t<67s57^pFX2v=-c@|~uJWn4RIYtkAUDVM +z6V{+??htP(Z&QX=X~=h!&%h-x@VD}Zs&9j4rMW`QlfBn@^T6#!k8RLB76u +zc8D+^4dhPqtIO+^8>`gghR(6wV3?DjufV%(cEP|t-MP4rHU6HEZ=}Rum=j|E`Z!o +z!bCKVyUGWa|EWY(Yx4o}Em)pw@8`R=&n(A|5yqj3+;zTg`5(%1U|YzyW9c94SYb4p +z%H872l>erzU)7UuD&LJIU=OnVxnJ0P$Q>_?Kr^^Iyy*5t8CJCx-$=d>-W<0%v=f9O +zXf}7B|LpcjsjOO)_m&^RjBdk+*u8vx^KvH%1JOM05r4<+gK|jK8oZbMZ!8wF710+q +z4?0X1`k{r~Q~re8JLT-E)%lw86IcLy7;>xsdaUQ!ZFs8C8!h2p@SEJ;C^v(xB0r6( +zo&5^A+we4@J6g`Y=I6M*RGzF_jjt#_kFB}(Zob^FY%bUtLN;2>z2k?vJy+hVT9tQ` +zU&0o!N7#SX!YZOXJ5%V4)^Q*Cj&4tt-@ulZU&ZD>*jYjcw2}M5N4h;$;%Zg+lJe`= +zM7QF<3*>&w?J!5kL|eG;ysz5>W%+6zyp#MkHssnnzxw8M_{Qcy-?>5>+RpKOMYns( +zhG04QJ*)?Nl-b+)LOZmJ)9{?z9c4td%DhDW23HfCMfJDqHsyA(XJkbsZ^52n +zHwyI4vD<}e=owc-wcd5J@*LO`vf`50bWX|HSsBSouxAT&;Mp|D-6Oc6cU*my(siYht5J^MEpwB+$hFt= +z_06+;g|g@)=c5XDU8bxIcAKn%a-`#eRZq%JRW1fQU*;`&XlK=I3iLfH +zNRW{WQ(Y)KNx2K`ELlUz1G)iUERdUHH{#<0V`eT&wY%&%jUQ +zf{Jk@OVz4uA7yi}{bZq%o4NLCzP=hZ3G4;o2UCy^D$lY#l!;(_$|5BK3IUZ~$S%TymU5Bp}$kpa{xFWn~rASZJ +z$1?4e%W9VAvt&tUZkNeW?gN`DOO;#!dzIPSe}xyU +zEE%XeUM59(1#DYchUA|=*z3Ym=0=99HkE0sd{xt(kCnBTT&8RBH3zvjg-6Vtj8M%f +z6RR|WjgWPcT*|fouv6b@+~Ohk1|* +zs?KFXl{ITs;9JYOOD_Du-V<)JYGjHkrc9u+71$QC-jZ{44ZiLm_r3tnD>6gXv`i~y +za;=Jd6InmW*<5?MK;Q9f9eyZWVV-2Rs!EyW%HCib$_7c!*jYUr&(`8c!X@TK=BtX9 +zX{?-Fs}f&VHdJyN>wX2lueMF_=9~Z9A&;_ +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 +zo#mHs2SiiGsCyx2mU+$ +zByCRzg56c1Z!b0)PY@T2U&%C$(rH3Qbi*(FNBlL{${g5<;sWs-nWKqx8lKU);dlNu +z{wY<`0a#wZDo`&r3Qrd2iQmaWO;e}-86z9={8Ox!X8plV6=#b-$Z}0Jr*0Vw8fy9b +zSTD__{V|7j=Ifi2I}%S5XNW(^8chkO_8B`G8u**o1h!uR>x}a33~`#slT8|H(RLZ< +z8d~@(*ecBcOY-IZXJ?6%MHShh`BXF}<4HrxpU0v!o%VHLN8s7wL{UxlYVH*c&QLW( +zs*@PYa;yUF_}$kT6+u1O2s~FDCu+!H&6%PtGKh~XGJ*@vk1VTCO9m#zEj^(-%UI9?!*6!qk+W?9kN8BKhgR6B4nu)T3n$Sr7x;YH#w +z(LgS1CKdI_i1jI<+JsBWQfM!*+wJUPafoOn|7!XbbTd1hxk*j<)6NTNL$RL+~oGr)VW_HC2mh(l7W_RZYfKWJ!OpYsBuN +zjeOP=FZw0@sZUMSSX^D!mUhP_>~aU=wPH5dpBhV%*Xe4X+N$B$6Kpq!cD>j|q(rOv +zRODg0qES87KwL+b2(~2Jny;@D^c{pZiXBCPm^Jr`+(`Fm)KJw6*9ZF-E|t%gLV0$R +z*j^Ngs5x8YV!B_W#;R=WBTM*$-6Cd+jL5XRiX2amYt&5D0XLDw(`@W)mpc$|6VpYc +zD5_mvWPf^gBY#yoZU(lio$byB;_YIJh!rKZlZ$LkAJeFfDhaog#esD}TYg_#PT%fq +z0NyDkixNdy?SLYy(-$`iQN`faV7uVb1#GcgyGu+IrHTq#WsybcyBbBP!f=o*mUebv +z`{O-gJlLw*s3J4cFEol#wZUPs7_epRa{J?bVvHzLcxwHMj7xvkC_&W%M}qAHc5}YI +zIUV}p{bH0TS9oiy7a5waX_Tz;#WAvIuw@@@73rO>@J&;B;{>oBv8$c! +ziw}#TB2hHcQbp(VD!xjUCr*+@(GG=dap=$&9}$DV257%3($f8WJE^MTlw4a5ZOYd- +z&mI-qhzdoB_K_kkJ +zR)SSxw_myW?Fq4^SX7aq-KS`gKE}7Nss!#NivU|bpDmf2+Z&$}n}JQyu2wWmU+g{aFB8|ozsv$G}O+Ir#hqK{Zy(Oug`;gbH$cbrO(`hv~C6>@W}EU!b3?TIgl4Z!x* +zCMXo?8sEt(9u1I%(sW!AZGgT7?Ip3ESVA#a>#q>f6pg2=zMvt0us!fUVjZ!hVx-nf +zp-b~Ny$(HZ|AQ%h%yA)*W9HYl@{5 +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 +zSHzMMTQN;_@gi861KSYyWl>qE@cj65*=SA@ +z4)E806P|+=P_~_|i$}4RLMcTjLpwAs$u%HE`(AhjmO8X!SaY!54IyYiQoVo}?F-=z +zSR48aO)J#54j#*z2_+T%42@Ceq@aLg?L*-`SS#x0z>a54g%XOPh8ie2DJ>vNdrSBP +z*5bf=;R&oU*fECEC^V^WKv(S*;VW1(>TZ`?8&6`5gyM?H1}XAOniSAmdsg@X)`WUE +zu#=gOP)sq)pkuX@Rs;;z9urhxjbNwdySB>kck{$kSp%>O4eyzI(!PMv+5>_XtO50O +zVByXPPKp(V`^+ina=>KmPQd{0g?iM>&ep;+SY4s0V!h!aqivrB%+_ua%wTm6Y)w3q +z)d9QRaES43)d7pOs|6caE$VHTTNBS_wS^*zeTI$fbz83WYVBe{0INZL(3C>gRs+vv +zwFHIYZ^J@%r)`DSo3(QU#MPr}2evw%$7+B*ZJ5X|wDoDdTRT;df>oiucDdE@0#;oh +zic5xp>`>dV)^ctVgb0 +z%sd3S;+`RiEonQj^<`~;p%~{)e}J9*``QS~u~qRBRvGM5Lol1#c3SJ3+8#nlu;0-D +zJ6i=WV-*FN;*G(V4Qsom^&@R(!5Qo~G|+)v&fEp5;)|g=>)!TY>sQ)Lp$yos4y*@W +z$=n2qLS-n;(%W8b{aKqVlmq((4YJFvj90O80#+CeQWn+rWowl-MsNrF84X603SC=e +zyoQwpD;V@*%eK1KCT*xtiK|aP{jzWf2;Kwo?n5QKmX#KeLT3CR)@!S1gLDBx6|f)C +zklfsYc0F?u7;!Q_5G%E<)JCE66RLszfQH)Hitw8dr38_<7%zz>+WNL})-@1nf_?wn +zin$%Cz~7<*{B}c0K_KqNBO*(TXydM{Ez}144h=&S;o1b2-)>>W1xl(Kw}|S*_HC-^ +zstR?v1{78W?5sQ9%A5onscl>;zDXR^rmoIi@CN(Ffh`Ze0Z>%1k_N`9;@!mQZG3eu +zLPM~x(1=30U0Hd&gDJo^H4YUoB(81auX7T7!M;Qz?W`N##W=x20*u|ngNcXQgz98M +zQ?4O>0d_)xYwOC~;5@rrFq2SYs<@zgl&bq>xZ;44>;1aFdAY7|h8hV5l40}` +zha@TjyX!vFK+cCgL1Q5I|F$Z0D2op=k?Kijqq~@$SSfIT?llbo`xuS2vt{6%u|RdC +zhq0)blGrG4r0xj~1N#W<_(Hj5@DXOCTGHQW6T%Y111IV3(nzqdLStu3!&zJ_)sSJv +zAA(<^GH|x;UmC+Tq7Tq`2lf~-gjVK@Cjz3Dl*l0Qz(}> +zEpV;wBuxZ+4^6Pkb%wK|2FjB;#xsH#x_AY{x=Y_7#8J}i4`jad+?i0)j +z2Lku&cGFbOm)=2>>})AGd#R;A$ZF$y;Y-3lfyZ@QXgb*24s1y{%c!Q`$tL4`;Yq^t +zzze#yGz;uaG}$hCNX9N|y;l^ie* +z6pkmzgC6SU(N18mgB_di+H!1hIPdp^ej&$=U4$J8?m@3~(`i?*|DvgdY&O_`*f;u_ +zoHHg1D-s$6eb$Yq-MA+78k%Nji^2K1uk<6iVhj~#B!mR1bt7mGuvZ;eCpf$InSLO* +zjZK9S3F$#r-9XwK>=iWKF4qapqkW?9$s?nu&?BL5kW}B3_T!q;f6xpx=J&P9Q8ic( +zC<6p +zZ|NKI!)T+;6ZQmo=#%MC&W~O|vvRGN``VY+K>=r=-q6=XXZ%6E63z#C>0{{#u;(4x +zd+Zf`Nvy_~w0y#&pho&II+|-n&!O1`a;w9&5jZFGlD;4k(=Dn<_#Wi151?bgo<(!e +zXt)pmb;z+CoY8qfpOYe{v(y}qf@l>U +zko}8E;QYpY`hYYsb)!q;M+cA7JJI=EOL`P7bYNezd-Oi>H>K05@e6`y=%sWK*uNcE +z4CgHF(7PnW6h()`ZwX$cr?#b>KRtpL+2tZQw{V-@A<-s(njL>4c#U3fTMqUxTI|5S +zXE*6>($?fnljCm%Z`1#@t>RkILtsbdyAL&B?UunWp4^}}NruUThQz-Q-mm{;TLbnW +zT4HBK^od=kH%KQ_De4<<3O=EKWn0e$(EVs>J}W~xxgz`$#Wi}JbT>(8_4r~Tm-LTq +z8^P|&X9bpL1^5++tMnS_Z_?Xb;;V$*(%-gi0lOD1`U`PDA5C7%b5YH~r%VetQn(a+o +z`;Z^{Pk#|;cI>JQrXf!&E#7P8%#6;4>6rx(c*({9_D +zxTzu7u+w&c3#8l8Dm!a|6Ts)_d9vEH*0v{ZRfv;elkG6rZ4RxDouTK*X48Dznz(%- +zWeuxre{(@}D_V_)7r3@=%nTHaj;v^8nAV9pYwV5p&K(H +zBRfS;lY^$gwo!3ULc9!fY$v&3y19_83Hv}ya6;%LJw;BKvTZ%%euOkOOtGB?y9uo= +zkeg$Tu+#21JweW!Qf=vRC^Wz@)^?5yp&QV;T+86KFQ-F}HNXnRF?yU_Gez1W;>w0b +z7>3#|aG`X)Lrd9FdW_sLwY2%gd4(n!`q?gnU5D1AVQ_8vbM^4)=Lr3qJT`gTYQ?n* +zRT{e4u5e*=E!tpbb@2Z@OplP)CJ$TLxWv$IhK{y>!LG5h-I)$fH5{Uc$S0GFO%|6O +zI?#}AyTOIiRcK?O-0n;ZyZH~&gM>H9Y`WMHp`#6nwp(CVqD^*I13T0A)BVI?GFsop +z&Iz4nh_c<~BIpW-R*v@3eT166SntGc3|(Ldvfbw*>2kCg4gGx|q;P+`Gd1ik-b?oo +znfaOZZ0z5ms|_t}kH9WNTkNa~5wwTyCQjxX*1fU+hHf+X+MaMxbP3w(z!pKf=uT4F +zeAc=;_EqQsLp|Fwu!{@XTF`+WgSeXySZBp*Lr)oM*j{qcbP?KCAUDVUM8(h! +zx{XvbZ?cYz<-)EQD%oChF?1o??!XpD+v!%~WnOCS9_t=<*HG5>7VHABL-O5+oZKG> +z_7c*~#K%0{ni}gJ_QFuY_JNC~^U#h$wg>wTJ3O|~jii}*q%|xyFzmB|*gk=si*`D& +z&S*2;Kw6voSR2Q-3)32y^$QnA=Qyz6P-(P@t|Q^*4%X_iJ;DTo+4`M}r?b&6yWFp^ +z+PjgiC2{7qR_E9;VZ^Am{scPY(FVGjq?kjjD0V@Zi}9;f#U;=g4(u0LEn7!d +z5vAGB%ExR8t7Lp@)pCh+I@*H<7r19V*k@S9SW8!sY_pg3Ma;3V+Qw&AJ=kezuLJ9j +z*3f07x4EMAdd!V5U*kQik!wq*qJ4Ju6HI|u)1_pvxrFt2%$u+P<8`ZQD$u27NZM`G+wmYz)nK@3+47?A7QcpCp*bRv)-~ahJ+^@Pgw;nnNCCpz}ETo +z`XEJ~u%Gq=Obg(&CYfpeY?&NWA-sd}u$6J`=mfBXz#@316j+{pkE)_&bRJn?erg#Q +zQ$M_yagP;~c62;CXlLKSr^=;t4q0KoVd)qX6h73r#VR8ybSyfQ&q{JTyhGK|5;~i# +zH=nh{$E1W$Fs`+7B$bYFVBf;Cc`=PDMRYpZ +zXWne78#5++nQ@-ADA-Zxhyz<2Eu_=PQS&lO`I!0Pn~c+}#Ys9H;lRE|UT6WGLe7|H +zT1d?1@V&8=0nS}Elo1%PzUxU@I3lvU-s&w1)%x2(?6$XkSvr^4?rAdR;__sj{^$=}Nn! +zvvAVu|Bs#8a0cWN@<$VCZ{lfrWG)hYFe2Vm&gxCF>0jvFFDt-vQ-X5rL(~dQpglT*P;sid_5*z8>E1<&LE+XtvM8c(~Erk2y@k5Nw|x|tMKAMzLNiq1oBVcQ0c +zqkoYA%YO5{sP7SjOvvg>y3x+)LLu9S-A93FEbU4{Et}2fqQr=CCX1yB=}tQpuo(LG +zVfRol8biB~Sj#f=o+#(YnI?_JkMy7&(Z$?coZI(58-hmDP9)hf%e*S8M&we{H%oKU +zlXgIt;8d6woNdgxwmf?mg`!ck1Ie_EHBXQ7i`-~>XK4vmi7wmOJ188Dq)O7oGSECU +zDk^fX>A9s9=|!^~*xM)qji8yNrzP9mB}y52!gSx#n)Ifb=pVb>+b9wZr|D#%CEc7D +z)j#qd(+x`?=|j`e6+3$iMWbOfm5i{&m;<6FMcy-AvILX9G_8>Jf^%OtQ4AVN+mQ*D +zHs*R!OCw*IPFq4rKbnfJ7Rb%Bv1kZQBGWC6&E=zZM1C_Jv4oTUv>m!;XK$c*G?*rm +z`4&(3@uZWHCevO^BpE=H!S>B}e{*uLqXaaF#*<~13TA!etw^bPt0kHYq)F&s2R0E6 +zq_Je3rKI_7}>u!-opo&6UjfsH0xEmHHXNPT1lcpZ)>gJ^;SdkrO{0W^~A +zwU|sNBe^I~^L$Gp8BF8RjY7Ho*frD+^{3(Fh~=AUM`Zb^#^&jkBr=4?qMLU1DoRED +zXec>td1YD}Sud)Md4i=K8A@Xu*efUv^`*h&lI5OhQe;3>jCq75l?YyW;s +zdcobkg3?hR8c1$f{xS8BOpHo5!y|(Xr;+Hko&5)8qTaMMxorDr%NF+0u!OrXlEFA={r_L>*BN>PIw|nI`ARJyFZdv6e1m +z3=J+|5xiseXBSW>)SWgV7Rxx37;!FYvpLk#m5il<=zealB=>pzpY4pgQD1_rgG}Ee +z?nUi42Uz|h<7gZ70AB5C!#9eY=X{<$59@+|Q6HkPb~8PR_!xEC+|<&YjHj&~*mJPf +zmrWaxlGaSqIur)6$zvr2gp9 +zZ!1EF9D5elq5OqEo(E=?1=i&DzlrV +zKbcIMqsN7Eb8Ju4nR*g$YdzEOh&IvG>}(l8rqE{SiJd(SYiFHk4bsF~)s!94Hah2h +zZV;JD{T$d+u*TJiRwMq_vZl5X+0m{RiDd|xMw_6g@UEJ7fAg+w06PV1Tpei@5@IcC +zY8^2wy1K<`9!93q#^@PX&)mPofA%D-adn`TNwifo){U4E-N2$Vk03LsuLFAm)~(vp +ziX_RZHM&KtiuSjBH;*JUsSkQyD0d)(PajB0-ARV^vr!(gCpyyd!91GGq7BgtJ9`|~ +zmz30vbhbV>YQoP(r&wN?$CBB!fdhLC){L@fS<=IL$M`DzZgdyRL-TkthkB!zcDYAk +zZ6}kKCIhUOjn~89NB6hfG*2LNX+8AHfgOf2s52REJ#IW2ZipUZ`Nuqo%%^o6*uP=D +zCWDqFVm%nWvLQw3Y*V7}iSCsDdoD&NlW4ZxwUUvfVtBET%Ql +zTf5vtuvU^vIkMI|!I%;rA9L2S-aMNuq1Dkl2X-t3nmUZ9TnX+4mK|( +zt7!%F$$_1U+EOET&+2Qu5q3SMqP4eq8CgT!(Pulm7v}znRL?!L);1msdlBPh%{H$f +zYpI(9y9eg}iB!wIwN^523FBk@tV;7LvW}KRUkc?8VY^|LpFmaISF4M0K^Te+v8I?; +zlMU1reRW`Gp?La}Q(K8~Oqg?QTWg$oE!jxRIIz25<{nSKb7rex=n+;uwu3d?ypC+5 +zrO`LL+?_B-kE35WX4M+ng*A@tV{L8TKsHln^xc7-i(=^~j@UjM0>i>$M_QYiHBORk3PltCLhEB1iZ +z-MoYBq(u>Lm%A0_(oysoSI>69@G5k5>{)AR^G>ph7C|boHS;|thqA3OmyV)OIA7Z~ +z!@r?>V{cfU%)7}RN*vfNFh7o@kGPh$)rP-A&&EEp%FKJnUdkc0UG8R>2}jcVT##*n +zVPoi>*e_OU+DG+3)AYFt!P1!V&Z?7iF7fm=pRo)@U`D_LKco>d>x4;q(@l +zXd7)95vq%o*?7}Ia*#@p)-HD=%z4A<4KCd_(2yM}i*vDkG94m^C_*|ry8-60Vf0_F +zqph1EF|=%)hwZiL2ssQ}zH~4_t%>sY-2n60FnWdSW>Xqkh1QDmwmmleO^#53>FsRJ +zj5U;A=K9%^3|^sraV>3kOvlJkN?|HnFn2i1nX!h_3*1m!gaM|sagnxbrsL!owK=pK +zPzXK8jkN_BP-uEws_ne#1UXJEFd6=Tt_ZI?!`WJxZwAxT+!R}5!;g@jaoM&Lrc>l3 +zHN(WYuw4W5&0uzTJ +zys!=3#~rj8^#en0$DOdvFx-OU}h{m{1$c@uZdHq~^QT%x=K +zyBubKt?5qgyzQMnGDH*i*f!2|g!EaLk +z-;QF7VW#F!mvegC8vTjj?07g)XSzdf({~Q+BAAo;)1@4>Ez)lZ9ugl#Lrizc9r}i0 +zyWE8^Cu<2Sgi<;~zaV&Od^+_v-6!|xYglzG++iWizFNY{qZ1vcA050jz8h^~dO+^e +zR}Sm~n0>W?6-^g9RNpOlTl`R3-}I0?pf8vdc9<5tw)rrlY5^;ycGx}xl?mk*{w~}^Wr_+8+yl~y#RJ7Or1USdxDxL +z*ys=A8}gRkW<~Pl3h-DT!)C%9rzz|p$fB6YTUK-z#5A=pZ`w!TDTu&<1_YLZi;3+&Zz9*mPzsxB&m&<()<>ZcK +z(_!Ay1a?vkq*h&e(1?Vl!foRR@|j+9V5h;nr3viN7(vy#kf0d}p~4m8NAi_kVa4on +zr@;)R3GDnBPe1D#1g%I&7S0(zlW+7N*dda0ZTUM)g&9g?*ikZ_zS6k|?MUb%95;R; +zKjaTj+7! +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 +z&gQKYc7Q#o`8c!_xY4`Jv +z32VT9t9d%KsbJm2z3d~kX__VPlCTWyQOzB?MZpt=<<7$*))1xQBwAfO#D=NSX?os$ +zVg8evhGUwW1Dl4@z*ZB#V}n$$G^hL*!Yr^SH5Zl*x!x6W(@;aOl6Z>sRcWekzLPiw +z>^=2fYOVZWaXi@5niF)`s+^mG8sTKhgv+c%J)0VzA1{sudqy*` +zT$^>Vt@VFlKXoxHvsAdr3e^3n>G{pXpvv!jh2HD#CNtTs5Zl$)73~fxV(3hc*+Z(0>GtWvH!EhvqLAbDo44uEI?O1$McK +zs43V7f`C%h_|#AGcZeOq-q17$HUTvQdrxpi395hU^!%e@8?e7=uk^x7xl5VVrqVlt +z2Z~j3>Z1IMVl%L}wSOJh`lvbB+k!ueR3D|R&A%t6KdE8(LwlhY+2z(lEx_IoLQ$A{ +zF=a>ob1@n0pW1Vq^(=SJma=-NB~GJPg$NX^ev@(_-${xGdtWQniy^n7jknp$LM-xC +zH>8}%50;=qpy7e`#Lg~b@u(H#UJw$IhdL|ee11JC4D2J#q8nk)ynOC5c%N#G8&c?8 +zh^nh2Qf}lolY+oL)>H>J7PSF;M#x06+AZaNezxTOB*>s>L^s)TUEi!cjp&NRv +zJZ=zDuuCen1Q=dv_wDQoxTEtOoI&>sz0m{ZN`vTv5j$Ufb~E0?smCRs3UGnw+o}uHDykN +z_64t`n_va~cbj!Dcg|M8-5Z_2ZV|?#OUmd5xdpEB6$^BL(QoNJAlGWky6?t9*V72} +zE^b0M2~*HHrDub#1vTaKU=8}sD(yO97Wz@?(BS=oB>6OS)^*lz=sn?g$cnkOQD>Y< +zR}1seNu@!9VFj(_<6vF%YYuG}uq%XR=%^CX;FE$v`LM;u;I3cQ->a0n3VxOBf}7GM +z!Wwi)ksC}a=r8XF>#1LHU~8c)unUFF=qp7{UQjSj-fi(Vc*9(dUXbesPxkzG9#+Ax +zMcKF+ohR%-Un*CVR~O8Yw_3ame)>fRHq2&c3wzOa<-6o91?%MvU<34D^#4`LT@Ak$ +z6Cn{fQOFA?uH1M4Pv#f<<8j}*eT4%E$K(X4KzndNq$)13!RqT3{fx}q%U+G +zdTV2#gK`a20CuGC2b!sbCO;{Nh7QhdhPwLq4s0+g#I5Ks;Q{(gf$hVB4CoB)YKVn7 +zBJbPfmf67qK@$~olA*9ObewiE)YFgI*|o4EQiNO6fx=TXPPv}sS=bXgS-Th#VCG1_ +za=9R;$yEzu$w+UQ^E +zgY2vi>JGMpkc4v-bK>yA@M>`u(a>Js<-mG_?LgZJ>A16UJ#k!NYPBefVCbOl)IX?{ +zy8*r_^#I#iXo@>1#}cO&wyzcj-M`<}w>z+2U^~+0LTlVs*_t@7&{Qo5Y!`j2KG-hT +z3-!dEXr|Bsw^ZgQE-xHh&BwwSa`Y`W>s;S;>R~Uk06+`0X!u!=MW-9m8SL;Ke1}F5^Zi07<-Z+a!2_tbGMNPO} +z__Eq#^DDU*%ye;N`+yA>KE@HswS)(SE>3@e?W3>IhuP)2puRYp))Xe +z5A(nB`}(pfY!0mvYBZLjFKsT!qc0z5-0?P{t&<6d9e)o1e==U{=fs$gNiHJZy$nu^-N(o&rq&P~J=M +zEgIzXqxqRU3}(gHTPK@!6V_o@rDH;9(Wg!)&86}P9j1;{%KZYW?~n6ob>R!_tTafd +zQ?$tGi212J8s^H3w6oRF0I&vOCzh3vgv6q)P6y0Sua5GiXLZhd9HV^H3M2#K<R%S>Uy`HsbBq3UT4yG*bzY6VmCztuOrP^V +z<5KcP{gNVA=N0D1vUOffne}|Veyue~=mW4%`HR>>=G5<9RLgm>`5$?PK3V_BR>NDn +zm5FFDHd2+ph6x#6|AV3w=eg#;<$~jzw=PWg5zr7^LLc(?@B{Kr{qaR6=PBlg@_c=~1Iyd&eg1F!CrPS5t!S|G1oL0= +zLYRXy7Wc1^yA7UD{SbGhcX%`Yg9O)~TQtdejQPI2ME}@<<-m5MxB2Jz77^+%D_Y__ +z!hBC&4l{G?b2&5=>?2>@Pe_p(2~= +z9WHw0+}-@Uyb*jok@a(dFUJWRJDpVvECq&pXzZ_8ikL%|NHl*`x%{2u+058}>{ +z5%qp9@~oa`z9nyiSv;TESsiRI`U4-vog&@pT`7vJ-o<=V-k}e+vpe9v#F1c+^HJPM +z(zf2MqV($Tm~Y6t^+Ec0$Q9w~@Bh}r4!E;nB>o>g%ExiXNJ72)MV+d*HeZ+b!rUH5 +zb`vU%C(Js5zbm?x@67EY>*IZk +zPgRdJUyx70JfO;U7kdfQw))Xcd>*%*%!m&uzF9rYd|v)R@1akukQ45xs86-aHG>^NNAR1tsRX8P +z7Qb@2s(vFs*53g;xKa&fn2b1re#md*CX>2xvy0tbFRBM+Rc~jrxZHWz%T%x<=?5@t +zeIoISTU=b*^{je8exkS4r$MgOmQB2kMpio!kD~qguetH$RqU$bhOVd8{qi%twF9ew +z9Zmbf{Pc0;&)AK{om@|-U&$|EhLU}*0+S~{qP_Uz+*tBc?Dpawu1D0p@+-ZCKD|;6 +z`xpT`hW6l3bEC=L*uBLgTo0;W%DUbR?2roemf5ki1m>KNBr9SM70+QGS__pg> +zb&Fh`HPmN9C)l?&)InddzhQFfc-oPF#0?-(vA2q!x~@<+%Wf>qW*O{mm%VOQ`v~j= +z+KyMbe#9;IUU4uuE +z-;?Z$K}Mt7Bz3i1gVhH+6h6`39@~CqwUcQY@62~6OJZc>V7E`ym2yoMU%|eBy|b^` +zUofF}3QdNY-CfD}7#HJYw~y52ayW~v!hS{*ct74m`o?%0m$?mBm&%bWMxR}-hO*rI +zkUN#e!5r>lk`)tZ+~qb{T`WhlXoq$No<{5PVSFJ;j|nrLbQ_>9l4DpD*kNyu&6<0F +z-Ggb#(`h6h#TSrTF;T|rZhh1Ray*OF=YZAVI@kId|7U0788n=a<@1PhOuSKX>#5F@ +z6Ig8r_D`7DJd=j<-w^sSn?rf0t~l+s4?!y^A_s +zZp=b#mX&6224(c?yDGS!;L2gC+2iQ5(mG8*EL&nz4HV$-e +zqkbm0U_o~F5VP93)QQjH+ml{(3yq(;w@@d`tyzEr`#Vf0pGRfBfNx7W)$M9r?A}D3 +zD7R&P`g}a1LJfzQ)y}6pZ{pjKl)Al)+uhUE3GzG4*JfY6IkqTth}{OefFiyJ--?9P +z?PomZ-a!3C?!>(9>^ETN;DwZOefX9{t~=Ox)xEy@vD}4u=?kES^10uzTVNN_m)rop +zIZ>iV7$3XGs$=9F=23-ROiQ^Td^7TE^jIV35v7in^O+mik(F|Pg9-FYsD&HJXOg4Q +zpBnu~i`S%xG>zMn%sz=6m?6L*$;U8rV^la&JKH +z3VN5D$)}U<(Myd3JUrA7cG0Vh6Fgkh0dij^Ik4Bk +zuA(=&MSLnrjNV{eqgKE_#>om+CaL^?0T9l83=9 +z%J%ju*md+Qw~bFE7wa4{KK6L7^pr<3-JxBG*V8lHZa#q=s&mxHc|K9P%O5eSErA+d +zRH)%swh(WiKXCi``ec2blSY3}qI8u%X0O10RKXr)R=bg&fH}tX$c#E?jB%ci6r((z +zy>wu&utj(iJ<5H@$CIIT&Kp~J-dBp`iR^h5b~8Q9eb2`cQ=QAk0?#{2fjosh)0Wz5 +z@PD(;j13iCJ^5kjksm(rzz0R^V8Hv6FyBKewUvcO87!p_K +zwsE58H6=%$$)1261K*^}+e=`#(l5Cyd|l#O=TGAj&&vvQ@nGgE>^8cSyTL~jJ?f!x +zr{^!qyYf7yYRl|$FGB8ix|RE#uS4!f5#tHZpOudCLPi|gC3pwj%-!Ro$hoK|#_OJ^ +zl=kux_7B*x@NNEWy~o%Ewgm5_>$yjKB-tPJ!l-(lP}<7N+22*zU33kn@DXHHlx7sY +zjw-F?RqUa*+%ESQwiNHCE4Zh8ZSq+ZXA1KAMrkRpWe=*bU(%)AOFo=@5G9)uyuMbN +z$s5>xupd{b_c%KbxqIkBP6t~M_C9 +zX)JGLceNFeThX3l%kWq9bIu@yk?1HN(-5z1O1iv*{ZWP8PiJs0LQUck6=0g;wOL7% +zceCHYj;oM+f}Mrjujyx;C)j@@Lrg2Y)+-Iq6-p_v1RzmJm*sK3fm +zllN>TT0Q}@&?@Fepp)zjTY>}9l73}x6+@rKVmo5a6#*xiT9lR$gwd9{+ZkoOQk*&nXXdf;U +zY(!)$QxEU)N~nAu=B7Ee$7wIFg%C(wBHNipdXH6V$QRi;ZM9tury=(Q?as9Y`z)fP +zX{PrmB~ZQsGuBq)3CvRN*nVJEdyq)y*B1%m6yx&*c +z<-0JCZ4FE;u)yz9W$P>gonlsdns(;83;yJji0-CW-n|tU`992Jvs!Zn`#oEY&(IEB +zFR*sPglht{{yqz>~l{-?$5LpHwbLQhykX? +zK1M~774{w2i4|%%&8+q;ZO#n^8x}FxlEuELcnJk)}_4x+uEz0_MD}#gi)8<6wWGsoVsxH)@YD +zE%fQAypkx)d8=%HWLA5TCUaB39t;08H5Vr|zNbNX79KOl)m2XYuS1AH*va>(4!(i`Fi8~HQ>34}a$0JDRynjA@B> +zCHO9U2K-a&TT@>@NjWMtK}&7+?>F^^qjR?0f9NCp7ud_Sj+(~#@ycPTIa>1C2ESgD +zR(k+ycufDo|A0MQ>$qv5A5soVtETMO?3ZHKqYkhCp=BJVUQd_hT>QWly6b|&l;y{)0lKA~4ICx(!=wa%L)e>2%C<)YczCWrPZ +zy?`Y#l+>?v!4&LI$Y!Yk&2nJBf*MNcIqVEJpw=Z*lKjjHN|kUKJ0hXI{%wwfdsR0Z1#bj)#yPS0d_{%9n(SoYhBPJXhs=2O%1fWu^nG#d@m +zzQFUCy>-^+;~X)LOt1OOv?t&o86?d^L+$KkTW)o2HZBn3$%i#xm`(?LP5Mg<(GUlA +z2h`xI&BR8r9x>K@Y5F~2AL%14L4(20hn>T>uf=7ygMESBw5hn8Sf8}2`O5S>U=Qgf +ztw4hu*zI85waNHBF@eO@q$bzEU8IM!8V$6wSD4j$XcKTBF^Txr)J(Mlx09~YIy3<6 +zf(kX1SuYKKBNdYg3uUH8fm=zjvCCT_E)wQa{aVnc$An*4utY0 +z;{w-_F4At)y9(>C4aQ@|hGcE1P_i&^4e2E9MZK!90op)3UQ8#`LdBBpfh$RSX+L@o +z>>}6|eOvFZYzx#7q`i+PiH*pIp;F0-z~!WkbO`mZvsZ04SnG|aiW$ThDwo^{TuNF< +z-=gl?mP)x-*%y#oL+goWicLt%P(z71a1m)LeTTY%U0k7tG8?LO!*j$;5*J#n#1OQA +zG?q@H5{GsRhL;vE5StR;P^Xg6pn0UBbPAbl_D;EDyUI4REjUao#7o5HgoQYlqy)_- +zDbg8K40Z|Z;=Vl(*K9Ui%flLne6W|2hc94c~PH$iS~Eeo#^Taoi2E+y{; +z%^>xp3#gz98=<|6H;Aptfe_b{kAkL>80j*~2fGw@e9PBh&5hDJ;4j3sWG&daK~qQ_ +z=^Dy=ZA0Izv+Hal*g9HUyj^TZriZwdYz~@4YD+g!P8Bv_CiQuLO-JHKes@`F^~KLwp;K}B1_LvJ3D)mS#7cwjn9h(uo+JIdN +zyX0?=?Iv3bHbslX7sW!d4(zPp4+xSp)Vd0rs)gfU#bPo8?1tchL=!P?WwW>Ja?`X> +zd_y#mVPL-r?oVEd0&W3z73{vht>HJe25Lyxg7Iy!D=7hcG5CD~%?xn!Dr_UoAKw+b +ylQv)<1@|Fl(HS?Z!e(eb_`cYK)T`lBf@}Pb5YZK9f?W+Y)U>T%XgB@;{P%xA!KrZo + +literal 0 +HcmV?d00001 + +diff --git a/filter/filter_8000_44100.dat b/filter/filter_8000_44100.dat +new file mode 100644 +index 0000000000000000000000000000000000000000..59872bcc6ae1d082d7ed11dfcf74406741f6872a +GIT binary patch +literal 32800 +zcmZskbzBr%8^`C&*35{Cf-M3fDj}GlsGu0w0g8czih_z_5K63_*Y3`1d-dwIyRUiG +z*Y4igWNFwlv*&%NWf#4Fc|Tu&&&-^iIOjRP=aHhU|07E4|1147Ari_&?5MAVDC<$# +zL{5nWl|l+pW+J0ySbiOPZ_noHu-aBh{UkEA=*hnSV8sWZfl +zGQv5Q@d8qndQApWO^K-dA9a{CrVK<;!U>#dKB-1MBaxH?@Jwn4@u9SE#>LlIcL*-LnLdZqrLL0&)J3yN*&8L1 +z4sbOUD4}Q!30!G5ai%Vj)zl7izH$T1qb-a{c|5cLK|43`{V2BYOc{YkD< +zp5{!Y3I&ki)JtM-#nXuwwUa!eDw;Eta@vQCp`OEUSgM!9X!=lF$Q#NirYjrLt|W$f +zN*v%GvZU!+X0 +zC9UAz5UDL9ubf9?b24?0RHq6`;wvZ(X-&;13`!G!D)-Xq<~h_I_{GY&8h(*9;)o)} +z@5&qWSMx%+Q)>dJi_T90cWirVCUHSs#4pM(^h@&}@N3nAyP}Yr;Z9JIAZj}CMvcW! +zN+h{wUPE1hU%ZU}B*9cH@ke&zd!?)7l6e#Snsu!B57L>6CY_K`c%$qfIbq&GorgOj +z&l3L!{NkfYU-VpfsT?KQYu*RHwv&ak)OWbIhm)b`obW&8Y{>@mVd@mAXT`t49WjWE +zL)(NW%3YEr<`dN4a7X2q#Ao5T?L&og9TK0NWorfNnhSEhEZvGdZ +zbT=#hkqoBVkzJ^Ya8=ns+THw^+6!-kQhf#L0~t#BlOre>UsR5gwl_bgcEKH+T@t?n +z^_~o)nvt{UEk3K9Ep2Lk3(sgH;F6->rvlvVBPnlk16{?Zl)I&F=Fiktc*e6zxE=Kt +zp6y2DG1`ZZE3Zqdn}1T9;EpfjZ^&56mApZV@e$=$DQnhI8;GYBe@(_wb;%DDi}x#O +znIL9TYvGB=w8Vc!qNy6hh(hrmrJF2WETC2q?-DM;llqEGq^b~%{PA{WC)qcVP|HaZ +zEB+GREp|jf*TtKaV`VQz8CnKUR7O$!Lj4PPV&tSMjqp0<0@*#W0$NObExZyujngPZ +zoampXmCF6HOJWsx2Q{()KX2TO%#-GBwEyEl{Z!pbPvhww!8%l+DU@5OmJt4`I&fJ4eF(oTK<%>lR +zGz*^Cba=BB#;*)-^fXFk4yPkc@yed^WYHHT5=e6r|=W)OcX +z{)o(_-kT@U-lhr4<#BnK7>uTnHdg#0SwuZE +z&!zJVMk=4kyNcc59UEZ9ACM)~BlB|lW5Ez*ro4^V2gQ(f@YX6m|0>jd@&|R-yotV5 +z5T0Af>bD|0S!a%jUo6RRvv@;fkta +zB#MMLN*TXP)==ln=jnuk4$35jOdO9!z&E0lSB1CPdg_$<7Co#WK)FScFT|n<(hvRd_%gxTeX-wz!!H1e4C7PZoae9mANS_ME&56RmN|SUDReX +zra$D@RCZ#{2!Ej7B*cneCwr)MW|`z>eidaDb5K}=dXR4L4K0m-jr>WiG}}uK=d;Si +z%vNC&>IQGTQtn7yB?qXb<~owq`LyydvqIR3x{x05)-Ki;@IR?;FGDk>o +z-t)91Hc+^QTEaK_Cwv(Tf4^$f1#*TOZyqQ4n)fhmE89%CkD8HC3$G4ei}TcIbDZRU +z-mSDNtefx@`M?{wR9~GsM=nys&B>C#^Dd=*W~&RYkQW(1{V0iFojOY{Q-jS5B%AY2 +zrAate_<$Oda4UX>T&2Ryt0c4Yj-)l@F#d)b!W`jyiM|GP8s-Ll%v&VUd3(~ja|WzI +zZtzC8<~OPC=07F<^0uT+;yz;|av?)XIEF9rKjaS8*?e5mI&XE_O74F+7dgQj|65V~ +zLVk+;O9h$FOPuo-r=8^PU;))85f)yPI!W$R0p?p0MV>P41$Pch=o;`vDAm`5uiZnc +zmHDwGJvSjOpF4tC+L4TauU_H!V))YkO&(Lt%&#S{a%0o#R@ja!(^cV%@fGHP#ry<$ +zLV26NNv`FNO$(~93RkBqlTq+hEatVS3e5RdEAEE#RZkC9iDlbM#z%neC9RAD^!pye=!`fQ1R6y{Df&34kr+`zO) +z6^3G8T0)|VI3XBjB1g$P%F$e1+9S7Rnz2GJ+zKYw<1D;3e62rFmCY{F=DD6}j&?z~ +z9W9#2!&g}Wvo8!YmBZu{#hE>&b#h(OTH7_l!L-R7ZN(3fFO)y>=`fNN1WSS@8oz +zMdgX1(knT6sdw$LDFWtbvGCPriq5YN%oa3MrZ`M`AV-&~wKJGT(>n8HEB+_ZQ3i3G +zbal?x)XEh(orCy1fq|P}`LV;t}v~jUz-zP +zR#F(hknbWU>XCRvnwh;WwPK|?ruFm-bD|aBNd)Sicv|{Cdr4}uO4ChS>1XDdFo!SI +z?<8jGmUvZqCp$GYyi$~DH~pV^7I3yGem$5iQRtd@PkJJIYU->?gG~qNhcJgOxzzbMs?jx^!@MaB9WMuBPksHS=r>cZRhChYpDa(%@{r)aI2P +zO#jlCVGduaccwNIJG4)vWlgd@QU_I*n;z2_%yVIlQXIdKS32yclL>rF=c9 +zftHGGWk<6w0h>Go3!s!6t(SK4ql6emuX`DCp~sa7SjppImt +zc@?bjO7*LVJDMn_$ZBQHP6?DnCLp%e)O{t)==Uuy*VyzLfRJ +z%u4>J>izuDl0;Y|mhuL$_HBdOi=SixnctJ&R=t!TEtz57X~h?lwy3qp%Nl0BNTwYA +z%AX>cYTgBF=;HVds70hbYAI&Os%G9vZsf2lKVCA~yc@V((fAbdK-5$;$w3)e&3mW^7QT>lK;9xP*Jd0{p6;+9f374N)~Kc2omxPGVQpMN{yJlG@@9v`{Kb+e +z^Pe`nGio3@%5P;XNxtR~lfP0j+PoiT)y2nmhqZfG +z^phuM^h_S&*gXG`B;0(&!W&X^NN;2>2Fb@}v`wDv*dYJ7B+Pu2`nM#0A@2ig`w)5m +z46oz^j@9$eNcx$N0k2pzehsPFq#sg<{p5ieb&?-BGWnMzz0JoVBUH+jBos--!E&#R +z3dz}yro0=H9EQRMlR3L&gxk0Q{I1) +z&gPRa>o1O9$OoZ(VVXS4_;yxwwWoP6B^}NGSn*Uc1Z4}eAY`}wvZ#R=EIOqSSG({JUHt^wS#$TNo(_2$f1-TKbed` +zys%b&$hc{iwEC7jqokGjoP{^0W|5KTyRcQh(YR=qSM@*gawRRy7l2nP8oxpwi9QSa +zS?}A-LUABAUEhJqo=|xd3$5CS?Se7@~TT4 +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 +zRY7;RjFb)U-?bZN(&EmKASHs?$wz +zF!!BrGjU4OHt7!(F+y@V?u)x{ANbl6w>E8({zNfeNI^qgjSQs~9TG0gp_XzBb(u59ZGC +zBPQ%>_QPOQ3>M~<h)vD|L{Q%v9HXAE+tx3CB$m&9*PwE^#tGak=v +zdO4~8}35az)4&RZ;qbRBFf;&v=df>&$9IVS`!z#I!@*i_>a*?TMRKY +zWdej%<#;um#!clfN55{-+t7;f7gpPFSK1NJ<|gsmqopl_4FOCm@USFW#doD0@H{S> +zPl@(z>1POHnhR@z*Do2L)}%gN1ux{r@Db4wExin#nWn-zlwiZ{@nUWS-!^(tOBX{A +zrirlLhP%;~@iJ}*Upx9#OGiUr#!J{xj#t9Vxq*Da_>V1F!vMxZ*ofjS@%>2yx*}f1 +z_2XZU=UR#SAxuN?*w}JAyoT$=pB?YlDpNm#X&`I{4_4{<7wRkE^;`(QVf^S;D*YJ7 +zRoG&~-DwtYfyG +z3cQUA;G2*C(dxE-8dF=?UXIK04$hCSGQNu61$`n@Q`i9>Fl)UG@8X*C>Eqh_9oMHY +z)xaZU%^T5DyqELgACHUn+ozwyI0(C~xF2amOYonZCx3L@I=@Z&g-jJ;51ML;U&v{E +zfNRJv8+XlbxqcZ_N!V+{8-q9R5Lcg%8K?7`t6#;~3H!=%3LoL>@gd`C`X}nwGaPu7 +z;;iB~ritkH{T4<8YUWPJRH2W>W;;A-%aaZ~&w^*b4vZ~#1Rw)`aL +z$bX62>L0G($4G>O<+y12hqLFeM&0%AsXxR}!XX>(NeiYkTt$9+RF;27{V~Rj52MLe +z@jYp5I>)hma#X$6e)^M)fRB{pCesB@&JT&|(b`LYmMOqTQLL5Ti!Lx-b4@q7T-DLB?rm~(|1k#qcR8M8y2WLymX7V;Myq?y +z=0i#E>OA&Pn-{tdj0*pQCRpj4&{?K? +zoL1#J_C=cqy06R+e7YRZG(F(dDzF6wT+{tzzTq>!@JHNF)%!8t0cUht<_kUx9>ucj +z_n|XPkGXHE^J4}F9Mu__kN8|UZZtjNzNprZnIEuQm(9G#=Ycl_cU0l?*NXViM$=R7 +zlWN+S;{h9W1?q@qVXx^D(CJs4$Z|61FdJ&7NJ2i98u!=&aetM-qo9r#!q%AUZFe&HJKl4|a#u7S6- +z;p|`daS6|d`B~xl{V-{{i>l$HrUqWr4rPx5A5|2;lz%trxC^Q_qqYbBtsTK0#{d1o +z_1t-tV?Ra)Seu_rg#Q$b8aA#EyM!E#8(@tdf;b*__ +zbm03(_6l02ox<+H{{xS&2aI3o`F%4PxihLcBNKz>YNxZi@N*m9oc;>@v})MMy+KLZ +zM0N*$@e9uY-g@NYpefp9b{l?)hFiri)E9Dxk*1(1t&-jH8=lGiqtcIP*kPD<9=i#@ +z`bD1w{NEA%JA`Q$u^aGfG|VRc7gHhMJ0i715A8B`9e(o*&jy}0;$Vl4+Li1Y{Ps8e +zlxoO`=Nw;-|(}l^}{{{ +zKhoS_XW<`c&@cLPswu;mPPa6-*(Cha!u_by_~%sJhqdfqbXfD0osRh;Zi45dl;^?o{VL*gr#+hI>{P7&4Zo!NJK{^H +z&6?Nj6!0hyg!pCpFQz%3a?j-8CPHoPg^UwQC;8XMu?d5Pu|JE@3!m+1XT +zF~6z`j2PW{w&oi<0qa0to?lbdh*;4%N%ND9#(Fg17k)#PG4y=rIE{uKj}5=!H&yqC +ze(xNu(X&xF{TH4K@ArK}D|Z>C$zaC-53`B?74FYFs??zYT?T2g+0o#^w&uR@{O7{= +zC46X9m%f^Ob`;L|h3CNc$#>|gE+HDsj=-5H)GB_VK8JgtVuxPp5~MM+!+*;ks=f|U +zb@A8GTm;Ut(zhnQ^f!2ZAFD17soK?7BjbkPY}6li{)>N~QvO7>ZbiQNK=dJSB^JU0}s6|SDEx2ulg~lTDRwFZ!QFj +zzu_9ygHT$Y=#<-vg3QvJbZuCRg(v;?{-DqiVKF~ +zz%m{H^LO5);WAYrgRXWvt8UG8{DrIG`=6t79;E4ZT-}xn!W3<*SDSb)Pn8#5t@}ZB +zAQy-c-OFYYDtZ$?*&0H>UM4f2_=(8yM4L +zsydu&j^!o10QQdxxxw^_bKqAET-RfQdN9`vE6VY7n7>x%qX%B;F-9H1H3ig!z3Ve#d|{Jv*smI1gL_cvBev +z!t*QUuQ)G0VZf!H?bH*w#^ty>tgl{hzI>knKYRMACvy$4ot3^lafkKUbFKyNKES?L +zQ*|8Y4m`vXzdhtPa!k)4zaWMM^zu+o=Ne$hD3{|;AwTgvEUK5AI)QV;l`OmkRjAK} +z^;IB$G;C!rCv_6%TEYw9{0q4otWO_v!Th|i^Sx@QlQ|ctLFo$di+NxXf5dg=hlYLY +zRYjf3Isd}*VSU(xZyr{$cLnuqt{%3x(btFd^?j}n&xZN;mZ|4*PPj@rZi4k`DE~P$ +zvNz%9b9I1s0cS+%@m*nke}@~ypAB8syMSNB)y7qS;kUU6ensf%-dX$-u9giCg8Z5Q +z>+6yHxX_Qi_53ofCU&sW7jn^bgB#1Y4`urB{0goH@XnUw7jm=d8syI$L!0;c%CF+8 +zV@DhA4Ed2OTr98cKdjGtehpXc7f#_zkiWape_@|j{Cds-SF_T0fczxF7a{+*x&QG# +zPx*~pRV&_{D(2_8S^Sj#Z~8psH*-~>2B=fX`4w^}$p4(>lzi9zlD>ENt(-lsQI1RS +zX>LC6)Ze@Bb$&Znxg4(x`KMFd5e4cNl3UI{=%?&^hTp?g +z1Re~|jKbfiIaSEz_yo6x-`(#}-@o~NoE@%Z!|Oo)>@RL3pVaSJ-=q9~uEH;z!ABv# +z+qa+4cRzoS<8W;&eK4sF`MblAA9nBO-fuU5m}7t896reH=Y_s~`)%Woaty9RceI>e +zFyzN8;QicD{#oCoejE9}IK?mA4)5ds<`4DV-ER$lf|ElHm9@Sm@}t|i>%4bgr~dQ#)0_l5mE-n! +zD|d&N^zGVT$)Dxua=bd^XE$>X`8R#0^q<9_=Mb)ErSD9t(N!V8`IJB2XLJ7q{$dGl +zQS|#XgZKtNA-Fh7QjE{a*B9M_!)ttGkt&y|CTeF8d>5O^CqxA6s~sYS!19R|Na-w&_1xgG+fR1=rFJr|A9*fecO`r +zFVrhwe=dR>qrTE3dSG?_Bk;ynya(`Ru)j4yy{^Zqfe!p9&QOlaVgE0jo2riKac*E` +z{xhd9;rTHBzTl6M(JgTpm!uBr@p+&f{{^^5QT$@w6L>4!k4sZK_F%$U{wt>|$ECDC +z?#(SwYq~cLm-F9$!&~DX+#l+z-3NzD_#d3s%(*nagl>aFxV7r_-DihW{7)P1 +z1O6o%_Fp@5ThtS}9}E{&KRJz+zK|oj9q!2ORtI(eFWjV3{e}m^{^vn;weET0c`BY$ +zo4hQ?_krFE6deTnr^nTrZq9>pRO(+iK^<{x?yUN1w~#@ZDh$^=J +zl&;bi@irybR~X-nI^*WtZS{n18wTlBI!UMdMMy3A^55eBt +zb9J?DKL+u?;R5Q0J-ByjO^Ds#A1VX)vs`?PdcgknH}%z!mV>{k(t$Uz9KQ+G7yKzb +zu^XpRuM3G7{2BOS^!~S}vIwoZ9;EyU}5pP{`eTDi0)Cbq)3e`@cx4^%feCRTLA@7f?bF4<)HGlAHRpu`|4~1a|&R%n+tMibT7VcMc +z|1_ccgFk2>uFTcctnJ!$$a7T|_pK;?8P7rC;9qdjM0brH^6a;KF!&!DYua~RH{^*b +z8}z<#er5V>Gz9z;zM86CFAjNJj(by~Bnw4gn)BDFx_lk-P?f`d1-*ZXzL004;n>Uu +zX)bkPhd%f%AAvC&qFL3&cj&!eco@k*qi{akR}uzm|JWGtr;O56?y_&_E#O~F)_ef)DDbyLYrc2BKlG+5?-y=B| +zG4#f7xE@90pKOw5Mdun3*M8vxi4IM`-`Lrj(VYV$uKtE=(IotdU83>tJT~G=3HK`* +zKQC$^(W1%t9lKg%*Li8gs(dRwhAdV%_z&apBleVLWGA;_=WX(-bT25BG1e{s)?cZ?KOvAA;8pJ8RLG^16lc)o71geXQ1%`*!E5kJwxjl7hqMv@l+zdTH)tJR#`e&r +zcGwF%%O-vye+~Z6MQoV1e}{jI_*bj*_kj9@SKuF=#}3mr?4Spp3D0-g^%e4$;6GKe +zQCd@w!^qR{{`{41!^!Lv?c<=%jrjeKYJIR&d${)2F)3H +z2KYC4eoB8o4{8MXyZ7KJ>@sbyp#3Ay!uP?NH-`FF2VP^l;^?y*_etXkHG&N%0AZC4%|QL +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 +zT&@l8hCT^T|*dog;?URgWk{@;k7B +z;-WQ5b}9I)ta&if3#a5eGdvqVj+>^L#V!Z`Rw=JVttTC!f73Df(G1c^9hahsXIFy% +z%bIsUnZg12`Hbg{q*E7a;@H*TAL~|f{6c*Y$`N+U?_?Zm_gTfc{rY3Cej+o#Zsu$0#X?uS@0QSO?lZ1{HS8%;Ox +z=c=suX6VmmCr*|7WDabYJ@uQW6Zm_7qMjx3YeIj)mZ*|AQQkJwvtgxa22CJ)2>g*{ +zd<$uTs)$kY?wM4>#?uNkt=S{sue9dPq5s%Od3fdv_fFHK+7|3F@Mre2#NP`2=W2*U +zJW~S~vDI +z_)mMo{%9UCLzVhA(gZm}|FUJ7-tLE|HPzN*&w_uol-B_6jp~aX<(o2*`>knhwKc&X +z{?UqWhyHu+Vq5v2nXejrm=>aS0Dt)h@Q)S8uR(1m9?<`-mHcGpu?Bh5Lba9HtKiSI +z=8ch;=qtaLIk$oR^buMH{O|9;-&U%JZr;d8^pHQw9NfTTdW@E4Z-GD9n!7`Py880B +znLZ7Ir^jnW<}Ub)%lJ;x0JVVrajHydgNW&~wRy}v@F(}P#NSEWke^sxo|F03ZN~IJ +zw3*C9@Hdz7U8Fv0BihU9tmAIWr*G2gnE$|EUCOINe@<7_PUPg3vlh7RpT1A~lX(jM +z?Ec_CC>-BH?u>#&soW_m!tLtx6WTA#bMSYU@!g~z3Kq>W&#Y!{ucu$qzGGg2KRnc; +z-wpj6JBxX;)>#TS^H{rkFPeW=gQc&_~q>NlR)@H(i6sFj6g +zovQCTdX6UuIpnl}B4X=s%L4U#6tdaFYXB23! +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 +zOUYjPCv(OX9sSI3rnK5R)#s~9Im>j+!2j~Ol +zp6h%RXM9oJSiJ^(&NZ0%@%{aL`RC*?EoYv&a-yP*Dtm%@1Nfh7gL$d^897RC!Y`$d +zN--wcwdx!x68ykG`BM0+ex{ch-aRU+rST0r1OBa6k(bGf;fMN_iF3D)>TFE6ySUv_ +z82E*O@@4R2ou+4)Chmx+bmM5dnfovJsT;s|@?T$>Y$E6A3Fb}rlgOdQS@y@=0q|Kj +z2J>68krdLyOn3LW$T7yx?RU8&68B1OAVqW^GuXW)@)P5F`*rRF__3RU>&O+lm6_}w8EG^Y+D~x>;M;Bif6I4$Aux?(z`wPDnd@#B +zxy*RiewZr)Kes-=1OM1f`W>^_9TEAh(Pq!(ioxg236{SjFMwMyo5^-RiO4aA)@Ed87J20xJvMocPR2Xq>9dB +zuDd%#lo@q3bGWDAFaMy(XOpLND)xX!MLaaFuK5If@E6D%)?ME{c^3R>6R?Nxx%P$e +z$C?j08~D*X75PkJrem>3>w;D^o~#)Te)%8d$GTht)6NWHqwix6&vvcKbhBn4=LP?I +zmm;4IcjbFvAPL%V(~Fv(oQgiesKH-q&+jWgjX3E*?131oO*C>V{s5^fJY)35i2#@g;hxas%cWA-Czg?FTqJimXBH^*ea*Ahn_yALegW*zW +z8ToH*d0+kjwxv)omgalD2>*v^l|y8k(wk(TA|DUGUL$6SXF~WG(=NwL_H}w4y=ve2 +z{pH7zC@{!Yd3uFUGM#ojV$CYUs00oxUP{R6@Bk6^p{3mA-r*aNoI +z)L1;u_5z>(Ao#1k>*Ha%8beaB#=OL{GHkV}i7qCX{*UA66$Xx91>0FWFpS%IH-ug?JrqA-r@%k)Ge!pe=dXe-ts~X| +z_Vg|ay3-VULa +zrZ=4Z*#+=#1>ZBPW>~U>p&cbh06wF`3);I-o +zq-j!|W`t1STFYFZU%@XEDE|_+$7z_Od|R^d9|*s@RxrizGyR5<3;+55ge`K0JW$nN +zy2^hnI9*HN-}(<)z4iIqWVW1+G4ecqk`U`&$du76v|8))E?6Vh9b?oh_~}BLdj@kC +z{;Fd1{Qbu_W2S!|=BQ>#Gx#~e0QY$20sL5(6?tc@VR}=gm)_;)3*+4*nLpsyx}wNC +z5gq1WmP)O7y>7H$zVrL?4kQzE +z5ZmAo$`bawJ2E2tW7idVd#nLTQsqe()XRlSSlj1?|EwgKTQO3dg)#ViX{UOnP~}cx +zR4|g>P~>l7jX}7o2o9)k1r^qQ@GzR*M9UhoDA% +zpvY74H9dkp)@im_$OM~oIQ*Co(K7a*-+`9ue)Q3o(H!=wun}V;qu}3s6wF1m6c3`0 +z{5{QNON3(>TlfeyUZo;W!PjO7`UvCLQsD;J#S`EceTv9$HB-Cb$(MH?O +zR0$@u%|FN5zh{a(5w($?c<5)$6Jb5v5X&(4{v3Wv-| +z@kYK-*|oG}X)={AgdZQ!>J9N&YQ?grXW +zZNM3}3K4McY{460hTqhGeh+G@QdqycVjq!BXoa@H4;UM>DDo)04WqD+wn$|c`okTS +zizn6^%)NNi%khmKA@5N+go*g}{e-@~4Srhx@x6Fcf5#Is4(k|2A(L*x-EIQEa(%AF +z)7Bq#>AEYJaZAuT8-hcMXw+Pw{L$ +z!e7J_%zX}c2d?Ofya@R+)TU4Ii~Rm~UwNN{-idoyj#@z$cA_>gqiONP +nc1P}Wo7dpp&{{vbFZVrT5}pP--a}b + #ifndef CONFIG_RESAMPLE_HP + #define FILTER_SHIFT 15 + +@@ -55,6 +56,7 @@ + #define WINDOW_TYPE 24 + #endif + ++#define PRE_FILTER_TABLE_PATH "/etc/pulse/filter" + + typedef struct AVResampleContext{ + FELEM *filter_bank; +@@ -175,7 +177,22 @@ void av_build_filter(FELEM *filter, double factor, int tap_count, int phase_coun + #endif + } + +-AVResampleContext *av_resample_init(int out_rate, int in_rate, int filter_size, int phase_shift, int linear, double cutoff){ ++int64_t __gettime(void) ++{ ++ struct timeval tv; ++ gettimeofday(&tv,NULL); ++ return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec; ++} ++ ++#define PRELOAD_FILTER ++ ++AVResampleContext *av_resample_init(int out_rate, int in_rate, int filter_size, int phase_shift, int linear, double cutoff) ++{ ++#ifdef DEBUG_MODE ++ int64_t start = __gettime (); ++ printf("[%s][%d] out=%d, in=%d, filter_size=%d, phase_shift=%d, linear=%d, cutoff=%f\n", __func__, __LINE__, ++ out_rate, in_rate, filter_size, phase_shift, linear, cutoff); ++#endif + AVResampleContext *c= av_mallocz(sizeof(AVResampleContext)); + double factor= FFMIN(out_rate * cutoff / in_rate, 1.0); + int phase_count= 1<filter_length= FFMAX((int)ceil(filter_size/factor), 1); + c->filter_bank= av_mallocz(c->filter_length*(phase_count+1)*sizeof(FELEM)); ++#ifdef DEBUG_MODE ++ printf("factor=%f, filter length=%d, filter_bank size=%d\n", factor, c->filter_length, c->filter_length*(phase_count+1)*sizeof(FELEM)); ++#endif ++ ++ int filter_bank_size = c->filter_length*(phase_count+1)*sizeof(FELEM); ++ ++#ifndef PRELOAD_FILTER + av_build_filter(c->filter_bank, factor, c->filter_length, phase_count, 1<filter_bank, 1, filter_bank_size, f1) != filter_bank_size) { ++ printf ("Error!!! Loading Filter [%s]!!!!!\n", filter_data_name); ++ } else { ++ printf ("Filter [%s] Loaded!!!!\n", filter_data_name); ++ } ++ fclose (f1); ++ } else { ++ /* If not exist, Create filter data */ ++ av_build_filter(c->filter_bank, factor, c->filter_length, phase_count, 1<filter_bank, 1, filter_bank_size, f2) == filter_bank_size) { ++ printf ("Filter data [%s] saved\n", filter_data_name); ++ } else { ++ printf ("Error!!! Writing Filter data [%s]\n", filter_data_name); ++ } ++ fclose (f2); ++ } else { ++ printf ("Error!!! Failed to open filter data file [%s]\n", filter_data_name); ++ } ++ ++ } ++#endif // PRELOAD_FILTER + memcpy(&c->filter_bank[c->filter_length*phase_count+1], c->filter_bank, (c->filter_length-1)*sizeof(FELEM)); + c->filter_bank[c->filter_length*phase_count]= c->filter_bank[c->filter_length - 1]; + + c->src_incr= out_rate; + c->ideal_dst_incr= c->dst_incr= in_rate * phase_count; + c->index= -phase_count*((c->filter_length-1)/2); ++#ifdef DEBUG_MODE ++ printf("[%s][%d] elapsed = %lld\n", __func__, __LINE__, __gettime() - start); ++#endif + + return c; + } +-- +1.8.1.4 + diff --git a/meta-wrt-tizen/recipes-multimedia/pulseaudio/files/0004-TIZEN-Enhance-for-echo-cancel-samsung.patch b/meta-wrt-tizen/recipes-multimedia/pulseaudio/files/0004-TIZEN-Enhance-for-echo-cancel-samsung.patch new file mode 100644 index 0000000..439fc1a --- /dev/null +++ b/meta-wrt-tizen/recipes-multimedia/pulseaudio/files/0004-TIZEN-Enhance-for-echo-cancel-samsung.patch @@ -0,0 +1,326 @@ +From ea99d218021475f61d3ad7d7bd414ea94be470f5 Mon Sep 17 00:00:00 2001 +From: "vivian,zhang" +Date: Tue, 18 Jun 2013 16:18:58 +0800 +Subject: [PATCH] Enhance for echo cancel - samsung + +Change-Id: I625ca676228b58b5d53f72b9d14b3e811d212d1e +--- + src/Makefile.am | 4 +- + src/map-file | 2 + + src/modules/echo-cancel/module-echo-cancel.c | 58 ++++++++++++++++ + src/pulse/ext-echo-cancel.c | 100 +++++++++++++++++++++++++++ + src/pulse/ext-echo-cancel.h | 49 +++++++++++++ + 5 files changed, 212 insertions(+), 1 deletion(-) + create mode 100644 src/pulse/ext-echo-cancel.c + create mode 100644 src/pulse/ext-echo-cancel.h + +diff --git a/src/Makefile.am b/src/Makefile.am +index 96a109c..100dc0d 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -747,6 +747,7 @@ pulseinclude_HEADERS = \ + pulse/ext-device-restore.h \ + pulse/ext-stream-restore.h \ + pulse/ext-node-manager.h \ ++ pulse/ext-echo-cancel.h \ + pulse/format.h \ + pulse/gccmacro.h \ + pulse/introspect.h \ +@@ -793,6 +794,7 @@ libpulse_la_SOURCES = \ + pulse/ext-device-restore.c pulse/ext-device-restore.h \ + pulse/ext-stream-restore.c pulse/ext-stream-restore.h \ + pulse/ext-node-manager.c pulse/ext-node-manager.h \ ++ pulse/ext-echo-cancel.c pulse/ext-echo-cancel.h \ + pulse/format.c pulse/format.h \ + pulse/gccmacro.h \ + pulse/internal.h \ +@@ -1916,7 +1918,7 @@ module_echo_cancel_la_SOURCES = \ + modules/echo-cancel/null.c \ + modules/echo-cancel/echo-cancel.h + module_echo_cancel_la_LDFLAGS = $(MODULE_LDFLAGS) +-module_echo_cancel_la_LIBADD = $(MODULE_LIBADD) $(LIBSPEEX_LIBS) ++module_echo_cancel_la_LIBADD = libprotocol-native.la $(MODULE_LIBADD) $(LIBSPEEX_LIBS) + module_echo_cancel_la_CFLAGS = $(AM_CFLAGS) $(SERVER_CFLAGS) $(LIBSPEEX_CFLAGS) + if HAVE_ADRIAN_EC + module_echo_cancel_la_SOURCES += \ +diff --git a/src/map-file b/src/map-file +index a074a49..f047338 100644 +--- a/src/map-file ++++ b/src/map-file +@@ -170,6 +170,8 @@ pa_ext_stream_restore_set_subscribe_cb; + pa_ext_stream_restore_subscribe; + pa_ext_stream_restore_test; + pa_ext_stream_restore_write; ++pa_ext_echo_cancel_set_volume; ++pa_ext_echo_cancel_set_device; + pa_ext_node_manager_test; + pa_ext_node_manager_read_nodes; + pa_ext_node_manager_connect_nodes; +diff --git a/src/modules/echo-cancel/module-echo-cancel.c b/src/modules/echo-cancel/module-echo-cancel.c +index b45a40c..35d2e9b 100644 +--- a/src/modules/echo-cancel/module-echo-cancel.c ++++ b/src/modules/echo-cancel/module-echo-cancel.c +@@ -53,6 +53,9 @@ + #include + #include + ++#include ++#include ++ + #include "module-echo-cancel-symdef.h" + + PA_MODULE_AUTHOR("Wim Taymans"); +@@ -94,6 +97,11 @@ typedef enum { + #endif + } pa_echo_canceller_method_t; + ++enum { ++ AEC_SET_VOLUME, ++ AEC_SET_DEVICE, ++}; ++ + #ifdef HAVE_WEBRTC + #define DEFAULT_ECHO_CANCELLER "webrtc" + #else +@@ -255,6 +263,8 @@ struct userdata { + struct { + pa_cvolume current_volume; + } thread_info; ++ ++ pa_native_protocol *protocol; + }; + + static void source_output_snapshot_within_thread(struct userdata *u, struct snapshot *snapshot); +@@ -1604,6 +1614,46 @@ static pa_echo_canceller_method_t get_ec_method_from_string(const char *method) + return PA_ECHO_CANCELLER_INVALID; + } + ++static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connection *c, uint32_t tag, pa_tagstruct *t) { ++ uint32_t command; ++ uint32_t value; ++ struct userdata *u = NULL; ++ pa_tagstruct *reply = NULL; ++ pa_assert(p); ++ pa_assert(m); ++ pa_assert(c); ++ pa_assert(t); ++ ++ u = m->userdata; ++ ++ if (pa_tagstruct_getu32(t, &command) < 0) ++ goto fail; ++ ++ reply = pa_tagstruct_new(NULL, 0); ++ pa_tagstruct_putu32(reply, PA_COMMAND_REPLY); ++ pa_tagstruct_putu32(reply, tag); ++ ++ switch (command) { ++ case AEC_SET_VOLUME: { ++ pa_tagstruct_getu32(t,&value); ++ pa_log_debug("AEC_SET_VOLUME in echo cancel = %d",value); ++ break; ++ } ++ case AEC_SET_DEVICE: { ++ pa_tagstruct_getu32(t,&value); ++ pa_log_debug("AEC_SET_DEVICE in echo cancel = %d",value); ++ break; ++ } ++ default: ++ goto fail; ++ } ++ pa_pstream_send_tagstruct(pa_native_connection_get_pstream(c), reply); ++ return 0; ++ ++fail: ++ return -1; ++} ++ + /* Common initialisation bits between module-echo-cancel and the standalone + * test program. + * +@@ -1994,6 +2044,9 @@ int pa__init(pa_module*m) { + + u->thread_info.current_volume = u->source->reference_volume; + ++ u->protocol = pa_native_protocol_get(m->core); ++ pa_native_protocol_install_ext(u->protocol, m, extension_cb); ++ + pa_sink_put(u->sink); + pa_source_put(u->source); + +@@ -2071,6 +2124,11 @@ void pa__done(pa_module*m) { + pa_xfree(u->ec); + } + ++ if (u->protocol) { ++ pa_native_protocol_remove_ext(u->protocol, m); ++ pa_native_protocol_unref(u->protocol); ++ } ++ + if (u->asyncmsgq) + pa_asyncmsgq_unref(u->asyncmsgq); + +diff --git a/src/pulse/ext-echo-cancel.c b/src/pulse/ext-echo-cancel.c +new file mode 100644 +index 0000000..9339939 +--- /dev/null ++++ b/src/pulse/ext-echo-cancel.c +@@ -0,0 +1,100 @@ ++/*** ++ This file is part of PulseAudio. ++ ++ PulseAudio is free software; you can redistribute it and/or modify ++ it under the terms of the GNU Lesser General Public License as published ++ by the Free Software Foundation; either version 2.1 of the License, ++ or (at your option) any later version. ++ ++ PulseAudio is distributed in the hope that it will be useful, but ++ WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public License ++ along with PulseAudio; if not, write to the Free Software ++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 ++ USA. ++***/ ++ ++#ifdef HAVE_CONFIG_H ++#include ++#endif ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include "internal.h" ++#include "operation.h" ++#include "fork-detect.h" ++ ++#include "ext-echo-cancel.h" ++ ++enum { ++ AEC_SET_VOLUME, ++ AEC_SET_DEVICE, ++}; ++ ++pa_operation *pa_ext_echo_cancel_set_device ( ++ pa_context *c, ++ int device, ++ pa_context_success_cb_t cb, ++ void *userdata) { ++ ++ uint32_t tag; ++ pa_operation *o = NULL; ++ pa_tagstruct *t = NULL; ++ ++ pa_assert(c); ++ pa_assert(PA_REFCNT_VALUE(c) >= 1); ++ PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED); ++ PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); ++ PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED); ++ ++ o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); ++ ++ t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag); ++ pa_tagstruct_putu32(t, PA_INVALID_INDEX); ++ pa_tagstruct_puts(t, "module-echo-cancel"); ++ pa_tagstruct_putu32(t, AEC_SET_DEVICE); ++ pa_tagstruct_putu32(t, device); ++ ++ pa_pstream_send_tagstruct(c->pstream, t); ++ pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref); ++ return o; ++} ++ ++ ++pa_operation *pa_ext_echo_cancel_set_volume ( ++ pa_context *c, ++ int volume, ++ pa_context_success_cb_t cb, ++ void *userdata) { ++ ++ uint32_t tag; ++ pa_operation *o = NULL; ++ pa_tagstruct *t = NULL; ++ ++ pa_assert(c); ++ pa_assert(PA_REFCNT_VALUE(c) >= 1); ++ PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED); ++ PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); ++ PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED); ++ ++ o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); ++ ++ t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag); ++ pa_tagstruct_putu32(t, PA_INVALID_INDEX); ++ pa_tagstruct_puts(t, "module-echo-cancel"); ++ pa_tagstruct_putu32(t, AEC_SET_VOLUME); ++ pa_tagstruct_putu32(t, volume); ++ ++ pa_pstream_send_tagstruct(c->pstream, t); ++ pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref); ++ ++ return o; ++} +diff --git a/src/pulse/ext-echo-cancel.h b/src/pulse/ext-echo-cancel.h +new file mode 100644 +index 0000000..12e4eeb +--- /dev/null ++++ b/src/pulse/ext-echo-cancel.h +@@ -0,0 +1,49 @@ ++#ifndef foopulseechocancelfoo ++#define foopulseechocancelfoo ++ ++/*** ++ This file is part of PulseAudio. ++ ++ PulseAudio is free software; you can redistribute it and/or modify ++ it under the terms of the GNU Lesser General Public License as published ++ by the Free Software Foundation; either version 2.1 of the License, ++ or (at your option) any later version. ++ ++ PulseAudio is distributed in the hope that it will be useful, but ++ WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public License ++ along with PulseAudio; if not, write to the Free Software ++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 ++ USA. ++***/ ++ ++#include ++#include ++ ++/** \file ++ * ++ * Routines for controlling module-echo-cancel ++ */ ++ ++PA_C_DECL_BEGIN ++ ++/** Set volume to AEC module */ ++pa_operation *pa_ext_echo_cancel_set_volume ( ++ pa_context *c, ++ int volume, ++ pa_context_success_cb_t cb, ++ void *userdata); ++ ++pa_operation *pa_ext_echo_cancel_set_device ( ++ pa_context *c, ++ int device, ++ pa_context_success_cb_t cb, ++ void *userdata); ++ ++ ++PA_C_DECL_END ++ ++#endif +-- +1.8.1.4 + diff --git a/meta-wrt-tizen/recipes-multimedia/pulseaudio/files/0005-TIZEN-add-support-for-dlog-samsung.patch b/meta-wrt-tizen/recipes-multimedia/pulseaudio/files/0005-TIZEN-add-support-for-dlog-samsung.patch new file mode 100644 index 0000000..06dd606 --- /dev/null +++ b/meta-wrt-tizen/recipes-multimedia/pulseaudio/files/0005-TIZEN-add-support-for-dlog-samsung.patch @@ -0,0 +1,214 @@ +From e8acc45092a360a39a2605b81005efc84b42c66a Mon Sep 17 00:00:00 2001 +From: "vivian,zhang" +Date: Tue, 18 Jun 2013 16:20:04 +0800 +Subject: [PATCH 5/6] add support for dlog - samsung + +Change-Id: Id795c76941710aaf7c984f375f0f0e51297ada50 +--- + configure.ac | 18 ++++++++++ + src/Makefile.am | 9 +++++ + src/daemon/daemon-conf.c | 8 +++++ + src/pulsecore/log.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++ + src/pulsecore/log.h | 4 +++ + 5 files changed, 128 insertions(+) + +diff --git a/configure.ac b/configure.ac +index 32bedf2..f251643 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -635,6 +635,24 @@ PKG_CHECK_MODULES(LIBSNDFILE, [ sndfile >= 1.0.20 ]) + AC_SUBST(LIBSNDFILE_CFLAGS) + AC_SUBST(LIBSNDFILE_LIBS) + ++dnl use dlog -------------------------------------------------------------------------- ++AC_ARG_ENABLE(dlog, AC_HELP_STRING([--enable-dlog], [using dlog]), ++[ ++ case "${enableval}" in ++ yes) USE_DLOG=yes ;; ++ no) USE_DLOG=no ;; ++ *) AC_MSG_ERROR(bad value ${enableval} for --enable-dlog) ;; ++ esac ++ ],[USE_DLOG=no]) ++ ++if test "x$USE_DLOG" = "xyes"; then ++ PKG_CHECK_MODULES(DLOG, dlog) ++ AC_SUBST(DLOG_CFLAGS) ++ AC_SUBST(DLOG_LIBS) ++fi ++AM_CONDITIONAL(USE_DLOG, test "x$USE_DLOG" = "xyes") ++dnl end -------------------------------------------------------------------- ++ + #### atomic-ops #### + + AC_MSG_CHECKING([whether we need libatomic_ops]) +diff --git a/src/Makefile.am b/src/Makefile.am +index 6a31031..95e58f4 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -172,6 +172,10 @@ else + pulseaudio_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(IMMEDIATE_LDFLAGS) -dlopen force $(foreach f,$(PREOPEN_LIBS),-dlopen $(f)) + endif + ++if USE_DLOG ++pulseaudio_CFLAGS += -DUSE_DLOG ++endif ++ + ################################### + # Utility programs # + ################################### +@@ -721,6 +725,11 @@ libpulsecommon_@PA_MAJORMINOR@_la_CFLAGS += $(DBUS_CFLAGS) + libpulsecommon_@PA_MAJORMINOR@_la_LIBADD += $(DBUS_LIBS) + endif + ++if USE_DLOG ++libpulsecommon_@PA_MAJORMINOR@_la_CFLAGS += $(DLOG_CFLAGS) -DUSE_DLOG ++libpulsecommon_@PA_MAJORMINOR@_la_LIBADD += $(DLOG_LIBS) ++endif ++ + ################################### + # Client library # + ################################### +diff --git a/src/daemon/daemon-conf.c b/src/daemon/daemon-conf.c +index f1e5476..19e3a2d 100644 +--- a/src/daemon/daemon-conf.c ++++ b/src/daemon/daemon-conf.c +@@ -236,6 +236,14 @@ int pa_daemon_conf_set_log_target(pa_daemon_conf *c, const char *string) { + c->log_target = PA_LOG_FD; + pa_log_set_fd(log_fd); + } ++#ifdef USE_DLOG ++ } else if (!strcmp(string, "dlog")) { ++ c->auto_log_target = 0; ++ c->log_target = PA_LOG_DLOG; ++ } else if (!strcmp(string, "dlog-color")) { ++ c->auto_log_target = 0; ++ c->log_target = PA_LOG_DLOG_COLOR; ++#endif + } else + return -1; + +diff --git a/src/pulsecore/log.c b/src/pulsecore/log.c +index 8eaef54..02baa6b 100644 +--- a/src/pulsecore/log.c ++++ b/src/pulsecore/log.c +@@ -53,6 +53,27 @@ + + #include "log.h" + ++#ifdef USE_DLOG ++#include ++#define DLOG_TAG "PULSEAUDIO" ++ ++#define COLOR_BLACK 30 ++#define COLOR_RED 31 ++#define COLOR_GREEN 32 ++#define COLOR_BLUE 34 ++#define COLOR_MAGENTA 35 ++#define COLOR_CYAN 36 ++#define COLOR_WHITE 97 ++#define COLOR_B_GRAY 100 ++#define COLOR_B_RED 101 ++#define COLOR_B_GREEN 102 ++#define COLOR_B_YELLOW 103 ++#define COLOR_B_BLUE 104 ++#define COLOR_B_MAGENTA 105 ++#define COLOR_B_CYAN 106 ++#define COLOR_REVERSE 7 ++ ++#endif + #define ENV_LOG_SYSLOG "PULSE_LOG_SYSLOG" + #define ENV_LOG_LEVEL "PULSE_LOG" + #define ENV_LOG_COLORS "PULSE_LOG_COLORS" +@@ -410,6 +431,74 @@ void pa_log_levelv_meta( + } + #endif + ++#ifdef USE_DLOG ++ case PA_LOG_DLOG: { ++ char *local_t; ++ ++ openlog(ident, LOG_PID, LOG_USER); ++ ++ if ((local_t = pa_utf8_to_locale(t))) ++ t = local_t; ++ ++ switch (level) ++ { ++ case PA_LOG_DEBUG: ++ SLOG (LOG_DEBUG, DLOG_TAG, "%s%s%s%s", timestamp, location, t, pa_strempty(bt)); ++ break; ++ case PA_LOG_INFO: ++ case PA_LOG_NOTICE: // no notice category in dlog, use info instead. ++ SLOG (LOG_INFO, DLOG_TAG, "%s%s%s%s", timestamp, location, t, pa_strempty(bt)); ++ break; ++ case PA_LOG_WARN: ++ SLOG (LOG_WARN, DLOG_TAG, "%s%s%s%s", timestamp, location, t, pa_strempty(bt)); ++ break; ++ case PA_LOG_ERROR: ++ SLOG (LOG_ERROR, DLOG_TAG, "%s%s%s%s", timestamp, location, t, pa_strempty(bt)); ++ break; ++ default: ++ SLOG (LOG_DEBUG, DLOG_TAG, "%s%s%s%s", timestamp, location, t, pa_strempty(bt)); ++ break; ++ } ++ ++ pa_xfree(local_t); ++ ++ break; ++ } ++ case PA_LOG_DLOG_COLOR: { ++ char *local_t; ++ ++ openlog(ident, LOG_PID, LOG_USER); ++ ++ if ((local_t = pa_utf8_to_locale(t))) ++ t = local_t; ++ ++ switch (level) ++ { ++ case PA_LOG_DEBUG: ++ SLOG (LOG_DEBUG, DLOG_TAG, "\033[%dm%s%s%s%s\033[0m", COLOR_GREEN, timestamp, location, t, pa_strempty(bt)); ++ break; ++ case PA_LOG_INFO: ++ case PA_LOG_NOTICE: // no notice category in dlog, use info instead. ++ SLOG (LOG_INFO, DLOG_TAG, "\033[%dm%s%s%s%s\033[0m", COLOR_BLUE, timestamp, location, t, pa_strempty(bt)); ++ break; ++ case PA_LOG_WARN: ++ SLOG (LOG_WARN, DLOG_TAG, "\033[%dm%s%s%s%s\033[0m", COLOR_MAGENTA, timestamp, location, t, pa_strempty(bt)); ++ break; ++ case PA_LOG_ERROR: ++ SLOG (LOG_ERROR, DLOG_TAG, "\033[%dm%s%s%s%s\033[0m", COLOR_RED, timestamp, location, t, pa_strempty(bt)); ++ break; ++ default: ++ SLOG (LOG_DEBUG, DLOG_TAG, "%s%s%s%s", timestamp, location, t, pa_strempty(bt)); ++ break; ++ } ++ ++ pa_xfree(local_t); ++ ++ break; ++ } ++ ++#endif ++ + case PA_LOG_FD: { + if (log_fd >= 0) { + char metadata[256]; +diff --git a/src/pulsecore/log.h b/src/pulsecore/log.h +index 8dd056b..082bbcd 100644 +--- a/src/pulsecore/log.h ++++ b/src/pulsecore/log.h +@@ -35,6 +35,10 @@ + typedef enum pa_log_target { + PA_LOG_STDERR, /* default */ + PA_LOG_SYSLOG, ++#ifdef USE_DLOG ++ PA_LOG_DLOG, ++ PA_LOG_DLOG_COLOR, ++#endif + PA_LOG_NULL, /* to /dev/null */ + PA_LOG_FD, /* to a file descriptor, e.g. a char device */ + PA_LOG_TARGET_MAX +-- +1.8.1.4 + diff --git a/meta-wrt-tizen/recipes-multimedia/pulseaudio/files/0006-TIZEN-add-policy-module-samsung.patch b/meta-wrt-tizen/recipes-multimedia/pulseaudio/files/0006-TIZEN-add-policy-module-samsung.patch new file mode 100644 index 0000000..e8cebac --- /dev/null +++ b/meta-wrt-tizen/recipes-multimedia/pulseaudio/files/0006-TIZEN-add-policy-module-samsung.patch @@ -0,0 +1,1308 @@ +From 753745220a0ef94f1c2219801be2715a4780fd11 Mon Sep 17 00:00:00 2001 +From: "vivian,zhang" +Date: Tue, 18 Jun 2013 16:21:32 +0800 +Subject: [PATCH] add policy module - samsung + +Change-Id: I50921a731805f180cff2feffff240c0808124685 +--- + configure.ac | 4 + + src/Makefile.am | 15 +- + src/map-file | 3 + + src/modules/module-policy.c | 926 ++++++++++++++++++++++++++++++++++++++++++++ + src/pulse/ext-policy.c | 177 +++++++++ + src/pulse/ext-policy.h | 61 +++ + src/pulse/proplist.h | 3 + + 7 files changed, 1186 insertions(+), 3 deletions(-) + create mode 100644 src/modules/module-policy.c + create mode 100644 src/pulse/ext-policy.c + create mode 100644 src/pulse/ext-policy.h + +diff --git a/configure.ac b/configure.ac +index aa3c3d9..c4e3b1f 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -638,6 +638,10 @@ PKG_CHECK_MODULES(LIBSNDFILE, [ sndfile >= 1.0.20 ]) + AC_SUBST(LIBSNDFILE_CFLAGS) + AC_SUBST(LIBSNDFILE_LIBS) + ++PKG_CHECK_MODULES(VCONF, vconf) ++AC_SUBST(VCONF_CFLAGS) ++AC_SUBST(VCONF_LIBS) ++ + dnl use dlog -------------------------------------------------------------------------- + AC_ARG_ENABLE(dlog, AC_HELP_STRING([--enable-dlog], [using dlog]), + [ +diff --git a/src/Makefile.am b/src/Makefile.am +index b176860..e9afeef 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -149,7 +149,7 @@ pulseaudio_SOURCES = \ + daemon/ltdl-bind-now.c daemon/ltdl-bind-now.h \ + daemon/main.c + +-pulseaudio_CFLAGS = $(AM_CFLAGS) $(CAP_CFLAGS) ++pulseaudio_CFLAGS = $(AM_CFLAGS) $(LIBSNDFILE_CFLAGS) $(CAP_CFLAGS) $(DBUS_CFLAGS) + pulseaudio_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@PA_MAJORMINOR@.la libpulse.la $(LIBLTDL) $(CAP_LIBS) + # This is needed because automake doesn't properly expand the foreach below + pulseaudio_DEPENDENCIES = libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@PA_MAJORMINOR@.la libpulse.la $(PREOPEN_LIBS) +@@ -757,6 +757,7 @@ pulseinclude_HEADERS = \ + pulse/ext-stream-restore.h \ + pulse/ext-node-manager.h \ + pulse/ext-echo-cancel.h \ ++ pulse/ext-policy.h \ + pulse/format.h \ + pulse/gccmacro.h \ + pulse/introspect.h \ +@@ -804,6 +805,7 @@ libpulse_la_SOURCES = \ + pulse/ext-stream-restore.c pulse/ext-stream-restore.h \ + pulse/ext-node-manager.c pulse/ext-node-manager.h \ + pulse/ext-echo-cancel.c pulse/ext-echo-cancel.h \ ++ pulse/ext-policy.c pulse/ext-policy.h \ + pulse/format.c pulse/format.h \ + pulse/gccmacro.h \ + pulse/internal.h \ +@@ -1079,7 +1081,8 @@ libavahi_wrap_la_LIBADD = $(AM_LIBADD) $(AVAHI_CFLAGS) libpulsecore-@PA_MAJORMIN + if HAVE_DBUS + # Serveral module (e.g. libalsa-util.la) + modlibexec_LTLIBRARIES += \ +- module-console-kit.la ++ module-console-kit.la \ ++ module-policy.la + endif + + modlibexec_LTLIBRARIES += \ +@@ -1445,7 +1448,8 @@ SYMDEF_FILES = \ + module-switch-on-connect-symdef.h \ + module-switch-on-port-available-symdef.h \ + module-filter-apply-symdef.h \ +- module-filter-heuristics-symdef.h ++ module-filter-heuristics-symdef.h \ ++ module-policy-symdef.h + + if HAVE_ESOUND + SYMDEF_FILES += \ +@@ -2072,6 +2076,11 @@ module_rygel_media_server_la_LDFLAGS = $(MODULE_LDFLAGS) + module_rygel_media_server_la_LIBADD = $(MODULE_LIBADD) $(DBUS_LIBS) libprotocol-http.la + module_rygel_media_server_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS) + ++module_policy_la_SOURCES = modules/module-policy.c ++module_policy_la_LDFLAGS = $(MODULE_LDFLAGS) ++module_policy_la_LIBADD = $(AM_LIBADD) $(DBUS_LIBS) $(VCONF_LIBS) libprotocol-native.la libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@PA_MAJORMINOR@.la libpulse.la ++module_policy_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS) $(VCONF_CFLAGS) ++ + ################################### + # Some minor stuff # + ################################### +diff --git a/src/map-file b/src/map-file +index f047338..e40fc75 100644 +--- a/src/map-file ++++ b/src/map-file +@@ -170,6 +170,9 @@ pa_ext_stream_restore_set_subscribe_cb; + pa_ext_stream_restore_subscribe; + pa_ext_stream_restore_test; + pa_ext_stream_restore_write; ++pa_ext_policy_test; ++pa_ext_policy_set_mono; ++pa_ext_policy_set_balance; + pa_ext_echo_cancel_set_volume; + pa_ext_echo_cancel_set_device; + pa_ext_node_manager_test; +diff --git a/src/modules/module-policy.c b/src/modules/module-policy.c +new file mode 100644 +index 0000000..8978346 +--- /dev/null ++++ b/src/modules/module-policy.c +@@ -0,0 +1,926 @@ ++#ifdef HAVE_CONFIG_H ++#include ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include // for mono ++ ++#include "module-policy-symdef.h" ++ ++PA_MODULE_AUTHOR("Seungbae Shin"); ++PA_MODULE_DESCRIPTION("Media Policy module"); ++PA_MODULE_VERSION(PACKAGE_VERSION); ++PA_MODULE_LOAD_ONCE(TRUE); ++PA_MODULE_USAGE( ++ "on_hotplug= "); ++ ++static const char* const valid_modargs[] = { ++ "on_hotplug", ++ NULL ++}; ++ ++struct userdata { ++ pa_core *core; ++ pa_module *module; ++ ++ pa_hook_slot *sink_input_new_hook_slot,*sink_put_hook_slot; ++ ++ pa_hook_slot *sink_input_unlink_slot,*sink_unlink_slot; ++ pa_hook_slot *sink_input_unlink_post_slot, *sink_unlink_post_slot; ++ pa_hook_slot *sink_input_move_start_slot,*sink_input_move_finish_slot; ++ pa_subscription *subscription; ++ ++ pa_bool_t on_hotplug:1; ++ int bt_off_idx; ++ ++ int is_mono; ++ float balance; ++ pa_module* module_mono_bt; ++ pa_module* module_combined; ++ pa_module* module_mono_combined; ++ pa_native_protocol *protocol; ++ pa_hook_slot *source_output_new_hook_slot; ++}; ++ ++enum { ++ SUBCOMMAND_TEST, ++ SUBCOMMAND_MONO, ++ SUBCOMMAND_BALANCE, ++}; ++ ++/* DEFINEs */ ++#define AEC_SINK "alsa_output.0.analog-stereo.echo-cancel" ++#define AEC_SOURCE "alsa_input.0.analog-stereo.echo-cancel" ++#define SINK_ALSA "alsa_output.0.analog-stereo" ++#define SINK_MONO_ALSA "mono_alsa" ++#define SINK_MONO_BT "mono_bt" ++#define SINK_COMBINED "combined" ++#define SINK_MONO_COMBINED "mono_combined" ++#define POLICY_AUTO "auto" ++#define POLICY_PHONE "phone" ++#define POLICY_ALL "all" ++#define POLICY_VOIP "voip" ++#define BLUEZ_API "bluez" ++#define ALSA_API "alsa" ++#define MONO_KEY VCONFKEY_SETAPPL_ACCESSIBILITY_MONO_AUDIO ++ ++/* check if this sink is bluez */ ++static pa_bool_t policy_is_bluez (pa_sink* sink) ++{ ++ const char* api_name = NULL; ++ ++ if (sink == NULL) { ++ pa_log_warn ("input param sink is null"); ++ return FALSE; ++ } ++ ++ api_name = pa_proplist_gets(sink->proplist, PA_PROP_DEVICE_API); ++ if (api_name) { ++ if (pa_streq (api_name, BLUEZ_API)) { ++#ifdef DEBUG_DETAIL ++ pa_log_debug("[POLICY][%s] [%s] exists and it is [%s]...TRUE !!", __func__, PA_PROP_DEVICE_API, api_name); ++#endif ++ return TRUE; ++ } else { ++#ifdef DEBUG_DETAIL ++ pa_log_debug("[POLICY][%s] [%s] exists, but not bluez...FALSE !!", __func__, PA_PROP_DEVICE_API); ++#endif ++ } ++ } else { ++#ifdef DEBUG_DETAIL ++ pa_log_debug("[POLICY][%s] No [%s] exists...FALSE!!", __func__, PA_PROP_DEVICE_API); ++#endif ++ } ++ ++ return FALSE; ++} ++ ++/* check if this sink is bluez */ ++static pa_bool_t policy_is_usb_alsa (pa_sink* sink) ++{ ++ const char* api_name = NULL; ++ const char* device_bus_name = NULL; ++ ++ if (sink == NULL) { ++ pa_log_warn ("input param sink is null"); ++ return FALSE; ++ } ++ ++ api_name = pa_proplist_gets(sink->proplist, PA_PROP_DEVICE_API); ++ if (api_name) { ++ if (pa_streq (api_name, ALSA_API)) { ++#ifdef DEBUG_DETAIL ++ pa_log_debug("[POLICY][%s] [%s] exists and it is [%s]...TRUE !!", __func__, PA_PROP_DEVICE_API, api_name); ++#endif ++ device_bus_name = pa_proplist_gets(sink->proplist, PA_PROP_DEVICE_BUS); ++ if (device_bus_name) { ++ if (pa_streq (device_bus_name, "usb")) { ++ return TRUE; ++ } ++ } ++ } else { ++#ifdef DEBUG_DETAIL ++ pa_log_debug("[POLICY][%s] [%s] exists, but not alsa...FALSE !!", __func__, PA_PROP_DEVICE_API); ++#endif ++ } ++ } else { ++#ifdef DEBUG_DETAIL ++ pa_log_debug("[POLICY][%s] No [%s] exists...FALSE!!", __func__, PA_PROP_DEVICE_API); ++#endif ++ } ++ ++ return FALSE; ++} ++ ++/* Get sink by name */ ++static pa_sink* policy_get_sink_by_name (pa_core *c, const char* sink_name) ++{ ++ pa_sink *s = NULL; ++ uint32_t idx; ++ ++ if (c == NULL || sink_name == NULL) { ++ pa_log_warn ("input param is null"); ++ return NULL; ++ } ++ ++ PA_IDXSET_FOREACH(s, c->sinks, idx) { ++ if (pa_streq (s->name, sink_name)) { ++ pa_log_debug ("[POLICY][%s] return [%p] for [%s]\n", __func__, s, sink_name); ++ return s; ++ } ++ } ++ return NULL; ++} ++ ++/* Get bt sink if available */ ++static pa_sink* policy_get_bt_sink (pa_core *c) ++{ ++ pa_sink *s = NULL; ++ uint32_t idx; ++ ++ if (c == NULL) { ++ pa_log_warn ("input param is null"); ++ return NULL; ++ } ++ ++ PA_IDXSET_FOREACH(s, c->sinks, idx) { ++ if (policy_is_bluez (s)) { ++ pa_log_debug ("[POLICY][%s] return [%p] for [%s]\n", __func__, s, s->name); ++ return s; ++ } ++ } ++ return NULL; ++} ++ ++/* Select sink for given condition */ ++static pa_sink* policy_select_proper_sink (pa_core *c, const char* policy, int is_mono) ++{ ++ pa_sink* sink = NULL; ++ pa_sink* bt_sink = NULL; ++ pa_sink* def = NULL; ++ ++ if (c == NULL || policy == NULL) { ++ pa_log_warn ("input param is null"); ++ return NULL; ++ } ++ ++ pa_assert (c); ++ ++ bt_sink = policy_get_bt_sink(c); ++ def = pa_namereg_get_default_sink(c); ++ if (def == NULL) { ++ pa_log_warn ("POLICY][%s] pa_namereg_get_default_sink() returns null", __func__); ++ return NULL; ++ } ++ ++ pa_log_debug ("[POLICY][%s] policy[%s], is_mono[%d], current default[%s], bt sink[%s]\n", ++ __func__, policy, is_mono, def->name, (bt_sink)? bt_sink->name:"null"); ++ ++ /* Select sink to */ ++ if (pa_streq(policy, POLICY_ALL)) { ++ /* all */ ++ if (bt_sink) { ++ sink = policy_get_sink_by_name(c, (is_mono)? SINK_MONO_COMBINED : SINK_COMBINED); ++ } else { ++ sink = policy_get_sink_by_name (c, (is_mono)? SINK_MONO_ALSA : SINK_ALSA); ++ } ++ ++ } else if (pa_streq(policy, POLICY_PHONE)) { ++ /* phone */ ++ sink = policy_get_sink_by_name (c, (is_mono)? SINK_MONO_ALSA : SINK_ALSA); ++ } else if (pa_streq(policy, POLICY_VOIP)) { ++ /* VOIP */ ++ sink = policy_get_sink_by_name (c,AEC_SINK); ++ } else { ++ /* auto */ ++ if (policy_is_bluez(def)) { ++ sink = (is_mono)? policy_get_sink_by_name (c, SINK_MONO_BT) : def; ++ } else if (policy_is_usb_alsa(def)) { ++ sink = def; ++ } else { ++ sink = (is_mono)? policy_get_sink_by_name (c, SINK_MONO_ALSA) : def; ++ } ++ } ++ ++ pa_log_debug ("[POLICY][%s] selected sink : [%s]\n", __func__, (sink)? sink->name : "null"); ++ return sink; ++} ++ ++static pa_bool_t policy_is_filter (pa_sink_input* si) ++{ ++ const char* role = NULL; ++ ++ if (si == NULL) { ++ pa_log_warn ("input param sink-input is null"); ++ return FALSE; ++ } ++ ++ if ((role = pa_proplist_gets(si->proplist, PA_PROP_MEDIA_ROLE))) { ++#ifdef DEBUG_DETAIL ++ pa_log_debug("[POLICY][%s] Role of sink input [%d] = %s", __func__, si->index, role); ++#endif ++ if (pa_streq(role, "filter")) { ++#ifdef DEBUG_DETAIL ++ pa_log_debug("[POLICY] no need to change of sink for %s", role); ++#endif ++ return TRUE; ++ } ++ } ++ ++ return FALSE; ++} ++ ++ ++ ++#define EXT_VERSION 1 ++ ++static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connection *c, uint32_t tag, pa_tagstruct *t) { ++ struct userdata *u = NULL; ++ uint32_t command; ++ pa_tagstruct *reply = NULL; ++ ++ pa_sink_input *si = NULL; ++ pa_sink *s = NULL; ++ uint32_t idx; ++ pa_sink* sink_to_move = NULL; ++ ++ pa_assert(p); ++ pa_assert(m); ++ pa_assert(c); ++ pa_assert(t); ++ ++ u = m->userdata; ++ ++ if (pa_tagstruct_getu32(t, &command) < 0) ++ goto fail; ++ ++ reply = pa_tagstruct_new(NULL, 0); ++ pa_tagstruct_putu32(reply, PA_COMMAND_REPLY); ++ pa_tagstruct_putu32(reply, tag); ++ ++ switch (command) { ++ case SUBCOMMAND_TEST: { ++ if (!pa_tagstruct_eof(t)) ++ goto fail; ++ ++ pa_tagstruct_putu32(reply, EXT_VERSION); ++ break; ++ } ++ ++ case SUBCOMMAND_MONO: { ++ ++ pa_bool_t enable; ++ ++ if (pa_tagstruct_get_boolean(t, &enable) < 0) ++ goto fail; ++ ++ pa_log_debug ("[POLICY][%s] new mono value = %d\n", __func__, enable); ++ if (enable == u->is_mono) { ++ pa_log_debug ("[POLICY][%s] No changes in mono value = %d", __func__, u->is_mono); ++ break; ++ } ++ ++ u->is_mono = enable; ++ ++ /* Move current sink-input to proper mono sink */ ++ PA_IDXSET_FOREACH(si, u->core->sink_inputs, idx) { ++ const char *policy = NULL; ++ ++ /* Skip this if it is already in the process of being moved ++ * anyway */ ++ if (!si->sink) ++ continue; ++ ++ /* It might happen that a stream and a sink are set up at the ++ same time, in which case we want to make sure we don't ++ interfere with that */ ++ if (!PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(si))) ++ continue; ++ ++ /* Get role (if role is filter, skip it) */ ++ if (policy_is_filter(si)) ++ continue; ++ ++ /* Check policy, if no policy exists, treat as AUTO */ ++ if (!(policy = pa_proplist_gets(si->proplist, PA_PROP_MEDIA_POLICY))) { ++ pa_log_debug("[POLICY] set policy of sink-input[%d] from [%s] to [auto]", si->index, "null"); ++ policy = POLICY_AUTO; ++ } ++ pa_log_debug("[POLICY] Policy of sink input [%d] = %s", si->index, policy); ++ ++ /* Select sink to move and move to it */ ++ sink_to_move = policy_select_proper_sink (u->core, policy, u->is_mono); ++ if (sink_to_move) { ++ pa_log_debug("[POLICY][%s] Moving sink-input[%d] from [%s] to [%s]", __func__, si->index, si->sink->name, sink_to_move->name); ++ pa_sink_input_move_to(si, sink_to_move, FALSE); ++ } else { ++ pa_log_debug("[POLICY][%s] Can't move sink-input....", __func__); ++ } ++ } ++ break; ++ } ++ ++ case SUBCOMMAND_BALANCE: { ++ float balance; ++ pa_cvolume cvol; ++ pa_channel_map map; ++ ++ if (pa_tagstruct_get_cvolume(t, &cvol) < 0) ++ goto fail; ++ ++ pa_channel_map_init_stereo(&map); ++ balance = pa_cvolume_get_balance(&cvol, &map); ++ ++ pa_log_debug ("[POLICY][%s] new balance value = [%f]\n", __func__, balance); ++ ++ if (balance == u->balance) { ++ pa_log_debug ("[POLICY][%s] No changes in balance value = [%f]", __func__, u->balance); ++ break; ++ } ++ ++ u->balance = balance; ++ ++ /* Apply balance value to each Sinks */ ++ PA_IDXSET_FOREACH(s, u->core->sinks, idx) { ++ pa_cvolume* cvol = pa_sink_get_volume (s, false); ++ pa_cvolume_set_balance (cvol, &s->channel_map, u->balance); ++ pa_sink_set_volume(s, cvol, TRUE, TRUE); ++ } ++ break; ++ } ++ ++ default: ++ goto fail; ++ } ++ ++ pa_pstream_send_tagstruct(pa_native_connection_get_pstream(c), reply); ++ return 0; ++ ++ fail: ++ ++ if (reply) ++ pa_tagstruct_free(reply); ++ ++ return -1; ++} ++ ++/* Called when new sink-input is creating */ ++static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_new_data *new_data, struct userdata *u) ++{ ++ const char *policy = NULL; ++ ++ pa_assert(c); ++ pa_assert(new_data); ++ pa_assert(u); ++ ++ if (!new_data->proplist) { ++ pa_log_debug("[POLICY] New stream lacks property data."); ++ return PA_HOOK_OK; ++ } ++ ++ /* If sink-input has already sink, skip */ ++ if (new_data->sink) { ++ /* sink-input with filter role will be also here because sink is already set */ ++#ifdef DEBUG_DETAIL ++ pa_log_debug("[POLICY] Not setting device for stream [%s], because already set.", ++ pa_strnull(pa_proplist_gets(new_data->proplist, PA_PROP_MEDIA_NAME))); ++#endif ++ return PA_HOOK_OK; ++ } ++ ++ /* If no policy exists, skip */ ++ if (!(policy = pa_proplist_gets(new_data->proplist, PA_PROP_MEDIA_POLICY))) { ++ pa_log_debug("[POLICY][%s] Not setting device for stream [%s], because it lacks policy.", ++ __func__, pa_strnull(pa_proplist_gets(new_data->proplist, PA_PROP_MEDIA_NAME))); ++ return PA_HOOK_OK; ++ } ++ pa_log_debug("[POLICY][%s] Policy for stream [%s] = [%s]", ++ __func__, pa_strnull(pa_proplist_gets(new_data->proplist, PA_PROP_MEDIA_NAME)), policy); ++ ++ /* Set proper sink to sink-input */ ++ pa_sink* new_sink = policy_select_proper_sink(c, policy, u->is_mono); ++ if(new_sink != new_data->sink) ++ { ++ pa_sink_input_new_data_set_sink(new_data, new_sink, FALSE); ++ } ++ /*new_data->save_sink = FALSE; ++ new_data->sink = policy_select_proper_sink (c, policy, u->is_mono);*/ ++ pa_log_debug("[POLICY][%s] set sink of sink-input to [%s]", __func__, (new_data->sink)? new_data->sink->name : "null"); ++ ++ return PA_HOOK_OK; ++} ++ ++/* Called when new sink is added while sink-input is existing */ ++static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, struct userdata *u) ++{ ++ pa_sink_input *si; ++ pa_sink *sink_to_move; ++ uint32_t idx; ++ char *args = NULL; ++ ++ pa_bool_t is_bt; ++ pa_bool_t is_usb_alsa; ++ ++ pa_assert(c); ++ pa_assert(sink); ++ pa_assert(u); ++ pa_assert(u->on_hotplug); ++ ++ /* If connected sink is BLUETOOTH, set as default */ ++ /* we are checking with device.api property */ ++ is_bt = policy_is_bluez(sink); ++ is_usb_alsa = policy_is_usb_alsa(sink); ++ ++ if (is_bt || is_usb_alsa) { ++ pa_log_debug("[POLICY][%s] set default sink to sink[%s][%d]", __func__, sink->name, sink->index); ++ pa_namereg_set_default_sink (c,sink); ++ } else { ++ pa_log_debug("[POLICY][%s] this sink [%s][%d] is not a bluez....return", __func__, sink->name, sink->index); ++ return PA_HOOK_OK; ++ } ++ ++ if (is_bt) { ++ /* Load mono_bt sink */ ++ args = pa_sprintf_malloc("sink_name=%s master=%s channels=1", SINK_MONO_BT, sink->name); ++ u->module_mono_bt = pa_module_load(u->module->core, "module-remap-sink", args); ++ pa_xfree(args); ++ ++ /* load combine sink */ ++ args = pa_sprintf_malloc("sink_name=%s slaves=\"%s,%s\"", SINK_COMBINED, sink->name, SINK_ALSA); ++ u->module_combined = pa_module_load(u->module->core, "module-combine", args); ++ pa_xfree(args); ++ ++ /* load mono_combine sink */ ++ args = pa_sprintf_malloc("sink_name=%s master=%s channels=1", SINK_MONO_COMBINED, SINK_COMBINED); ++ u->module_mono_combined = pa_module_load(u->module->core, "module-remap-sink", args); ++ pa_xfree(args); ++ } ++ ++ /* Iterate each sink inputs to decide whether we should move to new sink */ ++ PA_IDXSET_FOREACH(si, c->sink_inputs, idx) { ++ const char *policy = NULL; ++ ++ if (si->sink == sink) ++ continue; ++ ++ /* Skip this if it is already in the process of being moved ++ * anyway */ ++ if (!si->sink) ++ continue; ++ ++ /* It might happen that a stream and a sink are set up at the ++ same time, in which case we want to make sure we don't ++ interfere with that */ ++ if (!PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(si))) ++ continue; ++ ++ /* Get role (if role is filter, skip it) */ ++ if (policy_is_filter(si)) ++ continue; ++ ++ /* Check policy */ ++ if (!(policy = pa_proplist_gets(si->proplist, PA_PROP_MEDIA_POLICY))) { ++ /* No policy exists, this means auto */ ++ pa_log_debug("[POLICY][%s] set policy of sink-input[%d] from [%s] to [auto]", __func__, si->index, "null"); ++ policy = POLICY_AUTO; ++ } ++ ++ sink_to_move = policy_select_proper_sink (c, policy, u->is_mono); ++ if (sink_to_move) { ++ pa_log_debug("[POLICY][%s] Moving sink-input[%d] from [%s] to [%s]", __func__, si->index, si->sink->name, sink_to_move->name); ++ pa_sink_input_move_to(si, sink_to_move, FALSE); ++ } else { ++ pa_log_debug("[POLICY][%s] Can't move sink-input....",__func__); ++ } ++ } ++ ++ /* Reset sink volume with balance from userdata */ ++ pa_cvolume* cvol = pa_sink_get_volume(sink, FALSE); ++ pa_cvolume_set_balance(cvol, &sink->channel_map, u->balance); ++ pa_sink_set_volume(sink, cvol, TRUE, TRUE); ++ ++ return PA_HOOK_OK; ++} ++ ++static void subscribe_cb(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata) ++{ ++ struct userdata *u = userdata; ++ pa_sink *def; ++ pa_sink_input *si; ++ uint32_t idx2; ++ pa_sink *sink_to_move = NULL; ++ pa_assert(u); ++ ++ pa_log_debug("[POLICY][%s] subscribe_cb() t=[0x%x], idx=[%d]", __func__, t, idx); ++ ++ /* We only handle server changes */ ++ if (t == (PA_SUBSCRIPTION_EVENT_SERVER|PA_SUBSCRIPTION_EVENT_CHANGE)) { ++ ++ def = pa_namereg_get_default_sink(c); ++ if (def == NULL) { ++ pa_log_warn("[POLICY][%s] pa_namereg_get_default_sink() returns null", __func__); ++ return; ++ } ++ pa_log_debug("[POLICY][%s] trying to move stream to current default sink = [%s]", __func__, def->name); ++ ++ /* Iterate each sink inputs to decide whether we should move to new DEFAULT sink */ ++ PA_IDXSET_FOREACH(si, c->sink_inputs, idx2) { ++ const char *policy = NULL; ++ ++ if (!si->sink) ++ continue; ++ ++ /* Get role (if role is filter, skip it) */ ++ if (policy_is_filter(si)) ++ continue; ++ ++ /* Get policy */ ++ if (!(policy = pa_proplist_gets(si->proplist, PA_PROP_MEDIA_POLICY))) { ++ /* No policy exists, this means auto */ ++ pa_log_debug("[POLICY][%s] set policy of sink-input[%d] from [%s] to [auto]", __func__, si->index, "null"); ++ policy = POLICY_AUTO; ++ } ++ ++ sink_to_move = policy_select_proper_sink (c, policy, u->is_mono); ++ if (sink_to_move) { ++ /* Move sink-input to new DEFAULT sink */ ++ pa_log_debug("[POLICY][%s] Moving sink-input[%d] from [%s] to [%s]", __func__, si->index, si->sink->name, sink_to_move->name); ++ pa_sink_input_move_to(si, sink_to_move, FALSE); ++ } ++ } ++ } ++} ++ ++static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, pa_sink *sink, void* userdata) { ++ struct userdata *u = userdata; ++ uint32_t idx; ++ pa_sink *sink_to_move; ++ pa_sink_input *si; ++ ++ pa_assert(c); ++ pa_assert(sink); ++ pa_assert(u); ++ ++ /* There's no point in doing anything if the core is shut down anyway */ ++ if (c->state == PA_CORE_SHUTDOWN) ++ return PA_HOOK_OK; ++ ++ /* if unloading sink is not bt, just return */ ++ if (!policy_is_bluez (sink)) { ++ pa_log_debug("[POLICY][%s] sink[%s][%d] unlinked but not a bluez....return\n", __func__, sink->name, sink->index); ++ return PA_HOOK_OK; ++ } ++ ++ pa_log_debug ("[POLICY][%s] SINK unlinked ================================ sink [%s][%d], bt_off_idx was [%d]", ++ __func__, sink->name, sink->index,u->bt_off_idx); ++ ++ u->bt_off_idx = sink->index; ++ pa_log_debug ("[POLICY][%s] bt_off_idx is set to [%d]", __func__, u->bt_off_idx); ++ ++ /* BT sink is unloading, move sink-input to proper sink */ ++ PA_IDXSET_FOREACH(si, c->sink_inputs, idx) { ++ ++ if (!si->sink) ++ continue; ++ ++ /* Get role (if role is filter, skip it) */ ++ if (policy_is_filter(si)) ++ continue; ++ ++ /* Find who were using bt sink or bt related sink and move them to proper sink (alsa/mono_alsa) */ ++ if (pa_streq (si->sink->name, SINK_MONO_BT) || ++ pa_streq (si->sink->name, SINK_MONO_COMBINED) || ++ pa_streq (si->sink->name, SINK_COMBINED) || ++ policy_is_bluez (si->sink)) { ++ ++ /* Move sink-input to proper sink : only alsa related sink is available now */ ++ sink_to_move = policy_get_sink_by_name (c, (u->is_mono)? SINK_MONO_ALSA : SINK_ALSA); ++ if (sink_to_move) { ++ pa_log_debug("[POLICY][%s] Moving sink-input[%d] from [%s] to [%s]", __func__, si->index, si->sink->name, sink_to_move->name); ++ pa_sink_input_move_to(si, sink_to_move, FALSE); ++ } else { ++ pa_log_warn("[POLICY][%s] No sink to move", __func__); ++ } ++ } ++ } ++ ++ pa_log_debug ("[POLICY][%s] unload sink in dependencies", __func__); ++ ++ /* Unload mono_combine sink */ ++ if (u->module_mono_combined) { ++ pa_module_unload(u->module->core, u->module_mono_combined, TRUE); ++ u->module_mono_combined = NULL; ++ } ++ ++ /* Unload combine sink */ ++ if (u->module_combined) { ++ pa_module_unload(u->module->core, u->module_combined, TRUE); ++ u->module_combined = NULL; ++ } ++ ++ /* Unload mono_bt sink */ ++ if (u->module_mono_bt) { ++ pa_module_unload(u->module->core, u->module_mono_bt, TRUE); ++ u->module_mono_bt = NULL; ++ } ++ ++ return PA_HOOK_OK; ++} ++ ++static pa_hook_result_t sink_unlink_post_hook_callback(pa_core *c, pa_sink *sink, void* userdata) { ++ struct userdata *u = userdata; ++ ++ pa_assert(c); ++ pa_assert(sink); ++ pa_assert(u); ++ ++ pa_log_debug("[POLICY][%s] SINK unlinked POST ================================ sink [%s][%d]", __func__, sink->name, sink->index); ++ ++ /* There's no point in doing anything if the core is shut down anyway */ ++ if (c->state == PA_CORE_SHUTDOWN) ++ return PA_HOOK_OK; ++ ++ /* if unloading sink is not bt, just return */ ++ if (!policy_is_bluez (sink)) { ++ pa_log_debug("[POLICY][%s] not a bluez....return\n", __func__); ++ return PA_HOOK_OK; ++ } ++ ++ u->bt_off_idx = -1; ++ pa_log_debug ("[POLICY][%s] bt_off_idx is cleared to [%d]", __func__, u->bt_off_idx); ++ ++ return PA_HOOK_OK; ++} ++ ++static pa_hook_result_t sink_input_move_start_cb(pa_core *core, pa_sink_input *i, struct userdata *u) { ++ pa_core_assert_ref(core); ++ pa_sink_input_assert_ref(i); ++ ++ /* There's no point in doing anything if the core is shut down anyway */ ++ if (core->state == PA_CORE_SHUTDOWN) ++ return PA_HOOK_OK; ++ ++ pa_log_debug ("[POLICY][%s] sink_input_move_start_cb -------------------------------------- sink-input [%d] was sink [%s][%d] : Trying to mute!!!", ++ __func__, i->index, i->sink->name, i->sink->index); ++ pa_sink_input_set_mute(i, TRUE, FALSE); ++ ++ return PA_HOOK_OK; ++} ++ ++static pa_hook_result_t sink_input_move_finish_cb(pa_core *core, pa_sink_input *i, struct userdata *u) { ++ pa_core_assert_ref(core); ++ pa_sink_input_assert_ref(i); ++ ++ /* There's no point in doing anything if the core is shut down anyway */ ++ if (core->state == PA_CORE_SHUTDOWN) ++ return PA_HOOK_OK; ++ ++ pa_log_debug("[POLICY][%s] sink_input_move_finish_cb -------------------------------------- sink-input [%d], sink [%s][%d], bt_off_idx [%d] : %s", ++ __func__, i->index, i->sink->name, i->sink->index, u->bt_off_idx, ++ (u->bt_off_idx == -1)? "Trying to un-mute!!!!" : "skip un-mute..."); ++ ++ /* If sink input move is caused by bt sink unlink, then skip un-mute operation */ ++ if (u->bt_off_idx == -1) { ++ pa_sink_input_set_mute(i, FALSE, FALSE); ++ } ++ ++ return PA_HOOK_OK; ++} ++ ++static pa_source* policy_get_source_by_name (pa_core *c, const char* source_name) ++{ ++ pa_source *s = NULL; ++ uint32_t idx; ++ ++ if (c == NULL || source_name == NULL) { ++ pa_log_warn ("input param is null"); ++ return NULL; ++ } ++ ++ PA_IDXSET_FOREACH(s, c->sources, idx) { ++ if (pa_streq (s->name, source_name)) { ++ pa_log_debug ("[POLICY][%s] return [%p] for [%s]\n", __func__, s, source_name); ++ return s; ++ } ++ } ++ return NULL; ++} ++ ++/* Select source for given condition */ ++static pa_source* policy_select_proper_source (pa_core *c, const char* policy) ++{ ++ pa_source* source = NULL; ++ pa_source* def = NULL; ++ ++ if (c == NULL || policy == NULL) { ++ pa_log_warn ("input param is null"); ++ return NULL; ++ } ++ ++ pa_assert (c); ++ def = pa_namereg_get_default_source(c); ++ if (def == NULL) { ++ pa_log_warn ("POLICY][%s] pa_namereg_get_default_source() returns null", __func__); ++ return NULL; ++ } ++ ++ /* Select source to */ ++ if (pa_streq(policy, POLICY_VOIP)) { ++ source = policy_get_source_by_name (c, AEC_SOURCE); ++ ++ } else { ++ source = def; ++ } ++ ++ pa_log_debug ("[POLICY][%s] selected source : [%s]\n", __func__, (source)? source->name : "null"); ++ return source; ++} ++ ++ ++/* Called when new source-output is creating */ ++static pa_hook_result_t source_output_new_hook_callback(pa_core *c, pa_source_output_new_data *new_data, struct userdata *u) { ++ const char *policy = NULL; ++ pa_assert(c); ++ pa_assert(new_data); ++ pa_assert(u); ++ ++ if (!new_data->proplist) { ++ pa_log_debug("New stream lacks property data."); ++ return PA_HOOK_OK; ++ } ++ ++ if (new_data->source) { ++ pa_log_debug("Not setting device for stream %s, because already set.", pa_strnull(pa_proplist_gets(new_data->proplist, PA_PROP_MEDIA_NAME))); ++ return PA_HOOK_OK; ++ } ++ ++ /* If no policy exists, skip */ ++ if (!(policy = pa_proplist_gets(new_data->proplist, PA_PROP_MEDIA_POLICY))) { ++ pa_log_debug("[POLICY][%s] Not setting device for stream [%s], because it lacks policy.", ++ __func__, pa_strnull(pa_proplist_gets(new_data->proplist, PA_PROP_MEDIA_NAME))); ++ return PA_HOOK_OK; ++ } ++ pa_log_debug("[POLICY][%s] Policy for stream [%s] = [%s]", ++ __func__, pa_strnull(pa_proplist_gets(new_data->proplist, PA_PROP_MEDIA_NAME)), policy); ++ ++ /* Set proper source to source-output */ ++ pa_source* new_source = policy_select_proper_source(c, policy); ++ if(new_source != new_data->source) ++ { ++ pa_source_output_new_data_set_source(new_data, new_source, FALSE); ++ } ++ /*new_data->save_source= FALSE; ++ new_data->source= policy_select_proper_source (c, policy);*/ ++ pa_log_debug("[POLICY][%s] set source of source-input to [%s]", __func__, (new_data->source)? new_data->source->name : "null"); ++ ++ return PA_HOOK_OK; ++} ++ ++int pa__init(pa_module *m) ++{ ++ pa_modargs *ma = NULL; ++ struct userdata *u; ++ pa_bool_t on_hotplug = TRUE, on_rescue = TRUE; ++ ++ pa_assert(m); ++ ++ if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { ++ pa_log("Failed to parse module arguments"); ++ goto fail; ++ } ++ ++ if (pa_modargs_get_value_boolean(ma, "on_hotplug", &on_hotplug) < 0 || ++ pa_modargs_get_value_boolean(ma, "on_rescue", &on_rescue) < 0) { ++ pa_log("on_hotplug= and on_rescue= expect boolean arguments"); ++ goto fail; ++ } ++ ++ m->userdata = u = pa_xnew0(struct userdata, 1); ++ u->core = m->core; ++ u->module = m; ++ u->on_hotplug = on_hotplug; ++ ++ ++ /* A little bit later than module-stream-restore */ ++ u->sink_input_new_hook_slot = ++ pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_NEW], PA_HOOK_EARLY+10, (pa_hook_cb_t) sink_input_new_hook_callback, u); ++ ++ u->source_output_new_hook_slot = ++ pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_NEW], PA_HOOK_EARLY+10, (pa_hook_cb_t) source_output_new_hook_callback, u); ++ ++ if (on_hotplug) { ++ /* A little bit later than module-stream-restore */ ++ u->sink_put_hook_slot = ++ pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_PUT], PA_HOOK_LATE+10, (pa_hook_cb_t) sink_put_hook_callback, u); ++ } ++ ++ /* sink unlink comes before sink-input unlink */ ++ u->sink_unlink_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_UNLINK], PA_HOOK_EARLY, (pa_hook_cb_t) sink_unlink_hook_callback, u); ++ u->sink_unlink_post_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_UNLINK_POST], PA_HOOK_EARLY, (pa_hook_cb_t) sink_unlink_post_hook_callback, u); ++ ++ u->sink_input_move_start_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_START], PA_HOOK_LATE, (pa_hook_cb_t) sink_input_move_start_cb, u); ++ u->sink_input_move_finish_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_FINISH], PA_HOOK_LATE, (pa_hook_cb_t) sink_input_move_finish_cb, u); ++ ++ u->subscription = pa_subscription_new(u->core, PA_SUBSCRIPTION_MASK_SERVER, subscribe_cb, u); ++ ++ ++ u->bt_off_idx = -1; /* initial bt off sink index */ ++ ++ u->module_mono_bt = NULL; ++ u->module_combined = NULL; ++ u->module_mono_combined = NULL; ++ ++ u->protocol = pa_native_protocol_get(m->core); ++ pa_native_protocol_install_ext(u->protocol, m, extension_cb); ++ ++ /* Get mono key value for init */ ++ vconf_get_bool(MONO_KEY, &u->is_mono); ++ ++ pa_log_info("policy module is loaded\n"); ++ ++ if (ma) ++ pa_modargs_free(ma); ++ ++ return 0; ++ ++fail: ++ if (ma) ++ pa_modargs_free(ma); ++ ++ pa__done(m); ++ ++ return -1; ++} ++ ++void pa__done(pa_module *m) ++{ ++ struct userdata* u; ++ ++ pa_assert(m); ++ ++ if (!(u = m->userdata)) ++ return; ++ ++ if (u->sink_input_new_hook_slot) ++ pa_hook_slot_free(u->sink_input_new_hook_slot); ++ if (u->sink_put_hook_slot) ++ pa_hook_slot_free(u->sink_put_hook_slot); ++ if (u->sink_unlink_slot) ++ pa_hook_slot_free(u->sink_unlink_slot); ++ if (u->sink_unlink_post_slot) ++ pa_hook_slot_free(u->sink_unlink_post_slot); ++ if (u->sink_input_move_start_slot) ++ pa_hook_slot_free(u->sink_input_move_start_slot); ++ if (u->sink_input_move_finish_slot) ++ pa_hook_slot_free(u->sink_input_move_finish_slot); ++ if (u->subscription) ++ pa_subscription_free(u->subscription); ++ if (u->protocol) { ++ pa_native_protocol_remove_ext(u->protocol, m); ++ pa_native_protocol_unref(u->protocol); ++ } ++ if (u->source_output_new_hook_slot) ++ pa_hook_slot_free(u->source_output_new_hook_slot); ++ ++ pa_xfree(u); ++ ++ ++ pa_log_info("policy module is unloaded\n"); ++} +diff --git a/src/pulse/ext-policy.c b/src/pulse/ext-policy.c +new file mode 100644 +index 0000000..f3a3a8c +--- /dev/null ++++ b/src/pulse/ext-policy.c +@@ -0,0 +1,177 @@ ++/*** ++ This file is part of PulseAudio. ++ ++ PulseAudio is free software; you can redistribute it and/or modify ++ it under the terms of the GNU Lesser General Public License as published ++ by the Free Software Foundation; either version 2.1 of the License, ++ or (at your option) any later version. ++ ++ PulseAudio is distributed in the hope that it will be useful, but ++ WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public License ++ along with PulseAudio; if not, write to the Free Software ++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 ++ USA. ++***/ ++ ++#ifdef HAVE_CONFIG_H ++#include ++#endif ++ ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include "internal.h" ++#include "operation.h" ++#include "fork-detect.h" ++ ++#include "ext-policy.h" ++ ++enum { ++ SUBCOMMAND_TEST, ++ SUBCOMMAND_MONO, ++ SUBCOMMAND_BALANCE, ++}; ++ ++static void ext_policy_test_cb(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { ++ pa_operation *o = userdata; ++ uint32_t version = PA_INVALID_INDEX; ++ ++ pa_assert(pd); ++ pa_assert(o); ++ pa_assert(PA_REFCNT_VALUE(o) >= 1); ++ ++ if (!o->context) ++ goto finish; ++ ++ if (command != PA_COMMAND_REPLY) { ++ if (pa_context_handle_error(o->context, command, t, FALSE) < 0) ++ goto finish; ++ ++ } else if (pa_tagstruct_getu32(t, &version) < 0 || ++ !pa_tagstruct_eof(t)) { ++ ++ pa_context_fail(o->context, PA_ERR_PROTOCOL); ++ goto finish; ++ } ++ ++ if (o->callback) { ++ pa_ext_policy_test_cb_t cb = (pa_ext_policy_test_cb_t) o->callback; ++ cb(o->context, version, o->userdata); ++ } ++ ++finish: ++ pa_operation_done(o); ++ pa_operation_unref(o); ++} ++ ++pa_operation *pa_ext_policy_test( ++ pa_context *c, ++ pa_ext_device_manager_test_cb_t cb, ++ void *userdata) { ++ ++ uint32_t tag; ++ pa_operation *o; ++ pa_tagstruct *t; ++ ++ pa_assert(c); ++ pa_assert(PA_REFCNT_VALUE(c) >= 1); ++ ++ PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED); ++ PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); ++ PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED); ++ ++ o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); ++ ++ t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag); ++ pa_tagstruct_putu32(t, PA_INVALID_INDEX); ++ pa_tagstruct_puts(t, "module-policy"); ++ pa_tagstruct_putu32(t, SUBCOMMAND_TEST); ++ pa_pstream_send_tagstruct(c->pstream, t); ++ pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, ext_policy_test_cb, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref); ++ ++ return o; ++} ++ ++pa_operation *pa_ext_policy_set_mono ( ++ pa_context *c, ++ int enable, ++ pa_context_success_cb_t cb, ++ void *userdata) { ++ ++ uint32_t tag; ++ pa_operation *o = NULL; ++ pa_tagstruct *t = NULL; ++ ++ pa_assert(c); ++ pa_assert(PA_REFCNT_VALUE(c) >= 1); ++ ++ PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED); ++ PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); ++ PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED); ++ ++ o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); ++ ++ t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag); ++ pa_tagstruct_putu32(t, PA_INVALID_INDEX); ++ pa_tagstruct_puts(t, "module-policy"); ++ pa_tagstruct_putu32(t, SUBCOMMAND_MONO); ++ pa_tagstruct_put_boolean(t, !!enable); ++ ++ pa_pstream_send_tagstruct(c->pstream, t); ++ pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref); ++ ++ return o; ++} ++ ++pa_operation *pa_ext_policy_set_balance ( ++ pa_context *c, ++ double *balance, ++ pa_context_success_cb_t cb, ++ void *userdata) { ++ ++ uint32_t tag; ++ pa_operation *o = NULL; ++ pa_tagstruct *t = NULL; ++ pa_cvolume cvol; ++ pa_channel_map map; ++ ++ pa_assert(c); ++ pa_assert(PA_REFCNT_VALUE(c) >= 1); ++ ++ PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED); ++ PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); ++ PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED); ++ ++ o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); ++ ++ t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag); ++ pa_tagstruct_putu32(t, PA_INVALID_INDEX); ++ pa_tagstruct_puts(t, "module-policy"); ++ pa_tagstruct_putu32(t, SUBCOMMAND_BALANCE); ++ ++ /* Prepare cvolume for transfer */ ++ pa_channel_map_init_stereo(&map); ++ pa_cvolume_set(&cvol, map.channels, 65535); ++ ++ pa_log_error ("balance = %f", *balance); ++ ++ pa_cvolume_set_balance(&cvol, &map, *balance); ++ ++ pa_log_error ("balance get = %f", pa_cvolume_get_balance(&cvol, &map)); ++ ++ pa_tagstruct_put_cvolume(t, &cvol); ++ ++ pa_pstream_send_tagstruct(c->pstream, t); ++ pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref); ++ ++ return o; ++} ++ +diff --git a/src/pulse/ext-policy.h b/src/pulse/ext-policy.h +new file mode 100644 +index 0000000..ec62ead +--- /dev/null ++++ b/src/pulse/ext-policy.h +@@ -0,0 +1,61 @@ ++#ifndef foopulseextpolicyhfoo ++#define foopulseextpolicyhfoo ++ ++/*** ++ This file is part of PulseAudio. ++ ++ PulseAudio is free software; you can redistribute it and/or modify ++ it under the terms of the GNU Lesser General Public License as published ++ by the Free Software Foundation; either version 2.1 of the License, ++ or (at your option) any later version. ++ ++ PulseAudio is distributed in the hope that it will be useful, but ++ WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public License ++ along with PulseAudio; if not, write to the Free Software ++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 ++ USA. ++***/ ++ ++#include ++#include ++ ++/** \file ++ * ++ * Routines for controlling module-policy ++ */ ++ ++PA_C_DECL_BEGIN ++ ++/** Callback prototype for pa_ext_policy_test(). \since 0.9.21 */ ++typedef void (*pa_ext_policy_test_cb_t)( ++ pa_context *c, ++ uint32_t version, ++ void *userdata); ++ ++/** Test if this extension module is available in the server. \since 0.9.21 */ ++pa_operation *pa_ext_policy_test( ++ pa_context *c, ++ pa_ext_policy_test_cb_t cb, ++ void *userdata); ++ ++/** Enable the mono mode. \since 0.9.21 */ ++pa_operation *pa_ext_policy_set_mono ( ++ pa_context *c, ++ int enable, ++ pa_context_success_cb_t cb, ++ void *userdata); ++ ++/** Enable the balance mode. \since 0.9.21 */ ++pa_operation *pa_ext_policy_set_balance ( ++ pa_context *c, ++ double *balance, ++ pa_context_success_cb_t cb, ++ void *userdata); ++ ++PA_C_DECL_END ++ ++#endif +diff --git a/src/pulse/proplist.h b/src/pulse/proplist.h +index dc3cddc..341abaa 100644 +--- a/src/pulse/proplist.h ++++ b/src/pulse/proplist.h +@@ -65,6 +65,9 @@ PA_C_DECL_BEGIN + /** For streams: logic role of this media. One of the strings "video", "music", "game", "event", "phone", "animation", "production", "a11y", "test" */ + #define PA_PROP_MEDIA_ROLE "media.role" + ++/** For streams: logic role of this media. One of the strings "auto", "phone" */ ++#define PA_PROP_MEDIA_POLICY "media.policy" ++ + /** For streams: the name of a filter that is desired, e.g.\ "echo-cancel" or "equalizer-sink". PulseAudio may choose to not apply the filter if it does not make sense (for example, applying echo-cancellation on a Bluetooth headset probably does not make sense. \since 1.0 */ + #define PA_PROP_FILTER_WANT "filter.want" + +-- +1.8.1.4 + diff --git a/meta-wrt-tizen/recipes-multimedia/pulseaudio/files/0007-TIZEN-node-manager-addingexternalnodemanagerAPI.patch b/meta-wrt-tizen/recipes-multimedia/pulseaudio/files/0007-TIZEN-node-manager-addingexternalnodemanagerAPI.patch new file mode 100644 index 0000000..aaa0365 --- /dev/null +++ b/meta-wrt-tizen/recipes-multimedia/pulseaudio/files/0007-TIZEN-node-manager-addingexternalnodemanagerAPI.patch @@ -0,0 +1,563 @@ +From 08b161622643f5d2148bb14e6e1ee07ef4bf53e0 Mon Sep 17 00:00:00 2001 +From: Jaska Uimonen +Date: Tue, 4 Dec 2012 09:53:14 +0200 +Subject: [PATCH] node manager: adding external node manager API + +--- + src/Makefile.am | 2 + + src/map-file | 6 + + src/pulse/context.c | 5 + + src/pulse/ext-node-manager.c | 348 +++++++++++++++++++++++++++++++++++++++++++ + src/pulse/ext-node-manager.h | 93 ++++++++++++ + src/pulse/internal.h | 6 + + 6 files changed, 460 insertions(+) + create mode 100644 src/pulse/ext-node-manager.c + create mode 100644 src/pulse/ext-node-manager.h + +diff --git a/src/Makefile.am b/src/Makefile.am +index 44c191d..6340dbc 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -746,6 +746,7 @@ pulseinclude_HEADERS = \ + pulse/ext-device-manager.h \ + pulse/ext-device-restore.h \ + pulse/ext-stream-restore.h \ ++ pulse/ext-node-manager.h \ + pulse/format.h \ + pulse/gccmacro.h \ + pulse/introspect.h \ +@@ -791,6 +792,7 @@ libpulse_la_SOURCES = \ + pulse/ext-device-manager.c pulse/ext-device-manager.h \ + pulse/ext-device-restore.c pulse/ext-device-restore.h \ + pulse/ext-stream-restore.c pulse/ext-stream-restore.h \ ++ pulse/ext-node-manager.c pulse/ext-node-manager.h \ + pulse/format.c pulse/format.h \ + pulse/gccmacro.h \ + pulse/internal.h \ +diff --git a/src/map-file b/src/map-file +index 1756035..3dee7ee 100644 +--- a/src/map-file ++++ b/src/map-file +@@ -170,6 +170,12 @@ pa_ext_stream_restore_set_subscribe_cb; + pa_ext_stream_restore_subscribe; + pa_ext_stream_restore_test; + pa_ext_stream_restore_write; ++pa_ext_node_manager_test; ++pa_ext_node_manager_read_nodes; ++pa_ext_node_manager_connect_nodes; ++pa_ext_node_manager_disconnect_nodes; ++pa_ext_node_manager_subscribe; ++pa_ext_node_manager_set_subscribe_cb; + pa_format_info_copy; + pa_format_info_free; + pa_format_info_from_string; +diff --git a/src/pulse/context.c b/src/pulse/context.c +index 7176412..5a86e68 100644 +--- a/src/pulse/context.c ++++ b/src/pulse/context.c +@@ -122,6 +122,9 @@ static void reset_callbacks(pa_context *c) { + + c->ext_stream_restore.callback = NULL; + c->ext_stream_restore.userdata = NULL; ++ ++ c->ext_node_manager.callback = NULL; ++ c->ext_node_manager.userdata = NULL; + } + + pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char *name, pa_proplist *p) { +@@ -1361,6 +1364,8 @@ void pa_command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_t + pa_ext_device_restore_command(c, tag, t); + else if (pa_streq(name, "module-stream-restore")) + pa_ext_stream_restore_command(c, tag, t); ++ else if (pa_streq(name, "module-node-manager")) ++ pa_ext_node_manager_command(c, tag, t); + else + pa_log(_("Received message for unknown extension '%s'"), name); + +diff --git a/src/pulse/ext-node-manager.c b/src/pulse/ext-node-manager.c +new file mode 100644 +index 0000000..5cb3feb +--- /dev/null ++++ b/src/pulse/ext-node-manager.c +@@ -0,0 +1,348 @@ ++/*** ++ This file is part of PulseAudio. ++ ++ Copyright 2012 Jaska Uimonen ++ Copyright 2012 Janos Kovacs ++ ++ PulseAudio is free software; you can redistribute it and/or modify ++ it under the terms of the GNU Lesser General Public License as published ++ by the Free Software Foundation; either version 2.1 of the License, ++ or (at your option) any later version. ++ ++ PulseAudio is distributed in the hope that it will be useful, but ++ WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public License ++ along with PulseAudio; if not, write to the Free Software ++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 ++ USA. ++***/ ++ ++#ifdef HAVE_CONFIG_H ++#include ++#endif ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include "internal.h" ++#include "ext-node-manager.h" ++ ++enum { ++ SUBCOMMAND_TEST, ++ SUBCOMMAND_READ, ++ SUBCOMMAND_CONNECT, ++ SUBCOMMAND_DISCONNECT, ++ SUBCOMMAND_SUBSCRIBE, ++ SUBCOMMAND_EVENT ++}; ++ ++static void ext_node_manager_test_cb(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { ++ pa_operation *o = userdata; ++ uint32_t version = PA_INVALID_INDEX; ++ ++ pa_assert(pd); ++ pa_assert(o); ++ pa_assert(PA_REFCNT_VALUE(o) >= 1); ++ ++ if (!o->context) ++ goto finish; ++ ++ if (command != PA_COMMAND_REPLY) { ++ if (pa_context_handle_error(o->context, command, t, FALSE) < 0) ++ goto finish; ++ ++ } else if (pa_tagstruct_getu32(t, &version) < 0 || ++ !pa_tagstruct_eof(t)) { ++ ++ pa_context_fail(o->context, PA_ERR_PROTOCOL); ++ goto finish; ++ } ++ ++ if (o->callback) { ++ pa_ext_node_manager_test_cb_t cb = (pa_ext_node_manager_test_cb_t) o->callback; ++ cb(o->context, version, o->userdata); ++ } ++ ++finish: ++ pa_operation_done(o); ++ pa_operation_unref(o); ++} ++ ++pa_operation *pa_ext_node_manager_test( ++ pa_context *c, ++ pa_ext_node_manager_test_cb_t cb, ++ void *userdata) { ++ ++ uint32_t tag; ++ pa_operation *o; ++ pa_tagstruct *t; ++ ++ pa_assert(c); ++ pa_assert(PA_REFCNT_VALUE(c) >= 1); ++ ++ PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED); ++ PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); ++ PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED); ++ ++ o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); ++ ++ t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag); ++ pa_tagstruct_putu32(t, PA_INVALID_INDEX); ++ pa_tagstruct_puts(t, "module-murphy-ivi"); ++ pa_tagstruct_putu32(t, SUBCOMMAND_TEST); ++ pa_pstream_send_tagstruct(c->pstream, t); ++ pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, ext_node_manager_test_cb, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref); ++ ++ return o; ++} ++ ++static void ext_node_manager_read_cb(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { ++ pa_operation *o = userdata; ++ pa_ext_node_manager_info i; ++ ++ pa_assert(pd); ++ pa_assert(o); ++ pa_assert(PA_REFCNT_VALUE(o) >= 1); ++ ++ if (!o->context) ++ goto finish; ++ ++ if (command != PA_COMMAND_REPLY) { ++ if (pa_context_handle_error(o->context, command, t, FALSE) < 0) ++ goto finish; ++ } else { ++ ++ while (!pa_tagstruct_eof(t)) { ++ ++ memset(&i, 0, sizeof(i)); ++ ++ i.props = pa_proplist_new(); ++ ++ if (pa_tagstruct_gets(t, &i.name) < 0 || ++ pa_tagstruct_get_proplist(t, i.props) < 0) { ++ ++ pa_context_fail(o->context, PA_ERR_PROTOCOL); ++ goto finish; ++ } ++ ++ if (o->callback) { ++ pa_ext_node_manager_read_cb_t cb = (pa_ext_node_manager_read_cb_t) o->callback; ++ cb(o->context, &i, 0, o->userdata); ++ } ++ ++ pa_proplist_free(i.props); ++ } ++ ++ /* let's send end marker */ ++ if (o->callback) { ++ pa_ext_node_manager_read_cb_t cb = (pa_ext_node_manager_read_cb_t) o->callback; ++ cb(o->context, &i, 1, o->userdata); ++ } ++ } ++ ++finish: ++ pa_operation_done(o); ++ pa_operation_unref(o); ++} ++ ++pa_operation *pa_ext_node_manager_read_nodes( ++ pa_context *c, ++ pa_ext_node_manager_read_cb_t cb, ++ void *userdata) { ++ ++ uint32_t tag; ++ pa_operation *o; ++ pa_tagstruct *t; ++ ++ pa_assert(c); ++ pa_assert(PA_REFCNT_VALUE(c) >= 1); ++ ++ PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED); ++ PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); ++ PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED); ++ ++ o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); ++ ++ t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag); ++ pa_tagstruct_putu32(t, PA_INVALID_INDEX); ++ pa_tagstruct_puts(t, "module-murphy-ivi"); ++ pa_tagstruct_putu32(t, SUBCOMMAND_READ); ++ pa_pstream_send_tagstruct(c->pstream, t); ++ pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, ext_node_manager_read_cb, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref); ++ ++ return o; ++} ++ ++static void ext_node_manager_connect_cb(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { ++ pa_operation *o = userdata; ++ uint32_t connection = PA_INVALID_INDEX; ++ ++ pa_assert(pd); ++ pa_assert(o); ++ pa_assert(PA_REFCNT_VALUE(o) >= 1); ++ ++ if (!o->context) ++ goto finish; ++ ++ if (command != PA_COMMAND_REPLY) { ++ if (pa_context_handle_error(o->context, command, t, FALSE) < 0) ++ goto finish; ++ ++ } else if (pa_tagstruct_getu32(t, &connection) < 0 || ++ !pa_tagstruct_eof(t)) { ++ ++ pa_context_fail(o->context, PA_ERR_PROTOCOL); ++ goto finish; ++ } ++ ++ if (o->callback) { ++ pa_ext_node_manager_connect_cb_t cb = (pa_ext_node_manager_connect_cb_t) o->callback; ++ cb(o->context, connection, o->userdata); ++ } ++ ++finish: ++ pa_operation_done(o); ++ pa_operation_unref(o); ++} ++ ++pa_operation *pa_ext_node_manager_connect_nodes( ++ pa_context *c, ++ uint32_t source_node_id, ++ uint32_t sink_node_id, ++ pa_ext_node_manager_connect_cb_t cb, ++ void *userdata) { ++ ++ uint32_t tag; ++ pa_operation *o = NULL; ++ pa_tagstruct *t = NULL; ++ ++ pa_assert(c); ++ pa_assert(PA_REFCNT_VALUE(c) >= 1); ++ ++ PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED); ++ PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); ++ PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED); ++ ++ o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); ++ ++ t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag); ++ pa_tagstruct_putu32(t, PA_INVALID_INDEX); ++ pa_tagstruct_puts(t, "module-murphy-ivi"); ++ pa_tagstruct_putu32(t, SUBCOMMAND_CONNECT); ++ ++ pa_tagstruct_putu32(t, source_node_id); ++ pa_tagstruct_putu32(t, sink_node_id); ++ ++ pa_pstream_send_tagstruct(c->pstream, t); ++ pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, ext_node_manager_connect_cb, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref); ++ ++ return o; ++} ++ ++pa_operation *pa_ext_node_manager_disconnect_nodes( ++ pa_context *c, ++ uint32_t conn_id, ++ pa_context_success_cb_t cb, ++ void *userdata) { ++ ++ uint32_t tag; ++ pa_operation *o = NULL; ++ pa_tagstruct *t = NULL; ++ ++ pa_assert(c); ++ pa_assert(PA_REFCNT_VALUE(c) >= 1); ++ ++ PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED); ++ PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); ++ PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED); ++ ++ o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); ++ ++ t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag); ++ pa_tagstruct_putu32(t, PA_INVALID_INDEX); ++ pa_tagstruct_puts(t, "module-murphy-ivi"); ++ pa_tagstruct_putu32(t, SUBCOMMAND_DISCONNECT); ++ ++ pa_tagstruct_putu32(t, conn_id); ++ ++ pa_pstream_send_tagstruct(c->pstream, t); ++ pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref); ++ ++ return o; ++} ++ ++pa_operation *pa_ext_node_manager_subscribe( ++ pa_context *c, ++ int enable, ++ pa_context_success_cb_t cb, ++ void *userdata) { ++ ++ uint32_t tag; ++ pa_operation *o; ++ pa_tagstruct *t; ++ ++ pa_assert(c); ++ pa_assert(PA_REFCNT_VALUE(c) >= 1); ++ ++ PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED); ++ PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); ++ PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED); ++ ++ o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); ++ ++ t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag); ++ pa_tagstruct_putu32(t, PA_INVALID_INDEX); ++ pa_tagstruct_puts(t, "module-murphy-ivi"); ++ pa_tagstruct_putu32(t, SUBCOMMAND_SUBSCRIBE); ++ pa_tagstruct_put_boolean(t, enable); ++ pa_pstream_send_tagstruct(c->pstream, t); ++ pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref); ++ ++ return o; ++} ++ ++void pa_ext_node_manager_set_subscribe_cb( ++ pa_context *c, ++ pa_ext_node_manager_subscribe_cb_t cb, ++ void *userdata) { ++ ++ pa_assert(c); ++ pa_assert(PA_REFCNT_VALUE(c) >= 1); ++ ++ if (pa_detect_fork()) ++ return; ++ ++ c->ext_node_manager.callback = cb; ++ c->ext_node_manager.userdata = userdata; ++} ++ ++void pa_ext_node_manager_command(pa_context *c, uint32_t tag, pa_tagstruct *t) { ++ uint32_t subcommand; ++ ++ pa_assert(c); ++ pa_assert(PA_REFCNT_VALUE(c) >= 1); ++ pa_assert(t); ++ ++ if (pa_tagstruct_getu32(t, &subcommand) < 0 || ++ !pa_tagstruct_eof(t)) { ++ ++ pa_context_fail(c, PA_ERR_PROTOCOL); ++ return; ++ } ++ ++ if (subcommand != SUBCOMMAND_EVENT) { ++ pa_context_fail(c, PA_ERR_PROTOCOL); ++ return; ++ } ++ ++ if (c->ext_node_manager.callback) ++ c->ext_node_manager.callback(c, c->ext_node_manager.userdata); ++} +diff --git a/src/pulse/ext-node-manager.h b/src/pulse/ext-node-manager.h +new file mode 100644 +index 0000000..57b9f01 +--- /dev/null ++++ b/src/pulse/ext-node-manager.h +@@ -0,0 +1,93 @@ ++#ifndef foopulseextnodemanagerhfoo ++#define foopulseextnodemanagerhfoo ++ ++/*** ++ This file is part of PulseAudio. ++ ++ Copyright 2012 Jaska Uimonen ++ Copyright 2012 Janos Kovacs ++ ++ PulseAudio is free software; you can redistribute it and/or modify ++ it under the terms of the GNU Lesser General Public License as published ++ by the Free Software Foundation; either version 2.1 of the License, ++ or (at your option) any later version. ++ ++ PulseAudio is distributed in the hope that it will be useful, but ++ WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public License ++ along with PulseAudio; if not, write to the Free Software ++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 ++ USA. ++***/ ++ ++#include ++#include ++#include ++ ++PA_C_DECL_BEGIN ++ ++typedef struct pa_ext_node_manager_info { ++ const char *name; ++ pa_proplist *props; ++} pa_ext_node_manager_info; ++ ++typedef void (*pa_ext_node_manager_test_cb_t)( ++ pa_context *c, ++ uint32_t version, ++ void *userdata); ++ ++pa_operation *pa_ext_node_manager_test( ++ pa_context *c, ++ pa_ext_node_manager_test_cb_t cb, ++ void *userdata); ++ ++typedef void (*pa_ext_node_manager_read_cb_t)( ++ pa_context *c, ++ const pa_ext_node_manager_info *info, ++ int eol, ++ void *userdata); ++ ++pa_operation *pa_ext_node_manager_read_nodes( ++ pa_context *c, ++ pa_ext_node_manager_read_cb_t cb, ++ void *userdata); ++ ++typedef void (*pa_ext_node_manager_connect_cb_t)( ++ pa_context *c, ++ uint32_t connection, ++ void *userdata); ++ ++pa_operation *pa_ext_node_manager_connect_nodes( ++ pa_context *c, ++ uint32_t src, ++ uint32_t dst, ++ pa_ext_node_manager_connect_cb_t cb, ++ void *userdata); ++ ++pa_operation *pa_ext_node_manager_disconnect_nodes( ++ pa_context *c, ++ uint32_t conn, ++ pa_context_success_cb_t cb, ++ void *userdata); ++ ++pa_operation *pa_ext_node_manager_subscribe( ++ pa_context *c, ++ int enable, ++ pa_context_success_cb_t cb, ++ void *userdata); ++ ++typedef void (*pa_ext_node_manager_subscribe_cb_t)( ++ pa_context *c, ++ void *userdata); ++ ++void pa_ext_node_manager_set_subscribe_cb( ++ pa_context *c, ++ pa_ext_node_manager_subscribe_cb_t cb, ++ void *userdata); ++ ++PA_C_DECL_END ++ ++#endif +diff --git a/src/pulse/internal.h b/src/pulse/internal.h +index e72e285..382a182 100644 +--- a/src/pulse/internal.h ++++ b/src/pulse/internal.h +@@ -31,6 +31,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -115,6 +116,10 @@ struct pa_context { + pa_ext_stream_restore_subscribe_cb_t callback; + void *userdata; + } ext_stream_restore; ++ struct { ++ pa_ext_node_manager_subscribe_cb_t callback; ++ void *userdata; ++ } ext_node_manager; + }; + + #define PA_MAX_WRITE_INDEX_CORRECTIONS 32 +@@ -304,6 +309,7 @@ pa_tagstruct *pa_tagstruct_command(pa_context *c, uint32_t command, uint32_t *ta + void pa_ext_device_manager_command(pa_context *c, uint32_t tag, pa_tagstruct *t); + void pa_ext_device_restore_command(pa_context *c, uint32_t tag, pa_tagstruct *t); + void pa_ext_stream_restore_command(pa_context *c, uint32_t tag, pa_tagstruct *t); ++void pa_ext_node_manager_command(pa_context *c, uint32_t tag, pa_tagstruct *t); + + pa_bool_t pa_mainloop_is_our_api(pa_mainloop_api*m); + +-- +1.8.1.4 + diff --git a/meta-wrt-tizen/recipes-multimedia/pulseaudio/pulseaudio_4.0.bbappend b/meta-wrt-tizen/recipes-multimedia/pulseaudio/pulseaudio_4.0.bbappend index fec33e4..30f468d 100644 --- a/meta-wrt-tizen/recipes-multimedia/pulseaudio/pulseaudio_4.0.bbappend +++ b/meta-wrt-tizen/recipes-multimedia/pulseaudio/pulseaudio_4.0.bbappend @@ -1,3 +1,8 @@ FILESEXTRAPATHS_prepend := "${THISDIR}/files" -SRC_URI += "file://TIZEN-changes-topasimpleapi-samsung.patch;apply=yes" - +SRC_URI += "file://0007-TIZEN-node-manager-addingexternalnodemanagerAPI.patch;apply=yes " +SRC_URI += "file://0001-TIZEN-changes-to-pa-simple-api-samsung.patch;apply=yes " +SRC_URI += "file://0002-TIZEN-add-support-for-samsung-power-management-samsung.patch;apply=yes " +# SRC_URI += "file://0003-TIZEN-Add-preload-fileter-for-resample-samsung.patch;apply=yes " +SRC_URI += "file://0004-TIZEN-Enhance-for-echo-cancel-samsung.patch;apply=yes " +SRC_URI += "file://0005-TIZEN-add-support-for-dlog-samsung.patch;apply=yes " +SRC_URI += "file://0006-TIZEN-add-policy-module-samsung.patch;apply=yes " diff --git a/proto-meta-Tizen_ivi_3.0/.spec2yoctorc b/proto-meta-Tizen_ivi_3.0/.spec2yoctorc index 36f4416..880cf38 100644 --- a/proto-meta-Tizen_ivi_3.0/.spec2yoctorc +++ b/proto-meta-Tizen_ivi_3.0/.spec2yoctorc @@ -19,7 +19,7 @@ manifest=tizen_common_3.0_manifest, wrt_tz_addon, wrt_addon, maskcommonmanifest arch=x86_64 recipes_dir_sources=${HOME}/yoctoTizen/meta-wrt-tizen/recipes-wrt blacklist_autoreconf=tizen_ivi_autoreconf -whitelist=wrt, wrt-commons, wrt-installer, wrt-plugins-common, wrt-plugins-tizen, wrt-security, wrt-widgets, webkit-efl, system-settings, url-download, ui-gadget-1, slp-pkgmgr, libiri, dlog, libhaptic,haptic, cert-svc, notification, aul-1, secure-storage, libprivilege-control, app-manager, app-svc, smack, bundle, app-checker, libslp-utilx, app-core, app2sd, libslp-sysman, vconf, common, libslp-sensor,capi-system-sensor, libcryptsvc, librua, xdgmime, pkgmgr-info, ail, application, runtime-info, vconf-internal-keys,alarm-manager, security-server, libslp-pm, libslp-db-util, libslp-tapi, heynoti, iniparser, libtbm, libdri2,com-core, libdevice-node, xmlsec1, dukgenerator, devman, download-provider, connection, libnet-client, libwifi-direct, privacy-manager, shortcut, package-manager, geocoder, libslp-location,libsf-common, network-info, libmm-utility, gtest, power, location-manager, device, media-server, tts, libmm-common, libmm-session, libmm-player, libmm-log, libsvi, leveldb,libmm-sound, drm-client, libmm-ta, audio-session-manager, avsystem, alsa-scenario-0.2, sync-agent, contacts-service, metadata-extractor, syspopup, libslp-memo,libwbxml2, poi, media-content, email-service, libmm-fileinfo, system-info, msg-service, libaccounts-svc, favorites, route, pims-ipc, image-util, sys-assert, badge, zeromq, calendar-service, nfc-manager, nfc-manager-neard, smartcard-service, neardal, wav-player, bluetooth-frwk, bluetooth-tools, tethering, status, sound-manager, libmm-radio, libmedia-service, libmedia-thumbnail, uw-imap-toolkit +whitelist=wrt, wrt-commons, wrt-installer, wrt-plugins-common, wrt-plugins-tizen, wrt-security, system-settings, url-download, ui-gadget-1, slp-pkgmgr, libiri, dlog, libhaptic,haptic, cert-svc, notification, aul-1, secure-storage, libprivilege-control, app-manager, app-svc, smack, bundle, app-checker, libslp-utilx, app-core, app2sd, libslp-sysman, vconf, common, libslp-sensor,capi-system-sensor, libcryptsvc, librua, xdgmime, pkgmgr-info, ail, application, runtime-info, vconf-internal-keys,alarm-manager, security-server, libslp-pm, libslp-db-util, libslp-tapi, heynoti, iniparser, libtbm, libdri2,com-core, libdevice-node, xmlsec1, dukgenerator, devman, download-provider, connection, libnet-client, libwifi-direct, privacy-manager, shortcut, package-manager, geocoder, libslp-location, webkit-efl,libsf-common, network-info, libmm-utility, gtest, power, location-manager, device, media-server, tts, libmm-common, libmm-session, libmm-player, libmm-log, libsvi, leveldb,libmm-sound, drm-client, libmm-ta, audio-session-manager, avsystem, alsa-scenario-0.2, sync-agent, contacts-service, metadata-extractor, syspopup, libslp-memo,libwbxml2, poi, media-content, email-service, libmm-fileinfo, system-info, msg-service, libaccounts-svc, favorites, route, pims-ipc, image-util, sys-assert, badge, zeromq, calendar-service, nfc-manager, nfc-manager-neard, smartcard-service, neardal, wav-player, bluetooth-frwk, bluetooth-tools, tethering, status, sound-manager, libmm-radio, libmedia-service, libmedia-thumbnail, uw-imap-toolkit provided-extra=wrt-provided-extra [substitute] -- 2.7.4