问:
String manipulation in pine?
How would I decompose start/end and hrs as well minutes from this?</p>
```<code>sessionInput = input.session("0600-1700", "Session")
</code>```

答:
You can decomposite the input string into an array of strings using the str.split() function:</p>
```<code>//@version=5
indicator('Session start/end', overlay=true)
sessionInput  = input.session("0600-1700", "Session")

var string[] sessionStartEnd = str.split(sessionInput, '-')

if barstate.islastconfirmedhistory
    label.new(bar_index, high, 'session start :' + array.get(sessionStartEnd, 0))
    label.new(bar_index, low, 'session end :' + array.get(sessionStartEnd, 1))
</code>```

Title: String manipulation in pine?

Body:
How would I decompose start/end and hrs as well minutes from this?

sessionInput = input.session("0600-1700", "Session")

Body:
You can decomposite the input string into an array of strings using the str.split() function:

//@version=5
indicator('Session start/end', overlay=true)
sessionInput  = input.session("0600-1700", "Session")

var string[] sessionStartEnd = str.split(sessionInput, '-')

if barstate.islastconfirmedhistory
    label.new(bar_index, high, 'session start :' + array.get(sessionStartEnd, 0))
    label.new(bar_index, low, 'session end :' + array.get(sessionStartEnd, 1))


来源: stackexchange

问:
Can I deploy both python 2 django 1.9 and python 3.9 and django 3.2 apps with same apache server
i have developed one project using python 3.9 and django 3.2.

and also one existing project is there that was developed python version 2 and Django 1.9.4. it was deployed in apache server it is working fine.

problems are raised when we trying to deploy latest project like python 3.9 and Django 3.2 in current servers(which have already python 2 and django 1.9.4 project is running).

答: Yes, you can using modwsgi_express which will start another Apache with the modwsgi configure and you can proxy the new application from your first apache to the apache started with the modwsgi_express</p>

ContentLicense: CC BY-SA 4.0


问:
How can I disable the splitting of rows (not tables!) in Itext7 for C# when one row is to big to fit on the first page?
How can I disable the splitting of rows in an Itext7-Table if the row is the last one on a page and does not fit to the first page?

The only thing I found is an example for Itext5 where the method setSplitLate() is set to false:
http://what-when-how.com/itext-5/dealing-with-large-tables-itext-5/ (Listing 4.19 HeaderFooter2.java)

Does anyone have a solution for this?

答:
Here's my solution based on Uladzimir's one.

Basically you have to save a status, on a cell basis, that allow to nullify the SplitRenderer on the cells only the first time the layout method is called on that specific cell.

```<code>@Test
public void tableWithCellNotSplitted() {
    File fOut = getFileOutput("table-cellsNotSplitter.pdf");

    try {
        final float MARGIN = 80;

        Document document = getDocumentForOutput(fOut, true);
        document.setMargins(MARGIN, MARGIN, MARGIN, MARGIN);

        final String text = "Enjoyed minutes related as at on on. Is fanny dried as often me. Goodness as reserved raptures to mistaken steepest oh screened he.";
        final String bigText = text + "\n" + text + "\n" + text + "\n" + text + "\n" + text + "\n" + text;

        Table t = new Table(2);
        t.setWidth(new UnitValue(UnitValue.PERCENT, 60));
        for (int nRow = 0; nRow < 10; nRow++) {
            for (int iCol = 0; iCol < 2; iCol++) {
                String content = nRow == 1 ? bigText : text;
                t.addCell(createNonSplittingCell2(content));
            }

        }
        document.add(t);

        document.close();
        openOutputWithReader(fOut);
    } catch (Exception e) {
        Assert.fail(e.toString());
    }
}

private Cell createPlainCell(String text) {
    Cell c = new Cell().add(new Paragraph(text));
    return c;
}

private Cell createNonSplittingCell1(String text) {
    Cell c = new Cell().add(new Paragraph(text));
    c.setNextRenderer(new NonSplittingRenderer1(c));
    return c;
}

private Cell createNonSplittingCell2(String text) {
    Cell c = new NotSplittingCell().add(new Paragraph(text));
    c.setNextRenderer(new NonSplittingRenderer2(c));
    return c;
}

public class NonSplittingRenderer1 extends CellRenderer {
    public NonSplittingRenderer1(Cell modelElement) {
        super(modelElement);
    }

    @Override
    public LayoutResult layout(LayoutContext layoutContext) {
        LayoutResult result = super.layout(layoutContext);
        if (LayoutResult.FULL != result.getStatus()) {
            result.setStatus(LayoutResult.NOTHING);
            result.setSplitRenderer(null);
            result.setOverflowRenderer(this);
        }

        return result;
    }

    @Override
    public IRenderer getNextRenderer() {
        return new NonSplittingRenderer1((Cell) getModelElement());
    }
}

public class NonSplittingRenderer2 extends CellRenderer {
    public NonSplittingRenderer2(Cell modelElement) {
        super(modelElement);
    }

    @Override
    public LayoutResult layout(LayoutContext layoutContext) {
        LayoutResult result = super.layout(layoutContext);
        Cell c = (Cell) modelElement;
        if (c instanceof NotSplittingCell) {
            if (LayoutResult.FULL != result.getStatus()) {
                NotSplittingCell nsc = (NotSplittingCell) c;
                if ( !nsc.isSplit()) {
                    nsc.setSplit(true);
                    result.setStatus(LayoutResult.NOTHING);
                    result.setSplitRenderer(null);
                    result.setOverflowRenderer(this);
                }
            }
        }

        return result;
    }

    @Override
    public IRenderer getNextRenderer() {
        return new NonSplittingRenderer2((Cell) getModelElement());
    }
}

public class NotSplittingCell extends Cell {
    private boolean _split;

    public boolean isSplit() {
        return _split;
    }

    public void setSplit(boolean split) {
        _split = split;
    }
}
</code>```

this code has three ways to create cells:

Plain cells with no renderer (createPlainCell method)

Plain cells with renderer like the previous solution (createNonSplittingCell1 method)

Custom cell with modified version of renderer (createNonSplittingCell2 method)

Solution 1 obviously split cells.

Solution 2 stops writing cells after the firts row: the layout method nullify the splitrender every time he try to render the second row's cells: simply the table vanishes.

Solution 3 uses a subclass of Cell, NotSplittingCell, that simply store the split status of the cell: the splitrenderer is nullified only if the cell is never split. That way correctly keep cells unsplit,  but only if it's possible

Body:
Here's my solution based on Uladzimir's one.

Basically you have to save a status, on a cell basis, that allow to nullify the SplitRenderer on the cells only the first time the layout method is called on that specific cell.

@Test
public void tableWithCellNotSplitted() {
    File fOut = getFileOutput("table-cellsNotSplitter.pdf");

    try {
        final float MARGIN = 80;

        Document document = getDocumentForOutput(fOut, true);
        document.setMargins(MARGIN, MARGIN, MARGIN, MARGIN);

        final String text = "Enjoyed minutes related as at on on. Is fanny dried as often me. Goodness as reserved raptures to mistaken steepest oh screened he.";
        final String bigText = text + "\n" + text + "\n" + text + "\n" + text + "\n" + text + "\n" + text;

        Table t = new Table(2);
        t.setWidth(new UnitValue(UnitValue.PERCENT, 60));
        for (int nRow = 0; nRow < 10; nRow++) {
            for (int iCol = 0; iCol < 2; iCol++) {
                String content = nRow == 1 ? bigText : text;
                t.addCell(createNonSplittingCell2(content));
            }

        }
        document.add(t);

        document.close();
        openOutputWithReader(fOut);
    } catch (Exception e) {
        Assert.fail(e.toString());
    }
}

private Cell createPlainCell(String text) {
    Cell c = new Cell().add(new Paragraph(text));
    return c;
}

private Cell createNonSplittingCell1(String text) {
    Cell c = new Cell().add(new Paragraph(text));
    c.setNextRenderer(new NonSplittingRenderer1(c));
    return c;
}

private Cell createNonSplittingCell2(String text) {
    Cell c = new NotSplittingCell().add(new Paragraph(text));
    c.setNextRenderer(new NonSplittingRenderer2(c));
    return c;
}

public class NonSplittingRenderer1 extends CellRenderer {
    public NonSplittingRenderer1(Cell modelElement) {
        super(modelElement);
    }

    @Override
    public LayoutResult layout(LayoutContext layoutContext) {
        LayoutResult result = super.layout(layoutContext);
        if (LayoutResult.FULL != result.getStatus()) {
            result.setStatus(LayoutResult.NOTHING);
            result.setSplitRenderer(null);
            result.setOverflowRenderer(this);
        }

        return result;
    }

    @Override
    public IRenderer getNextRenderer() {
        return new NonSplittingRenderer1((Cell) getModelElement());
    }
}

public class NonSplittingRenderer2 extends CellRenderer {
    public NonSplittingRenderer2(Cell modelElement) {
        super(modelElement);
    }

    @Override
    public LayoutResult layout(LayoutContext layoutContext) {
        LayoutResult result = super.layout(layoutContext);
        Cell c = (Cell) modelElement;
        if (c instanceof NotSplittingCell) {
            if (LayoutResult.FULL != result.getStatus()) {
                NotSplittingCell nsc = (NotSplittingCell) c;
                if ( !nsc.isSplit()) {
                    nsc.setSplit(true);
                    result.setStatus(LayoutResult.NOTHING);
                    result.setSplitRenderer(null);
                    result.setOverflowRenderer(this);
                }
            }
        }

        return result;
    }

    @Override
    public IRenderer getNextRenderer() {
        return new NonSplittingRenderer2((Cell) getModelElement());
    }
}

public class NotSplittingCell extends Cell {
    private boolean _split;

    public boolean isSplit() {
        return _split;
    }

    public void setSplit(boolean split) {
        _split = split;
    }
}

this code has three ways to create cells:

Plain cells with no renderer (createPlainCell method)

Plain cells with renderer like the previous solution (createNonSplittingCell1 method)

Custom cell with modified version of renderer (createNonSplittingCell2 method)

Solution 1 obviously split cells.

Solution 2 stops writing cells after the firts row: the layout method nullify the splitrender every time he try to render the second row's cells: simply the table vanishes.

Solution 3 uses a subclass of Cell, NotSplittingCell, that simply store the split status of the cell: the splitrenderer is nullified only if the cell is never split. That way correctly keep cells unsplit,  but only if it's possible


问:
Hibernate Search: mapping IndexedEmbedded on ElasticSearch causes No field found for [] in mapping
I've two entities, Search and Amount that I'm mapping using Hibernate Search  in this way:

```<code>@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ToString
@Entity
@Indexed
public class Search extends SearchableItem {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEARCH_SEQ")
    @DocumentId
    private Long id;

    @Embedded
    @Valid
    @IndexedEmbedded
    private Amount maxAmount;

    @Embedded
    @Valid
    @IndexedEmbedded
    private Amount minAmount;
}
</code>```
```<code>@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ToString
@Embeddable
public class Amount {

    @NotNull
    @ScaledNumberField(sortable = Sortable.YES)
    private BigDecimal value;

    @NotNull
    @Enumerated(EnumType.STRING)
    @GenericField
    private CurrencyCode currency;

}
</code>```

These annotations creates my index in this way on Elasticsearch:

```<code>{
    "search-000001": {
        "aliases": {
            "search-read": {
                "is_write_index": false
            },
            "search-write": {
                "is_write_index": true
            }
        },
        "mappings": {
            "dynamic": "strict",
            "properties": {
                "_entity_type": {
                    "type": "keyword",
                    "index": false
                },
                "maxAmount": {
                    "dynamic": "strict",
                    "properties": {
                        "currency": {
                            "type": "keyword",
                            "doc_values": false
                        },
                        "value": {
                            "type": "scaled_float",
                            "scaling_factor": 100
                        }
                    }
                },
                "minAmount": {
                    "dynamic": "strict",
                    "properties": {
                        "currency": {
                            "type": "keyword",
                            "doc_values": false
                        },
                        "value": {
                            "type": "scaled_float",
                            "scaling_factor": 100
                        }
                    }
                }
            }
        },
        "settings": {
            "index": {
                "routing": {
                    "allocation": {
                        "include": {
                            "_tier_preference": "data_content"
                        }
                    }
                },
                "number_of_shards": "1",
                "provided_name": "search-000001",
                "creation_date": "1644485712235",
                "analysis": {
                    "normalizer": {
                        "sort": {
                            "filter": [
                                "asciifolding",
                                "lowercase"
                            ],
                            "type": "custom"
                        }
                    },
                    "analyzer": {
                        "name": {
                            "filter": [
                                "asciifolding",
                                "lowercase"
                            ],
                            "type": "custom",
                            "tokenizer": "standard"
                        },
                        "generic_text": {
                            "filter": [
                                "asciifolding",
                                "lowercase",
                                "porter_stem"
                            ],
                            "type": "custom",
                            "tokenizer": "standard"
                        }
                    }
                },
                "number_of_replicas": "1",
                "uuid": "GBfV36PLT2-JEVPlbE2DVw",
                "version": {
                    "created": "7160399"
                }
            }
        }
    }
}
</code>```

For the search on Elasticsearch, I'm using a custom score function which try to access to minAmount and maxAmount objects inside the search document, but I receive this error:

```<code>Unhandled Exception illegal_argument_exception

No field found for [maxAmount] in mapping

Stack:
[
  "org.elasticsearch.search.lookup.LeafDocLookup.get(LeafDocLookup.java:100)",
  "org.elasticsearch.search.lookup.LeafDocLookup.get(LeafDocLookup.java:28)",
  "score += calculateScoreAmount(doc.maxAmount, doc.minAmount, params);\n  ",
  "                                 ^---- HERE"
]
</code>```

I had the same problem in the past on other entities and I solved it specifying @GenericField(sortable = Sortable.YES) on the property that I needed to access in the score script (please note that without the explicit Sortable.YES I received the error from Elasticsearch during the script score function execution). The problem here is that Amount is a custom defined object and @GenericField(sortable = Sortable.YES) cannot be specified on it.

Can someone help on this?

答:
maxAmount is an object field. It does not make sense to retrieve its value through doc.maxAmount, because this syntax is for accessing doc values, and object fields are not represented in doc values.

I'm not sure what your script is or where you are passing it to Elasticsearch, but the problem is probably there.

If you want to access the docvalues of maxAmount.value/minAmount.value, then you should probably replace calculateScoreAmount(doc.maxAmount, doc.minAmount, params); with calculateScoreAmount(doc['maxAmount.value'].value, doc['minAmount.value'].value, params);

If you want to access the JSON object representing maxAmount/minAmount, then you should not use docvalues but the _source: calculateScoreAmount(ctx._source.maxAmount, ctx._source.minAmount, params);. I'm not sure this syntax is exactly right, since I couldn't find any documentation to access the source in a sort, but it should be close to this. Also, keep in mind that this will be slow if you have lots of documents.

See also:

https://www.elastic.co/guide/en/elasticsearch/reference/7.17/modules-scripting-using.html

https://www.elastic.co/guide/en/elasticsearch/reference/7.17/sort-search-results.html#script-based-sorting

Body:
I've two entities, Search and Amount that I'm mapping using Hibernate Search  in this way:

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ToString
@Entity
@Indexed
public class Search extends SearchableItem {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEARCH_SEQ")
    @DocumentId
    private Long id;

    @Embedded
    @Valid
    @IndexedEmbedded
    private Amount maxAmount;

    @Embedded
    @Valid
    @IndexedEmbedded
    private Amount minAmount;
}

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ToString
@Embeddable
public class Amount {

    @NotNull
    @ScaledNumberField(sortable = Sortable.YES)
    private BigDecimal value;

    @NotNull
    @Enumerated(EnumType.STRING)
    @GenericField
    private CurrencyCode currency;

}

These annotations creates my index in this way on Elasticsearch:

{
    "search-000001": {
        "aliases": {
            "search-read": {
                "is_write_index": false
            },
            "search-write": {
                "is_write_index": true
            }
        },
        "mappings": {
            "dynamic": "strict",
            "properties": {
                "_entity_type": {
                    "type": "keyword",
                    "index": false
                },
                "maxAmount": {
                    "dynamic": "strict",
                    "properties": {
                        "currency": {
                            "type": "keyword",
                            "doc_values": false
                        },
                        "value": {
                            "type": "scaled_float",
                            "scaling_factor": 100
                        }
                    }
                },
                "minAmount": {
                    "dynamic": "strict",
                    "properties": {
                        "currency": {
                            "type": "keyword",
                            "doc_values": false
                        },
                        "value": {
                            "type": "scaled_float",
                            "scaling_factor": 100
                        }
                    }
                }
            }
        },
        "settings": {
            "index": {
                "routing": {
                    "allocation": {
                        "include": {
                            "_tier_preference": "data_content"
                        }
                    }
                },
                "number_of_shards": "1",
                "provided_name": "search-000001",
                "creation_date": "1644485712235",
                "analysis": {
                    "normalizer": {
                        "sort": {
                            "filter": [
                                "asciifolding",
                                "lowercase"
                            ],
                            "type": "custom"
                        }
                    },
                    "analyzer": {
                        "name": {
                            "filter": [
                                "asciifolding",
                                "lowercase"
                            ],
                            "type": "custom",
                            "tokenizer": "standard"
                        },
                        "generic_text": {
                            "filter": [
                                "asciifolding",
                                "lowercase",
                                "porter_stem"
                            ],
                            "type": "custom",
                            "tokenizer": "standard"
                        }
                    }
                },
                "number_of_replicas": "1",
                "uuid": "GBfV36PLT2-JEVPlbE2DVw",
                "version": {
                    "created": "7160399"
                }
            }
        }
    }
}

For the search on Elasticsearch, I'm using a custom score function which try to access to minAmount and maxAmount objects inside the search document, but I receive this error:

Unhandled Exception illegal_argument_exception

No field found for [maxAmount] in mapping

Stack:
[
  "org.elasticsearch.search.lookup.LeafDocLookup.get(LeafDocLookup.java:100)",
  "org.elasticsearch.search.lookup.LeafDocLookup.get(LeafDocLookup.java:28)",
  "score += calculateScoreAmount(doc.maxAmount, doc.minAmount, params);\n  ",
  "                                 ^---- HERE"
]

I had the same problem in the past on other entities and I solved it specifying @GenericField(sortable = Sortable.YES) on the property that I needed to access in the score script (please note that without the explicit Sortable.YES I received the error from Elasticsearch during the script score function execution). The problem here is that Amount is a custom defined object and @GenericField(sortable = Sortable.YES) cannot be specified on it.

Can someone help on this?


问:
MongoDB: how to pass current value to operator?
Here is sample db structure where I'm trying to modify value of every work_starts_at.

```<code>{
    "_id": 1,
    "work_week": [
        {'name': 'ponedeljak', 'work_hours': []},
        {'name': 'utorak', 'work_hours': []},
    ]
},
{
    "_id": 2,
    "work_week": [
        {'name': 'monday', 'work_hours': [
            {'work_starts_at': 1, 'work_ends_at': 2}
        ]},
    ]
},
{
    "_id": 3,
    "work_week": [
        {'name': 'понедельник', 'work_hours': [
            {'work_starts_at': 2, 'work_ends_at': 3},
            {'work_starts_at': 6, 'work_ends_at': 7},
        ]},
        {'name': 'вторник', 'work_hours': []},
    ]
}
</code>```

The best solution I came to is the following (in python), but instead of subtracting 5 from current value of work_week.work_hours.work_starts_at it's traversing I got null. I suppose it's because construction $$CURRENT.work_hours.work_starts_at doesn't point to work_starts_at, so I'm actually subtracting 5 from null.

How can I properly address value of currently traversed element?

collection.update_many(
{},
[
    {
        '$set': {
            'work_week.work_hours.work_starts_at': {
                '$subtract': ['$$CURRENT.work_hours.work_starts_at', 5]
            }
        }
    }
]
```

答:
Thanks to @R2D2! I've translated it to Python (pymongo):

collection.update_many(
        {'work_week.work_hours.work_starts_at': {'$exists': True}},
        {'$inc': {
            'work_week.$[].work_hours.$[].work_starts_at': -5
        }}
    )
```

Body:
Here is sample db structure where I'm trying to modify value of every work_starts_at.

{
    "_id": 1,
    "work_week": [
        {'name': 'ponedeljak', 'work_hours': []},
        {'name': 'utorak', 'work_hours': []},
    ]
},
{
    "_id": 2,
    "work_week": [
        {'name': 'monday', 'work_hours': [
            {'work_starts_at': 1, 'work_ends_at': 2}
        ]},
    ]
},
{
    "_id": 3,
    "work_week": [
        {'name': 'понедельник', 'work_hours': [
            {'work_starts_at': 2, 'work_ends_at': 3},
            {'work_starts_at': 6, 'work_ends_at': 7},
        ]},
        {'name': 'вторник', 'work_hours': []},
    ]
}

The best solution I came to is the following (in python), but instead of subtracting 5 from current value of work_week.work_hours.work_starts_at it's traversing I got null. I suppose it's because construction $$CURRENT.work_hours.work_starts_at doesn't point to work_starts_at, so I'm actually subtracting 5 from null.

How can I properly address value of currently traversed element?

collection.update_many(
{},
[
    {
        '$set': {
            'work_week.work_hours.work_starts_at': {
                '$subtract': ['$$CURRENT.work_hours.work_starts_at', 5]
            }
        }
    }
]


问:
Getting 'DTLS alert' while implementing Quickblox Video Conferencing in React Js
I am implementing Quickblox Video Conference service in my React Application - However I have implemented the Quickblox SDK in my react app and all the Quickblox functions are working perfectly. In the console I have checked the responses of the function they are also working fine. Whenever system tried to attach my localMediaStream to the Streaming server it gives me this error:

```<code>LOCAL WebRTC PeerConnection is down now (reason: DTLS alert) (userId: null)
</code>```

I thought that it could be an issue of SSL because it was deployed on my local MacOS machine, So I deployed that on a Live Server with SSL enabled but error is still same. Here's the code which I am using:

```<code>import React from 'react';
import {observer} from 'mobx-react';
import endcall from '../../../assets/images/endcall.svg';
import './styles.scss';
import adapter from 'webrtc-adapter';
const QBVideoConferencingClient = require('quickblox/quickblox-multiparty-video-conferencing-client-0.8.6.min.js');

@observer class VideoConferencing extends React.Component {

    componentDidMount() {
        const config = {
            server: "wss://-----.quickblox.com:8989", // Hiding on stackoverflow
            //debug: true, // optional
            //iceServers: [], // optional
        };
        //const QB = new QuickBlox();

        const client = new QBVideoConferencingClient(config);
        client
        .createSession()
        .then(() => {
            // session created
            const isRemote = false;
            const userId = null;
            client
            .attachVideoConferencingPlugin(isRemote, userId)
            .then((plugin) => {
                const eventHandler = console.log; // use your own event handler(s)
                Object.keys(plugin.events).forEach((key) =>
                    plugin.on(plugin.events[key], eventHandler)
                );

                plugin.addListener(plugin.events.CONSENT_DIALOG, this.consentDialog);
                plugin.addListener(plugin.events.MEDIA_STATE, this.mediaState);
                plugin.addListener(plugin.events.WEBRTC_STATE, this.webrtcState);
                plugin.addListener(plugin.events.SLOW_LINK, this.slowLink);
                plugin.addListener(plugin.events.ICE_STATE, this.iceState);
                plugin.addListener(plugin.events.DETACHED, this.detached);
                plugin.addListener(plugin.events.CLEANUP, this.cleanup);

                const joinParams = {
                    roomId: "room_12311",
                    userId: parseInt(this.props.match.params.id),
                    // display: "Tarun Narula",
                    // onlyAudio: false,
                    // role: "publisher",
                    // video: "fhdres",
                };

                client
                .join(joinParams)
                .then(() => {
                    // joined successfully

                    client
                    .listOnlineParticipants('room_123')
                    .then((participants) => {
                        // handle as necessary
                        console.log('Participants List');
                        console.log(participants);
                    })
                    .catch((error) => {
                        // handle error
                    });

                    client.on(client.events.PARTICIPANT_JOINED, (userId, userDisplayName) => {
                        //alert('Participant Joined ' + userId + ' -- '+userDisplayName);
                    });

                    client.on(client.events.PARTICIPANT_LEFT, (userId, userDisplayName) => {
                        //alert('Participant Left ' + userId + ' -- '+userDisplayName);
                    });

                    client.on(client.events.LOCAL_STREAM, (stream) => {
                        const localVideo = document.querySelector("video#curUserVidElem");
                        QBVideoConferencingClient.attachMediaStream(localVideo, stream);
                    });

                    client.on(client.events.REMOTE_STREAM, (stream, userId) => {
                        const remoteVideo = document.querySelector("video#frontVideoElem");
                        QBVideoConferencingClient.attachMediaStream(remoteVideo, stream);
                    });

                    client.on(client.events.SESSION_DESTROYED, () => {
                        //alert('Session Destroyed');
                    });

                    client.on(client.events.ERROR, (error) => {
                        // handle error
                        console.log('error');
                        console.log(error);
                        console.log('error');
                    });
                })
                .catch((error) => {
                    // handle error
                });

            })
            .catch((error) => {
                // some error occurred
            });
        })
        .catch((error) => {
            // some error occurred
        });
    }

    consentDialog(on) {
        console.log('consentDialog event start');
        console.log(on);
        console.log('consentDialog event end');
    }

    mediaState(media, receiving) {
        console.log('mediaState event start');
        console.log(media);
        console.log(receiving);
        console.log('mediaState event end');
    }

    webrtcState(on, reason) {
        console.log('webrtcState event start');
        console.log(on);
        console.log(reason);
        console.log('webrtcState event end');
    }

    slowLink(uplink, lost) {
        console.log('slowLink event start');
        console.log(uplink);
        console.log(lost);
        console.log('slowLink event end');
    }

    iceState(state) {
        console.log('iceState event start');
        console.log(state);
        console.log('iceState event end');
    }

    detached() {
        console.log('detached event start');
        console.log('detached event end');
    }

    cleanup() {
        console.log('cleanup event start');
        console.log('cleanup event end');
    }

    render() {
        return (
            <div className="VideoConferencingPage">
                <div className="UpperSection">
                    <video id="frontVideoElem"></video>
                    <video id="curUserVidElem"></video>
                </div>
                <div className="ActionBtns">
                    <div className="StatusText">
                        <p>Status</p>
                    </div>
                    <div className="centerSec">
                        <button className={`MuteCallBtn`}>
                            <span className="icon icon-microphone"></span>
                        </button>
                        <button className="EndCallBtn">
                            <img src={endcall} />
                        </button>
                        <button className={`ToggleScreenCallBtn`}>
                            <span className="icon icon-camrecorder"></span>
                        </button>
                    </div>
                </div>
            </div>
        );
    }
}

export default VideoConferencing;
</code>```

Logs:

```<code>true
index.js:111 consentDialog event start
index.js:112 true
index.js:113 consentDialog event end
index.js:60 Participants List
index.js:61 [{…}]
quickblox-multiparty-video-conferencing-client-0.8.6.min.js:161 false
index.js:111 consentDialog event start
index.js:112 false
index.js:113 consentDialog event end
quickblox-multiparty-video-conferencing-client-0.8.6.min.js:161 checking
index.js:138 iceState event start
index.js:139 checking
index.js:140 iceState event end
quickblox-multiparty-video-conferencing-client-0.8.6.min.js:161 connected
index.js:138 iceState event start
index.js:139 connected
index.js:140 iceState event end
quickblox-multiparty-video-conferencing-client-0.8.6.min.js:161 false "DTLS alert"
index.js:124 webrtcState event start
index.js:125 false
index.js:126 **DTLS alert**
index.js:127 webrtcState event end
index.js:149 cleanup event start
index.js:150 cleanup event end
</code>```

Screenshot:

Steps taken to resolve:

Verified the firewall disabled of my local machine

Verified that any HTML block isn't blocking the camera space

Uploaded the final build to Live server with SSL enabled but still error is there

Researching from many hours but unable to find anything about this. Any help would be appreciated.

Thanks in Advance.

答:
The issue is most likely related to test server problems, as it works fine for me on dedicated one.

As far as I know they cannot guarantee stability of the connection for test server (that was the main reason for our team to use a dedicated server).

Body:
I am implementing Quickblox Video Conference service in my React Application - However I have implemented the Quickblox SDK in my react app and all the Quickblox functions are working perfectly. In the console I have checked the responses of the function they are also working fine. Whenever system tried to attach my localMediaStream to the Streaming server it gives me this error:

LOCAL WebRTC PeerConnection is down now (reason: DTLS alert) (userId: null)

I thought that it could be an issue of SSL because it was deployed on my local MacOS machine, So I deployed that on a Live Server with SSL enabled but error is still same. Here's the code which I am using:

import React from 'react';
import {observer} from 'mobx-react';
import endcall from '../../../assets/images/endcall.svg';
import './styles.scss';
import adapter from 'webrtc-adapter';
const QBVideoConferencingClient = require('quickblox/quickblox-multiparty-video-conferencing-client-0.8.6.min.js');

@observer class VideoConferencing extends React.Component {

    componentDidMount() {
        const config = {
            server: "wss://-----.quickblox.com:8989", // Hiding on stackoverflow
            //debug: true, // optional
            //iceServers: [], // optional
        };
        //const QB = new QuickBlox();

        const client = new QBVideoConferencingClient(config);
        client
        .createSession()
        .then(() => {
            // session created
            const isRemote = false;
            const userId = null;
            client
            .attachVideoConferencingPlugin(isRemote, userId)
            .then((plugin) => {
                const eventHandler = console.log; // use your own event handler(s)
                Object.keys(plugin.events).forEach((key) =>
                    plugin.on(plugin.events[key], eventHandler)
                );

                plugin.addListener(plugin.events.CONSENT_DIALOG, this.consentDialog);
                plugin.addListener(plugin.events.MEDIA_STATE, this.mediaState);
                plugin.addListener(plugin.events.WEBRTC_STATE, this.webrtcState);
                plugin.addListener(plugin.events.SLOW_LINK, this.slowLink);
                plugin.addListener(plugin.events.ICE_STATE, this.iceState);
                plugin.addListener(plugin.events.DETACHED, this.detached);
                plugin.addListener(plugin.events.CLEANUP, this.cleanup);

                const joinParams = {
                    roomId: "room_12311",
                    userId: parseInt(this.props.match.params.id),
                    // display: "Tarun Narula",
                    // onlyAudio: false,
                    // role: "publisher",
                    // video: "fhdres",
                };

                client
                .join(joinParams)
                .then(() => {
                    // joined successfully

                    client
                    .listOnlineParticipants('room_123')
                    .then((participants) => {
                        // handle as necessary
                        console.log('Participants List');
                        console.log(participants);
                    })
                    .catch((error) => {
                        // handle error
                    });

                    client.on(client.events.PARTICIPANT_JOINED, (userId, userDisplayName) => {
                        //alert('Participant Joined ' + userId + ' -- '+userDisplayName);
                    });

                    client.on(client.events.PARTICIPANT_LEFT, (userId, userDisplayName) => {
                        //alert('Participant Left ' + userId + ' -- '+userDisplayName);
                    });

                    client.on(client.events.LOCAL_STREAM, (stream) => {
                        const localVideo = document.querySelector("video#curUserVidElem");
                        QBVideoConferencingClient.attachMediaStream(localVideo, stream);
                    });

                    client.on(client.events.REMOTE_STREAM, (stream, userId) => {
                        const remoteVideo = document.querySelector("video#frontVideoElem");
                        QBVideoConferencingClient.attachMediaStream(remoteVideo, stream);
                    });

                    client.on(client.events.SESSION_DESTROYED, () => {
                        //alert('Session Destroyed');
                    });

                    client.on(client.events.ERROR, (error) => {
                        // handle error
                        console.log('error');
                        console.log(error);
                        console.log('error');
                    });
                })
                .catch((error) => {
                    // handle error
                });

            })
            .catch((error) => {
                // some error occurred
            });
        })
        .catch((error) => {
            // some error occurred
        });
    }

    consentDialog(on) {
        console.log('consentDialog event start');
        console.log(on);
        console.log('consentDialog event end');
    }

    mediaState(media, receiving) {
        console.log('mediaState event start');
        console.log(media);
        console.log(receiving);
        console.log('mediaState event end');
    }

    webrtcState(on, reason) {
        console.log('webrtcState event start');
        console.log(on);
        console.log(reason);
        console.log('webrtcState event end');
    }

    slowLink(uplink, lost) {
        console.log('slowLink event start');
        console.log(uplink);
        console.log(lost);
        console.log('slowLink event end');
    }

    iceState(state) {
        console.log('iceState event start');
        console.log(state);
        console.log('iceState event end');
    }

    detached() {
        console.log('detached event start');
        console.log('detached event end');
    }

    cleanup() {
        console.log('cleanup event start');
        console.log('cleanup event end');
    }

    render() {
        return (

                    <video id="frontVideoElem"></video>
                    <video id="curUserVidElem"></video>

Status

                        <button className={`MuteCallBtn`}>

                        </button>
                        <button className="EndCallBtn">

                        </button>
                        <button className={`ToggleScreenCallBtn`}>

                        </button>

        );
    }
}

export default VideoConferencing;

Logs:

true
index.js:111 consentDialog event start
index.js:112 true
index.js:113 consentDialog event end
index.js:60 Participants List
index.js:61 [{…}]
quickblox-multiparty-video-conferencing-client-0.8.6.min.js:161 false
index.js:111 consentDialog event start
index.js:112 false
index.js:113 consentDialog event end
quickblox-multiparty-video-conferencing-client-0.8.6.min.js:161 checking
index.js:138 iceState event start
index.js:139 checking
index.js:140 iceState event end
quickblox-multiparty-video-conferencing-client-0.8.6.min.js:161 connected
index.js:138 iceState event start
index.js:139 connected
index.js:140 iceState event end
quickblox-multiparty-video-conferencing-client-0.8.6.min.js:161 false "DTLS alert"
index.js:124 webrtcState event start
index.js:125 false
index.js:126 **DTLS alert**
index.js:127 webrtcState event end
index.js:149 cleanup event start
index.js:150 cleanup event end

Screenshot:

Steps taken to resolve:

Verified the firewall disabled of my local machine

Verified that any HTML block isn't blocking the camera space

Uploaded the final build to Live server with SSL enabled but still error is there

Researching from many hours but unable to find anything about this. Any help would be appreciated.

Thanks in Advance.


问:
Visual Code: can't open file [Errno 2] No such file or directory
I need help with my project, I get this when I run my code
https://imgur.com/a/IiYBEBY

and here is my folder, and there is bot.py:

https://imgur.com/a/IiYBEBY

any help will be appreciated, please

答:
You are not in the bot directory.

```<code>
cd bot
</code>```

then run python -u bot.py

Body:
You are not in the bot directory.

cd bot

then run python -u bot.py


问:
It looks like you're trying to access functions.config().algolia but there is no value there
I am trying to run firebase emulators for cloud functions, but when I type firebase emulators:start, everytime I get this error

I tried setting up functions configuration too as suggested by => https://firebase.google.com/docs/functions/local-emulator . It generates .runtimeconfig.json file. But I am still getting the same error.

Note that I am a complete beginner in cloud functions.

答:
changing

```<code> "firebase-tools": "^9.10.2"
</code>```

to

```<code> "firebase-tools": "9.10.2"
</code>```

solved the issue.

Body:
changing

 "firebase-tools": "^9.10.2"

to

 "firebase-tools": "9.10.2"

solved the issue.


问:
Making a simple car game with HTML5 canvas
I'm having a play with HTML5 canvas, and for my first experiment I decided to try make a simple car animation with basic user input. I think I'm most of the way there with basic input and movement, but I just wanted to see if I could take it a bit further.

Demo: http://jsfiddle.net/mpxML/20/
(use arrow keys)

I have an image loading in, you can also see a black square which moves, that is the translate point, or where the car is steering from. I wanted to somehow create a drift effect which can be achieved at higher speeds etc. It also can turn when it's not moving, that isn't right.

Anyway, I just don't know what logic I need to make the car feel more semi-realistic.

Thanks

答:
Great little demo, love it!  I don't drive, these are my ideas.  I recommend experimenting, you don't have to go for realism - remember you are making a game, you want to go for fun :)

Reversing

I would make reverse work properly, when you reverse it doesn't turn in the direction I expect from traditional car movement.

Drifting

This would be triggered when the speed/angle of turning is at a certain amount.  Once these conditions have been met you could do something like prevent any more turning (by locking the current direction) and angle the car ~30o from the direction until the accelerate key is unpressed

Turning

I'm not a driver, but I would think your turning angle would be tighter when you are at a slower speed, perhaps create a simple formula for this, some sort of relationship between speed and turning amount.

Shameless plug

I have to disclose I work for Scirra.com and we have some software Construct 2 (Download), which is a Windows game making program for HTML5 games, it might be worth a look for you (depending on your objectives)!  It is extendible with JavaScript, so you can write your own movement behaviours and use others peoples, making car games is a lot more visual and easier (in our opinions any way!)

ContentLicense: CC BY-SA 3.0


问:
How is a class name used as a generic parameter?
I understand generics in C# and they are used to keep things strongly typed.  I'm using Entity Framework and I'm seeing the < > syntax used, but it seems to be naming a parameter for a method as opposed to a type.

For example

```<code>services.AddDbContext<MyDbContext>(options => options.UseSqlServer(...));
</code>```

MyDbContext is not a type, it's a class needed to link the DB and Models together.  But how is the syntax used here?  Shouldn't it be....

```<code> services.AddDbContext(MyDbContext);
</code>```

Clearly I'm not understanding something about syntax here.

答:
Broadly speaking, unless you've changed them, in recent VS properties would be colored white, types a sort of green and methods yellow.

If you take a look at the MyDbContext in the angle brackets of the first line of code, it will be a greenish kind of color:

```<code>services.AddDbContext<MyDbContext>(...)
                      ^^^^^^^^^^^
                   green means type
</code>```

And in the second it would be white meaning a property representing some instance of a context somewhere (property because it's PascalCase not camelCase):

```<code>services.AddDbContext(MyDbContext)
                      ^^^^^^^^^^^
                   white means property
</code>```

AddDbContext doesn't need an instance; it doesn't want an instance. An important part of what it does is set up dependency injection so that the injector provides instances of a db context: it just wants a type parameter so it knows what type of instances to provide (and how they're configured, options wise etc, what kind of database connection to use etc). Once it knows this it can e.g. create an instance of MyDbContext every time it sees a parameter of type MyDBContext being mentioned in a constructor

```<code>class WhateverController{
    WhateverController(MyDbContext x) <-- this constructor needs a MyDbContext; the injector will make one and supply it

}
</code>```

As such, yes the type(or class; same thing) name you provide in the < > is a parameter, telling what type is being registered, but it actually being an instance of the type wouldn't be super helpful because the only thing the injector would reasonably do with it would be to inspect what type the instance is, remember the type and throw away the instance (because it wants to know the type, it doesn't want an instance - it's job is to create instances of the type for you)

When you write a generic method you're essentially giving the compiler a skeleton it can use to write methods for you. You specify the method as being generic by putting words in angle brackets and the compiler treats them as types that it can substitute for the types it sees you use when you use the method:

```<code>string GetDatedString<T>(T thing){
  return $"{DateTime.Now} {thing.ToString()}"(
}
</code>```

If you call this and provide an int the compiler can conceptually write an int flavored version, which means you don't have to write it.

```<code>string GetDatedString(int thing){
  return $"{DateTime.Now} {thing.ToString()}"(
}
</code>```

Writing one of those for every type in your program would be pretty horrific

There are times, and a good example is when you're setting up dependency injection, when you don't want to (or cannot create) an instance the type you want the injector to provide when it sees you using it. Suppose you have some type MyDbContext that implements interface IMyDbContext and you want the DI to inject an instance of MyDbContext every time it sees you using the interface IMyDbContext in a constructor. If your aim is to communicate the type-you-see and the type-you-shall-create to the injector via some method that took an instance, you'd end up having to cast your type:

```<code>services.AddDbContext((IMyDbContext)new MyDbContext());
</code>```

Here we could do some trickery to stash the static (compile time) type IMyDbContext as well as the runtime type MyDbContext and then know "whenever i see IMyDbContext provide an instance of MyDbContext" but it's not so pretty and essentially still requires us to provide a useless instance when all the injector wants to know are types.. Being able to pass types as arguments without needing to pass instances is nice and clean and helps out with compile time type related goodness. Look at the ugly we had to do to parse an enum before generics:

```<code>Status myStatus = (Status)Enum.Parse(typeof(Status), "Active");
</code>```

Compared to being able to specify a type argument:

```<code>Status myStatus = Enum.Parse<Status>("Active");
</code>```

So all in, with that thing you asked about originally:

```<code>services.AddDbContext<MyDbContext>(...)
</code>```

And another overload:

```<code>services.AddDbContext<IMyDbContext, MyDbContext>(...)
</code>```

that are calls that take arguments that are types because we want it to be - the first is saying "when you come across a class calling for a MyDbContext, give it an instance of one, and the second overload of "when you come across a class calling for a IMyDbContext, give it a MyDbContext" - this letter form being very useful if you want to eg swap your real MyDbContext out for a FakeMyDbContext that also implements IMyDbContext; it looks like a real one for testing purposes but just generates fake data etc so tests run; you don't have to change any of your classes that call for an IMyDbContext, they just call the methods they see in the interface and testing or running your app for real is switched simply by telling the injector "when you see X provide Z instead of Y"

Body:
I understand generics in C# and they are used to keep things strongly typed.  I'm using Entity Framework and I'm seeing the < > syntax used, but it seems to be naming a parameter for a method as opposed to a type.

For example

services.AddDbContext<MyDbContext>(options => options.UseSqlServer(...));

MyDbContext is not a type, it's a class needed to link the DB and Models together.  But how is the syntax used here?  Shouldn't it be....

 services.AddDbContext(MyDbContext);

Clearly I'm not understanding something about syntax here.

Body:
Broadly speaking, unless you've changed them, in recent VS properties would be colored white, types a sort of green and methods yellow.

If you take a look at the MyDbContext in the angle brackets of the first line of code, it will be a greenish kind of color:

services.AddDbContext<MyDbContext>(...)
                      ^^^^^^^^^^^
                   green means type

And in the second it would be white meaning a property representing some instance of a context somewhere (property because it's PascalCase not camelCase):

services.AddDbContext(MyDbContext)
                      ^^^^^^^^^^^
                   white means property

AddDbContext doesn't need an instance; it doesn't want an instance. An important part of what it does is set up dependency injection so that the injector provides instances of a db context: it just wants a type parameter so it knows what type of instances to provide (and how they're configured, options wise etc, what kind of database connection to use etc). Once it knows this it can e.g. create an instance of MyDbContext every time it sees a parameter of type MyDBContext being mentioned in a constructor

class WhateverController{
    WhateverController(MyDbContext x) <-- this constructor needs a MyDbContext; the injector will make one and supply it

}

As such, yes the type(or class; same thing) name you provide in the < > is a parameter, telling what type is being registered, but it actually being an instance of the type wouldn't be super helpful because the only thing the injector would reasonably do with it would be to inspect what type the instance is, remember the type and throw away the instance (because it wants to know the type, it doesn't want an instance - it's job is to create instances of the type for you)

When you write a generic method you're essentially giving the compiler a skeleton it can use to write methods for you. You specify the method as being generic by putting words in angle brackets and the compiler treats them as types that it can substitute for the types it sees you use when you use the method:

string GetDatedString<T>(T thing){
  return $"{DateTime.Now} {thing.ToString()}"(
}

If you call this and provide an int the compiler can conceptually write an int flavored version, which means you don't have to write it.

string GetDatedString(int thing){
  return $"{DateTime.Now} {thing.ToString()}"(
}

Writing one of those for every type in your program would be pretty horrific

There are times, and a good example is when you're setting up dependency injection, when you don't want to (or cannot create) an instance the type you want the injector to provide when it sees you using it. Suppose you have some type MyDbContext that implements interface IMyDbContext and you want the DI to inject an instance of MyDbContext every time it sees you using the interface IMyDbContext in a constructor. If your aim is to communicate the type-you-see and the type-you-shall-create to the injector via some method that took an instance, you'd end up having to cast your type:

services.AddDbContext((IMyDbContext)new MyDbContext());

Here we could do some trickery to stash the static (compile time) type IMyDbContext as well as the runtime type MyDbContext and then know "whenever i see IMyDbContext provide an instance of MyDbContext" but it's not so pretty and essentially still requires us to provide a useless instance when all the injector wants to know are types.. Being able to pass types as arguments without needing to pass instances is nice and clean and helps out with compile time type related goodness. Look at the ugly we had to do to parse an enum before generics:

Status myStatus = (Status)Enum.Parse(typeof(Status), "Active");

Compared to being able to specify a type argument:

Status myStatus = Enum.Parse<Status>("Active");

So all in, with that thing you asked about originally:

services.AddDbContext<MyDbContext>(...)

And another overload:

services.AddDbContext<IMyDbContext, MyDbContext>(...)

that are calls that take arguments that are types because we want it to be - the first is saying "when you come across a class calling for a MyDbContext, give it an instance of one, and the second overload of "when you come across a class calling for a IMyDbContext, give it a MyDbContext" - this letter form being very useful if you want to eg swap your real MyDbContext out for a FakeMyDbContext that also implements IMyDbContext; it looks like a real one for testing purposes but just generates fake data etc so tests run; you don't have to change any of your classes that call for an IMyDbContext, they just call the methods they see in the interface and testing or running your app for real is switched simply by telling the injector "when you see X provide Z instead of Y"


问:
How to view/save AVFrame have format AV_PIX_FMT_YUVJ420P to file
I have a AVFrame and I want to save it to file. If I only store frame->data[0] to file, the image will be Grey image, how to view full color? I use C language.

Do you have any suggestions on what I should read to understand and do these things by myself?

答:
AV_PIX_FMT_YUVJ420P is a planar format.
data[0] is just a Y frame (grayscale), for the full image with the color you need to take into consideration:
data[1] and data[2] for the U and V part of the frame respectively.

And it seems this format (AV_PIX_FMT_YUVJ420P) is deprecated in favor of the more common AV_PIX_FMT_YUV420P format, use this if it's up to you.


问:
How to run shell command after gunicorn service? this is for docker enterypoint.sh file
Below is my docker enterypoint.sh file code

```<code>#!/bin/bash
set -e

python3 test1.py

gunicorn -b 0.0.0.0:8000 "app:app" --workers=1 --threads=10 --timeout=3600

node /home/test2.js
</code>```

I want to run test2.js nodejs app after gunicorn service starts because test2.js required to connect with localhost:8000. Please help me with a solution for this

答:
By default, the next line is only executed after the previous one, but maybe the command ends before the port is active, so you can use a while to check that

```<code>#!/bin/bash
set -e

python3 test1.py

gunicorn -b 0.0.0.0:8000 "app:app" --workers=1 --threads=10 --timeout=3600
#
check=1
#
while [ $check -eq 1 ]
do
  echo "Testing"
  test=$(netstat -nlt | grep "0.0.0.0:8000" &> /dev/null)
  check=$?
  sleep 2
done

node /home/test2.js
</code>```

Body:
Below is my docker enterypoint.sh file code

#!/bin/bash
set -e

python3 test1.py

gunicorn -b 0.0.0.0:8000 "app:app" --workers=1 --threads=10 --timeout=3600

node /home/test2.js

I want to run test2.js nodejs app after gunicorn service starts because test2.js required to connect with localhost:8000. Please help me with a solution for this

Body:
By default, the next line is only executed after the previous one, but maybe the command ends before the port is active, so you can use a while to check that

#!/bin/bash
set -e

python3 test1.py

gunicorn -b 0.0.0.0:8000 "app:app" --workers=1 --threads=10 --timeout=3600
#
check=1
#
while [ $check -eq 1 ]
do
  echo "Testing"
  test=$(netstat -nlt | grep "0.0.0.0:8000" &> /dev/null)
  check=$?
  sleep 2
done

node /home/test2.js


问:
Can't format moment object to date and time
I'm using a react component for Date picking which returns a moment object. Also, I'm using my custom component to select time and saving the value like this for example 3:30 pm .

What I want to do is make this one moment object that I can later user and format however I want.

This is my current implementation but it's not working:

formatting the time is always returning AM

```<code>const time = moment(pickupTime.formattedTime, ['hh:mm a'])
        .locale('en')
        .format('hh:mm A');

const dateTime =
        startDay.locale('en').format('MMM Do YY') + // This is the Date which is a moment object
        ' ' +
        time;
</code>```

答:
Because string + string = string, you cannot get an object by concatenating strings.

What you need is to convert a string to a moment object:

moment('24/12/2019 09:15:00', "DD MM YYYY hh:mm:ss");
```
<p>Result:</p>
```Moment {_isAMomentObject: true, _i: '24/12/2019 09:15:00', _f: 'DD MM YYYY hh:mm:ss', _isUTC: false, _pf: {…}, …}
```

Check out https://momentjs.com/docs/#/parsing/string-format/

Body:
I'm using a react component for Date picking which returns a moment object. Also, I'm using my custom component to select time and saving the value like this for example 3:30 pm .

What I want to do is make this one moment object that I can later user and format however I want.

This is my current implementation but it's not working:

formatting the time is always returning AM

const time = moment(pickupTime.formattedTime, ['hh:mm a'])
        .locale('en')
        .format('hh:mm A');

const dateTime =
        startDay.locale('en').format('MMM Do YY') + // This is the Date which is a moment object
        ' ' +
        time;

Body:
Because string + string = string, you cannot get an object by concatenating strings.

What you need is to convert a string to a moment object:

moment('24/12/2019 09:15:00', "DD MM YYYY hh:mm:ss");

Result:

Moment {_isAMomentObject: true, _i: '24/12/2019 09:15:00', _f: 'DD MM YYYY hh:mm:ss', _isUTC: false, _pf: {…}, …}

Check out https://momentjs.com/docs/#/parsing/string-format/


问:
Merge overlapping date intervals
Is there a better way of merging overlapping date intervals?

The solution I came up with is so simple that now I wonder if someone else has a better idea of how this could be done.

```<code>/***** DATA EXAMPLE *****/
DECLARE @T TABLE (d1 DATETIME, d2 DATETIME)
INSERT INTO @T (d1, d2)
        SELECT '2010-01-01','2010-03-31' UNION SELECT '2010-04-01','2010-05-31'
  UNION SELECT '2010-06-15','2010-06-25' UNION SELECT '2010-06-26','2010-07-10'
  UNION SELECT '2010-08-01','2010-08-05' UNION SELECT '2010-08-01','2010-08-09'
  UNION SELECT '2010-08-02','2010-08-07' UNION SELECT '2010-08-08','2010-08-08'
  UNION SELECT '2010-08-09','2010-08-12' UNION SELECT '2010-07-04','2010-08-16'
  UNION SELECT '2010-11-01','2010-12-31' UNION SELECT '2010-03-01','2010-06-13'

/***** INTERVAL ANALYSIS *****/
WHILE (1=1)  BEGIN
  UPDATE t1 SET t1.d2 = t2.d2
  FROM @T AS t1 INNER JOIN @T AS t2 ON
            DATEADD(day, 1, t1.d2) BETWEEN t2.d1 AND t2.d2
  IF @@ROWCOUNT = 0 BREAK
END

/***** RESULT *****/
SELECT StartDate = MIN(d1) , EndDate = d2
FROM @T
GROUP BY d2
ORDER BY StartDate, EndDate

/***** OUTPUT *****/
/*****
StartDate   EndDate
2010-01-01  2010-06-13
2010-06-15  2010-08-16
2010-11-01  2010-12-31
*****/
</code>```

答:
This Solution is similar to the 1st solution with additional Deletion Condition.
This will sort the data in the main table itself instead of using different table to store the result.

```<code>DROP TABLE IF EXISTS #SampleTable;
CREATE TABLE #SampleTable (StartTime DATETIME NULL, EndTime DATETIME NULL);
INSERT INTO #SampleTable(StartTime, EndTime)
VALUES
    (N'2010-01-01T00:00:00', N'2010-03-31T00:00:00'),
    (N'2010-03-01T00:00:00', N'2010-06-13T00:00:00'),
    (N'2010-04-01T00:00:00', N'2010-05-31T00:00:00'),
    (N'2010-06-15T00:00:00', N'2010-06-25T00:00:00'),
    (N'2010-06-26T00:00:00', N'2010-07-10T00:00:00'),
    (N'2010-07-04T00:00:00', N'2010-08-16T00:00:00'),
    (N'2010-08-01T00:00:00', N'2010-08-05T00:00:00'),
    (N'2010-08-01T00:00:00', N'2010-08-09T00:00:00'),
    (N'2010-08-02T00:00:00', N'2010-08-07T00:00:00'),
    (N'2010-08-08T00:00:00', N'2010-08-08T00:00:00'),
    (N'2010-08-09T00:00:00', N'2010-08-12T00:00:00'),
    (N'2010-11-01T00:00:00', N'2010-12-31T00:00:00');
--
DECLARE @RowCount INT=0;
WHILE(1=1) --
BEGIN
    SET @RowCount=0;
    --
    UPDATE  T1
    SET T1.EndTime=T2.EndTime
    FROM    dbo.#SampleTable AS T1
            INNER JOIN dbo.#SampleTable AS T2 ON  DATEADD(DAY, 1, T1.EndTime) BETWEEN T2.StartTime AND T2.EndTime;
    --
    SET @RowCount=@RowCount+@@ROWCOUNT;
    --
    DELETE  T1
    FROM    dbo.#SampleTable AS T1
            INNER JOIN dbo.#SampleTable AS T2 ON T1.EndTime=T2.EndTime AND T1.StartTime>T2.StartTime;
    --
    SET @RowCount=@RowCount+@@ROWCOUNT;
    --
    IF  @RowCount=0 --
        BREAK;
END;

SELECT * FROM #SampleTable
</code>```

ContentLicense: CC BY-SA 2.5

Title: Merge overlapping date intervals

Body:
Is there a better way of merging overlapping date intervals?

The solution I came up with is so simple that now I wonder if someone else has a better idea of how this could be done.

/***** DATA EXAMPLE *****/
DECLARE @T TABLE (d1 DATETIME, d2 DATETIME)
INSERT INTO @T (d1, d2)
        SELECT '2010-01-01','2010-03-31' UNION SELECT '2010-04-01','2010-05-31'
  UNION SELECT '2010-06-15','2010-06-25' UNION SELECT '2010-06-26','2010-07-10'
  UNION SELECT '2010-08-01','2010-08-05' UNION SELECT '2010-08-01','2010-08-09'
  UNION SELECT '2010-08-02','2010-08-07' UNION SELECT '2010-08-08','2010-08-08'
  UNION SELECT '2010-08-09','2010-08-12' UNION SELECT '2010-07-04','2010-08-16'
  UNION SELECT '2010-11-01','2010-12-31' UNION SELECT '2010-03-01','2010-06-13'

/***** INTERVAL ANALYSIS *****/
WHILE (1=1)  BEGIN
  UPDATE t1 SET t1.d2 = t2.d2
  FROM @T AS t1 INNER JOIN @T AS t2 ON
            DATEADD(day, 1, t1.d2) BETWEEN t2.d1 AND t2.d2
  IF @@ROWCOUNT = 0 BREAK
END

/***** RESULT *****/
SELECT StartDate = MIN(d1) , EndDate = d2
FROM @T
GROUP BY d2
ORDER BY StartDate, EndDate

/***** OUTPUT *****/
/*****
StartDate   EndDate
2010-01-01  2010-06-13
2010-06-15  2010-08-16
2010-11-01  2010-12-31
*****/

Body:
This Solution is similar to the 1st solution with additional Deletion Condition.
This will sort the data in the main table itself instead of using different table to store the result.

DROP TABLE IF EXISTS #SampleTable;
CREATE TABLE #SampleTable (StartTime DATETIME NULL, EndTime DATETIME NULL);
INSERT INTO #SampleTable(StartTime, EndTime)
VALUES
    (N'2010-01-01T00:00:00', N'2010-03-31T00:00:00'),
    (N'2010-03-01T00:00:00', N'2010-06-13T00:00:00'),
    (N'2010-04-01T00:00:00', N'2010-05-31T00:00:00'),
    (N'2010-06-15T00:00:00', N'2010-06-25T00:00:00'),
    (N'2010-06-26T00:00:00', N'2010-07-10T00:00:00'),
    (N'2010-07-04T00:00:00', N'2010-08-16T00:00:00'),
    (N'2010-08-01T00:00:00', N'2010-08-05T00:00:00'),
    (N'2010-08-01T00:00:00', N'2010-08-09T00:00:00'),
    (N'2010-08-02T00:00:00', N'2010-08-07T00:00:00'),
    (N'2010-08-08T00:00:00', N'2010-08-08T00:00:00'),
    (N'2010-08-09T00:00:00', N'2010-08-12T00:00:00'),
    (N'2010-11-01T00:00:00', N'2010-12-31T00:00:00');
--
DECLARE @RowCount INT=0;
WHILE(1=1) --
BEGIN
    SET @RowCount=0;
    --
    UPDATE  T1
    SET T1.EndTime=T2.EndTime
    FROM    dbo.#SampleTable AS T1
            INNER JOIN dbo.#SampleTable AS T2 ON  DATEADD(DAY, 1, T1.EndTime) BETWEEN T2.StartTime AND T2.EndTime;
    --
    SET @RowCount=@RowCount+@@ROWCOUNT;
    --
    DELETE  T1
    FROM    dbo.#SampleTable AS T1
            INNER JOIN dbo.#SampleTable AS T2 ON T1.EndTime=T2.EndTime AND T1.StartTime>T2.StartTime;
    --
    SET @RowCount=@RowCount+@@ROWCOUNT;
    --
    IF  @RowCount=0 --
        BREAK;
END;

SELECT * FROM #SampleTable


问:
VSCode prettier adds `value` to imports in TypeScript React
After configuring prettier with the plugin in VSCode the format on save function adds weird value keywords to every non-default import in my React+TS code.

Like this:

```<code>import { value ApolloProvider } from '@apollo/client';
import { value BrowserRouter as Router, value Switch } from 'react-router-dom';
import Routes from './routes';
import { value client } from './data/apollo-config';
</code>```

With this TS complains about Duplicate identifier 'value'.ts(2300)

Could anyone help me with this? Not sure why this is happening and how to solve it. Running npx prettier --write someFile doesn't add the value keywords.

My package.json:

```<code>    "dependencies": {
        "@apollo/client": "^3.3.6",
        "axios": "^0.21.1",
        "graphql": "^15.4.0",
        "react": "^17.0.1",
        "react-dom": "^17.0.1",
        "react-router-dom": "^5.1.2",
        "react-scripts": "^4.0.0"
    },
    "devDependencies": {
        "prettier": "^2.1.2",
        "eslint-config-prettier": "^8.3.0",
        "eslint-plugin-cypress": "^2.11.2",
        "eslint-plugin-prettier": "^3.1.4",
        "@types/jest": "^26.0.15",
        "@types/lodash.merge": "^4.6.6",
        "@types/node": "^14.14.6",
        "@types/react": "^16.9.55",
        "@types/react-dom": "^16.9.5",
        "@types/react-router-dom": "^5.1.3",
        "cypress": "^6.4.0",
        "http-proxy-middleware": "^1.0.3",
        "lodash.merge": "^4.6.2",
        "start-server-and-test": "^1.11.7",
        "typescript": "^4.5.4"
    },
</code>```

tsconfig.json

```<code>{
  "compilerOptions": {
    "baseUrl": ".",
    "target": "es5",
    "lib": [
      "es6",
      "dom"
    ],
    "allowJs": true,
    "rootDir": "src",
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",
    "sourceMap": true,
    "declaration": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true,
    "noImplicitAny": false
  },
  "include": [
    "src/**/*"
  ],
  "exclude": [
    "node_modules",
    "build"
  ],
  "typeRoots": [
    "./node_modules/@types"
  ],
  "types": [
    "react",
    "react-dom",
    "react-dom-router",
    "jest",
    "node"
  ]
}
</code>```

eslintrc.js

```<code>{
    "parser": "@typescript-eslint/parser", // Specifies the ESLint parser
    "extends": [
        "react-app",
        "plugin:react/recommended", // Uses the recommended rules from @eslint-plugin-react
        "plugin:@typescript-eslint/recommended", // Uses the recommended rules from @typescript-eslint/eslint-plugin+   'prettier/@typescript-eslint',  // Uses eslint-config-prettier to disable ESLint rules from @typescript-eslint/eslint-plugin that would conflict with prettier
        "plugin:prettier/recommended" // Enables eslint-plugin-prettier and displays prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array.
    ],
    "plugins": ["react", "@typescript-eslint", "jest", "cypress"],
    "env": {
        "browser": true,
        "es6": true,
        "jest": true
    },
    "parserOptions": {
        "ecmaVersion": 2018, // Allows for the parsing of modern ECMAScript features
        "sourceType": "module", // Allows for the use of imports
        "ecmaFeatures": {
            "jsx": true // Allows for the parsing of JSX
        }
    },
    "rules": {
        "no-unused-vars": "off",
        "@typescript-eslint/no-unused-vars": "off",
        "@typescript-eslint/explicit-module-boundary-types": "off",
        "@typescript-eslint/no-redeclare": "off",
        "@typescript-eslint/explicit-function-return-type": "off",
        "@typescript-eslint/triple-slash-reference": "off"
    },
    "settings": {
        "react": {
            "version": "detect" // Tells eslint-plugin-react to automatically detect the version of React to use
        }
    }
}
</code>```

答:
Restarting the Extension Host solved the problem for me.

To do so, open the Command Palette (default keyboard shortcut Ctrl⇧P or ⌘⇧P) and search for:

Developer: Restart Extension Host

Body:
After configuring prettier with the plugin in VSCode the format on save function adds weird value keywords to every non-default import in my React+TS code.

Like this:

import { value ApolloProvider } from '@apollo/client';
import { value BrowserRouter as Router, value Switch } from 'react-router-dom';
import Routes from './routes';
import { value client } from './data/apollo-config';

With this TS complains about Duplicate identifier 'value'.ts(2300)

Could anyone help me with this? Not sure why this is happening and how to solve it. Running npx prettier --write someFile doesn't add the value keywords.

My package.json:

    "dependencies": {
        "@apollo/client": "^3.3.6",
        "axios": "^0.21.1",
        "graphql": "^15.4.0",
        "react": "^17.0.1",
        "react-dom": "^17.0.1",
        "react-router-dom": "^5.1.2",
        "react-scripts": "^4.0.0"
    },
    "devDependencies": {
        "prettier": "^2.1.2",
        "eslint-config-prettier": "^8.3.0",
        "eslint-plugin-cypress": "^2.11.2",
        "eslint-plugin-prettier": "^3.1.4",
        "@types/jest": "^26.0.15",
        "@types/lodash.merge": "^4.6.6",
        "@types/node": "^14.14.6",
        "@types/react": "^16.9.55",
        "@types/react-dom": "^16.9.5",
        "@types/react-router-dom": "^5.1.3",
        "cypress": "^6.4.0",
        "http-proxy-middleware": "^1.0.3",
        "lodash.merge": "^4.6.2",
        "start-server-and-test": "^1.11.7",
        "typescript": "^4.5.4"
    },

tsconfig.json

{
  "compilerOptions": {
    "baseUrl": ".",
    "target": "es5",
    "lib": [
      "es6",
      "dom"
    ],
    "allowJs": true,
    "rootDir": "src",
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",
    "sourceMap": true,
    "declaration": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true,
    "noImplicitAny": false
  },
  "include": [
    "src/**/*"
  ],
  "exclude": [
    "node_modules",
    "build"
  ],
  "typeRoots": [
    "./node_modules/@types"
  ],
  "types": [
    "react",
    "react-dom",
    "react-dom-router",
    "jest",
    "node"
  ]
}

eslintrc.js

{
    "parser": "@typescript-eslint/parser", // Specifies the ESLint parser
    "extends": [
        "react-app",
        "plugin:react/recommended", // Uses the recommended rules from @eslint-plugin-react
        "plugin:@typescript-eslint/recommended", // Uses the recommended rules from @typescript-eslint/eslint-plugin+   'prettier/@typescript-eslint',  // Uses eslint-config-prettier to disable ESLint rules from @typescript-eslint/eslint-plugin that would conflict with prettier
        "plugin:prettier/recommended" // Enables eslint-plugin-prettier and displays prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array.
    ],
    "plugins": ["react", "@typescript-eslint", "jest", "cypress"],
    "env": {
        "browser": true,
        "es6": true,
        "jest": true
    },
    "parserOptions": {
        "ecmaVersion": 2018, // Allows for the parsing of modern ECMAScript features
        "sourceType": "module", // Allows for the use of imports
        "ecmaFeatures": {
            "jsx": true // Allows for the parsing of JSX
        }
    },
    "rules": {
        "no-unused-vars": "off",
        "@typescript-eslint/no-unused-vars": "off",
        "@typescript-eslint/explicit-module-boundary-types": "off",
        "@typescript-eslint/no-redeclare": "off",
        "@typescript-eslint/explicit-function-return-type": "off",
        "@typescript-eslint/triple-slash-reference": "off"
    },
    "settings": {
        "react": {
            "version": "detect" // Tells eslint-plugin-react to automatically detect the version of React to use
        }
    }
}


问:
WooCommerce custom pagination is not fetching products according to post per page option value
WooCommerce pagination is not fetching products according to posts per page option value. It shows different products when click on pagination link, sometimes show correct number of products on click of pagination link but some time not. Same query is working for all custom pagination.
Here is my code:

```<code>public function render()
    {
        global $wp_query, $wp_rewrite;
        $args= [];
        $ordering_args =[];
        $pagination_args =[];
        $taxonomy   = 'product_cat';

        $args = array(
            'post_type'           => 'product',
            'post_status'         => 'publish',
            'posts_per_page'      =>  absint(get_option('posts_per_page')),
        );

        if (isset($_POST['orderby'])) {
            if ('price-desc' === $_POST['orderby']) {
                $args['orderby'] = 'price';
                $args['order']   = 'DESC';
            } elseif ('price' === $_POST['orderby']) {
                $args['orderby'] = 'price';
                $args['order']   = 'ASC';
            } elseif ('date' === $_POST['orderby']) {
                $args['orderby'] = 'date';
                $args['order']   = 'DESC';
            } else {
                $args['orderby'] = $_POST['orderby'];
                $args['order'] ='';

            }

            $ordering_args = WC()->query->get_catalog_ordering_args($args['orderby'], $args['order']);
            $args['orderby'] = $ordering_args['orderby'];
            $args['ordering_args']   = $ordering_args;
            $args['order']   = $ordering_args['order'];
            if ($ordering_args['meta_key']) {
                $args['meta_key'] = $ordering_args['meta_key'];
            }
        }else{
            $ordering_args = WC()->query->get_catalog_ordering_args();
            $args['orderby'] = $ordering_args['orderby'];
            $args['ordering_args']   = $ordering_args;
            $args['order']   = $ordering_args['order'];
            if ($ordering_args['meta_key']) {
                $args['meta_key'] = $ordering_args['meta_key'];
            }
        }

        if (isset($_POST['paged'])) {
            $args['paged'] = absint($_POST['paged']);
            if (1 < absint($_POST['paged'])) {
                $args['paged'] = absint($_POST['paged']);
            }
            $pagination_args = array(
                'total'   => wc_get_loop_prop('total_pages'),
                'current' =>absint($_POST['paged']),
            );
            $args['limit'] = isset($args['posts_per_page']) ? intval($args['posts_per_page']) : intval(get_option('posts_per_page'));

            if (empty($args['offset'])) {
               $args['offset'] = 1 < $args['paged'] ? ($args['paged'] - 1) * $args['limit'] : 0;
            }
        }

        if (!empty($args['meta_query'])) {
            if (!empty($_POST['rating'])) {
                $args['meta_query']['relation'] ='AND';
                $rating = $_POST['rating'];
                $args['meta_query'][]= array(
                    'key'     => '_wc_average_rating',
                    'value'   => array( (int)$rating[0],  (int)$rating[1] ),
                    'compare' => 'BETWEEN',
                    'type'    => 'numeric'
                );
            }
        } else {
            if (!empty($_POST['rating'])) {
                $rating = $_POST['rating'];
                $args['meta_query']= array(
                array(
                    'key'     => '_wc_average_rating',
                    'value'   => array( (int)$rating[0],  (int)$rating[1] ),
                    'compare' => 'BETWEEN',
                    'type'    => 'numeric'
                )
            );
            }
        }

        if (!empty($_POST['product-cata'])) {
            $category = $_POST['product-cata'];
            $args['tax_query']= array(
            array(
                'taxonomy'   =>  $taxonomy,
                'field'      => 'term_id',
                'terms'      =>  (int)$category
            )
        );
        }else{
            if (!empty($_POST['category'])) {
                $category = $_POST['category'];
                $args['tax_query']= array(
                array(
                    'taxonomy'   =>  $taxonomy,
                    'field'      => 'term_id',
                    'terms'      =>  (int)$category
                )
            );
            }

        }

        $wp_query = new WP_Query($args);

        if ($wp_query->have_posts()) {
            ob_start();
            // do_action('woocommerce_before_shop_loop');

            woocommerce_product_loop_start();

            while ($wp_query->have_posts()) {
                $wp_query->the_post();
                /**
                 * Hook: woocommerce_shop_loop.
                 */
                do_action('woocommerce_shop_loop');
                echo wc_get_template_part('content', 'product');
            }

            woocommerce_product_loop_end();

            //do_action('woocommerce_after_shop_loop');

            wp_reset_postdata();
            $_RESPONSE['posted_data'] =$_POST;
            $_RESPONSE['products'] = ob_get_contents();
            ob_end_clean();
            if (isset($_POST['paged'])) {
                $paged = (int) $_POST['paged'];
                $base = $_POST['link'].'page/%#%';
                $pagination_args = array(
                    'base'    =>  $base,
                    'total'   => (int)$wp_query->max_num_pages,
                    'per_page' => (int)get_option('posts_per_page'),
                    'current' => (int) max(1,  $paged),
                    'format' => '',
                );
                $_RESPONSE['pagination'] =  $this->custom_woocommerce_pagination($pagination_args);
                $_RESPONSE['result_counts'] =  $this->custom_result_count($pagination_args);
            } else {
                $base = $_POST['link'].'page/%#%';
                $pagination_args = array(
                    'base'    =>  $base,
                    'total'   =>(int) $wp_query->max_num_pages,
                    'per_page' =>(int) get_option('posts_per_page'),
                    'current' => (int) max(1, 1),
                    'format' => '',
                );
                $_RESPONSE['pagination'] =  $this->custom_woocommerce_pagination($pagination_args);
                $_RESPONSE['result_counts'] =  $this->custom_result_count($pagination_args);
            }
            $_RESPONSE['args'] = $args;
            $_RESPONSE['pagination_args'] = $pagination_args;

        } else {
            ob_start();
            do_action('woocommerce_no_products_found');
            $_RESPONSE['products'] = ob_get_contents();
            $_RESPONSE['args'] = $args;
            ob_end_clean();
        }
        echo json_encode($_RESPONSE);
        die();
    }

</code>```

Any help will appreciate. I am using this in ajax post method.

答:
```<code> /*Display only in stock*/
    $args['meta_query'][]= [
        'key' => '_stock_status',
        'value' => 'instock'
    ];
    /*Display only visible product*/
    $args['tax_query'][]= [
            'taxonomy'  => 'product_visibility',
            'terms'     => array( 'exclude-from-catalog' ),
            'field'     => 'name',
            'operator'  => 'NOT IN',
        ];
</code>```

Body:
WooCommerce pagination is not fetching products according to posts per page option value. It shows different products when click on pagination link, sometimes show correct number of products on click of pagination link but some time not. Same query is working for all custom pagination.
Here is my code:

public function render()
    {
        global $wp_query, $wp_rewrite;
        $args= [];
        $ordering_args =[];
        $pagination_args =[];
        $taxonomy   = 'product_cat';

        $args = array(
            'post_type'           => 'product',
            'post_status'         => 'publish',
            'posts_per_page'      =>  absint(get_option('posts_per_page')),
        );

        if (isset($_POST['orderby'])) {
            if ('price-desc' === $_POST['orderby']) {
                $args['orderby'] = 'price';
                $args['order']   = 'DESC';
            } elseif ('price' === $_POST['orderby']) {
                $args['orderby'] = 'price';
                $args['order']   = 'ASC';
            } elseif ('date' === $_POST['orderby']) {
                $args['orderby'] = 'date';
                $args['order']   = 'DESC';
            } else {
                $args['orderby'] = $_POST['orderby'];
                $args['order'] ='';

            }

            $ordering_args = WC()->query->get_catalog_ordering_args($args['orderby'], $args['order']);
            $args['orderby'] = $ordering_args['orderby'];
            $args['ordering_args']   = $ordering_args;
            $args['order']   = $ordering_args['order'];
            if ($ordering_args['meta_key']) {
                $args['meta_key'] = $ordering_args['meta_key'];
            }
        }else{
            $ordering_args = WC()->query->get_catalog_ordering_args();
            $args['orderby'] = $ordering_args['orderby'];
            $args['ordering_args']   = $ordering_args;
            $args['order']   = $ordering_args['order'];
            if ($ordering_args['meta_key']) {
                $args['meta_key'] = $ordering_args['meta_key'];
            }
        }

        if (isset($_POST['paged'])) {
            $args['paged'] = absint($_POST['paged']);
            if (1 < absint($_POST['paged'])) {
                $args['paged'] = absint($_POST['paged']);
            }
            $pagination_args = array(
                'total'   => wc_get_loop_prop('total_pages'),
                'current' =>absint($_POST['paged']),
            );
            $args['limit'] = isset($args['posts_per_page']) ? intval($args['posts_per_page']) : intval(get_option('posts_per_page'));

            if (empty($args['offset'])) {
               $args['offset'] = 1 < $args['paged'] ? ($args['paged'] - 1) * $args['limit'] : 0;
            }
        }

        if (!empty($args['meta_query'])) {
            if (!empty($_POST['rating'])) {
                $args['meta_query']['relation'] ='AND';
                $rating = $_POST['rating'];
                $args['meta_query'][]= array(
                    'key'     => '_wc_average_rating',
                    'value'   => array( (int)$rating[0],  (int)$rating[1] ),
                    'compare' => 'BETWEEN',
                    'type'    => 'numeric'
                );
            }
        } else {
            if (!empty($_POST['rating'])) {
                $rating = $_POST['rating'];
                $args['meta_query']= array(
                array(
                    'key'     => '_wc_average_rating',
                    'value'   => array( (int)$rating[0],  (int)$rating[1] ),
                    'compare' => 'BETWEEN',
                    'type'    => 'numeric'
                )
            );
            }
        }

        if (!empty($_POST['product-cata'])) {
            $category = $_POST['product-cata'];
            $args['tax_query']= array(
            array(
                'taxonomy'   =>  $taxonomy,
                'field'      => 'term_id',
                'terms'      =>  (int)$category
            )
        );
        }else{
            if (!empty($_POST['category'])) {
                $category = $_POST['category'];
                $args['tax_query']= array(
                array(
                    'taxonomy'   =>  $taxonomy,
                    'field'      => 'term_id',
                    'terms'      =>  (int)$category
                )
            );
            }

        }

        $wp_query = new WP_Query($args);

        if ($wp_query->have_posts()) {
            ob_start();
            // do_action('woocommerce_before_shop_loop');

            woocommerce_product_loop_start();

            while ($wp_query->have_posts()) {
                $wp_query->the_post();
                /**
                 * Hook: woocommerce_shop_loop.
                 */
                do_action('woocommerce_shop_loop');
                echo wc_get_template_part('content', 'product');
            }

            woocommerce_product_loop_end();

            //do_action('woocommerce_after_shop_loop');

            wp_reset_postdata();
            $_RESPONSE['posted_data'] =$_POST;
            $_RESPONSE['products'] = ob_get_contents();
            ob_end_clean();
            if (isset($_POST['paged'])) {
                $paged = (int) $_POST['paged'];
                $base = $_POST['link'].'page/%#%';
                $pagination_args = array(
                    'base'    =>  $base,
                    'total'   => (int)$wp_query->max_num_pages,
                    'per_page' => (int)get_option('posts_per_page'),
                    'current' => (int) max(1,  $paged),
                    'format' => '',
                );
                $_RESPONSE['pagination'] =  $this->custom_woocommerce_pagination($pagination_args);
                $_RESPONSE['result_counts'] =  $this->custom_result_count($pagination_args);
            } else {
                $base = $_POST['link'].'page/%#%';
                $pagination_args = array(
                    'base'    =>  $base,
                    'total'   =>(int) $wp_query->max_num_pages,
                    'per_page' =>(int) get_option('posts_per_page'),
                    'current' => (int) max(1, 1),
                    'format' => '',
                );
                $_RESPONSE['pagination'] =  $this->custom_woocommerce_pagination($pagination_args);
                $_RESPONSE['result_counts'] =  $this->custom_result_count($pagination_args);
            }
            $_RESPONSE['args'] = $args;
            $_RESPONSE['pagination_args'] = $pagination_args;

        } else {
            ob_start();
            do_action('woocommerce_no_products_found');
            $_RESPONSE['products'] = ob_get_contents();
            $_RESPONSE['args'] = $args;
            ob_end_clean();
        }
        echo json_encode($_RESPONSE);
        die();
    }

Any help will appreciate. I am using this in ajax post method.


问:
Update SVG progress circle by clicking checkboxes
I have 5 checkboxes representing a To-Do list, for every checkbox I click, the circle's diameter should complete 1/5, 2/5 , 3/5, 4/5, 5/5 until it completes the 5 checkboxes, the order of how the checkboxes are created shouldn't matter. If I clicked "first ToDo" and "third ToDo" without selecting "second ToDo" the circle should still show 2/5 of itself.

So far I've been able to make the circle interact with the input of the checkboxes, but I'm struggling to make the visual progress happen, when I click one of the ToDos the progress circle it's marked but not in the right order and portions, also the idea is that the visual progress should move forward to the right until completing the circle.

Looking for information online, I see people uses <circle path>but it is really confusing for me because some configurations are made through CSS while other people do it in the JS, according to me it is best that I use JS to show the progress, because it should behave in base of the checkboxes.

function update() {

  var myBar = document.getElementById("myCircle");
  //Reference the Form.
  var toDo = document.getElementById("toDo");

  //Reference all the CheckBoxes in Table.
  boxes = toDo.querySelectorAll("input[type='checkbox']:checked");
  checked = boxes.length

  myBar.style.strokeDasharray = ((checked) * 100) + "%";
  if (checked === 0) {
    alert("Please select CheckBox(s).");
  }
  return true;
}

checks = document.querySelectorAll("input[type='checkbox']");
checks.forEach(function(box) {
  box.addEventListener("change", function() {
    update()
  });
});```
<pre class="snippet-code-css lang-css prettyprint-override"><code>#myCircle {
  width: 0;
  height: 30px;
  stroke: #A3BBAD;
  stroke-width: 3px;
}

#myProgress {
  margin: auto;
  width: 50%;
  stroke: #357266;
  stroke-width: 3px;
}</code>```

<svg height="100" width="100">
  <circle id="myProgress" cx="50" cy="50" r="40" fill="transparent"/>
  <circle id="myCircle" cx="50" cy="50" r="40" fill="transparent"/>
</svg>

<form id="toDo">
  <input id="FirstToDo" type="checkbox" value="1" />First
  <input id="SecondToDo" type="checkbox" value="2" />Second
  <input id="ThirdToDo" type="checkbox" value="3" />Third
  <input id="FourthToDo" type="checkbox" value="4" />Fourth
  <input id="FifthToDo" type="checkbox" value="5" />Fifth
</form>
```

答:
you can :

set pathLength="100" on circle tag to say percentage circle take 100% of circle path

the % calculation will be 100 - percent

the css property strokeDashoffset is the one where you can affect percentage with

```<code> myBar.style.strokeDashoffset = 100 - percent;
</code>```

    function update() {

      var myBar = document.getElementById("myProgress");
      //Reference the Form.
      var toDo = document.getElementById("toDo");

      //Reference all the CheckBoxes in Table.
      boxes = toDo.querySelectorAll("input[type='checkbox']:checked");
      checked = boxes.length

      var percent = (checked) * 20;

      myBar.style.strokeDashoffset = 100 - percent;
      if (checked === 0) {
        alert("Please select CheckBox(s).");
      }
      return true;
    }

    checks = document.querySelectorAll("input[type='checkbox']");
    checks.forEach(function(box) {
      box.addEventListener("change", function() {
        update()
      });
    });```
<pre class="snippet-code-css lang-css prettyprint-override"><code>   #mySvg {
      transform: rotate(-90deg);
   }

   #myCircle {
      width: 0;
      height: 30px;
      stroke: #A3BBAD;
      stroke-width: 3px;
    }

    #myProgress {
      margin: auto;
      width: 50%;
      stroke: #357266;
      stroke-width: 3px;
      stroke-dasharray: 100;
      stroke-dashoffset: 100;
    }</code>```

    <!DOCTYPE html>

      <meta charset="UTF-8">
      <title>Circle</title>
      <link rel="stylesheet" href="style.css">

      <svg id="mySvg" height="100" width="100">
        <circle id="myCircle" cx="50" cy="50" r="40" fill="transparent"/>
        <circle id="myProgress" cx="50" cy="50" r="40" fill="transparent" pathLength="100"/>
      </svg>

      <form id="toDo">
        <input id="FirstToDo" type="checkbox" value="1" />First
        <input id="SecondToDo" type="checkbox" value="2" />Second
        <input id="ThirdToDo" type="checkbox" value="3" />Third
        <input id="FourthToDo" type="checkbox" value="4" />Fourth
        <input id="FifthToDo" type="checkbox" value="5" />Fifth
      </form>

    ```

Body:
I have 5 checkboxes representing a To-Do list, for every checkbox I click, the circle's diameter should complete 1/5, 2/5 , 3/5, 4/5, 5/5 until it completes the 5 checkboxes, the order of how the checkboxes are created shouldn't matter. If I clicked "first ToDo" and "third ToDo" without selecting "second ToDo" the circle should still show 2/5 of itself.

So far I've been able to make the circle interact with the input of the checkboxes, but I'm struggling to make the visual progress happen, when I click one of the ToDos the progress circle it's marked but not in the right order and portions, also the idea is that the visual progress should move forward to the right until completing the circle.

Looking for information online, I see people uses <circle path>but it is really confusing for me because some configurations are made through CSS while other people do it in the JS, according to me it is best that I use JS to show the progress, because it should behave in base of the checkboxes.

function update() {

  var myBar = document.getElementById("myCircle");
  //Reference the Form.
  var toDo = document.getElementById("toDo");

  //Reference all the CheckBoxes in Table.
  boxes = toDo.querySelectorAll("input[type='checkbox']:checked");
  checked = boxes.length

  myBar.style.strokeDasharray = ((checked) * 100) + "%";
  if (checked === 0) {
    alert("Please select CheckBox(s).");
  }
  return true;
}

checks = document.querySelectorAll("input[type='checkbox']");
checks.forEach(function(box) {
  box.addEventListener("change", function() {
    update()
  });
});

#myCircle {
  width: 0;
  height: 30px;
  stroke: #A3BBAD;
  stroke-width: 3px;
}

#myProgress {
  margin: auto;
  width: 50%;
  stroke: #357266;
  stroke-width: 3px;
}

<svg height="100" width="100">
  <circle id="myProgress" cx="50" cy="50" r="40" fill="transparent"/>
  <circle id="myCircle" cx="50" cy="50" r="40" fill="transparent"/>
</svg>

<form id="toDo">
  <input id="FirstToDo" type="checkbox" value="1" />First
  <input id="SecondToDo" type="checkbox" value="2" />Second
  <input id="ThirdToDo" type="checkbox" value="3" />Third
  <input id="FourthToDo" type="checkbox" value="4" />Fourth
  <input id="FifthToDo" type="checkbox" value="5" />Fifth
</form>

Body:
you can :

set pathLength="100" on circle tag to say percentage circle take 100% of circle path

the % calculation will be 100 - percent

the css property strokeDashoffset is the one where you can affect percentage with

 myBar.style.strokeDashoffset = 100 - percent;

    function update() {

      var myBar = document.getElementById("myProgress");
      //Reference the Form.
      var toDo = document.getElementById("toDo");

      //Reference all the CheckBoxes in Table.
      boxes = toDo.querySelectorAll("input[type='checkbox']:checked");
      checked = boxes.length

      var percent = (checked) * 20;

      myBar.style.strokeDashoffset = 100 - percent;
      if (checked === 0) {
        alert("Please select CheckBox(s).");
      }
      return true;
    }

    checks = document.querySelectorAll("input[type='checkbox']");
    checks.forEach(function(box) {
      box.addEventListener("change", function() {
        update()
      });
    });

   #mySvg {
      transform: rotate(-90deg);
   }

   #myCircle {
      width: 0;
      height: 30px;
      stroke: #A3BBAD;
      stroke-width: 3px;
    }

    #myProgress {
      margin: auto;
      width: 50%;
      stroke: #357266;
      stroke-width: 3px;
      stroke-dasharray: 100;
      stroke-dashoffset: 100;
    }

    <!DOCTYPE html>
    <html lang="en">

    <head>
      <meta charset="UTF-8">
      <title>Circle</title>
      <link rel="stylesheet" href="style.css">
    </head>

    <body>

      <svg id="mySvg" height="100" width="100">
        <circle id="myCircle" cx="50" cy="50" r="40" fill="transparent"/>
        <circle id="myProgress" cx="50" cy="50" r="40" fill="transparent" pathLength="100"/>
      </svg>
      <br>

      <form id="toDo">
        <input id="FirstToDo" type="checkbox" value="1" /><label for="FirstToDo">First</label>
        <input id="SecondToDo" type="checkbox" value="2" /><label for="SecondToDo">Second</label>
        <input id="ThirdToDo" type="checkbox" value="3" /><label for="ThirdToDo">Third</label>
        <input id="FourthToDo" type="checkbox" value="4" /><label for="FourthToDo">Fourth</label>
        <input id="FifthToDo" type="checkbox" value="5" /><label for="FifthToDo">Fifth</label>
      </form>
      <script src="Circle.js"></script>
    </body>

    </html>