问:
can i create ImageView programmatically before setcontentview android
can i initialize ImageView or any other view programmatically before setContentView(R.layout.activity_main); in android??

actually i am getting an instance of a custom class (not activity)
before onCreate method globally
like this

```<code>MyInAppPurchaseBilling myInAppPurchaseBilling = new MyInAppPurchaseBilling(MenuClass.this);
</code>```

and in that class constructor i have to use that context to initialize my preference class

```<code>public MyInAppPurchaseBilling(Activity launcher) {
        this.activity = launcher;
        tinyDB= new TinyDB(launcher);
    }
</code>```

Here is my logcat of error that i am facing

```<code>07-05 17:22:01.852 9660-9660/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.write.urdu.poetry.urdutexteditor, PID: 9660
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.write.urdu.poetry.urdutexteditor/com.write.urdu.poetry.urdutexteditor.MenuClass}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2339)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2494)
    at android.app.ActivityThread.access$900(ActivityThread.java:157)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1356)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:148)
    at android.app.ActivityThread.main(ActivityThread.java:5551)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
 Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
    at android.content.ContextWrapper.getPackageName(ContextWrapper.java:133)
    at android.preference.PreferenceManager.getDefaultSharedPreferencesName(PreferenceManager.java:375)
    at android.preference.PreferenceManager.getDefaultSharedPreferences(PreferenceManager.java:370)
    at com.write.urdu.poetry.urdutexteditor.TinyDB.<init>(TinyDB.java:55)
    at com.write.urdu.poetry.urdutexteditor.inapppurchase.MyInAppPurchaseBilling.<init>(MyInAppPurchaseBilling.java:48)
    at com.write.urdu.poetry.urdutexteditor.MenuClass.<init>(MenuClass.java:38)
    at java.lang.Class.newInstance(Native Method)
    at android.app.Instrumentation.newActivity(Instrumentation.java:1068)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2329)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2494)
    at android.app.ActivityThread.access$900(ActivityThread.java:157)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1356)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:148)
    at android.app.ActivityThread.main(ActivityThread.java:5551)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
</code>```

答:
What you have to do is</p>

```<code>   View view  = getLayoutInflater().inflate(R.layout.activity_main, null, false);
    imageView  = (ImageView) view.findViewById(R.id.image);

    setContentView(view);
</code>```

Body:
can i initialize ImageView or any other view programmatically before setContentView(R.layout.activity_main); in android??

actually i am getting an instance of a custom class (not activity)
before onCreate method globally
like this

MyInAppPurchaseBilling myInAppPurchaseBilling = new MyInAppPurchaseBilling(MenuClass.this);

and in that class constructor i have to use that context to initialize my preference class

public MyInAppPurchaseBilling(Activity launcher) {
        this.activity = launcher;
        tinyDB= new TinyDB(launcher);
    }

Here is my logcat of error that i am facing

07-05 17:22:01.852 9660-9660/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.write.urdu.poetry.urdutexteditor, PID: 9660
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.write.urdu.poetry.urdutexteditor/com.write.urdu.poetry.urdutexteditor.MenuClass}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2339)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2494)
    at android.app.ActivityThread.access$900(ActivityThread.java:157)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1356)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:148)
    at android.app.ActivityThread.main(ActivityThread.java:5551)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
 Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
    at android.content.ContextWrapper.getPackageName(ContextWrapper.java:133)
    at android.preference.PreferenceManager.getDefaultSharedPreferencesName(PreferenceManager.java:375)
    at android.preference.PreferenceManager.getDefaultSharedPreferences(PreferenceManager.java:370)
    at com.write.urdu.poetry.urdutexteditor.TinyDB.<init>(TinyDB.java:55)
    at com.write.urdu.poetry.urdutexteditor.inapppurchase.MyInAppPurchaseBilling.<init>(MyInAppPurchaseBilling.java:48)
    at com.write.urdu.poetry.urdutexteditor.MenuClass.<init>(MenuClass.java:38)
    at java.lang.Class.newInstance(Native Method)
    at android.app.Instrumentation.newActivity(Instrumentation.java:1068)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2329)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2494)
    at android.app.ActivityThread.access$900(ActivityThread.java:157)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1356)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:148)
    at android.app.ActivityThread.main(ActivityThread.java:5551)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)

Body:
What you have to do is

   View view  = getLayoutInflater().inflate(R.layout.activity_main, null, false);
    imageView  = (ImageView) view.findViewById(R.id.image);

    setContentView(view);


来源: stackexchange

问:
How can I do color output for cucumber tests in jenkins console output?
I use Jenkins pipeline for run cucumber tests. When I run cucumber test in bash console I see colorful output. But in Jenkins console output only single color text.
I run cucumber test from bash script file and I have tried add to this file:

```<code>CUCUMBER_COLORS='passed=green,bold:passed_param=green,skipped=cyan,bold:skipped_param=cyan,failed=red,bold:failed_paramm=red,pedning=yellow'
export CUCUMBER_COLORS
</code>```

like in this article https://github.com/cucumber/cucumber/wiki/Console-Colours
but it's not help.

答:
Please install the ANSIColor plugin  from https://wiki.jenkins.io/display/JENKINS/AnsiColor+Plugin

Then you will get color output.

ContentLicense: CC BY-SA 3.0

Body:
I use Jenkins pipeline for run cucumber tests. When I run cucumber test in bash console I see colorful output. But in Jenkins console output only single color text.
I run cucumber test from bash script file and I have tried add to this file:

CUCUMBER_COLORS='passed=green,bold:passed_param=green,skipped=cyan,bold:skipped_param=cyan,failed=red,bold:failed_paramm=red,pedning=yellow'
export CUCUMBER_COLORS

like in this article https://github.com/cucumber/cucumber/wiki/Console-Colours
but it's not help.


问:
C# SendGrid - SendAsync Method Error
I have followed a tutorial to setup SendGrid in my C# ASP.NET application.
I have the following code in my IdentityConfig.cs as suggested:

```<code>using SendGrid;
using System.Net;
using System.Configuration;
using System.Diagnostics;
using Microsoft.AspNet.Identity;
using System.Threading.Tasks;
using SendGrid.Helpers.Mail;

    public async Task SendAsync(IdentityMessage message)
    {
        await configSendGridasync(message);
    }

    // Use NuGet to install SendGrid (Basic C# client lib)
    private async Task configSendGridasync(IdentityMessage message)
    {
        var myMessage = new SendGridMessage();
        myMessage.AddTo(message.Destination);
        myMessage.From = new EmailAddress(
                            "johnlowry484@gmail.com", "John Lowry");
        myMessage.Subject = message.Subject;
        myMessage.PlainTextContent = message.Body;
        myMessage.HtmlContent = message.Body;

        var credentials = new NetworkCredential(
                   ConfigurationManager.AppSettings["mailAccount"],
                   ConfigurationManager.AppSettings["mailPassword"]
                   );

        // Create a Web transport for sending email.
        **var transportWeb = new Web(credentials);**

        // Send the email.
        if (transportWeb != null)
        {
            await transportWeb.DeliverAsync(myMessage);
        }
        else
        {
            Trace.TraceError("Failed to create Web transport.");
            await Task.FromResult(0);
        }
    }
</code>```

The line var transportWeb = new Web(credentials); is causing the error:

The type or namespace 'Web' could not be found

Everywhere I look online, SendGrid.Web(credentials) is valid, but it isn't for me.

Am I missing something?

Thanks,
John

答:
You could use SmtpClient to create an instance for the credentials.

```<code>var Smtp = new SmtpClient()
{
    Credentials = new NetworkCredential(ConfigurationManager.AppSettings["mailAccount"],
                    ConfigurationManager.AppSettings["mailPassword"])
};
...
await Smtp.SendAsync(myMessage);
</code>```

Title: C# SendGrid - SendAsync Method Error

Body:
I have followed a tutorial to setup SendGrid in my C# ASP.NET application.
I have the following code in my IdentityConfig.cs as suggested:

using SendGrid;
using System.Net;
using System.Configuration;
using System.Diagnostics;
using Microsoft.AspNet.Identity;
using System.Threading.Tasks;
using SendGrid.Helpers.Mail;

    public async Task SendAsync(IdentityMessage message)
    {
        await configSendGridasync(message);
    }

    // Use NuGet to install SendGrid (Basic C# client lib)
    private async Task configSendGridasync(IdentityMessage message)
    {
        var myMessage = new SendGridMessage();
        myMessage.AddTo(message.Destination);
        myMessage.From = new EmailAddress(
                            "johnlowry484@gmail.com", "John Lowry");
        myMessage.Subject = message.Subject;
        myMessage.PlainTextContent = message.Body;
        myMessage.HtmlContent = message.Body;

        var credentials = new NetworkCredential(
                   ConfigurationManager.AppSettings["mailAccount"],
                   ConfigurationManager.AppSettings["mailPassword"]
                   );

        // Create a Web transport for sending email.
        **var transportWeb = new Web(credentials);**

        // Send the email.
        if (transportWeb != null)
        {
            await transportWeb.DeliverAsync(myMessage);
        }
        else
        {
            Trace.TraceError("Failed to create Web transport.");
            await Task.FromResult(0);
        }
    }

The line var transportWeb = new Web(credentials); is causing the error:

The type or namespace 'Web' could not be found

Everywhere I look online, SendGrid.Web(credentials) is valid, but it isn't for me.

Am I missing something?

Thanks,
John

Body:
You could use SmtpClient to create an instance for the credentials.

var Smtp = new SmtpClient()
{
    Credentials = new NetworkCredential(ConfigurationManager.AppSettings["mailAccount"],
                    ConfigurationManager.AppSettings["mailPassword"])
};
...
await Smtp.SendAsync(myMessage);


问:
Loopback component push weird AWS error
I got an international app running with LoopbackJS push notifications component.
I actually got this weird error which seems related with AWS, but I can't understand how to solve it:

```<code>Push Notification error:  Error: 123993035933568:error:14094416:SSL routines:SSL3_READ_BYTES:sslv3 alert certificate unknown:../deps/openssl/openssl/ssl/s3_pkt.c:1293:SSL alert number 46

        at SlabBuffer.use (tls.js:235:18)
        at CleartextStream.read [as _read] (tls.js:455:29)
        at CleartextStream.Readable.read (_stream_readable.js:341:10)
        at EncryptedStream.write [as _write] (tls.js:369:25)
        at doWrite (_stream_writable.js:226:10)
        at writeOrBuffer (_stream_writable.js:216:5)
        at EncryptedStream.Writable.write (_stream_writable.js:183:11)
        at write (_stream_readable.js:602:24)
        at flow (_stream_readable.js:611:7)
        at Socket.pipeOnReadable (_stream_readable.js:643:5)
        at Socket.emit (events.js:92:17)

    events.js:72
            throw er; // Unhandled 'error' event
                  ^
    TypeError: Cannot read property 'error' of null
        at SecurePair.error (tls.js:1005:21)
        at EncryptedStream.CryptoStream._done (tls.js:703:22)
        at CleartextStream.onCryptoStreamFinish (tls.js:310:54)
        at CleartextStream.g (events.js:180:16)
        at CleartextStream.emit (events.js:92:17)
        at finishMaybe (_stream_writable.js:360:12)
        at endWritable (_stream_writable.js:367:3)
        at CleartextStream.Writable.end (_stream_writable.js:345:5)
        at CleartextStream.CryptoStream.end (tls.js:641:31)
        at Connection.<anonymous> (/data/API/myAPI/node_modules/loopback-component-push/node_modules/apn/lib/connection.js:194:17)
</code>```

Any clue?

答: My guess (but I'm not 100% sure) is that it was a certificate expiration error - but the trace does not reflect this correctly.</p>

Title: Loopback component push weird AWS error

Body:
I got an international app running with LoopbackJS push notifications component.
I actually got this weird error which seems related with AWS, but I can't understand how to solve it:

Push Notification error:  Error: 123993035933568:error:14094416:SSL routines:SSL3_READ_BYTES:sslv3 alert certificate unknown:../deps/openssl/openssl/ssl/s3_pkt.c:1293:SSL alert number 46

        at SlabBuffer.use (tls.js:235:18)
        at CleartextStream.read [as _read] (tls.js:455:29)
        at CleartextStream.Readable.read (_stream_readable.js:341:10)
        at EncryptedStream.write [as _write] (tls.js:369:25)
        at doWrite (_stream_writable.js:226:10)
        at writeOrBuffer (_stream_writable.js:216:5)
        at EncryptedStream.Writable.write (_stream_writable.js:183:11)
        at write (_stream_readable.js:602:24)
        at flow (_stream_readable.js:611:7)
        at Socket.pipeOnReadable (_stream_readable.js:643:5)
        at Socket.emit (events.js:92:17)

    events.js:72
            throw er; // Unhandled 'error' event
                  ^
    TypeError: Cannot read property 'error' of null
        at SecurePair.error (tls.js:1005:21)
        at EncryptedStream.CryptoStream._done (tls.js:703:22)
        at CleartextStream.onCryptoStreamFinish (tls.js:310:54)
        at CleartextStream.g (events.js:180:16)
        at CleartextStream.emit (events.js:92:17)
        at finishMaybe (_stream_writable.js:360:12)
        at endWritable (_stream_writable.js:367:3)
        at CleartextStream.Writable.end (_stream_writable.js:345:5)
        at CleartextStream.CryptoStream.end (tls.js:641:31)
        at Connection.<anonymous> (/data/API/myAPI/node_modules/loopback-component-push/node_modules/apn/lib/connection.js:194:17)

Any clue?


问:
Strange issue in Eclipse about Chinese character
platform：opensuse leap 42.2 KDE

Eclipse：Version: Oxygen Release (4.7.0)  UTF-8

```<code>xxx@linux-bq5s:~> java -showversion
java version "1.8.0_131"
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)
</code>```

I use Java write a simple code, the code is fine since I can run it in a special way (shows in the image), so don't focus too much on the code.

I put in the word "高数" ，but as you can see, it returned something else, but it's not done yet, look at the second picture.

I copied the word "高数" in input filed at somewhere else that I typed in, and I paste in the Eclipse input filed and enter, it returned correct.

I have changed another Input Method, but nothing changed.

答:
I run the code in terminal, and input normally, and it seems alright, so I think the problem is in the Eclipse

```<code>xzyx@linux-bq5s:~/桌面> java User
请输入指令：1-按书名选择；2-按序号选择
1
请输入书名
高数
您已选择：高数
xzyx@linux-bq5s:~/桌面> java User
请输入指令：1-按书名选择；2-按序号选择
1
请输入书名
电子
您已选择：电子
</code>```

In Eclipse, when I add a table before input the charater "高数", the code could work correct, I think there is something wrong with Eclipse's input field.

Body:
platform：opensuse leap 42.2 KDE

Eclipse：Version: Oxygen Release (4.7.0)  UTF-8

xxx@linux-bq5s:~> java -showversion
java version "1.8.0_131"
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)

I use Java write a simple code, the code is fine since I can run it in a special way (shows in the image), so don't focus too much on the code.

I put in the word "高数" ，but as you can see, it returned something else, but it's not done yet, look at the second picture.

I copied the word "高数" in input filed at somewhere else that I typed in, and I paste in the Eclipse input filed and enter, it returned correct.

I have changed another Input Method, but nothing changed.

Body:
I run the code in terminal, and input normally, and it seems alright, so I think the problem is in the Eclipse

xzyx@linux-bq5s:~/桌面> java User
请输入指令：1-按书名选择；2-按序号选择
1
请输入书名
高数
您已选择：高数
xzyx@linux-bq5s:~/桌面> java User
请输入指令：1-按书名选择；2-按序号选择
1
请输入书名
电子
您已选择：电子

In Eclipse, when I add a table before input the charater "高数", the code could work correct, I think there is something wrong with Eclipse's input field.


问:
rule to run a command on newly generated files with gnumake
I am very new with make. I have a perl script that generates three latex files. I want to create a makefile that would execute the perl script and then run lualatex on the newly generates tex files. So far, I have the following:

```<code>make:
    perl diff.pl
pdf:
    make
    $(eval LIST := $(shell ls *.tex))
    lualatex $(LIST).tex
    make clean

clean:
    rm -rf *.log *.aux
</code>```

Output:

```<code>lualatex FLAT_FLAT_AVDD.tex FLAT_FLAT_VDD.tex FLAT_FLAT_VSS.tex.tex
</code>```

And I only get one pdf FLAT_FLAT_AVDD.pdf.
How can I run lualatex on all the files?
I can just declare three variables and then run make. But, how can I automate this? Is there a loop concept in make? What is a better way to achieve this with "hard-coding" the file names?

Thanks.
EDIT:
I tried to incorporate foreach.

```<code>make:
    perl diff.pl

list:
    $(eval LIST := $(shell ls *.tex))

pdf:
    make list
    $(foreach tex,$(LIST),$(lualatex $(tex)))
    make clean

clean:
    rm -rf *.log *.aux
</code>```

and then I ran, make pdf
I got the following output in terminal.

```<code>dedehog01:tislam1:243 > make pdf
make list
make[1]: Entering directory `/home/tislam1/Documents/THESIS/Script_v0.1/BOX_approach/Modified_Layout_mesh/IR_Report_mesh/flat_flat/make'
make[1]: `list' is up to date.
make[1]: Leaving directory `/home/tislam1/Documents/THESIS/Script_v0.1/BOX_approach/Modified_Layout_mesh/IR_Report_mesh/flat_flat/make'
make clean
make[1]: Entering directory `/home/tislam1/Documents/THESIS/Script_v0.1/BOX_approach/Modified_Layout_mesh/IR_Report_mesh/flat_flat/make'
rm -rf *.log *.aux
make[1]: Leaving directory `/home/tislam1/Documents/THESIS/Script_v0.1/BOX_approach/Modified_Layout_mesh/IR_Report_mesh/flat_flat/make'
</code>```

答:
If you want to run your perl script on each make invocation, make is not really useful. A shell script could do the same. But if you really want to put all this a makefile:

```<code>.PHONY: all clean

all:
    perl diff.pl && \
    for t in *.tex; do \
        lualatex $$t; \
    done

clean:
    rm -rf *.log *.aux
</code>```

Else, you must know in advance the list of LaTeX sources. And you should probably stick with make target-prerequisites philosophy, that is, express all dependencies and the corresponding recipes:

```<code>LATEXSOURCES := foo.tex bar.tex ... cuz.tex
PDFS := $(patsubst %.tex,%.pdf,$(LATEXSOURCES))

all: $(PDFS)

$(LATEXSOURCES): diff.pl
    perl diff.pl

$(PDFS): %.pdf: %.tex
    lualatex $<

clean:
    rm -rf *.log *.aux
</code>```

But, as bobbogo noticed, with this second option, the perl script will be run as many times as there are LaTeX source files. A pattern rule solves this:

```<code>LATEXSOURCES := foo.tex bar.tex ... cuz.tex
PDFS := $(patsubst %.tex,%.pdf,$(LATEXSOURCES))

all: $(PDFS)

$(LATEXSOURCES): %.tex: diff.pl
    @echo "Rebuilding $(LATEXSOURCES)"
    perl diff.pl

$(PDFS): %.pdf: %.tex
    lualatex $<

clean:
    rm -rf *.log *.aux
</code>```

Now we have a true solution that:

rebuilds the LaTeX source files only if one is missing or if the perl script changed since they were last built,

executes the perl script only once to build all LaTeX source files,

expresses all dependencies between the various files.

There is still a problem, however: if only one LaTeX source file is missing and the others are up-to-date, the perl script will be run, all LaTeX source files will be rebuilt and their last modification time will thus be changed. Only the missing one will be compiled but, on the next make invocation, the others will also be re-compiled, which is a waste. bobbogo's proposal of using intermediate LaTeX sources solves this.

Body:
I am very new with make. I have a perl script that generates three latex files. I want to create a makefile that would execute the perl script and then run lualatex on the newly generates tex files. So far, I have the following:

make:
    perl diff.pl
pdf:
    make
    $(eval LIST := $(shell ls *.tex))
    lualatex $(LIST).tex
    make clean

clean:
    rm -rf *.log *.aux

Output:

lualatex FLAT_FLAT_AVDD.tex FLAT_FLAT_VDD.tex FLAT_FLAT_VSS.tex.tex

And I only get one pdf FLAT_FLAT_AVDD.pdf.
How can I run lualatex on all the files?
I can just declare three variables and then run make. But, how can I automate this? Is there a loop concept in make? What is a better way to achieve this with "hard-coding" the file names?

Thanks.
EDIT:
I tried to incorporate foreach.

make:
    perl diff.pl

list:
    $(eval LIST := $(shell ls *.tex))

pdf:
    make list
    $(foreach tex,$(LIST),$(lualatex $(tex)))
    make clean

clean:
    rm -rf *.log *.aux

and then I ran, make pdf
I got the following output in terminal.

dedehog01:tislam1:243 > make pdf
make list
make[1]: Entering directory `/home/tislam1/Documents/THESIS/Script_v0.1/BOX_approach/Modified_Layout_mesh/IR_Report_mesh/flat_flat/make'
make[1]: `list' is up to date.
make[1]: Leaving directory `/home/tislam1/Documents/THESIS/Script_v0.1/BOX_approach/Modified_Layout_mesh/IR_Report_mesh/flat_flat/make'
make clean
make[1]: Entering directory `/home/tislam1/Documents/THESIS/Script_v0.1/BOX_approach/Modified_Layout_mesh/IR_Report_mesh/flat_flat/make'
rm -rf *.log *.aux
make[1]: Leaving directory `/home/tislam1/Documents/THESIS/Script_v0.1/BOX_approach/Modified_Layout_mesh/IR_Report_mesh/flat_flat/make'

Body:
If you want to run your perl script on each make invocation, make is not really useful. A shell script could do the same. But if you really want to put all this a makefile:

.PHONY: all clean

all:
    perl diff.pl && \
    for t in *.tex; do \
        lualatex $$t; \
    done

clean:
    rm -rf *.log *.aux

Else, you must know in advance the list of LaTeX sources. And you should probably stick with make target-prerequisites philosophy, that is, express all dependencies and the corresponding recipes:

LATEXSOURCES := foo.tex bar.tex ... cuz.tex
PDFS := $(patsubst %.tex,%.pdf,$(LATEXSOURCES))

all: $(PDFS)

$(LATEXSOURCES): diff.pl
    perl diff.pl

$(PDFS): %.pdf: %.tex
    lualatex $<

clean:
    rm -rf *.log *.aux

But, as bobbogo noticed, with this second option, the perl script will be run as many times as there are LaTeX source files. A pattern rule solves this:

LATEXSOURCES := foo.tex bar.tex ... cuz.tex
PDFS := $(patsubst %.tex,%.pdf,$(LATEXSOURCES))

all: $(PDFS)

$(LATEXSOURCES): %.tex: diff.pl
    @echo "Rebuilding $(LATEXSOURCES)"
    perl diff.pl

$(PDFS): %.pdf: %.tex
    lualatex $<

clean:
    rm -rf *.log *.aux

Now we have a true solution that:

rebuilds the LaTeX source files only if one is missing or if the perl script changed since they were last built,

executes the perl script only once to build all LaTeX source files,

expresses all dependencies between the various files.

There is still a problem, however: if only one LaTeX source file is missing and the others are up-to-date, the perl script will be run, all LaTeX source files will be rebuilt and their last modification time will thus be changed. Only the missing one will be compiled but, on the next make invocation, the others will also be re-compiled, which is a waste. bobbogo's proposal of using intermediate LaTeX sources solves this.


问:
Debugging ReactJs in Chrome on page load - this and everything else is undefined when using console
I have a problem when debugging React on initial page load. As you can see from the screenshot, if I hover over this I can see the content but if I use console it says that this is undefined. This only happens when I reload the page, if I debug when clicking around this problem does not occur. I have React Developer Tools for Chrome installed and noted that when this is happening it only says Connecting to React…. Could this be the problem?

https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en

I'm using .tsx files (.jsx but with TypeScript) if that could matter.

Sources tab:

React tab:

答: Based on your updated comments, if you launch your function from the constructor and then stop it with a breakpoint, the constructor won't finish executing, which means it won't be able to correctly set the prototype chain and most important, set the correct reference to this.


问:
inline-block elements evenly spaced inside variable width container
I am trying to evenly space out inline-elements inside a 90% width container. I already looked for a solution and tried different things with zero success.

The most promising idea was the text-align: justify with and 100% width child

Here is my code:

```<code>    <div id="stage">
        <div class="thumb">
            <img src="generic_source" height="200px"/>
        </div>
        <div class="thumb">
            <img src="generic_source" height="200px"/>
        </div>
        .
        .
        .
        .
    </div>
</code>```

CSS:

```<code>#stage {
   width: 90%;
   margin: 50px auto;
   text-align: justify;
   border: 1px solid black;
}
#stage::after {
   display:inline-block;
   width:100%;
   content:'';
}
.thumb {
   height: 200px;
   display: inline-block;
   margin: 10px;
   width: 300px;
   text-align: center;
   padding: 2px;
}
</code>```

Everything looks great except the space left on the right. Zooming in and out makes it more or less obvious, but obvious nonetheless

I have 100+ thumbs that i would like to see symmetrically arranged

Thank you

EDIT:
Here you can see the example. Notice the space left to the right side border when scaling the page

答:
I think the only way to do it in css is by using flexbox. You'll need to change #stage selector:

```<code>#stage{
    width: 90%;
    margin: 50px auto;
    text-align: justify;
    border: 1px solid black;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-around;
}
</code>```

if you can't use it (need to support older browsers) you can try a js solution like freewall

Body:
I am trying to evenly space out inline-elements inside a 90% width container. I already looked for a solution and tried different things with zero success.

The most promising idea was the text-align: justify with and 100% width child

Here is my code:

        .
        .
        .
        .

CSS:

#stage {
   width: 90%;
   margin: 50px auto;
   text-align: justify;
   border: 1px solid black;
}
#stage::after {
   display:inline-block;
   width:100%;
   content:'';
}
.thumb {
   height: 200px;
   display: inline-block;
   margin: 10px;
   width: 300px;
   text-align: center;
   padding: 2px;
}

Everything looks great except the space left on the right. Zooming in and out makes it more or less obvious, but obvious nonetheless

I have 100+ thumbs that i would like to see symmetrically arranged

Thank you

EDIT:
Here you can see the example. Notice the space left to the right side border when scaling the page

Body:
I think the only way to do it in css is by using flexbox. You'll need to change #stage selector:

#stage{
    width: 90%;
    margin: 50px auto;
    text-align: justify;
    border: 1px solid black;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-around;
}

if you can't use it (need to support older browsers) you can try a js solution like freewall


问:
Tell bots apart from human visitors for stats?
I am looking to roll my own simple web stats script.

The only major obstacle on the road, as far as I can see, is telling human visitors apart from bots. I would like to have a solution for that which I don't need to maintain on a regular basis (i.e. I don't want to update text files with bot-related User-agents).

Is there any open service that does that, like Akismet does for spam?
Or is there a PHP project that is dedicated to recognizing spiders and bots and provides frequent updates?

To clarify: I'm not looking to block bots. I do not need 100% watertight results. I just
 want to exclude as many as I can from my stats. In
 know that parsing the user-Agent is an
 option but maintaining the patterns to
 parse for is a lot of work. My
 question is whether there is any
 project or service that does that
 already.

Bounty: I thought I'd push this as a reference question on the topic. The best / most original / most technically viable contribution will receive the bounty amount.

答:
You could exclude all requests that come from a User Agent that also requests robots.txt. All well behaved bots will make such a request, but the bad bots will escape detection.

You'd also have problems with false positives - as a human, it's not very often that I read a robots.txt in my browser, but I certainly can. To avoid these incorrectly showing up as bots, you could whitelist some common browser User Agents, and consider them to always be human. But this would just turn into maintaining a list of User Agents for browsers instead of one for bots.

So, this did-they-request-robots.txt approach certainly won't give 100% watertight results, but it may provide some heuristics to feed into a complete solution.

ContentLicense: CC BY-SA 2.5


问:
Using webpack to prepend variables for SCSS
Webpack amateur here... I'm trying to incorporate a theme.scss file to customize the theme used by React Toolbox by following the directions specified here, namely:

If you are using Webpack as module bundler, you are probably using sass-loader as well. What we want to do is to prepend to each SASS file compilation a bunch of variables to override and this can be done with the data option. For example:

sassLoader: { data: '@import "' + path.resolve(__dirname, 'theme/_theme.scss') + '";' }

In this case we have are prepending the theme import to each SASS compilation so the primary color will be changed in every single stylesheet.

I'm having trouble implementing this instruction with my current webpack configuration, which looks like this:

```<code>const webpack = require('webpack');
const path = require('path');
let ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
    context: path.join(__dirname, 'client'),
    entry: [
        './main.js',
    ],
    output: {
        path: path.join(__dirname, 'www'),
        filename: 'bundle.js',
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: [
                    'babel-loader',
                ],
            },
            {
                test: /\.css$/,
                use: [
                    "style-loader",
                    {
                        loader: "css-loader",
                        options: {
                            modules: true,
                            sourceMap: true,
                            importLoaders: 1,
                            localIdentName: "[name]--[local]--[hash:base64:8]"
                        }
                    },
                    "postcss-loader" // has separate config, see postcss.config.js nearby
                ]
            },
            {
                test: /\.scss$/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: [
                        {
                            loader: 'css-loader', options: {
                                sourceMap: true,
                                data: '@import "' + path.resolve(__dirname, 'theme.scss') + '";'
                            }
                        },
                        'postcss-loader',
                        {
                            loader: 'sass-loader', options: {
                                sourceMap: true,
                                data: '@import "' + path.resolve(__dirname, 'theme.scss') + '";'
                            }
                        },
                    ],
                })
            }
        ]
    },
    plugins: [
        new ExtractTextPlugin({
            filename: 'style.css',
            allChunks: true
        }),
        new webpack.DefinePlugin({
            'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
        }),
    ],
    resolve: {
        modules: [
            path.join(__dirname, 'node_modules'),
        ],
    },
};
</code>```

I don't get an error, but it seems like the data option is being entirely ignored because my file does not get imported.

Here is my theme.scss file (located in client/theme.scss):

```<code>@import "~react-toolbox/lib/colors";

$color-primary: $palette-red-500;
$color-primary-dark: $palette-red-700;

body {
  background-color: black; //testing
}
</code>```

I feel like I must be doing something stupid here, but I'm driving myself crazy. I have tried messing with the path of the theme.scss file (changing the data attribute to data: '@import "' + path.resolve(__dirname, 'client/theme.scss') + '";') but that doesn't make a difference. I'm surprised I'm not getting an error of some kind.

Any suggestions?

答:
The below configuration worked for me

```<code>  {
    test: /\.scss$/,
    include: /client/,
    use: ExtractTextPlugin.extract({
      fallback: 'style-loader',
      loader: [
        {
          loader: 'css-loader',
          query: {
            modules: true,
            sourceMap: false,
            localIdentName: '[name]_[local]_[hash:base64:5]',
          },
        },
        'postcss-loader',
        {
          loader: 'sass-loader',
          query: {
            sourceMap: false,
            data: `@import "${path.resolve(__dirname, 'client/_theme.scss')}";`
          }
        }
      ],
    }),
  },
</code>```

and client/_theme.scss file

```<code>@import "react-toolbox/lib/colors.css";

$color-primary: var(--palette-blue-500);
$color-primary-dark: var(--palette-blue-700);
</code>```

I checked the colors.css file in the react-toolbox library and used the same variable names. i.e --palette-blue-500, not $palette-blue-500.

Body:
Webpack amateur here... I'm trying to incorporate a theme.scss file to customize the theme used by React Toolbox by following the directions specified here, namely:

If you are using Webpack as module bundler, you are probably using sass-loader as well. What we want to do is to prepend to each SASS file compilation a bunch of variables to override and this can be done with the data option. For example:

sassLoader: { data: '@import "' + path.resolve(__dirname, 'theme/_theme.scss') + '";' }

In this case we have are prepending the theme import to each SASS compilation so the primary color will be changed in every single stylesheet.

I'm having trouble implementing this instruction with my current webpack configuration, which looks like this:

const webpack = require('webpack');
const path = require('path');
let ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
    context: path.join(__dirname, 'client'),
    entry: [
        './main.js',
    ],
    output: {
        path: path.join(__dirname, 'www'),
        filename: 'bundle.js',
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: [
                    'babel-loader',
                ],
            },
            {
                test: /\.css$/,
                use: [
                    "style-loader",
                    {
                        loader: "css-loader",
                        options: {
                            modules: true,
                            sourceMap: true,
                            importLoaders: 1,
                            localIdentName: "[name]--[local]--[hash:base64:8]"
                        }
                    },
                    "postcss-loader" // has separate config, see postcss.config.js nearby
                ]
            },
            {
                test: /\.scss$/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: [
                        {
                            loader: 'css-loader', options: {
                                sourceMap: true,
                                data: '@import "' + path.resolve(__dirname, 'theme.scss') + '";'
                            }
                        },
                        'postcss-loader',
                        {
                            loader: 'sass-loader', options: {
                                sourceMap: true,
                                data: '@import "' + path.resolve(__dirname, 'theme.scss') + '";'
                            }
                        },
                    ],
                })
            }
        ]
    },
    plugins: [
        new ExtractTextPlugin({
            filename: 'style.css',
            allChunks: true
        }),
        new webpack.DefinePlugin({
            'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
        }),
    ],
    resolve: {
        modules: [
            path.join(__dirname, 'node_modules'),
        ],
    },
};

I don't get an error, but it seems like the data option is being entirely ignored because my file does not get imported.

Here is my theme.scss file (located in client/theme.scss):

@import "~react-toolbox/lib/colors";

$color-primary: $palette-red-500;
$color-primary-dark: $palette-red-700;

body {
  background-color: black; //testing
}

I feel like I must be doing something stupid here, but I'm driving myself crazy. I have tried messing with the path of the theme.scss file (changing the data attribute to data: '@import "' + path.resolve(__dirname, 'client/theme.scss') + '";') but that doesn't make a difference. I'm surprised I'm not getting an error of some kind.

Any suggestions?

Body:
The below configuration worked for me

  {
    test: /\.scss$/,
    include: /client/,
    use: ExtractTextPlugin.extract({
      fallback: 'style-loader',
      loader: [
        {
          loader: 'css-loader',
          query: {
            modules: true,
            sourceMap: false,
            localIdentName: '[name]_[local]_[hash:base64:5]',
          },
        },
        'postcss-loader',
        {
          loader: 'sass-loader',
          query: {
            sourceMap: false,
            data: `@import "${path.resolve(__dirname, 'client/_theme.scss')}";`
          }
        }
      ],
    }),
  },

and client/_theme.scss file

@import "react-toolbox/lib/colors.css";

$color-primary: var(--palette-blue-500);
$color-primary-dark: var(--palette-blue-700);

I checked the colors.css file in the react-toolbox library and used the same variable names. i.e --palette-blue-500, not $palette-blue-500.


问:
What is the most optimal way of running an SQL Query with optional arguments?
I'm currently running the following query to add data to a table in my database:

```<code>INSERT INTO IDEIAS_INTERACOES (CODIGO, ARQUIVO, REMETENTE, MENSAGEM, UNIT, DATA)
VALUES (@codigo, @file, @remetente, @mensagem, @unit, @data)
</code>```

This works fine, however the @file argument isn't always present, and I want the column to be 'Undefined' in that case. I can accomplish this easily using ternary operators, but the resultant code is messy and probably unoptimal. What's a more elegant way of accomplishing this?

Ps.: I'm using the mssql module.

答:
Based on your comments, when the @file is not present, its value is 'undefined'.  You can use NULLIF to look for that value and return a NULL:

```<code>INSERT INTO IDEIAS_INTERACOES (CODIGO, ARQUIVO, REMETENTE, MENSAGEM, UNIT, DATA)
VALUES (@codigo, NULLIF(@file, 'Undefined'), @remetente, @mensagem, @unit, @data)
</code>```

Body:
I'm currently running the following query to add data to a table in my database:

INSERT INTO IDEIAS_INTERACOES (CODIGO, ARQUIVO, REMETENTE, MENSAGEM, UNIT, DATA)
VALUES (@codigo, @file, @remetente, @mensagem, @unit, @data)

This works fine, however the @file argument isn't always present, and I want the column to be 'Undefined' in that case. I can accomplish this easily using ternary operators, but the resultant code is messy and probably unoptimal. What's a more elegant way of accomplishing this?

Ps.: I'm using the mssql module.

Body:
Based on your comments, when the @file is not present, its value is 'undefined'.  You can use NULLIF to look for that value and return a NULL:

INSERT INTO IDEIAS_INTERACOES (CODIGO, ARQUIVO, REMETENTE, MENSAGEM, UNIT, DATA)
VALUES (@codigo, NULLIF(@file, 'Undefined'), @remetente, @mensagem, @unit, @data)


问:
IText: registering font: not found as file or resource
I am developing on windows plattform. My maven project has the following structure for font resources:

```<code>src/main/resources/package/name/fonts
</code>```

I try to register a font as following:

```<code>FontFactory.register("package/name/fonts/fontname.otf");
</code>```

But I get the error:

```<code>package/name/fonts/fontname.otf not found as file or resource
</code>```

What is my failure?

Thank you

答:
First I get the correct path with getResource():

```<code>String pathtofont = "/package/name/fonts/fontname.otf";
String fontname = myworkingclass.class.getResource(pathtofont).toString();
</code>```

then I get it registerd:

```<code>FontFactory.register(fontname);
</code>```

Important is that the path to font starts with a /.

Body:
I am developing on windows plattform. My maven project has the following structure for font resources:

src/main/resources/package/name/fonts

I try to register a font as following:

FontFactory.register("package/name/fonts/fontname.otf");

But I get the error:

package/name/fonts/fontname.otf not found as file or resource

What is my failure?

Thank you

Body:
First I get the correct path with getResource():

String pathtofont = "/package/name/fonts/fontname.otf";
String fontname = myworkingclass.class.getResource(pathtofont).toString();

then I get it registerd:

FontFactory.register(fontname);

Important is that the path to font starts with a /.


问:
making each canvas line draggable and droppable
I am able to draw some lines on the canvas.
I want to make each line draggable and droppable.

However, it is implemented by storing the positions of different lines in the array, how can I make each of them like an instance that is draggable and droppable? Or did I get it wrong?

You can check out the code here

var storedLines = []

http://jsfiddle.net/m1erickson/NnZ7a/

Thanks a lot!

答:
Canvas draggables.

To make draggable lines you keep an array of endpoints and an array of lines as indexes to end points.

Then when the user clicks and drags near an end point or line you just update the endpoints by the amount the mouse has moved.

A point, a line, and some lists

First create a simple point structure

```<code>const Point2 = (x,y) => ({x,y});  // creates a point
</code>```

Then an list that will hold points, add points, and what ever else you may need.

```<code>const list = {
    items : null,
    add(item) { this.items.push(item); return item },
    eachItem(callback) {
        var i;
        while(i < this.items.length){
             callback(this.items[i],i);
        }
    }
}
</code>```

You then create a points list from the list structure

```<code>function createList(extend){
    return Object.assign({},list,{items : []},extend);
}

const points = createList();
</code>```

The line is a set of point indexes

```<code>const Line = (p1,p2) => ({p1,p2});
const lines = createList();
</code>```

Finding the closest

To select a point from a mouse coordinate you need to find the closest point to the mouse.

```<code>// this will extend the points list
function getClosestPoint(from ,minDist) {
    var closestPoint;
    this.eachItem(point => {
        const dist = Math.hypot(from.x - point.x, from.y - point.y);
        if(dist < minDist){
            closestPoint = point;
            minDist = dist;
        }
    });
    return closestPoint;
}
</code>```

The same for the line but that is not as simple. You need a function that finds the distance that a point is from a line segment.

```<code>function distanceLineFromPoint(line,point){
    const lx = points.items[line.p1].x;
    const ly = points.items[line.p1].y;
    const v1x = points.items[line.p2].x - lx;
    const v1y = points.items[line.p2].y - ly;
    const v2x = point.x - lx;
    const v2y = point.y - ly;
    // get unit dist of closest point
    const u = (v2x * v1x + v2y * v1y)/(v1y * v1y + v1x * v1x);
    if(u >= 0 && u <= 1){  // is the point on the line
        return Math.hypot(lx + v1x * u - point.x, ly + v1y * u - point.y);
    } else if ( u < 0 ) {  // point is before start
        return Math.hypot(lx - point.x, ly - point.y);
    }
    // point is after end of line
    return Math.hypot(points.items[line.p2].x - point.x, points.items[line.p2].y - point.y);
}

// this will extend the lines list
function getClosestline(from ,minDist) {
    var closestLine;
    this.eachItem(line => {
        const dist = distanceLineFromPoint(line,from);
        if(dist < minDist){
            closestLine = line;
            minDist = dist;
        }
    });
    return closestLine;
}
</code>```

With these function we should have extended the list object so will recreate them with the extensions.

```<code> const points = createList({getClosest : getClosestPoint});
 const lines = createList({getClosest : getClosestline});
</code>```

Then the rest is implementing a mouse interface and a rendering function. You add draggable points and lines connecting them. If you click near a line or point you drag them. The snippet shows the rest.

User feedback is important

It is also important to show the correct user feedback. You need to set the cursor, tooltip (via canvas.style.cursor and canvas.title) and highlight objects that will be effected, so that the user knows what actions will happen and to what when they click and drag.

Also you should set the mouse events to the document rather than the canvas as this will capture the mouse drag allowing the user to drag outside the canvas while you still get the mouseup and move events.

Create and drag points and lines.

const ctx = canvas.getContext("2d");
const Point2 = (x,y) => ({x,y});  // creates a point
const Line = (p1,p2) => ({p1,p2});
const setStyle = (style) => eachOf(Object.keys(style), key => { ctx[key] = style[key] } );
const eachOf = (array, callback) => {var i = 0; while (i < array.length && callback(array[i],i ++) !== true ); };

const list = {
    items : null,
    add(item) { this.items.push(item); return item },
    eachItem(callback) {
        var i = 0;
        while(i < this.items.length){
             callback(this.items[i],i++);
        }
    }
}
function createList(extend){
    return Object.assign({},list,{items : []},extend);
}
// this will extend the points list
function getClosestPoint(from ,minDist) {
    var closestPoint;
    this.eachItem(point => {
        const dist = Math.hypot(from.x - point.x, from.y - point.y);
        if(dist < minDist){
            closestPoint = point;
            minDist = dist;
        }
    });
    return closestPoint;
}
function distanceLineFromPoint(line,point){
    const lx = points.items[line.p1].x;
    const ly = points.items[line.p1].y;
    const v1x = points.items[line.p2].x - lx;
    const v1y = points.items[line.p2].y - ly;
    const v2x = point.x - lx;
    const v2y = point.y - ly;
    // get unit dist of closest point
    const u = (v2x * v1x + v2y * v1y)/(v1y * v1y + v1x * v1x);
    if(u >= 0 && u <= 1){  // is the point on the line
        return Math.hypot(lx + v1x * u - point.x, ly + v1y * u - point.y);
    } else if ( u < 0 ) {  // point is before start
        return Math.hypot(lx - point.x, ly - point.y);
    }
    // point is after end of line
    return Math.hypot(points.items[line.p2].x - point.x, points.items[line.p2].y - point.y);
}
// this will extend the lines list
function getClosestline(from ,minDist) {
    var closestLine;
    this.eachItem(line => {
        const dist = distanceLineFromPoint(line,from);
        if(dist < minDist){
            closestLine = line;
            minDist = dist;
        }
    });
    return closestLine;
}
function drawPoint(point){
    ctx.moveTo(point.x,point.y);
    ctx.rect(point.x - 2,point.y - 2, 4,4);
}
function drawLine(line){
    ctx.moveTo(points.items[line.p1].x,points.items[line.p1].y);
    ctx.lineTo(points.items[line.p2].x,points.items[line.p2].y);
}
function drawLines(){ this.eachItem(line => drawLine(line)) }
function drawPoints(){this.eachItem(point => drawPoint(point)) }

const points = createList({
  getClosest : getClosestPoint,
  draw : drawPoints,
});
const lines = createList({
  getClosest : getClosestline,
  draw : drawLines,
});
const mouse  = {x : 0, y : 0, button : false, drag : false, dragStart : false, dragEnd : false, dragStartX : 0, dragStartY : 0}
function mouseEvents(e){
 mouse.x = e.pageX;
 mouse.y = e.pageY;
 const lb = mouse.button;
 mouse.button = e.type === "mousedown" ? true : e.type === "mouseup" ? false : mouse.button;
 if(lb !== mouse.button){
  if(mouse.button){
   mouse.drag = true;
   mouse.dragStart = true;
   mouse.dragStartX = mouse.x;
   mouse.dragStartY = mouse.y;
  }else{
   mouse.drag = false;
   mouse.dragEnd = true;
  }
 }
}
["down","up","move"].forEach(name => document.addEventListener("mouse" + name, mouseEvents));
// short cut vars
var w = canvas.width;
var h = canvas.height;
var cw = w / 2;  // center
var ch = h / 2;
var globalTime;
var closestLine;
var closestPoint;
var pointDrag; // true is dragging a point else dragging a line
var dragOffsetX;
var dragOffsetY;
var cursor;
var toolTip;
var helpCount = 0;
const minDist = 20;
const lineStyle = {
  lineWidth : 2,
  strokeStyle : "green",
}
const pointStyle = {
  lineWidth : 1,
  strokeStyle : "blue",
}
const highlightStyle = {
  lineWidth : 3,
  strokeStyle : "red",
}
const font = {
  font : "18px arial",
  fillStyle : "black",
  textAlign : "center",
}

// main update function
function update(timer){
    cursor = "crosshair";
    toolTip = helpCount < 2 ? "Click drag to create a line" : "";
    globalTime = timer;
    ctx.setTransform(1,0,0,1,0,0); // reset transform
    ctx.globalAlpha = 1;           // reset alpha
 if(w !== innerWidth || h !== innerHeight){
  cw = (w = canvas.width = innerWidth) / 2;
  ch = (h = canvas.height = innerHeight) / 2;
 }else{
  ctx.clearRect(0,0,w,h);
 }
  if(mouse.drag=== false){
    closestLine = undefined;
    closestPoint = points.getClosest(mouse,minDist);
    if(closestPoint === undefined){
       closestLine = lines.getClosest(mouse,minDist);
    }
    if(closestPoint || closestLine){
       toolTip = "Click drag to move " + (closestPoint ? "point" : "line");
       cursor = "move";
    }
  }
  if(mouse.dragStart){
    if(closestPoint){
      dragOffsetX = closestPoint.x - mouse.x;
      dragOffsetY =  closestPoint.y - mouse.y;
      pointDrag = true;

    }else if( closestLine){
      dragOffsetX = points.items[closestLine.p1].x - mouse.x;
      dragOffsetY = points.items[closestLine.p1].y - mouse.y;
      pointDrag = false;

    } else {
      points.add(Point2(mouse.x,mouse.y));
      closestPoint = points.add(Point2(mouse.x,mouse.y));
      closestLine = lines.add(Line(points.items.length-2,points.items.length-1));
      dragOffsetX = 0;
      dragOffsetY = 0;
      pointDrag = true;
      helpCount += 1;

    }
    mouse.dragStart = false;

  }else if(mouse.drag){
      cursor = 'none';
      if(pointDrag){
        closestPoint.x = mouse.x + dragOffsetX;
        closestPoint.y = mouse.y + dragOffsetY;
      }else{
        const dx = mouse.x- mouse.dragStartX;
        const dy = mouse.y -mouse.dragStartY;
        mouse.dragStartX = mouse.x;
        mouse.dragStartY = mouse.y;
        points.items[closestLine.p1].x +=  dx;
        points.items[closestLine.p1].y +=  dy;
        points.items[closestLine.p2].x +=  dx;
        points.items[closestLine.p2].y +=  dy;
      }
  }else{

  }
  // draw all points and lines
  setStyle(lineStyle);
  ctx.beginPath();
  lines.draw();
  ctx.stroke();
  setStyle(pointStyle);
  ctx.beginPath();
  points.draw();
  ctx.stroke();

  // draw highlighted point or line
  setStyle(highlightStyle);
  ctx.beginPath();
  if(closestLine){ drawLine(closestLine) }
  if(closestPoint){ drawPoint(closestPoint) }

  ctx.stroke();

  if(helpCount < 2){
     setStyle(font);
     ctx.fillText(toolTip,cw,30);
  }

  canvas.style.cursor = cursor;
  if(helpCount < 5){
      canvas.title = toolTip;
  }else{
      canvas.title = "";
  }
  requestAnimationFrame(update);
}
requestAnimationFrame(update);```
<pre class="snippet-code-css lang-css prettyprint-override"><code>canvas {
  position : absolute;
  top : 0px;
  left : 0px;
}</code>```

<canvas id="canvas"></canvas>```

Body:
Canvas draggables.

To make draggable lines you keep an array of endpoints and an array of lines as indexes to end points.

Then when the user clicks and drags near an end point or line you just update the endpoints by the amount the mouse has moved.

A point, a line, and some lists

First create a simple point structure

const Point2 = (x,y) => ({x,y});  // creates a point

Then an list that will hold points, add points, and what ever else you may need.

const list = {
    items : null,
    add(item) { this.items.push(item); return item },
    eachItem(callback) {
        var i;
        while(i < this.items.length){
             callback(this.items[i],i);
        }
    }
}

You then create a points list from the list structure

function createList(extend){
    return Object.assign({},list,{items : []},extend);
}

const points = createList();

The line is a set of point indexes

const Line = (p1,p2) => ({p1,p2});
const lines = createList();

Finding the closest

To select a point from a mouse coordinate you need to find the closest point to the mouse.

// this will extend the points list
function getClosestPoint(from ,minDist) {
    var closestPoint;
    this.eachItem(point => {
        const dist = Math.hypot(from.x - point.x, from.y - point.y);
        if(dist < minDist){
            closestPoint = point;
            minDist = dist;
        }
    });
    return closestPoint;
}

The same for the line but that is not as simple. You need a function that finds the distance that a point is from a line segment.

function distanceLineFromPoint(line,point){
    const lx = points.items[line.p1].x;
    const ly = points.items[line.p1].y;
    const v1x = points.items[line.p2].x - lx;
    const v1y = points.items[line.p2].y - ly;
    const v2x = point.x - lx;
    const v2y = point.y - ly;
    // get unit dist of closest point
    const u = (v2x * v1x + v2y * v1y)/(v1y * v1y + v1x * v1x);
    if(u >= 0 && u <= 1){  // is the point on the line
        return Math.hypot(lx + v1x * u - point.x, ly + v1y * u - point.y);
    } else if ( u < 0 ) {  // point is before start
        return Math.hypot(lx - point.x, ly - point.y);
    }
    // point is after end of line
    return Math.hypot(points.items[line.p2].x - point.x, points.items[line.p2].y - point.y);
}

// this will extend the lines list
function getClosestline(from ,minDist) {
    var closestLine;
    this.eachItem(line => {
        const dist = distanceLineFromPoint(line,from);
        if(dist < minDist){
            closestLine = line;
            minDist = dist;
        }
    });
    return closestLine;
}

With these function we should have extended the list object so will recreate them with the extensions.

 const points = createList({getClosest : getClosestPoint});
 const lines = createList({getClosest : getClosestline});

Then the rest is implementing a mouse interface and a rendering function. You add draggable points and lines connecting them. If you click near a line or point you drag them. The snippet shows the rest.

User feedback is important

It is also important to show the correct user feedback. You need to set the cursor, tooltip (via canvas.style.cursor and canvas.title) and highlight objects that will be effected, so that the user knows what actions will happen and to what when they click and drag.

Also you should set the mouse events to the document rather than the canvas as this will capture the mouse drag allowing the user to drag outside the canvas while you still get the mouseup and move events.

Create and drag points and lines.

const ctx = canvas.getContext("2d");
const Point2 = (x,y) => ({x,y});  // creates a point
const Line = (p1,p2) => ({p1,p2});
const setStyle = (style) => eachOf(Object.keys(style), key => { ctx[key] = style[key] } );
const eachOf = (array, callback) => {var i = 0; while (i < array.length && callback(array[i],i ++) !== true ); };

const list = {
    items : null,
    add(item) { this.items.push(item); return item },
    eachItem(callback) {
        var i = 0;
        while(i < this.items.length){
             callback(this.items[i],i++);
        }
    }
}
function createList(extend){
    return Object.assign({},list,{items : []},extend);
}
// this will extend the points list
function getClosestPoint(from ,minDist) {
    var closestPoint;
    this.eachItem(point => {
        const dist = Math.hypot(from.x - point.x, from.y - point.y);
        if(dist < minDist){
            closestPoint = point;
            minDist = dist;
        }
    });
    return closestPoint;
}
function distanceLineFromPoint(line,point){
    const lx = points.items[line.p1].x;
    const ly = points.items[line.p1].y;
    const v1x = points.items[line.p2].x - lx;
    const v1y = points.items[line.p2].y - ly;
    const v2x = point.x - lx;
    const v2y = point.y - ly;
    // get unit dist of closest point
    const u = (v2x * v1x + v2y * v1y)/(v1y * v1y + v1x * v1x);
    if(u >= 0 && u <= 1){  // is the point on the line
        return Math.hypot(lx + v1x * u - point.x, ly + v1y * u - point.y);
    } else if ( u < 0 ) {  // point is before start
        return Math.hypot(lx - point.x, ly - point.y);
    }
    // point is after end of line
    return Math.hypot(points.items[line.p2].x - point.x, points.items[line.p2].y - point.y);
}
// this will extend the lines list
function getClosestline(from ,minDist) {
    var closestLine;
    this.eachItem(line => {
        const dist = distanceLineFromPoint(line,from);
        if(dist < minDist){
            closestLine = line;
            minDist = dist;
        }
    });
    return closestLine;
}
function drawPoint(point){
    ctx.moveTo(point.x,point.y);
    ctx.rect(point.x - 2,point.y - 2, 4,4);
}
function drawLine(line){
    ctx.moveTo(points.items[line.p1].x,points.items[line.p1].y);
    ctx.lineTo(points.items[line.p2].x,points.items[line.p2].y);
}
function drawLines(){ this.eachItem(line => drawLine(line)) }
function drawPoints(){this.eachItem(point => drawPoint(point)) }

const points = createList({
  getClosest : getClosestPoint,
  draw : drawPoints,
});
const lines = createList({
  getClosest : getClosestline,
  draw : drawLines,
});
const mouse  = {x : 0, y : 0, button : false, drag : false, dragStart : false, dragEnd : false, dragStartX : 0, dragStartY : 0}
function mouseEvents(e){
 mouse.x = e.pageX;
 mouse.y = e.pageY;
 const lb = mouse.button;
 mouse.button = e.type === "mousedown" ? true : e.type === "mouseup" ? false : mouse.button;
 if(lb !== mouse.button){
  if(mouse.button){
   mouse.drag = true;
   mouse.dragStart = true;
   mouse.dragStartX = mouse.x;
   mouse.dragStartY = mouse.y;
  }else{
   mouse.drag = false;
   mouse.dragEnd = true;
  }
 }
}
["down","up","move"].forEach(name => document.addEventListener("mouse" + name, mouseEvents));
// short cut vars
var w = canvas.width;
var h = canvas.height;
var cw = w / 2;  // center
var ch = h / 2;
var globalTime;
var closestLine;
var closestPoint;
var pointDrag; // true is dragging a point else dragging a line
var dragOffsetX;
var dragOffsetY;
var cursor;
var toolTip;
var helpCount = 0;
const minDist = 20;
const lineStyle = {
  lineWidth : 2,
  strokeStyle : "green",
}
const pointStyle = {
  lineWidth : 1,
  strokeStyle : "blue",
}
const highlightStyle = {
  lineWidth : 3,
  strokeStyle : "red",
}
const font = {
  font : "18px arial",
  fillStyle : "black",
  textAlign : "center",
}

// main update function
function update(timer){
    cursor = "crosshair";
    toolTip = helpCount < 2 ? "Click drag to create a line" : "";
    globalTime = timer;
    ctx.setTransform(1,0,0,1,0,0); // reset transform
    ctx.globalAlpha = 1;           // reset alpha
 if(w !== innerWidth || h !== innerHeight){
  cw = (w = canvas.width = innerWidth) / 2;
  ch = (h = canvas.height = innerHeight) / 2;
 }else{
  ctx.clearRect(0,0,w,h);
 }
  if(mouse.drag=== false){
    closestLine = undefined;
    closestPoint = points.getClosest(mouse,minDist);
    if(closestPoint === undefined){
       closestLine = lines.getClosest(mouse,minDist);
    }
    if(closestPoint || closestLine){
       toolTip = "Click drag to move " + (closestPoint ? "point" : "line");
       cursor = "move";
    }
  }
  if(mouse.dragStart){
    if(closestPoint){
      dragOffsetX = closestPoint.x - mouse.x;
      dragOffsetY =  closestPoint.y - mouse.y;
      pointDrag = true;

    }else if( closestLine){
      dragOffsetX = points.items[closestLine.p1].x - mouse.x;
      dragOffsetY = points.items[closestLine.p1].y - mouse.y;
      pointDrag = false;

    } else {
      points.add(Point2(mouse.x,mouse.y));
      closestPoint = points.add(Point2(mouse.x,mouse.y));
      closestLine = lines.add(Line(points.items.length-2,points.items.length-1));
      dragOffsetX = 0;
      dragOffsetY = 0;
      pointDrag = true;
      helpCount += 1;

    }
    mouse.dragStart = false;

  }else if(mouse.drag){
      cursor = 'none';
      if(pointDrag){
        closestPoint.x = mouse.x + dragOffsetX;
        closestPoint.y = mouse.y + dragOffsetY;
      }else{
        const dx = mouse.x- mouse.dragStartX;
        const dy = mouse.y -mouse.dragStartY;
        mouse.dragStartX = mouse.x;
        mouse.dragStartY = mouse.y;
        points.items[closestLine.p1].x +=  dx;
        points.items[closestLine.p1].y +=  dy;
        points.items[closestLine.p2].x +=  dx;
        points.items[closestLine.p2].y +=  dy;
      }
  }else{

  }
  // draw all points and lines
  setStyle(lineStyle);
  ctx.beginPath();
  lines.draw();
  ctx.stroke();
  setStyle(pointStyle);
  ctx.beginPath();
  points.draw();
  ctx.stroke();

  // draw highlighted point or line
  setStyle(highlightStyle);
  ctx.beginPath();
  if(closestLine){ drawLine(closestLine) }
  if(closestPoint){ drawPoint(closestPoint) }

  ctx.stroke();

  if(helpCount < 2){
     setStyle(font);
     ctx.fillText(toolTip,cw,30);
  }

  canvas.style.cursor = cursor;
  if(helpCount < 5){
      canvas.title = toolTip;
  }else{
      canvas.title = "";
  }
  requestAnimationFrame(update);
}
requestAnimationFrame(update);

canvas {
  position : absolute;
  top : 0px;
  left : 0px;
}

<canvas id="canvas"></canvas>


问:
Powershell Getting Error Cannot convert value "System.Xml.XPathNodeList" to type "System.Xml.XmlDocument
I have following powershell code, which is selecting a xml node which has namespace.

```<code>$ns = new-Object System.Xml.XmlNamespaceManager $doc.NameTable
$ns.AddNamespace("dns", "http://www.nlog-project.org/schemas/NLog.xsd")
$obj3 = $doc.SelectNodes('//dns:nlog',$ns)
</code>```

But I am getting following error:

Cannot convert value "System.Xml.XPathNodeList" to type
  "System.Xml.XmlDocument". Error: "The specified node cannot be
  inserted as  the valid child of this node, because the specified node
  is the wrong type." At
  C:\MetacubeAutoBuildDeployment\PowershellScripts\PEStandAloneWebConfigReplace.ps1:15
  char:1
  + $obj3 = $doc.SelectNodes('//dns:nlog',$ns)
  + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      + CategoryInfo          : MetadataError: (:) [], ArgumentTransformationMetadataException
      + FullyQualifiedErrorId : RuntimeException

Is there any specific reason for this error?
I Have to fetch the value of connectionString tag highlighted in the $doc.
$doc Contains:

```<code><configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog" />
    <section name="ciel" type="Ciel.Application.Common.CielConfigSectionHandler, Ciel.Application" />
    <sectionGroup name="elmah">
      <section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah" />
      <section name="errorLog" requirePermission="false" type="Elmah.FallbackErrorLogSectionHandler, Elmah.FallbackErrorLog" />
      <section name="errorMail" requirePermission="false" type="Elmah.ErrorMailSectionHandler, Elmah" />
      <section name="errorFilter" requirePermission="false" type="Elmah.ErrorFilterSectionHandler, Elmah" />
    </sectionGroup>
  </configSections>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
  <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <!-- Load NLog extensions from the *.dll file -->
    <extensions>
      <add assembly="NLog.Web" />
      <add assembly="NLog.Extended" />
    </extensions>
    <!-- Targets or Output -->
    <targets>
      <default-wrapper xsi:type="AsyncWrapper" />
      <!-- File Target -->
      <target name="sqllog" xsi:type="File" fileName="App_Data/NLoggerLogs/PESql.log" archiveFileName="App_Data/log/CielSql.{#####}.log" maxArchiveFiles="100" archiveAboveSize="10485760" archiveNumbering="Sequence" concurrentWrites="true" keepFileOpen="false" encoding="UTF-8">
        <layout xsi:type="CSVLayout" delimiter="Tab">
          <column name="level" layout="${level:uppercase=true}" />
          <column name="aspnet-sessionid" layout="${aspnet-sessionid}" />
          <column name="aspnet-request(ASP.NET_SessionId)" layout="${aspnet-request:cookie=ASP.NET_SessionId}" />
          <column name="aspnet-request(HTTP_USER_AGENT)" layout="${aspnet-request:serverVariable=HTTP_USER_AGENT}" />
          <column name="aspnet-request(REMOTE_ADDR)" layout="${aspnet-request:serverVariable=REMOTE_ADDR}" />
          <column name="aspnet-request(REMOTE_HOST)" layout="${aspnet-request:serverVariable=REMOTE_HOST}" />
          <column name="date" layout="${longdate}" />
          <column name="message" layout="${message:exceptionSeparator=|:withException=true}" />
          <column name="aspnet-user-identity" layout="${aspnet-user-identity}" />
        </layout>
      </target>
      <target name="debuglog" xsi:type="File" fileName="App_Data/NLoggerLogs/PE.log" archiveFileName="App_Data/log/Ciel.{#####}.log" maxArchiveFiles="100" archiveAboveSize="2097152" archiveNumbering="Sequence" concurrentWrites="true" keepFileOpen="false" encoding="UTF-8">
        <layout xsi:type="CSVLayout" delimiter="Tab">
          <column name="date" layout="${longdate}" />
          <column name="level" layout="${level:uppercase=true}" />
          <column name="asp-application" layout="${asp-application}" />
          <column name="asp-request" layout="${asp-request:cookie=String:serverVariable=String:queryString=String:item=String:form=String}" />
          <column name="asp-session" layout="${asp-session:variable=String}" />
          <column name="aspnet-sessionid" layout="${aspnet-sessionid}" />
          <column name="aspnet-session" layout="${aspnet-session:variable=Sring}" />
          <column name="aspnet-application" layout="${aspnet-application:variable=String}" />
          <column name="aspnet-request" layout="${aspnet-request:cookie=String:serverVariable=String:queryString=String:item=String:form=String}" />
          <column name="aspnet-request(ASP.NET_SessionId)" layout="${aspnet-request:cookie=ASP.NET_SessionId}" />
          <column name="aspnet-request(HTTP_USER_AGENT)" layout="${aspnet-request:serverVariable=HTTP_USER_AGENT}" />
          <column name="aspnet-request(URL)" layout="${aspnet-request:serverVariable=URL}" />
          <column name="aspnet-request(REMOTE_ADDR)" layout="${aspnet-request:serverVariable=REMOTE_ADDR}" />
          <column name="aspnet-request(REMOTE_HOST)" layout="${aspnet-request:serverVariable=REMOTE_HOST}" />
          <column name="aspnet-user-authtype" layout="${aspnet-user-authtype}" />
          <column name="aspnet-user-identity" layout="${aspnet-user-identity}" />
          <column name="threadid" layout="${threadid}" />
          <column name="stacktrace" layout="${stacktrace:topFrames=2}" />
          <column name="machinename" layout="${machinename}" />
          <column name="document-uri" layout="${document-uri}" />
          <column name="callsite" layout="${callsite:className=true:fileName=true:includeSourcePath=true:methodName=true}" />
          <column name="message" layout="${message:exceptionSeparator=|:withException=true}" />
        </layout>
      </target>
      <target name="accesslog" xsi:type="File" fileName="${basedir}/APP_Data/NLoggerLogs/PEAccess.log" archiveFileName="${basedir}/App_Data/log/CielAccess.{#####}.log" maxArchiveFiles="100" archiveAboveSize="2097152" archiveNumbering="Sequence" concurrentWrites="true" keepFileOpen="false" encoding="UTF-8">
        <layout xsi:type="CSVLayout" delimiter="Tab">
          <column name="aspnet-sessionid" layout="${aspnet-sessionid}" />
          <column name="aspnet-request(HTTP_USER_AGENT)" layout="${aspnet-request:serverVariable=HTTP_USER_AGENT}" />
          <column name="aspnet-request(REMOTE_ADDR)" layout="${aspnet-request:serverVariable=REMOTE_ADDR}" />
          <column name="aspnet-request(REMOTE_HOST)" layout="${aspnet-request:serverVariable=REMOTE_HOST}" />
          <column name="date" layout="${longdate}" />
          <column name="message" layout="${message:exceptionSeparator=|:withException=true}" />
        </layout>
      </target>
      <target name="database" xsi:type="Database">
        <!--
        Remarks:
          The appsetting layouts require the NLog.Extended assembly.
          The aspnet-* layouts require the NLog.Web assembly.
          The Application value is determined by an AppName appSetting in Web.config.
          The "NLogDb" connection string determines the database that NLog write to.
          The create dbo.Log script in the comment below must be manually executed.
        -->
        <!--<connectionStringName>SQLServer_develop</connectionStringName>-->
        <dbProvider>System.Data.SqlClient</dbProvider>
        **<connectionString>server=server;database=database;integrated security=False;User ID=userid;Password=password</connectionString>**
        <commandText>
          insert into [CIEL].[DPR_JOBINSTANCEDETAILS] (
          JOBID, JOBINSTANCEID, STEPINSTANCEID,STEPID,LOGTYPE, MESSAGETYPE, MESSAGE, PARENTID,LOGGEDON
          )
          values (
          @JOBID, @JOBINSTANCEID, @STEPINSTANCEID, @STEPID, @LOGTYPE,@MESSAGETYPE, @MESSAGE, @PARENTID, @LOGGEDON
          );
        </commandText>
        <parameter name="@JOBID" layout="${event-properties:item=JOBID}" />
        <parameter name="@JOBINSTANCEID" layout="${event-properties:item=JOBINSTANCEID}" />
        <parameter name="@STEPINSTANCEID" layout="${event-properties:item=STEPINSTANCEID}" />
        <parameter name="@STEPID" layout="${event-properties:item=STEPID}" />
        <parameter name="@LOGTYPE" layout="${event-properties:item=LOGTYPE}" />
        <parameter name="@MESSAGETYPE" layout="${event-properties:item=MESSAGETYPE}" />
        <parameter name="@MESSAGE" layout="${event-properties:item=MESSAGE}" />
        <parameter name="@PARENTID" layout="${event-properties:item=PARENTID}" />
        <parameter name="@LOGGEDON" layout="${date}" />
      </target>
      <target name="sqllog_table" xsi:type="Database">
        <!--Remarks:
          The appsetting layouts require the NLog.Extended assembly.
          The aspnet-* layouts require the NLog.Web assembly.
          The Application value is determined by an AppName appSetting in Web.config.
          The "NLogDb" connection string determines the database that NLog write to.
          The create dbo.Log script in the comment below must be manually executed.-->
        <connectionStringName>NLogConnection</connectionStringName>
      </target>
    </targets>
    <!-- Rules for calling the appropriate Target -->
    <rules>
      <logger name="DebugLogger" minlevel="Debug" writeTo="debuglog" />
      <logger name="SqlLogger" minlevel="Debug" writeTo="sqllog" />
      <logger name="AccessLogger" minlevel="Info" writeTo="accesslog" />
      <logger name="PROCESSENGINEDB" minlevel="Trace" writeTo="database" />
    </rules>
  </nlog>
</configuration>
</code>```

答:
You could use GetElementsByTagName as suggested by WOxxOm's comments. It's elegant. But potential issues could be caused by changing xml structure, re-ordering or multiple connectionStrings.

You could dot-index into the XML. The advantage is that it is more explicit. The disadvantage is that it is more explicit.

If you change the path to the connectionString this will need to be updated where as GetElementsByTagName will not. However this is better for explicitly defining the tag you are interesting in and to give you convenient access to the other pieces of information within that tag. I find it is generally more intuitive.

```<code>$dbdetails = $doc.configuration.nlog.targets.target | Where-Object {$_.name -eq "database"}
$dbdetails.ConnectionString
</code>```

Your code did not give me the same error on PowerShell v5.1. I copied your code for $doc, assigning it to a variable using a here-string:

```<code>[xml]$doc = @"
    ...
"@
</code>```

Edit:

Best of both worlds?

```<code>$dbdetails = $doc.GetElementsByTagName("target") | Where-Object {$_.name -eq "database"}
</code>```

Get-Member, showing the accessible properties

Body:
I have following powershell code, which is selecting a xml node which has namespace.

$ns = new-Object System.Xml.XmlNamespaceManager $doc.NameTable
$ns.AddNamespace("dns", "http://www.nlog-project.org/schemas/NLog.xsd")
$obj3 = $doc.SelectNodes('//dns:nlog',$ns)

But I am getting following error:

Cannot convert value "System.Xml.XPathNodeList" to type
  "System.Xml.XmlDocument". Error: "The specified node cannot be
  inserted as  the valid child of this node, because the specified node
  is the wrong type." At
  C:\MetacubeAutoBuildDeployment\PowershellScripts\PEStandAloneWebConfigReplace.ps1:15
  char:1
  + $obj3 = $doc.SelectNodes('//dns:nlog',$ns)
  + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      + CategoryInfo          : MetadataError: (:) [], ArgumentTransformationMetadataException
      + FullyQualifiedErrorId : RuntimeException

Is there any specific reason for this error?
I Have to fetch the value of connectionString tag highlighted in the $doc.
$doc Contains:

<configuration>
  <configSections>

    <sectionGroup name="elmah">

    </sectionGroup>
  </configSections>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
  <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    <extensions>
      <add assembly="NLog.Web" />
      <add assembly="NLog.Extended" />
    </extensions>

    <targets>
      <default-wrapper xsi:type="AsyncWrapper" />

      <target name="sqllog" xsi:type="File" fileName="App_Data/NLoggerLogs/PESql.log" archiveFileName="App_Data/log/CielSql.{#####}.log" maxArchiveFiles="100" archiveAboveSize="10485760" archiveNumbering="Sequence" concurrentWrites="true" keepFileOpen="false" encoding="UTF-8">
        <layout xsi:type="CSVLayout" delimiter="Tab">
          <column name="level" layout="${level:uppercase=true}" />
          <column name="aspnet-sessionid" layout="${aspnet-sessionid}" />
          <column name="aspnet-request(ASP.NET_SessionId)" layout="${aspnet-request:cookie=ASP.NET_SessionId}" />
          <column name="aspnet-request(HTTP_USER_AGENT)" layout="${aspnet-request:serverVariable=HTTP_USER_AGENT}" />
          <column name="aspnet-request(REMOTE_ADDR)" layout="${aspnet-request:serverVariable=REMOTE_ADDR}" />
          <column name="aspnet-request(REMOTE_HOST)" layout="${aspnet-request:serverVariable=REMOTE_HOST}" />
          <column name="date" layout="${longdate}" />
          <column name="message" layout="${message:exceptionSeparator=|:withException=true}" />
          <column name="aspnet-user-identity" layout="${aspnet-user-identity}" />
        </layout>
      </target>
      <target name="debuglog" xsi:type="File" fileName="App_Data/NLoggerLogs/PE.log" archiveFileName="App_Data/log/Ciel.{#####}.log" maxArchiveFiles="100" archiveAboveSize="2097152" archiveNumbering="Sequence" concurrentWrites="true" keepFileOpen="false" encoding="UTF-8">
        <layout xsi:type="CSVLayout" delimiter="Tab">
          <column name="date" layout="${longdate}" />
          <column name="level" layout="${level:uppercase=true}" />
          <column name="asp-application" layout="${asp-application}" />
          <column name="asp-request" layout="${asp-request:cookie=String:serverVariable=String:queryString=String:item=String:form=String}" />
          <column name="asp-session" layout="${asp-session:variable=String}" />
          <column name="aspnet-sessionid" layout="${aspnet-sessionid}" />
          <column name="aspnet-session" layout="${aspnet-session:variable=Sring}" />
          <column name="aspnet-application" layout="${aspnet-application:variable=String}" />
          <column name="aspnet-request" layout="${aspnet-request:cookie=String:serverVariable=String:queryString=String:item=String:form=String}" />
          <column name="aspnet-request(ASP.NET_SessionId)" layout="${aspnet-request:cookie=ASP.NET_SessionId}" />
          <column name="aspnet-request(HTTP_USER_AGENT)" layout="${aspnet-request:serverVariable=HTTP_USER_AGENT}" />
          <column name="aspnet-request(URL)" layout="${aspnet-request:serverVariable=URL}" />
          <column name="aspnet-request(REMOTE_ADDR)" layout="${aspnet-request:serverVariable=REMOTE_ADDR}" />
          <column name="aspnet-request(REMOTE_HOST)" layout="${aspnet-request:serverVariable=REMOTE_HOST}" />
          <column name="aspnet-user-authtype" layout="${aspnet-user-authtype}" />
          <column name="aspnet-user-identity" layout="${aspnet-user-identity}" />
          <column name="threadid" layout="${threadid}" />
          <column name="stacktrace" layout="${stacktrace:topFrames=2}" />
          <column name="machinename" layout="${machinename}" />
          <column name="document-uri" layout="${document-uri}" />
          <column name="callsite" layout="${callsite:className=true:fileName=true:includeSourcePath=true:methodName=true}" />
          <column name="message" layout="${message:exceptionSeparator=|:withException=true}" />
        </layout>
      </target>
      <target name="accesslog" xsi:type="File" fileName="${basedir}/APP_Data/NLoggerLogs/PEAccess.log" archiveFileName="${basedir}/App_Data/log/CielAccess.{#####}.log" maxArchiveFiles="100" archiveAboveSize="2097152" archiveNumbering="Sequence" concurrentWrites="true" keepFileOpen="false" encoding="UTF-8">
        <layout xsi:type="CSVLayout" delimiter="Tab">
          <column name="aspnet-sessionid" layout="${aspnet-sessionid}" />
          <column name="aspnet-request(HTTP_USER_AGENT)" layout="${aspnet-request:serverVariable=HTTP_USER_AGENT}" />
          <column name="aspnet-request(REMOTE_ADDR)" layout="${aspnet-request:serverVariable=REMOTE_ADDR}" />
          <column name="aspnet-request(REMOTE_HOST)" layout="${aspnet-request:serverVariable=REMOTE_HOST}" />
          <column name="date" layout="${longdate}" />
          <column name="message" layout="${message:exceptionSeparator=|:withException=true}" />
        </layout>
      </target>
      <target name="database" xsi:type="Database">

        <dbProvider>System.Data.SqlClient</dbProvider>
        **<connectionString>server=server;database=database;integrated security=False;User ID=userid;Password=password</connectionString>**
        <commandText>
          insert into [CIEL].[DPR_JOBINSTANCEDETAILS] (
          JOBID, JOBINSTANCEID, STEPINSTANCEID,STEPID,LOGTYPE, MESSAGETYPE, MESSAGE, PARENTID,LOGGEDON
          )
          values (
          @JOBID, @JOBINSTANCEID, @STEPINSTANCEID, @STEPID, @LOGTYPE,@MESSAGETYPE, @MESSAGE, @PARENTID, @LOGGEDON
          );
        </commandText>
        <parameter name="@JOBID" layout="${event-properties:item=JOBID}" />
        <parameter name="@JOBINSTANCEID" layout="${event-properties:item=JOBINSTANCEID}" />
        <parameter name="@STEPINSTANCEID" layout="${event-properties:item=STEPINSTANCEID}" />
        <parameter name="@STEPID" layout="${event-properties:item=STEPID}" />
        <parameter name="@LOGTYPE" layout="${event-properties:item=LOGTYPE}" />
        <parameter name="@MESSAGETYPE" layout="${event-properties:item=MESSAGETYPE}" />
        <parameter name="@MESSAGE" layout="${event-properties:item=MESSAGE}" />
        <parameter name="@PARENTID" layout="${event-properties:item=PARENTID}" />
        <parameter name="@LOGGEDON" layout="${date}" />
      </target>
      <target name="sqllog_table" xsi:type="Database">

        <connectionStringName>NLogConnection</connectionStringName>
      </target>
    </targets>

    <rules>
      <logger name="DebugLogger" minlevel="Debug" writeTo="debuglog" />
      <logger name="SqlLogger" minlevel="Debug" writeTo="sqllog" />
      <logger name="AccessLogger" minlevel="Info" writeTo="accesslog" />
      <logger name="PROCESSENGINEDB" minlevel="Trace" writeTo="database" />
    </rules>
  </nlog>
</configuration>

Body:
You could use GetElementsByTagName as suggested by WOxxOm's comments. It's elegant. But potential issues could be caused by changing xml structure, re-ordering or multiple connectionStrings.

You could dot-index into the XML. The advantage is that it is more explicit. The disadvantage is that it is more explicit.

If you change the path to the connectionString this will need to be updated where as GetElementsByTagName will not. However this is better for explicitly defining the tag you are interesting in and to give you convenient access to the other pieces of information within that tag. I find it is generally more intuitive.

$dbdetails = $doc.configuration.nlog.targets.target | Where-Object {$_.name -eq "database"}
$dbdetails.ConnectionString

Your code did not give me the same error on PowerShell v5.1. I copied your code for $doc, assigning it to a variable using a here-string:

[xml]$doc = @"
    ...
"@

Edit:

Best of both worlds?

$dbdetails = $doc.GetElementsByTagName("target") | Where-Object {$_.name -eq "database"}

Get-Member, showing the accessible properties


问:
Passing ActualWidth and ActualHeight into a MultiBinding
I have a WPF project (c#, MVVM using MVVM Light) and I have a MultiBinding that passes information to a converter, as you would expect.

The code for that is here:

```<code><ListBox.ItemTemplate>
    <DataTemplate>
        <Grid>
            <Path Stroke = "{Binding LineColour}" >
                < Path.Data >
                    < MultiBinding Converter="{StaticResource NodeToPathDataConverter}">
                        <Binding Path = "NodeListViewModel.NodeList" Source="{StaticResource Locator}" />
                        <Binding />
                    </MultiBinding>
                </Path.Data>
            </Path>
        </Grid>
    </DataTemplate>
</ListBox.ItemTemplate>
</code>```

The converter then uses the information from these bindings to spit out the details for the line. The problem is that the line goes from the (0,0) position of one control to another, but I want it to go from the middle of the controls in question. To do this, the converter in the MultiBinding needs to get the ActualWidth and ActualHeight of the controls in question.

So what are the controls in question? I have another almost identical ListBox control below this one that uses the same data set, but instead of drawing lines between controls, it draws the controls themselves. This is as follows:

```<code><ListBox.ItemTemplate>
    <DataTemplate>
            <Grid>
                <Thumb Name = "myThumb" Template="{StaticResource NodeVisualTemplate}">
                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName = "DragDelta" >
                                < cmd:EventToCommand Command = "{Binding NodeListViewModel.DragDeltaCommand, Source={StaticResource Locator}}" PassEventArgsToCommand="True"/>
                        </i:EventTrigger>
                    </i:Interaction.Triggers>
                </Thumb>
            </Grid>
        </DataTemplate>
</ListBox.ItemTemplate>
</code>```

The reason I used two ListBox controls was to ensure that all lines appeared lower than all Thumbs. I tried many ways of them in the same ListBox, but it wasn't going to happen. They do share the same data set though, which is a 'NodeList'.

So the bit I can't figure out is how to get the ActualWidth and ActualHeight of the Thumbs in the second ListBox into the converter in the first ListBox. Which is why I'm here.

Any help would be greatly appreciated.

答:
You can "bind" the ActualWidth and ActualHeight read-only properties of the Thumb in the second ListView to some double source properties of your data object using any of the workaround mentioned here:

Bind to ActualHeight of Item ItemsControl

You can then bind to the same source properties in the ItemTemplate of the first ListView. This should work provided that both ListViews bind to the same source collection.

There is no way to bind directly to the actual Thumb element in the second ListView using pure XAML though.

Body:
I have a WPF project (c#, MVVM using MVVM Light) and I have a MultiBinding that passes information to a converter, as you would expect.

The code for that is here:

<ListBox.ItemTemplate>
    <DataTemplate>
        <Grid>
            <Path Stroke = "{Binding LineColour}" >
                < Path.Data >
                    < MultiBinding Converter="{StaticResource NodeToPathDataConverter}">
                        <Binding Path = "NodeListViewModel.NodeList" Source="{StaticResource Locator}" />
                        <Binding />
                    </MultiBinding>
                </Path.Data>
            </Path>
        </Grid>
    </DataTemplate>
</ListBox.ItemTemplate>

The converter then uses the information from these bindings to spit out the details for the line. The problem is that the line goes from the (0,0) position of one control to another, but I want it to go from the middle of the controls in question. To do this, the converter in the MultiBinding needs to get the ActualWidth and ActualHeight of the controls in question.

So what are the controls in question? I have another almost identical ListBox control below this one that uses the same data set, but instead of drawing lines between controls, it draws the controls themselves. This is as follows:

<ListBox.ItemTemplate>
    <DataTemplate>
            <Grid>
                <Thumb Name = "myThumb" Template="{StaticResource NodeVisualTemplate}">

                                < cmd:EventToCommand Command = "{Binding NodeListViewModel.DragDeltaCommand, Source={StaticResource Locator}}" PassEventArgsToCommand="True"/>

                </Thumb>
            </Grid>
        </DataTemplate>
</ListBox.ItemTemplate>

The reason I used two ListBox controls was to ensure that all lines appeared lower than all Thumbs. I tried many ways of them in the same ListBox, but it wasn't going to happen. They do share the same data set though, which is a 'NodeList'.

So the bit I can't figure out is how to get the ActualWidth and ActualHeight of the Thumbs in the second ListBox into the converter in the first ListBox. Which is why I'm here.

Any help would be greatly appreciated.


问:
Laravel carbon retrieve record even when it shouldn't
I am searching by start and end date or with a weekday, which kind of works fine however if weekday is equal to 'WE' and today's  weekday is equal to 'WE' it still brings back results even when $today date is < than endate.

```<code>public function show($id)
{
    $weekMap = [
        0 => 'SU',
        1 => 'MO',
        2 => 'TU',
        3 => 'WE',
        4 => 'TH',
        5 => 'FR',
        6 => 'SA',
    ];
    $todayWeek = Carbon::now()->dayOfWeek;
    $today= Carbon::now();
    $weekday = $weekMap[$todayWeek];
    $event = Event::with('businesses')
       ->where('startdate', '<', $today->format('Y-m-d'))
       ->where('endate', '>', $today->format('Y-m-d'))
       ->orWhere('weekday', '=', $weekday)
       ->get();
    dd($event);
    return view('events.showEvent', compact('event'));
}
</code>```

If I change orWhere to where, results are all good, however user not always enters a weekday so it can be empty. I want it to work like this:

output everything where startdate < today and where endate > today and if weekday is not empty, output everything where startdate < today, endate > today and weekday = $weekday. I hope that makes sense.

//edit

sample data:

data

So what I want is really search by frequency so it would look like this:

if frequency = daily
compare start and end with today's date.
if frequency = weekly
compare start and end with today's date and weekday.

bring back all results for frequency = daily+weekly

答:
you can use if condition in query like this:

```<code>$query = Event::with('businesses')
   ->where('startdate', '<', $today->format('Y-m-d'))
   ->where('endate', '>', $today->format('Y-m-d'));

   if ($weekday != '') {
       $query->where('weekday', $weekday);
   }

   $event = $query->get();
</code>```

also

condition if ($weekday != '') check $weekday isset or not you can use

if ( ! is_null($weekday )) instead

Body:
I am searching by start and end date or with a weekday, which kind of works fine however if weekday is equal to 'WE' and today's  weekday is equal to 'WE' it still brings back results even when $today date is < than endate.

public function show($id)
{
    $weekMap = [
        0 => 'SU',
        1 => 'MO',
        2 => 'TU',
        3 => 'WE',
        4 => 'TH',
        5 => 'FR',
        6 => 'SA',
    ];
    $todayWeek = Carbon::now()->dayOfWeek;
    $today= Carbon::now();
    $weekday = $weekMap[$todayWeek];
    $event = Event::with('businesses')
       ->where('startdate', '<', $today->format('Y-m-d'))
       ->where('endate', '>', $today->format('Y-m-d'))
       ->orWhere('weekday', '=', $weekday)
       ->get();
    dd($event);
    return view('events.showEvent', compact('event'));
}

If I change orWhere to where, results are all good, however user not always enters a weekday so it can be empty. I want it to work like this:

output everything where startdate < today and where endate > today and if weekday is not empty, output everything where startdate < today, endate > today and weekday = $weekday. I hope that makes sense.

//edit

sample data:

data

So what I want is really search by frequency so it would look like this:

if frequency = daily
compare start and end with today's date.
if frequency = weekly
compare start and end with today's date and weekday.

bring back all results for frequency = daily+weekly

Body:
you can use if condition in query like this:

$query = Event::with('businesses')
   ->where('startdate', '<', $today->format('Y-m-d'))
   ->where('endate', '>', $today->format('Y-m-d'));

   if ($weekday != '') {
       $query->where('weekday', $weekday);
   }

   $event = $query->get();

also

condition if ($weekday != '') check $weekday isset or not you can use

if ( ! is_null($weekday )) instead