From d53e6a320ae129a6019c316ee2efd02dd8ac68a8 Mon Sep 17 00:00:00 2001 From: brent s Date: Thu, 7 Apr 2016 16:33:35 -0400 Subject: [PATCH] further work... nothing reaaaally good yet, but getting there. --- bts_podcast/bts_podcast.php | 56 +++- upm_file_popper-0.2.2.diff | 91 +++++ upm_file_popper-0.2.2.old | 636 +++++++++++++++++++++++++++++++++++ upm_file_popper-0.2.2.orig | 650 ++++++++++++++++++++++++++++++++++++ upm_file_popper-0.2.2.txt | 327 ++++++++++++++++++ 5 files changed, 1753 insertions(+), 7 deletions(-) create mode 100644 upm_file_popper-0.2.2.diff create mode 100644 upm_file_popper-0.2.2.old create mode 100644 upm_file_popper-0.2.2.orig create mode 100644 upm_file_popper-0.2.2.txt diff --git a/bts_podcast/bts_podcast.php b/bts_podcast/bts_podcast.php index 36595b5..759acd8 100644 --- a/bts_podcast/bts_podcast.php +++ b/bts_podcast/bts_podcast.php @@ -19,7 +19,7 @@ $plugin['flags'] = PLUGIN_LIFECYCLE_NOTIFY; // @include_once('zem_tpl.php'); register_callback('bts_podcast_initdb','plugin_lifecycle.bts_podcast', 'enabled'); -register_callback('bts_podcast_genguid','article_saved'); +register_callback('bts_podcast_gen_metainfo','article_saved'); if (0) { ?> @@ -88,15 +88,21 @@ This plugin creates a *sha256* table in your Textpattern DB. There, it stores th # --- BEGIN PLUGIN CODE --- -// Hooks +// Hooks/callbacks function bts_podcast_initdb () { - safe_query("CREATE TABLE IF NOT EXISTS sha256 (id int(11) NOT NULL AUTO_INCREMENT,url_title varchar(64) NOT NULL,filename varchar(64) NOT NULL,type char(3) NOT NULL,checksum char(64) NOT NULL,created datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,changed timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,PRIMARY KEY (id),UNIQUE KEY `unique_index` (url_title,type)"); + safe_query("CREATE TABLE IF NOT EXISTS bts_podcast (id int(11) NOT NULL AUTO_INCREMENT,url_title varchar(64) NOT NULL,filename varchar(64) NOT NULL,type char(3) NOT NULL,checksum char(64) NOT NULL,bytesize varchar(16) NOT NULL,created datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,changed timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,PRIMARY KEY (id),UNIQUE KEY unique_index (url_title,type)) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8"); } -function bts_podcast_gen_guid () { - hash_file('sha256',file_article_upload()); +function bts_podcast_gen_metainfo ($input) { + $hash = hash_file('sha256',file_article_upload()); +// safe_query("INSERT INTO bts_podcast (url_title,filename,type,checksum,bytesize) VALUES ('" . $input['urltitle'] . "','" . $input['mediafile'] . "','" . $input['mediatype'] . "','" . $input['mediachksum'] . "','" . $input['mediabytes'] . "') ON DUPLICATE KEY UPDATE url_title = '" . $input['urltitle'] . "', filename = '" . $input['mediafile'] . "', type = '" . $input['mediatype'] . "', checksum = '" . $input['mediachksum'] . "', bytesize = '" . $input['mediabytes'] . "'"); } +//use pluggable_ui(event,step,default content, record set) +//event, i believe, is article_ui +//maybe use step "custom_fields" and totally replace custom fields with the file uploader? +//i should also find a way to get the "S0E0" format automatically used for the url title/permlink. + // Register the plugin... if(class_exists('\Textpattern\Tag\Registry')) { Txp::get('\Textpattern\Tag\Registry') @@ -142,7 +148,7 @@ function bts_podcast_guid ($atts) { ), $atts)); if (($byte == '1' && $db == '1') || ($string == '')) { - $checksum = fetch('checksum','sha256','filename',bts_podcast_filename($atts)); + $checksum = fetch('checksum','bts_podcast','filename',bts_podcast_filename($atts)); } elseif ($byte == '1') { $checksum = hash_file('sha256',$string); } else { @@ -156,13 +162,49 @@ function bts_podcast_media_uri ($atts) { $default_vals = array('media' => 'mp3'); $default_vals['uri'] = site_url($atts) . bts_podcast_path($atts) . bts_podcast_filename($atts); extract(lAtts(array($default_vals), $atts)); - if ( $uri == '') { + if (! isset($uri)) { $uri = site_url($atts) . bts_podcast_path($atts) . bts_podcast_filename($atts); } return $uri; } +/* +function bts_podccast_filesize($atts) { +} +function bts_podcast_medialength($atts) { +} +function bts_podcast_get_guid($atts) { +} +*/ +// UNDER DEVELOPMENT: needs bts_podcast_filesize (which i need to rename to actually be bytesize) +// i also need to get media length so that can be returned in the actual feed. +/* +$metainfo_mp3 = array( + //$input['urltitle'] + //$input['mediafile'] + //$input['mediatype'] + //$input['mediachksum'] + //$input['mediabytes'] + urltitle => title($atts), + mediafile => bts_podcast_filename($atts), + mediatype => 'mp3', + mediachksum => bts_podcast_guid($atts), + mediabytes => bts_podcast_filesize($atts)); +$metainfo_ogg = array( + //$input['urltitle'] + //$input['mediafile'] + //$input['mediatype'] + //$input['mediachksum'] + //$input['mediabytes'] + urltitle => title($atts), + mediafile => bts_podcast_filename($atts), + mediatype => 'mp3', + mediachksum => bts_podcast_guid($atts), + mediabytes => bts_podcast_filesize($atts)); +bts_podcast_gen_metainfo ($metainfo_mp3); +bts_podcast_gen_metainfo ($metainfo_ogg); +*/ # --- END PLUGIN CODE --- ?> diff --git a/upm_file_popper-0.2.2.diff b/upm_file_popper-0.2.2.diff new file mode 100644 index 0000000..bf168e6 --- /dev/null +++ b/upm_file_popper-0.2.2.diff @@ -0,0 +1,91 @@ +--- upm_file_popper-0.2.2.orig 2016-01-01 17:13:48.000000000 +0100 ++++ upm_file_popper-0.2.2.new 2016-01-01 17:13:48.000000000 +0100 +@@ -1,6 +1,6 @@ +-if (txpinterface == 'admin') ++if (@txpinterface == 'admin') + { + add_privs('upm_file_popper', '1,2,3,4,5'); + register_callback('upm_file_popper', 'upm_file_popper'); + + add_privs('upm_file_popper_link', '1,2,3,4,5'); +@@ -9,12 +9,25 @@ + add_privs('upm_file_popper_js', '1,2,3,4,5'); + register_callback('upm_file_popper_js', 'upm_file_popper_js', '', 1); + + add_privs('upm_file_popper_img', '1,2,3,4,5'); + register_callback('upm_file_popper_img', 'upm_file_popper_img', '', 1); ++ ++ register_callback('upm_file_popper_menu', 'article_ui', 'extend_col_1'); ++ + } + ++ /** ++ * Insert upm_file_popper link in column 1 on the write-tab ++ * ++ * @param string $event (article_ui) ++ * @param string $step (extend_col_1) ++ */ ++ function upm_file_popper_menu($event, $step) { ++ return '

'.upm_file_popper_gTxt('attach_file').'

'; ++ } ++ + // ------------------------------------------------------------- + + function upm_file_popper() + { + global $step, $prefs; +@@ -88,13 +101,14 @@ + + + css; + + extract(gpsa(array('page', 'sort', 'dir', 'crit', 'search_method'))); ++ if ($sort === '') $sort = get_pref('file_sort_column', 'filename'); ++ if ($dir === '') $dir = get_pref('file_sort_dir', 'asc'); ++ $dir = ($dir == 'desc') ? 'desc' : 'asc'; + +- $dir = ($dir == 'desc') ? 'desc' : 'asc'; +- + switch ($sort) + { + case 'id': + $sort_sql = "id $dir, filename asc"; + break; +@@ -183,11 +197,11 @@ + + if ($rs) + { + $sort_link = 'upm_file_popper'.a.'bm=true'; + +- echo startTable('list'), ++ echo startTable('','','txp-list'), + tr( + column_head('ID', 'id', $sort_link, true, $switch_dir, $crit, $search_method). + column_head('file_name', 'filename', $sort_link, true, $switch_dir, $crit, $search_method). + column_head('description', 'description', $sort_link, true, $switch_dir, $crit, $search_method). + column_head('file_category', 'category', $sort_link, true, $switch_dir, $crit, $search_method). +@@ -397,21 +411,21 @@ + $('#upm_file_popper_start').val( $('body').val() ); + + // ------------------------------ + // create and insert popup link + +- var w = 575; +- var h = 375; ++ var w = 800; ++ var h = 500; + + var t = (screen.height) ? (screen.height - h) / 2 : 0; + var l = (screen.width) ? (screen.width - w) / 2 : 0; + + var a = $(document.createElement('a')). + text('$lang_attach_file'). + attr({ + target: '_blank', +- href: '?event=upm_file_popper\u0026bm=1' ++ href: '?event=upm_file_popper\u0026bm=1\u0026sort=id\u0026dir=desc' + }). + click(function () { + var upm_file_popper = window.open(this.href, 'upm_file_popper', 'top = '+t+', left = '+l+', width = '+w+', height = '+h+', toolbar = no, location = no, directories = no, status = yes, menubar = no, scrollbars = yes, copyhistory = no, resizable = yes'); + upm_file_popper.focus(); + return false; diff --git a/upm_file_popper-0.2.2.old b/upm_file_popper-0.2.2.old new file mode 100644 index 0000000..f7c37d3 --- /dev/null +++ b/upm_file_popper-0.2.2.old @@ -0,0 +1,636 @@ +if (txpinterface == 'admin') + { + add_privs('upm_file_popper', '1,2,3,4,5'); + register_callback('upm_file_popper', 'upm_file_popper'); + + add_privs('upm_file_popper_link', '1,2,3,4,5'); + register_callback('upm_file_popper_link', 'article'); + + add_privs('upm_file_popper_js', '1,2,3,4,5'); + register_callback('upm_file_popper_js', 'upm_file_popper_js', '', 1); + + add_privs('upm_file_popper_img', '1,2,3,4,5'); + register_callback('upm_file_popper_img', 'upm_file_popper_img', '', 1); + } + +// ------------------------------------------------------------- + + function upm_file_popper() + { + global $step, $prefs; + + if ($step == 'upm_file_popper_change_pageby') + { + event_change_pageby('file'); + $GLOBALS['prefs'] = get_prefs(); + } + + upm_file_popper_list(); + } + +// ------------------------------------------------------------- + + function upm_file_popper_list() + { + global $file_base_path, $prefs; + + pagetop(upm_file_popper_gTxt('file_selector')); + + echo << + + + + +css; + + extract(gpsa(array('page', 'sort', 'dir', 'crit', 'search_method'))); + + $dir = ($dir == 'desc') ? 'desc' : 'asc'; + + switch ($sort) + { + case 'id': + $sort_sql = "id $dir, filename asc"; + break; + + case 'filename': + $sort_sql = "filename $dir"; + break; + + case 'description': + $sort_sql = 'description '.$dir.', filename desc'; + break; + + case 'category': + $sort_sql = "category $dir, filename asc"; + break; + + case 'downloads': + $sort_sql = "downloads $dir, filename asc"; + break; + + default: + $dir = 'desc'; + $sort_sql = "filename $dir"; + break; + } + + $switch_dir = ($dir == 'desc') ? 'asc' : 'desc'; + + $criteria = 1; + + if ($search_method and $crit) + { + $crit_escaped = doSlash($crit); + + $critsql = array( + 'id' => "id = '$crit_escaped'", + 'filename' => "filename like '%$crit_escaped%'", + 'category' => "category like '%$crit_escaped%'", + 'description' => "description like '%$crit_escaped%'" + ); + + if (array_key_exists($search_method, $critsql)) + { + $criteria = $critsql[$search_method]; + $limit = 500; + } + + else + { + $search_method = ''; + $crit = ''; + } + } + + else + { + $search_method = ''; + $crit = ''; + } + + $total = safe_count('txp_file', "$criteria"); + + if ($total < 1) + { + if ($criteria != 1) + { + echo n.upm_file_popper_search_form($crit, $search_method, $sort, $dir). + n.graf(gTxt('no_results_found'), ' style="text-align: center;"'); + } + + else + { + echo n.graf(gTxt('no_files_recorded'), ' style="text-align: center;"'); + } + + return; + } + + $limit = max($prefs['file_list_pageby'], 15); + + list($page, $offset, $numPages) = pager($total, $limit, $page); + + echo upm_file_popper_search_form($crit, $search_method, $sort, $dir); + + $rs = safe_rows_start('*', 'txp_file', "$criteria order by $sort_sql limit $offset, $limit"); + + if ($rs) + { + $sort_link = 'upm_file_popper'.a.'bm=true'; + + echo startTable('list'), + tr( + column_head('ID', 'id', $sort_link, true, $switch_dir, $crit, $search_method). + column_head('file_name', 'filename', $sort_link, true, $switch_dir, $crit, $search_method). + column_head('description', 'description', $sort_link, true, $switch_dir, $crit, $search_method). + column_head('file_category', 'category', $sort_link, true, $switch_dir, $crit, $search_method). + hCell(). + hCell(gTxt('tags')). + hCell(gTxt('status')). + column_head('downloads', 'downloads', $sort_link, true, $switch_dir, $crit, $search_method) + ); + + while ($a = nextRow($rs)) + { + extract($a); + + // god I hate javascript in php + $insert = ''.upm_file_popper_gTxt('attach_file').''; + + $tag_url = '?event=tag'.a.'tag_name=file_download_link'.a.'id='.$id.a.'description='.urlencode($description). + a.'filename='.urlencode($filename); + + $file_exists = file_exists(build_file_path($file_base_path, $filename)); + + $status = ($file_exists) ? + ''.gTxt('file_status_ok').'' : + ''.gTxt('file_status_missing').''; + + if (!isset($downloads)) + { + safe_alter('txp_file', "ADD downloads INT DEFAULT '0' NOT NULL"); + $downloads = 0; + } + + elseif (empty($downloads)) + { + $downloads = '0'; + } + + + echo n.n.tr( + + n.td($id). + + td(''.$filename.'', 125). + + td($description, 150). + td($category, 90). + + td($insert). + + td( + n.'' + , 75). + + td($status, 45). + + td( + ($downloads == '0' ? gTxt('none') : $downloads) + , 25) + ); + } + + echo endTable(). + + nav_form('upm_file_popper', $page, $numPages, $sort, $dir, $crit, $search_method). + + upm_file_popper_pageby_form(). + + n.tag( + n.graf(upm_file_popper_gTxt('return')). + n.graf(''.gTxt('yes').'.'. + ' '.gTxt('no').'.') + , 'div', ' id="return" style="display: none; width: 200px; height: 75px;"'). + + n.graf(upm_file_popper_gTxt('success'), ' id="success" style="display: none; width: 150px; height: 35px;"'). + n.graf(upm_file_popper_gTxt('failed'), ' id="failed" style="display: none; width: 150px; height: 35px;"'); + } + } + +// ------------------------------------------------------------- + + function upm_file_popper_search_form($crit, $method, $sort, $dir) + { + $default_method = 'filename'; + + $method = ($method) ? $method : $default_method; + + $methods = array( + 'id' => gTxt('id'), + 'filename' => gTxt('file_name'), + 'description' => gTxt('description'), + 'category' => gTxt('file_category') + ); + + return n.n.'
'. + graf( + ''.sp. + selectInput('search_method', $methods, $method, '', '', 'upm-file-popper-search').sp. + fInput('text', 'crit', $crit, 'edit', '', '', '15'). + eInput('upm_file_popper'). + hInput('bm','true'). + fInput('submit', 'search', gTxt('go'), 'smallerbox') + ). + + ($crit ? n.graf(''.upm_file_popper_gTxt('view_all').'') : ''). + + n.'
'; + } + +// ------------------------------------------------------------- + + function upm_file_popper_pageby_form() + { + global $prefs; + + $vals = array( + 15 => 15, + 25 => 25, + 50 => 50, + 100 => 100 + ); + + $select_page = selectInput('qty', $vals, $prefs['file_list_pageby'], '', 1); + + // proper localisation + $page = str_replace('{page}', $select_page, gTxt('view_per_page')); + + return form( + '
'. + $page. + eInput('upm_file_popper'). + sInput('upm_file_popper_change_pageby'). + hInput('bm', '1'). + ''. + '
' + ); + } + +// ------------------------------------------------------------- + + function upm_file_popper_link() + { + $view = gps('view'); + + if ($view == 'text' or empty($view)) + { + echo <<
+ +
+ + +form; + } + } + +// ------------------------------------------------------------- + + function upm_file_popper_js() + { + global $prefs; + + while (@ob_end_clean()); + + header("Content-type: text/javascript"); + + if (empty($prefs['upm_file_field'])) + { + $lang_forgot_field = upm_file_popper_gTxt('forgot_field'); + + echo << a:contains("$txt")'). + before(link); +}); +js; + + exit(0); + } + + elseif (gps('name') == 'pop') + { + $lang_check_leave = upm_file_popper_gTxt('check_leave'); + + echo << 'Attach', + 'attach_file' => 'Attach File', + 'check_leave' => 'You have made changes to the current post which you have not saved. Continue without saving?', + 'description_for' => 'Description for', + 'failed' => 'Insert failed.', + 'file_selector' => 'File Selector', + 'forgot_field' => 'You forgot to define the custom field for upm_file/upm_file_popper to use. Ensure that you have a custom field available, and that you have upm_file installed and activated, then visit Extensions > upm_file.', + 'no_description' => 'No description has been defined for this file.', + 'packet_custom_field' => 'Packet Custom Field', + 'return' => 'Return to editing the post?', + 'success' => 'Success.', + 'view_all' => 'View All' + ); + + return strtr($lang[$var], $atts); + } diff --git a/upm_file_popper-0.2.2.orig b/upm_file_popper-0.2.2.orig new file mode 100644 index 0000000..b5a23c0 --- /dev/null +++ b/upm_file_popper-0.2.2.orig @@ -0,0 +1,650 @@ +if (@txpinterface == 'admin') + { + add_privs('upm_file_popper', '1,2,3,4,5'); + register_callback('upm_file_popper', 'upm_file_popper'); + + add_privs('upm_file_popper_link', '1,2,3,4,5'); + register_callback('upm_file_popper_link', 'article'); + + add_privs('upm_file_popper_js', '1,2,3,4,5'); + register_callback('upm_file_popper_js', 'upm_file_popper_js', '', 1); + + add_privs('upm_file_popper_img', '1,2,3,4,5'); + register_callback('upm_file_popper_img', 'upm_file_popper_img', '', 1); + + register_callback('upm_file_popper_menu', 'article_ui', 'extend_col_1'); + + } + + /** + * Insert upm_file_popper link in column 1 on the write-tab + * + * @param string $event (article_ui) + * @param string $step (extend_col_1) + */ + function upm_file_popper_menu($event, $step) { + return '

'.upm_file_popper_gTxt('attach_file').'

'; + } + +// ------------------------------------------------------------- + + function upm_file_popper() + { + global $step, $prefs; + + if ($step == 'upm_file_popper_change_pageby') + { + event_change_pageby('file'); + $GLOBALS['prefs'] = get_prefs(); + } + + upm_file_popper_list(); + } + +// ------------------------------------------------------------- + + function upm_file_popper_list() + { + global $file_base_path, $prefs; + + pagetop(upm_file_popper_gTxt('file_selector')); + + echo << + + + + +css; + + extract(gpsa(array('page', 'sort', 'dir', 'crit', 'search_method'))); + if ($sort === '') $sort = get_pref('file_sort_column', 'filename'); + if ($dir === '') $dir = get_pref('file_sort_dir', 'asc'); + $dir = ($dir == 'desc') ? 'desc' : 'asc'; + + switch ($sort) + { + case 'id': + $sort_sql = "id $dir, filename asc"; + break; + + case 'filename': + $sort_sql = "filename $dir"; + break; + + case 'description': + $sort_sql = 'description '.$dir.', filename desc'; + break; + + case 'category': + $sort_sql = "category $dir, filename asc"; + break; + + case 'downloads': + $sort_sql = "downloads $dir, filename asc"; + break; + + default: + $dir = 'desc'; + $sort_sql = "filename $dir"; + break; + } + + $switch_dir = ($dir == 'desc') ? 'asc' : 'desc'; + + $criteria = 1; + + if ($search_method and $crit) + { + $crit_escaped = doSlash($crit); + + $critsql = array( + 'id' => "id = '$crit_escaped'", + 'filename' => "filename like '%$crit_escaped%'", + 'category' => "category like '%$crit_escaped%'", + 'description' => "description like '%$crit_escaped%'" + ); + + if (array_key_exists($search_method, $critsql)) + { + $criteria = $critsql[$search_method]; + $limit = 500; + } + + else + { + $search_method = ''; + $crit = ''; + } + } + + else + { + $search_method = ''; + $crit = ''; + } + + $total = safe_count('txp_file', "$criteria"); + + if ($total < 1) + { + if ($criteria != 1) + { + echo n.upm_file_popper_search_form($crit, $search_method, $sort, $dir). + n.graf(gTxt('no_results_found'), ' style="text-align: center;"'); + } + + else + { + echo n.graf(gTxt('no_files_recorded'), ' style="text-align: center;"'); + } + + return; + } + + $limit = max($prefs['file_list_pageby'], 15); + + list($page, $offset, $numPages) = pager($total, $limit, $page); + + echo upm_file_popper_search_form($crit, $search_method, $sort, $dir); + + $rs = safe_rows_start('*', 'txp_file', "$criteria order by $sort_sql limit $offset, $limit"); + + if ($rs) + { + $sort_link = 'upm_file_popper'.a.'bm=true'; + + echo startTable('','','txp-list'), + tr( + column_head('ID', 'id', $sort_link, true, $switch_dir, $crit, $search_method). + column_head('file_name', 'filename', $sort_link, true, $switch_dir, $crit, $search_method). + column_head('description', 'description', $sort_link, true, $switch_dir, $crit, $search_method). + column_head('file_category', 'category', $sort_link, true, $switch_dir, $crit, $search_method). + hCell(). + hCell(gTxt('tags')). + hCell(gTxt('status')). + column_head('downloads', 'downloads', $sort_link, true, $switch_dir, $crit, $search_method) + ); + + while ($a = nextRow($rs)) + { + extract($a); + + // god I hate javascript in php + $insert = ''.upm_file_popper_gTxt('attach_file').''; + + $tag_url = '?event=tag'.a.'tag_name=file_download_link'.a.'id='.$id.a.'description='.urlencode($description). + a.'filename='.urlencode($filename); + + $file_exists = file_exists(build_file_path($file_base_path, $filename)); + + $status = ($file_exists) ? + ''.gTxt('file_status_ok').'' : + ''.gTxt('file_status_missing').''; + + if (!isset($downloads)) + { + safe_alter('txp_file', "ADD downloads INT DEFAULT '0' NOT NULL"); + $downloads = 0; + } + + elseif (empty($downloads)) + { + $downloads = '0'; + } + + + echo n.n.tr( + + n.td($id). + + td(''.$filename.'', 125). + + td($description, 150). + td($category, 90). + + td($insert). + + td( + n.'' + , 75). + + td($status, 45). + + td( + ($downloads == '0' ? gTxt('none') : $downloads) + , 25) + ); + } + + echo endTable(). + + nav_form('upm_file_popper', $page, $numPages, $sort, $dir, $crit, $search_method). + + upm_file_popper_pageby_form(). + + n.tag( + n.graf(upm_file_popper_gTxt('return')). + n.graf(''.gTxt('yes').'.'. + ' '.gTxt('no').'.') + , 'div', ' id="return" style="display: none; width: 200px; height: 75px;"'). + + n.graf(upm_file_popper_gTxt('success'), ' id="success" style="display: none; width: 150px; height: 35px;"'). + n.graf(upm_file_popper_gTxt('failed'), ' id="failed" style="display: none; width: 150px; height: 35px;"'); + } + } + +// ------------------------------------------------------------- + + function upm_file_popper_search_form($crit, $method, $sort, $dir) + { + $default_method = 'filename'; + + $method = ($method) ? $method : $default_method; + + $methods = array( + 'id' => gTxt('id'), + 'filename' => gTxt('file_name'), + 'description' => gTxt('description'), + 'category' => gTxt('file_category') + ); + + return n.n.'
'. + graf( + ''.sp. + selectInput('search_method', $methods, $method, '', '', 'upm-file-popper-search').sp. + fInput('text', 'crit', $crit, 'edit', '', '', '15'). + eInput('upm_file_popper'). + hInput('bm','true'). + fInput('submit', 'search', gTxt('go'), 'smallerbox') + ). + + ($crit ? n.graf(''.upm_file_popper_gTxt('view_all').'') : ''). + + n.'
'; + } + +// ------------------------------------------------------------- + + function upm_file_popper_pageby_form() + { + global $prefs; + + $vals = array( + 15 => 15, + 25 => 25, + 50 => 50, + 100 => 100 + ); + + $select_page = selectInput('qty', $vals, $prefs['file_list_pageby'], '', 1); + + // proper localisation + $page = str_replace('{page}', $select_page, gTxt('view_per_page')); + + return form( + '
'. + $page. + eInput('upm_file_popper'). + sInput('upm_file_popper_change_pageby'). + hInput('bm', '1'). + ''. + '
' + ); + } + +// ------------------------------------------------------------- + + function upm_file_popper_link() + { + $view = gps('view'); + + if ($view == 'text' or empty($view)) + { + echo <<
+ +
+ + +form; + } + } + +// ------------------------------------------------------------- + + function upm_file_popper_js() + { + global $prefs; + + while (@ob_end_clean()); + + header("Content-type: text/javascript"); + + if (empty($prefs['upm_file_field'])) + { + $lang_forgot_field = upm_file_popper_gTxt('forgot_field'); + + echo << a:contains("$txt")'). + before(link); +}); +js; + + exit(0); + } + + elseif (gps('name') == 'pop') + { + $lang_check_leave = upm_file_popper_gTxt('check_leave'); + + echo << 'Attach', + 'attach_file' => 'Attach File', + 'check_leave' => 'You have made changes to the current post which you have not saved. Continue without saving?', + 'description_for' => 'Description for', + 'failed' => 'Insert failed.', + 'file_selector' => 'File Selector', + 'forgot_field' => 'You forgot to define the custom field for upm_file/upm_file_popper to use. Ensure that you have a custom field available, and that you have upm_file installed and activated, then visit Extensions > upm_file.', + 'no_description' => 'No description has been defined for this file.', + 'packet_custom_field' => 'Packet Custom Field', + 'return' => 'Return to editing the post?', + 'success' => 'Success.', + 'view_all' => 'View All' + ); + + return strtr($lang[$var], $atts); + } diff --git a/upm_file_popper-0.2.2.txt b/upm_file_popper-0.2.2.txt new file mode 100644 index 0000000..473f01a --- /dev/null +++ b/upm_file_popper-0.2.2.txt @@ -0,0 +1,327 @@ +# upm_file_popper v.0.2.2 +# An easy-to-use file picker, for use with upm_file. + +# Mary Fredborg +# http://utterplush.com/txp-plugins/upm_file_popper + +# .......................................................................... +# A plugin for Textpattern +# http://textpattern.com/ +# +# Adding Plugins to Your Textpattern Installation +# http://textpattern.net/wiki/index.php?title=Intermediate_Weblog_Model#Adding_Plugins_to_Your_Textpattern_Installation +# .......................................................................... + +YToxMTp7czo0OiJuYW1lIjtzOjE1OiJ1cG1fZmlsZV9wb3BwZXIiO3M6MTE6ImRlc2NyaXB0 +aW9uIjtzOjUwOiJBbiBlYXN5LXRvLXVzZSBmaWxlIHBpY2tlciwgZm9yIHVzZSB3aXRoIHVw +bV9maWxlLiI7czo3OiJ2ZXJzaW9uIjtzOjU6IjAuMi4yIjtzOjQ6InR5cGUiO2k6MTtzOjY6 +ImF1dGhvciI7czoxMzoiTWFyeSBGcmVkYm9yZyI7czoxMDoiYXV0aG9yX3VyaSI7czo0OToi +aHR0cDovL3V0dGVycGx1c2guY29tL3R4cC1wbHVnaW5zL3VwbV9maWxlX3BvcHBlciI7czo0 +OiJjb2RlIjtzOjE1ODk2OiJpZiAodHhwaW50ZXJmYWNlID09ICdhZG1pbicpCgl7CgkJYWRk +X3ByaXZzKCd1cG1fZmlsZV9wb3BwZXInLCAnMSwyLDMsNCw1Jyk7CgkJcmVnaXN0ZXJfY2Fs +bGJhY2soJ3VwbV9maWxlX3BvcHBlcicsICd1cG1fZmlsZV9wb3BwZXInKTsKCgkJYWRkX3By +aXZzKCd1cG1fZmlsZV9wb3BwZXJfbGluaycsICcxLDIsMyw0LDUnKTsKCQlyZWdpc3Rlcl9j +YWxsYmFjaygndXBtX2ZpbGVfcG9wcGVyX2xpbmsnLCAnYXJ0aWNsZScpOwoKCQlhZGRfcHJp +dnMoJ3VwbV9maWxlX3BvcHBlcl9qcycsICcxLDIsMyw0LDUnKTsKCQlyZWdpc3Rlcl9jYWxs +YmFjaygndXBtX2ZpbGVfcG9wcGVyX2pzJywgJ3VwbV9maWxlX3BvcHBlcl9qcycsICcnLCAx +KTsKCgkJYWRkX3ByaXZzKCd1cG1fZmlsZV9wb3BwZXJfaW1nJywgJzEsMiwzLDQsNScpOwoJ +CXJlZ2lzdGVyX2NhbGxiYWNrKCd1cG1fZmlsZV9wb3BwZXJfaW1nJywgJ3VwbV9maWxlX3Bv +cHBlcl9pbWcnLCAnJywgMSk7Cgl9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgoJZnVuY3Rpb24gdXBtX2ZpbGVf +cG9wcGVyKCkKCXsKCQlnbG9iYWwgJHN0ZXAsICRwcmVmczsKCgkJaWYgKCRzdGVwID09ICd1 +cG1fZmlsZV9wb3BwZXJfY2hhbmdlX3BhZ2VieScpCgkJewoJCQlldmVudF9jaGFuZ2VfcGFn +ZWJ5KCdmaWxlJyk7CgkJCSRHTE9CQUxTWydwcmVmcyddID0gZ2V0X3ByZWZzKCk7CgkJfQoK +CQl1cG1fZmlsZV9wb3BwZXJfbGlzdCgpOwoJfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKCWZ1bmN0aW9uIHVw +bV9maWxlX3BvcHBlcl9saXN0KCkKCXsKCQlnbG9iYWwgJGZpbGVfYmFzZV9wYXRoLCAkcHJl +ZnM7CgoJCXBhZ2V0b3AodXBtX2ZpbGVfcG9wcGVyX2dUeHQoJ2ZpbGVfc2VsZWN0b3InKSk7 +CgoJZWNobyA8PDxjc3MKPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KPCEtLQpsYWJlbCB7CmN1 +cnNvcjogcG9pbnRlcjsKY29sb3I6ICMwMDA7Cn0KCmltZyB7CmJvcmRlcjogbm9uZTsKfQoK +dWwgewptYXJnaW46IDA7CnBhZGRpbmc6IDA7Cmxpc3Qtc3R5bGU6IG5vbmU7Cn0KCmxpIHsK +bWFyZ2luOiAwIDAgMnB4IDA7CnBhZGRpbmc6IDA7Cn0KCnAgewptYXJnaW46IDVweCAwOwpw +YWRkaW5nOiAwOwp9CgoucmlnaHQgewp0ZXh0LWFsaWduOiByaWdodDsKfQoKLmNlbnRlciB7 +Cm1hcmdpbjogMCBhdXRvOwp0ZXh0LWFsaWduOiBjZW50ZXI7Cn0KCiNubyB7Cm1hcmdpbi1s +ZWZ0OiAyZW07Cn0KCiNyZXR1cm4sICNzdWNjZXNzLCAjZmFpbGVkIHsKcGFkZGluZzogMWVt +Owp0ZXh0LWFsaWduOiBjZW50ZXI7CmJhY2tncm91bmQtY29sb3I6ICNmZmY7CmJvcmRlcjog +NXB4IHNvbGlkICNmYzM7Cn0KLS0+Cjwvc3R5bGU+Cgo8c2NyaXB0IHR5cGU9InRleHQvamF2 +YXNjcmlwdCIgc3JjPSJpbmRleC5waHA/ZXZlbnQ9dXBtX2ZpbGVfcG9wcGVyX2pzJiMzODtu +YW1lPXBvcCI+PC9zY3JpcHQ+CmNzczsKCgkJZXh0cmFjdChncHNhKGFycmF5KCdwYWdlJywg +J3NvcnQnLCAnZGlyJywgJ2NyaXQnLCAnc2VhcmNoX21ldGhvZCcpKSk7CgoJCSRkaXIgPSAo +JGRpciA9PSAnZGVzYycpID8gJ2Rlc2MnIDogJ2FzYyc7CgoJCXN3aXRjaCAoJHNvcnQpCgkJ +ewoJCQljYXNlICdpZCc6CgkJCQkkc29ydF9zcWwgPSAiaWQgJGRpciwgZmlsZW5hbWUgYXNj +IjsKCQkJYnJlYWs7CgoJCQljYXNlICdmaWxlbmFtZSc6CgkJCQkkc29ydF9zcWwgPSAiZmls +ZW5hbWUgJGRpciI7CgkJCWJyZWFrOwoKCQkJY2FzZSAnZGVzY3JpcHRpb24nOgoJCQkJJHNv +cnRfc3FsID0gJ2Rlc2NyaXB0aW9uICcuJGRpci4nLCBmaWxlbmFtZSBkZXNjJzsKCQkJYnJl +YWs7CgoJCQljYXNlICdjYXRlZ29yeSc6CgkJCQkkc29ydF9zcWwgPSAiY2F0ZWdvcnkgJGRp +ciwgZmlsZW5hbWUgYXNjIjsKCQkJYnJlYWs7CgoJCQljYXNlICdkb3dubG9hZHMnOgoJCQkJ +JHNvcnRfc3FsID0gImRvd25sb2FkcyAkZGlyLCBmaWxlbmFtZSBhc2MiOwoJCQlicmVhazsK +CgkJCWRlZmF1bHQ6CgkJCQkkZGlyID0gJ2Rlc2MnOwoJCQkJJHNvcnRfc3FsID0gImZpbGVu +YW1lICRkaXIiOwoJCQlicmVhazsKCQl9CgoJCSRzd2l0Y2hfZGlyID0gKCRkaXIgPT0gJ2Rl +c2MnKSA/ICdhc2MnIDogJ2Rlc2MnOwoKCQkkY3JpdGVyaWEgPSAxOwoKCQlpZiAoJHNlYXJj +aF9tZXRob2QgYW5kICRjcml0KQoJCXsKCQkJJGNyaXRfZXNjYXBlZCA9IGRvU2xhc2goJGNy +aXQpOwoKCQkJJGNyaXRzcWwgPSBhcnJheSgKCQkJCSdpZCcJCQkJCT0+ICJpZCA9ICckY3Jp +dF9lc2NhcGVkJyIsCgkJCQknZmlsZW5hbWUnCQk9PiAiZmlsZW5hbWUgbGlrZSAnJSRjcml0 +X2VzY2FwZWQlJyIsCgkJCQknY2F0ZWdvcnknCQk9PiAiY2F0ZWdvcnkgbGlrZSAnJSRjcml0 +X2VzY2FwZWQlJyIsCgkJCQknZGVzY3JpcHRpb24nID0+ICJkZXNjcmlwdGlvbiBsaWtlICcl +JGNyaXRfZXNjYXBlZCUnIgoJCQkpOwoKCQkJaWYgKGFycmF5X2tleV9leGlzdHMoJHNlYXJj +aF9tZXRob2QsICRjcml0c3FsKSkKCQkJewoJCQkJJGNyaXRlcmlhID0gJGNyaXRzcWxbJHNl +YXJjaF9tZXRob2RdOwoJCQkJJGxpbWl0ID0gNTAwOwoJCQl9CgoJCQllbHNlCgkJCXsKCQkJ +CSRzZWFyY2hfbWV0aG9kID0gJyc7CgkJCQkkY3JpdCA9ICcnOwoJCQl9CgkJfQoKCQllbHNl +CgkJewoJCQkkc2VhcmNoX21ldGhvZCA9ICcnOwoJCQkkY3JpdCA9ICcnOwoJCX0KCgkJJHRv +dGFsID0gc2FmZV9jb3VudCgndHhwX2ZpbGUnLCAiJGNyaXRlcmlhIik7CgoJCWlmICgkdG90 +YWwgPCAxKQoJCXsKCQkJaWYgKCRjcml0ZXJpYSAhPSAxKQoJCQl7CgkJCQllY2hvIG4udXBt +X2ZpbGVfcG9wcGVyX3NlYXJjaF9mb3JtKCRjcml0LCAkc2VhcmNoX21ldGhvZCwgJHNvcnQs +ICRkaXIpLgoJCQkJCW4uZ3JhZihnVHh0KCdub19yZXN1bHRzX2ZvdW5kJyksICcgc3R5bGU9 +InRleHQtYWxpZ246IGNlbnRlcjsiJyk7CgkJCX0KCgkJCWVsc2UKCQkJewoJCQkJZWNobyBu +LmdyYWYoZ1R4dCgnbm9fZmlsZXNfcmVjb3JkZWQnKSwgJyBzdHlsZT0idGV4dC1hbGlnbjog +Y2VudGVyOyInKTsKCQkJfQoKCQkJcmV0dXJuOwoJCX0KCgkJJGxpbWl0ID0gbWF4KCRwcmVm +c1snZmlsZV9saXN0X3BhZ2VieSddLCAxNSk7CgoJCWxpc3QoJHBhZ2UsICRvZmZzZXQsICRu +dW1QYWdlcykgPSBwYWdlcigkdG90YWwsICRsaW1pdCwgJHBhZ2UpOwoKCQllY2hvIHVwbV9m +aWxlX3BvcHBlcl9zZWFyY2hfZm9ybSgkY3JpdCwgJHNlYXJjaF9tZXRob2QsICRzb3J0LCAk +ZGlyKTsKCgkJJHJzID0gc2FmZV9yb3dzX3N0YXJ0KCcqJywgJ3R4cF9maWxlJywgIiRjcml0 +ZXJpYSBvcmRlciBieSAkc29ydF9zcWwgbGltaXQgJG9mZnNldCwgJGxpbWl0Iik7CgoJCWlm +ICgkcnMpCgkJewoJCQkkc29ydF9saW5rID0gJ3VwbV9maWxlX3BvcHBlcicuYS4nYm09dHJ1 +ZSc7CgoJCQllY2hvIHN0YXJ0VGFibGUoJ2xpc3QnKSwKCQkJCXRyKAoJCQkJCWNvbHVtbl9o +ZWFkKCdJRCcsICdpZCcsICRzb3J0X2xpbmssIHRydWUsICRzd2l0Y2hfZGlyLCAkY3JpdCwg +JHNlYXJjaF9tZXRob2QpLgoJCQkJCWNvbHVtbl9oZWFkKCdmaWxlX25hbWUnLCAnZmlsZW5h +bWUnLCAkc29ydF9saW5rLCB0cnVlLAkkc3dpdGNoX2RpciwgJGNyaXQsICRzZWFyY2hfbWV0 +aG9kKS4KCQkJCQljb2x1bW5faGVhZCgnZGVzY3JpcHRpb24nLCAnZGVzY3JpcHRpb24nLCAk +c29ydF9saW5rLCB0cnVlLCAkc3dpdGNoX2RpciwgJGNyaXQsICRzZWFyY2hfbWV0aG9kKS4K +CQkJCQljb2x1bW5faGVhZCgnZmlsZV9jYXRlZ29yeScsICdjYXRlZ29yeScsICRzb3J0X2xp +bmssIHRydWUsICRzd2l0Y2hfZGlyLCAkY3JpdCwgJHNlYXJjaF9tZXRob2QpLgoJCQkJCWhD +ZWxsKCkuCgkJCQkJaENlbGwoZ1R4dCgndGFncycpKS4KCQkJCQloQ2VsbChnVHh0KCdzdGF0 +dXMnKSkuCgkJCQkJY29sdW1uX2hlYWQoJ2Rvd25sb2FkcycsICdkb3dubG9hZHMnLCAkc29y +dF9saW5rLCB0cnVlLCAkc3dpdGNoX2RpciwgJGNyaXQsICRzZWFyY2hfbWV0aG9kKQoJCQkJ +KTsKCgkJCXdoaWxlICgkYSA9IG5leHRSb3coJHJzKSkKCQkJewoJCQkJZXh0cmFjdCgkYSk7 +CgoJCQkJLy8gZ29kIEkgaGF0ZSBqYXZhc2NyaXB0IGluIHBocAoJCQkJJGluc2VydCA9ICc8 +YSBocmVmPSIjIiBvbmNsaWNrPSJ1cG1fZmlsZV9wb3BwZXJfYXR0YWNoRmlsZSgnLmNocigz +OSkuJGlkLmNocigzOSkuJyk7IHJldHVybiBmYWxzZTsiPjxpbWcgc3JjPSJpbmRleC5waHA/ +ZXZlbnQ9dXBtX2ZpbGVfcG9wcGVyX2ltZyIgd2lkdGg9IjE2cHgiIGhlaWdodD0iMTZweCIg +YWx0PSInLnVwbV9maWxlX3BvcHBlcl9nVHh0KCdhdHRhY2hfZmlsZScpLiciIHRpdGxlPSIn +LnVwbV9maWxlX3BvcHBlcl9nVHh0KCdhdHRhY2hfZmlsZScpLiciIC8+PC9hPic7CgoJCQkJ +JHRhZ191cmwgPSAnP2V2ZW50PXRhZycuYS4ndGFnX25hbWU9ZmlsZV9kb3dubG9hZF9saW5r +Jy5hLidpZD0nLiRpZC5hLidkZXNjcmlwdGlvbj0nLnVybGVuY29kZSgkZGVzY3JpcHRpb24p +LgoJCQkJCWEuJ2ZpbGVuYW1lPScudXJsZW5jb2RlKCRmaWxlbmFtZSk7CgoJCQkJJGZpbGVf +ZXhpc3RzID0gZmlsZV9leGlzdHMoYnVpbGRfZmlsZV9wYXRoKCRmaWxlX2Jhc2VfcGF0aCwg +JGZpbGVuYW1lKSk7CgoJCQkJJHN0YXR1cyA9ICgkZmlsZV9leGlzdHMpID8KCQkJCQknPHNw +YW4gY2xhc3M9Im9rIj4nLmdUeHQoJ2ZpbGVfc3RhdHVzX29rJykuJzwvc3Bhbj4nIDoKCQkJ +CQknPHNwYW4gY2xhc3M9Im5vdC1vayI+Jy5nVHh0KCdmaWxlX3N0YXR1c19taXNzaW5nJyku +Jzwvc3Bhbj4nOwoKCQkJCWlmICghaXNzZXQoJGRvd25sb2FkcykpCgkJCQl7CgkJCQkJc2Fm +ZV9hbHRlcigndHhwX2ZpbGUnLCAiQUREIGRvd25sb2FkcyBJTlQgREVGQVVMVCAnMCcgTk9U +IE5VTEwiKTsKCQkJCQkkZG93bmxvYWRzID0gMDsKCQkJCX0KCgkJCQllbHNlaWYgKGVtcHR5 +KCRkb3dubG9hZHMpKQoJCQkJewoJCQkJCSRkb3dubG9hZHMgPSAnMCc7CgkJCQl9CgoKCQkJ +CWVjaG8gbi5uLnRyKAoKCQkJCQluLnRkKCRpZCkuCgoJCQkJCXRkKCc8YSBocmVmPSIjIiBv +bmNsaWNrPSJ1cG1fZmlsZV9wb3BwZXJfd2FybkVkaXRGaWxlKCcuJGlkLicpOyByZXR1cm4g +ZmFsc2U7Ij4nLiRmaWxlbmFtZS4nPC9hPicsIDEyNSkuCgoJCQkJCXRkKCRkZXNjcmlwdGlv +biwgMTUwKS4KCQkJCQl0ZCgkY2F0ZWdvcnksIDkwKS4KCgkJCQkJdGQoJGluc2VydCkuCgoJ +CQkJCXRkKAoJCQkJCQluLic8dWw+Jy4KCQkJCQkJbi50Lic8bGk+PGEgdGFyZ2V0PSJfYmxh +bmsiIGhyZWY9IicuJHRhZ191cmwuYS4ndHlwZT10ZXh0aWxlIiBvbmNsaWNrPSJwb3BXaW4o +dGhpcy5ocmVmLCA0MDAsIDI1MCk7IHJldHVybiBmYWxzZTsiPlRleHRpbGU8L2E+PC9saT4n +LgoJCQkJCQluLnQuJzxsaT48YSB0YXJnZXQ9Il9ibGFuayIgaHJlZj0iJy4kdGFnX3VybC5h +Lid0eXBlPXRleHRwYXR0ZXJuIiBvbmNsaWNrPSJwb3BXaW4odGhpcy5ocmVmLCA0MDAsIDI1 +MCk7IHJldHVybiBmYWxzZTsiPlRleHRwYXR0ZXJuPC9hPjwvbGk+Jy4KCQkJCQkJbi50Lic8 +bGk+PGEgdGFyZ2V0PSJfYmxhbmsiIGhyZWY9IicuJHRhZ191cmwuYS4ndHlwZT14aHRtbCIg +b25jbGljaz0icG9wV2luKHRoaXMuaHJlZiwgNDAwLCAyNTApOyByZXR1cm4gZmFsc2U7Ij5Y +SFRNTDwvYT48L2xpPicuCgkJCQkJCW4uJzwvdWw+JwoJCQkJCSwgNzUpLgoKCQkJCQl0ZCgk +c3RhdHVzLCA0NSkuCgoJCQkJCXRkKAoJCQkJCQkoJGRvd25sb2FkcyA9PSAnMCcgPyBnVHh0 +KCdub25lJykgOiAkZG93bmxvYWRzKQoJCQkJCSwgMjUpCgkJCQkpOwoJCQl9CgoJCQllY2hv +IGVuZFRhYmxlKCkuCgoJCQkJbmF2X2Zvcm0oJ3VwbV9maWxlX3BvcHBlcicsICRwYWdlLCAk +bnVtUGFnZXMsICRzb3J0LCAkZGlyLCAkY3JpdCwgJHNlYXJjaF9tZXRob2QpLgoKCQkJCXVw +bV9maWxlX3BvcHBlcl9wYWdlYnlfZm9ybSgpLgoKCQkJCW4udGFnKAoJCQkJCW4uZ3JhZih1 +cG1fZmlsZV9wb3BwZXJfZ1R4dCgncmV0dXJuJykpLgoJCQkJCW4uZ3JhZignPGEgaWQ9Inll +cyIgaHJlZj0iIyIgb25jbGljaz0idXBtX2ZpbGVfcG9wcGVyX2dvQmFjayh0aGlzLmhyZWYp +OyByZXR1cm4gZmFsc2U7Ij4nLmdUeHQoJ3llcycpLic8L2E+LicuCgkJCQkJCScgPGEgaWQ9 +Im5vIiBocmVmPSIjIiBvbmNsaWNrPSJ1cG1fZmlsZV9wb3BwZXJfZG9uZShcJ3JldHVyblwn +KTsgcmV0dXJuIGZhbHNlOyI+Jy5nVHh0KCdubycpLic8L2E+LicpCgkJCQksICdkaXYnLAkn +IGlkPSJyZXR1cm4iIHN0eWxlPSJkaXNwbGF5OiBub25lOyB3aWR0aDogMjAwcHg7IGhlaWdo +dDogNzVweDsiJykuCgoJCQkJbi5ncmFmKHVwbV9maWxlX3BvcHBlcl9nVHh0KCdzdWNjZXNz +JyksICcgaWQ9InN1Y2Nlc3MiIHN0eWxlPSJkaXNwbGF5OiBub25lOyB3aWR0aDogMTUwcHg7 +IGhlaWdodDogMzVweDsiJykuCgkJCQluLmdyYWYodXBtX2ZpbGVfcG9wcGVyX2dUeHQoJ2Zh +aWxlZCcpLCAnIGlkPSJmYWlsZWQiIHN0eWxlPSJkaXNwbGF5OiBub25lOyB3aWR0aDogMTUw +cHg7IGhlaWdodDogMzVweDsiJyk7CgkJfQoJfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKCWZ1bmN0aW9uIHVw +bV9maWxlX3BvcHBlcl9zZWFyY2hfZm9ybSgkY3JpdCwgJG1ldGhvZCwgJHNvcnQsICRkaXIp +Cgl7CgkJJGRlZmF1bHRfbWV0aG9kID0gJ2ZpbGVuYW1lJzsKCgkJJG1ldGhvZCA9ICgkbWV0 +aG9kKSA/ICRtZXRob2QgOiAkZGVmYXVsdF9tZXRob2Q7CgoJCSRtZXRob2RzID0JYXJyYXko +CgkJCSdpZCcJCQkJCT0+IGdUeHQoJ2lkJyksCgkJCSdmaWxlbmFtZScJCT0+IGdUeHQoJ2Zp +bGVfbmFtZScpLAoJCQknZGVzY3JpcHRpb24nID0+IGdUeHQoJ2Rlc2NyaXB0aW9uJyksCgkJ +CSdjYXRlZ29yeScJCT0+IGdUeHQoJ2ZpbGVfY2F0ZWdvcnknKQoJCSk7CgoJCXJldHVybiBu +Lm4uJzxmb3JtIG1ldGhvZD0iZ2V0IiBhY3Rpb249ImluZGV4LnBocCIgc3R5bGU9Im1hcmdp +bjogYXV0bzsgdGV4dC1hbGlnbjogY2VudGVyOyI+Jy4KCQkJZ3JhZigKCQkJCSc8bGFiZWwg +Zm9yPSJ1cG0tZmlsZS1wb3BwZXItc2VhcmNoIj4nLmdUeHQoJ3NlYXJjaCcpLic8L2xhYmVs +Picuc3AuCgkJCQlzZWxlY3RJbnB1dCgnc2VhcmNoX21ldGhvZCcsICRtZXRob2RzLCAkbWV0 +aG9kLCAnJywgJycsICd1cG0tZmlsZS1wb3BwZXItc2VhcmNoJykuc3AuCgkJCQlmSW5wdXQo +J3RleHQnLCAnY3JpdCcsICRjcml0LCAnZWRpdCcsICcnLCAnJywgJzE1JykuCgkJCQllSW5w +dXQoJ3VwbV9maWxlX3BvcHBlcicpLgoJCQkJaElucHV0KCdibScsJ3RydWUnKS4KCQkJCWZJ +bnB1dCgnc3VibWl0JywgJ3NlYXJjaCcsIGdUeHQoJ2dvJyksICdzbWFsbGVyYm94JykKCQkJ +KS4KCgkJCSgkY3JpdCA/IG4uZ3JhZignPGEgaHJlZj0iP2V2ZW50PXVwbV9maWxlX3BvcHBl +cicuYS4nYm09dHJ1ZSI+Jy51cG1fZmlsZV9wb3BwZXJfZ1R4dCgndmlld19hbGwnKS4nPC9h +PicpIDogJycpLgoKCQluLic8L2Zvcm0+JzsKCX0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCglmdW5jdGlvbiB1 +cG1fZmlsZV9wb3BwZXJfcGFnZWJ5X2Zvcm0oKQoJewoJCWdsb2JhbCAkcHJlZnM7CgoJCSR2 +YWxzID0gYXJyYXkoCgkJCTE1CT0+IDE1LAoJCQkyNQk9PiAyNSwKCQkJNTAJPT4gNTAsCgkJ +CTEwMCA9PiAxMDAKCQkpOwoKCQkkc2VsZWN0X3BhZ2UgPSBzZWxlY3RJbnB1dCgncXR5Jywg +JHZhbHMsICRwcmVmc1snZmlsZV9saXN0X3BhZ2VieSddLCAnJywgMSk7CgoJCS8vIHByb3Bl +ciBsb2NhbGlzYXRpb24KCQkkcGFnZSA9IHN0cl9yZXBsYWNlKCd7cGFnZX0nLCAkc2VsZWN0 +X3BhZ2UsIGdUeHQoJ3ZpZXdfcGVyX3BhZ2UnKSk7CgoJCXJldHVybiBmb3JtKAoJCQknPGRp +diBzdHlsZT0ibWFyZ2luOiBhdXRvOyB0ZXh0LWFsaWduOiBjZW50ZXI7Ij4nLgoJCQkJJHBh +Z2UuCgkJCQllSW5wdXQoJ3VwbV9maWxlX3BvcHBlcicpLgoJCQkJc0lucHV0KCd1cG1fZmls +ZV9wb3BwZXJfY2hhbmdlX3BhZ2VieScpLgoJCQkJaElucHV0KCdibScsICcxJykuCgkJCQkn +PG5vc2NyaXB0PiA8aW5wdXQgdHlwZT0ic3VibWl0IiB2YWx1ZT0iJy5nVHh0KCdnbycpLici +IGNsYXNzPSJzbWFsbGVyYm94IiAvPjwvbm9zY3JpcHQ+Jy4KCQkJJzwvZGl2PicKCQkpOwoJ +fQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLQoKCWZ1bmN0aW9uIHVwbV9maWxlX3BvcHBlcl9saW5rKCkKCXsKCQkk +dmlldyA9IGdwcygndmlldycpOwoKCQlpZiAoJHZpZXcgPT0gJ3RleHQnIG9yIGVtcHR5KCR2 +aWV3KSkKCQl7CgkJCWVjaG8gPDw8Zm9ybQoKPGZvcm0gYWN0aW9uPSIiPgo8aW5wdXQgdHlw +ZT0iaGlkZGVuIiBpZD0idXBtX2ZpbGVfcG9wcGVyX3N0YXJ0IiB2YWx1ZT0iIj4KPC9mb3Jt +PgoKPHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0iaW5kZXgucGhwP2V2ZW50 +PXVwbV9maWxlX3BvcHBlcl9qcyYjMzg7bmFtZT1saW5rIj48L3NjcmlwdD4KZm9ybTsKCQl9 +Cgl9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tCgoJZnVuY3Rpb24gdXBtX2ZpbGVfcG9wcGVyX2pzKCkKCXsKCQln +bG9iYWwgJHByZWZzOwoKCQl3aGlsZSAoQG9iX2VuZF9jbGVhbigpKTsKCgkJaGVhZGVyKCJD +b250ZW50LXR5cGU6IHRleHQvamF2YXNjcmlwdCIpOwoKCQlpZiAoZW1wdHkoJHByZWZzWyd1 +cG1fZmlsZV9maWVsZCddKSkKCQl7CgkJCSRsYW5nX2ZvcmdvdF9maWVsZCA9IHVwbV9maWxl +X3BvcHBlcl9nVHh0KCdmb3Jnb3RfZmllbGQnKTsKCgkJCWVjaG8gPDw8anMKLyoKdXBtX2Zp +bGVfcG9wcGVyIC0gY3VzdG9tIGZpZWxkIGhhcyBub3QgYmVlbiBkZWZpbmVkCiovCgokKGRv +Y3VtZW50KS5yZWFkeShmdW5jdGlvbigpIHsKCWFsZXJ0KCckbGFuZ19mb3Jnb3RfZmllbGQn +KTsKfSk7CmpzOwoJCQlleGl0KDApOwoJCX0KCgkJZWxzZQoJCXsKCQkJJHVwbV9maWxlX2Zp +ZWxkID0gIWVtcHR5KCRwcmVmc1sndXBtX2ZpbGVfZmllbGQnXSkgPyAkcHJlZnNbJ3VwbV9m +aWxlX2ZpZWxkJ10gOiAnJzsKCQkJJHVwbV9maWxlX2ZpZWxkID0gc3RyX3JlcGxhY2UoJ18n +LCAnLScsICR1cG1fZmlsZV9maWVsZCk7CgkJfQoKCQlpZiAoZ3BzKCduYW1lJykgPT0gJ2xp +bmsnKQoJCXsKCQkJJHR4dCA9IGdUeHQoJ2FkdmFuY2VkX29wdGlvbnMnKTsKCgkJCSRsYW5n +X2F0dGFjaF9maWxlID0gdXBtX2ZpbGVfcG9wcGVyX2dUeHQoJ2F0dGFjaF9maWxlJyk7CgoJ +CQllY2hvIDw8PGpzCi8qCnVwbV9maWxlX3BvcHBlciAtIGFydGljbGUgd2luZG93CiovCgok +KGRvY3VtZW50KS5yZWFkeShmdW5jdGlvbigpIHsKCS8vIC0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLQoJLy8gc2V0dXAgYXJ0aWNsZSBlZGl0IHRyYWNraW5nCgoJJCgnI3VwbV9m +aWxlX3BvcHBlcl9zdGFydCcpLnZhbCggJCgnYm9keScpLnZhbCgpICk7CgoJLy8gLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgkvLyBjcmVhdGUgYW5kIGluc2VydCBwb3B1cCBs +aW5rCgoJdmFyIHcgPSA1NzU7Cgl2YXIgaCA9IDM3NTsKCgl2YXIgdCA9IChzY3JlZW4uaGVp +Z2h0KSA/IChzY3JlZW4uaGVpZ2h0IC0gaCkgLyAyIDogMDsKCXZhciBsID0gKHNjcmVlbi53 +aWR0aCkgPyAoc2NyZWVuLndpZHRoIC0gdykgLyAyIDogMDsKCgl2YXIgYSA9ICQoZG9jdW1l +bnQuY3JlYXRlRWxlbWVudCgnYScpKS4KCQl0ZXh0KCckbGFuZ19hdHRhY2hfZmlsZScpLgoJ +CWF0dHIoewoJCQl0YXJnZXQ6ICdfYmxhbmsnLAoJCQlocmVmOiAnP2V2ZW50PXVwbV9maWxl +X3BvcHBlclx1MDAyNmJtPTEnCgkJfSkuCgkJY2xpY2soZnVuY3Rpb24gKCkgewoJCQl2YXIg +dXBtX2ZpbGVfcG9wcGVyID0gd2luZG93Lm9wZW4odGhpcy5ocmVmLCAndXBtX2ZpbGVfcG9w +cGVyJywgJ3RvcCA9ICcrdCsnLCBsZWZ0ID0gJytsKycsIHdpZHRoID0gJyt3KycsIGhlaWdo +dCA9ICcraCsnLCB0b29sYmFyID0gbm8sIGxvY2F0aW9uID0gbm8sIGRpcmVjdG9yaWVzID0g +bm8sIHN0YXR1cyA9IHllcywgbWVudWJhciA9IG5vLCBzY3JvbGxiYXJzID0geWVzLCBjb3B5 +aGlzdG9yeSA9IG5vLCByZXNpemFibGUgPSB5ZXMnKTsKCQkJdXBtX2ZpbGVfcG9wcGVyLmZv +Y3VzKCk7CgkJCXJldHVybiBmYWxzZTsKCQl9KTsKCgl2YXIgbGluayA9ICQoZG9jdW1lbnQu +Y3JlYXRlRWxlbWVudCgnaDMnKSkuCgkJYWRkQ2xhc3MoJ3BsYWluJykuCgkJYXBwZW5kKGEp +OwoKCSQoJ2gzLnBsYWluID4gYTpjb250YWlucygiJHR4dCIpJykuCgkJYmVmb3JlKGxpbmsp +Owp9KTsKanM7CgoJCWV4aXQoMCk7Cgl9CgoJZWxzZWlmIChncHMoJ25hbWUnKSA9PSAncG9w +JykKCXsKCQkkbGFuZ19jaGVja19sZWF2ZSA9IHVwbV9maWxlX3BvcHBlcl9nVHh0KCdjaGVj +a19sZWF2ZScpOwoKCQllY2hvIDw8PGpzCi8qCnVwbV9maWxlX3BvcHBlciAtIHBvcHVwIHdp +bmRvdwoqLwoKCWZ1bmN0aW9uIHVwbV9maWxlX3BvcHBlcl9hdHRhY2hGaWxlKGlkKQoJewoJ +CXZhciBmaWVsZCA9ICQoJyMkdXBtX2ZpbGVfZmllbGQnLCB3aW5kb3cub3BlbmVyLmRvY3Vt +ZW50KS52YWwoKTsKCgkJaWYgKCQoJ2Zvcm1bbmFtZT0iYXJ0aWNsZSJdJywgd2luZG93Lm9w +ZW5lcikpCgkJewoJCQlpZiAoZmllbGQgPT0gJycpCgkJCXsKCQkJCSQoJyMkdXBtX2ZpbGVf +ZmllbGQnLCB3aW5kb3cub3BlbmVyLmRvY3VtZW50KS52YWwoaWQpOwoJCQkJcmV0dXJuIHVw +bV9maWxlX3BvcHBlcl9zaG93TXNnKCdzdWNjZXNzJyk7CgkJCX0KCgkJCWVsc2UKCQkJewoJ +CQkJJCgnIyR1cG1fZmlsZV9maWVsZCcsIHdpbmRvdy5vcGVuZXIuZG9jdW1lbnQpLnZhbChm +aWVsZCArICcsJyArIGlkKTsKCQkJCXJldHVybiB1cG1fZmlsZV9wb3BwZXJfc2hvd01zZygn +c3VjY2VzcycpOwoJCQl9CgkJfQoKCQlyZXR1cm4gdXBtX2ZpbGVfcG9wcGVyX3Nob3dNc2co +J2ZhaWxlZCcpOwoJfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKCWZ1bmN0aW9uIHVwbV9maWxlX3BvcHBlcl93 +YXJuRWRpdEZpbGUoaWQpCgl7CgkJaWYgKCQoJyNib2R5Jywgd2luZG93Lm9wZW5lci5kb2N1 +bWVudCkudmFsKCkgIT0gJCgnI3VwbV9maWxlX3BvcHBlcl9zdGFydCcsIHdpbmRvdy5vcGVu +ZXIuZG9jdW1lbnQpLnZhbCgpKQoJCXsKCQkJdmFyIGNoZWNrID0gY29uZmlybSgnJGxhbmdf +Y2hlY2tfbGVhdmUnKTsKCgkJCWlmIChjaGVjaykKCQkJewoJCQkJdXBtX2ZpbGVfcG9wcGVy +X2dvRWRpdEZpbGUoaWQpOwoJCQl9CgkJfQoKCQllbHNlCgkJewoJCQl1cG1fZmlsZV9wb3Bw +ZXJfZ29FZGl0RmlsZShpZCk7CgkJfQoJfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKCWZ1bmN0aW9uIHVwbV9m +aWxlX3BvcHBlcl9nb0VkaXRGaWxlKGlkKQoJewoJCXdpbmRvdy5vcGVuZXIuZm9jdXMoKTsK +CgkJaWYgKCQoJ2lucHV0W25hbWU9InN0ZXAiXScsIHdpbmRvdy5vcGVuZXIuZG9jdW1lbnQp +LnZhbCgpICE9ICdjcmVhdGUnKQoJCXsKCQkJJCgnI3llcycpLmF0dHIoJ2hyZWYnLCB3aW5k +b3cub3BlbmVyLmRvY3VtZW50LmxvY2F0aW9uKTsKCQkJdXBtX2ZpbGVfcG9wcGVyX3Nob3dN +c2coJ3JldHVybicpOwoJCX0KCgkJd2luZG93Lm9wZW5lci5kb2N1bWVudC5sb2NhdGlvbiA9 +ICc/ZXZlbnQ9ZmlsZVx1MDAyNnN0ZXA9ZmlsZV9lZGl0XHUwMDI2aWQ9JytpZDsKCX0KCi8v +IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0KCglmdW5jdGlvbiB1cG1fZmlsZV9wb3BwZXJfZ29CYWNrKHVybCkKCXsKCQl3 +aW5kb3cub3BlbmVyLmZvY3VzKCk7CgoJCXVwbV9maWxlX3BvcHBlcl9kb25lKCdyZXR1cm4n +KTsKCgkJd2luZG93Lm9wZW5lci5kb2N1bWVudC5sb2NhdGlvbiA9IHVybDsKCX0KCi8vIC0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0KCglmdW5jdGlvbiB1cG1fZmlsZV9wb3BwZXJfc2hvd01zZyhpZCkKCXsKCQl2YXIg +bXNnID0gJCgnIycraWQpOwoKCQltc2cuY3NzKHsKCQkJcG9zaXRpb246ICdhYnNvbHV0ZScs +CgkJCXRvcDoJCQkxMDAgKyB1cG1fZmlsZV9wb3BwZXJfc2Nyb2xsVG9wKCkgKyAncHgnLAoJ +CQlsZWZ0OgkJCSggKHVwbV9maWxlX3BvcHBlcl9wYWdlV2lkdGgoKSAvIDIpIC0gKHBhcnNl +SW50KG1zZy5jc3MoJ3dpZHRoJykpIC8gMikgKSArIHVwbV9maWxlX3BvcHBlcl9zY3JvbGxM +ZWZ0KCkgKyAncHgnLAoJCQlkaXNwbGF5OgknYmxvY2snCgkJfSk7CgoJCWlmIChpZCAhPSAn +cmV0dXJuJykKCQl7CgkJCXNldFRpbWVvdXQoInVwbV9maWxlX3BvcHBlcl9kb25lKCciK2lk +KyInKSIsIDEwMDApOwoJCX0KCX0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCglmdW5jdGlvbiB1cG1fZmlsZV9w +b3BwZXJfZG9uZShpZCkKCXsKCQkkKCcjJytpZCkuY3NzKCdkaXNwbGF5JywgJ25vbmUnKTsK +CX0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0KCglmdW5jdGlvbiB1cG1fZmlsZV9wb3BwZXJfcGFnZVdpZHRoKCkK +CXsKCQlpZiAoc2VsZi5pbm5lcldpZHRoKQoJCXsKCQkJcmV0dXJuIHNlbGYuaW5uZXJXaWR0 +aDsKCQl9CgoJCWVsc2UgaWYgKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCAmJiBkb2N1bWVu +dC5kb2N1bWVudEVsZW1lbnQuY2xpZW50V2lkdGgpCgkJewoJCQlyZXR1cm4gZG9jdW1lbnQu +ZG9jdW1lbnRFbGVtZW50LmNsaWVudFdpZHRoOwoJCX0KCgkJcmV0dXJuIDA7Cgl9CgovLyAt +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tCgoJZnVuY3Rpb24gdXBtX2ZpbGVfcG9wcGVyX3Njcm9sbFRvcCgpCgl7CgkJaWYg +KHNlbGYucGFnZVlPZmZzZXQpCgkJewoJCQlyZXR1cm4gc2VsZi5wYWdlWU9mZnNldDsKCQl9 +CgoJCWVsc2UgaWYgKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCAmJiBkb2N1bWVudC5kb2N1 +bWVudEVsZW1lbnQuc2Nyb2xsVG9wKQoJCXsKCQkJcmV0dXJuIGRvY3VtZW50LmRvY3VtZW50 +RWxlbWVudC5zY3JvbGxUb3A7CgkJfQoKCQlyZXR1cm4gMDsKCX0KCi8vIC0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCglm +dW5jdGlvbiB1cG1fZmlsZV9wb3BwZXJfc2Nyb2xsTGVmdCgpCgl7CgkJaWYgKHNlbGYucGFn +ZVlPZmZzZXQpCgkJewoJCQlyZXR1cm4gc2VsZi5wYWdlWE9mZnNldDsKCQl9CgoJCWVsc2Ug +aWYgKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCAmJiBkb2N1bWVudC5kb2N1bWVudEVsZW1l +bnQuc2Nyb2xsVG9wKQoJCXsKCQkJcmV0dXJuIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5z +Y3JvbGxMZWZ0OwoJCX0KCgkJcmV0dXJuIDA7Cgl9CmpzOwoKCQlleGl0KDApOwoJfQp9Cgov +LyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tCgoJZnVuY3Rpb24gdXBtX2ZpbGVfcG9wcGVyX2ltZygpCgl7CgkJd2hpbGUg +KEBvYl9lbmRfY2xlYW4oKSk7CgoJCWhlYWRlcigiQ29udGVudC10eXBlOiBpbWFnZS9naWYi +KTsKCgkJZWNobyBiYXNlNjRfZGVjb2RlKCdpVkJPUncwS0dnb0FBQUFOU1VoRVVnQUFBQkFB +QUFBUUNBWUFBQUFmOC85aEFBQUFCR2RCVFVFQUFLL0lOd1dLNicuCgkJCSdRQUFBQmwwUlZo +MFUyOW1kSGRoY21VQVFXUnZZbVVnU1cxaFoyVlNaV0ZrZVhISlpUd0FBQUp2U1VSQlZEakxw +WlByUzVOaEdJZjlXN1l2QllPJy4KCQkJJ2tobGtvcUNrbFdDaHYyV3lLaWs3YmxuTnJpczcy +Ymk2ZHVzMERMWjBURHhXMW9kdG9wRHM0RDhNRFp1TFUwa1hxNjFDaWpTSUlhc092djk0VlQn +LgoJCQknVWZMaUI3NGZYbmd1cDdudnJudkpBQkovNVBmTG5UVGRjd09qNFJzZFltbzVnbEJX +UDZpT3R6d3ZJS1NXc3RJMFdneDgwU0JibHBLdEU5S1FzLycuCgkJCSdXZTdFYVdvVC84d2JX +UDYxZ01tQ0gwbE1Edm9rVDRqMjVUaVFVL0lURmtlazlPdzYrN1dIMmd3c21haENQZHd5dzc1 +dXc5SEVPMmdVWlNrZnlJJy4KCQkJJzl6QlBDSk9vSjJTTW1nNDZONjFZTy9yTm9hMzlYaTQx +b0Z1WHlzTWZoMzYvRnAwYjdiQWZXQUg2UkdpMEhnbFdOQ2J6WWdKYUZqUnY2ekd1eSsnLgoJ +CQknYjlJdDk2TjNTUXZOS2lWOUh2U2FEZkZFSXhYSXRuUHMyM0J6SlFkNkRERVZNME9Lc29W +d0JHLzFWTXpwWFZXaGJrVU0ySzRvSkJEWXVHbWJLSScuCgkJCSdKMHF4c0FiSGZSTHpiamNu +VWJGQklweC9xSDN2UXY5YjNVMDNJUS9IZkZrRVJUemZGajh3OGpTcFI3R0JFMTIzdUZFWUF6 +YURSSXFYLzJKQXRKJy4KCQkJJ2JEYXQvQ09rZDdDTkJ2YTJjTXZxME1HeHAwUFJTQ1BGOEJY +aldHM0ZnTkhjOVhQVDcxT2p5M3NNRmRmSlJDZUt4RXNWdEt3Rkh3QUxaZkNVazMnLgoJCQkn +dElmTlI4WGlKd2MxTG1MNGRnMTQxSlBLdGozV1VkTkZKcUxHRlZQQzRPa1I0QnhhalRXc0No +WTY0d21Dbk14c1dQQ0hjdXRLQnhNVnA1bXhBMScuCgkJCSdTK2FNQ29tVG9hcVRSVVFrbkxU +SDYya0hPVkVFK1ZRbmphaHNjTkN5MGNNQldzU0kwVENRY1pjNUFMa0VZY2tMNUE1bm9XU0Jo +Zm0yQWVjTUFqJy4KCQkJJ2JjUldWMHBVVGgwSEU2NFROZjBtY3pjbm5ReXUvTWlsYUZKQ2Fl +MW53MmZiejFEblZPeHlHVGxLZVpmdC9GZjh4MUJSc3NmQUNqVHdRQUFBQUInLgoJCQknSlJV +NUVya0pnZ2c9PScpOwoKCQlleGl0KDApOwoJfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKCWZ1bmN0aW9uIHVw +bV9maWxlX3BvcHBlcl9nVHh0KCR2YXIsICRhdHRzID0gYXJyYXkoKSkKCXsKCQkkbGFuZyA9 +IGFycmF5KAoJCQknYXR0YWNoJyAgICAgICAgICAgICAgPT4gJ0F0dGFjaCcsCgkJCSdhdHRh +Y2hfZmlsZScgICAgICAgICA9PiAnQXR0YWNoIEZpbGUnLAoJCQknY2hlY2tfbGVhdmUnICAg +ICAgICAgPT4gJ1lvdSBoYXZlIG1hZGUgY2hhbmdlcyB0byB0aGUgY3VycmVudCBwb3N0IHdo +aWNoIHlvdSBoYXZlIG5vdCBzYXZlZC4gQ29udGludWUgd2l0aG91dCBzYXZpbmc/JywKCQkJ +J2Rlc2NyaXB0aW9uX2ZvcicgICAgID0+ICdEZXNjcmlwdGlvbiBmb3InLAoJCQknZmFpbGVk +JyAgICAgICAgICAgICAgPT4gJ0luc2VydCBmYWlsZWQuJywKCQkJJ2ZpbGVfc2VsZWN0b3In +ICAgICAgID0+ICdGaWxlIFNlbGVjdG9yJywKCQkJJ2ZvcmdvdF9maWVsZCcgICAgICAgID0+ +ICdZb3UgZm9yZ290IHRvIGRlZmluZSB0aGUgY3VzdG9tIGZpZWxkIGZvciB1cG1fZmlsZS91 +cG1fZmlsZV9wb3BwZXIgdG8gdXNlLiBFbnN1cmUgdGhhdCB5b3UgaGF2ZSBhIGN1c3RvbSBm +aWVsZCBhdmFpbGFibGUsIGFuZCB0aGF0IHlvdSBoYXZlIHVwbV9maWxlIGluc3RhbGxlZCBh +bmQgYWN0aXZhdGVkLCB0aGVuIHZpc2l0IEV4dGVuc2lvbnMgPiB1cG1fZmlsZS4nLAoJCQkn +bm9fZGVzY3JpcHRpb24nICAgICAgPT4gJ05vIGRlc2NyaXB0aW9uIGhhcyBiZWVuIGRlZmlu +ZWQgZm9yIHRoaXMgZmlsZS4nLAoJCQkncGFja2V0X2N1c3RvbV9maWVsZCcgPT4gJ1BhY2tl +dCBDdXN0b20gRmllbGQnLAoJCQkncmV0dXJuJyAgICAgICAgICAgICAgPT4gJ1JldHVybiB0 +byBlZGl0aW5nIHRoZSBwb3N0PycsCgkJCSdzdWNjZXNzJyAgICAgICAgICAgICA9PiAnU3Vj +Y2Vzcy4nLAoJCQkndmlld19hbGwnICAgICAgICAgICAgPT4gJ1ZpZXcgQWxsJwoJCSk7CgoJ +CXJldHVybiBzdHJ0cigkbGFuZ1skdmFyXSwgJGF0dHMpOwoJfSI7czo0OiJoZWxwIjtzOjI3 +MToiaDEuIHVwbV9maWxlX3BvcHBlcgoKVGhpcyBwbHVnaW4gYWRkcyBhIGxpbmsgdG8gYSBw +b3B1cCB3aW5kb3cgb2YgYSBsaXN0IG9mIHlvdXIgZmlsZXMsIHRvIGJlIHVzZWQgd2l0aCB1 +cG1fZmlsZS4gdXBtX2ZpbGUgaXMgcmVxdWlyZWQgaW4gb3JkZXIgZm9yIHVwbV9maWxlX3Bv +cHBlciB0byB3b3JrLgoKVGhlICJBdHRhY2giIGljb24gaXMgZnJvbSAiTWFyayBKYW1lcycg +U2lsa+KAnWljb24gc2V0IjpodHRwOi8vd3d3LmZhbWZhbWZhbS5jb20vbGFiL2ljb25zL3Np +bGsvLiI7czo4OiJoZWxwX3JhdyI7czoyNzE6ImgxLiB1cG1fZmlsZV9wb3BwZXIKClRoaXMg +cGx1Z2luIGFkZHMgYSBsaW5rIHRvIGEgcG9wdXAgd2luZG93IG9mIGEgbGlzdCBvZiB5b3Vy +IGZpbGVzLCB0byBiZSB1c2VkIHdpdGggdXBtX2ZpbGUuIHVwbV9maWxlIGlzIHJlcXVpcmVk +IGluIG9yZGVyIGZvciB1cG1fZmlsZV9wb3BwZXIgdG8gd29yay4KClRoZSAiQXR0YWNoIiBp +Y29uIGlzIGZyb20gIk1hcmsgSmFtZXMnIFNpbGvigJ1pY29uIHNldCI6aHR0cDovL3d3dy5m +YW1mYW1mYW0uY29tL2xhYi9pY29ucy9zaWxrLy4iO3M6MTU6ImFsbG93X2h0bWxfaGVscCI7 +aTowO3M6MzoibWQ1IjtzOjMyOiIwYTY4ZjU1MTM3ODVmOGYwMjA4OTVlNGQ1Mjg2MTI2ZSI7 +fQ==