Ed Nisley's Blog: Shop notes, electronics, firmware, machinery, 3D printing, laser cuttery, and curiosities. Contents: 100% human thinking, 0% AI slop.
Tag: Improvements
Making the world a better place, one piece at a time
We frequently host touring bicyclists who need a campsite in the Mid-Hudson Valley. The most recent couple has been riding for two years, starting eastward from Paris shortly after their wedding. Yeah, it’s a honeymoon trip.
After riding through Western and Eastern Europe, the Middle East, and several of the ‘Stans, JeanMarc’s handlebar mirror broke in Kazakhstan. Marie toted the carcass out of the ‘Stans, across India, through China, and then from Montreal to here. They’re biking to Houston, where they’ll fly to Peru, ride south and across the Andes, and work their way across the Atlantic on a cargo ship that eventually docks in Germany. Then, a year from now, they’ll just bike back to Paris.
Makes you feel like sludge, too, doesn’t it?
With that as prologue, JeanMarc wondered if I could fix the mirror mount. It started as a 10 mm plastic ball on a molded plastic fitting with an integral worm screw and strap; of course, the ball stem snapped off during a hard landing or some such event that comes naturally during long-distance riding. We kicked around some ideas, rummaged through the heap, and came up with a workable, albeit hideous solution.
I applied a Dremel slitting wheel to a pair of Zerk grease fittings, sliced off the inlet valve, extracted the valve spring, and cleaned up the residue to leave a somewhat misshapen 9.3 mm (really a scant 3/8 inch) ball-like end. A bit of lathe work converted a chunk of PVC pipe into a sleeve grooved for a metal hose clamp. I drilled two #3 holes, tapped them 1/4-28 (which, believe it or not, is the correct thread for a Zerk), bandsawed the pipe in half, introduced the pieces to Mr Belt Sander to round the edges, screwed Zerks into holes, and wound up with a pair of these:
Handlebar Mirror Mount – detail
Which looks awful on the handlebars, but we’re pretty sure it won’t break and he has a spare if the mirror on Marie’s bike snaps off:
Handlebar Mirror Mount – fixed
The Zerk fitting could unscrew, but the threads aren’t exactly in pristine condition after all that fussing and seem to be jammed firmly in place. If we had more time, I’d have heated the PVC and molded it around the handlebars, but we decided that wasn’t really necessary.
They rode off into the distance this morning… may you have smooth roads and a tailwind, JeanMarc and Marie!
I finally got around to replacing the sink in the front bathroom, which required a surprising number of tools:
Bathroom tool midden heap
As with the three other sinks I’ve replaced over the years, this one was a beautiful cast-iron monster made by the American Regulator & Standard Sanitary company, back before the name mushed into American Standard. This casting shows the original typography:
Bathroom sink by American Regulator and Standard Sanitary
A thin stainless steel trim ring and 16 (!) clamps held the sink in place on the countertop. Harsh experience taught me to support the sink while removing the clamps, because without the clamps there is nothing holding the sink up and I no longer enjoy stopping the tailpiece of a cast-iron sink with my chest…
Supporting the old sink
As it turned out, the sink required two pumps on the jack to break it free from the gunk gluing it in place; I was pleased to be wrong. I toted it to the end of the driveway, put a FREE sign on it, wherefrom it vanished within two hours. We’ll never know if it became someone’s precious antique or just a source of heavy brass fittings at the scrap metal recycler.
The original vanitory countertop had been recessed into the corner walls before the tiles went up, so I sawed out a chunk of the front edge and bent the plywood enough to tap it out without destroying anything. The countertop rotated around the left-front corner and the right-rear corner looked like this when the dust settled:
Extracted vanitory countertop
Half a century ago, the tile installers did a lovely mud job; the tiles adjoin and the grout is barely 1/16 inch wide. The vanitory case top was dead level, but the tiles weren’t quite aligned and my carefully applied and very neat 5 mm stripe of new caulk looks downright amateurish.
For what it’s worth, the new countertop started life as a stock kitchen countertop. I sawed off the backsplash, trimmed the length, cut a pair of notches to match the recesses, sawed a hole for the sink, rotated it into place, and screwed it down. You can go the custom-top route, but given that you only see about two square feet when you’re done, dropping $400 for 6 ft2 of fancy material with a gaping sink hole or over a kilobuck for a countertop with built-in recessed sink didn’t make enough sense to us.
And, no, vanitory is not a misspelling; I learned a new word during this project:
Vanitory job label
After we sell the house, the new owners will rip all this out without a second thought. After all, Dusky Rose went out of style a long time ago, a perfect hand-set array of 3/4 x 1-5/8 inch floor tiles isn’t attractive, and nobody cares about mud jobs. We’d rather keep that nice work around (even if we’re willing to put up with a simple countertop), but that’s just us; we’re the type of people who think keeping the original spring-loaded turned-wood dowel in the toilet paper holder is charming.
They’ll junk that space heater recessed into the wall, too: it has a long coily 120 V heating element strung inside, easily within the reach of questing little fingers. I added a GFI to that circuit, but I can’t imagine anybody else tolerating it. Times change.
Having had my old ICOM IC-Z1A HT stop working, most likely due to the innards finally shaking loose, I replaced it with a Wouxun KG-UV3D dual-band radio. Unfortunately, the interface box I designed to connect the Byonics TinyTrak 3+ GPS modem, the helmet earbud/mic, and the external battery pack to the Z-1A doesn’t work with the Wouxun. It’s all different:
Mechanical interface to the radio
Battery voltage
Power control
Mic level
PTT interface
I modified the interface box from my bike thusly:
GPS-HT Interface Circuit Mods for Wouxun
Because the KG-UV3D uses the Kenwood HT interface with a single ground for mic, speaker, and PTT functions, there’s no need for galvanic isolation; all the optoisolators & the audio transformer will Go Away when I rebuild it.
The plug connections:
Wouxun KG-UV3D Mic & Speaker Jacks
Tip
Ring
Shell
3.5 mm
+5 V
Mic audio
PTT
2.5 mm
Speaker audio
Buttons
Ground
One distressing change: the IC-Z1A mic power was 3.5 V behind 400 Ω = 6 mA into an optoisolator LED, but the KG-UV3D puts 5 V behind 50 kΩ = 100 µA into a dead short. I think the voltage will suffice to drive a logic-gate MOSFET to switch the power through a PNP transistor, but, for the moment, I hotwired OK1 and “control” the interface power by unplugging the external battery. The radio runs from its own snap-on Li-Ion pack.
The PTT now has a separate logic wire and is no longer multiplexed as a DC current on the audio line. The hack on OK2 was the easiest way to make that happen on the existing board, but the TT3 PTT Out line can probably drive the PTT directly.
I’m not happy with the audio levels; the KG-UV3D requires more mic gain (which change doesn’t appear in the mods) and more TT3 output. Having tediously calibrated the TT3 for the IC-Z1A, I’m not looking forward to doing that again. I still like using an analog multiplexer to switch the audio signal, though, because it doesn’t mix the machine noise with the voice transmissions.
Bungied GPS Interface Box
There being no way to mount the box on the radio and no way to control the interface power if I did, I simply lashed it to the side of the pack holding the radio behind the seat. Obviously, that can’t last forever…
I think the KG-UV3D stuffs more RFI into the mic circuit, because that box is now in the only position that doesn’t result in weird voice audio dropouts. Given the precarious nature of the thing, though, I must look again after getting it in a box on the radio.
Earth to amateur radio manufacturers: seen from out here, it’d be perfectly OK to standardize some of this stuff!
That little Lenovo Q150 doesn’t include an optical drive and, mostly, I don’t need one, but sometimes it’s handy to boot from a CD. I picked up a used DVD burner that also fits my Dell E1405 laptop (should I need a spare) and a tiny USB laptop drive case from the usual eBay sources for a grand total of $17 delivered.
The drive had a mounting bracket on the back that obviously had to come off, because the bracket screws snuggled right in among the USB adapter electronics:
E1405 DVD drive bracket vs USB electronics
In fact, that flat tab with a hole would have clunked up against the back of the case and prevented it from sliding all the way in, but the screws also foiled Plan B: flip the bracket around so the tab goes under the drive where it couldn’t get lost if I needed it again.
So now the bracket & screws live in a little bag in the Box o’ USB Stuff.
The DVD drive works fine with just a single USB cable, although the case came with a power-only USB cable, so the latter also lives in the bag with the bracket. Maybe I’ll need it in the unlikely event I actually burn a DVD in that drive?
A discussion on the MHV LUG mailing list pointed to the Gibson Research DNSBench utility. Letting it chew on all the nameservers it can find, then mulling over the results for a bit, produced this short list:
NY Public Library: 68.88.88.2
Level 3 Comm: 4.2.2.3 or .5
Yale: 130.132.1.10 or 11
NTT: 129.250.48.98
Feed those into Network Manager (or /etc/resolv.conf) in some permuted order and away you go… at least if you’re near Poughkeepsie and using Optimum Online. Change anything and the results will differ.
I’d been using OpenDNS at 208.67.22[02].22[02], but the new ones test out as marginally faster and are certainly more diverse. Who knew NYPL ran a DNS?
In the process of adapting my HT GPS interface to a Wouxun KG-UV3D radio, I printed some trial-fit pieces that consistently came out a little short. A bit of division showed that the larger pieces tended to be small in the X & Y axes by about 0.5%. This makes no difference for most 3D printed objects, but in this case the pieces must match up precisely with the radio’s existing battery interface layout. Half a percent matters a lot across a 75 mm part.
The advice found with most calibration pieces seems to boil down to fudging the printer’s steps/mm setting to make the answer come out right. The default Thing-O-Matic calibration (in machines/thingomatic.xml, wherever that’s hidden in your installation) looks like this:
You will, of course, have twiddled the maxfeedrate, homingfeedrate, and maybe even the comments to make the answers work on your machine.
Nophead slapped me upside the head when I made the same mistake that produced the stock stepspermm values: the pulley moves the belt by a fixed number of teeth on each revolution, so you just multiply by the belt tooth pitch to find the distance per revolution. Divide that into the number of (micro)steps per revolution and you get the exact stepspermm value. The stock MBI pulleys have 17 teeth and the belt has a 2 mm tooth pitch, so:
47.05882 step/mm = 1600 step / (17 * 2 mm)
That differs from the stock value by not very much at all:
0.999766 = 47.05882 / 47.069852
Given that these steppers aren’t losing steps (don’t start with me, you know how I get), I’m quite confident that the X and Y stages move by exactly the commanded distance every time.
The money quote is that ABS shrinks just about exactly 0.5% as it cools. That’s modulo the starting temperature, the molding process, and so forth and so on, but it’s a pretty nice match.
Therefore, fudging the printer’s scale isn’t appropriate, because that affects everything you might do with it. Such as, for example, the initial homing sequence, which depends on fairly precise locations that must match up with reality and have no shrinkage problems whatsoever.
Skeinforge’s Scale plugin applies a factor to the object, so that’s (probably) a more appropriate location for this adjustment. The myriad SF settings get broken down by Craft (extrusion, milling, whatever) and material (ABS, PLA, whatever), so if you can keep all that straight, then you can apply the appropriate Scale for each process and material.
The Scale doc may seem a tad sparse, but the plugin does have separate settings for the XY plane and the Z height. The latter (probably) doesn’t need scaling, because the nozzle height sets the actual extrusion level; the top layer or two will stretch to make the vertical size come out right as the object cools while it’s a-building.
I’ll toss a 1.005 scale factor into the XY mix and see what horrors that unleashes by way of unintended consequences.
More on the radio interface & suchlike in a while…
After that failure, I thought maybe making the spring guide pocket a bit wider and seating the spring wire in a solid plug would work. A tweak to the OpenSCAD script produced this, along with slightly larger locating ribs around the battery compartment:
NB-5L Holder – Plug spring – solid model
A closer look at the plug spring assembly:
NB-5L Holder – Plug spring – detail
The hole is now slightly larger, distinct from the side of the pocket, and the partition between the pocket and plug (although something of a formality) seats the plug during assembly. The plug started out at 3 mm in diameter, as I intended to try ramming a heated wire into a length of filament. That worked, mmmm, somewhat poorly, so I drilled a hole in a length of filament:
Music wire in filament plug
Unfortunately, that whole bodge didn’t work any better than the spring in the first pass at a holder, so I gave up and cast the springs in epoxy. The OpenSCAD code produces a 5 mm diameter hole that should provide a larger epoxy plate with better grip than the 3 mm holes in this picture, but it probably won’t make much difference:
Music wire in epoxy plug
The alert reader will note a complete faceplant: yeah, I forgot to solder the wires into the pins before blobbing the springs in place. Fortunately, the epoxy cures slowly enough that I could:
Take the picture
Immediately see the obvious problem
Ease the music wire springs out just a tidge
Extract the pins
Quick-like-a-bunny solder wires to pins
Insert pins with proper polarity
Ease springs back in place
I hate it when that happens…
With springs & wires properly in place and the epoxy cured overnight, the pins had considerably better springiness and free motion than before, although they didn’t have quite the range of travel I wanted. I think the spring wire bent slightly on the first push, as the pins never came quite as far out after that.
So this was a qualified success, but not a solid win. Time for round three…
The OpenSCAD source code:
// Holder for Canon NB-5L Li-Ion battery
// Ed Nisley KE4ZNU August 2011
include </home/ed/Thing-O-Matic/lib/MCAD/units.scad>
include </home/ed/Thing-O-Matic/lib/MCAD/boxes.scad>
include </home/ed/Thing-O-Matic/Useful Sizes.scad>
// Layout options
Layout = "Show"; // Case Lid Show Build Fit
//- Extrusion parameters - must match reality!
// Print with +2 shells and 3 solid layers
ThreadThick = 0.33;
ThreadWidth = 2.0 * ThreadThick;
HoleWindage = 0.2;
function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit);
Protrusion = 0.1; // make holes end cleanly
BuildOffset = 3.0; // clearance for build layout
//- Battery dimensions - rationalized from several samples
// Coordinate origin at battery corner by contact plates on bottom surface
BatteryLength = 45.25;
BatteryWidth = 32.17;
BatteryThick = 7.85;
ContactWidth = 2.10;
ContactLength = 4.10;
ContactRecess = 0.85;
ContactOC = 3.18; // center-to-center across contact face
ContactOffset = 4.45; // offset from battery edge
ContactHeight = 3.05; // offset from battery bottom plane
AlignThick = 2.2; // alignment recesses on contact face
AlignDepth = 2.0; // into face
AlignWidth1 = 0.7; // across face at contacts
AlignWidth2 = 2.8; // ... other edge
//- Pin dimensions
PinTipDia = 1.6;
PinTipLength = 10.0;
PinTaperLength = 2.3;
PinShaftDia = 2.4;
PinShaftLength = 6.8;
PinFerruleDia = 3.0;
PinFerruleLength = 2.0;
PinLength = PinTipLength + PinTaperLength + PinShaftLength + PinFerruleLength;
PinHoleOffset = 13.9; // tip to spring hole
ExtendRelax = 1.5 + ContactRecess; // pin extension when no battery is present
ExtendOvertravel = 1.0; // ... beyond engaged position
//- Holder dimensions
GuideRadius = ThreadWidth; // friction fit ridges
GuideOffset = 10;
WallThick = 4*ThreadWidth; // holder sidewalls
BaseThick = IntegerMultiple(6.0,ThreadThick); // bottom of holder to bottom of battery
TopThick = 6*ThreadThick; // top of battery to top of holder
ThumbRadius = 10.0; // thumb opening at end of battery
CornerRadius = 3*ThreadThick; // nice corner rounding
CaseLength = 2*WallThick + PinLength - ExtendRelax + ExtendOvertravel + BatteryLength + GuideRadius;
CaseWidth = 2*WallThick + 2*GuideRadius + BatteryWidth;
CaseThick = BaseThick + BatteryThick + TopThick;
//- XY origin at front left battery corner, Z on platform below that
CaseLengthOffset = -(WallThick + PinLength - ExtendRelax + ExtendOvertravel);
CaseWidthOffset = -(WallThick + GuideRadius);
CaseThickOffset = BaseThick;
LidLength = ExtendRelax - CaseLengthOffset;
//- Spring dimensions
SpringPlugDia = 5.0; // epoxy plug holding spring wire
SpringPlugLength = IntegerMultiple(1.5,ThreadThick);
SpringDia = 0.024 * inch; // music wire spring
SpringTravel = ExtendRelax + ExtendOvertravel;
SpringLength = BaseThick + ContactHeight - SpringPlugLength - 2*ThreadThick;
echo(str("Spring wire from end: ",WallThick + PinLength - PinHoleOffset));
echo(str(" from side: ",WallThick + GuideRadius + ContactOffset));
echo(str("Pin spacing on centers: ",ContactOC));
//----------------------
// Useful routines
module PolyCyl(Dia,Height,ForceSides=0) { // based on nophead's polyholes
Sides = (ForceSides != 0) ? ForceSides : (ceil(Dia) + 2);
FixDia = Dia / cos(180/Sides);
cylinder(r=(FixDia + HoleWindage)/2,
h=Height,
$fn=Sides);
}
module ShowPegGrid(Space = 10.0,Size = 1.0) {
Range = floor(50 / Space);
for (x=[-Range:Range])
for (y=[-Range:Range])
translate([x*Space,y*Space,Size/2])
%cube(Size,center=true);
}
//-------------------
//-- Guides for tighter friction fit
module Guides() {
translate([GuideOffset,-GuideRadius,CaseThickOffset])
PolyCyl(2*GuideRadius,(BatteryThick - Protrusion),4);
translate([GuideOffset,(BatteryWidth + GuideRadius),CaseThickOffset])
PolyCyl(2*GuideRadius,(BatteryThick - Protrusion),4);
translate([(BatteryLength - GuideOffset),-GuideRadius,CaseThickOffset])
PolyCyl(2*GuideRadius,(BatteryThick - Protrusion),4);
translate([(BatteryLength - GuideOffset),(BatteryWidth + GuideRadius),CaseThickOffset])
PolyCyl(2*GuideRadius,(BatteryThick - Protrusion),4);
translate([(BatteryLength + GuideRadius),GuideOffset/2,CaseThickOffset])
PolyCyl(2*GuideRadius,(BatteryThick - Protrusion),4);
translate([(BatteryLength + GuideRadius),(BatteryWidth - GuideOffset/2),CaseThickOffset])
PolyCyl(2*GuideRadius,(BatteryThick - Protrusion),4);
}
//-- Contact pins (holes therefore)
module PinShape() {
PolyPin = false;
union() {
if (PolyPin)
PolyCyl(PinTipDia,(PinTipLength + Protrusion));
else
cylinder(r=(PinTipDia + HoleWindage)/2,h=(PinTipLength + Protrusion),$fn=6);
translate([0,0,PinTipLength])
if (PolyPin)
PolyCyl(PinShaftDia,(PinTaperLength + PinShaftLength + Protrusion));
else
cylinder(r=(PinShaftDia + HoleWindage)/2,
h=(PinTaperLength + PinShaftLength + Protrusion),$fn=6);
translate([0,0,(PinLength - PinFerruleLength)])
if (PolyPin)
PolyCyl(PinFerruleDia,(PinFerruleLength + Protrusion));
else
cylinder(r=(PinFerruleDia + HoleWindage)/2,
h=(PinFerruleLength + Protrusion),$fn=6);
translate([0,0,PinLength])
if (PolyPin)
PolyCyl(PinFerruleDia,PinLength); // very long holes to punch case
else
cylinder(r=(PinFerruleDia + HoleWindage)/2,h=PinLength,$fn=6);
}
}
module PinAssembly() {
translate([ExtendRelax,ContactOffset,CaseThickOffset + ContactHeight]) {
rotate([0,270,0]) {
PinShape(); // pins
translate([0,(2*ContactOC),0])
PinShape();
}
}
translate([-(PinHoleOffset - ExtendRelax + SpringTravel/2 - SpringDia/2 - HoleWindage/2),
ContactOffset,
(CaseThickOffset + ContactHeight - SpringLength/2 - Protrusion)]) {
cube([(SpringTravel + SpringDia/2 + HoleWindage),
PinShaftDia,
(SpringLength + 2*Protrusion)],
center=true); // spring deflection pocket
translate([0,(2*ContactOC),0])
cube([(SpringTravel + SpringDia/2 + HoleWindage),
PinShaftDia,
(SpringLength + 2*Protrusion)],
center=true);
}
translate([-(PinHoleOffset - ExtendRelax),
ContactOffset,
(-Protrusion/2)]) {
PolyCyl(SpringDia,(BaseThick + ContactHeight + Protrusion),4); // spring wire
PolyCyl(SpringPlugDia,(SpringPlugLength + Protrusion)); // wire holder
translate([0,(2*ContactOC),0]) {
PolyCyl(SpringDia,(BaseThick + ContactHeight + Protrusion),4);
PolyCyl(SpringPlugDia,(SpringPlugLength + Protrusion));
}
}
}
//-- Case with origin at battery corner
module Case() {
difference() {
union() {
difference() {
translate([(CaseLength/2 + CaseLengthOffset),
(CaseWidth/2 + CaseWidthOffset),
(CaseThick/2)])
roundedBox([CaseLength,CaseWidth,CaseThick],CornerRadius); // basic case shape
translate([-ExtendOvertravel,-GuideRadius,CaseThickOffset])
cube([(BatteryLength + GuideRadius + ExtendOvertravel),
(BatteryWidth + 2* GuideRadius),
(BatteryThick + Protrusion)]); // battery space
}
Guides();
translate([-ExtendOvertravel,-GuideRadius,BaseThick])
cube([(AlignDepth + ExtendOvertravel),
(AlignWidth1 + GuideRadius),
AlignThick]); // alignment blocks
translate([-ExtendOvertravel,
(BatteryWidth - AlignWidth2),
BaseThick])
cube([(AlignDepth + ExtendOvertravel),
(AlignWidth2 + GuideRadius),
AlignThick]);
}
translate([(-ExtendOvertravel),
(CaseWidthOffset - Protrusion),
(CaseThickOffset + BatteryThick)])
cube([CaseLength,
(CaseWidth + 2*Protrusion),
(TopThick + Protrusion)]); // battery access
translate([(CaseLengthOffset - Protrusion),
(CaseWidthOffset - Protrusion),
(CaseThickOffset + BatteryThick)])
cube([(CaseLength + 2*Protrusion),
(CaseWidth + 2*Protrusion),
(TopThick + Protrusion)]); // battery insertion allowance
translate([(BatteryLength - Protrusion),
(CaseWidth/2 + CaseWidthOffset),
(CaseThickOffset + ThumbRadius)])
rotate([90,0,0])
rotate([0,90,0])
cylinder(r=ThumbRadius,
h=(WallThick + GuideRadius + 2*Protrusion),
$fn=22); // remove thumb notch
PinAssembly();
}
}
module Lid() {
difference() {
translate([0,0,(CaseThick/2 - BaseThick - BatteryThick)])
roundedBox([LidLength,
CaseWidth,CaseThick],CornerRadius);
translate([0,0,-(CaseThick/2)])
cube([(LidLength + 2*Protrusion),
(CaseWidth + 2*Protrusion),
(CaseThick)],center=true);
}
}
//-------------------
// Build it!
ShowPegGrid();
if (Layout == "Case")
Case();
if (Layout == "Lid")
Lid();
if (Layout == "Show") { // reveal pin assembly
difference() {
Case();
translate([(CaseLengthOffset - Protrusion),
(CaseWidthOffset - Protrusion + WallThick + ContactOffset + ContactOC),
(BaseThick + ContactHeight)])
cube([(-CaseLengthOffset + Protrusion),
(CaseWidth + 2*Protrusion),
CaseThick + BaseThick - ContactHeight + Protrusion]);
translate([(CaseLengthOffset - Protrusion),
(CaseWidthOffset - Protrusion),
-Protrusion])
cube([(-CaseLengthOffset + Protrusion),
(WallThick + GuideRadius + ContactOffset + Protrusion),
CaseThick]);
}
translate([ExtendRelax,ContactOffset,CaseThickOffset + ContactHeight]) { // pins
rotate([0,270,0]) {
%PinShape();
// translate([0,(2*ContactOC),0])
// %PinShape();
}
}
}
if (Layout == "Build") {
translate([-(CaseLength/2 + CaseLengthOffset),-(CaseWidthOffset - BuildOffset),0])
Case();
translate([0,(CaseLengthOffset/2 - BuildOffset),0])
rotate([0,0,90])
Lid();
}
if (Layout == "Fit") {
Case();
translate([(-LidLength/2 + ExtendRelax),
(CaseWidth/2 + CaseWidthOffset),
(BaseThick + BatteryThick)])
Lid();
translate([ExtendRelax,ContactOffset,CaseThickOffset + ContactHeight]) { // pins
rotate([0,270,0]) {
%PinShape();
translate([0,(2*ContactOC),0])
%PinShape();
}
}
}